.
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 GlyphCanvas.redraw ();
183 }
184
185 public override void motion_notify (double x, double y) {
186 Widget t;
187
188 if (keyboard_focus != null) {
189 t = (!) keyboard_focus;
190 if (t.motion (x, y)) {
191 GlyphCanvas.redraw ();
192 }
193 }
194 }
195
196 public override string get_label () {
197 return t_("Name and Description");
198 }
199
200 public override string get_name () {
201 return "Description";
202 }
203
204 public override bool has_scrollbar () {
205 return true;
206 }
207
208 public override void scroll_wheel_down (double x, double y) {
209 scroll += 25 * MainWindow.units;
210
211 if (scroll + allocation.height >= content_height) {
212 scroll = content_height - allocation.height;
213 }
214
215 update_scrollbar ();
216 GlyphCanvas.redraw ();
217 }
218
219 public override void scroll_wheel_up (double x, double y) {
220 scroll -= 25 * MainWindow.units;
221
222 if (scroll < 0) {
223 scroll = 0;
224 }
225
226 update_scrollbar ();
227 GlyphCanvas.redraw ();
228 }
229
230 public override void selected_canvas () {
231 update_scrollbar ();
232 GlyphCanvas.redraw ();
233 }
234
235 public override void update_scrollbar () {
236 double h = content_height - allocation.height;
237 MainWindow.set_scrollbar_size (allocation.height / content_height);
238 MainWindow.set_scrollbar_position (scroll / h);
239 }
240
241 public override void scroll_to (double percent) {
242 double h = content_height - allocation.height;
243 scroll = percent * h;
244 GlyphCanvas.redraw ();
245 }
246 }
247
248 }
249