4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2007 Blender Foundation.
21 * All rights reserved.
24 * Contributor(s): Blender Foundation
26 * ***** END GPL LICENSE BLOCK *****
32 #include "DNA_screen_types.h"
33 #include "DNA_windowmanager_types.h"
35 #include "MEM_guardedalloc.h"
37 #include "BLI_blenlib.h"
39 #include "BKE_blender.h"
40 #include "BKE_global.h"
41 #include "BKE_idprop.h"
42 #include "BKE_library.h"
44 #include "BKE_utildefines.h"
46 #include "RNA_access.h"
47 #include "RNA_define.h"
53 #include "wm_window.h"
54 #include "wm_subwindow.h"
55 #include "wm_event_system.h"
57 static ListBase global_ops= {NULL, NULL};
59 /* ************ operator API, exported ********** */
61 wmOperatorType *WM_operatortype_find(const char *idname)
65 for(ot= global_ops.first; ot; ot= ot->next) {
66 if(strncmp(ot->idname, idname, OP_MAX_TYPENAME)==0)
69 printf("search for unknown operator %s\n", idname);
73 /* all ops in 1 list (for time being... needs evaluation later) */
74 void WM_operatortype_append(void (*opfunc)(wmOperatorType*))
78 ot= MEM_callocN(sizeof(wmOperatorType), "operatortype");
79 ot->srna= RNA_def_struct(&BLENDER_RNA, "", "Operator", "");
81 RNA_def_struct_identifier(ot->srna, ot->idname, ot->name);
82 BLI_addtail(&global_ops, ot);
85 /* ************ default op callbacks, exported *********** */
87 int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event)
89 // if(okee(op->type->name)) {
90 // return op->type->exec(C, op);
94 int WM_operator_winactive(bContext *C)
96 if(C->window==NULL) return 0;
100 /* ************ window / screen operator definitions ************** */
102 static void WM_OT_window_duplicate(wmOperatorType *ot)
104 ot->name= "Duplicate Window";
105 ot->idname= "WM_OT_window_duplicate";
107 ot->invoke= NULL; //WM_operator_confirm;
108 ot->exec= wm_window_duplicate_op;
109 ot->poll= WM_operator_winactive;
112 static void WM_OT_save_homefile(wmOperatorType *ot)
114 ot->name= "Save User Settings";
115 ot->idname= "WM_OT_save_homefile";
117 ot->invoke= NULL; //WM_operator_confirm;
118 ot->exec= WM_write_homefile;
119 ot->poll= WM_operator_winactive;
121 ot->flag= OPTYPE_REGISTER;
124 static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
126 ot->name= "Toggle Fullscreen";
127 ot->idname= "WM_OT_window_fullscreen_toggle";
130 ot->exec= wm_window_fullscreen_toggle_op;
131 ot->poll= WM_operator_winactive;
134 static void WM_OT_exit_blender(wmOperatorType *ot)
136 ot->name= "Exit Blender";
137 ot->idname= "WM_OT_exit_blender";
139 ot->invoke= NULL; /* do confirm stuff */
140 ot->exec= wm_exit_blender_op;
141 ot->poll= WM_operator_winactive;
144 /* ************ window gesture operator-callback definitions ************** */
146 * These are default callbacks for use in operators requiring gesture input
149 /* **************** Border gesture *************** */
151 /* Border gesture has two types:
152 1) WM_GESTURE_CROSS_RECT: starts a cross, on mouse click it changes to border
153 2) WM_GESTURE_RECT: starts immediate as a border, on mouse click or release it ends
155 It stores 4 values (xmin, xmax, ymin, ymax) and event it ended with (event_type)
158 static void border_select_apply(bContext *C, wmOperator *op, int event_type)
160 wmGesture *gesture= op->customdata;
161 rcti *rect= gesture->customdata;
163 if(rect->xmin > rect->xmax)
164 SWAP(int, rect->xmin, rect->xmax);
165 if(rect->ymin > rect->ymax)
166 SWAP(int, rect->ymin, rect->ymax);
168 /* operator arguments and storage. */
169 RNA_int_set(op->ptr, "xmin", rect->xmin);
170 RNA_int_set(op->ptr, "ymin", rect->ymin);
171 RNA_int_set(op->ptr, "xmax", rect->xmax);
172 RNA_int_set(op->ptr, "ymax", rect->ymax);
174 RNA_int_set(op->ptr, "event_type", event_type);
176 op->type->exec(C, op);
179 static void border_select_end(bContext *C, wmOperator *op)
181 wmGesture *gesture= op->customdata;
183 WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
184 op->customdata= NULL;
186 WM_event_add_notifier(C, WM_NOTE_AREA_REDRAW, 0, NULL);
190 int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
192 op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT);
194 /* add modal handler */
195 WM_event_add_modal_handler(C, &C->window->handlers, op);
197 WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
199 return OPERATOR_RUNNING_MODAL;
202 int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
204 wmGesture *gesture= op->customdata;
205 rcti *rect= gesture->customdata;
208 switch(event->type) {
211 wm_subwindow_getorigin(C->window, gesture->swinid, &sx, &sy);
213 if(gesture->type==WM_GESTURE_CROSS_RECT && gesture->mode==0) {
214 rect->xmin= rect->xmax= event->x - sx;
215 rect->ymin= rect->ymax= event->y - sy;
218 rect->xmax= event->x - sx;
219 rect->ymax= event->y - sy;
222 WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
230 if(gesture->type==WM_GESTURE_CROSS_RECT && gesture->mode==0) {
232 WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
236 border_select_apply(C, op, event->type);
237 border_select_end(C, op);
238 return OPERATOR_FINISHED;
242 border_select_end(C, op);
243 return OPERATOR_CANCELLED;
245 return OPERATOR_RUNNING_MODAL;
248 /* **************** Tweak gesture *************** */
250 static int tweak_gesture_invoke(bContext *C, wmOperator *op, wmEvent *event)
252 op->customdata= WM_gesture_new(C, event, WM_GESTURE_TWEAK);
254 /* add modal handler */
255 WM_event_add_modal_handler(C, &C->window->handlers, op);
257 WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
259 return OPERATOR_RUNNING_MODAL;
262 static void tweak_gesture_end(bContext *C, wmOperator *op)
264 wmGesture *gesture= op->customdata;
266 WM_gesture_end(C, gesture); /* frees gesture itself, and unregisters from window */
267 op->customdata= NULL;
269 WM_event_add_notifier(C, WM_NOTE_AREA_REDRAW, 0, NULL);
273 static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
275 wmGesture *gesture= op->customdata;
276 rcti *rect= gesture->customdata;
279 switch(event->type) {
282 wm_subwindow_getorigin(C->window, gesture->swinid, &sx, &sy);
284 rect->xmax= event->x - sx;
285 rect->ymax= event->y - sy;
287 if((val= wm_gesture_evaluate(C, gesture))) {
290 event= *(C->window->eventstate);
291 if(gesture->event_type==LEFTMOUSE)
292 event.type= EVT_TWEAK_L;
293 else if(gesture->event_type==RIGHTMOUSE)
294 event.type= EVT_TWEAK_R;
296 event.type= EVT_TWEAK_M;
299 wm_event_add(C->window, &event);
301 tweak_gesture_end(C, op);
302 return OPERATOR_FINISHED;
305 WM_event_add_notifier(C, WM_NOTE_GESTURE_REDRAW, 0, NULL);
312 if(gesture->event_type==event->type) {
313 wm_gesture_evaluate(C, gesture);
314 tweak_gesture_end(C, op);
315 return OPERATOR_FINISHED;
319 return OPERATOR_RUNNING_MODAL;
322 void WM_OT_tweak_gesture(wmOperatorType *ot)
324 ot->name= "Tweak Gesture";
325 ot->idname= "WM_OT_tweak_gesture";
327 ot->invoke= tweak_gesture_invoke;
328 ot->modal= tweak_gesture_modal;
330 ot->poll= WM_operator_winactive;
334 /* ******************************************************* */
336 /* called on initialize WM_exit() */
337 void wm_operatortype_free(void)
339 BLI_freelistN(&global_ops);
342 /* called on initialize WM_init() */
343 void wm_operatortype_init(void)
345 WM_operatortype_append(WM_OT_window_duplicate);
346 WM_operatortype_append(WM_OT_save_homefile);
347 WM_operatortype_append(WM_OT_window_fullscreen_toggle);
348 WM_operatortype_append(WM_OT_exit_blender);
349 WM_operatortype_append(WM_OT_tweak_gesture);
352 /* default keymap for windows and screens, only call once per WM */
353 void wm_window_keymap(wmWindowManager *wm)
355 ListBase *keymap= WM_keymap_listbase(wm, "Window", 0, 0);
357 /* note, this doesn't replace existing keymap items */
358 WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
359 WM_keymap_verify_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
360 WM_keymap_verify_item(keymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0);
361 WM_keymap_verify_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0);