[Bf-blender-cvs] [a297e1bb93a] master: WM: move gesture operator callbacks into own file
Campbell Barton
noreply at git.blender.org
Tue Oct 17 06:15:02 CEST 2017
Commit: a297e1bb93afcd2a216e074e6fd72c7914768cdf
Author: Campbell Barton
Date: Tue Oct 17 15:09:29 2017 +1100
Branches: master
https://developer.blender.org/rBa297e1bb93afcd2a216e074e6fd72c7914768cdf
WM: move gesture operator callbacks into own file
`wm_operators.c` is near 5k LOC with lots of mixed functionality,
extract gesture callbacks since they aren't closely related.
===================================================================
M source/blender/windowmanager/CMakeLists.txt
M source/blender/windowmanager/WM_api.h
A source/blender/windowmanager/intern/wm_gesture_ops.c
M source/blender/windowmanager/intern/wm_operators.c
M source/blender/windowmanager/wm.h
===================================================================
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index f22ed34ca2e..a8b3c994d24 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -60,6 +60,7 @@ set(SRC
intern/wm_files.c
intern/wm_files_link.c
intern/wm_gesture.c
+ intern/wm_gesture_ops.c
intern/wm_init_exit.c
intern/wm_jobs.c
intern/wm_keymap.c
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 595050e12f7..e40026880c4 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -379,7 +379,7 @@ bool WM_menutype_add(struct MenuType *mt);
void WM_menutype_freelink(struct MenuType *mt);
void WM_menutype_free(void);
- /* default operator callbacks for border/circle/lasso */
+/* wm_gesture_ops.c */
int WM_gesture_border_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_border_modal (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
void WM_gesture_border_cancel(struct bContext *C, struct wmOperator *op);
diff --git a/source/blender/windowmanager/intern/wm_gesture_ops.c b/source/blender/windowmanager/intern/wm_gesture_ops.c
new file mode 100644
index 00000000000..a554727cacd
--- /dev/null
+++ b/source/blender/windowmanager/intern/wm_gesture_ops.c
@@ -0,0 +1,883 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/windowmanager/intern/wm_gesture_ops.c
+ * \ingroup wm
+ *
+ * Default operator callbacks for use with gestures (border/circle/lasso/straightline).
+ * Operators themselves are defined elsewhere.
+ *
+ * - Keymaps are in ``wm_operators.c``.
+ * - Property definitions are in ``wm_operator_props.c``.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+
+#include "WM_types.h"
+#include "WM_api.h"
+
+#include "wm.h"
+#include "wm_event_types.h"
+#include "wm_event_system.h"
+#include "wm_subwindow.h"
+
+#include "ED_screen.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Gesture Utilities
+ *
+ * Border gesture has two types:
+ * -# #WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border.
+ * -# #WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends.
+ *
+ * It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type).
+ *
+ * \{ */
+
+static void gesture_modal_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));
+
+ if (RNA_struct_find_property(op->ptr, "cursor")) {
+ WM_cursor_modal_restore(CTX_wm_window(C));
+ }
+}
+
+static void gesture_modal_state_to_operator(wmOperator *op, int modal_state)
+{
+ PropertyRNA *prop;
+
+ switch (modal_state) {
+ case GESTURE_MODAL_SELECT:
+ case GESTURE_MODAL_DESELECT:
+ if ((prop = RNA_struct_find_property(op->ptr, "deselect"))) {
+ RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_DESELECT));
+ }
+ break;
+ case GESTURE_MODAL_IN:
+ case GESTURE_MODAL_OUT:
+ if ((prop = RNA_struct_find_property(op->ptr, "zoom_out"))) {
+ RNA_property_boolean_set(op->ptr, prop, (modal_state == GESTURE_MODAL_OUT));
+ }
+ break;
+ }
+}
+
+static int gesture_modal_state_from_operator(wmOperator *op)
+{
+ PropertyRNA *prop;
+
+ if ((prop = RNA_struct_find_property(op->ptr, "deselect"))) {
+ if (RNA_property_is_set(op->ptr, prop)) {
+ return RNA_property_boolean_get(op->ptr, prop) ? GESTURE_MODAL_DESELECT : GESTURE_MODAL_SELECT;
+ }
+ }
+ if ((prop = RNA_struct_find_property(op->ptr, "zoom_out"))) {
+ if (RNA_property_is_set(op->ptr, prop)) {
+ return RNA_property_boolean_get(op->ptr, prop) ? GESTURE_MODAL_OUT : GESTURE_MODAL_IN;
+ }
+ }
+ return GESTURE_MODAL_NOP;
+}
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/** \name Border Gesture
+ *
+ * Border gesture has two types:
+ * -# #WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border.
+ * -# #WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends.
+ *
+ * It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type).
+ *
+ * \{ */
+
+static bool gesture_border_apply_rect(wmOperator *op)
+{
+ wmGesture *gesture = op->customdata;
+ rcti *rect = gesture->customdata;
+
+ if (rect->xmin == rect->xmax || rect->ymin == rect->ymax)
+ return 0;
+
+
+ /* operator arguments and storage. */
+ RNA_int_set(op->ptr, "xmin", min_ii(rect->xmin, rect->xmax));
+ RNA_int_set(op->ptr, "ymin", min_ii(rect->ymin, rect->ymax));
+ RNA_int_set(op->ptr, "xmax", max_ii(rect->xmin, rect->xmax));
+ RNA_int_set(op->ptr, "ymax", max_ii(rect->ymin, rect->ymax));
+
+ return 1;
+}
+
+static bool gesture_border_apply(bContext *C, wmOperator *op)
+{
+ wmGesture *gesture = op->customdata;
+
+ int retval;
+
+ if (!gesture_border_apply_rect(op)) {
+ return 0;
+ }
+
+ gesture_modal_state_to_operator(op, gesture->modal_state);
+
+ retval = op->type->exec(C, op);
+ OPERATOR_RETVAL_CHECK(retval);
+
+ return 1;
+}
+
+int WM_gesture_border_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int modal_state = gesture_modal_state_from_operator(op);
+
+ if (ISTWEAK(event->type) || (modal_state != GESTURE_MODAL_NOP)) {
+ op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
+ }
+ else {
+ op->customdata = WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
+ }
+
+ /* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
+ if (modal_state == GESTURE_MODAL_NOP) {
+ wmGesture *gesture = op->customdata;
+ gesture->wait_for_input = true;
+ }
+ else {
+ wmGesture *gesture = op->customdata;
+ gesture->modal_state = modal_state;
+ }
+
+ /* add modal handler */
+ WM_event_add_modal_handler(C, op);
+
+ wm_gesture_tag_redraw(C);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+int WM_gesture_border_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ wmGesture *gesture = op->customdata;
+ rcti *rect = gesture->customdata;
+ int sx, sy;
+
+ if (event->type == MOUSEMOVE) {
+ wm_subwindow_origin_get(CTX_wm_window(C), gesture->swinid, &sx, &sy);
+
+ if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
+ rect->xmin = rect->xmax = event->x - sx;
+ rect->ymin = rect->ymax = event->y - sy;
+ }
+ else {
+ rect->xmax = event->x - sx;
+ rect->ymax = event->y - sy;
+ }
+ gesture_border_apply_rect(op);
+
+ wm_gesture_tag_redraw(C);
+ }
+ else if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case GESTURE_MODAL_BEGIN:
+ if (gesture->type == WM_GESTURE_CROSS_RECT && gesture->is_active == false) {
+ gesture->is_active = true;
+ wm_gesture_tag_redraw(C);
+ }
+ break;
+ case GESTURE_MODAL_SELECT:
+ case GESTURE_MODAL_DESELECT:
+ case GESTURE_MODAL_IN:
+ case GESTURE_MODAL_OUT:
+ if (gesture->wait_for_input) {
+ gesture->modal_state = event->val;
+ }
+ if (gesture_border_apply(C, op)) {
+ gesture_modal_end(C, op);
+ return OPERATOR_FINISHED;
+ }
+ gesture_modal_end(C, op);
+ return OPERATOR_CANCELLED;
+
+ case GESTURE_MODAL_CANCEL:
+ gesture_modal_end(C, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ }
+#ifdef WITH_INPUT_NDOF
+ else if (event->type == NDOF_MOTION) {
+ return OPERATOR_PASS_THROUGH;
+ }
+#endif
+
+#if 0
+ /* Allow view navigation??? */
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
+#endif
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void WM_gesture_border_cancel(bContext *C, wmOperator *op)
+{
+ gesture_modal_end(C, op);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/** \name Circle Gesture
+ *
+ * Currently only used for selection or modal paint stuff,
+ * calls ``exec`` while hold mouse, exits on release (with no difference between cancel and confirm).
+ *
+ * \{ */
+
+static void gesture_circle_apply(bContext *C, wmOperator *op);
+
+int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int modal_state = gesture_modal_state_from_operator(op);
+
+ op->customdata = WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
+ wmGesture *gesture = op->customdata;
+ rcti *rect = gesture->customdata;
+
+ /* Default or previously stored value. */
+ rect->xmax = RNA_int_get(op->ptr, "radius");
+
+ /* Starting with the mode starts immediately, like having 'wait_for_input' disabled (some tools use this). */
+ if (modal_state == GESTURE_MODAL_NOP) {
+ gesture->wait_for_input = true;
+ }
+ else {
+ gesture->is_active = true;
+ gesture->modal_state = modal_state;
+ gesture_circle_apply(C, op);
+ }
+
+ /* add modal handler */
+ WM_event_add_modal_handler(C, op);
+
+ wm_gesture_tag_redraw(C);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void gesture_circle_apply(bContext *C, wmOperator *op)
+{
+ wmGesture *gesture = op->customdata;
+ rcti *rect = gesture->customdata;
+
+ if (gesture->modal_state == GESTURE_MODAL_NOP) {
+ r
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list