Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-03-03 07:29:57 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-03-03 07:29:57 +0400
commita02c8c4177486c1ae04b8d8cd0d15089039f7be0 (patch)
treea5fc842b1a496249c27b4061f777743c08604bbc /source/blender/editors
parentc6642b8ec8c2b12aed3bf9c72d7378bcfd75da77 (diff)
move toggle drag into a UI handler (was modal operator)
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/interface/interface_handlers.c170
-rw-r--r--source/blender/editors/interface/interface_ops.c200
2 files changed, 159 insertions, 211 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b199e5f66ca..e0d6c293be5 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -740,6 +740,153 @@ static void ui_apply_but_CHARTAB(bContext *C, uiBut *but, uiHandleButtonData *da
/* ****************** drag drop code *********************** */
+#ifdef USE_DRAG_TOGGLE
+
+typedef struct uiDragToggleHandle {
+ /* init */
+ bool is_set;
+ float but_cent_start[2];
+ eButType but_type_start;
+
+ bool xy_lock[2];
+ int xy_last[2];
+} uiDragToggleHandle;
+
+static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
+ const int xy_src[2], const int xy_dst[2])
+{
+ bool change = false;
+ uiBlock *block;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ uiBut *but;
+
+ float xy_a_block[2] = {UNPACK2(xy_src)};
+ float xy_b_block[2] = {UNPACK2(xy_dst)};
+
+ ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
+ ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]);
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (ui_is_but_interactive(but)) {
+ if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
+
+ /* execute the button */
+ if (ui_is_but_bool(but) && but->type == but_type_start) {
+ /* is it pressed? */
+ bool is_set_but = ui_is_but_push(but);
+ BLI_assert(ui_is_but_bool(but) == true);
+ if (is_set_but != is_set) {
+ uiButExecute(C, but);
+ change = true;
+ }
+ }
+ /* done */
+
+ }
+ }
+ }
+ }
+
+ return change;
+}
+
+static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const int xy_input[2])
+{
+ ARegion *ar = CTX_wm_region(C);
+ bool do_draw = false;
+ int xy[2];
+
+ /**
+ * Initialize Locking:
+ *
+ * Check if we need to initialize the lock axis by finding if the first
+ * button we mouse over is X or Y aligned, then lock the mouse to that axis after.
+ */
+ if (drag_info->xy_lock[0] == false && drag_info->xy_lock[1] == false) {
+ ARegion *ar = CTX_wm_region(C);
+
+ /* first store the buttons original coords */
+ uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]);
+ if (but) {
+ const float but_cent_new[2] = {BLI_rctf_cent_x(&but->rect),
+ BLI_rctf_cent_y(&but->rect)};
+
+ /* check if this is a different button, chances are high the button wont move about :) */
+ if (len_manhattan_v2v2(drag_info->but_cent_start, but_cent_new) > 1.0f) {
+ if (fabsf(drag_info->but_cent_start[0] - but_cent_new[0]) <
+ fabsf(drag_info->but_cent_start[1] - but_cent_new[1]))
+ {
+ drag_info->xy_lock[0] = true;
+ }
+ else {
+ drag_info->xy_lock[1] = true;
+ }
+ }
+ }
+ }
+ /* done with axis locking */
+
+
+ xy[0] = (drag_info->xy_lock[0] == false) ? xy_input[0] : drag_info->xy_last[0];
+ xy[1] = (drag_info->xy_lock[1] == false) ? xy_input[1] : drag_info->xy_last[1];
+
+
+ /* touch all buttons between last mouse coord and this one */
+ do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->is_set, drag_info->but_type_start, drag_info->xy_last, xy);
+
+ if (do_draw) {
+ ED_region_tag_redraw(ar);
+ }
+
+ copy_v2_v2_int(drag_info->xy_last, xy);
+}
+
+static void ui_handler_region_drag_toggle_remove(bContext *UNUSED(C), void *userdata)
+{
+ uiDragToggleHandle *drag_info = userdata;
+ MEM_freeN(drag_info);
+}
+
+static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void *userdata)
+{
+ uiDragToggleHandle *drag_info = userdata;
+ bool done = false;
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ {
+ if (event->val != KM_PRESS) {
+ done = true;
+ }
+ break;
+ }
+ case MOUSEMOVE:
+ {
+ ui_drag_toggle_set(C, drag_info, &event->x);
+ break;
+ }
+ }
+
+ if (done) {
+ wmWindow *win = CTX_wm_window(C);
+ WM_event_remove_ui_handler(&win->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info, false);
+ ui_handler_region_drag_toggle_remove(C, drag_info);
+
+ WM_event_add_mousemove(C);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+}
+
+#endif /* USE_DRAG_TOGGLE */
+
+
static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *event)
{
rcti rect;
@@ -775,17 +922,18 @@ static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data,
data->cancel = TRUE;
#ifdef USE_DRAG_TOGGLE
if (ui_is_but_bool(but)) {
- /* assumes button has already been pressed */
- const bool is_set = ui_is_but_push(but);
- PointerRNA ptr;
- /* auto-key is typically called on mouse-up, but we'r leaving the button so call here */
- ui_apply_autokey(C, but);
- WM_operator_properties_create(&ptr, "UI_OT_drag_toggle");
- RNA_boolean_set(&ptr, "state", is_set);
- RNA_int_set(&ptr, "last_x", data->dragstartx);
- RNA_int_set(&ptr, "last_y", data->dragstarty);
- WM_operator_name_call(C, "UI_OT_drag_toggle", WM_OP_INVOKE_DEFAULT, &ptr);
- WM_operator_properties_free(&ptr);
+ uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
+
+ drag_info->is_set = ui_is_but_push(but);
+ drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
+ drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
+ drag_info->but_type_start = but->type;
+ copy_v2_v2_int(drag_info->xy_last, &event->x);
+
+ WM_event_add_ui_handler(C, &data->window->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info);
}
else
#endif
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index f59d970b39a..3298859ee0c 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1071,205 +1071,6 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot)
ot->exec = reloadtranslation_exec;
}
-
-/* -------------------------------------------------------------------- */
-/* Toggle Drag Operator */
-
-typedef struct DragOpInfo {
- bool xy_lock[2];
- float but_cent_start[2];
- eButType but_type_start;
-} DragOpInfo;
-
-static bool ui_but_set_xy_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
- const int xy_src[2], const int xy_dst[2])
-{
- bool change = false;
- uiBlock *block;
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- uiBut *but;
-
- float xy_a_block[2] = {UNPACK2(xy_src)};
- float xy_b_block[2] = {UNPACK2(xy_dst)};
-
- ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
- ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]);
-
- for (but = block->buttons.first; but; but = but->next) {
- if (ui_is_but_interactive(but)) {
- if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
-
- /* execute the button */
- if (ui_is_but_bool(but) && but->type == but_type_start) {
- /* is it pressed? */
- bool is_set_but = ui_is_but_push(but);
- BLI_assert(ui_is_but_bool(but) == true);
- if (is_set_but != is_set) {
- uiButExecute(C, but);
- change = true;
- }
- }
- /* done */
-
- }
- }
- }
- }
-
- return change;
-}
-
-
-static void ui_drag_but_set(bContext *C, wmOperator *op, const int xy_input[2])
-{
- ARegion *ar = CTX_wm_region(C);
- DragOpInfo *drag_info = op->customdata;
- bool do_draw = false;
-
- const bool is_set = RNA_boolean_get(op->ptr, "state");
- const int xy_last[2] = {RNA_int_get(op->ptr, "last_x"),
- RNA_int_get(op->ptr, "last_y")};
-
- int xy[2];
-
- /**
- * Initialize Locking:
- *
- * Check if we need to initialize the lock axis by finding if the first
- * button we mouse over is X or Y aligned, then lock the mouse to that axis after.
- */
- if (drag_info->xy_lock[0] == false && drag_info->xy_lock[1] == false) {
- ARegion *ar = CTX_wm_region(C);
-
- /* first store the buttons original coords */
- uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]);
- if (but) {
- const float but_cent_new[2] = {BLI_rctf_cent_x(&but->rect),
- BLI_rctf_cent_y(&but->rect)};
-
- /* check if this is a different button, chances are high the button wont move about :) */
- if (len_manhattan_v2v2(drag_info->but_cent_start, but_cent_new) > 1.0f) {
- if (fabsf(drag_info->but_cent_start[0] - but_cent_new[0]) <
- fabsf(drag_info->but_cent_start[1] - but_cent_new[1]))
- {
- drag_info->xy_lock[0] = true;
- }
- else {
- drag_info->xy_lock[1] = true;
- }
- }
- }
- }
- /* done with axis locking */
-
-
- xy[0] = (drag_info->xy_lock[0] == false) ? xy_input[0] : xy_last[0];
- xy[1] = (drag_info->xy_lock[1] == false) ? xy_input[1] : xy_last[1];
-
-
- /* touch all buttons between last mouse coord and this one */
- do_draw = ui_but_set_xy_xy(C, ar, is_set, drag_info->but_type_start, xy_last, xy);
-
- if (do_draw) {
- ED_region_tag_redraw(ar);
- }
-
- RNA_int_set(op->ptr, "last_x", xy[0]);
- RNA_int_set(op->ptr, "last_y", xy[1]);
-}
-
-static int ui_drag_toggle_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- int xy_last[2] = {RNA_int_get(op->ptr, "last_x"),
- RNA_int_get(op->ptr, "last_y")};
-
- float but_cent_start[2];
- eButType but_type_start;
- DragOpInfo *drag_info;
-
- {
- /* find the button where we started dragging */
- ARegion *ar = CTX_wm_region(C);
- uiBut *but = ui_but_find_mouse_over(ar, xy_last[0], xy_last[1]);
- if (but) {
- but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
- but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
- but_type_start = but->type;
- }
- else {
- return OPERATOR_CANCELLED;
- }
- }
-
- drag_info = op->customdata = MEM_callocN(sizeof(DragOpInfo), __func__);
- copy_v2_v2(drag_info->but_cent_start, but_cent_start);
- drag_info->but_type_start = but_type_start;
-
- /* set the initial button */
- ui_drag_but_set(C, op, xy_last);
- ui_drag_but_set(C, op, &event->x);
-
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int ui_drag_toggle_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- bool done = false;
-
- switch (event->type) {
- case LEFTMOUSE:
- {
- if (event->val != KM_PRESS) {
- done = true;
- }
- break;
- }
- case MOUSEMOVE:
- {
- ui_drag_but_set(C, op, &event->x);
- break;
- }
- }
-
- if (done) {
- WM_event_add_mousemove(C);
- MEM_freeN(op->customdata);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_RUNNING_MODAL;
- }
-}
-
-static int ui_drag_toggle_cancel(bContext *UNUSED(C), wmOperator *op)
-{
- MEM_freeN(op->customdata);
- return OPERATOR_CANCELLED;
-}
-
-static void UI_OT_drag_toggle(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Button Drag Toggle";
- ot->description = "";
- ot->idname = "UI_OT_drag_toggle";
-
- /* api callbacks */
- ot->invoke = ui_drag_toggle_invoke;
- ot->modal = ui_drag_toggle_modal;
- ot->cancel = ui_drag_toggle_cancel;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- /* properties */
- RNA_def_boolean(ot->srna, "state", true, "State", "");
- RNA_def_int(ot->srna, "last_x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
- RNA_def_int(ot->srna, "last_y", 0, 0, INT_MAX, "Y", "", 0, INT_MAX);
-}
-
/* ********************************************************* */
/* Registration */
@@ -1287,5 +1088,4 @@ void UI_buttons_operatortypes(void)
WM_operatortype_append(UI_OT_edittranslation_init);
#endif
WM_operatortype_append(UI_OT_reloadtranslation);
- WM_operatortype_append(UI_OT_drag_toggle);
}