Fix a crash when running single-threaded and dragging the time slider.
[synfig.git] / synfig-studio / trunk / src / gtkmm / renderer_guides.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file renderer_guides.cpp
3 **      \brief Template File
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "renderer_guides.h"
33 #include "workarea.h"
34 #include <ETL/misc>
35
36 #endif
37
38 /* === U S I N G =========================================================== */
39
40 using namespace std;
41 using namespace etl;
42 using namespace synfig;
43 using namespace studio;
44
45 /* === M A C R O S ========================================================= */
46
47 /* === G L O B A L S ======================================================= */
48
49 /* === P R O C E D U R E S ================================================= */
50
51 /* === M E T H O D S ======================================================= */
52
53 Renderer_Guides::Renderer_Guides():
54         dragging(false)
55 {
56
57 }
58
59 Renderer_Guides::~Renderer_Guides()
60 {
61 }
62
63 bool
64 Renderer_Guides::get_enabled_vfunc()const
65 {
66         return get_work_area()->get_show_guides();
67 }
68
69 std::list<float>&
70 Renderer_Guides::get_guide_list_x()
71 {
72         return get_work_area()->get_guide_list_x();
73 }
74
75 std::list<float>&
76 Renderer_Guides::get_guide_list_y()
77 {
78         return get_work_area()->get_guide_list_y();
79 }
80
81 bool
82 Renderer_Guides::event_vfunc(GdkEvent* event)
83 {
84         synfig::Point mouse_pos;
85         // float bezier_click_pos;
86         // const float radius((abs(get_pw())+abs(get_ph()))*4);
87         int button_pressed(0);
88         float pressure(0);
89         bool is_mouse(false);
90         Gdk::ModifierType modifier(Gdk::ModifierType(0));
91
92         // Handle input stuff
93         if(
94                 event->any.type==GDK_MOTION_NOTIFY ||
95                 event->any.type==GDK_BUTTON_PRESS ||
96                 event->any.type==GDK_2BUTTON_PRESS ||
97                 event->any.type==GDK_3BUTTON_PRESS ||
98                 event->any.type==GDK_BUTTON_RELEASE
99         )
100         {
101                 GdkDevice *device;
102                 if(event->any.type==GDK_MOTION_NOTIFY)
103                 {
104                         device=event->motion.device;
105                         modifier=Gdk::ModifierType(event->motion.state);
106                 }
107                 else
108                 {
109                         device=event->button.device;
110                         modifier=Gdk::ModifierType(event->button.state);
111                 }
112
113                 // Make sure we recognise the device
114                 /*if(curr_input_device)
115                 {
116                         if(curr_input_device!=device)
117                         {
118                                 assert(device);
119                                 curr_input_device=device;
120                                 signal_input_device_changed()(curr_input_device);
121                         }
122                 }
123                 else*/ if(device)
124                 {
125                         //curr_input_device=device;
126                         //signal_input_device_changed()(curr_input_device);
127                 }
128
129                 //assert(curr_input_device);
130
131                 // Calculate the position of the
132                 // input device in canvas coordinates
133                 // and the buttons
134                 if(!event->button.axes)
135                 {
136                         mouse_pos=synfig::Point(screen_to_comp_coords(synfig::Point(event->button.x,event->button.y)));
137                         button_pressed=event->button.button;
138                         pressure=1.0f;
139                         is_mouse=true;
140                         if(isnan(event->button.x) || isnan(event->button.y))
141                                 return false;
142                 }
143                 else
144                 {
145                         double x(event->button.axes[0]);
146                         double y(event->button.axes[1]);
147                         if(isnan(x) || isnan(y))
148                                 return false;
149
150                         pressure=event->button.axes[2];
151                         //synfig::info("pressure=%f",pressure);
152                         pressure-=0.04f;
153                         pressure/=1.0f-0.04f;
154
155
156                         assert(!isnan(pressure));
157
158                         mouse_pos=synfig::Point(screen_to_comp_coords(synfig::Point(x,y)));
159
160                         button_pressed=event->button.button;
161
162                         if(button_pressed==1 && pressure<0 && (event->any.type!=GDK_BUTTON_RELEASE && event->any.type!=GDK_BUTTON_PRESS))
163                                 button_pressed=0;
164                         if(pressure<0)
165                                 pressure=0;
166
167                         //if(event->any.type==GDK_BUTTON_PRESS && button_pressed)
168                         //      synfig::info("Button pressed on input device = %d",event->button.button);
169
170                         //if(event->button.axes[2]>0.1)
171                         //      button_pressed=1;
172                         //else
173                         //      button_pressed=0;
174                 }
175         }
176         switch(event->type)
177     {
178         case GDK_BUTTON_PRESS:
179                 break;
180         case GDK_MOTION_NOTIFY:
181                 break;
182         case GDK_BUTTON_RELEASE:
183                 break;
184         default:
185                 break;
186         }
187
188         return false;
189 }
190
191 void
192 Renderer_Guides::render_vfunc(
193         const Glib::RefPtr<Gdk::Drawable>& drawable,
194         const Gdk::Rectangle& /*expose_area*/
195 )
196 {
197         assert(get_work_area());
198         if(!get_work_area())
199                 return;
200
201         // const synfig::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
202
203         const synfig::Vector focus_point(get_work_area()->get_focus_point());
204
205         //std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
206
207         int drawable_w,drawable_h;
208         drawable->get_size(drawable_w,drawable_h);
209
210         // Calculate the window coordinates of the top-left
211         // corner of the canvas.
212         // const synfig::Vector::value_type
213         //      x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
214         //      y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
215
216         /*const synfig::Vector::value_type window_startx(window_tl[0]);
217         const synfig::Vector::value_type window_endx(window_br[0]);
218         const synfig::Vector::value_type window_starty(window_tl[1]);
219         const synfig::Vector::value_type window_endy(window_br[1]);
220         */
221         // const int
222         //      tile_w(get_work_area()->get_tile_w()),
223         //      tile_h(get_work_area()->get_tile_h());
224
225         // const int
226         //      w(get_w()),
227         //      h(get_h());
228
229         Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
230
231         //const synfig::Vector grid_size(get_grid_size());
232
233         const synfig::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
234         // const synfig::Vector::value_type window_endx(get_work_area()->get_window_br()[0]);
235         const synfig::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
236         // const synfig::Vector::value_type window_endy(get_work_area()->get_window_br()[1]);
237         const float pw(get_pw()),ph(get_ph());
238
239         // Draw out the guides
240         {
241                 gc->set_function(Gdk::COPY);
242                 gc->set_rgb_fg_color(Gdk::Color("#9f9fff"));
243                 gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
244
245                 Duckmatic::GuideList::const_iterator iter;
246
247                 // vertical
248                 for(iter=get_guide_list_x().begin();iter!=get_guide_list_x().end();++iter)
249                 {
250                         const float x((*iter-window_startx)/pw);
251
252                         if(iter==get_work_area()->curr_guide)
253                                 gc->set_rgb_fg_color(Gdk::Color("#ff6f6f"));
254                         else
255                                 gc->set_rgb_fg_color(Gdk::Color("#6f6fff"));
256
257                         drawable->draw_line(gc,
258                                 round_to_int(x),
259                                 0,
260                                 round_to_int(x),
261                                 drawable_h
262                         );
263                 }
264                 // horizontal
265                 for(iter=get_guide_list_y().begin();iter!=get_guide_list_y().end();++iter)
266                 {
267                         const float y((*iter-window_starty)/ph);
268
269                         if(iter==get_work_area()->curr_guide)
270                                 gc->set_rgb_fg_color(Gdk::Color("#ff6f6f"));
271                         else
272                                 gc->set_rgb_fg_color(Gdk::Color("#6f6fff"));
273
274                         drawable->draw_line(gc,
275                                 0,
276                                 round_to_int(y),
277                                 drawable_w,
278                                 round_to_int(y)
279                         );
280                 }
281         }
282 }