[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