initial version
[synfig.git] / synfig-studio / trunk / src / gtkmm / state_stroke.cpp
1 /* === S I N F G =========================================================== */
2 /*!     \file state_stroke.cpp
3 **      \brief Template File
4 **
5 **      $Id: state_stroke.cpp,v 1.1.1.1 2005/01/07 03:34:37 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 <gtkmm/dialog.h>
32 #include <gtkmm/entry.h>
33
34 #include <sinfg/valuenode_dynamiclist.h>
35
36 #include "state_stroke.h"
37 #include "canvasview.h"
38 #include "workarea.h"
39 #include "app.h"
40 #include <sinfg/valuenode_bline.h>
41 #include <ETL/hermite>
42 #include <ETL/calculus>
43 #include <utility>
44 #include "event_mouse.h"
45 #include "event_layerclick.h"
46 #include "toolbox.h"
47 #include <sinfgapp/main.h>
48
49 #endif
50
51 /* === U S I N G =========================================================== */
52
53 using namespace std;
54 using namespace etl;
55 using namespace sinfg;
56 using namespace studio;
57
58 /* === M A C R O S ========================================================= */
59
60 /* === G L O B A L S ======================================================= */
61
62 StateStroke studio::state_stroke;
63
64 /* === C L A S S E S & S T R U C T S ======================================= */
65
66 class studio::StateStroke_Context : public sigc::trackable
67 {
68         etl::handle<CanvasView> canvas_view_;
69         CanvasView::IsWorking is_working;
70         
71         Duckmatic::Push duckmatic_push;
72         
73         etl::smart_ptr<std::list<sinfg::Point> > stroke_data;
74
75         etl::smart_ptr<std::list<sinfg::Real> > width_data;
76
77         Gdk::ModifierType modifier;
78
79 public:
80
81         Smach::event_result event_stop_handler(const Smach::event& x);
82
83         Smach::event_result event_refresh_handler(const Smach::event& x);
84
85         Smach::event_result event_mouse_up_handler(const Smach::event& x);
86
87         Smach::event_result event_mouse_draw_handler(const Smach::event& x);
88         Smach::event_result event_refresh_tool_options(const Smach::event& x);
89
90         StateStroke_Context(CanvasView* canvas_view);
91
92         ~StateStroke_Context();
93
94         const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
95         etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
96         sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
97         WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
98         
99 };      // END of class StateStroke_Context
100
101
102 /* === M E T H O D S ======================================================= */
103
104 StateStroke::StateStroke():
105         Smach::state<StateStroke_Context>("stroke")
106 {
107         insert(event_def(EVENT_STOP,&StateStroke_Context::event_stop_handler));
108         insert(event_def(EVENT_REFRESH,&StateStroke_Context::event_refresh_handler));
109 //      insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateStroke_Context::event_mouse_down_handler));
110         insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateStroke_Context::event_mouse_up_handler));
111         insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateStroke_Context::event_mouse_draw_handler));
112         insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateStroke_Context::event_refresh_tool_options));
113 }       
114
115 StateStroke::~StateStroke()
116 {
117 }
118
119
120 StateStroke_Context::StateStroke_Context(CanvasView* canvas_view):
121         canvas_view_(canvas_view),
122         is_working(*canvas_view),
123         duckmatic_push(get_work_area())
124 {
125         width_data.spawn();
126         stroke_data.spawn();
127
128         get_work_area()->add_stroke(stroke_data, sinfgapp::Main::get_foreground_color());
129
130         sinfg::info("Now Scribbling...");       
131 }
132
133 StateStroke_Context::~StateStroke_Context()
134 {
135         duckmatic_push.restore();
136         
137         App::toolbox->refresh();
138         sinfg::info("No longer scribbling");    
139
140         // Send the stroke data to whatever previously called this state.
141         if(stroke_data->size()>=2)
142                 get_canvas_view()->get_smach().process_event(EventStroke(stroke_data,width_data,modifier));
143 }
144
145 Smach::event_result
146 StateStroke_Context::event_refresh_tool_options(const Smach::event& x)
147 {
148         return Smach::RESULT_ACCEPT;
149 }
150
151 Smach::event_result
152 StateStroke_Context::event_stop_handler(const Smach::event& x)
153 {
154         throw Smach::pop_exception();
155 }
156
157 Smach::event_result
158 StateStroke_Context::event_refresh_handler(const Smach::event& x)
159 {
160         return Smach::RESULT_ACCEPT;
161 }
162
163 Smach::event_result
164 StateStroke_Context::event_mouse_up_handler(const Smach::event& x)
165 {
166         const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
167         switch(event.button)
168         {
169         case BUTTON_LEFT:
170                 {
171                         modifier=event.modifier;
172                         throw Smach::pop_exception();
173                 }
174         
175         case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
176                 return Smach::RESULT_ACCEPT;
177         
178         default:        
179                 return Smach::RESULT_OK;
180         }
181 }
182
183 Smach::event_result
184 StateStroke_Context::event_mouse_draw_handler(const Smach::event& x)
185 {
186         const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
187         switch(event.button)
188         {
189         case BUTTON_LEFT:
190                 {
191                         stroke_data->push_back(event.pos);
192                         width_data->push_back(event.pressure);
193                         get_work_area()->queue_draw();                  
194                         return Smach::RESULT_ACCEPT;
195                 }
196         
197         case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
198                 return Smach::RESULT_ACCEPT;
199         
200         default:        
201                 return Smach::RESULT_OK;
202         }
203 }