TGUI  0.9.1
MenuBar.hpp
1 //
3 // TGUI - Texus' Graphical User Interface
4 // Copyright (C) 2012-2021 Bruno Van de Velde (vdv_b@tgui.eu)
5 //
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source distribution.
22 //
24 
25 
26 #ifndef TGUI_MENU_BAR_HPP
27 #define TGUI_MENU_BAR_HPP
28 
29 
30 #include <TGUI/Widget.hpp>
31 #include <TGUI/Renderers/MenuBarRenderer.hpp>
32 #include <TGUI/CopiedSharedPtr.hpp>
33 #include <TGUI/Text.hpp>
34 
36 
37 namespace tgui
38 {
39  class MenuBarMenuPlaceholder;
40 
41 
45  class TGUI_API MenuBar : public Widget
46  {
47  public:
48 
49  typedef std::shared_ptr<MenuBar> Ptr;
50  typedef std::shared_ptr<const MenuBar> ConstPtr;
51 
54  {
55  String text;
56  bool enabled;
57  std::vector<GetMenusElement> menuItems;
58  };
59 
61  struct Menu
62  {
63  Text text;
64  bool enabled = true;
65  int selectedMenuItem = -1;
66  std::vector<Menu> menuItems;
67  };
68 
69 
77  MenuBar(const char* typeName = "MenuBar", bool initRenderer = true);
78 
79 
81  // Copy constructor
83  MenuBar(const MenuBar& other);
84 
86  // Move constructor
88  MenuBar(MenuBar&& other);
89 
91  // Copy assignment operator
93  MenuBar& operator=(const MenuBar& other);
94 
96  // Move assignment operator
98  MenuBar& operator=(MenuBar&& other);
99 
100 
108 
109 
119 
120 
126  const MenuBarRenderer* getSharedRenderer() const;
127 
134  const MenuBarRenderer* getRenderer() const;
135 
136 
150  template <typename Func, typename... Args>
151  unsigned int connectMenuItem(const String& menu, const String& menuItem, Func&& handler, const Args&... args)
152  {
153  return connectMenuItem({menu, menuItem}, std::forward<Func>(handler), args...);
154  }
155 
156 
170  template <typename Func, typename... Args>
171  unsigned int connectMenuItem(const std::vector<String>& hierarchy, Func&& handler, const Args&... args)
172  {
173 #if defined(__cpp_lib_invoke) && (__cpp_lib_invoke >= 201411L)
174  return onMenuItemClick.connect(
175  [=](const std::vector<String>& clickedMenuItem)
176  {
177  if (clickedMenuItem == hierarchy)
178  std::invoke(handler, args...);
179  }
180  );
181 #else
182  return onMenuItemClick.connect(
183  [f=std::function<void(const Args&...)>(handler),args...,hierarchy](const std::vector<String>& clickedMenuItem)
184  {
185  if (clickedMenuItem == hierarchy)
186  f(args...);
187  }
188  );
189 #endif
190  }
191 
192 
201  void setSize(const Layout2d& size) override;
202  using Widget::setSize;
203 
204 
212  void setEnabled(bool enabled) override;
213 
214 
221  void addMenu(const String& text);
222 
223 
241  bool addMenuItem(const String& text);
242 
243 
262  bool addMenuItem(const String& menu, const String& text);
263 
264 
281  bool addMenuItem(const std::vector<String>& hierarchy, bool createParents = true);
282 
283 
288 
289 
300  bool removeMenu(const String& menu);
301 
302 
312  bool removeMenuItem(const String& menu, const String& menuItem);
313 
314 
328  bool removeMenuItem(const std::vector<String>& hierarchy, bool removeParentsWhenEmpty = true);
329 
330 
339  bool removeMenuItems(const String& menu);
340 
341 
353  bool removeSubMenuItems(const std::vector<String>& hierarchy);
354 
355 
362  bool setMenuEnabled(const String& menu, bool enabled);
363 
364 
370  bool getMenuEnabled(const String& menu) const;
371 
372 
380  bool setMenuItemEnabled(const String& menu, const String& menuItem, bool enabled);
381 
382 
389  bool setMenuItemEnabled(const std::vector<String>& hierarchy, bool enabled);
390 
391 
398  bool getMenuItemEnabled(const String& menu, const String& menuItem) const;
399 
400 
406  bool getMenuItemEnabled(const std::vector<String>& hierarchy) const;
407 
408 
413  void setTextSize(unsigned int size) override;
414 
415 
425  void setMinimumSubMenuWidth(float minimumWidth);
426 
427 
436  float getMinimumSubMenuWidth() const;
437 
438 
445  void setInvertedMenuDirection(bool invertDirection);
446 
447 
455 
456 
462  std::vector<GetMenusElement> getMenus() const;
463 
464 
468  void closeMenu();
469 
470 
477  bool isMouseOnWidget(Vector2f pos) const override;
478 
482  void leftMousePressed(Vector2f pos) override;
483 
487  void leftMouseReleased(Vector2f pos) override;
488 
492  void mouseMoved(Vector2f pos) override;
493 
494 
502  void draw(BackendRenderTargetBase& target, RenderStates states) const override;
503 
504 
506  protected:
507 
517  Signal& getSignal(String signalName) override;
518 
519 
526  void rendererChanged(const String& property) override;
527 
528 
532  std::unique_ptr<DataIO::Node> save(SavingRenderersMap& renderers) const override;
533 
534 
538  void load(const std::unique_ptr<DataIO::Node>& node, const LoadingRenderersMap& renderers) override;
539 
540 
542  // Makes a copy of the widget
544  Widget::Ptr clone() const override
545  {
546  return std::make_shared<MenuBar>(*this);
547  }
548 
549 
554  void openMenu(std::size_t menuIndex);
555 
556 
559  void createMenu(std::vector<Menu>& menus, const String& text);
560 
564  Menu* findMenu(const std::vector<String>& hierarchy, unsigned int parentIndex, std::vector<Menu>& menus, bool createParents);
565 
569  const Menu* findMenu(const std::vector<String>& hierarchy, unsigned int parentIndex, const std::vector<Menu>& menus) const;
570 
573  const Menu* findMenuItem(const std::vector<String>& hierarchy) const;
574 
577  void loadMenus(const std::unique_ptr<DataIO::Node>& node, std::vector<Menu>& menus);
578 
581  void closeSubMenus(std::vector<Menu>& menus, int& selectedMenu);
582 
584  void deselectBottomItem();
585 
587  void updateMenuTextColor(Menu& menu, bool selected);
588 
590  void updateTextColors(std::vector<Menu>& menus, int selectedMenu);
591 
593  void updateTextOpacity(std::vector<Menu>& menus);
594 
596  void updateTextFont(std::vector<Menu>& menus);
597 
600  float calculateMenuWidth(const Menu& menu) const;
601 
604  float getMenuItemHeight(const Menu& menuItem) const;
605 
608  float calculateOpenMenuHeight(const std::vector<Menu>& menuItems) const;
609 
611  Vector2f calculateSubmenuOffset(const Menu& menu, float globalLeftPos, float menuWidth, float subMenuWidth, bool& openSubMenuToRight) const;
612 
614  bool isMouseOnTopOfMenu(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, const Menu& menu, float menuWidth) const;
615 
617  bool findMenuItemBelowMouse(Vector2f menuPos, Vector2f mousePos, bool openSubMenuToRight, Menu& menu, float menuWidth, Menu** resultMenu, int* resultSelectedMenuItem);
618 
621  void drawMenusOnBar(BackendRenderTargetBase& target, RenderStates states) const;
622 
625  void drawMenu(BackendRenderTargetBase& target, RenderStates states, const Menu& menu, float menuWidth, float globalLeftPos, bool openSubMenuToRight) const;
626 
627 
634  bool isMouseOnOpenMenu(Vector2f pos) const;
635 
640  void leftMouseReleasedOnMenu();
641 
647  void mouseMovedOnMenu(Vector2f pos);
648 
655  void drawOpenMenu(BackendRenderTargetBase& target, RenderStates states) const;
656 
657 
659  public:
660 
665  SignalItemHierarchy onMenuItemClick = {"MenuItemClicked"};
666 
667 
669  protected:
670 
671  std::vector<Menu> m_menus;
672  std::shared_ptr<MenuBarMenuPlaceholder> m_menuWidgetPlaceholder;
673 
674  int m_visibleMenu = -1;
675 
676  float m_minimumSubMenuWidth = 125;
677 
678  bool m_invertedMenuDirection = false;
679 
680  Sprite m_spriteBackground;
681  Sprite m_spriteItemBackground;
682  Sprite m_spriteSelectedItemBackground;
683 
684  // Cached renderer properties
685  Color m_backgroundColorCached;
686  Color m_selectedBackgroundColorCached;
687  Color m_textColorCached;
688  Color m_selectedTextColorCached;
689  Color m_textColorDisabledCached;
690  Color m_separatorColorCached = Color::Black;
691  float m_separatorThicknessCached = 1;
692  float m_separatorVerticalPaddingCached = 0;
693  float m_separatorSidePaddingCached = 0;
694  float m_distanceToSideCached = 0;
695 
697 
698  friend class MenuBarMenuPlaceholder;
699  };
700 
701 
707  {
708  public:
709 
710  // Instances of this class can't be copied
712  MenuBarMenuPlaceholder& operator=(const MenuBarMenuPlaceholder&) = delete;
713 
714 
720 
721 
729  Vector2f getFullSize() const override;
730 
731 
739  Vector2f getWidgetOffset() const override;
740 
741 
746  bool isMouseOnWidget(Vector2f pos) const override;
747 
748 
755  void draw(BackendRenderTargetBase& target, RenderStates states) const override;
756 
757 
761  void leftMouseButtonNoLongerDown() override;
762 
766  void mouseMoved(Vector2f pos) override;
767 
768 
770  // Makes a copy of the widget
772  Widget::Ptr clone() const override;
773 
774 
776  private:
777  MenuBar* m_menuBar;
778  bool m_mouseWasOnMenuBar = true; // When a menu opens then the mouse will be on top of the menu bar
779  };
780 
782 }
783 
784 
786 
787 #endif // TGUI_MENU_BAR_HPP
Base class for render targets.
Definition: BackendRenderTarget.hpp:48
Wrapper for colors.
Definition: Color.hpp:52
static const Color Black
Black predefined color.
Definition: Color.hpp:236
Class to store the position or size of a widget.
Definition: Layout.hpp:262
Widget that is added to a container when the user clicks on the menu bar. This widget will be added i...
Definition: MenuBar.hpp:707
Vector2f getFullSize() const override
Returns the entire size that the widget is using.
void draw(BackendRenderTargetBase &target, RenderStates states) const override
Draw the widget to a render target.
Widget::Ptr clone() const override
Makes a copy of the widget if you don't know its exact type.
MenuBarMenuPlaceholder(MenuBar *menuBar)
Constructor.
Vector2f getWidgetOffset() const override
Returns the distance between the position where the widget is drawn and where the widget is placed.
bool isMouseOnWidget(Vector2f pos) const override
Returns whether the mouse position (which is relative to the parent widget) lies on top of an open me...
Renderer for the MenuBar widget.
Definition: MenuBarRenderer.hpp:40
Menu bar widget.
Definition: MenuBar.hpp:46
bool setMenuItemEnabled(const String &menu, const String &menuItem, bool enabled)
Enable or disable a menu item.
bool removeMenuItems(const String &menu)
Removes all menu items from a menu.
bool setMenuEnabled(const String &menu, bool enabled)
Enable or disable an entire menu.
void setEnabled(bool enabled) override
Enables or disables the widget.
unsigned int connectMenuItem(const std::vector< String > &hierarchy, Func &&handler, const Args &... args)
Connects a signal handler to the "MenuItemClicked" callback that will only be called when a specific ...
Definition: MenuBar.hpp:171
bool removeSubMenuItems(const std::vector< String > &hierarchy)
Removes a all menu items below a (sub) menu.
Widget::Ptr clone() const override
Makes a copy of the widget if you don't know its exact type.
Definition: MenuBar.hpp:544
float getMinimumSubMenuWidth() const
Returns the distance between the text and the side of the menu item.
void closeMenu()
Closes the open menu when one of the menus is open.
void rendererChanged(const String &property) override
Function called when one of the properties of the renderer is changed.
void setTextSize(unsigned int size) override
Changes the character size of the text.
bool addMenuItem(const String &menu, const String &text)
Adds a new menu item to an existing menu.
bool addMenuItem(const std::vector< String > &hierarchy, bool createParents=true)
Adds a new menu item (or sub menu item)
std::shared_ptr< const MenuBar > ConstPtr
Shared constant widget pointer.
Definition: MenuBar.hpp:50
bool getInvertedMenuDirection() const
Returns whether the menus open above or below the menu bar.
void openMenu(std::size_t menuIndex)
Opens a menu.
bool isMouseOnWidget(Vector2f pos) const override
Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget...
void load(const std::unique_ptr< DataIO::Node > &node, const LoadingRenderersMap &renderers) override
Loads the widget from a tree of nodes.
void addMenu(const String &text)
Adds a new menu.
void removeAllMenus()
Removes all menus.
bool removeMenuItem(const String &menu, const String &menuItem)
Removes a menu item.
static MenuBar::Ptr copy(MenuBar::ConstPtr menuBar)
Makes a copy of another menu bar.
bool getMenuEnabled(const String &menu) const
Check if an entire menu is enabled or disabled.
std::shared_ptr< MenuBar > Ptr
Shared widget pointer.
Definition: MenuBar.hpp:49
void setMinimumSubMenuWidth(float minimumWidth)
Changes the minimum width of the submenus.
MenuBarRenderer * getSharedRenderer()
Returns the renderer, which gives access to functions that determine how the widget is displayed.
static MenuBar::Ptr create()
Creates a new menu bar widget.
bool addMenuItem(const String &text)
Adds a new menu item to the last added menu.
std::unique_ptr< DataIO::Node > save(SavingRenderersMap &renderers) const override
Saves the widget as a tree node in order to save it to a file.
bool setMenuItemEnabled(const std::vector< String > &hierarchy, bool enabled)
Enable or disable a menu item.
bool removeMenuItem(const std::vector< String > &hierarchy, bool removeParentsWhenEmpty=true)
Removes a menu item (or sub menu item)
bool getMenuItemEnabled(const std::vector< String > &hierarchy) const
Check if a menu item is enabled or disabled.
unsigned int connectMenuItem(const String &menu, const String &menuItem, Func &&handler, const Args &... args)
Connects a signal handler to the "MenuItemClicked" callback that will only be called when a specific ...
Definition: MenuBar.hpp:151
void setInvertedMenuDirection(bool invertDirection)
Changes whether the menus open above or below the menu bar.
void setSize(const Layout2d &size) override
Changes the size of the menu bar.
bool getMenuItemEnabled(const String &menu, const String &menuItem) const
Check if a menu item is enabled or disabled.
MenuBarRenderer * getRenderer()
Returns the renderer, which gives access to functions that determine how the widget is displayed.
bool removeMenu(const String &menu)
Removes a menu.
Signal & getSignal(String signalName) override
Retrieves a signal based on its name.
void draw(BackendRenderTargetBase &target, RenderStates states) const override
Draw the widget to a render target.
Signal to which the user can subscribe to get callbacks from.
Definition: Signal.hpp:780
Signal to which the user can subscribe to get callbacks from.
Definition: Signal.hpp:58
Definition: Sprite.hpp:49
Wrapper class to store strings.
Definition: String.hpp:74
Definition: Text.hpp:44
The parent class for every widget.
Definition: Widget.hpp:70
std::shared_ptr< Widget > Ptr
Shared widget pointer.
Definition: Widget.hpp:73
virtual void setSize(const Layout2d &size)
Changes the size of the widget.
Namespace that contains all TGUI functions and classes.
Definition: AbsoluteOrRelativeValue.hpp:36
Used for return value of getMenus.
Definition: MenuBar.hpp:54
Definition: MenuBar.hpp:62
States used for drawing.
Definition: RenderStates.hpp:39