Drag and drop 2.5 integration! Finally, slashdot regulars can use
[blender-staging.git] / source / blender / windowmanager / intern / wm_cursors.c
index e4299b8949b306da63c36d64dc02a726f4ebb87c..f23688404b1428df027a9f20fe7bc0e7279d92ca 100644 (file)
@@ -35,7 +35,9 @@
 #include "DNA_listBase.h"
 #include "DNA_userdef_types.h" 
 
+#include "BKE_context.h"
 #include "BKE_global.h"
+#include "BKE_main.h"
 
 #include "WM_api.h"
 #include "wm_cursors.h"
@@ -53,10 +55,16 @@ static GHOST_TStandardCursor convert_cursor(int curs)
                case CURSOR_FACESEL:    return GHOST_kStandardCursorRightArrow;
                case CURSOR_WAIT:               return GHOST_kStandardCursorWait;
                case CURSOR_EDIT:               return GHOST_kStandardCursorCrosshair;
-               case CURSOR_HELP:               return GHOST_kStandardCursorHelp;
+               case CURSOR_HELP:               
+#ifdef __APPLE__
+                       return GHOST_kStandardCursorLeftRight;
+#else
+                       return GHOST_kStandardCursorHelp;
+#endif
                case CURSOR_X_MOVE:             return GHOST_kStandardCursorLeftRight;
                case CURSOR_Y_MOVE:             return GHOST_kStandardCursorUpDown;
                case CURSOR_PENCIL:             return GHOST_kStandardCursorPencil;
+               case CURSOR_COPY:               return GHOST_kStandardCursorCopy;
        }
 }
 
@@ -86,34 +94,34 @@ static void window_set_custom_cursor_ex(wmWindow *win, BCursor *cursor, int useB
 
 /* Cursor Globals */
 static BCursor *BlenderCursor[BC_NUMCURSORS]; /*Points to static BCursor Structs */
-static short CurrentCursor=-1, LastCursor=-1;
 
-void WM_set_cursor(bContext *C, int curs)
+void WM_cursor_set(wmWindow *win, int curs)
 {
-       wmWindow *win= C->window;
 
        if (win==NULL) return; /* Can't set custom cursor before Window init */
-       win->cursor= curs;
-       
+
        if (curs==CURSOR_NONE) {
                GHOST_SetCursorVisibility(win->ghostwin, 0);
                return;
        }
 
+#ifdef _WIN32
+       /* the default win32 cross cursor is barely visible,
+        * only 1 pixel thick, use another one instead */
+       if(curs==CURSOR_EDIT)
+               curs= BC_CROSSCURSOR;
+#endif
+
        GHOST_SetCursorVisibility(win->ghostwin, 1);
        
-       LastCursor=CurrentCursor;
-       CurrentCursor=curs;
-       
-       /* previous cursor? */
-       if (curs==LASTCURSOR) curs=LastCursor;
+       win->cursor= curs;
        
        /* detect if we use system cursor or Blender cursor */
        if(curs>=BC_GHOST_CURSORS) {
                GHOST_SetCursorShape(win->ghostwin, convert_cursor(curs));
        }
        else {
-               if ((curs<LASTCURSOR)||(curs>=BC_NUMCURSORS)) return;   
+               if ((curs<SYSCURSOR) || (curs>=BC_NUMCURSORS)) return;  
 
                if (curs==SYSCURSOR) {  /* System default Cursor */
                        GHOST_SetCursorShape(win->ghostwin, convert_cursor(CURSOR_STD));
@@ -127,18 +135,71 @@ void WM_set_cursor(bContext *C, int curs)
        }
 }
 
-void WM_waitcursor(bContext *C, int val)
+void WM_cursor_modal(wmWindow *win, int val)
 {
-       if(C->window) {
+       if(win->lastcursor == 0) {
+               win->lastcursor = win->cursor;
+               WM_cursor_set(win, val);
+       }
+}
+
+void WM_cursor_restore(wmWindow *win)
+{
+       if(win->lastcursor)
+               WM_cursor_set(win, win->lastcursor);
+       win->lastcursor = 0;
+}
+
+/* to allow usage all over, we do entire WM */
+void WM_cursor_wait(int val)
+{
+       wmWindowManager *wm= G.main->wm.first;
+       wmWindow *win= wm->windows.first; 
+       
+       for(; win; win= win->next) {
                if(val) {
-                       WM_set_cursor(C, CURSOR_WAIT);
+                       WM_cursor_modal(win, CURSOR_WAIT);
                } else {
-                       WM_set_cursor(C, LASTCURSOR);
+                       WM_cursor_restore(win);
+               }
+       }
+}
+
+void WM_cursor_grab(wmWindow *win, int wrap, int hide, int *bounds)
+{
+       /* Only grab cursor when not running debug.
+        * It helps not to get a stuck WM when hitting a breakpoint  
+        * */
+       GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
+
+       if(hide)                mode = GHOST_kGrabHide;
+       else if(wrap)   mode = GHOST_kGrabWrap;
+       if ((G.f & G_DEBUG) == 0) {
+               if (win && win->ghostwin) {
+                       const GHOST_TabletData *tabletdata= GHOST_GetTabletData(win->ghostwin);
+                       // Note: There is no tabletdata on Windows if no tablet device is connected.
+                       if (!tabletdata)
+                               GHOST_SetCursorGrab(win->ghostwin, mode, bounds);
+                       else if (tabletdata->Active == GHOST_kTabletModeNone)
+                               GHOST_SetCursorGrab(win->ghostwin, mode, bounds);
+
+                       win->grabcursor = mode;
+               }
+       }
+}
+
+void WM_cursor_ungrab(wmWindow *win)
+{
+       if ((G.f & G_DEBUG) == 0) {
+               if(win && win->ghostwin) {
+                       GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL);
+                       win->grabcursor = GHOST_kGrabDisable;
                }
        }
 }
 
-void WM_timecursor(bContext *C, int nr)
+/* afer this you can call restore too */
+void WM_timecursor(wmWindow *win, int nr)
 {
        /* 10 8x8 digits */
        static char number_bitmaps[10][8]= {
@@ -157,6 +218,9 @@ void WM_timecursor(bContext *C, int nr)
        unsigned char bitmap[16][2];
        int i, idx;
        
+       if(win->lastcursor == 0)
+               win->lastcursor= win->cursor; 
+       
        memset(&bitmap, 0x00, sizeof(bitmap));
        memset(&mask, 0xFF, sizeof(mask));
        
@@ -171,7 +235,7 @@ void WM_timecursor(bContext *C, int nr)
                nr/= 10;
        }
        
-       window_set_custom_cursor(C->window, mask, bitmap, 7, 7);
+       window_set_custom_cursor(win, mask, bitmap, 7, 7);
 }
 
 
@@ -217,7 +281,7 @@ are for */
 #define BEGIN_CURSOR_BLOCK {
 #define END_CURSOR_BLOCK   }
 
-void WM_init_cursor_data(void){
+void wm_init_cursor_data(void){
 
        /********************** NW_ARROW Cursor **************************/
 BEGIN_CURSOR_BLOCK
@@ -294,7 +358,7 @@ BEGIN_CURSOR_BLOCK
 
        static char ew_smsk[]={
                0x00,  0x00,  0x00,  0x00,  0x10,  0x08,  0x38,  0x1c,
-               0x3c,  0x3c,  0xfe,  0x7f,  0xff,  0xff,  0x3f,  0xfc,
+               0x3c,  0x3c,  0xfe,  0x7f,  0xff,  0xff,  0xff,  0xff,
                0xff,  0xff,  0xfe,  0x7f,  0x3c,  0x3c,  0x38,  0x1c,
                0x10,  0x08,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
        };
@@ -918,6 +982,38 @@ BlenderCursor[BC_EYEDROPPER_CURSOR]=&EyedropperCursor;
 
 END_CURSOR_BLOCK
 
+/********************** Swap Area Cursor ***********************/
+BEGIN_CURSOR_BLOCK
+static char swap_sbm[]={
+       0xc0,  0xff,  0x40,  0x80,  0x40,  0x80,  0x40,  0x9c,
+       0x40,  0x98,  0x40,  0x94,  0x00,  0x82,  0xfe,  0x80,
+       0x7e,  0xfd,  0xbe,  0x01,  0xda,  0x01,  0xe2,  0x01,
+       0xe2,  0x01,  0xc2,  0x01,  0xfe,  0x01,  0x00,  0x00,
+};
+
+static char swap_smsk[]={
+       0xc0,  0xff,  0xc0,  0xff,  0xc0,  0xff,  0xc0,  0xff,
+       0xc0,  0xff,  0xc0,  0xff,  0xff,  0xff,  0xff,  0xff,
+       0xff,  0xff,  0xff,  0x03,  0xff,  0x03,  0xff,  0x03,
+       0xff,  0x03,  0xff,  0x03,  0xff,  0x03,  0xff,  0x03,
+};
+
+static BCursor SwapCursor = {
+       /*small*/
+       swap_sbm, swap_smsk,
+       16, 16, 
+       8,  8,
+       /*big*/
+       NULL, NULL,
+       32,32, 
+       15, 15,
+       /*color*/
+       BC_YELLOW, BC_BLUE
+};
+
+BlenderCursor[BC_SWAPAREA_CURSOR]=&SwapCursor;
+
+END_CURSOR_BLOCK
 /********************** Put the cursors in the array ***********************/