Allow linking widths and tangents to positions on a bline. It also now works with...
[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 #include "general.h"
37
38 #endif
39
40 /* === U S I N G =========================================================== */
41
42 using namespace std;
43 using namespace etl;
44 using namespace synfig;
45 using namespace studio;
46
47 /* === M A C R O S ========================================================= */
48
49 /* === G L O B A L S ======================================================= */
50
51 /* === P R O C E D U R E S ================================================= */
52
53 /* === M E T H O D S ======================================================= */
54
55 Renderer_Guides::Renderer_Guides():
56         dragging(false)
57 {
58
59 }
60
61 Renderer_Guides::~Renderer_Guides()
62 {
63 }
64
65 bool
66 Renderer_Guides::get_enabled_vfunc()const
67 {
68         return get_work_area()->get_show_guides();
69 }
70
71 std::list<float>&
72 Renderer_Guides::get_guide_list_x()
73 {
74         return get_work_area()->get_guide_list_x();
75 }
76
77 std::list<float>&
78 Renderer_Guides::get_guide_list_y()
79 {
80         return get_work_area()->get_guide_list_y();
81 }
82
83 bool
84 Renderer_Guides::event_vfunc(GdkEvent* event)
85 {
86         synfig::Point mouse_pos;
87         // float bezier_click_pos;
88         // const float radius((abs(get_pw())+abs(get_ph()))*4);
89         int button_pressed(0);
90         float pressure(0);
91         bool is_mouse(false);
92         Gdk::ModifierType modifier(Gdk::ModifierType(0));
93
94         // Handle input stuff
95         if(
96                 event->any.type==GDK_MOTION_NOTIFY ||
97                 event->any.type==GDK_BUTTON_PRESS ||
98                 event->any.type==GDK_2BUTTON_PRESS ||
99                 event->any.type==GDK_3BUTTON_PRESS ||
100                 event->any.type==GDK_BUTTON_RELEASE
101         )
102         {
103                 GdkDevice *device;
104                 if(event->any.type==GDK_MOTION_NOTIFY)
105                 {
106                         device=event->motion.device;
107                         modifier=Gdk::ModifierType(event->motion.state);
108                 }
109                 else
110                 {
111                         device=event->button.device;
112                         modifier=Gdk::ModifierType(event->button.state);
113                 }
114
115                 // Make sure we recognize the device
116                 /*if(curr_input_device)
117                 {
118                         if(curr_input_device!=device)
119                         {
120                                 assert(device);
121                                 curr_input_device=device;
122                                 signal_input_device_changed()(curr_input_device);
123                         }
124                 }
125                 else*/ if(device)
126                 {
127                         //curr_input_device=device;
128                         //signal_input_device_changed()(curr_input_device);
129                 }
130
131                 //assert(curr_input_device);
132
133                 // Calculate the position of the
134                 // input device in canvas coordinates
135                 // and the buttons
136                 if(!event->button.axes)
137                 {
138                         mouse_pos=synfig::Point(screen_to_comp_coords(synfig::Point(event->button.x,event->button.y)));
139                         button_pressed=event->button.button;
140                         pressure=1.0f;
141                         is_mouse=true;
142                         if(isnan(event->button.x) || isnan(event->button.y))
143                                 return false;
144                 }
145                 else
146                 {
147                         double x(event->button.axes[0]);
148                         double y(event->button.axes[1]);
149                         if(isnan(x) || isnan(y))
150                                 return false;
151
152                         pressure=event->button.axes[2];
153                         //synfig::info("pressure=%f",pressure);
154                         pressure-=0.04f;
155                         pressure/=1.0f-0.04f;
156
157
158                         assert(!isnan(pressure));
159
160                         mouse_pos=synfig::Point(screen_to_comp_coords(synfig::Point(x,y)));
161
162                         button_pressed=event->button.button;
163
164                         if(button_pressed==1 && pressure<0 && (event->any.type!=GDK_BUTTON_RELEASE && event->any.type!=GDK_BUTTON_PRESS))
165                                 button_pressed=0;
166                         if(pressure<0)
167                                 pressure=0;
168
169                         //if(event->any.type==GDK_BUTTON_PRESS && button_pressed)
170                         //      synfig::info("Button pressed on input device = %d",event->button.button);
171
172                         //if(event->button.axes[2]>0.1)
173                         //      button_pressed=1;
174                         //else
175                         //      button_pressed=0;
176                 }
177         }
178         switch(event->type)
179     {
180         case GDK_BUTTON_PRESS:
181                 break;
182         case GDK_MOTION_NOTIFY:
183                 break;
184         case GDK_BUTTON_RELEASE:
185                 break;
186         default:
187                 break;
188         }
189
190         return false;
191 }
192
193 void
194 Renderer_Guides::render_vfunc(
195         const Glib::RefPtr<Gdk::Drawable>& drawable,
196         const Gdk::Rectangle& /*expose_area*/
197 )
198 {
199         assert(get_work_area());
200         if(!get_work_area())
201                 return;
202
203         // const synfig::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
204
205         const synfig::Vector focus_point(get_work_area()->get_focus_point());
206
207         //std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
208
209         int drawable_w,drawable_h;
210         drawable->get_size(drawable_w,drawable_h);
211
212         // Calculate the window coordinates of the top-left
213         // corner of the canvas.
214         // const synfig::Vector::value_type
215         //      x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
216         //      y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
217
218         /*const synfig::Vector::value_type window_startx(window_tl[0]);
219         const synfig::Vector::value_type window_endx(window_br[0]);
220         const synfig::Vector::value_type window_starty(window_tl[1]);
221         const synfig::Vector::value_type window_endy(window_br[1]);
222         */
223         // const int
224         //      tile_w(get_work_area()->get_tile_w()),
225         //      tile_h(get_work_area()->get_tile_h());
226
227         // const int
228         //      w(get_w()),
229         //      h(get_h());
230
231         Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
232
233         //const synfig::Vector grid_size(get_grid_size());
234
235         const synfig::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
236         // const synfig::Vector::value_type window_endx(get_work_area()->get_window_br()[0]);
237         const synfig::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
238         // const synfig::Vector::value_type window_endy(get_work_area()->get_window_br()[1]);
239         const float pw(get_pw()),ph(get_ph());
240
241         // Draw out the guides
242         {
243                 gc->set_function(Gdk::COPY);
244                 gc->set_rgb_fg_color(Gdk::Color("#9f9fff"));
245                 gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
246
247                 Duckmatic::GuideList::const_iterator iter;
248
249                 // vertical
250                 for(iter=get_guide_list_x().begin();iter!=get_guide_list_x().end();++iter)
251                 {
252                         const float x((*iter-window_startx)/pw);
253
254                         if(iter==get_work_area()->curr_guide)
255                                 gc->set_rgb_fg_color(Gdk::Color("#ff6f6f"));
256                         else
257                                 gc->set_rgb_fg_color(Gdk::Color("#6f6fff"));
258
259                         drawable->draw_line(gc,
260                                 round_to_int(x),
261                                 0,
262                                 round_to_int(x),
263                                 drawable_h
264                         );
265                 }
266                 // horizontal
267                 for(iter=get_guide_list_y().begin();iter!=get_guide_list_y().end();++iter)
268                 {
269                         const float y((*iter-window_starty)/ph);
270
271                         if(iter==get_work_area()->curr_guide)
272                                 gc->set_rgb_fg_color(Gdk::Color("#ff6f6f"));
273                         else
274                                 gc->set_rgb_fg_color(Gdk::Color("#6f6fff"));
275
276                         drawable->draw_line(gc,
277                                 0,
278                                 round_to_int(y),
279                                 drawable_w,
280                                 round_to_int(y)
281                         );
282                 }
283         }
284 }