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