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);
}
|