Commit: 33bed11248884334754f9744312e29af8da0b99e
Author: Julian Eisel
Date:   Fri Oct 6 17:00:58 2017 +0200
Branches: topbar
https://developer.blender.org/rB33bed11248884334754f9744312e29af8da0b99e

Add 'x' icon to active workspace tab to delete workspace

Icon could be a bit nicer, but is consistent with other places in the
UI. Code is also a bit hacky, as usual in interface handling...

===================================================================

M       source/blender/editors/interface/interface.c
M       source/blender/editors/interface/interface_handlers.c
M       source/blender/editors/interface/interface_intern.h
M       source/blender/editors/interface/interface_templates.c
M       source/blender/editors/screen/workspace_edit.c
M       source/blender/windowmanager/WM_types.h
M       source/blender/windowmanager/intern/wm_event_system.c

===================================================================

diff --git a/source/blender/editors/interface/interface.c 
b/source/blender/editors/interface/interface.c
index 1cd6177c0bd..00f25a7fb68 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2005,7 +2005,7 @@ static bool ui_but_icon_extra_is_visible_text_clear(const 
uiBut *but)
 
 static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but)
 {
-       BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+       BLI_assert(ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_TAB));
        return ((but->editstr == NULL) &&
                (but->drawstr[0] != '\0') &&
                (but->flag & UI_BUT_VALUE_CLEAR));
@@ -2048,6 +2048,11 @@ uiButExtraIconType ui_but_icon_extra_get(uiBut *but)
                                return UI_BUT_ICONEXTRA_EYEDROPPER;
                        }
                        break;
+               case UI_BTYPE_TAB:
+                       if (ui_but_icon_extra_is_visible_search_unlink(but)) {
+                               return UI_BUT_ICONEXTRA_CLEAR;
+                       }
+                       break;
                default:
                        break;
        }
@@ -3121,6 +3126,16 @@ void ui_block_cm_to_display_space_range(uiBlock *block, 
float *min, float *max)
        *max = max_fff(UNPACK3(pixel));
 }
 
+static uiBut *ui_but_alloc(const eButType type)
+{
+       switch (type) {
+               case UI_BTYPE_TAB:
+                       return MEM_callocN(sizeof(uiButTab), "uiButTab");
+               default:
+                       return MEM_callocN(sizeof(uiBut), "uiBut");
+       }
+}
+
 /**
  * \brief ui_def_but is the function that draws many button types
  *
@@ -3154,7 +3169,7 @@ static uiBut *ui_def_but(
                }
        }
 
-       but = MEM_callocN(sizeof(uiBut), "uiBut");
+       but = ui_but_alloc(type & BUTTYPE);
 
        but->type = type & BUTTYPE;
        but->pointype = type & UI_BUT_POIN_TYPES;
diff --git a/source/blender/editors/interface/interface_handlers.c 
b/source/blender/editors/interface/interface_handlers.c
index 3f2684eb333..f5a7c90a622 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -3873,6 +3873,21 @@ static int ui_do_but_KEYEVT(
        return WM_UI_HANDLER_CONTINUE;
 }
 
+static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, 
const int mouse_xy[2])
+{
+       int x = mouse_xy[0], y = mouse_xy[1];
+       rcti icon_rect;
+
+       BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE);
+
+       ui_window_to_block(region, but->block, &x, &y);
+
+       BLI_rcti_rctf_copy(&icon_rect, &but->rect);
+       icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect));
+
+       return BLI_rcti_isect_pt(&icon_rect, x, y);
+}
+
 static int ui_do_but_TAB(bContext *C, uiBlock *block, uiBut *but, 
uiHandleButtonData *data, const wmEvent *event)
 {
        if (data->state == BUTTON_STATE_HIGHLIGHT) {
@@ -3883,6 +3898,17 @@ static int ui_do_but_TAB(bContext *C, uiBlock *block, 
uiBut *but, uiHandleButton
                        return WM_UI_HANDLER_BREAK;
                }
                else if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && 
(event->val == KM_CLICK)) {
+                       const bool has_icon_extra = ui_but_icon_extra_get(but) 
== UI_BUT_ICONEXTRA_CLEAR;
+
+                       if (has_icon_extra && 
ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) {
+                               uiButTab *tab = (uiButTab *)but;
+                               wmOperatorType *ot_backup = but->optype;
+
+                               but->optype = tab->unlink_ot;
+                               /* Force calling unlink/delete operator. */
+                               ui_apply_but(C, block, but, data, true);
+                               but->optype = ot_backup;
+                       }
                        button_activate_state(C, but, BUTTON_STATE_EXIT);
                        return WM_UI_HANDLER_BREAK;
                }
@@ -3899,21 +3925,6 @@ static int ui_do_but_TAB(bContext *C, uiBlock *block, 
uiBut *but, uiHandleButton
        return WM_UI_HANDLER_CONTINUE;
 }
 
-static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, 
const int mouse_xy[2])
-{
-       int x = mouse_xy[0], y = mouse_xy[1];
-       rcti icon_rect;
-
-       BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE);
-
-       ui_window_to_block(region, but->block, &x, &y);
-
-       BLI_rcti_rctf_copy(&icon_rect, &but->rect);
-       icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect));
-
-       return BLI_rcti_isect_pt(&icon_rect, x, y);
-}
-
 static int ui_do_but_TEX(
         bContext *C, uiBlock *block, uiBut *but,
         uiHandleButtonData *data, const wmEvent *event)
diff --git a/source/blender/editors/interface/interface_intern.h 
b/source/blender/editors/interface/interface_intern.h
index 137fdfb2c7e..e0b35b1cc3b 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -329,6 +329,11 @@ struct uiBut {
        uiBlock *block;
 };
 
+typedef struct uiButTab {
+       uiBut but;
+       struct wmOperatorType *unlink_ot;
+} uiButTab;
+
 typedef struct ColorPicker {
        struct ColorPicker *next, *prev;
        float color_data[3]; /* colr data may be HSV or HSL for now */
diff --git a/source/blender/editors/interface/interface_templates.c 
b/source/blender/editors/interface/interface_templates.c
index 444d5d97f46..a5f27e20542 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -704,7 +704,7 @@ static void template_ID(
 
 static void template_ID_tabs(
         bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, 
int flag,
-        const char *newop, const char *UNUSED(openop), const char 
*UNUSED(unlinkop))
+        const char *newop, const char *UNUSED(openop), const char *unlinkop)
 {
        const ARegion *region = CTX_wm_region(C);
        const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, 
template->prop);
@@ -712,29 +712,34 @@ static void template_ID_tabs(
 
        uiBlock *block = uiLayoutGetBlock(layout);
        uiStyle *style = UI_style_get_dpi();
-       uiBut *but;
 
 
        for (ID *id = template->idlb->first; id; id = id->next) {
+               wmOperatorType *unlink_ot = WM_operatortype_find(unlinkop, 
false);
                const char *id_name = id->name + 2;
-               const int but_width = 
UI_fontstyle_string_width(&style->widgetlabel, id_name) + UI_UNIT_X;
+               const bool is_active = active_ptr.data == id;
+               const unsigned int but_width = 
UI_fontstyle_string_width(&style->widgetlabel, id_name) + UI_UNIT_X +
+                                              (is_active ? 
ICON_DEFAULT_WIDTH_SCALE : 0);
+               uiButTab *tab;
 
-               but = uiDefButR_prop(
+               tab = (uiButTab *)uiDefButR_prop(
                        block, UI_BTYPE_TAB, 0, id_name, 0, 0, but_width, 
UI_UNIT_Y,
                        &template->ptr, template->prop, 0, 0.0f,
                        sizeof(id->name) - 2, 0.0f, 0.0f, "");
-               UI_but_funcN_set(but, id_search_call_cb, 
MEM_dupallocN(template), id);
-               but->poin = &id->name[2];
+               UI_but_funcN_set(&tab->but, id_search_call_cb, 
MEM_dupallocN(template), id);
+               tab->but.poin = &id->name[2];
+               tab->unlink_ot = unlink_ot;
 
-               UI_but_func_rename_set(but, id_rename_cb, id);
-               if (active_ptr.data == id) {
-                       UI_but_flag_enable(but, UI_SELECT);
+               UI_but_func_rename_set(&tab->but, id_rename_cb, id);
+               if (is_active) {
+                       UI_but_flag_enable(&tab->but, UI_SELECT | 
UI_BUT_VALUE_CLEAR);
                }
-               UI_but_drawflag_enable(but, but_align);
+               UI_but_drawflag_enable(&tab->but, but_align);
        }
 
        if (flag & UI_ID_ADD_NEW) {
                const bool editable = RNA_property_editable(&template->ptr, 
template->prop);
+               uiBut *but;
 
                if (active_ptr.type) {
                        type = active_ptr.type;
diff --git a/source/blender/editors/screen/workspace_edit.c 
b/source/blender/editors/screen/workspace_edit.c
index 34def82f16e..49efd9ab2f5 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -311,11 +311,9 @@ static void 
WORKSPACE_OT_workspace_duplicate(wmOperatorType *ot)
 
 static int workspace_delete_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Main *bmain = CTX_data_main(C);
-       wmWindowManager *wm = CTX_wm_manager(C);
        wmWindow *win = CTX_wm_window(C);
 
-       ED_workspace_delete(WM_window_get_active_workspace(win), bmain, C, wm, 
win);
+       WM_event_add_notifier(C, NC_SCREEN | ND_WORKSPACE_DELETE, 
WM_window_get_active_workspace(win));
 
        return OPERATOR_FINISHED;
 }
diff --git a/source/blender/windowmanager/WM_types.h 
b/source/blender/windowmanager/WM_types.h
index 9df9afcb064..6b723b034c9 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -271,6 +271,7 @@ typedef struct wmNotifier {
 #define ND_LAYOUTSET           (7<<16)
 #define ND_SKETCH                      (8<<16)
 #define ND_WORKSPACE_SET       (9<<16)
+#define ND_WORKSPACE_DELETE (10<<16)
 
        /* NC_SCENE Scene */
 #define ND_SCENEBROWSE         (1<<16)
diff --git a/source/blender/windowmanager/intern/wm_event_system.c 
b/source/blender/windowmanager/intern/wm_event_system.c
index f3dbbb38036..cc03bd11569 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -352,6 +352,13 @@ void wm_event_do_notifiers(bContext *C)
                                                if (G.debug & G_DEBUG_EVENTS)
                                                        printf("%s: Workspace 
set %p\n", __func__, note->reference);
                                        }
+                                       else if (note->data == 
ND_WORKSPACE_DELETE) {
+                                               WorkSpace *workspace = 
note->reference;
+
+                                               ED_workspace_delete(workspace, 
CTX_data_main(C), C, wm, win);   // XXX hrms, think this over!
+                                               if (G.debug & G_DEBUG_EVENTS)
+                                                       printf("%s: Workspace 
delete %p\n", __func__, workspace);
+                                       }
                                        else if (note->data == ND_LAYOUTBROWSE) 
{
                                                bScreen *ref_screen = 
BKE_workspace_layout_screen_get(note->reference);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to