Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2017-03-13 12:43:49 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-03-13 12:45:15 +0300
commit7bc76f8a3c1416bf2dca09bfc0d2eeee0147bd1a (patch)
tree362e6fc24a99df1130759c6d440bb6bf23cf30a4 /source/blender
parent4dacda58f96d91fd4f358f418bf450bbc4bb3a43 (diff)
New Window Operator (to replace Duplicate Window)
A user doesn't want to necessarily create a new Screen only because she wants a new window. This patch allows the user to pick the screen to use for the new Window. If the screen picked is the active one, it duplicates it (as the old behaviour in Blender). Patch with contributions and fixes by Julian Eisel (Severin) Subscribers: venomgfx Differential Revision: https://developer.blender.org/D2555
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/interface/interface.c2
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c74
-rw-r--r--source/blender/windowmanager/intern/wm_window.c95
-rw-r--r--source/blender/windowmanager/wm_window.h9
5 files changed, 153 insertions, 28 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index fe9b3054ea7..0b026750900 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -4399,7 +4399,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c
for (item = item_array; item->identifier; item++) {
/* note: need to give the index rather than the identifier because the enum can be freed */
if (BLI_strcasestr(item->name, str)) {
- if (false == UI_search_item_add(items, item->name, SET_INT_IN_POINTER(item->value), 0))
+ if (false == UI_search_item_add(items, item->name, SET_INT_IN_POINTER(item->value), item->icon))
break;
}
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 2809795268d..c8d3c85c5da 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -238,6 +238,7 @@ void WM_operator_view3d_unit_defaults(struct bContext *C, struct wmOperator *op
int WM_operator_smooth_viewtx_get(const struct wmOperator *op);
int WM_menu_invoke_ex(struct bContext *C, struct wmOperator *op, int opcontext);
int WM_menu_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_enum_search_invoke_previews(struct bContext *C, struct wmOperator *op, short prv_cols, short prv_rows);
int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, confirm menu + exec */
int WM_operator_confirm (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 3cbcaf2810f..2cf4e16155c 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1107,46 +1107,70 @@ int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_REGION_WIN);
}
+struct EnumSearchMenu {
+ wmOperator *op; /* the operator that will be executed when selecting an item */
+
+ bool use_previews;
+ short prv_cols, prv_rows;
+};
/* generic enum search invoke popup */
-static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
+static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg)
{
- static char search[256] = "";
- wmEvent event;
+ struct EnumSearchMenu *search_menu = arg;
wmWindow *win = CTX_wm_window(C);
+ wmOperator *op = search_menu->op;
+ /* template_ID uses 4 * widget_unit for width, we use a bit more, some items may have a suffix to show */
+ const int width = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_cols : UI_searchbox_size_x();
+ const int height = search_menu->use_previews ? 5 * U.widget_unit * search_menu->prv_rows : UI_searchbox_size_y();
+ static char search[256] = "";
uiBlock *block;
uiBut *but;
- wmOperator *op = (wmOperator *)arg_op;
block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
search[0] = '\0';
+ BLI_assert(search_menu->use_previews || (search_menu->prv_cols == 0 && search_menu->prv_rows == 0));
#if 0 /* ok, this isn't so easy... */
uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
#endif
but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
- 10, 10, UI_searchbox_size_x(), UI_UNIT_Y, 0, 0, "");
+ 10, 10, width, UI_UNIT_Y, search_menu->prv_rows, search_menu->prv_cols, "");
/* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), UI_searchbox_size_x(), UI_searchbox_size_y(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 10 - UI_searchbox_size_y(), width, height, NULL, 0, 0, 0, 0, NULL);
UI_block_bounds_set_popup(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
-
- wm_event_init_from_window(win, &event);
- event.type = EVT_BUT_OPEN;
- event.val = KM_PRESS;
- event.customdata = but;
- event.customdatafree = false;
- wm_event_add(win, &event);
+ UI_but_focus_on_enter_event(win, but);
return block;
}
+/**
+ * Similar to #WM_enum_search_invoke, but draws previews. Also, this can't
+ * be used as invoke callback directly since it needs additional info.
+ */
+int WM_enum_search_invoke_previews(
+ bContext *C, wmOperator *op, short prv_cols, short prv_rows)
+{
+ static struct EnumSearchMenu search_menu;
+
+ search_menu.op = op;
+ search_menu.use_previews = true;
+ search_menu.prv_cols = prv_cols;
+ search_menu.prv_rows = prv_rows;
+
+ UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
+
+ return OPERATOR_INTERFACE;
+}
int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- UI_popup_block_invoke(C, wm_enum_search_menu, op);
+ static struct EnumSearchMenu search_menu;
+ search_menu.op = op;
+ UI_popup_block_invoke(C, wm_enum_search_menu, &search_menu);
return OPERATOR_INTERFACE;
}
@@ -2079,14 +2103,22 @@ static void WM_OT_window_close(wmOperatorType *ot)
ot->poll = WM_operator_winactive;
}
-static void WM_OT_window_duplicate(wmOperatorType *ot)
+static void WM_OT_window_new(wmOperatorType *ot)
{
- ot->name = "Duplicate Window";
- ot->idname = "WM_OT_window_duplicate";
- ot->description = "Duplicate the current Blender window";
-
- ot->exec = wm_window_duplicate_exec;
+ PropertyRNA *prop;
+
+ ot->name = "New Window";
+ ot->idname = "WM_OT_window_new";
+ ot->description = "Create a new Blender window";
+
+ ot->exec = wm_window_new_exec;
+ ot->invoke = wm_window_new_invoke;
ot->poll = wm_operator_winactive_normal;
+
+ prop = RNA_def_enum(ot->srna, "screen", DummyRNA_NULL_items, 0, "Screen", "");
+ RNA_def_enum_funcs(prop, wm_window_new_screen_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
}
static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
@@ -4177,7 +4209,7 @@ void wm_operatortype_init(void)
global_ops_hash = BLI_ghash_str_new_ex("wm_operatortype_init gh", 2048);
WM_operatortype_append(WM_OT_window_close);
- WM_operatortype_append(WM_OT_window_duplicate);
+ WM_operatortype_append(WM_OT_window_new);
WM_operatortype_append(WM_OT_read_history);
WM_operatortype_append(WM_OT_read_homefile);
WM_operatortype_append(WM_OT_read_factory_settings);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index e271225e437..b6f1b431009 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -58,6 +58,7 @@
#include "RNA_access.h"
+#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -71,6 +72,7 @@
#include "ED_fileselect.h"
#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "PIL_time.h"
@@ -79,6 +81,8 @@
#include "GPU_init_exit.h"
#include "GPU_immediate.h"
+#include "UI_resources.h"
+
/* for assert */
#ifndef NDEBUG
# include "BLI_threads.h"
@@ -244,6 +248,25 @@ wmWindow *wm_window_new(bContext *C)
return win;
}
+/**
+ * A higher level version of copy that tests the new window can be added.
+ */
+static wmWindow *wm_window_new_test(bContext *C)
+{
+ wmWindow *win = wm_window_new(C);
+
+ WM_check(C);
+
+ if (win->ghostwin) {
+ WM_event_add_notifier(C, NC_WINDOW | NA_ADDED, NULL);
+ return win;
+ }
+ else {
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wm_window_close(C, wm, win);
+ return NULL;
+ }
+}
/* part of wm_window.c api */
wmWindow *wm_window_copy(bContext *C, wmWindow *win_src)
@@ -723,17 +746,79 @@ int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-/* operator callback */
-int wm_window_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
+/* new window operator callback */
+int wm_window_new_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
wmWindow *win_src = CTX_wm_window(C);
- bool ok;
+ const int screen_id = RNA_enum_get(op->ptr, "screen");
+ bScreen *screen = BLI_findlink(&bmain->screen, screen_id);
+ wmWindow *win_dst;
- ok = (wm_window_copy_test(C, win_src) != NULL);
+ if (screen->winid) {
+ /* Screen is already used, duplicate window and screen */
+ win_dst = wm_window_copy_test(C, win_src);
+ }
+ else if ((win_dst = wm_window_new_test(C))) {
+ /* New window with a different screen */
+ win_dst->screen = screen;
+ screen->winid = win_dst->winid;
+ CTX_wm_window_set(C, win_dst);
+ ED_screen_refresh(CTX_wm_manager(C), win_dst);
+ }
- return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return (win_dst != NULL) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+int wm_window_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ Main *bmain = CTX_data_main(C);
+
+ if (BLI_listbase_count_ex(&bmain->screen, 2) == 1) {
+ RNA_enum_set(op->ptr, "screen", 0);
+ return wm_window_new_exec(C, op);
+ }
+ else {
+ return WM_enum_search_invoke_previews(C, op, 6, 2);
+ }
+}
+
+struct EnumPropertyItem *wm_window_new_screen_itemf(
+ bContext *C, struct PointerRNA *UNUSED(ptr), struct PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ Main *bmain = CTX_data_main(C);
+ EnumPropertyItem *item = NULL;
+ EnumPropertyItem tmp = {0, "", 0, "", ""};
+ int value = 0, totitem = 0;
+ int count_act_screens = 0;
+ /* XXX setting max number of windows to 20. We'd need support
+ * for dynamic strings in EnumPropertyItem.name to avoid this. */
+ static char active_screens[20][MAX_NAME + 12];
+
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ if (screen->winid) {
+ BLI_snprintf(active_screens[count_act_screens], sizeof(*active_screens), "%s (Duplicate)",
+ screen->id.name + 2);
+ tmp.name = active_screens[count_act_screens++];
+ }
+ else {
+ tmp.name = screen->id.name + 2;
+ }
+
+ tmp.value = value;
+ tmp.identifier = screen->id.name;
+ UI_id_icon_render(C, CTX_data_scene(C), &screen->id, true, false);
+ tmp.icon = BKE_icon_id_ensure(&screen->id);
+
+ RNA_enum_item_add(&item, &totitem, &tmp);
+ value++;
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
+}
/* fullscreen operator callback */
int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index c106f9d7851..5a45cf718ec 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -32,7 +32,11 @@
#ifndef __WM_WINDOW_H__
#define __WM_WINDOW_H__
+struct EnumPropertyItem;
+struct wmEvent;
struct wmOperator;
+struct PointerRNA;
+struct PropertyRNA;
/* *************** internal api ************** */
void wm_ghost_init (bContext *C);
@@ -78,9 +82,12 @@ void wm_window_IME_end (wmWindow *win);
/* *************** window operators ************** */
int wm_window_close_exec(bContext *C, struct wmOperator *op);
-int wm_window_duplicate_exec(bContext *C, struct wmOperator *op);
int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
+struct EnumPropertyItem *wm_window_new_screen_itemf(bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, bool *r_free);
+int wm_window_new_exec(bContext *C, struct wmOperator *op);
+int wm_window_new_invoke(bContext *C, struct wmOperator *op, const struct wmEvent *event);
+
/* Initial (unmaximized) size to start with for
* systems that can't find it for themselves (X11).
* Clamped by real desktop limits */