diff --git a/Common/UI/ScrollView.cpp b/Common/UI/ScrollView.cpp index 67769db2b6..c3808eb792 100644 --- a/Common/UI/ScrollView.cpp +++ b/Common/UI/ScrollView.cpp @@ -490,6 +490,25 @@ void ScrollView::ScrollTo(float newScrollPos) { scrollToTarget_ = true; } +void ScrollView::ScrollToCenter(const View *view) { + const Bounds &vBounds = view->GetBounds(); + if (orientation_ == ORIENT_VERTICAL) { + ScrollTo(layoutScrollPos_ + vBounds.centerY() - bounds_.y - bounds_.h * 0.5f); + } else { + ScrollTo(layoutScrollPos_ + vBounds.centerX() - bounds_.x - bounds_.w * 0.5f); + } +} + +ScrollView *GetEnclosingScrollView(View *view) { + for (ViewGroup *group = view->Parent(); group; group = group->Parent()) { + ScrollView *scrollView = dynamic_cast(group); + if (scrollView) { + return scrollView; + } + } + return nullptr; +} + void ScrollView::ScrollRelative(float distance) { scrollTarget_ = scrollPos_ + distance; scrollToTarget_ = true; diff --git a/Common/UI/ScrollView.h b/Common/UI/ScrollView.h index b416dcb8e0..a054e3e752 100644 --- a/Common/UI/ScrollView.h +++ b/Common/UI/ScrollView.h @@ -5,6 +5,11 @@ namespace UI { +class ScrollView; + +// The nearest scroll view the view is in, or null. +ScrollView *GetEnclosingScrollView(View *view); + // A scrollview usually contains just a single child - a linear layout or similar. class ScrollView : public ViewGroup { public: @@ -21,6 +26,8 @@ public: void ScrollTo(float newScrollPos); void ScrollToBottom(); + // Scrolls so that the view (which must be laid out) ends up in the middle. + void ScrollToCenter(const View *view); void ScrollRelative(float distance); bool CanScroll() const; void Update() override; diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index b14d87b7eb..28b01f8631 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -217,6 +217,9 @@ void Clickable::DrawBG(UIContext &dc, const Style &style) { } else { dc.FillRoundRect(style.background, bounds_, dc.GetTheme().choiceRoundRadius, roundCorners_); } + if (highlighted_) { + dc.Draw()->DrawRoundRect(bounds_, dc.GetTheme().choiceRoundRadius, 0xFFFFFFFF, RoundRectStyle::OutlineThin, roundCorners_); + } } void Clickable::ClickInternal() { diff --git a/Common/UI/View.h b/Common/UI/View.h index 768bd38414..0eef740735 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -565,6 +565,9 @@ public: void FocusChanged(FocusFlags focusFlags) override; + // Outlines it, to point it out without the keyboard focus (which would turn on keyboard navigation). + void SetHighlighted(bool highlighted) { highlighted_ = highlighted; } + Event OnClick; protected: @@ -579,6 +582,7 @@ protected: int downCountDown_ = 0; bool dragging_ = false; bool down_ = false; + bool highlighted_ = false; }; // TODO: Very similar to Choice, should probably merge them. diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 3aac594438..8dc508d686 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -891,12 +891,14 @@ void NativeInit(int argc, const char *argv[], const CommandLineOptions &cmdLineO if (equals(cmdLineOptions.startScreen.value(), "touchscreentest")) { g_screenManager->switchScreen(new MainScreen()); g_screenManager->push(new TouchTestScreen(Path())); - } - if (equals(cmdLineOptions.startScreen.value(), "gamesettings")) { + } else if (equals(cmdLineOptions.startScreen.value(), "gamesettings")) { g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::TO_GAME_SETTINGS)); } else if (equals(cmdLineOptions.startScreen.value(), "developertools")) { g_screenManager->switchScreen(new MainScreen()); g_screenManager->push(new DeveloperToolsScreen(Path())); + } else { + WARN_LOG(Log::System, "Unknown start screen '%s'", cmdLineOptions.startScreen.value().c_str()); + g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT)); } } else if (skipLogo && !boot_filename.empty()) { INFO_LOG(Log::System, "Launching EmuScreen with boot filename '%s'", boot_filename.c_str()); diff --git a/UI/UIAtlas.cpp b/UI/UIAtlas.cpp index e936252d76..f7ca4191a9 100644 --- a/UI/UIAtlas.cpp +++ b/UI/UIAtlas.cpp @@ -124,6 +124,7 @@ static const ImageMeta g_uiImageIDs[] = { {"I_ARROW_RIGHT", true}, {"I_ARROW_UP", true}, {"I_ARROW_DOWN", true}, + {"I_CHEVRON_RIGHT", false}, {"I_SLIDERS", false}, {"I_THREE_DOTS", true}, {"I_INFO", false}, diff --git a/assets/ui_images/images.svg b/assets/ui_images/images.svg index 7ac247ca9e..b6db9ec045 100644 --- a/assets/ui_images/images.svg +++ b/assets/ui_images/images.svg @@ -233,6 +233,9 @@ d="m 20.003686,15.425178 -4.588999,-4.577262 -0.0308,3.553627 -4.535971,3e-6 v 2.072375 l 4.535971,-2e-6 0.031,3.529868 z" style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.35133" sodipodi:nodetypes="cccccccc" />