Drag and drop 2.5 integration! Finally, slashdot regulars can use
[blender-staging.git] / source / blender / windowmanager / intern / wm_cursors.c
index 8c86070ca6177ef7de12e540a6de247eefefe9b8..f23688404b1428df027a9f20fe7bc0e7279d92ca 100644 (file)
 */
 
 #include <stdio.h>
+#include <string.h>
 
 #include "GHOST_C-api.h"
 
 #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"
@@ -52,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;
        }
 }
 
@@ -85,47 +94,151 @@ 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);
-               
+       
+       win->cursor= curs;
+       
        /* detect if we use system cursor or Blender cursor */
        if(curs>=BC_GHOST_CURSORS) {
                GHOST_SetCursorShape(win->ghostwin, convert_cursor(curs));
-               return;
        }
+       else {
+               if ((curs<SYSCURSOR) || (curs>=BC_NUMCURSORS)) return;  
+
+               if (curs==SYSCURSOR) {  /* System default Cursor */
+                       GHOST_SetCursorShape(win->ghostwin, convert_cursor(CURSOR_STD));
+               }
+               else if ( (U.curssize==0) || (BlenderCursor[curs]->big_bm == NULL) ) {
+                       window_set_custom_cursor_ex(win, BlenderCursor[curs], 0);
+               }
+               else {
+                       window_set_custom_cursor_ex(win, BlenderCursor[curs], 1);
+               }
+       }
+}
 
-       if ((curs<LASTCURSOR)||(curs>=BC_NUMCURSORS)) return;
-
+void WM_cursor_modal(wmWindow *win, int val)
+{
+       if(win->lastcursor == 0) {
+               win->lastcursor = win->cursor;
+               WM_cursor_set(win, val);
+       }
+}
 
-       LastCursor=CurrentCursor;
-       CurrentCursor=curs;
+void WM_cursor_restore(wmWindow *win)
+{
+       if(win->lastcursor)
+               WM_cursor_set(win, win->lastcursor);
+       win->lastcursor = 0;
+}
 
-       if (curs==LASTCURSOR) curs=LastCursor;
+/* 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_cursor_modal(win, CURSOR_WAIT);
+               } else {
+                       WM_cursor_restore(win);
+               }
+       }
+}
 
-       if (curs==SYSCURSOR) {  /* System default Cursor */
-               GHOST_SetCursorShape(win->ghostwin, convert_cursor(CURSOR_STD));
+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;
+               }
        }
-       else if ( (U.curssize==0) || (BlenderCursor[curs]->big_bm == NULL) ) {
-               window_set_custom_cursor_ex(win, BlenderCursor[curs], 0);
+}
+
+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;
+               }
        }
-       else {
-               window_set_custom_cursor_ex(win, BlenderCursor[curs], 1);
+}
+
+/* afer this you can call restore too */
+void WM_timecursor(wmWindow *win, int nr)
+{
+       /* 10 8x8 digits */
+       static char number_bitmaps[10][8]= {
+       {0,  56,  68,  68,  68,  68,  68,  56}, 
+       {0,  24,  16,  16,  16,  16,  16,  56}, 
+       {0,  60,  66,  32,  16,   8,   4, 126}, 
+       {0, 124,  32,  16,  56,  64,  66,  60}, 
+       {0,  32,  48,  40,  36, 126,  32,  32}, 
+       {0, 124,   4,  60,  64,  64,  68,  56}, 
+       {0,  56,   4,   4,  60,  68,  68,  56}, 
+       {0, 124,  64,  32,  16,   8,   8,   8}, 
+       {0,  60,  66,  66,  60,  66,  66,  60}, 
+       {0,  56,  68,  68, 120,  64,  68,  56} 
+       };
+       unsigned char mask[16][2];
+       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));
+       
+       /* print number bottom right justified */
+       for (idx= 3; nr && idx>=0; idx--) {
+               char *digit= number_bitmaps[nr%10];
+               int x = idx%2;
+               int y = idx/2;
+               
+               for (i=0; i<8; i++)
+                       bitmap[i + y*8][x]= digit[i];
+               nr/= 10;
        }
+       
+       window_set_custom_cursor(win, mask, bitmap, 7, 7);
 }
 
+
 /* ****************************************************************** 
 Custom Cursor Description:
 
@@ -168,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
@@ -245,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,
        };
@@ -869,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 ***********************/