style cleanup: spaces -> tabs
[blender.git] / source / blender / editors / interface / interface_panel.c
index 3eb4026f0e0ea0d3442d631d1802d5a26a50e131..1b2034d6e4058db23f50fc6e1f7e4ad69d788ae9 100644 (file)
@@ -112,7 +112,7 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
        else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
                return BUT_VERTICAL;
        else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
-               return BUT_VERTICAL; 
+               return BUT_VERTICAL;
        else if (ELEM3(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS))
                return BUT_VERTICAL;
        
@@ -133,8 +133,6 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
                        if (sbuts->re_align || sbuts->mainbo != sbuts->mainb)
                                return 1;
        }
-       else if (ar->regiontype == RGN_TYPE_UI)
-               return 1;
        else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
                return 1;
        else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
@@ -164,15 +162,20 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
 
 /****************************** panels ******************************/
 
-static void panels_collapse_all(ScrArea *sa, ARegion *ar)
+static void panels_collapse_all(ScrArea *sa, ARegion *ar, Panel *from_pa)
 {
        Panel *pa;
+       PanelType *pt, *from_pt;
        int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY);
 
        for (pa = ar->panels.first; pa; pa = pa->next) {
-               if (pa->type && !(pa->type->flag & PNL_NO_HEADER)) {
-                       pa->flag = flag;
-               }
+               pt = pa->type;
+               from_pt = from_pa->type;
+
+               /* close panels with headers in the same context */
+               if (pt && from_pt && !(pt->flag & PNL_NO_HEADER))
+                       if (!pt->context[0] || strcmp(pt->context, from_pt->context) == 0)
+                               pa->flag = flag;
        }
 }
 
@@ -244,6 +247,14 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int
                }
        }
 
+       /* Do not allow closed panels without headers! Else user could get "disappeared" UI! */
+       if ((pt->flag & PNL_NO_HEADER) && (pa->flag & PNL_CLOSED)) {
+               pa->flag &= ~PNL_CLOSED;
+               /* Force update of panels' positions! */
+               pa->sizex = 0;
+               pa->sizey = 0;
+       }
+
        BLI_strncpy(pa->drawname, drawname, UI_MAX_NAME_STR);
 
        /* if a new panel is added, we insert it right after the panel
@@ -499,7 +510,6 @@ static void rectf_scale(rctf *rect, const float scale)
 /* panel integrated in buttonswindow, tool/property lists etc */
 void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
 {
-       bTheme *btheme = UI_GetTheme();
        Panel *panel = block->panel;
        rcti headrect;
        rctf itemrect;
@@ -520,11 +530,10 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
                float y = headrect.ymax;
 
                glEnable(GL_BLEND);
-
-               if (btheme->tui.panel.show_header) {
+               
+               if (UI_GetThemeValue(TH_PANEL_SHOW_HEADER)) {
                        /* draw with background color */
-                       glEnable(GL_BLEND);
-                       glColor4ubv((unsigned char *)btheme->tui.panel.header);
+                       UI_ThemeColor4(TH_PANEL_HEADER);
                        glRectf(minx, headrect.ymin + 1, maxx, y);
 
                        fdrawline(minx, y, maxx, y);
@@ -539,7 +548,6 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
                        fdrawline(minx, y, maxx, y);
                        glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
                        fdrawline(minx, y - 1, maxx, y - 1);
-                       glDisable(GL_BLEND);
                }
 
                glDisable(GL_BLEND);
@@ -581,6 +589,14 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
                        uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8);
                }
                
+               /* panel backdrop */
+               if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
+                       /* draw with background color */
+                       glEnable(GL_BLEND);
+                       UI_ThemeColor4(TH_PANEL_BACK);
+                       glRecti(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+               }
+               
                if (panel->control & UI_PNL_SCALE)
                        ui_draw_panel_scalewidget(rect);
        }
@@ -801,8 +817,8 @@ static void ui_panels_size(ScrArea *sa, ARegion *ar, int *x, int *y)
 {
        Panel *pa;
        int align = panel_aligned(sa, ar);
-       int sizex = UI_PANEL_WIDTH;
-       int sizey = UI_PANEL_WIDTH;
+       int sizex = 0;
+       int sizey = 0;
 
        /* compute size taken up by panels, for setting in view2d */
        for (pa = ar->panels.first; pa; pa = pa->next) {
@@ -823,6 +839,11 @@ static void ui_panels_size(ScrArea *sa, ARegion *ar, int *x, int *y)
                }
        }
 
+       if (sizex == 0)
+               sizex = UI_PANEL_WIDTH;
+       if (sizey == 0)
+               sizey = -UI_PANEL_WIDTH;
+       
        *x = sizex;
        *y = sizey;
 }
@@ -854,7 +875,7 @@ static void ui_do_animate(const bContext *C, Panel *panel)
 void uiBeginPanels(const bContext *UNUSED(C), ARegion *ar)
 {
        Panel *pa;
-  
+
        /* set all panels as inactive, so that at the end we know
         * which ones were used */
        for (pa = ar->panels.first; pa; pa = pa->next) {
@@ -904,6 +925,7 @@ void uiEndPanels(const bContext *C, ARegion *ar, int *x, int *y)
 
        /* re-align, possibly with animation */
        if (panels_re_align(sa, ar, &pa)) {
+               /* XXX code never gets here... PNL_ANIM_ALIGN flag is never set */
                if (pa)
                        panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
                else
@@ -944,6 +966,25 @@ void uiDrawPanels(const bContext *C, ARegion *ar)
        }
 }
 
+void uiScalePanels(ARegion *ar, float new_width)
+{
+       uiBlock *block;
+       uiBut *but;
+       
+       for (block = ar->uiblocks.first; block; block = block->next) {
+               if (block->panel) {
+                       float fac = new_width / (float)block->panel->sizex;
+                       printf("scaled %f\n", fac);
+                       block->panel->sizex = new_width;
+                       
+                       for (but = block->buttons.first; but; but = but->next) {
+                               but->rect.xmin *= fac;
+                               but->rect.xmax *= fac;
+                       }
+               }
+       }
+}
+
 /* ------------ panel merging ---------------- */
 
 static void check_panel_overlap(ARegion *ar, Panel *panel)
@@ -975,7 +1016,7 @@ static void check_panel_overlap(ARegion *ar, Panel *panel)
 
 /************************ panel dragging ****************************/
 
-static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel)
+static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
 {
        uiHandlePanelData *data = panel->activedata;
        ScrArea *sa = CTX_wm_area(C);
@@ -1020,7 +1061,7 @@ static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel)
 
 /* this function is supposed to call general window drawing too */
 /* also it supposes a block has panel, and isn't a menu */
-static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event)
+static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event, int ctrl)
 {
        ScrArea *sa = CTX_wm_area(C);
        ARegion *ar = CTX_wm_region(C);
@@ -1053,6 +1094,9 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
                        ED_region_tag_redraw(ar);
                }
                else {  /* collapse */
+                       if (ctrl)
+                               panels_collapse_all(sa, ar, block->panel);
+
                        if (block->panel->flag & PNL_CLOSED) {
                                block->panel->flag &= ~PNL_CLOSED;
                                /* snap back up so full panel aligns with screen edge */
@@ -1090,9 +1134,8 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
 /* XXX should become modal keymap */
 /* AKey is opening/closing panels, independent of button state now */
 
-int ui_handler_panel_region(bContext *C, wmEvent *event)
+int ui_handler_panel_region(bContext *C, const wmEvent *event)
 {
-       ScrArea *sa = CTX_wm_area(C);
        ARegion *ar = CTX_wm_region(C);
        uiBlock *block;
        Panel *pa;
@@ -1119,6 +1162,9 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
                        if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx)
                                inside_header = 1;
                }
+               else if (block->rect.xmin > mx || block->rect.xmax < mx) {
+                       /* outside left/right side */
+               }
                else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
                        inside_header = 1;
                }
@@ -1135,16 +1181,17 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
                }
                
                /* XXX hardcoded key warning */
-               if (inside && event->val == KM_PRESS) {
+               if ((inside || inside_header) && event->val == KM_PRESS) {
                        if (event->type == AKEY && !ELEM4(KM_MOD_FIRST, event->ctrl, event->oskey, event->shift, event->alt)) {
                                
                                if (pa->flag & PNL_CLOSEDY) {
                                        if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my))
-                                               ui_handle_panel_header(C, block, mx, my, event->type);
+                                               ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
                                }
                                else
-                                       ui_handle_panel_header(C, block, mx, my, event->type);
+                                       ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl);
                                
+                               retval = WM_UI_HANDLER_BREAK;
                                continue;
                        }
                }
@@ -1160,7 +1207,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
                                /* open close on header */
                                if (ELEM(event->type, RETKEY, PADENTER)) {
                                        if (inside_header) {
-                                               ui_handle_panel_header(C, block, mx, my, RETKEY);
+                                               ui_handle_panel_header(C, block, mx, my, RETKEY, event->ctrl);
                                                retval = WM_UI_HANDLER_BREAK;
                                                break;
                                        }
@@ -1170,9 +1217,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
                                        retval = WM_UI_HANDLER_BREAK;
                                        
                                        if (inside_header) {
-                                               if (event->ctrl)
-                                                       panels_collapse_all(sa, ar);
-                                               ui_handle_panel_header(C, block, mx, my, 0);
+                                               ui_handle_panel_header(C, block, mx, my, 0, event->ctrl);
                                                retval = WM_UI_HANDLER_BREAK;
                                                break;
                                        }
@@ -1232,7 +1277,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
 /**************** window level modal panel interaction **************/
 
 /* note, this is modal handler and should not swallow events for animation */
-static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
+static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
 {
        Panel *panel = userdata;
        uiHandlePanelData *data = panel->activedata;