[Bf-blender-cvs] [33bed112488] topbar: Add 'x' icon to active workspace tab to delete workspace

Julian Eisel noreply at git.blender.org
Fri Oct 6 17:03:11 CEST 2017


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);



More information about the Bf-blender-cvs mailing list