== Rip Area into new Window Operator ==
authorAndrea Weikert <elubie@gmx.net>
Thu, 19 Jun 2008 19:09:21 +0000 (19:09 +0000)
committerAndrea Weikert <elubie@gmx.net>
Thu, 19 Jun 2008 19:09:21 +0000 (19:09 +0000)
- operator that rips current area into new window
- implemented on the window level.
- sets C->area in current context if necessary
== fix ==
- small bugfix: missing return in WM_event_add_keymap_handler

source/blender/editors/include/ED_screen.h
source/blender/editors/screen/screen_edit.c
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm_window.h

index 0adac2c9657622785c7831ea02bf6d9b2adc401c..ac66e4420d9f6a5a9fa30ca21b194ddbcac292fa 100644 (file)
@@ -56,6 +56,7 @@ void  ED_screen_gesture(struct wmWindow *win);
 void   ED_screen_refresh(struct wmWindowManager *wm, struct wmWindow *win);
 void   ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, bScreen *sc);
+bScreen *ED_screen_riparea(struct wmWindow *win, bScreen *sc, struct ScrArea *sa);
 void   ED_screen_set_subwinactive(struct wmWindow *win);
 
 void   ED_operatortypes_screen(void);
index b1ec306ba6994b59f53c50b33422d4c548146415..7d827a5daade699763e005dab95c76f25a24b70f 100644 (file)
@@ -410,7 +410,12 @@ static void screen_delarea(bScreen *sc, ScrArea *sa)
        MEM_freeN(sa);
 }
 
-bScreen *addscreen(wmWindow *win, char *name)
+/* 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);
+
+static bScreen *addscreen_area(wmWindow *win, char *name, short headertype, short spacetype)
 {
        bScreen *sc;
        ScrVert *sv1, *sv2, *sv3, *sv4;
@@ -429,11 +434,15 @@ bScreen *addscreen(wmWindow *win, char *name)
        screen_addedge(sc, sv3, sv4);
        screen_addedge(sc, sv4, sv1);
        
-       screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_INFO);
+       screen_addarea(sc, sv1, sv2, sv3, sv4, headertype, spacetype);
                
        return sc;
 }
 
+static bScreen *addscreen(wmWindow *win, char *name) 
+{
+       return addscreen_area(win, name, HEADERDOWN, SPACE_INFO);
+}
 
 static void screen_copy(bScreen *to, bScreen *from)
 {
@@ -482,6 +491,34 @@ static void screen_copy(bScreen *to, bScreen *from)
 
 }
 
+bScreen *ED_screen_riparea(struct wmWindow *win, bScreen *sc, struct ScrArea *sa)
+{
+       bScreen *newsc=NULL;
+       ScrArea *newa;
+       ScrArea *tsa;
+
+       if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
+       
+       /* make new screen: */
+       newsc= addscreen_area(win, sc->id.name+2, sa->headertype, sa->spacetype);
+
+       /* new area is first (and only area) added to new win */
+       newa = (ScrArea *)newsc->areabase.first;
+       area_copy_data(newa, sa, 0);
+
+       /*remove the original area if possible*/
+       for(tsa= sc->areabase.first; tsa; tsa= tsa->next) {
+               if (screen_join_areas(sc,tsa,sa)) 
+                       break;
+       }
+
+       removedouble_scredges(sc);
+       removenotused_scredges(sc);
+       removenotused_scrverts(sc);
+
+       return newsc;
+}
+
 bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
 {
        bScreen *newsc;
@@ -665,6 +702,55 @@ static ScrArea* splitarea(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, flo
 }
 
 
+/* 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) 
+{
+       int dir;
+       
+       dir = area_getorientation(scr, sa1, sa2);
+       /*printf("dir is : %i \n", dir);*/
+       
+       if (dir < 0)
+       {
+               if (sa1 ) sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
+               if (sa2 ) sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+               return 0;
+       }
+       
+       if(dir == 0) {
+               sa1->v1= sa2->v1;
+               sa1->v2= sa2->v2;
+               screen_addedge(scr, sa1->v2, sa1->v3);
+               screen_addedge(scr, sa1->v1, sa1->v4);
+       }
+       else if(dir == 1) {
+               sa1->v2= sa2->v2;
+               sa1->v3= sa2->v3;
+               screen_addedge(scr, sa1->v1, sa1->v2);
+               screen_addedge(scr, sa1->v3, sa1->v4);
+       }
+       else if(dir == 2) {
+               sa1->v3= sa2->v3;
+               sa1->v4= sa2->v4;
+               screen_addedge(scr, sa1->v2, sa1->v3);
+               screen_addedge(scr, sa1->v1, sa1->v4);
+       }
+       else if(dir == 3) {
+               sa1->v1= sa2->v1;
+               sa1->v4= sa2->v4;
+               screen_addedge(scr, sa1->v1, sa1->v2);
+               screen_addedge(scr, sa1->v3, sa1->v4);
+       }
+       
+       screen_delarea(scr, sa2);
+       removedouble_scrverts(scr);
+       sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
+       
+       return 1;
+}
+
 /* *************************************************************** */
 
 /* test if screen vertices should be scaled */
@@ -1508,46 +1594,6 @@ static int split_area_invoke(bContext *C, wmOperator *op, wmEvent *event)
        return OPERATOR_RUNNING_MODAL;
 }
 
-/* join areas */
-static void split_joincurrent(bContext *C, sAreaSplitData *sd)
-{
-       int orientation= area_getorientation(C->window->screen, sd->sarea, sd->narea);
-       if(orientation>-1) {
-               if(orientation==0) {
-                       sd->sarea->v1= sd->narea->v1;
-                       sd->sarea->v2= sd->narea->v2;
-                       screen_addedge(C->screen, sd->sarea->v2, sd->sarea->v3);
-                       screen_addedge(C->screen, sd->sarea->v1, sd->sarea->v4);
-               }
-               else if(orientation==1) {
-                       sd->sarea->v2= sd->narea->v2;
-                       sd->sarea->v3= sd->narea->v3;
-                       screen_addedge(C->screen, sd->sarea->v1, sd->sarea->v2);
-                       screen_addedge(C->screen, sd->sarea->v3, sd->sarea->v4);
-               }
-               else if(orientation==2) {
-                       sd->sarea->v3= sd->narea->v3;
-                       sd->sarea->v4= sd->narea->v4;
-                       screen_addedge(C->screen, sd->sarea->v2,sd-> sarea->v3);
-                       screen_addedge(C->screen, sd->sarea->v1, sd->sarea->v4);
-               }
-               else if(orientation==3) {
-                       sd->sarea->v1= sd->narea->v1;
-                       sd->sarea->v4= sd->narea->v4;
-                       screen_addedge(C->screen, sd->sarea->v1, sd->sarea->v2);
-                       screen_addedge(C->screen, sd->sarea->v3, sd->sarea->v4);
-               }
-
-               if (C->area == sd->narea) {
-                       C->area = NULL;
-               }
-               screen_delarea(C->screen, sd->narea);
-               sd->narea = NULL;
-               removedouble_scrverts(C->screen);
-               removedouble_scredges(C->screen);
-       }
-}
-
 static int split_area_cancel(bContext *C, wmOperator *op)
 {
        sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
@@ -1555,7 +1601,12 @@ static int split_area_cancel(bContext *C, wmOperator *op)
        WM_event_remove_modal_handler(&C->window->handlers, op);
 
        OP_set_int(op, "delta", 0);
-       split_joincurrent(C, sd);
+       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;
@@ -1602,7 +1653,12 @@ static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
                                /* area containing cursor has changed */
                                if(sa && sd->sarea!=sa && sd->narea!=sa) {
                                        sold= sd->sarea;
-                                       split_joincurrent(C, sd);
+                                       if (screen_join_areas(C->screen,sd->sarea, sd->narea)) {
+                                               if (C->area == sd->narea) {
+                                                       C->area = NULL;
+                                               }
+                                               sd->narea = NULL;
+                                       }
 
                                        /* now find aedge with same orientation as sd->dir (inverted) */
                                        if(dir=='v') {
@@ -1734,47 +1790,12 @@ static int join_areas_apply(bContext *C, wmOperator *op)
        sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
        if (!jd) return 0;
 
-       jd->dir = area_getorientation(C->screen, jd->sa1, jd->sa2);
-       printf("dir is : %i \n", jd->dir);
-       if (jd->dir < 0)
-       {
-               if (jd->sa1 ) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
-               if (jd->sa2 ) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+       if(!screen_join_areas(C->screen,jd->sa1,jd->sa2)){
                return 0;
        }
-       
-       if(jd->dir == 0) {
-               jd->sa1->v1= jd->sa2->v1;
-               jd->sa1->v2= jd->sa2->v2;
-               screen_addedge(C->screen, jd->sa1->v2, jd->sa1->v3);
-               screen_addedge(C->screen, jd->sa1->v1, jd->sa1->v4);
-       }
-       else if(jd->dir == 1) {
-               jd->sa1->v2= jd->sa2->v2;
-               jd->sa1->v3= jd->sa2->v3;
-               screen_addedge(C->screen, jd->sa1->v1, jd->sa1->v2);
-               screen_addedge(C->screen, jd->sa1->v3, jd->sa1->v4);
-       }
-       else if(jd->dir == 2) {
-               jd->sa1->v3= jd->sa2->v3;
-               jd->sa1->v4= jd->sa2->v4;
-               screen_addedge(C->screen, jd->sa1->v2,jd-> sa1->v3);
-               screen_addedge(C->screen, jd->sa1->v1, jd->sa1->v4);
-       }
-       else if(jd->dir == 3) {
-               jd->sa1->v1= jd->sa2->v1;
-               jd->sa1->v4= jd->sa2->v4;
-               screen_addedge(C->screen, jd->sa1->v1, jd->sa1->v2);
-               screen_addedge(C->screen, jd->sa1->v3, jd->sa1->v4);
-       }
-
        if (C->area == jd->sa2) {
                C->area = NULL;
        }
-       screen_delarea(C->screen, jd->sa2);
-       jd->sa2 = NULL;
-
-       jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
 
        return 1;
 }
index d40fd75116274e464903f4256f626c0f28e867a1..9727aa0f4ca060c03b04b6325bc3b7dd0c937b2b 100644 (file)
@@ -80,6 +80,7 @@ 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_window_rip", RKEY, KM_PRESS, KM_ALT, 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);
index af61b78746231d9d0c8ebdd5f27c367d1799059c..c33ac0cd3422f39d4ab4579e92ec0585b9f122bb 100644 (file)
@@ -479,7 +479,7 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *handlers
        /* only allow same keymap once */
        for(handler= handlers->first; handler; handler= handler->next)
                if(handler->keymap==keymap)
-                       return;
+                       return handler;
 
        handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
        BLI_addtail(handlers, handler);
index 8b4a167365d19afb84fa7a64cf672bbb1beb42a7..3c7465e191230b1efee6e65247d2ccac6d1c03ef 100644 (file)
@@ -98,6 +98,16 @@ static void WM_OT_window_duplicate(wmOperatorType *ot)
        ot->poll= WM_operator_winactive;
 }
 
+static void WM_OT_window_rip(wmOperatorType *ot)
+{
+       ot->name= "Rip Area into New Window";
+       ot->idname= "WM_OT_window_rip";
+       
+       ot->invoke= wm_window_rip_op; //WM_operator_confirm;
+       ot->exec= NULL;
+       ot->poll= WM_operator_winactive;
+}
+
 static void WM_OT_save_homefile(wmOperatorType *ot)
 {
        ot->name= "Save User Settings";
@@ -256,6 +266,7 @@ void wm_operatortype_free(void)
 void wm_operatortype_init(void)
 {
        WM_operatortype_append(WM_OT_window_duplicate);
+       WM_operatortype_append(WM_OT_window_rip);
        WM_operatortype_append(WM_OT_save_homefile);
        WM_operatortype_append(WM_OT_window_fullscreen_toggle);
        WM_operatortype_append(WM_OT_exit_blender);
@@ -291,13 +302,13 @@ void op_init_property(wmOperator *op)
 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;
+       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;
        }
 }
 
index dd481cef1c01012896b82a9eb50b86d09e00c154..9425dd6cf58d4c17cfc22be07f8d2518220b35a9 100644 (file)
@@ -167,6 +167,45 @@ int wm_window_duplicate_op(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
+wmWindow *wm_window_rip(bContext *C, wmWindow *winorig)
+{
+       wmWindow *win= wm_window_new(C, winorig->screen);
+       
+       win->posx= winorig->posx+10;
+       win->posy= winorig->posy;
+       win->sizex= C->area->winx;
+       win->sizey= C->area->winy;
+       
+       win->screen= ED_screen_riparea(win, win->screen, C->area);
+       C->area = NULL; /* is removed */
+       win->screen->do_refresh= 1;
+       win->screen->do_draw= 1;
+       
+       return win;
+}
+/* operator callback */
+int wm_window_rip_op(bContext *C, wmOperator *op, wmEvent *event)
+{
+       /* need to make sure area is set in the current context */
+       if (!C->area) {
+               ScrArea *sa= C->window->screen->areabase.first;
+               for(; sa; sa= sa->next) {
+                       if(BLI_in_rcti(&sa->totrct, event->x, event->y)) {
+                               C->area = sa;
+                               break;
+                       }
+               }
+               if(C->area==NULL)
+                       return OPERATOR_CANCELLED;
+       }
+
+       wm_window_rip(C, C->window);
+       wm_check(C);
+       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
+       return OPERATOR_FINISHED;
+}
+
+
 /* fullscreen operator callback */
 int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op)
 {
index a9953725d8040431031cb5819d6f45dfd081486a..df77bdc0082fac3b087c4c5494961aa091cf3197 100644 (file)
@@ -50,9 +50,11 @@ void         wm_window_set_title             (wmWindow *win, char *title);
 void           wm_window_swap_buffers  (wmWindow *win);
 
 wmWindow       *wm_window_copy                 (bContext *C, wmWindow *winorig);
+wmWindow       *wm_window_rip                  (bContext *C, wmWindow *winorig);
 
 /* *************** window operators ************** */
 int                    wm_window_duplicate_op  (bContext *C, wmOperator *op);
+int                    wm_window_rip_op        (bContext *C, wmOperator *op, struct wmEvent *event);
 int                    wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op);
 int                    wm_exit_blender_op(bContext *C, wmOperator *op);