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-01-10 20:38:17 +0300
committerTon Roosendaal <ton@blender.org>2008-01-10 20:38:17 +0300
commit43cf3af8c07a534f06b14a003eef2fc65c3c937b (patch)
tree9a93be5e2e3b4abb969ce751f0b8aa7d4948d7f8 /source/blender/editors/screen
parentb81b6be18458462939aefbb260ca6a68020131d4 (diff)
Blender 2.5 project: added first more complex handler + operator
- on mouse-over edge, you can drag area borders around. - note it's a handerized system now, so it updates UI while you move mouse. Feedback needed: - read bottom part of the screen_edit.c file. It's the proposed method for adding tools and handlers. I think it's close, but might need some tweaks.
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r--source/blender/editors/screen/area.c20
-rw-r--r--source/blender/editors/screen/ed_screen.c57
-rw-r--r--source/blender/editors/screen/screen_edit.c279
-rw-r--r--source/blender/editors/screen/screen_intern.h4
-rw-r--r--source/blender/editors/screen/screen_ops.c23
-rw-r--r--source/blender/editors/screen/spacetypes.c1
6 files changed, 259 insertions, 125 deletions
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 5acc3091364..e12bd82c627 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -88,15 +88,19 @@ static void region_draw_emboss(ARegion *ar)
void ED_region_do_listen(ARegion *ar, wmNotifier *note)
{
- if(ar->type->listener)
- ar->type->listener(ar, note);
-
- /* generic notes */
- if(note->type==WM_NOTE_REDRAW)
- ar->do_draw= 1;
- if(note->type==WM_NOTE_REFRESH)
- ar->do_refresh= 1;
+ /* generic notes first */
+ switch(note->type) {
+ case WM_NOTE_WINDOW_REDRAW:
+ ar->do_draw= 1;
+ break;
+ case WM_NOTE_SCREEN_CHANGED:
+ ar->do_draw= ar->do_refresh= 1;
+ break;
+ default:
+ if(ar->type->listener)
+ ar->type->listener(ar, note);
+ }
}
void ED_region_do_draw(bContext *C, ARegion *ar)
diff --git a/source/blender/editors/screen/ed_screen.c b/source/blender/editors/screen/ed_screen.c
deleted file mode 100644
index 5da65166c95..00000000000
--- a/source/blender/editors/screen/ed_screen.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * $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) 2007 Blender Foundation.
- * All rights reserved.
- *
- *
- * Contributor(s): Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "WM_api.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "ED_area.h"
-#include "ED_screen.h"
-
-
-static void del_area(ScrArea *sa)
-{
-
- freespacelist(sa);
-
-// uiFreeBlocks(&sa->uiblocks);
-// uiFreePanels(&sa->panels);
-
-// BPY_free_scriptlink(&sa->scriptlink);
-
-}
-
-
-/* bad level to blenkernel, solve */
-void unlink_screen(bScreen *sc)
-{
- ScrArea *sa;
-
- for (sa= sc->areabase.first; sa; sa= sa->next)
- del_area(sa);
-} \ No newline at end of file
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index e73a4e8e77b..cbb0e82b185 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -237,7 +237,7 @@ static int scredge_is_horizontal(ScrEdge *se)
return (se->v1->vec.y == se->v2->vec.y);
}
-static ScrEdge *screen_find_active_scredge(bScreen *sc, short *mval)
+static ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
{
ScrEdge *se;
@@ -247,7 +247,7 @@ static ScrEdge *screen_find_active_scredge(bScreen *sc, short *mval)
min= MIN2(se->v1->vec.x, se->v2->vec.x);
max= MAX2(se->v1->vec.x, se->v2->vec.x);
- if (abs(mval[1]-se->v1->vec.y)<=2 && mval[0] >= min && mval[0]<=max)
+ if (abs(my-se->v1->vec.y)<=2 && mx>=min && mx<=max)
return se;
}
else {
@@ -255,7 +255,7 @@ static ScrEdge *screen_find_active_scredge(bScreen *sc, short *mval)
min= MIN2(se->v1->vec.y, se->v2->vec.y);
max= MAX2(se->v1->vec.y, se->v2->vec.y);
- if (abs(mval[0]-se->v1->vec.x)<=2 && mval[1] >= min && mval[1]<=max)
+ if (abs(mx-se->v1->vec.x)<=2 && my>=min && my<=max)
return se;
}
}
@@ -263,6 +263,7 @@ static ScrEdge *screen_find_active_scredge(bScreen *sc, short *mval)
return NULL;
}
+/* danger: is used while areamove! */
static void select_connected_scredge(bScreen *sc, ScrEdge *edge)
{
ScrEdge *se;
@@ -278,7 +279,7 @@ static void select_connected_scredge(bScreen *sc, ScrEdge *edge)
sv= sc->vertbase.first;
while(sv) {
- sv->flag= 0;
+ sv->flag = 0;
sv= sv->next;
}
@@ -410,13 +411,11 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
/* *************************************************************** */
/* test if screen vertices should be scaled */
-/* also check offset */
void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
{
ScrVert *sv=NULL;
- ScrEdge *se;
ScrArea *sa, *san;
- int sizex, sizey, yval;
+ int sizex, sizey;
float facx, facy, tempf, min[2], max[2];
/* calculate size */
@@ -472,29 +471,6 @@ void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
MEM_freeN(sa);
}
}
-
- /* make each window at least HEADERY high */
- for(sa= sc->areabase.first; sa; sa= sa->next) {
-
- if(sa->v1->vec.y+HEADERY > sa->v2->vec.y) {
- /* lower edge */
- se= screen_findedge(sc, sa->v4, sa->v1);
- if(se && sa->v1!=sa->v2 ) {
- select_connected_scredge(sc, se);
-
- /* all selected vertices get the right offset */
- yval= sa->v2->vec.y-HEADERY;
- sv= sc->vertbase.first;
- while(sv) {
- /* if is a collapsed area */
- if(sv!=sa->v2 && sv!=sa->v3) {
- if(sv->flag) sv->vec.y= yval;
- }
- sv= sv->next;
- }
- }
- }
- }
}
@@ -529,12 +505,14 @@ void ED_screen_do_listen(bScreen *screen, wmNotifier *note)
{
/* generic notes */
- if(note->type==WM_NOTE_REDRAW)
- screen->do_draw= 1;
- if(note->type==WM_NOTE_REFRESH)
- if(note->swinid==0)
- screen->do_refresh= screen->do_draw= 1;
-
+ switch(note->type) {
+ case WM_NOTE_WINDOW_REDRAW:
+ screen->do_draw= 1;
+ break;
+ case WM_NOTE_SCREEN_CHANGED:
+ screen->do_draw= screen->do_refresh= 1;
+ break;
+ }
}
@@ -552,7 +530,7 @@ void ED_screen_draw(wmWindow *win)
}
/* make this screen usable */
-/* for file read and first use, for scaling window */
+/* for file read and first use, for scaling window, area moves */
void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
{
ScrArea *sa;
@@ -592,28 +570,48 @@ void ED_screens_initialize(wmWindowManager *wm)
void placeholder()
{
- removedouble_scrverts(NULL);
removenotused_scrverts(NULL);
- removedouble_scredges(NULL);
removenotused_scredges(NULL);
}
-/* *************************************************** */
+/* called in wm_event_system.c. sets state var in screen */
+void ED_screen_set_subwinactive(wmWindow *win)
+{
+ if(win->screen) {
+ wmEvent *event= win->eventstate;
+ ScrArea *sa;
+
+ for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+ if(event->x > sa->totrct.xmin && event->x < sa->totrct.xmax)
+ if(event->y > sa->totrct.ymin && event->y < sa->totrct.ymax)
+ break;
+ }
+ if(sa) {
+ ARegion *ar;
+ for(ar= sa->regionbase.first; ar; ar= ar->next) {
+ if(BLI_in_rcti(&ar->winrct, event->x, event->y))
+ win->screen->subwinactive= ar->swinid;
+ }
+ }
+ else
+ win->screen->subwinactive= win->screen->mainwin;
+
+ }
+}
+
+/* ****************** cursor near edge operator ********************************* */
/* operator cb */
int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
{
- short mval[2]= {event->x, event->y};
- ScrEdge *actedge= screen_find_active_scredge(C->screen, mval);
-
- if (actedge) {
- if (scredge_is_horizontal(actedge)) {
+ 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);
}
- // this does global hotkeys too
-// screen_edge_edit_event(g_activearea, actedge, event, val);
} else {
WM_set_cursor(C, CURSOR_STD);
}
@@ -622,3 +620,190 @@ int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
}
+
+/* ************** move area edge 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 can be moved, select edges,
+ clear delta, calculate min and max movement
+
+ exec() apply op->delta on selection
+
+ invoke() handler gets called on a mouse click near edge
+ call init()
+ add handler
+
+ modal() accept modal events while doing it
+ call exec() with delta motion
+ call exit() and remove handler
+
+ exit() cleanup, send notifier
+
+*/
+
+/* "global" variables for all functions inside this operator */
+/* we could do it with properties? */
+static int bigger, smaller, dir, origval;
+
+/* validate selection inside screen, set variables OK */
+/* return 0: init failed */
+static int move_areas_init (bContext *C, wmOperator *op)
+{
+ ScrEdge *actedge= screen_find_active_scredge(C->screen, op->veci.x, op->veci.y);
+ ScrArea *sa;
+
+ if(actedge==NULL) return 0;
+
+ dir= scredge_is_horizontal(actedge)?'h':'v';
+ if(dir=='h') origval= actedge->v1->vec.y;
+ else origval= actedge->v1->vec.x;
+
+ select_connected_scredge(C->screen, actedge);
+
+ /* now all verices with 'flag==1' are the ones that can be moved. */
+ /* we check all areas and test for free space with MINSIZE */
+ bigger= smaller= 10000;
+ for(sa= C->screen->areabase.first; sa; sa= sa->next) {
+ if(dir=='h') { /* if top or down edge selected, test height */
+
+ if(sa->v1->flag && sa->v4->flag) {
+ int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
+ bigger= MIN2(bigger, y1);
+ }
+ else if(sa->v2->flag && sa->v3->flag) {
+ int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
+ smaller= MIN2(smaller, y1);
+ }
+ }
+ else { /* if left or right edge selected, test width */
+ if(sa->v1->flag && sa->v2->flag) {
+ int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
+ bigger= MIN2(bigger, x1);
+ }
+ else if(sa->v3->flag && sa->v4->flag) {
+ int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
+ smaller= MIN2(smaller, x1);
+ }
+ }
+ }
+
+ return 1;
+}
+
+/* moves selected screen edge amount of delta */
+/* needs init call to work */
+static int move_areas_exec(bContext *C, wmOperator *op)
+{
+ ScrVert *v1;
+
+ op->delta= CLAMPIS(op->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 + op->delta;
+ if(op->delta != bigger && op->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 + op->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;
+ }
+ }
+ }
+ return 1;
+}
+
+static int move_areas_exit(bContext *C, wmOperator *op)
+{
+
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0);
+
+ /* this makes sure aligned edges will result in aligned grabbing */
+ removedouble_scrverts(C->screen);
+ removedouble_scredges(C->screen);
+
+ return 1;
+}
+
+/* interaction callback */
+/* return 0 = stop evaluating for next handlers */
+static int move_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;
+
+ if(0==move_areas_init(C, op))
+ return 1;
+
+ /* add temp handler */
+ WM_event_add_modal_handler(&C->window->handlers, op);
+
+ return 0;
+}
+
+/* modal callback for while moving edges */
+/* return 0 = stop evaluating for next handlers */
+static int move_areas_modal (bContext *C, wmOperator *op, wmEvent *event)
+{
+ /* execute the events */
+ switch(event->type) {
+ case MOUSEMOVE:
+
+ if(dir=='v')
+ op->delta= event->x - op->veci.x;
+ else
+ op->delta= event->y - op->veci.y;
+
+ move_areas_exec(C, op);
+ WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0);
+ break;
+
+ case LEFTMOUSE:
+ if(event->val==0) {
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ move_areas_exit(C, op);
+ }
+ break;
+
+ case ESCKEY:
+ op->delta= 0;
+ move_areas_exec(C, op);
+
+ WM_event_remove_modal_handler(&C->window->handlers, op);
+ move_areas_exit(C, op);
+ break;
+ }
+
+ return 1;
+}
+
+void ED_SCR_OT_move_areas(wmOperatorType *ot)
+{
+
+ /* identifiers */
+ ot->name= "Move area edges";
+ ot->idname= "ED_SCR_OT_move_areas";
+
+ ot->init= move_areas_init;
+ ot->invoke= move_areas_invoke;
+ ot->modal= move_areas_modal;
+ ot->exec= move_areas_exec;
+ ot->exit= move_areas_exit;
+
+ ot->poll= ED_operator_screen_mainwinactive;
+}
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 01c9c08ac51..680404cc41b 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -36,7 +36,9 @@ struct wmEvent;
void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space);
/* screen_edit.c */
-int screen_cursor_test(bContext *C, struct wmOperator *op, struct wmEvent *event);
+int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event);
+
+void ED_SCR_OT_move_areas(wmOperatorType *ot);
#endif /* ED_SCREEN_INTERN_H */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index b88438ecdfc..c6d44017db7 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -44,6 +44,8 @@
static ListBase local_ops;
+/* ************** Poll tests ********************** */
+
int ED_operator_screenactive(bContext *C)
{
if(C->window==NULL) return 0;
@@ -51,24 +53,22 @@ int ED_operator_screenactive(bContext *C)
return 1;
}
-
-
-static void ED_SCR_OT_move_areas(wmOperatorType *ot)
+int ED_operator_screen_mainwinactive(bContext *C)
{
- ot->name= "Move area edges";
- ot->idname= "ED_SCR_OT_move_areas";
-
- ot->interactive= NULL;
- ot->exec= NULL;
- ot->poll= ED_operator_screenactive;
+ if(C->window==NULL) return 0;
+ if(C->screen==NULL) return 0;
+ if (C->screen->subwinactive!=C->screen->mainwin) return 0;
+ return 1;
}
+/* ******************************* */
+
static void ED_SCR_OT_cursor_type(wmOperatorType *ot)
{
ot->name= "Cursor type";
ot->idname= "ED_SCR_OT_cursor_type";
- ot->interactive= screen_cursor_test;
+ ot->invoke= screen_cursor_test;
ot->exec= NULL;
ot->poll= ED_operator_screenactive;
}
@@ -88,8 +88,6 @@ void ED_operatortypes_screen(void)
ADD_OPTYPE( ED_SCR_OT_move_areas );
ADD_OPTYPE( ED_SCR_OT_cursor_type );
-
-
WM_operatortypelist_append(&local_ops);
}
@@ -97,6 +95,7 @@ void ED_operatortypes_screen(void)
void ed_screen_keymap(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_move_areas", LEFTMOUSE, KM_PRESS, 0, 0);
}
diff --git a/source/blender/editors/screen/spacetypes.c b/source/blender/editors/screen/spacetypes.c
index eec6da90e1a..88ac8de1f88 100644
--- a/source/blender/editors/screen/spacetypes.c
+++ b/source/blender/editors/screen/spacetypes.c
@@ -33,6 +33,7 @@
#include "BIF_gl.h"
#include "WM_api.h"
+#include "WM_types.h"
#include "ED_screen.h"
#include "ED_area.h"