[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13252] branches/blender2.5/blender/source /blender: Operators: Join Areas
Andrea Weikert
elubie at gmx.net
Tue Jan 15 21:42:00 CET 2008
Revision: 13252
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13252
Author: elubie
Date: 2008-01-15 21:42:00 +0100 (Tue, 15 Jan 2008)
Log Message:
-----------
Operators: Join Areas
add split area to screen manager
- RMB+ALT down on area edge activates
- mouse move interactively to area that is to be removed
- LMB to confirm, ESC to cancel
TODO:
- notifications for interactive drawing to mark area to remove
Some fixes
- uninitialized var warning.
- exit function of operators need to run before modal handler is removed if operator is used there.
- replaced MEM_mallocN with MEM_callocN to get rid of uninitialized mem for wmOperator.
- respect return value of wm_handler_operator_call() and break out of operator handling.
Modified Paths:
--------------
branches/blender2.5/blender/source/blender/editors/screen/screen_edit.c
branches/blender2.5/blender/source/blender/editors/screen/screen_intern.h
branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c
branches/blender2.5/blender/source/blender/windowmanager/intern/wm.c
branches/blender2.5/blender/source/blender/windowmanager/intern/wm_event_system.c
branches/blender2.5/blender/source/blender/windowmanager/intern/wm_operators.c
Modified: branches/blender2.5/blender/source/blender/editors/screen/screen_edit.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/screen/screen_edit.c 2008-01-15 20:40:52 UTC (rev 13251)
+++ branches/blender2.5/blender/source/blender/editors/screen/screen_edit.c 2008-01-15 20:42:00 UTC (rev 13252)
@@ -972,6 +972,7 @@
{
/* operator arguments and storage */
+ op->properties = NULL;
op->delta= 0;
op->veci.x= event->x;
op->veci.y= event->y;
@@ -1011,8 +1012,8 @@
case LEFTMOUSE:
if(event->val==0) {
- WM_event_remove_modal_handler(&C->window->handlers, op);
move_areas_exit(C, op);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
}
break;
@@ -1119,18 +1120,18 @@
sd->max= sd->aedge->v2->vec.x;
}
- sd->narea= splitarea(C->window, C->screen, sd->sarea, sd->dir, fac);
-
- if(sd->narea==NULL) return 0;
+ sd->narea= splitarea(C->window, C->screen, sd->sarea, sd->dir, fac);
+ if(sd->narea==NULL) return 0;
+
sd->nedge= area_findsharededge(C->screen, sd->sarea, sd->narea);
printf("split_area_init\n");
/* get newly created edge and select it */
- select_connected_scredge(C->screen, sd->nedge);
-
+ select_connected_scredge(C->screen, sd->nedge);
+
WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0);
-
+
return 1;
}
@@ -1155,6 +1156,7 @@
static int split_area_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
/* operator arguments and storage */
+ op->customdata= NULL;
op->delta= 0;
op->veci.x= event->x;
op->veci.y= event->y;
@@ -1255,8 +1257,8 @@
case RIGHTMOUSE:
if(event->val==0) { /* mouse up */
+ split_area_exit(C, op);
WM_event_remove_modal_handler(&C->window->handlers, op);
- split_area_exit(C, op);
}
break;
@@ -1286,3 +1288,267 @@
ot->poll= ED_operator_screenactive;
//ot->poll= ED_operator_screen_mainwinactive;
}
+
+/* ************** join area operator ********************************************** */
+
+/* operator state vars used:
+ op->veci mouse coord near edge
+ op->delta movement of edge
+
+ callbacks:
+
+ init() find edge based on op->veci,
+ test if the edge divides two areas,
+ store active and nonactive area,
+
+
+ exec() remove active window,
+ recalc size,
+ make nonactive window active,
+ add notifier for redraw.
+
+ invoke() handler gets called on Alt+RMB near edge
+ call init()
+ add handler
+
+ modal() accept modal events while doing it
+ call exec() with active window and nonactive window
+ call exit() and remove handler when LMB confirm
+
+ exit() cleanup, send notifier
+
+*/
+
+typedef struct sAreaJoinData
+{
+ int dir;
+ ScrArea *up;
+ ScrArea *down;
+ ScrArea *left;
+ ScrArea *right;
+ 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 */
+static int join_areas_init (bContext *C, wmOperator *op)
+{
+ ScrEdge *actedge= screen_find_active_scredge(C->screen, op->veci.x, op->veci.y);
+ ScrArea *sa = C->curarea;
+ ScrEdge *se;
+ sAreaJoinData* jd= NULL;
+ short val = 0;
+
+ if(actedge==NULL) return 0;
+
+ jd = (sAreaJoinData*)MEM_callocN(sizeof (sAreaJoinData), "op_join_areas");
+ jd->dir= scredge_is_horizontal(actedge) ? 'h':'v';
+ op->customdata = jd;
+
+ select_connected_scredge(C->screen, actedge);
+
+ jd->sa1 = screen_test_edge_area(C->screen, sa, actedge);
+ if(jd->sa1==0) return 0;
+
+ /* find directions with same edge */
+ jd->sa2= C->screen->areabase.first;
+ while(jd->sa2) {
+ if(jd->sa2 != jd->sa1) {
+ se= screen_findedge(C->screen, jd->sa2->v1, jd->sa2->v2);
+ if(actedge==se) jd->right= jd->sa2;
+ se= screen_findedge(C->screen, jd->sa2->v2, jd->sa2->v3);
+ if(actedge==se) jd->down= jd->sa2;
+ se= screen_findedge(C->screen, jd->sa2->v3, jd->sa2->v4);
+ if(actedge==se) jd->left= jd->sa2;
+ se= screen_findedge(C->screen, jd->sa2->v4, jd->sa2->v1);
+ if(actedge==se) jd->up= jd->sa2;
+ }
+ jd->sa2= jd->sa2->next;
+ }
+
+ if(jd->left) val++;
+ if(jd->up) val++;
+ if(jd->right) val++;
+ if(jd->down) val++;
+
+ if(val==0) return 0;
+ else if(val==1) {
+ if(jd->left) {
+ jd->right = jd->sa1;
+ jd->sa2 = jd->left;
+ jd->dir = 'h';
+ }
+ else if(jd->right) {
+ jd->left = jd->sa1;
+ jd->sa2 = jd->right;
+ jd->dir = 'h';
+ }
+ else if(jd->up) {
+ jd->down = jd->sa1;
+ jd->sa2= jd->up;
+ jd->dir = 'v';
+ }
+ else if(jd->down) {
+ jd->up = jd->sa1;
+ jd->sa2 = jd->down;
+ jd->dir = 'v';
+ }
+ }
+
+ /* initial set up screen area asigned for destroying */
+ jd->scr = jd->sa2;
+
+ return 1;
+}
+
+/* apply the join of the areas (space types) */
+static int join_areas_exec(bContext *C, wmOperator *op)
+{
+ sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
+ if (!jd) return 0;
+
+ if(jd->sa2!=jd->scr) {
+ jd->sa1 = jd->sa2;
+ jd->sa2 = jd->scr;
+ }
+
+ if(jd->sa2==jd->left) {
+ 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->sa2==jd->up) {
+ 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->sa2==jd->right) {
+ 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->sa2==jd->down) {
+ 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->curarea == jd->sa2) {
+ C->curarea = NULL;
+ }
+ screen_delarea(C->screen, jd->sa2);
+ jd->sa2 = NULL;
+ return 1;
+}
+
+/* interaction callback */
+/* return 0 = stop evaluating for next handlers */
+static int join_areas_invoke (bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* operator arguments and storage */
+ op->delta= 0;
+ op->veci.x= event->x;
+ op->veci.y= event->y;
+ op->customdata = NULL;
+
+ if(0==join_areas_init(C, op))
+ return 1;
+
+ /* add temp handler */
+ WM_event_add_modal_handler(&C->window->handlers, op);
+
+ return 0;
+}
+
+static int is_inside_area(ScrArea *ar, short x, short y)
+{
+ int is_inside = 0;
+ if ( (ar->v1->vec.x < x) && (x < ar->v3->vec.x) ) {
+ if ( (y<ar->v3->vec.y) && (ar->v1->vec.y<y) ) {
+ is_inside = 1;
+ }
+ }
+ return is_inside;
+}
+
+
+/* finish operation */
+static int 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);
+
+ return 1;
+}
+
+/* modal callback while selecting area (space) that will be removed */
+/* return 0 = stop evaluating for next handlers */
+static int join_areas_modal (bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* execute the events */
+ switch(event->type) {
+
+ case MOUSEMOVE:
+ {
+ sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
+ ScrArea *sa = screen_areahascursor(C->screen, event->x, event->y);
+ if (sa && sa != jd->sa2) {
+ if (sa == jd->sa1) {
+ jd->scr = jd->sa1;
+ jd->sa1 = jd->sa2;
+ jd->sa2 = jd->scr;
+ printf("Changed area\n");
+ }
+ }
+ break;
+ }
+ case LEFTMOUSE:
+ if(event->val==0) {
+ join_areas_exec(C, op);
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0);
+ join_areas_exit(C, op);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ }
+ break;
+
+ case ESCKEY:
+ op->delta= 0;
+ join_areas_exit(C, op);
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ break;
+ }
+ return 1;
+}
+
+/* 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->init= join_areas_init;
+ ot->invoke= join_areas_invoke;
+ ot->modal= join_areas_modal;
+ ot->exec= join_areas_exec;
+ ot->exit= join_areas_exit;
+
+ ot->poll= ED_operator_screen_mainwinactive;
+}
+
Modified: branches/blender2.5/blender/source/blender/editors/screen/screen_intern.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/screen/screen_intern.h 2008-01-15 20:40:52 UTC (rev 13251)
+++ branches/blender2.5/blender/source/blender/editors/screen/screen_intern.h 2008-01-15 20:42:00 UTC (rev 13252)
@@ -41,8 +41,8 @@
void ED_SCR_OT_move_areas(wmOperatorType *ot);
void ED_SCR_OT_split_area(wmOperatorType *ot);
+void ED_SCR_OT_join_areas(wmOperatorType *ot);
-
#endif /* ED_SCREEN_INTERN_H */
Modified: branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c 2008-01-15 20:40:52 UTC (rev 13251)
+++ branches/blender2.5/blender/source/blender/editors/screen/screen_ops.c 2008-01-15 20:42:00 UTC (rev 13252)
@@ -87,6 +87,7 @@
ADD_OPTYPE( ED_SCR_OT_move_areas );
ADD_OPTYPE( ED_SCR_OT_cursor_type );
ADD_OPTYPE( ED_SCR_OT_split_area );
+ ADD_OPTYPE( ED_SCR_OT_join_areas );
WM_operatortypelist_append(&local_ops);
}
@@ -97,6 +98,7 @@
WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_cursor_type", MOUSEMOVE, 0, 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", RIGHTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_join_areas", RIGHTMOUSE, KM_PRESS, KM_ALT, 0);
}
Modified: branches/blender2.5/blender/source/blender/windowmanager/intern/wm.c
===================================================================
--- branches/blender2.5/blender/source/blender/windowmanager/intern/wm.c 2008-01-15 20:40:52 UTC (rev 13251)
+++ branches/blender2.5/blender/source/blender/windowmanager/intern/wm.c 2008-01-15 20:42:00 UTC (rev 13252)
@@ -53,7 +53,7 @@
/* called on event handling by event_system.c */
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list