[Bf-blender-cvs] [eade6e7] pie-menus: Animated pie menus!
Antony Riakiotakis
noreply at git.blender.org
Mon Jun 30 00:26:27 CEST 2014
Commit: eade6e7b66af7180cfae39520162433fe2da3850
Author: Antony Riakiotakis
Date: Mon Jun 30 01:26:09 2014 +0300
https://developer.blender.org/rBeade6e7b66af7180cfae39520162433fe2da3850
Animated pie menus!
Nuff said :)
===================================================================
M source/blender/editors/interface/interface_handlers.c
M source/blender/editors/interface/interface_intern.h
M source/blender/editors/interface/interface_layout.c
M source/blender/editors/interface/interface_widgets.c
===================================================================
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index dfbf84e..22e4b86 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -114,6 +114,7 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve
#define BUTTON_TOOLTIP_DELAY 0.500
#define BUTTON_FLASH_DELAY 0.020
#define MENU_SCROLL_INTERVAL 0.1
+#define PIE_MENU_INTERVAL 0.01
#define BUTTON_AUTO_OPEN_THRESH 0.3
#define BUTTON_MOUSE_TOWARDS_THRESH 1.0
/* pixels to move the cursor to get out of keyboard navigation */
@@ -6251,6 +6252,44 @@ static bool ui_but_contains_pt(uiBut *but, float mx, float my)
return BLI_rctf_isect_pt(&but->rect, mx, my);
}
+static void ui_but_pie_visual_dir(RadialDirection dir, float vec[2]) {
+ float angle;
+
+ switch (dir) {
+ case UI_RADIAL_W:
+ angle = 180.0f;
+ break;
+ case UI_RADIAL_E:
+ angle = 0.0f;
+ break;
+ case UI_RADIAL_S:
+ angle = 270.0f;
+ break;
+ case UI_RADIAL_N:
+ angle = 90.0f;
+ break;
+ case UI_RADIAL_NW:
+ angle = 140.0f;
+ break;
+ case UI_RADIAL_NE:
+ angle = 40.0f;
+ break;
+ case UI_RADIAL_SW:
+ angle = 220.0f;
+ break;
+ case UI_RADIAL_SE:
+ angle = 320.0f;
+ break;
+ default:
+ angle = 0.0f;
+ break;
+ }
+
+ angle = angle / 180.0f * M_PI;
+ vec[0] = cos(angle);
+ vec[1] = sin(angle);
+}
+
static bool ui_but_isect_pie_seg(uiBlock *block, uiBut *but)
{
float angle_range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_4 : M_PI_4 / 2.0f;
@@ -8380,7 +8419,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
ARegion *ar;
uiBlock *block;
int mx, my;
- double time_diff;
+ double duration;
/* we block all events, this is modal interaction, except for drop events which is described below */
int retval = WM_UI_HANDLER_BREAK;
@@ -8394,16 +8433,48 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
ar = menu->region;
block = ar->uiblocks.first;
- /* add menu timer, this is used to evaluate the time that is needed for
- * calculating collision from final/initial position or if pie menu is drag-style
- * or press and release style */
- time_diff = PIL_check_seconds_timer() - menu->towardstime;
+ if (menu->scrolltimer == NULL) {
+ menu->scrolltimer =
+ WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, PIE_MENU_INTERVAL);
+ menu->scrolltimer->duration = 0.0;
+ }
- /* deactivate initial direction after a while */
- if (time_diff > 0.01 * U.pie_initial_timeout) {
- block->pie_data.flags &= ~UI_PIE_INITIAL_DIRECTION;
- /* force redraw */
- ED_region_tag_redraw(ar);
+ duration = menu->scrolltimer->duration;
+
+ if (event->type == TIMER) {
+ if (event->customdata == menu->scrolltimer) {
+ /* deactivate initial direction after a while */
+ if (duration > 0.01 * U.pie_initial_timeout) {
+ block->pie_data.flags &= ~UI_PIE_INITIAL_DIRECTION;
+ }
+
+ /* handle animation */
+ if (!(block->pie_data.flags & UI_PIE_ANIMATION_FINISHED)) {
+ uiBut *but;
+ double final_time = 0.08;
+ float fac = duration / final_time;
+
+ if (fac > 1.0f) {
+ fac = 1.0f;
+ block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED;
+ }
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->pie_dir) {
+ float dir[2];
+
+ ui_but_pie_visual_dir(but->pie_dir, dir);
+
+ mul_v2_fl(dir, fac * U.pie_menu_radius);
+ add_v2_v2(dir, block->pie_data.pie_center_spawned);
+ BLI_rctf_recenter(&but->rect, dir[0], dir[1]);
+ }
+ }
+ block->pie_data.alphafac = fac;
+
+ ED_region_tag_redraw(ar);
+ }
+ }
}
mx = event->x;
@@ -8433,7 +8504,7 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle
ED_region_tag_redraw(ar);
}
else {
- if (time_diff > U.pie_drag_timeout * 0.01) {
+ if (duration > U.pie_drag_timeout * 0.01) {
retval = ui_pie_menu_apply(C, menu, event, true);
}
else {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index f21ab75..52ba3e6 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -165,6 +165,7 @@ typedef enum RadialDirection {
#define UI_PIE_INVALID_DIR (1 << 3) /* mouse not far enough from center position */
#define UI_PIE_CANCELLED (1 << 4) /* pie menu cancelled but we still wait for a release event */
#define UI_PIE_CLICK_STYLE (1 << 5) /* pie menu changed to click style, click to confirm */
+#define UI_PIE_ANIMATION_FINISHED (1 << 6) /* pie animation finished, do not calculate any more motio */
typedef struct uiLinkLine { /* only for draw/edit */
struct uiLinkLine *next, *prev;
@@ -301,6 +302,7 @@ struct PieMenuData {
float pie_center_spawned[2];
int flags;
int event; /* initial event used to fire the pie menu, store here so we can query for release */
+ float alphafac;
};
struct uiBlock {
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 426309b..83c30f9 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -2098,7 +2098,7 @@ static void ui_litem_layout_column(uiLayout *litem)
/* calculates the angle of a specified button in a radial menu,
* stores a float vector in unit circle */
-static RadialDirection ui_get_radialbut_vec(float *vec, short itemnum, short totitems)
+static RadialDirection ui_get_radialbut_vec(float *vec, short itemnum)
{
float angle = 0.0f;
RadialDirection dir = UI_RADIAL_NONE;
@@ -2126,7 +2126,7 @@ static RadialDirection ui_get_radialbut_vec(float *vec, short itemnum, short tot
* --Matt 07/2006
*/
- if (itemnum < 5) {
+ /* if (itemnum < 5) { */
switch (itemnum) {
case 1:
dir = UI_RADIAL_W;
@@ -2144,10 +2144,11 @@ static RadialDirection ui_get_radialbut_vec(float *vec, short itemnum, short tot
dir = UI_RADIAL_N;
angle = 90.0f;
break;
- }
+/* }
}
else if (totitems < 9) {
switch (itemnum) {
+ */
case 5:
dir = UI_RADIAL_NW;
angle = 140;
@@ -2164,10 +2165,13 @@ static RadialDirection ui_get_radialbut_vec(float *vec, short itemnum, short tot
dir = UI_RADIAL_SE;
angle = 320;
break;
+
+ default:
+ break;
}
+#if 0
}
else {
-#if 0
/* subdivide quadrants progressively, depending on number of items */
int anglepad, curquad, numinquad, aligncorrect=0;
int quaditems, overflow;
@@ -2210,8 +2214,8 @@ static RadialDirection ui_get_radialbut_vec(float *vec, short itemnum, short tot
aligncorrect = angle - 360;
angle += aligncorrect/17; /* 17 == magic number, works nicely */
-#endif
}
+#endif
angle = DEG2RADF(angle);
@@ -2277,7 +2281,7 @@ static void ui_litem_layout_radial(uiLayout *litem)
itemnum++;
- dir = ui_get_radialbut_vec(vec, itemnum, totitems);
+ dir = ui_get_radialbut_vec(vec, itemnum);
if (item->type == ITEM_BUTTON) {
uiButtonItem *bitem = (uiButtonItem *) item;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 4eb6ab6..8c73816 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -3005,15 +3005,24 @@ static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(sta
widgetbase_draw(&wtb, wcol);
}
-static void widget_menu_radial_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+static void widget_menu_radial_itembut(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
uiWidgetBase wtb;
float rad;
+ float fac = but->block->pie_data.alphafac;
+
widget_init(&wtb);
rad = 0.5f * BLI_rcti_size_y(rect);
round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+ wcol->inner[3] *= fac;
+ wcol->inner_sel[3] *= fac;
+ wcol->item[3] *= fac;
+ wcol->text[3] *= fac;
+ wcol->text_sel[3] *= fac;
+ wcol->outline[3] *= fac;
+
widgetbase_draw(&wtb, wcol);
}
@@ -3338,7 +3347,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
case UI_WTYPE_MENU_ITEM_RADIAL:
wt.wcol_theme = &btheme->tui.wcol_pie_menu;
- wt.draw = widget_menu_radial_itembut;
+ wt.custom = widget_menu_radial_itembut;
wt.state = widget_state_pie_menu_item;
break;
}
More information about the Bf-blender-cvs
mailing list