View2D - Initial commit of Pan-View Operator
authorJoshua Leung <aligorith@gmail.com>
Sun, 30 Nov 2008 06:15:33 +0000 (06:15 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 30 Nov 2008 06:15:33 +0000 (06:15 +0000)
* Moved View2D data from space-data to ARegion (aka regions). This has been done because drawing occurs in regions not areas anymore. The View2D struct is currently stored in the ARegion struct (not as pointer), given that most of the regions in use will be 2D anyway (only the 3d-view's "window" region is the exception).
Added version patch code for outliner and timeline only for now. Headers are also likely to need this.

* Added separate keymap for View2D operators. All regions that use View2D will need this added. This includes headers too.

* Pan view operator (ED_View2D_OT_view_pan), currently works for Outliner and Timeline. Use MMB-drag as before.
- It currently doesn't exposed any parameters for redo (via RNA-ID-Props), but only uses some customdata. Suggestions on what these parameters could be are welcomed.
- I've yet to implement the necessary axis-locking features for this panning (which is required in Timeline for example to prevent vertical panning, which moves the markers out of view).

16 files changed:
SConstruct
projectfiles_vc9/blender/editors/ED_editors.vcproj
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/UI_view2d.h
source/blender/editors/interface/view2d.c
source/blender/editors/interface/view2d_ops.c [new file with mode: 0644]
source/blender/editors/screen/screen_ops.c
source/blender/editors/screen/spacetypes.c
source/blender/editors/space_outliner/space_outliner.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_time/time_ops.c
source/blender/makesdna/DNA_screen_types.h
source/blender/makesdna/DNA_view2d_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/nodes/intern/CMP_util.h
source/blender/nodes/intern/SHD_util.h

index 59152cdc9f3a5fd8d67bc6aca797c702ebd65067..0bc05a59df22f0a8cf348450cc397ccc2e38977e 100644 (file)
@@ -115,8 +115,8 @@ if toolset:
                env.Tool('mstoolkit', ['tools'])
        else:
                env = BlenderEnvironment(tools=[toolset], ENV = os.environ)
-               if env:
-                       btools.SetupSpawn(env)
+               #if env:
+               #       btools.SetupSpawn(env)
 else:
        env = BlenderEnvironment(ENV = os.environ)
 
index 426add657ab94d6c951711342d5d30e23fdcfca6..1e76a41ec8283d805978af6b90c3a8e5b98c0905 100644 (file)
                                RelativePath="..\..\..\source\blender\editors\interface\view2d.c"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\blender\editors\interface\view2d_ops.c"\r
+                               >\r
+                       </File>\r
                </Filter>\r
                <Filter\r
                        Name="space_view3d"\r
index 3fd0812338c4e58ebc8931ec875772f796614cc2..a4038f29c3b0fb345f663b61b96a1645f8bcffe9 100644 (file)
@@ -3787,6 +3787,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
        wm->operators.first= wm->operators.last= NULL;
        wm->windowkeymap.first= wm->windowkeymap.last= NULL;
        wm->screenkeymap.first= wm->screenkeymap.last= NULL;
+       wm->view2dkeymap.first= wm->view2dkeymap.last= NULL;
        wm->uikeymap.first= wm->uikeymap.last= NULL;
        wm->timekeymap.first= wm->timekeymap.last= NULL;
        
@@ -5061,12 +5062,24 @@ static void do_versions_windowmanager_2_50(bScreen *screen)
                                ar->alignment= RGN_ALIGN_BOTTOM;
                        else
                                ar->alignment= RGN_ALIGN_TOP;
+                       // TODO: add conversion stuff for header scrolling to v2d of header region
                }
                
                ar= MEM_callocN(sizeof(ARegion), "area region from do_versions");
                BLI_addtail(&sa->regionbase, ar);
                ar->winrct= sa->totrct;
                ar->regiontype= RGN_TYPE_WINDOW;
+               
+               /* if active spacetype has view2d data, copy that over to main region */
+               switch(sa->spacetype) {
+                       case SPACE_OOPS:
+                               memcpy(&ar->v2d, &((SpaceOops *)sa->spacedata.first)->v2d, sizeof(View2D));
+                               break;
+                       case SPACE_TIME:
+                               memcpy(&ar->v2d, &((SpaceTime *)sa->spacedata.first)->v2d, sizeof(View2D));
+                               break;
+                       //case SPACE_XXX: // FIXME... add other ones
+               }
        }
 }
 
index 1a37463aaab0e89236ca8848bb4b234bdd07fc5f..1929e29bb4acc7783d3050ffb44c619c007c1877 100644 (file)
 /* ------------------------------------------ */
 /* Settings:                                                           */
 
+/* generic value to use when coordinate lies out of view when converting */
+#define V2D_IS_CLIPPED 12000
+
+/* ---  Grids --- */
 /* grid-units (for drawing time) */
 #define V2D_UNIT_SECONDS       0
 #define V2D_UNIT_FRAMES                1
 #define V2D_GRID_CLAMP         0
 #define V2D_GRID_NOCLAMP       1
 
-/* generic value to use when coordinate lies out of view when converting */
-#define V2D_IS_CLIPPED 12000
-
 /* flags for grid-lines to draw */
 #define V2D_HORIZONTAL_LINES   (1<<0)
 #define V2D_VERTICAL_LINES             (1<<1)
 #define V2D_HORIZONTAL_AXIS            (1<<2)
 #define V2D_VERTICAL_AXIS              (1<<3)
 
+/* --- Scrollers --- */
+
 /* ------------------------------------------ */
 /* Macros:                                                             */
 
-/* test if mouse in scrollbar */
-// XXX do we want more elegant method?
+/* test if mouse in a scrollbar */
 #define IN_2D_VERT_SCROLL(v2d, co) (BLI_in_rcti(&v2d->vert, co[0], co[1]))
 #define IN_2D_HORIZ_SCROLL(v2d, co) (BLI_in_rcti(&v2d->hor, co[0], co[1]))
 
 
 struct View2D;
 struct View2DGrid;
+struct View2DScrollers;
+
+struct wmWindowManager;
 struct bContext;
 
 typedef struct View2DGrid View2DGrid;
+typedef struct View2DScrollers View2DScrollers;
 
 /* ----------------------------------------- */
 /* Prototypes:                                             */
@@ -75,6 +81,7 @@ typedef struct View2DGrid View2DGrid;
 /* setup */
 void UI_view2d_ortho(const struct bContext *C, struct View2D *v2d);
 void UI_view2d_update_size(struct View2D *v2d, int winx, int winy);
+void UI_view2d_enforce_status(struct View2D *v2d, int winx, int winy);
 
 /* grid drawing */
 View2DGrid *UI_view2d_calc_grid(const struct bContext *C, struct View2D *v2d, short unit, short type, int winx, int winy);
@@ -83,6 +90,8 @@ void UI_view2d_free_grid(View2DGrid *grid);
 
 /* scrollbar drawing */
 
+void UI_view2d_draw_scrollers(const struct bContext *C, struct View2D *v2d, View2DScrollers *scrollers, int flag);
+void UI_view2d_free_scrollbars(View2DScrollers *scrollers);
 
 /* coordinate conversion */
 void UI_view2d_region_to_view(struct View2D *v2d, short x, short y, float *viewx, float *viewy);
@@ -90,8 +99,12 @@ void UI_view2d_view_to_region(struct View2D *v2d, float x, float y, short *regio
 void UI_view2d_to_region_no_clip(struct View2D *v2d, float x, float y, short *regionx, short *region_y);
 
 /* utilities */
-void UI_view2d_getscale(View2D *v2d, float *x, float *y);
+void UI_view2d_getscale(struct View2D *v2d, float *x, float *y);
+
 
+/* operators */
+void ui_view2d_operatortypes(void);
+void UI_view2d_keymap(struct wmWindowManager *wm);
 
 #endif /* UI_VIEW2D_H */
 
index 6d86f6dcb1a3c21f66381d996d746307e013dc53..a2fc8186664057675e4f1ae404d7c0a27363d1e2 100644 (file)
@@ -35,6 +35,7 @@
 #include "DNA_view2d_types.h"
 
 #include "BKE_global.h"
+#include "BKE_utildefines.h"
 
 #include "WM_api.h"
 
@@ -47,6 +48,7 @@
 /* Setup and Refresh Code */
 
 /* Set view matrices to ortho for View2D drawing */
+// XXX in past, this was not always the case!
 void UI_view2d_ortho(const bContext *C, View2D *v2d)
 {
        wmOrtho2(C->window, v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax);
@@ -61,9 +63,10 @@ void UI_view2d_update_size(View2D *v2d, int winx, int winy)
        v2d->mask.xmax= winx;
        v2d->mask.ymax= winy;
        
-       /* scrollbars shrink mask area, but should be based off regionsize */
-       // XXX scrollbars should become limited to one bottom lower edges of region like everyone else does!
-       if(v2d->scroll) {
+       /* scrollbars shrink mask area, but should be based off regionsize 
+        *      - they can only be on one edge of the region they define
+        */
+       if (v2d->scroll) {
                /* vertical scrollbar */
                if (v2d->scroll & L_SCROLL) {
                        /* on left-hand edge of region */
@@ -71,7 +74,7 @@ void UI_view2d_update_size(View2D *v2d, int winx, int winy)
                        v2d->vert.xmax= SCROLLB;
                        v2d->mask.xmin= SCROLLB;
                }
-               else if(v2d->scroll & R_SCROLL) {
+               else if (v2d->scroll & R_SCROLL) {
                        /* on right-hand edge of region */
                        v2d->vert= v2d->mask;
                        v2d->vert.xmin= v2d->vert.xmax-SCROLLB;
@@ -85,7 +88,7 @@ void UI_view2d_update_size(View2D *v2d, int winx, int winy)
                        v2d->hor.ymax= SCROLLH;
                        v2d->mask.ymin= SCROLLH;
                }
-               else if(v2d->scroll & T_SCROLL) {
+               else if (v2d->scroll & T_SCROLL) {
                        /* on upper edge of region */
                        v2d->hor= v2d->mask;
                        v2d->hor.ymin= v2d->hor.ymax-SCROLLH;
@@ -94,6 +97,238 @@ void UI_view2d_update_size(View2D *v2d, int winx, int winy)
        }
 }
 
+/* Ensure View2D rects remain in a viable configuration 
+ *     - cur is not allowed to be: larger than max, smaller than min, or outside of tot
+ */
+// XXX pre2.5 -> this used to be called  test_view2d()
+// XXX FIXME - still need to go through this and figure out what it all parts of it do
+void UI_view2d_enforce_status(View2D *v2d, int winx, int winy)
+{
+       /* cur is not allowed to be larger than max, smaller than min, or outside of tot */
+       rctf *cur, *tot;
+       float dx, dy, temp, fac, zoom;
+       
+       /* correct winx for scrollbars */
+       if (v2d->scroll & L_SCROLL) winx-= SCROLLB;
+       if (v2d->scroll & B_SCROLL) winy-= SCROLLH;
+       if (v2d->scroll & B_SCROLLO) winy-= SCROLLH; /* B_SCROLL and B_SCROLLO are basically same thing */
+       
+       /* header completely closed window */
+       if (winy <= 0) return;
+       
+       /* get pointers */
+       cur= &v2d->cur;
+       tot= &v2d->tot;
+       
+       /* dx, dy are width and height of v2d->cur, respectively */
+       dx= cur->xmax - cur->xmin;
+       dy= cur->ymax - cur->ymin;
+       
+       /* keepzoom - restore old zoom */
+       if (v2d->keepzoom) {    
+               /* keepzoom on x or y axis - reset size of current-viewable area to size of region (i.e. no zooming happened) */
+               if (v2d->keepzoom & V2D_LOCKZOOM_Y)
+                       cur->ymax= cur->ymin + ((float)winy);
+               if (v2d->keepzoom & V2D_LOCKZOOM_X)
+                       cur->xmax= cur->xmin + ((float)winx);
+               
+               /* calculate zoom-factor for x */
+               zoom= ((float)winx)/dx;
+               
+               /* if zoom factor is excessive, normalise it and calculate new width */
+               if ((zoom < v2d->minzoom) || (zoom > v2d->maxzoom)) {
+                       if (zoom < v2d->minzoom) fac= zoom / v2d->minzoom;
+                       else fac= zoom / v2d->maxzoom;
+                       
+                       dx *= fac;
+                       temp= 0.5f * (cur->xmax + cur->xmin);
+                       
+                       cur->xmin= temp - (0.5f * dx);
+                       cur->xmax= temp + (0.5f * dx);
+               }
+               
+               /* calculate zoom-factor for y */
+               zoom= ((float)winy)/dy;
+               
+               /* if zoom factor is excessive, normalise it and calculate new width */
+               if ((zoom < v2d->minzoom) || (zoom > v2d->maxzoom)) {
+                       if (zoom < v2d->minzoom) fac= zoom / v2d->minzoom;
+                       else fac= zoom / v2d->maxzoom;
+                       
+                       dy *= fac;
+                       temp= 0.5f * (cur->ymax + cur->ymin);
+                       
+                       cur->ymin= temp - (0.5f * dy);
+                       cur->ymax= temp + (0.5f * dy);
+               }
+       }
+       else {
+               /* if extents of cur are below or above what's acceptable, interpolate extent to lie halfway */
+               if (dx < v2d->min[0]) {
+                       dx= v2d->min[0];
+                       temp= 0.5f * (cur->xmax + cur->xmin);
+                       
+                       cur->xmin= temp - (0.5f * dx);
+                       cur->xmax= temp + (0.5f * dx);
+               }
+               else if (dx > v2d->max[0]) {
+                       dx= v2d->max[0];
+                       temp= 0.5f * (cur->xmax + cur->xmin);
+                       
+                       cur->xmin= temp - (0.5f * dx);
+                       cur->xmax= temp + (0.5f * dx);
+               }
+               
+               if (dy < v2d->min[1]) {
+                       dy= v2d->min[1];
+                       temp= 0.5f * (cur->ymax + cur->ymin);
+                       
+                       cur->ymin= temp - (0.5f * dy);
+                       cur->ymax= temp + (0.5f * dy);
+               }
+               else if (dy > v2d->max[1]) {
+                       dy= v2d->max[1];
+                       temp= 0.5f * (cur->ymax + cur->ymin);
+                       cur->ymin= temp-0.5*dy;
+                       cur->ymax= temp+0.5*dy;
+               }
+       }
+       
+       /* keep aspect - maintain aspect ratio */
+       if (v2d->keepaspect) {
+               short do_x=0, do_y=0;
+               
+               /* when a window edge changes, the aspect ratio can't be used to
+                * find which is the best new 'cur' rect. thats why it stores 'old' 
+                */
+               if (winx != v2d->oldwinx) do_x= 1;
+               if (winy != v2d->oldwiny) do_y= 1;
+               
+               /* here dx is cur ratio, while dy is win ratio */
+               dx= (cur->ymax - cur->ymin) / (cur->xmax - cur->xmin);
+               dy= ((float)winy) / ((float)winx);
+               
+               /* both sizes change (area/region maximised)  */
+               if (do_x == do_y) {
+                       if ((do_x==1) && (do_y==1)) {
+                               if (ABS(winx - v2d->oldwinx) > ABS(winy - v2d->oldwiny)) do_y= 0;
+                               else do_x= 0;
+                       }
+                       else if (dy > 1.0f) do_x= 0; 
+                       else do_x= 1;
+               }
+               
+               if (do_x) {
+                       if ((v2d->keeptot == 2) && (winx < v2d->oldwinx)) {
+                               /* This is a special hack for the outliner, to ensure that the 
+                                * outliner contents will not eventually get pushed out of view
+                                * when shrinking the view. 
+                                */
+                               cur->xmax -= cur->xmin;
+                               cur->xmin= 0.0f;
+                       }
+                       else {
+                               /* portrait window: correct for x */
+                               dx= cur->ymax - cur->ymin;
+                               temp= cur->xmax + cur->xmin;
+                               
+                               cur->xmin= (temp / 2.0f) - (0.5f * dx / dy);
+                               cur->xmax= (temp / 2.0f) + (0.5f * dx / dy);
+                       }
+               }
+               else {
+                       dx= cur->xmax - cur->xmin;
+                       temp= cur->ymax + cur->ymin;
+                       
+                       cur->ymin= (temp / 2.0f) - (0.5f * dy * dx);
+                       cur->ymax= (temp / 2.0f) + (0.5f * dy * dx);
+               }
+               
+               /* store region size for next time */
+               v2d->oldwinx= winx; 
+               v2d->oldwiny= winy;
+       }
+       
+       /* keeptot - make sure that size of cur doesn't exceed that of tot, otherwise, adjust! */
+       if (v2d->keeptot) {
+               /* calculate extents of cur */
+               dx= cur->xmax - cur->xmin;
+               dy= cur->ymax - cur->ymin;
+               
+               /* cur is wider than tot? */
+               if (dx > (tot->xmax - tot->xmin)) {
+                       if (v2d->keepzoom == 0) {
+                               if (cur->xmin < tot->xmin) cur->xmin= tot->xmin;
+                               if (cur->xmax > tot->xmax) cur->xmax= tot->xmax;
+                       }
+                       else {
+                               /* maintaining zoom, so restore cur to tot size */
+                               if (cur->xmax < tot->xmax) {
+                                       dx= tot->xmax - cur->xmax;
+                                       
+                                       cur->xmin+= dx;
+                                       cur->xmax+= dx;
+                               }
+                               else if (cur->xmin > tot->xmin) {
+                                       dx= cur->xmin - tot->xmin;
+                                       
+                                       cur->xmin-= dx;
+                                       cur->xmax-= dx;
+                               }
+                       }
+               }
+               else {
+                       /* cur is smaller than tot, but cur cannot be outside of tot */
+                       if (cur->xmin < tot->xmin) {
+                               dx= tot->xmin - cur->xmin;
+                               
+                               cur->xmin += dx;
+                               cur->xmax += dx;
+                       }
+                       else if ((v2d->keeptot != 2) && (cur->xmax > tot->xmax)) {
+                               /* NOTE: keeptot is 2, as keeptot!=0 makes sure it does get
+                                *              too freely scrolled on x-axis, but keeptot=1 will result
+                                *              in a snap-back when clicking on elements
+                                */
+                               dx= cur->xmax - tot->xmax;
+                               cur->xmin -= dx;
+                               cur->xmax -= dx;
+                       }
+               }
+               
+               if (dy > (tot->ymax - tot->ymin)) {
+                       if (v2d->keepzoom==0) {
+                               if (cur->ymin < tot->ymin) cur->ymin= tot->ymin;
+                               if (cur->ymax > tot->ymax) cur->ymax= tot->ymax;
+                       }
+                       else {
+                               if (cur->ymax < tot->ymax) {
+                                       dy= tot->ymax - cur->ymax;
+                                       cur->ymin+= dy;
+                                       cur->ymax+= dy;
+                               }
+                               else if (cur->ymin > tot->ymin) {
+                                       dy= cur->ymin - tot->ymin;
+                                       cur->ymin -= dy;
+                                       cur->ymax -= dy;
+                               }
+                       }
+               }
+               else {
+                       if (cur->ymin < tot->ymin) {
+                               dy= tot->ymin - cur->ymin;
+                               cur->ymin += dy;
+                               cur->ymax += dy;
+                       }
+                       else if (cur->ymax > tot->ymax) {
+                               dy= cur->ymax - tot->ymax;
+                               cur->ymin-= dy;
+                               cur->ymax-= dy;
+                       }
+               }
+       }
+}
+
 /* *********************************************************************** */
 /* Gridlines */
 
@@ -310,6 +545,11 @@ void UI_view2d_free_grid(View2DGrid *grid)
        MEM_freeN(grid);
 }
 
+/* *********************************************************************** */
+/* Scrollbars */
+
+
+
 /* *********************************************************************** */
 /* Coordinate Conversions */
 
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
new file mode 100644 (file)
index 0000000..f036563
--- /dev/null
@@ -0,0 +1,257 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program 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. 
+ *
+ * This program 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ * 
+ * Contributor(s): Blender Foundation, Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_view2d_types.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BIF_gl.h"
+
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+/* ********************************************************* */
+
+/* ********************************************************* */
+/* View Panning Operator */
+
+/* 
+operator state vars:  
+       (currently none) // XXX must figure out some vars to expose to user! 
+
+operator customdata:
+       area                    pointer to (active) area
+       x, y                            last used mouse pos
+       (more, see below)
+
+functions:
+
+       init()   set default property values, find v2d based on context
+
+       apply() split area based on state vars
+
+       exit()  cleanup, send notifier
+
+       cancel() remove duplicated area
+
+callbacks:
+
+       exec()   execute without any user interaction, based on state vars
+            call init(), apply(), exit()
+
+       invoke() gets called on mouse click in action-widget
+            call init(), add modal handler
+                       call apply() with initial motion
+
+       modal()  accept modal events while doing it
+            call move-areas code with delta motion
+            call exit() or cancel() and remove handler
+
+*/
+
+typedef struct v2dViewPanData {
+       ARegion *region;                /* region we're operating in */
+       View2D *v2d;                    /* view2d we're operating in */
+       
+       float facx, facy;               /* amount to move view relative to zoom */
+       
+               /* mouse stuff... */
+       int lastx, lasty;               /* previous x/y values of mouse in area */
+       int x, y;                               /* current x/y values of mosue in area */
+} v2dViewPanData;
+
+
+static int pan_view_init(bContext *C, wmOperator *op)
+{
+       v2dViewPanData *vpd;
+       ARegion *ar;
+       View2D *v2d;
+       float winx, winy;
+       
+       /* regions now have v2d-data by default, so check for region */
+       if (C->region == NULL)
+               return 0;
+       
+       /* set custom-data for operator */
+       vpd= MEM_callocN(sizeof(v2dViewPanData), "v2dViewPanData");
+       op->customdata= vpd;
+       
+       /* set pointers to owners */
+       vpd->region= ar= C->region;
+       vpd->v2d= v2d= &C->region->v2d;
+       
+       /* calculate translation factor - based on size of view */
+       winx= (float)(ar->winrct.xmax - ar->winrct.xmin);
+       winy= (float)(ar->winrct.ymax - ar->winrct.ymin);
+       vpd->facx= (v2d->cur.xmax - v2d->cur.xmin) / winx;
+       vpd->facy= (v2d->cur.ymax - v2d->cur.ymin) / winy;
+               
+       return 1;
+}
+
+static void pan_view_apply(bContext *C, wmOperator *op)
+{
+       v2dViewPanData *vpd= op->customdata;
+       View2D *v2d= vpd->v2d;
+       float dx, dy;
+       
+       /* calculate amount to move view by */
+       dx= vpd->facx * (vpd->lastx - vpd->x);
+       dy= vpd->facy * (vpd->lasty - vpd->y);
+       
+       /* only move view on an axis if change is allowed */
+       if ((v2d->keepofs & V2D_LOCKOFS_X)==0) {
+               v2d->cur.xmin += dx;
+               v2d->cur.xmax += dx;
+       }
+       if ((v2d->keepofs & V2D_LOCKOFS_Y)==0) {
+               v2d->cur.ymin += dy;
+               v2d->cur.ymax += dy;
+       }
+       
+       vpd->lastx= vpd->x;
+       vpd->lasty= vpd->y;
+
+       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+       /* XXX: add WM_NOTE_TIME_CHANGED? */
+}
+
+static void pan_view_exit(bContext *C, wmOperator *op)
+{
+       if (op->customdata) {
+               MEM_freeN(op->customdata);
+               op->customdata= NULL;
+               WM_event_remove_modal_handler(&C->window->handlers, op);                                
+       }
+}
+
+static int pan_view_exec(bContext *C, wmOperator *op)
+{
+       if (!pan_view_init(C, op))
+               return OPERATOR_CANCELLED;
+       
+       pan_view_apply(C, op);
+       pan_view_exit(C, op);
+       return OPERATOR_FINISHED;
+}
+
+static int pan_view_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       v2dViewPanData *vpd= op->customdata;
+       
+       pan_view_init(C, op);
+       
+       vpd= op->customdata;
+       vpd->lastx= vpd->x= event->x;
+       vpd->lasty= vpd->y= event->y;
+       
+       pan_view_apply(C, op);
+
+       /* add temp handler */
+       WM_event_add_modal_handler(&C->window->handlers, op);
+
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static int pan_view_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+       v2dViewPanData *vpd= op->customdata;
+       
+       /* execute the events */
+       switch(event->type) {
+               case MOUSEMOVE:
+                       vpd->x= event->x;
+                       vpd->y= event->y;
+                       
+                       pan_view_apply(C, op);
+                       break;
+                       
+               case MIDDLEMOUSE:
+                       if (event->val==0) {
+                               pan_view_exit(C, op);
+                               WM_event_remove_modal_handler(&C->window->handlers, op);                                
+                               return OPERATOR_FINISHED;
+                       }
+                       break;
+       }
+
+       return OPERATOR_RUNNING_MODAL;
+}
+
+void ED_View2D_OT_view_pan(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Pan View";
+       ot->idname= "ED_View2D_OT_view_pan";
+       
+       /* api callbacks */
+       ot->exec= pan_view_exec;
+       ot->invoke= pan_view_invoke;
+       ot->modal= pan_view_modal;
+}
+
+/* ********************************************************* */
+/* Registration */
+
+void ui_view2d_operatortypes(void)
+{
+       WM_operatortype_append(ED_View2D_OT_view_pan);
+}
+
+void UI_view2d_keymap(wmWindowManager *wm)
+{
+       ui_view2d_operatortypes();
+       
+       /* pan/scroll operators */
+       WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
+       
+       //WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_scrollright", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
+       //WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_scrollleft", WHEELUPMOUSE, KM_CTRL, 0, 0);
+       
+       //WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_scrolldown", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0);
+       //WM_keymap_add_item(&wm->view2dkeymap, "ED_View2D_OT_view_scrollup", WHEELUPMOUSE, KM_SHIFT, 0, 0);
+       
+       /* zoom */
+       
+       /* scrollbars */
+       //WM_keymap_add_item(&wm->view2dkeymap, "ED_V2D_OT_scrollbar_activate", MOUSEMOVE, 0, 0, 0);
+}
+
index cbb348c79247dff2d1e2872a01588e2efdbb40ca..4c7a98e97c399b900d47cb149672e53102b8b4dd 100644 (file)
@@ -1286,6 +1286,9 @@ void ED_operatortypes_screen(void)
        WM_operatortype_append(ED_SCR_OT_area_join);
        WM_operatortype_append(ED_SCR_OT_area_rip);
        
+       /* view2d stuff */
+       
+       
        /* tools shared by more space types */
        ED_marker_operatortypes();      
        
index 91e773b36e1274c122977e79b7810afa3ff0d5d5..a74b3a20e4e0eb9f51301a8fb8eba42d3f9ac5d5 100644 (file)
@@ -31,6 +31,7 @@
 #include "BKE_screen.h"
 
 #include "UI_interface.h"
+#include "UI_view2d.h"
 
 #include "BIF_gl.h"
 
@@ -71,6 +72,7 @@ void ED_spacetypes_keymap(wmWindowManager *wm)
        SpaceType *type;
 
        ED_keymap_screen(wm);
+       UI_view2d_keymap(wm);
        UI_keymap(wm);
 
        spacetypes = BKE_spacetypes_list();
index 2445e02fbee2b08740080dca992a1f54ff74c85f..8903f26cf3e268de428003dd90f4f24addd12c2a 100644 (file)
@@ -107,17 +107,19 @@ void UI_table_free(uiTable *table)
 void UI_table_draw(wmWindow *window, ARegion *region, uiTable *table)
 {
        uiBlock *block;
+       View2D *v2d;
        rcti *rct, cellrct;
        int y, row, col;
-
+       
+       v2d= &region->v2d;
        rct= &table->rct;
-
+       
        block= uiBeginBlock(window, region, "table outliner", UI_EMBOSST, UI_HELV);
-
+       
        for(y=rct->ymax, row=0; y>rct->ymin; y-=ROW_HEIGHT, row++) {
                if(row%2 == 0) {
                        UI_ThemeColorShade(TH_BACK, 6);
-                       glRecti(rct->xmin, y-ROW_HEIGHT, rct->xmax, y);
+                       glRecti(v2d->cur.xmin, y-ROW_HEIGHT, v2d->cur.xmax, y);
                }
 
                if(row >= table->rows)
@@ -335,23 +337,20 @@ static void outliner_main_area_draw(const bContext *C, ARegion *ar)
        PropertyRNA *prop, *iterprop;
        PointerRNA newptr;
        float col[3];
-       int rows, cols, width, height;
+       int rows, cols, awidth, aheight, width, height;
        SpaceOops *soutliner= C->area->spacedata.first;
+       View2D *v2d= &ar->v2d;
 
        /* clear */
        UI_GetThemeColor3fv(TH_BACK, col);
        glClearColor(col[0], col[1], col[2], 0.0);
        glClear(GL_COLOR_BUFFER_BIT);
 
-       width= ar->winrct.xmax - ar->winrct.xmin;
-       height= ar->winrct.ymax - ar->winrct.ymin;
+       // XXX width should be depend on max length of items (like height)...
+       awidth= width= ar->winrct.xmax - ar->winrct.xmin;
+       aheight= height= ar->winrct.ymax - ar->winrct.ymin;
        
        /* create table */
-       rct.xmin= 0;
-       rct.ymin= 0;
-       rct.xmax= width;
-       rct.ymax= height;
-
        cell.space= soutliner;
        cell.lastrow= -1;
        RNA_main_pointer_create(G.main, &cell.ptr);
@@ -390,6 +389,24 @@ static void outliner_main_area_draw(const bContext *C, ARegion *ar)
 
        RNA_property_collection_end(&cell.iter);
 
+       if ((rows*ROW_HEIGHT) > height)
+               height= rows * ROW_HEIGHT;
+       
+       /* need to validate view2d after updating size of tot */
+       v2d->tot.xmin= 0;
+       v2d->tot.xmax= width;
+       v2d->tot.ymax= 0;
+       v2d->tot.ymin= -height;
+       UI_view2d_enforce_status(v2d, awidth, aheight);
+       
+       rct.xmin= 0;
+       rct.ymin= -height;
+       rct.xmax= width;
+       rct.ymax= 0;
+       
+       /* set matrix for 2d-view controls */
+       UI_view2d_ortho(C, v2d);
+       
        /* create and draw table */
        table= UI_table_create(rows, 2, &rct, rna_table_cell_func, &cell);
 
@@ -482,6 +499,7 @@ static void outliner_init(wmWindowManager *wm, ScrArea *sa)
                        ar->type= &mainart;
 
                        WM_event_add_keymap_handler(&ar->handlers, &wm->uikeymap);
+                       WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap);
                }
                else if(ar->regiontype == RGN_TYPE_HEADER) {
                        static ARegionType headerart={NULL, NULL, NULL, NULL, NULL};
@@ -492,6 +510,7 @@ static void outliner_init(wmWindowManager *wm, ScrArea *sa)
                        ar->type= &headerart;
 
                        WM_event_add_keymap_handler(&ar->handlers, &wm->uikeymap);
+                       WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap);
                }
                else {
                        static ARegionType headerart={NULL, NULL, NULL, NULL, NULL};
index bc7c86c173e0145892267ccd35be5d39c7525b1f..e500477ba23c7ff1d18f29ddc2a279896cb9bf86 100644 (file)
@@ -58,7 +58,7 @@
 /* ************************ main time area region *********************** */
 
 /* draws a current frame indicator for the TimeLine */
-static void time_draw_cfra_time(const bContext *C, SpaceTime *stime)
+static void time_draw_cfra_time(const bContext *C, SpaceTime *stime, ARegion *ar)
 {
        Scene *scene= C->scene;
        float vec[2];
@@ -69,33 +69,33 @@ static void time_draw_cfra_time(const bContext *C, SpaceTime *stime)
        glLineWidth(3.0);
 
        glBegin(GL_LINES);
-               vec[1]= stime->v2d.cur.ymin;
+               vec[1]= ar->v2d.cur.ymin;
                glVertex2fv(vec);
-               vec[1]= stime->v2d.cur.ymax;
+               vec[1]= ar->v2d.cur.ymax;
                glVertex2fv(vec);
        glEnd();
        
        glLineWidth(1.0);
 }
 
-static void time_draw_sfra_efra(const bContext *C, SpaceTime *stime)
+static void time_draw_sfra_efra(const bContext *C, SpaceTime *stime, ARegion *ar)
 {
     /* draw darkened area outside of active timeline 
         * frame range used is preview range or scene range */
        UI_ThemeColorShade(TH_BACK, -25);
 
        if (PSFRA < PEFRA) {
-               glRectf(stime->v2d.cur.xmin, stime->v2d.cur.ymin, PSFRA, stime->v2d.cur.ymax);
-               glRectf(PEFRA, stime->v2d.cur.ymin, stime->v2d.cur.xmax, stime->v2d.cur.ymax);
+               glRectf(ar->v2d.cur.xmin, ar->v2d.cur.ymin, PSFRA, ar->v2d.cur.ymax);
+               glRectf(PEFRA, ar->v2d.cur.ymin, ar->v2d.cur.xmax, ar->v2d.cur.ymax);
        }
        else {
-               glRectf(stime->v2d.cur.xmin, stime->v2d.cur.ymin, stime->v2d.cur.xmax, stime->v2d.cur.ymax);
+               glRectf(ar->v2d.cur.xmin, ar->v2d.cur.ymin, ar->v2d.cur.xmax, ar->v2d.cur.ymax);
        }
 
        UI_ThemeColorShade(TH_BACK, -60);
        /* thin lines where the actual frames are */
-       fdrawline(PSFRA, stime->v2d.cur.ymin, PSFRA, stime->v2d.cur.ymax);
-       fdrawline(PEFRA, stime->v2d.cur.ymin, PEFRA, stime->v2d.cur.ymax);
+       fdrawline(PSFRA, ar->v2d.cur.ymin, PSFRA, ar->v2d.cur.ymax);
+       fdrawline(PEFRA, ar->v2d.cur.ymin, PEFRA, ar->v2d.cur.ymax);
 }
 
 static void time_main_area_init(const bContext *C, ARegion *ar)
@@ -112,6 +112,7 @@ static void time_main_area_draw(const bContext *C, ARegion *ar)
 {
        /* draw entirely, windowsize changes should be handled here */
        SpaceTime *stime= C->area->spacedata.first;
+       View2D *v2d= &ar->v2d;
        View2DGrid *grid;
        float col[3];
        int unit, winx, winy;
@@ -119,26 +120,26 @@ static void time_main_area_draw(const bContext *C, ARegion *ar)
        winx= ar->winrct.xmax-ar->winrct.xmin;
        winy= ar->winrct.ymax-ar->winrct.ymin;
 
-       UI_view2d_update_size(&stime->v2d, winx, winy);
+       UI_view2d_update_size(v2d, winx, winy);
 
        /* clear and setup matrix */
        UI_GetThemeColor3fv(TH_BACK, col);
        glClearColor(col[0], col[1], col[2], 0.0);
        glClear(GL_COLOR_BUFFER_BIT);
 
-       UI_view2d_ortho(C, &stime->v2d);
+       UI_view2d_ortho(C, v2d);
 
        /* start and end frame */
-       time_draw_sfra_efra(C, stime);
+       time_draw_sfra_efra(C, stime, ar);
 
        /* grid */
        unit= (stime->flag & TIME_DRAWFRAMES)? V2D_UNIT_FRAMES: V2D_UNIT_SECONDS;
-       grid= UI_view2d_calc_grid(C, &stime->v2d, unit, V2D_GRID_CLAMP, winx, winy);
-       UI_view2d_draw_grid(C, &stime->v2d, grid, V2D_VERTICAL_LINES|V2D_VERTICAL_AXIS);
+       grid= UI_view2d_calc_grid(C, v2d, unit, V2D_GRID_CLAMP, winx, winy);
+       UI_view2d_draw_grid(C, v2d, grid, (V2D_VERTICAL_LINES|V2D_VERTICAL_AXIS));
        UI_view2d_free_grid(grid);
 
        /* current frame */
-       time_draw_cfra_time(C, stime);
+       time_draw_cfra_time(C, stime, ar);
        
        /* markers */
        draw_markers_time(C, 0);
@@ -180,6 +181,7 @@ static SpaceLink *time_new(void)
        stime->blockscale= 0.7;
        stime->redraws= TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN;
 
+       // XXX move to region!
        stime->v2d.tot.xmin= -4.0;
        stime->v2d.tot.ymin=  0.0;
        stime->v2d.tot.xmax= (float)EFRA + 4.0;
@@ -240,6 +242,7 @@ static void time_init(wmWindowManager *wm, ScrArea *sa)
                         * be looked at further */
                        WM_event_remove_keymap_handler(&ar->handlers, &wm->timekeymap);
                        WM_event_add_keymap_handler(&ar->handlers, &wm->timekeymap);
+                       WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap); // XXX this should be added automatically!
                }
                else if(ar->regiontype == RGN_TYPE_HEADER) {
                        static ARegionType headerart={NULL, NULL, NULL, NULL, NULL};
@@ -249,6 +252,7 @@ static void time_init(wmWindowManager *wm, ScrArea *sa)
 
                        ar->type= &headerart;
                        WM_event_add_keymap_handler(&ar->handlers, &wm->uikeymap);
+                       WM_event_add_keymap_handler(&ar->handlers, &wm->view2dkeymap); // XXX this should be added automatically!
                }
                else {
                        static ARegionType art={NULL, NULL, NULL, NULL, NULL};
index acf9d392ed4e24b3de6c1d89e1a13879e723871e..bc30d07f878b6e455afb4f335deb2fc8881af642 100644 (file)
@@ -111,10 +111,10 @@ static int frame_from_event(bContext *C, wmEvent *event)
        ARegion *region= C->region;
        int x, y;
        float viewx;
-
+       
        x= event->x - region->winrct.xmin;
        y= event->y - region->winrct.ymin;
-       UI_view2d_region_to_view(&stime->v2d, x, y, &viewx, NULL);
+       UI_view2d_region_to_view(&region->v2d, x, y, &viewx, NULL);
 
        return (int)(viewx+0.5f);
 }
@@ -126,7 +126,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
        change_frame_apply(C, op);
 
        /* add temp handler */
-       WM_event_add_modal_handler(&C->region->handlers, op);
+       WM_event_add_modal_handler(&C->region->handlers, op); // XXX should be for window, but we crash otherwise
 
        return OPERATOR_RUNNING_MODAL;
 }
@@ -149,7 +149,7 @@ static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
                case LEFTMOUSE:
                        if(event->val==0) {
                                change_frame_exit(C, op);
-                               WM_event_remove_modal_handler(&C->region->handlers, op);                                
+                               WM_event_remove_modal_handler(&C->region->handlers, op);         // XXX should be for window, but we crash otherwise                    
                                return OPERATOR_FINISHED;
                        }
                        break;
index c49a70ee9cfae5843a18616f1af69388051cf181..2f25d96f28585a6599adf552b8b2c8a2ced5d148 100644 (file)
@@ -28,6 +28,7 @@
 #define DNA_SCREEN_TYPES_H
 
 #include "DNA_listBase.h"
+#include "DNA_view2d_types.h"
 #include "DNA_vec_types.h"
 
 #include "DNA_scriptlink_types.h"
@@ -132,7 +133,9 @@ typedef struct ScrArea {
 typedef struct ARegion {
        struct ARegion *next, *prev;
        
-       rcti winrct;
+       View2D v2d;                                     /* 2D-View scrolling/zoom info (most regions are 2d anyways) */
+       rcti winrct;                            /* coordinates of region */
+       
        short swinid;
        short regiontype;                       /* window, header, etc. identifier for drawing */
        short alignment;                        /* how it should split */
index d4425b43f7608df3ef68dfa882fa9c5da7158536..0a44b6b87594ef1bb582fa5c519d2f9a935b0b07 100644 (file)
 
 /* View 2D data - stored per region */
 typedef struct View2D {
-       rctf tot, cur;
-       rcti vert, hor, mask;
+       rctf tot, cur;                                  /* tot - area that data can be drawn in; cur - region of tot that is visible in viewport */
+       rcti vert, hor;                                 /* vert - vertical scrollbar region; hor - horizontal scrollbar region */
+       rcti mask;                                              /* mask - region (in screenspace) within which 'cur' can be viewed */
        
-       float min[2], max[2];
-       float minzoom, maxzoom;
+       float min[2], max[2];                   /* min/max sizes? */
+       float minzoom, maxzoom;                 /* self explanatory. allowable zoom factor range */
        
-       short scroll, keeptot;                  /* scroll - scrollbars to display (bitflag); keeptot - 'tot' rect  */
-       short keepaspect, keepzoom;
-       short oldwinx, oldwiny;
+       short scroll;                                   /* scroll - scrollbars to display (bitflag) */
+       short keeptot;                                  /* keeptot - 'tot' rect  */
+       short keepaspect, keepzoom;             /* axes that zoomimg cannot occur on, and need to maintain aspect ratio */
+       short keepofs;                                  /* keepofs - axes that translation is not allowed to occur on */
        
-       int flag;                                               /* settings */
+       short flag;                                             /* settings */
+       
+       short oldwinx, oldwiny;                 /* storage of previous winx/winy values encountered by UI_view2d_enforce_status(), for keepaspect */
        
        float cursor[2];                                /* only used in the UV view for now (for 2D-cursor) */
        short around;                                   /* pivot point for transforms (rotate and scale) */
@@ -61,6 +65,10 @@ typedef struct View2D {
 #define V2D_LOCKZOOM_X 0x0100
 #define V2D_LOCKZOOM_Y 0x0200
 
+/* v2d->keepofs */
+#define V2D_LOCKOFS_X  (1<<1)
+#define V2D_LOCKOFS_Y  (1<<2)
+
 /* event codes for locking function */
 #define V2D_LOCK_COPY          1
 #define V2D_LOCK_REDRAW                2
index 2d2cc962f8a9b72f6b3c67671bc0986217dbede4..07abe9fd75fe43c21d4be550b055ccf9658b0bd2 100644 (file)
@@ -69,6 +69,7 @@ typedef struct wmWindowManager {
        /* custom keymaps */
        ListBase windowkeymap;
        ListBase screenkeymap;
+       ListBase view2dkeymap;
        ListBase uikeymap;
        ListBase timekeymap;
        /* keymaps have to be NULLed in readfile.c */
index 8443c022d1746bb84c1368a7fcb9212f603e8dee..1433c37ae9e60c6e6facd3946cf7c8551377b0d6 100644 (file)
@@ -37,9 +37,9 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_camera_types.h" /* qdn: defocus node, need camera info */
-#include "DNA_action_types.h"
+//#include "DNA_action_types.h"
 #include "DNA_color_types.h"
-#include "DNA_ipo_types.h"
+//#include "DNA_ipo_types.h"
 #include "DNA_ID.h"
 #include "DNA_image_types.h"
 #include "DNA_material_types.h"
index 0d9783fdd4bc3dd9463bc52b27c33634c08f944e..8bcd6e40038c9e09e3cfb3cf5075888613b6285e 100644 (file)
@@ -36,9 +36,9 @@
 
 #include "MEM_guardedalloc.h"
 
-#include "DNA_action_types.h"
+//#include "DNA_action_types.h"
 #include "DNA_color_types.h"
-#include "DNA_ipo_types.h"
+//#include "DNA_ipo_types.h"
 #include "DNA_ID.h"
 #include "DNA_image_types.h"
 #include "DNA_material_types.h"