File: popup_menu.cpp

package info (click to toggle)
btanks 0.9.8083-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 43,616 kB
  • sloc: cpp: 46,425; ansic: 12,005; xml: 4,262; python: 313; sh: 13; makefile: 13
file content (116 lines) | stat: -rw-r--r-- 2,754 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "popup_menu.h"
#include "box.h"
#include "label.h"

class ToggleLabel : public Label {
public: 
	ToggleLabel(const std::string &item, const bool state) : Label("medium", item), state(state) {
		update();
	}
	void toggle() {
		state = !state;
		update();
	}
	const bool get_state() const { return state; }
private: 
	void update() {
		setFont(state?"medium_dark":"medium");
	}
	bool state;
};

PopupMenu::PopupMenu() : _background(new Box), hl_pos(-1, -1) {}
PopupMenu::~PopupMenu() { delete _background; }


void PopupMenu::clear() {
	Container::clear();
	hl_pos = v2<int>(-1, -1);
}

void PopupMenu::get(std::set<std::string> &labels) const {
	labels.clear();
	for(ControlList::const_iterator i = _controls.begin(); i != _controls.end(); ++i) {
		const ToggleLabel * l = dynamic_cast<const ToggleLabel *>(*i);
		if (l == NULL) 
			continue;
		if (l->get_state())
			labels.insert(l->get());
	}		
}

void PopupMenu::append(const std::string &item, const bool state) {
	int w, h;
	get_size(w, h);
	add(0, h + 5, new ToggleLabel(item, state));
	get_size(w, h);
	w += 32; h += 24;
	_background->init("menu/background_box_dark.png", w, h, 24);
}

bool PopupMenu::onMouse(const int button, const bool pressed, const int x, const int y) {
	if (Container::onMouse(button, pressed, x, y))
		return true;
	if (pressed)
		return true;
	
	for(ControlList::iterator i = _controls.begin(); i != _controls.end(); ++i) {
		ToggleLabel * l = dynamic_cast<ToggleLabel *>(*i);
		if (l == NULL) 
			continue;

		int bw, bh;
		l->get_size(bw, bh);
		int base_x, base_y;
		(*i)->get_base(base_x, base_y);
		const sdlx::Rect dst(base_x, base_y, bw, bh);
		if (dst.in(x, y)) {
			l->toggle();
			result = l->get();
			invalidate();
			return true;
		}
	}
	return true;
}

bool PopupMenu::onMouseMotion(const int state, const int x, const int y, const int xrel, const int yrel) {
	if (Container::onMouseMotion(state, x, y, xrel, yrel))
		return true;

	hl_pos = v2<int>(-1, -1);
	for(ControlList::const_iterator i = _controls.begin(); i != _controls.end(); ++i) {
		const ToggleLabel * l = dynamic_cast<const ToggleLabel *>(*i);
		if (l == NULL) 
			continue;

		int bw, bh;
		l->get_size(bw, bh);

		int base_x, base_y;
		(*i)->get_base(base_x, base_y);
		const sdlx::Rect dst(base_x, base_y, bw, bh);
		if (dst.in(x, y)) {
			hl_pos.x = base_x - 16;
			hl_pos.y = base_y + 9;
		}
	}
	
	return false;
}

void PopupMenu::render(sdlx::Surface &surface, const int x, const int y) const {
	if (_controls.empty())
		return;
	
	int mx, my;
	_background->getMargins(mx, my);

	_background->render(surface, x - mx, y - my);
	Container::render(surface, x, y);
	
	if (hl_pos.x == -1 || hl_pos.y == -1) 
		return;
	
	_background->renderHL(surface, x + hl_pos.x, y + hl_pos.y);
}