Apply 1659126: fix Win32 icon generation with png2ico. Patch by Dmitriy Pomerantsev...
[synfig.git] / synfig-studio / trunk / src / gtkmm / workarea.cpp
index 5e0eef3..e22108a 100644 (file)
@@ -5,16 +5,18 @@
 **     $Id: workarea.cpp,v 1.3 2005/01/16 19:55:57 darco Exp $
 **
 **     \legal
-**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright 2006 Yue Shi Lai
 **
-**     This software and associated documentation
-**     are CONFIDENTIAL and PROPRIETARY property of
-**     the above-mentioned copyright holder.
+**     This package is free software; you can redistribute it and/or
+**     modify it under the terms of the GNU General Public License as
+**     published by the Free Software Foundation; either version 2 of
+**     the License, or (at your option) any later version.
 **
-**     You may not copy, print, publish, or in any
-**     other way distribute this software without
-**     a prior written agreement with
-**     the copyright holder.
+**     This package is distributed in the hope that it will be useful,
+**     but WITHOUT ANY WARRANTY; without even the implied warranty of
+**     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+**     General Public License for more details.
 **     \endlegal
 */
 /* ========================================================================= */
@@ -91,7 +93,7 @@ using namespace studio;
 
 /* === C L A S S E S ======================================================= */
 
-class WorkAreaTarget : public synfig::Target_Tile
+class studio::WorkAreaTarget : public synfig::Target_Tile
 {
 public:
        WorkArea *workarea;
@@ -380,7 +382,7 @@ public:
 };
 
 
-class WorkAreaTarget_Full : public synfig::Target_Scanline
+class studio::WorkAreaTarget_Full : public synfig::Target_Scanline
 {
 public:
        WorkArea *workarea;
@@ -624,6 +626,9 @@ WorkArea::WorkArea(etl::loose_handle<synfigapp::CanvasInterface> canvas_interfac
        canvas(canvas_interface->get_canvas()),
        scrollx_adjustment(0,-4,4,0.01,0.1),
        scrolly_adjustment(0,-4,4,0.01,0.1),
+       w(128),
+       h(128),
+       last_event_time(0),
        progresscallback(0),
        dragging(DRAG_NONE),
        show_grid(false),
@@ -1238,7 +1243,17 @@ WorkArea::on_drawing_area_event(GdkEvent *event)
                        //      button_pressed=0;                               
                }
        }
+       // GDK mouse scrolling events
+       else if(event->any.type==GDK_SCROLL)
+       {
+               // GDK information needed to properly interprete mouse
+               // scrolling events are: scroll.state, scroll.x/scroll.y, and
+               // scroll.direction. The value of scroll.direction will be
+               // obtained later.
 
+               modifier=Gdk::ModifierType(event->scroll.state);
+               mouse_pos=synfig::Point(screen_to_comp_coords(synfig::Point(event->scroll.x,event->scroll.y)));
+       }
 
        // Handle the renderables
        {
@@ -1640,6 +1655,97 @@ WorkArea::on_drawing_area_event(GdkEvent *event)
                return ret;
        }
                break;
+       case GDK_SCROLL:
+       {
+               // Handle a mouse scrolling event like Xara Xtreme and
+               // Inkscape:
+
+               // Scroll up/down: scroll up/down
+               // Shift + scroll up/down: scroll left/right
+               // Control + scroll up/down: zoom in/out
+
+               if(modifier&GDK_CONTROL_MASK)
+               {
+                       
+                       // The zoom is performed while preserving the pointer
+                       // position as a fixed point (similarly to Xara Xtreme and
+                       // Inkscape).
+
+                       // The strategy used below is to scroll to the updated
+                       // position, then zoom. This is easy to implement within
+                       // the present architecture, but has the disadvantage of
+                       // triggering multiple visible refreshes. Note: 1.25 is
+                       // the hard wired ratio in zoom_in()/zoom_out(). The
+                       // variable "drift" compensates additional inaccuracies in
+                       // the zoom. There is also an additional minus sign for
+                       // the inverted y coordinates.
+
+                       // FIXME: One might want to figure out where in the code
+                       // this empirical drift is been introduced.
+
+                       const synfig::Point scroll_point(get_scrollx_adjustment()->get_value(),get_scrolly_adjustment()->get_value());
+                       const double drift = 0.052;
+
+                       switch(event->scroll.direction)
+                       {
+                               case GDK_SCROLL_UP:
+                                       get_scrollx_adjustment()->set_value(scroll_point[0]+(mouse_pos[0]-scroll_point[0])*(1.25-(1+drift)));
+                                       get_scrolly_adjustment()->set_value(scroll_point[1]-(mouse_pos[1]+scroll_point[1])*(1.25-(1+drift)));
+                                       zoom_in();
+                                       break;
+                               case GDK_SCROLL_DOWN:
+                                       get_scrollx_adjustment()->set_value(scroll_point[0]+(mouse_pos[0]-scroll_point[0])*(1/1.25-(1+drift)));
+                                       get_scrolly_adjustment()->set_value(scroll_point[1]-(mouse_pos[1]+scroll_point[1])*(1/1.25-(1+drift)));
+                                       zoom_out();
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               else if(modifier&GDK_SHIFT_MASK)
+               {
+                       // Scroll in either direction by 20 pixels. Ideally, the
+                       // amount of pixels per scrolling event should be
+                       // configurable. Xara Xtreme currently uses an (hard
+                       // wired) amount 20 pixel, Inkscape defaults to 40 pixels.
+
+                       const int scroll_pixel = 20;
+
+                       switch(event->scroll.direction)
+                       {
+                               case GDK_SCROLL_UP:
+                                       get_scrollx_adjustment()->set_value(get_scrollx_adjustment()->get_value()-scroll_pixel*pw);
+                                       break;
+                               case GDK_SCROLL_DOWN:
+                                       get_scrollx_adjustment()->set_value(get_scrollx_adjustment()->get_value()+scroll_pixel*pw);
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+               else
+               {       
+                       // Scroll in either direction by 20 pixels. Ideally, the
+                       // amount of pixels per scrolling event should be
+                       // configurable. Xara Xtreme currently uses an (hard
+                       // wired) amount 20 pixel, Inkscape defaults to 40 pixels.
+
+                       const int scroll_pixel = 20;
+
+                       switch(event->scroll.direction)
+                       {
+                               case GDK_SCROLL_UP:
+                                       get_scrolly_adjustment()->set_value(get_scrolly_adjustment()->get_value()+scroll_pixel*ph);
+                                       break;
+                               case GDK_SCROLL_DOWN:
+                                       get_scrolly_adjustment()->set_value(get_scrolly_adjustment()->get_value()-scroll_pixel*ph);
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       }
+               break;
        default:
                break;
        }