UI: buttons that open menus now align to the menu rather than looking disconnected.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 4 Oct 2012 20:12:05 +0000 (20:12 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 4 Oct 2012 20:12:05 +0000 (20:12 +0000)
Also fixed some cases where the menu was offset 1 or 2 pixels wrong, though not
quite all of them, still off by 1 pixel sometimes.

http://www.pasteall.org/pic/show.php?id=38478

source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_widgets.c

index 32132f4..5d2709f 100644 (file)
@@ -421,7 +421,6 @@ void    uiBlockSetDirection(uiBlock *block, int direction);
 void    uiBlockFlipOrder(uiBlock *block);
 void    uiBlockSetFlag(uiBlock *block, int flag);
 void    uiBlockClearFlag(uiBlock *block, int flag);
-void    uiBlockSetXOfs(uiBlock *block, int xofs);
 
 int     uiButGetRetVal(uiBut *but);
 
index 810cbc2..2c00e39 100644 (file)
@@ -996,24 +996,20 @@ void ui_fontscale(short *points, float aspect)
 /* project button or block (but==NULL) to pixels in regionspace */
 static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, uiBut *but)
 {
-       float gx, gy;
-       float getsizex, getsizey;
+       rctf rectf = (but)? but->rect: block->rect;
        
-       getsizex = ar->winx;
-       getsizey = ar->winy;
+       ui_block_to_window_fl(ar, block, &rectf.xmin, &rectf.ymin);
+       ui_block_to_window_fl(ar, block, &rectf.xmax, &rectf.ymax);
 
-       gx = (but ? but->rect.xmin : block->rect.xmin) + (block->panel ? block->panel->ofsx : 0.0f);
-       gy = (but ? but->rect.ymin : block->rect.ymin) + (block->panel ? block->panel->ofsy : 0.0f);
-       
-       rect->xmin = floorf(getsizex * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] + block->winmat[3][0])));
-       rect->ymin = floorf(getsizey * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] + block->winmat[3][1])));
-       
-       gx = (but ? but->rect.xmax : block->rect.xmax) + (block->panel ? block->panel->ofsx : 0.0f);
-       gy = (but ? but->rect.ymax : block->rect.ymax) + (block->panel ? block->panel->ofsy : 0.0f);
-       
-       rect->xmax = floorf(getsizex * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] + block->winmat[3][0])));
-       rect->ymax = floorf(getsizey * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] + block->winmat[3][1])));
+       rectf.xmin -= ar->winrct.xmin;
+       rectf.ymin -= ar->winrct.ymin;
+       rectf.xmax -= ar->winrct.xmin;
+       rectf.ymax -= ar->winrct.ymin;
 
+       rect->xmin = floorf(rectf.xmin);
+       rect->ymin = floorf(rectf.ymin);
+       rect->xmax = floorf(rectf.xmax);
+       rect->ymax = floorf(rectf.ymax);
 }
 
 /* uses local copy of style, to scale things down, and allow widgets to change stuff */
@@ -2160,8 +2156,6 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, shor
                wm_subwindow_getmatrix(window, region->swinid, block->winmat);
                wm_subwindow_getsize(window, region->swinid, &getsizex, &getsizey);
 
-               /* TODO - investigate why block->winmat[0][0] is negative
-                * in the image view when viewRedrawForce is called */
                block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]);
        }
        else {
@@ -3423,11 +3417,6 @@ void uiBlockClearFlag(uiBlock *block, int flag)
        block->flag &= ~flag;
 }
 
-void uiBlockSetXOfs(uiBlock *block, int xofs)
-{
-       block->xofs = xofs;
-}
-
 void uiButSetFlag(uiBut *but, int flag)
 {
        but->flag |= flag;
index bfa9cc2..60e4c2a 100644 (file)
@@ -2167,6 +2167,16 @@ static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
        }
 }
 
+int ui_button_open_menu_direction(uiBut *but)
+{
+       uiHandleButtonData *data = but->active;
+
+       if (data && data->menu)
+               return data->menu->direction;
+       
+       return 0;
+}
+
 /* ***************** events for different button types *************** */
 
 static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event)
index e345296..b4b0686 100644 (file)
@@ -315,7 +315,6 @@ struct uiBlock {
        char tooltipdisabled;       /* to avoid tooltip after click */
        char endblock;              /* uiEndBlock done? */
 
-       float xofs, yofs;           /* offset to parent button */
        eBlockBoundsCalc bounds_type;  /* for doing delayed */
        int mx, my;
        int bounds, minbounds;      /* for doing delayed */
@@ -419,6 +418,9 @@ struct uiPopupBlockHandle {
        int menuretval;
        float retvalue;
        float retvec[4];
+
+       /* menu direction */
+       int direction;
 };
 
 uiBlock *ui_block_func_COLOR(struct bContext *C, uiPopupBlockHandle *handle, void *arg_but);
@@ -481,6 +483,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wc
 extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
 extern void ui_button_active_free(const struct bContext *C, uiBut *but);
 extern int ui_button_is_active(struct ARegion *ar);
+extern int ui_button_open_menu_direction(uiBut *but);
 
 /* interface_widgets.c */
 void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);
index 605233c..4dafb4b 100644 (file)
@@ -1341,6 +1341,14 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
        ui_block_to_window_fl(butregion, but->block, &butrct.xmin, &butrct.ymin);
        ui_block_to_window_fl(butregion, but->block, &butrct.xmax, &butrct.ymax);
 
+       /* widget_roundbox_set has this correction too, keep in sync */
+       if (but->type != PULLDOWN) {
+               if (but->flag & UI_BUT_ALIGN_TOP)
+                       butrct.ymax += 1.0f;
+               if (but->flag & UI_BUT_ALIGN_LEFT)
+                       butrct.xmin -= 1.0f;
+       }
+
        /* calc block rect */
        if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
                if (block->buttons.first) {
@@ -1467,9 +1475,6 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
                        }
                }
                
-               /* apply requested offset in the block */
-               xof += block->xofs / block->aspect;
-               yof += block->yofs / block->aspect;
 #if 0
                /* clamp to window bounds, could be made into an option if its ever annoying */
                if (     (offscreen = (block->rect.ymin + yof)) < 0) yof -= offscreen;   /* bottom */
@@ -1659,12 +1664,10 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
 
        /* if this is being created from a button */
        if (but) {
-               if (ELEM(but->type, BLOCK, PULLDOWN))
-                       block->xofs = -2;   /* for proper alignment */
-
                block->aspect = but->block->aspect;
 
                ui_block_position(window, butregion, but, block);
+               handle->direction = block->direction;
        }
        else {
                /* keep a list of these, needed for pulldown menus */
index 06d4715..3fc2030 100644 (file)
@@ -2702,16 +2702,16 @@ static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat
        *wcol = wcol_backup;
 }
 
-static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
+static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
 {
        if (state & UI_ACTIVE) {
                uiWidgetBase wtb;
-               float rad = 0.5f * BLI_rcti_size_y(rect);  /* 4.0f */
-               
+               float rad = 0.25f * BLI_rcti_size_y(rect);  /* 4.0f */
+
                widget_init(&wtb);
-               
+
                /* half rounded */
-               round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+               round_box_edges(&wtb, roundboxalign, rect, rad);
                
                widgetbase_draw(&wtb, wcol);
        }
@@ -3048,9 +3048,12 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
 
 static int widget_roundbox_set(uiBut *but, rcti *rect)
 {
+       int roundbox = UI_CNR_ALL;
+
        /* alignment */
-       if (but->flag & UI_BUT_ALIGN) {
+       if ((but->flag & UI_BUT_ALIGN) && but->type != PULLDOWN) {
                
+               /* ui_block_position has this correction too, keep in sync */
                if (but->flag & UI_BUT_ALIGN_TOP)
                        rect->ymax += 1;
                if (but->flag & UI_BUT_ALIGN_LEFT)
@@ -3058,27 +3061,50 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
                
                switch (but->flag & UI_BUT_ALIGN) {
                        case UI_BUT_ALIGN_TOP:
-                               return UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT;
+                               roundbox = UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT;
+                               break;
                        case UI_BUT_ALIGN_DOWN:
-                               return UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
+                               roundbox = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
+                               break;
                        case UI_BUT_ALIGN_LEFT:
-                               return UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT;
+                               roundbox = UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT;
+                               break;
                        case UI_BUT_ALIGN_RIGHT:
-                               return UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT;
+                               roundbox = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT;
+                               break;
                        case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT:
-                               return UI_CNR_TOP_LEFT;
+                               roundbox = UI_CNR_TOP_LEFT;
+                               break;
                        case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT:
-                               return UI_CNR_TOP_RIGHT;
+                               roundbox = UI_CNR_TOP_RIGHT;
+                               break;
                        case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT:
-                               return UI_CNR_BOTTOM_LEFT;
+                               roundbox = UI_CNR_BOTTOM_LEFT;
+                               break;
                        case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT:
-                               return UI_CNR_BOTTOM_RIGHT;
+                               roundbox = UI_CNR_BOTTOM_RIGHT;
+                               break;
                        default:
-                               return 0;
+                               roundbox = 0;
+                               break;
                }
        }
 
-       return UI_CNR_ALL;
+       /* align with open menu */
+       if (but->active) {
+               int direction = ui_button_open_menu_direction(but);
+
+               if (direction == UI_TOP)
+                       roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_TOP_LEFT);
+               else if (direction == UI_DOWN)
+                       roundbox &= ~(UI_CNR_BOTTOM_RIGHT|UI_CNR_BOTTOM_LEFT);
+               else if (direction == UI_LEFT)
+                       roundbox &= ~(UI_CNR_TOP_LEFT|UI_CNR_BOTTOM_LEFT);
+               else if (direction == UI_RIGHT)
+                       roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_BOTTOM_RIGHT);
+       }
+
+       return roundbox;
 }
 
 /* conversion from old to new buttons, so still messy */