Simple GUI Library
menu_bar.cpp
Go to the documentation of this file.
1/**
2 * @author Nikita Mochalov (github.com/tralf-strues)
3 * @file menu_bar.cpp
4 * @date 2021-11-10
5 *
6 * @copyright Copyright (c) 2021
7 */
8
10#include "scene/scene.h"
11
12namespace Sgl
13{
14 class MenuSelectListener : public Sml::Listener
15 {
16 public:
17 DEFINE_STATIC_LISTENED_EVENT_TYPES(Sml::MouseButtonPressedEvent::getStaticType(),
18 MouseExitedEvent::getStaticType())
19
20 public:
21 MenuSelectListener(MenuBar& menuBar, Menu* menu) : m_MenuBar(menuBar), m_Menu(menu) {}
22
23 virtual void onEvent(Sml::Event* event) override
24 {
25 assert(event->isInCategory(Sml::MouseEvent::getStaticCategory()));
26
27 LOG_LIB_INFO("MenuSelectListener triggered");
28
29 switch (event->getType())
30 {
31 case Sml::MouseButtonPressedEvent::getStaticType():
32 {
33 m_MenuBar.showMenu(m_Menu);
34 break;
35 }
36
37 case MouseExitedEvent::getStaticType():
38 {
39 /* TODO:
40 * Check if the hover transffered to another menu in order to switch
41 * visible menu's context menu with the adjacent one. */
42 break;
43 }
44
45 default:
46 {
47 LOG_LIB_ERROR("Invalid MenuSelectListener event type!");
48 break;
49 }
50 }
51 }
52
53 private:
54 MenuBar& m_MenuBar;
55 Menu* m_Menu;
56 };
57
58 Menu::Menu(Scene* scene, const char* title)
59 : m_TitleButton(new Button{title}), m_ContextMenu(new ContextMenu(scene, m_TitleButton))
60 {
61 m_ContextMenu->setFillAcross(true);
62 }
63
64 Menu::~Menu()
65 {
66 delete m_TitleButton;
67 delete m_ContextMenu;
68 }
69
70 const char* Menu::getTitle() const
71 {
72 return m_TitleButton->getLabel();
73 }
74
75 Button* Menu::getTitleButton()
76 {
77 return m_TitleButton;
78 }
79
80 ContextMenu* Menu::getContextMenu()
81 {
82 return m_ContextMenu;
83 }
84
85 const ColorFill DEFAULT_CONTAINER_FILL = {0xF5'F5'F5'FF};
86 const Background MenuBar::DEFAULT_BACKGROUND = {&DEFAULT_CONTAINER_FILL};
87 const Border MenuBar::DEFAULT_BORDER = Border{Insets{0, 0, 1, 0}, 0xE9'E9'E9'FF};
88
89 MenuBar::MenuBar(Scene* scene)
90 {
91 setScene(scene);
92 setFillAcross(true);
93 setBackground(&DEFAULT_BACKGROUND);
94 setBorder(&DEFAULT_BORDER);
95 }
96
97 // TODO: delete context menus from the scene
98 MenuBar::~MenuBar()
99 {
100 for (Menu* menu : m_Menus)
101 {
102 delete menu;
103 }
104 }
105
106 Menu* MenuBar::addMenu(const char* title)
107 {
108 assert(title);
109 assert(getScene());
110
111 Menu* menu = new Menu{getScene(), title};
112 m_Menus.push_back(menu);
113 menu->getContextMenu()->setVisible(false);
114 menu->getTitleButton()->getEventDispatcher()->attachHandler(MenuSelectListener::EVENT_TYPES,
115 new MenuSelectListener{*this, menu});
116
117 // menu->getTitleButton()->setWidth(menu->getTitleButton().g);
118 // FIXME:
119 // m_Components.insert(getFirstComponent(), menu->getTitleButton());
120 // m_Components.push_back(menu->getMenuItems());
121 addChild(menu->getTitleButton());
122 getScene()->registerContextMenu(menu->getContextMenu());
123
124 return menu;
125 }
126
127 Menu* MenuBar::getMenu(const char* title)
128 {
129 assert(title);
130
131 for (auto menu : m_Menus)
132 {
133 if (strcmp(title, menu->getTitle()) == 0)
134 {
135 return menu;
136 }
137 }
138
139 return nullptr;
140 }
141
142 void MenuBar::showMenu(Menu* menu)
143 {
144 assert(menu);
145 menu->getContextMenu()->show();
146 }
147
148 void MenuBar::hideMenu(Menu* menu)
149 {
150 assert(menu);
151 menu->getContextMenu()->hide();
152 }
153}
void addChild(Component *child)
Convenience method for adding a child to Parent.
Definition: parent.cpp:129