113 lines
3.3 KiB
C++
113 lines
3.3 KiB
C++
#include "menu_bar.h"
|
|
#include "gfx/shape_renderer.h"
|
|
#include "gfx/txt_renderer.h"
|
|
#include "gfx/types.h"
|
|
|
|
MenuBar::MenuBar(int height)
|
|
: _height(height) {}
|
|
|
|
MenuBar::~MenuBar(void) {}
|
|
|
|
void MenuBar::add_menu(const std::string& label) {
|
|
_menus.push_back({label, {}, false});
|
|
}
|
|
|
|
void MenuBar::add_menu_item(const std::string& menu_label, const std::string& item_label,
|
|
std::function<void()> action) {
|
|
for(auto& menu : _menus) {
|
|
if(menu.label == menu_label) {
|
|
menu.items.push_back({item_label, action});
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
int MenuBar::get_height(void) const {
|
|
return _height;
|
|
}
|
|
|
|
void MenuBar::handle_event(SDL_Event* event, int window_x, int window_y) {
|
|
if(event->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
|
|
int mouse_x = event->button.x;
|
|
int mouse_y = event->button.y;
|
|
const int title_bar_height = 30;
|
|
|
|
int menu_bar_screen_y = window_y + title_bar_height;
|
|
int current_menu_x = window_x;
|
|
bool click_on_bar = false;
|
|
|
|
if(mouse_y >= menu_bar_screen_y && mouse_y <= menu_bar_screen_y + _height) {
|
|
for(size_t i = 0; i < _menus.size(); ++i) {
|
|
int menu_width = 60;
|
|
if(mouse_x >= current_menu_x && mouse_x <= current_menu_x + menu_width) {
|
|
_open_menu_index = (_open_menu_index == (int)i) ? -1: i;
|
|
click_on_bar = true;
|
|
break;
|
|
}
|
|
current_menu_x += menu_width;
|
|
}
|
|
}
|
|
|
|
if(click_on_bar) return;
|
|
|
|
if(_open_menu_index != -1) {
|
|
Menu& open_menu = _menus[_open_menu_index];
|
|
int dropdown_x = window_x + (_open_menu_index * 60);
|
|
int dropdown_y = menu_bar_screen_y + _height;
|
|
int item_height = 30;
|
|
int dropdown_width = 150;
|
|
|
|
for(const auto& item: open_menu.items) {
|
|
if(mouse_x >= dropdown_x && mouse_x <= dropdown_x + dropdown_width &&
|
|
mouse_y >= dropdown_y && mouse_y <= dropdown_y + item_height) {
|
|
item.action();
|
|
_open_menu_index = -1; /* Close menu. */
|
|
return;
|
|
}
|
|
dropdown_y += item_height;
|
|
}
|
|
}
|
|
/* Close any open menu when clicked outside. */
|
|
_open_menu_index = -1;
|
|
}
|
|
}
|
|
|
|
void MenuBar::render_bar_bg(UIRenderer* ui_renderer, int x, int y, int width) {
|
|
const Color bg_color = { 0.15f, 0.17f, 0.19f };
|
|
ui_renderer->draw_rect(x, y, width, _height, bg_color);
|
|
}
|
|
|
|
void MenuBar::render_bar_text(UIRenderer *ui_renderer, int x, int y, int width) {
|
|
const Color text_color = { 0.9f, 0.9f, 0.9f };
|
|
|
|
int menu_x = x;
|
|
for(size_t i = 0; i < _menus.size(); ++i) {
|
|
int menu_width = 60;
|
|
ui_renderer->render_text(_menus[i].label.c_str(), menu_x+10, y+20, text_color);
|
|
menu_x += menu_width;
|
|
}
|
|
}
|
|
|
|
void MenuBar::render_dropdown(UIRenderer* ui_renderer, int x, int y, int width ) {
|
|
if(_open_menu_index == -1) return;
|
|
|
|
const Color bg_color = { 0.15f, 0.17f, 0.19f };
|
|
const Color text_color = { 0.9f, 0.9f, 0.9f };
|
|
|
|
ui_renderer->begin_shapes();
|
|
ui_renderer->begin_text();
|
|
|
|
int menu_x = x + (_open_menu_index*60);
|
|
int item_y = y + _height;
|
|
int item_height = 30;
|
|
int dropdown_width = 150;
|
|
for(const auto& item : _menus[_open_menu_index].items) {
|
|
ui_renderer->draw_rect(menu_x, item_y, dropdown_width, item_height, bg_color);
|
|
ui_renderer->render_text(item.label.c_str(), menu_x+10, item_y+20, text_color);
|
|
item_y += item_height;
|
|
}
|
|
|
|
ui_renderer->flush_shapes();
|
|
ui_renderer->flush_text();
|
|
}
|