Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / source / blender / editors / screen / area.c
index 7e79849..435330a 100644 (file)
@@ -84,19 +84,19 @@ static void region_draw_emboss(ARegion *ar, rcti *scirct)
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        
        /* right  */
-       glColor4ub(0,0,0, 50);
+       glColor4ub(0,0,0, 30);
        sdrawline(rect.xmax, rect.ymin, rect.xmax, rect.ymax);
        
        /* bottom  */
-       glColor4ub(0,0,0, 80);
+       glColor4ub(0,0,0, 30);
        sdrawline(rect.xmin, rect.ymin, rect.xmax, rect.ymin);
        
        /* top  */
-       glColor4ub(255,255,255, 60);
+       glColor4ub(255,255,255, 30);
        sdrawline(rect.xmin, rect.ymax, rect.xmax, rect.ymax);
 
        /* left  */
-       glColor4ub(255,255,255, 50);
+       glColor4ub(255,255,255, 30);
        sdrawline(rect.xmin, rect.ymin, rect.xmin, rect.ymax);
        
        glDisable( GL_BLEND );
@@ -169,24 +169,33 @@ void ED_area_overdraw_flush(ScrArea *sa, ARegion *ar)
 
 static void area_draw_azone(short x1, short y1, short x2, short y2)
 {
-       int dx= floor(0.3f*(x2-x1));
-       int dy= floor(0.3f*(y2-y1));
-       
-       glColor4ub(255, 255, 255, 180);
-       fdrawline(x1, y2, x2, y1);
-       glColor4ub(255, 255, 255, 130);
-       fdrawline(x1, y2-dy, x2-dx, y1);
-       glColor4ub(255, 255, 255, 80);
-       fdrawline(x1, y2-2*dy, x2-2*dx, y1);
-       
-       glColor4ub(0, 0, 0, 210);
-       fdrawline(x1, y2+1, x2+1, y1);
-       glColor4ub(0, 0, 0, 180);
-       fdrawline(x1, y2-dy+1, x2-dx+1, y1);
-       glColor4ub(0, 0, 0, 150);
-       fdrawline(x1, y2-2*dy+1, x2-2*dx+1, y1);
-}
+       int dx= 0.3f*(x2-x1);
+       int dy= 0.3f*(y2-y1);
+       int i;
+
+       glEnable(GL_BLEND);
+
+       glColor4f(0.0f, 0.0f, 0.0f, 0.35f);
+
+       glBegin(GL_TRIANGLES);
+       glVertex2f(x1, y1);
+       glVertex2f(x2, y1);
+       glVertex2f(x1, y2);
+       glEnd();
+
+       glEnable(GL_LINE_SMOOTH);
+
+       glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
 
+       x2 += (x2 > x1)? -1: 1;
+       y2 += (y2 > y1)? -1: 1;
+
+       for(i=0; i<4; i++)
+               fdrawline(x1, y2-i*dy, x2-i*dx, y1);
+
+       glDisable(GL_LINE_SMOOTH);
+       glDisable(GL_BLEND);
+}
 
 static void region_draw_azone_icon(AZone *az)
 {
@@ -222,6 +231,54 @@ static void region_draw_azone_icon(AZone *az)
        sdrawline(midx-2, midy, midx+3, midy);
 }
 
+static void draw_azone_plus(float x1, float y1, float x2, float y2)
+{
+       float width = 2.0f;
+       float pad = 4.0f;
+
+       glRectf((x1 + x2 - width)*0.5f, y1 + pad, (x1 + x2 + width)*0.5f, y2 - pad);
+       glRectf(x1 + pad, (y1 + y2 - width)*0.5f, (x1 + x2 - width)*0.5f, (y1 + y2 + width)*0.5f);
+       glRectf((x1 + x2 + width)*0.5f, (y1 + y2 - width)*0.5f, x2 - pad, (y1 + y2 + width)*0.5f);
+}
+
+static void region_draw_azone_tab_plus(AZone *az)
+{
+       float yofs= 0.0f;
+       
+       glEnable(GL_BLEND);
+       
+       /* add code to draw region hidden as 'too small' */
+       switch(az->edge) {
+               case AE_TOP_TO_BOTTOMRIGHT:
+                       uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
+                       yofs= 0.3f;
+                       break;
+               case AE_BOTTOM_TO_TOPLEFT:
+                       uiSetRoundBox(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+                       yofs= 0.3f;
+                       break;
+               case AE_LEFT_TO_TOPRIGHT:
+                       uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+                       yofs= 0.0f;
+                       break;
+               case AE_RIGHT_TO_TOPLEFT:
+                       uiSetRoundBox(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+                       yofs= 0.0f;
+                       break;
+       }
+
+       glColor4f(0.0f, 0.0f, 0.0f, 0.25f);
+       uiRoundBox((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f);
+
+       UI_ThemeColorShade(TH_BACK, 20);
+       draw_azone_plus((float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2);
+
+       glColor4f(0.0f, 0.0f, 0.0f, 0.35f);
+       uiRoundRect((float)az->x1, (float)az->y1+yofs, (float)az->x2, (float)az->y2+yofs, 4.0f);
+       
+       glDisable(GL_BLEND);
+}
+
 static void region_draw_azone_tab(AZone *az)
 {
        float col[3];
@@ -320,13 +377,14 @@ void ED_area_overdraw(bContext *C)
                                        if(az->ar) {
                                                /* only display tab or icons when the region is hidden */
                                                if (az->ar->flag & (RGN_FLAG_HIDDEN|RGN_FLAG_TOO_SMALL)) {
-                                       
-                                                       if(G.rt==2)
+                                                       if(G.rt==3)
+                                                               region_draw_azone_icon(az);
+                                                       else if(G.rt==2)
                                                                region_draw_azone_tria(az);
                                                        else if(G.rt==1)
                                                                region_draw_azone_tab(az);
                                                        else
-                                                               region_draw_azone_icon(az);
+                                                               region_draw_azone_tab_plus(az);
                                                }
                                        }
                                }
@@ -414,6 +472,9 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
        
        /* note; this sets state, so we can use wmOrtho and friends */
        wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct);
+
+       ar->do_draw= 0;
+       memset(&ar->drawrct, 0, sizeof(ar->drawrct));
        
        UI_SetTheme(sa?sa->spacetype:0, ar->type?ar->type->regionid:0);
        
@@ -433,14 +494,11 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
        
        uiFreeInactiveBlocks(C, &ar->uiblocks);
        
-       if(sa)
-               region_draw_emboss(ar, &winrct);
-       
        /* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */
        ED_region_pixelspace(ar);
-       
-       ar->do_draw= 0;
-       memset(&ar->drawrct, 0, sizeof(ar->drawrct));
+
+       if(sa)
+               region_draw_emboss(ar, &winrct);
 }
 
 /* **********************************
@@ -659,8 +717,53 @@ static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar)
        }
 }
 
+#define AZONEPAD_TAB_PLUSW     16
+#define AZONEPAD_TAB_PLUSH     16
+
+/* region already made zero sized, in shape of edge */
+static void region_azone_tab_plus(ScrArea *sa, AZone *az, ARegion *ar)
+{
+       AZone *azt;
+       int tot= 0, add;
+       
+       for(azt= sa->actionzones.first; azt; azt= azt->next) {
+               if(azt->edge == az->edge) tot++;
+       }
+       
+       switch(az->edge) {
+               case AE_TOP_TO_BOTTOMRIGHT:
+                       if(ar->winrct.ymax == sa->totrct.ymin) add= 1; else add= 0;
+                       az->x1= ar->winrct.xmax - 2.5*AZONEPAD_TAB_PLUSW;
+                       az->y1= ar->winrct.ymax - add;
+                       az->x2= ar->winrct.xmax - 1.5*AZONEPAD_TAB_PLUSW;
+                       az->y2= ar->winrct.ymax - add + AZONEPAD_TAB_PLUSH;
+                       break;
+               case AE_BOTTOM_TO_TOPLEFT:
+                       az->x1= ar->winrct.xmax - 2.5*AZONEPAD_TAB_PLUSW;
+                       az->y1= ar->winrct.ymin - AZONEPAD_TAB_PLUSH;
+                       az->x2= ar->winrct.xmax - 1.5*AZONEPAD_TAB_PLUSW;
+                       az->y2= ar->winrct.ymin;
+                       break;
+               case AE_LEFT_TO_TOPRIGHT:
+                       az->x1= ar->winrct.xmin + 1 - AZONEPAD_TAB_PLUSH;
+                       az->y1= ar->winrct.ymax - 2.5*AZONEPAD_TAB_PLUSW;
+                       az->x2= ar->winrct.xmin + 1;
+                       az->y2= ar->winrct.ymax - 1.5*AZONEPAD_TAB_PLUSW;
+                       break;
+               case AE_RIGHT_TO_TOPLEFT:
+                       az->x1= ar->winrct.xmax - 1;
+                       az->y1= ar->winrct.ymax - 2.5*AZONEPAD_TAB_PLUSW;
+                       az->x2= ar->winrct.xmax - 1 + AZONEPAD_TAB_PLUSH;
+                       az->y2= ar->winrct.ymax - 1.5*AZONEPAD_TAB_PLUSW;
+                       break;
+       }
+       /* rect needed for mouse pointer test */
+       BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
+}      
+
+
 #define AZONEPAD_TABW  18
-#define AZONEPAD_TABH  7
+#define AZONEPAD_TABH  6
 
 /* region already made zero sized, in shape of edge */
 static void region_azone_tab(ScrArea *sa, AZone *az, ARegion *ar)
@@ -760,12 +863,14 @@ static void region_azone_initialize(ScrArea *sa, ARegion *ar, AZEdge edge)
        az->edge= edge;
        
        if (ar->flag & (RGN_FLAG_HIDDEN|RGN_FLAG_TOO_SMALL)) {
-               if(G.rt==2)
+               if(G.rt==3)
+                       region_azone_icon(sa, az, ar);
+               else if(G.rt==2)
                        region_azone_tria(sa, az, ar);
                else if(G.rt==1)
                        region_azone_tab(sa, az, ar);
                else
-                       region_azone_icon(sa, az, ar);
+                       region_azone_tab_plus(sa, az, ar);
        } else {
                region_azone_edge(az, ar);
        }
@@ -1450,28 +1555,15 @@ 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, const char *context, int contextnr)
+static void region_panels_layout(const bContext *C, ARegion *ar, int vertical, const char *context, int w, int em, int *r_x, int *r_y)
 {
        ScrArea *sa= CTX_wm_area(C);
        uiStyle *style= UI_GetStyle();
        uiBlock *block;
        PanelType *pt;
        Panel *panel;
-       View2D *v2d= &ar->v2d;
-       View2DScrollers *scrollers;
-       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;
-               em= (ar->type->prefsizex)? UI_UNIT_Y/2: UI_UNIT_Y;
-       }
-       else {
-               w= UI_PANEL_WIDTH;
-               em= (ar->type->prefsizex)? UI_UNIT_Y/2: UI_UNIT_Y;
-       }
+       int x, y, miny=0, xco, yco;
+       int open, header, triangle;
 
        x= 0;
        y= -style->panelouter;
@@ -1479,9 +1571,6 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
        /* create panels */
        uiBeginPanels(C, ar);
 
-       /* set view2d view matrix for scrolling (without scrollers) */
-       UI_view2d_view_ortho(v2d);
-
        for(pt= ar->type->paneltypes.first; pt; pt= pt->next) {
                /* verify context */
                if(context)
@@ -1566,6 +1655,40 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
                y= UI_PANEL_WIDTH;
        }
 
+       uiEndPanels(C, ar);
+
+       *r_x = x;
+       *r_y = y;
+}
+
+void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *context, int contextnr)
+{
+       View2D *v2d= &ar->v2d;
+       View2DScrollers *scrollers;
+       int x, y, w, em, newcontext= 0, need_scrollers;
+
+       if(contextnr >= 0)
+               newcontext= UI_view2d_tab_set(v2d, contextnr);
+
+       if(vertical) {
+               w= v2d->cur.xmax - v2d->cur.xmin;
+               em= (ar->type->prefsizex)? UI_UNIT_Y/2: UI_UNIT_Y;
+       }
+       else {
+               w= UI_PANEL_WIDTH;
+               em= (ar->type->prefsizex)? UI_UNIT_Y/2: UI_UNIT_Y;
+       }
+
+       /* try to draw without scrollbars */
+       UI_view2d_view_ortho(v2d);
+
+       region_panels_layout(C, ar, vertical, context, ar->winx, em, &x, &y);
+
+       /* if it doesn't fit, draw again in smaller space with scrollers */
+       need_scrollers = (abs(y) > ar->winy);
+       if(need_scrollers)
+               region_panels_layout(C, ar, vertical, context, ar->winx-V2D_SCROLL_WIDTH, em, &x, &y);
+
        /* clear */
        UI_ThemeClearColor((ar->type->regionid == RGN_TYPE_PREVIEW)?TH_PREVIEW_BACK:TH_BACK);
        glClear(GL_COLOR_BUFFER_BIT);
@@ -1575,8 +1698,9 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
                /* only allow scrolling in vertical direction */
                v2d->keepofs |= V2D_LOCKOFS_X|V2D_KEEPOFS_Y;
                v2d->keepofs &= ~(V2D_LOCKOFS_Y|V2D_KEEPOFS_X);
-               v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
-               v2d->scroll &= ~V2D_SCROLL_VERTICAL_HIDE;
+               v2d->scroll &= ~(V2D_SCROLL_HORIZONTAL_HIDE|V2D_SCROLL_VERTICAL_HIDE);
+               if(!need_scrollers)
+                       v2d->scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
                
                // don't jump back when panels close or hide
                if(!newcontext)
@@ -1591,8 +1715,9 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
                v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_LOCKOFS_Y|V2D_KEEPOFS_X|V2D_KEEPOFS_Y);
                //v2d->keepofs |= V2D_LOCKOFS_Y|V2D_KEEPOFS_X;
                //v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_KEEPOFS_Y);
-               v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
-               v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_HIDE;
+               v2d->scroll &= ~(V2D_SCROLL_HORIZONTAL_HIDE|V2D_SCROLL_VERTICAL_HIDE);
+               if(!need_scrollers)
+                       v2d->scroll |= V2D_SCROLL_VERTICAL_HIDE;
                
                // don't jump back when panels close or hide
                if(!newcontext)
@@ -1602,20 +1727,23 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
 
        // +V2D_SCROLL_HEIGHT is workaround to set the actual height
        UI_view2d_totRect_set(v2d, x+V2D_SCROLL_WIDTH, y+V2D_SCROLL_HEIGHT);
+       UI_view2d_totRect_set(v2d, x+V2D_SCROLL_WIDTH, y+V2D_SCROLL_HEIGHT);
 
        /* set the view */
        UI_view2d_view_ortho(v2d);
 
        /* this does the actual drawing! */
-       uiEndPanels(C, ar);
+       uiDrawPanels(C, ar);
        
        /* restore view matrix */
        UI_view2d_view_restore(C);
        
        /* scrollers */
-       scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
-       UI_view2d_scrollers_draw(C, v2d, scrollers);
-       UI_view2d_scrollers_free(scrollers);
+       if(need_scrollers) {
+               scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+               UI_view2d_scrollers_draw(C, v2d, scrollers);
+               UI_view2d_scrollers_free(scrollers);
+       }
 }
 
 void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)