diff --git a/SConstruct b/SConstruct index 59152cdc9f3..0bc05a59df2 100644 --- a/SConstruct +++ b/SConstruct @@ -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) diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj index 426add657ab..1e76a41ec82 100644 --- a/projectfiles_vc9/blender/editors/ED_editors.vcproj +++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj @@ -306,6 +306,10 @@ RelativePath="..\..\..\source\blender\editors\interface\view2d.c" > + + 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 + } } } diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 1a37463aaab..1929e29bb4a 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -35,6 +35,10 @@ /* ------------------------------------------ */ /* 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 @@ -43,20 +47,18 @@ #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])) @@ -65,9 +67,13 @@ 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 */ diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 6d86f6dcb1a..a2fc8186664 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -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 index 00000000000..f0365632d1d --- /dev/null +++ b/source/blender/editors/interface/view2d_ops.c @@ -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 + +#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); +} + diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index cbb348c7924..4c7a98e97c3 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -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(); diff --git a/source/blender/editors/screen/spacetypes.c b/source/blender/editors/screen/spacetypes.c index 91e773b36e1..a74b3a20e4e 100644 --- a/source/blender/editors/screen/spacetypes.c +++ b/source/blender/editors/screen/spacetypes.c @@ -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(); diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 2445e02fbee..8903f26cf3e 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -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= ®ion->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}; diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index bc7c86c173e..e500477ba23 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -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}; diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c index acf9d392ed4..bc30d07f878 100644 --- a/source/blender/editors/space_time/time_ops.c +++ b/source/blender/editors/space_time/time_ops.c @@ -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(®ion->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; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index c49a70ee9cf..2f25d96f285 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -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 */ diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h index d4425b43f76..0a44b6b8759 100644 --- a/source/blender/makesdna/DNA_view2d_types.h +++ b/source/blender/makesdna/DNA_view2d_types.h @@ -37,17 +37,21 @@ /* 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 diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 2d2cc962f8a..07abe9fd75f 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -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 */ diff --git a/source/blender/nodes/intern/CMP_util.h b/source/blender/nodes/intern/CMP_util.h index 8443c022d17..1433c37ae9e 100644 --- a/source/blender/nodes/intern/CMP_util.h +++ b/source/blender/nodes/intern/CMP_util.h @@ -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" diff --git a/source/blender/nodes/intern/SHD_util.h b/source/blender/nodes/intern/SHD_util.h index 0d9783fdd4b..8bcd6e40038 100644 --- a/source/blender/nodes/intern/SHD_util.h +++ b/source/blender/nodes/intern/SHD_util.h @@ -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"