* Start ActionZone support for areas. This is bScreen level stuff to be able to do...
authorNathan Letwory <nathan@letworyinteractive.com>
Thu, 17 Jan 2008 05:33:54 +0000 (05:33 +0000)
committerNathan Letwory <nathan@letworyinteractive.com>
Thu, 17 Jan 2008 05:33:54 +0000 (05:33 +0000)
Right now 2 AZones are defined for each new ScrArea, and mouse over is now detected. Enter ugly triangle.

source/blender/blenkernel/intern/screen.c
source/blender/blenlib/BLI_arithb.h
source/blender/blenlib/intern/arithb.c
source/blender/editors/include/ED_screen_types.h [new file with mode: 0644]
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/makesdna/DNA_screen_types.h
source/blender/windowmanager/WM_types.h

index 33e131606c2d535410c0ee36ffee3d2337ee6cc4..c5b30b26f7436250c59fab8f8739f2a407f2b106 100644 (file)
@@ -93,6 +93,7 @@ void BKE_screen_area_free(ScrArea *sa)
        BKE_spacedata_freelist(&sa->spacedata);
        
        BLI_freelistN(&sa->regionbase);
+       BLI_freelistN(&sa->actionzones);
        
        BLI_freelistN(&sa->panels);
        //      uiFreeBlocks(&sa->uiblocks);
index ecee16f2b727325e42bddd75b536497d5396333f..6697a7b2ba5dfac80afa589dbe10eb55feb29e6a 100644 (file)
@@ -374,6 +374,8 @@ int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]
 void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v);
 void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
 void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
+int IsPointInTri2D(float v0[2], float v1[2], float v2[2], float pt[2]);
+int IsPointInTri2DInts(int x1, int y1, int x2, int y2, int a, int b);
 int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]);
 
 float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3]);
index d0530e565fad6c63616f74aa4ae96126e037c51e..735ff2e65f72d0fe267f4667b494d1b98c63e329 100644 (file)
@@ -4084,6 +4084,63 @@ void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3
        }
 }
 
+int IsPointInTri2D(float v0[2], float v1[2], float v2[2], float pt[2])
+{
+               /* not for quads, use for our abuse of LineIntersectsTriangleUV */
+               float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3];
+               /* not used */
+               float lambda, uv[3];
+                       
+               p1_3d[0] = p2_3d[0] = uv[0]= pt[0];
+               p1_3d[1] = p2_3d[1] = uv[1]= uv[2]= pt[1];
+               p1_3d[2] = 1.0f;
+               p2_3d[2] = -1.0f;
+               v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
+               
+               /* generate a new fuv, (this is possibly a non optimal solution,
+                * since we only need 2d calculation but use 3d func's)
+                * 
+                * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
+                * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
+                * This means the new values will be correct in relation to the derived meshes face. 
+                */
+               Vec2Copyf(v0_3d, v0);
+               Vec2Copyf(v1_3d, v1);
+               Vec2Copyf(v2_3d, v2);
+               
+               /* Doing this in 3D is not nice */
+               return LineIntersectsTriangle(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, &uv);
+}
+
+/*
+
+       x1,y2
+       |  \
+       |   \     .(a,b)
+       |    \
+       x1,y1-- x2,y1
+
+*/
+int IsPointInTri2DInts(int x1, int y1, int x2, int y2, int a, int b)
+{
+       float v1[2], v2[2], v3[2], p[2];
+       
+       v1[0]= (float)x1;
+       v1[1]= (float)y1;
+       
+       v2[0]= (float)x1;
+       v2[1]= (float)y2;
+       
+       v3[0]= (float)x2;
+       v3[1]= (float)y1;
+       
+       p[0]= (float)a;
+       p[1]= (float)b;
+       
+       return IsPointInTri2D(v1, v2, v3, p);
+       
+}
+
 /* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
 void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v)
 {
diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h
new file mode 100644 (file)
index 0000000..ee19210
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef ED_SCREEN_TYPES_H__
+#define ED_SCREEN_TYPES_H__
+
+typedef struct AZone {
+       struct AZone *next, *prev;
+       int type;
+       int flag;
+       int action;
+       int pos;
+       short x1, y1, x2, y2;
+} AZone;
+
+#define MAX_AZONES                     8
+
+
+/* actionzone type */
+#define        AZONE_TRI                       1
+#define AZONE_QUAD                     2
+
+/* actionzone action */
+#define AZONE_SPLIT                    1
+#define AZONE_JOIN                     2
+#define AZONE_DRAG                     3
+
+/* actionzone pos */
+#define AZONE_S                                1
+#define AZONE_SW                       2
+#define AZONE_W                                3
+#define AZONE_NW                       4
+#define AZONE_N                                5
+#define AZONE_NE                       6
+#define AZONE_E                                7
+#define AZONE_SE                       8
+
+#endif /* ED_SCREEN_TYPES_H__ */
index e12bd82c627fc67db06dbb5f04c1e279de4468d7..188e4be72e2ee65a0eef6e3166da0cdd5be20c1d 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "ED_area.h"
 #include "ED_screen.h"
+#include "ED_screen_types.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -259,6 +260,95 @@ static void area_calc_totrct(ScrArea *sa, int sizex, int sizey)
        sa->winy= sa->totrct.ymax-sa->totrct.ymin+1;
 }
 
+void area_azone_initialize(ScrArea *sa) {
+       AZone *az;
+       if(sa->actionzones.first==NULL) {
+               printf("area_azone_initialize\n");
+               /* set action zones - should these actually be ARegions? With these we can easier check area hotzones */
+               az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&(sa->actionzones), az);
+               az->type= AZONE_TRI;
+               az->x1= sa->v1->vec.x+1;
+               az->y1= sa->v1->vec.y+1;
+               az->x2= sa->v1->vec.x+HEADERY;
+               az->y2= sa->v1->vec.y+HEADERY;
+               az->pos= AZONE_SW;
+               az->action= AZONE_SPLIT;
+               
+               az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&(sa->actionzones), az);
+               az->type= AZONE_TRI;
+               az->x1= sa->v3->vec.x-1;
+               az->y1= sa->v3->vec.y-1;
+               az->x2= sa->v3->vec.x-HEADERY;
+               az->y2= sa->v3->vec.y-HEADERY;
+               az->pos= AZONE_NE;
+               az->action= AZONE_DRAG;
+               
+               /*az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&sa->azones, az);
+               az->type= AZONE_TRI;
+               az->x1= as->v1->vec.x;
+               az->y1= as->v1->vec.y;
+               az->x2= as->v1->vec.x+HEADERY;
+               az->y2= as->v1->vec.y+HEADERY;
+               
+               az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&sa->azones, az);
+               az->type= AZONE_TRI;
+               az->x1= as->v1->vec.x;
+               az->y1= as->v1->vec.y;
+               az->x2= as->v1->vec.x+HEADERY;
+               az->y2= as->v1->vec.y+HEADERY;
+               
+               az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&sa->azones, az);
+               az->type= AZONE_QUAD;
+               az->x1= as->v1->vec.x;
+               az->y1= as->v1->vec.y;
+               az->x2= as->v1->vec.x+HEADERY;
+               az->y2= as->v1->vec.y+HEADERY;
+               
+               az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&sa->azones, az);
+               az->type= AZONE_QUAD;
+               az->x1= as->v1->vec.x;
+               az->y1= as->v1->vec.y;
+               az->x2= as->v1->vec.x+HEADERY;
+               az->y2= as->v1->vec.y+HEADERY;
+               
+               az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&sa->azones, az);
+               az->type= AZONE_QUAD;
+               az->x1= as->v1->vec.x;
+               az->y1= as->v1->vec.y;
+               az->x2= as->v1->vec.x+HEADERY;
+               az->y2= as->v1->vec.y+HEADERY;
+               
+               az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
+               BLI_addtail(&sa->azones, az);
+               az->type= AZONE_QUAD;
+               az->x1= as->v1->vec.x;
+               az->y1= as->v1->vec.y;
+               az->x2= as->v1->vec.x+HEADERY;
+               az->y2= as->v1->vec.y+HEADERY;*/
+       }
+       
+       for(az= sa->actionzones.first; az; az= az->next) {
+               if(az->pos==AZONE_SW) {
+                       az->x1= sa->v1->vec.x+1;
+                       az->y1= sa->v1->vec.y+1;
+                       az->x2= sa->v1->vec.x+HEADERY;
+                       az->y2= sa->v1->vec.y+HEADERY;
+               } else if (az->pos==AZONE_NE) {
+                       az->x1= sa->v3->vec.x-1;
+                       az->y1= sa->v3->vec.y-1;
+                       az->x2= sa->v3->vec.x-HEADERY;
+                       az->y2= sa->v3->vec.y-HEADERY;
+               }
+       }
+}
+
 /* called in screen_refresh, or screens_init */
 void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
 {
@@ -294,6 +384,8 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
                else 
                        wm_subwindow_position(win, ar->swinid, &ar->winrct);
        }
+       
+       area_azone_initialize(sa);
 }
 
 /* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
@@ -303,6 +395,7 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
 {
        Panel *pa1, *pa2, *patab;
        ARegion *ar;
+       AZone *az;
        
        sa1->headertype= sa2->headertype;
        sa1->spacetype= sa2->spacetype;
@@ -342,6 +435,12 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
        for(ar= sa1->regionbase.first; ar; ar= ar->next)
                ar->swinid= 0;
        
+       /* azones */
+       BLI_freelistN(&sa1->actionzones);
+       BLI_duplicatelist(&sa1->actionzones, &sa2->actionzones);
+       for(az= sa1->actionzones.first; az; az= az->next)
+               az->flag= 0;
+       
        /* scripts */
        BPY_free_scriptlink(&sa1->scriptlink);
        sa1->scriptlink= sa2->scriptlink;
index fc15a14a97471385ef080cf8e5dc14507b07f511..acf21e63d5a54f1deecd8804f21cd04bf6bf2371 100644 (file)
@@ -27,6 +27,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_arithb.h"
 
 #include "BKE_global.h"
 #include "BKE_library.h"
@@ -43,7 +44,7 @@
 
 #include "ED_area.h"
 #include "ED_screen.h"
-
+#include "ED_screen_types.h"
 
 #include "wm_subwindow.h"
 
@@ -141,6 +142,23 @@ static ScrArea *screen_areahascursor(bScreen *scr, int x, int y)
        return sa;
 }
 
+static AZone *is_in_area_actionzone(ScrArea *sa, int x, int y)
+{
+       AZone *az= NULL;
+       int i= 0;
+       
+       for(az= sa->actionzones.first, i= 0; az; az= az->next, i++) {
+               if(az->type == AZONE_TRI) {
+                       if(IsPointInTri2DInts(az->x1, az->y1, az->x2, az->y2, x, y)) break;
+               }
+               if(az->type == AZONE_QUAD) {
+                       if(az->x1 < x && x < az->x2 && az->y1 < y && y < az->y2) break;
+               }
+       }
+       
+       return az;
+}
+
 static void removedouble_scrverts(bScreen *sc)
 {
        ScrVert *v1, *verg;
@@ -353,6 +371,7 @@ static void select_connected_scredge(bScreen *sc, ScrEdge *edge)
 
 static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v3, ScrVert *v4, short headertype, short spacetype)
 {
+       AZone *az= NULL;
        ScrArea *sa= MEM_callocN(sizeof(ScrArea), "addscrarea");
        sa->v1= v1;
        sa->v2= v2;
@@ -699,6 +718,7 @@ void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
 
 static void drawscredge_area(ScrArea *sa)
 {
+       AZone *az;
        short x1= sa->v1->vec.x;
        short xa1= x1+HEADERY;
        short y1= sa->v1->vec.y;
@@ -725,8 +745,9 @@ static void drawscredge_area(ScrArea *sa)
        sdrawline(x1, y1, x2, y1);
        
        /* temporary viz for 'action corner' */
-       sdrawtrifill(x1, y1, xa1, ya1, .2, .2, .2);
-       
+       for(az= sa->actionzones.first; az; az= az->next) {
+               if(az->type==AZONE_TRI) sdrawtrifill(az->x1, az->y1, az->x2, az->y2, .2, .2, .2);
+       }
 }
 
 void ED_screen_do_listen(bScreen *screen, wmNotifier *note)
@@ -740,6 +761,12 @@ void ED_screen_do_listen(bScreen *screen, wmNotifier *note)
                case WM_NOTE_SCREEN_CHANGED:
                        screen->do_draw= screen->do_refresh= 1;
                        break;
+               case WM_NOTE_AREA_SPLIT:
+                       printf("WM_NOTE_AREA_SPLIT\n");
+                       break;
+               case WM_NOTE_AREA_DRAG:
+                       printf("WM_NOTE_AREA_DRAG\n");
+                       break;
        }
 }
 
@@ -841,7 +868,14 @@ int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
                        WM_set_cursor(C, CURSOR_X_MOVE);
                }
        } else {
-               WM_set_cursor(C, CURSOR_STD);
+               ScrArea *sa= NULL;
+               AZone *az= NULL;
+               for(sa= C->screen->areabase.first; sa; sa= sa->next) {
+                       az= is_in_area_actionzone(sa, event->x, event->y);
+                       if(az!=NULL) break;
+               }
+               if(az!=NULL) WM_set_cursor(C, CURSOR_EDIT);
+               else WM_set_cursor(C, CURSOR_STD);
        }
        
        return 1;
index 61f8bab83fd352dd49740af52c5812b61095ce22..85c6bbf9172d0945779c1853ea7207bddb264fbd 100644 (file)
@@ -125,6 +125,8 @@ typedef struct ScrArea {
        ListBase panels;
        ListBase regionbase;    /* ARegion */
        ListBase handlers;              /* wmEventHandler */
+       
+       ListBase actionzones;   /* AZone */
 } ScrArea;
 
 typedef struct ARegion {
@@ -149,7 +151,6 @@ typedef struct ARegion {
        
 } ARegion;
 
-
 /* area->flag */
 #define HEADER_NO_PULLDOWN     1
 
@@ -214,6 +215,5 @@ typedef struct ARegion {
 #define RGN_FLAG_HIDDEN                1
 #define RGN_FLAG_TOO_SMALL     2
 
-
 #endif
 
index c232815fd49c1b8895323489321262b7ea659dff..195fa3a00632012f543a44dd49034783481552c2 100644 (file)
@@ -94,6 +94,7 @@ typedef struct wmNotifier {
        int swinid;
        int type;
        int value;
+       void *data;
        
 } wmNotifier;
 
@@ -102,7 +103,8 @@ enum {
        WM_NOTE_WINDOW_REDRAW,
        WM_NOTE_SCREEN_CHANGED,
        WM_NOTE_OBJECT_CHANGED,
-       
+       WM_NOTE_AREA_SPLIT,
+       WM_NOTE_AREA_DRAG,
        WM_NOTE_LAST
 };