- Added default Circle 'gesture' operator callbacks.
  As test, added in view3d window as Ckey, paint over object centers.
- Fixed notifier for gesture, to only cause redraws in own region.
This commit is contained in:
Ton Roosendaal 2008-12-21 16:24:19 +00:00
parent bdb3e2eb2b
commit eb8e220f26
9 changed files with 197 additions and 12 deletions

@ -106,10 +106,13 @@ void ED_region_do_listen(ARegion *ar, wmNotifier *note)
/* generic notes first */
switch(note->type) {
case WM_NOTE_WINDOW_REDRAW:
case WM_NOTE_GESTURE_REDRAW:
case WM_NOTE_SCREEN_CHANGED:
ED_region_tag_redraw(ar);
break;
case WM_NOTE_GESTURE_REDRAW:
if(note->swinid==ar->swinid)
ED_region_tag_redraw(ar);
break;
default:
if(ar->type->listener)
ar->type->listener(ar, note);

@ -110,6 +110,7 @@ void view3d_update_depths(ARegion *ar, View3D *v3d);
/* view3d_select.c */
void ED_VIEW3D_OT_select(struct wmOperatorType *ot);
void ED_VIEW3D_OT_borderselect(struct wmOperatorType *ot);
void ED_VIEW3D_OT_circle_select(struct wmOperatorType *ot);
/* view3d_view.c */
void view3d_operator_needs_opengl(const struct bContext *C);

@ -69,7 +69,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(ED_VIEW3D_OT_select);
WM_operatortype_append(ED_VIEW3D_OT_borderselect);
WM_operatortype_append(ED_VIEW3D_OT_clipping);
WM_operatortype_append(ED_VIEW3D_OT_circle_select);
}
void view3d_keymap(wmWindowManager *wm)
@ -92,6 +92,7 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "ED_VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ED_VIEW3D_OT_borderselect", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ED_VIEW3D_OT_clipping", BKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "ED_VIEW3D_OT_circle_select", CKEY, KM_PRESS, 0, 0);
}

@ -1859,3 +1859,45 @@ void obedit_selectionCB(Scene *scene, ARegion *ar, View3D *v3d, short selecting,
// force_draw(0);
}
static int view3d_circle_select(bContext *C, wmOperator *op)
{
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= CTX_wm_region(C);
View3D *v3d= sa->spacedata.first;
Base *base;
int x= RNA_int_get(op->ptr, "x");
int y= RNA_int_get(op->ptr, "y");
int radius= RNA_int_get(op->ptr, "radius");
for(base= FIRSTBASE; base; base= base->next) {
if(base->lay & v3d->lay) {
project_short(ar, v3d, base->object->obmat[3], &base->sx);
if(base->sx!=IS_CLIPPED) {
int dx= base->sx-x;
int dy= base->sy-y;
if( dx*dx + dy*dy < radius*radius)
select_base_v3d(base, BA_SELECT);
base->object->flag= base->flag;
}
}
}
return 0;
}
void ED_VIEW3D_OT_circle_select(wmOperatorType *ot)
{
ot->name= "Circle Select";
ot->idname= "ED_VIEW3D_OT_circle_select";
ot->invoke= WM_gesture_circle_invoke;
ot->modal= WM_gesture_circle_modal;
ot->exec= view3d_circle_select;
ot->poll= WM_operator_winactive;
RNA_def_property(ot->srna, "x", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "y", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "radius", PROP_INT, PROP_NONE);
}

@ -119,9 +119,11 @@ void WM_operatortype_append (void (*opfunc)(wmOperatorType*));
int WM_operator_call (struct bContext *C, const char *opstring, int context, struct IDProperty *properties);
/* default operator callbacks for border/lasso */
/* default operator callbacks for border/circle/lasso */
int WM_border_select_invoke (struct bContext *C, wmOperator *op, struct wmEvent *event);
int WM_border_select_modal (struct bContext *C, wmOperator *op, struct wmEvent *event);
int WM_gesture_circle_invoke(struct bContext *C, wmOperator *op, struct wmEvent *event);
int WM_gesture_circle_modal(struct bContext *C, wmOperator *op, struct wmEvent *event);
/* default operator for arearegions, generates event */
void WM_OT_tweak_gesture(wmOperatorType *ot);

@ -146,6 +146,7 @@ typedef struct wmGesture {
void *customdata;
/* customdata for border is a recti */
/* customdata for circle is recti, (xmin, ymin) is center, xmax radius */
} wmGesture;

@ -66,14 +66,18 @@ wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type)
wm_subwindow_getorigin(window, gesture->swinid, &sx, &sy);
if( ELEM3(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK)) {
if( ELEM4(type, WM_GESTURE_RECT, WM_GESTURE_CROSS_RECT, WM_GESTURE_TWEAK, WM_GESTURE_CIRCLE)) {
rcti *rect= MEM_callocN(sizeof(rcti), "gesture rect new");
gesture->customdata= rect;
rect->xmin= event->x - sx;
rect->ymin= event->y - sy;
rect->xmax= event->x - sx;
rect->ymax= event->y - sy;
if(type==WM_GESTURE_CIRCLE)
rect->xmax= 25; // XXX temp
else {
rect->xmax= event->x - sx;
rect->ymax= event->y - sy;
}
}
return gesture;
@ -162,6 +166,26 @@ static void wm_gesture_draw_line(wmWindow *win, wmGesture *gt)
}
static void wm_gesture_draw_circle(wmWindow *win, wmGesture *gt)
{
rcti *rect= (rcti *)gt->customdata;
glTranslatef((float)rect->xmin, (float)rect->ymin, 0.0f);
glEnable(GL_LINE_STIPPLE);
glColor3ub(0, 0, 0);
glLineStipple(1, 0xAAAA);
glutil_draw_lined_arc(0.0, M_PI*2.0, rect->xmax, 40);
glColor3ub(255, 255, 255);
glLineStipple(1, 0x5555);
glutil_draw_lined_arc(0.0, M_PI*2.0, rect->xmax, 40);
glDisable(GL_LINE_STIPPLE);
glTranslatef((float)-rect->xmin, (float)-rect->ymin, 0.0f);
}
static void wm_gesture_draw_cross(wmWindow *win, wmGesture *gt)
{
rcti *rect= (rcti *)gt->customdata;
@ -192,6 +216,8 @@ void wm_gesture_draw(wmWindow *win)
wm_gesture_draw_rect(win, gt);
else if(gt->type==WM_GESTURE_TWEAK)
wm_gesture_draw_line(win, gt);
else if(gt->type==WM_GESTURE_CIRCLE)
wm_gesture_draw_circle(win, gt);
else if(gt->type==WM_GESTURE_CROSS_RECT) {
if(gt->mode==1)
wm_gesture_draw_rect(win, gt);

@ -173,6 +173,7 @@ void WM_exit(bContext *C)
/* first wrap up running stuff, we assume only the active WM is running */
/* modal handlers are on window level freed, others too? */
/* note; same code copied in wm_files.c */
if(C && CTX_wm_manager(C)) {
for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) {

@ -249,7 +249,7 @@ static void WM_OT_exit_blender(wmOperatorType *ot)
It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
*/
static void border_select_apply(bContext *C, wmOperator *op, int event_type)
static void border_apply(bContext *C, wmOperator *op, int event_type)
{
wmGesture *gesture= op->customdata;
rcti *rect= gesture->customdata;
@ -264,13 +264,13 @@ static void border_select_apply(bContext *C, wmOperator *op, int event_type)
RNA_int_set(op->ptr, "ymin", rect->ymin);
RNA_int_set(op->ptr, "xmax", rect->xmax);
RNA_int_set(op->ptr, "ymax", rect->ymax);
if( RNA_property_is_set(op->ptr, "event_type"))
if( RNA_struct_find_property(op->ptr, "event_type") )
RNA_int_set(op->ptr, "event_type", event_type);
op->type->exec(C, op);
}
static void border_select_end(bContext *C, wmOperator *op)
static void border_end(bContext *C, wmOperator *op)
{
wmGesture *gesture= op->customdata;
@ -327,18 +327,125 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
}
}
else {
border_select_apply(C, op, event->type);
border_select_end(C, op);
border_apply(C, op, event->type);
border_end(C, op);
return OPERATOR_FINISHED;
}
break;
case ESCKEY:
border_select_end(C, op);
border_end(C, op);
return OPERATOR_CANCELLED;
}
return OPERATOR_RUNNING_MODAL;
}
/* **************** circle gesture *************** */
/* works now only for selection or modal paint stuff, calls exec while hold mouse */
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
op->customdata= WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
/* add modal handler */
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
return OPERATOR_RUNNING_MODAL;
}
static void gesture_circle_end(bContext *C, wmOperator *op)
{
wmGesture *gesture= op->customdata;
WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
op->customdata= NULL;
ED_area_tag_redraw(CTX_wm_area(C));
}
static void gesture_circle_apply(bContext *C, wmOperator *op, int event_type)
{
wmGesture *gesture= op->customdata;
rcti *rect= gesture->customdata;
/* operator arguments and storage. */
RNA_int_set(op->ptr, "x", rect->xmin);
RNA_int_set(op->ptr, "y", rect->ymin);
RNA_int_set(op->ptr, "radius", rect->xmax);
if( RNA_struct_find_property(op->ptr, "event_type") )
RNA_int_set(op->ptr, "event_type", event_type);
if(op->type->exec)
op->type->exec(C, op);
}
int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
{
wmGesture *gesture= op->customdata;
rcti *rect= gesture->customdata;
int sx, sy;
switch(event->type) {
case MOUSEMOVE:
wm_subwindow_getorigin(CTX_wm_window(C), gesture->swinid, &sx, &sy);
rect->xmin= event->x - sx;
rect->ymin= event->y - sy;
WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
if(gesture->mode)
gesture_circle_apply(C, op, event->type);
break;
case WHEELUPMOUSE:
rect->xmax += 2 + rect->xmax/10;
WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
break;
case WHEELDOWNMOUSE:
rect->xmax -= 2 + rect->xmax/10;
if(rect->xmax < 1) rect->xmax= 1;
WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
break;
case LEFTMOUSE:
case MIDDLEMOUSE:
case RIGHTMOUSE:
if(event->val==0) { /* key release */
gesture_circle_end(C, op);
return OPERATOR_FINISHED;
}
else
gesture->mode= 1;
break;
case ESCKEY:
gesture_circle_end(C, op);
return OPERATOR_CANCELLED;
}
return OPERATOR_RUNNING_MODAL;
}
#if 0
/* template to copy from */
void WM_OT_circle_gesture(wmOperatorType *ot)
{
ot->name= "Circle Gesture";
ot->idname= "WM_OT_circle_gesture";
ot->invoke= WM_gesture_circle_invoke;
ot->modal= WM_gesture_circle_modal;
ot->poll= WM_operator_winactive;
RNA_def_property(ot->srna, "x", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "y", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "radius", PROP_INT, PROP_NONE);
}
#endif
/* **************** Tweak gesture *************** */
static int tweak_gesture_invoke(bContext *C, wmOperator *op, wmEvent *event)
@ -456,5 +563,6 @@ 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_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0);
}