.
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 bpl.selection.assigned_glyph = gc.get_name ();
155 bpl.label = gc.get_name ();
156 gc.get_current ().set_background_image (bpl.selection.image);
157
158 if (bpl.selection.image != null) {
159 ((!) bpl.selection.image).center_in_glyph (gc.get_current ());
160 }
161
162 set_default_canvas ();
163 ZoomTool.zoom_full_background_image ();
164 }
165
166 public override Gee.ArrayList<Expander> get_expanders () {
167 return expanders;
168 }
169
170 void load_image () {
171 FileChooser fc = new FileChooser ();
172 fc.file_selected.connect ((fn) => {
173 if (fn != null) {
174 add_image_file ((!) fn);
175 }
176 });
177
178 MainWindow.file_chooser (t_("Open"), fc, FileChooser.LOAD);
179 }
180
181 void add_image_file (string file_path) {
182 File f = File.new_for_path (file_path);
183 string fn = (!) f.get_basename ();
184 BackgroundImage image = new BackgroundImage (file_path);
185 int i;
186
187 i = fn.index_of (".");
188 if (i > -1) {
189 fn = fn.substring (0, i);
190 }
191
192 image.name = fn;
193
194 add_image (image);
195
196 GlyphCanvas.redraw ();
197 MainWindow.get_toolbox ().update_expanders ();
198 Toolbox.redraw_tool_box ();
199 }
200
201 public void add_image (BackgroundImage image) {
202 LabelTool image_selection;
203 double xc, yc;
204 BackgroundTab bt;
205 Font font;
206
207 font = BirdFont.get_current_font ();
208
209 image_selection = new BackgroundSelectionLabel (image, image.name);
210 image_selection.select_action.connect ((t) => {
211 BackgroundTab background_tab = BackgroundTab.get_instance ();
212 BackgroundSelectionLabel bg = (BackgroundSelectionLabel) t;
213
214 if (!bg.deleted) {
215 background_tab.set_background_image (bg.img);
216 background_tab.set_background_visible (true);
217 ZoomTool.zoom_full_background_image ();
218 update_parts_list (bg.img);
219 GlyphCanvas.redraw ();
220 Toolbox.redraw_tool_box ();
221 }
222
223 set_default_canvas ();
224 });
225
226 image_selection.delete_action.connect ((t) => {
227 // don't invalidate the toolbox iterator
228 IdleSource idle = new IdleSource ();
229 idle.set_callback (() => {
230 BackgroundSelectionLabel bsl;
231 Font f = BirdFont.get_current_font ();
232
233 bsl = (BackgroundSelectionLabel) t;
234 bsl.deleted = true;
235
236 files.tool.remove (bsl);
237 f.background_images.remove (bsl.img);
238
239 MainWindow.get_current_glyph ().set_background_image (null);
240
241 MainWindow.get_toolbox ().update_expanders ();
242 set_default_canvas ();
243 Toolbox.redraw_tool_box ();
244 GlyphCanvas.redraw ();
245 return false;
246 });
247 idle.attach (null);
248 });
249
250 image_selection.has_delete_button = true;
251
252 files.add_tool (image_selection);
253
254 bt = BackgroundTab.get_instance ();
255 bt.set_background_image (image);
256 bt.set_background_visible (true);
257 ZoomTool.zoom_full_background_image ();
258
259 foreach (Tool t in files.tool) {
260 t.set_selected (false);
261 }
262 image_selection.set_selected (true);
263
264 bt.set_background_image (image);
265 bt.set_background_visible (true);
266
267 xc = image.img_middle_x;
268 yc = image.img_middle_y;
269
270 image.set_img_scale (0.2, 0.2);
271
272 image.img_middle_x = xc;
273 image.img_middle_y = yc;
274
275 image.center_in_glyph ();
276 ZoomTool.zoom_full_background_image ();
277
278 font.add_background_image (image);
279 }
280
281 public override Gee.ArrayList<string> get_displays () {
282 Gee.ArrayList<string> d = new Gee.ArrayList<string> ();
283 d.add ("Backgrounds");
284 return d;
285 }
286
287 class BackgroundSelectionLabel : LabelTool {
288 public BackgroundImage img;
289 public bool deleted;
290 public BackgroundSelectionLabel (BackgroundImage img, string base_name) {
291 base (base_name);
292 this.img = img;
293 deleted = false;
294 }
295 }
296
297 class BackgroundPartLabel : LabelTool {
298 public bool deleted;
299 public BackgroundSelection selection;
300 public BackgroundPartLabel (BackgroundSelection selection, string base_name) {
301 base (base_name);
302 this.selection = selection;
303 deleted = false;
304 }
305 }
306 }
307
308 }
309