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
/**
* $ 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 .
*
* Contributor ( s ) : Blender Foundation 2009.
*
* * * * * * END GPL LICENSE BLOCK * * * * *
*/
# include <stdlib.h>
2009-06-07 13:20:41 +00:00
# include <string.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 "MEM_guardedalloc.h"
2009-06-27 01:15:31 +00:00
# include "DNA_scene_types.h"
2009-06-24 17:22:22 +00:00
# include "DNA_screen_types.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 "BLI_string.h"
# include "BKE_context.h"
2009-06-24 17:22:22 +00:00
# include "BKE_icons.h"
2009-06-27 01:15:31 +00:00
# include "BKE_global.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 "BKE_library.h"
# include "BKE_utildefines.h"
# include "ED_screen.h"
2009-06-07 11:12:35 +00:00
# include "ED_previewrender.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 "RNA_access.h"
# include "WM_api.h"
# include "WM_types.h"
# include "UI_interface.h"
# include "UI_resources.h"
2009-06-25 15:41:27 +00:00
# include "interface_intern.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
void ui_template_fix_linking ( )
{
}
/********************** Header Template *************************/
2009-08-18 12:56:43 +00:00
void uiTemplateHeader ( uiLayout * layout , bContext * C , int menus )
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
{
uiBlock * block ;
2009-05-19 17:13:33 +00:00
block = uiLayoutFreeBlock ( layout ) ;
2009-08-18 12:56:43 +00:00
if ( menus ) ED_area_header_standardbuttons ( C , block , 0 ) ;
else ED_area_header_switchbutton ( C , block , 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
}
2009-06-27 01:15:31 +00:00
/********************** Search Callbacks *************************/
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
2009-06-07 13:20:41 +00:00
typedef struct TemplateID {
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
PointerRNA ptr ;
PropertyRNA * prop ;
2009-06-27 01:15:31 +00:00
ListBase * idlb ;
2009-06-07 13:20:41 +00:00
} TemplateID ;
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
2009-06-27 01:15:31 +00:00
/* Search browse menu, assign */
static void id_search_call_cb ( struct bContext * C , void * arg_template , void * item )
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
{
2009-06-27 01:15:31 +00:00
TemplateID * template = ( TemplateID * ) arg_template ;
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
2009-06-27 01:15:31 +00:00
/* ID */
2009-06-11 17:21:27 +00:00
if ( item ) {
2009-06-27 01:15:31 +00:00
PointerRNA idptr ;
2009-06-11 17:21:27 +00:00
RNA_id_pointer_create ( item , & idptr ) ;
RNA_property_pointer_set ( & template - > ptr , template - > prop , idptr ) ;
RNA_property_update ( C , & template - > ptr , template - > prop ) ;
2009-06-27 01:15:31 +00:00
}
2009-06-11 17:21:27 +00:00
}
/* ID Search browse menu, do the search */
2009-06-27 01:15:31 +00:00
static void id_search_cb ( const struct bContext * C , void * arg_template , char * str , uiSearchItems * items )
2009-06-11 17:21:27 +00:00
{
2009-06-27 01:15:31 +00:00
TemplateID * template = ( TemplateID * ) arg_template ;
Scene * scene = CTX_data_scene ( C ) ;
ListBase * lb = template - > idlb ;
2009-06-11 17:21:27 +00:00
ID * id ;
2009-06-27 01:15:31 +00:00
int iconid ;
/* ID listbase */
2009-06-11 17:21:27 +00:00
for ( id = lb - > first ; id ; id = id - > next ) {
2009-07-21 01:26:17 +00:00
if ( BLI_strcasestr ( id - > name + 2 , str ) ) {
iconid = ui_id_icon_get ( scene , id ) ;
2009-06-27 01:15:31 +00:00
if ( ! uiSearchItemAdd ( items , id - > name + 2 , id , iconid ) )
2009-06-11 17:21:27 +00:00
break ;
2009-07-21 01:26:17 +00:00
}
2009-06-11 17:21:27 +00:00
}
}
/* ID Search browse menu, open */
2009-06-27 01:15:31 +00:00
static uiBlock * search_menu ( bContext * C , ARegion * ar , void * arg_litem )
2009-06-11 17:21:27 +00:00
{
static char search [ 256 ] ;
static TemplateID template ;
2009-06-29 11:29:52 +00:00
PointerRNA idptr ;
2009-06-11 17:21:27 +00:00
wmEvent event ;
wmWindow * win = CTX_wm_window ( C ) ;
uiBlock * block ;
uiBut * but ;
/* clear initial search string, then all items show */
search [ 0 ] = 0 ;
/* arg_litem is malloced, can be freed by parent button */
template = * ( ( TemplateID * ) arg_litem ) ;
2009-06-29 11:29:52 +00:00
/* get active id for showing first item */
idptr = RNA_property_pointer_get ( & template . ptr , template . prop ) ;
2009-06-11 17:21:27 +00:00
block = uiBeginBlock ( C , ar , " _popup " , UI_EMBOSS ) ;
uiBlockSetFlag ( block , UI_BLOCK_LOOP | UI_BLOCK_REDRAW | UI_BLOCK_RET_1 ) ;
/* fake button, it holds space for search items */
uiDefBut ( block , LABEL , 0 , " " , 10 , 15 , 150 , uiSearchBoxhHeight ( ) , NULL , 0 , 0 , 0 , 0 , NULL ) ;
but = uiDefSearchBut ( block , search , 0 , ICON_VIEWZOOM , 256 , 10 , 0 , 150 , 19 , " " ) ;
2009-06-29 11:29:52 +00:00
uiButSetSearchFunc ( but , id_search_cb , & template , id_search_call_cb , idptr . data ) ;
2009-06-11 17:21:27 +00:00
uiBoundsBlock ( block , 6 ) ;
uiBlockSetDirection ( block , UI_DOWN ) ;
uiEndBlock ( C , block ) ;
event = * ( win - > eventstate ) ; /* XXX huh huh? make api call */
event . type = EVT_BUT_OPEN ;
event . val = KM_PRESS ;
event . customdata = but ;
event . customdatafree = FALSE ;
wm_event_add ( win , & event ) ;
return block ;
}
2009-06-27 01:15:31 +00:00
/************************ ID Template ***************************/
2009-06-11 17:21:27 +00:00
2009-06-27 01:15:31 +00:00
static void template_id_cb ( bContext * C , void * arg_litem , void * arg_event )
{
TemplateID * template = ( TemplateID * ) arg_litem ;
PointerRNA idptr = RNA_property_pointer_get ( & template - > ptr , template - > prop ) ;
2009-09-04 21:02:43 +00:00
ID * id = idptr . data , * newid ;
2009-06-27 01:15:31 +00:00
int event = GET_INT_FROM_POINTER ( arg_event ) ;
switch ( event ) {
case UI_ID_BROWSE :
case UI_ID_PIN :
2009-06-30 19:20:45 +00:00
printf ( " warning, id event %d shouldnt come here \n " , event ) ;
break ;
2009-06-27 01:15:31 +00:00
case UI_ID_OPEN :
case UI_ID_ADD_NEW :
2009-06-30 19:20:45 +00:00
if ( template - > idlb - > last ) {
RNA_id_pointer_create ( template - > idlb - > last , & idptr ) ;
RNA_property_pointer_set ( & template - > ptr , template - > prop , idptr ) ;
RNA_property_update ( C , & template - > ptr , template - > prop ) ;
}
2009-06-27 01:15:31 +00:00
break ;
case UI_ID_DELETE :
memset ( & idptr , 0 , sizeof ( idptr ) ) ;
RNA_property_pointer_set ( & template - > ptr , template - > prop , idptr ) ;
RNA_property_update ( C , & template - > ptr , template - > prop ) ;
break ;
case UI_ID_FAKE_USER :
if ( id ) {
if ( id - > flag & LIB_FAKEUSER ) id - > us + + ;
else id - > us - - ;
}
else return ;
break ;
case UI_ID_LOCAL :
2009-09-04 21:02:43 +00:00
if ( id ) {
if ( id_make_local ( id , 0 ) ) {
/* reassign to get get proper updates/notifiers */
idptr = RNA_property_pointer_get ( & template - > ptr , template - > prop ) ;
RNA_property_pointer_set ( & template - > ptr , template - > prop , idptr ) ;
RNA_property_update ( C , & template - > ptr , template - > prop ) ;
}
}
2009-06-27 01:15:31 +00:00
break ;
2009-09-04 21:02:43 +00:00
case UI_ID_ALONE :
if ( id ) {
/* make copy */
if ( id_copy ( id , & newid , 0 ) & & newid ) {
/* us is 1 by convention, but RNA_property_pointer_set
will also incremement it , so set it to zero */
newid - > us = 0 ;
/* assign copy */
RNA_id_pointer_create ( newid , & idptr ) ;
RNA_property_pointer_set ( & template - > ptr , template - > prop , idptr ) ;
RNA_property_update ( C , & template - > ptr , template - > prop ) ;
}
}
break ;
#if 0
2009-06-27 01:15:31 +00:00
case UI_ID_AUTO_NAME :
break ;
# endif
}
}
2009-06-11 17:21:27 +00:00
2009-09-04 21:02:43 +00:00
static void template_ID ( bContext * C , uiBlock * block , TemplateID * template , StructRNA * type , int flag , char * newop , char * openop , char * unlinkop )
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
{
uiBut * but ;
PointerRNA idptr ;
ListBase * lb ;
2009-09-04 21:02:43 +00:00
ID * id , * idfrom ;
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
idptr = RNA_property_pointer_get ( & template - > ptr , template - > prop ) ;
2009-09-04 21:02:43 +00:00
id = idptr . data ;
idfrom = template - > ptr . id . data ;
2009-06-27 01:15:31 +00:00
lb = template - > idlb ;
2009-06-07 13:20:41 +00:00
2009-06-30 19:20:45 +00:00
uiBlockBeginAlign ( block ) ;
2009-06-07 13:20:41 +00:00
if ( idptr . type )
type = idptr . type ;
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
2009-07-09 19:45:27 +00:00
if ( flag & UI_ID_BROWSE ) {
but = uiDefBlockButN ( block , search_menu , MEM_dupallocN ( template ) , " " , 0 , 0 , UI_UNIT_X * 1.6 , UI_UNIT_Y , " Browse ID data " ) ;
if ( type ) {
but - > icon = RNA_struct_ui_icon ( type ) ;
but - > flag | = UI_HAS_ICON ;
but - > flag | = UI_ICON_LEFT ;
}
2009-09-04 21:02:43 +00:00
if ( ( idfrom & & idfrom - > lib ) )
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
2009-07-09 19:45:27 +00:00
}
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
/* text button with name */
2009-09-04 21:02:43 +00:00
if ( id ) {
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
char name [ 64 ] ;
2009-09-04 21:02:43 +00:00
//text_idbutton(id, name);
2009-06-07 13:20:41 +00:00
name [ 0 ] = ' \0 ' ;
but = uiDefButR ( block , TEX , 0 , name , 0 , 0 , UI_UNIT_X * 6 , UI_UNIT_Y , & idptr , " name " , - 1 , 0 , 0 , - 1 , - 1 , NULL ) ;
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_RENAME ) ) ;
2009-09-04 21:02:43 +00:00
if ( id - > lib ) {
if ( id - > flag & LIB_INDIRECT ) {
but = uiDefIconBut ( block , BUT , 0 , ICON_LIBRARY_DATA_INDIRECT , 0 , 0 , UI_UNIT_X , UI_UNIT_Y , 0 , 0 , 0 , 0 , 0 ,
" Indirect library datablock, cannot change. " ) ;
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
}
else {
but = uiDefIconBut ( block , BUT , 0 , ICON_LIBRARY_DATA_DIRECT , 0 , 0 , UI_UNIT_X , UI_UNIT_Y , 0 , 0 , 0 , 0 , 0 ,
" Direct linked library datablock, click to make local. " ) ;
if ( ! id_make_local ( id , 1 /* test */ ) | | ( idfrom & & idfrom - > lib ) )
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
}
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_LOCAL ) ) ;
}
if ( id - > us > 1 ) {
char str [ 32 ] ;
sprintf ( str , " %d " , id - > us ) ;
if ( id - > us < 10 )
but = uiDefBut ( block , BUT , 0 , str , 0 , 0 , UI_UNIT_X , UI_UNIT_Y , 0 , 0 , 0 , 0 , 0 , " Displays number of users of this data. Click to make a single-user copy. " ) ;
else
but = uiDefBut ( block , BUT , 0 , str , 0 , 0 , UI_UNIT_X + 10 , UI_UNIT_Y , 0 , 0 , 0 , 0 , 0 , " Displays number of users of this data. Click to make a single-user copy. " ) ;
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_ALONE ) ) ;
if ( ! id_copy ( id , NULL , 1 /* test only */ ) | | ( idfrom & & idfrom - > lib ) )
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
}
2009-06-11 17:21:27 +00:00
}
2009-06-27 01:15:31 +00:00
if ( flag & UI_ID_ADD_NEW ) {
2009-09-04 21:02:43 +00:00
int w = id ? UI_UNIT_X : ( flag & UI_ID_OPEN ) ? UI_UNIT_X * 3 : UI_UNIT_X * 6 ;
2009-06-11 17:21:27 +00:00
2009-06-27 01:15:31 +00:00
if ( newop ) {
2009-09-04 21:02:43 +00:00
but = uiDefIconTextButO ( block , BUT , newop , WM_OP_INVOKE_REGION_WIN , ICON_ZOOMIN , ( id ) ? " " : " New " , 0 , 0 , w , UI_UNIT_Y , NULL ) ;
2009-06-30 19:20:45 +00:00
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_ADD_NEW ) ) ;
2009-06-11 17:21:27 +00:00
}
else {
2009-09-04 21:02:43 +00:00
but = uiDefIconTextBut ( block , BUT , 0 , ICON_ZOOMIN , ( id ) ? " " : " New " , 0 , 0 , w , UI_UNIT_Y , NULL , 0 , 0 , 0 , 0 , NULL ) ;
2009-06-11 17:21:27 +00:00
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_ADD_NEW ) ) ;
}
2009-09-04 21:02:43 +00:00
if ( ( idfrom & & idfrom - > lib ) )
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
}
if ( flag & UI_ID_OPEN ) {
int w = id ? UI_UNIT_X : ( flag & UI_ID_ADD_NEW ) ? UI_UNIT_X * 3 : UI_UNIT_X * 6 ;
if ( openop ) {
but = uiDefIconTextButO ( block , BUT , openop , WM_OP_INVOKE_REGION_WIN , ICON_FILESEL , ( id ) ? " " : " Open " , 0 , 0 , w , UI_UNIT_Y , NULL ) ;
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_OPEN ) ) ;
}
else {
but = uiDefIconTextBut ( block , BUT , 0 , ICON_FILESEL , ( id ) ? " " : " Open " , 0 , 0 , w , UI_UNIT_Y , NULL , 0 , 0 , 0 , 0 , NULL ) ;
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_OPEN ) ) ;
}
if ( ( idfrom & & idfrom - > lib ) )
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
2009-06-11 17:21:27 +00:00
}
/* delete button */
2009-09-04 21:02:43 +00:00
if ( id & & ( flag & UI_ID_DELETE ) ) {
2009-06-27 01:15:31 +00:00
if ( unlinkop ) {
2009-08-15 16:43:03 +00:00
but = uiDefIconButO ( block , BUT , unlinkop , WM_OP_INVOKE_REGION_WIN , ICON_X , 0 , 0 , UI_UNIT_X , UI_UNIT_Y , NULL ) ;
2009-06-11 17:21:27 +00:00
}
else {
but = uiDefIconBut ( block , BUT , 0 , ICON_X , 0 , 0 , UI_UNIT_X , UI_UNIT_Y , NULL , 0 , 0 , 0 , 0 , NULL ) ;
uiButSetNFunc ( but , template_id_cb , MEM_dupallocN ( template ) , SET_INT_IN_POINTER ( UI_ID_DELETE ) ) ;
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
}
2009-09-04 21:02:43 +00:00
if ( ( idfrom & & idfrom - > lib ) )
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
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
}
2009-06-11 17:21:27 +00:00
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
uiBlockEndAlign ( block ) ;
}
2009-09-04 21:02:43 +00:00
void uiTemplateID ( uiLayout * layout , bContext * C , PointerRNA * ptr , char * propname , char * newop , char * openop , char * unlinkop )
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
{
2009-06-07 13:20:41 +00:00
TemplateID * template ;
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
uiBlock * block ;
PropertyRNA * prop ;
2009-06-07 13:20:41 +00:00
StructRNA * type ;
2009-06-27 01:15:31 +00:00
int flag ;
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 ( ! ptr - > data )
return ;
prop = RNA_struct_find_property ( ptr , propname ) ;
2009-06-07 13:20:41 +00:00
if ( ! prop | | RNA_property_type ( prop ) ! = PROP_POINTER ) {
printf ( " uiTemplateID: pointer property not found: %s \n " , propname ) ;
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
return ;
}
2009-06-07 13:20:41 +00:00
template = MEM_callocN ( sizeof ( TemplateID ) , " TemplateID " ) ;
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
template - > ptr = * ptr ;
template - > prop = prop ;
2009-06-27 01:15:31 +00:00
flag = UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE ;
if ( newop )
flag | = UI_ID_ADD_NEW ;
2009-09-04 21:02:43 +00:00
if ( openop )
flag | = UI_ID_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
2009-06-07 13:20:41 +00:00
type = RNA_property_pointer_type ( ptr , prop ) ;
2009-06-27 01:15:31 +00:00
template - > idlb = wich_libbase ( CTX_data_main ( C ) , RNA_type_to_ID_code ( type ) ) ;
2009-06-07 13:20:41 +00:00
2009-06-27 01:15:31 +00:00
if ( template - > idlb ) {
2009-06-07 13:20:41 +00:00
uiLayoutRow ( layout , 1 ) ;
block = uiLayoutGetBlock ( layout ) ;
2009-09-04 21:02:43 +00:00
template_ID ( C , block , template , type , flag , newop , openop , unlinkop ) ;
2009-06-07 13:20:41 +00:00
}
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
MEM_freeN ( template ) ;
}
2009-05-21 15:34:09 +00:00
/************************ Modifier Template *************************/
# define ERROR_LIBDATA_MESSAGE "Can't edit external libdata"
# include <string.h>
# include "DNA_object_force.h"
# include "DNA_object_types.h"
# include "DNA_modifier_types.h"
# include "DNA_scene_types.h"
# include "BKE_depsgraph.h"
# include "BKE_DerivedMesh.h"
# include "BKE_global.h"
# include "BKE_modifier.h"
# include "BKE_object.h"
# include "BKE_particle.h"
# include "BKE_report.h"
# include "UI_resources.h"
# include "ED_util.h"
# include "BLI_arithb.h"
# include "BLI_listbase.h"
# include "ED_object.h"
static void modifiers_setOnCage ( bContext * C , void * ob_v , void * md_v )
{
Object * ob = ob_v ;
ModifierData * md ;
int i , cageIndex = modifiers_getCageIndex ( ob , NULL ) ;
2009-06-03 00:09:30 +00:00
for ( i = 0 , md = ob - > modifiers . first ; md ; + + i , md = md - > next ) {
if ( md = = md_v ) {
if ( i > = cageIndex )
2009-05-21 15:34:09 +00:00
md - > mode ^ = eModifierMode_OnCage ;
break ;
}
2009-06-03 00:09:30 +00:00
}
WM_event_add_notifier ( C , NC_OBJECT | ND_MODIFIER , ob ) ;
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
DAG_id_flush_update ( & ob - > id , OB_RECALC_DATA ) ;
2009-05-21 15:34:09 +00:00
}
2009-05-27 00:03:49 +00:00
static void modifiers_convertToReal ( bContext * C , void * ob_v , void * md_v )
{
Object * ob = ob_v ;
ModifierData * md = md_v ;
ModifierData * nmd = modifier_new ( md - > type ) ;
modifier_copyData ( md , nmd ) ;
nmd - > mode & = ~ eModifierMode_Virtual ;
BLI_addhead ( & ob - > modifiers , nmd ) ;
ob - > partype = PAROBJECT ;
2009-06-03 00:09:30 +00:00
WM_event_add_notifier ( C , NC_OBJECT | ND_MODIFIER , ob ) ;
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
DAG_id_flush_update ( & ob - > id , OB_RECALC_DATA ) ;
2009-05-21 15:34:09 +00:00
2009-06-03 00:09:30 +00:00
ED_undo_push ( C , " Modifier convert to real " ) ;
2009-05-21 15:34:09 +00:00
}
2009-06-03 00:09:30 +00:00
static int modifier_can_delete ( ModifierData * md )
2009-05-21 15:34:09 +00:00
{
2009-06-03 00:09:30 +00:00
// fluid particle modifier can't be deleted here
if ( md - > type = = eModifierType_ParticleSystem )
2009-05-21 15:34:09 +00:00
if ( ( ( ParticleSystemModifierData * ) md ) - > psys - > part - > type = = PART_FLUID )
2009-06-03 00:09:30 +00:00
return 0 ;
return 1 ;
2009-05-21 15:34:09 +00:00
}
2009-05-27 00:03:49 +00:00
static uiLayout * draw_modifier ( uiLayout * layout , Object * ob , ModifierData * md , int index , int cageIndex , int lastCageIndex )
2009-05-21 15:34:09 +00:00
{
ModifierTypeInfo * mti = modifierType_getInfo ( md - > type ) ;
2009-06-03 00:09:30 +00:00
PointerRNA ptr ;
2009-05-21 15:34:09 +00:00
uiBut * but ;
uiBlock * block ;
2009-07-02 19:41:31 +00:00
uiLayout * column , * row , * result = NULL ;
int isVirtual = md - > mode & eModifierMode_Virtual ;
2009-06-03 00:09:30 +00:00
// XXX short color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
2009-05-21 15:34:09 +00:00
char str [ 128 ] ;
2009-07-02 19:41:31 +00:00
/* create RNA pointer */
2009-06-03 00:09:30 +00:00
RNA_pointer_create ( & ob - > id , & RNA_Modifier , md , & ptr ) ;
2009-05-21 15:34:09 +00:00
column = uiLayoutColumn ( layout , 1 ) ;
2009-06-03 00:09:30 +00:00
uiLayoutSetContextPointer ( column , " modifier " , & ptr ) ;
2009-05-21 15:34:09 +00:00
/* rounded header */
/* XXX uiBlockSetCol(block, color); */
/* roundbox 4 free variables: corner-rounding, nop, roundbox type, shade */
2009-06-03 00:09:30 +00:00
row = uiLayoutRow ( uiLayoutBox ( column ) , 0 ) ;
2009-07-02 19:41:31 +00:00
uiLayoutSetAlignment ( row , UI_LAYOUT_ALIGN_EXPAND ) ;
2009-06-03 00:09:30 +00:00
2009-07-02 19:41:31 +00:00
block = uiLayoutGetBlock ( row ) ;
2009-05-21 15:34:09 +00:00
//uiDefBut(block, ROUNDBOX, 0, "", x-10, y-4, width, 25, NULL, 7.0, 0.0,
2009-07-02 19:41:31 +00:00
// (!isVirtual && (md->mode & eModifierMode_Expanded))?3:15, 20, "");
2009-05-21 15:34:09 +00:00
/* XXX uiBlockSetCol(block, TH_AUTO); */
/* open/close icon */
2009-07-02 19:41:31 +00:00
if ( ! isVirtual ) {
2009-05-21 15:34:09 +00:00
uiBlockSetEmboss ( block , UI_EMBOSSN ) ;
2009-06-03 00:09:30 +00:00
uiDefIconButBitI ( block , ICONTOG , eModifierMode_Expanded , 0 , ICON_TRIA_RIGHT , 0 , 0 , UI_UNIT_X , UI_UNIT_Y , & md - > mode , 0.0 , 0.0 , 0.0 , 0.0 , " Collapse/Expand Modifier " ) ;
2009-05-21 15:34:09 +00:00
}
2009-06-23 11:28:48 +00:00
/* modifier-type icon */
2009-07-02 19:41:31 +00:00
uiItemL ( row , " " , RNA_struct_ui_icon ( ptr . type ) ) ;
2009-06-23 11:28:48 +00:00
2009-05-21 15:34:09 +00:00
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
2009-07-02 19:41:31 +00:00
if ( isVirtual ) {
/* virtual modifier */
2009-05-21 15:34:09 +00:00
sprintf ( str , " %s parent deform " , md - > name ) ;
2009-06-03 00:09:30 +00:00
uiDefBut ( block , LABEL , 0 , str , 0 , 0 , 185 , UI_UNIT_Y , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Modifier name " ) ;
2009-05-21 15:34:09 +00:00
2009-06-03 00:09:30 +00:00
but = uiDefBut ( block , BUT , 0 , " Make Real " , 0 , 0 , 80 , 16 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Convert virtual modifier to a real modifier " ) ;
2009-05-21 15:34:09 +00:00
uiButSetFunc ( but , modifiers_convertToReal , ob , md ) ;
2009-07-02 19:41:31 +00:00
}
else {
/* real modifier */
2009-05-21 15:34:09 +00:00
uiBlockBeginAlign ( block ) ;
2009-08-21 12:57:47 +00:00
uiItemR ( row , " " , 0 , & ptr , " name " , 0 ) ;
2009-05-21 15:34:09 +00:00
/* Softbody not allowed in this situation, enforce! */
2009-07-02 19:41:31 +00:00
if ( ( ( md - > type ! = eModifierType_Softbody & & md - > type ! = eModifierType_Collision ) | | ! ( ob - > pd & & ob - > pd - > deflect ) ) & & ( md - > type ! = eModifierType_Surface ) ) {
2009-08-21 12:57:47 +00:00
uiItemR ( row , " " , ICON_SCENE , & ptr , " render " , 0 ) ;
uiItemR ( row , " " , ICON_RESTRICT_VIEW_OFF , & ptr , " realtime " , 0 ) ;
2009-07-02 19:41:31 +00:00
if ( mti - > flags & eModifierTypeFlag_SupportsEditmode )
2009-08-21 12:57:47 +00:00
uiItemR ( row , " " , ICON_EDITMODE_HLT , & ptr , " editmode " , 0 ) ;
2009-05-21 15:34:09 +00:00
}
2009-07-31 10:21:29 +00:00
2009-05-21 15:34:09 +00:00
/* XXX uiBlockSetEmboss(block, UI_EMBOSSR); */
2009-07-02 19:41:31 +00:00
if ( ob - > type = = OB_MESH & & modifier_couldBeCage ( md ) & & index < = lastCageIndex ) {
2009-07-31 10:21:29 +00:00
2009-05-21 15:34:09 +00:00
/* XXX uiBlockSetCol(block, color); */
2009-07-31 10:21:29 +00:00
but = uiDefIconBut ( block , BUT , 0 , ICON_MESH_DATA , 0 , 0 , 16 , 20 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Apply modifier to editing cage during Editmode " ) ;
2009-05-21 15:34:09 +00:00
uiButSetFunc ( but , modifiers_setOnCage , ob , md ) ;
2009-07-31 10:21:29 +00:00
uiBlockEndAlign ( block ) ;
2009-05-21 15:34:09 +00:00
/* XXX uiBlockSetCol(block, TH_AUTO); */
}
2009-06-03 00:09:30 +00:00
}
2009-05-21 15:34:09 +00:00
2009-07-02 19:41:31 +00:00
/* up/down/delete */
2009-06-03 00:09:30 +00:00
if ( ! isVirtual ) {
2009-05-21 15:34:09 +00:00
/* XXX uiBlockSetCol(block, TH_BUT_ACTION); */
2009-07-31 10:21:29 +00:00
uiBlockBeginAlign ( block ) ;
2009-07-02 19:41:31 +00:00
uiItemO ( row , " " , VICON_MOVE_UP , " OBJECT_OT_modifier_move_up " ) ;
uiItemO ( row , " " , VICON_MOVE_DOWN , " OBJECT_OT_modifier_move_down " ) ;
2009-07-31 10:21:29 +00:00
uiBlockEndAlign ( block ) ;
2009-05-21 15:34:09 +00:00
uiBlockSetEmboss ( block , UI_EMBOSSN ) ;
2009-07-02 19:41:31 +00:00
if ( modifier_can_delete ( md ) )
uiItemO ( row , " " , VICON_X , " OBJECT_OT_modifier_remove " ) ;
2009-05-21 15:34:09 +00:00
/* XXX uiBlockSetCol(block, TH_AUTO); */
}
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
2009-07-02 19:41:31 +00:00
if ( ! isVirtual & & ( md - > mode & eModifierMode_Expanded ) ) {
/* apply/convert/copy */
2009-05-21 15:34:09 +00:00
uiLayout * box ;
box = uiLayoutBox ( column ) ;
row = uiLayoutRow ( box , 1 ) ;
2009-07-02 19:41:31 +00:00
if ( ! isVirtual & & ( md - > type ! = eModifierType_Collision ) & & ( md - > type ! = eModifierType_Surface ) ) {
/* only here obdata, the rest of modifiers is ob level */
uiBlockSetButLock ( block , object_data_is_libdata ( ob ) , ERROR_LIBDATA_MESSAGE ) ;
2009-05-21 15:34:09 +00:00
2009-07-02 19:41:31 +00:00
if ( md - > type = = eModifierType_ParticleSystem ) {
2009-05-21 15:34:09 +00:00
ParticleSystem * psys = ( ( ParticleSystemModifierData * ) md ) - > psys ;
2009-08-16 02:35:44 +00:00
if ( ! ( ob - > mode & OB_MODE_PARTICLE_EDIT ) )
2009-07-04 03:50:12 +00:00
if ( ELEM3 ( psys - > part - > ren_as , PART_DRAW_PATH , PART_DRAW_GR , PART_DRAW_OB ) & & psys - > pathcache )
2009-07-02 19:41:31 +00:00
uiItemO ( row , " Convert " , 0 , " OBJECT_OT_modifier_convert " ) ;
2009-05-21 15:34:09 +00:00
}
2009-07-02 19:41:31 +00:00
else
uiItemO ( row , " Apply " , 0 , " OBJECT_OT_modifier_apply " ) ;
2009-05-21 15:34:09 +00:00
uiBlockClearButLock ( block ) ;
uiBlockSetButLock ( block , ob & & ob - > id . lib , ERROR_LIBDATA_MESSAGE ) ;
2009-07-02 19:41:31 +00:00
if ( ! ELEM4 ( md - > type , eModifierType_Fluidsim , eModifierType_Softbody , eModifierType_ParticleSystem , eModifierType_Cloth ) )
uiItemO ( row , " Copy " , 0 , " OBJECT_OT_modifier_copy " ) ;
2009-05-21 15:34:09 +00:00
}
result = uiLayoutColumn ( box , 0 ) ;
block = uiLayoutFreeBlock ( box ) ;
}
2009-07-02 19:41:31 +00:00
if ( md - > error ) {
2009-05-21 15:34:09 +00:00
row = uiLayoutRow ( uiLayoutBox ( column ) , 0 ) ;
/* XXX uiBlockSetCol(block, color); */
uiItemL ( row , md - > error , ICON_ERROR ) ;
/* XXX uiBlockSetCol(block, TH_AUTO); */
}
return result ;
}
2009-05-27 00:03:49 +00:00
uiLayout * uiTemplateModifier ( uiLayout * layout , PointerRNA * ptr )
2009-05-21 15:34:09 +00:00
{
Object * ob ;
ModifierData * md , * vmd ;
int i , lastCageIndex , cageIndex ;
/* verify we have valid data */
if ( ! RNA_struct_is_a ( ptr - > type , & RNA_Modifier ) ) {
printf ( " uiTemplateModifier: expected modifier on object. \n " ) ;
return NULL ;
}
ob = ptr - > id . data ;
md = ptr - > data ;
if ( ! ob | | ! ( GS ( ob - > id . name ) = = ID_OB ) ) {
printf ( " uiTemplateModifier: expected modifier on object. \n " ) ;
return NULL ;
}
2009-05-28 23:37:55 +00:00
uiBlockSetButLock ( uiLayoutGetBlock ( layout ) , ( ob & & ob - > id . lib ) , ERROR_LIBDATA_MESSAGE ) ;
2009-05-21 15:34:09 +00:00
/* find modifier and draw it */
cageIndex = modifiers_getCageIndex ( ob , & lastCageIndex ) ;
// XXX virtual modifiers are not accesible for python
vmd = modifiers_getVirtualModifierList ( ob ) ;
for ( i = 0 ; vmd ; i + + , vmd = vmd - > next ) {
if ( md = = vmd )
2009-05-27 00:03:49 +00:00
return draw_modifier ( layout , ob , md , i , cageIndex , lastCageIndex ) ;
2009-07-02 19:41:31 +00:00
else if ( vmd - > mode & eModifierMode_Virtual )
2009-05-21 15:34:09 +00:00
i - - ;
}
return NULL ;
}
2009-05-27 00:03:49 +00:00
/************************ Constraint Template *************************/
# include "DNA_action_types.h"
# include "DNA_constraint_types.h"
# include "BKE_action.h"
# include "BKE_constraint.h"
# define REDRAWIPO 1
# define REDRAWNLA 2
# define REDRAWBUTSOBJECT 3
# define REDRAWACTION 4
# define B_CONSTRAINT_TEST 5
# define B_CONSTRAINT_CHANGETARGET 6
# define B_CONSTRAINT_INF 7
# define REMAKEIPO 8
# define B_DIFF 9
void do_constraint_panels ( bContext * C , void * arg , int event )
{
Scene * scene = CTX_data_scene ( C ) ;
Object * ob = CTX_data_active_object ( C ) ;
switch ( event ) {
case B_CONSTRAINT_TEST :
// XXX allqueue(REDRAWVIEW3D, 0);
// XXX allqueue(REDRAWBUTSOBJECT, 0);
// XXX allqueue(REDRAWBUTSEDIT, 0);
break ; // no handling
case B_CONSTRAINT_INF :
/* influence; do not execute actions for 1 dag_flush */
if ( ob - > pose )
ob - > pose - > flag | = ( POSE_LOCKED | POSE_DO_UNLOCK ) ;
break ;
case B_CONSTRAINT_CHANGETARGET :
if ( ob - > pose ) ob - > pose - > flag | = POSE_RECALC ; // checks & sorts pose channels
DAG_scene_sort ( scene ) ;
break ;
default :
break ;
}
object_test_constraints ( ob ) ;
if ( ob - > pose ) update_pose_constraint_flags ( ob - > pose ) ;
2.5
Notifiers
---------
Various fixes for wrong use of notifiers, and some new notifiers
to make things a bit more clear and consistent, with two notable
changes:
* Geometry changes are now done with NC_GEOM, rather than
NC_OBJECT|ND_GEOM_, so an object does need to be available.
* Space data now use NC_SPACE|ND_SPACE_*, instead of data
notifiers or even NC_WINDOW in some cases. Note that NC_SPACE
should only be used for notifying about changes in space data,
we don't want to go back to allqueue(REDRAW..).
Depsgraph
---------
The dependency graph now has a different flush call:
DAG_object_flush_update(scene, ob, flag)
is replaced by:
DAG_id_flush_update(id, flag)
It still works basically the same, one difference is that it now
also accepts object data (e.g. Mesh), again to avoid requiring an
Object to be available. Other ID types will simply do nothing at
the moment.
Docs
----
I made some guidelines for how/when to do which kinds of updates
and notifiers. I can't specify totally exact how to make these
decisions, but these are basically the guidelines I use. So, new
and updated docs are here:
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/NotifiersUpdates
http://wiki.blender.org/index.php/BlenderDev/Blender2.5/DataNotifiers
2009-09-04 20:51:09 +00:00
if ( ob - > type = = OB_ARMATURE ) DAG_id_flush_update ( & ob - > id , OB_RECALC_DATA | OB_RECALC_OB ) ;
else DAG_id_flush_update ( & ob - > id , OB_RECALC_OB ) ;
2009-05-27 00:03:49 +00:00
// XXX allqueue(REDRAWVIEW3D, 0);
// XXX allqueue(REDRAWBUTSOBJECT, 0);
// XXX allqueue(REDRAWBUTSEDIT, 0);
}
static void constraint_active_func ( bContext * C , void * ob_v , void * con_v )
{
ED_object_constraint_set_active ( ob_v , con_v ) ;
}
static void verify_constraint_name_func ( bContext * C , void * con_v , void * name_v )
{
Object * ob = CTX_data_active_object ( C ) ;
bConstraint * con = con_v ;
char oldname [ 32 ] ;
if ( ! con )
return ;
/* put on the stack */
BLI_strncpy ( oldname , ( char * ) name_v , 32 ) ;
ED_object_constraint_rename ( ob , con , oldname ) ;
ED_object_constraint_set_active ( ob , con ) ;
// XXX allqueue(REDRAWACTION, 0);
}
/* some commonly used macros in the constraints drawing code */
# define is_armature_target(target) (target && target->type==OB_ARMATURE)
2009-08-16 03:24:23 +00:00
# define is_armature_owner(ob) ((ob->type == OB_ARMATURE) && (ob->mode & OB_MODE_POSE))
2009-05-27 00:03:49 +00:00
# define is_geom_target(target) (target && (ELEM(target->type, OB_MESH, OB_LATTICE)) )
/* Helper function for draw constraint - draws constraint space stuff
* This function should not be called if no menus are required
* owner / target : - 1 = don ' t draw menu ; 0 = not posemode , 1 = posemode
*/
static void draw_constraint_spaceselect ( uiBlock * block , bConstraint * con , short xco , short yco , short owner , short target )
{
2009-05-27 03:42:51 +00:00
short tarx , ownx , iconx ;
2009-05-27 00:03:49 +00:00
short bwidth ;
2009-05-27 03:42:51 +00:00
short iconwidth = 20 ;
2009-05-27 00:03:49 +00:00
/* calculate sizes and placement of menus */
if ( owner = = - 1 ) {
bwidth = 125 ;
tarx = 120 ;
ownx = 0 ;
}
else if ( target = = - 1 ) {
bwidth = 125 ;
tarx = 0 ;
ownx = 120 ;
}
else {
bwidth = 100 ;
2009-05-27 03:42:51 +00:00
tarx = 85 ;
iconx = tarx + bwidth + 5 ;
ownx = tarx + bwidth + iconwidth + 10 ;
2009-05-27 00:03:49 +00:00
}
2009-05-27 03:42:51 +00:00
uiDefBut ( block , LABEL , B_CONSTRAINT_TEST , " Convert: " , xco , yco , 80 , 18 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
2009-05-27 00:03:49 +00:00
/* Target-Space */
if ( target = = 1 ) {
uiDefButC ( block , MENU , B_CONSTRAINT_TEST , " Target Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1 " ,
tarx , yco , bwidth , 18 , & con - > tarspace , 0 , 0 , 0 , 0 , " Choose space that target is evaluated in " ) ;
}
else if ( target = = 0 ) {
uiDefButC ( block , MENU , B_CONSTRAINT_TEST , " Target Space %t|World Space %x0|Local (Without Parent) Space %x1 " ,
tarx , yco , bwidth , 18 , & con - > tarspace , 0 , 0 , 0 , 0 , " Choose space that target is evaluated in " ) ;
}
2009-05-27 03:42:51 +00:00
if ( ( target ! = - 1 ) & & ( owner ! = - 1 ) )
2009-06-03 00:09:30 +00:00
uiDefIconBut ( block , LABEL , 0 , ICON_ARROW_LEFTRIGHT ,
2009-05-27 03:42:51 +00:00
iconx , yco , 20 , 20 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
2009-05-27 00:03:49 +00:00
/* Owner-Space */
if ( owner = = 1 ) {
uiDefButC ( block , MENU , B_CONSTRAINT_TEST , " Owner Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1 " ,
ownx , yco , bwidth , 18 , & con - > ownspace , 0 , 0 , 0 , 0 , " Choose space that owner is evaluated in " ) ;
}
else if ( owner = = 0 ) {
uiDefButC ( block , MENU , B_CONSTRAINT_TEST , " Owner Space %t|World Space %x0|Local (Without Parent) Space %x1 " ,
ownx , yco , bwidth , 18 , & con - > ownspace , 0 , 0 , 0 , 0 , " Choose space that owner is evaluated in " ) ;
}
}
/* draw panel showing settings for a constraint */
static uiLayout * draw_constraint ( uiLayout * layout , Object * ob , bConstraint * con )
{
bPoseChannel * pchan = get_active_posechannel ( ob ) ;
bConstraintTypeInfo * cti ;
uiBlock * block ;
2009-06-03 00:09:30 +00:00
uiLayout * result = NULL , * col , * box , * row , * subrow ;
2009-05-27 00:03:49 +00:00
uiBut * but ;
2009-06-03 00:09:30 +00:00
PointerRNA ptr ;
2009-05-27 00:03:49 +00:00
char typestr [ 32 ] ;
short width = 265 ;
short proxy_protected , xco = 0 , yco = 0 ;
int rb_col ;
/* get constraint typeinfo */
cti = constraint_get_typeinfo ( con ) ;
if ( cti = = NULL ) {
/* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
if ( con - > type = = CONSTRAINT_TYPE_NULL )
strcpy ( typestr , " Null " ) ;
else
strcpy ( typestr , " Unknown " ) ;
}
else
strcpy ( typestr , cti - > name ) ;
/* determine whether constraint is proxy protected or not */
if ( proxylocked_constraints_owner ( ob , pchan ) )
proxy_protected = ( con - > flag & CONSTRAINT_PROXY_LOCAL ) = = 0 ;
else
proxy_protected = 0 ;
/* unless button has own callback, it adds this callback to button */
2009-05-28 23:37:55 +00:00
block = uiLayoutGetBlock ( layout ) ;
2009-05-27 00:03:49 +00:00
uiBlockSetHandleFunc ( block , do_constraint_panels , NULL ) ;
uiBlockSetFunc ( block , constraint_active_func , ob , con ) ;
2009-06-03 00:09:30 +00:00
RNA_pointer_create ( & ob - > id , & RNA_Constraint , con , & ptr ) ;
2009-05-27 00:03:49 +00:00
col = uiLayoutColumn ( layout , 1 ) ;
2009-06-03 00:09:30 +00:00
uiLayoutSetContextPointer ( col , " constraint " , & ptr ) ;
2009-05-27 00:03:49 +00:00
box = uiLayoutBox ( col ) ;
2009-06-03 00:09:30 +00:00
row = uiLayoutRow ( box , 0 ) ;
2009-05-27 00:03:49 +00:00
2009-07-10 13:56:29 +00:00
block = uiLayoutGetBlock ( box ) ;
2009-06-03 00:09:30 +00:00
subrow = uiLayoutRow ( row , 0 ) ;
uiLayoutSetAlignment ( subrow , UI_LAYOUT_ALIGN_LEFT ) ;
2009-05-27 00:03:49 +00:00
/* Draw constraint header */
uiBlockSetEmboss ( block , UI_EMBOSSN ) ;
/* rounded header */
rb_col = ( con - > flag & CONSTRAINT_ACTIVE ) ? 50 : 20 ;
/* open/close */
2009-05-27 03:42:51 +00:00
uiDefIconButBitS ( block , ICONTOG , CONSTRAINT_EXPAND , B_CONSTRAINT_TEST , ICON_TRIA_RIGHT , xco - 10 , yco , 20 , 20 , & con - > flag , 0.0 , 0.0 , 0.0 , 0.0 , " Collapse/Expand Constraint " ) ;
2009-05-27 00:03:49 +00:00
/* name */
2009-07-10 13:56:29 +00:00
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
/* XXX if (con->flag & CONSTRAINT_DISABLE)
uiBlockSetCol ( block , TH_REDALERT ) ; */
uiDefBut ( block , LABEL , B_CONSTRAINT_TEST , typestr , xco + 10 , yco , 100 , 18 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
if ( proxy_protected = = 0 ) {
2009-05-27 00:03:49 +00:00
but = uiDefBut ( block , TEX , B_CONSTRAINT_TEST , " " , xco + 120 , yco , 85 , 18 , con - > name , 0.0 , 29.0 , 0.0 , 0.0 , " Constraint name " ) ;
2009-07-21 02:54:02 +00:00
uiButSetFunc ( but , verify_constraint_name_func , con , con - > name ) ;
2009-05-27 00:03:49 +00:00
}
2009-07-10 13:56:29 +00:00
else
uiDefBut ( block , LABEL , B_CONSTRAINT_TEST , con - > name , xco + 120 , yco - 1 , 135 , 19 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
2009-05-27 00:03:49 +00:00
// XXX uiBlockSetCol(block, TH_AUTO);
2009-06-03 00:09:30 +00:00
subrow = uiLayoutRow ( row , 0 ) ;
uiLayoutSetAlignment ( subrow , UI_LAYOUT_ALIGN_RIGHT ) ;
2009-05-27 00:03:49 +00:00
/* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
if ( proxy_protected ) {
uiBlockSetEmboss ( block , UI_EMBOSSN ) ;
/* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
uiDefIconBut ( block , BUT , B_CONSTRAINT_TEST , ICON_GHOST , xco + 244 , yco , 19 , 19 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Proxy Protected " ) ;
uiDefIconBut ( block , BUT , B_CONSTRAINT_TEST , ICON_LOCKED , xco + 262 , yco , 19 , 19 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Proxy Protected " ) ;
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
}
else {
short prev_proxylock , show_upbut , show_downbut ;
/* Up/Down buttons:
* Proxy - constraints are not allowed to occur after local ( non - proxy ) constraints
* as that poses problems when restoring them , so disable the " up " button where
* it may cause this situation .
*
* Up / Down buttons should only be shown ( or not greyed - todo ) if they serve some purpose .
*/
if ( proxylocked_constraints_owner ( ob , pchan ) ) {
if ( con - > prev ) {
prev_proxylock = ( con - > prev - > flag & CONSTRAINT_PROXY_LOCAL ) ? 0 : 1 ;
}
else
prev_proxylock = 0 ;
}
else
prev_proxylock = 0 ;
show_upbut = ( ( prev_proxylock = = 0 ) & & ( con - > prev ) ) ;
show_downbut = ( con - > next ) ? 1 : 0 ;
if ( show_upbut | | show_downbut ) {
uiBlockBeginAlign ( block ) ;
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
2009-07-11 12:54:17 +00:00
if ( show_upbut )
uiDefIconButO ( block , BUT , " CONSTRAINT_OT_move_up " , WM_OP_INVOKE_DEFAULT , VICON_MOVE_UP , xco + width - 50 , yco , 16 , 18 , " Move constraint up in constraint stack " ) ;
2009-05-27 00:03:49 +00:00
2009-07-11 12:54:17 +00:00
if ( show_downbut )
uiDefIconButO ( block , BUT , " CONSTRAINT_OT_move_down " , WM_OP_INVOKE_DEFAULT , VICON_MOVE_DOWN , xco + width - 50 + 18 , yco , 16 , 18 , " Move constraint down in constraint stack " ) ;
2009-05-27 00:03:49 +00:00
uiBlockEndAlign ( block ) ;
}
/* Close 'button' - emboss calls here disable drawing of 'button' behind X */
uiBlockSetEmboss ( block , UI_EMBOSSN ) ;
2009-07-11 12:54:17 +00:00
uiDefIconButO ( block , BUT , " CONSTRAINT_OT_delete " , WM_OP_INVOKE_DEFAULT , ICON_X , xco + 262 , yco , 19 , 19 , " Delete constraint " ) ;
2009-05-27 00:03:49 +00:00
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
}
/* Set but-locks for protected settings (magic numbers are used here!) */
if ( proxy_protected )
uiBlockSetButLock ( block , 1 , " Cannot edit Proxy-Protected Constraint " ) ;
/* Draw constraint data */
if ( ( con - > flag & CONSTRAINT_EXPAND ) = = 0 ) {
( yco ) - = 21 ;
}
else {
box = uiLayoutBox ( col ) ;
block = uiLayoutFreeBlock ( box ) ;
switch ( con - > type ) {
# ifndef DISABLE_PYTHON
case CONSTRAINT_TYPE_PYTHON :
{
bPythonConstraint * data = con - > data ;
bConstraintTarget * ct ;
// uiBut *but2;
int tarnum , theight ;
// static int pyconindex=0;
// char *menustr;
theight = ( data - > tarnum ) ? ( data - > tarnum * 38 ) : ( 38 ) ;
uiDefBut ( block , LABEL , B_CONSTRAINT_TEST , " Script: " , xco + 60 , yco - 24 , 55 , 18 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
/* do the scripts menu */
/* XXX menustr = buildmenu_pyconstraints(data->text, &pyconindex);
but2 = uiDefButI ( block , MENU , B_CONSTRAINT_TEST , menustr ,
xco + 120 , yco - 24 , 150 , 20 , & pyconindex ,
0 , 0 , 0 , 0 , " Set the Script Constraint to use " ) ;
uiButSetFunc ( but2 , validate_pyconstraint_cb , data , & pyconindex ) ;
MEM_freeN ( menustr ) ; */
/* draw target(s) */
if ( data - > flag & PYCON_USETARGETS ) {
/* Draw target parameters */
for ( ct = data - > targets . first , tarnum = 1 ; ct ; ct = ct - > next , tarnum + + ) {
char tarstr [ 32 ] ;
short yoffset = ( ( tarnum - 1 ) * 38 ) ;
/* target label */
sprintf ( tarstr , " Target %d: " , tarnum ) ;
uiDefBut ( block , LABEL , B_CONSTRAINT_TEST , tarstr , xco + 45 , yco - ( 48 + yoffset ) , 100 , 18 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
/* target space-selector - per target */
if ( is_armature_target ( ct - > tar ) ) {
uiDefButS ( block , MENU , B_CONSTRAINT_TEST , " Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1 " ,
xco + 10 , yco - ( 66 + yoffset ) , 100 , 18 , & ct - > space , 0 , 0 , 0 , 0 , " Choose space that target is evaluated in " ) ;
}
else {
uiDefButS ( block , MENU , B_CONSTRAINT_TEST , " Target Space %t|World Space %x0|Local (Without Parent) Space %x1 " ,
xco + 10 , yco - ( 66 + yoffset ) , 100 , 18 , & ct - > space , 0 , 0 , 0 , 0 , " Choose space that target is evaluated in " ) ;
}
uiBlockBeginAlign ( block ) ;
/* target object */
uiDefIDPoinBut ( block , test_obpoin_but , ID_OB , B_CONSTRAINT_CHANGETARGET , " OB: " , xco + 120 , yco - ( 48 + yoffset ) , 150 , 18 , & ct - > tar , " Target Object " ) ;
/* subtarget */
if ( is_armature_target ( ct - > tar ) ) {
but = uiDefBut ( block , TEX , B_CONSTRAINT_CHANGETARGET , " BO: " , xco + 120 , yco - ( 66 + yoffset ) , 150 , 18 , & ct - > subtarget , 0 , 24 , 0 , 0 , " Subtarget Bone " ) ;
uiButSetCompleteFunc ( but , autocomplete_bone , ( void * ) ct - > tar ) ;
}
else if ( is_geom_target ( ct - > tar ) ) {
but = uiDefBut ( block , TEX , B_CONSTRAINT_CHANGETARGET , " VG: " , xco + 120 , yco - ( 66 + yoffset ) , 150 , 18 , & ct - > subtarget , 0 , 24 , 0 , 0 , " Name of Vertex Group defining 'target' points " ) ;
uiButSetCompleteFunc ( but , autocomplete_vgroup , ( void * ) ct - > tar ) ;
}
else {
strcpy ( ct - > subtarget , " " ) ;
}
uiBlockEndAlign ( block ) ;
}
}
else {
/* Draw indication that no target needed */
uiDefBut ( block , LABEL , B_CONSTRAINT_TEST , " Target: " , xco + 60 , yco - 48 , 55 , 18 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
uiDefBut ( block , LABEL , B_CONSTRAINT_TEST , " Not Applicable " , xco + 120 , yco - 48 , 150 , 18 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " " ) ;
}
/* settings */
uiBlockBeginAlign ( block ) ;
but = uiDefBut ( block , BUT , B_CONSTRAINT_TEST , " Options " , xco , yco - ( 52 + theight ) , ( width / 2 ) , 18 , NULL , 0 , 24 , 0 , 0 , " Change some of the constraint's settings. " ) ;
// XXX uiButSetFunc(but, BPY_pyconstraint_settings, data, NULL);
but = uiDefBut ( block , BUT , B_CONSTRAINT_TEST , " Refresh " , xco + ( ( width / 2 ) + 10 ) , yco - ( 52 + theight ) , ( width / 2 ) , 18 , NULL , 0 , 24 , 0 , 0 , " Force constraint to refresh it's settings " ) ;
uiBlockEndAlign ( block ) ;
/* constraint space settings */
draw_constraint_spaceselect ( block , con , xco , yco - ( 73 + theight ) , is_armature_owner ( ob ) , - 1 ) ;
}
break ;
2009-08-06 18:31:25 +00:00
# endif
2009-05-30 23:31:10 +00:00
2009-05-27 00:03:49 +00:00
case CONSTRAINT_TYPE_NULL :
{
uiItemL ( box , " " , 0 ) ;
}
break ;
default :
result = box ;
break ;
}
}
/* clear any locks set up for proxies/lib-linking */
uiBlockClearButLock ( block ) ;
return result ;
}
uiLayout * uiTemplateConstraint ( uiLayout * layout , PointerRNA * ptr )
{
Object * ob ;
bConstraint * con ;
/* verify we have valid data */
if ( ! RNA_struct_is_a ( ptr - > type , & RNA_Constraint ) ) {
printf ( " uiTemplateConstraint: expected constraint on object. \n " ) ;
return NULL ;
}
ob = ptr - > id . data ;
con = ptr - > data ;
if ( ! ob | | ! ( GS ( ob - > id . name ) = = ID_OB ) ) {
printf ( " uiTemplateConstraint: expected constraint on object. \n " ) ;
return NULL ;
}
2009-05-28 23:37:55 +00:00
uiBlockSetButLock ( uiLayoutGetBlock ( layout ) , ( ob & & ob - > id . lib ) , ERROR_LIBDATA_MESSAGE ) ;
2009-05-27 00:03:49 +00:00
/* hrms, the temporal constraint should not draw! */
if ( con - > type = = CONSTRAINT_TYPE_KINEMATIC ) {
bKinematicConstraint * data = con - > data ;
if ( data - > flag & CONSTRAINT_IK_TEMP )
return NULL ;
}
return draw_constraint ( layout , ob , con ) ;
}
2009-05-28 23:41:12 +00:00
/************************* Group Template ***************************/
#if 0
static void do_add_groupmenu ( void * arg , int event )
{
Object * ob = OBACT ;
if ( ob ) {
if ( event = = - 1 ) {
Group * group = add_group ( " Group " ) ;
add_to_group ( group , ob ) ;
}
else
add_to_group ( BLI_findlink ( & G . main - > group , event ) , ob ) ;
ob - > flag | = OB_FROMGROUP ;
BASACT - > flag | = OB_FROMGROUP ;
allqueue ( REDRAWBUTSOBJECT , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
}
}
static uiBlock * add_groupmenu ( void * arg_unused )
{
uiBlock * block ;
Group * group ;
short xco = 0 , yco = 0 , index = 0 ;
char str [ 32 ] ;
block = uiNewBlock ( & curarea - > uiblocks , " add_constraintmenu " , UI_EMBOSSP , UI_HELV , curarea - > win ) ;
uiBlockSetButmFunc ( block , do_add_groupmenu , NULL ) ;
uiDefBut ( block , BUTM , B_NOP , " ADD NEW " , 0 , 20 , 160 , 19 , NULL , 0.0 , 0.0 , 1 , - 1 , " " ) ;
for ( group = G . main - > group . first ; group ; group = group - > id . next , index + + ) {
/*if(group->id.lib) strcpy(str, "L ");*/ /* we cant allow adding objects inside linked groups, it wont be saved anyway */
if ( group - > id . lib = = 0 ) {
strcpy ( str , " " ) ;
strcat ( str , group - > id . name + 2 ) ;
uiDefBut ( block , BUTM , B_NOP , str , xco * 160 , - 20 * yco , 160 , 19 , NULL , 0.0 , 0.0 , 1 , index , " " ) ;
yco + + ;
if ( yco > 24 ) {
yco = 0 ;
xco + + ;
}
}
}
uiTextBoundsBlock ( block , 50 ) ;
uiBlockSetDirection ( block , UI_DOWN ) ;
return block ;
}
static void group_ob_rem ( void * gr_v , void * ob_v )
{
Object * ob = OBACT ;
if ( rem_from_group ( gr_v , ob ) & & find_group ( ob , NULL ) = = NULL ) {
ob - > flag & = ~ OB_FROMGROUP ;
BASACT - > flag & = ~ OB_FROMGROUP ;
}
allqueue ( REDRAWBUTSOBJECT , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
}
static void group_local ( void * gr_v , void * unused )
{
Group * group = gr_v ;
group - > id . lib = NULL ;
allqueue ( REDRAWBUTSOBJECT , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
}
uiLayout * uiTemplateGroup ( uiLayout * layout , Object * ob , Group * group )
{
uiSetButLock ( 1 , NULL ) ;
uiDefBlockBut ( block , add_groupmenu , NULL , " Add to Group " , 10 , 150 , 150 , 20 , " Add Object to a new Group " ) ;
/* all groups */
if ( group - > id . lib ) {
uiLayoutRow ( )
uiBlockBeginAlign ( block ) ;
uiSetButLock ( GET_INT_FROM_POINTER ( group - > id . lib ) , ERROR_LIBDATA_MESSAGE ) ; /* We cant actually use this button */
uiDefBut ( block , TEX , B_IDNAME , " GR: " , 10 , 120 - yco , 100 , 20 , group - > id . name + 2 , 0.0 , 21.0 , 0 , 0 , " Displays Group name. Click to change. " ) ;
uiClearButLock ( ) ;
but = uiDefIconBut ( block , BUT , B_NOP , ICON_PARLIB , 110 , 120 - yco , 20 , 20 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Make Group local " ) ;
uiButSetFunc ( but , group_local , group , NULL ) ;
uiBlockEndAlign ( block ) ;
} else {
but = uiDefBut ( block , TEX , B_IDNAME , " GR: " , 10 , 120 - yco , 120 , 20 , group - > id . name + 2 , 0.0 , 21.0 , 0 , 0 , " Displays Group name. Click to change. " ) ;
uiButSetFunc ( but , test_idbutton_cb , group - > id . name , NULL ) ;
}
xco = 290 ;
if ( group - > id . lib = = 0 ) { /* cant remove objects from linked groups */
but = uiDefIconBut ( block , BUT , B_NOP , VICON_X , xco , 120 - yco , 20 , 20 , NULL , 0.0 , 0.0 , 0.0 , 0.0 , " Remove Group membership " ) ;
uiButSetFunc ( but , group_ob_rem , group , ob ) ;
}
}
# endif
/************************* Preview Template ***************************/
2009-07-21 12:57:55 +00:00
# include "DNA_lamp_types.h"
2009-05-28 23:41:12 +00:00
# include "DNA_material_types.h"
2009-07-21 12:57:55 +00:00
# include "DNA_world_types.h"
2009-05-28 23:41:12 +00:00
# define B_MATPRV 1
2009-06-07 11:12:35 +00:00
static void do_preview_buttons ( bContext * C , void * arg , int event )
{
switch ( event ) {
case B_MATPRV :
WM_event_add_notifier ( C , NC_MATERIAL | ND_SHADING , arg ) ;
break ;
}
}
2009-08-18 19:58:27 +00:00
void uiTemplatePreview ( uiLayout * layout , ID * id , ID * parent , MTex * slot )
2009-05-28 23:41:12 +00:00
{
uiLayout * row , * col ;
uiBlock * block ;
2009-07-21 12:38:01 +00:00
Material * ma = NULL ;
2009-07-21 01:57:46 +00:00
ID * pid , * pparent ;
2009-07-21 12:57:55 +00:00
short * pr_texture = NULL ;
2009-05-28 23:41:12 +00:00
2009-06-11 17:21:27 +00:00
if ( id & & ! ELEM4 ( GS ( id - > name ) , ID_MA , ID_TE , ID_WO , ID_LA ) ) {
2009-06-07 11:42:13 +00:00
printf ( " uiTemplatePreview: expected ID of type material, texture, lamp or world. \n " ) ;
2009-05-28 23:41:12 +00:00
return ;
}
2009-07-21 01:57:46 +00:00
/* decide what to render */
pid = id ;
pparent = NULL ;
2009-05-28 23:41:12 +00:00
2009-07-21 12:57:55 +00:00
if ( id & & ( GS ( id - > name ) = = ID_TE ) ) {
if ( parent & & ( GS ( parent - > name ) = = ID_MA ) )
pr_texture = & ( ( Material * ) parent ) - > pr_texture ;
else if ( parent & & ( GS ( parent - > name ) = = ID_WO ) )
pr_texture = & ( ( World * ) parent ) - > pr_texture ;
else if ( parent & & ( GS ( parent - > name ) = = ID_LA ) )
pr_texture = & ( ( Lamp * ) parent ) - > pr_texture ;
if ( pr_texture ) {
if ( * pr_texture = = TEX_PR_OTHER )
pid = parent ;
else if ( * pr_texture = = TEX_PR_BOTH )
pparent = parent ;
}
2009-07-21 01:57:46 +00:00
}
/* layout */
block = uiLayoutGetBlock ( layout ) ;
row = uiLayoutRow ( layout , 0 ) ;
2009-05-28 23:41:12 +00:00
col = uiLayoutColumn ( row , 0 ) ;
uiLayoutSetKeepAspect ( col , 1 ) ;
2009-06-08 10:00:14 +00:00
2009-07-21 01:57:46 +00:00
/* add preview */
uiDefBut ( block , BUT_EXTRA , 0 , " " , 0 , 0 , UI_UNIT_X * 6 , UI_UNIT_Y * 6 , pid , 0.0 , 0.0 , 0 , 0 , " " ) ;
2009-08-18 19:58:27 +00:00
uiBlockSetDrawExtraFunc ( block , ED_preview_draw , pparent , slot ) ;
2009-06-07 11:12:35 +00:00
uiBlockSetHandleFunc ( block , do_preview_buttons , NULL ) ;
2009-07-21 01:57:46 +00:00
/* add buttons */
2009-07-21 13:20:35 +00:00
if ( pid ) {
if ( GS ( pid - > name ) = = ID_MA | | ( pparent & & GS ( pparent - > name ) = = ID_MA ) ) {
if ( GS ( pid - > name ) = = ID_MA ) ma = ( Material * ) pid ;
else ma = ( Material * ) pparent ;
2009-06-07 13:20:41 +00:00
uiLayoutColumn ( row , 1 ) ;
uiDefIconButC ( block , ROW , B_MATPRV , ICON_MATPLANE , 0 , 0 , UI_UNIT_X * 1.5 , UI_UNIT_Y , & ( ma - > pr_type ) , 10 , MA_FLAT , 0 , 0 , " Preview type: Flat XY plane " ) ;
uiDefIconButC ( block , ROW , B_MATPRV , ICON_MATSPHERE , 0 , 0 , UI_UNIT_X * 1.5 , UI_UNIT_Y , & ( ma - > pr_type ) , 10 , MA_SPHERE , 0 , 0 , " Preview type: Sphere " ) ;
uiDefIconButC ( block , ROW , B_MATPRV , ICON_MATCUBE , 0 , 0 , UI_UNIT_X * 1.5 , UI_UNIT_Y , & ( ma - > pr_type ) , 10 , MA_CUBE , 0 , 0 , " Preview type: Cube " ) ;
uiDefIconButC ( block , ROW , B_MATPRV , ICON_MONKEY , 0 , 0 , UI_UNIT_X * 1.5 , UI_UNIT_Y , & ( ma - > pr_type ) , 10 , MA_MONKEY , 0 , 0 , " Preview type: Monkey " ) ;
uiDefIconButC ( block , ROW , B_MATPRV , ICON_HAIR , 0 , 0 , UI_UNIT_X * 1.5 , UI_UNIT_Y , & ( ma - > pr_type ) , 10 , MA_HAIR , 0 , 0 , " Preview type: Hair strands " ) ;
2009-07-31 02:16:07 +00:00
uiDefIconButC ( block , ROW , B_MATPRV , ICON_MAT_SPHERE_SKY , 0 , 0 , UI_UNIT_X * 1.5 , UI_UNIT_Y , & ( ma - > pr_type ) , 10 , MA_SPHERE_A , 0 , 0 , " Preview type: Large sphere with sky " ) ;
2009-06-07 13:20:41 +00:00
}
2009-07-21 01:57:46 +00:00
2009-07-21 12:57:55 +00:00
if ( pr_texture ) {
2009-07-21 01:57:46 +00:00
uiLayoutRow ( layout , 1 ) ;
2009-07-21 12:57:55 +00:00
uiDefButS ( block , ROW , B_MATPRV , " Texture " , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , pr_texture , 10 , TEX_PR_TEXTURE , 0 , 0 , " " ) ;
if ( GS ( parent - > name ) = = ID_MA )
uiDefButS ( block , ROW , B_MATPRV , " Material " , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , pr_texture , 10 , TEX_PR_OTHER , 0 , 0 , " " ) ;
else if ( GS ( parent - > name ) = = ID_LA )
uiDefButS ( block , ROW , B_MATPRV , " Lamp " , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , pr_texture , 10 , TEX_PR_OTHER , 0 , 0 , " " ) ;
else if ( GS ( parent - > name ) = = ID_WO )
uiDefButS ( block , ROW , B_MATPRV , " World " , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , pr_texture , 10 , TEX_PR_OTHER , 0 , 0 , " " ) ;
uiDefButS ( block , ROW , B_MATPRV , " Both " , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , pr_texture , 10 , TEX_PR_BOTH , 0 , 0 , " " ) ;
2009-07-21 01:57:46 +00:00
}
2009-05-28 23:41:12 +00:00
}
}
2009-06-03 00:14:12 +00:00
/********************** ColorRamp Template **************************/
void uiTemplateColorRamp ( uiLayout * layout , ColorBand * coba , int expand )
{
uiBlock * block ;
rctf rect ;
if ( coba ) {
rect . xmin = 0 ; rect . xmax = 200 ;
rect . ymin = 0 ; rect . ymax = 190 ;
block = uiLayoutFreeBlock ( layout ) ;
colorband_buttons ( block , coba , & rect , ! expand ) ;
}
}
/********************* CurveMapping Template ************************/
# include "DNA_color_types.h"
2009-08-10 20:48:38 +00:00
void uiTemplateCurveMapping ( uiLayout * layout , CurveMapping * cumap , int type , int compact )
2009-06-03 00:14:12 +00:00
{
rctf rect ;
if ( cumap ) {
2009-08-10 20:48:38 +00:00
if ( compact ) {
rect . xmin = 0 ; rect . xmax = 150 ;
rect . ymin = 0 ; rect . ymax = 140 ;
}
else {
rect . xmin = 0 ; rect . xmax = 200 ;
rect . ymin = 0 ; rect . ymax = 190 ;
}
2009-06-03 00:14:12 +00:00
2009-08-10 20:48:38 +00:00
curvemap_layout ( layout , cumap , type , 0 , 0 , & rect ) ;
2009-06-03 00:14:12 +00:00
}
}
2009-07-21 12:38:01 +00:00
/********************* TriColor (ThemeWireColorSet) Template ************************/
void uiTemplateTriColorSet ( uiLayout * layout , PointerRNA * ptr , char * propname )
{
uiLayout * row ;
PropertyRNA * prop ;
PointerRNA csPtr ;
if ( ! ptr - > data )
return ;
prop = RNA_struct_find_property ( ptr , propname ) ;
if ( ! prop ) {
printf ( " uiTemplateTriColorSet: property not found: %s \n " , propname ) ;
return ;
}
/* we lay out the data in a row as 3 color swatches */
row = uiLayoutRow ( layout , 1 ) ;
/* nselected, selected, active color swatches */
csPtr = RNA_property_pointer_get ( ptr , prop ) ;
2009-08-21 12:57:47 +00:00
uiItemR ( row , " " , 0 , & csPtr , " normal " , 0 ) ;
uiItemR ( row , " " , 0 , & csPtr , " selected " , 0 ) ;
uiItemR ( row , " " , 0 , & csPtr , " active " , 0 ) ;
2009-07-21 12:38:01 +00:00
}
2009-06-13 11:21:02 +00:00
/********************* Layer Buttons Template ************************/
// TODO:
// - option for showing extra info like whether layer has contents?
// - for now, grouping of layers is determined by dividing up the length of
// the array of layer bitflags
void uiTemplateLayers ( uiLayout * layout , PointerRNA * ptr , char * propname )
{
uiLayout * uRow , * uSplit , * uCol ;
PropertyRNA * prop ;
int groups , cols , layers ;
int group , col , layer , row ;
if ( ! ptr - > data )
return ;
prop = RNA_struct_find_property ( ptr , propname ) ;
if ( ! prop ) {
printf ( " uiTemplateLayer: layers property not found: %s \n " , propname ) ;
return ;
}
/* the number of layers determines the way we group them
* - we want 2 rows only ( for now )
* - the number of columns ( cols ) is the total number of buttons per row
* the ' remainder ' is added to this , as it will be ok to have first row slightly wider if need be
* - for now , only split into groups if if group will have at least 5 items
*/
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
layers = RNA_property_array_length ( ptr , prop ) ;
2009-06-13 11:21:02 +00:00
cols = ( layers / 2 ) + ( layers % 2 ) ;
groups = ( ( cols / 2 ) < 5 ) ? ( 1 ) : ( cols / 2 ) ;
/* layers are laid out going across rows, with the columns being divided into groups */
2009-07-21 12:38:01 +00:00
if ( groups > 1 )
uSplit = uiLayoutSplit ( layout , ( 1.0f / ( float ) groups ) ) ;
else
uSplit = layout ;
2009-06-13 11:21:02 +00:00
for ( group = 0 ; group < groups ; group + + ) {
uCol = uiLayoutColumn ( uSplit , 1 ) ;
for ( row = 0 ; row < 2 ; row + + ) {
uRow = uiLayoutRow ( uCol , 1 ) ;
layer = groups * cols * row + cols * group ;
/* add layers as toggle buts */
for ( col = 0 ; ( col < cols ) & & ( layer < layers ) ; col + + , layer + + ) {
int icon = 0 ; // XXX - add some way of setting this...
2009-08-21 12:57:47 +00:00
uiItemFullR ( uRow , " " , icon , ptr , prop , layer , 0 , UI_ITEM_R_TOGGLE ) ;
2009-06-13 11:21:02 +00:00
}
}
}
}
2009-06-22 23:58:16 +00:00
2009-06-24 14:16:56 +00:00
/************************* List Template **************************/
2009-07-21 01:26:17 +00:00
#if 0
static void list_item_add ( ListBase * lb , ListBase * itemlb , uiLayout * layout , PointerRNA * data )
2009-06-24 14:16:56 +00:00
{
2009-06-27 01:15:31 +00:00
CollectionPointerLink * link ;
2009-07-21 01:26:17 +00:00
uiListItem * item ;
/* add to list to store in box */
item = MEM_callocN ( sizeof ( uiListItem ) , " uiListItem " ) ;
item - > layout = layout ;
item - > data = * data ;
BLI_addtail ( itemlb , item ) ;
/* add to list to return from function */
link = MEM_callocN ( sizeof ( CollectionPointerLink ) , " uiTemplateList return " ) ;
RNA_pointer_create ( NULL , & RNA_UIListItem , item , & link - > ptr ) ;
BLI_addtail ( lb , link ) ;
}
# endif
ListBase uiTemplateList ( uiLayout * layout , bContext * C , PointerRNA * ptr , char * propname , PointerRNA * activeptr , char * activepropname , int rows , int listtype )
{
//Scene *scene= CTX_data_scene(C);
2009-07-01 22:25:49 +00:00
PropertyRNA * prop = NULL , * activeprop ;
2009-06-24 14:16:56 +00:00
PropertyType type , activetype ;
2009-07-15 19:20:59 +00:00
StructRNA * ptype ;
2009-07-21 01:26:17 +00:00
uiLayout * box , * row , * col , * subrow ;
2009-06-24 14:16:56 +00:00
uiBlock * block ;
uiBut * but ;
2009-07-01 22:25:49 +00:00
Panel * pa ;
2009-07-21 01:26:17 +00:00
ListBase lb , * itemlb ;
2009-07-01 22:25:49 +00:00
char * name , str [ 32 ] ;
2009-08-26 00:38:43 +00:00
int icon = 0 , i = 0 , activei = 0 , len = 0 , items , found , min , max ;
2009-06-27 01:15:31 +00:00
lb . first = lb . last = NULL ;
2009-06-24 14:16:56 +00:00
/* validate arguments */
2009-07-01 22:25:49 +00:00
block = uiLayoutGetBlock ( layout ) ;
pa = block - > panel ;
if ( ! pa ) {
printf ( " uiTemplateList: only works inside a panel. \n " ) ;
2009-06-27 01:15:31 +00:00
return lb ;
2009-07-01 22:25:49 +00:00
}
if ( ! activeptr - > data )
2009-06-27 01:15:31 +00:00
return lb ;
2009-07-01 22:25:49 +00:00
if ( ptr - > data ) {
prop = RNA_struct_find_property ( ptr , propname ) ;
if ( ! prop ) {
printf ( " uiTemplateList: property not found: %s \n " , propname ) ;
return lb ;
}
2009-06-24 14:16:56 +00:00
}
2009-07-01 22:25:49 +00:00
activeprop = RNA_struct_find_property ( activeptr , activepropname ) ;
2009-06-24 14:16:56 +00:00
if ( ! activeprop ) {
printf ( " uiTemplateList: property not found: %s \n " , activepropname ) ;
2009-06-27 01:15:31 +00:00
return lb ;
2009-06-24 14:16:56 +00:00
}
2009-07-01 22:25:49 +00:00
if ( prop ) {
type = RNA_property_type ( prop ) ;
if ( type ! = PROP_COLLECTION ) {
printf ( " uiTemplateList: expected collection property. \n " ) ;
return lb ;
}
2009-06-24 14:16:56 +00:00
}
activetype = RNA_property_type ( activeprop ) ;
2009-07-01 22:25:49 +00:00
if ( activetype ! = PROP_INT ) {
printf ( " uiTemplateList: expected integer property. \n " ) ;
2009-06-27 01:15:31 +00:00
return lb ;
2009-06-24 14:16:56 +00:00
}
2009-07-15 19:20:59 +00:00
/* get icon */
if ( ptr - > data & & prop ) {
ptype = RNA_property_pointer_type ( ptr , prop ) ;
icon = RNA_struct_ui_icon ( ptype ) ;
}
2009-06-24 14:16:56 +00:00
/* get active data */
2009-07-01 22:25:49 +00:00
activei = RNA_property_int_get ( activeptr , activeprop ) ;
2009-06-24 14:16:56 +00:00
2009-07-21 01:26:17 +00:00
if ( listtype = = ' i ' ) {
box = uiLayoutListBox ( layout ) ;
col = uiLayoutColumn ( box , 1 ) ;
row = uiLayoutRow ( col , 0 ) ;
itemlb = uiLayoutBoxGetList ( box ) ;
if ( ptr - > data & & prop ) {
/* create list items */
RNA_PROP_BEGIN ( ptr , itemptr , prop ) {
/* create button */
if ( i = = 9 )
row = uiLayoutRow ( col , 0 ) ;
if ( RNA_struct_is_a ( itemptr . type , & RNA_TextureSlot ) ) {
#if 0
MTex * mtex = itemptr . data ;
if ( mtex & & mtex - > tex )
icon = ui_id_icon_get ( scene , & mtex - > tex - > id ) ;
# endif
}
uiDefIconButR ( block , LISTROW , 0 , icon , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , activeptr , activepropname , 0 , 0 , i , 0 , 0 , " " ) ;
//list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
i + + ;
}
RNA_PROP_END ;
}
}
else if ( listtype = = ' c ' ) {
2009-06-27 01:15:31 +00:00
/* compact layout */
found = 0 ;
row = uiLayoutRow ( layout , 1 ) ;
2009-07-01 22:25:49 +00:00
if ( ptr - > data & & prop ) {
/* create list items */
RNA_PROP_BEGIN ( ptr , itemptr , prop ) {
2009-06-27 01:15:31 +00:00
found = ( activei = = i ) ;
2009-07-01 22:25:49 +00:00
if ( found ) {
/* create button */
name = RNA_struct_name_get_alloc ( & itemptr , NULL , 0 ) ;
2009-07-15 19:20:59 +00:00
uiItemL ( row , ( name ) ? name : " " , icon ) ;
if ( name )
2009-07-01 22:25:49 +00:00
MEM_freeN ( name ) ;
/* add to list to return */
2009-07-21 01:26:17 +00:00
//list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
2009-06-27 01:15:31 +00:00
}
2009-07-01 22:25:49 +00:00
i + + ;
2009-06-27 01:15:31 +00:00
}
2009-07-01 22:25:49 +00:00
RNA_PROP_END ;
2009-06-27 01:15:31 +00:00
}
2009-06-24 14:16:56 +00:00
2009-07-01 22:25:49 +00:00
/* if not found, add in dummy button */
if ( i = = 0 )
2009-06-27 01:15:31 +00:00
uiItemL ( row , " " , 0 ) ;
2009-06-24 14:16:56 +00:00
2009-07-01 22:25:49 +00:00
/* next/prev button */
sprintf ( str , " %d : " , i ) ;
but = uiDefIconTextButR ( block , NUM , 0 , 0 , str , 0 , 0 , UI_UNIT_X * 5 , UI_UNIT_Y , activeptr , activepropname , 0 , 0 , 0 , 0 , 0 , " " ) ;
if ( i = = 0 )
2009-06-27 01:15:31 +00:00
uiButSetFlag ( but , UI_BUT_DISABLED ) ;
}
else {
2009-07-21 01:26:17 +00:00
/* default rows */
2009-06-27 01:15:31 +00:00
if ( rows = = 0 )
rows = 5 ;
2009-06-24 14:16:56 +00:00
2009-07-01 22:25:49 +00:00
/* layout */
2009-07-21 01:26:17 +00:00
box = uiLayoutListBox ( layout ) ;
2009-06-27 01:15:31 +00:00
row = uiLayoutRow ( box , 0 ) ;
col = uiLayoutColumn ( row , 1 ) ;
2009-07-01 22:25:49 +00:00
/* init numbers */
RNA_property_int_range ( activeptr , activeprop , & min , & max ) ;
2009-06-27 01:15:31 +00:00
2009-08-16 21:05:57 +00:00
if ( prop )
len = RNA_property_collection_length ( ptr , prop ) ;
2009-07-21 01:26:17 +00:00
items = CLAMPIS ( len , rows , 5 ) ;
2009-06-27 01:15:31 +00:00
2009-07-01 22:25:49 +00:00
pa - > list_scroll = MIN2 ( pa - > list_scroll , len - items ) ;
pa - > list_scroll = MAX2 ( pa - > list_scroll , 0 ) ;
2009-06-24 14:16:56 +00:00
2009-07-21 01:26:17 +00:00
itemlb = uiLayoutBoxGetList ( box ) ;
2009-07-01 22:25:49 +00:00
if ( ptr - > data & & prop ) {
/* create list items */
RNA_PROP_BEGIN ( ptr , itemptr , prop ) {
if ( i > = pa - > list_scroll & & i < pa - > list_scroll + items ) {
name = RNA_struct_name_get_alloc ( & itemptr , NULL , 0 ) ;
2009-06-24 14:16:56 +00:00
2009-07-21 01:26:17 +00:00
subrow = uiLayoutRow ( col , 0 ) ;
2009-07-15 19:20:59 +00:00
/* create button */
2009-07-21 01:26:17 +00:00
if ( ! icon | | icon = = ICON_DOT )
but = uiDefButR ( block , LISTROW , 0 , ( name ) ? name : " " , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , activeptr , activepropname , 0 , 0 , i , 0 , 0 , " " ) ;
else
but = uiDefIconTextButR ( block , LISTROW , 0 , icon , ( name ) ? name : " " , 0 , 0 , UI_UNIT_X * 10 , UI_UNIT_Y , activeptr , activepropname , 0 , 0 , i , 0 , 0 , " " ) ;
2009-07-15 19:20:59 +00:00
uiButSetFlag ( but , UI_ICON_LEFT | UI_TEXT_LEFT ) ;
2009-06-24 14:16:56 +00:00
2009-07-21 01:26:17 +00:00
/* XXX hardcoded */
if ( itemptr . type = = & RNA_MeshTextureFaceLayer | | itemptr . type = = & RNA_MeshColorLayer ) {
uiBlockSetEmboss ( block , UI_EMBOSSN ) ;
2009-07-28 18:59:36 +00:00
uiDefIconButR ( block , TOG , 0 , ICON_SCENE , 0 , 0 , UI_UNIT_X , UI_UNIT_Y , & itemptr , " active_render " , 0 , 0 , 0 , 0 , 0 , NULL ) ;
2009-07-21 01:26:17 +00:00
uiBlockSetEmboss ( block , UI_EMBOSS ) ;
}
2009-07-15 19:20:59 +00:00
if ( name )
2009-07-01 22:25:49 +00:00
MEM_freeN ( name ) ;
/* add to list to return */
2009-07-21 01:26:17 +00:00
//list_item_add(&lb, itemlb, subrow, &itemptr);
2009-06-27 01:15:31 +00:00
}
2009-07-01 22:25:49 +00:00
i + + ;
}
RNA_PROP_END ;
2009-06-24 14:16:56 +00:00
}
2009-07-01 22:25:49 +00:00
/* add dummy buttons to fill space */
while ( i < pa - > list_scroll + items ) {
if ( i > = pa - > list_scroll )
2009-06-27 01:15:31 +00:00
uiItemL ( col , " " , 0 ) ;
i + + ;
}
2009-06-24 14:16:56 +00:00
2009-07-01 22:25:49 +00:00
/* add scrollbar */
2009-06-27 01:15:31 +00:00
if ( len > items ) {
col = uiLayoutColumn ( row , 0 ) ;
2009-07-01 22:25:49 +00:00
uiDefButI ( block , SCROLL , 0 , " " , 0 , 0 , UI_UNIT_X * 0.75 , UI_UNIT_Y * items , & pa - > list_scroll , 0 , len - items , items , 0 , " " ) ;
2009-06-27 01:15:31 +00:00
}
2009-06-24 14:16:56 +00:00
}
2009-07-01 22:25:49 +00:00
/* return items in list */
2009-06-27 01:15:31 +00:00
return lb ;
2009-06-24 14:16:56 +00:00
}
2009-06-30 19:20:45 +00:00
/************************* Operator Search Template **************************/
static void operator_call_cb ( struct bContext * C , void * arg1 , void * arg2 )
{
wmOperatorType * ot = arg2 ;
if ( ot )
WM_operator_name_call ( C , ot - > idname , WM_OP_INVOKE_DEFAULT , NULL ) ;
}
static void operator_search_cb ( const struct bContext * C , void * arg , char * str , uiSearchItems * items )
{
wmOperatorType * ot = WM_operatortype_first ( ) ;
for ( ; ot ; ot = ot - > next ) {
if ( BLI_strcasestr ( ot - > name , str ) ) {
if ( ot - > poll = = NULL | | ot - > poll ( ( bContext * ) C ) ) {
char name [ 256 ] ;
int len = strlen ( ot - > name ) ;
/* display name for menu, can hold hotkey */
BLI_strncpy ( name , ot - > name , 256 ) ;
/* check for hotkey */
if ( len < 256 - 6 ) {
if ( WM_key_event_operator_string ( C , ot - > idname , WM_OP_EXEC_DEFAULT , NULL , & name [ len + 1 ] , 256 - len - 1 ) )
name [ len ] = ' | ' ;
}
if ( 0 = = uiSearchItemAdd ( items , name , ot , 0 ) )
break ;
}
}
}
}
void uiTemplateOperatorSearch ( uiLayout * layout )
{
uiBlock * block ;
uiBut * but ;
static char search [ 256 ] = " " ;
block = uiLayoutGetBlock ( layout ) ;
uiBlockSetCurLayout ( block , layout ) ;
but = uiDefSearchBut ( block , search , 0 , ICON_VIEWZOOM , sizeof ( search ) , 0 , 0 , UI_UNIT_X * 6 , UI_UNIT_Y , " " ) ;
uiButSetSearchFunc ( but , operator_search_cb , NULL , operator_call_cb , NULL ) ;
}
/************************* Running Jobs Template **************************/
# define B_STOPRENDER 1
# define B_STOPCAST 2
# define B_STOPANIM 3
static void do_running_jobs ( bContext * C , void * arg , int event )
{
switch ( event ) {
case B_STOPRENDER :
G . afbreek = 1 ;
break ;
case B_STOPCAST :
WM_jobs_stop ( CTX_wm_manager ( C ) , CTX_wm_screen ( C ) ) ;
break ;
case B_STOPANIM :
2009-08-16 20:37:22 +00:00
WM_operator_name_call ( C , " SCREEN_OT_animation_play " , WM_OP_INVOKE_SCREEN , NULL ) ;
2009-06-30 19:20:45 +00:00
break ;
}
}
void uiTemplateRunningJobs ( uiLayout * layout , bContext * C )
{
bScreen * screen = CTX_wm_screen ( C ) ;
Scene * scene = CTX_data_scene ( C ) ;
wmWindowManager * wm = CTX_wm_manager ( C ) ;
uiBlock * block ;
block = uiLayoutGetBlock ( layout ) ;
uiBlockSetCurLayout ( block , layout ) ;
uiBlockSetHandleFunc ( block , do_running_jobs , NULL ) ;
if ( WM_jobs_test ( wm , scene ) )
uiDefIconTextBut ( block , BUT , B_STOPRENDER , ICON_REC , " Render " , 0 , 0 , 75 , UI_UNIT_Y , NULL , 0.0f , 0.0f , 0 , 0 , " Stop rendering " ) ;
if ( WM_jobs_test ( wm , screen ) )
uiDefIconTextBut ( block , BUT , B_STOPCAST , ICON_REC , " Capture " , 0 , 0 , 85 , UI_UNIT_Y , NULL , 0.0f , 0.0f , 0 , 0 , " Stop screencast " ) ;
if ( screen - > animtimer )
uiDefIconTextBut ( block , BUT , B_STOPANIM , ICON_REC , " Anim Player " , 0 , 0 , 85 , UI_UNIT_Y , NULL , 0.0f , 0.0f , 0 , 0 , " Stop animation playback " ) ;
}
2009-07-21 12:57:55 +00:00
/************************* Image Template **************************/
# include "ED_image.h"
void uiTemplateTextureImage ( uiLayout * layout , bContext * C , Tex * tex )
{
uiBlock * block ;
if ( tex ) {
block = uiLayoutFreeBlock ( layout ) ;
ED_image_uiblock_panel ( C , block , & tex - > ima , & tex - > iuser , 0 , 0 ) ;
}
}