.
1 /*
2 Copyright (C) 2014 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 namespace BirdFont {
16
17 public class BackgroundTools : ToolCollection {
18
19 public BackgroundSelectionTool select_background;
20
21 Expander files;
22 Expander parts;
23 public Gee.ArrayList<Expander> expanders = new Gee.ArrayList<Expander> ();
24
25 public BackgroundTools () {
26 Expander background_tools = new Expander (t_("Background Image"));
27 Expander background_selection = new Expander (t_("Images"));
28
29 Expander font_name = new Expander ();
30 font_name.add_tool (new FontName ());
31
32 select_background = new BackgroundSelectionTool ();
33
34 files = new Expander (t_("Files"));
35 files.set_persistent (true);
36 files.set_unique (true);
37
38 parts = new Expander (t_("Parts"));
39 parts.set_persistent (true);
40 parts.set_unique (true);
41
42 background_tools.add_tool (select_background);
43
44 LabelTool add_new_image = new LabelTool (t_("Add"));
45 add_new_image.select_action.connect ((t) => {
46 load_image ();
47 });
48 background_selection.add_tool (add_new_image);
49
50 background_tools.add_tool (DrawingTools.move_background);
51 background_tools.add_tool (DrawingTools.move_canvas);
52 background_tools.add_tool (DrawingTools.background_scale);
53
54 expanders.add (font_name);
55 expanders.add (background_tools);
56 expanders.add (DrawingTools.zoombar_tool);
57 expanders.add (DrawingTools.guideline_tools);
58 expanders.add (background_selection);
59 expanders.add (files);
60 expanders.add (parts);
61 }
62
63 public void remove_images () {
64 files.tool.clear ();
65 parts.tool.clear ();
66 }
67
68 void set_default_canvas () {
69 MainWindow.get_tab_bar ().select_tab_name ("Backgrounds");
70 }
71
72 public void update_parts_list (BackgroundImage current_image) {
73 parts.tool.clear ();
74
75 foreach (BackgroundSelection selection in current_image.selections) {
76 add_part (selection);
77 }
78
79 parts.redraw ();
80 }
81
82 public void add_part (BackgroundSelection selection) {
83 BackgroundPartLabel label;
84
85 if (selection.assigned_glyph == null) {
86 label = new BackgroundPartLabel (selection, t_("Select Glyph"));
87 } else {
88 label = new BackgroundPartLabel (selection, (!) selection.assigned_glyph);
89 }
90
91 label.select_action.connect ((t) => {
92 BackgroundPartLabel bpl = (BackgroundPartLabel) t;
93 GlyphSelection gs = new GlyphSelection ();
94
95 gs.selected_glyph.connect ((gc) => {
96 GlyphCollection? pgc;
97 Font font = BirdFont.get_current_font ();
98
99 pgc = font.get_glyph_collection_by_name (bpl.selection.assigned_glyph);
100 if (pgc != null) {
101 ((!) pgc).get_current ().set_background_image (null);
102 }
103
104 set_new_background_image (gc, bpl);
105 });
106
107 gs.open_new_glyph_signal.connect ((character) => {
108 GlyphCollection gc = gs.create_new_glyph (character);
109 set_new_background_image (gc, bpl);
110 });
111
112 if (!bpl.deleted) {
113 GlyphCanvas.set_display (gs);
114 Toolbox.set_toolbox_from_tab ("Overview");
115 }
116 });
117
118 label.delete_action.connect ((t) => {
119 // don't invalidate the toolbox iterator
120 IdleSource idle = new IdleSource ();
121 idle.set_callback (() => {
122 GlyphCollection? gc;
123 BackgroundPartLabel bpl;
124 Font font = BirdFont.get_current_font ();
125
126 bpl = (BackgroundPartLabel) t;
127 bpl.deleted = true;
128
129 gc = font.get_glyph_collection_by_name (bpl.selection.assigned_glyph);
130 if (gc != null) {
131 ((!) gc).get_current ().set_background_image (null);
132 }
133
134 parts.tool.remove (bpl);
135 bpl.selection.parent_image.selections.remove (bpl.selection);
136 MainWindow.get_toolbox ().update_expanders ();
137 parts.clear_cache ();
138 set_default_canvas ();
139 Toolbox.redraw_tool_box ();
140 GlyphCanvas.redraw ();
141
142 return false;
143 });
144 idle.attach (null);
145 });
146 label.has_delete_button = true;
147 parts.add_tool (label, 0);
148
149 if (!is_null (MainWindow.get_toolbox ())) {
150 MainWindow.get_toolbox ().update_expanders ();
151 Toolbox.redraw_tool_box ();
152 }
153
154 parts.redraw ();
155 }
156
157 void set_new_background_image (GlyphCollection gc, BackgroundPartLabel bpl) {
158 Glyph g;
159
160 g = gc.get_current ();
161 bpl.selection.assigned_glyph = gc.get_name ();
162 bpl.label = gc.get_name ();
163 g.set_background_image (bpl.selection.image);
164 g.set_background_visible (true);
165
166 if (bpl.selection.image != null) {
167 ((!) bpl.selection.image).center_in_glyph (gc.get_current ());
168 }
169
170 set_default_canvas ();
171 ZoomTool.zoom_full_background_image ();
172 MainWindow.get_toolbox ().update_expanders ();
173 }
174
175 public override Gee.ArrayList<Expander> get_expanders () {
176 return expanders;
177 }
178
179 void load_image () {
180 FileChooser fc = new FileChooser ();
181 fc.file_selected.connect ((fn) => {
182 if (fn != null) {
183 add_image_file ((!) fn);
184 }
185 });
186
187 MainWindow.file_chooser (t_("Open"), fc, FileChooser.LOAD);
188 }
189
190 void add_image_file (string file_path) {
191 File f = File.new_for_path (file_path);
192 string fn = (!) f.get_basename ();
193 BackgroundImage image = new BackgroundImage (file_path);
194 int i;
195
196 i = fn.index_of (".");
197 if (i > -1) {
198 fn = fn.substring (0, i);
199 }
200
201 image.name = fn;
202
203 add_image (image);
204
205 GlyphCanvas.redraw ();
206 MainWindow.get_toolbox ().update_expanders ();
207 Toolbox.redraw_tool_box ();
208 }
209
210 public void add_image (BackgroundImage image) {
211 LabelTool image_selection;
212 double xc, yc;
213 BackgroundTab bt;
214 Font font;
215
216 font = BirdFont.get_current_font ();
217
218 image_selection = new BackgroundSelectionLabel (image, image.name);
219 image_selection.select_action.connect ((t) => {
220 BackgroundTab background_tab = BackgroundTab.get_instance ();
221 BackgroundSelectionLabel bg = (BackgroundSelectionLabel) t;
222
223 if (!bg.deleted) {
224 background_tab.set_background_image (bg.img);
225 background_tab.set_background_visible (true);
226 ZoomTool.zoom_full_background_image ();
227 update_parts_list (bg.img);
228 GlyphCanvas.redraw ();
229 Toolbox.redraw_tool_box ();
230 }
231
232 set_default_canvas ();
233 });
234
235 image_selection.delete_action.connect ((t) => {
236 // don't invalidate the toolbox iterator
237 IdleSource idle = new IdleSource ();
238 idle.set_callback (() => {
239 BackgroundSelectionLabel bsl;
240 Font f = BirdFont.get_current_font ();
241
242 bsl = (BackgroundSelectionLabel) t;
243 bsl.deleted = true;
244
245 files.tool.remove (bsl);
246 f.background_images.remove (bsl.img);
247
248 MainWindow.get_current_glyph ().set_background_image (null);
249
250 MainWindow.get_toolbox ().update_expanders ();
251 set_default_canvas ();
252 image_selection.redraw ();
253 GlyphCanvas.redraw ();
254 return false;
255 });
256 idle.attach (null);
257 });
258
259 image_selection.has_delete_button = true;
260
261 files.add_tool (image_selection);
262
263 bt = BackgroundTab.get_instance ();
264 bt.set_background_image (image);
265 bt.set_background_visible (true);
266 ZoomTool.zoom_full_background_image ();
267
268 foreach (Tool t in files.tool) {
269 t.set_selected (false);
270 }
271 image_selection.set_selected (true);
272
273 bt.set_background_image (image);
274 bt.set_background_visible (true);
275
276 xc = image.img_middle_x;
277 yc = image.img_middle_y;
278
279 image.set_img_scale (0.2, 0.2);
280
281 image.img_middle_x = xc;
282 image.img_middle_y = yc;
283
284 image.center_in_glyph ();
285 ZoomTool.zoom_full_background_image ();
286
287 font.add_background_image (image);
288 }
289
290 public override Gee.ArrayList<string> get_displays () {
291 Gee.ArrayList<string> d = new Gee.ArrayList<string> ();
292 d.add ("Backgrounds");
293 return d;
294 }
295
296 class BackgroundSelectionLabel : LabelTool {
297 public BackgroundImage img;
298 public bool deleted;
299 public BackgroundSelectionLabel (BackgroundImage img, string base_name) {
300 base (base_name);
301 this.img = img;
302 deleted = false;
303 }
304 }
305
306 class BackgroundPartLabel : LabelTool {
307 public bool deleted;
308 public BackgroundSelection selection;
309 public BackgroundPartLabel (BackgroundSelection selection, string base_name) {
310 base (base_name);
311 this.selection = selection;
312 deleted = false;
313 }
314 }
315 }
316
317 }
318