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:
-rw-r--r--release/scripts/modules/bpy_types.py9
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py1
-rw-r--r--source/blender/editors/interface/interface.c4
-rw-r--r--source/blender/editors/interface/interface_handlers.c88
-rw-r--r--source/blender/editors/interface/interface_intern.h8
-rw-r--r--source/blender/editors/interface/interface_regions.c36
-rw-r--r--source/blender/editors/interface/interface_widgets.c6
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h13
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c9
11 files changed, 132 insertions, 49 deletions
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index e19766310ec..c7ec7e1e54a 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -144,10 +144,11 @@ class WindowManager(bpy_types.ID):
import bpy
pie = self.piemenu_begin__internal(title, icon, event)
- try:
- draw_func(pie, bpy.context)
- finally:
- self.piemenu_end__internal(pie)
+ if pie:
+ try:
+ draw_func(pie, bpy.context)
+ finally:
+ self.piemenu_end__internal(pie)
class _GenericBone:
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index dc18dd73abc..a7ddec040a5 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -223,6 +223,7 @@ class USERPREF_PT_interface(Panel):
sub.prop(view, "pie_initial_timeout")
sub.prop(view, "pie_menu_radius")
sub.prop(view, "pie_menu_threshold")
+ sub.prop(view, "pie_menu_confirm")
col.separator()
col.separator()
col.separator()
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index b987f970b9e..41bf5d5494e 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1312,10 +1312,6 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
rcti rect;
int multisample_enabled;
- /* early exit if cancelled */
- if ((block->flag & UI_BLOCK_RADIAL) && (block->pie_data.flags & UI_PIE_FINISHED))
- return;
-
/* get menu region or area region */
ar = CTX_wm_menu(C);
if (!ar)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 5bd85f855ba..fc9d1d9f090 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -8632,6 +8632,13 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
duration = menu->scrolltimer->duration;
+ event_xy[0] = event->x;
+ event_xy[1] = event->y;
+
+ ui_window_to_block_fl(ar, block, &event_xy[0], &event_xy[1]);
+
+ ui_block_calculate_pie_segment(block, event_xy);
+
if (event->type == TIMER) {
if (event->customdata == menu->scrolltimer) {
/* deactivate initial direction after a while */
@@ -8677,24 +8684,26 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
ED_region_tag_redraw(ar);
}
}
- }
- event_xy[0] = event->x;
- event_xy[1] = event->y;
+ /* check pie velociy here if gesture has ended */
+ if (block->pie_data.flags & UI_PIE_GESTURE_END_WAIT) {
+ float len_sq = 10;
- ui_window_to_block_fl(ar, block, &event_xy[0], &event_xy[1]);
+ /* use a time threshold to ensure we leave time to the mouse to move */
+ if (duration - block->pie_data.duration_gesture > 0.02) {
+ len_sq = len_squared_v2v2(event_xy, block->pie_data.last_pos);
+ copy_v2_v2(block->pie_data.last_pos, event_xy);
+ block->pie_data.duration_gesture = duration;
+ }
- ui_block_calculate_pie_segment(block, event_xy);
+ if (len_sq < 1.0) {
+ uiBut *but = ui_but_find_activated(menu->region);
- if (block->pie_data.flags & UI_PIE_FINISHED) {
- if ((event->type == block->pie_data.event && event->val == KM_RELEASE) ||
- ((event->type == RIGHTMOUSE || event->type == ESCKEY) && (event->val == KM_PRESS)))
- {
- menu->menuretval = UI_RETURN_OK;
+ if (but) {
+ return ui_but_pie_menu_apply(C, menu, but, true);
+ }
+ }
}
-
- ED_region_tag_redraw(ar);
- return WM_UI_HANDLER_BREAK;
}
if (event->type == block->pie_data.event && !is_click_style) {
@@ -8714,9 +8723,18 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
block->pie_data.flags |= UI_PIE_CLICK_STYLE;
}
else {
+ float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init);
uiBut *but = ui_but_find_activated(menu->region);
+ if (but && (U.pie_menu_confirm >= U.pie_menu_threshold) &&
+ (sqrtf(len_sq) >= U.pie_menu_confirm))
+ {
+ if (but)
+ return ui_but_pie_menu_apply(C, menu, but, true);
+ }
+
retval = ui_but_pie_menu_apply(C, menu, but, true);
+
}
}
}
@@ -8726,11 +8744,23 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
switch (event->type) {
case MOUSEMOVE:
- if (!is_click_style &&
- (len_squared_v2v2(event_xy, block->pie_data.pie_center_init) > PIE_CLICK_THRESHOLD_SQ))
- {
- block->pie_data.flags |= UI_PIE_DRAG_STYLE;
+ if (!is_click_style) {
+ float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init);
+
+ if (len_sq > PIE_CLICK_THRESHOLD_SQ)
+ {
+ block->pie_data.flags |= UI_PIE_DRAG_STYLE;
+ }
+
+ if ((U.pie_menu_confirm >= U.pie_menu_threshold) &&
+ (sqrtf(len_sq) >= U.pie_menu_confirm))
+ {
+ block->pie_data.flags |= UI_PIE_GESTURE_END_WAIT;
+ copy_v2_v2(block->pie_data.last_pos, event_xy);
+ block->pie_data.duration_gesture = duration;
+ }
}
+
ui_handle_menu_button(C, event, menu);
/* mouse move should always refresh the area for pie menus */
@@ -8750,13 +8780,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
case ESCKEY:
case RIGHTMOUSE:
- if (!is_click_style) {
- block->pie_data.flags |= UI_PIE_FINISHED;
- menu->menuretval = 0;
- ED_region_tag_redraw(ar);
- }
- else
- menu->menuretval = UI_RETURN_CANCEL;
+ menu->menuretval = UI_RETURN_CANCEL;
break;
case AKEY:
@@ -9043,6 +9067,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
struct ARegion *menu_region;
/* we block all events, this is modal interaction, except for drop events which is described below */
int retval = WM_UI_HANDLER_BREAK;
+ bool reset_pie = false;
menu_region = CTX_wm_menu(C);
CTX_wm_menu_set(C, menu->region);
@@ -9063,6 +9088,13 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
wmWindow *win = CTX_wm_window(C);
/* copy values, we have to free first (closes region) */
uiPopupBlockHandle temp = *menu;
+ uiBlock *block = menu->region->uiblocks.first;
+
+ /* set last pie event to allow chained pie spawning */
+ if (block->flag & UI_BLOCK_RADIAL) {
+ win->last_pie_event = block->pie_data.event;
+ reset_pie = true;
+ }
ui_popup_block_free(C, menu);
UI_remove_popup_handlers(&win->modalhandlers, menu);
@@ -9094,6 +9126,14 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata)
/* delayed apply callbacks */
ui_apply_but_funcs_after(C);
+ if (reset_pie) {
+ /* reaqcuire window in case pie invalidates it somehow */
+ wmWindow *win = CTX_wm_window(C);
+
+ if (win)
+ win->last_pie_event = EVENT_NONE;
+ }
+
CTX_wm_region_set(C, menu_region);
return retval;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 2f66c4a9900..efd67effd73 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -168,9 +168,9 @@ enum {
UI_PIE_INITIAL_DIRECTION = (1 << 1), /* use initial center of pie menu to calculate direction */
UI_PIE_DRAG_STYLE = (1 << 2), /* pie menu is drag style */
UI_PIE_INVALID_DIR = (1 << 3), /* mouse not far enough from center position */
- UI_PIE_FINISHED = (1 << 4), /* pie menu finished but we still wait for a release event */
- UI_PIE_CLICK_STYLE = (1 << 5), /* pie menu changed to click style, click to confirm */
- UI_PIE_ANIMATION_FINISHED = (1 << 6), /* pie animation finished, do not calculate any more motio */
+ UI_PIE_CLICK_STYLE = (1 << 4), /* pie menu changed to click style, click to confirm */
+ UI_PIE_ANIMATION_FINISHED = (1 << 5), /* pie animation finished, do not calculate any more motion */
+ UI_PIE_GESTURE_END_WAIT = (1 << 6), /* pie gesture selection has been done, now wait for mouse motion to end */
};
#define PIE_CLICK_THRESHOLD_SQ 50.0f
@@ -310,6 +310,8 @@ struct PieMenuData {
float pie_dir[2];
float pie_center_init[2];
float pie_center_spawned[2];
+ float last_pos[2];
+ double duration_gesture;
int flags;
int event; /* initial event used to fire the pie menu, store here so we can query for release */
float alphafac;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 5739ebebe64..49823d4e472 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -2709,8 +2709,18 @@ static float uiPieTitleWidth(const char *name, int icon)
uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const wmEvent *event)
{
- uiStyle *style = UI_GetStyleDraw();
- uiPieMenu *pie = MEM_callocN(sizeof(uiPopupMenu), "pie menu");
+ uiStyle *style;
+ uiPieMenu *pie;
+ short event_type;
+
+ wmWindow *win = CTX_wm_window(C);
+
+ /* allow respawning a pie from the last pie event */
+ if (event->type == win->lock_pie_event && event->type != win->last_pie_event)
+ return NULL;
+
+ style = UI_GetStyleDraw();
+ pie = MEM_callocN(sizeof(uiPopupMenu), "pie menu");
pie->block_radial = uiBeginBlock(C, NULL, __func__, UI_EMBOSS);
/* may be useful later to allow spawning pies
@@ -2718,10 +2728,17 @@ uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, const
/* pie->block_radial->flag |= UI_BLOCK_POPUP_MEMORY; */
pie->block_radial->puphash = ui_popup_menu_hash(title);
pie->block_radial->flag |= UI_BLOCK_RADIAL;
- pie->block_radial->pie_data.event = event->type;
+
+ if (win->last_pie_event != EVENT_NONE)
+ event_type = win->last_pie_event;
+ else
+ event_type = event->type;
+
+ pie->block_radial->pie_data.event = event_type;
+ win->lock_pie_event = event_type;
/* if pie is spawned by a left click, it is always assumed to be click style */
- if (event->type == LEFTMOUSE) {
+ if (event_type == LEFTMOUSE) {
pie->block_radial->flag |= UI_PIE_CLICK_STYLE;
}
@@ -2785,7 +2802,8 @@ void uiPieMenuInvoke(struct bContext *C, const char *idname, const wmEvent *even
if (mt->poll && mt->poll(C, mt) == 0)
return;
- pie = uiPieMenuBegin(C, IFACE_(mt->label), ICON_NONE, event);
+ if (!(pie = uiPieMenuBegin(C, IFACE_(mt->label), ICON_NONE, event)))
+ return;
layout = uiPieMenuLayout(pie);
menu.layout = layout;
@@ -2806,7 +2824,9 @@ void uiPieOperatorEnumInvoke(struct bContext *C, const char *title, const char *
uiPieMenu *pie;
uiLayout *layout;
- pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event);
+ if (!(pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event)))
+ return;
+
layout = uiPieMenuLayout(pie);
layout = uiLayoutRadial(layout);
@@ -2836,7 +2856,9 @@ void uiPieEnumInvoke(struct bContext *C, const char *title, const char *path,
return;
}
- pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event);
+ if (!(pie = uiPieMenuBegin(C, IFACE_(title), ICON_NONE, event)))
+ return;
+
layout = uiPieMenuLayout(pie);
layout = uiLayoutRadial(layout);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index f958c70ae50..2355d2be9e6 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -3838,6 +3838,8 @@ void ui_draw_pie_center(uiBlock *block)
float pie_radius_internal = U.pixelsize * U.pie_menu_threshold;
float pie_radius_external = U.pixelsize * (U.pie_menu_threshold + 7.0f);
+ float pie_confirm_radius = U.pixelsize * (U.pie_menu_confirm);
+ float pie_confirm_external = U.pixelsize * (U.pie_menu_confirm + 2.0f);
int subd = 40;
@@ -3874,6 +3876,10 @@ void ui_draw_pie_center(uiBlock *block)
glutil_draw_lined_arc(0.0f, (float)M_PI * 2.0f, pie_radius_internal, subd);
glutil_draw_lined_arc(0.0f, (float)M_PI * 2.0f, pie_radius_external, subd);
+ if (pie_confirm_radius > pie_radius_external) {
+ glColor4ub(btheme->tui.wcol_pie_menu.text_sel[0], btheme->tui.wcol_pie_menu.text_sel[1], btheme->tui.wcol_pie_menu.text_sel[2], 64);
+ draw_disk_shaded(angle - range / 2.0f, range, pie_confirm_radius, pie_confirm_external, subd, NULL, NULL, false);
+ }
glDisable(GL_BLEND);
glPopMatrix();
}
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 382fd8c1dbd..769e2573aa4 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -540,7 +540,8 @@ typedef struct UserDef {
* a drag/release pie menu */
short pie_initial_timeout; /* direction in the pie menu will always be calculated from the initial position
* within this time limit */
- int pie_animation_timeout;
+ short pie_animation_timeout;
+ short pie_menu_confirm;
short pie_menu_radius; /* pie menu radius */
short pie_menu_threshold; /* pie menu distance from center before a direction is set */
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index a17e416b5bd..4cf6bfe9a8f 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -171,11 +171,6 @@ typedef struct wmWindow {
void *ghostwin; /* don't want to include ghost.h stuff */
- int winid; /* winid also in screens, is for retrieving this window after read */
-
- short grabcursor; /* cursor grab mode */
- short pad;
-
struct bScreen *screen; /* active screen */
struct bScreen *newscreen; /* temporary when switching */
char screenname[64]; /* MAX_ID_NAME for matching window with active screen after file read */
@@ -187,8 +182,14 @@ typedef struct wmWindow {
short cursor; /* current mouse cursor type */
short lastcursor; /* previous cursor when setting modal one */
short modalcursor; /* the current modal cursor */
+ short grabcursor; /* cursor grab mode */
short addmousemove; /* internal: tag this for extra mousemove event, makes cursors/buttons active on UI switching */
- short pad2;
+
+ int winid; /* winid also in screens, is for retrieving this window after read */
+
+ short lock_pie_event; /* internal, lock pie creation from this event until released */
+ short last_pie_event; /* exception to the above rule for nested pies, store last pie event for operators
+ * that spawn a new pie right after destruction of last pie */
struct wmEvent *eventstate; /* storage for event system */
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index b4968333d3f..976a89ae85f 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3250,6 +3250,10 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 1000);
RNA_def_property_ui_text(prop, "Threshold", "Distance from center needed before a selection can be made");
+ prop = RNA_def_property(srna, "pie_menu_confirm", PROP_INT, PROP_PIXEL);
+ RNA_def_property_range(prop, 0, 1000);
+ RNA_def_property_ui_text(prop, "Confirm Threshold", "Distance from center after which selection is made");
+
prop = RNA_def_property(srna, "use_quit_dialog", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_QUIT_PROMPT);
RNA_def_property_ui_text(prop, "Prompt Quit",
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 2f8ee1ca141..0218513c03f 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2188,6 +2188,12 @@ static void wm_event_drag_test(wmWindowManager *wm, wmWindow *win, wmEvent *even
}
+static void wm_event_pie_filter(wmWindow *win, wmEvent *event)
+{
+ if (win->lock_pie_event == event->type && event->val == KM_RELEASE)
+ win->lock_pie_event = EVENT_NONE;
+}
+
/* called in main loop */
/* goes over entire hierarchy: events -> window -> screen -> area -> region */
void wm_event_do_handlers(bContext *C)
@@ -2263,6 +2269,9 @@ void wm_event_do_handlers(bContext *C)
wm_region_mouse_co(C, event);
+ /* take care of pie event filter */
+ wm_event_pie_filter(win, event);
+
/* first we do priority handlers, modal + some limited keymaps */
action |= wm_handlers_do(C, event, &win->modalhandlers);