From fbb2d16639491fdb0c49e388278fabcc4b0800f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 29 Jun 2016 17:27:28 +0200 Subject: [PATCH] allow to alter button labels via fluxbox-remote Command is "RelabelButton button.foo $LABEL" This is useful to eg. hint the amount of unread mails in a button to start your MUA, reflect the $USER in a session menu button etc. --- src/Screen.cc | 24 ++++++++++++++++++++++++ src/Screen.hh | 11 +++++++++++ src/ToolFactory.cc | 1 + src/Toolbar.cc | 13 ++++++++----- src/Toolbar.hh | 2 ++ src/WorkspaceCmd.cc | 25 +++++++++++++++++++++++++ src/WorkspaceCmd.hh | 11 +++++++++++ 7 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/Screen.cc b/src/Screen.cc index 24e06072..83a864bc 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -392,6 +392,7 @@ BScreen::~BScreen() { return; m_toolbar.reset(0); + m_toolButtonMap.reset(0); FbTk::EventManager *evm = FbTk::EventManager::instance(); evm->remove(rootWindow()); @@ -454,6 +455,7 @@ void BScreen::initWindows() { #ifdef USE_TOOLBAR if (m_opts & Fluxbox::OPT_TOOLBAR) { + m_toolButtonMap.reset(new ToolButtonMap()); Toolbar* tb = new Toolbar(*this, *layerManager().getLayer(::ResourceLayer::NORMAL)); m_toolbar.reset(tb); } @@ -1293,6 +1295,28 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, } } +#if USE_TOOLBAR + +void BScreen::clearToolButtonMap() { + m_toolButtonMap->clear(); +} + +void BScreen::mapToolButton(std::string name, FbTk::TextButton *button) { + m_toolButtonMap->insert(std::pair(name, button)); +} + +bool BScreen::relabelToolButton(std::string button, std::string label) { + ToolButtonMap::const_iterator it = m_toolButtonMap->find(button); + if (it != m_toolButtonMap->end() && it->second) { + it->second->setText(label); + m_toolbar->relayout(); + return true; + } + return false; +} + +#endif + void BScreen::initMenus() { m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); diff --git a/src/Screen.hh b/src/Screen.hh index a6aa9fb0..f418d0ca 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -69,8 +69,10 @@ class Menu; class ImageControl; class LayerItem; class FbWindow; +class TextButton; } +typedef std::map ToolButtonMap; /// Handles screen connection, screen clients and workspaces /** @@ -343,6 +345,14 @@ public: void reassociateWindow(FluxboxWindow *window, unsigned int workspace_id, bool ignore_sticky); +#if USE_TOOLBAR + /** + * manage a map of named FbTk::TextButton's + */ + void clearToolButtonMap(); + void mapToolButton(std::string name, FbTk::TextButton *button); + bool relabelToolButton(std::string button, std::string label); +#endif void reconfigure(); void reconfigureTabs(); @@ -489,6 +499,7 @@ private: std::auto_ptr m_slit; std::auto_ptr m_toolbar; + std::auto_ptr m_toolButtonMap; Workspace *m_current_workspace; diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc index 4a932eaf..d1d3581e 100644 --- a/src/ToolFactory.cc +++ b/src/ToolFactory.cc @@ -119,6 +119,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow & if (label.empty()) return 0; FbTk::TextButton *btn = new FbTk::TextButton(parent, m_button_theme->font(), label); + screen().mapToolButton(name, btn); std::string cmd_str = FbTk::Resource (m_screen.resourceManager(), "", diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 29209252..3ceb880b 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -364,6 +364,12 @@ void Toolbar::screenChanged(BScreen &screen) { reconfigure(); } +void Toolbar::relayout() { + forAll(m_item_list, std::mem_fun(&ToolbarItem::updateSizing)); + rearrangeItems(); + forAll(m_item_list, std::bind2nd(std::mem_fun(&ToolbarItem::renderTheme), alpha())); +} + void Toolbar::reconfigure() { updateVisibleState(); @@ -404,6 +410,7 @@ void Toolbar::reconfigure() { // destroy tools and rebuild them deleteItems(); + screen().clearToolButtonMap(); // they will be readded later menu().removeAll(); setupMenus(true); // rebuild menu but skip rebuild of placement menu @@ -489,11 +496,7 @@ void Toolbar::reconfigure() { if (theme()->shape() && m_shape.get()) m_shape->update(); - forAll(m_item_list, std::mem_fun(&ToolbarItem::updateSizing)); - - rearrangeItems(); - - forAll(m_item_list, std::bind2nd(std::mem_fun(&ToolbarItem::renderTheme), alpha())); + relayout(); // we're done with all resizing and stuff now we can request a new // area to be reserved on screen diff --git a/src/Toolbar.hh b/src/Toolbar.hh index c31a85f7..919b22f0 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -53,6 +53,7 @@ class ToolbarItem; namespace FbTk { class ImageControl; class Shape; +class TextButton; } /// The toolbar. @@ -100,6 +101,7 @@ public: void handleEvent(XEvent &event); //@} + void relayout(); void reconfigure(); void setPlacement(Placement where); diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index bdba96ca..a6420081 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc @@ -686,3 +686,28 @@ void CloseAllWindowsCmd::execute() { windows.end(), std::mem_fun(&FluxboxWindow::close)); } + +void RelabelButtonCmd::execute() { +#if USE_TOOLBAR + if (BScreen *screen = Fluxbox::instance()->mouseScreen()) + screen->relabelToolButton(m_button, m_label); +#endif +} + +FbTk::Command *RelabelButtonCmd::parse(const std::string &command, + const std::string &args, bool trusted) { + std::string button, label; + std::size_t ws = args.find_first_of(" \t\n"); + if (ws != std::string::npos) { + button = args.substr(0, ws); + if (button.find("button.") == 0) { + label = args.substr(ws + 1, std::string::npos); + } else { + button.clear(); + } + } + return new RelabelButtonCmd(button, label); +} + +REGISTER_COMMAND_PARSER(relabelbutton, RelabelButtonCmd::parse, void); + diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh index ae0b577f..b118d02e 100644 --- a/src/WorkspaceCmd.hh +++ b/src/WorkspaceCmd.hh @@ -217,4 +217,15 @@ public: void execute(); }; +class RelabelButtonCmd: public FbTk::Command { +public: + explicit RelabelButtonCmd(std::string button, std::string label): + m_button(button), m_label(label) {} + void execute(); + static FbTk::Command *parse(const std::string &command, + const std::string &args, bool trusted); +private: + std::string m_button, m_label; +}; + #endif // WORKSPACECMD_HH