.
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_("Select 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 font_name.draw_separator = false;
32
33 select_background = new BackgroundSelectionTool ();
34
35 files = new Expander (t_("Files"));
36 files.set_persistent (true);
37 files.set_unique (true);
38
39 parts = new Expander (t_("Parts"));
40 parts.set_persistent (true);
41 parts.set_unique (true);
42
43 background_tools.add_tool (select_background);
44
45 LabelTool add_new_image = new LabelTool (t_("Add"));
46 add_new_image.select_action.connect ((t) => {
47 load_image ();
48 });
49 background_selection.add_tool (add_new_image);
50
51 background_tools.add_tool (DrawingTools.move_background);
52 background_tools.add_tool (DrawingTools.move_canvas);
53 background_tools.add_tool (DrawingTools.background_scale);
54
55 expanders.add (font_name);
56 expanders.add (background_tools);
57 expanders.add (DrawingTools.zoombar_tool);
58 expanders.add (DrawingTools.view_tools);
59 expanders.add (DrawingTools.guideline_tools);
60 expanders.add (background_selection);
61 expanders.add (files);
62 expanders.add (parts);
63 }
64
65 public void remove_images () {
66 files.tool.clear ();
67 parts.tool.clear ();
68 }
69
70 void set_default_canvas () {
71 MainWindow.get_tab_bar ().select_tab_name ("Backgrounds");
72 }
73
74 public void update_parts_list (BackgroundImage current_image) {
75 parts.tool.clear ();
76
77 foreach (BackgroundSelection selection in current_image.selections) {
78 add_part (selection);
79 }
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 set_default_canvas ();
138 Toolbox.redraw_tool_box ();
139 GlyphCanvas.redraw ();
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 class BackgroundSelectionLabel : LabelTool {
282 public BackgroundImage img;
283 public bool deleted;
284 public BackgroundSelectionLabel (BackgroundImage img, string base_name) {
285 base (base_name);
286 this.img = img;
287 deleted = false;
288 }
289 }
290
291 class BackgroundPartLabel : LabelTool {
292 public bool deleted;
293 public BackgroundSelection selection;
294 public BackgroundPartLabel (BackgroundSelection selection, string base_name) {
295 base (base_name);
296 this.selection = selection;
297 deleted = false;
298 }
299 }
300 }
301
302 }
303