.
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 abstract class SettingsDisplay : FontDisplay {
21
22 double scroll = 0;
23 double content_height = 1;
24 WidgetAllocation allocation;
25 public Gee.ArrayList<SettingsItem> tools;
26
27 public static SpinButton precision;
28
29 SettingsItem new_key_bindings = new SettingsItem.head_line ("");
30 public static bool update_key_bindings = false;
31
32 public SettingsDisplay () {
33 allocation = new WidgetAllocation ();
34 tools = new Gee.ArrayList<SettingsItem> ();
35 content_height = 200;
36 precision = new SpinButton ("precision");
37 }
38
39 public abstract void create_setting_items ();
40
41 public override void draw (WidgetAllocation allocation, Context cr) {
42 this.allocation = allocation;
43
44 layout ();
45
46 // background
47 cr.save ();
48 cr.rectangle (0, 0, allocation.width, allocation.height);
49 cr.set_line_width (0);
50 Theme.color (cr, "Default Background");
51 cr.fill ();
52 cr.stroke ();
53 cr.restore ();
54
55 foreach (SettingsItem s in tools) {
56 if (-20 * MainWindow.units <= s.y <= allocation.height + 20 * MainWindow.units) {
57 s.draw (allocation, cr);
58 }
59 }
60 }
61
62 public void layout () {
63 double y = -scroll;
64 bool first = true;
65 foreach (SettingsItem s in tools) {
66
67 if (!first && s.headline) {
68 y += 30 * MainWindow.units;
69 }
70
71 s.y = y;
72
73 if (s.button != null) {
74 ((!) s.button).y = y;
75 ((!) s.button).x = 20 * MainWindow.units;
76 }
77
78 if (s.headline) {
79 y += 50 * MainWindow.units;
80 } else {
81 y += 40 * MainWindow.units;
82 }
83
84 first = false;
85 }
86
87 content_height = y + scroll;
88 }
89
90 void set_key_bindings (SettingsItem item) {
91 if (new_key_bindings.active) {
92 new_key_bindings.active = false;
93 update_key_bindings = false;
94 } else {
95 new_key_bindings.active = false;
96 new_key_bindings = item;
97 update_key_bindings = true;
98 new_key_bindings.active = true;
99 }
100 }
101
102 public override void key_release (uint keyval) {
103 SettingsItem old_key_binding;
104
105 if (!is_modifier_key (keyval) || keyval == Key.BACK_SPACE || keyval == Key.DEL) {
106 if (update_key_bindings) {
107 if (keyval == Key.BACK_SPACE || keyval == Key.DEL) {
108 update_key_bindings = false;
109 new_key_bindings.active = false;
110 new_key_bindings.menu_item.modifiers = NONE;
111 new_key_bindings.menu_item.key = '\0';
112 } else if (KeyBindings.get_mod_from_key (keyval) == NONE) {
113
114 if (has_key_binding (KeyBindings.modifier, (unichar) keyval)) {
115 old_key_binding = (!) get_key_binding (KeyBindings.modifier, (unichar) keyval);
116 old_key_binding.menu_item.modifiers = NONE;
117 old_key_binding.menu_item.key = '\0';
118 }
119
120 new_key_bindings.menu_item.modifiers = KeyBindings.modifier;
121 new_key_bindings.menu_item.key = (unichar) keyval;
122 update_key_bindings = false;
123 new_key_bindings.active = false;
124 }
125
126 MainWindow.get_menu ().write_key_bindings ();
127 GlyphCanvas.redraw ();
128 }
129 }
130 }
131
132 bool has_key_binding (uint modifier, unichar key) {
133 return get_key_binding (modifier, key) != null;
134 }
135
136 SettingsItem? get_key_binding (uint modifier, unichar key) {
137 foreach (SettingsItem i in tools) {
138 if (i.menu_item.modifiers == modifier && i.menu_item.key == key) {
139 return i;
140 }
141 }
142
143 return null;
144 }
145
146 public override void button_press (uint button, double x, double y) {
147 foreach (SettingsItem s in tools) {
148 if (s.handle_events && s.button != null) {
149 if (((!) s.button).is_over (x, y)) {
150
151 ((!) s.button).set_selected (! ((!) s.button).selected);
152
153 if (((!) s.button).selected) {
154 ((!) s.button).select_action ((!) s.button);
155 }
156
157 ((!) s.button).panel_press_action ((!) s.button, button, x, y);
158 }
159 }
160 }
161 GlyphCanvas.redraw ();
162 }
163
164 public override void button_release (int button, double x, double y) {
165 foreach (SettingsItem s in tools) {
166 if (s.handle_events && s.button != null) {
167 ((!) s.button).panel_release_action (((!) s.button), button, x, y);
168 }
169
170 if (s.key_bindings && s.y <= y < s.y + 40 * MainWindow.units && button == 1) {
171 set_key_bindings (s);
172 }
173 }
174 GlyphCanvas.redraw ();
175 }
176
177 public override void motion_notify (double x, double y) {
178 bool consumed = false;
179 bool active;
180 bool update = false;
181
182 foreach (SettingsItem si in tools) {
183
184 if (si.handle_events && si.button != null) {
185 active = ((!) si.button).is_over (x, y);
186
187 if (!active && ((!) si.button).is_active ()) {
188 ((!) si.button).move_out_action ((!) si.button);
189 }
190
191 if (((!) si.button).set_active (active)) {
192 update = true;
193 }
194 }
195 }
196
197 foreach (SettingsItem s in tools) {
198 if (s.handle_events && s.button != null) {
199 if (((!) s.button).panel_move_action ((!) s.button, x, y)) {
200 consumed = true;
201 }
202 }
203 }
204
205 if (consumed || update) {
206 GlyphCanvas.redraw ();
207 }
208 }
209
210 public override string get_label () {
211 return t_("Settings");
212 }
213
214 public override string get_name () {
215 return "Settings";
216 }
217
218 public override bool has_scrollbar () {
219 return true;
220 }
221
222 public override void scroll_wheel (double x, double y, double pixeldelta, double dy) {
223 if (dy < 0) {
224 foreach (SettingsItem s in tools) {
225 if (s.handle_events && s.button != null) {
226 if (((!) s.button).is_over (x, y)) {
227 ((!) s.button).scroll_wheel_down_action ((!) s.button);
228 return;
229 }
230 }
231 }
232 } else {
233 foreach (SettingsItem s in tools) {
234 if (s.handle_events && s.button != null) {
235 if (((!) s.button).is_over (x, y)) {
236 ((!) s.button).scroll_wheel_up_action ((!) s.button);
237 return;
238 }
239 }
240 }
241 }
242
243 scroll -= dy * MainWindow.units;
244
245 if (scroll + allocation.height >= content_height) {
246 scroll = content_height - allocation.height;
247 }
248
249 if (scroll < 0) {
250 scroll = 0;
251 }
252
253 update_scrollbar ();
254 GlyphCanvas.redraw ();
255 }
256
257 public override void selected_canvas () {
258 MainWindow.get_toolbox ().set_default_tool_size ();
259 update_scrollbar ();
260 GlyphCanvas.redraw ();
261 }
262
263 public override void update_scrollbar () {
264 double h = content_height - allocation.height;
265 MainWindow.set_scrollbar_size (allocation.height / content_height);
266 MainWindow.set_scrollbar_position (scroll / h);
267 }
268
269 public override void scroll_to (double percent) {
270 double h = content_height - allocation.height;
271 scroll = percent * h;
272 GlyphCanvas.redraw ();
273 }
274 }
275
276 }
277