1 #include "popup_menu.h"
2 #include "box.h"
3 #include "label.h"
4
5 class ToggleLabel : public Label {
6 public:
ToggleLabel(const std::string & item,const bool state)7 ToggleLabel(const std::string &item, const bool state) : Label("medium", item), state(state) {
8 update();
9 }
toggle()10 void toggle() {
11 state = !state;
12 update();
13 }
get_state() const14 const bool get_state() const { return state; }
15 private:
update()16 void update() {
17 setFont(state?"medium_dark":"medium");
18 }
19 bool state;
20 };
21
PopupMenu()22 PopupMenu::PopupMenu() : _background(new Box), hl_pos(-1, -1) {}
~PopupMenu()23 PopupMenu::~PopupMenu() { delete _background; }
24
25
clear()26 void PopupMenu::clear() {
27 Container::clear();
28 hl_pos = v2<int>(-1, -1);
29 }
30
get(std::set<std::string> & labels) const31 void PopupMenu::get(std::set<std::string> &labels) const {
32 labels.clear();
33 for(ControlList::const_iterator i = _controls.begin(); i != _controls.end(); ++i) {
34 const ToggleLabel * l = dynamic_cast<const ToggleLabel *>(*i);
35 if (l == NULL)
36 continue;
37 if (l->get_state())
38 labels.insert(l->get());
39 }
40 }
41
append(const std::string & item,const bool state)42 void PopupMenu::append(const std::string &item, const bool state) {
43 int w, h;
44 get_size(w, h);
45 add(0, h + 5, new ToggleLabel(item, state));
46 get_size(w, h);
47 w += 32; h += 24;
48 _background->init("menu/background_box_dark.png", w, h, 24);
49 }
50
onMouse(const int button,const bool pressed,const int x,const int y)51 bool PopupMenu::onMouse(const int button, const bool pressed, const int x, const int y) {
52 if (Container::onMouse(button, pressed, x, y))
53 return true;
54 if (pressed)
55 return true;
56
57 for(ControlList::iterator i = _controls.begin(); i != _controls.end(); ++i) {
58 ToggleLabel * l = dynamic_cast<ToggleLabel *>(*i);
59 if (l == NULL)
60 continue;
61
62 int bw, bh;
63 l->get_size(bw, bh);
64 int base_x, base_y;
65 (*i)->get_base(base_x, base_y);
66 const sdlx::Rect dst(base_x, base_y, bw, bh);
67 if (dst.in(x, y)) {
68 l->toggle();
69 result = l->get();
70 invalidate();
71 return true;
72 }
73 }
74 return true;
75 }
76
onMouseMotion(const int state,const int x,const int y,const int xrel,const int yrel)77 bool PopupMenu::onMouseMotion(const int state, const int x, const int y, const int xrel, const int yrel) {
78 if (Container::onMouseMotion(state, x, y, xrel, yrel))
79 return true;
80
81 hl_pos = v2<int>(-1, -1);
82 for(ControlList::const_iterator i = _controls.begin(); i != _controls.end(); ++i) {
83 const ToggleLabel * l = dynamic_cast<const ToggleLabel *>(*i);
84 if (l == NULL)
85 continue;
86
87 int bw, bh;
88 l->get_size(bw, bh);
89
90 int base_x, base_y;
91 (*i)->get_base(base_x, base_y);
92 const sdlx::Rect dst(base_x, base_y, bw, bh);
93 if (dst.in(x, y)) {
94 hl_pos.x = base_x - 16;
95 hl_pos.y = base_y + 9;
96 }
97 }
98
99 return false;
100 }
101
render(sdlx::Surface & surface,const int x,const int y) const102 void PopupMenu::render(sdlx::Surface &surface, const int x, const int y) const {
103 if (_controls.empty())
104 return;
105
106 int mx, my;
107 _background->getMargins(mx, my);
108
109 _background->render(surface, x - mx, y - my);
110 Container::render(surface, x, y);
111
112 if (hl_pos.x == -1 || hl_pos.y == -1)
113 return;
114
115 _background->renderHL(surface, x + hl_pos.x, y + hl_pos.y);
116 }
117