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:
authorTon Roosendaal <ton@blender.org>2008-11-19 19:28:11 +0300
committerTon Roosendaal <ton@blender.org>2008-11-19 19:28:11 +0300
commita1b2c0c0fb7adb1758b0503a5422c377f8d0f73e (patch)
treee34a21c6621c407b6b140ef107797b9d29819ee7
parentfd8c94fdb156ce83f5aa70eddcd85b0af6f1456a (diff)
Code shuffle to make a bit more structure.
- operator definitions, callbacks, registry to WM and handlers for it are now always in a file xxxx_ops.c or xxxx_operators.c, in the bottom you will find the registry and handler code. - fixed some confusing naming conventions "rip_area vs area_join" etc. Now stick to convention to first name subject, then operation (like UI :). So it's area_rip, screen_add, and so on. - Nicely put exported calls (outside module) together in bottom: this using names such as ED_screen_duplicate(). - Moved Operator-Property API to new C file.
-rw-r--r--source/blender/editors/screen/screen_edit.c1400
-rw-r--r--source/blender/editors/screen/screen_intern.h23
-rw-r--r--source/blender/editors/screen/screen_ops.c1156
-rw-r--r--source/blender/windowmanager/WM_api.h34
-rw-r--r--source/blender/windowmanager/intern/wm.c11
-rw-r--r--source/blender/windowmanager/intern/wm_operator_props.c298
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c268
-rw-r--r--source/blender/windowmanager/wm.h1
8 files changed, 1612 insertions, 1579 deletions
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 9d668e79eb5..5c39a1b00bd 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -31,7 +31,6 @@
#include "DNA_vec_types.h"
#include "BLI_blenlib.h"
-#include "BLI_arithb.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -90,7 +89,7 @@ static ScrEdge *screen_addedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
}
-static ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
+ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
{
ScrEdge *se;
@@ -102,170 +101,7 @@ static ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
return NULL;
}
-static ScrArea *screen_areahascursor(bScreen *scr, int x, int y)
-{
- ScrArea *sa= NULL;
- sa= scr->areabase.first;
- while(sa) {
- if(BLI_in_rcti(&sa->totrct, x, y)) break;
- sa= sa->next;
- }
-
- return sa;
-}
-
-/* *************************** action zone operator ************************** */
-
-/* operator state vars used:
- none
-
-functions:
-
- apply() set actionzone event
-
- exit() free customdata
-
-callbacks:
-
- exec() never used
-
- invoke() check if in zone
- add customdata, put mouseco and area in it
- add modal handler
-
- modal() accept modal events while doing it
- call apply() with gesture info, active window, nonactive window
- call exit() and remove handler when LMB confirm
-
-*/
-
-typedef struct sActionzoneData {
- ScrArea *sa1, *sa2;
- AZone *az;
- int x, y, gesture_dir;
-} sActionzoneData;
-
-
-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 && 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 int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- AZone *az= is_in_area_actionzone(C->area, event->x, event->y);
- sActionzoneData *sad;
-
- /* quick escape */
- if(az==NULL)
- return OPERATOR_PASS_THROUGH;
-
- /* ok we do the actionzone */
- sad= op->customdata= MEM_callocN(sizeof(sActionzoneData), "sActionzoneData");
- sad->sa1= C->area;
- sad->az= az;
- sad->x= event->x; sad->y= event->y;
-
- /* add modal handler */
- WM_event_add_modal_handler(&C->window->handlers, op);
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static void actionzone_exit(bContext *C, wmOperator *op)
-{
- if(op->customdata)
- MEM_freeN(op->customdata);
- op->customdata= NULL;
-}
-
-/* send EVT_ACTIONZONE event */
-static void actionzone_apply(bContext *C, wmOperator *op)
-{
- wmEvent event;
-
- event= *(C->window->eventstate); /* XXX huh huh? make api call */
- event.type= EVT_ACTIONZONE;
- event.customdata= op->customdata;
- event.customdatafree= TRUE;
- op->customdata= NULL;
-
- wm_event_add(C->window, &event);
-}
-
-static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- sActionzoneData *sad= op->customdata;
- int deltax, deltay;
-
- switch(event->type) {
- case MOUSEMOVE:
- /* calculate gesture direction */
- deltax= (event->x - sad->x);
- deltay= (event->y - sad->y);
-
- if(deltay > ABS(deltax))
- sad->gesture_dir= AZONE_N;
- else if(deltax > ABS(deltay))
- sad->gesture_dir= AZONE_E;
- else if(deltay < -ABS(deltax))
- sad->gesture_dir= AZONE_S;
- else
- sad->gesture_dir= AZONE_W;
-
- /* gesture is large enough? */
- if(ABS(deltax) > 12 || ABS(deltay) > 12) {
-
- /* second area, for join */
- sad->sa2= screen_areahascursor(C->screen, event->x, event->y);
- /* apply sends event */
- actionzone_apply(C, op);
- actionzone_exit(C, op);
-
- WM_event_remove_modal_handler(&C->window->handlers, op);
-
- return OPERATOR_FINISHED;
- }
- break;
- case ESCKEY:
- case LEFTMOUSE:
- actionzone_exit(C, op);
- WM_event_remove_modal_handler(&C->window->handlers, op);
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-void ED_SCR_OT_actionzone(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Handle area action zones";
- ot->idname= "ED_SCR_OT_actionzone";
-
- ot->invoke= actionzone_invoke;
- ot->modal= actionzone_modal;
-
- ot->poll= ED_operator_areaactive;
-}
-
-/* ************************************** */
-
-static void removedouble_scrverts(bScreen *sc)
+void removedouble_scrverts(bScreen *sc)
{
ScrVert *v1, *verg;
ScrEdge *se;
@@ -319,7 +155,7 @@ static void removedouble_scrverts(bScreen *sc)
}
-static void removenotused_scrverts(bScreen *sc)
+void removenotused_scrverts(bScreen *sc)
{
ScrVert *sv, *svn;
ScrEdge *se;
@@ -345,7 +181,7 @@ static void removenotused_scrverts(bScreen *sc)
}
}
-static void removedouble_scredges(bScreen *sc)
+void removedouble_scredges(bScreen *sc)
{
ScrEdge *verg, *se, *sn;
@@ -365,7 +201,7 @@ static void removedouble_scredges(bScreen *sc)
}
}
-static void removenotused_scredges(bScreen *sc)
+void removenotused_scredges(bScreen *sc)
{
ScrEdge *se, *sen;
ScrArea *sa;
@@ -401,80 +237,6 @@ static void removenotused_scredges(bScreen *sc)
}
}
-static int scredge_is_horizontal(ScrEdge *se)
-{
- return (se->v1->vec.y == se->v2->vec.y);
-}
-
-static ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
-{
- ScrEdge *se;
-
- for (se= sc->edgebase.first; se; se= se->next) {
- if (scredge_is_horizontal(se)) {
- short min, max;
- min= MIN2(se->v1->vec.x, se->v2->vec.x);
- max= MAX2(se->v1->vec.x, se->v2->vec.x);
-
- if (abs(my-se->v1->vec.y)<=2 && mx>=min && mx<=max)
- return se;
- }
- else {
- short min, max;
- min= MIN2(se->v1->vec.y, se->v2->vec.y);
- max= MAX2(se->v1->vec.y, se->v2->vec.y);
-
- if (abs(mx-se->v1->vec.x)<=2 && my>=min && my<=max)
- return se;
- }
- }
-
- return NULL;
-}
-
-/* danger: is used while areamove! */
-static void select_connected_scredge(bScreen *sc, ScrEdge *edge)
-{
- ScrEdge *se;
- ScrVert *sv;
- int oneselected;
- char dir;
-
- /* select connected, only in the right direction */
- /* 'dir' is the direction of EDGE */
-
- if(edge->v1->vec.x==edge->v2->vec.x) dir= 'v';
- else dir= 'h';
-
- sv= sc->vertbase.first;
- while(sv) {
- sv->flag = 0;
- sv= sv->next;
- }
-
- edge->v1->flag= 1;
- edge->v2->flag= 1;
-
- oneselected= 1;
- while(oneselected) {
- se= sc->edgebase.first;
- oneselected= 0;
- while(se) {
- if(se->v1->flag + se->v2->flag==1) {
- if(dir=='h') if(se->v1->vec.y==se->v2->vec.y) {
- se->v1->flag= se->v2->flag= 1;
- oneselected= 1;
- }
- if(dir=='v') if(se->v1->vec.x==se->v2->vec.x) {
- se->v1->flag= se->v2->flag= 1;
- oneselected= 1;
- }
- }
- se= se->next;
- }
- }
-}
-
/* adds no space data */
static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v3, ScrVert *v4, short headertype, short spacetype)
{
@@ -499,14 +261,108 @@ static void screen_delarea(bScreen *sc, ScrArea *sa)
MEM_freeN(sa);
}
-/* Helper function to join 2 areas, it has a return value, 0=failed 1=success
- * used by the split, join and rip operators
- */
-int screen_join_areas(bScreen *scr, ScrArea *sa1, ScrArea *sa2);
+/* return 0: no split possible */
+/* else return (integer) screencoordinate split point */
+static short testsplitpoint(wmWindow *win, ScrArea *sa, char dir, float fac)
+{
+ short x, y;
+
+ // area big enough?
+ if(sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX) return 0;
+ if(sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY) return 0;
+
+ // to be sure
+ if(fac<0.0) fac= 0.0;
+ if(fac>1.0) fac= 1.0;
+
+ if(dir=='h') {
+ y= sa->v1->vec.y+ fac*(sa->v2->vec.y- sa->v1->vec.y);
+
+ if(y- sa->v1->vec.y < AREAMINY)
+ y= sa->v1->vec.y+ AREAMINY;
+ else if(sa->v2->vec.y- y < AREAMINY)
+ y= sa->v2->vec.y- AREAMINY;
+ else y-= (y % AREAGRID);
+
+ return y;
+ }
+ else {
+ x= sa->v1->vec.x+ fac*(sa->v4->vec.x- sa->v1->vec.x);
+
+ if(x- sa->v1->vec.x < AREAMINX)
+ x= sa->v1->vec.x+ AREAMINX;
+ else if(sa->v4->vec.x- x < AREAMINX)
+ x= sa->v4->vec.x- AREAMINX;
+ else x-= (x % AREAGRID);
+
+ return x;
+ }
+}
+
+ScrArea *area_split(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac)
+{
+ ScrArea *newa=NULL;
+ ScrVert *sv1, *sv2;
+ short split;
+
+ if(sa==0) return NULL;
+
+ split= testsplitpoint(win, sa, dir, fac);
+ if(split==0) return NULL;
+
+ if(dir=='h') {
+ /* new vertices */
+ sv1= screen_addvert(sc, sa->v1->vec.x, split);
+ sv2= screen_addvert(sc, sa->v4->vec.x, split);
+
+ /* new edges */
+ screen_addedge(sc, sa->v1, sv1);
+ screen_addedge(sc, sv1, sa->v2);
+ screen_addedge(sc, sa->v3, sv2);
+ screen_addedge(sc, sv2, sa->v4);
+ screen_addedge(sc, sv1, sv2);
+
+ /* new areas: top */
+ newa= screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->headertype, sa->spacetype);
+ area_copy_data(newa, sa, 0);
+
+ /* area below */
+ sa->v2= sv1;
+ sa->v3= sv2;
+
+ }
+ else {
+ /* new vertices */
+ sv1= screen_addvert(sc, split, sa->v1->vec.y);
+ sv2= screen_addvert(sc, split, sa->v2->vec.y);
+
+ /* new edges */
+ screen_addedge(sc, sa->v1, sv1);
+ screen_addedge(sc, sv1, sa->v4);
+ screen_addedge(sc, sa->v2, sv2);
+ screen_addedge(sc, sv2, sa->v3);
+ screen_addedge(sc, sv1, sv2);
+
+ /* new areas: left */
+ newa= screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->headertype, sa->spacetype);
+ area_copy_data(newa, sa, 0);
+
+ /* area right */
+ sa->v1= sv1;
+ sa->v2= sv2;
+ }
+
+ /* remove double vertices en edges */
+ removedouble_scrverts(sc);
+ removedouble_scredges(sc);
+ removenotused_scredges(sc);
+
+ return newa;
+}
/* empty screen, with 1 dummy area without spacedata */
/* uses window size */
-static bScreen *screen_add(wmWindow *win, char *name)
+bScreen *screen_add(wmWindow *win, char *name)
{
bScreen *sc;
ScrVert *sv1, *sv2, *sv3, *sv4;
@@ -581,100 +437,11 @@ static void screen_copy(bScreen *to, bScreen *from)
}
-/* *********** Rip area operator ****************** */
-
-
-/* operator callback */
-/* (ton) removed attempt to merge ripped area with another, don't think this is desired functionality.
- conventions: 'atomic' and 'dont think for user' :) */
-static int screen_area_rip_op(bContext *C, wmOperator *op)
-{
- wmWindow *win;
- bScreen *newsc;
- rcti rect;
-
- /* poll() checks area context, but we don't accept full-area windows */
- if(C->screen->full != SCREENNORMAL)
- return OPERATOR_CANCELLED;
-
- /* adds window to WM */
- rect= C->area->totrct;
- BLI_translate_rcti(&rect, C->window->posx, C->window->posy);
- win= WM_window_open(C, &rect);
-
- /* allocs new screen and adds to newly created window, using window size */
- newsc= screen_add(win, C->screen->id.name+2);
-
- /* copy area to new screen */
- area_copy_data((ScrArea *)newsc->areabase.first, C->area, 0);
-
- /* screen, areas init */
- WM_event_add_notifier(C->wm, win, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-
-
-void ED_SCR_OT_area_rip(wmOperatorType *ot)
-{
- ot->name= "Rip Area into New Window";
- ot->idname= "ED_SCR_OT_area_rip";
-
- ot->invoke= NULL; //WM_operator_confirm;
- ot->exec= screen_area_rip_op;
- ot->poll= ED_operator_areaactive;
-}
-
-/* ********************************************* */
-
-bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
-{
- bScreen *newsc;
-
- if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
-
- /* make new empty screen: */
- newsc= screen_add(win, sc->id.name+2);
- /* copy all data */
- screen_copy(newsc, sc);
-
- return newsc;
-}
-
-/* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */
-/* used with split operator */
-static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
-{
- ScrVert *sav1= sa->v1;
- ScrVert *sav2= sa->v2;
- ScrVert *sav3= sa->v3;
- ScrVert *sav4= sa->v4;
- ScrVert *sbv1= sb->v1;
- ScrVert *sbv2= sb->v2;
- ScrVert *sbv3= sb->v3;
- ScrVert *sbv4= sb->v4;
-
- if(sav1==sbv4 && sav2==sbv3) { /* sa to right of sb = W */
- return screen_findedge(screen, sav1, sav2);
- }
- else if(sav2==sbv1 && sav3==sbv4) { /* sa to bottom of sb = N */
- return screen_findedge(screen, sav2, sav3);
- }
- else if(sav3==sbv2 && sav4==sbv1) { /* sa to left of sb = E */
- return screen_findedge(screen, sav3, sav4);
- }
- else if(sav1==sbv2 && sav4==sbv3) { /* sa on top of sb = S*/
- return screen_findedge(screen, sav1, sav4);
- }
-
- return NULL;
-}
/* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */
/* -1 = not valid check */
/* used with join operator */
-static int area_getorientation(bScreen *screen, ScrArea *sa, ScrArea *sb)
+int area_getorientation(bScreen *screen, ScrArea *sa, ScrArea *sb)
{
ScrVert *sav1, *sav2, *sav3, *sav4;
ScrVert *sbv1, *sbv2, *sbv3, *sbv4;
@@ -706,115 +473,10 @@ static int area_getorientation(bScreen *screen, ScrArea *sa, ScrArea *sb)
return -1;
}
-/* return 0: no split possible */
-/* else return (integer) screencoordinate split point */
-static short testsplitpoint(wmWindow *win, ScrArea *sa, char dir, float fac)
-{
- short x, y;
-
- // area big enough?
- if(sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX) return 0;
- if(sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY) return 0;
-
- // to be sure
- if(fac<0.0) fac= 0.0;
- if(fac>1.0) fac= 1.0;
-
- if(dir=='h') {
- y= sa->v1->vec.y+ fac*(sa->v2->vec.y- sa->v1->vec.y);
-
- if(sa->v2->vec.y==win->sizey-1 && sa->v2->vec.y- y < HEADERY)
- y= sa->v2->vec.y- HEADERY;
-
- else if(sa->v1->vec.y==0 && y- sa->v1->vec.y < HEADERY)
- y= sa->v1->vec.y+ HEADERY;
-
- else if(y- sa->v1->vec.y < AREAMINY) y= sa->v1->vec.y+ AREAMINY;
- else if(sa->v2->vec.y- y < AREAMINY) y= sa->v2->vec.y- AREAMINY;
- else y-= (y % AREAGRID);
-
- return y;
- }
- else {
- x= sa->v1->vec.x+ fac*(sa->v4->vec.x- sa->v1->vec.x);
- if(x- sa->v1->vec.x < AREAMINX) x= sa->v1->vec.x+ AREAMINX;
- else if(sa->v4->vec.x- x < AREAMINX) x= sa->v4->vec.x- AREAMINX;
- else x-= (x % AREAGRID);
-
- return x;
- }
-}
-
-static ScrArea *splitarea(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac)
-{
- ScrArea *newa=NULL;
- ScrVert *sv1, *sv2;
- short split;
-
- if(sa==0) return NULL;
-
- split= testsplitpoint(win, sa, dir, fac);
- if(split==0) return NULL;
-
- //sc= G.curscreen;
-
- //areawinset(sa->win);
-
- if(dir=='h') {
- /* new vertices */
- sv1= screen_addvert(sc, sa->v1->vec.x, split);
- sv2= screen_addvert(sc, sa->v4->vec.x, split);
-
- /* new edges */
- screen_addedge(sc, sa->v1, sv1);
- screen_addedge(sc, sv1, sa->v2);
- screen_addedge(sc, sa->v3, sv2);
- screen_addedge(sc, sv2, sa->v4);
- screen_addedge(sc, sv1, sv2);
-
- /* new areas: top */
- newa= screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->headertype, sa->spacetype);
- area_copy_data(newa, sa, 0);
-
- /* area below */
- sa->v2= sv1;
- sa->v3= sv2;
-
- }
- else {
- /* new vertices */
- sv1= screen_addvert(sc, split, sa->v1->vec.y);
- sv2= screen_addvert(sc, split, sa->v2->vec.y);
-
- /* new edges */
- screen_addedge(sc, sa->v1, sv1);
- screen_addedge(sc, sv1, sa->v4);
- screen_addedge(sc, sa->v2, sv2);
- screen_addedge(sc, sv2, sa->v3);
- screen_addedge(sc, sv1, sv2);
-
- /* new areas: left */
- newa= screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->headertype, sa->spacetype);
- area_copy_data(newa, sa, 0);
-
- /* area right */
- sa->v1= sv1;
- sa->v2= sv2;
- }
-
- /* remove double vertices en edges */
- removedouble_scrverts(sc);
- removedouble_scredges(sc);
- removenotused_scredges(sc);
-
- return newa;
-}
-
-
/* Helper function to join 2 areas, it has a return value, 0=failed 1=success
- * used by the split, join and rip operators
- */
-int screen_join_areas(bScreen* scr, ScrArea *sa1, ScrArea *sa2)
+* used by the split, join operators
+*/
+int screen_area_join(bScreen* scr, ScrArea *sa1, ScrArea *sa2)
{
int dir;
@@ -860,10 +522,9 @@ int screen_join_areas(bScreen* scr, ScrArea *sa1, ScrArea *sa2)
return 1;
}
-/* *************************************************************** */
/* test if screen vertices should be scaled */
-void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
+static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
{
ScrVert *sv=NULL;
ScrArea *sa, *san;
@@ -922,6 +583,7 @@ void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
}
}
+/* *********************** DRAWING **************************************** */
#define SCR_BACK 0.55
@@ -1135,6 +797,23 @@ static void drawscredge_area(ScrArea *sa)
}
}
+/* ****************** EXPORTED API TO OTHER MODULES *************************** */
+
+bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
+{
+ bScreen *newsc;
+
+ if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
+
+ /* make new empty screen: */
+ newsc= screen_add(win, sc->id.name+2);
+ /* copy all data */
+ screen_copy(newsc, sc);
+
+ return newsc;
+}
+
+
void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
{
@@ -1169,6 +848,7 @@ void ED_screen_draw(wmWindow *win)
drawscredge_area(sa);
}
+ /* blended join arrow */
if (sa1 && sa2) {
dir = area_getorientation(win->screen, sa1, sa2);
if (dir >= 0) {
@@ -1194,6 +874,7 @@ void ED_screen_draw(wmWindow *win)
scrarea_draw_shape_dark(sa2, dir);
scrarea_draw_shape_light(sa1, dira);
}
+
if(G.f & G_DEBUG) printf("draw screen\n");
win->screen->do_draw= 0;
}
@@ -1301,827 +982,4 @@ void ED_screen_set_subwinactive(wmWindow *win)
}
}
-/* ****************** cursor near edge operator ********************************* */
-
-/* operator cb */
-int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
-{
- if (C->screen->subwinactive==C->screen->mainwin) {
- ScrEdge *actedge= screen_find_active_scredge(C->screen, event->x, event->y);
-
- if (actedge && scredge_is_horizontal(actedge)) {
- WM_set_cursor(C, CURSOR_Y_MOVE);
- } else {
- WM_set_cursor(C, CURSOR_X_MOVE);
- }
- } else {
- 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 OPERATOR_PASS_THROUGH;
-}
-
-/* ************** move area edge operator *********************************** */
-
-/* operator state vars used:
- x, y mouse coord near edge
- delta movement of edge
-
- functions:
-
- init() set default property values, find edge based on mouse coords, test
- if the edge can be moved, select edges, calculate min and max movement
-
- apply() apply delta on selection
-
- exit() cleanup, send notifier
-
- cancel() cancel moving
-
- callbacks:
-
- exec() execute without any user interaction, based on properties
- call init(), apply(), exit()
-
- invoke() gets called on mouse click near edge
- call init(), add handler
-
- modal() accept modal events while doing it
- call apply() with delta motion
- call exit() and remove handler
-
-*/
-
-typedef struct sAreaMoveData {
- int bigger, smaller, origval;
- char dir;
-} sAreaMoveData;
-
-/* helper call to move area-edge, sets limits */
-static void move_areas_set_limits(bScreen *sc, int dir, int *bigger, int *smaller)
-{
- ScrArea *sa;
-
- /* we check all areas and test for free space with MINSIZE */
- *bigger= *smaller= 100000;
-
- for(sa= sc->areabase.first; sa; sa= sa->next) {
- if(dir=='h') {
- int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
-
- /* if top or down edge selected, test height */
- if(sa->v1->flag && sa->v4->flag)
- *bigger= MIN2(*bigger, y1);
- else if(sa->v2->flag && sa->v3->flag)
- *smaller= MIN2(*smaller, y1);
- }
- else {
- int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
-
- /* if left or right edge selected, test width */
- if(sa->v1->flag && sa->v2->flag)
- *bigger= MIN2(*bigger, x1);
- else if(sa->v3->flag && sa->v4->flag)
- *smaller= MIN2(*smaller, x1);
- }
- }
-}
-
-/* validate selection inside screen, set variables OK */
-/* return 0: init failed */
-static int move_areas_init (bContext *C, wmOperator *op)
-{
- ScrEdge *actedge;
- sAreaMoveData *md;
- int x, y;
-
- /* required properties */
- if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
- return 0;
-
- /* default properties */
- OP_verify_int(op, "delta", 0, NULL);
-
- /* setup */
- actedge= screen_find_active_scredge(C->screen, x, y);
- if(actedge==NULL) return 0;
-
- md= MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData");
- op->customdata= md;
-
- md->dir= scredge_is_horizontal(actedge)?'h':'v';
- if(md->dir=='h') md->origval= actedge->v1->vec.y;
- else md->origval= actedge->v1->vec.x;
-
- select_connected_scredge(C->screen, actedge);
- /* now all vertices with 'flag==1' are the ones that can be moved. */
-
- move_areas_set_limits(C->screen, md->dir, &md->bigger, &md->smaller);
-
- return 1;
-}
-
-/* moves selected screen edge amount of delta, used by split & move */
-static void move_areas_apply_do(bContext *C, int origval, int delta, int dir, int bigger, int smaller)
-{
- ScrVert *v1;
-
- delta= CLAMPIS(delta, -smaller, bigger);
-
- for (v1= C->screen->vertbase.first; v1; v1= v1->next) {
- if (v1->flag) {
- /* that way a nice AREAGRID */
- if((dir=='v') && v1->vec.x>0 && v1->vec.x<C->window->sizex-1) {
- v1->vec.x= origval + delta;
- if(delta != bigger && delta != -smaller) v1->vec.x-= (v1->vec.x % AREAGRID);
- }
- if((dir=='h') && v1->vec.y>0 && v1->vec.y<C->window->sizey-1) {
- v1->vec.y= origval + delta;
-
- v1->vec.y+= AREAGRID-1;
- v1->vec.y-= (v1->vec.y % AREAGRID);
-
- /* prevent too small top header */
- if(v1->vec.y > C->window->sizey-HEADERY)
- v1->vec.y= C->window->sizey-HEADERY;
- }
- }
- }
-
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-}
-
-static void move_areas_apply(bContext *C, wmOperator *op)
-{
- sAreaMoveData *md= op->customdata;
- int delta;
-
- OP_get_int(op, "delta", &delta);
- move_areas_apply_do(C, md->origval, delta, md->dir, md->bigger, md->smaller);
-}
-
-static void move_areas_exit(bContext *C, wmOperator *op)
-{
- if(op->customdata)
- MEM_freeN(op->customdata);
- op->customdata= NULL;
-
- /* this makes sure aligned edges will result in aligned grabbing */
- removedouble_scrverts(C->screen);
- removedouble_scredges(C->screen);
-}
-
-static int move_areas_exec(bContext *C, wmOperator *op)
-{
- if(!move_areas_init(C, op))
- return OPERATOR_CANCELLED;
-
- move_areas_apply(C, op);
- move_areas_exit(C, op);
-
- return OPERATOR_FINISHED;
-}
-
-/* interaction callback */
-static int move_areas_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- OP_verify_int(op, "x", event->x, NULL);
- OP_verify_int(op, "y", event->y, NULL);
-
- if(!move_areas_init(C, op))
- return OPERATOR_PASS_THROUGH;
-
- /* add temp handler */
- WM_event_add_modal_handler(&C->window->handlers, op);
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int move_areas_cancel(bContext *C, wmOperator *op)
-{
- WM_event_remove_modal_handler(&C->window->handlers, op);
-
- OP_set_int(op, "delta", 0);
- move_areas_apply(C, op);
- move_areas_exit(C, op);
-
- return OPERATOR_CANCELLED;
-}
-
-/* modal callback for while moving edges */
-static int move_areas_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- sAreaMoveData *md;
- int delta, x, y;
-
- md= op->customdata;
-
- OP_get_int(op, "x", &x);
- OP_get_int(op, "y", &y);
-
- /* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
- delta= (md->dir == 'v')? event->x - x: event->y - y;
- OP_set_int(op, "delta", delta);
-
- move_areas_apply(C, op);
- break;
-
- case LEFTMOUSE:
- if(event->val==0) {
- move_areas_exit(C, op);
- WM_event_remove_modal_handler(&C->window->handlers, op);
- return OPERATOR_FINISHED;
- }
- break;
-
- case ESCKEY:
- return move_areas_cancel(C, op);
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-void ED_SCR_OT_move_areas(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Move area edges";
- ot->idname= "ED_SCR_OT_move_areas";
-
- ot->exec= move_areas_exec;
- ot->invoke= move_areas_invoke;
- ot->cancel= move_areas_cancel;
- ot->modal= move_areas_modal;
-
- ot->poll= ED_operator_screen_mainwinactive; /* when mouse is over area-edge */
-}
-
-/* ************** split area operator *********************************** */
-
-/*
-operator state vars:
- fac spit point
- dir direction 'v' or 'h'
-
-operator customdata:
- area pointer to (active) area
- x, y last used mouse pos
- (more, see below)
-
-functions:
-
- init() set default property values, find area based on context
-
- apply() split area based on state vars
-
- exit() cleanup, send notifier
-
- cancel() remove duplicated area
-
-callbacks:
-
- exec() execute without any user interaction, based on state vars
- call init(), apply(), exit()
-
- invoke() gets called on mouse click in action-widget
- call init(), add modal handler
- call apply() with initial motion
-
- modal() accept modal events while doing it
- call move-areas code with delta motion
- call exit() or cancel() and remove handler
-
-*/
-
-#define SPLIT_STARTED 1
-#define SPLIT_PROGRESS 2
-
-typedef struct sAreaSplitData
-{
- int x, y; /* last used mouse position */
-
- int origval; /* for move areas */
- int bigger, smaller; /* constraints for moving new edge */
- int delta; /* delta move edge */
-
- ScrEdge *nedge; /* new edge */
- ScrArea *sarea; /* start area */
- ScrArea *narea; /* new area */
-} sAreaSplitData;
-
-/* generic init, no UI stuff here */
-static int split_area_init(bContext *C, wmOperator *op)
-{
- sAreaSplitData *sd;
- int dir;
-
- /* required context */
- if(C->area==NULL) return 0;
-
- /* required properties */
- OP_verify_float(op, "fac", 0.5f, NULL);
- OP_verify_int(op, "dir", 'h', &dir);
-
- /* minimal size */
- if(dir=='v' && C->area->winx < 2*AREAMINX) return 0;
- if(dir=='h' && C->area->winy < 2*AREAMINY) return 0;
-
- /* custom data */
- sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_split_area");
- op->customdata= sd;
-
- sd->sarea= C->area;
-
- return 1;
-}
-
-/* do the split */
-static void split_area_apply(bContext *C, wmOperator *op)
-{
- sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
- float fac;
- int dir;
-
- OP_get_float(op, "fac", &fac);
- OP_get_int(op, "dir", &dir);
-
- sd->narea= splitarea(C->window, C->screen, sd->sarea, dir, fac);
-
- if(sd->narea) {
- ScrVert *sv;
-
- sd->nedge= area_findsharededge(C->screen, sd->sarea, sd->narea);
-
- /* select newly created edge, prepare for moving edge */
- for(sv= C->screen->vertbase.first; sv; sv= sv->next)
- sv->flag = 0;
-
- sd->nedge->v1->flag= 1;
- sd->nedge->v2->flag= 1;
-
- if(dir=='h') sd->origval= sd->nedge->v1->vec.y;
- else sd->origval= sd->nedge->v1->vec.x;
-
- }
-
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-
-}
-
-static void split_area_exit(bContext *C, wmOperator *op)
-{
- if (op->customdata) {
- MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
-
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-
- /* this makes sure aligned edges will result in aligned grabbing */
- removedouble_scrverts(C->screen);
- removedouble_scredges(C->screen);
-}
-
-
-/* UI callback, adds new handler */
-static int split_area_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- sAreaSplitData *sd;
-
- if(event->type==EVT_ACTIONZONE) {
- sActionzoneData *sad= event->customdata;
- int dir;
-
- /* verify *sad itself */
- if(sad==NULL || sad->sa1==NULL || sad->az==NULL)
- return OPERATOR_PASS_THROUGH;
-
- /* is this our *sad? if areas not equal it should be passed on */
- if(C->area!=sad->sa1 || sad->sa1!=sad->sa2)
- return OPERATOR_PASS_THROUGH;
-
- /* prepare operator state vars */
- if(sad->gesture_dir==AZONE_N || sad->gesture_dir==AZONE_S) {
- dir= 'h';
- OP_set_float(op, "fac", ((float)(event->x - sad->sa1->v1->vec.x)) / (float)sad->sa1->winx);
- }
- else {
- dir= 'v';
- OP_set_float(op, "fac", ((float)(event->y - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy);
- }
- OP_set_int(op, "dir", dir);
-
- /* general init, also non-UI case, adds customdata, sets area and defaults */
- if(!split_area_init(C, op))
- return OPERATOR_PASS_THROUGH;
-
- sd= (sAreaSplitData *)op->customdata;
-
- sd->x= event->x;
- sd->y= event->y;
-
- /* do the split */
- split_area_apply(C, op);
- move_areas_set_limits(C->screen, dir, &sd->bigger, &sd->smaller);
-
- /* add temp handler for edge move or cancel */
- WM_event_add_modal_handler(&C->window->handlers, op);
-
- return OPERATOR_RUNNING_MODAL;
-
- }
- return OPERATOR_PASS_THROUGH;
-}
-
-/* function to be called outside UI context, or for redo */
-static int split_area_exec(bContext *C, wmOperator *op)
-{
-
- if(!split_area_init(C, op))
- return OPERATOR_CANCELLED;
-
- split_area_apply(C, op);
- split_area_exit(C, op);
-
- return OPERATOR_FINISHED;
-}
-
-static int split_area_cancel(bContext *C, wmOperator *op)
-{
- sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
-
- WM_event_remove_modal_handler(&C->window->handlers, op);
-
- if (screen_join_areas(C->screen,sd->sarea, sd->narea)) {
- if (C->area == sd->narea) {
- C->area = NULL;
- }
- sd->narea = NULL;
- }
- split_area_exit(C, op);
-
- return OPERATOR_CANCELLED;
-}
-
-static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
- int dir;
-
- /* execute the events */
- switch(event->type) {
- case MOUSEMOVE:
-
- OP_get_int(op, "dir", &dir);
-
- sd->delta= (dir == 'v')? event->x - sd->origval: event->y - sd->origval;
- move_areas_apply_do(C, sd->origval, sd->delta, dir, sd->bigger, sd->smaller);
-
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
- break;
-
- case LEFTMOUSE:
- if(event->val==0) { /* mouse up */
- split_area_exit(C, op);
- WM_event_remove_modal_handler(&C->window->handlers, op);
- return OPERATOR_FINISHED;
- }
- break;
- case RIGHTMOUSE: /* cancel operation */
- case ESCKEY:
- return split_area_cancel(C, op);
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-void ED_SCR_OT_split_area(wmOperatorType *ot)
-{
- ot->name = "Split area";
- ot->idname = "ED_SCR_OT_split_area";
-
- ot->exec= split_area_exec;
- ot->invoke= split_area_invoke;
- ot->modal= split_area_modal;
-
- ot->poll= ED_operator_screenactive; /* XXX should be area active */
-}
-
-/* ************** join area operator ********************************************** */
-
-/* operator state vars used:
- x1, y1 mouse coord in first area, which will disappear
- x2, y2 mouse coord in 2nd area, which will become joined
-
-functions:
-
- init() find edge based on state vars
- test if the edge divides two areas,
- store active and nonactive area,
-
- apply() do the actual join
-
- exit() cleanup, send notifier
-
-callbacks:
-
- exec() calls init, apply, exit
-
- invoke() sets mouse coords in x,y
- call init()
- add modal handler
-
- modal() accept modal events while doing it
- call apply() with active window and nonactive window
- call exit() and remove handler when LMB confirm
-
-*/
-
-typedef struct sAreaJoinData
-{
- ScrArea *sa1; /* first area to be considered */
- ScrArea *sa2; /* second area to be considered */
- ScrArea *scr; /* designed for removal */
-
-} sAreaJoinData;
-
-
-/* validate selection inside screen, set variables OK */
-/* return 0: init failed */
-/* XXX todo: find edge based on (x,y) and set other area? */
-static int join_areas_init(bContext *C, wmOperator *op)
-{
- ScrArea *sa1, *sa2;
- sAreaJoinData* jd= NULL;
- int x1, y1;
- int x2, y2;
-
- /* required properties, make negative to get return 0 if not set by caller */
- OP_verify_int(op, "x1", -100, &x1);
- OP_verify_int(op, "y1", -100, &y1);
- OP_verify_int(op, "x2", -100, &x2);
- OP_verify_int(op, "y2", -100, &y2);
-
- sa1 = screen_areahascursor(C->screen, x1, y1);
- sa2 = screen_areahascursor(C->screen, x2, y2);
- if(sa1==NULL || sa2==NULL || sa1==sa2)
- return 0;
-
- jd = (sAreaJoinData*)MEM_callocN(sizeof (sAreaJoinData), "op_join_areas");
-
- jd->sa1 = sa1;
- jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
- jd->sa2 = sa2;
- jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
-
- op->customdata= jd;
-
- return 1;
-}
-
-/* apply the join of the areas (space types) */
-static int join_areas_apply(bContext *C, wmOperator *op)
-{
- sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
- if (!jd) return 0;
-
- if(!screen_join_areas(C->screen,jd->sa1,jd->sa2)){
- return 0;
- }
- if (C->area == jd->sa2) {
- C->area = NULL;
- }
-
- return 1;
-}
-
-/* finish operation */
-static void join_areas_exit(bContext *C, wmOperator *op)
-{
- if (op->customdata) {
- MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
-
- /* this makes sure aligned edges will result in aligned grabbing */
- removedouble_scredges(C->screen);
- removenotused_scredges(C->screen);
- removenotused_scrverts(C->screen);
-}
-
-static int join_areas_exec(bContext *C, wmOperator *op)
-{
- if(!join_areas_init(C, op))
- return OPERATOR_CANCELLED;
-
- join_areas_apply(C, op);
- join_areas_exit(C, op);
-
- return OPERATOR_FINISHED;
-}
-
-/* interaction callback */
-static int join_areas_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
-
- if(event->type==EVT_ACTIONZONE) {
- sActionzoneData *sad= event->customdata;
-
- /* verify *sad itself */
- if(sad==NULL || sad->sa1==NULL || sad->sa2==NULL)
- return OPERATOR_PASS_THROUGH;
-
- /* is this our *sad? if areas equal it should be passed on */
- if(sad->sa1==sad->sa2)
- return OPERATOR_PASS_THROUGH;
-
- /* prepare operator state vars */
- OP_set_int(op, "x1", sad->x);
- OP_set_int(op, "y1", sad->y);
- OP_set_int(op, "x2", event->x);
- OP_set_int(op, "y2", event->y);
-
- if(!join_areas_init(C, op))
- return OPERATOR_PASS_THROUGH;
-
- /* add temp handler */
- WM_event_add_modal_handler(&C->window->handlers, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
-
- return OPERATOR_PASS_THROUGH;
-}
-
-static int join_areas_cancel(bContext *C, wmOperator *op)
-{
- sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
-
- if (jd->sa1) {
- jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
- jd->sa1->flag &= ~AREA_FLAG_DRAWJOINTO;
- }
- if (jd->sa2) {
- jd->sa2->flag &= ~AREA_FLAG_DRAWJOINFROM;
- jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
- }
-
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
- WM_event_remove_modal_handler(&C->window->handlers, op);
-
- join_areas_exit(C, op);
-
- return OPERATOR_CANCELLED;
-}
-
-/* modal callback while selecting area (space) that will be removed */
-static int join_areas_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
-
- /* execute the events */
- switch(event->type) {
-
- case MOUSEMOVE:
- {
- ScrArea *sa = screen_areahascursor(C->screen, event->x, event->y);
- int dir;
-
- if (sa) {
- if (jd->sa1 != sa) {
- dir = area_getorientation(C->screen, jd->sa1, sa);
- if (dir >= 0) {
- if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
- jd->sa2 = sa;
- jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
- }
- else {
- /* we are not bordering on the previously selected area
- we check if area has common border with the one marked for removal
- in this case we can swap areas.
- */
- dir = area_getorientation(C->screen, sa, jd->sa2);
- if (dir >= 0) {
- if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
- if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
- jd->sa1 = jd->sa2;
- jd->sa2 = sa;
- if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
- if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
- }
- else {
- if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
- jd->sa2 = NULL;
- }
- }
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
- }
- else {
- /* we are back in the area previously selected for keeping
- * we swap the areas if possible to allow user to choose */
- if (jd->sa2 != NULL) {
- if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
- if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
- jd->sa1 = jd->sa2;
- jd->sa2 = sa;
- if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
- if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
- dir = area_getorientation(C->screen, jd->sa1, jd->sa2);
- if (dir < 0) {
- printf("oops, didn't expect that!\n");
- }
- }
- else {
- dir = area_getorientation(C->screen, jd->sa1, sa);
- if (dir >= 0) {
- if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
- jd->sa2 = sa;
- jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
- }
- }
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
- }
- }
- }
- break;
- case LEFTMOUSE:
- if(event->val==0) {
- join_areas_apply(C, op);
- WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
- join_areas_exit(C, op);
- WM_event_remove_modal_handler(&C->window->handlers, op);
- return OPERATOR_FINISHED;
- }
- break;
-
- case ESCKEY:
- return join_areas_cancel(C, op);
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-/* Operator for joining two areas (space types) */
-void ED_SCR_OT_join_areas(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Join area";
- ot->idname= "ED_SCR_OT_join_areas";
-
- /* api callbacks */
- ot->exec= join_areas_exec;
- ot->invoke= join_areas_invoke;
- ot->modal= join_areas_modal;
-
- ot->poll= ED_operator_screenactive;
-}
-
-/* ************** border select operator (test only) ***************************** */
-
-/* operator state vars used: (added by default WM callbacks)
- xmin, ymin
- xmax, ymax
-
- customdata: the wmGesture pointer
-
-callbacks:
-
- exec() has to be filled in by user
-
- invoke() default WM function
- adds modal handler
-
- modal() default WM function
- accept modal events while doing it, calls exec(), handles ESC and border drawing
-
- poll() has to be filled in by user for context
-*/
-
-static int border_select_do(bContext *C, wmOperator *op)
-{
- printf("border select do\n");
- return 1;
-}
-
-void ED_SCR_OT_border_select(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Border select";
- ot->idname= "ED_SCR_OT_border_select";
-
- /* api callbacks */
- ot->exec= border_select_do;
- ot->invoke= WM_border_select_invoke;
- ot->modal= WM_border_select_modal;
-
- ot->poll= ED_operator_areaactive;
-}
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index c1ab9266f2f..6d8bd9e0434 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -29,23 +29,22 @@
#define ED_SCREEN_INTERN_H
/* internal exports only */
-struct wmOperator;
-struct wmEvent;
+struct wmWindow;
/* area.c */
void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space);
/* screen_edit.c */
-int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event);
-int area_cursor_test(bContext *C, wmOperator *op, wmEvent *event);
-
-void ED_SCR_OT_move_areas(wmOperatorType *ot);
-void ED_SCR_OT_split_area(wmOperatorType *ot);
-void ED_SCR_OT_join_areas(wmOperatorType *ot);
-void ED_SCR_OT_actionzone(wmOperatorType *ot);
-void ED_SCR_OT_area_rip(wmOperatorType *ot);
-
-void ED_SCR_OT_border_select(wmOperatorType *ot);
+bScreen *screen_add(struct wmWindow *win, char *name);
+ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2);
+ScrArea *area_split(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac);
+int screen_area_join(bScreen* scr, ScrArea *sa1, ScrArea *sa2);
+int area_getorientation(bScreen *screen, ScrArea *sa, ScrArea *sb);
+
+void removenotused_scrverts(bScreen *sc);
+void removedouble_scrverts(bScreen *sc);
+void removedouble_scredges(bScreen *sc);
+void removenotused_scredges(bScreen *sc);
#endif /* ED_SCREEN_INTERN_H */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 508fc70cf92..e2680f9cb02 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -27,6 +27,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -39,10 +40,11 @@
#include "ED_area.h"
#include "ED_screen.h"
+#include "ED_screen_types.h"
#include "screen_intern.h" /* own module include */
-/* ************** Poll tests ********************** */
+/* ************** Exported Poll tests ********************** */
int ED_operator_areaactive(bContext *C)
{
@@ -68,7 +70,226 @@ int ED_operator_screen_mainwinactive(bContext *C)
return 1;
}
-/* ******************************* */
+/* *************************** action zone operator ************************** */
+
+/* operator state vars used:
+ none
+
+functions:
+
+ apply() set actionzone event
+
+ exit() free customdata
+
+callbacks:
+
+ exec() never used
+
+ invoke() check if in zone
+ add customdata, put mouseco and area in it
+ add modal handler
+
+ modal() accept modal events while doing it
+ call apply() with gesture info, active window, nonactive window
+ call exit() and remove handler when LMB confirm
+
+*/
+
+typedef struct sActionzoneData {
+ ScrArea *sa1, *sa2;
+ AZone *az;
+ int x, y, gesture_dir;
+} sActionzoneData;
+
+/* used by other operators too */
+static ScrArea *screen_areahascursor(bScreen *scr, int x, int y)
+{
+ ScrArea *sa= NULL;
+ sa= scr->areabase.first;
+ while(sa) {
+ if(BLI_in_rcti(&sa->totrct, x, y)) break;
+ sa= sa->next;
+ }
+
+ 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 && 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 int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ AZone *az= is_in_area_actionzone(C->area, event->x, event->y);
+ sActionzoneData *sad;
+
+ /* quick escape */
+ if(az==NULL)
+ return OPERATOR_PASS_THROUGH;
+
+ /* ok we do the actionzone */
+ sad= op->customdata= MEM_callocN(sizeof(sActionzoneData), "sActionzoneData");
+ sad->sa1= C->area;
+ sad->az= az;
+ sad->x= event->x; sad->y= event->y;
+
+ /* add modal handler */
+ WM_event_add_modal_handler(&C->window->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void actionzone_exit(bContext *C, wmOperator *op)
+{
+ if(op->customdata)
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+}
+
+/* send EVT_ACTIONZONE event */
+static void actionzone_apply(bContext *C, wmOperator *op)
+{
+ wmEvent event;
+
+ event= *(C->window->eventstate); /* XXX huh huh? make api call */
+ event.type= EVT_ACTIONZONE;
+ event.customdata= op->customdata;
+ event.customdatafree= TRUE;
+ op->customdata= NULL;
+
+ wm_event_add(C->window, &event);
+}
+
+static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ sActionzoneData *sad= op->customdata;
+ int deltax, deltay;
+
+ switch(event->type) {
+ case MOUSEMOVE:
+ /* calculate gesture direction */
+ deltax= (event->x - sad->x);
+ deltay= (event->y - sad->y);
+
+ if(deltay > ABS(deltax))
+ sad->gesture_dir= AZONE_N;
+ else if(deltax > ABS(deltay))
+ sad->gesture_dir= AZONE_E;
+ else if(deltay < -ABS(deltax))
+ sad->gesture_dir= AZONE_S;
+ else
+ sad->gesture_dir= AZONE_W;
+
+ /* gesture is large enough? */
+ if(ABS(deltax) > 12 || ABS(deltay) > 12) {
+
+ /* second area, for join */
+ sad->sa2= screen_areahascursor(C->screen, event->x, event->y);
+ /* apply sends event */
+ actionzone_apply(C, op);
+ actionzone_exit(C, op);
+
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+
+ return OPERATOR_FINISHED;
+ }
+ break;
+ case ESCKEY:
+ case LEFTMOUSE:
+ actionzone_exit(C, op);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void ED_SCR_OT_actionzone(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Handle area action zones";
+ ot->idname= "ED_SCR_OT_actionzone";
+
+ ot->invoke= actionzone_invoke;
+ ot->modal= actionzone_modal;
+
+ ot->poll= ED_operator_areaactive;
+}
+
+/* ****************** cursor near edge operator ********************************* */
+
+static int scredge_is_horizontal(ScrEdge *se)
+{
+ return (se->v1->vec.y == se->v2->vec.y);
+}
+
+static ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
+{
+ ScrEdge *se;
+
+ for (se= sc->edgebase.first; se; se= se->next) {
+ if (scredge_is_horizontal(se)) {
+ short min, max;
+ min= MIN2(se->v1->vec.x, se->v2->vec.x);
+ max= MAX2(se->v1->vec.x, se->v2->vec.x);
+
+ if (abs(my-se->v1->vec.y)<=2 && mx>=min && mx<=max)
+ return se;
+ }
+ else {
+ short min, max;
+ min= MIN2(se->v1->vec.y, se->v2->vec.y);
+ max= MAX2(se->v1->vec.y, se->v2->vec.y);
+
+ if (abs(mx-se->v1->vec.x)<=2 && my>=min && my<=max)
+ return se;
+ }
+ }
+
+ return NULL;
+}
+
+
+/* operator cb */
+static int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (C->screen->subwinactive==C->screen->mainwin) {
+ ScrEdge *actedge= screen_find_active_scredge(C->screen, event->x, event->y);
+
+ if (actedge && scredge_is_horizontal(actedge)) {
+ WM_set_cursor(C, CURSOR_Y_MOVE);
+ } else {
+ WM_set_cursor(C, CURSOR_X_MOVE);
+ }
+ } else {
+ 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 OPERATOR_PASS_THROUGH;
+}
static void ED_SCR_OT_cursor_type(wmOperatorType *ot)
{
@@ -79,6 +300,925 @@ static void ED_SCR_OT_cursor_type(wmOperatorType *ot)
ot->poll= ED_operator_screenactive;
}
+
+
+/* *********** Rip area operator ****************** */
+
+
+/* operator callback */
+/* (ton) removed attempt to merge ripped area with another, don't think this is desired functionality.
+conventions: 'atomic' and 'dont think for user' :) */
+static int screen_area_rip_op(bContext *C, wmOperator *op)
+{
+ wmWindow *win;
+ bScreen *newsc;
+ rcti rect;
+
+ /* poll() checks area context, but we don't accept full-area windows */
+ if(C->screen->full != SCREENNORMAL)
+ return OPERATOR_CANCELLED;
+
+ /* adds window to WM */
+ rect= C->area->totrct;
+ BLI_translate_rcti(&rect, C->window->posx, C->window->posy);
+ win= WM_window_open(C, &rect);
+
+ /* allocs new screen and adds to newly created window, using window size */
+ newsc= screen_add(win, C->screen->id.name+2);
+
+ /* copy area to new screen */
+ area_copy_data((ScrArea *)newsc->areabase.first, C->area, 0);
+
+ /* screen, areas init */
+ WM_event_add_notifier(C->wm, win, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void ED_SCR_OT_area_rip(wmOperatorType *ot)
+{
+ ot->name= "Rip Area into New Window";
+ ot->idname= "ED_SCR_OT_area_rip";
+
+ ot->invoke= NULL; //WM_operator_confirm;
+ ot->exec= screen_area_rip_op;
+ ot->poll= ED_operator_areaactive;
+}
+
+
+/* ************** move area edge operator *********************************** */
+
+/* operator state vars used:
+ x, y mouse coord near edge
+ delta movement of edge
+
+ functions:
+
+ init() set default property values, find edge based on mouse coords, test
+ if the edge can be moved, select edges, calculate min and max movement
+
+ apply() apply delta on selection
+
+ exit() cleanup, send notifier
+
+ cancel() cancel moving
+
+ callbacks:
+
+ exec() execute without any user interaction, based on properties
+ call init(), apply(), exit()
+
+ invoke() gets called on mouse click near edge
+ call init(), add handler
+
+ modal() accept modal events while doing it
+ call apply() with delta motion
+ call exit() and remove handler
+
+*/
+
+typedef struct sAreaMoveData {
+ int bigger, smaller, origval;
+ char dir;
+} sAreaMoveData;
+
+/* helper call to move area-edge, sets limits */
+static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller)
+{
+ ScrArea *sa;
+
+ /* we check all areas and test for free space with MINSIZE */
+ *bigger= *smaller= 100000;
+
+ for(sa= sc->areabase.first; sa; sa= sa->next) {
+ if(dir=='h') {
+ int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
+
+ /* if top or down edge selected, test height */
+ if(sa->v1->flag && sa->v4->flag)
+ *bigger= MIN2(*bigger, y1);
+ else if(sa->v2->flag && sa->v3->flag)
+ *smaller= MIN2(*smaller, y1);
+ }
+ else {
+ int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
+
+ /* if left or right edge selected, test width */
+ if(sa->v1->flag && sa->v2->flag)
+ *bigger= MIN2(*bigger, x1);
+ else if(sa->v3->flag && sa->v4->flag)
+ *smaller= MIN2(*smaller, x1);
+ }
+ }
+}
+
+static void select_connected_scredge(bScreen *sc, ScrEdge *edge)
+{
+ ScrEdge *se;
+ ScrVert *sv;
+ int oneselected;
+ char dir;
+
+ /* select connected, only in the right direction */
+ /* 'dir' is the direction of EDGE */
+
+ if(edge->v1->vec.x==edge->v2->vec.x) dir= 'v';
+ else dir= 'h';
+
+ sv= sc->vertbase.first;
+ while(sv) {
+ sv->flag = 0;
+ sv= sv->next;
+ }
+
+ edge->v1->flag= 1;
+ edge->v2->flag= 1;
+
+ oneselected= 1;
+ while(oneselected) {
+ se= sc->edgebase.first;
+ oneselected= 0;
+ while(se) {
+ if(se->v1->flag + se->v2->flag==1) {
+ if(dir=='h') if(se->v1->vec.y==se->v2->vec.y) {
+ se->v1->flag= se->v2->flag= 1;
+ oneselected= 1;
+ }
+ if(dir=='v') if(se->v1->vec.x==se->v2->vec.x) {
+ se->v1->flag= se->v2->flag= 1;
+ oneselected= 1;
+ }
+ }
+ se= se->next;
+ }
+ }
+}
+
+/* validate selection inside screen, set variables OK */
+/* return 0: init failed */
+static int area_move_init (bContext *C, wmOperator *op)
+{
+ ScrEdge *actedge;
+ sAreaMoveData *md;
+ int x, y;
+
+ /* required properties */
+ if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
+ return 0;
+
+ /* default properties */
+ OP_verify_int(op, "delta", 0, NULL);
+
+ /* setup */
+ actedge= screen_find_active_scredge(C->screen, x, y);
+ if(actedge==NULL) return 0;
+
+ md= MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData");
+ op->customdata= md;
+
+ md->dir= scredge_is_horizontal(actedge)?'h':'v';
+ if(md->dir=='h') md->origval= actedge->v1->vec.y;
+ else md->origval= actedge->v1->vec.x;
+
+ select_connected_scredge(C->screen, actedge);
+ /* now all vertices with 'flag==1' are the ones that can be moved. */
+
+ area_move_set_limits(C->screen, md->dir, &md->bigger, &md->smaller);
+
+ return 1;
+}
+
+/* moves selected screen edge amount of delta, used by split & move */
+static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int bigger, int smaller)
+{
+ ScrVert *v1;
+
+ delta= CLAMPIS(delta, -smaller, bigger);
+
+ for (v1= C->screen->vertbase.first; v1; v1= v1->next) {
+ if (v1->flag) {
+ /* that way a nice AREAGRID */
+ if((dir=='v') && v1->vec.x>0 && v1->vec.x<C->window->sizex-1) {
+ v1->vec.x= origval + delta;
+ if(delta != bigger && delta != -smaller) v1->vec.x-= (v1->vec.x % AREAGRID);
+ }
+ if((dir=='h') && v1->vec.y>0 && v1->vec.y<C->window->sizey-1) {
+ v1->vec.y= origval + delta;
+
+ v1->vec.y+= AREAGRID-1;
+ v1->vec.y-= (v1->vec.y % AREAGRID);
+
+ /* prevent too small top header */
+ if(v1->vec.y > C->window->sizey-AREAMINY)
+ v1->vec.y= C->window->sizey-AREAMINY;
+ }
+ }
+ }
+
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+}
+
+static void area_move_apply(bContext *C, wmOperator *op)
+{
+ sAreaMoveData *md= op->customdata;
+ int delta;
+
+ OP_get_int(op, "delta", &delta);
+ area_move_apply_do(C, md->origval, delta, md->dir, md->bigger, md->smaller);
+}
+
+static void area_move_exit(bContext *C, wmOperator *op)
+{
+ if(op->customdata)
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+
+ /* this makes sure aligned edges will result in aligned grabbing */
+ removedouble_scrverts(C->screen);
+ removedouble_scredges(C->screen);
+}
+
+static int area_move_exec(bContext *C, wmOperator *op)
+{
+ if(!area_move_init(C, op))
+ return OPERATOR_CANCELLED;
+
+ area_move_apply(C, op);
+ area_move_exit(C, op);
+
+ return OPERATOR_FINISHED;
+}
+
+/* interaction callback */
+static int area_move_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ OP_verify_int(op, "x", event->x, NULL);
+ OP_verify_int(op, "y", event->y, NULL);
+
+ if(!area_move_init(C, op))
+ return OPERATOR_PASS_THROUGH;
+
+ /* add temp handler */
+ WM_event_add_modal_handler(&C->window->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int area_move_cancel(bContext *C, wmOperator *op)
+{
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+
+ OP_set_int(op, "delta", 0);
+ area_move_apply(C, op);
+ area_move_exit(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
+/* modal callback for while moving edges */
+static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ sAreaMoveData *md;
+ int delta, x, y;
+
+ md= op->customdata;
+
+ OP_get_int(op, "x", &x);
+ OP_get_int(op, "y", &y);
+
+ /* execute the events */
+ switch(event->type) {
+ case MOUSEMOVE:
+ delta= (md->dir == 'v')? event->x - x: event->y - y;
+ OP_set_int(op, "delta", delta);
+
+ area_move_apply(C, op);
+ break;
+
+ case LEFTMOUSE:
+ if(event->val==0) {
+ area_move_exit(C, op);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ return OPERATOR_FINISHED;
+ }
+ break;
+
+ case ESCKEY:
+ return area_move_cancel(C, op);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void ED_SCR_OT_area_move(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Move area edges";
+ ot->idname= "ED_SCR_OT_area_move";
+
+ ot->exec= area_move_exec;
+ ot->invoke= area_move_invoke;
+ ot->cancel= area_move_cancel;
+ ot->modal= area_move_modal;
+
+ ot->poll= ED_operator_screen_mainwinactive; /* when mouse is over area-edge */
+}
+
+/* ************** split area operator *********************************** */
+
+/*
+operator state vars:
+ fac spit point
+ dir direction 'v' or 'h'
+
+operator customdata:
+ area pointer to (active) area
+ x, y last used mouse pos
+ (more, see below)
+
+functions:
+
+ init() set default property values, find area based on context
+
+ apply() split area based on state vars
+
+ exit() cleanup, send notifier
+
+ cancel() remove duplicated area
+
+callbacks:
+
+ exec() execute without any user interaction, based on state vars
+ call init(), apply(), exit()
+
+ invoke() gets called on mouse click in action-widget
+ call init(), add modal handler
+ call apply() with initial motion
+
+ modal() accept modal events while doing it
+ call move-areas code with delta motion
+ call exit() or cancel() and remove handler
+
+*/
+
+#define SPLIT_STARTED 1
+#define SPLIT_PROGRESS 2
+
+typedef struct sAreaSplitData
+{
+ int x, y; /* last used mouse position */
+
+ int origval; /* for move areas */
+ int bigger, smaller; /* constraints for moving new edge */
+ int delta; /* delta move edge */
+
+ ScrEdge *nedge; /* new edge */
+ ScrArea *sarea; /* start area */
+ ScrArea *narea; /* new area */
+} sAreaSplitData;
+
+/* generic init, no UI stuff here */
+static int area_split_init(bContext *C, wmOperator *op)
+{
+ sAreaSplitData *sd;
+ int dir;
+
+ /* required context */
+ if(C->area==NULL) return 0;
+
+ /* required properties */
+ OP_verify_float(op, "fac", 0.5f, NULL);
+ OP_verify_int(op, "dir", 'h', &dir);
+
+ /* minimal size */
+ if(dir=='v' && C->area->winx < 2*AREAMINX) return 0;
+ if(dir=='h' && C->area->winy < 2*AREAMINY) return 0;
+
+ /* custom data */
+ sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_area_split");
+ op->customdata= sd;
+
+ sd->sarea= C->area;
+
+ return 1;
+}
+
+/* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */
+/* used with split operator */
+static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
+{
+ ScrVert *sav1= sa->v1;
+ ScrVert *sav2= sa->v2;
+ ScrVert *sav3= sa->v3;
+ ScrVert *sav4= sa->v4;
+ ScrVert *sbv1= sb->v1;
+ ScrVert *sbv2= sb->v2;
+ ScrVert *sbv3= sb->v3;
+ ScrVert *sbv4= sb->v4;
+
+ if(sav1==sbv4 && sav2==sbv3) { /* sa to right of sb = W */
+ return screen_findedge(screen, sav1, sav2);
+ }
+ else if(sav2==sbv1 && sav3==sbv4) { /* sa to bottom of sb = N */
+ return screen_findedge(screen, sav2, sav3);
+ }
+ else if(sav3==sbv2 && sav4==sbv1) { /* sa to left of sb = E */
+ return screen_findedge(screen, sav3, sav4);
+ }
+ else if(sav1==sbv2 && sav4==sbv3) { /* sa on top of sb = S*/
+ return screen_findedge(screen, sav1, sav4);
+ }
+
+ return NULL;
+}
+
+
+/* do the split */
+static void area_split_apply(bContext *C, wmOperator *op)
+{
+ sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
+ float fac;
+ int dir;
+
+ OP_get_float(op, "fac", &fac);
+ OP_get_int(op, "dir", &dir);
+
+ sd->narea= area_split(C->window, C->screen, sd->sarea, dir, fac);
+
+ if(sd->narea) {
+ ScrVert *sv;
+
+ sd->nedge= area_findsharededge(C->screen, sd->sarea, sd->narea);
+
+ /* select newly created edge, prepare for moving edge */
+ for(sv= C->screen->vertbase.first; sv; sv= sv->next)
+ sv->flag = 0;
+
+ sd->nedge->v1->flag= 1;
+ sd->nedge->v2->flag= 1;
+
+ if(dir=='h') sd->origval= sd->nedge->v1->vec.y;
+ else sd->origval= sd->nedge->v1->vec.x;
+
+ }
+
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+
+}
+
+static void area_split_exit(bContext *C, wmOperator *op)
+{
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
+
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+
+ /* this makes sure aligned edges will result in aligned grabbing */
+ removedouble_scrverts(C->screen);
+ removedouble_scredges(C->screen);
+}
+
+
+/* UI callback, adds new handler */
+static int area_split_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ sAreaSplitData *sd;
+
+ if(event->type==EVT_ACTIONZONE) {
+ sActionzoneData *sad= event->customdata;
+ int dir;
+
+ /* verify *sad itself */
+ if(sad==NULL || sad->sa1==NULL || sad->az==NULL)
+ return OPERATOR_PASS_THROUGH;
+
+ /* is this our *sad? if areas not equal it should be passed on */
+ if(C->area!=sad->sa1 || sad->sa1!=sad->sa2)
+ return OPERATOR_PASS_THROUGH;
+
+ /* prepare operator state vars */
+ if(sad->gesture_dir==AZONE_N || sad->gesture_dir==AZONE_S) {
+ dir= 'h';
+ OP_set_float(op, "fac", ((float)(event->x - sad->sa1->v1->vec.x)) / (float)sad->sa1->winx);
+ }
+ else {
+ dir= 'v';
+ OP_set_float(op, "fac", ((float)(event->y - sad->sa1->v1->vec.y)) / (float)sad->sa1->winy);
+ }
+ OP_set_int(op, "dir", dir);
+
+ /* general init, also non-UI case, adds customdata, sets area and defaults */
+ if(!area_split_init(C, op))
+ return OPERATOR_PASS_THROUGH;
+
+ sd= (sAreaSplitData *)op->customdata;
+
+ sd->x= event->x;
+ sd->y= event->y;
+
+ /* do the split */
+ area_split_apply(C, op);
+ area_move_set_limits(C->screen, dir, &sd->bigger, &sd->smaller);
+
+ /* add temp handler for edge move or cancel */
+ WM_event_add_modal_handler(&C->window->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+
+ }
+ return OPERATOR_PASS_THROUGH;
+}
+
+/* function to be called outside UI context, or for redo */
+static int area_split_exec(bContext *C, wmOperator *op)
+{
+
+ if(!area_split_init(C, op))
+ return OPERATOR_CANCELLED;
+
+ area_split_apply(C, op);
+ area_split_exit(C, op);
+
+ return OPERATOR_FINISHED;
+}
+
+
+static int area_split_cancel(bContext *C, wmOperator *op)
+{
+ sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
+
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+
+ if (screen_area_join(C->screen,sd->sarea, sd->narea)) {
+ if (C->area == sd->narea) {
+ C->area = NULL;
+ }
+ sd->narea = NULL;
+ }
+ area_split_exit(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
+static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
+ int dir;
+
+ /* execute the events */
+ switch(event->type) {
+ case MOUSEMOVE:
+
+ OP_get_int(op, "dir", &dir);
+
+ sd->delta= (dir == 'v')? event->x - sd->origval: event->y - sd->origval;
+ area_move_apply_do(C, sd->origval, sd->delta, dir, sd->bigger, sd->smaller);
+
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+ break;
+
+ case LEFTMOUSE:
+ if(event->val==0) { /* mouse up */
+ area_split_exit(C, op);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ case RIGHTMOUSE: /* cancel operation */
+ case ESCKEY:
+ return area_split_cancel(C, op);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void ED_SCR_OT_area_split(wmOperatorType *ot)
+{
+ ot->name = "Split area";
+ ot->idname = "ED_SCR_OT_area_split";
+
+ ot->exec= area_split_exec;
+ ot->invoke= area_split_invoke;
+ ot->modal= area_split_modal;
+
+ ot->poll= ED_operator_screenactive; /* XXX should be area active */
+}
+
+/* ************** join area operator ********************************************** */
+
+/* operator state vars used:
+ x1, y1 mouse coord in first area, which will disappear
+ x2, y2 mouse coord in 2nd area, which will become joined
+
+functions:
+
+ init() find edge based on state vars
+ test if the edge divides two areas,
+ store active and nonactive area,
+
+ apply() do the actual join
+
+ exit() cleanup, send notifier
+
+callbacks:
+
+ exec() calls init, apply, exit
+
+ invoke() sets mouse coords in x,y
+ call init()
+ add modal handler
+
+ modal() accept modal events while doing it
+ call apply() with active window and nonactive window
+ call exit() and remove handler when LMB confirm
+
+*/
+
+typedef struct sAreaJoinData
+{
+ ScrArea *sa1; /* first area to be considered */
+ ScrArea *sa2; /* second area to be considered */
+ ScrArea *scr; /* designed for removal */
+
+} sAreaJoinData;
+
+
+/* validate selection inside screen, set variables OK */
+/* return 0: init failed */
+/* XXX todo: find edge based on (x,y) and set other area? */
+static int area_join_init(bContext *C, wmOperator *op)
+{
+ ScrArea *sa1, *sa2;
+ sAreaJoinData* jd= NULL;
+ int x1, y1;
+ int x2, y2;
+
+ /* required properties, make negative to get return 0 if not set by caller */
+ OP_verify_int(op, "x1", -100, &x1);
+ OP_verify_int(op, "y1", -100, &y1);
+ OP_verify_int(op, "x2", -100, &x2);
+ OP_verify_int(op, "y2", -100, &y2);
+
+ sa1 = screen_areahascursor(C->screen, x1, y1);
+ sa2 = screen_areahascursor(C->screen, x2, y2);
+ if(sa1==NULL || sa2==NULL || sa1==sa2)
+ return 0;
+
+ jd = (sAreaJoinData*)MEM_callocN(sizeof (sAreaJoinData), "op_area_join");
+
+ jd->sa1 = sa1;
+ jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
+ jd->sa2 = sa2;
+ jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
+
+ op->customdata= jd;
+
+ return 1;
+}
+
+/* apply the join of the areas (space types) */
+static int area_join_apply(bContext *C, wmOperator *op)
+{
+ sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
+ if (!jd) return 0;
+
+ if(!screen_area_join(C->screen,jd->sa1,jd->sa2)){
+ return 0;
+ }
+ if (C->area == jd->sa2) {
+ C->area = NULL;
+ }
+
+ return 1;
+}
+
+/* finish operation */
+static void area_join_exit(bContext *C, wmOperator *op)
+{
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
+
+ /* this makes sure aligned edges will result in aligned grabbing */
+ removedouble_scredges(C->screen);
+ removenotused_scredges(C->screen);
+ removenotused_scrverts(C->screen);
+}
+
+static int area_join_exec(bContext *C, wmOperator *op)
+{
+ if(!area_join_init(C, op))
+ return OPERATOR_CANCELLED;
+
+ area_join_apply(C, op);
+ area_join_exit(C, op);
+
+ return OPERATOR_FINISHED;
+}
+
+/* interaction callback */
+static int area_join_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+
+ if(event->type==EVT_ACTIONZONE) {
+ sActionzoneData *sad= event->customdata;
+
+ /* verify *sad itself */
+ if(sad==NULL || sad->sa1==NULL || sad->sa2==NULL)
+ return OPERATOR_PASS_THROUGH;
+
+ /* is this our *sad? if areas equal it should be passed on */
+ if(sad->sa1==sad->sa2)
+ return OPERATOR_PASS_THROUGH;
+
+ /* prepare operator state vars */
+ OP_set_int(op, "x1", sad->x);
+ OP_set_int(op, "y1", sad->y);
+ OP_set_int(op, "x2", event->x);
+ OP_set_int(op, "y2", event->y);
+
+ if(!area_join_init(C, op))
+ return OPERATOR_PASS_THROUGH;
+
+ /* add temp handler */
+ WM_event_add_modal_handler(&C->window->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ return OPERATOR_PASS_THROUGH;
+}
+
+static int area_join_cancel(bContext *C, wmOperator *op)
+{
+ sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
+
+ if (jd->sa1) {
+ jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
+ jd->sa1->flag &= ~AREA_FLAG_DRAWJOINTO;
+ }
+ if (jd->sa2) {
+ jd->sa2->flag &= ~AREA_FLAG_DRAWJOINFROM;
+ jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+ }
+
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+
+ area_join_exit(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
+/* modal callback while selecting area (space) that will be removed */
+static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
+
+ /* execute the events */
+ switch(event->type) {
+
+ case MOUSEMOVE:
+ {
+ ScrArea *sa = screen_areahascursor(C->screen, event->x, event->y);
+ int dir;
+
+ if (sa) {
+ if (jd->sa1 != sa) {
+ dir = area_getorientation(C->screen, jd->sa1, sa);
+ if (dir >= 0) {
+ if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+ jd->sa2 = sa;
+ jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
+ }
+ else {
+ /* we are not bordering on the previously selected area
+ we check if area has common border with the one marked for removal
+ in this case we can swap areas.
+ */
+ dir = area_getorientation(C->screen, sa, jd->sa2);
+ if (dir >= 0) {
+ if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
+ if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+ jd->sa1 = jd->sa2;
+ jd->sa2 = sa;
+ if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
+ if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
+ }
+ else {
+ if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+ jd->sa2 = NULL;
+ }
+ }
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
+ }
+ else {
+ /* we are back in the area previously selected for keeping
+ * we swap the areas if possible to allow user to choose */
+ if (jd->sa2 != NULL) {
+ if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
+ if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+ jd->sa1 = jd->sa2;
+ jd->sa2 = sa;
+ if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
+ if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
+ dir = area_getorientation(C->screen, jd->sa1, jd->sa2);
+ if (dir < 0) {
+ printf("oops, didn't expect that!\n");
+ }
+ }
+ else {
+ dir = area_getorientation(C->screen, jd->sa1, sa);
+ if (dir >= 0) {
+ if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+ jd->sa2 = sa;
+ jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
+ }
+ }
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
+ }
+ }
+ }
+ break;
+ case LEFTMOUSE:
+ if(event->val==0) {
+ area_join_apply(C, op);
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+ area_join_exit(C, op);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ return OPERATOR_FINISHED;
+ }
+ break;
+
+ case ESCKEY:
+ return area_join_cancel(C, op);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Operator for joining two areas (space types) */
+void ED_SCR_OT_area_join(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Join area";
+ ot->idname= "ED_SCR_OT_area_join";
+
+ /* api callbacks */
+ ot->exec= area_join_exec;
+ ot->invoke= area_join_invoke;
+ ot->modal= area_join_modal;
+
+ ot->poll= ED_operator_screenactive;
+}
+
+/* ************** border select operator (test only) ***************************** */
+
+/* operator state vars used: (added by default WM callbacks)
+ xmin, ymin
+ xmax, ymax
+
+ customdata: the wmGesture pointer
+
+callbacks:
+
+ exec() has to be filled in by user
+
+ invoke() default WM function
+ adds modal handler
+
+ modal() default WM function
+ accept modal events while doing it, calls exec(), handles ESC and border drawing
+
+ poll() has to be filled in by user for context
+*/
+
+static int border_select_do(bContext *C, wmOperator *op)
+{
+ printf("border select do\n");
+ return 1;
+}
+
+void ED_SCR_OT_border_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Border select";
+ ot->idname= "ED_SCR_OT_border_select";
+
+ /* api callbacks */
+ ot->exec= border_select_do;
+ ot->invoke= WM_border_select_invoke;
+ ot->modal= WM_border_select_modal;
+
+ ot->poll= ED_operator_areaactive;
+}
+
+
+/* **************** Assigning operatortypes to global list, adding handlers **************** */
+
/* called in spacetypes.c */
void ED_operatortypes_screen(void)
{
@@ -87,9 +1227,9 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(ED_SCR_OT_actionzone);
/* tools */
- WM_operatortype_append(ED_SCR_OT_move_areas);
- WM_operatortype_append(ED_SCR_OT_split_area);
- WM_operatortype_append(ED_SCR_OT_join_areas);
+ WM_operatortype_append(ED_SCR_OT_area_move);
+ WM_operatortype_append(ED_SCR_OT_area_split);
+ WM_operatortype_append(ED_SCR_OT_area_join);
WM_operatortype_append(ED_SCR_OT_area_rip);
/* for test only */
@@ -102,9 +1242,9 @@ void ED_keymap_screen(wmWindowManager *wm)
WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_cursor_type", MOUSEMOVE, 0, 0, 0);
WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_move_areas", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_split_area", EVT_ACTIONZONE, 0, 0, 0); /* action tria */
- WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_join_areas", EVT_ACTIONZONE, 0, 0, 0); /* action tria */
+ WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_split", EVT_ACTIONZONE, 0, 0, 0); /* action tria */
+ WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_join", EVT_ACTIONZONE, 0, 0, 0); /* action tria */
WM_keymap_verify_item(&wm->windowkeymap, "ED_SCR_OT_area_rip", RKEY, KM_PRESS, KM_ALT, 0);
/* for test only */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 86e6fe77c73..b81184df049 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -139,23 +139,23 @@ int WM_border_select_modal (struct bContext *C, wmOperator *op, struct wmEvent
* len= 4; <---- set the size!!
* OP_get_int_array (op, "vector", vec, &len);
*/
-void OP_set_int(wmOperator *op, char *name, int value);
-void OP_set_float(wmOperator *op, char *name, float value);
-void OP_set_string(wmOperator *op, char *name, char *str);
-void OP_set_int_array(wmOperator *op, char *name, int *array, short len);
-void OP_set_float_array(wmOperator *op, char *name, float *array, short len);
-
-int OP_get_int(wmOperator *op, char *name, int *value);
-int OP_get_float(wmOperator *op, char *name, float *value);
-char *OP_get_string(wmOperator *op, char *name);
-int OP_get_int_array(wmOperator *op, char *name, int *array, short *len);
-int OP_get_float_array(wmOperator *op, char *name, float *array, short *len);
-
-void OP_verify_int(wmOperator *op, char *name, int value, int *result);
-void OP_verify_float(wmOperator *op, char *name, float value, int *result);
-char *OP_verify_string(wmOperator *op, char *name, char *str);
-void OP_verify_int_array(wmOperator *op, char *name, int *array, short len, int *resultarray, short *resultlen);
-void OP_verify_float_array(wmOperator *op, char *name, float *array, short len, float *resultarray, short *resultlen);
+void OP_set_int (wmOperator *op, char *name, int value);
+void OP_set_float (wmOperator *op, char *name, float value);
+void OP_set_string (wmOperator *op, char *name, char *str);
+void OP_set_int_array(wmOperator *op, char *name, int *array, short len);
+void OP_set_float_array(wmOperator *op, char *name, float *array, short len);
+
+int OP_get_int (wmOperator *op, char *name, int *value);
+int OP_get_float (wmOperator *op, char *name, float *value);
+char *OP_get_string (wmOperator *op, char *name);
+int OP_get_int_array(wmOperator *op, char *name, int *array, short *len);
+int OP_get_float_array(wmOperator *op, char *name, float *array, short *len);
+
+void OP_verify_int (wmOperator *op, char *name, int value, int *result);
+void OP_verify_float (wmOperator *op, char *name, float value, int *result);
+char *OP_verify_string(wmOperator *op, char *name, char *str);
+void OP_verify_int_array(wmOperator *op, char *name, int *array, short len, int *resultarray, short *resultlen);
+void OP_verify_float_array(wmOperator *op, char *name, float *array, short len, float *resultarray, short *resultlen);
/*
* Need call this function in the "exit callback"
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index cafc7a7b597..165ca88ab71 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -74,17 +74,6 @@ void wm_operator_register(wmWindowManager *wm, wmOperator *op)
}
}
-/* **************** standard keymap for WM ********************** */
-
-/* default keymap for windows and screens, only call once per WM */
-static void wm_window_keymap(wmWindowManager *wm)
-{
- /* note, this doesn't replace existing keymap items */
- WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, 0, 0);
- WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0);
- WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0);
-}
/* ****************************************** */
diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c
new file mode 100644
index 00000000000..9ba350fbb04
--- /dev/null
+++ b/source/blender/windowmanager/intern/wm_operator_props.c
@@ -0,0 +1,298 @@
+/**
+* $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 *****
+ */
+
+#include "DNA_ID.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_idprop.h"
+
+#include "WM_api.h"
+
+
+/* wrapped to get property from a operator. */
+static IDProperty *op_get_property(wmOperator *op, char *name)
+{
+ IDProperty *prop;
+
+ if(!op->properties)
+ return NULL;
+
+ prop= IDP_GetPropertyFromGroup(op->properties, name);
+ return prop;
+}
+
+/*
+ * We need create a "group" to store the operator properties.
+ * We don't have a WM_operator_new or some thing like that,
+ * so this function is called by all the OP_set_* function
+ * in case that op->properties is equal to NULL.
+ */
+static void op_init_property(wmOperator *op)
+{
+ IDPropertyTemplate val;
+ val.i = 0; /* silence MSVC warning about uninitialized var when debugging */
+ op->properties= IDP_New(IDP_GROUP, val, "property");
+}
+
+/* ***** Property API, exported ***** */
+void OP_free_property(wmOperator *op)
+{
+ if(op->properties) {
+ IDP_FreeProperty(op->properties);
+ /*
+ * This need change, when the idprop code only
+ * need call IDP_FreeProperty. (check BKE_idprop.h)
+ */
+ MEM_freeN(op->properties);
+ op->properties= NULL;
+ }
+}
+
+void OP_set_int(wmOperator *op, char *name, int value)
+{
+ IDPropertyTemplate val;
+ IDProperty *prop;
+
+ if(!op->properties)
+ op_init_property(op);
+
+ val.i= value;
+ prop= IDP_New(IDP_INT, val, name);
+ IDP_ReplaceInGroup(op->properties, prop);
+}
+
+void OP_set_float(wmOperator *op, char *name, float value)
+{
+ IDPropertyTemplate val;
+ IDProperty *prop;
+
+ if(!op->properties)
+ op_init_property(op);
+
+ val.f= value;
+ prop= IDP_New(IDP_FLOAT, val, name);
+ IDP_ReplaceInGroup(op->properties, prop);
+}
+
+void OP_set_int_array(wmOperator *op, char *name, int *array, short len)
+{
+ IDPropertyTemplate val;
+ IDProperty *prop;
+ short i;
+ int *pointer;
+
+ if(!op->properties)
+ op_init_property(op);
+
+ val.array.len= len;
+ val.array.type= IDP_INT;
+ prop= IDP_New(IDP_ARRAY, val, name);
+
+ pointer= (int *)prop->data.pointer;
+ for(i= 0; i < len; i++)
+ pointer[i]= array[i];
+ IDP_ReplaceInGroup(op->properties, prop);
+}
+
+void OP_set_float_array(wmOperator *op, char *name, float *array, short len)
+{
+ IDPropertyTemplate val;
+ IDProperty *prop;
+ short i;
+ float *pointer;
+
+ if(!op->properties)
+ op_init_property(op);
+
+ val.array.len= len;
+ val.array.type= IDP_FLOAT;
+ prop= IDP_New(IDP_ARRAY, val, name);
+
+ pointer= (float *) prop->data.pointer;
+ for(i= 0; i < len; i++)
+ pointer[i]= array[i];
+ IDP_ReplaceInGroup(op->properties, prop);
+}
+
+void OP_set_string(wmOperator *op, char *name, char *str)
+{
+ IDPropertyTemplate val;
+ IDProperty *prop;
+
+ if(!op->properties)
+ op_init_property(op);
+
+ val.str= str;
+ prop= IDP_New(IDP_STRING, val, name);
+ IDP_ReplaceInGroup(op->properties, prop);
+}
+
+int OP_get_int(wmOperator *op, char *name, int *value)
+{
+ IDProperty *prop= op_get_property(op, name);
+ int status= 0;
+
+ if ((prop) && (prop->type == IDP_INT)) {
+ (*value)= prop->data.val;
+ status= 1;
+ }
+ return (status);
+}
+
+int OP_get_float(wmOperator *op, char *name, float *value)
+{
+ IDProperty *prop= op_get_property(op, name);
+ int status= 0;
+
+ if ((prop) && (prop->type == IDP_FLOAT)) {
+ (*value)= *(float*)&prop->data.val;
+ status= 1;
+ }
+ return (status);
+}
+
+int OP_get_int_array(wmOperator *op, char *name, int *array, short *len)
+{
+ IDProperty *prop= op_get_property(op, name);
+ short i;
+ int status= 0;
+ int *pointer;
+
+ if ((prop) && (prop->type == IDP_ARRAY)) {
+ pointer= (int *) prop->data.pointer;
+
+ for(i= 0; (i < prop->len) && (i < *len); i++)
+ array[i]= pointer[i];
+
+ (*len)= i;
+ status= 1;
+ }
+ return (status);
+}
+
+int OP_get_float_array(wmOperator *op, char *name, float *array, short *len)
+{
+ IDProperty *prop= op_get_property(op, name);
+ short i;
+ float *pointer;
+ int status= 0;
+
+ if ((prop) && (prop->type == IDP_ARRAY)) {
+ pointer= (float *) prop->data.pointer;
+
+ for(i= 0; (i < prop->len) && (i < *len); i++)
+ array[i]= pointer[i];
+
+ (*len)= i;
+ status= 1;
+ }
+ return (status);
+}
+
+char *OP_get_string(wmOperator *op, char *name)
+{
+ IDProperty *prop= op_get_property(op, name);
+ if ((prop) && (prop->type == IDP_STRING))
+ return ((char *) prop->data.pointer);
+ return (NULL);
+}
+
+void OP_verify_int(wmOperator *op, char *name, int value, int *result)
+{
+ int rvalue;
+
+ if(OP_get_int(op, name, &rvalue))
+ value= rvalue;
+ else
+ OP_set_int(op, name, value);
+
+ if(result)
+ *result= value;
+}
+
+void OP_verify_float(wmOperator *op, char *name, float value, int *result)
+{
+ float rvalue;
+
+ if(OP_get_float(op, name, &rvalue))
+ value= rvalue;
+ else
+ OP_set_float(op, name, value);
+
+ if(result)
+ *result= value;
+}
+
+char *OP_verify_string(wmOperator *op, char *name, char *str)
+{
+ char *result= OP_get_string(op, name);
+
+ if(!result) {
+ OP_set_string(op, name, str);
+ result= OP_get_string(op, name);
+ }
+
+ return result;
+}
+
+void OP_verify_int_array(wmOperator *op, char *name, int *array, short len, int *resultarray, short *resultlen)
+{
+ int rarray[1];
+ short rlen= 1;
+
+ if(resultarray && resultlen) {
+ if(!OP_get_int_array(op, name, resultarray, &rlen)) {
+ OP_set_int_array(op, name, array, len);
+ OP_get_int_array(op, name, resultarray, resultlen);
+ }
+ }
+ else {
+ if(!OP_get_int_array(op, name, rarray, &rlen))
+ OP_set_int_array(op, name, array, len);
+ }
+}
+
+void OP_verify_float_array(wmOperator *op, char *name, float *array, short len, float *resultarray, short *resultlen)
+{
+ float rarray[1];
+ short rlen= 1;
+
+ if(resultarray && resultlen) {
+ if(!OP_get_float_array(op, name, resultarray, &rlen)) {
+ OP_set_float_array(op, name, array, len);
+ OP_get_float_array(op, name, resultarray, resultlen);
+ }
+ }
+ else {
+ if(!OP_get_float_array(op, name, rarray, &rlen))
+ OP_set_float_array(op, name, array, len);
+ }
+}
+
+
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 32efa8eb71a..5374592180e 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -236,265 +236,13 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_exit_blender);
}
-/* ******************************************************* */
-
-/* wrapped to get property from a operator. */
-IDProperty *op_get_property(wmOperator *op, char *name)
-{
- IDProperty *prop;
-
- if(!op->properties)
- return NULL;
-
- prop= IDP_GetPropertyFromGroup(op->properties, name);
- return prop;
-}
-
-/*
- * We need create a "group" to store the operator properties.
- * We don't have a WM_operator_new or some thing like that,
- * so this function is called by all the OP_set_* function
- * in case that op->properties is equal to NULL.
- */
-void op_init_property(wmOperator *op)
-{
- IDPropertyTemplate val;
- val.i = 0; /* silence MSVC warning about uninitialized var when debugging */
- op->properties= IDP_New(IDP_GROUP, val, "property");
-}
-
-/* ***** Property API, exported ***** */
-void OP_free_property(wmOperator *op)
-{
- if(op->properties) {
- IDP_FreeProperty(op->properties);
- /*
- * This need change, when the idprop code only
- * need call IDP_FreeProperty. (check BKE_idprop.h)
- */
- MEM_freeN(op->properties);
- op->properties= NULL;
- }
-}
-
-void OP_set_int(wmOperator *op, char *name, int value)
-{
- IDPropertyTemplate val;
- IDProperty *prop;
-
- if(!op->properties)
- op_init_property(op);
-
- val.i= value;
- prop= IDP_New(IDP_INT, val, name);
- IDP_ReplaceInGroup(op->properties, prop);
-}
-
-void OP_set_float(wmOperator *op, char *name, float value)
-{
- IDPropertyTemplate val;
- IDProperty *prop;
-
- if(!op->properties)
- op_init_property(op);
-
- val.f= value;
- prop= IDP_New(IDP_FLOAT, val, name);
- IDP_ReplaceInGroup(op->properties, prop);
-}
-
-void OP_set_int_array(wmOperator *op, char *name, int *array, short len)
-{
- IDPropertyTemplate val;
- IDProperty *prop;
- short i;
- int *pointer;
-
- if(!op->properties)
- op_init_property(op);
-
- val.array.len= len;
- val.array.type= IDP_INT;
- prop= IDP_New(IDP_ARRAY, val, name);
-
- pointer= (int *)prop->data.pointer;
- for(i= 0; i < len; i++)
- pointer[i]= array[i];
- IDP_ReplaceInGroup(op->properties, prop);
-}
-
-void OP_set_float_array(wmOperator *op, char *name, float *array, short len)
-{
- IDPropertyTemplate val;
- IDProperty *prop;
- short i;
- float *pointer;
-
- if(!op->properties)
- op_init_property(op);
-
- val.array.len= len;
- val.array.type= IDP_FLOAT;
- prop= IDP_New(IDP_ARRAY, val, name);
-
- pointer= (float *) prop->data.pointer;
- for(i= 0; i < len; i++)
- pointer[i]= array[i];
- IDP_ReplaceInGroup(op->properties, prop);
-}
-
-void OP_set_string(wmOperator *op, char *name, char *str)
-{
- IDPropertyTemplate val;
- IDProperty *prop;
-
- if(!op->properties)
- op_init_property(op);
-
- val.str= str;
- prop= IDP_New(IDP_STRING, val, name);
- IDP_ReplaceInGroup(op->properties, prop);
-}
-
-int OP_get_int(wmOperator *op, char *name, int *value)
-{
- IDProperty *prop= op_get_property(op, name);
- int status= 0;
-
- if ((prop) && (prop->type == IDP_INT)) {
- (*value)= prop->data.val;
- status= 1;
- }
- return (status);
-}
-
-int OP_get_float(wmOperator *op, char *name, float *value)
-{
- IDProperty *prop= op_get_property(op, name);
- int status= 0;
-
- if ((prop) && (prop->type == IDP_FLOAT)) {
- (*value)= *(float*)&prop->data.val;
- status= 1;
- }
- return (status);
-}
-
-int OP_get_int_array(wmOperator *op, char *name, int *array, short *len)
-{
- IDProperty *prop= op_get_property(op, name);
- short i;
- int status= 0;
- int *pointer;
-
- if ((prop) && (prop->type == IDP_ARRAY)) {
- pointer= (int *) prop->data.pointer;
-
- for(i= 0; (i < prop->len) && (i < *len); i++)
- array[i]= pointer[i];
-
- (*len)= i;
- status= 1;
- }
- return (status);
-}
-
-int OP_get_float_array(wmOperator *op, char *name, float *array, short *len)
-{
- IDProperty *prop= op_get_property(op, name);
- short i;
- float *pointer;
- int status= 0;
-
- if ((prop) && (prop->type == IDP_ARRAY)) {
- pointer= (float *) prop->data.pointer;
-
- for(i= 0; (i < prop->len) && (i < *len); i++)
- array[i]= pointer[i];
-
- (*len)= i;
- status= 1;
- }
- return (status);
-}
-
-char *OP_get_string(wmOperator *op, char *name)
-{
- IDProperty *prop= op_get_property(op, name);
- if ((prop) && (prop->type == IDP_STRING))
- return ((char *) prop->data.pointer);
- return (NULL);
-}
-
-void OP_verify_int(wmOperator *op, char *name, int value, int *result)
-{
- int rvalue;
-
- if(OP_get_int(op, name, &rvalue))
- value= rvalue;
- else
- OP_set_int(op, name, value);
-
- if(result)
- *result= value;
-}
-
-void OP_verify_float(wmOperator *op, char *name, float value, int *result)
-{
- float rvalue;
-
- if(OP_get_float(op, name, &rvalue))
- value= rvalue;
- else
- OP_set_float(op, name, value);
-
- if(result)
- *result= value;
-}
-
-char *OP_verify_string(wmOperator *op, char *name, char *str)
-{
- char *result= OP_get_string(op, name);
-
- if(!result) {
- OP_set_string(op, name, str);
- result= OP_get_string(op, name);
- }
-
- return result;
-}
-
-void OP_verify_int_array(wmOperator *op, char *name, int *array, short len, int *resultarray, short *resultlen)
-{
- int rarray[1];
- short rlen= 1;
-
- if(resultarray && resultlen) {
- if(!OP_get_int_array(op, name, resultarray, &rlen)) {
- OP_set_int_array(op, name, array, len);
- OP_get_int_array(op, name, resultarray, resultlen);
- }
- }
- else {
- if(!OP_get_int_array(op, name, rarray, &rlen))
- OP_set_int_array(op, name, array, len);
- }
-}
-
-void OP_verify_float_array(wmOperator *op, char *name, float *array, short len, float *resultarray, short *resultlen)
-{
- float rarray[1];
- short rlen= 1;
-
- if(resultarray && resultlen) {
- if(!OP_get_float_array(op, name, resultarray, &rlen)) {
- OP_set_float_array(op, name, array, len);
- OP_get_float_array(op, name, resultarray, resultlen);
- }
- }
- else {
- if(!OP_get_float_array(op, name, rarray, &rlen))
- OP_set_float_array(op, name, array, len);
- }
+/* default keymap for windows and screens, only call once per WM */
+void wm_window_keymap(wmWindowManager *wm)
+{
+ /* note, this doesn't replace existing keymap items */
+ WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0);
}
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 4699374a612..ec9c56f6404 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -45,6 +45,7 @@ extern void wm_report_free(wmReport *report);
/* wm_operator.c, for init/exit */
void wm_operatortype_free(void);
void wm_operatortype_init(void);
+void wm_window_keymap(wmWindowManager *wm);
/* wm_gesture.c */
void wm_gesture_draw(struct wmWindow *win);