File: problempanel.bs

package info (click to toggle)
storm-lang 0.7.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 51,836 kB
  • sloc: ansic: 261,420; cpp: 138,870; sh: 14,877; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (98 lines) | stat: -rw-r--r-- 2,131 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
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);
	}
}