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