diff --git a/NEWS b/NEWS index 04a374cd..3f5fd5ea 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ ncmpc 0.50 - not yet released * lyrics/google: fix partial loading of lyrics * support MPD 0.22 tag "label" (requires libmpdclient 2.17) * fix config file overriding MPD_HOST environment variable +* click on title bar switches to page * click on progress bar seeks current song * fix tab completion bug diff --git a/src/TabBar.cxx b/src/TabBar.cxx index 54271a6d..f2c2e5c1 100644 --- a/src/TabBar.cxx +++ b/src/TabBar.cxx @@ -9,6 +9,7 @@ #include "GlobalBindings.hxx" #include "i18n.h" #include "ui/Window.hxx" +#include "util/LocaleString.hxx" static void PaintPageTab(const Window window, Command cmd, std::string_view label, bool selected) noexcept @@ -55,3 +56,42 @@ PaintTabBar(const Window window, const PageMeta ¤t_page_meta, page == ¤t_page_meta); } } + +static unsigned +GetTabWidth(Command cmd, std::string_view label) noexcept +{ + unsigned width = 3 + StringWidthMB(label); + + const char *key = GetGlobalKeyBindings().GetFirstKeyName(cmd); + if (key != nullptr) + width += StringWidthMB(key); + + return width; +} + +const PageMeta * +GetTabAtX(const PageMeta ¤t_page_meta, + std::string_view current_page_title, + unsigned x) noexcept +{ + for (unsigned i = 0;; ++i) { + const auto *page = GetPageMeta(i); + if (page == nullptr) + break; + + std::string_view title{}; + if (page == ¤t_page_meta) + title = current_page_title; + + if (title.data() == nullptr) + title = my_gettext(page->title); + + const unsigned tab_width = GetTabWidth(page->command, title); + if (x < tab_width) + return page; + + x -= tab_width; + } + + return nullptr; +} diff --git a/src/TabBar.hxx b/src/TabBar.hxx index eab379ed..6e0153f7 100644 --- a/src/TabBar.hxx +++ b/src/TabBar.hxx @@ -11,3 +11,9 @@ struct PageMeta; void PaintTabBar(Window window, const PageMeta ¤t_page_meta, std::string_view current_page_title) noexcept; + +[[gnu::pure]] +const PageMeta * +GetTabAtX(const PageMeta ¤t_page_meta, + std::string_view current_page_title, + unsigned x) noexcept; diff --git a/src/screen.cxx b/src/screen.cxx index 0f91248d..01c28acf 100644 --- a/src/screen.cxx +++ b/src/screen.cxx @@ -24,6 +24,10 @@ #include "util/ScopeExit.hxx" #include "util/StringAPI.hxx" +#ifdef HAVE_GETMOUSE +#include "TabBar.hxx" +#endif + #include ScreenManager::PageMap::iterator @@ -305,6 +309,17 @@ ScreenManager::OnCommand(struct mpdclient &c, DelayedSeek &seek, Command cmd) #ifdef HAVE_GETMOUSE +inline void +ScreenManager::OnTitleBarMouse(struct mpdclient &c, int x, mmask_t bstate) +{ + if (options.welcome_screen_list && (bstate & BUTTON1_CLICKED)) { + const auto title = GetCurrentPage().GetTitle({buf, buf_size}); + const auto *page = GetTabAtX(GetCurrentPageMeta(), title, x); + if (page != nullptr) + Switch(*page, c); + } +} + inline void ScreenManager::OnProgressBarMouse(struct mpdclient &c, DelayedSeek &seek, int x, mmask_t bstate) @@ -339,6 +354,7 @@ ScreenManager::OnMouse(struct mpdclient &c, DelayedSeek &seek, if (options.show_title_bar) { const int title_height = title_bar.GetHeight(); if (p.y < title_height) { + OnTitleBarMouse(c, p.x, bstate); return; } diff --git a/src/screen.hxx b/src/screen.hxx index d71ed9bb..47ed9448 100644 --- a/src/screen.hxx +++ b/src/screen.hxx @@ -123,6 +123,7 @@ public: void OnCommand(struct mpdclient &c, DelayedSeek &seek, Command cmd); #ifdef HAVE_GETMOUSE + void OnTitleBarMouse(struct mpdclient &c, int x, mmask_t bstate); void OnProgressBarMouse(struct mpdclient &c, DelayedSeek &seek, int x, mmask_t bstate); void OnMouse(struct mpdclient &c, DelayedSeek &seek,