This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/screen/area.c

1423 lines
35 KiB
C
Raw Normal View History

/**
* $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 <string.h>
#include <stdio.h>
#include "MEM_guardedalloc.h"
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_rand.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm_subwindow.h"
#include "ED_screen.h"
#include "ED_screen_types.h"
#include "ED_types.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BLF_api.h"
#include "UI_interface.h"
Port of part of the Interface code to 2.50. This is based on the current trunk version, so these files should not need merges. There's two things (clipboard and intptr_t) that are missing in 2.50 and commented out with XXX 2.48, these can be enabled again once trunk is merged into this branch. Further this is not all interface code, there are many parts commented out: * interface.c: nearly all button types, missing: links, chartab, keyevent. * interface_draw.c: almost all code, with some small exceptions. * interface_ops.c: this replaces ui_do_but and uiDoBlocks with two operators, making it non-blocking. * interface_regions: this is a part of interface.c, split off, contains code to create regions for tooltips, menus, pupmenu (that one is crashing currently), color chooser, basically regions with buttons which is fairly independent of core interface code. * interface_panel.c and interface_icons.c: not ported over, so no panels and icons yet. Panels should probably become (free floating) regions? * text.c: (formerly language.c) for drawing text and translation. this works but is using bad globals still and could be cleaned up. Header Files: * ED_datafiles.h now has declarations for datatoc_ files, so those extern declarations can be #included instead of repeated. * The user interface code is in UI_interface.h and other UI_* files. Core: * The API for creating blocks, buttons, etc is nearly the same still. Blocks are now created per region instead of per area. * The code was made non-blocking, which means that any changes and redraws should be possible while editing a button. That means though that we need some sort of persistence even though the blender model is to recreate buttons for each redraw. So when a new block is created, some matching happens to find out which buttons correspond to buttons in the previously created block, and for activated buttons some data is then copied over to the new button. * Added UI_init/UI_init_userdef/UI_exit functions that should initialize code in this module, instead of multiple function calls in the windowmanager. * Removed most static/globals from interface.c. * Removed UIafterfunc_ I don't think it's needed anymore, and not sure how it would integrate here? * Currently only full window redraws are used, this should become per region and maybe per button later. Operators: * Events are currently handled through two operators: button activate and menu handle. Operators may not be the best way to implement this, since there are currently some issues with events being missed, but they can become a special handler type instead, this should not be a big change. * The button activate operator runs as long as a button is active, and will handle all interaction with that button until the button is not activated anymore. This means clicking, text editing, number dragging, opening menu blocks, etc. * Since this operator has to be non-blocking, the ui_do_but code needed to made non-blocking. That means variables that were previously on the stack, now need to be stored away in a struct such that they can be accessed again when the operator receives more events. * Additionally the place in the ui_do_but code indicated the state, now that needs to be set explicit in order to handle the right events in the right state. So an activated button can be in one of these states: init, highlight, wait_flash, wait_release, wait_key_event, num_editing, text_editing, text_selecting, block_open, exit. * For each button type an ui_apply_but_* function has also been separated out from ui_do_but. This makes it possible to continuously apply the button as text is being typed for example, and there is an option in the code to enable this. Since the code non-blocking and can deal with the button being deleted even, it should be safe to do this. * When editing text, dragging numbers, etc, the actual data (but->poin) is not being edited, since that would mean data is being edited without correct updates happening, while some other part of blender may be accessing that data in the meantime. So data values, strings, vectors are written to a temporary location and only flush in the apply function. Regions: * Menus, color chooser, tooltips etc all create screen level regions. Such menu blocks give a handle to the button that creates it, which will contain the results of the menu block once a MESSAGE event is received from that menu block. * For this type of menu block the coordinates used to be in window space. They are still created that way and ui_positionblock still works with window coordinates, but after that the block and buttons are brought back to region coordinates since these are now contained in a region. * The flush/overdraw frontbuffer drawing code was removed, the windowmanager should have enough information with these screen level regions to have full control over what gets drawn when and to then do correct compositing. Testing: * The header in the time space currently has some buttons to test the UI code.
2008-11-11 18:31:32 +00:00
#include "UI_resources.h"
#include "UI_view2d.h"
Port of part of the Interface code to 2.50. This is based on the current trunk version, so these files should not need merges. There's two things (clipboard and intptr_t) that are missing in 2.50 and commented out with XXX 2.48, these can be enabled again once trunk is merged into this branch. Further this is not all interface code, there are many parts commented out: * interface.c: nearly all button types, missing: links, chartab, keyevent. * interface_draw.c: almost all code, with some small exceptions. * interface_ops.c: this replaces ui_do_but and uiDoBlocks with two operators, making it non-blocking. * interface_regions: this is a part of interface.c, split off, contains code to create regions for tooltips, menus, pupmenu (that one is crashing currently), color chooser, basically regions with buttons which is fairly independent of core interface code. * interface_panel.c and interface_icons.c: not ported over, so no panels and icons yet. Panels should probably become (free floating) regions? * text.c: (formerly language.c) for drawing text and translation. this works but is using bad globals still and could be cleaned up. Header Files: * ED_datafiles.h now has declarations for datatoc_ files, so those extern declarations can be #included instead of repeated. * The user interface code is in UI_interface.h and other UI_* files. Core: * The API for creating blocks, buttons, etc is nearly the same still. Blocks are now created per region instead of per area. * The code was made non-blocking, which means that any changes and redraws should be possible while editing a button. That means though that we need some sort of persistence even though the blender model is to recreate buttons for each redraw. So when a new block is created, some matching happens to find out which buttons correspond to buttons in the previously created block, and for activated buttons some data is then copied over to the new button. * Added UI_init/UI_init_userdef/UI_exit functions that should initialize code in this module, instead of multiple function calls in the windowmanager. * Removed most static/globals from interface.c. * Removed UIafterfunc_ I don't think it's needed anymore, and not sure how it would integrate here? * Currently only full window redraws are used, this should become per region and maybe per button later. Operators: * Events are currently handled through two operators: button activate and menu handle. Operators may not be the best way to implement this, since there are currently some issues with events being missed, but they can become a special handler type instead, this should not be a big change. * The button activate operator runs as long as a button is active, and will handle all interaction with that button until the button is not activated anymore. This means clicking, text editing, number dragging, opening menu blocks, etc. * Since this operator has to be non-blocking, the ui_do_but code needed to made non-blocking. That means variables that were previously on the stack, now need to be stored away in a struct such that they can be accessed again when the operator receives more events. * Additionally the place in the ui_do_but code indicated the state, now that needs to be set explicit in order to handle the right events in the right state. So an activated button can be in one of these states: init, highlight, wait_flash, wait_release, wait_key_event, num_editing, text_editing, text_selecting, block_open, exit. * For each button type an ui_apply_but_* function has also been separated out from ui_do_but. This makes it possible to continuously apply the button as text is being typed for example, and there is an option in the code to enable this. Since the code non-blocking and can deal with the button being deleted even, it should be safe to do this. * When editing text, dragging numbers, etc, the actual data (but->poin) is not being edited, since that would mean data is being edited without correct updates happening, while some other part of blender may be accessing that data in the meantime. So data values, strings, vectors are written to a temporary location and only flush in the apply function. Regions: * Menus, color chooser, tooltips etc all create screen level regions. Such menu blocks give a handle to the button that creates it, which will contain the results of the menu block once a MESSAGE event is received from that menu block. * For this type of menu block the coordinates used to be in window space. They are still created that way and ui_positionblock still works with window coordinates, but after that the block and buttons are brought back to region coordinates since these are now contained in a region. * The flush/overdraw frontbuffer drawing code was removed, the windowmanager should have enough information with these screen level regions to have full control over what gets drawn when and to then do correct compositing. Testing: * The header in the time space currently has some buttons to test the UI code.
2008-11-11 18:31:32 +00:00
2008-11-24 21:57:58 +00:00
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
2008-11-24 21:57:58 +00:00
#endif
#include "screen_intern.h"
/* general area and region code */
2009-04-27 13:44:11 +00:00
static void region_draw_emboss(ARegion *ar, rcti *scirct)
{
2009-04-27 13:44:11 +00:00
rcti rect;
2009-04-27 13:44:11 +00:00
/* translate scissor rect to region space */
rect.xmin= scirct->xmin - ar->winrct.xmin;
rect.ymin= scirct->ymin - ar->winrct.ymin;
rect.xmax= scirct->xmax - ar->winrct.xmin;
rect.ymax= scirct->ymax - ar->winrct.ymin;
/* set transp line */
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
/* right */
glColor4ub(0,0,0, 50);
2009-04-27 13:44:11 +00:00
sdrawline(rect.xmax, rect.ymin, rect.xmax, rect.ymax);
/* bottom */
glColor4ub(0,0,0, 80);
2009-04-27 13:44:11 +00:00
sdrawline(rect.xmin, rect.ymin, rect.xmax, rect.ymin);
/* top */
glColor4ub(255,255,255, 60);
2009-04-27 13:44:11 +00:00
sdrawline(rect.xmin, rect.ymax, rect.xmax, rect.ymax);
/* left */
glColor4ub(255,255,255, 50);
2009-04-27 13:44:11 +00:00
sdrawline(rect.xmin, rect.ymin, rect.xmin, rect.ymax);
glDisable( GL_BLEND );
}
void ED_region_pixelspace(ARegion *ar)
{
int width= ar->winrct.xmax-ar->winrct.xmin+1;
int height= ar->winrct.ymax-ar->winrct.ymin+1;
wmOrtho2(-0.375, (float)width-0.375, -0.375, (float)height-0.375);
wmLoadIdentity();
}
/* only exported for WM */
void ED_region_do_listen(ARegion *ar, wmNotifier *note)
{
/* generic notes first */
switch(note->category) {
case NC_WM:
if(note->data==ND_FILEREAD)
ED_region_tag_redraw(ar);
break;
case NC_WINDOW:
ED_region_tag_redraw(ar);
break;
case NC_SCREEN:
if(note->action==NA_EDITED)
ED_region_tag_redraw(ar);
/* pass on */
default:
if(ar->type && ar->type->listener)
ar->type->listener(ar, note);
}
}
/* only exported for WM */
void ED_area_do_listen(ScrArea *sa, wmNotifier *note)
{
/* no generic notes? */
if(sa->type && sa->type->listener) {
sa->type->listener(sa, note);
}
}
/* only exported for WM */
void ED_area_do_refresh(bContext *C, ScrArea *sa)
{
/* no generic notes? */
if(sa->type && sa->type->refresh) {
sa->type->refresh(C, sa);
}
sa->do_refresh= 0;
}
/* based on screen region draw tags, set draw tags in azones, and future region tabs etc */
/* only exported for WM */
void ED_area_overdraw_flush(bContext *C, ScrArea *sa, ARegion *ar)
{
AZone *az;
for(az= sa->actionzones.first; az; az= az->next) {
int xs, ys;
xs= (az->x1+az->x2)/2;
ys= (az->y1+az->y2)/2;
/* test if inside */
if(BLI_in_rcti(&ar->winrct, xs, ys)) {
az->do_draw= 1;
}
}
}
static void area_draw_azone(short x1, short y1, short x2, short y2)
{
float xmin = x1;
float xmax = x2-2;
float ymin = y1-1;
float ymax = y2-3;
float dx= 0.3f*(xmax-xmin);
float dy= 0.3f*(ymax-ymin);
glColor4ub(255, 255, 255, 80);
fdrawline(xmin, ymax, xmax, ymin);
fdrawline(xmin, ymax-dy, xmax-dx, ymin);
fdrawline(xmin, ymax-2*dy, xmax-2*dx, ymin);
glColor4ub(0, 0, 0, 150);
fdrawline(xmin, ymax+1, xmax+1, ymin);
fdrawline(xmin, ymax-dy+1, xmax-dx+1, ymin);
fdrawline(xmin, ymax-2*dy+1, xmax-2*dx+1, ymin);
}
static void region_draw_azone(ScrArea *sa, AZone *az)
{
GLUquadricObj *qobj = gluNewQuadric();
short midx = az->x1 + (az->x2 - az->x1)/2;
short midy = az->y1 + (az->y2 - az->y1)/2;
if(az->ar==NULL) return;
/* only display action zone icons when the region is hidden */
if (!(az->ar->flag & RGN_FLAG_HIDDEN)) return;
glPushMatrix();
glTranslatef(midx, midy, 0.);
/* outlined circle */
glEnable(GL_LINE_SMOOTH);
glColor4f(1.f, 1.f, 1.f, 0.8f);
gluQuadricDrawStyle(qobj, GLU_FILL);
gluDisk( qobj, 0.0, 4.25f, 16, 1);
glColor4f(0.2f, 0.2f, 0.2f, 0.9f);
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
gluDisk( qobj, 0.0, 4.25f, 16, 1);
glDisable(GL_LINE_SMOOTH);
glPopMatrix();
gluDeleteQuadric(qobj);
/* + */
sdrawline(midx, midy-2, midx, midy+3);
sdrawline(midx-2, midy, midx+3, midy);
}
/* only exported for WM */
void ED_area_overdraw(bContext *C)
{
wmWindow *win= CTX_wm_window(C);
bScreen *screen= CTX_wm_screen(C);
ScrArea *sa;
/* Draw AZones, in screenspace */
wmSubWindowSet(win, screen->mainwin);
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
for(sa= screen->areabase.first; sa; sa= sa->next) {
AZone *az;
for(az= sa->actionzones.first; az; az= az->next) {
if(az->do_draw) {
if(az->type==AZONE_AREA) {
area_draw_azone(az->x1, az->y1, az->x2, az->y2);
} else if(az->type==AZONE_REGION) {
region_draw_azone(sa, az);
}
az->do_draw= 0;
}
}
}
glDisable( GL_BLEND );
}
2009-04-27 13:44:11 +00:00
/* get scissor rect, checking overlapping regions */
void region_scissor_winrct(ARegion *ar, rcti *winrct)
2009-04-27 13:44:11 +00:00
{
*winrct= ar->winrct;
if(ELEM(ar->alignment, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT))
return;
while(ar->prev) {
ar= ar->prev;
if(BLI_isect_rcti(winrct, &ar->winrct, NULL)) {
if(ar->flag & RGN_FLAG_HIDDEN);
else if(ar->alignment & RGN_SPLIT_PREV);
else if(ar->alignment==RGN_OVERLAP_LEFT) {
winrct->xmin= ar->winrct.xmax + 1;
}
else if(ar->alignment==RGN_OVERLAP_RIGHT) {
winrct->xmax= ar->winrct.xmin - 1;
}
else break;
2009-04-27 13:44:11 +00:00
}
}
}
/* only exported for WM */
/* makes region ready for drawing, sets pixelspace */
void ED_region_set(const bContext *C, ARegion *ar)
{
wmWindow *win= CTX_wm_window(C);
ScrArea *sa= CTX_wm_area(C);
rcti winrct;
/* checks other overlapping regions */
region_scissor_winrct(ar, &winrct);
ar->drawrct= winrct;
/* note; this sets state, so we can use wmOrtho and friends */
wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct);
UI_SetTheme(sa?sa->spacetype:0, ar->type?ar->type->regionid:0);
ED_region_pixelspace(ar);
}
/* only exported for WM */
void ED_region_do_draw(bContext *C, ARegion *ar)
{
wmWindow *win= CTX_wm_window(C);
ScrArea *sa= CTX_wm_area(C);
ARegionType *at= ar->type;
2009-04-27 13:44:11 +00:00
rcti winrct;
/* checks other overlapping regions */
region_scissor_winrct(ar, &winrct);
2.5: WM Compositing * Triple Buffer is now more complete: - Proper handling of window resize, duplicate, etc. - It now uses 3x3 textures (or less) if the power of two sizes do not match well. That still has a worst case wast of 23.4%, but better than 300%. - It can also use the ARB/NV/EXT_texture_rectangle extension now, which may be supported on hardware that does not support ARB_texture_non_power_of_two. - Gesture, menu and brushe redraws now require no redraws at all from the area regions. So even on a high poly scene just moving the paint cursor or opening a menu should be fast. * Testing can be done by setting the "Window Draw Method" in the User Preferences in the outliner. "Overlap" is still default, since "Triple Buffer" has not been tested on computers other than mine, would like to avoid crashing Blender on startup in case there is a common bug, but it's ready for testing now. - For reference "Full" draws the full window each time. - "Triple Buffer" should work for both swap copy and swap exchange systems, the latter still need the -E command line option for "Overlap". - Resizing and going fullscreen still gives flicker here but no more than "Full" drawing. * Partial Redraw was added. ED_region_tag_redraw_partial takes a rect in window coordinates to define a subarea of the region. On region draw it will then set glScissor to a smaller area, and ar->drawrct will always be set to either the partial or full window rect. The latter can then be used for clipping in the 3D view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
/* if no partial draw rect set, full rect */
if(ar->drawrct.xmin == ar->drawrct.xmax)
2009-04-27 13:44:11 +00:00
ar->drawrct= winrct;
else {
/* extra clip for safety */
ar->drawrct.xmin= MAX2(winrct.xmin, ar->drawrct.xmin);
ar->drawrct.ymin= MAX2(winrct.ymin, ar->drawrct.ymin);
ar->drawrct.xmax= MIN2(winrct.xmax, ar->drawrct.xmax);
ar->drawrct.ymax= MIN2(winrct.ymax, ar->drawrct.ymax);
}
/* note; this sets state, so we can use wmOrtho and friends */
2.5: WM Compositing * Triple Buffer is now more complete: - Proper handling of window resize, duplicate, etc. - It now uses 3x3 textures (or less) if the power of two sizes do not match well. That still has a worst case wast of 23.4%, but better than 300%. - It can also use the ARB/NV/EXT_texture_rectangle extension now, which may be supported on hardware that does not support ARB_texture_non_power_of_two. - Gesture, menu and brushe redraws now require no redraws at all from the area regions. So even on a high poly scene just moving the paint cursor or opening a menu should be fast. * Testing can be done by setting the "Window Draw Method" in the User Preferences in the outliner. "Overlap" is still default, since "Triple Buffer" has not been tested on computers other than mine, would like to avoid crashing Blender on startup in case there is a common bug, but it's ready for testing now. - For reference "Full" draws the full window each time. - "Triple Buffer" should work for both swap copy and swap exchange systems, the latter still need the -E command line option for "Overlap". - Resizing and going fullscreen still gives flicker here but no more than "Full" drawing. * Partial Redraw was added. ED_region_tag_redraw_partial takes a rect in window coordinates to define a subarea of the region. On region draw it will then set glScissor to a smaller area, and ar->drawrct will always be set to either the partial or full window rect. The latter can then be used for clipping in the 3D view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct);
2009-04-27 13:44:11 +00:00
UI_SetTheme(sa?sa->spacetype:0, ar->type?ar->type->regionid:0);
/* optional header info instead? */
if(ar->headerstr) {
float col[3];
UI_GetThemeColor3fv(TH_HEADER, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
2009-04-27 13:44:11 +00:00
UI_ThemeColor(TH_TEXT);
BLF_draw_default(20, 8, 0.0f, ar->headerstr);
}
else if(at->draw) {
at->draw(C, ar);
}
uiFreeInactiveBlocks(C, &ar->uiblocks);
2009-04-27 13:44:11 +00:00
if(sa)
region_draw_emboss(ar, &winrct);
/* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */
ED_region_pixelspace(ar);
ar->do_draw= 0;
2.5: WM Compositing * Triple Buffer is now more complete: - Proper handling of window resize, duplicate, etc. - It now uses 3x3 textures (or less) if the power of two sizes do not match well. That still has a worst case wast of 23.4%, but better than 300%. - It can also use the ARB/NV/EXT_texture_rectangle extension now, which may be supported on hardware that does not support ARB_texture_non_power_of_two. - Gesture, menu and brushe redraws now require no redraws at all from the area regions. So even on a high poly scene just moving the paint cursor or opening a menu should be fast. * Testing can be done by setting the "Window Draw Method" in the User Preferences in the outliner. "Overlap" is still default, since "Triple Buffer" has not been tested on computers other than mine, would like to avoid crashing Blender on startup in case there is a common bug, but it's ready for testing now. - For reference "Full" draws the full window each time. - "Triple Buffer" should work for both swap copy and swap exchange systems, the latter still need the -E command line option for "Overlap". - Resizing and going fullscreen still gives flicker here but no more than "Full" drawing. * Partial Redraw was added. ED_region_tag_redraw_partial takes a rect in window coordinates to define a subarea of the region. On region draw it will then set glScissor to a smaller area, and ar->drawrct will always be set to either the partial or full window rect. The latter can then be used for clipping in the 3D view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
}
/* **********************************
maybe silly, but let's try for now
to keep these tags protected
********************************** */
void ED_region_tag_redraw(ARegion *ar)
{
2.5: WM Compositing * Triple Buffer is now more complete: - Proper handling of window resize, duplicate, etc. - It now uses 3x3 textures (or less) if the power of two sizes do not match well. That still has a worst case wast of 23.4%, but better than 300%. - It can also use the ARB/NV/EXT_texture_rectangle extension now, which may be supported on hardware that does not support ARB_texture_non_power_of_two. - Gesture, menu and brushe redraws now require no redraws at all from the area regions. So even on a high poly scene just moving the paint cursor or opening a menu should be fast. * Testing can be done by setting the "Window Draw Method" in the User Preferences in the outliner. "Overlap" is still default, since "Triple Buffer" has not been tested on computers other than mine, would like to avoid crashing Blender on startup in case there is a common bug, but it's ready for testing now. - For reference "Full" draws the full window each time. - "Triple Buffer" should work for both swap copy and swap exchange systems, the latter still need the -E command line option for "Overlap". - Resizing and going fullscreen still gives flicker here but no more than "Full" drawing. * Partial Redraw was added. ED_region_tag_redraw_partial takes a rect in window coordinates to define a subarea of the region. On region draw it will then set glScissor to a smaller area, and ar->drawrct will always be set to either the partial or full window rect. The latter can then be used for clipping in the 3D view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
if(ar) {
/* zero region means full region redraw */
ar->do_draw= 1;
2.5: WM Compositing * Triple Buffer is now more complete: - Proper handling of window resize, duplicate, etc. - It now uses 3x3 textures (or less) if the power of two sizes do not match well. That still has a worst case wast of 23.4%, but better than 300%. - It can also use the ARB/NV/EXT_texture_rectangle extension now, which may be supported on hardware that does not support ARB_texture_non_power_of_two. - Gesture, menu and brushe redraws now require no redraws at all from the area regions. So even on a high poly scene just moving the paint cursor or opening a menu should be fast. * Testing can be done by setting the "Window Draw Method" in the User Preferences in the outliner. "Overlap" is still default, since "Triple Buffer" has not been tested on computers other than mine, would like to avoid crashing Blender on startup in case there is a common bug, but it's ready for testing now. - For reference "Full" draws the full window each time. - "Triple Buffer" should work for both swap copy and swap exchange systems, the latter still need the -E command line option for "Overlap". - Resizing and going fullscreen still gives flicker here but no more than "Full" drawing. * Partial Redraw was added. ED_region_tag_redraw_partial takes a rect in window coordinates to define a subarea of the region. On region draw it will then set glScissor to a smaller area, and ar->drawrct will always be set to either the partial or full window rect. The latter can then be used for clipping in the 3D view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
}
}
void ED_region_tag_redraw_partial(ARegion *ar, rcti *rct)
{
if(ar) {
if(!ar->do_draw) {
/* no redraw set yet, set partial region */
ar->do_draw= 1;
ar->drawrct= *rct;
}
else if(ar->drawrct.xmin != ar->drawrct.xmax) {
/* partial redraw already set, expand region */
ar->drawrct.xmin= MIN2(ar->drawrct.xmin, rct->xmin);
ar->drawrct.ymin= MIN2(ar->drawrct.ymin, rct->ymin);
ar->drawrct.xmax= MAX2(ar->drawrct.xmax, rct->xmax);
ar->drawrct.ymax= MAX2(ar->drawrct.ymax, rct->ymax);
}
}
}
void ED_area_tag_redraw(ScrArea *sa)
{
ARegion *ar;
if(sa)
for(ar= sa->regionbase.first; ar; ar= ar->next)
2.5: WM Compositing * Triple Buffer is now more complete: - Proper handling of window resize, duplicate, etc. - It now uses 3x3 textures (or less) if the power of two sizes do not match well. That still has a worst case wast of 23.4%, but better than 300%. - It can also use the ARB/NV/EXT_texture_rectangle extension now, which may be supported on hardware that does not support ARB_texture_non_power_of_two. - Gesture, menu and brushe redraws now require no redraws at all from the area regions. So even on a high poly scene just moving the paint cursor or opening a menu should be fast. * Testing can be done by setting the "Window Draw Method" in the User Preferences in the outliner. "Overlap" is still default, since "Triple Buffer" has not been tested on computers other than mine, would like to avoid crashing Blender on startup in case there is a common bug, but it's ready for testing now. - For reference "Full" draws the full window each time. - "Triple Buffer" should work for both swap copy and swap exchange systems, the latter still need the -E command line option for "Overlap". - Resizing and going fullscreen still gives flicker here but no more than "Full" drawing. * Partial Redraw was added. ED_region_tag_redraw_partial takes a rect in window coordinates to define a subarea of the region. On region draw it will then set glScissor to a smaller area, and ar->drawrct will always be set to either the partial or full window rect. The latter can then be used for clipping in the 3D view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
ED_region_tag_redraw(ar);
}
void ED_area_tag_refresh(ScrArea *sa)
{
if(sa)
sa->do_refresh= 1;
}
/* *************************************************************** */
/* use NULL to disable it */
void ED_area_headerprint(ScrArea *sa, const char *str)
{
ARegion *ar;
for(ar= sa->regionbase.first; ar; ar= ar->next) {
if(ar->regiontype==RGN_TYPE_HEADER) {
if(str) {
if(ar->headerstr==NULL)
ar->headerstr= MEM_mallocN(256, "headerprint");
BLI_strncpy(ar->headerstr, str, 256);
}
else if(ar->headerstr) {
MEM_freeN(ar->headerstr);
ar->headerstr= NULL;
}
ED_region_tag_redraw(ar);
}
}
}
/* ************************************************************ */
#define AZONESPOT 12
static void area_azone_initialize(ScrArea *sa)
{
AZone *az;
/* reinitalize entirely, regions add azones too */
BLI_freelistN(&sa->actionzones);
/* set area action zones */
az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
BLI_addtail(&(sa->actionzones), az);
az->type= AZONE_AREA;
az->x1= sa->totrct.xmin;
az->y1= sa->totrct.ymin;
az->x2= sa->totrct.xmin + AZONESPOT-1;
az->y2= sa->totrct.ymin + AZONESPOT-1;
BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
BLI_addtail(&(sa->actionzones), az);
az->type= AZONE_AREA;
az->x1= sa->totrct.xmax+1;
az->y1= sa->totrct.ymax+1;
az->x2= sa->totrct.xmax-AZONESPOT+1;
az->y2= sa->totrct.ymax-AZONESPOT+1;
BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
#define AZONEPAD_EDGE 4
#define AZONEPAD_ICON 8
static void region_azone_edge(AZone *az, ARegion *ar)
{
if(az->edge=='t') {
az->x1= ar->winrct.xmin;
az->y1= ar->winrct.ymax - AZONEPAD_EDGE;
az->x2= ar->winrct.xmax;
az->y2= ar->winrct.ymax;
}
else if(az->edge=='b') {
az->x1= ar->winrct.xmin;
az->y1= ar->winrct.ymin + AZONEPAD_EDGE;
az->x2= ar->winrct.xmax;
az->y2= ar->winrct.ymin;
}
else if(az->edge=='l') {
az->x1= ar->winrct.xmin;
az->y1= ar->winrct.ymin;
az->x2= ar->winrct.xmin + AZONEPAD_EDGE;
az->y2= ar->winrct.ymax;
}
else { // if(az->edge=='r') {
az->x1= ar->winrct.xmax;
az->y1= ar->winrct.ymin;
az->x2= ar->winrct.xmax - AZONEPAD_EDGE;
az->y2= ar->winrct.ymax;
}
BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
static void region_azone_icon(ScrArea *sa, AZone *az, ARegion *ar)
{
AZone *azt;
if(az->edge=='t') {
az->x1= ar->winrct.xmax - AZONEPAD_ICON;
az->y1= ar->winrct.ymax + AZONEPAD_ICON;
az->x2= ar->winrct.xmax - 2*AZONEPAD_ICON;
az->y2= ar->winrct.ymax + 2*AZONEPAD_ICON;
}
else if(az->edge=='b') {
az->x1= ar->winrct.xmin + AZONEPAD_ICON;
az->y1= ar->winrct.ymin - AZONEPAD_ICON;
az->x2= ar->winrct.xmin + 2*AZONEPAD_ICON;
az->y2= ar->winrct.ymin - 2*AZONEPAD_ICON;
}
else if(az->edge=='l') {
az->x1= ar->winrct.xmin - 2*AZONEPAD_ICON;
az->y1= ar->winrct.ymax - 2*AZONEPAD_ICON;
az->x2= ar->winrct.xmin - AZONEPAD_ICON;
az->y2= ar->winrct.ymax - AZONEPAD_ICON;
}
else { // if(az->edge=='r') {
az->x1= ar->winrct.xmax + AZONEPAD_ICON;
az->y1= ar->winrct.ymax - 2*AZONEPAD_ICON;
az->x2= ar->winrct.xmax + 2*AZONEPAD_ICON;
az->y2= ar->winrct.ymax - AZONEPAD_ICON;
}
BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
/* if more azones on 1 spot, set offset */
for(azt= sa->actionzones.first; azt; azt= azt->next) {
if(az!=azt) {
if( ABS(az->x1-azt->x1) < 2 && ABS(az->y1-azt->y1) < 2) {
if(az->edge=='t' || az->edge=='b') {
az->x1+= AZONESPOT;
az->x2+= AZONESPOT;
BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
else {
az->y1-= AZONESPOT;
az->y2-= AZONESPOT;
BLI_init_rcti(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
}
}
}
}
static void region_azone_initialize(ScrArea *sa, ARegion *ar, char edge)
{
AZone *az;
az= (AZone *)MEM_callocN(sizeof(AZone), "actionzone");
BLI_addtail(&(sa->actionzones), az);
az->type= AZONE_REGION;
az->ar= ar;
az->edge= edge;
if (ar->flag & RGN_FLAG_HIDDEN) {
region_azone_icon(sa, az, ar);
} else {
region_azone_edge(az, ar);
}
}
/* *************************************************************** */
static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment)
{
/* edge code (t b l r) is where azone will be drawn */
if(alignment==RGN_ALIGN_TOP)
region_azone_initialize(sa, ar, 'b');
else if(alignment==RGN_ALIGN_BOTTOM)
region_azone_initialize(sa, ar, 't');
else if(ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT))
region_azone_initialize(sa, ar, 'l');
else if(ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT))
region_azone_initialize(sa, ar, 'r');
}
/* dir is direction to check, not the splitting edge direction! */
static int rct_fits(rcti *rect, char dir, int size)
{
if(dir=='h') {
return rect->xmax-rect->xmin - size;
}
else { // 'v'
return rect->ymax-rect->ymin - size;
}
}
static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int quad)
{
rcti *remainder_prev= remainder;
int prefsizex, prefsizey;
int alignment;
if(ar==NULL)
return;
/* no returns in function, winrct gets set in the end again */
BLI_init_rcti(&ar->winrct, 0, 0, 0, 0);
/* for test; allow split of previously defined region */
if(ar->alignment & RGN_SPLIT_PREV)
if(ar->prev)
remainder= &ar->prev->winrct;
alignment = ar->alignment & ~RGN_SPLIT_PREV;
/* clear state flags first */
ar->flag &= ~RGN_FLAG_TOO_SMALL;
/* user errors */
if(ar->next==NULL && alignment!=RGN_ALIGN_QSPLIT)
alignment= RGN_ALIGN_NONE;
prefsizex= ar->type->minsizex;
prefsizey= ar->type->minsizey;
/* hidden is user flag */
if(ar->flag & RGN_FLAG_HIDDEN);
Various changes made in the process of working on the UI code: * Added functions to generate Timer events. There was some unfinished code to create one timer per window, this replaces that with a way to let operators or other handlers add/remove their own timers as needed. This is currently delivered as an event with the timer handle, perhaps this should be a notifier instead? Also includes some fixes in ghost for timer events that were not delivered in time, due to passing negative timeout. * Added a Message event, which is a generic event that can be added by any operator. This is used in the UI code to communicate the results of opened blocks. Again, this may be better as a notifier. * These two events should not be blocked as they are intended for a specific operator or handler, so there were exceptions added for this, which is one of the reasons they might work better as notifiers, but currently these things can't listen to notifier yet. * Added an option to events to indicate if the customdata should be freed or not. * Added a free() callback for area regions, and added a free function for area regions in blenkernel since it was already there for screens and areas. * Added ED_screen/area/region_exit functions to clean up things like operators and handlers when they are closed. * Added screen level regions, these will draw over areas boundaries, with the last created region on top. These are useful for tooltips, menus, etc, and are not saved to file. It's using the same ARegion struct as areas to avoid code duplication, but perhaps that should be renamed then. Note that redraws currently go correct, because only full window redraws are used, for partial redraws without any frontbuffer drawing, the window manager needs to get support for compositing subwindows. * Minor changes in the subwindow code to retrieve the matrix, and moved setlinestyle to glutil.c. * Reversed argument order in WM_event_add/remove_keymap_handler to be consistent with modal_handler. * Operators can now block events but not necessarily cancel/finish. * Modal operators are now stored in a list in the window/area/region they were created in. This means for example that when a transform operator is invoked from a region but registers a handler at the window level (since mouse motion across areas should work), it will still get removed when the region is closed while the operator is running.
2008-11-11 15:18:21 +00:00
/* XXX floating area region, not handled yet here */
else if(alignment == RGN_ALIGN_FLOAT);
/* remainder is too small for any usage */
else if( rct_fits(remainder, 'v', 1)<0 || rct_fits(remainder, 'h', 1) < 0 ) {
ar->flag |= RGN_FLAG_TOO_SMALL;
}
else if(alignment==RGN_ALIGN_NONE) {
/* typically last region */
ar->winrct= *remainder;
BLI_init_rcti(remainder, 0, 0, 0, 0);
}
else if(alignment==RGN_ALIGN_TOP || alignment==RGN_ALIGN_BOTTOM) {
if( rct_fits(remainder, 'v', prefsizey) < 0 ) {
ar->flag |= RGN_FLAG_TOO_SMALL;
}
else {
int fac= rct_fits(remainder, 'v', prefsizey);
Various changes made in the process of working on the UI code: * Added functions to generate Timer events. There was some unfinished code to create one timer per window, this replaces that with a way to let operators or other handlers add/remove their own timers as needed. This is currently delivered as an event with the timer handle, perhaps this should be a notifier instead? Also includes some fixes in ghost for timer events that were not delivered in time, due to passing negative timeout. * Added a Message event, which is a generic event that can be added by any operator. This is used in the UI code to communicate the results of opened blocks. Again, this may be better as a notifier. * These two events should not be blocked as they are intended for a specific operator or handler, so there were exceptions added for this, which is one of the reasons they might work better as notifiers, but currently these things can't listen to notifier yet. * Added an option to events to indicate if the customdata should be freed or not. * Added a free() callback for area regions, and added a free function for area regions in blenkernel since it was already there for screens and areas. * Added ED_screen/area/region_exit functions to clean up things like operators and handlers when they are closed. * Added screen level regions, these will draw over areas boundaries, with the last created region on top. These are useful for tooltips, menus, etc, and are not saved to file. It's using the same ARegion struct as areas to avoid code duplication, but perhaps that should be renamed then. Note that redraws currently go correct, because only full window redraws are used, for partial redraws without any frontbuffer drawing, the window manager needs to get support for compositing subwindows. * Minor changes in the subwindow code to retrieve the matrix, and moved setlinestyle to glutil.c. * Reversed argument order in WM_event_add/remove_keymap_handler to be consistent with modal_handler. * Operators can now block events but not necessarily cancel/finish. * Modal operators are now stored in a list in the window/area/region they were created in. This means for example that when a transform operator is invoked from a region but registers a handler at the window level (since mouse motion across areas should work), it will still get removed when the region is closed while the operator is running.
2008-11-11 15:18:21 +00:00
if(fac < 0 )
prefsizey += fac;
ar->winrct= *remainder;
if(alignment==RGN_ALIGN_TOP) {
ar->winrct.ymin= ar->winrct.ymax - prefsizey + 1;
remainder->ymax= ar->winrct.ymin - 1;
}
else {
ar->winrct.ymax= ar->winrct.ymin + prefsizey - 1;
remainder->ymin= ar->winrct.ymax + 1;
}
}
}
else if( ELEM4(alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT, RGN_OVERLAP_LEFT, RGN_OVERLAP_RIGHT)) {
if( rct_fits(remainder, 'h', prefsizex) < 0 ) {
ar->flag |= RGN_FLAG_TOO_SMALL;
}
else {
int fac= rct_fits(remainder, 'h', prefsizex);
if(fac < 0 )
prefsizex += fac;
ar->winrct= *remainder;
if(ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT)) {
ar->winrct.xmin= ar->winrct.xmax - prefsizex + 1;
if(alignment==RGN_ALIGN_RIGHT)
remainder->xmax= ar->winrct.xmin - 1;
}
else {
ar->winrct.xmax= ar->winrct.xmin + prefsizex - 1;
if(alignment==RGN_ALIGN_LEFT)
remainder->xmin= ar->winrct.xmax + 1;
}
}
}
else if(alignment==RGN_ALIGN_VSPLIT || alignment==RGN_ALIGN_HSPLIT) {
/* percentage subdiv*/
ar->winrct= *remainder;
if(alignment==RGN_ALIGN_HSPLIT) {
if( rct_fits(remainder, 'h', prefsizex) > 4) {
ar->winrct.xmax= (remainder->xmin+remainder->xmax)/2;
remainder->xmin= ar->winrct.xmax+1;
}
else {
BLI_init_rcti(remainder, 0, 0, 0, 0);
}
}
else {
if( rct_fits(remainder, 'v', prefsizey) > 4) {
ar->winrct.ymax= (remainder->ymin+remainder->ymax)/2;
remainder->ymin= ar->winrct.ymax+1;
}
else {
BLI_init_rcti(remainder, 0, 0, 0, 0);
}
}
}
else if(alignment==RGN_ALIGN_QSPLIT) {
ar->winrct= *remainder;
/* test if there's still 4 regions left */
if(quad==0) {
ARegion *artest= ar->next;
int count= 1;
while(artest) {
artest->alignment= RGN_ALIGN_QSPLIT;
artest= artest->next;
count++;
}
if(count!=4) {
/* let's stop adding regions */
BLI_init_rcti(remainder, 0, 0, 0, 0);
printf("region quadsplit failed\n");
}
else quad= 1;
}
if(quad) {
if(quad==1) { /* left bottom */
ar->winrct.xmax = (remainder->xmin + remainder->xmax)/2;
ar->winrct.ymax = (remainder->ymin + remainder->ymax)/2;
}
else if(quad==2) { /* left top */
ar->winrct.xmax = (remainder->xmin + remainder->xmax)/2;
ar->winrct.ymin = 1 + (remainder->ymin + remainder->ymax)/2;
}
else if(quad==3) { /* right bottom */
ar->winrct.xmin = 1 + (remainder->xmin + remainder->xmax)/2;
ar->winrct.ymax = (remainder->ymin + remainder->ymax)/2;
}
else { /* right top */
ar->winrct.xmin = 1 + (remainder->xmin + remainder->xmax)/2;
ar->winrct.ymin = 1 + (remainder->ymin + remainder->ymax)/2;
BLI_init_rcti(remainder, 0, 0, 0, 0);
}
quad++;
}
}
/* for speedup */
ar->winx= ar->winrct.xmax - ar->winrct.xmin + 1;
ar->winy= ar->winrct.ymax - ar->winrct.ymin + 1;
/* restore test exception */
if(ar->alignment & RGN_SPLIT_PREV) {
if(ar->prev) {
remainder= remainder_prev;
ar->prev->winx= ar->prev->winrct.xmax - ar->prev->winrct.xmin + 1;
ar->prev->winy= ar->prev->winrct.ymax - ar->prev->winrct.ymin + 1;
}
}
/* set winrect for azones */
if(ar->flag & (RGN_FLAG_HIDDEN|RGN_FLAG_TOO_SMALL)) {
ar->winrct= *remainder;
if(alignment==RGN_ALIGN_TOP)
ar->winrct.ymin= ar->winrct.ymax;
else if(alignment==RGN_ALIGN_BOTTOM)
ar->winrct.ymax= ar->winrct.ymin;
else if(ELEM(alignment, RGN_ALIGN_RIGHT, RGN_OVERLAP_RIGHT))
ar->winrct.xmin= ar->winrct.xmax;
else if(ELEM(alignment, RGN_ALIGN_LEFT, RGN_OVERLAP_LEFT))
ar->winrct.xmax= ar->winrct.xmin;
else /* prevent winrct to be valid */
ar->winrct.xmax= ar->winrct.xmin;
}
/* in end, add azones, where appropriate */
region_azone_add(sa, ar, alignment);
region_rect_recursive(sa, ar->next, remainder, quad);
}
static void area_calc_totrct(ScrArea *sa, int sizex, int sizey)
{
short rt= CLAMPIS(G.rt, 0, 16);
if(sa->v1->vec.x>0) sa->totrct.xmin= sa->v1->vec.x+1+rt;
else sa->totrct.xmin= sa->v1->vec.x;
if(sa->v4->vec.x<sizex-1) sa->totrct.xmax= sa->v4->vec.x-1-rt;
else sa->totrct.xmax= sa->v4->vec.x;
if(sa->v1->vec.y>0) sa->totrct.ymin= sa->v1->vec.y+1+rt;
else sa->totrct.ymin= sa->v1->vec.y;
if(sa->v2->vec.y<sizey-1) sa->totrct.ymax= sa->v2->vec.y-1-rt;
else sa->totrct.ymax= sa->v2->vec.y;
/* for speedup */
sa->winx= sa->totrct.xmax-sa->totrct.xmin+1;
sa->winy= sa->totrct.ymax-sa->totrct.ymin+1;
}
/* used for area initialize below */
static void region_subwindow(wmWindowManager *wm, wmWindow *win, ARegion *ar)
Various changes made in the process of working on the UI code: * Added functions to generate Timer events. There was some unfinished code to create one timer per window, this replaces that with a way to let operators or other handlers add/remove their own timers as needed. This is currently delivered as an event with the timer handle, perhaps this should be a notifier instead? Also includes some fixes in ghost for timer events that were not delivered in time, due to passing negative timeout. * Added a Message event, which is a generic event that can be added by any operator. This is used in the UI code to communicate the results of opened blocks. Again, this may be better as a notifier. * These two events should not be blocked as they are intended for a specific operator or handler, so there were exceptions added for this, which is one of the reasons they might work better as notifiers, but currently these things can't listen to notifier yet. * Added an option to events to indicate if the customdata should be freed or not. * Added a free() callback for area regions, and added a free function for area regions in blenkernel since it was already there for screens and areas. * Added ED_screen/area/region_exit functions to clean up things like operators and handlers when they are closed. * Added screen level regions, these will draw over areas boundaries, with the last created region on top. These are useful for tooltips, menus, etc, and are not saved to file. It's using the same ARegion struct as areas to avoid code duplication, but perhaps that should be renamed then. Note that redraws currently go correct, because only full window redraws are used, for partial redraws without any frontbuffer drawing, the window manager needs to get support for compositing subwindows. * Minor changes in the subwindow code to retrieve the matrix, and moved setlinestyle to glutil.c. * Reversed argument order in WM_event_add/remove_keymap_handler to be consistent with modal_handler. * Operators can now block events but not necessarily cancel/finish. * Modal operators are now stored in a list in the window/area/region they were created in. This means for example that when a transform operator is invoked from a region but registers a handler at the window level (since mouse motion across areas should work), it will still get removed when the region is closed while the operator is running.
2008-11-11 15:18:21 +00:00
{
if(ar->flag & (RGN_FLAG_HIDDEN|RGN_FLAG_TOO_SMALL)) {
if(ar->swinid)
wm_subwindow_close(win, ar->swinid);
ar->swinid= 0;
}
else if(ar->swinid==0)
ar->swinid= wm_subwindow_open(win, &ar->winrct);
else
wm_subwindow_position(win, ar->swinid, &ar->winrct);
}
static void ed_default_handlers(wmWindowManager *wm, ListBase *handlers, int flag)
{
/* note, add-handler checks if it already exists */
// XXX it would be good to have boundbox checks for some of these...
if(flag & ED_KEYMAP_UI) {
UI_add_region_handlers(handlers);
}
if(flag & ED_KEYMAP_VIEW2D) {
ListBase *keymap= WM_keymap_listbase(wm, "View2D", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if(flag & ED_KEYMAP_MARKERS) {
ListBase *keymap= WM_keymap_listbase(wm, "Markers", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
// XXX need boundbox check urgently!!!
}
if(flag & ED_KEYMAP_ANIMATION) {
ListBase *keymap= WM_keymap_listbase(wm, "Animation", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if(flag & ED_KEYMAP_FRAMES) {
ListBase *keymap= WM_keymap_listbase(wm, "Frames", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if(flag & ED_KEYMAP_GPENCIL) {
ListBase *keymap= WM_keymap_listbase(wm, "Grease Pencil", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
}
/* called in screen_refresh, or screens_init, also area size changes */
void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
{
ARegion *ar;
rcti rect;
/* set typedefinitions */
sa->type= BKE_spacetype_from_id(sa->spacetype);
if(sa->type==NULL) {
sa->butspacetype= sa->spacetype= SPACE_VIEW3D;
sa->type= BKE_spacetype_from_id(sa->spacetype);
}
for(ar= sa->regionbase.first; ar; ar= ar->next)
ar->type= BKE_regiontype_from_id(sa->type, ar->regiontype);
/* area sizes */
area_calc_totrct(sa, win->sizex, win->sizey);
/* clear all azones, add the area triange widgets */
area_azone_initialize(sa);
/* region rect sizes */
rect= sa->totrct;
region_rect_recursive(sa, sa->regionbase.first, &rect, 0);
/* default area handlers */
ed_default_handlers(wm, &sa->handlers, sa->type->keymapflag);
/* checks spacedata, adds own handlers */
if(sa->type->init)
sa->type->init(wm, sa);
/* region windows, default and own handlers */
for(ar= sa->regionbase.first; ar; ar= ar->next) {
region_subwindow(wm, win, ar);
if(ar->swinid) {
/* default region handlers */
ed_default_handlers(wm, &ar->handlers, ar->type->keymapflag);
if(ar->type->init)
ar->type->init(wm, ar);
}
else {
/* prevent uiblocks to run */
uiFreeBlocks(NULL, &ar->uiblocks);
}
}
}
/* externally called for floating regions like menus */
void ED_region_init(bContext *C, ARegion *ar)
{
// ARegionType *at= ar->type;
/* refresh can be called before window opened */
region_subwindow(CTX_wm_manager(C), CTX_wm_window(C), ar);
ar->winx= ar->winrct.xmax - ar->winrct.xmin + 1;
ar->winy= ar->winrct.ymax - ar->winrct.ymin + 1;
/* UI convention */
wmLoadIdentity();
wmOrtho2(-0.01f, ar->winx-0.01f, -0.01f, ar->winy-0.01f);
}
/* sa2 to sa1, we swap spaces for fullscreen to keep all allocated data */
/* area vertices were set */
void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
{
SpaceType *st;
ARegion *ar;
sa1->headertype= sa2->headertype;
sa1->spacetype= sa2->spacetype;
sa1->butspacetype= sa2->butspacetype;
if(swap_space == 1) {
SWAP(ListBase, sa1->spacedata, sa2->spacedata);
/* exception: ensure preview is reset */
// if(sa1->spacetype==SPACE_VIEW3D)
// XXX BIF_view3d_previewrender_free(sa1->spacedata.first);
}
else if (swap_space == 2) {
BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
}
else {
BKE_spacedata_freelist(&sa1->spacedata);
BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
}
/* Note; SPACE_EMPTY is possible on new screens */
/* regions */
if(swap_space<2) {
st= BKE_spacetype_from_id(sa1->spacetype);
for(ar= sa1->regionbase.first; ar; ar= ar->next)
BKE_area_region_free(st, ar);
BLI_freelistN(&sa1->regionbase);
}
st= BKE_spacetype_from_id(sa2->spacetype);
for(ar= sa2->regionbase.first; ar; ar= ar->next) {
ARegion *newar= BKE_area_region_copy(st, ar);
BLI_addtail(&sa1->regionbase, newar);
Various changes made in the process of working on the UI code: * Added functions to generate Timer events. There was some unfinished code to create one timer per window, this replaces that with a way to let operators or other handlers add/remove their own timers as needed. This is currently delivered as an event with the timer handle, perhaps this should be a notifier instead? Also includes some fixes in ghost for timer events that were not delivered in time, due to passing negative timeout. * Added a Message event, which is a generic event that can be added by any operator. This is used in the UI code to communicate the results of opened blocks. Again, this may be better as a notifier. * These two events should not be blocked as they are intended for a specific operator or handler, so there were exceptions added for this, which is one of the reasons they might work better as notifiers, but currently these things can't listen to notifier yet. * Added an option to events to indicate if the customdata should be freed or not. * Added a free() callback for area regions, and added a free function for area regions in blenkernel since it was already there for screens and areas. * Added ED_screen/area/region_exit functions to clean up things like operators and handlers when they are closed. * Added screen level regions, these will draw over areas boundaries, with the last created region on top. These are useful for tooltips, menus, etc, and are not saved to file. It's using the same ARegion struct as areas to avoid code duplication, but perhaps that should be renamed then. Note that redraws currently go correct, because only full window redraws are used, for partial redraws without any frontbuffer drawing, the window manager needs to get support for compositing subwindows. * Minor changes in the subwindow code to retrieve the matrix, and moved setlinestyle to glutil.c. * Reversed argument order in WM_event_add/remove_keymap_handler to be consistent with modal_handler. * Operators can now block events but not necessarily cancel/finish. * Modal operators are now stored in a list in the window/area/region they were created in. This means for example that when a transform operator is invoked from a region but registers a handler at the window level (since mouse motion across areas should work), it will still get removed when the region is closed while the operator is running.
2008-11-11 15:18:21 +00:00
}
}
/* *********** Space switching code *********** */
void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
{
ScrArea *tmp= MEM_callocN(sizeof(ScrArea), "addscrarea");
ED_area_exit(C, sa1);
ED_area_exit(C, sa2);
tmp->spacetype= sa1->spacetype;
tmp->butspacetype= sa1->butspacetype;
BKE_spacedata_copyfirst(&tmp->spacedata, &sa1->spacedata);
area_copy_data(tmp, sa1, 2);
area_copy_data(sa1, sa2, 0);
area_copy_data(sa2, tmp, 0);
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa1);
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa2);
BKE_screen_area_free(tmp);
MEM_freeN(tmp);
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
ED_area_tag_redraw(sa1);
ED_area_tag_refresh(sa1);
ED_area_tag_redraw(sa2);
ED_area_tag_refresh(sa2);
}
void ED_area_newspace(bContext *C, ScrArea *sa, int type)
{
if(sa->spacetype != type) {
SpaceType *st;
SpaceLink *slold;
SpaceLink *sl;
ED_area_exit(C, sa);
st= BKE_spacetype_from_id(type);
slold= sa->spacedata.first;
sa->spacetype= type;
sa->butspacetype= type;
sa->type= st;
/* check previously stored space */
for (sl= sa->spacedata.first; sl; sl= sl->next)
if(sl->spacetype==type)
break;
/* old spacedata... happened during work on 2.50, remove */
if(sl && sl->regionbase.first==NULL) {
st->free(sl);
BLI_freelinkN(&sa->spacedata, sl);
sl= NULL;
}
if (sl) {
/* swap regions */
slold->regionbase= sa->regionbase;
sa->regionbase= sl->regionbase;
sl->regionbase.first= sl->regionbase.last= NULL;
/* put in front of list */
BLI_remlink(&sa->spacedata, sl);
BLI_addhead(&sa->spacedata, sl);
}
else {
/* new space */
if(st) {
sl= st->new(C);
BLI_addhead(&sa->spacedata, sl);
/* swap regions */
if(slold)
slold->regionbase= sa->regionbase;
sa->regionbase= sl->regionbase;
sl->regionbase.first= sl->regionbase.last= NULL;
}
}
ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
ED_area_tag_redraw(sa);
ED_area_tag_refresh(sa);
}
}
void ED_area_prevspace(bContext *C)
{
SpaceLink *sl= CTX_wm_space_data(C);
ScrArea *sa= CTX_wm_area(C);
/* cleanup */
#if 0 // XXX needs to be space type specific
if(sfile->spacetype==SPACE_FILE) {
if(sfile->pupmenu) {
MEM_freeN(sfile->pupmenu);
sfile->pupmenu= NULL;
}
}
#endif
if(sl->next) {
#if 0 // XXX check whether this is still needed
if (sfile->spacetype == SPACE_SCRIPT) {
SpaceScript *sc = (SpaceScript *)sfile;
if (sc->script) sc->script->flags &=~SCRIPT_FILESEL;
}
#endif
/* workaround for case of double prevspace, render window
with a file browser on top of it */
if(sl->next->spacetype == SPACE_FILE && sl->next->next)
ED_area_newspace(C, sa, sl->next->next->spacetype);
else
ED_area_newspace(C, sa, sl->next->spacetype);
}
else {
ED_area_newspace(C, sa, SPACE_INFO);
}
ED_area_tag_redraw(sa);
}
static char *windowtype_pup(void)
{
return(
"Window type:%t"
"|3D View %x1"
"|%l"
"|Timeline %x15"
"|Graph Editor %x2"
"|DopeSheet %x12"
"|NLA Editor %x13"
"|%l"
"|UV/Image Editor %x6"
"|Video Sequence Editor %x8"
"|Text Editor %x9"
"|Node Editor %x16"
"|Logic Editor %x17"
"|%l"
"|Properties %x4"
"|Outliner %x3"
"|User Preferences %x19"
"|Info%x7"
"|%l"
"|File Browser %x5"
"|%l"
"|Console %x18"
);
}
static void spacefunc(struct bContext *C, void *arg1, void *arg2)
{
ED_area_newspace(C, CTX_wm_area(C), CTX_wm_area(C)->butspacetype);
ED_area_tag_redraw(CTX_wm_area(C));
}
/* returns offset for next button in header */
int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
{
ScrArea *sa= CTX_wm_area(C);
uiBut *but;
int xco= 8;
but= uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D,
windowtype_pup(), xco, yco, XIC+10, YIC,
&(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0,
"Displays Current Window Type. "
"Click for menu of available types.");
uiButSetFunc(but, spacefunc, NULL, NULL);
return xco + XIC + 14;
}
int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
{
ScrArea *sa= CTX_wm_area(C);
int xco= 8;
xco= ED_area_header_switchbutton(C, block, yco);
uiBlockSetEmboss(block, UI_EMBOSSN);
if (sa->flag & HEADER_NO_PULLDOWN) {
uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_RIGHT,
xco,yco,XIC,YIC-2,
&(sa->flag), 0, 0, 0, 0,
"Show pulldown menus");
}
else {
uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_DOWN,
xco,yco,XIC,YIC-2,
&(sa->flag), 0, 0, 0, 0,
"Hide pulldown menus");
}
uiBlockSetEmboss(block, UI_EMBOSS);
return xco + XIC;
}
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
/************************ standard UI regions ************************/
void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *context, int contextnr)
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
{
ScrArea *sa= CTX_wm_area(C);
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
uiStyle *style= U.uistyles.first;
uiBlock *block;
PanelType *pt;
Panel *panel;
View2D *v2d= &ar->v2d;
View2DScrollers *scrollers;
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
float col[3];
int xco, yco, x, y, miny=0, w, em, header, triangle, open, newcontext= 0;
if(contextnr >= 0)
newcontext= UI_view2d_tab_set(v2d, contextnr);
if(vertical) {
w= v2d->cur.xmax - v2d->cur.xmin;
em= (ar->type->minsizex)? 10: 20;
}
else {
w= UI_PANEL_WIDTH;
em= (ar->type->minsizex)? 10: 20;
}
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
x= 0;
y= -style->panelouter;
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
/* create panels */
uiBeginPanels(C, ar);
/* set view2d view matrix for scrolling (without scrollers) */
UI_view2d_view_ortho(C, v2d);
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
for(pt= ar->type->paneltypes.first; pt; pt= pt->next) {
/* verify context */
if(context)
if(pt->context[0] && strcmp(context, pt->context) != 0)
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
continue;
/* draw panel */
if(pt->draw && (!pt->poll || pt->poll(C, pt))) {
block= uiBeginBlock(C, ar, pt->idname, UI_EMBOSS);
panel= uiBeginPanel(sa, ar, block, pt, &open);
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
/* bad fixed values */
header= (pt->flag & PNL_NO_HEADER)? 0: 20;
triangle= 22;
if(vertical)
y -= header;
if(pt->draw_header && header && (open || vertical)) {
/* for enabled buttons */
panel->layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
triangle, header+style->panelspace, header, 1, style);
pt->draw_header(C, panel);
uiBlockLayoutResolve(C, block, &xco, &yco);
panel->labelofs= xco - triangle;
panel->layout= NULL;
}
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
if(open) {
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
panel->layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL,
style->panelspace, 0, w-2*style->panelspace, em, style);
pt->draw(C, panel);
uiBlockLayoutResolve(C, block, &xco, &yco);
panel->layout= NULL;
yco -= 2*style->panelspace;
uiEndPanel(block, w, -yco);
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
}
else {
yco= 0;
uiEndPanel(block, w, 0);
}
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
uiEndBlock(C, block);
if(vertical) {
if(pt->flag & PNL_NO_HEADER)
y += yco;
else
y += yco-style->panelouter;
}
else {
x += w;
miny= MIN2(y, yco-style->panelouter-header);
}
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
}
}
if(vertical)
x += w;
else
y= miny;
/* in case there are no panels */
if(x == 0 || y == 0) {
x= UI_PANEL_WIDTH;
y= UI_PANEL_WIDTH;
}
/* clear */
UI_GetThemeColor3fv(TH_BACK, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* before setting the view */
if(vertical) {
/* only allow scrolling in vertical direction */
v2d->keepofs |= V2D_LOCKOFS_X|V2D_KEEPOFS_Y;
v2d->keepofs &= ~(V2D_LOCKOFS_Y|V2D_KEEPOFS_X);
// don't jump back when panels close or hide
if(!newcontext)
y= MAX2(-y, -v2d->cur.ymin);
else
y= -y;
}
else {
/* for now, allow scrolling in both directions (since layouts are optimised for vertical,
* they often don't fit in horizontal layout)
*/
v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_LOCKOFS_Y|V2D_KEEPOFS_X|V2D_KEEPOFS_Y);
//v2d->keepofs |= V2D_LOCKOFS_Y|V2D_KEEPOFS_X;
//v2d->keepofs &= ~(V2D_LOCKOFS_X|V2D_KEEPOFS_Y);
// don't jump back when panels close or hide
if(!newcontext)
x= MAX2(x, v2d->cur.xmax);
y= -y;
}
// +V2D_SCROLL_HEIGHT is workaround to set the actual height
UI_view2d_totRect_set(v2d, x+V2D_SCROLL_WIDTH, y+V2D_SCROLL_HEIGHT);
/* set the view */
UI_view2d_view_ortho(C, v2d);
/* this does the actual drawing! */
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
uiEndPanels(C, ar);
/* restore view matrix */
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
UI_view2d_view_restore(C);
/* scrollers */
scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
}
void ED_region_panels_init(wmWindowManager *wm, ARegion *ar)
{
ListBase *keymap;
// XXX quick hacks for files saved with 2.5 already (i.e. the builtin defaults file)
// scrollbars for button regions
ar->v2d.scroll |= (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
ar->v2d.keepzoom |= V2D_KEEPZOOM;
// correctly initialised User-Prefs?
if(!(ar->v2d.align & V2D_ALIGN_NO_POS_Y))
ar->v2d.flag &= ~V2D_IS_INITIALISED;
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0);
WM_event_add_keymap_handler(&ar->handlers, keymap);
}
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
void ED_region_header(const bContext *C, ARegion *ar)
{
uiStyle *style= U.uistyles.first;
uiBlock *block;
uiLayout *layout;
HeaderType *ht;
Header header = {0};
float col[3];
int maxco, xco, yco;
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
/* clear */
if(ED_screen_area_active(C))
UI_GetThemeColor3fv(TH_HEADER, col);
else
UI_GetThemeColor3fv(TH_HEADERDESEL, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* set view2d view matrix for scrolling (without scrollers) */
UI_view2d_view_ortho(C, &ar->v2d);
xco= maxco= 8;
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
yco= HEADERY-3;
/* draw all headers types */
for(ht= ar->type->headertypes.first; ht; ht= ht->next) {
block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS);
layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, HEADERY-6, 1, style);
if(ht->draw) {
header.type= ht;
header.layout= layout;
ht->draw(C, &header);
/* for view2d */
xco= uiLayoutGetWidth(layout);
if(xco > maxco)
maxco= xco;
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
}
uiBlockLayoutResolve(C, block, &xco, &yco);
/* for view2d */
if(xco > maxco)
maxco= xco;
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
uiEndBlock(C, block);
uiDrawBlock(C, block);
}
/* always as last */
UI_view2d_totRect_set(&ar->v2d, maxco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
UI: Layout Engine * Buttons are now created first, and after that the layout is computed. This means the layout engine now works at button level, and makes it easier to write templates. Otherwise you had to store all info and create the buttons later. * Added interface_templates.c as a separate file to put templates in. These can contain regular buttons, and can be put in a Free layout, which means you can specify manual coordinates, but still get nested correct inside other layouts. * API was changed to allow better nesting. Previously items were added in the last added layout specifier, i.e. one level up in the layout hierarchy. This doesn't work well in always, so now when creating things like rows or columns it always returns a layout which you have to add the items in. All py scripts were updated to follow this. * Computing the layout now goes in two passes, first estimating the required width/height of all nested layouts, and then in the second pass using the results of that to decide on the actual locations. * Enum and array buttons now follow the direction of the layout, i.e. they are vertical or horizontal depending if they are in a column or row. * Color properties now get a color picker, and only get the additional RGB sliders with Expand=True. * File/directory string properties now get a button next to them for opening the file browse, though this is not implemented yet. * Layout items can now be aligned, set align=True when creating a column, row, etc. * Buttons now get a minimum width of one icon (avoids squashing icon buttons). * Moved some more space variables into Style.
2009-05-15 11:19:59 +00:00
/* restore view matrix? */
UI_view2d_view_restore(C);
}
void ED_region_header_init(ARegion *ar)
{
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
}