1 /** 2 * @file 3 * @brief Menu button used in non-game menus 4 **/ 5 6 #pragma once 7 8 #include <vector> 9 10 #include "ui.h" 11 #include "tilefont.h" 12 13 using std::vector; 14 15 class MenuButton : public ui::Bin 16 { 17 friend class OuterMenu; 18 public: 19 MenuButton(); 20 21 virtual void _render() override; 22 virtual ui::SizeReq _get_preferred_size(ui::Widget::Direction, int) override; 23 virtual void _allocate_region() override; 24 virtual bool on_event(const ui::Event& event) override; 25 26 int id = 0; 27 int hotkey = 0; 28 colour_t highlight_colour = LIGHTGREY; 29 #ifndef USE_TILE_LOCAL 30 colour_t fg_highlight = BLACK; 31 #endif 32 string description; 33 34 bool activate(); 35 36 #ifdef USE_TILE_WEB 37 void serialize(); 38 #endif 39 40 protected: can_take_focus()41 bool can_take_focus() override { return true; }; 42 43 bool focused = false; 44 bool hovered = false; 45 bool active = false; 46 #ifdef USE_TILE_LOCAL 47 ShapeBuffer m_buf; 48 LineBuffer m_line_buf; 49 #endif 50 51 #ifndef USE_TILE_LOCAL 52 void recolour_descendants(const shared_ptr<Widget>& node); 53 colour_t fg_normal = LIGHTGREY; 54 #endif 55 }; 56 57 class OuterMenu : public ui::Widget 58 { 59 public: 60 OuterMenu(bool can_shrink, int width, int height); 61 62 #ifdef USE_TILE_WEB 63 ~OuterMenu(); 64 void serialize(string name); 65 static void recv_outer_menu_focus(const char *menu_id, int hotkey); 66 #endif 67 68 virtual void _render() override; 69 virtual ui::SizeReq _get_preferred_size(ui::Widget::Direction, int) override; 70 virtual void _allocate_region() override; 71 virtual bool on_event(const ui::Event& event) override; 72 get_child_at_offset(int,int)73 virtual shared_ptr<Widget> get_child_at_offset(int, int) override { 74 return m_root; 75 } 76 77 void add_button(shared_ptr<MenuButton> btn, int x, int y); 78 void add_label(shared_ptr<ui::Text> label, int x, int y); 79 MenuButton* get_button(int x, int y); 80 MenuButton* get_button_by_id(int id); get_buttons()81 const vector<MenuButton*>& get_buttons() { return m_buttons; }; set_initial_focus(MenuButton * btn)82 void set_initial_focus(MenuButton *btn) { 83 ASSERT(!have_allocated); 84 m_initial_focus = btn; 85 }; 86 87 void scroll_button_into_view(MenuButton *btn); 88 89 weak_ptr<OuterMenu> linked_menus[4]; 90 shared_ptr<ui::Switcher> descriptions; 91 const char *menu_id {nullptr}; 92 93 protected: 94 bool scroller_event_hook(const ui::Event& ev); 95 bool move_button_focus(int fx, int fy, int dx, int dy, int limit); 96 97 shared_ptr<ui::Grid> m_grid; 98 shared_ptr<ui::Widget> m_root; 99 vector<MenuButton*> m_buttons; 100 vector<pair<formatted_string, coord_def>> m_labels; 101 vector<int> m_description_indexes; 102 int m_width; 103 int m_height; 104 MenuButton* m_initial_focus {nullptr}; 105 106 bool have_allocated {false}; 107 108 static bool focus_button_on_mouseenter; 109 }; 110