.
1 /*
2 Copyright (C) 2014 2015 Johan Mattsson
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 3 of the
7 License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13 */
14
15 using Cairo;
16 using Math;
17
18 namespace BirdFont {
19
20 public class TableLayout : FontDisplay {
21
22 public double scroll = 0;
23 public double content_height = 1;
24 public WidgetAllocation allocation = new WidgetAllocation ();
25 public Gee.ArrayList<Widget> widgets = new Gee.ArrayList<Widget> ();
26 public Gee.ArrayList<Widget> focus_ring = new Gee.ArrayList<Widget> ();
27 public int focus_index = 0;
28
29 public Widget? keyboard_focus = null;
30
31 public TableLayout () {
32 }
33
34 public override void draw (WidgetAllocation allocation, Context cr) {
35 this.allocation = allocation;
36
37 layout ();
38
39 // background
40 cr.save ();
41 cr.rectangle (0, 0, allocation.width, allocation.height);
42 cr.set_line_width (0);
43
44 Theme.color (cr, "Default Background");
45
46 cr.fill ();
47 cr.stroke ();
48 cr.restore ();
49
50 foreach (Widget w in widgets) {
51 if (w.is_on_screen ()) {
52 if (w is Text) {
53 cr.save ();
54 Theme.color (cr, "Foreground 1");
55 w.draw (cr);
56 cr.restore ();
57 } else {
58 w.draw (cr);
59 }
60 }
61 }
62 }
63
64 void layout () {
65 double y = -scroll;
66
67 foreach (Widget w in widgets) {
68 w.widget_x = 17 * MainWindow.units;
69 w.widget_y = y;
70 w.allocation = allocation;
71
72 if (w is TextArea) {
73 ((TextArea) w).layout ();
74 }
75
76 y += w.get_height () + w.margin_bottom;
77 }
78
79 content_height = y + scroll;
80 update_scrollbar ();
81 }
82
83 public void scroll_event (double p) {
84 scroll += p;
85 layout ();
86 GlyphCanvas.redraw ();
87 }
88
89 public override void key_press (uint keyval) {
90 Widget focus;
91
92 if (keyval == Key.SHIFT_TAB) {
93 focus_previous ();
94 } else if (keyval == Key.TAB) {
95 focus_next ();
96 } else if (keyboard_focus != null) {
97 focus = (!) keyboard_focus;
98 focus.key_press (keyval);
99 }
100
101 GlyphCanvas.redraw ();
102 }
103
104 void focus_previous () {
105 focus_index--;
106
107 if (focus_index < 0) {
108 focus_index = 0;
109 }
110
111 set_focus (focus_ring.get (focus_index));
112 }
113
114 void focus_next () {
115 focus_index++;
116
117 if (focus_index >= focus_ring.size) {
118 focus_index = focus_ring.size - 1;
119 }
120
121 set_focus (focus_ring.get (focus_index));
122 }
123
124 public override void button_press (uint button, double x, double y) {
125 Widget t;
126 Widget old;
127 CheckBox c;
128
129 foreach (Widget w in widgets) {
130 if (w.is_over (x, y)) {
131 if (w is TextArea) {
132 t = (TextArea) w;
133 if (keyboard_focus != null && (!) keyboard_focus != t) {
134 old = (!) keyboard_focus;
135 old.focus (false);
136 }
137
138 set_focus (t);
139 t.button_press (button, x, y);
140 } else if (w is CheckBox) {
141 c = (CheckBox) w;
142 c.set_checked (!c.checked);
143 } else {
144 w.button_press (button, x, y);
145 }
146 }
147 }
148
149 GlyphCanvas.redraw ();
150 }
151
152 public void set_focus (Widget w) {
153 Widget old;
154
155 if (keyboard_focus != null && (!) keyboard_focus != w) {
156 old = (!) keyboard_focus;
157 old.focus (false);
158 }
159
160 keyboard_focus = w;
161 w.focus (true);
162
163 focus_index = focus_ring.index_of (w);
164
165 if (!(0 <= focus_index < focus_ring.size)) {
166 focus_index = 0;
167 }
168
169 update_scrollbar ();
170 GlyphCanvas.redraw ();
171 }
172
173 public override void button_release (int button, double x, double y) {
174 Widget t;
175
176 if (keyboard_focus != null) {
177 t = (!) keyboard_focus;
178 set_focus (t);
179 t.button_release (button, x, y);
180 }
181
182 foreach (Widget w in widgets) {
183 if (w.is_over (x, y)) {
184 w.button_release (button, x, y);
185 }
186 }
187
188 GlyphCanvas.redraw ();
189 }
190
191 public override void motion_notify (double x, double y) {
192 Widget t;
193
194 if (keyboard_focus != null) {
195 t = (!) keyboard_focus;
196 if (t.motion (x, y)) {
197 GlyphCanvas.redraw ();
198 }
199 }
200 }
201
202 public override string get_label () {
203 return t_("Name and Description");
204 }
205
206 public override string get_name () {
207 return "Description";
208 }
209
210 public override bool has_scrollbar () {
211 return true;
212 }
213
214 public override void scroll_wheel (double x, double y, double pixeldelta, double dy) {
215 scroll -= dy * MainWindow.units;
216
217 if (scroll + allocation.height >= content_height) {
218 scroll = content_height - allocation.height;
219
220 if (scroll < 0) {
221 scroll = 0;
222 }
223 }
224
225 if (scroll < 0) {
226 scroll = 0;
227 }
228
229 update_scrollbar ();
230 GlyphCanvas.redraw ();
231 }
232
233 public override void selected_canvas () {
234 update_scrollbar ();
235 GlyphCanvas.redraw ();
236 }
237
238 public override void update_scrollbar () {
239 double h = content_height - allocation.height;
240 MainWindow.set_scrollbar_size (allocation.height / content_height);
241 MainWindow.set_scrollbar_position (scroll / h);
242 }
243
244 public override void scroll_to (double percent) {
245 double h = content_height - allocation.height;
246 scroll = percent * h;
247 GlyphCanvas.redraw ();
248 }
249 }
250
251 }
252