1 | /* === S Y N F I G ========================================================= */ |
---|
2 | /*! \file state_text.cpp |
---|
3 | ** \brief Template File |
---|
4 | ** |
---|
5 | ** $Id$ |
---|
6 | ** |
---|
7 | ** \legal |
---|
8 | ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley |
---|
9 | ** Copyright (c) 2008 Chris Moore |
---|
10 | ** Copyright (c) 2010 Carlos López |
---|
11 | ** |
---|
12 | ** This package is free software; you can redistribute it and/or |
---|
13 | ** modify it under the terms of the GNU General Public License as |
---|
14 | ** published by the Free Software Foundation; either version 2 of |
---|
15 | ** the License, or (at your option) any later version. |
---|
16 | ** |
---|
17 | ** This package is distributed in the hope that it will be useful, |
---|
18 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
19 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
20 | ** General Public License for more details. |
---|
21 | ** \endlegal |
---|
22 | */ |
---|
23 | /* ========================================================================= */ |
---|
24 | |
---|
25 | /* === H E A D E R S ======================================================= */ |
---|
26 | |
---|
27 | #ifdef USING_PCH |
---|
28 | # include "pch.h" |
---|
29 | #else |
---|
30 | #ifdef HAVE_CONFIG_H |
---|
31 | # include <config.h> |
---|
32 | #endif |
---|
33 | |
---|
34 | #include "state_text.h" |
---|
35 | #include "state_normal.h" |
---|
36 | #include "canvasview.h" |
---|
37 | #include "workarea.h" |
---|
38 | #include "app.h" |
---|
39 | |
---|
40 | #include <synfigapp/action.h> |
---|
41 | #include "event_mouse.h" |
---|
42 | #include "event_layerclick.h" |
---|
43 | #include "docks/dock_toolbox.h" |
---|
44 | #include "docks/dialog_tooloptions.h" |
---|
45 | #include "duck.h" |
---|
46 | #include "widgets/widget_enum.h" |
---|
47 | #include <synfigapp/main.h> |
---|
48 | |
---|
49 | #include "general.h" |
---|
50 | |
---|
51 | #endif |
---|
52 | |
---|
53 | /* === U S I N G =========================================================== */ |
---|
54 | |
---|
55 | using namespace std; |
---|
56 | using namespace etl; |
---|
57 | using namespace synfig; |
---|
58 | using namespace studio; |
---|
59 | |
---|
60 | /* === M A C R O S ========================================================= */ |
---|
61 | |
---|
62 | #ifndef LAYER_CREATION |
---|
63 | #define LAYER_CREATION(button, stockid, tooltip) \ |
---|
64 | { \ |
---|
65 | Gtk::Image *icon = manage(new Gtk::Image(Gtk::StockID(stockid), \ |
---|
66 | Gtk::ICON_SIZE_SMALL_TOOLBAR)); \ |
---|
67 | button.add(*icon); \ |
---|
68 | } \ |
---|
69 | button.set_relief(Gtk::RELIEF_NONE); \ |
---|
70 | button.set_tooltip_text(tooltip); \ |
---|
71 | button.signal_toggled().connect(sigc::mem_fun(*this, \ |
---|
72 | &studio::StateText_Context::toggle_layer_creation)) |
---|
73 | #endif |
---|
74 | |
---|
75 | // indentation for options layout |
---|
76 | #ifndef SPACING |
---|
77 | #define SPACING(name, px) \ |
---|
78 | Gtk::Alignment *name = Gtk::manage(new Gtk::Alignment()); \ |
---|
79 | name->set_size_request(px) |
---|
80 | #endif |
---|
81 | |
---|
82 | #define GAP (3) |
---|
83 | #define INDENTATION (6) |
---|
84 | |
---|
85 | /* === G L O B A L S ======================================================= */ |
---|
86 | |
---|
87 | StateText studio::state_text; |
---|
88 | |
---|
89 | /* === C L A S S E S & S T R U C T S ======================================= */ |
---|
90 | |
---|
91 | class studio::StateText_Context |
---|
92 | { |
---|
93 | etl::handle<CanvasView> canvas_view; |
---|
94 | CanvasView::IsWorking is_working; |
---|
95 | |
---|
96 | Duckmatic::Push duckmatic_push; |
---|
97 | |
---|
98 | void refresh_ducks(); |
---|
99 | |
---|
100 | bool prev_workarea_layer_status_; |
---|
101 | |
---|
102 | //Toolbox settings |
---|
103 | synfigapp::Settings& settings; |
---|
104 | |
---|
105 | // holder of options |
---|
106 | Gtk::Table options_table; |
---|
107 | |
---|
108 | // title |
---|
109 | Gtk::Label title_label; |
---|
110 | |
---|
111 | // layer name: |
---|
112 | Gtk::Label id_label; |
---|
113 | Gtk::HBox id_box; |
---|
114 | Gtk::Entry id_entry; |
---|
115 | |
---|
116 | // layer types to create: |
---|
117 | Gtk::Label layer_types_label; |
---|
118 | Gtk::ToggleButton layer_text_togglebutton; |
---|
119 | Gtk::HBox layer_types_box; |
---|
120 | |
---|
121 | // blend method |
---|
122 | Gtk::Label blend_label; |
---|
123 | Gtk::HBox blend_box; |
---|
124 | Widget_Enum blend_enum; |
---|
125 | |
---|
126 | // opacity |
---|
127 | Gtk::Label opacity_label; |
---|
128 | Gtk::HScale opacity_hscl; |
---|
129 | |
---|
130 | // paragraph |
---|
131 | Gtk::Label paragraph_label; |
---|
132 | Gtk::CheckButton paragraph_checkbutton; |
---|
133 | Gtk::HBox paragraph_box; |
---|
134 | |
---|
135 | // size |
---|
136 | Gtk::Label size_label; |
---|
137 | Widget_Vector size_widget; |
---|
138 | |
---|
139 | // orientation |
---|
140 | Gtk::Label orientation_label; |
---|
141 | Widget_Vector orientation_widget; |
---|
142 | |
---|
143 | // font family |
---|
144 | Gtk::Label family_label; |
---|
145 | Gtk::Entry family_entry; |
---|
146 | |
---|
147 | |
---|
148 | public: |
---|
149 | |
---|
150 | synfig::String get_id()const { return id_entry.get_text(); } |
---|
151 | void set_id(const synfig::String& x) { return id_entry.set_text(x); } |
---|
152 | |
---|
153 | bool get_layer_text_flag()const { return layer_text_togglebutton.get_active(); } |
---|
154 | void set_layer_text_flag(bool x) { return layer_text_togglebutton.set_active(x); } |
---|
155 | |
---|
156 | int get_blend()const { return blend_enum.get_value(); } |
---|
157 | void set_blend(int x) { return blend_enum.set_value(x); } |
---|
158 | |
---|
159 | Real get_opacity()const { return opacity_hscl.get_value(); } |
---|
160 | void set_opacity(Real x) { opacity_hscl.set_value(x); } |
---|
161 | |
---|
162 | bool get_paragraph_flag()const { return paragraph_checkbutton.get_active(); } |
---|
163 | void set_paragraph_flag(bool x) { return paragraph_checkbutton.set_active(x); } |
---|
164 | |
---|
165 | Vector get_size() { return size_widget.get_value(); } |
---|
166 | void set_size(Vector s) { return size_widget.set_value(s); } |
---|
167 | |
---|
168 | Vector get_orientation() { return orientation_widget.get_value(); } |
---|
169 | void set_orientation(Vector s) { return orientation_widget.set_value(s); } |
---|
170 | |
---|
171 | String get_family()const { return family_entry.get_text(); } |
---|
172 | void set_family(String s) { return family_entry.set_text(s); } |
---|
173 | |
---|
174 | bool layer_text_flag; |
---|
175 | |
---|
176 | void refresh_tool_options(); //to refresh the toolbox |
---|
177 | |
---|
178 | //events |
---|
179 | Smach::event_result event_stop_handler(const Smach::event& x); |
---|
180 | Smach::event_result event_refresh_handler(const Smach::event& x); |
---|
181 | Smach::event_result event_mouse_click_handler(const Smach::event& x); |
---|
182 | Smach::event_result event_refresh_tool_options(const Smach::event& x); |
---|
183 | Smach::event_result event_workarea_mouse_button_down_handler(const Smach::event& x); |
---|
184 | |
---|
185 | //constructor destructor |
---|
186 | StateText_Context(CanvasView *canvas_view); |
---|
187 | ~StateText_Context(); |
---|
188 | |
---|
189 | const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view;} |
---|
190 | etl::handle<synfigapp::CanvasInterface> get_canvas_interface()const{return canvas_view->canvas_interface();} |
---|
191 | WorkArea * get_work_area()const{return canvas_view->get_work_area();} |
---|
192 | |
---|
193 | //Modifying settings etc. |
---|
194 | void load_settings(); |
---|
195 | void save_settings(); |
---|
196 | void reset(); |
---|
197 | void increment_id(); |
---|
198 | bool egress_on_selection_change; |
---|
199 | Smach::event_result event_layer_selection_changed_handler(const Smach::event& /*x*/) |
---|
200 | { |
---|
201 | if(egress_on_selection_change) |
---|
202 | throw &state_normal; //throw Smach::egress_exception(); |
---|
203 | return Smach::RESULT_OK; |
---|
204 | } |
---|
205 | |
---|
206 | void make_text(const Point& point); |
---|
207 | void toggle_layer_creation(); |
---|
208 | |
---|
209 | }; // END of class StateText_Context |
---|
210 | |
---|
211 | /* === P R O C E D U R E S ================================================= */ |
---|
212 | |
---|
213 | /* === M E T H O D S ======================================================= */ |
---|
214 | |
---|
215 | StateText::StateText(): |
---|
216 | Smach::state<StateText_Context>("text") |
---|
217 | { |
---|
218 | insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateText_Context::event_layer_selection_changed_handler)); |
---|
219 | insert(event_def(EVENT_STOP,&StateText_Context::event_stop_handler)); |
---|
220 | insert(event_def(EVENT_REFRESH,&StateText_Context::event_refresh_handler)); |
---|
221 | insert(event_def(EVENT_REFRESH_DUCKS,&StateText_Context::event_refresh_handler)); |
---|
222 | insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateText_Context::event_workarea_mouse_button_down_handler)); |
---|
223 | insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateText_Context::event_refresh_tool_options)); |
---|
224 | } |
---|
225 | |
---|
226 | StateText::~StateText() |
---|
227 | { |
---|
228 | } |
---|
229 | |
---|
230 | void |
---|
231 | StateText_Context::load_settings() |
---|
232 | { |
---|
233 | try |
---|
234 | { |
---|
235 | synfig::ChangeLocale change_locale(LC_NUMERIC, "C"); |
---|
236 | String value; |
---|
237 | Vector v; |
---|
238 | |
---|
239 | //parse the arguments yargh! |
---|
240 | if(settings.get_value("text.id",value)) |
---|
241 | set_id(value); |
---|
242 | else |
---|
243 | set_id("Text"); |
---|
244 | |
---|
245 | if(settings.get_value("text.blend",value) && value != "") |
---|
246 | set_blend(atoi(value.c_str())); |
---|
247 | else |
---|
248 | set_blend(0);//(int)Color::BLEND_COMPOSITE); //0 should be blend composites value |
---|
249 | |
---|
250 | if(settings.get_value("text.opacity",value)) |
---|
251 | set_opacity(atof(value.c_str())); |
---|
252 | else |
---|
253 | set_opacity(1); |
---|
254 | |
---|
255 | if(settings.get_value("text.paragraph",value) && value=="1") |
---|
256 | set_paragraph_flag(true); |
---|
257 | else |
---|
258 | set_paragraph_flag(false); |
---|
259 | |
---|
260 | if(settings.get_value("text.size_x",value)) |
---|
261 | v[0] = atof(value.c_str()); |
---|
262 | else |
---|
263 | v[0] = 0.25; |
---|
264 | if(settings.get_value("text.size_y",value)) |
---|
265 | v[1] = atof(value.c_str()); |
---|
266 | else |
---|
267 | v[1] = 0.25; |
---|
268 | set_size(v); |
---|
269 | |
---|
270 | if(settings.get_value("text.orient_x",value)) |
---|
271 | v[0] = atof(value.c_str()); |
---|
272 | else |
---|
273 | v[0] = 0.5; |
---|
274 | if(settings.get_value("text.orient_y",value)) |
---|
275 | v[1] = atof(value.c_str()); |
---|
276 | else |
---|
277 | v[1] = 0.5; |
---|
278 | set_orientation(v); |
---|
279 | |
---|
280 | if(settings.get_value("text.family",value)) |
---|
281 | set_family(value); |
---|
282 | else |
---|
283 | set_family("Sans Serif"); |
---|
284 | |
---|
285 | // since we have only text layer creation button, always turn it on. |
---|
286 | if(settings.get_value("text.layer_text",value) && value=="0") |
---|
287 | set_layer_text_flag(true); |
---|
288 | else |
---|
289 | set_layer_text_flag(true); |
---|
290 | |
---|
291 | // determine layer flags |
---|
292 | layer_text_flag = get_layer_text_flag(); |
---|
293 | } |
---|
294 | catch(...) |
---|
295 | { |
---|
296 | synfig::warning("State Text: Caught exception when attempting to load settings."); |
---|
297 | } |
---|
298 | } |
---|
299 | |
---|
300 | void |
---|
301 | StateText_Context::save_settings() |
---|
302 | { |
---|
303 | try |
---|
304 | { |
---|
305 | synfig::ChangeLocale change_locale(LC_NUMERIC, "C"); |
---|
306 | settings.set_value("text.id",get_id()); |
---|
307 | settings.set_value("text.layer_polygon",get_layer_text_flag()?"1":"0"); |
---|
308 | settings.set_value("text.blend",strprintf("%d",get_blend())); |
---|
309 | settings.set_value("text.opacity",strprintf("%f",(float)get_opacity())); |
---|
310 | settings.set_value("text.paragraph",get_paragraph_flag()?"1":"0"); |
---|
311 | settings.set_value("text.size_x",strprintf("%f",(float)get_size()[0])); |
---|
312 | settings.set_value("text.size_y",strprintf("%f",(float)get_size()[1])); |
---|
313 | settings.set_value("text.orient_x",strprintf("%f",(float)get_orientation()[0])); |
---|
314 | settings.set_value("text.orient_y",strprintf("%f",(float)get_orientation()[1])); |
---|
315 | settings.set_value("text.family",get_family()); |
---|
316 | } |
---|
317 | catch(...) |
---|
318 | { |
---|
319 | synfig::warning("State Text: Caught exception when attempting to save settings."); |
---|
320 | } |
---|
321 | } |
---|
322 | |
---|
323 | void |
---|
324 | StateText_Context::reset() |
---|
325 | { |
---|
326 | refresh_ducks(); |
---|
327 | } |
---|
328 | |
---|
329 | void |
---|
330 | StateText_Context::increment_id() |
---|
331 | { |
---|
332 | String id(get_id()); |
---|
333 | int number=1; |
---|
334 | int digits=0; |
---|
335 | |
---|
336 | if(id.empty()) |
---|
337 | id="Text"; |
---|
338 | |
---|
339 | // If there is a number |
---|
340 | // already at the end of the |
---|
341 | // id, then remove it. |
---|
342 | if(id[id.size()-1]<='9' && id[id.size()-1]>='0') |
---|
343 | { |
---|
344 | // figure out how many digits it is |
---|
345 | for (digits = 0; |
---|
346 | (int)id.size()-1 >= digits && id[id.size()-1-digits] <= '9' && id[id.size()-1-digits] >= '0'; |
---|
347 | digits++) |
---|
348 | ; |
---|
349 | |
---|
350 | String str_number; |
---|
351 | str_number=String(id,id.size()-digits,id.size()); |
---|
352 | id=String(id,0,id.size()-digits); |
---|
353 | |
---|
354 | number=atoi(str_number.c_str()); |
---|
355 | } |
---|
356 | else |
---|
357 | { |
---|
358 | number=1; |
---|
359 | digits=3; |
---|
360 | } |
---|
361 | |
---|
362 | number++; |
---|
363 | |
---|
364 | // Add the number back onto the id |
---|
365 | { |
---|
366 | const String format(strprintf("%%0%dd",digits)); |
---|
367 | id+=strprintf(format.c_str(),number); |
---|
368 | } |
---|
369 | |
---|
370 | // Set the ID |
---|
371 | set_id(id); |
---|
372 | } |
---|
373 | |
---|
374 | StateText_Context::StateText_Context(CanvasView *canvas_view): |
---|
375 | canvas_view(canvas_view), |
---|
376 | is_working(*canvas_view), |
---|
377 | duckmatic_push(get_work_area()), |
---|
378 | prev_workarea_layer_status_(get_work_area()->get_allow_layer_clicks()), |
---|
379 | settings(synfigapp::Main::get_selected_input_device()->settings()), |
---|
380 | opacity_hscl(0.0f, 1.01f, 0.01f) |
---|
381 | { |
---|
382 | egress_on_selection_change=true; |
---|
383 | |
---|
384 | |
---|
385 | /* Set up the tool options dialog */ |
---|
386 | |
---|
387 | // 0, title |
---|
388 | title_label.set_label(_("Text Creation")); |
---|
389 | Pango::AttrList list; |
---|
390 | Pango::AttrInt attr = Pango::Attribute::create_attr_weight(Pango::WEIGHT_BOLD); |
---|
391 | list.insert(attr); |
---|
392 | title_label.set_attributes(list); |
---|
393 | title_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
394 | |
---|
395 | // 1, layer name label and entry |
---|
396 | id_label.set_label(_("Name:")); |
---|
397 | id_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
398 | SPACING(id_gap, GAP); |
---|
399 | id_box.pack_start(id_label, Gtk::PACK_SHRINK); |
---|
400 | id_box.pack_start(*id_gap, Gtk::PACK_SHRINK); |
---|
401 | |
---|
402 | id_box.pack_start(id_entry); |
---|
403 | |
---|
404 | // 2, layer types creation |
---|
405 | layer_types_label.set_label(_("Layer Type:")); |
---|
406 | layer_types_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
407 | |
---|
408 | LAYER_CREATION(layer_text_togglebutton, |
---|
409 | ("synfig-layer_other_text"), _("Create a text layer")); |
---|
410 | |
---|
411 | SPACING(layer_types_indent, INDENTATION); |
---|
412 | |
---|
413 | layer_types_box.pack_start(*layer_types_indent, Gtk::PACK_SHRINK); |
---|
414 | layer_types_box.pack_start(layer_text_togglebutton, Gtk::PACK_SHRINK); |
---|
415 | |
---|
416 | // 3, blend method label and dropdown list |
---|
417 | blend_label.set_label(_("Blend Method:")); |
---|
418 | blend_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
419 | SPACING(blend_gap, GAP); |
---|
420 | blend_box.pack_start(blend_label, Gtk::PACK_SHRINK); |
---|
421 | blend_box.pack_start(*blend_gap, Gtk::PACK_SHRINK); |
---|
422 | |
---|
423 | blend_enum.set_param_desc(ParamDesc(Color::BLEND_COMPOSITE,"blend_method") |
---|
424 | .set_local_name(_("Blend Method")) |
---|
425 | .set_description(_("Defines the blend method to be used for texts"))); |
---|
426 | |
---|
427 | // 4, opacity label and slider |
---|
428 | opacity_label.set_label(_("Opacity:")); |
---|
429 | opacity_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
430 | |
---|
431 | opacity_hscl.set_digits(2); |
---|
432 | opacity_hscl.set_value_pos(Gtk::POS_LEFT); |
---|
433 | opacity_hscl.set_tooltip_text(_("Opacity")); |
---|
434 | |
---|
435 | // 5, paragraph |
---|
436 | paragraph_label.set_label(_("Multiline Text")); |
---|
437 | paragraph_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
438 | paragraph_box.pack_start(paragraph_label, Gtk::PACK_SHRINK); |
---|
439 | paragraph_box.pack_end(paragraph_checkbutton, Gtk::PACK_SHRINK); |
---|
440 | |
---|
441 | // 6, size |
---|
442 | size_label.set_label(_("Size:")); |
---|
443 | size_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
444 | |
---|
445 | size_widget.set_digits(2); |
---|
446 | size_widget.set_canvas(canvas_view->get_canvas()); |
---|
447 | |
---|
448 | // 7, orientation |
---|
449 | orientation_label.set_label(_("Orientation:")); |
---|
450 | orientation_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
451 | |
---|
452 | orientation_widget.set_digits(2); |
---|
453 | |
---|
454 | // 8, family |
---|
455 | family_label.set_label(_("Family:")); |
---|
456 | family_label.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); |
---|
457 | |
---|
458 | // pack all options to the options_table |
---|
459 | |
---|
460 | // 0, title |
---|
461 | options_table.attach(title_label, |
---|
462 | 0, 2, 0, 1, Gtk::FILL, Gtk::FILL, 0, 0 |
---|
463 | ); |
---|
464 | // 1, name |
---|
465 | options_table.attach(id_box, |
---|
466 | 0, 2, 1, 2, Gtk::FILL, Gtk::FILL, 0, 0 |
---|
467 | ); |
---|
468 | // 2, layer types creation |
---|
469 | options_table.attach(layer_types_label, |
---|
470 | 0, 2, 2, 3, Gtk::FILL, Gtk::FILL, 0, 0 |
---|
471 | ); |
---|
472 | options_table.attach(layer_types_box, |
---|
473 | 0, 2, 3, 4, Gtk::FILL, Gtk::FILL, 0, 0 |
---|
474 | ); |
---|
475 | // 3, blend method |
---|
476 | options_table.attach(blend_box, |
---|
477 | 0, 1, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
478 | ); |
---|
479 | options_table.attach(blend_enum, |
---|
480 | 1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
481 | ); |
---|
482 | // 4, opacity |
---|
483 | options_table.attach(opacity_label, |
---|
484 | 0, 1, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
485 | ); |
---|
486 | options_table.attach(opacity_hscl, |
---|
487 | 1, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
488 | ); |
---|
489 | // 5, paragraph |
---|
490 | options_table.attach(paragraph_box, |
---|
491 | 0, 2, 6, 7, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
492 | ); |
---|
493 | // 6, size |
---|
494 | options_table.attach(size_label, |
---|
495 | 0, 1, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
496 | ); |
---|
497 | options_table.attach(size_widget, |
---|
498 | 1, 2, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
499 | ); |
---|
500 | // 7, orientation |
---|
501 | options_table.attach(orientation_label, |
---|
502 | 0, 1, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
503 | ); |
---|
504 | options_table.attach(orientation_widget, |
---|
505 | 1, 2, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0 |
---|
506 | ); |
---|
507 | // 8, family |
---|
508 | options_table.attach(family_label, |
---|
509 | 0, 1, 9, 10, Gtk::FILL, Gtk::FILL, 0, 0 |
---|
510 | ); |
---|
511 | options_table.attach(family_entry, |
---|
512 | 1, 2, 9, 10, Gtk::FILL, Gtk::FILL, 0, 0 |
---|
513 | ); |
---|
514 | // fine-tune options layout |
---|
515 | options_table.set_border_width(GAP*2); // border width |
---|
516 | options_table.set_row_spacings(GAP); // row gap |
---|
517 | options_table.set_row_spacing(0, GAP*2); // the gap between first and second row. |
---|
518 | options_table.set_row_spacing(2, 1); // row gap between label and icon of layer type |
---|
519 | options_table.set_row_spacing(10, 0); // the final row using border width of table |
---|
520 | |
---|
521 | options_table.show_all(); |
---|
522 | |
---|
523 | load_settings(); |
---|
524 | |
---|
525 | refresh_tool_options(); |
---|
526 | App::dialog_tool_options->present(); |
---|
527 | |
---|
528 | // Turn off layer clicking |
---|
529 | get_work_area()->set_allow_layer_clicks(false); |
---|
530 | |
---|
531 | // clear out the ducks |
---|
532 | get_work_area()->clear_ducks(); |
---|
533 | |
---|
534 | // Refresh the work area |
---|
535 | get_work_area()->queue_draw(); |
---|
536 | |
---|
537 | // Hide the tables if they are showing |
---|
538 | //prev_table_status=get_canvas_view()->tables_are_visible(); |
---|
539 | //if(prev_table_status)get_canvas_view()->hide_tables(); |
---|
540 | |
---|
541 | // Disable the time bar |
---|
542 | //get_canvas_view()->set_sensitive_timebar(false); |
---|
543 | |
---|
544 | // Connect a signal |
---|
545 | //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateText_Context::on_user_click)); |
---|
546 | get_work_area()->set_cursor(Gdk::XTERM); |
---|
547 | |
---|
548 | App::dock_toolbox->refresh(); |
---|
549 | } |
---|
550 | |
---|
551 | void |
---|
552 | StateText_Context::refresh_tool_options() |
---|
553 | { |
---|
554 | App::dialog_tool_options->clear(); |
---|
555 | App::dialog_tool_options->set_widget(options_table); |
---|
556 | App::dialog_tool_options->set_local_name(_("Text Tool")); |
---|
557 | App::dialog_tool_options->set_name("text"); |
---|
558 | } |
---|
559 | |
---|
560 | Smach::event_result |
---|
561 | StateText_Context::event_refresh_tool_options(const Smach::event& /*x*/) |
---|
562 | { |
---|
563 | refresh_tool_options(); |
---|
564 | return Smach::RESULT_ACCEPT; |
---|
565 | } |
---|
566 | |
---|
567 | StateText_Context::~StateText_Context() |
---|
568 | { |
---|
569 | save_settings(); |
---|
570 | |
---|
571 | // Restore layer clicking |
---|
572 | get_work_area()->set_allow_layer_clicks(prev_workarea_layer_status_); |
---|
573 | get_work_area()->reset_cursor(); |
---|
574 | |
---|
575 | App::dialog_tool_options->clear(); |
---|
576 | |
---|
577 | get_work_area()->queue_draw(); |
---|
578 | |
---|
579 | get_canvas_view()->queue_rebuild_ducks(); |
---|
580 | |
---|
581 | App::dock_toolbox->refresh(); |
---|
582 | } |
---|
583 | |
---|
584 | Smach::event_result |
---|
585 | StateText_Context::event_stop_handler(const Smach::event& /*x*/) |
---|
586 | { |
---|
587 | //throw Smach::egress_exception(); |
---|
588 | throw &state_normal; |
---|
589 | return Smach::RESULT_OK; |
---|
590 | } |
---|
591 | |
---|
592 | Smach::event_result |
---|
593 | StateText_Context::event_refresh_handler(const Smach::event& /*x*/) |
---|
594 | { |
---|
595 | refresh_ducks(); |
---|
596 | return Smach::RESULT_ACCEPT; |
---|
597 | } |
---|
598 | |
---|
599 | void |
---|
600 | StateText_Context::make_text(const Point& _point) |
---|
601 | { |
---|
602 | if (get_layer_text_flag()) |
---|
603 | { |
---|
604 | |
---|
605 | synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New Text")); |
---|
606 | synfigapp::PushMode push_mode(get_canvas_interface(),synfigapp::MODE_NORMAL); |
---|
607 | |
---|
608 | Layer::Handle layer; |
---|
609 | |
---|
610 | Canvas::Handle canvas(get_canvas_view()->get_canvas()); |
---|
611 | int depth(0); |
---|
612 | |
---|
613 | // we are temporarily using the layer to hold something |
---|
614 | layer=get_canvas_view()->get_selection_manager()->get_selected_layer(); |
---|
615 | if(layer) |
---|
616 | { |
---|
617 | depth=layer->get_depth(); |
---|
618 | canvas=layer->get_canvas(); |
---|
619 | } |
---|
620 | |
---|
621 | synfigapp::SelectionManager::LayerList layer_selection; |
---|
622 | if (!getenv("SYNFIG_TOOLS_CLEAR_SELECTION")) |
---|
623 | layer_selection = get_canvas_view()->get_selection_manager()->get_selected_layers(); |
---|
624 | |
---|
625 | const synfig::TransformStack& transform(get_work_area()->get_curr_transform_stack()); |
---|
626 | const Point point(transform.unperform(_point)); |
---|
627 | |
---|
628 | String text; |
---|
629 | if (get_paragraph_flag()) |
---|
630 | App::dialog_paragraph(_("Text Paragraph"), _("Enter text here:"), text); |
---|
631 | else |
---|
632 | App::dialog_entry(_("Input text"), |
---|
633 | _("Text: "), |
---|
634 | text, |
---|
635 | _("Cancel"), |
---|
636 | _("Ok")); |
---|
637 | |
---|
638 | egress_on_selection_change=false; |
---|
639 | layer=get_canvas_interface()->add_layer_to("text",canvas,depth); |
---|
640 | egress_on_selection_change=true; |
---|
641 | if (!layer) |
---|
642 | { |
---|
643 | get_canvas_view()->get_ui_interface()->error(_("Unable to create layer")); |
---|
644 | group.cancel(); |
---|
645 | return; |
---|
646 | } |
---|
647 | layer_selection.push_back(layer); |
---|
648 | |
---|
649 | layer->set_param("blend_method", get_blend()); |
---|
650 | get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method"); |
---|
651 | |
---|
652 | layer->set_param("amount", get_opacity()); |
---|
653 | get_canvas_interface()->signal_layer_param_changed()(layer, "amount"); |
---|
654 | |
---|
655 | layer->set_param("origin",point); |
---|
656 | get_canvas_interface()->signal_layer_param_changed()(layer,"origin"); |
---|
657 | |
---|
658 | layer->set_param("text",text); |
---|
659 | get_canvas_interface()->signal_layer_param_changed()(layer,"text"); |
---|
660 | |
---|
661 | layer->set_param("size",get_size()); |
---|
662 | get_canvas_interface()->signal_layer_param_changed()(layer,"size"); |
---|
663 | |
---|
664 | layer->set_param("orient",get_orientation()); |
---|
665 | get_canvas_interface()->signal_layer_param_changed()(layer,"orient"); |
---|
666 | |
---|
667 | layer->set_param("family",get_family()); |
---|
668 | get_canvas_interface()->signal_layer_param_changed()(layer,"family"); |
---|
669 | |
---|
670 | layer->set_description(get_id()); |
---|
671 | get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description()); |
---|
672 | |
---|
673 | egress_on_selection_change=false; |
---|
674 | get_canvas_interface()->get_selection_manager()->clear_selected_layers(); |
---|
675 | get_canvas_interface()->get_selection_manager()->set_selected_layers(layer_selection); |
---|
676 | egress_on_selection_change=true; |
---|
677 | |
---|
678 | reset(); |
---|
679 | increment_id(); |
---|
680 | } |
---|
681 | } |
---|
682 | |
---|
683 | Smach::event_result |
---|
684 | StateText_Context::event_workarea_mouse_button_down_handler(const Smach::event& x) |
---|
685 | { |
---|
686 | const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x)); |
---|
687 | if(event.button==BUTTON_LEFT) |
---|
688 | { |
---|
689 | make_text(get_work_area()->snap_point_to_grid(event.pos)); |
---|
690 | |
---|
691 | get_work_area()->clear_ducks(); |
---|
692 | return Smach::RESULT_ACCEPT; |
---|
693 | } |
---|
694 | return Smach::RESULT_OK; |
---|
695 | } |
---|
696 | |
---|
697 | void |
---|
698 | StateText_Context::refresh_ducks() |
---|
699 | { |
---|
700 | get_work_area()->clear_ducks(); |
---|
701 | get_work_area()->queue_draw(); |
---|
702 | } |
---|
703 | |
---|
704 | void |
---|
705 | StateText_Context::toggle_layer_creation() |
---|
706 | { |
---|
707 | // don't allow none layer creation |
---|
708 | if (get_layer_text_flag() == 0) |
---|
709 | { |
---|
710 | if(layer_text_flag) set_layer_text_flag(true); |
---|
711 | } |
---|
712 | |
---|
713 | // update layer flags |
---|
714 | layer_text_flag = get_layer_text_flag(); |
---|
715 | } |
---|