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
|
use ui;
use core:geometry;
/**
* A small pop-down panel shown when the user is solving a problem from the server.
*/
class ProblemPanel on Render {
// Caption text to draw.
private Text caption;
// Button text and action.
private Text[] buttons;
private Fn<void>[] actions;
// Height of this panel (computed based on contents).
private Float height;
// Extra button space.
private Size buttonSpace;
// Our last size and position.
private Rect lastPos;
init(Str text) {
init {
caption(text, panelCaption);
buttonSpace(6, 2);
}
height = caption.size.h;
}
void button(Str text, Fn<void> action) {
buttons << Text(text, panelButton);
actions << action;
height = height.max(buttons.last.size.h);
}
void render(Rect viewport, Graphics g) {
lastPos = pos(viewport);
Rect pos = lastPos;
{
Rect t = pos.grow(Size(6, 3));
t.p0.y -= 10; // To not make rounded corners appear on top.
g.fill(t, Size(6), panelBg);
}
// Draw buttons, right to left.
for (Nat i = buttons.count; i > 0; i--) {
var button = buttons[i - 1];
Size sz = button.size + buttonSpace;
Rect r(Point(pos.p1.x - sz.w, pos.p0.y), sz);
g.draw(r, Size(3), panelFg);
g.push(r);
g.draw(button, panelFg, r.center - button.size / 2);
g.pop();
pos.p1.x = r.p0.x - buttonSpace.w;
}
// Clip.
g.push(pos);
g.draw(caption, panelFg, pos.p0 + Size((pos.size.w - caption.size.w) / 2, 0));
g.pop();
}
// Called when the mouse is pressed. Returns "true" if it was captured by the panel.
Bool mouseClicked(Point pt) {
Rect pos = lastPos;
if (!pos.contains(pt))
return false;
for (Nat i = buttons.count; i > 0; i--) {
var button = buttons[i - 1];
Size sz = button.size + buttonSpace;
Rect r(Point(pos.p1.x - sz.w, pos.p0.y), sz);
if (r.contains(pt)) {
actions[i - 1].call();
return true;
}
pos.p1.x = r.p0.x - buttonSpace.w;
}
true;
}
// Compute our position based on the current viewport.
private Rect pos(Rect viewport) {
Float w = viewport.size.w;
Size sz(w * 0.7, height);
Rect(viewport.p0 + Point((w - sz.w) / 2, 3), sz);
}
}
|