Changed the "tagrelease" and "tagstable" make targets to use subversion. Also increme...
[synfig.git] / synfig-studio / tags / stable / src / gtkmm / state_normal.cpp
1 /* === S I N F G =========================================================== */
2 /*!     \file template.cpp
3 **      \brief Template File
4 **
5 **      $Id: state_normal.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "state_normal.h"
32 #include "workarea.h"
33 #include "event_mouse.h"
34 #include "event_layerclick.h"
35 #include "toolbox.h"
36 #include "dialog_tooloptions.h"
37 #include <gtkmm/dialog.h>
38 #include "widget_waypointmodel.h"
39 #include <sinfg/valuenode_animated.h>
40 #include <sinfg/valuenode_composite.h>
41 #include <sinfg/valuenode_const.h>
42 #include "canvasview.h"
43 #endif
44
45 /* === U S I N G =========================================================== */
46
47 using namespace std;
48 using namespace etl;
49 using namespace sinfg;
50 using namespace studio;
51
52 /* === M A C R O S ========================================================= */
53
54 /* === C L A S S E S & S T R U C T S ======================================= */
55
56 class studio::StateNormal_Context : public sigc::trackable
57 {
58         CanvasView *canvas_view;
59         
60         CanvasView* get_canvas_view() { return canvas_view; }
61         Canvas::Handle get_canvas() { return canvas_view->get_canvas(); }
62         WorkArea* get_work_area() { return canvas_view->get_work_area(); }
63         etl::handle<sinfgapp::CanvasInterface> get_canvas_interface() { return canvas_view->canvas_interface(); }
64         
65 public:
66         StateNormal_Context(CanvasView *canvas_view);
67         ~StateNormal_Context();
68         
69         Smach::event_result event_stop_handler(const Smach::event& x);
70
71         Smach::event_result event_refresh_handler(const Smach::event& x);
72
73         Smach::event_result event_refresh_ducks_handler(const Smach::event& x);
74
75         Smach::event_result event_undo_handler(const Smach::event& x);
76
77         Smach::event_result event_redo_handler(const Smach::event& x);
78
79         Smach::event_result event_mouse_button_down_handler(const Smach::event& x);
80
81         Smach::event_result event_multiple_ducks_clicked_handler(const Smach::event& x);
82
83         Smach::event_result event_refresh_tool_options(const Smach::event& x);
84
85         Smach::event_result event_layer_click(const Smach::event& x);
86
87         void edit_several_waypoints(std::list<sinfgapp::ValueDesc> value_desc_list);
88
89         void refresh_tool_options();
90 }; // END of class StateNormal_Context
91
92 /* === G L O B A L S ======================================================= */
93
94 StateNormal studio::state_normal;
95
96 /* === P R O C E D U R E S ================================================= */
97
98 /* === M E T H O D S ======================================================= */
99
100 StateNormal::StateNormal():
101         Smach::state<StateNormal_Context>("normal")
102 {
103         insert(event_def(EVENT_STOP,&StateNormal_Context::event_stop_handler));
104         insert(event_def(EVENT_REFRESH,&StateNormal_Context::event_refresh_handler));
105         insert(event_def(EVENT_REFRESH_DUCKS,&StateNormal_Context::event_refresh_ducks_handler));
106         insert(event_def(EVENT_UNDO,&StateNormal_Context::event_undo_handler));
107         insert(event_def(EVENT_REDO,&StateNormal_Context::event_redo_handler));
108         insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateNormal_Context::event_mouse_button_down_handler));
109         insert(event_def(EVENT_WORKAREA_MULTIPLE_DUCKS_CLICKED,&StateNormal_Context::event_multiple_ducks_clicked_handler));
110         insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateNormal_Context::event_refresh_tool_options)); 
111         insert(event_def(EVENT_WORKAREA_LAYER_CLICKED,&StateNormal_Context::event_layer_click));        
112 }       
113
114 StateNormal::~StateNormal()
115 {
116 }
117
118 StateNormal_Context::StateNormal_Context(CanvasView *canvas_view):
119         canvas_view(canvas_view)
120 {
121         sinfg::info("Enterted Normal State");
122 }
123
124 StateNormal_Context::~StateNormal_Context()
125 {
126         sinfg::info("Left Normal State");
127 }
128
129 void
130 StateNormal_Context::refresh_tool_options()
131 {
132         App::dialog_tool_options->clear();
133         App::dialog_tool_options->set_name("normal");
134 }
135
136 Smach::event_result
137 StateNormal_Context::event_refresh_tool_options(const Smach::event& x)
138 {
139         refresh_tool_options();
140         return Smach::RESULT_ACCEPT;
141 }
142
143 Smach::event_result
144 StateNormal_Context::event_stop_handler(const Smach::event& x)
145 {
146         sinfg::info("STATE NORMAL: Received Stop Event");
147         canvas_view->stop();
148         return Smach::RESULT_ACCEPT;
149 }
150
151 Smach::event_result
152 StateNormal_Context::event_refresh_handler(const Smach::event& x)
153 {
154         sinfg::info("STATE NORMAL: Received Refresh Event");
155         canvas_view->rebuild_tables();
156         canvas_view->work_area->queue_render_preview();
157         return Smach::RESULT_ACCEPT;
158 }
159
160 Smach::event_result
161 StateNormal_Context::event_refresh_ducks_handler(const Smach::event& x)
162 {
163         sinfg::info("STATE NORMAL: Received Refresh Ducks");
164         canvas_view->queue_rebuild_ducks();
165         return Smach::RESULT_ACCEPT;
166 }
167
168 Smach::event_result
169 StateNormal_Context::event_undo_handler(const Smach::event& x)
170 {
171         sinfg::info("STATE NORMAL: Received Undo Event");
172         canvas_view->get_instance()->undo();
173         return Smach::RESULT_ACCEPT;
174 }
175
176 Smach::event_result
177 StateNormal_Context::event_redo_handler(const Smach::event& x)
178 {
179         sinfg::info("STATE NORMAL: Received Redo Event");
180         canvas_view->get_instance()->redo();
181         return Smach::RESULT_ACCEPT;
182 }
183
184 Smach::event_result
185 StateNormal_Context::event_mouse_button_down_handler(const Smach::event& x)
186 {
187         sinfg::info("STATE NORMAL: Received mouse button down Event");
188
189         const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
190
191         switch(event.button)
192         {
193         case BUTTON_RIGHT:
194                 canvas_view->popup_main_menu();
195                 return Smach::RESULT_ACCEPT;
196         default:
197                 return Smach::RESULT_OK;
198         }
199 }
200
201 Smach::event_result
202 StateNormal_Context::event_layer_click(const Smach::event& x)
203 {
204         const EventLayerClick& event(*reinterpret_cast<const EventLayerClick*>(&x));
205         
206         if(event.layer)
207         {
208                 sinfg::info("STATE NORMAL: Received layer click Event, \"%s\"",event.layer->get_name().c_str());
209         }
210         else
211         {
212                 sinfg::info("STATE NORMAL: Received layer click Event with an empty layer.");
213         }
214         
215         switch(event.button)
216         {
217         case BUTTON_LEFT:
218                 if(!(event.modifier&Gdk::CONTROL_MASK))
219                         canvas_view->get_selection_manager()->clear_selected_layers();
220                 if(event.layer)
221                 {
222                         std::list<Layer::Handle> layer_list(canvas_view->get_selection_manager()->get_selected_layers());
223                         std::set<Layer::Handle> layers(layer_list.begin(),layer_list.end());
224                         if(layers.count(event.layer))
225                         {
226                                 layers.erase(event.layer);
227                                 layer_list=std::list<Layer::Handle>(layers.begin(),layers.end());
228                                 canvas_view->get_selection_manager()->clear_selected_layers();
229                                 canvas_view->get_selection_manager()->set_selected_layers(layer_list);
230                         }
231                         else
232                         {
233                                 canvas_view->get_selection_manager()->set_selected_layer(event.layer);
234                         }
235                 }
236                 return Smach::RESULT_ACCEPT;
237         case BUTTON_RIGHT:
238                 canvas_view->popup_layer_menu(event.layer);
239                 return Smach::RESULT_ACCEPT;
240         default:
241                 return Smach::RESULT_OK;
242         }
243 }
244
245 /*
246 void
247 StateNormal_Context::edit_several_waypoints(std::list<sinfgapp::ValueDesc> value_desc_list)
248 {
249         Gtk::Dialog dialog(
250                 "Edit Multiple Waypoints",              // Title
251                 true,           // Modal
252                 true            // use_separator
253         );
254
255         Widget_WaypointModel widget_waypoint_model;
256         widget_waypoint_model.show();
257
258         dialog.get_vbox()->pack_start(widget_waypoint_model);
259         
260         
261         dialog.add_button(Gtk::StockID("gtk-apply"),1);
262         dialog.add_button(Gtk::StockID("gtk-cancel"),0);
263         dialog.show();
264         
265         DEBUGPOINT();
266         if(dialog.run()==0)
267                 return;
268         DEBUGPOINT();
269         sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Set Waypoints"));
270
271         std::list<sinfgapp::ValueDesc>::iterator iter;
272         for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
273         {
274                 sinfgapp::ValueDesc value_desc(*iter);
275                 
276                 if(!value_desc.is_valid())
277                         continue;
278
279                 ValueNode_Animated::Handle value_node;
280                 
281                 // If this value isn't a ValueNode_Animated, but
282                 // it is somewhat constant, then go ahead and convert
283                 // it to a ValueNode_Animated.
284                 if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
285                 {
286                         ValueBase value;
287                         if(value_desc.is_value_node())
288                                 value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value();
289                         else
290                                 value=value_desc.get_value();
291                         
292                         value_node=ValueNode_Animated::create(value,get_canvas()->get_time());
293                         
294                         sinfgapp::Action::Handle action;
295                         
296                         if(!value_desc.is_value_node())
297                         {
298                                 action=sinfgapp::Action::create("value_desc_connect");
299                                 action->set_param("dest",value_desc);
300                                 action->set_param("src",ValueNode::Handle(value_node));
301                         }
302                         else
303                         {
304                                 action=sinfgapp::Action::create("value_node_replace");
305                                 action->set_param("dest",value_desc.get_value_node());
306                                 action->set_param("src",ValueNode::Handle(value_node));
307                         }
308                         
309                         action->set_param("canvas",get_canvas());
310                         action->set_param("canvas_interface",get_canvas_interface());
311                         
312         
313                         if(!get_canvas_interface()->get_instance()->perform_action(action))
314                         {
315                                 get_canvas_view()->get_ui_interface()->error(_("Unable to convert to animated waypoint"));
316                                 group.cancel();
317                                 return;
318                         }
319                 }
320                 else
321                 {
322                         if(value_desc.is_value_node())
323                                 value_node=ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node());
324                 }
325                 
326                 
327                 if(value_node)
328                 {
329                         
330                         sinfgapp::Action::Handle action(sinfgapp::Action::create("waypoint_set_smart"));
331
332                         if(!action)
333                         {
334                                 get_canvas_view()->get_ui_interface()->error(_("Unable to find waypoint_set_smart action"));
335                                 group.cancel();
336                                 return;
337                         }
338                                 
339
340                         action->set_param("canvas",get_canvas());                       
341                         action->set_param("canvas_interface",get_canvas_interface());                   
342                         action->set_param("value_node",ValueNode::Handle(value_node));                  
343                         action->set_param("time",get_canvas()->get_time());                                             
344                         action->set_param("model",widget_waypoint_model.get_waypoint_model());
345                 
346                         if(!get_canvas_interface()->get_instance()->perform_action(action))
347                         {
348                                 get_canvas_view()->get_ui_interface()->error(_("Unable to set a specific waypoint"));
349                                 group.cancel();
350                                 return;
351                         }
352                 }
353                 else
354                 {
355                         //get_canvas_view()->get_ui_interface()->error(_("Unable to animate a specific valuedesc"));
356                         //group.cancel();
357                         //return;
358                 }
359                         
360         }
361 }
362 */
363
364 Smach::event_result
365 StateNormal_Context::event_multiple_ducks_clicked_handler(const Smach::event& x)
366 {
367         sinfg::info("STATE NORMAL: Received multiple duck click event");
368
369         //const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
370
371         std::list<sinfgapp::ValueDesc> value_desc_list;
372         
373         // Create a list of value_descs associated with selection
374         const DuckList selected_ducks(get_work_area()->get_selected_ducks());
375         DuckList::const_iterator iter;
376         for(iter=selected_ducks.begin();iter!=selected_ducks.end();++iter)
377         {
378                 sinfgapp::ValueDesc value_desc((*iter)->get_value_desc());
379                 
380                 if(!value_desc.is_valid())
381                         continue;
382                 
383                 if(value_desc.get_value_type()==ValueBase::TYPE_BLINEPOINT && value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
384                 {
385                         value_desc_list.push_back(
386                                 sinfgapp::ValueDesc(
387                                         ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())
388                                         ,0
389                                 )
390                         );
391                 }
392                 else
393                         value_desc_list.push_back(value_desc);
394         }
395
396         Gtk::Menu *menu=manage(new Gtk::Menu());
397         
398         canvas_view->get_instance()->make_param_menu(menu,canvas_view->get_canvas(),value_desc_list);
399         
400         /*
401         sinfgapp::Action::ParamList param_list;
402         param_list=get_canvas_interface()->generate_param_list(value_desc_list);
403
404         canvas_view->add_actions_to_menu(menu, param_list,sinfgapp::Action::CATEGORY_VALUEDESC|sinfgapp::Action::CATEGORY_VALUENODE);
405
406         menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Edit Waypoints"),
407                 sigc::bind(
408                         sigc::mem_fun(
409                                 *this,
410                                 &studio::StateNormal_Context::edit_several_waypoints
411                         ),
412                         value_desc_list
413                 )
414         ));
415         */
416         menu->popup(3,gtk_get_current_event_time());
417
418         return Smach::RESULT_ACCEPT;
419 }