diff options
-rw-r--r-- | source/blender/editors/sculpt/sculpt.c | 63 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ops.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/vpaint.c | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 154 | ||||
-rw-r--r-- | source/blender/windowmanager/wm.h | 4 |
8 files changed, 231 insertions, 16 deletions
diff --git a/source/blender/editors/sculpt/sculpt.c b/source/blender/editors/sculpt/sculpt.c index a4682912891..080fb3cef63 100644 --- a/source/blender/editors/sculpt/sculpt.c +++ b/source/blender/editors/sculpt/sculpt.c @@ -1366,13 +1366,61 @@ static void sculpt_undo_push(bContext *C, Sculpt *sd) } } -/**** Operator for applying a stroke (various attributes including mouse path) - using the current brush. ****/ -static int sculpt_brush_stroke_poll(bContext *C) +static int sculpt_poll(bContext *C) { - return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D; + return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D && + CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW; } +static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Brush *br = CTX_data_scene(C)->toolsettings->sculpt->brush; + int mode = RNA_int_get(op->ptr, "mode"); + float original_value; + + if(mode == WM_RADIALCONTROL_SIZE) + original_value = br->size; + else if(mode == WM_RADIALCONTROL_STRENGTH) + original_value = br->alpha; + /*else if(mode == WM_RADIALCONTROL_ANGLE) + original_value = br->rotation;*/ + + RNA_float_set(op->ptr, "initial_value", original_value); + return WM_radial_control_invoke(C, op, event); +} + +static int sculpt_radial_control_exec(bContext *C, wmOperator *op) +{ + Brush *br = CTX_data_scene(C)->toolsettings->sculpt->brush; + int mode = RNA_int_get(op->ptr, "mode"); + float new_value = RNA_float_get(op->ptr, "new_value"); + + if(mode == WM_RADIALCONTROL_SIZE) + br->size = new_value; + else if(mode == WM_RADIALCONTROL_STRENGTH) + br->alpha = new_value; + /*else if(mode == WM_RADIALCONTROL_ANGLE) + br->rotation = new_value;*/ + + return OPERATOR_FINISHED; +} + +/**** Radial control ****/ +static void SCULPT_OT_radial_control(wmOperatorType *ot) +{ + WM_OT_radial_control_partial(ot); + + ot->name= "Sculpt Radial Control"; + ot->idname= "SCULPT_OT_radial_control"; + + ot->invoke= sculpt_radial_control_invoke; + ot->exec= sculpt_radial_control_exec; + ot->poll= sculpt_poll; +} + +/**** Operator for applying a stroke (various attributes including mouse path) + using the current brush. ****/ + static void sculpt_load_mats(bglMats *mats, ViewContext *vc) { float cpy[4][4]; @@ -1688,7 +1736,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot) ot->invoke= sculpt_brush_stroke_invoke; ot->modal= sculpt_brush_stroke_modal; ot->exec= sculpt_brush_stroke_exec; - ot->poll= sculpt_brush_stroke_poll; + ot->poll= sculpt_poll; /* properties */ RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); @@ -1712,7 +1760,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot) /**** Toggle operator for turning sculpt mode on or off ****/ /* XXX: The code for drawing all the paint cursors is really the same, would be better to unify them */ -static void draw_paint_cursor(bContext *C, int x, int y) +static void draw_paint_cursor(bContext *C, int x, int y, void *customdata) { Sculpt *sd= CTX_data_tool_settings(C)->sculpt; @@ -1760,7 +1808,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) /* Activate visible brush */ ts->sculpt->session->cursor = - WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_brush_stroke_poll, draw_paint_cursor); + WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_poll, draw_paint_cursor, NULL); @@ -1796,6 +1844,7 @@ static void SCULPT_OT_toggle_mode(wmOperatorType *ot) void ED_operatortypes_sculpt() { + WM_operatortype_append(SCULPT_OT_radial_control); WM_operatortype_append(SCULPT_OT_brush_stroke); WM_operatortype_append(SCULPT_OT_toggle_mode); } diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 8bf78a255bd..0d4e6fb9f47 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -98,6 +98,10 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "VIEW3D_OT_wpaint", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0); + + RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); + //RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + //RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE); WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/editors/space_view3d/vpaint.c b/source/blender/editors/space_view3d/vpaint.c index a636f8be9ee..568c64572b1 100644 --- a/source/blender/editors/space_view3d/vpaint.c +++ b/source/blender/editors/space_view3d/vpaint.c @@ -1069,7 +1069,7 @@ static int wp_poll(bContext *C) return 0; } -static void wp_drawcursor(bContext *C, int x, int y) +static void wp_drawcursor(bContext *C, int x, int y, void *customdata) { ToolSettings *ts= CTX_data_tool_settings(C); @@ -1118,7 +1118,7 @@ static int set_wpaint(bContext *C, wmOperator *op) /* toggle */ if(wp==NULL) wp= scene->toolsettings->wpaint= new_vpaint(1); - wp->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), wp_poll, wp_drawcursor); + wp->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), wp_poll, wp_drawcursor, NULL); mesh_octree_table(ob, NULL, NULL, 's'); @@ -1501,7 +1501,7 @@ static int vp_poll(bContext *C) return 0; } -static void vp_drawcursor(bContext *C, int x, int y) +static void vp_drawcursor(bContext *C, int x, int y, void *customdata) { ToolSettings *ts= CTX_data_tool_settings(C); @@ -1559,7 +1559,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ if(vp==NULL) vp= scene->toolsettings->vpaint= new_vpaint(0); - vp->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), vp_poll, vp_drawcursor); + vp->paintcursor = WM_paint_cursor_activate(CTX_wm_manager(C), vp_poll, vp_drawcursor, NULL); } if (me) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 010a0108459..a87937d7cad 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -67,7 +67,7 @@ void WM_cursor_restore (struct wmWindow *win); void WM_cursor_wait (struct wmWindow *win, int val); void WM_timecursor (struct wmWindow *win, int nr); -void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int)); +void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int, void *customdata), void *customdata); void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle); /* keymap */ @@ -156,6 +156,10 @@ void WM_OT_tweak_gesture(struct wmOperatorType *ot); struct wmGesture *WM_gesture_new(struct bContext *C, struct wmEvent *event, int type); void WM_gesture_end(struct bContext *C, struct wmGesture *gesture); + /* radial control operator */ +int WM_radial_control_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); +void WM_OT_radial_control_partial(struct wmOperatorType *ot); + /* OpenGL wrappers, mimicking opengl syntax */ void wmSubWindowSet (struct wmWindow *win, int swinid); void wmSubWindowScissorSet (struct wmWindow *win, int swinid, struct rcti *srct); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index d2906f6512b..1473bfcf115 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -229,6 +229,12 @@ typedef struct wmGesture { /* customdata for lasso is short array */ } wmGesture; +/* **************** Radial control *******************/ +typedef enum wmRadialControlMode { + WM_RADIALCONTROL_SIZE, + WM_RADIALCONTROL_STRENGTH, + WM_RADIALCONTROL_ANGLE +} wmRadialControlMode; /* ************** custom wmEvent data ************** */ diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index c411bdeece8..af14bc95207 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -72,7 +72,7 @@ static void wm_paintcursor_draw(bContext *C, ARegion *ar) for(pc= wm->paintcursors.first; pc; pc= pc->next) { if(pc->poll(C)) { ARegion *ar= CTX_wm_region(C); - pc->draw(C, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin); + pc->draw(C, win->eventstate->x - ar->winrct.xmin, win->eventstate->y - ar->winrct.ymin, pc->customdata); } } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 12903f131be..39e197ede0d 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -26,6 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include <float.h> +#include <math.h> #include <string.h> #include "DNA_ID.h" @@ -46,6 +48,9 @@ #include "BKE_main.h" #include "BKE_utildefines.h" +#include "BIF_gl.h" +#include "BIF_glutil.h" /* for paint cursor */ + #include "ED_fileselect.h" #include "ED_screen.h" @@ -450,12 +455,14 @@ static void WM_OT_exit_blender(wmOperatorType *ot) - draw(bContext): drawing callback for paint cursor */ -void *WM_paint_cursor_activate(wmWindowManager *wm, int (*poll)(bContext *C), void (*draw)(bContext *C, int, int)) +void *WM_paint_cursor_activate(wmWindowManager *wm, int (*poll)(bContext *C), + void (*draw)(bContext *C, int, int, void *customdata), void *customdata) { wmPaintCursor *pc= MEM_callocN(sizeof(wmPaintCursor), "paint cursor"); BLI_addtail(&wm->paintcursors, pc); + pc->customdata = customdata; pc->poll= poll; pc->draw= draw; @@ -866,6 +873,149 @@ void WM_OT_lasso_gesture(wmOperatorType *ot) } #endif +/* *********************** radial control ****************** */ + +typedef struct wmRadialControl { + float radius; + int initial_mouse[2]; + void *cursor; + // XXX: texture data +} wmRadialControl; + +static void wm_radial_control_paint(bContext *C, int x, int y, void *customdata) +{ + wmRadialControl *p = (wmRadialControl*)customdata; + ARegion *ar = CTX_wm_region(C); + + /* Keep cursor in the original place */ + x = p->initial_mouse[0] - ar->winrct.xmin; + y = p->initial_mouse[1] - ar->winrct.ymin; + + glTranslatef((float)x, (float)y, 0.0f); + + glColor4ub(255, 255, 255, 128); + glEnable( GL_LINE_SMOOTH ); + glEnable(GL_BLEND); + glutil_draw_lined_arc(0.0, M_PI*2.0, p->radius, 40); + glDisable(GL_BLEND); + glDisable( GL_LINE_SMOOTH ); + + glTranslatef((float)-x, (float)-y, 0.0f); +} + +static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + wmRadialControl *rc = (wmRadialControl*)op->customdata; + int mode, initial_mouse[2], delta[2]; + float dist; + double new_value = RNA_float_get(op->ptr, "new_value"); + int ret = OPERATOR_RUNNING_MODAL; + + mode = RNA_int_get(op->ptr, "mode"); + RNA_int_get_array(op->ptr, "initial_mouse", initial_mouse); + + switch(event->type) { + case MOUSEMOVE: + delta[0]= initial_mouse[0] - event->x; + delta[1]= initial_mouse[1] - event->y; + dist= sqrt(delta[0]*delta[0]+delta[1]*delta[1]); + + if(mode == WM_RADIALCONTROL_SIZE) + new_value = dist; + else if(mode == WM_RADIALCONTROL_STRENGTH) { + float fin = (200.0f - dist) * 0.5f; + new_value = fin>=0 ? fin : 0; + } else if(mode == WM_RADIALCONTROL_ANGLE) + new_value = ((int)(atan2(delta[1], delta[0]) * (180.0 / M_PI)) + 180); + + if(event->ctrl) + new_value = ((int)new_value + 5) / 10*10; + + break; + case ESCKEY: + case RIGHTMOUSE: + ret = OPERATOR_CANCELLED; + break; + case LEFTMOUSE: + case PADENTER: + op->type->exec(C, op); + ret = OPERATOR_FINISHED; + break; + } + + /* Update paint data */ + rc->radius = new_value; + + RNA_float_set(op->ptr, "new_value", new_value); + + if(ret != OPERATOR_RUNNING_MODAL) { + WM_paint_cursor_end(CTX_wm_manager(C), rc->cursor); + MEM_freeN(rc); + } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return ret; +} + +int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + wmRadialControl *rc = MEM_callocN(sizeof(wmRadialControl), "radial control"); + int mode = RNA_int_get(op->ptr, "mode"); + float initial_value = RNA_float_get(op->ptr, "initial_value"); + int mouse[2] = {event->x, event->y}; + + if(mode == WM_RADIALCONTROL_SIZE) + mouse[0]-= initial_value; + else if(mode == WM_RADIALCONTROL_STRENGTH) + mouse[0]-= 200 - 2*initial_value; + else if(mode == WM_RADIALCONTROL_ANGLE) { + mouse[0]-= 200 * cos(initial_value * M_PI / 180.0); + mouse[1]-= 200 * sin(initial_value * M_PI / 180.0); + } + + RNA_int_set_array(op->ptr, "initial_mouse", mouse); + RNA_float_set(op->ptr, "new_value", initial_value); + + op->customdata = rc; + rc->initial_mouse[0] = mouse[0]; + rc->initial_mouse[1] = mouse[1]; + rc->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), op->type->poll, + wm_radial_control_paint, op->customdata); + + /* add modal handler */ + WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + + wm_radial_control_modal(C, op, event); + + return OPERATOR_RUNNING_MODAL; +} + +/** Important: this doesn't define an actual operator, it + just sets up the common parts of the radial control op. **/ +void WM_OT_radial_control_partial(wmOperatorType *ot) +{ + static EnumPropertyItem prop_mode_items[] = { + {WM_RADIALCONTROL_SIZE, "SIZE", "Size", ""}, + {WM_RADIALCONTROL_STRENGTH, "STRENGTH", "Strength", ""}, + {WM_RADIALCONTROL_ANGLE, "ANGLE", "Angle", ""}, + {0, NULL, NULL, NULL}}; + + ot->modal= wm_radial_control_modal; + + /* Should be set in custom invoke() */ + RNA_def_float(ot->srna, "initial_value", 0, 0, FLT_MAX, "Initial Value", "", 0, FLT_MAX); + + /* Set internally, should be used in custom exec() to get final value */ + RNA_def_float(ot->srna, "new_value", 0, 0, FLT_MAX, "New Value", "", 0, FLT_MAX); + + /* Should be set before calling operator */ + RNA_def_enum(ot->srna, "mode", prop_mode_items, 0, "Mode", ""); + + /* Internal */ + RNA_def_int_vector(ot->srna, "initial_mouse", 2, NULL, INT_MIN, INT_MAX, "initial_mouse", "", INT_MIN, INT_MAX); +} + /* ******************************************************* */ /* called on initialize WM_exit() */ @@ -902,7 +1052,7 @@ void wm_window_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "WM_OT_open_mainfile", F1KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "WM_OT_save_as_mainfile", F2KEY, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", F11KEY, KM_PRESS, 0, 0); WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); } diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h index ecb40f34174..556a3fadcfb 100644 --- a/source/blender/windowmanager/wm.h +++ b/source/blender/windowmanager/wm.h @@ -32,9 +32,11 @@ struct wmWindow; typedef struct wmPaintCursor { struct wmPaintCursor *next, *prev; + + void *customdata; int (*poll)(struct bContext *C); - void (*draw)(bContext *C, int, int); + void (*draw)(bContext *C, int, int, void *customdata); } wmPaintCursor; extern void wm_close_and_free(bContext *C, wmWindowManager *); |