2.5: Buttons View
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 29 Jul 2009 22:57:53 +0000 (22:57 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 29 Jul 2009 22:57:53 +0000 (22:57 +0000)
* When resizing the window, the top position is now preserved,
  instead of the center position.
* Fix zoom level not being preserved in various cases, when
  changing both with and height. This replaces some earlier code
  which did this at screen level but wasn't very reliable.
* Different tabs now each preserve their own scroll.
* When switching between tabs, it now scrolls to show as many
  buttons as possible, instead of possibly showing empty space.
  There is a trade-off here between doing that keeping the
  buttons in the same place, no ideal solution exists I think.
* Change zooming in/out to be symmetric, for example doing
  numpad + then - did not give the original zoom level back.
* Added some calls to avoid hanging tooltips when manipulating
  the view.

Internals:
* Added V2D_KEEPOFS_X and V2D_KEEPOFS_Y to keep the top/bottom
  rather than the center.
* Renamed V2D_KEEPZOOM to V2D_LIMITZOOM (seems more appropriate),
  and make V2D_KEEPZOOM preserve the zoom level.

22 files changed:
source/blender/blenkernel/intern/screen.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/ED_screen.h
source/blender/editors/include/UI_view2d.h
source/blender/editors/interface/view2d.c
source/blender/editors/interface/view2d_ops.c
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_console/space_console.c
source/blender/editors/space_file/space_file.c
source/blender/editors/space_graph/space_graph.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_info/space_info.c
source/blender/editors/space_logic/space_logic.c
source/blender/editors/space_nla/space_nla.c
source/blender/editors/space_node/space_node.c
source/blender/editors/space_outliner/space_outliner.c
source/blender/editors/space_sequencer/space_sequencer.c
source/blender/editors/space_text/space_text.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/makesdna/DNA_view2d_types.h

index c1f621274c00f0cbd5c7d7a1be98d2c9aa48a218..cc740d7fb3daccbd3992b332c624c1c40002d2e3 100644 (file)
@@ -179,6 +179,9 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
                else
                        newar->regiondata= MEM_dupallocN(ar->regiondata);
        }
+
+       if(ar->v2d.tab_offset)
+               newar->v2d.tab_offset= MEM_dupallocN(ar->v2d.tab_offset);
        
        newar->panels.first= newar->panels.last= NULL;
        BLI_duplicatelist(&newar->panels, &ar->panels);
@@ -271,10 +274,14 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
        }
        else if(ar->type && ar->type->free)
                ar->type->free(ar);
+       
+       if(ar->v2d.tab_offset) {
+               MEM_freeN(ar->v2d.tab_offset);
+               ar->v2d.tab_offset= NULL;
+       }
 
-       if(ar) {
+       if(ar)
                BLI_freelistN(&ar->panels);
-       }
 }
 
 /* not area itself */
index bdb98a8ae724a66d36c87fc0aea21305aba47217..3029e48231299a6ef16bf777ac462ec8d9557a76 100644 (file)
@@ -4681,6 +4681,9 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
                }
        }
        
+       ar->v2d.tab_offset= NULL;
+       ar->v2d.tab_num= 0;
+       ar->v2d.tab_cur= 0;
        ar->handlers.first= ar->handlers.last= NULL;
        ar->uiblocks.first= ar->uiblocks.last= NULL;
        ar->headerstr= NULL;
@@ -5654,7 +5657,7 @@ static void area_add_header_region(ScrArea *sa, ListBase *lb)
        
        /* initialise view2d data for header region, to allow panning */
        /* is copy from ui_view2d.c */
-       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
        ar->v2d.keepofs = V2D_LOCKOFS_Y;
        ar->v2d.keeptot = V2D_KEEPTOT_STRICT; 
        ar->v2d.align = V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_NEG_Y;
@@ -5847,7 +5850,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                memcpy(&ar->v2d, &snode->v2d, sizeof(View2D));
                                
                                ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
-                               ar->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
+                               ar->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT;
                                break;
                        }
                        case SPACE_BUTS:
@@ -5868,7 +5871,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
                                ar->regiontype= RGN_TYPE_WINDOW;
                                ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
                                ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
-                               ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+                               ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
                                break;
                        }
                        case SPACE_TEXT:
@@ -8199,7 +8202,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                                        simasel->v2d.minzoom= 0.5f;
                                                        simasel->v2d.maxzoom= 1.21f;                                            
                                                        simasel->v2d.scroll= 0;
-                                                       simasel->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
+                                                       simasel->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT;
                                                        simasel->v2d.keeptot= 0;
                                                        simasel->prv_h = 96;
                                                        simasel->prv_w = 96;
index d2e058f9f6d4fbe8101f2111276ae166444ce625..fc29d64eb37354667a9815110e68e33396014acf 100644 (file)
@@ -55,7 +55,7 @@ void  ED_region_init(struct bContext *C, struct ARegion *ar);
 void   ED_region_tag_redraw(struct ARegion *ar);
 void   ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct);
 void   ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar);
-void   ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, char *context);
+void   ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, char *context, int contextnr);
 void   ED_region_header_init(struct ARegion *ar);
 void   ED_region_header(const struct bContext *C, struct ARegion *ar);
 
index e3fbd906cf6e0f3967c33764c040210be53bb72d..38c4d82e6daafef06cf941fc00a04b4f102e21a7 100644 (file)
@@ -145,10 +145,15 @@ typedef struct View2DScrollers View2DScrollers;
 void UI_view2d_region_reinit(struct View2D *v2d, short type, int winx, int winy);
 
 void UI_view2d_curRect_validate(struct View2D *v2d);
+void UI_view2d_curRect_validate_resize(struct View2D *v2d, int resize);
 void UI_view2d_curRect_reset(struct View2D *v2d);
 void UI_view2d_sync(struct bScreen *screen, struct ScrArea *sa, struct View2D *v2dcur, int flag);
 
 void UI_view2d_totRect_set(struct View2D *v2d, int width, int height);
+void UI_view2d_totRect_set_resize(struct View2D *v2d, int width, int height, int resize);
+
+/* per tab offsets, returns 1 if tab changed */
+int UI_view2d_tab_set(struct View2D *v2d, int tab);
 
 /* view matrix operations */
 void UI_view2d_view_ortho(const struct bContext *C, struct View2D *v2d);
index c76110ac440d661e3e07d4ca5171fed945161d9f..f9fb7a9306f25ef210b1c9979b1a9969c7df982e 100644 (file)
@@ -154,13 +154,15 @@ static void view2d_masks(View2D *v2d)
  */
 void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
 {
-       short tot_changed= 0;
+       short tot_changed= 0, init= 0;
        uiStyle *style= U.uistyles.first;
 
        /* initialise data if there is a need for such */
        if ((v2d->flag & V2D_IS_INITIALISED) == 0) {
                /* set initialised flag so that View2D doesn't get reinitialised next time again */
                v2d->flag |= V2D_IS_INITIALISED;
+
+               init= 1;
                
                /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
                switch (type) {
@@ -170,7 +172,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
                        case V2D_COMMONVIEW_STANDARD:
                        {
                                /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
-                               v2d->keepzoom= (V2D_KEEPASPECT|V2D_KEEPZOOM);
+                               v2d->keepzoom= (V2D_KEEPASPECT|V2D_LIMITZOOM);
                                v2d->minzoom= 0.01f;
                                v2d->maxzoom= 1000.0f;
                                
@@ -197,7 +199,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
                        case V2D_COMMONVIEW_LIST:
                        {
                                /* zoom + aspect ratio are locked */
-                               v2d->keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+                               v2d->keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
                                v2d->minzoom= v2d->maxzoom= 1.0f;
                                
                                /* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
@@ -214,7 +216,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
                        case V2D_COMMONVIEW_STACK:
                        {
                                /* zoom + aspect ratio are locked */
-                               v2d->keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+                               v2d->keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
                                v2d->minzoom= v2d->maxzoom= 1.0f;
                                
                                /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
@@ -230,7 +232,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
                        case V2D_COMMONVIEW_HEADER:
                        {
                                /* zoom + aspect ratio are locked */
-                               v2d->keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+                               v2d->keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
                                v2d->minzoom= v2d->maxzoom= 1.0f;
                                v2d->min[0]= v2d->max[0]= (float)(winx-1);
                                v2d->min[1]= v2d->max[1]= (float)(winy-1);
@@ -257,9 +259,10 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
                                float panelzoom= (style) ? style->panelzoom : 1.0f;
                                
                                /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
-                               v2d->keepzoom= (V2D_KEEPASPECT|V2D_KEEPZOOM);
+                               v2d->keepzoom= (V2D_KEEPASPECT|V2D_LIMITZOOM|V2D_KEEPZOOM);
                                v2d->minzoom= 0.5f;
                                v2d->maxzoom= 2.0f;
+                               //tot_changed= 1;
                                
                                v2d->align= (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
                                v2d->keeptot= V2D_KEEPTOT_BOUNDS;
@@ -298,17 +301,16 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
        
        /* set 'tot' rect before setting cur? */
        if (tot_changed) 
-               UI_view2d_totRect_set(v2d, winx, winy);
+               UI_view2d_totRect_set_resize(v2d, winx, winy, !init);
        else
-               UI_view2d_curRect_validate(v2d);
-       
+               UI_view2d_curRect_validate_resize(v2d, !init);
 }
 
 /* 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()
-void UI_view2d_curRect_validate(View2D *v2d)
+void UI_view2d_curRect_validate_resize(View2D *v2d, int resize)
 {
        float totwidth, totheight, curwidth, curheight, width, height;
        float winx, winy;
@@ -351,10 +353,30 @@ void UI_view2d_curRect_validate(View2D *v2d)
        if(winx<1) winx= 1;
        if(winy<1) winy= 1;
        
-       /* keepzoom (V2D_KEEPZOOM set), indicates that zoom level on each axis must not exceed limits 
+       /* V2D_LIMITZOOM indicates that zoom level should be preserved when the window size changes */
+       if (resize && (v2d->keepzoom & V2D_KEEPZOOM)) {
+               float zoom, oldzoom;
+
+               if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0) {
+                       zoom= winx / width;
+                       oldzoom= v2d->oldwinx / curwidth;
+
+                       if(oldzoom != zoom)
+                               width *= zoom/oldzoom;
+               }
+
+               if ((v2d->keepzoom & V2D_LOCKZOOM_Y)==0) {
+                       zoom= winy / height;
+                       oldzoom= v2d->oldwiny / curheight;
+
+                       if(oldzoom != zoom)
+                               height *= zoom/oldzoom;
+               }
+       }
+       /* keepzoom (V2D_LIMITZOOM set), indicates that zoom level on each axis must not exceed limits 
         * NOTE: in general, it is not expected that the lock-zoom will be used in conjunction with this
         */
-       if (v2d->keepzoom & V2D_KEEPZOOM) {
+       else if (v2d->keepzoom & V2D_LIMITZOOM) {
                float zoom, fac;
                
                /* check if excessive zoom on x-axis */
@@ -460,11 +482,17 @@ void UI_view2d_curRect_validate(View2D *v2d)
        if ((width != curwidth) || (height != curheight)) {
                float temp, dh;
                
-               /* resize from centerpoint */
+               /* resize from centerpoint, unless otherwise specified */
                if (width != curwidth) {
                        if (v2d->keepofs & V2D_LOCKOFS_X) {
                                cur->xmax += width - (cur->xmax - cur->xmin);
                        }
+                       else if (v2d->keepofs & V2D_KEEPOFS_X) {
+                               if(v2d->align & V2D_ALIGN_NO_POS_X)
+                                       cur->xmin -= width - (cur->xmax - cur->xmin);
+                               else
+                                       cur->xmax += width - (cur->xmax - cur->xmin);
+                       }
                        else {
                                temp= (cur->xmax + cur->xmin) * 0.5f;
                                dh= width * 0.5f;
@@ -477,6 +505,12 @@ void UI_view2d_curRect_validate(View2D *v2d)
                        if (v2d->keepofs & V2D_LOCKOFS_Y) {
                                cur->ymax += height - (cur->ymax - cur->ymin);
                        }
+                       else if (v2d->keepofs & V2D_KEEPOFS_Y) {
+                               if(v2d->align & V2D_ALIGN_NO_POS_Y)
+                                       cur->ymin -= height - (cur->ymax - cur->ymin);
+                               else
+                                       cur->ymax += height - (cur->ymax - cur->ymin);
+                       }
                        else {
                                temp= (cur->ymax + cur->ymin) * 0.5f;
                                dh= height * 0.5f;
@@ -496,7 +530,7 @@ void UI_view2d_curRect_validate(View2D *v2d)
                curheight= cur->ymax - cur->ymin;
                
                /* width */
-               if ( (curwidth > totwidth) && !(v2d->keepzoom & (V2D_KEEPZOOM|V2D_LOCKZOOM_X)) ) {
+               if ( (curwidth > totwidth) && !(v2d->keepzoom & (V2D_KEEPZOOM|V2D_LOCKZOOM_X|V2D_LIMITZOOM)) ) {
                        /* if zoom doesn't have to be maintained, just clamp edges */
                        if (cur->xmin < tot->xmin) cur->xmin= tot->xmin;
                        if (cur->xmax > tot->xmax) cur->xmax= tot->xmax;
@@ -542,13 +576,13 @@ void UI_view2d_curRect_validate(View2D *v2d)
                         * We favour moving the 'minimum' across, as that's origin for most things
                         * (XXX - in the past, max was favoured... if there are bugs, swap!)
                         */
-                       if ((cur->ymin < tot->ymin) && (cur->ymax > tot->ymax)) {
+                       if ((cur->xmin < tot->xmin) && (cur->xmax > tot->xmax)) {
                                /* outside boundaries on both sides, so take middle-point of tot, and place in balanced way */
-                               temp= (tot->ymax + tot->ymin) * 0.5f;
+                               temp= (tot->xmax + tot->xmin) * 0.5f;
                                diff= curheight * 0.5f;
                                
-                               cur->ymin= temp - diff;
-                               cur->ymax= temp + diff;
+                               cur->xmin= temp - diff;
+                               cur->xmax= temp + diff;
                        }
                        else if (cur->xmin < tot->xmin) {
                                /* move cur across so that it sits at minimum of tot */
@@ -579,7 +613,7 @@ void UI_view2d_curRect_validate(View2D *v2d)
                }
                
                /* height */
-               if ( (curheight > totheight) && !(v2d->keepzoom & (V2D_KEEPZOOM|V2D_LOCKZOOM_Y)) ) {
+               if ( (curheight > totheight) && !(v2d->keepzoom & (V2D_KEEPZOOM|V2D_LOCKZOOM_Y|V2D_LIMITZOOM)) ) {
                        /* if zoom doesn't have to be maintained, just clamp edges */
                        if (cur->ymin < tot->ymin) cur->ymin= tot->ymin;
                        if (cur->ymax > tot->ymax) cur->ymax= tot->ymax;
@@ -664,6 +698,11 @@ void UI_view2d_curRect_validate(View2D *v2d)
        view2d_masks(v2d);
 }
 
+void UI_view2d_curRect_validate(View2D *v2d)
+{
+       return UI_view2d_curRect_validate_resize(v2d, 0);
+}
+
 /* ------------------ */
 
 /* Called by menus to activate it, or by view2d operators to make sure 'related' views stay in synchrony */
@@ -783,7 +822,7 @@ void UI_view2d_curRect_reset (View2D *v2d)
 /* ------------------ */
 
 /* Change the size of the maximum viewable area (i.e. 'tot' rect) */
-void UI_view2d_totRect_set (View2D *v2d, int width, int height)
+void UI_view2d_totRect_set_resize (View2D *v2d, int width, int height, int resize)
 {
        int scroll= view2d_scroll_mapped(v2d->scroll);
        
@@ -841,7 +880,57 @@ void UI_view2d_totRect_set (View2D *v2d, int width, int height)
        }
        
        /* make sure that 'cur' rect is in a valid state as a result of these changes */
-       UI_view2d_curRect_validate(v2d);
+       UI_view2d_curRect_validate_resize(v2d, resize);
+}
+
+void UI_view2d_totRect_set(View2D *v2d, int width, int height)
+{
+       UI_view2d_totRect_set_resize(v2d, width, height, 0);
+}
+
+int UI_view2d_tab_set(View2D *v2d, int tab)
+{
+       float default_offset[2]= {0.0f, 0.0f};
+       float *offset, *new_offset;
+       int changed= 0;
+
+       /* if tab changed, change offset */
+       if(tab != v2d->tab_cur && v2d->tab_offset) {
+               if(tab < v2d->tab_num)
+                       offset= &v2d->tab_offset[tab*2];
+               else
+                       offset= default_offset;
+
+               v2d->cur.xmax += offset[0] - v2d->cur.xmin;
+               v2d->cur.xmin= offset[0];
+
+               v2d->cur.ymin += offset[1] - v2d->cur.ymax;
+               v2d->cur.ymax= offset[1];
+
+               /* validation should happen in subsequent totRect_set */
+
+               changed= 1;
+       }
+
+       /* resize array if needed */
+       if(tab >= v2d->tab_num) {
+               new_offset= MEM_callocN(sizeof(float)*(tab+1)*2, "view2d tab offset");
+
+               if(v2d->tab_offset) {
+                       memcpy(new_offset, v2d->tab_offset, sizeof(float)*v2d->tab_num*2);
+                       MEM_freeN(v2d->tab_offset);
+               }
+
+               v2d->tab_offset= new_offset;
+               v2d->tab_num= tab+1;
+       }
+
+       /* set current tab and offset */
+       v2d->tab_cur= tab;
+       v2d->tab_offset[2*tab+0]= v2d->cur.xmin;
+       v2d->tab_offset[2*tab+1]= v2d->cur.ymax;
+
+       return changed;
 }
 
 /* *********************************************************************** */
index ee2a50d12a97ad11cb521d31b20bef9f5a69520c..1e8cda68e6de2159d059c6d88cc545e0c19723a4 100644 (file)
@@ -151,6 +151,7 @@ static void view_pan_apply(bContext *C, wmOperator *op)
        /* request updates to be done... */
        ED_area_tag_redraw(vpd->sa);
        UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
+       WM_event_add_mousemove(C);
        
        /* exceptions */
        if(vpd->sa->spacetype==SPACE_OUTLINER) {
@@ -493,17 +494,33 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
 {
        ARegion *ar= CTX_wm_region(C);
        View2D *v2d= &ar->v2d;
-       float dx, dy;
-       
-       /* calculate amount to move view by */
-       dx= (v2d->cur.xmax - v2d->cur.xmin) * (float)RNA_float_get(op->ptr, "zoomfacx");
-       dy= (v2d->cur.ymax - v2d->cur.ymin) * (float)RNA_float_get(op->ptr, "zoomfacy");
+       float dx, dy, facx, facy;
        
+       /* calculate amount to move view by, ensuring symmetry so the
+        * old zoom level is restored after zooming back the same amount */
+       facx= RNA_float_get(op->ptr, "zoomfacx");
+       facy= RNA_float_get(op->ptr, "zoomfacy");
+
+       if(facx >= 0.0f) {
+               dx= (v2d->cur.xmax - v2d->cur.xmin) * facx;
+               dy= (v2d->cur.ymax - v2d->cur.ymin) * facy;
+       }
+       else {
+               dx= ((v2d->cur.xmax - v2d->cur.xmin)/(1.0f + 2.0f*facx)) * facx;
+               dy= ((v2d->cur.ymax - v2d->cur.ymin)/(1.0f + 2.0f*facy)) * facy;
+       }
+
        /* only resize view on an axis if change is allowed */
        if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0) {
                if (v2d->keepofs & V2D_LOCKOFS_X) {
                        v2d->cur.xmax -= 2*dx;
                }
+               else if (v2d->keepofs & V2D_KEEPOFS_X) {
+                       if(v2d->align & V2D_ALIGN_NO_POS_X)
+                               v2d->cur.xmin += 2*dx;
+                       else
+                               v2d->cur.xmax -= 2*dx;
+               }
                else {
                        v2d->cur.xmin += dx;
                        v2d->cur.xmax -= dx;
@@ -513,18 +530,25 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
                if (v2d->keepofs & V2D_LOCKOFS_Y) {
                        v2d->cur.ymax -= 2*dy;
                }
+               else if (v2d->keepofs & V2D_KEEPOFS_Y) {
+                       if(v2d->align & V2D_ALIGN_NO_POS_Y)
+                               v2d->cur.ymin += 2*dy;
+                       else
+                               v2d->cur.ymax -= 2*dy;
+               }
                else {
                        v2d->cur.ymin += dy;
                        v2d->cur.ymax -= dy;
                }
        }
-       
+
        /* validate that view is in valid configuration after this operation */
        UI_view2d_curRect_validate(v2d);
-       
+
        /* request updates to be done... */
        ED_area_tag_redraw(CTX_wm_area(C));
        UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+       WM_event_add_mousemove(C);
 }
 
 /* --------------- Individual Operators ------------------- */
@@ -681,6 +705,7 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
        /* request updates to be done... */
        ED_area_tag_redraw(CTX_wm_area(C));
        UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+       WM_event_add_mousemove(C);
 }
 
 /* cleanup temp customdata  */
@@ -922,6 +947,7 @@ static int view_borderzoom_exec(bContext *C, wmOperator *op)
        /* request updates to be done... */
        ED_area_tag_redraw(CTX_wm_area(C));
        UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+       WM_event_add_mousemove(C);
        
        return OPERATOR_FINISHED;
 } 
@@ -1162,6 +1188,7 @@ static void scroller_activate_apply(bContext *C, wmOperator *op)
        /* request updates to be done... */
        ED_area_tag_redraw(CTX_wm_area(C));
        UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+       WM_event_add_mousemove(C);
 }
 
 /* handle user input for scrollers - calculations of mouse-movement need to be done here, not in the apply callback! */
@@ -1301,20 +1328,20 @@ static int reset_exec(bContext *C, wmOperator *op)
                /* posx and negx flags are mutually exclusive, so watch out */
                if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
                        v2d->cur.xmax= 0.0f;
-                       v2d->cur.xmin= v2d->winx*style->panelzoom;
+                       v2d->cur.xmin= -winx*style->panelzoom;
                }
                else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
-                       v2d->cur.xmax= (v2d->cur.xmax - v2d->cur.xmin)*style->panelzoom;
+                       v2d->cur.xmax= winx*style->panelzoom;
                        v2d->cur.xmin= 0.0f;
                }
 
                /* - posx and negx flags are mutually exclusive, so watch out */
                if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
                        v2d->cur.ymax= 0.0f;
-                       v2d->cur.ymin= -v2d->winy*style->panelzoom;
+                       v2d->cur.ymin= -winy*style->panelzoom;
                }
                else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
-                       v2d->cur.ymax= (v2d->cur.ymax - v2d->cur.ymin)*style->panelzoom;
+                       v2d->cur.ymax= winy*style->panelzoom;
                        v2d->cur.ymin= 0.0f;
                }
        }
@@ -1325,6 +1352,7 @@ static int reset_exec(bContext *C, wmOperator *op)
        /* request updates to be done... */
        ED_area_tag_redraw(CTX_wm_area(C));
        UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+       WM_event_add_mousemove(C);
        
        return OPERATOR_FINISHED;
 }
@@ -1340,7 +1368,7 @@ void VIEW2D_OT_reset(wmOperatorType *ot)
        ot->poll= view2d_poll;
        
        /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       // ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
  
 /* ********************************************************* */
index c74a5ca9c87d7a644c72e3f4f55a972691a16e8f..79ba11a5c55269e472e6a6d881765342ec5c940d 100644 (file)
@@ -1132,7 +1132,7 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
 
 /************************ standard UI regions ************************/
 
-void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *context)
+void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *context, int contextnr)
 {
        ScrArea *sa= CTX_wm_area(C);
        uiStyle *style= U.uistyles.first;
@@ -1142,7 +1142,10 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex
        View2D *v2d= &ar->v2d;
        View2DScrollers *scrollers;
        float col[3];
-       int xco, yco, x, y, miny=0, w, em, header, triangle, open;
+       int xco, yco, x, y, miny=0, w, em, header, triangle, open, newcontext= 0;
+
+       if(contextnr >= 0)
+               newcontext= UI_view2d_tab_set(v2d, contextnr);
 
        if(vertical) {
                w= v2d->cur.xmax - v2d->cur.xmin;
@@ -1242,23 +1245,27 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex
 
        /* before setting the view */
        if(vertical) {
-               v2d->keepofs |= V2D_LOCKOFS_X;
-               v2d->keepofs &= ~V2D_LOCKOFS_Y;
+               v2d->keepofs |= V2D_LOCKOFS_X|V2D_KEEPOFS_Y;
+               v2d->keepofs &= ~(V2D_LOCKOFS_Y|V2D_KEEPOFS_X);
                
                // don't jump back when panels close or hide
-               y= MAX2(-y, -v2d->cur.ymin);
+               if(!newcontext)
+                       y= MAX2(-y, -v2d->cur.ymin);
+               else
+                       y= -y;
        }
        else {
-               v2d->keepofs &= ~V2D_LOCKOFS_X;
-               v2d->keepofs |= V2D_LOCKOFS_Y;
+               v2d->keepofs |= V2D_LOCKOFS_Y|V2D_KEEPOFS_X;
+               v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_KEEPOFS_Y);
                
                // don't jump back when panels close or hide
-               x= MAX2(x, v2d->cur.xmax);
+               if(!newcontext)
+                       x= MAX2(x, v2d->cur.xmax);
                y= -y;
        }
 
        // +V2D_SCROLL_HEIGHT is workaround to set the actual height
-       UI_view2d_totRect_set(v2d, x, y+V2D_SCROLL_HEIGHT);
+       UI_view2d_totRect_set(v2d, x+V2D_SCROLL_WIDTH, y+V2D_SCROLL_HEIGHT);
 
        /* set the view */
        UI_view2d_view_ortho(C, v2d);
@@ -1282,6 +1289,8 @@ void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
        // XXX quick hacks for files saved with 2.5 already (i.e. the builtin defaults file)
                // scrollbars for button regions
        ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM); 
+       ar->v2d.keepzoom |= V2D_KEEPZOOM;
+
                // correctly initialised User-Prefs?
        if(!(ar->v2d.align & V2D_ALIGN_NO_POS_Y))
                ar->v2d.flag &= ~V2D_IS_INITIALISED;
index dd6bb09c1e4cc7d306fe2f9fa16385fffabe7f03..817959aef13fbd4e166a5b179ba6e82aad034456 100644 (file)
@@ -603,21 +603,6 @@ void select_connected_scredge(bScreen *sc, ScrEdge *edge)
        }
 }
 
-/* helper call for below, correct buttons view */
-static void screen_test_scale_region(ListBase *regionbase, float facx, float facy)
-{
-       ARegion *ar;
-       
-       for(ar= regionbase->first; ar; ar= ar->next) {
-               if(ar->regiontype==RGN_TYPE_WINDOW) {
-                       ar->v2d.cur.xmin *= facx;
-                       ar->v2d.cur.xmax *= facx;
-                       ar->v2d.cur.ymin *= facy;
-                       ar->v2d.cur.ymax *= facy;
-               }
-       }
-}
-
 /* test if screen vertices should be scaled */
 static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
 {
@@ -668,19 +653,6 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
                        
                        CLAMP(sv->vec.y, 0, winsizey);
                }
-               
-               /* keep buttons view2d same size */
-               for(sa= sc->areabase.first; sa; sa= sa->next) {
-                       SpaceLink *sl;
-                       
-                       if(sa->spacetype==SPACE_BUTS)
-                               screen_test_scale_region(&sa->regionbase, facx, facy);
-                       
-                       for(sl= sa->spacedata.first; sl; sl= sl->next)
-                               if(sl->spacetype==SPACE_BUTS)
-                                       screen_test_scale_region(&sl->regionbase, facx, facy);
-               }
-               
        }
        
        /* test for collapsed areas. This could happen in some blender version... */
index 0f57152cef6a2a90f60361a779efff6fadd13766..71f8642afd489b9518bf9d5bad04e878667225a2 100644 (file)
@@ -155,27 +155,27 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
        buttons_context_compute(C, sbuts);
 
        if(sbuts->mainb == BCONTEXT_SCENE)
-               ED_region_panels(C, ar, vertical, "scene");
+               ED_region_panels(C, ar, vertical, "scene", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_WORLD)
-               ED_region_panels(C, ar, vertical, "world");
+               ED_region_panels(C, ar, vertical, "world", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_OBJECT)
-               ED_region_panels(C, ar, vertical, "object");
+               ED_region_panels(C, ar, vertical, "object", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_DATA)
-               ED_region_panels(C, ar, vertical, "data");
+               ED_region_panels(C, ar, vertical, "data", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_MATERIAL)
-               ED_region_panels(C, ar, vertical, "material");
+               ED_region_panels(C, ar, vertical, "material", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_TEXTURE)
-               ED_region_panels(C, ar, vertical, "texture");
+               ED_region_panels(C, ar, vertical, "texture", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_PARTICLE)
-               ED_region_panels(C, ar, vertical, "particle");
+               ED_region_panels(C, ar, vertical, "particle", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_PHYSICS)
-               ED_region_panels(C, ar, vertical, "physics");
+               ED_region_panels(C, ar, vertical, "physics", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_BONE)
-               ED_region_panels(C, ar, vertical, "bone");
+               ED_region_panels(C, ar, vertical, "bone", sbuts->mainb);
        else if(sbuts->mainb == BCONTEXT_MODIFIER)
-               ED_region_panels(C, ar, vertical, "modifier");
+               ED_region_panels(C, ar, vertical, "modifier", sbuts->mainb);
        else if (sbuts->mainb == BCONTEXT_CONSTRAINT)
-               ED_region_panels(C, ar, vertical, "constraint");
+               ED_region_panels(C, ar, vertical, "constraint", sbuts->mainb);
 
     sbuts->re_align= 0;
        sbuts->mainbo= sbuts->mainb;
index 408d0410067952f63fb41436f7e07d7958028707..e406cc5a56119cb9123af693519573c880f60700 100644 (file)
@@ -100,12 +100,12 @@ static SpaceLink *console_new(const bContext *C)
        ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
        ar->v2d.align |= V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_NEG_Y; /* align bottom left */
        ar->v2d.keepofs |= V2D_LOCKOFS_X;
-       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
        ar->v2d.keeptot= V2D_KEEPTOT_BOUNDS;
        ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
 
        /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
-       //ar->v2d.keepzoom= (V2D_KEEPASPECT|V2D_KEEPZOOM);
+       //ar->v2d.keepzoom= (V2D_KEEPASPECT|V2D_LIMITZOOM);
 
        return (SpaceLink *)sconsole;
 }
index aa879820cfff68e63032122956308f4d24ea88bd..ea640eab090e3abdd71d02a36dc8726d07d67abe 100644 (file)
@@ -106,7 +106,7 @@ static SpaceLink *file_new(const bContext *C)
        ar->regiontype= RGN_TYPE_WINDOW;
        ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
        ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
-       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
        ar->v2d.keeptot= V2D_KEEPTOT_STRICT;
        ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
 
@@ -418,7 +418,7 @@ static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void file_channel_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 static void file_channel_area_listener(ARegion *ar, wmNotifier *wmn)
index 31daee2187eacc285aa9e8e005ceac12aa084e84..222f2142c38013aadc78e59ec614d664ae337bce 100644 (file)
@@ -362,7 +362,7 @@ static void graph_buttons_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void graph_buttons_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 static void graph_region_listener(ARegion *ar, wmNotifier *wmn)
index aaea875a005cf6ec3f2ec4b404e0c56cbc74e422..1506df89c45b703ee19a435400fe9a756610bc94 100644 (file)
@@ -487,7 +487,7 @@ static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void image_buttons_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
index 60d8b17668eae38c368778a68d300424cf1e2982..fe5bbf04af1fedae686803c43eccafa5238b740a 100644 (file)
@@ -120,7 +120,7 @@ static void info_main_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void info_main_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 void info_operatortypes(void)
index 9f458bd812936a1e31332321b8577377e947f36d..703b408aae6a07cf1b9a55c7b1d16ca3e98552a4 100644 (file)
@@ -142,7 +142,7 @@ static SpaceLink *logic_new(const bContext *C)
        ar->v2d.maxzoom= 1.21f;
        
        ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
-       ar->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
+       ar->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT;
        ar->v2d.keeptot= 0;
        
        
@@ -279,7 +279,7 @@ static void logic_buttons_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void logic_buttons_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 /************************* header region **************************/
index 09ca1d6ee19b409be8ec84bf0301eeb8a0aac5dc..6f377aabd4e247307e9bb077ae8df1ad4b6c0d8a 100644 (file)
@@ -364,7 +364,7 @@ static void nla_buttons_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void nla_buttons_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 static void nla_region_listener(ARegion *ar, wmNotifier *wmn)
index 773c61f14d6bc4ac5c82b5dd477f0ecbec35b399..25e1b368ccb65d0f1026cb02b915dbec137c2361 100644 (file)
@@ -118,7 +118,7 @@ static SpaceLink *node_new(const bContext *C)
        ar->v2d.maxzoom= 1.21f;
        
        ar->v2d.scroll= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
-       ar->v2d.keepzoom= V2D_KEEPZOOM|V2D_KEEPASPECT;
+       ar->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT;
        ar->v2d.keeptot= 0;
        
        return (SpaceLink *)snode;
index 4737fb53a1a7b1154c09d5132b8ca06bdc6fe709..f57445a32f1f93dd36046d9bb36ffd1fe21225a8 100644 (file)
@@ -218,7 +218,7 @@ static SpaceLink *outliner_new(const bContext *C)
        
        ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM_O);
        ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
-       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
+       ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_LIMITZOOM|V2D_KEEPASPECT);
        ar->v2d.keeptot= V2D_KEEPTOT_STRICT;
        ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
        
index c7c92b71861c5c30e8a73ab2b19a17c31f263618..084416f3a60783dc5e240a26a96beb62483e834e 100644 (file)
@@ -234,7 +234,7 @@ static void sequencer_buttons_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void sequencer_buttons_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 static void sequencer_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
index c260fe05093f9e9aa490ac917e238a9d09325f65..a9c0d3ff76bb15998083cb2318339ef62c6df60b 100644 (file)
@@ -372,7 +372,7 @@ static void text_properties_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void text_properties_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 /********************* registration ********************/
index fa6bbb476da8a96558d960fede6a4aa2e10fb847..e1f0b537241841a38099187985080eb63d97eec5 100644 (file)
@@ -538,7 +538,7 @@ static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void view3d_buttons_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, NULL);
+       ED_region_panels(C, ar, 1, NULL, -1);
 }
 
 static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
@@ -595,7 +595,7 @@ static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar)
 
 static void view3d_tools_area_draw(const bContext *C, ARegion *ar)
 {
-       ED_region_panels(C, ar, 1, view3d_context_string(C));
+       ED_region_panels(C, ar, 1, view3d_context_string(C), -1);
 }
 
 static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
index dd73d691b6221dae025f51bffd5b7ca8d76fb12e..bc019ef81212d75c0d7e2553257a279b7e5fa224 100644 (file)
@@ -59,15 +59,21 @@ typedef struct View2D {
        
        short around;                                   /* pivot point for transforms (rotate and scale) */
        float cursor[2];                                /* only used in the UV view for now (for 2D-cursor) */
+
+       float *tab_offset;                              /* different offset per tab, for buttons */
+       int tab_num;                                    /* number of tabs stored */
+       int tab_cur;                                    /* current tab */
 } View2D;
 
 /* ---------------------------------- */
 
 /* view zooming restrictions, per axis (v2d->keepzoom) */
        /* zoom is clamped to lie within limits set by minzoom and maxzoom */
-#define V2D_KEEPZOOM           0x0001
+#define V2D_LIMITZOOM          0x0001
        /* aspect ratio is maintained on view resize */
 #define V2D_KEEPASPECT         0x0002
+       /* zoom is kept when the window resizes */
+#define V2D_KEEPZOOM           0x0004
        /* zooming on x-axis is not allowed */
 #define V2D_LOCKZOOM_X         0x0100
        /* zooming on y-axis is not allowed */
@@ -78,6 +84,10 @@ typedef struct View2D {
 #define V2D_LOCKOFS_X  (1<<1)
        /* panning on y-axis is not allowed */
 #define V2D_LOCKOFS_Y  (1<<2)
+       /* on resize, keep the x offset */
+#define V2D_KEEPOFS_X  (1<<3)
+       /* on resize, keep the y offset */
+#define V2D_KEEPOFS_Y  (1<<4)
 
 /* view extent restrictions (v2d->keeptot) */
        /* 'cur' view can be out of extents of 'tot' */