Commit: daf4a3b16635f4f1e489291ca62b7f36662b7f88
Author: Julian Eisel
Date:   Fri Dec 4 00:35:35 2015 +0100
Branches: wiggly-widgets
https://developer.blender.org/rBdaf4a3b16635f4f1e489291ca62b7f36662b7f88

Widget precision tweaking support

Adds support for precision tweaking by holding shift. For now used by 
arrow-widgets only, rest can be adapted later.

Also - and this shouldn't have any noticeable influence for users, widget 
tweaking is handled via a modal operator now (WIDGETGROUP_OT_widget_tweak). 
This way, the shortcut for toggling precision tweaking doesn't have to be 
hardcoded.

===================================================================

M       source/blender/editors/transform/transform_manipulator.c
M       source/blender/windowmanager/WM_api.h
M       source/blender/windowmanager/intern/wm_generic_widgets.c
M       source/blender/windowmanager/intern/wm_operators.c
M       source/blender/windowmanager/intern/wm_widgets.c
M       source/blender/windowmanager/wm.h

===================================================================

diff --git a/source/blender/editors/transform/transform_manipulator.c 
b/source/blender/editors/transform/transform_manipulator.c
index 6644f4a..aff24a1 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -1009,7 +1009,7 @@ static ManipulatorGroup *manipulatorgroup_init(
 /**
  * Custom handler for manipulator widgets
  */
-static int manipulator_handler(bContext *C, const wmEvent *UNUSED(event), 
wmWidget *widget)
+static int manipulator_handler(bContext *C, const wmEvent *UNUSED(event), 
wmWidget *widget, const int UNUSED(flag))
 {
        const ScrArea *sa = CTX_wm_area(C);
        ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/windowmanager/WM_api.h 
b/source/blender/windowmanager/WM_api.h
index f624f2a..9f6f2f9 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -508,7 +508,7 @@ bool        WM_event_is_tablet(const struct wmEvent *event);
 struct wmWidget *WM_widget_new(void (*draw)(const struct bContext *, struct 
wmWidget *),
                                void (*render_3d_intersection)(const struct 
bContext *, struct wmWidget *, int),
                                int  (*intersect)(struct bContext *, const 
struct wmEvent *, struct wmWidget *),
-                               int  (*handler)(struct bContext *, const struct 
wmEvent *, struct wmWidget *));
+                               int  (*handler)(struct bContext *, const struct 
wmEvent *, struct wmWidget *, const int));
 
 void  WM_widgetmap_widgets_update(const struct bContext *C, struct wmWidgetMap 
*wmap);
 void  WM_widgetmap_widgets_draw(const struct bContext *C, const struct 
wmWidgetMap *wmap,
@@ -534,6 +534,16 @@ enum widgetflags {
        WM_WIDGET_SELECTABLE  = (1 << 8),
 };
 
+/**
+ * \brief Widget tweak flag.
+ * Bitflag passed to widget while tweaking.
+ */
+enum {
+       /* drag with extra precision (shift)
+        * NOTE: Widgets are responsible for handling this (widget->handler 
callback)! */
+       WM_WIDGET_TWEAK_PRECISE = (1 << 0),
+};
+
 void WM_widget_set_property(struct wmWidget *, int slot, struct PointerRNA 
*ptr, const char *propname);
 struct PointerRNA *WM_widget_set_operator(struct wmWidget *, const char 
*opname);
 void WM_widget_set_func_select(
diff --git a/source/blender/windowmanager/intern/wm_generic_widgets.c 
b/source/blender/windowmanager/intern/wm_generic_widgets.c
index a564ff5..9434968 100644
--- a/source/blender/windowmanager/intern/wm_generic_widgets.c
+++ b/source/blender/windowmanager/intern/wm_generic_widgets.c
@@ -196,10 +196,16 @@ typedef struct ArrowInteraction {
        float orig_offset;
        float orig_scale;
 
-       /* direction vector, projected in screen space */
-       float proj_direction[2];
+       /* offset of last handling step */
+       float prev_offset;
+       /* Total offset added by precision tweaking.
+        * Needed to allow toggling precision on/off without causing jumps */
+       float precision_offset;
 } ArrowInteraction;
 
+/* factor for precision tweaking */
+#define ARROW_PRECISION_FAC 0.05f
+
 
 static void widget_arrow_get_final_pos(wmWidget *widget, float r_pos[3])
 {
@@ -376,12 +382,13 @@ static void widget_arrow_draw(const bContext *UNUSED(C), 
wmWidget *widget)
  */
 #define USE_ABS_HANDLE_RANGE
 
-static int widget_arrow_handler(bContext *C, const wmEvent *event, wmWidget 
*widget)
+static int widget_arrow_handler(bContext *C, const wmEvent *event, wmWidget 
*widget, const int flag)
 {
        ArrowWidget *arrow = (ArrowWidget *)widget;
        ArrowInteraction *data = widget->interaction_data;
        ARegion *ar = CTX_wm_region(C);
        RegionView3D *rv3d = ar->regiondata;
+       const bool use_precision = (flag & WM_WIDGET_TWEAK_PRECISE);
 
        float orig_origin[4];
        float viewvec[3], tangent[3], plane[3];
@@ -461,12 +468,22 @@ static int widget_arrow_handler(bContext *C, const 
wmEvent *event, wmWidget *wid
                facdir = (m_diff[1] < 0.0) ? -1.0 : 1.0;
        }
 
+
+       const float ofs_new = facdir * len_v3(offset);
+
        /* set the property for the operator and call its modal function */
        if (widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE]) {
                float max = arrow->min + arrow->range;
                float value;
 
-               value = data->orig_offset + facdir * len_v3(offset);
+               if (use_precision) {
+                       /* add delta offset of this step to total 
precision_offset */
+                       data->precision_offset += ofs_new - data->prev_offset;
+               }
+               data->prev_offset = ofs_new;
+
+               value = data->orig_offset + ofs_new - data->precision_offset * 
(1.0f - ARROW_PRECISION_FAC);
+
                if (arrow->style & WIDGET_ARROW_STYLE_CONSTRAINED) {
                        if (arrow->style & WIDGET_ARROW_STYLE_INVERTED)
                                value = max - (value * arrow->range / 
arrow->range_fac);
@@ -483,6 +500,7 @@ static int widget_arrow_handler(bContext *C, const wmEvent 
*event, wmWidget *wid
                        CLAMP(value, arrow->min, max);
                }
 
+
                PointerRNA ptr = widget->ptr[ARROW_SLOT_OFFSET_WORLD_SPACE];
                PropertyRNA *prop = 
widget->props[ARROW_SLOT_OFFSET_WORLD_SPACE];
 
@@ -506,11 +524,12 @@ static int widget_arrow_handler(bContext *C, const 
wmEvent *event, wmWidget *wid
                        arrow->offset = value;
        }
        else {
-               arrow->offset = facdir * len_v3(offset);
+               arrow->offset = ofs_new;
        }
 
        /* tag the region for redraw */
        ED_region_tag_redraw(ar);
+       WM_event_add_mousemove(C);
 
        return OPERATOR_PASS_THROUGH;
 }
@@ -1369,7 +1388,7 @@ static int widget_rect_transform_invoke(bContext 
*UNUSED(C), const wmEvent *even
        return OPERATOR_RUNNING_MODAL;
 }
 
-static int widget_rect_transform_handler(bContext *C, const wmEvent *event, 
wmWidget *widget)
+static int widget_rect_transform_handler(bContext *C, const wmEvent *event, 
wmWidget *widget, const int UNUSED(flag))
 {
        RectTransformWidget *cage = (RectTransformWidget *)widget;
        RectTransformInteraction *data = widget->interaction_data;
diff --git a/source/blender/windowmanager/intern/wm_operators.c 
b/source/blender/windowmanager/intern/wm_operators.c
index 006b570..f5c891c 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -5330,10 +5330,8 @@ void wm_operatortype_init(void)
        WM_operatortype_append(WM_OT_doc_view_manual_ui_context);
 
        /* widgets */
-       WM_operatortype_append(WIDGETGROUP_OT_widget_set_active);
        WM_operatortype_append(WIDGETGROUP_OT_widget_select);
        WM_operatortype_append(WIDGETGROUP_OT_widget_tweak);
-       WM_operatortype_append(WIDGETGROUP_OT_widget_tweak_cancel);
 }
 
 /* circleselect-like modal operators */
diff --git a/source/blender/windowmanager/intern/wm_widgets.c 
b/source/blender/windowmanager/intern/wm_widgets.c
index 03915f6..0b53725 100644
--- a/source/blender/windowmanager/intern/wm_widgets.c
+++ b/source/blender/windowmanager/intern/wm_widgets.c
@@ -200,7 +200,7 @@ static GHash *wm_widgetmap_widget_hash_new(
 wmWidget *WM_widget_new(void (*draw)(const bContext *C, wmWidget *customdata),
                         void (*render_3d_intersection)(const bContext *C, 
wmWidget *customdata, int selectionbase),
                         int  (*intersect)(bContext *C, const wmEvent *event, 
wmWidget *widget),
-                        int  (*handler)(bContext *C, const wmEvent *event, 
wmWidget *widget))
+                        int  (*handler)(bContext *C, const wmEvent *event, 
wmWidget *widget, const int flag))
 {
        wmWidget *widget = MEM_callocN(sizeof(wmWidget), "widget");
 
@@ -658,49 +658,6 @@ void WM_widget_set_colors(wmWidget *widget, const float 
col[4], const float col_
  *
  * \{ */
 
-static int widget_set_active_invoke(bContext *C, wmOperator *op, const wmEvent 
*event)
-{
-       ARegion *ar = CTX_wm_region(C);
-       const bool deactivate = RNA_boolean_get(op->ptr, "deactivate");
-
-       for (wmWidgetMap *wmap = ar->widgetmaps.first; wmap; wmap = wmap->next) 
{
-               if (deactivate) {
-                       wm_widgetmap_set_active_widget(wmap, C, event, NULL);
-
-                       /* ugly hack - send widget release event */
-                       ((wmEvent *)event)->type = EVT_WIDGET_RELEASED;
-               }
-               else {
-                       wmWidget *widget = 
wmap->wmap_context.highlighted_widget;
-                       if (widget) {
-                               wm_widgetmap_set_active_widget(wmap, C, event, 
widget);
-                               break;
-                       }
-                       else {
-                               BLI_assert(0);
-                               return (OPERATOR_CANCELLED | 
OPERATOR_PASS_THROUGH);
-                       }
-               }
-       }
-
-       return OPERATOR_FINISHED;
-}
-
-void WIDGETGROUP_OT_widget_set_active(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name = "Widget Activate";
-       ot->description = "Activate the currently highlighted widget";
-       ot->idname = "WIDGETGROUP_OT_widget_set_active";
-
-       /* api callbacks */
-       ot->invoke = widget_set_active_invoke;
-
-       ot->flag = OPTYPE_UNDO;
-
-       RNA_def_boolean(ot->srna, "deactivate", 0, "Deactivate", "Deactivate 
currently active widget");
-}
-
 /**
  * Deselect all selected widgets in \a wmap.
  * \return if selection has changed.
@@ -917,86 +874,143 @@ void WIDGETGROUP_OT_widget_select(wmOperatorType *ot)
        WM_operator_properties_mouse_select(ot);
 }
 
-/**
- * Search for an active widget in region \a ar.
- */
-static wmWidget *widget_find_active_in_region(const ARegion *ar, wmWidgetMap 
**r_wmap)
+typedef struct WidgetTweakData {
+       wmWidgetMap *wmap;
+       wmWidget *active;
+
+       int init_event; /* initial event type */
+       int flag;       /* tweak flags */
+} WidgetTweakData;
+
+enum {
+       TWEAK_MODAL_CANCEL = 1,
+       TWEAK_MODAL_CONFIRM,
+       TWEAK_MODAL_PRECISION_ON,
+       TWEAK_MODAL_PRECISION_OFF,
+};
+
+static void widget_tweak_finish(bContext *C, wmOperator *op)
 {
-       for (*r_wmap = ar->widgetmaps.first; *r_wmap; *r_wmap = 
(*r_wmap)->next) {
-               if ((*r_wmap)->wmap_context.active_widget) {
-                       return (*r_wmap)->wmap_context.active_widget;
-               }
-       }
+       WidgetTweakData *wtweak = op->customdata;
+       wm_widgetmap_set_active_widget(wtweak->wmap, C, NULL, NULL);
+       MEM_freeN(wtweak);
+}
 
-       *r_wmap = NULL;
-       return NULL;
+static void widget_tweak_cancel(bContext *C, wmOperator *op)
+{
+       WidgetTweakData *wtweak = op->customdata;
+       if (wtweak->active->cancel) {
+               wtweak->active->cancel(C, wtweak->active);
+       }
+       widget_tweak_finish(C, op);
 }
 
-static int widget_tweak_invoke(bContext *C, wmOperator *UNUSED(op), const 
wmEvent *event)
+static int widget_tweak_modal(bContext *C, wmOperator *op, const wmEvent 
*event)
 {
-       ARegion *ar = CTX_wm_region(C);
-       wmWidgetMap *wmap;
-       wmWidget *widget = widget_find_active_in_region(ar, &wmap);
+       WidgetTweakData *wtw

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to