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:
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/CMakeLists.txt47
-rw-r--r--source/blender/windowmanager/SConscript5
-rw-r--r--source/blender/windowmanager/WM_api.h18
-rw-r--r--source/blender/windowmanager/WM_types.h14
-rw-r--r--source/blender/windowmanager/intern/wm.c11
-rw-r--r--source/blender/windowmanager/intern/wm_apple.c8
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c8
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c88
-rw-r--r--source/blender/windowmanager/intern/wm_files.c126
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c26
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c16
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c855
-rw-r--r--source/blender/windowmanager/intern/wm_window.c29
-rw-r--r--source/blender/windowmanager/wm.h2
14 files changed, 791 insertions, 462 deletions
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 6f03928e1fc..20ac3ba7077 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -26,23 +26,26 @@
set(INC
.
- ../nodes
- ../gpu
../blenfont
- ../blenlib
- ../makesdna
- ../makesrna
../blenkernel
- ../imbuf
+ ../blenlib
../blenloader
../editors/include
+ ../gpu
+ ../imbuf
+ ../makesdna
+ ../makesrna
+ ../nodes
../render/extern/include
- ../../../intern/guardedalloc
- ../../../intern/memutil
+ ../../gameengine/BlenderRoutines
../../../intern/elbeem/extern
../../../intern/ghost
+ ../../../intern/guardedalloc
+ ../../../intern/memutil
../../../intern/opennl/extern
- ../../../source/gameengine/BlenderRoutines
+)
+
+set(INC_SYS
${ZLIB_INCLUDE_DIRS}
${OPENGL_INCLUDE_DIR}
${GLEW_INCLUDE_PATH}
@@ -50,7 +53,6 @@ set(INC
set(SRC
intern/wm.c
- intern/wm_apple.c
intern/wm_cursors.c
intern/wm_dragdrop.c
intern/wm_draw.c
@@ -87,17 +89,26 @@ if(WITH_OPENCOLLADA)
endif()
if(WITH_CODEC_QUICKTIME)
- list(APPEND INC ../quicktime ${QUICKTIME_INC})
+ list(APPEND INC
+ ../quicktime
+ )
+ list(APPEND INC_SYS
+ ${QUICKTIME_INCLUDE_DIRS}
+ )
add_definitions(-DWITH_QUICKTIME)
endif()
if(WITH_CODEC_FFMPEG)
- list(APPEND INC ${FFMPEG_INC})
+ list(APPEND INC_SYS
+ ${FFMPEG_INCLUDE_DIRS}
+ )
add_definitions(-DWITH_FFMPEG)
endif()
if(WITH_PYTHON)
- list(APPEND INC ../python ${PYTHON_INCLUDE_DIRS})
+ list(APPEND INC
+ ../python
+ )
add_definitions(-DWITH_PYTHON)
if(WITH_PYTHON_SECURITY)
@@ -109,12 +120,16 @@ if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
endif()
-if(WITH_COCOA)
- list(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/wm_apple.c")
+if(APPLE)
+ if(NOT WITH_COCOA)
+ list(APPEND SRC
+ intern/wm_apple.c
+ )
+ endif()
endif()
if(WITH_BUILDINFO)
add_definitions(-DNAN_BUILDINFO)
endif()
-blender_add_lib_nolist(bf_windowmanager "${SRC}" "${INC}")
+blender_add_lib_nolist(bf_windowmanager "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript
index f52ac8ba3cb..5b6e8b1ab30 100644
--- a/source/blender/windowmanager/SConscript
+++ b/source/blender/windowmanager/SConscript
@@ -1,5 +1,6 @@
#!/usr/bin/python
Import ('env')
+import os
sources = env.Glob('intern/*.c')
@@ -32,8 +33,8 @@ if env['OURPLATFORM'] == 'linux2':
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs += ' ' + env['BF_PTHREADS_INC']
-if env['WITH_GHOST_COCOA']:
- sources.remove('intern/wm_apple.c')
+if env['OURPLATFORM'] != 'darwin' or env['WITH_GHOST_COCOA']:
+ sources.remove('intern' + os.sep + 'wm_apple.c')
if env['BF_BUILDINFO']:
defs.append('NAN_BUILDINFO')
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 1b4fff8cd13..e6325e2101a 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -95,7 +95,7 @@ void WM_window_open_temp (struct bContext *C, struct rcti *position, int type);
int WM_read_homefile_exec(struct bContext *C, struct wmOperator *op);
int WM_read_homefile (struct bContext *C, struct ReportList *reports, short from_memory);
int WM_write_homefile (struct bContext *C, struct wmOperator *op);
-void WM_read_file (struct bContext *C, const char *name, struct ReportList *reports);
+void WM_read_file (struct bContext *C, const char *filepath, struct ReportList *reports);
int WM_write_file (struct bContext *C, const char *target, int fileflags, struct ReportList *reports, int copy);
void WM_read_autosavefile(struct bContext *C);
void WM_autosave_init (struct wmWindowManager *wm);
@@ -216,7 +216,7 @@ int WM_operator_confirm_message(struct bContext *C, struct wmOperator *op, con
/* operator api */
void WM_operator_free (struct wmOperator *op);
-void WM_operator_stack_clear(struct bContext *C);
+void WM_operator_stack_clear(struct wmWindowManager *wm);
struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet);
struct wmOperatorType *WM_operatortype_first(void);
@@ -247,6 +247,8 @@ void WM_operator_properties_gesture_border(struct wmOperatorType *ot, int exten
void WM_operator_properties_gesture_straightline(struct wmOperatorType *ot, int cursor);
void WM_operator_properties_select_all(struct wmOperatorType *ot);
+wmOperator *WM_operator_last_redo(const struct bContext *C);
+
/* MOVE THIS SOMEWHERE ELSE */
#define SEL_TOGGLE 0
#define SEL_SELECT 1
@@ -270,20 +272,26 @@ void WM_operator_py_idname(char *to, const char *from);
/* *************** menu types ******************** */
struct MenuType *WM_menutype_find(const char *idname, int quiet);
int WM_menutype_add(struct MenuType* mt);
+int WM_menutype_contains(struct MenuType* mt);
void WM_menutype_freelink(struct MenuType* mt);
void WM_menutype_free(void);
/* default operator callbacks for border/circle/lasso */
int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_border_select_modal (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_border_select_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_circle_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_circle_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_circle_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op);
/* default operator for arearegions, generates event */
void WM_OT_tweak_gesture(struct wmOperatorType *ot);
@@ -293,12 +301,6 @@ struct wmGesture *WM_gesture_new(struct bContext *C, struct wmEvent *event, int
void WM_gesture_end(struct bContext *C, struct wmGesture *gesture);
void WM_gestures_remove(struct bContext *C);
- /* radial control operator */
-int WM_radial_control_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_radial_control_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-void WM_OT_radial_control_partial(struct wmOperatorType *ot);
-void WM_radial_control_string(struct wmOperator *op, char str[], int maxlen);
-
/* fileselecting support */
void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op);
void WM_event_fileselect_event(struct bContext *C, void *ophandle, int eventval);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 8748703ad8e..49bd3ede37d 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -61,6 +61,10 @@ struct ImBuf;
#define OPTYPE_MACRO 8
#define OPTYPE_GRAB_POINTER 16 /* */
#define OPTYPE_PRESET 32 /* show preset menu */
+#define OPTYPE_INTERNAL 64 /* some operators are mainly for internal use
+ * and don't make sense to be accessed from the
+ * search menu, even if poll() returns TRUE.
+ * currently only used for the search toolbox */
/* context to call operator in for WM_operator_name_call */
/* rna_ui.c contains EnumPropertyItem's of these, keep in sync */
@@ -335,8 +339,8 @@ typedef struct wmEvent {
short type; /* event code itself (short, is also in keymap) */
short val; /* press, release, scrollvalue */
- short x, y; /* mouse pointer position, screen coord */
- short mval[2]; /* region mouse position, name convention pre 2.5 :) */
+ int x, y; /* mouse pointer position, screen coord */
+ int mval[2]; /* region mouse position, name convention pre 2.5 :) */
short unicode; /* future, ghost? */
char ascii; /* from ghost */
char pad;
@@ -344,9 +348,9 @@ typedef struct wmEvent {
/* previous state */
short prevtype;
short prevval;
- short prevx, prevy;
+ int prevx, prevy;
double prevclicktime;
- short prevclickx, prevclicky;
+ int prevclickx, prevclicky;
/* modifier states */
short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */
@@ -494,7 +498,7 @@ typedef struct wmDrag {
struct ImBuf *imb; /* if no icon but imbuf should be drawn around cursor */
float scale;
- short sx, sy;
+ int sx, sy;
char opname[240]; /* FILE_MAX */ /* if set, draws operator name*/
} wmDrag;
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 424c13f089f..a535c0bc1f8 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -137,9 +137,8 @@ void wm_operator_register(bContext *C, wmOperator *op)
}
-void WM_operator_stack_clear(bContext *C)
+void WM_operator_stack_clear(wmWindowManager *wm)
{
- wmWindowManager *wm= CTX_wm_manager(C);
wmOperator *op;
while((op= wm->operators.first)) {
@@ -147,7 +146,7 @@ void WM_operator_stack_clear(bContext *C)
WM_operator_free(op);
}
- WM_event_add_notifier(C, NC_WM|ND_HISTORY, NULL);
+ WM_main_add_notifier(NC_WM|ND_HISTORY, NULL);
}
/* ****************************************** */
@@ -176,6 +175,12 @@ int WM_menutype_add(MenuType* mt)
return 1;
}
+/* inefficient but only used for tooltip code */
+int WM_menutype_contains(MenuType* mt)
+{
+ return (mt != NULL && BLI_findindex(&menutypes, mt) != -1);
+}
+
void WM_menutype_freelink(MenuType* mt)
{
BLI_freelinkN(&menutypes, mt);
diff --git a/source/blender/windowmanager/intern/wm_apple.c b/source/blender/windowmanager/intern/wm_apple.c
index 083500420a4..7748efb6f64 100644
--- a/source/blender/windowmanager/intern/wm_apple.c
+++ b/source/blender/windowmanager/intern/wm_apple.c
@@ -30,8 +30,7 @@
* \ingroup wm
*/
-
-#ifdef __APPLE__
+/* note, this file builds on apple-carbon only! */
#include "BKE_context.h"
#include "BKE_global.h"
@@ -137,8 +136,3 @@ void wm_set_apple_prefsize(int scr_x, int scr_y)
G.windowstate= 0;
}
}
-
-
-#endif /* __APPLE__ */
-
-
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index c94ad74be72..4fe82917705 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -816,11 +816,3 @@ void wm_draw_region_clear(wmWindow *win, ARegion *ar)
win->screen->do_draw= 1;
}
-static void wm_draw_region_modified(wmWindow *win, ARegion *ar)
-{
- int drawmethod= wm_automatic_draw_method(win);
-
- if(ELEM(drawmethod, USER_DRAW_OVERLAP, USER_DRAW_OVERLAP_FLIP))
- ED_region_tag_redraw(ar);
-}
-
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index feff0393b88..ce3830b059c 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -340,7 +340,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
int is_wheel= ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
int retval;
- /* UI is quite agressive with swallowing events, like scrollwheel */
+ /* UI is quite aggressive with swallowing events, like scrollwheel */
/* I realize this is not extremely nice code... when UI gets keymaps it can be maybe smarter */
if(do_wheel_ui==0) {
if(is_wheel)
@@ -661,6 +661,11 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event)
event->mval[0]= event->x - ar->winrct.xmin;
event->mval[1]= event->y - ar->winrct.ymin;
}
+ else {
+ /* these values are invalid (avoid odd behavior by relying on old mval values) */
+ event->mval[0]= -1;
+ event->mval[1]= -1;
+ }
}
static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, PointerRNA *properties, ReportList *reports, short poll_only)
@@ -1284,16 +1289,23 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
if (handler->op_area == NULL) {
bScreen *screen = CTX_wm_screen(C);
sa = (ScrArea *)screen->areabase.first;
- } else
+ }
+ else {
sa = handler->op_area;
+ }
- if(event->val==EVT_FILESELECT_OPEN)
- ED_area_newspace(C, sa, SPACE_FILE);
- else
- ED_screen_full_newspace(C, sa, SPACE_FILE); /* sets context */
-
+ if(event->val==EVT_FILESELECT_OPEN) {
+ ED_area_newspace(C, sa, SPACE_FILE); /* 'sa' is modified in-place */
+ }
+ else {
+ sa= ED_screen_full_newspace(C, sa, SPACE_FILE); /* sets context */
+ }
+
+ /* note, getting the 'sa' back from the context causes a nasty bug where the newly created
+ * 'sa' != CTX_wm_area(C). removed the line below and set 'sa' in the 'if' above */
+ /* sa = CTX_wm_area(C); */
+
/* settings for filebrowser, sfile is not operator owner but sends events */
- sa = CTX_wm_area(C);
sfile= (SpaceFile*)sa->spacedata.first;
sfile->op= handler->op;
@@ -1565,7 +1577,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
* so check for mouse moves too.
* note2: the first click event will be handled but still used to create a
* double click event if clicking again quickly.
- * If no double click events are found itwill fallback to a single click.
+ * If no double click events are found it will fallback to a single click.
* So a double click event can result in 2 successive single click calls
* if its not handled by the keymap - campbell */
if ( (ABS(event->x - win->eventstate->prevclickx)) <= 2 &&
@@ -1776,6 +1788,8 @@ void wm_event_do_handlers(bContext *C)
/* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */
wm_window_make_drawable(C, win);
+ wm_region_mouse_co(C, event);
+
/* first we do priority handlers, modal + some limited keymaps */
action |= wm_handlers_do(C, event, &win->modalhandlers);
@@ -1811,10 +1825,12 @@ void wm_event_do_handlers(bContext *C)
if(wm_event_inside_i(event, &ar->winrct)) {
CTX_wm_region_set(C, ar);
+ /* call even on non mouse events, since the */
+ wm_region_mouse_co(C, event);
+
/* does polls for drop regions and checks uibuts */
/* need to be here to make sure region context is true */
if(ELEM(event->type, MOUSEMOVE, EVT_DROP)) {
- wm_region_mouse_co(C, event);
wm_drags_check_ops(C, event);
}
@@ -1834,9 +1850,10 @@ void wm_event_do_handlers(bContext *C)
CTX_wm_region_set(C, NULL);
- if((action & WM_HANDLER_BREAK) == 0)
+ if((action & WM_HANDLER_BREAK) == 0) {
+ wm_region_mouse_co(C, event); /* only invalidates event->mval in this case */
action |= wm_handlers_do(C, event, &sa->handlers);
-
+ }
CTX_wm_area_set(C, NULL);
/* NOTE: do not escape on WM_HANDLER_BREAK, mousemove needs handled for previous area */
@@ -1848,6 +1865,8 @@ void wm_event_do_handlers(bContext *C)
CTX_wm_area_set(C, area_event_inside(C, event->x, event->y));
CTX_wm_region_set(C, region_event_inside(C, event->x, event->y));
+ wm_region_mouse_co(C, event);
+
action |= wm_handlers_do(C, event, &win->handlers);
/* fileread case */
@@ -2293,7 +2312,7 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
/* imperfect but probably usable... draw/enable drags to other windows */
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *evt)
{
- short mx= evt->x, my= evt->y;
+ int mx= evt->x, my= evt->y;
if(wm->windows.first== wm->windows.last)
return NULL;
@@ -2310,8 +2329,8 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
return NULL;
/* to desktop space */
- mx+= win->posx;
- my+= win->posy;
+ mx += (int)win->posx;
+ my += (int)win->posy;
/* check other windows to see if it has mouse inside */
for(owin= wm->windows.first; owin; owin= owin->next) {
@@ -2319,8 +2338,8 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
if(owin!=win) {
if(mx-owin->posx >= 0 && my-owin->posy >= 0 &&
mx-owin->posx <= owin->sizex && my-owin->posy <= owin->sizey) {
- evt->x= mx-owin->posx;
- evt->y= my-owin->posy;
+ evt->x= mx - (int)owin->posx;
+ evt->y= my - (int)owin->posy;
return owin;
}
@@ -2346,18 +2365,11 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
if(win->active) {
GHOST_TEventCursorData *cd= customdata;
wmEvent *lastevent= win->queue.last;
-
-#if defined(__APPLE__) && defined(GHOST_COCOA)
- //Cocoa already uses coordinates with y=0 at bottom, and returns inwindow coordinates on mouse moved event
- evt->x= cd->x;
- evt->y= cd->y;
-#else
int cx, cy;
GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy);
evt->x= cx;
evt->y= (win->sizey-1) - cy;
-#endif
event.x= evt->x;
event.y= evt->y;
@@ -2404,21 +2416,17 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
event.type= MOUSEPAN;
break;
}
-#if defined(__APPLE__) && defined(GHOST_COCOA)
- //Cocoa already uses coordinates with y=0 at bottom, and returns inwindow coordinates on mouse moved event
- event.x= evt->x = pd->x;
- event.y = evt->y = pd->y;
-#else
+
{
- int cx, cy;
- GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy);
- event.x= evt->x= cx;
- event.y= evt->y= (win->sizey-1) - cy;
+ int cx, cy;
+ GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy);
+ event.x= evt->x= cx;
+ event.y= evt->y= (win->sizey-1) - cy;
}
-#endif
+
// Use prevx/prevy so we can calculate the delta later
event.prevx= event.x - pd->deltaX;
- event.prevy= event.y - pd->deltaY;
+ event.prevy= event.y - (-pd->deltaY);
update_tablet_data(win, &event);
wm_event_add(win, &event);
@@ -2441,6 +2449,16 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
else
event.type= MIDDLEMOUSE;
+ if(win->active==0) {
+ int cx, cy;
+
+ /* entering window, update mouse pos. (ghost sends win-activate *after* the mouseclick in window!) */
+ wm_get_cursor_position(win, &cx, &cy);
+
+ event.x= evt->x= cx;
+ event.y= evt->y= cy;
+ }
+
/* add to other window if event is there (not to both!) */
owin= wm_event_cursor_other_windows(wm, win, &event);
if(owin) {
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 2783504ae90..27fc0caeccc 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -57,6 +57,7 @@
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_utildefines.h"
+#include "BLI_callbacks.h"
#include "DNA_anim_types.h"
#include "DNA_ipo_types.h" // XXX old animation system
@@ -333,7 +334,7 @@ static int wm_read_exotic(Scene *UNUSED(scene), const char *name)
return retval;
}
-void WM_read_file(bContext *C, const char *name, ReportList *reports)
+void WM_read_file(bContext *C, const char *filepath, ReportList *reports)
{
int retval;
@@ -342,10 +343,12 @@ void WM_read_file(bContext *C, const char *name, ReportList *reports)
WM_cursor_wait(1);
+ BLI_exec_cb(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
+
/* first try to append data from exotic file formats... */
/* it throws error box when file doesnt exist and returns -1 */
/* note; it should set some error message somewhere... (ton) */
- retval= wm_read_exotic(CTX_data_scene(C), name);
+ retval= wm_read_exotic(CTX_data_scene(C), filepath);
/* we didn't succeed, now try to read Blender file */
if (retval == BKE_READ_EXOTIC_OK_BLEND) {
@@ -356,7 +359,7 @@ void WM_read_file(bContext *C, const char *name, ReportList *reports)
/* also exit screens and editors */
wm_window_match_init(C, &wmbase);
- retval= BKE_read_file(C, name, reports);
+ retval= BKE_read_file(C, filepath, reports);
G.save_over = 1;
/* this flag is initialized by the operator but overwritten on read.
@@ -392,6 +395,7 @@ void WM_read_file(bContext *C, const char *name, ReportList *reports)
#ifdef WITH_PYTHON
/* run any texts that were loaded in and flagged as modules */
BPY_driver_reset();
+ BPY_app_handlers_reset();
BPY_modules_load_user(C);
#endif
CTX_wm_window_set(C, NULL); /* exits queues */
@@ -411,21 +415,22 @@ void WM_read_file(bContext *C, const char *name, ReportList *reports)
// XXX undo_editmode_clear();
BKE_reset_undo();
BKE_write_undo(C, "original"); /* save current state */
-
+
+ BLI_exec_cb(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);
}
else if(retval == BKE_READ_EXOTIC_OK_OTHER)
BKE_write_undo(C, "Import file");
else if(retval == BKE_READ_EXOTIC_FAIL_OPEN) {
- BKE_reportf(reports, RPT_ERROR, "Can't read file: \"%s\", %s.", name, errno ? strerror(errno) : "Unable to open the file");
+ BKE_reportf(reports, RPT_ERROR, "Can't read file: \"%s\", %s.", filepath, errno ? strerror(errno) : "Unable to open the file");
}
else if(retval == BKE_READ_EXOTIC_FAIL_FORMAT) {
- BKE_reportf(reports, RPT_ERROR, "File format is not supported in file: \"%s\".", name);
+ BKE_reportf(reports, RPT_ERROR, "File format is not supported in file: \"%s\".", filepath);
}
else if(retval == BKE_READ_EXOTIC_FAIL_PATH) {
- BKE_reportf(reports, RPT_ERROR, "File path invalid: \"%s\".", name);
+ BKE_reportf(reports, RPT_ERROR, "File path invalid: \"%s\".", filepath);
}
else {
- BKE_reportf(reports, RPT_ERROR, "Unknown error loading: \"%s\".", name);
+ BKE_reportf(reports, RPT_ERROR, "Unknown error loading: \"%s\".", filepath);
BLI_assert(!"invalid 'retval'");
}
@@ -485,15 +490,16 @@ int WM_read_homefile(bContext *C, ReportList *reports, short from_memory)
/* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise
* can remove this eventually, only in a 2.53 and older, now its not written */
G.fileflags &= ~G_FILE_RELATIVE_REMAP;
-
+
+ /* check userdef before open window, keymaps etc */
+ wm_init_userdef(C);
+
/* match the read WM with current WM */
wm_window_match_do(C, &wmbase);
WM_check(C); /* opens window(s), checks keymaps */
G.main->name[0]= '\0';
- wm_init_userdef(C);
-
/* When loading factory settings, the reset solid OpenGL lights need to be applied. */
if (!G.background) GPU_default_lights();
@@ -517,6 +523,7 @@ int WM_read_homefile(bContext *C, ReportList *reports, short from_memory)
BPY_string_exec(C, "__import__('addon_utils').reset_all()");
BPY_driver_reset();
+ BPY_app_handlers_reset();
BPY_modules_load_user(C);
}
#endif
@@ -544,7 +551,7 @@ void WM_read_history(void)
struct RecentFile *recent;
char *line;
int num;
- char *cfgdir = BLI_get_folder(BLENDER_CONFIG, NULL);
+ char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (!cfgdir) return;
@@ -620,31 +627,6 @@ static void write_history(void)
}
}
-static void do_history(char *name, ReportList *reports)
-{
- char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE];
- int hisnr= U.versions;
-
- if(U.versions==0) return;
- if(strlen(name)<2) return;
-
- while(hisnr > 1) {
- BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr-1);
- BLI_snprintf(tempname2, sizeof(tempname2), "%s%d", name, hisnr);
-
- if(BLI_rename(tempname1, tempname2))
- BKE_report(reports, RPT_ERROR, "Unable to make version backup");
-
- hisnr--;
- }
-
- /* is needed when hisnr==1 */
- BLI_snprintf(tempname1, sizeof(tempname1), "%s%d", name, hisnr);
-
- if(BLI_rename(name, tempname1))
- BKE_report(reports, RPT_ERROR, "Unable to make version backup");
-}
-
static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt)
{
/* will be scaled down, but gives some nice oversampling */
@@ -653,8 +635,9 @@ static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt)
char err_out[256]= "unknown";
*thumb_pt= NULL;
-
- if(G.background || scene->camera==NULL)
+
+ /* scene can be NULL if running a script at startup and calling the save operator */
+ if(G.background || scene==NULL || scene->camera==NULL)
return NULL;
/* gets scaled to BLEN_THUMB_SIZE */
@@ -693,9 +676,11 @@ static ImBuf *blend_file_thumb(Scene *scene, int **thumb_pt)
int write_crash_blend(void)
{
char path[FILE_MAX];
+ int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on crash file */
+
BLI_strncpy(path, G.main->name, sizeof(path));
BLI_replace_extension(path, sizeof(path), "_crash.blend");
- if(BLO_write_file(G.main, path, G.fileflags, NULL, NULL)) {
+ if(BLO_write_file(G.main, path, fileflags, NULL, NULL)) {
printf("written: %s\n", path);
return 1;
}
@@ -709,7 +694,7 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re
{
Library *li;
int len;
- char di[FILE_MAX];
+ char filepath[FILE_MAX];
int *thumb= NULL;
ImBuf *ibuf_thumb= NULL;
@@ -726,18 +711,26 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re
return -1;
}
- BLI_strncpy(di, target, FILE_MAX);
- BLI_replace_extension(di, FILE_MAX, ".blend");
+ BLI_strncpy(filepath, target, FILE_MAX);
+ BLI_replace_extension(filepath, FILE_MAX, ".blend");
/* dont use 'target' anymore */
/* send the OnSave event */
for (li= G.main->library.first; li; li= li->id.next) {
- if (BLI_path_cmp(li->filepath, di) == 0) {
- BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.200s'", di);
+ if (BLI_path_cmp(li->filepath, filepath) == 0) {
+ BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.200s'", filepath);
return -1;
}
}
+ /* blend file thumbnail */
+ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */
+ if(U.flag & USER_SAVE_PREVIEWS) {
+ ibuf_thumb= blend_file_thumb(CTX_data_scene(C), &thumb);
+ }
+
+ BLI_exec_cb(G.main, NULL, BLI_CB_EVT_SAVE_PRE);
+
/* operator now handles overwrite checks */
if (G.fileflags & G_AUTOPACK) {
@@ -750,16 +743,12 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re
/* don't forget not to return without! */
WM_cursor_wait(1);
- /* blend file thumbnail */
- ibuf_thumb= blend_file_thumb(CTX_data_scene(C), &thumb);
+ fileflags |= G_FILE_HISTORY; /* write file history */
- /* rename to .blend1, do this as last before write */
- do_history(di, reports);
-
- if (BLO_write_file(CTX_data_main(C), di, fileflags, reports, thumb)) {
+ if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) {
if(!copy) {
G.relbase_valid = 1;
- BLI_strncpy(G.main->name, di, sizeof(G.main->name)); /* is guaranteed current file */
+ BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); /* is guaranteed current file */
G.save_over = 1; /* disable untitled.blend convention */
}
@@ -770,11 +759,16 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re
if(fileflags & G_FILE_AUTOPLAY) G.fileflags |= G_FILE_AUTOPLAY;
else G.fileflags &= ~G_FILE_AUTOPLAY;
- write_history();
+ /* prevent background mode scripts from clobbering history */
+ if(!G.background) {
+ write_history();
+ }
+
+ BLI_exec_cb(G.main, NULL, BLI_CB_EVT_SAVE_POST);
/* run this function after because the file cant be written before the blend is */
if (ibuf_thumb) {
- ibuf_thumb= IMB_thumb_create(di, THB_NORMAL, THB_SOURCE_BLEND, ibuf_thumb);
+ ibuf_thumb= IMB_thumb_create(filepath, THB_NORMAL, THB_SOURCE_BLEND, ibuf_thumb);
IMB_freeImBuf(ibuf_thumb);
}
@@ -798,20 +792,20 @@ int WM_write_homefile(bContext *C, wmOperator *op)
{
wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win= CTX_wm_window(C);
- char tstr[FILE_MAXDIR+FILE_MAXFILE];
+ char filepath[FILE_MAXDIR+FILE_MAXFILE];
int fileflags;
/* check current window and close it if temp */
if(win->screen->temp)
wm_window_close(C, wm, win);
- BLI_make_file_string("/", tstr, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
- printf("trying to save homefile at %s ", tstr);
+ BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
+ printf("trying to save homefile at %s ", filepath);
/* force save as regular blend file */
- fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN);
+ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY);
- if(BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports, NULL) == 0) {
+ if(BLO_write_file(CTX_data_main(C), filepath, fileflags, op->reports, NULL) == 0) {
printf("fail\n");
return OPERATOR_CANCELLED;
}
@@ -825,7 +819,7 @@ int WM_write_homefile(bContext *C, wmOperator *op)
/************************ autosave ****************************/
-void wm_autosave_location(char *filename)
+void wm_autosave_location(char *filepath)
{
char pidstr[32];
#ifdef WIN32
@@ -845,12 +839,12 @@ void wm_autosave_location(char *filename)
* If there is no C:\tmp autosave fails. */
if (!BLI_exists(U.tempdir)) {
savedir = BLI_get_folder_create(BLENDER_USER_AUTOSAVE, NULL);
- BLI_make_file_string("/", filename, savedir, pidstr);
+ BLI_make_file_string("/", filepath, savedir, pidstr);
return;
}
#endif
- BLI_make_file_string("/", filename, U.tempdir, pidstr);
+ BLI_make_file_string("/", filepath, U.tempdir, pidstr);
}
void WM_autosave_init(wmWindowManager *wm)
@@ -865,7 +859,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w
{
wmWindow *win;
wmEventHandler *handler;
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
int fileflags;
WM_event_remove_timer(wm, NULL, wm->autosavetimer);
@@ -880,13 +874,13 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w
}
}
- wm_autosave_location(filename);
+ wm_autosave_location(filepath);
/* force save as regular blend file */
- fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_AUTOPLAY |G_FILE_LOCK|G_FILE_SIGN);
+ fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_AUTOPLAY |G_FILE_LOCK|G_FILE_SIGN|G_FILE_HISTORY);
/* no error reporting to console */
- BLO_write_file(CTX_data_main(C), filename, fileflags, NULL, NULL);
+ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
/* do timer after file write, just in case file write takes a long time */
wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index b09e264bd1d..4c280fe4341 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -48,6 +48,7 @@
#include "BKE_blender.h"
#include "BKE_context.h"
+#include "BKE_screen.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
@@ -154,6 +155,8 @@ void WM_init(bContext *C, int argc, const char **argv)
BPY_python_start(argc, argv);
BPY_driver_reset();
+ BPY_app_handlers_reset(); /* causes addon callbacks to be freed [#28068],
+ * but this is actually what we want. */
BPY_modules_load_user(C);
#else
(void)argc; /* unused */
@@ -168,6 +171,7 @@ void WM_init(bContext *C, int argc, const char **argv)
if (!G.background) {
GPU_extensions_init();
GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
+ GPU_set_anisotropic(U.anisotropic_filter);
UI_init();
}
@@ -247,15 +251,7 @@ int WM_init_game(bContext *C)
CTX_wm_window_set(C, win);
sa = biggest_view3d(C);
-
- if(sa)
- {
- for(ar=sa->regionbase.first; ar; ar=ar->next) {
- if(ar->regiontype == RGN_TYPE_WINDOW) {
- break;
- }
- }
- }
+ ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
// if we have a valid 3D view
if (sa && ar) {
@@ -335,7 +331,6 @@ static void free_openrecent(void)
/* bad stuff*/
-extern ListBase editelems;
extern wchar_t *copybuf;
extern wchar_t *copybufinfo;
@@ -387,7 +382,6 @@ void WM_exit(bContext *C)
BKE_freecubetable();
- fastshade_free_render(); /* shaded view */
ED_preview_free_dbase(); /* frees a Main dbase, before free_blender! */
if(C && CTX_wm_manager(C))
@@ -401,10 +395,6 @@ void WM_exit(bContext *C)
free_anim_drivers_copybuf();
free_fmodifiers_copybuf();
free_posebuf();
-// free_vertexpaint();
-// free_imagepaint();
-
-// fsmenu_free();
BLF_exit();
@@ -427,11 +417,7 @@ void WM_exit(bContext *C)
BPY_python_end();
#endif
- if (!G.background) {
-// XXX UI_filelist_free_icons();
- }
-
- GPU_buffer_pool_free(NULL);
+ GPU_global_buffer_pool_free();
GPU_free_unused_buffers();
GPU_extensions_exit();
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 336acd9f9bf..1720c738dd7 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -493,17 +493,17 @@ static wmKeyMapItem *wm_keymap_item_find_props(const bContext *C, const char *op
}
else if(ELEM(opcontext, WM_OP_EXEC_REGION_CHANNELS, WM_OP_INVOKE_REGION_CHANNELS)) {
if (!(ar && ar->regiontype == RGN_TYPE_CHANNELS))
- ar= BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS);
-
- if(ar)
- found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
+ ar= BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS);
+
+ if(ar)
+ found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
}
else if(ELEM(opcontext, WM_OP_EXEC_REGION_PREVIEW, WM_OP_INVOKE_REGION_PREVIEW)) {
if (!(ar && ar->regiontype == RGN_TYPE_PREVIEW))
- ar= BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
-
- if(ar)
- found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
+ ar= BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
+
+ if(ar)
+ found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r);
}
else {
if(ar)
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 63a8ecc4043..29afdb570ea 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -56,11 +56,13 @@
#include "BLI_blenlib.h"
#include "BLI_dynstr.h" /*for WM_operator_pystring */
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLO_readfile.h"
#include "BKE_blender.h"
+#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_idprop.h"
@@ -440,10 +442,12 @@ void WM_operator_py_idname(char *to, const char *from)
{
char *sep= strstr(from, "_OT_");
if(sep) {
- int i, ofs= (sep-from);
-
- for(i=0; i<ofs; i++)
- to[i]= tolower(from[i]);
+ int ofs= (sep-from);
+
+ /* note, we use ascii tolower instead of system tolower, because the
+ latter depends on the locale, and can lead to idname mistmatch */
+ memcpy(to, from, sizeof(char)*ofs);
+ BLI_ascii_strtolower(to, ofs);
to[ofs] = '.';
BLI_strncpy(to+(ofs+1), sep+4, OP_MAX_TYPENAME);
@@ -461,10 +465,10 @@ void WM_operator_bl_idname(char *to, const char *from)
char *sep= strchr(from, '.');
if(sep) {
- int i, ofs= (sep-from);
+ int ofs= (sep-from);
- for(i=0; i<ofs; i++)
- to[i]= toupper(from[i]);
+ memcpy(to, from, sizeof(char)*ofs);
+ BLI_ascii_strtoupper(to, ofs);
BLI_strncpy(to+ofs, "_OT_", OP_MAX_TYPENAME);
BLI_strncpy(to+(ofs+4), sep+1, OP_MAX_TYPENAME);
@@ -682,7 +686,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *arg_ot, cons
RNA_property_enum_items((bContext *)C, &ptr, prop, &item_array, NULL, &do_free);
for(item= item_array; item->identifier; item++) {
- /* note: need to give the intex rather then the dientifier because the enum can be freed */
+ /* note: need to give the intex rather than the dientifier because the enum can be freed */
if(BLI_strcasestr(item->name, str))
if(0==uiSearchItemAdd(items, item->name, SET_INT_IN_POINTER(item->value), 0))
break;
@@ -698,11 +702,16 @@ static void operator_enum_call_cb(struct bContext *C, void *arg1, void *arg2)
wmOperatorType *ot= arg1;
if(ot) {
- PointerRNA props_ptr;
- WM_operator_properties_create_ptr(&props_ptr, ot);
- RNA_property_enum_set(&props_ptr, ot->prop, GET_INT_FROM_POINTER(arg2));
- WM_operator_name_call(C, ot->idname, WM_OP_EXEC_DEFAULT, &props_ptr);
- WM_operator_properties_free(&props_ptr);
+ if(ot->prop) {
+ PointerRNA props_ptr;
+ WM_operator_properties_create_ptr(&props_ptr, ot);
+ RNA_property_enum_set(&props_ptr, ot->prop, GET_INT_FROM_POINTER(arg2));
+ WM_operator_name_call(C, ot->idname, WM_OP_EXEC_DEFAULT, &props_ptr);
+ WM_operator_properties_free(&props_ptr);
+ }
+ else {
+ printf("operator_enum_call_cb: op->prop for '%s' is NULL\n", ot->idname);
+ }
}
}
@@ -718,14 +727,14 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
- //uiDefBut(block, LABEL, 0, op->type->name, 10, 10, 180, 19, NULL, 0.0, 0.0, 0, 0, ""); // ok, this isnt so easy...
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, "");
+ //uiDefBut(block, LABEL, 0, op->type->name, 10, 10, 180, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); // ok, this isnt so easy...
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
uiButSetSearchFunc(but, operator_enum_search_cb, op->type, operator_enum_call_cb, NULL);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9*UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
- uiPopupBoundsBlock(block, 6, 0, -20); /* move it downwards, mouse over button */
+ uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
event= *(win->eventstate); /* XXX huh huh? make api call */
@@ -876,6 +885,19 @@ int WM_operator_winactive(bContext *C)
return 1;
}
+wmOperator *WM_operator_last_redo(const bContext *C)
+{
+ wmWindowManager *wm= CTX_wm_manager(C);
+ wmOperator *op;
+
+ /* only for operators that are registered and did an undo push */
+ for(op= wm->operators.last; op; op= op->prev)
+ if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
+ break;
+
+ return op;
+}
+
static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
{
wmOperator *op= arg_op;
@@ -894,12 +916,21 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
assert(op->type->flag & OPTYPE_REGISTER);
uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, arg_op);
- layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, 20, style);
+ layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, style);
if(ED_undo_valid(C, op->type->name)==0)
uiLayoutSetEnabled(layout, 0);
- uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
+ if(op->type->flag & OPTYPE_MACRO) {
+ for(op= op->macro.first; op; op= op->next) {
+ uiItemL(layout, op->type->name, ICON_NONE);
+ uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
+ }
+ }
+ else {
+ uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
+ }
+
uiPopupBoundsBlock(block, 4, 0, 0);
uiEndBlock(C, block);
@@ -907,13 +938,28 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
return block;
}
-/* Only invoked by OK button in popups created with wm_block_create_dialog() */
+typedef struct wmOpPopUp
+{
+ wmOperator *op;
+ int width;
+ int height;
+ int free_op;
+} wmOpPopUp;
+
+/* Only invoked by OK button in popups created with wm_block_dialog_create() */
static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
{
- wmOperator *op= arg1;
+ wmOpPopUp *data= arg1;
uiBlock *block= arg2;
- WM_operator_call(C, op);
+ WM_operator_call(C, data->op);
+
+ /* let execute handle freeing it */
+ //data->free_op= FALSE;
+ //data->op= NULL;
+
+ /* in this case, wm_operator_ui_popup_cancel wont run */
+ MEM_freeN(data);
uiPupBlockClose(C, block);
}
@@ -929,9 +975,9 @@ static void dialog_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
}
/* Dialogs are popups that require user verification (click OK) before exec */
-static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
+static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
{
- struct { wmOperator *op; int width; int height; } * data = userData;
+ wmOpPopUp *data= userData;
wmOperator *op= data->op;
uiBlock *block;
uiLayout *layout;
@@ -959,8 +1005,8 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
col= uiLayoutColumn(layout, FALSE);
col_block= uiLayoutGetBlock(col);
/* Create OK button, the callback of which will execute op */
- btn= uiDefBut(col_block, BUT, 0, "OK", 0, -30, 0, 20, NULL, 0, 0, 0, 0, "");
- uiButSetFunc(btn, dialog_exec_cb, op, col_block);
+ btn= uiDefBut(col_block, BUT, 0, "OK", 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ uiButSetFunc(btn, dialog_exec_cb, data, col_block);
}
/* center around the mouse */
@@ -970,9 +1016,9 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
return block;
}
-static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData)
+static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
{
- struct { wmOperator *op; int width; int height; } * data = userData;
+ wmOpPopUp *data= userData;
wmOperator *op= data->op;
uiBlock *block;
uiLayout *layout;
@@ -993,6 +1039,28 @@ static uiBlock *wm_operator_create_ui(bContext *C, ARegion *ar, void *userData)
return block;
}
+static void wm_operator_ui_popup_cancel(void *userData)
+{
+ wmOpPopUp *data= userData;
+ if(data->free_op && data->op) {
+ wmOperator *op= data->op;
+ WM_operator_free(op);
+ }
+
+ MEM_freeN(data);
+}
+
+int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
+{
+ wmOpPopUp *data= MEM_callocN(sizeof(wmOpPopUp), "WM_operator_ui_popup");
+ data->op= op;
+ data->width= width;
+ data->height= height;
+ data->free_op= TRUE; /* if this runs and gets registered we may want not to free it */
+ uiPupBlockEx(C, wm_operator_ui_create, wm_operator_ui_popup_cancel, data);
+ return OPERATOR_RUNNING_MODAL;
+}
+
/* operator menu needs undo, for redo callback */
int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
@@ -1012,28 +1080,19 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int height)
{
- struct { wmOperator *op; int width; int height; } data;
+ wmOpPopUp *data= MEM_callocN(sizeof(wmOpPopUp), "WM_operator_props_dialog_popup");
- data.op= op;
- data.width= width;
- data.height= height;
+ data->op= op;
+ data->width= width;
+ data->height= height;
+ data->free_op= TRUE; /* if this runs and gets registered we may want not to free it */
/* op is not executed until popup OK but is clicked */
- uiPupBlock(C, wm_block_create_dialog, &data);
+ uiPupBlockEx(C, wm_block_dialog_create, wm_operator_ui_popup_cancel, data);
return OPERATOR_RUNNING_MODAL;
}
-int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
-{
- struct { wmOperator *op; int width; int height; } data;
- data.op = op;
- data.width = width;
- data.height = height;
- uiPupBlock(C, wm_operator_create_ui, &data);
- return OPERATOR_RUNNING_MODAL;
-}
-
int WM_operator_redo_popup(bContext *C, wmOperator *op)
{
/* CTX_wm_reports(C) because operator is on stack, not active in event system */
@@ -1065,7 +1124,7 @@ static int wm_debug_menu_exec(bContext *C, wmOperator *op)
static int wm_debug_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
RNA_int_set(op->ptr, "debug_value", G.rt);
- return WM_operator_props_dialog_popup(C, op, 180, 20);
+ return WM_operator_props_dialog_popup(C, op, 9*UI_UNIT_X, UI_UNIT_Y);
}
static void WM_OT_debug_menu(wmOperatorType *ot)
@@ -1163,8 +1222,8 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
#ifdef NAN_BUILDINFO
- uiDefBut(block, LABEL, 0, version_str, 494-ver_width, 282-24, ver_width, 20, NULL, 0, 0, 0, 0, NULL);
- uiDefBut(block, LABEL, 0, revision_str, 494-rev_width, 282-36, rev_width, 20, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, version_str, 494-ver_width, 282-24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, revision_str, 494-rev_width, 282-36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
#endif //NAN_BUILDINFO
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style);
@@ -1188,7 +1247,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
col = uiLayoutColumn(split, 0);
uiItemL(col, "Links", ICON_NONE);
uiItemStringO(col, "Donations", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/blenderorg/blender-foundation/donation-payment/");
- uiItemStringO(col, "Release Log", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-257/");
+ uiItemStringO(col, "Release Log", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/release-logs/blender-258/");
uiItemStringO(col, "Manual", ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.5/Manual");
uiItemStringO(col, "Blender Website", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/");
uiItemStringO(col, "User Community", ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/community/user-community/"); //
@@ -1255,7 +1314,10 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
-
+
+ if((ot->flag & OPTYPE_INTERNAL) && (G.f & G_DEBUG) == 0)
+ continue;
+
if(BLI_strcasestr(ot->name, str)) {
if(WM_operator_poll((bContext*)C, ot)) {
char name[256];
@@ -1288,13 +1350,13 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, "");
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9*UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
- uiPopupBoundsBlock(block, 6, 0, -20); /* move it downwards, mouse over button */
+ uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
event= *(win->eventstate); /* XXX huh huh? make api call */
@@ -1322,10 +1384,20 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(ev
/* op->poll */
static int wm_search_menu_poll(bContext *C)
{
- if(CTX_wm_window(C)==NULL) return 0;
- if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_CONSOLE) return 0; // XXX - so we can use the shortcut in the console
- if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_TEXT) return 0; // XXX - so we can use the spacebar in the text editor
- if(CTX_data_edit_object(C) && CTX_data_edit_object(C)->type==OB_FONT) return 0; // XXX - so we can use the spacebar for entering text
+ if(CTX_wm_window(C)==NULL) {
+ return 0;
+ }
+ else {
+ ScrArea *sa= CTX_wm_area(C);
+ if(sa) {
+ if(sa->spacetype==SPACE_CONSOLE) return 0; // XXX - so we can use the shortcut in the console
+ if(sa->spacetype==SPACE_TEXT) return 0; // XXX - so we can use the spacebar in the text editor
+ }
+ else {
+ Object *editob= CTX_data_edit_object(C);
+ if(editob && editob->type==OB_FONT) return 0; // XXX - so we can use the spacebar for entering text
+ }
+ }
return 1;
}
@@ -1357,6 +1429,8 @@ static void WM_OT_call_menu(wmOperatorType *ot)
ot->exec= wm_call_menu_exec;
ot->poll= WM_operator_winactive;
+ ot->flag= OPTYPE_INTERNAL;
+
RNA_def_string(ot->srna, "name", "", BKE_ST_MAXNAME, "Name", "Name of the menu");
}
@@ -1428,7 +1502,7 @@ static void open_set_load_ui(wmOperator *op)
static void open_set_use_scripts(wmOperator *op)
{
if(!RNA_property_is_set(op->ptr, "use_scripts")) {
- /* use G_SCRIPT_AUTOEXEC rather then the userpref because this means if
+ /* use G_SCRIPT_AUTOEXEC rather than the userpref because this means if
* the flag has been disabled from the command line, then opening
* from the menu wont enable this setting. */
RNA_boolean_set(op->ptr, "use_scripts", (G.f & G_SCRIPT_AUTOEXEC));
@@ -1439,6 +1513,14 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
{
const char *openname= G.main->name;
+ if(CTX_wm_window(C) == NULL) {
+ /* in rare cases this could happen, when trying to invoke in background
+ * mode on load for example. Don't use poll for this because exec()
+ * can still run without a window */
+ BKE_report(op->reports, RPT_ERROR, "Context window not set");
+ return OPERATOR_CANCELLED;
+ }
+
/* if possible, get the name of the most recently used .blend file */
if (G.recent_files.first) {
struct RecentFile *recent = G.recent_files.first;
@@ -1489,7 +1571,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
ot->invoke= wm_open_mainfile_invoke;
ot->exec= wm_open_mainfile_exec;
- ot->poll= WM_operator_winactive;
+ /* ommit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH);
@@ -1610,12 +1692,12 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* here appending/linking starts */
mainl = BLO_library_append_begin(C, &bh, libname);
if(totfiles == 0) {
- BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag);
+ BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
}
else {
RNA_BEGIN(op->ptr, itemptr, "files") {
RNA_string_get(&itemptr, "name", name);
- BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag);
+ BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
}
RNA_END;
}
@@ -1908,7 +1990,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
ot->invoke= wm_save_mainfile_invoke;
ot->exec= wm_save_as_mainfile_exec;
ot->check= blend_save_check;
- ot->poll= NULL;
+ /* ommit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH);
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file");
@@ -1922,6 +2004,8 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
+ int selected = 0;
+
if(!RNA_property_is_set(op->ptr, "filepath")) {
char filepath[FILE_MAX];
BLI_strncpy(filepath, G.main->name, sizeof(filepath));
@@ -1938,6 +2022,7 @@ static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED
static int wm_collada_export_exec(bContext *C, wmOperator *op)
{
char filename[FILE_MAX];
+ int selected;
if(!RNA_property_is_set(op->ptr, "filepath")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
@@ -1945,7 +2030,8 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
}
RNA_string_get(op->ptr, "filepath", filename);
- if(collada_export(CTX_data_scene(C), filename)) {
+ selected = RNA_boolean_get(op->ptr, "selected");
+ if(collada_export(CTX_data_scene(C), filename, selected)) {
return OPERATOR_FINISHED;
}
else {
@@ -1963,6 +2049,8 @@ static void WM_OT_collada_export(wmOperatorType *ot)
ot->poll= WM_operator_winactive;
WM_operator_properties_filesel(ot, FOLDERFILE|COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH);
+ RNA_def_boolean(ot->srna, "selected", 0, "Export only selected",
+ "Export only selected elements");
}
/* function used for WM_OT_save_mainfile too */
@@ -2030,6 +2118,8 @@ static void WM_OT_quit_blender(wmOperatorType *ot)
/* *********************** */
+#if defined(WIN32)
+
static int wm_console_toggle_op(bContext *UNUSED(C), wmOperator *UNUSED(op))
{
GHOST_toggleConsole(2);
@@ -2046,6 +2136,8 @@ static void WM_OT_console_toggle(wmOperatorType *ot)
ot->poll= WM_operator_winactive;
}
+#endif
+
/* ************ default paint cursors, draw always around cursor *********** */
/*
- returns handler to free
@@ -2208,6 +2300,13 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_border_select_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
/* **************** circle gesture *************** */
/* works now only for selection or modal paint stuff, calls exec while hold mouse, exit on release */
@@ -2304,6 +2403,13 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_gesture_circle_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
#if 0
/* template to copy from */
void WM_OT_circle_gesture(wmOperatorType *ot)
@@ -2482,7 +2588,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event)
}
{
- short x, y;
+ int x, y;
short *lasso= gesture->customdata;
lasso += (2 * gesture->points - 2);
@@ -2520,6 +2626,20 @@ int WM_gesture_lines_modal(bContext *C, wmOperator *op, wmEvent *event)
return WM_gesture_lasso_modal(C, op, event);
}
+int WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
+int WM_gesture_lines_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
#if 0
/* template to copy from */
@@ -2641,6 +2761,13 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
#if 0
/* template to copy from */
void WM_OT_straightline_gesture(wmOperatorType *ot)
@@ -2665,272 +2792,475 @@ void WM_OT_straightline_gesture(wmOperatorType *ot)
static const int WM_RADIAL_CONTROL_DISPLAY_SIZE = 200;
-typedef struct wmRadialControl {
- int mode;
- float initial_value, value, max_value;
- float col[4], tex_col[4];
+typedef struct {
+ PropertyType type;
+ PropertySubType subtype;
+ PointerRNA ptr, col_ptr, fill_col_ptr, rot_ptr, zoom_ptr, image_id_ptr;
+ PropertyRNA *prop, *col_prop, *fill_col_prop, *rot_prop, *zoom_prop;
+ StructRNA *image_id_srna;
+ float initial_value, current_value, min_value, max_value;
int initial_mouse[2];
+ unsigned int gltex;
+ ListBase orig_paintcursors;
void *cursor;
- GLuint tex;
-} wmRadialControl;
+} RadialControl;
-static void wm_radial_control_paint(bContext *C, int x, int y, void *customdata)
+static void radial_control_set_initial_mouse(RadialControl *rc, wmEvent *event)
{
- wmRadialControl *rc = (wmRadialControl*)customdata;
- ARegion *ar = CTX_wm_region(C);
- float r1=0.0f, r2=0.0f, r3=0.0f, angle=0.0f;
+ float d[2] = {0, 0};
+ float zoom[2] = {1, 1};
- // int hit = 0;
-
- if(rc->mode == WM_RADIALCONTROL_STRENGTH)
- rc->tex_col[3]= (rc->value + 0.5f);
+ rc->initial_mouse[0]= event->x;
+ rc->initial_mouse[1]= event->y;
- if(rc->mode == WM_RADIALCONTROL_SIZE) {
- r1= rc->value;
- r2= rc->initial_value;
- r3= r1;
- } else if(rc->mode == WM_RADIALCONTROL_STRENGTH) {
- r1= (1 - rc->value) * WM_RADIAL_CONTROL_DISPLAY_SIZE;
- r2= r3= (float)WM_RADIAL_CONTROL_DISPLAY_SIZE;
- } else if(rc->mode == WM_RADIALCONTROL_ANGLE) {
- r1= r2= r3= (float)WM_RADIAL_CONTROL_DISPLAY_SIZE;
- angle = rc->value;
+ switch(rc->subtype) {
+ case PROP_DISTANCE:
+ d[0] = rc->initial_value;
+ break;
+ case PROP_FACTOR:
+ d[0] = WM_RADIAL_CONTROL_DISPLAY_SIZE * (1 - rc->initial_value);
+ break;
+ case PROP_ANGLE:
+ d[0] = WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(rc->initial_value);
+ d[1] = WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(rc->initial_value);
+ break;
+ default:
+ return;
}
- /* Keep cursor in the original place */
- x = rc->initial_mouse[0] - ar->winrct.xmin;
- y = rc->initial_mouse[1] - ar->winrct.ymin;
+ if(rc->zoom_prop) {
+ RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
+ d[0] *= zoom[0];
+ d[1] *= zoom[1];
+ }
- glTranslatef((float)x, (float)y, 0.0f);
+ rc->initial_mouse[0]-= d[0];
+ rc->initial_mouse[1]-= d[1];
+}
- glEnable(GL_BLEND);
+static void radial_control_set_tex(RadialControl *rc)
+{
+ ImBuf *ibuf;
- if(rc->mode == WM_RADIALCONTROL_ANGLE) {
- glRotatef(angle, 0, 0, 1);
+ switch(RNA_type_to_ID_code(rc->image_id_ptr.type)) {
+ case ID_BR:
+ if((ibuf = brush_gen_radial_control_imbuf(rc->image_id_ptr.data))) {
+ glGenTextures(1, &rc->gltex);
+ glBindTexture(GL_TEXTURE_2D, rc->gltex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, ibuf->x, ibuf->y, 0,
+ GL_ALPHA, GL_FLOAT, ibuf->rect_float);
+ MEM_freeN(ibuf->rect_float);
+ MEM_freeN(ibuf);
+ }
+ break;
+ default:
+ break;
}
+}
+
+static void radial_control_paint_tex(RadialControl *rc, float radius, float alpha)
+{
+ float col[3] = {0, 0, 0};
+ float rot;
+
+ /* set fill color */
+ if(rc->fill_col_prop)
+ RNA_property_float_get_array(&rc->fill_col_ptr, rc->fill_col_prop, col);
+ glColor4f(col[0], col[1], col[2], alpha);
- if (rc->tex) {
- glBindTexture(GL_TEXTURE_2D, rc->tex);
+ if(rc->gltex) {
+ glBindTexture(GL_TEXTURE_2D, rc->gltex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ /* set up rotation if available */
+ if(rc->rot_prop) {
+ rot = RNA_property_float_get(&rc->rot_ptr, rc->rot_prop);
+ glPushMatrix();
+ glRotatef(RAD2DEGF(rot), 0, 0, 1);
+ }
+
+ /* draw textured quad */
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
- glColor4fv(rc->tex_col);
glTexCoord2f(0,0);
- glVertex2f(-r3, -r3);
+ glVertex2f(-radius, -radius);
glTexCoord2f(1,0);
- glVertex2f(r3, -r3);
+ glVertex2f(radius, -radius);
glTexCoord2f(1,1);
- glVertex2f(r3, r3);
+ glVertex2f(radius, radius);
glTexCoord2f(0,1);
- glVertex2f(-r3, r3);
+ glVertex2f(-radius, radius);
glEnd();
glDisable(GL_TEXTURE_2D);
+
+ /* undo rotation */
+ if(rc->rot_prop)
+ glPopMatrix();
+ }
+ else {
+ /* flat color if no texture available */
+ glutil_draw_filled_arc(0, M_PI * 2, radius, 40);
+ }
+}
+
+static void radial_control_paint_cursor(bContext *C, int x, int y, void *customdata)
+{
+ RadialControl *rc = customdata;
+ ARegion *ar = CTX_wm_region(C);
+ float r1=0.0f, r2=0.0f, tex_radius, alpha;
+ float zoom[2], col[3] = {1, 1, 1};
+
+ switch(rc->subtype) {
+ case PROP_DISTANCE:
+ r1= rc->current_value;
+ r2= rc->initial_value;
+ tex_radius= r1;
+ alpha = 0.75;
+ break;
+ case PROP_FACTOR:
+ r1= (1 - rc->current_value) * WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ r2= tex_radius= WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ alpha = rc->current_value / 2 + 0.5;
+ break;
+ case PROP_ANGLE:
+ r1= r2= tex_radius= WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ alpha = 0.75;
+ break;
+ default:
+ tex_radius= WM_RADIAL_CONTROL_DISPLAY_SIZE; /* note, this is a dummy value */
+ alpha = 0.75;
+ break;
}
- if(rc->mode == WM_RADIALCONTROL_ANGLE) {
- glColor4fv(rc->col);
- glEnable(GL_LINE_SMOOTH);
- glRotatef(-angle, 0, 0, 1);
+ /* Keep cursor in the original place */
+ x = rc->initial_mouse[0] - ar->winrct.xmin;
+ y = rc->initial_mouse[1] - ar->winrct.ymin;
+ glTranslatef((float)x, (float)y, 0.0f);
+
+ glEnable(GL_BLEND);
+ glEnable(GL_LINE_SMOOTH);
+
+ /* apply zoom if available */
+ if(rc->zoom_prop) {
+ RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
+ glScalef(zoom[0], zoom[1], 1);
+ }
+
+ /* draw rotated texture */
+ radial_control_paint_tex(rc, tex_radius, alpha);
+
+ /* set line color */
+ if(rc->col_prop)
+ RNA_property_float_get_array(&rc->col_ptr, rc->col_prop, col);
+ glColor4f(col[0], col[1], col[2], 0.5);
+
+ if(rc->subtype == PROP_ANGLE) {
+ glPushMatrix();
+ /* draw original angle line */
+ glRotatef(RAD2DEGF(rc->initial_value), 0, 0, 1);
fdrawline(0.0f, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
- glRotatef(angle, 0, 0, 1);
+ /* draw new angle line */
+ glRotatef(RAD2DEGF(rc->current_value - rc->initial_value), 0, 0, 1);
fdrawline(0.0f, 0.0f, (float)WM_RADIAL_CONTROL_DISPLAY_SIZE, 0.0f);
- glDisable(GL_LINE_SMOOTH);
+ glPopMatrix();
}
- glColor4fv(rc->col);
+ /* draw circles on top */
glutil_draw_lined_arc(0.0, (float)(M_PI*2.0), r1, 40);
glutil_draw_lined_arc(0.0, (float)(M_PI*2.0), r2, 40);
+
glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
}
-int WM_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
+/* attempt to retrieve the rna pointer/property from an rna path;
+ returns 0 for failure, 1 for success, and also 1 if property is not
+ set */
+static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op,
+ const char *name, PointerRNA *r_ptr,
+ PropertyRNA **r_prop, int req_float,
+ int req_length, int allow_missing)
{
- wmRadialControl *rc = (wmRadialControl*)op->customdata;
- int mode, initial_mouse[2], delta[2];
- float dist;
- double new_value = RNA_float_get(op->ptr, "new_value");
- int ret = OPERATOR_RUNNING_MODAL;
- // float initial_value = RNA_float_get(op->ptr, "initial_value");
+ PropertyRNA *unused_prop;
+ int len;
+ char *str;
- mode = RNA_enum_get(op->ptr, "mode");
- RNA_int_get_array(op->ptr, "initial_mouse", initial_mouse);
+ /* get an rna string path from the operator's properties */
+ if(!(str = RNA_string_get_alloc(op->ptr, name, NULL, 0)))
+ return 1;
- switch(event->type) {
- case MOUSEMOVE:
- delta[0]= initial_mouse[0] - event->x;
- delta[1]= initial_mouse[1] - event->y;
+ if(str[0] == '\0') {
+ MEM_freeN(str);
+ return 1;
+ }
- //if (mode == WM_RADIALCONTROL_SIZE)
- // delta[0]+= initial_value;
- //else if(mode == WM_RADIALCONTROL_STRENGTH)
- // delta[0]+= WM_RADIAL_CONTROL_DISPLAY_SIZE * (1 - initial_value);
- //else if(mode == WM_RADIALCONTROL_ANGLE) {
- // delta[0]+= WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(initial_value*M_PI/180.0f);
- // delta[1]+= WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(initial_value*M_PI/180.0f);
- //}
+ if(!r_prop)
+ r_prop = &unused_prop;
- dist= sqrtf(delta[0]*delta[0]+delta[1]*delta[1]);
+ /* get rna from path */
+ if(!RNA_path_resolve(ctx_ptr, str, r_ptr, r_prop)) {
+ MEM_freeN(str);
+ if(allow_missing)
+ return 1;
+ else {
+ BKE_reportf(op->reports, RPT_ERROR, "Couldn't resolve path %s", name);
+ return 0;
+ }
+ }
- if(mode == WM_RADIALCONTROL_SIZE)
- new_value = dist;
- else if(mode == WM_RADIALCONTROL_STRENGTH) {
- new_value = 1 - dist / WM_RADIAL_CONTROL_DISPLAY_SIZE;
- } else if(mode == WM_RADIALCONTROL_ANGLE)
- new_value = ((int)(atan2f(delta[1], delta[0]) * (float)(180.0 / M_PI)) + 180);
-
- if(event->ctrl) {
- if(mode == WM_RADIALCONTROL_STRENGTH)
- new_value = ((int)ceilf(new_value * 10.f) * 10.0f) / 100.f;
- else
- new_value = ((int)new_value + 5) / 10*10;
+ /* if property is expected to be a float, check its type */
+ if(req_float) {
+ if(!(*r_prop) || (RNA_property_type(*r_prop) != PROP_FLOAT)) {
+ MEM_freeN(str);
+ BKE_reportf(op->reports, RPT_ERROR,
+ "Property from path %s is not a float", name);
+ return 0;
}
-
- break;
- case ESCKEY:
- case RIGHTMOUSE:
- ret = OPERATOR_CANCELLED;
- break;
- case LEFTMOUSE:
- case PADENTER:
- op->type->exec(C, op);
- ret = OPERATOR_FINISHED;
- break;
+ }
+
+ /* check property's array length */
+ if(*r_prop && (len = RNA_property_array_length(r_ptr, *r_prop)) != req_length) {
+ MEM_freeN(str);
+ BKE_reportf(op->reports, RPT_ERROR,
+ "Property from path %s has length %d instead of %d",
+ name, len, req_length);
+ return 0;
}
- /* Clamp */
- if(new_value > rc->max_value)
- new_value = rc->max_value;
- else if(new_value < 0)
- new_value = 0;
+ /* success */
+ MEM_freeN(str);
+ return 1;
+}
- /* Update paint data */
- rc->value = (float)new_value;
+/* initialize the rna pointers and properties using rna paths */
+static int radial_control_get_properties(bContext *C, wmOperator *op)
+{
+ RadialControl *rc = op->customdata;
+ PointerRNA ctx_ptr;
- RNA_float_set(op->ptr, "new_value", rc->value);
+ RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
- if(ret != OPERATOR_RUNNING_MODAL) {
- WM_paint_cursor_end(CTX_wm_manager(C), rc->cursor);
- MEM_freeN(rc);
- }
-
- ED_region_tag_redraw(CTX_wm_region(C));
+ if(!radial_control_get_path(&ctx_ptr, op, "data_path", &rc->ptr, &rc->prop, 0, 0, 0))
+ return 0;
- //if (ret != OPERATOR_RUNNING_MODAL) {
- // wmWindow *win = CTX_wm_window(C);
- // WM_cursor_restore(win);
- //}
+ /* data path is required */
+ if(!rc->prop)
+ return 0;
+
+ if(!radial_control_get_path(&ctx_ptr, op, "rotation_path", &rc->rot_ptr, &rc->rot_prop, 1, 0, 0))
+ return 0;
+ if(!radial_control_get_path(&ctx_ptr, op, "color_path", &rc->col_ptr, &rc->col_prop, 1, 3, 0))
+ return 0;
+ if(!radial_control_get_path(&ctx_ptr, op, "fill_color_path", &rc->fill_col_ptr, &rc->fill_col_prop, 1, 3, 0))
+ return 0;
+
+ /* slightly ugly; allow this property to not resolve
+ correctly. needed because 3d texture paint shares the same
+ keymap as 2d image paint */
+ if(!radial_control_get_path(&ctx_ptr, op, "zoom_path", &rc->zoom_ptr, &rc->zoom_prop, 1, 2, 1))
+ return 0;
+
+ if(!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0, 0))
+ return 0;
+ else if(rc->image_id_ptr.data) {
+ /* extra check, pointer must be to an ID */
+ if(!RNA_struct_is_ID(rc->image_id_ptr.type)) {
+ BKE_report(op->reports, RPT_ERROR,
+ "Pointer from path image_id is not an ID");
+ return 0;
+ }
+ }
- return ret;
+ return 1;
}
-/* Expects the operator customdata to be an ImBuf (or NULL) */
-int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- wmRadialControl *rc = MEM_callocN(sizeof(wmRadialControl), "radial control");
- // wmWindow *win = CTX_wm_window(C);
- int mode = RNA_enum_get(op->ptr, "mode");
- float initial_value = RNA_float_get(op->ptr, "initial_value");
- //float initial_size = RNA_float_get(op->ptr, "initial_size");
- int mouse[2];
-
- mouse[0]= event->x;
- mouse[1]= event->y;
+ wmWindowManager *wm;
+ RadialControl *rc;
+ int min_value_int, max_value_int, step_int;
+ float step_float, precision;
- //if (initial_size == 0)
- // initial_size = WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ if(!(op->customdata = rc = MEM_callocN(sizeof(RadialControl), "RadialControl")))
+ return OPERATOR_CANCELLED;
- if(mode == WM_RADIALCONTROL_SIZE) {
- rc->max_value = 200;
- mouse[0]-= (int)initial_value;
- }
- else if(mode == WM_RADIALCONTROL_STRENGTH) {
- rc->max_value = 1;
- mouse[0]-= (int)(WM_RADIAL_CONTROL_DISPLAY_SIZE * (1.0f - initial_value));
- }
- else if(mode == WM_RADIALCONTROL_ANGLE) {
- rc->max_value = 360;
- mouse[0]-= (int)(WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(initial_value));
- mouse[1]-= (int)(WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(initial_value));
- initial_value *= 180.0f/(float)M_PI;
+ if(!radial_control_get_properties(C, op)) {
+ MEM_freeN(rc);
+ return OPERATOR_CANCELLED;
}
- if(op->customdata) {
- ImBuf *im = (ImBuf*)op->customdata;
- /* Build GL texture */
- glGenTextures(1, &rc->tex);
- glBindTexture(GL_TEXTURE_2D, rc->tex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, im->x, im->y, 0, GL_ALPHA, GL_FLOAT, im->rect_float);
- MEM_freeN(im->rect_float);
- MEM_freeN(im);
+ /* get type, initial, min, and max values of the property */
+ switch((rc->type = RNA_property_type(rc->prop))) {
+ case PROP_INT:
+ rc->initial_value = RNA_property_int_get(&rc->ptr, rc->prop);
+ RNA_property_int_ui_range(&rc->ptr, rc->prop, &min_value_int,
+ &max_value_int, &step_int);
+ rc->min_value = min_value_int;
+ rc->max_value = max_value_int;
+ break;
+ case PROP_FLOAT:
+ rc->initial_value = RNA_property_float_get(&rc->ptr, rc->prop);
+ RNA_property_float_ui_range(&rc->ptr, rc->prop, &rc->min_value,
+ &rc->max_value, &step_float, &precision);
+ break;
+ default:
+ BKE_report(op->reports, RPT_ERROR, "Property must be an integer or a float");
+ MEM_freeN(rc);
+ return OPERATOR_CANCELLED;
}
- RNA_float_get_array(op->ptr, "color", rc->col);
- RNA_float_get_array(op->ptr, "texture_color", rc->tex_col);
-
- RNA_int_set_array(op->ptr, "initial_mouse", mouse);
- RNA_float_set(op->ptr, "new_value", initial_value);
+ /* get subtype of property */
+ rc->subtype = RNA_property_subtype(rc->prop);
+ if(!ELEM3(rc->subtype, PROP_DISTANCE, PROP_FACTOR, PROP_ANGLE)) {
+ BKE_report(op->reports, RPT_ERROR, "Property must be a distance, a factor, or an angle");
+ MEM_freeN(rc);
+ return OPERATOR_CANCELLED;
+ }
- op->customdata = rc;
- rc->mode = mode;
- rc->initial_value = initial_value;
- rc->initial_mouse[0] = mouse[0];
- rc->initial_mouse[1] = mouse[1];
- rc->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), op->type->poll,
- wm_radial_control_paint, op->customdata);
+ rc->current_value = rc->initial_value;
+ radial_control_set_initial_mouse(rc, event);
+ radial_control_set_tex(rc);
- //WM_cursor_modal(win, CURSOR_NONE);
+ /* temporarily disable other paint cursors */
+ wm = CTX_wm_manager(C);
+ rc->orig_paintcursors = wm->paintcursors;
+ wm->paintcursors.first = wm->paintcursors.last = NULL;
+
+ /* add radial control paint cursor */
+ rc->cursor = WM_paint_cursor_activate(wm, op->type->poll,
+ radial_control_paint_cursor, rc);
- /* add modal handler */
WM_event_add_modal_handler(C, op);
-
- WM_radial_control_modal(C, op, event);
-
+
return OPERATOR_RUNNING_MODAL;
}
-/* Gets a descriptive string of the operation */
-void WM_radial_control_string(wmOperator *op, char str[], int maxlen)
+static void radial_control_set_value(RadialControl *rc, float val)
+{
+ switch(rc->type) {
+ case PROP_INT:
+ RNA_property_int_set(&rc->ptr, rc->prop, val);
+ break;
+ case PROP_FLOAT:
+ RNA_property_float_set(&rc->ptr, rc->prop, val);
+ break;
+ default:
+ break;
+ }
+}
+
+static int radial_control_cancel(bContext *C, wmOperator *op)
{
- int mode = RNA_enum_get(op->ptr, "mode");
- float v = RNA_float_get(op->ptr, "new_value");
+ RadialControl *rc = op->customdata;
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ WM_paint_cursor_end(wm, rc->cursor);
+
+ /* restore original paint cursors */
+ wm->paintcursors = rc->orig_paintcursors;
+
+ /* not sure if this is a good notifier to use;
+ intended purpose is to update the UI so that the
+ new value is displayed in sliders/numfields */
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ glDeleteTextures(1, &rc->gltex);
- if(mode == WM_RADIALCONTROL_SIZE)
- BLI_snprintf(str, maxlen, "Size: %d", (int)v);
- else if(mode == WM_RADIALCONTROL_STRENGTH)
- BLI_snprintf(str, maxlen, "Strength: %d", (int)v);
- else if(mode == WM_RADIALCONTROL_ANGLE)
- BLI_snprintf(str, maxlen, "Angle: %d", (int)(v * 180.0f/(float)M_PI));
+ MEM_freeN(rc);
+
+ return OPERATOR_CANCELLED;
}
-/** Important: this doesn't define an actual operator, it
- just sets up the common parts of the radial control op. **/
-void WM_OT_radial_control_partial(wmOperatorType *ot)
+static int radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
{
- static EnumPropertyItem radial_mode_items[] = {
- {WM_RADIALCONTROL_SIZE, "SIZE", 0, "Size", ""},
- {WM_RADIALCONTROL_STRENGTH, "STRENGTH", 0, "Strength", ""},
- {WM_RADIALCONTROL_ANGLE, "ANGLE", 0, "Angle", ""},
- {0, NULL, 0, NULL, NULL}};
- static float color[4] = {1.0f, 1.0f, 1.0f, 0.5f};
- static float tex_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ RadialControl *rc = op->customdata;
+ float new_value, dist, zoom[2];
+ float delta[2], snap, ret = OPERATOR_RUNNING_MODAL;
+
+ /* TODO: fix hardcoded events */
+
+ snap = event->ctrl;
+
+ switch(event->type) {
+ case MOUSEMOVE:
+ delta[0]= rc->initial_mouse[0] - event->x;
+ delta[1]= rc->initial_mouse[1] - event->y;
- /* Should be set in custom invoke() */
- RNA_def_float(ot->srna, "initial_value", 0, 0, FLT_MAX, "Initial Value", "", 0, FLT_MAX);
+ if(rc->zoom_prop) {
+ RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
+ delta[0] /= zoom[0];
+ delta[1] /= zoom[1];
+ }
+
+ dist= sqrt(delta[0]*delta[0]+delta[1]*delta[1]);
+
+ /* calculate new value and apply snapping */
+ switch(rc->subtype) {
+ case PROP_DISTANCE:
+ new_value = dist;
+ if(snap) new_value = ((int)new_value + 5) / 10*10;
+ break;
+ case PROP_FACTOR:
+ new_value = 1 - dist / WM_RADIAL_CONTROL_DISPLAY_SIZE;
+ if(snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
+ break;
+ case PROP_ANGLE:
+ new_value = atan2(delta[1], delta[0]) + M_PI;
+ if(snap) new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10*10);
+ break;
+ default:
+ new_value = dist; /* dummy value, should this ever happen? - campbell */
+ break;
+ }
+
+ /* clamp and update */
+ CLAMP(new_value, rc->min_value, rc->max_value);
+ radial_control_set_value(rc, new_value);
+ rc->current_value = new_value;
+ break;
+
+ case ESCKEY:
+ case RIGHTMOUSE:
+ /* cancelled; restore original value */
+ radial_control_set_value(rc, rc->initial_value);
+ ret = OPERATOR_CANCELLED;
+ break;
+
+ case LEFTMOUSE:
+ case PADENTER:
+ /* done; value already set */
+ ret = OPERATOR_FINISHED;
+ break;
+ }
- /* Set internally, should be used in custom exec() to get final value */
- RNA_def_float(ot->srna, "new_value", 0, 0, FLT_MAX, "New Value", "", 0, FLT_MAX);
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ if(ret != OPERATOR_RUNNING_MODAL)
+ radial_control_cancel(C, op);
+
+ return ret;
+}
+
+static void WM_OT_radial_control(wmOperatorType *ot)
+{
+ ot->name= "Radial Control";
+ ot->idname= "WM_OT_radial_control";
- /* Should be set before calling operator */
- RNA_def_enum(ot->srna, "mode", radial_mode_items, 0, "Mode", "");
+ ot->invoke= radial_control_invoke;
+ ot->modal= radial_control_modal;
+ ot->cancel= radial_control_cancel;
- /* Internal */
- RNA_def_int_vector(ot->srna, "initial_mouse", 2, NULL, INT_MIN, INT_MAX, "Initial Mouse", "", INT_MIN, INT_MAX);
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
- RNA_def_float_color(ot->srna, "color", 4, color, 0.0f, FLT_MAX, "Color", "Radial control color", 0.0f, 1.0f);
- RNA_def_float_color(ot->srna, "texture_color", 4, tex_color, 0.0f, FLT_MAX, "Texture Color", "Radial control texture color", 0.0f, 1.0f);
+ /* all paths relative to the context */
+ RNA_def_string(ot->srna, "data_path", "", 0, "Data Path", "Path of property to be set by the radial control.");
+ RNA_def_string(ot->srna, "rotation_path", "", 0, "Rotation Path", "Path of property used to rotate the texture display.");
+ RNA_def_string(ot->srna, "color_path", "", 0, "Color Path", "Path of property used to set the color of the control.");
+ RNA_def_string(ot->srna, "fill_color_path", "", 0, "Fill Color Path", "Path of property used to set the fill color of the control.");
+ RNA_def_string(ot->srna, "zoom_path", "", 0, "Zoom Path", "Path of property used to set the zoom level for the control.");
+ RNA_def_string(ot->srna, "image_id", "", 0, "Image ID", "Path of ID that is used to generate an image for the control.");
}
/* ************************** timer for testing ***************** */
@@ -3124,6 +3454,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_splash);
WM_operatortype_append(WM_OT_search_menu);
WM_operatortype_append(WM_OT_call_menu);
+ WM_operatortype_append(WM_OT_radial_control);
#if defined(WIN32)
WM_operatortype_append(WM_OT_console_toggle);
#endif
@@ -3236,10 +3567,12 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
/* items for modal map */
WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
- WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, GESTURE_MODAL_CANCEL);
+ /* Note: cancel only on press otherwise you cannot map this to RMB-gesture */
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN);
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
+ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT);
#if 0 // Durian guys like this
WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN);
@@ -3418,38 +3751,38 @@ static EnumPropertyItem *rna_id_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(pt
}
/* can add more as needed */
-EnumPropertyItem *RNA_action_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_action_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, FALSE);
}
-EnumPropertyItem *RNA_action_local_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_action_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->action.first : NULL, TRUE);
}
-EnumPropertyItem *RNA_group_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_group_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, FALSE);
}
-EnumPropertyItem *RNA_group_local_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_group_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->group.first : NULL, TRUE);
}
-EnumPropertyItem *RNA_image_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_image_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, FALSE);
}
-EnumPropertyItem *RNA_image_local_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_image_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->image.first : NULL, TRUE);
}
-EnumPropertyItem *RNA_scene_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_scene_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, FALSE);
}
-EnumPropertyItem *RNA_scene_local_itemf(bContext *C, PointerRNA *ptr, int *do_free)
+EnumPropertyItem *RNA_scene_local_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *do_free)
{
return rna_id_itemf(C, ptr, do_free, C ? (ID *)CTX_data_main(C)->scene.first : NULL, TRUE);
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 5cf2f8932f5..9b1695be67a 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -271,9 +271,11 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
void wm_window_title(wmWindowManager *wm, wmWindow *win)
{
- /* handle the 'temp' window */
+ /* handle the 'temp' window, only set title when not set before */
if(win->screen && win->screen->temp) {
- GHOST_SetTitle(win->ghostwin, "Blender");
+ char *title= GHOST_GetTitle(win->ghostwin);
+ if(title==NULL || title[0]==0)
+ GHOST_SetTitle(win->ghostwin, "Blender");
}
else {
@@ -671,13 +673,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
win->eventstate->x= cx;
-
-#if defined(__APPLE__) && defined(GHOST_COCOA)
- //Cocoa already uses coordinates with y=0 at bottom
- win->eventstate->y= cy;
-#else
win->eventstate->y= (win->sizey-1) - cy;
-#endif
win->addmousemove= 1; /* enables highlighted buttons */
@@ -794,20 +790,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
wmEvent event;
GHOST_TEventDragnDropData *ddd= GHOST_GetEventData(evt);
int cx, cy, wx, wy;
-
/* entering window, update mouse pos */
GHOST_GetCursorPosition(g_system, &wx, &wy);
GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy);
win->eventstate->x= cx;
-
-#if defined(__APPLE__) && defined(GHOST_COCOA)
- //Cocoa already uses coordinates with y=0 at bottom
- win->eventstate->y= cy;
-#else
win->eventstate->y= (win->sizey-1) - cy;
-#endif
event= *(win->eventstate); /* copy last state, like mouse coords */
@@ -1009,6 +998,8 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *
if(wt==timer)
break;
if(wt) {
+ if(wm->reports.reporttimer == wt)
+ wm->reports.reporttimer= NULL;
BLI_remlink(&wm->timers, wt);
if(wt->customdata)
@@ -1145,12 +1136,7 @@ void wm_get_cursor_position(wmWindow *win, int *x, int *y)
{
GHOST_GetCursorPosition(g_system, x, y);
GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
-#if defined(__APPLE__) && defined(GHOST_COCOA)
- //Cocoa has silly exception that should be fixed at the ghost level
- //(ghost is an allegory for an invisible system specific code)
-#else
*y = (win->sizey-1) - *y;
-#endif
}
/* ******************* exported api ***************** */
@@ -1183,9 +1169,8 @@ void WM_cursor_warp(wmWindow *win, int x, int y)
if (win && win->ghostwin) {
int oldx=x, oldy=y;
-#if !defined(__APPLE__) || !defined(GHOST_COCOA)
y= win->sizey -y - 1;
-#endif
+
GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y);
GHOST_SetCursorPosition(g_system, x, y);
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index f73652125b1..fd279c31f3c 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -78,7 +78,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt);
void wm_autosave_timer_ended(wmWindowManager *wm);
void wm_autosave_delete(void);
void wm_autosave_read(bContext *C, struct ReportList *reports);
-void wm_autosave_location(char *filename);
+void wm_autosave_location(char *filepath);
/* hack to store circle select size - campbell, must replace with nice operator memory */
#define GESTURE_MEMORY