From 40ae17d2f6e2d5dbbe89321491572035c304872c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 19 May 2009 17:13:33 +0000 Subject: UI * Fix buttons jumping around when resizing and zoom. Part of this was adding a tiny a 0.001f offset in UI_view2d_view_ortho, otherwise the rounding is unpredictable (used to be 0.375f, but that was disabled). * Fix various issues with zooming, panning panels. V2D_LOCKOFS_X/Y is now taken into account in more places in the view2d code, to avoid zooming into the center or panning out of the view. * Remove "Free" align mode in buttons window (it's not really useful). * View3D/Graph/Image editors now use the same PanelType system as the buttons window, means some deprecated panel code could be removed. * Some small visual tweaks for panels. * View 2D Reset operator (Home key), to reset zoom and panning for panels. * Added argument to set number buttons as sliders (slider=True for itemR). * Ignore labels for button alignment (doesn't look right). * Fix some use of context.main in py scripts, should get data from active object instead. * Fix autotexspace -> auto_texspace in py script. --- source/blender/blenkernel/BKE_screen.h | 2 + source/blender/blenloader/intern/readfile.c | 1 - source/blender/editors/include/ED_screen.h | 2 + source/blender/editors/include/UI_interface.h | 17 +- source/blender/editors/include/UI_view2d.h | 2 - source/blender/editors/interface/interface.c | 9 +- source/blender/editors/interface/interface_api.c | 1 + .../blender/editors/interface/interface_handlers.c | 5 + .../blender/editors/interface/interface_intern.h | 4 +- .../blender/editors/interface/interface_layout.c | 282 ++-- source/blender/editors/interface/interface_panel.c | 349 +---- .../editors/interface/interface_templates.c | 14 +- source/blender/editors/interface/interface_utils.c | 30 +- source/blender/editors/interface/view2d.c | 79 +- source/blender/editors/interface/view2d_ops.c | 126 +- source/blender/editors/screen/area.c | 125 +- .../blender/editors/space_buttons/buttons_header.c | 9 +- .../blender/editors/space_buttons/space_buttons.c | 7 +- source/blender/editors/space_graph/graph_buttons.c | 163 ++- source/blender/editors/space_graph/graph_intern.h | 3 +- source/blender/editors/space_graph/space_graph.c | 23 +- source/blender/editors/space_image/image_buttons.c | 1476 ++++++++++++++++++++ source/blender/editors/space_image/image_header.c | 14 +- source/blender/editors/space_image/image_intern.h | 3 +- source/blender/editors/space_image/image_panels.c | 1463 ------------------- source/blender/editors/space_image/space_image.c | 24 +- source/blender/editors/space_text/space_text.c | 5 +- source/blender/editors/space_view3d/space_view3d.c | 49 +- .../blender/editors/space_view3d/view3d_buttons.c | 355 +++-- .../blender/editors/space_view3d/view3d_header.c | 24 +- .../blender/editors/space_view3d/view3d_intern.h | 5 +- .../blender/editors/space_view3d/view3d_toolbar.c | 30 +- source/blender/makesdna/DNA_screen_types.h | 4 +- source/blender/makesrna/intern/rna_access.c | 22 +- source/blender/makesrna/intern/rna_ui.c | 22 + source/blender/python/intern/bpy_ui.c | 41 - source/blender/windowmanager/intern/wm_operators.c | 6 +- 37 files changed, 2313 insertions(+), 2483 deletions(-) create mode 100644 source/blender/editors/space_image/image_buttons.c delete mode 100644 source/blender/editors/space_image/image_panels.c (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 4797616a471..9b5d99f6ae6 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -159,6 +159,8 @@ typedef struct PanelType { /* verify if the panel should draw or not */ int (*poll)(const struct bContext *, struct PanelType *); + /* draw header (optional) */ + void (*draw_header)(const struct bContext *, struct Panel *); /* draw entirely, view changes should be handled here */ void (*draw)(const struct bContext *, struct Panel *); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 67887769d38..c680c6b3b54 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5650,7 +5650,6 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) { SpaceButs *sbuts= (SpaceButs *)sl; memcpy(&ar->v2d, &sbuts->v2d, sizeof(View2D)); - ar->v2d.keepzoom |= V2D_KEEPASPECT; break; } case SPACE_FILE: diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index bfa0c680bd6..2484b558b04 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -53,7 +53,9 @@ void ED_region_pixelspace(struct ARegion *ar); void ED_region_init(struct bContext *C, struct ARegion *ar); void ED_region_tag_redraw(struct ARegion *ar); void ED_region_tag_redraw_partial(struct ARegion *ar, struct rcti *rct); +void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar); void ED_region_panels(const struct bContext *C, struct ARegion *ar, int vertical, char *context); +void ED_region_header_init(struct ARegion *ar); void ED_region_header(const struct bContext *C, struct ARegion *ar); /* spaces */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 475d77d90f3..dba944ad9b7 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -400,7 +400,7 @@ void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1, void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval); uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2); -int uiDefAutoButsRNA(const struct bContext *C, uiBlock *block, struct PointerRNA *ptr); +void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr); /* Links * @@ -462,16 +462,9 @@ void autocomplete_end(AutoComplete *autocpl, char *autoname); void uiBeginPanels(const struct bContext *C, struct ARegion *ar); void uiEndPanels(const struct bContext *C, struct ARegion *ar); -struct Panel *uiBeginPanel(struct ARegion *ar, uiBlock *block, struct PanelType *pt); +struct Panel *uiBeginPanel(struct ARegion *ar, uiBlock *block, struct PanelType *pt, int *open); void uiEndPanel(uiBlock *block, int width, int height); -void uiPanelsHome(struct ARegion *ar); - -/* deprecated */ -extern int uiNewPanel(const struct bContext *C, struct ARegion *ar, uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey); -extern void uiNewPanelHeight(struct uiBlock *block, int sizey); -extern void uiNewPanelTitle(struct uiBlock *block, char *str); - /* Handlers * * Handlers that can be registered in regions, areas and windows for @@ -558,6 +551,8 @@ uiLayout *uiLayoutBox(uiLayout *layout); uiLayout *uiLayoutFree(uiLayout *layout, int align); uiLayout *uiLayoutSplit(uiLayout *layout); +uiBlock *uiLayoutFreeBlock(uiLayout *layout); + /* templates */ void uiTemplateHeader(uiLayout *layout, struct bContext *C); void uiTemplateHeaderID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, @@ -573,8 +568,8 @@ void uiItemFloatO(uiLayout *layout, char *name, int icon, char *opname, char *pr void uiItemStringO(uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value); void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, struct IDProperty *properties, int context); -void uiItemR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int expand); -void uiItemFullR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int expand); +void uiItemR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int expand, int slider); +void uiItemFullR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int expand, int slider); void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value); void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname); diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 0650a5611dc..7ff312151c5 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -54,8 +54,6 @@ enum { V2D_COMMONVIEW_LIST, /* headers (this is basically the same as listview, but no y-panning) */ V2D_COMMONVIEW_HEADER, - /* ui listviews, tries to wrap tot inside region width */ - V2D_COMMONVIEW_LIST_UI, /* ui region containing panels */ V2D_COMMONVIEW_PANELS_UI, } eView2D_CommonViewTypes; diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 57f45059865..e937ab0c50a 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -559,7 +559,7 @@ void uiEndBlock(const bContext *C, uiBlock *block) } /* handle pending stuff */ - if(block->layout) uiBlockLayoutResolve(C, block, NULL, NULL); + if(block->layouts.first) uiBlockLayoutResolve(C, block, NULL, NULL); ui_block_do_align(block); if(block->flag & UI_BLOCK_LOOP) ui_menu_block_set_keymaps(C, block); @@ -1984,6 +1984,11 @@ void uiBlockEndAlign(uiBlock *block) block->flag &= ~UI_BUT_ALIGN; // all 4 flags } +int ui_but_can_align(uiBut *but) +{ + return !ELEM(but->type, LABEL, ROUNDBOX); +} + static void ui_block_do_align_but(uiBlock *block, uiBut *first, int nr) { uiBut *prev, *but=NULL, *next; @@ -2176,7 +2181,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short but->aspect= 1.0f; //XXX block->aspect; but->block= block; // pointer back, used for frontbuffer status, and picker - if(block->flag & UI_BUT_ALIGN) + if((block->flag & UI_BUT_ALIGN) && ui_but_can_align(but)) but->alignnr= block->alignnr; but->func= block->func; diff --git a/source/blender/editors/interface/interface_api.c b/source/blender/editors/interface/interface_api.c index 873406de7aa..b593aef2208 100644 --- a/source/blender/editors/interface/interface_api.c +++ b/source/blender/editors/interface/interface_api.c @@ -89,6 +89,7 @@ void RNA_api_ui_layout(StructRNA *srna) parm= RNA_def_string(func, "property", "", 0, "", "Identifier of property in data."); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail."); + RNA_def_boolean(func, "slider", 0, "", "Use slider for numeric values."); func= RNA_def_function(srna, "items_enumR", "uiItemsEnumR"); parm= RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property."); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c38f147a480..ed126ed870d 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2767,6 +2767,11 @@ static uiBut *ui_but_find_activated(ARegion *ar) return NULL; } +int ui_button_is_active(ARegion *ar) +{ + return (ui_but_find_activated(ar) != NULL); +} + static void ui_blocks_set_tooltips(ARegion *ar, int enable) { uiBlock *block; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index b96726a5ead..13c9d09aff1 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -222,7 +222,7 @@ struct uiBlock { Panel *panel; uiBlock *oldblock; - struct uiLayout *layout; + ListBase layouts; struct uiLayout *curlayout; char name[UI_MAX_NAME_STR]; @@ -378,6 +378,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rct /* interface_handlers.c */ extern void ui_button_active_cancel(const struct bContext *C, uiBut *but); +extern int ui_button_is_active(struct ARegion *ar); /* interface_widgets.c */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); @@ -398,6 +399,7 @@ void ui_resources_free(void); /* interface_layout.c */ void ui_layout_add_but(struct uiLayout *layout, uiBut *but); +int ui_but_can_align(uiBut *but); /* interface_anim.c */ void ui_but_anim_flag(uiBut *but, float cfra); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index ab2bb57a25f..c1877ac8861 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -70,9 +70,11 @@ #define EM_SEPR_X 6 #define EM_SEPR_Y 6 -/* uiLayoutCommon */ +/* uiLayoutRoot */ + +typedef struct uiLayoutRoot { + struct uiLayoutRoot *next, *prev; -typedef struct uiLayoutCommon { int type; int opcontext; @@ -83,7 +85,8 @@ typedef struct uiLayoutCommon { uiStyle *style; uiBlock *block; -} uiLayoutCommon; + uiLayout *layout; +} uiLayoutRoot; /* Item */ @@ -122,7 +125,7 @@ typedef struct uiButtonItem { struct uiLayout { uiItem item; - uiLayoutCommon *common; + uiLayoutRoot *root; ListBase items; int x, y, w, h; @@ -198,7 +201,7 @@ static int ui_item_fit(int item, int pos, int all, int available, int spacing, i static int ui_layout_vary_direction(uiLayout *layout) { - return (layout->common->type == UI_LAYOUT_HEADER)? UI_ITEM_VARY_X: UI_ITEM_VARY_Y; + return (layout->root->type == UI_LAYOUT_HEADER)? UI_ITEM_VARY_X: UI_ITEM_VARY_Y; } /* estimated size of text + icon */ @@ -253,6 +256,8 @@ static void ui_item_position(uiItem *item, int x, int y, int w, int h) bitem->but->y1= y; bitem->but->x2= x+w; bitem->but->y2= y+h; + + ui_check_but(bitem->but); /* for strlen */ } else { uiLayout *litem= (uiLayout*)item; @@ -296,9 +301,10 @@ static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, int a } /* create buttons for an item with an RNA array */ -static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int h, int expand) +static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int h, int expand, int slider) { - uiStyle *style= layout->common->style; + uiStyle *style= layout->root->style; + uiBut *but; PropertyType type; PropertySubType subtype; uiLayout *sub; @@ -308,7 +314,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon type= RNA_property_type(prop); subtype= RNA_property_subtype(prop); - sub= ui_item_local_sublayout(layout, layout, 0); + sub= ui_item_local_sublayout(layout, layout, 1); uiBlockSetCurLayout(block, sub); /* create label */ @@ -358,12 +364,12 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon col= a%len; row= a/len; - uiDefAutoButR(block, ptr, prop, a, "", 0, x + w*col, y+(row-a-1)*UI_UNIT_Y, w, UI_UNIT_Y); + but= uiDefAutoButR(block, ptr, prop, a, "", 0, x + w*col, y+(row-a-1)*UI_UNIT_Y, w, UI_UNIT_Y); + if(slider && but->type==NUM) + but->type= NUMSLI; } } else if(len <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) { - uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, sub, 1)); - if(subtype == PROP_COLOR) uiDefAutoButR(block, ptr, prop, -1, "", 0, 0, 0, w, UI_UNIT_Y); @@ -390,18 +396,23 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon str[2]= '\0'; } - uiDefAutoButR(block, ptr, prop, a, str, 0, 0, 0, w, UI_UNIT_Y); + but= uiDefAutoButR(block, ptr, prop, a, str, 0, 0, 0, w, UI_UNIT_Y); + if(slider && but->type==NUM) + but->type= NUMSLI; } } - else if(subtype == PROP_COLOR && len == 4) - uiDefAutoButR(block, ptr, prop, 3, "A:", 0, 0, 0, w, UI_UNIT_Y); + else if(subtype == PROP_COLOR && len == 4) { + but= uiDefAutoButR(block, ptr, prop, 3, "A:", 0, 0, 0, w, UI_UNIT_Y); + if(slider && but->type==NUM) + but->type= NUMSLI; + } } else { - /* default array layout */ - uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, sub, 1)); - - for(a=0; atype==NUM) + but->type= NUMSLI; + } } uiBlockSetCurLayout(block, layout); @@ -456,7 +467,7 @@ static void ui_item_with_label(uiLayout *layout, uiBlock *block, char *name, int /* disabled item */ static void ui_item_disabled(uiLayout *layout, char *name) { - uiBlock *block= layout->common->block; + uiBlock *block= layout->root->block; uiBut *but; int w; @@ -476,7 +487,7 @@ static void ui_item_disabled(uiLayout *layout, char *name) /* operator items */ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDProperty *properties, int context) { - uiBlock *block= layout->common->block; + uiBlock *block= layout->root->block; wmOperatorType *ot= WM_operatortype_find(idname); uiBut *but; int w; @@ -488,7 +499,7 @@ void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDPropert if(!name) name= ot->name; - if(layout->common->type == UI_LAYOUT_MENU && !icon) + if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; /* create button */ @@ -547,7 +558,7 @@ void uiItemEnumO(uiLayout *layout, char *name, int icon, char *opname, char *pro if(!name) name= ui_menu_enumpropname(opname, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext); } void uiItemsEnumO(uiLayout *layout, char *opname, char *propname) @@ -582,7 +593,7 @@ void uiItemBooleanO(uiLayout *layout, char *name, int icon, char *opname, char * WM_operator_properties_create(&ptr, opname); RNA_boolean_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext); } void uiItemIntO(uiLayout *layout, char *name, int icon, char *opname, char *propname, int value) @@ -592,7 +603,7 @@ void uiItemIntO(uiLayout *layout, char *name, int icon, char *opname, char *prop WM_operator_properties_create(&ptr, opname); RNA_int_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext); } void uiItemFloatO(uiLayout *layout, char *name, int icon, char *opname, char *propname, float value) @@ -602,7 +613,7 @@ void uiItemFloatO(uiLayout *layout, char *name, int icon, char *opname, char *pr WM_operator_properties_create(&ptr, opname); RNA_float_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext); } void uiItemStringO(uiLayout *layout, char *name, int icon, char *opname, char *propname, char *value) @@ -612,12 +623,12 @@ void uiItemStringO(uiLayout *layout, char *name, int icon, char *opname, char *p WM_operator_properties_create(&ptr, opname); RNA_string_set(&ptr, propname, value); - uiItemFullO(layout, name, icon, opname, ptr.data, layout->common->opcontext); + uiItemFullO(layout, name, icon, opname, ptr.data, layout->root->opcontext); } void uiItemO(uiLayout *layout, char *name, int icon, char *opname) { - uiItemFullO(layout, name, icon, opname, NULL, layout->common->opcontext); + uiItemFullO(layout, name, icon, opname, NULL, layout->root->opcontext); } /* RNA property items */ @@ -660,9 +671,10 @@ static void ui_item_rna_size(uiLayout *layout, char *name, int icon, PropertyRNA *r_h= h; } -void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int expand) +void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int expand, int slider) { - uiBlock *block= layout->common->block; + uiBlock *block= layout->root->block; + uiBut *but; PropertyType type; char namestr[UI_MAX_NAME_STR]; int len, w, h; @@ -685,7 +697,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper if(type == PROP_BOOLEAN && len) name= ui_item_name_add_colon(name, namestr); - if(layout->common->type == UI_LAYOUT_MENU) { + if(layout->root->type == UI_LAYOUT_MENU) { if(type == PROP_BOOLEAN) icon= (RNA_property_boolean_get(ptr, prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT; else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) @@ -697,7 +709,7 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper /* array property */ if(index == RNA_NO_INDEX && len > 0) - ui_item_array(layout, block, name, icon, ptr, prop, len, 0, 0, w, h, expand); + ui_item_array(layout, block, name, icon, ptr, prop, len, 0, 0, w, h, expand, slider); /* enum item */ else if(type == PROP_ENUM && index == RNA_ENUM_VALUE) { char *identifier= (char*)RNA_property_identifier(prop); @@ -716,11 +728,15 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h); /* single button */ - else - uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h); + else { + but= uiDefAutoButR(block, ptr, prop, index, (char*)name, icon, 0, 0, w, h); + + if(slider && but->type==NUM) + but->type= NUMSLI; + } } -void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand) +void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *propname, int expand, int slider) { PropertyRNA *prop; @@ -735,7 +751,7 @@ void uiItemR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, char *prop return; } - uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, 0, expand); + uiItemFullR(layout, name, icon, ptr, prop, RNA_NO_INDEX, 0, expand, slider); } void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, char *propname, int value) @@ -753,7 +769,7 @@ void uiItemEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA *ptr, return; } - uiItemFullR(layout, name, icon, ptr, prop, RNA_ENUM_VALUE, value, 0); + uiItemFullR(layout, name, icon, ptr, prop, RNA_ENUM_VALUE, value, 0, 0); } void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, char *propname) @@ -791,24 +807,24 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt) static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN) { - uiBlock *block= layout->common->block; + uiBlock *block= layout->root->block; uiBut *but; int w, h; uiBlockSetCurLayout(block, layout); - if(layout->common->type == UI_LAYOUT_HEADER) + if(layout->root->type == UI_LAYOUT_HEADER) uiBlockSetEmboss(block, UI_EMBOSSP); if(!name) name= ""; - if(layout->common->type == UI_LAYOUT_MENU && !icon) + if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; w= ui_text_icon_width(layout, name, icon); h= UI_UNIT_Y; - if(layout->common->type == UI_LAYOUT_HEADER) /* ugly .. */ + if(layout->root->type == UI_LAYOUT_HEADER) /* ugly .. */ w -= 3; if(icon) @@ -821,7 +837,7 @@ static void ui_item_menu(uiLayout *layout, char *name, int icon, uiMenuCreateFun but->func_argN= argN; } - if(layout->common->type == UI_LAYOUT_HEADER) + if(layout->root->type == UI_LAYOUT_HEADER) uiBlockSetEmboss(block, UI_EMBOSS); } @@ -837,7 +853,7 @@ void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname if(strcmp(menuname, mt->idname) == 0) { if(!name) name= mt->label; - if(layout->common->type == UI_LAYOUT_MENU && !icon) + if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; ui_item_menu(layout, name, icon, ui_item_menutype_func, mt, NULL); break; @@ -848,7 +864,7 @@ void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname /* label item */ void uiItemL(uiLayout *layout, char *name, int icon) { - uiBlock *block= layout->common->block; + uiBlock *block= layout->root->block; uiBut *but; int w; @@ -856,7 +872,7 @@ void uiItemL(uiLayout *layout, char *name, int icon) if(!name) name= ""; - if(layout->common->type == UI_LAYOUT_MENU && !icon) + if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; w= ui_text_icon_width(layout, name, icon); @@ -873,7 +889,7 @@ void uiItemL(uiLayout *layout, char *name, int icon) void uiItemV(uiLayout *layout, char *name, int icon, int argval) { /* label */ - uiBlock *block= layout->common->block; + uiBlock *block= layout->root->block; float *retvalue= (block->handle)? &block->handle->retvalue: NULL; int w; @@ -881,7 +897,7 @@ void uiItemV(uiLayout *layout, char *name, int icon, int argval) if(!name) name= ""; - if(layout->common->type == UI_LAYOUT_MENU && !icon) + if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; w= ui_text_icon_width(layout, name, icon); @@ -897,7 +913,7 @@ void uiItemV(uiLayout *layout, char *name, int icon, int argval) /* separator item */ void uiItemS(uiLayout *layout) { - uiBlock *block= layout->common->block; + uiBlock *block= layout->root->block; uiBlockSetCurLayout(block, layout); uiDefBut(block, SEPR, 0, "", 0, 0, EM_SEPR_X, EM_SEPR_Y, NULL, 0.0, 0.0, 0, 0, ""); @@ -939,13 +955,13 @@ void uiItemMenuEnumO(uiLayout *layout, char *name, int icon, char *opname, char if(!name) name= ot->name; - if(layout->common->type == UI_LAYOUT_MENU && !icon) + if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); lvl->opname= opname; lvl->propname= propname; - lvl->opcontext= layout->common->opcontext; + lvl->opcontext= layout->root->opcontext; ui_item_menu(layout, name, icon, menu_item_enum_opname_menu, NULL, lvl); } @@ -971,13 +987,13 @@ void uiItemMenuEnumR(uiLayout *layout, char *name, int icon, struct PointerRNA * if(!name) name= (char*)RNA_property_ui_name(prop); - if(layout->common->type == UI_LAYOUT_MENU && !icon) + if(layout->root->type == UI_LAYOUT_MENU && !icon) icon= ICON_BLANK1; lvl= MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); lvl->rnapoin= *ptr; lvl->propname= propname; - lvl->opcontext= layout->common->opcontext; + lvl->opcontext= layout->root->opcontext; ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl); } @@ -1117,7 +1133,7 @@ static void ui_litem_estimate_root(uiLayout *litem) static void ui_litem_layout_root(uiLayout *litem) { - if(litem->common->type == UI_LAYOUT_HEADER) + if(litem->root->type == UI_LAYOUT_HEADER) ui_litem_layout_row(litem); else ui_litem_layout_column(litem); @@ -1126,7 +1142,7 @@ static void ui_litem_layout_root(uiLayout *litem) /* box layout */ static void ui_litem_estimate_box(uiLayout *litem) { - uiStyle *style= litem->common->style; + uiStyle *style= litem->root->style; ui_litem_estimate_column(litem); litem->w += 2*style->boxspace; @@ -1135,7 +1151,7 @@ static void ui_litem_estimate_box(uiLayout *litem) static void ui_litem_layout_box(uiLayout *litem) { - uiStyle *style= litem->common->style; + uiStyle *style= litem->root->style; int w, h; w= litem->w; @@ -1156,13 +1172,13 @@ static void ui_litem_layout_box(uiLayout *litem) if(h != 0) litem->h += 2*style->boxspace; /* roundbox around the sublayout */ - uiDefBut(litem->common->block, ROUNDBOX, 0, "", litem->x, litem->y, litem->w, litem->h, NULL, 7.0, 0.0, 3, 20, ""); + uiDefBut(litem->root->block, ROUNDBOX, 0, "", litem->x, litem->y, litem->w, litem->h, NULL, 7.0, 0.0, 3, 20, ""); } /* multi-column layout, automatically flowing to the next */ static void ui_litem_estimate_column_flow(uiLayout *litem) { - uiStyle *style= litem->common->style; + uiStyle *style= litem->root->style; uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem; uiItem *item; int col, x, y, emh, emy, miny, itemw, itemh, maxw=0; @@ -1185,7 +1201,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) return; } - flow->totcol= MAX2(litem->common->emw/maxw, 1); + flow->totcol= MAX2(litem->root->emw/maxw, 1); flow->totcol= MIN2(flow->totcol, totitem); } else @@ -1224,7 +1240,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) static void ui_litem_layout_column_flow(uiLayout *litem) { - uiStyle *style= litem->common->style; + uiStyle *style= litem->root->style; uiLayoutItemFlow *flow= (uiLayoutItemFlow*)litem; uiItem *item; int col, x, y, w, emh, emy, miny, itemw, itemh; @@ -1404,11 +1420,13 @@ uiLayout *uiLayoutRow(uiLayout *layout, int align) litem= MEM_callocN(sizeof(uiLayout), "uiLayoutRow"); litem->item.type= ITEM_LAYOUT_ROW; - litem->common= layout->common; + litem->root= layout->root; litem->align= align; - litem->space= (align)? 0: layout->common->style->buttonspacex; + litem->space= (align)? 0: layout->root->style->buttonspacex; BLI_addtail(&layout->items, litem); + uiBlockSetCurLayout(layout->root->block, litem); + return litem; } @@ -1418,11 +1436,13 @@ uiLayout *uiLayoutColumn(uiLayout *layout, int align) litem= MEM_callocN(sizeof(uiLayout), "uiLayoutColumn"); litem->item.type= ITEM_LAYOUT_COLUMN; - litem->common= layout->common; + litem->root= layout->root; litem->align= align; - litem->space= (litem->align)? 0: layout->common->style->buttonspacey; + litem->space= (litem->align)? 0: layout->root->style->buttonspacey; BLI_addtail(&layout->items, litem); + uiBlockSetCurLayout(layout->root->block, litem); + return litem; } @@ -1432,12 +1452,14 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align) flow= MEM_callocN(sizeof(uiLayoutItemFlow), "uiLayoutItemFlow"); flow->litem.item.type= ITEM_LAYOUT_COLUMN_FLOW; - flow->litem.common= layout->common; + flow->litem.root= layout->root; flow->litem.align= align; - flow->litem.space= (flow->litem.align)? 0: layout->common->style->columnspace; + flow->litem.space= (flow->litem.align)? 0: layout->root->style->columnspace; flow->number= number; BLI_addtail(&layout->items, flow); + uiBlockSetCurLayout(layout->root->block, &flow->litem); + return &flow->litem; } @@ -1447,10 +1469,12 @@ uiLayout *uiLayoutBox(uiLayout *layout) box= MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx"); box->litem.item.type= ITEM_LAYOUT_BOX; - box->litem.common= layout->common; - box->litem.space= layout->common->style->columnspace; + box->litem.root= layout->root; + box->litem.space= layout->root->style->columnspace; BLI_addtail(&layout->items, box); + uiBlockSetCurLayout(layout->root->block, &box->litem); + return &box->litem; } @@ -1460,21 +1484,35 @@ uiLayout *uiLayoutFree(uiLayout *layout, int align) litem= MEM_callocN(sizeof(uiLayout), "uiLayoutFree"); litem->item.type= ITEM_LAYOUT_FREE; - litem->common= layout->common; + litem->root= layout->root; litem->align= align; BLI_addtail(&layout->items, litem); + uiBlockSetCurLayout(layout->root->block, litem); + return litem; } +uiBlock *uiLayoutFreeBlock(uiLayout *layout) +{ + uiBlock *block; + + block= uiLayoutBlock(layout); + uiLayoutFree(layout, 0); + + return block; +} + uiLayout *uiLayoutSplit(uiLayout *layout) { uiLayout *litem; litem= uiLayoutRow(layout, 0); litem->item.type = ITEM_LAYOUT_SPLIT; - litem->common= layout->common; - litem->space= layout->common->style->columnspace; + litem->root= layout->root; + litem->space= layout->root->style->columnspace; + + uiBlockSetCurLayout(layout->root->block, litem); return litem; } @@ -1491,6 +1529,9 @@ static void ui_item_estimate(uiItem *item) for(subitem=litem->items.first; subitem; subitem=subitem->next) ui_item_estimate(subitem); + if(litem->items.first == NULL) + return; + switch(litem->item.type) { case ITEM_LAYOUT_COLUMN: ui_litem_estimate_column(litem); @@ -1522,10 +1563,14 @@ static void ui_item_estimate(uiItem *item) static void ui_item_align(uiLayout *litem, int nr) { uiItem *item; + uiButtonItem *bitem; for(item=litem->items.first; item; item=item->next) { - if(item->type == ITEM_BUTTON) - ((uiButtonItem*)item)->but->alignnr= nr; + if(item->type == ITEM_BUTTON) { + bitem= (uiButtonItem*)item; + if(ui_but_can_align(bitem->but)) + bitem->but->alignnr= nr; + } else ui_item_align((uiLayout*)item, nr); } @@ -1538,8 +1583,11 @@ static void ui_item_layout(uiItem *item, int align) if(item->type != ITEM_BUTTON) { uiLayout *litem= (uiLayout*)item; + if(litem->items.first == NULL) + return; + if(litem->align && !align) - ui_item_align(litem, ++litem->common->block->alignnr); + ui_item_align(litem, ++litem->root->block->alignnr); switch(litem->item.type) { case ITEM_LAYOUT_COLUMN: @@ -1580,8 +1628,8 @@ static void ui_layout_items(const bContext *C, uiBlock *block, uiLayout *layout) static void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y) { - if(layout->common->handlefunc) - uiBlockSetButmFunc(block, layout->common->handlefunc, layout->common->argv); + if(layout->root->handlefunc) + uiBlockSetButmFunc(block, layout->root->handlefunc, layout->root->argv); ui_layout_items(C, block, layout); @@ -1608,45 +1656,44 @@ static void ui_layout_free(uiLayout *layout) uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, uiStyle *style) { uiLayout *layout; - uiLayoutCommon *common; + uiLayoutRoot *root; - if(!block->layout) { - common= MEM_callocN(sizeof(uiLayoutCommon), "uiLayoutCommon"); - common->type= type; - common->style= style; - common->block= block; - common->opcontext= WM_OP_INVOKE_REGION_WIN; + root= MEM_callocN(sizeof(uiLayoutRoot), "uiLayoutRoot"); + root->type= type; + root->style= style; + root->block= block; + root->opcontext= WM_OP_INVOKE_REGION_WIN; - layout= MEM_callocN(sizeof(uiLayout), "uiLayout"); - layout->item.type= ITEM_LAYOUT_ROOT; + layout= MEM_callocN(sizeof(uiLayout), "uiLayout"); + layout->item.type= ITEM_LAYOUT_ROOT; - layout->x= x; - layout->y= y; - layout->common= common; - layout->space= style->templatespace; + layout->x= x; + layout->y= y; + layout->root= root; + layout->space= style->templatespace; - if(type == UI_LAYOUT_MENU) - layout->space= 0; - - if(dir == UI_LAYOUT_HORIZONTAL) { - layout->h= size; - layout->common->emh= em*UI_UNIT_Y; - } - else { - layout->w= size; - layout->common->emw= em*UI_UNIT_X; - } + if(type == UI_LAYOUT_MENU) + layout->space= 0; - block->curlayout= layout; - block->layout= layout; + if(dir == UI_LAYOUT_HORIZONTAL) { + layout->h= size; + layout->root->emh= em*UI_UNIT_Y; + } + else { + layout->w= size; + layout->root->emw= em*UI_UNIT_X; } + + block->curlayout= layout; + root->layout= layout; + BLI_addtail(&block->layouts, root); - return block->layout; + return layout; } uiBlock *uiLayoutBlock(uiLayout *layout) { - return layout->common->block; + return layout->root->block; } void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout) @@ -1666,33 +1713,32 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but) void uiLayoutContext(uiLayout *layout, int opcontext) { - layout->common->opcontext= opcontext; + layout->root->opcontext= opcontext; } void uiLayoutFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) { - layout->common->handlefunc= handlefunc; - layout->common->argv= argv; + layout->root->handlefunc= handlefunc; + layout->root->argv= argv; } void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y) { - uiLayout *layout= block->layout; + uiLayoutRoot *root; - if(layout) { - /* NULL in advance so we don't interfere when adding button */ - block->layout= NULL; - block->curlayout= NULL; + if(x) *x= 0; + if(y) *y= 0; - ui_layout_end(C, block, layout, x, y); - MEM_freeN(layout->common); - ui_layout_free(layout); - } - else { - if(x) *x= 0; - if(y) *y= 0; + block->curlayout= NULL; + + for(root=block->layouts.first; root; root=root->next) { + /* NULL in advance so we don't interfere when adding button */ + ui_layout_end(C, block, root->layout, x, y); + ui_layout_free(root->layout); } + BLI_freelistN(&block->layouts); + /* XXX silly trick, interface_templates.c doesn't get linked * because it's not used by other files in this module? */ { diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 36c794ab098..96683750062 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -125,6 +125,7 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa) else if(ar->regiontype==RGN_TYPE_UI) return 1; + /* in case panel is added or disappears */ for(pa=ar->panels.first; pa; pa=pa->next) { if((pa->runtime_flag & PNL_WAS_ACTIVE) && !(pa->runtime_flag & PNL_ACTIVE)) return 1; @@ -134,6 +135,7 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa) active= 1; } + /* in case we need to do an animation (size changes) */ for(pa=ar->panels.first; pa; pa=pa->next) { if(pa->runtime_flag & PNL_ANIM_ALIGN) { if(!active) @@ -155,7 +157,7 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar) pa->ofsy= papar->ofsy + papar->sizey-pa->sizey; } -Panel *uiBeginPanel(ARegion *ar, uiBlock *block, PanelType *pt) +Panel *uiBeginPanel(ARegion *ar, uiBlock *block, PanelType *pt, int *open) { uiStyle *style= U.uistyles.first; Panel *pa, *patab, *palast, *panext; @@ -182,7 +184,7 @@ Panel *uiBeginPanel(ARegion *ar, uiBlock *block, PanelType *pt) BLI_strncpy(pa->panelname, panelname, UI_MAX_NAME_STR); BLI_strncpy(pa->tabname, tabname, UI_MAX_NAME_STR); - pa->ofsx= style->panelouter; + pa->ofsx= 0; pa->ofsy= style->panelouter; pa->sizex= 0; pa->sizey= 0; @@ -227,11 +229,13 @@ Panel *uiBeginPanel(ARegion *ar, uiBlock *block, PanelType *pt) block->panel= pa; pa->runtime_flag |= PNL_ACTIVE|PNL_LAST_ADDED; - if(pa->paneltab) return NULL; - if(pa->flag & PNL_CLOSED) return NULL; + *open= 0; - /* the 'return 0' above makes this to be in end. otherwise closes panels show wrong title */ - pa->drawname[0]= 0; + if(pa->paneltab) return pa; + if(pa->flag & PNL_CLOSED) return pa; + + *open= 1; + pa->drawname[0]= 0; /* otherwise closes panels show wrong title */ return pa; } @@ -274,93 +278,6 @@ void uiPanelToMouse(const bContext *C, Panel *pa) } #endif -/* ofsx/ofsy only used for new panel definitions */ -/* return 1 if visible (create buttons!) */ -int uiNewPanel(const bContext *C, ARegion *ar, uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey) -{ - Panel *pa; - - /* check if Panel exists, then use that one */ - for(pa=ar->panels.first; pa; pa=pa->next) - if(strncmp(pa->panelname, panelname, UI_MAX_NAME_STR)==0) - if(strncmp(pa->tabname, tabname, UI_MAX_NAME_STR)==0) - break; - - if(pa) { - /* scale correction */ - if(pa->control & UI_PNL_SCALE); - else { - pa->sizex= sizex; - if(pa->sizey != sizey) { - pa->ofsy+= (pa->sizey - sizey); // check uiNewPanelHeight() - pa->sizey= sizey; - } - } - } - else { - /* new panel */ - pa= MEM_callocN(sizeof(Panel), "new panel"); - BLI_addtail(&ar->panels, pa); - strncpy(pa->panelname, panelname, UI_MAX_NAME_STR); - strncpy(pa->tabname, tabname, UI_MAX_NAME_STR); - - pa->ofsx= ofsx & ~(PNL_GRID-1); - pa->ofsy= ofsy & ~(PNL_GRID-1); - pa->sizex= sizex; - pa->sizey= sizey; - -#if 0 - /* make new Panel tabbed? */ - if(panel_tabbed && group_tabbed) { - Panel *papar; - for(papar= ar->panels.first; papar; papar= papar->next) { - if(papar->active && papar->paneltab==NULL) { - if( strncmp(panel_tabbed, papar->panelname, UI_MAX_NAME_STR)==0) { - if( strncmp(group_tabbed, papar->tabname, UI_MAX_NAME_STR)==0) { - pa->paneltab= papar; - copy_panel_offset(pa, papar); - break; - } - } - } - } - } -#endif - } - - block->panel= pa; - pa->runtime_flag |= PNL_ACTIVE; - - /* clear ugly globals */ - // XXX pa->control= pnl_control; - // XXX panel_tabbed= group_tabbed= NULL; - // XXX pa->control= UI_PNL_TRANSP; // back to default - - if(pa->paneltab) return 0; - if(pa->flag & PNL_CLOSED) return 0; - - /* the 'return 0' above makes this to be in end. otherwise closes panels show wrong title */ - pa->drawname[0]= 0; - - return 1; -} - -void uiNewPanelHeight(uiBlock *block, int sizey) -{ - if(sizey<0) sizey= 0; - - if(block->panel) { - block->panel->ofsy+= (block->panel->sizey - sizey); - block->panel->sizey= sizey; - } -} - -void uiNewPanelTitle(uiBlock *block, char *str) -{ - if(block->panel) - BLI_strncpy(block->panel->drawname, str, UI_MAX_NAME_STR); -} - static int panel_has_tabs(ARegion *ar, Panel *panel) { Panel *pa= ar->panels.first; @@ -376,35 +293,20 @@ static int panel_has_tabs(ARegion *ar, Panel *panel) return 0; } -static void ui_scale_panel_block(uiBlock *block) +static void ui_offset_panel_block(uiBlock *block) { uiStyle *style= U.uistyles.first; uiBut *but; - float facx= 1.0, facy= 1.0; - int centerx= 0, topy=0, tabsy=0, space= style->panelspace; - - if(block->panel==NULL) return; + int space= style->panelspace; /* buttons min/max centered, offset calculated */ ui_bounds_block(block); - if((!block->panel->type) && block->maxx-block->minx > block->panel->sizex - 2*space) - facx= (block->panel->sizex - (2*space))/(block->maxx-block->minx); - else - centerx= (block->panel->sizex-(block->maxx-block->minx) - 2*space)/2; - - // tabsy= PNL_HEADER*panel_has_tabs(block->panel); - if((!block->panel->type) && (block->maxy-block->miny) > block->panel->sizey - 2*space - tabsy) - facy= (block->panel->sizey - (2*space) - tabsy)/(block->maxy-block->miny); - else - topy= (block->panel->sizey- 2*space - tabsy) - (block->maxy-block->miny) ; - for(but= block->buttons.first; but; but=but->next) { - but->x1= space+centerx+ facx*(but->x1-block->minx); - but->y1= space+topy + facy*(but->y1-block->miny); - but->x2= space+centerx+ facx*(but->x2-block->minx); - but->y2= space+topy + facy*(but->y2-block->miny); - if(facx!=1.0) ui_check_but(but); /* for strlen */ + but->x1= space + (but->x1-block->minx); + but->y1= space + (but->y1-block->miny); + but->x2= space + (but->x2-block->minx); + but->y2= space + (but->y2-block->miny); } block->maxx= block->panel->sizex; @@ -412,110 +314,6 @@ static void ui_scale_panel_block(uiBlock *block) block->minx= block->miny= 0.0; } -// for 'home' key -void uiPanelsHome(ARegion *ar) -{ - uiStyle *style= U.uistyles.first; - Panel *pa; - uiBlock *block; - View2D *v2d; - float minx=10000, maxx= -10000, miny=10000, maxy= -10000; - int done=0; - - v2d= &ar->v2d; - - for(pa= ar->panels.first; pa; pa=pa->next) { - if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { - done= 1; - if(pa->ofsx < minx) minx= pa->ofsx; - if(pa->ofsx+pa->sizex > maxx) maxx= pa->ofsx+pa->sizex; - if(pa->ofsy < miny) miny= pa->ofsy; - if(pa->ofsy+pa->sizey+PNL_HEADER > maxy) maxy= pa->ofsy+pa->sizey+PNL_HEADER; - } - } - - if(done) { - v2d->tot.xmin= minx-style->panelouter; - v2d->tot.xmax= maxx+style->panelouter; - v2d->tot.ymin= miny-style->panelouter; - v2d->tot.ymax= maxy+style->panelouter; - } - else { - v2d->tot.xmin= 0; - v2d->tot.xmax= 1280; - v2d->tot.ymin= 0; - v2d->tot.ymax= 228; - - /* no panels, but old 'loose' buttons, as in old logic editor */ - for(block= ar->uiblocks.first; block; block= block->next) { - if(block->minx < v2d->tot.xmin) v2d->tot.xmin= block->minx; - if(block->maxx > v2d->tot.xmax) v2d->tot.xmax= block->maxx; - if(block->miny < v2d->tot.ymin) v2d->tot.ymin= block->miny; - if(block->maxy > v2d->tot.ymax) v2d->tot.ymax= block->maxy; - } - } -} - -// make sure the panels are not outside 'tot' area -static void ui_panels_update_totrct(ARegion *ar) -{ - Panel *pa; - uiBlock *block; - View2D *v2d; - int done=0; - - v2d= &ar->v2d; - - v2d->tot.xmin= 0.0f; - v2d->tot.xmax= ar->winx; - v2d->tot.ymax= 0.0f; - v2d->tot.ymin= -ar->winy; - - for(pa= ar->panels.first; pa; pa=pa->next) { - if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { - done= 1; - - if(pa->ofsx < v2d->tot.xmin) - v2d->tot.xmin= pa->ofsx; - if(pa->ofsx+pa->sizex > v2d->tot.xmax) - v2d->tot.xmax= pa->ofsx+pa->sizex; - if(pa->ofsy < v2d->tot.ymin) - v2d->tot.ymin= pa->ofsy; - if(pa->ofsy+pa->sizey+PNL_HEADER > v2d->tot.ymax) - v2d->tot.ymax= pa->ofsy+pa->sizey+PNL_HEADER; - } - } - - if(done==0) { - /* no panels, but old 'loose' buttons, as in old logic editor */ - for(block= ar->uiblocks.first; block; block= block->next) { - if(block->minx < v2d->tot.xmin) v2d->tot.xmin= block->minx; - if(block->maxx > v2d->tot.xmax) v2d->tot.xmax= block->maxx; - if(block->miny < v2d->tot.ymin) v2d->tot.ymin= block->miny; - if(block->maxy > v2d->tot.ymax) v2d->tot.ymax= block->maxy; - } - } - - UI_view2d_totRect_set(v2d, v2d->tot.xmax, v2d->tot.ymin); -} - -uiBlock *uiFindOpenPanelBlockName(ListBase *lb, char *name) -{ - uiBlock *block; - Panel *pa; - - for(block= lb->first; block; block= block->next) { - pa= block->panel; - - if(pa && (pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { - if(pa->flag & PNL_CLOSED); - else if(strncmp(name, pa->panelname, UI_MAX_NAME_STR)==0) break; - } - } - - return block; -} - /**************************** drawing *******************************/ /* extern used by previewrender */ @@ -652,8 +450,9 @@ static void ui_draw_aligned_panel_header(ARegion *ar, uiStyle *style, uiBlock *b if(pa->paneltab==panel) nr++; - if(panel->control & UI_PNL_CLOSE) pnl_icons=(2*PNL_ICON+10)/block->aspect; - else pnl_icons= (PNL_ICON+10)/block->aspect; + /* + 0.001f to avoid flirting with float inaccuracy */ + if(panel->control & UI_PNL_CLOSE) pnl_icons=(2*PNL_ICON+5)/block->aspect + 0.001f; + else pnl_icons= (PNL_ICON+5)/block->aspect + 0.001f; if(nr==1) { @@ -718,9 +517,10 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re if(panel->paneltab) return; /* calculate header rect */ + /* + 0.001f to prevent flicker due to float inaccuracy */ headrect= *rect; headrect.ymin= headrect.ymax; - headrect.ymax= headrect.ymin + floor(PNL_HEADER/block->aspect); + headrect.ymax= headrect.ymin + floor(PNL_HEADER/block->aspect + 0.001f); /* divider only when there's a previous panel */ prev= panel->prev; @@ -729,8 +529,8 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re prev= prev->prev; } - if(prev) { - float minx= rect->xmin+10.0f/block->aspect; + if(panel->sortorder != 0) { + float minx= rect->xmin+5.0f/block->aspect; float maxx= rect->xmax-5.0f/block->aspect; float y= headrect.ymax; @@ -747,7 +547,7 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re ui_draw_aligned_panel_header(ar, style, block, &headrect); /* itemrect smaller */ - itemrect.xmax= headrect.xmax - 10.0f/block->aspect; + itemrect.xmax= headrect.xmax - 5.0f/block->aspect; itemrect.xmin= itemrect.xmax - (headrect.ymax-headrect.ymin); itemrect.ymin= headrect.ymin; itemrect.ymax= headrect.ymax; @@ -808,12 +608,12 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re UI_ThemeColor(TH_TEXT); /* itemrect smaller */ - itemrect.xmin= headrect.xmin + 10.0f/block->aspect; + itemrect.xmin= headrect.xmin + 5.0f/block->aspect; itemrect.xmax= itemrect.xmin + (headrect.ymax-headrect.ymin); itemrect.ymin= headrect.ymin; itemrect.ymax= headrect.ymax; - rectf_scale(&itemrect, 0.7f); + rectf_scale(&itemrect, 0.5f); if(panel->flag & PNL_CLOSEDY) ui_draw_tria_rect(&itemrect, 'h'); @@ -944,7 +744,7 @@ int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac, int drag) /* no smart other default start loc! this keeps switching f5/f6/etc compatible */ ps= panelsort; - ps->pa->ofsx= style->panelouter; + ps->pa->ofsx= 0; ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-style->panelouter; for(a=0; apa->ofsy= get_panel_real_ofsy(ps->pa) - psnext->pa->sizey-PNL_HEADER-style->panelouter; } else { - psnext->pa->ofsx= get_panel_real_ofsx(ps->pa)+style->panelouter; + psnext->pa->ofsx= get_panel_real_ofsx(ps->pa); psnext->pa->ofsy= ps->pa->ofsy + ps->pa->sizey - psnext->pa->sizey; } } @@ -1034,7 +834,7 @@ void uiEndPanels(const bContext *C, ARegion *ar) /* scaling contents */ for(block= ar->uiblocks.first; block; block= block->next) if(block->active && block->panel) - ui_scale_panel_block(block); + ui_offset_panel_block(block); /* consistancy; are panels not made, whilst they have tabs */ for(panot= ar->panels.first; panot; panot= panot->next) { @@ -1068,93 +868,6 @@ void uiEndPanels(const bContext *C, ARegion *ar) else uiAlignPanelStep(sa, ar, 1.0, 0); } - - if(sa->spacetype!=SPACE_BUTS) { -#if 0 // XXX make float panel exception - SpaceLink *sl= sa->spacedata.first; - for(block= ar->uiblocks.first; block; block= block->next) { - if(block->active && block->panel && block->panel->active && block->panel->paneltab == NULL) { - float dx=0.0, dy=0.0, minx, miny, maxx, maxy, miny_panel; - - minx= sl->blockscale*block->panel->ofsx; - maxx= sl->blockscale*(block->panel->ofsx+block->panel->sizex); - miny= sl->blockscale*(block->panel->ofsy+block->panel->sizey); - maxy= sl->blockscale*(block->panel->ofsy+block->panel->sizey+PNL_HEADER); - miny_panel= sl->blockscale*(block->panel->ofsy); - - /* check to see if snapped panels have been left out in the open by resizing a window - * and if so, offset them back to where they belong */ - if (block->panel->snap) { - if (((block->panel->snap) & PNL_SNAP_RIGHT) && - (maxx < (float)sa->winx)) { - - dx = sa->winx-maxx; - block->panel->ofsx+= dx/sl->blockscale; - } - if (((block->panel->snap) & PNL_SNAP_TOP) && - (maxy < (float)sa->winy)) { - - dy = sa->winy-maxy; - block->panel->ofsy+= dy/sl->blockscale; - } - - /* reset these vars with updated panel offset distances */ - minx= sl->blockscale*block->panel->ofsx; - maxx= sl->blockscale*(block->panel->ofsx+block->panel->sizex); - miny= sl->blockscale*(block->panel->ofsy+block->panel->sizey); - maxy= sl->blockscale*(block->panel->ofsy+block->panel->sizey+PNL_HEADER); - miny_panel= sl->blockscale*(block->panel->ofsy); - } else - /* reset to no snapping */ - block->panel->snap = PNL_SNAP_NONE; - - - /* clip panels (headers) for non-butspace situations (maybe make optimized event later) */ - - /* check left and right edges */ - if (minx < PNL_SNAP_DIST) { - dx = -minx; - block->panel->snap |= PNL_SNAP_LEFT; - } - else if (maxx > ((float)sa->winx - PNL_SNAP_DIST)) { - dx= sa->winx-maxx; - block->panel->snap |= PNL_SNAP_RIGHT; - } - if(minx + dx < 0.0) dx= -minx; // when panel cant fit, put it fixed here - - /* check top and bottom edges */ - if ((miny_panel < PNL_SNAP_DIST) && (miny_panel > -PNL_SNAP_DIST)) { - dy= -miny_panel; - block->panel->snap |= PNL_SNAP_BOTTOM; - } - if(miny < PNL_SNAP_DIST) { - dy= -miny; - block->panel->snap |= PNL_SNAP_BOTTOM; - } - else if(maxy > ((float)sa->winy - PNL_SNAP_DIST)) { - dy= sa->winy-maxy; - block->panel->snap |= PNL_SNAP_TOP; - } - if(miny + dy < 0.0) dy= -miny; // when panel cant fit, put it fixed here - - - block->panel->ofsx+= dx/sl->blockscale; - block->panel->ofsy+= dy/sl->blockscale; - - /* copy locations */ - for(patest= ar->panels.first; patest; patest= patest->next) { - if(patest->paneltab==block->panel) ui_panel_copy_offset(patest, block->panel); - } - - } - } -#endif - } - - /* update v2d->totrct and update view */ - ui_panels_update_totrct(ar); - UI_view2d_view_restore(C); - UI_view2d_view_ortho(C, &ar->v2d); /* draw panels, selected on top */ for(block= ar->uiblocks.first; block; block=block->next) { @@ -1464,6 +1177,10 @@ int ui_handler_panel_region(bContext *C, wmEvent *event) retval= WM_UI_HANDLER_CONTINUE; + /* buttons get priority */ + if(ui_button_is_active(ar)) + return retval; + for(block=ar->uiblocks.last; block; block=block->prev) { mx= event->x; my= event->y; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 5244c9983cf..8969e2b69ae 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -42,16 +42,6 @@ #include "UI_interface.h" #include "UI_resources.h" -static uiBlock *block_free_layout(uiLayout *layout) -{ - uiBlock *block; - - block= uiLayoutBlock(layout); - uiBlockSetCurLayout(block, uiLayoutFree(layout, 0)); - - return block; -} - void ui_template_fix_linking() { } @@ -62,7 +52,7 @@ void uiTemplateHeader(uiLayout *layout, bContext *C) { uiBlock *block; - block= block_free_layout(layout); + block= uiLayoutFreeBlock(layout); ED_area_header_standardbuttons(C, block, 0); } @@ -240,7 +230,7 @@ void uiTemplateHeaderID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr BLI_strncpy(template->unlinkop, unlinkop, sizeof(template->unlinkop)); } - block= block_free_layout(layout); + block= uiLayoutFreeBlock(layout); template_header_ID(C, block, template); MEM_freeN(template); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index e3f986efde9..e9d96446c11 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -315,16 +315,12 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind return but; } -int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) +void uiDefAutoButsRNA(const bContext *C, uiLayout *layout, PointerRNA *ptr) { - uiStyle *style= U.uistyles.first; CollectionPropertyIterator iter; PropertyRNA *iterprop, *prop; - uiLayout *layout, *split; + uiLayout *split; char *name; - int x= 0, y= 0; - - layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, DEF_BUT_WIDTH*2, 20, style); uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0); @@ -342,26 +338,19 @@ int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) name= (char*)RNA_property_ui_name(prop); uiItemL(uiLayoutColumn(split, 0), name, 0); - uiItemFullR(uiLayoutColumn(split, 0), "", 0, ptr, prop, -1, 0, 0); + uiItemFullR(uiLayoutColumn(split, 0), "", 0, ptr, prop, -1, 0, 0, 0); } RNA_property_collection_end(&iter); - uiBlockLayoutResolve(C, block, &x, &y); - - return -y; } /* temp call, single collumn, test for toolbar only */ -int uiDefAutoButsRNA_single(const bContext *C, uiBlock *block, PointerRNA *ptr) +void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr) { - uiStyle *style= U.uistyles.first; CollectionPropertyIterator iter; PropertyRNA *iterprop, *prop; - uiLayout *layout; + uiLayout *col; char *name; - int x= 0, y= 0; - - layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, block->panel->sizex, 20, style); uiItemL(layout, (char*)RNA_struct_ui_name(ptr->type), 0); @@ -375,17 +364,14 @@ int uiDefAutoButsRNA_single(const bContext *C, uiBlock *block, PointerRNA *ptr) continue; name= (char*)RNA_property_ui_name(prop); - uiItemL(layout, name, 0); - uiItemFullR(layout, "", 0, ptr, prop, -1, 0, 0); + col= uiLayoutColumn(layout, 1); + uiItemL(col, name, 0); + uiItemFullR(col, "", 0, ptr, prop, -1, 0, 0, 0); } RNA_property_collection_end(&iter); - uiBlockLayoutResolve(C, block, &x, &y); - - return -y; } - /***************************** ID Utilities *******************************/ typedef struct uiIDPoinParams { diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 191f38ad7d0..f2fc2deefbb 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -155,23 +155,6 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) { short tot_changed= 0; - /* XXX always set state vars for buttonsview, this is hardcoded */ - switch (type) { - /* panels view, with free/horizontal/vertical align */ - case V2D_COMMONVIEW_PANELS_UI: - { - /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */ - v2d->keepzoom= (V2D_KEEPASPECT|V2D_KEEPZOOM); - v2d->minzoom= 0.5f; - v2d->maxzoom= 2.0f; - - v2d->align= (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y); - v2d->keeptot= V2D_KEEPTOT_BOUNDS; - } - break; - } - - /* initialise data if there is a need for such */ if ((v2d->flag & V2D_IS_INITIALISED) == 0) { /* set initialised flag so that View2D doesn't get reinitialised next time again */ @@ -249,28 +232,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) } break; - /* ui listviews, tries to wrap 'tot' inside region width */ - case V2D_COMMONVIEW_LIST_UI: - { - /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */ - v2d->keepzoom= (V2D_KEEPASPECT|V2D_KEEPZOOM); - v2d->minzoom= 0.5f; - v2d->maxzoom= 2.0f; - - v2d->align= (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y); - v2d->keeptot= V2D_KEEPTOT_BOUNDS; - - v2d->tot.xmin= 0.0f; - v2d->tot.xmax= 336.f; // XXX 320 width + 2 x PNL_DIST - - v2d->tot.ymax= 0.0f; - v2d->tot.ymin= -336.0f*((float)winy)/(float)winx; - - v2d->cur= v2d->tot; - } - break; - - /* panels view, with free/horizontal/vertical align */ + /* panels view, with horizontal/vertical align */ case V2D_COMMONVIEW_PANELS_UI: { /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */ @@ -465,18 +427,28 @@ void UI_view2d_curRect_validate(View2D *v2d) /* resize from centerpoint */ if (width != curwidth) { - temp= (cur->xmax + cur->xmin) * 0.5f; - dh= width * 0.5f; - - cur->xmin = temp - dh; - cur->xmax = temp + dh; + if (v2d->keepofs & V2D_LOCKOFS_X) { + cur->xmax += width - (cur->xmax - cur->xmin); + } + else { + temp= (cur->xmax + cur->xmin) * 0.5f; + dh= width * 0.5f; + + cur->xmin = temp - dh; + cur->xmax = temp + dh; + } } if (height != curheight) { - temp= (cur->ymax + cur->ymin) * 0.5f; - dh= height * 0.5f; - - cur->ymin = temp - dh; - cur->ymax = temp + dh; + if (v2d->keepofs & V2D_LOCKOFS_Y) { + cur->ymax += height - (cur->ymax - cur->ymin); + } + else { + temp= (cur->ymax + cur->ymin) * 0.5f; + dh= height * 0.5f; + + cur->ymin = temp - dh; + cur->ymax = temp + dh; + } } } @@ -872,8 +844,13 @@ void UI_view2d_view_ortho(const bContext *C, View2D *v2d) * but only applied where requsted */ /* XXX ton: fix this! */ - xofs= 0.0f; // (v2d->flag & V2D_PIXELOFS_X) ? 0.375f : 0.0f; - yofs= 0.0f; // (v2d->flag & V2D_PIXELOFS_Y) ? 0.375f : 0.0f; + xofs= 0.0; // (v2d->flag & V2D_PIXELOFS_X) ? 0.375f : 0.0f; + yofs= 0.0; // (v2d->flag & V2D_PIXELOFS_Y) ? 0.375f : 0.0f; + + /* XXX brecht: instead of zero at least use a tiny offset, otherwise + * pixel rounding is effectively random due to float inaccuracy */ + xofs= 0.001f; + yofs= 0.001f; /* apply mask-based adjustments to cur rect (due to scrollers), to eliminate scaling artifacts */ view2d_map_cur_using_mask(v2d, &curmasked); diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 6da9512f9e0..bd1c734b870 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -54,6 +54,12 @@ #include "UI_resources.h" #include "UI_view2d.h" +static int view2d_poll(bContext *C) +{ + ARegion *ar= CTX_wm_region(C); + + return (ar != NULL) && (ar->v2d.flag & V2D_IS_INITIALISED); +} /* ********************************************************* */ /* VIEW PANNING OPERATOR */ @@ -110,8 +116,8 @@ static int view_pan_init(bContext *C, wmOperator *op) vpd->v2d= v2d; /* calculate translation factor - based on size of view */ - winx= (float)(ar->winrct.xmax - ar->winrct.xmin); - winy= (float)(ar->winrct.ymax - ar->winrct.ymin); + winx= (float)(ar->winrct.xmax - ar->winrct.xmin + 1); + winy= (float)(ar->winrct.ymax - ar->winrct.ymin + 1); vpd->facx= (v2d->cur.xmax - v2d->cur.xmin) / winx; vpd->facy= (v2d->cur.ymax - v2d->cur.ymin) / winy; @@ -489,12 +495,22 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op) /* only resize view on an axis if change is allowed */ if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0) { - v2d->cur.xmin += dx; - v2d->cur.xmax -= dx; + if (v2d->keepofs & V2D_LOCKOFS_X) { + v2d->cur.xmax -= 2*dx; + } + else { + v2d->cur.xmin += dx; + v2d->cur.xmax -= dx; + } } if ((v2d->keepzoom & V2D_LOCKZOOM_Y)==0) { - v2d->cur.ymin += dy; - v2d->cur.ymax -= dy; + if (v2d->keepofs & V2D_LOCKOFS_Y) { + v2d->cur.ymax -= 2*dy; + } + else { + v2d->cur.ymin += dy; + v2d->cur.ymax -= dy; + } } /* validate that view is in valid configuration after this operation */ @@ -635,12 +651,22 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) /* only move view on an axis if change is allowed */ if ((v2d->keepzoom & V2D_LOCKZOOM_X)==0) { - v2d->cur.xmin += dx; - v2d->cur.xmax -= dx; + if (v2d->keepofs & V2D_LOCKOFS_X) { + v2d->cur.xmax -= 2*dx; + } + else { + v2d->cur.xmin += dx; + v2d->cur.xmax -= dx; + } } if ((v2d->keepzoom & V2D_LOCKZOOM_Y)==0) { - v2d->cur.ymin += dy; - v2d->cur.ymax -= dy; + if (v2d->keepofs & V2D_LOCKOFS_Y) { + v2d->cur.ymax -= 2*dy; + } + else { + v2d->cur.ymin += dy; + v2d->cur.ymax -= dy; + } } /* validate that view is in valid configuration after this operation */ @@ -1187,15 +1213,8 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, wmEvent *event) static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event) { ARegion *ar= CTX_wm_region(C); - View2D *v2d= NULL; + View2D *v2d= &ar->v2d; short in_scroller= 0; - - /* firstly, check context to see if mouse is actually in region */ - // XXX isn't this the job of poll() callbacks which can't check events, but only context? - if (ar == NULL) - return OPERATOR_PASS_THROUGH;//OPERATOR_CANCELLED; - else - v2d= &ar->v2d; /* check if mouse in scrollbars, if they're enabled */ in_scroller= UI_view2d_mouse_in_scrollers(C, v2d, event->x, event->y); @@ -1241,6 +1260,70 @@ void VIEW2D_OT_scroller_activate(wmOperatorType *ot) /* api callbacks */ ot->invoke= scroller_activate_invoke; ot->modal= scroller_activate_modal; + ot->poll= view2d_poll; +} + +/* ********************************************************* */ +/* RESET */ + +static int reset_exec(bContext *C, wmOperator *op) +{ + ARegion *ar= CTX_wm_region(C); + View2D *v2d= &ar->v2d; + int winx, winy; + + /* zoom 1.0 */ + winx= (float)(v2d->mask.xmax - v2d->mask.xmin + 1); + winy= (float)(v2d->mask.ymax - v2d->mask.ymin + 1); + + v2d->cur.xmax= v2d->cur.xmin + winx; + v2d->cur.ymax= v2d->cur.ymin + winy; + + /* align */ + if(v2d->align) { + /* posx and negx flags are mutually exclusive, so watch out */ + if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) { + v2d->cur.xmax= 0.0f; + v2d->cur.xmin= v2d->winx; + } + else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) { + v2d->cur.xmax= v2d->cur.xmax - v2d->cur.xmin; + v2d->cur.xmin= 0.0f; + } + + /* - posx and negx flags are mutually exclusive, so watch out */ + if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) { + v2d->cur.ymax= 0.0f; + v2d->cur.ymin= -v2d->winy; + } + else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) { + v2d->cur.ymax= v2d->cur.ymax - v2d->cur.ymin; + v2d->cur.ymin= 0.0f; + } + } + + /* validate that view is in valid configuration after this operation */ + UI_view2d_curRect_validate(v2d); + + /* request updates to be done... */ + ED_area_tag_redraw(CTX_wm_area(C)); + UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); + + return OPERATOR_FINISHED; +} + +void VIEW2D_OT_reset(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reset View"; + ot->idname= "VIEW2D_OT_reset"; + + /* api callbacks */ + ot->exec= reset_exec; + ot->poll= view2d_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } /* ********************************************************* */ @@ -1262,6 +1345,8 @@ void ui_view2d_operatortypes(void) WM_operatortype_append(VIEW2D_OT_zoom_border); WM_operatortype_append(VIEW2D_OT_scroller_activate); + + WM_operatortype_append(VIEW2D_OT_reset); } void UI_view2d_keymap(wmWindowManager *wm) @@ -1300,12 +1385,15 @@ void UI_view2d_keymap(wmWindowManager *wm) /* scrollers */ WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0); - + /* Alternative keymap for buttons listview */ keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW2D_OT_reset", HOMEKEY, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index e344a177517..4920182c16b 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -966,24 +966,29 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex uiBlock *block; PanelType *pt; Panel *panel; + View2D *v2d= &ar->v2d; float col[3]; - int xco, yco, x, y, w, em, header; + int xco, yco, x, y, miny=0, w, em, header, open; + + if(vertical) { + w= v2d->cur.xmax - v2d->cur.xmin; + em= (ar->type->minsizex)? 10: 20; + } + else { + w= UI_PANEL_WIDTH; + em= (ar->type->minsizex)? 10: 20; + } header= 20; // XXX - x= style->panelouter; - y= -(header + style->panelouter); + x= 0; + y= -style->panelouter; - /* clear */ - UI_GetThemeColor3fv(TH_BACK, col); - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - /* create panels */ uiBeginPanels(C, ar); + /* set view2d view matrix for scrolling (without scrollers) */ + UI_view2d_view_ortho(C, v2d); + for(pt= ar->type->paneltypes.first; pt; pt= pt->next) { /* verify context */ if(context) @@ -993,18 +998,25 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex /* draw panel */ if(pt->draw && (!pt->poll || pt->poll(C, pt))) { block= uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); - panel= uiBeginPanel(ar, block, pt); + panel= uiBeginPanel(ar, block, pt, &open); - if(panel) { - if(vertical) { - w= (ar->type->minsizex)? ar->type->minsizex-12: uiBlockAspect(block)*ar->winx-12; - em= (ar->type->minsizex)? 10: 20; - } - else { - w= (ar->type->minsizex)? ar->type->minsizex-12: UI_PANEL_WIDTH-12; - em= (ar->type->minsizex)? 10: 20; - } + if(vertical) + y -= header; + + /* XXX enable buttons test */ +#if 0 + panel->layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, + header+style->panelspace, header+style->panelspace, header, 1, style); + + if(pt->draw_header) + pt->draw_header(C, panel); + else + uiItemL(panel->layout, pt->label, 0); + + panel->layout= NULL; +#endif + if(open) { panel->type= pt; panel->layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, style->panelspace, 0, w-2*style->panelspace, em, style); @@ -1012,29 +1024,74 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex pt->draw(C, panel); uiBlockLayoutResolve(C, block, &xco, &yco); - uiEndPanel(block, w, -yco + 12); panel->layout= NULL; + + yco -= 2*style->panelspace; + uiEndPanel(block, w, -yco); } - else { - w= header; - yco= header; - } + else + yco= 0; uiEndBlock(C, block); - if(vertical) - y += yco+style->panelouter; - else - x += w+style->panelouter; + if(vertical) { + y += yco-style->panelouter; + } + else { + x += w; + miny= MIN2(y, yco-style->panelouter-header); + } } } + if(vertical) + x += w; + else + y= miny; + + /* in case there are no panels */ + if(x == 0 || y == 0) { + x= UI_PANEL_WIDTH; + y= UI_PANEL_WIDTH; + } + + /* clear */ + UI_GetThemeColor3fv(TH_BACK, col); + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* before setting the view */ + if(vertical) { + v2d->keepofs |= V2D_LOCKOFS_X; + v2d->keepofs &= ~V2D_LOCKOFS_Y; + } + else { + v2d->keepofs &= ~V2D_LOCKOFS_X; + v2d->keepofs |= V2D_LOCKOFS_Y; + } + + UI_view2d_totRect_set(v2d, x, -y); + + /* set the view */ + UI_view2d_view_ortho(C, v2d); + + /* this does the actual drawing! */ uiEndPanels(C, ar); - /* restore view matrix? */ + /* restore view matrix */ UI_view2d_view_restore(C); } +void ED_region_panels_init(wmWindowManager *wm, ARegion *ar) +{ + ListBase *keymap; + + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); + + keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); +} + void ED_region_header(const bContext *C, ARegion *ar) { uiStyle *style= U.uistyles.first; @@ -1083,3 +1140,9 @@ void ED_region_header(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); } +void ED_region_header_init(ARegion *ar) +{ + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); + ar->v2d.flag &= ~(V2D_PIXELOFS_X|V2D_PIXELOFS_Y); // XXX temporary +} + diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c index 91b88ad5b1b..83586986e23 100644 --- a/source/blender/editors/space_buttons/buttons_header.c +++ b/source/blender/editors/space_buttons/buttons_header.c @@ -68,12 +68,10 @@ static void do_viewmenu(bContext *C, void *arg, int event) ScrArea *sa= CTX_wm_area(C); switch(event) { - case 0: /* panel alignment */ case 1: case 2: sbuts->align= event; - if(sbuts->align) - sbuts->re_align= 1; + sbuts->re_align= 1; break; } @@ -96,9 +94,6 @@ static uiBlock *dummy_viewmenu(bContext *C, ARegion *ar, void *arg_unused) if (sbuts->align == 2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Vertical", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Vertical", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, ""); - if (sbuts->align == 0) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Free", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, ""); - else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Free", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, ""); - if(sa->headertype==HEADERTOP) { uiBlockSetDirection(block, UI_DOWN); } @@ -151,7 +146,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar) uiDefPulldownBut(block, dummy_viewmenu, CTX_wm_area(C), "View", xco, yco, xmax-3, 20, ""); - xco+=XIC+xmax; + xco+=xmax; } // DATA Icons if(ob) { diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 785f0d0b89b..9f5e0f5974a 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -132,7 +132,7 @@ static void buttons_init(struct wmWindowManager *wm, ScrArea *sa) SpaceButs *sbuts= sa->spacedata.first; /* auto-align based on size */ - if(sbuts->align == BUT_AUTO) { + if(sbuts->align == BUT_AUTO || !sbuts->align) { if(sa->winx > sa->winy) sbuts->align= BUT_HORIZONTAL; else @@ -155,8 +155,7 @@ static void buttons_main_area_init(wmWindowManager *wm, ARegion *ar) { ListBase *keymap; -// ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f; - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); + ED_region_panels_init(wm, ar); /* own keymap */ keymap= WM_keymap_listbase(wm, "Buttons", SPACE_BUTS, 0); /* XXX weak? */ @@ -280,7 +279,7 @@ void ED_spacetype_buttons(void) art->init= buttons_main_area_init; art->draw= buttons_main_area_draw; art->listener= buttons_area_listener; - art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES; + art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; BLI_addhead(&st->regiontypes, art); /* regions: header */ diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 16628f31b63..a4babaad74c 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -104,18 +104,49 @@ static void do_graph_region_buttons(bContext *C, void *arg, int event) //WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); } -static void graph_panel_properties(const bContext *C, ARegion *ar, short cntrl, bAnimListElem *ale) +static int graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve **fcu) { - FCurve *fcu= (FCurve *)ale->data; + bAnimContext ac; + bAnimListElem *elem= NULL; + + /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools) + * to work correctly is able to be correctly retrieved. There's no point showing empty panels? + */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return 0; + + /* try to find 'active' F-Curve */ + elem= get_active_fcurve_channel(&ac); + if(elem == NULL) + return 0; + + if(fcu) + *fcu= (FCurve*)elem->data; + if(ale) + *ale= elem; + else + MEM_freeN(elem); + + return 1; +} + +static int graph_panel_poll(const bContext *C, PanelType *pt) +{ + return graph_panel_context(C, NULL, NULL); +} + +static void graph_panel_properties(const bContext *C, Panel *pa) +{ + bAnimListElem *ale; + FCurve *fcu; uiBlock *block; char name[128]; - block= uiBeginBlock(C, ar, "graph_panel_properties", UI_EMBOSS); - if (uiNewPanel(C, ar, block, "Properties", "Graph", 340, 30, 318, 254)==0) return; - uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); + if(!graph_panel_context(C, &ale, &fcu)) + return; - /* to force height */ - uiNewPanelHeight(block, 204); + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); /* Info - Active F-Curve */ uiDefBut(block, LABEL, 1, "Active F-Curve:", 10, 200, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); @@ -136,6 +167,8 @@ static void graph_panel_properties(const bContext *C, ARegion *ar, short cntrl, * - Access details (ID-block + RNA-Path + Array Index) * - ... */ + + MEM_freeN(ale); } /* ******************* drivers ******************************** */ @@ -206,11 +239,23 @@ static void driver_update_flags_cb (bContext *C, void *fcu_v, void *dummy_v) driver->flag &= ~DRIVER_FLAG_INVALID; } +/* drivers panel poll */ +static int graph_panel_drivers_poll(const bContext *C, PanelType *pt) +{ + SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C); + + if(sipo->mode != SIPO_MODE_DRIVERS) + return 0; + + return graph_panel_context(C, NULL, NULL); +} -static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAnimListElem *ale) +/* driver settings for active F-Curve (only for 'Drivers' mode) */ +static void graph_panel_drivers(const bContext *C, Panel *pa) { - FCurve *fcu= (FCurve *)ale->data; - ChannelDriver *driver= fcu->driver; + bAnimListElem *ale; + FCurve *fcu; + ChannelDriver *driver; DriverTarget *dtar; PointerRNA rna_ptr; @@ -218,12 +263,13 @@ static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAn uiBut *but; int yco=85, i=0; - block= uiBeginBlock(C, ar, "graph_panel_drivers", UI_EMBOSS); - if (uiNewPanel(C, ar, block, "Drivers", "Graph", 340, 30, 318, 254)==0) return; - uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); + if(!graph_panel_context(C, &ale, &fcu)) + return; - /* to force height */ - uiNewPanelHeight(block, 204); + driver= fcu->driver; + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); /* general actions */ but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Update Dependencies", 10, 200, 180, 22, NULL, 0.0, 0.0, 0, 0, "Force updates of dependencies"); @@ -296,12 +342,8 @@ static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAn yco -= height; i++; } - - /* since these buttons can have variable height */ - if (yco < 0) - uiNewPanelHeight(block, (204 - yco)); - else - uiNewPanelHeight(block, 204); + + MEM_freeN(ale); } /* ******************* f-modifiers ******************************** */ @@ -928,18 +970,19 @@ static void graph_panel_modifier_draw(uiBlock *block, FCurve *fcu, FModifier *fc (*yco) -= (height + 27); } -static void graph_panel_modifiers(const bContext *C, ARegion *ar, short cntrl, bAnimListElem *ale) +static void graph_panel_modifiers(const bContext *C, Panel *pa) { - FCurve *fcu= (FCurve *)ale->data; + bAnimListElem *ale; + FCurve *fcu; FModifier *fcm; uiBlock *block; int yco= 190; - block= uiBeginBlock(C, ar, "graph_panel_modifiers", UI_EMBOSS); - if (uiNewPanel(C, ar, block, "Modifiers", "Graph", 340, 30, 318, 254)==0) return; - uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL); + if(!graph_panel_context(C, &ale, &fcu)) + return; - uiNewPanelHeight(block, 204); + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL); /* 'add modifier' button at top of panel */ // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator @@ -948,12 +991,8 @@ static void graph_panel_modifiers(const bContext *C, ARegion *ar, short cntrl, b /* draw each modifier */ for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) graph_panel_modifier_draw(block, fcu, fcm, &yco); - - /* since these buttons can have variable height */ - if (yco < 0) - uiNewPanelHeight(block, (204 - yco)); - else - uiNewPanelHeight(block, 204); + + MEM_freeN(ale); } /* ******************* general ******************************** */ @@ -986,44 +1025,32 @@ bAnimListElem *get_active_fcurve_channel (bAnimContext *ac) return NULL; } -void graph_region_buttons(const bContext *C, ARegion *ar) +void graph_buttons_register(ARegionType *art) { - SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C); - bAnimContext ac; - bAnimListElem *ale= NULL; - - /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools) - * to work correctly is able to be correctly retrieved. There's no point showing empty panels? - */ - if (ANIM_animdata_get_context(C, &ac) == 0) - return; - - - /* try to find 'active' F-Curve */ - ale= get_active_fcurve_channel(&ac); - if (ale == NULL) - return; - - uiBeginPanels(C, ar); - - /* for now, the properties panel displays info about the selected channels */ - graph_panel_properties(C, ar, 0, ale); - - /* driver settings for active F-Curve (only for 'Drivers' mode) */ - if (sipo->mode == SIPO_MODE_DRIVERS) - graph_panel_drivers(C, ar, 0, ale); - - /* modifiers */ - graph_panel_modifiers(C, ar, 0, ale); - - - uiEndPanels(C, ar); - - /* free temp data */ - MEM_freeN(ale); + PanelType *pt; + + pt= MEM_callocN(sizeof(PanelType), "spacetype graph panel properties"); + strcpy(pt->idname, "GRAPH_PT_properties"); + strcpy(pt->label, "Properties"); + pt->draw= graph_panel_properties; + pt->poll= graph_panel_poll; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers"); + strcpy(pt->idname, "GRAPH_PT_drivers"); + strcpy(pt->label, "Drivers"); + pt->draw= graph_panel_drivers; + pt->poll= graph_panel_drivers_poll; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype graph panel modifiers"); + strcpy(pt->idname, "GRAPH_PT_modifiers"); + strcpy(pt->label, "Modifiers"); + pt->draw= graph_panel_modifiers; + pt->poll= graph_panel_poll; + BLI_addtail(&art->paneltypes, pt); } - static int graph_properties(bContext *C, wmOperator *op) { ScrArea *sa= CTX_wm_area(C); diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index a06cdddbec8..7ba636302a5 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -35,6 +35,7 @@ struct bAnimListElem; struct SpaceIpo; struct ScrArea; struct ARegion; +struct ARegionType; struct View2DGrid; /* internal exports only */ @@ -137,7 +138,7 @@ void GRAPHEDIT_OT_ghost_curves_clear(struct wmOperatorType *ot); /* ***************************************** */ /* graph_buttons.c */ void GRAPHEDIT_OT_properties(struct wmOperatorType *ot); -void graph_region_buttons(const struct bContext *C, struct ARegion *ar); +void graph_buttons_register(struct ARegionType *art); struct bAnimListElem *get_active_fcurve_channel(struct bAnimContext *ac); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 66ebc145621..74002f64187 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -346,34 +346,17 @@ static void graph_buttons_area_init(wmWindowManager *wm, ARegion *ar) { ListBase *keymap; - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST_UI, ar->winx, ar->winy); + ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } static void graph_buttons_area_draw(const bContext *C, ARegion *ar) { - float col[3]; - - /* clear */ - UI_GetThemeColor3fv(TH_BACK, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - graph_region_buttons(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + ED_region_panels(C, ar, 1, NULL); } - static void graph_region_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ @@ -586,6 +569,8 @@ void ED_spacetype_ipo(void) art->draw= graph_buttons_area_draw; BLI_addhead(&st->regiontypes, art); + + graph_buttons_register(art); BKE_spacetype_register(st); } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c new file mode 100644 index 00000000000..35004a4bdef --- /dev/null +++ b/source/blender/editors/space_image/image_buttons.c @@ -0,0 +1,1476 @@ +/** + * $Id$ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Blender Foundation, 2002-2009 + * + * ***** END GPL LICENSE BLOCK ***** + */ + + +#include +#include + +#include "DNA_color_types.h" +#include "DNA_image_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_object_types.h" +#include "DNA_packedFile_types.h" +#include "DNA_node_types.h" +#include "DNA_space_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" +#include "BLI_rand.h" + +#include "BKE_colortools.h" +#include "BKE_context.h" +#include "BKE_customdata.h" +#include "BKE_image.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_node.h" +#include "BKE_packedFile.h" +#include "BKE_screen.h" +#include "BKE_utildefines.h" + +#include "RE_pipeline.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "ED_image.h" +#include "ED_mesh.h" +#include "ED_space_api.h" +#include "ED_screen.h" +#include "ED_uvedit.h" +#include "ED_util.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "image_intern.h" + +#define B_REDR 1 +#define B_IMAGECHANGED 2 +#define B_TRANS_IMAGE 3 +#define B_CURSOR_IMAGE 4 +#define B_NOP 0 +#define B_TWINANIM 5 +#define B_SIMAGETILE 6 +#define B_IDNAME 10 +#define B_FACESEL_PAINT_TEST 11 +#define B_SIMA_RECORD 12 +#define B_SIMA_PLAY 13 +#define B_SIMARANGE 14 +#define B_SIMACURVES 15 + +#define B_SIMANOTHING 16 +#define B_SIMABRUSHCHANGE 17 +#define B_SIMABRUSHBROWSE 18 +#define B_SIMABRUSHLOCAL 19 +#define B_SIMABRUSHDELETE 20 +#define B_KEEPDATA 21 +#define B_SIMABTEXBROWSE 22 +#define B_SIMABTEXDELETE 23 +#define B_VPCOLSLI 24 +#define B_SIMACLONEBROWSE 25 +#define B_SIMACLONEDELETE 26 + +/* XXX */ +static int okee() {return 0;} +static int simaFaceDraw_Check() {return 0;} +static int simaUVSel_Check() {return 0;} +static int is_uv_tface_editing_allowed_silent() {return 0;} +/* XXX */ + +/* proto */ +static void image_editvertex_buts(const bContext *C, uiBlock *block); +static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block); + + +static void do_image_panel_events(bContext *C, void *arg, int event) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + ARegion *ar= CTX_wm_region(C); + + switch(event) { + case B_REDR: + break; + case B_SIMACURVES: + curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima)); + break; + case B_SIMARANGE: + curvemapping_set_black_white(sima->cumap, NULL, NULL); + curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima)); + break; + case B_TRANS_IMAGE: + image_editvertex_buts(C, NULL); + break; + case B_CURSOR_IMAGE: + image_editcursor_buts(C, &ar->v2d, NULL); + break; + } + /* all events now */ + WM_event_add_notifier(C, NC_IMAGE, sima->image); +} + + + +static void image_info(Image *ima, ImBuf *ibuf, char *str) +{ + int ofs= 0; + + str[0]= 0; + + if(ima==NULL) return; + if(ibuf==NULL) { + sprintf(str, "Can not get an image"); + return; + } + + if(ima->source==IMA_SRC_MOVIE) { + ofs= sprintf(str, "Movie "); + if(ima->anim) + ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim)); + } + else + ofs= sprintf(str, "Image "); + + ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y); + + if(ibuf->rect_float) { + if(ibuf->channels!=4) { + sprintf(str+ofs, "%d float channel(s)", ibuf->channels); + } + else if(ibuf->depth==32) + strcat(str, " RGBA float"); + else + strcat(str, " RGB float"); + } + else { + if(ibuf->depth==32) + strcat(str, " RGBA byte"); + else + strcat(str, " RGB byte"); + } + if(ibuf->zbuf || ibuf->zbuf_float) + strcat(str, " + Z"); + +} + +/* gets active viewer user */ +struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree) +{ + bNode *node; + + if(ntree) + for(node= ntree->nodes.first; node; node= node->next) + if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) + if(node->flag & NODE_DO_OUTPUT) + return node->storage; + return NULL; +} + + +/* ************ panel stuff ************* */ + +/* this function gets the values for cursor and vertex number buttons */ +static void image_transform_but_attr(SpaceImage *sima, int *imx, int *imy, int *step, int *digits) /*, float *xcoord, float *ycoord)*/ +{ + ImBuf *ibuf= ED_space_image_buffer(sima); + if(ibuf) { + *imx= ibuf->x; + *imy= ibuf->y; + } + + if (sima->flag & SI_COORDFLOATS) { + *step= 1; + *digits= 3; + } + else { + *step= 100; + *digits= 2; + } +} + + +/* is used for both read and write... */ +static void image_editvertex_buts(const bContext *C, uiBlock *block) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + Object *obedit= CTX_data_edit_object(C); + static float ocent[2]; + float cent[2]= {0.0, 0.0}; + int imx= 256, imy= 256; + int nactive= 0, step, digits; + EditMesh *em; + EditFace *efa; + MTFace *tf; + + if(obedit==NULL || obedit->type!=OB_MESH) return; + + if( is_uv_tface_editing_allowed_silent()==0 ) return; + + image_transform_but_attr(sima, &imx, &imy, &step, &digits); + + em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + for (efa= em->faces.first; efa; efa= efa->next) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + if (simaFaceDraw_Check(efa, tf)) { + + if (simaUVSel_Check(efa, tf, 0)) { + cent[0]+= tf->uv[0][0]; + cent[1]+= tf->uv[0][1]; + nactive++; + } + if (simaUVSel_Check(efa, tf, 1)) { + cent[0]+= tf->uv[1][0]; + cent[1]+= tf->uv[1][1]; + nactive++; + } + if (simaUVSel_Check(efa, tf, 2)) { + cent[0]+= tf->uv[2][0]; + cent[1]+= tf->uv[2][1]; + nactive++; + } + if (efa->v4 && simaUVSel_Check(efa, tf, 3)) { + cent[0]+= tf->uv[3][0]; + cent[1]+= tf->uv[3][1]; + nactive++; + } + } + } + + if(block) { // do the buttons + if (nactive) { + ocent[0]= cent[0]/nactive; + ocent[1]= cent[1]/nactive; + if (sima->flag & SI_COORDFLOATS) { + } else { + ocent[0] *= imx; + ocent[1] *= imy; + } + + //uiBlockBeginAlign(block); + if(nactive==1) { + uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, ""); + uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, ""); + } + else { + uiDefButF(block, NUM, B_TRANS_IMAGE, "Median X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, ""); + uiDefButF(block, NUM, B_TRANS_IMAGE, "Median Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, ""); + } + //uiBlockEndAlign(block); + } + } + else { // apply event + float delta[2]; + + cent[0]= cent[0]/nactive; + cent[1]= cent[1]/nactive; + + if (sima->flag & SI_COORDFLOATS) { + delta[0]= ocent[0]-cent[0]; + delta[1]= ocent[1]-cent[1]; + } + else { + delta[0]= ocent[0]/imx - cent[0]; + delta[1]= ocent[1]/imy - cent[1]; + } + + for (efa= em->faces.first; efa; efa= efa->next) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + if (simaFaceDraw_Check(efa, tf)) { + if (simaUVSel_Check(efa, tf, 0)) { + tf->uv[0][0]+= delta[0]; + tf->uv[0][1]+= delta[1]; + } + if (simaUVSel_Check(efa, tf, 1)) { + tf->uv[1][0]+= delta[0]; + tf->uv[1][1]+= delta[1]; + } + if (simaUVSel_Check(efa, tf, 2)) { + tf->uv[2][0]+= delta[0]; + tf->uv[2][1]+= delta[1]; + } + if (efa->v4 && simaUVSel_Check(efa, tf, 3)) { + tf->uv[3][0]+= delta[0]; + tf->uv[3][1]+= delta[1]; + } + } + } + + WM_event_add_notifier(C, NC_IMAGE, sima->image); + } + + BKE_mesh_end_editmesh(obedit->data, em); +} + + +/* is used for both read and write... */ +static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + static float ocent[2]; + int imx= 256, imy= 256; + int step, digits; + + if( is_uv_tface_editing_allowed_silent()==0 ) return; + + image_transform_but_attr(sima, &imx, &imy, &step, &digits); + + if(block) { // do the buttons + ocent[0]= v2d->cursor[0]; + ocent[1]= v2d->cursor[1]; + if (sima->flag & SI_COORDFLOATS) { + } else { + ocent[0] *= imx; + ocent[1] *= imy; + } + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor X:", 165, 120, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, ""); + uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor Y:", 165, 100, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, ""); + uiBlockEndAlign(block); + } + else { // apply event + if (sima->flag & SI_COORDFLOATS) { + v2d->cursor[0]= ocent[0]; + v2d->cursor[1]= ocent[1]; + } + else { + v2d->cursor[0]= ocent[0]/imx; + v2d->cursor[1]= ocent[1]/imy; + } + WM_event_add_notifier(C, NC_IMAGE, sima->image); + } +} + +static void image_panel_game_properties(const bContext *C, Panel *pa) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser); + uiBlock *block; + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_image_panel_events, NULL); + + if (ibuf) { + char str[128]; + + image_info(sima->image, ibuf, str); + uiDefBut(block, LABEL, B_NOP, str, 10,180,300,19, 0, 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, IMA_TWINANIM, B_TWINANIM, "Anim", 10,150,140,19, &sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of animated texture"); + uiDefButS(block, NUM, B_TWINANIM, "Start:", 10,130,140,19, &sima->image->twsta, 0.0, 128.0, 0, 0, "Displays the start frame of an animated texture"); + uiDefButS(block, NUM, B_TWINANIM, "End:", 10,110,140,19, &sima->image->twend, 0.0, 128.0, 0, 0, "Displays the end frame of an animated texture"); + uiDefButS(block, NUM, B_NOP, "Speed", 10,90,140,19, &sima->image->animspeed, 1.0, 100.0, 0, 0, "Displays Speed of the animation in frames per second"); + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, IMA_TILES, B_SIMAGETILE, "Tiles", 160,150,140,19, &sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of tilemode for faces (Shift LMB to pick the tile for selected faces)"); + uiDefButS(block, NUM, B_REDR, "X:", 160,130,70,19, &sima->image->xrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the X direction"); + uiDefButS(block, NUM, B_REDR, "Y:", 230,130,70,19, &sima->image->yrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the Y direction"); + uiBlockBeginAlign(block); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, IMA_CLAMP_U, B_REDR, "ClampX", 160,100,70,19, &sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating horizontaly"); + uiDefButBitS(block, TOG, IMA_CLAMP_V, B_REDR, "ClampY", 230,100,70,19, &sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating vertically"); + uiBlockEndAlign(block); + } +} + +static void image_panel_view_properties(const bContext *C, Panel *pa) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + ARegion *ar= CTX_wm_region(C); + Object *obedit= CTX_data_edit_object(C); + uiBlock *block; + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_image_panel_events, NULL); + + uiDefButBitI(block, TOG, SI_DRAW_TILE, B_REDR, "Repeat Image", 10,160,140,19, &sima->flag, 0, 0, 0, 0, "Repeat/Tile the image display"); + uiDefButBitI(block, TOG, SI_COORDFLOATS, B_REDR, "Normalized Coords", 165,160,145,19, &sima->flag, 0, 0, 0, 0, "Display coords from 0.0 to 1.0 rather then in pixels"); + + if (sima->image) { + uiDefBut(block, LABEL, B_NOP, "Image Display:", 10,140,140,19, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_REDR, "AspX:", 10,120,140,19, &sima->image->aspx, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect renderingm 0 disables."); + uiDefButF(block, NUM, B_REDR, "AspY:", 10,100,140,19, &sima->image->aspy, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect rendering 0 disables."); + uiBlockEndAlign(block); + } + + if (obedit && obedit->type==OB_MESH) { + Mesh *me= obedit->data; + EditMesh *em= BKE_mesh_get_editmesh(me); + + if(EM_texFaceCheck(em)) { + uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 80,120,19, 0, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButC(block, ROW, B_REDR, "Outline", 10,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype"); + uiDefButC(block, ROW, B_REDR, "Dash", 68, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype"); + uiDefButC(block, ROW, B_REDR, "Black", 126, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype"); + uiDefButC(block, ROW, B_REDR, "White", 184,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype"); + + uiBlockEndAlign(block); + uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth", 250,60,60,19, &sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view"); + + + uiDefButBitI(block, TOG, ME_DRAWFACES, B_REDR, "Faces", 10,30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays all faces as shades in the 3d view and UV editor"); + uiDefButBitI(block, TOG, ME_DRAWEDGES, B_REDR, "Edges", 70, 30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays selected edges using hilights in the 3d view and UV editor"); + + uiDefButBitI(block, TOG, SI_DRAWSHADOW, B_REDR, "Final Shadow", 130, 30,110,19, &sima->flag, 0, 0, 0, 0, "Draw the final result from the objects modifiers"); + uiDefButBitI(block, TOG, SI_DRAW_OTHER, B_REDR, "Other Objs", 230, 30, 80, 19, &sima->flag, 0, 0, 0, 0, "Also draw all 3d view selected mesh objects that use this image"); + + uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)"); + if (sima->flag & SI_DRAW_STRETCH) { + uiBlockBeginAlign(block); + uiDefButC(block, ROW, B_REDR, "Area", 120,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_AREA, 0, 0, "Area distortion between UV's and 3D coords"); + uiDefButC(block, ROW, B_REDR, "Angle", 180,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_ANGLE, 0, 0, "Angle distortion between UV's and 3D coords"); + uiBlockEndAlign(block); + } + } + + BKE_mesh_end_editmesh(me, em); + } + image_editcursor_buts(C, &ar->v2d, block); +} + +void brush_buttons(const bContext *C, uiBlock *block, short fromsima, + int evt_nop, int evt_change, + int evt_browse, int evt_local, + int evt_del, int evt_keepdata, + int evt_texbrowse, int evt_texdel) +{ +// SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + ToolSettings *settings= CTX_data_tool_settings(C); + Brush *brush= settings->imapaint.brush; + ID *id; + int yco, xco, butw, but_idx; +// short *menupoin = &(sima->menunr); // XXX : &(G.buts->menunr); + short do_project = settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE ? 0:1; + + yco= 160; + + butw = fromsima ? 80 : 106; + + uiBlockBeginAlign(block); + but_idx = 0; + uiDefButS(block, ROW, evt_change, "Draw", butw*(but_idx++),yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_DRAW, 0, 0, "Draw brush"); + if (fromsima || do_project==0) + uiDefButS(block, ROW, evt_change, "Soften", butw*(but_idx++), yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SOFTEN, 0, 0, "Soften brush"); + uiDefButS(block, ROW, evt_change, "Smear", butw*(but_idx++), yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SMEAR, 0, 0, "Smear brush"); + if (fromsima || do_project) + uiDefButS(block, ROW, evt_change, "Clone", butw*(but_idx++), yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_CLONE, 0, 0, "Clone brush, use RMB to drag source image"); + + uiBlockEndAlign(block); + yco -= 30; + + id= (ID*)settings->imapaint.brush; + xco= 200; // std_libbuttons(block, 0, yco, 0, NULL, evt_browse, ID_BR, 0, id, NULL, menupoin, 0, evt_local, evt_del, 0, evt_keepdata); + + if(brush && !brush->id.lib) { + + butw= 320-(xco+10); + + uiDefButS(block, MENU, evt_nop, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5|Erase Alpha %x6|Add Alpha %x7", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes"); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG|BIT, BRUSH_AIRBRUSH, evt_change, "Airbrush", xco+10,yco-25,butw/2,19, &brush->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse (spray)"); + uiDefButF(block, NUM, evt_nop, "", xco+10 + butw/2,yco-25,butw/2,19, &brush->rate, 0.01, 1.0, 0, 0, "Number of paints per second for Airbrush"); + uiBlockEndAlign(block); + + if (fromsima) { + uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, evt_change, "Wrap", xco+10,yco-45,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping"); + yco -= 25; + } + else { + yco -= 25; + uiBlockBeginAlign(block); + uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_DISABLE, B_REDR, "Project Paint", xco+10,yco-25,butw,19, &settings->imapaint.flag, 0, 0, 0, 0, "Use projection painting for improved consistency in the brush strokes"); + + if ((settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0) { + /* Projection Painting */ + + uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_XRAY, B_NOP, "Occlude", xco+10,yco-45,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Only paint onto the faces directly under the brush (slower)"); + uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_BACKFACE, B_NOP, "Cull", xco+10+butw/2,yco-45,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)"); + + uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_FLAT, B_NOP, "Normal", xco+10,yco-65,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Paint most on faces pointing towards the view"); + uiDefButS(block, NUM, B_NOP, "", xco+10 +(butw/2),yco-65,butw/2,19, &settings->imapaint.normal_angle, 10.0, 90.0, 0, 0, "Paint most on faces pointing towards the view acording to this angle"); + + uiDefButS(block, NUM, B_NOP, "Bleed: ", xco+10,yco-85,butw,19, &settings->imapaint.seam_bleed, 0.0, 8.0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)"); + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK, B_NOP, "Stencil Layer", xco+10,yco-110,butw-30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Set the mask layer from the UV layer buttons"); + uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK_INV, B_NOP, "Inv", xco+10 + butw-30,yco-110,30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Invert the mask"); + uiBlockEndAlign(block); + + } + uiBlockEndAlign(block); + } + + uiBlockBeginAlign(block); + uiDefButF(block, COL, B_VPCOLSLI, "", 0,yco,200,19, brush->rgb, 0, 0, 0, 0, ""); + uiDefButF(block, NUMSLI, evt_nop, "Opacity ", 0,yco-20,180,19, &brush->alpha, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); + uiDefButBitS(block, TOG|BIT, BRUSH_ALPHA_PRESSURE, evt_nop, "P", 180,yco-20,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiDefButI(block, NUMSLI, evt_nop, "Size ", 0,yco-40,180,19, &brush->size, 1, 200, 0, 0, "The size of the brush"); + uiDefButBitS(block, TOG|BIT, BRUSH_SIZE_PRESSURE, evt_nop, "P", 180,yco-40,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiDefButF(block, NUMSLI, evt_nop, "Falloff ", 0,yco-60,180,19, &brush->innerradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush"); + uiDefButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, "P", 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiDefButF(block, NUMSLI, evt_nop, "Spacing ",0,yco-80,180,19, &brush->spacing, 1.0, 100.0, 0, 0, "Repeating paint on %% of brush diameter"); + uiDefButBitS(block, TOG|BIT, BRUSH_SPACING_PRESSURE, evt_nop, "P", 180,yco-80,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); + uiBlockEndAlign(block); + + yco -= 110; + + if(fromsima && settings->imapaint.tool == PAINT_TOOL_CLONE) { + id= (ID*)brush->clone.image; + xco= 200; // std_libbuttons(block, 0, yco, 0, NULL, B_SIMACLONEBROWSE, ID_IM, 0, id, 0, menupoin, 0, 0, B_SIMACLONEDELETE, 0, 0); + if(id) { + butw= 320-(xco+5); + uiDefButF(block, NUMSLI, evt_change, "B ",xco+5,yco,butw,19, &brush->clone.alpha , 0.0, 1.0, 0, 0, "Opacity of clone image display"); + } + } + else { + if ( + (fromsima==0) && /* 3D View */ + (settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0 && /* Projection Painting */ + (settings->imapaint.tool == PAINT_TOOL_CLONE) + ) { + butw = 130; + uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_CLONE, B_REDR, "Clone Layer", 0,yco,butw,20, &settings->imapaint.flag, 0, 0, 0, 0, "Use another UV layer as clone source, otherwise use 3D the cursor as the source"); + } + else { + MTex *mtex= brush->mtex[brush->texact]; + + id= (mtex)? (ID*)mtex->tex: NULL; + xco= 200; // std_libbuttons(block, 0, yco, 0, NULL, evt_texbrowse, ID_TE, 0, id, NULL, menupoin, 0, 0, evt_texdel, 0, 0); + /*uiDefButBitS(block, TOG|BIT, BRUSH_FIXED_TEX, evt_change, "Fixed", xco+5,yco,butw,19, &brush->flag, 0, 0, 0, 0, "Keep texture origin in fixed position");*/ + } + } + } + +#if 0 + uiDefButBitS(block, TOG|BIT, IMAGEPAINT_DRAW_TOOL_DRAWING, B_SIMABRUSHCHANGE, "TD", 0,1,50,19, &settings->imapaint.flag.flag, 0, 0, 0, 0, "Enables brush shape while drawing"); + uiDefButBitS(block, TOG|BIT, IMAGEPAINT_DRAW_TOOL, B_SIMABRUSHCHANGE, "TP", 50,1,50,19, &settings->imapaint.flag.flag, 0, 0, 0, 0, "Enables brush shape while not drawing"); +#endif +} + +static int image_panel_paint_poll(const bContext *C, PanelType *pt) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + + return (sima->image && (sima->flag & SI_DRAWTOOL)); +} + +static void image_panel_paintcolor(const bContext *C, Panel *pa) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + ToolSettings *settings= CTX_data_tool_settings(C); + Brush *brush= settings->imapaint.brush; + uiBlock *block; + static float hsv[3], old[3]; // used as temp mem for picker + static char hexcol[128]; + + if(!sima->image || (sima->flag & SI_DRAWTOOL)==0) + return; + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_image_panel_events, NULL); + + if(brush) + uiBlockPickerButtons(block, brush->rgb, hsv, old, hexcol, 'f', B_REDR); +} + +static void image_panel_paint(const bContext *C, Panel *pa) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + uiBlock *block; + + if(!sima->image || (sima->flag & SI_DRAWTOOL)==0) + return; + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_image_panel_events, NULL); + + brush_buttons(C, block, 1, B_SIMANOTHING, B_SIMABRUSHCHANGE, B_SIMABRUSHBROWSE, B_SIMABRUSHLOCAL, B_SIMABRUSHDELETE, B_KEEPDATA, B_SIMABTEXBROWSE, B_SIMABTEXDELETE); +} + +static void image_panel_curves_reset(bContext *C, void *cumap_v, void *ibuf_v) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + CurveMapping *cumap = cumap_v; + int a; + + for(a=0; acm+a, &cumap->clipr); + + cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f; + cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f; + curvemapping_set_black_white(cumap, NULL, NULL); + + curvemapping_changed(cumap, 0); + curvemapping_do_ibuf(cumap, ibuf_v); + + WM_event_add_notifier(C, NC_IMAGE, sima->image); +} + + +static void image_panel_curves(const bContext *C, Panel *pa) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + ImBuf *ibuf; + uiBlock *block; + uiBut *bt; + + /* and we check for spare */ + ibuf= ED_space_image_buffer(sima); + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_image_panel_events, NULL); + + if (ibuf) { + rctf rect; + + if(sima->cumap==NULL) + sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); + + rect.xmin= 110; rect.xmax= 310; + rect.ymin= 10; rect.ymax= 200; + curvemap_buttons(block, sima->cumap, 'c', B_SIMACURVES, B_REDR, &rect); + + /* curvemap min/max only works for RGBA */ + if(ibuf->channels==4) { + bt=uiDefBut(block, BUT, B_SIMARANGE, "Reset", 10, 160, 90, 19, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves"); + uiButSetFunc(bt, image_panel_curves_reset, sima->cumap, ibuf); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_SIMARANGE, "Min R:", 10, 120, 90, 19, sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level"); + uiDefButF(block, NUM, B_SIMARANGE, "Min G:", 10, 100, 90, 19, sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level"); + uiDefButF(block, NUM, B_SIMARANGE, "Min B:", 10, 80, 90, 19, sima->cumap->black+2, -1000.0f, 1000.0f, 10, 2, "Black level"); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_SIMARANGE, "Max R:", 10, 50, 90, 19, sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level"); + uiDefButF(block, NUM, B_SIMARANGE, "Max G:", 10, 30, 90, 19, sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level"); + uiDefButF(block, NUM, B_SIMARANGE, "Max B:", 10, 10, 90, 19, sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level"); + } + } +} + +#if 0 +/* 0: disable preview + otherwise refresh preview +*/ +void image_preview_event(int event) +{ + int exec= 0; + + if(event==0) { + G.scene->r.scemode &= ~R_COMP_CROP; + exec= 1; + } + else { + if(image_preview_active(curarea, NULL, NULL)) { + G.scene->r.scemode |= R_COMP_CROP; + exec= 1; + } + else + G.scene->r.scemode &= ~R_COMP_CROP; + } + + if(exec && G.scene->nodetree) { + /* should work when no node editor in screen..., so we execute right away */ + + ntreeCompositTagGenerators(G.scene->nodetree); + + G.afbreek= 0; + G.scene->nodetree->timecursor= set_timecursor; + G.scene->nodetree->test_break= blender_test_break; + + BIF_store_spare(); + + ntreeCompositExecTree(G.scene->nodetree, &G.scene->r, 1); /* 1 is do_previews */ + + G.scene->nodetree->timecursor= NULL; + G.scene->nodetree->test_break= NULL; + + scrarea_do_windraw(curarea); + waitcursor(0); + + WM_event_add_notifier(C, NC_IMAGE, ima_v); + } +} + + +/* nothing drawn here, we use it to store values */ +static void preview_cb(struct ScrArea *sa, struct uiBlock *block) +{ + SpaceImage *sima= sa->spacedata.first; + rctf dispf; + rcti *disprect= &G.scene->r.disprect; + int winx= (G.scene->r.size*G.scene->r.xsch)/100; + int winy= (G.scene->r.size*G.scene->r.ysch)/100; + short mval[2]; + + if(G.scene->r.mode & R_BORDER) { + winx*= (G.scene->r.border.xmax - G.scene->r.border.xmin); + winy*= (G.scene->r.border.ymax - G.scene->r.border.ymin); + } + + /* while dragging we need to update the rects, otherwise it doesn't end with correct one */ + + BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f); + ui_graphics_to_window_rct(sa->win, &dispf, disprect); + + /* correction for gla draw */ + BLI_translate_rcti(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); + + calc_image_view(sima, 'p'); +// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); + /* map to image space coordinates */ + mval[0]= disprect->xmin; mval[1]= disprect->ymin; + areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin); + mval[0]= disprect->xmax; mval[1]= disprect->ymax; + areamouseco_to_ipoco(v2d, mval, &dispf.xmax, &dispf.ymax); + + /* map to render coordinates */ + disprect->xmin= dispf.xmin; + disprect->xmax= dispf.xmax; + disprect->ymin= dispf.ymin; + disprect->ymax= dispf.ymax; + + CLAMP(disprect->xmin, 0, winx); + CLAMP(disprect->xmax, 0, winx); + CLAMP(disprect->ymin, 0, winy); + CLAMP(disprect->ymax, 0, winy); +// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); + +} + +static int is_preview_allowed(ScrArea *cur) +{ + SpaceImage *sima= cur->spacedata.first; + ScrArea *sa; + + /* check if another areawindow has preview set */ + for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { + if(sa!=cur && sa->spacetype==SPACE_IMAGE) { + if(image_preview_active(sa, NULL, NULL)) + return 0; + } + } + /* check image type */ + if(sima->image==NULL || sima->image->type!=IMA_TYPE_COMPOSITE) + return 0; + + return 1; +} + + +static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVIEW +{ + uiBlock *block; + SpaceImage *sima= sa->spacedata.first; + int ofsx, ofsy; + + if(is_preview_allowed(sa)==0) { + rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW); + G.scene->r.scemode &= ~R_COMP_CROP; /* quite weak */ + return; + } + + block= uiBeginBlock(C, ar, "image_panel_preview", UI_EMBOSS); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); + uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc + + ofsx= -150+(sa->winx/2)/sima->blockscale; + ofsy= -100+(sa->winy/2)/sima->blockscale; + if(uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200)==0) return; + + uiBlockSetDrawExtraFunc(block, preview_cb); + +} + +static void image_panel_gpencil(short cntrl) // IMAGE_HANDLER_GREASEPENCIL +{ + uiBlock *block; + SpaceImage *sima; + + sima= curarea->spacedata.first; + + block= uiBeginBlock(C, ar, "image_panel_gpencil", UI_EMBOSS); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(IMAGE_HANDLER_GREASEPENCIL); // for close and esc + if (uiNewPanel(C, ar, block, "Grease Pencil", "SpaceImage", 100, 30, 318, 204)==0) return; + + /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */ + if (sima->flag & SI_DISPGP) { + if (sima->gpd == NULL) + gpencil_data_setactive(curarea, gpencil_data_addnew()); + } + + if (sima->flag & SI_DISPGP) { + bGPdata *gpd= sima->gpd; + short newheight; + + /* this is a variable height panel, newpanel doesnt force new size on existing panels */ + /* so first we make it default height */ + uiNewPanelHeight(block, 204); + + /* draw button for showing gpencil settings and drawings */ + uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor (draw using Shift-LMB)"); + + /* extend the panel if the contents won't fit */ + newheight= draw_gpencil_panel(block, gpd, curarea); + uiNewPanelHeight(block, newheight); + } + else { + uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor"); + uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, ""); + } +} +#endif + + +/* ********************* callbacks for standard image buttons *************** */ + +/* called from fileselect or button */ +static void load_image_cb(bContext *C, char *str, void *ima_pp_v, void *iuser_v) +{ + Image **ima_pp= (Image **)ima_pp_v; + Image *ima= NULL; + + ima= BKE_add_image_file(str, 0); + if(ima) { + if(*ima_pp) { + (*ima_pp)->id.us--; + } + *ima_pp= ima; + + BKE_image_signal(ima, iuser_v, IMA_SIGNAL_RELOAD); + WM_event_add_notifier(C, NC_IMAGE, ima); + + /* button event gets lost when it goes via filewindow */ +// if(G.buts && G.buts->lockpoin) { +// Tex *tex= G.buts->lockpoin; +// if(GS(tex->id.name)==ID_TE) { +// BIF_preview_changed(ID_TE); +// allqueue(REDRAWBUTSSHADING, 0); +// allqueue(REDRAWVIEW3D, 0); +// allqueue(REDRAWOOPS, 0); +// } +// } + } + + ED_undo_push(C, "Load image"); +} + +static char *layer_menu(RenderResult *rr, short *curlay) +{ + RenderLayer *rl; + int len= 64 + 32*BLI_countlist(&rr->layers); + short a, nr= 0; + char *str= MEM_callocN(len, "menu layers"); + + strcpy(str, "Layer %t"); + a= strlen(str); + + /* compo result */ + if(rr->rectf) { + a+= sprintf(str+a, "|Composite %%x0"); + nr= 1; + } + for(rl= rr->layers.first; rl; rl= rl->next, nr++) { + a+= sprintf(str+a, "|%s %%x%d", rl->name, nr); + } + + /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */ + + return str; +} + +/* rl==NULL means composite result */ +static char *pass_menu(RenderLayer *rl, short *curpass) +{ + RenderPass *rpass; + int len= 64 + 32*(rl?BLI_countlist(&rl->passes):1); + short a, nr= 0; + char *str= MEM_callocN(len, "menu layers"); + + strcpy(str, "Pass %t"); + a= strlen(str); + + /* rendered results don't have a Combined pass */ + if(rl==NULL || rl->rectf) { + a+= sprintf(str+a, "|Combined %%x0"); + nr= 1; + } + + if(rl) + for(rpass= rl->passes.first; rpass; rpass= rpass->next, nr++) + a+= sprintf(str+a, "|%s %%x%d", rpass->name, nr); + + if(*curpass >= nr) + *curpass= 0; + + return str; +} + +static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v) +{ + Scene *scene= CTX_data_scene(C); + Image *ima= ima_v; + ImageUser *iuser= iuser_v; + + if(ima->anim) { + iuser->frames = IMB_anim_get_duration(ima->anim); + BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0); + } +} + +static void image_src_change_cb(bContext *C, void *ima_v, void *iuser_v) +{ + BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_SRC_CHANGE); +} + +/* buttons have 2 arg callbacks, filewindow has 3 args... so thats why the wrapper below */ +static void image_browse_cb1(bContext *C, void *ima_pp_v, void *iuser_v) +{ + Image **ima_pp= (Image **)ima_pp_v; + ImageUser *iuser= iuser_v; + + if(ima_pp) { + Image *ima= *ima_pp; + + if(iuser->menunr== -2) { + // XXX activate_databrowse_args(&ima->id, ID_IM, 0, &iuser->menunr, image_browse_cb1, ima_pp, iuser); + } + else if (iuser->menunr>0) { + Image *newima= (Image*) BLI_findlink(&CTX_data_main(C)->image, iuser->menunr-1); + + if (newima && newima!=ima) { + *ima_pp= newima; + id_us_plus(&newima->id); + if(ima) ima->id.us--; + + BKE_image_signal(newima, iuser, IMA_SIGNAL_USER_NEW_IMAGE); + + ED_undo_push(C, "Browse image"); + } + } + } +} + +static void image_browse_cb(bContext *C, void *ima_pp_v, void *iuser_v) +{ + image_browse_cb1(C, ima_pp_v, iuser_v); +} + +static void image_reload_cb(bContext *C, void *ima_v, void *iuser_v) +{ + if(ima_v) { + BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_RELOAD); + } +} + +static void image_field_test(bContext *C, void *ima_v, void *iuser_v) +{ + Image *ima= ima_v; + + if(ima) { + ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); + if(ibuf) { + short nr= 0; + if( !(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1; + if( (ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1; + if(nr) { + BKE_image_signal(ima, iuser_v, IMA_SIGNAL_FREE); + } + } + } +} + +static void image_unlink_cb(bContext *C, void *ima_pp_v, void *unused) +{ + Image **ima_pp= (Image **)ima_pp_v; + + if(ima_pp && *ima_pp) { + Image *ima= *ima_pp; + /* (for time being, texturefaces are no users, conflict in design...) */ + if(ima->id.us>1) + ima->id.us--; + *ima_pp= NULL; + } +} + +static void image_load_fs_cb(bContext *C, void *ima_pp_v, void *iuser_v) +{ + ScrArea *sa= CTX_wm_area(C); +// Image **ima_pp= (Image **)ima_pp_v; + + if(sa->spacetype==SPACE_IMAGE) + WM_operator_name_call(C, "IMAGE_OT_open", WM_OP_INVOKE_REGION_WIN, NULL); + else + printf("not supported yet\n"); +} + +/* 5 layer button callbacks... */ +static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) +{ + BKE_image_multilayer_index(rr_v, iuser_v); +} +static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) +{ + RenderResult *rr= rr_v; + ImageUser *iuser= iuser_v; + int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0); /* fake compo result layer */ + if(iuser->layerlayer++; + BKE_image_multilayer_index(rr, iuser); +} +static void image_multi_declay_cb(bContext *C, void *rr_v, void *iuser_v) +{ + ImageUser *iuser= iuser_v; + if(iuser->layer>0) + iuser->layer--; + BKE_image_multilayer_index(rr_v, iuser); +} +static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) +{ + RenderResult *rr= rr_v; + ImageUser *iuser= iuser_v; + RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer); + if(rl) { + int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0); /* builtin render result has no combined pass in list */ + if(iuser->passpass++; + BKE_image_multilayer_index(rr, iuser); + } + } +} +static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) +{ + ImageUser *iuser= iuser_v; + if(iuser->pass>0) { + iuser->pass--; + BKE_image_multilayer_index(rr_v, iuser); + } +} + +static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v) +{ + if(ima_v) { + Image *ima= ima_v; + if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) { + if (ima->packedfile) { + if (G.fileflags & G_AUTOPACK) { + if (okee("Disable AutoPack ?")) { + G.fileflags &= ~G_AUTOPACK; + } + } + + if ((G.fileflags & G_AUTOPACK) == 0) { + unpackImage(ima, PF_ASK); + ED_undo_push(C, "Unpack image"); + } + } + else { + ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); + if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) { + // XXX error("Can't pack painted image. Save image or use Repack as PNG."); + } else { + ima->packedfile = newPackedFile(ima->name); + ED_undo_push(C, "Pack image"); + } + } + } + } +} + +static void image_load_cb(bContext *C, void *ima_pp_v, void *iuser_v) +{ + if(ima_pp_v) { + Image *ima= *((Image **)ima_pp_v); + ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); + char str[FILE_MAX]; + + /* name in ima has been changed by button! */ + BLI_strncpy(str, ima->name, FILE_MAX); + if(ibuf) BLI_strncpy(ima->name, ibuf->name, FILE_MAX); + + load_image_cb(C, str, ima_pp_v, iuser_v); + } +} + +static void image_freecache_cb(bContext *C, void *ima_v, void *unused) +{ + Scene *scene= CTX_data_scene(C); + BKE_image_free_anim_ibufs(ima_v, scene->r.cfra); + WM_event_add_notifier(C, NC_IMAGE, ima_v); +} + +static void image_generated_change_cb(bContext *C, void *ima_v, void *iuser_v) +{ + BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_FREE); +} + +static void image_user_change(bContext *C, void *iuser_v, void *unused) +{ + Scene *scene= CTX_data_scene(C); + BKE_image_user_calc_imanr(iuser_v, scene->r.cfra, 0); +} + +static void uiblock_layer_pass_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int event, int x, int y, int w) +{ + uiBut *but; + RenderLayer *rl= NULL; + int wmenu1, wmenu2; + char *strp; + + /* layer menu is 1/3 larger than pass */ + wmenu1= (3*w)/5; + wmenu2= (2*w)/5; + + /* menu buts */ + strp= layer_menu(rr, &iuser->layer); + but= uiDefButS(block, MENU, event, strp, x, y, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer"); + uiButSetFunc(but, image_multi_cb, rr, iuser); + MEM_freeN(strp); + + rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */ + strp= pass_menu(rl, &iuser->pass); + but= uiDefButS(block, MENU, event, strp, x+wmenu1, y, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass"); + uiButSetFunc(but, image_multi_cb, rr, iuser); + MEM_freeN(strp); +} + +static void uiblock_layer_pass_arrow_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int imagechanged) +{ + uiBut *but; + + if(rr==NULL || iuser==NULL) + return; + if(rr->layers.first==NULL) { + uiDefBut(block, LABEL, 0, "No Layers in Render Result,", 10, 107, 300, 20, NULL, 1, 0, 0, 0, ""); + return; + } + + uiBlockBeginAlign(block); + + /* decrease, increase arrows */ + but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 10,107,17,20, NULL, 0, 0, 0, 0, "Previous Layer"); + uiButSetFunc(but, image_multi_declay_cb, rr, iuser); + but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 27,107,18,20, NULL, 0, 0, 0, 0, "Next Layer"); + uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); + + uiblock_layer_pass_buttons(block, rr, iuser, imagechanged, 45, 107, 230); + + /* decrease, increase arrows */ + but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 275,107,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); + uiButSetFunc(but, image_multi_decpass_cb, rr, iuser); + but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 292,107,18,20, NULL, 0, 0, 0, 0, "Next Pass"); + uiButSetFunc(but, image_multi_incpass_cb, rr, iuser); + + uiBlockEndAlign(block); + +} + +// XXX HACK! +static int packdummy=0; + +/* The general Image panel with the loadsa callbacks! */ +void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, ImageUser *iuser, + short redraw, short imagechanged) +{ + Scene *scene= CTX_data_scene(C); + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + Image *ima= *ima_pp; + uiBut *but; + char str[128], *strp; + + /* different stuff when we show viewer */ + if(ima && ima->source==IMA_SRC_VIEWER) { + ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser); + + image_info(ima, ibuf, str); + uiDefBut(block, LABEL, 0, ima->id.name+2, 10, 180, 300, 20, NULL, 1, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, str, 10, 160, 300, 20, NULL, 1, 0, 0, 0, ""); + + if(ima->type==IMA_TYPE_COMPOSITE) { + iuser= ntree_get_active_iuser(scene->nodetree); + if(iuser) { + uiBlockBeginAlign(block); + uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, ""); + uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, ""); + but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, ""); + uiButSetFunc(but, image_freecache_cb, ima, NULL); + + if(iuser->frames) + sprintf(str, "(%d) Frames:", iuser->framenr); + else strcpy(str, "Frames:"); + uiBlockBeginAlign(block); + uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); + uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); + } + } + else if(ima->type==IMA_TYPE_R_RESULT) { + /* browse layer/passes */ + uiblock_layer_pass_arrow_buttons(block, RE_GetResult(RE_GetRender(scene->id.name)), iuser, imagechanged); + } + return; + } + + /* the main ima source types */ + if(ima) { +// XXX uiSetButLock(ima->id.lib!=NULL, ERROR_LIBDATA_MESSAGE); + uiBlockBeginAlign(block); + uiBlockSetFunc(block, image_src_change_cb, ima, iuser); + uiDefButS(block, ROW, imagechanged, "Still", 10, 180, 60, 20, &ima->source, 0.0, IMA_SRC_FILE, 0, 0, "Single Image file"); + uiDefButS(block, ROW, imagechanged, "Movie", 70, 180, 60, 20, &ima->source, 0.0, IMA_SRC_MOVIE, 0, 0, "Movie file"); + uiDefButS(block, ROW, imagechanged, "Sequence", 130, 180, 90, 20, &ima->source, 0.0, IMA_SRC_SEQUENCE, 0, 0, "Multiple Image files, as a sequence"); + uiDefButS(block, ROW, imagechanged, "Generated", 220, 180, 90, 20, &ima->source, 0.0, IMA_SRC_GENERATED, 0, 0, "Generated Image"); + uiBlockSetFunc(block, NULL, NULL, NULL); + } + else + uiDefBut(block, LABEL, 0, " ", 10, 180, 300, 20, 0, 0, 0, 0, 0, ""); /* for align in panel */ + + /* Browse */ + IMAnames_to_pupstring(&strp, NULL, NULL, &(CTX_data_main(C)->image), NULL, &iuser->menunr); + + uiBlockBeginAlign(block); + but= uiDefButS(block, MENU, imagechanged, strp, 10,155,23,20, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie"); + uiButSetFunc(but, image_browse_cb, ima_pp, iuser); + + MEM_freeN(strp); + + /* name + options, or only load */ + if(ima) { + int drawpack= (ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE && ima->ok); + + but= uiDefBut(block, TEX, B_IDNAME, "IM:", 33, 155, 177, 20, ima->id.name+2, 0.0, 21.0, 0, 0, "Current Image Datablock name."); + uiButSetFunc(but, test_idbutton_cb, ima->id.name, NULL); + but= uiDefBut(block, BUT, imagechanged, "Reload", 210, 155, 60, 20, NULL, 0, 0, 0, 0, "Reloads Image or Movie"); + uiButSetFunc(but, image_reload_cb, ima, iuser); + + but= uiDefIconBut(block, BUT, imagechanged, ICON_X, 270,155,20,20, 0, 0, 0, 0, 0, "Unlink Image block"); + uiButSetFunc(but, image_unlink_cb, ima_pp, NULL); + sprintf(str, "%d", ima->id.us); + uiDefBut(block, BUT, B_NOP, str, 290,155,20,20, 0, 0, 0, 0, 0, "Only displays number of users of Image block"); + + but= uiDefIconBut(block, BUT, imagechanged, ICON_FILESEL, 10, 135, 23, 20, 0, 0, 0, 0, 0, "Open Fileselect to load new Image"); + uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser); + but= uiDefBut(block, TEX, imagechanged, "", 33,135,257+(drawpack?0:20),20, ima->name, 0.0, 239.0, 0, 0, "Image/Movie file name, change to load new"); + uiButSetFunc(but, image_load_cb, ima_pp, iuser); + + if(drawpack) { + if (ima->packedfile) packdummy = 1; + else packdummy = 0; + but= uiDefIconButBitI(block, TOG, 1, redraw, ICON_PACKAGE, 290,135,20,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image"); + uiButSetFunc(but, image_pack_cb, ima, iuser); + } + + } + else { + but= uiDefBut(block, BUT, imagechanged, "Load", 33, 155, 100,20, NULL, 0, 0, 0, 0, "Load new Image of Movie"); + uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser); + } + uiBlockEndAlign(block); + + if(ima) { + ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser); + + /* check for re-render, only buttons */ + if(imagechanged==B_IMAGECHANGED) { + if(iuser->flag & IMA_ANIM_REFRESHED) { + iuser->flag &= ~IMA_ANIM_REFRESHED; + WM_event_add_notifier(C, NC_IMAGE, ima); + } + } + + /* multilayer? */ + if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { + uiblock_layer_pass_arrow_buttons(block, ima->rr, iuser, imagechanged); + } + else { + image_info(ima, ibuf, str); + uiDefBut(block, LABEL, 0, str, 10, 112, 300, 20, NULL, 1, 0, 0, 0, ""); + } + + /* exception, let's do because we only use this panel 3 times in blender... but not real good code! */ + if( (FACESEL_PAINT_TEST) && sima && &sima->iuser==iuser) + return; + /* left side default per-image options, right half the additional options */ + + /* fields */ + uiBlockBeginAlign(block); + but= uiDefButBitS(block, TOGBUT, IMA_FIELDS, imagechanged, "Fields", 10, 70, 65, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image"); + uiButSetFunc(but, image_field_test, ima, iuser); + uiDefButBitS(block, TOGBUT, IMA_STD_FIELD, B_NOP, "Odd", 75, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle"); + + uiBlockSetFunc(block, image_reload_cb, ima, iuser); + uiDefButBitS(block, TOGBUT, IMA_ANTIALI, B_NOP, "Anti", 10, 50, 45, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors"); + uiDefButBitS(block, TOGBUT, IMA_DO_PREMUL, imagechanged, "Premul", 55, 50, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha"); + uiBlockEndAlign(block); + + if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + sprintf(str, "(%d) Frames:", iuser->framenr); + + uiBlockBeginAlign(block); + uiBlockSetFunc(block, image_user_change, iuser, NULL); + uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 70, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes"); + + if(ima->anim) { + uiDefButI(block, NUM, imagechanged, str, 120, 50,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); + but= uiDefBut(block, BUT, redraw, "<", 290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button"); + uiButSetFunc(but, set_frames_cb, ima, iuser); + } + else + uiDefButI(block, NUM, imagechanged, str, 120, 50,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); + + uiDefButI(block, NUM, imagechanged, "Offs:", 120,30,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); + uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,30,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)"); + + uiDefButI(block, NUM, imagechanged, "StartFr:", 120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); + uiDefButS(block, TOG, imagechanged, "Cyclic", 220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie"); + + uiBlockSetFunc(block, NULL, iuser, NULL); + } + else if(ima->source==IMA_SRC_GENERATED) { + + uiBlockBeginAlign(block); + uiBlockSetFunc(block, image_generated_change_cb, ima, iuser); + uiDefButS(block, NUM, imagechanged, "SizeX:", 120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x"); + uiDefButS(block, NUM, imagechanged, "SizeY:", 220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y"); + uiDefButS(block, TOGBUT, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, ""); + uiBlockSetFunc(block, NULL, NULL, NULL); + } + } + uiBlockEndAlign(block); +} + + +static void image_panel_properties(const bContext *C, Panel *pa) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + uiBlock *block; + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_image_panel_events, NULL); + + /* note, it draws no bottom half in facemode, for vertex buttons */ + ED_image_uiblock_panel(C, block, &sima->image, &sima->iuser, B_REDR, B_REDR); + image_editvertex_buts(C, block); +} + +void image_buttons_register(ARegionType *art) +{ + PanelType *pt; + + pt= MEM_callocN(sizeof(PanelType), "spacetype image panel properties"); + strcpy(pt->idname, "IMAGE_PT_properties"); + strcpy(pt->label, "Image Properties"); + pt->draw= image_panel_properties; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype image panel game properties"); + strcpy(pt->idname, "IMAGE_PT_game_properties"); + strcpy(pt->label, "Game Properties"); + pt->draw= image_panel_game_properties; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype image view properties"); + strcpy(pt->idname, "IMAGE_PT_view_properties"); + strcpy(pt->label, "View Properties"); + pt->draw= image_panel_view_properties; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint"); + strcpy(pt->idname, "IMAGE_PT_paint"); + strcpy(pt->label, "Paint"); + pt->draw= image_panel_paint; + pt->poll= image_panel_paint_poll; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype image panel paint color"); + strcpy(pt->idname, "IMAGE_PT_paint_color"); + strcpy(pt->label, "Paint Color"); + pt->draw= image_panel_paintcolor; + pt->poll= image_panel_paint_poll; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype image panel curves"); + strcpy(pt->idname, "IMAGE_PT_curves"); + strcpy(pt->label, "Curves"); + pt->draw= image_panel_curves; + BLI_addtail(&art->paneltypes, pt); +} + +static int image_properties(bContext *C, wmOperator *op) +{ + ScrArea *sa= CTX_wm_area(C); + ARegion *ar= image_has_buttons_region(sa); + + if(ar) { + ar->flag ^= RGN_FLAG_HIDDEN; + ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ + + ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); + ED_area_tag_redraw(sa); + } + return OPERATOR_FINISHED; +} + +void IMAGE_OT_properties(wmOperatorType *ot) +{ + ot->name= "Properties"; + ot->idname= "IMAGE_OT_properties"; + + ot->exec= image_properties; + ot->poll= ED_operator_image_active; + + /* flags */ + ot->flag= 0; +} + + + diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c index 7a28499009b..2accef990d3 100644 --- a/source/blender/editors/space_image/image_header.c +++ b/source/blender/editors/space_image/image_header.c @@ -150,8 +150,8 @@ static void image_viewmenu(bContext *C, uiLayout *layout, void *arg_unused) uiItemS(layout); - uiItemR(layout, NULL, 0, &spaceptr, "update_automatically", 0); - // XXX if(show_uvedit) uiItemR(layout, NULL, 0, &uvptr, "local_view", 0); // "UV Local View", Numpad / + uiItemR(layout, NULL, 0, &spaceptr, "update_automatically", 0, 0); + // XXX if(show_uvedit) uiItemR(layout, NULL, 0, &uvptr, "local_view", 0, 0); // "UV Local View", Numpad / uiItemS(layout); @@ -234,7 +234,7 @@ static void image_imagemenu(bContext *C, uiLayout *layout, void *arg_unused) uiItemS(layout); - uiItemR(layout, NULL, 0, &spaceptr, "image_painting", 0); + uiItemR(layout, NULL, 0, &spaceptr, "image_painting", 0, 0); /* move to realtime properties panel */ RNA_id_pointer_create(&ima->id, &imaptr); @@ -338,12 +338,12 @@ static void image_uvsmenu(bContext *C, uiLayout *layout, void *arg_unused) RNA_id_pointer_create(&scene->id, &sceneptr); /* create menu */ - uiItemR(layout, NULL, 0, &uvptr, "snap_to_pixels", 0); - uiItemR(layout, NULL, 0, &uvptr, "constrain_to_image_bounds", 0); + uiItemR(layout, NULL, 0, &uvptr, "snap_to_pixels", 0, 0); + uiItemR(layout, NULL, 0, &uvptr, "constrain_to_image_bounds", 0, 0); uiItemS(layout); - uiItemR(layout, NULL, 0, &uvptr, "live_unwrap", 0); + uiItemR(layout, NULL, 0, &uvptr, "live_unwrap", 0, 0); uiItemO(layout, NULL, 0, "UV_OT_unwrap"); uiItemBooleanO(layout, "Unpin", 0, "UV_OT_pin", "clear", 1); uiItemO(layout, NULL, 0, "UV_OT_pin"); @@ -363,7 +363,7 @@ static void image_uvsmenu(bContext *C, uiLayout *layout, void *arg_unused) uiItemS(layout); - uiItemR(layout, NULL, 0, &sceneptr, "proportional_editing", 0); + uiItemR(layout, NULL, 0, &sceneptr, "proportional_editing", 0, 0); uiItemMenuEnumR(layout, NULL, 0, &sceneptr, "proportional_editing_falloff"); uiItemS(layout); diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index c592e2cb004..aa97e339c68 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -32,6 +32,7 @@ /* internal exports only */ struct bContext; struct ARegion; +struct ARegionType; struct ScrArea; struct SpaceImage; struct Object; @@ -84,7 +85,7 @@ void draw_uvedit_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene /* image_panels.c */ struct ImageUser *ntree_get_active_iuser(struct bNodeTree *ntree); -void image_buttons_area_defbuts(const struct bContext *C, struct ARegion *ar); +void image_buttons_register(struct ARegionType *art); void IMAGE_OT_properties(struct wmOperatorType *ot); #endif /* ED_IMAGE_INTERN_H */ diff --git a/source/blender/editors/space_image/image_panels.c b/source/blender/editors/space_image/image_panels.c deleted file mode 100644 index 971f3a70a8a..00000000000 --- a/source/blender/editors/space_image/image_panels.c +++ /dev/null @@ -1,1463 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * Contributor(s): Blender Foundation, 2002-2009 - * - * ***** END GPL LICENSE BLOCK ***** - */ - - -#include -#include - -#include "DNA_color_types.h" -#include "DNA_image_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_packedFile_types.h" -#include "DNA_node_types.h" -#include "DNA_space_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_userdef_types.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_editVert.h" -#include "BLI_rand.h" - -#include "BKE_colortools.h" -#include "BKE_context.h" -#include "BKE_customdata.h" -#include "BKE_image.h" -#include "BKE_global.h" -#include "BKE_library.h" -#include "BKE_main.h" -#include "BKE_mesh.h" -#include "BKE_node.h" -#include "BKE_packedFile.h" -#include "BKE_screen.h" -#include "BKE_utildefines.h" - -#include "RE_pipeline.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "ED_image.h" -#include "ED_mesh.h" -#include "ED_space_api.h" -#include "ED_screen.h" -#include "ED_uvedit.h" -#include "ED_util.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" - -#include "RNA_access.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "UI_interface.h" -#include "UI_resources.h" -#include "UI_view2d.h" - -#include "image_intern.h" - -#define B_REDR 1 -#define B_IMAGECHANGED 2 -#define B_TRANS_IMAGE 3 -#define B_CURSOR_IMAGE 4 -#define B_NOP 0 -#define B_TWINANIM 5 -#define B_SIMAGETILE 6 -#define B_IDNAME 10 -#define B_FACESEL_PAINT_TEST 11 -#define B_SIMA_RECORD 12 -#define B_SIMA_PLAY 13 -#define B_SIMARANGE 14 -#define B_SIMACURVES 15 - -#define B_SIMANOTHING 16 -#define B_SIMABRUSHCHANGE 17 -#define B_SIMABRUSHBROWSE 18 -#define B_SIMABRUSHLOCAL 19 -#define B_SIMABRUSHDELETE 20 -#define B_KEEPDATA 21 -#define B_SIMABTEXBROWSE 22 -#define B_SIMABTEXDELETE 23 -#define B_VPCOLSLI 24 -#define B_SIMACLONEBROWSE 25 -#define B_SIMACLONEDELETE 26 - -/* XXX */ -static int okee() {return 0;} -static int simaFaceDraw_Check() {return 0;} -static int simaUVSel_Check() {return 0;} -static int is_uv_tface_editing_allowed_silent() {return 0;} -/* XXX */ - -/* proto */ -static void image_editvertex_buts(const bContext *C, uiBlock *block); -static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block); - - -static void do_image_panel_events(bContext *C, void *arg, int event) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - ARegion *ar= CTX_wm_region(C); - - switch(event) { - case B_REDR: - break; - case B_SIMACURVES: - curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima)); - break; - case B_SIMARANGE: - curvemapping_set_black_white(sima->cumap, NULL, NULL); - curvemapping_do_ibuf(sima->cumap, ED_space_image_buffer(sima)); - break; - case B_TRANS_IMAGE: - image_editvertex_buts(C, NULL); - break; - case B_CURSOR_IMAGE: - image_editcursor_buts(C, &ar->v2d, NULL); - break; - } - /* all events now */ - WM_event_add_notifier(C, NC_IMAGE, sima->image); -} - - - -static void image_info(Image *ima, ImBuf *ibuf, char *str) -{ - int ofs= 0; - - str[0]= 0; - - if(ima==NULL) return; - if(ibuf==NULL) { - sprintf(str, "Can not get an image"); - return; - } - - if(ima->source==IMA_SRC_MOVIE) { - ofs= sprintf(str, "Movie "); - if(ima->anim) - ofs+= sprintf(str+ofs, "%d frs", IMB_anim_get_duration(ima->anim)); - } - else - ofs= sprintf(str, "Image "); - - ofs+= sprintf(str+ofs, ": size %d x %d,", ibuf->x, ibuf->y); - - if(ibuf->rect_float) { - if(ibuf->channels!=4) { - sprintf(str+ofs, "%d float channel(s)", ibuf->channels); - } - else if(ibuf->depth==32) - strcat(str, " RGBA float"); - else - strcat(str, " RGB float"); - } - else { - if(ibuf->depth==32) - strcat(str, " RGBA byte"); - else - strcat(str, " RGB byte"); - } - if(ibuf->zbuf || ibuf->zbuf_float) - strcat(str, " + Z"); - -} - -/* gets active viewer user */ -struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree) -{ - bNode *node; - - if(ntree) - for(node= ntree->nodes.first; node; node= node->next) - if( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) - if(node->flag & NODE_DO_OUTPUT) - return node->storage; - return NULL; -} - - -/* ************ panel stuff ************* */ - -/* this function gets the values for cursor and vertex number buttons */ -static void image_transform_but_attr(SpaceImage *sima, int *imx, int *imy, int *step, int *digits) /*, float *xcoord, float *ycoord)*/ -{ - ImBuf *ibuf= ED_space_image_buffer(sima); - if(ibuf) { - *imx= ibuf->x; - *imy= ibuf->y; - } - - if (sima->flag & SI_COORDFLOATS) { - *step= 1; - *digits= 3; - } - else { - *step= 100; - *digits= 2; - } -} - - -/* is used for both read and write... */ -static void image_editvertex_buts(const bContext *C, uiBlock *block) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - Object *obedit= CTX_data_edit_object(C); - static float ocent[2]; - float cent[2]= {0.0, 0.0}; - int imx= 256, imy= 256; - int nactive= 0, step, digits; - EditMesh *em; - EditFace *efa; - MTFace *tf; - - if(obedit==NULL || obedit->type!=OB_MESH) return; - - if( is_uv_tface_editing_allowed_silent()==0 ) return; - - image_transform_but_attr(sima, &imx, &imy, &step, &digits); - - em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - for (efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (simaFaceDraw_Check(efa, tf)) { - - if (simaUVSel_Check(efa, tf, 0)) { - cent[0]+= tf->uv[0][0]; - cent[1]+= tf->uv[0][1]; - nactive++; - } - if (simaUVSel_Check(efa, tf, 1)) { - cent[0]+= tf->uv[1][0]; - cent[1]+= tf->uv[1][1]; - nactive++; - } - if (simaUVSel_Check(efa, tf, 2)) { - cent[0]+= tf->uv[2][0]; - cent[1]+= tf->uv[2][1]; - nactive++; - } - if (efa->v4 && simaUVSel_Check(efa, tf, 3)) { - cent[0]+= tf->uv[3][0]; - cent[1]+= tf->uv[3][1]; - nactive++; - } - } - } - - if(block) { // do the buttons - if (nactive) { - ocent[0]= cent[0]/nactive; - ocent[1]= cent[1]/nactive; - if (sima->flag & SI_COORDFLOATS) { - } else { - ocent[0] *= imx; - ocent[1] *= imy; - } - - //uiBlockBeginAlign(block); - if(nactive==1) { - uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, ""); - uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, ""); - } - else { - uiDefButF(block, NUM, B_TRANS_IMAGE, "Median X:", 10, 10, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, ""); - uiDefButF(block, NUM, B_TRANS_IMAGE, "Median Y:", 165, 10, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, ""); - } - //uiBlockEndAlign(block); - } - } - else { // apply event - float delta[2]; - - cent[0]= cent[0]/nactive; - cent[1]= cent[1]/nactive; - - if (sima->flag & SI_COORDFLOATS) { - delta[0]= ocent[0]-cent[0]; - delta[1]= ocent[1]-cent[1]; - } - else { - delta[0]= ocent[0]/imx - cent[0]; - delta[1]= ocent[1]/imy - cent[1]; - } - - for (efa= em->faces.first; efa; efa= efa->next) { - tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (simaFaceDraw_Check(efa, tf)) { - if (simaUVSel_Check(efa, tf, 0)) { - tf->uv[0][0]+= delta[0]; - tf->uv[0][1]+= delta[1]; - } - if (simaUVSel_Check(efa, tf, 1)) { - tf->uv[1][0]+= delta[0]; - tf->uv[1][1]+= delta[1]; - } - if (simaUVSel_Check(efa, tf, 2)) { - tf->uv[2][0]+= delta[0]; - tf->uv[2][1]+= delta[1]; - } - if (efa->v4 && simaUVSel_Check(efa, tf, 3)) { - tf->uv[3][0]+= delta[0]; - tf->uv[3][1]+= delta[1]; - } - } - } - - WM_event_add_notifier(C, NC_IMAGE, sima->image); - } - - BKE_mesh_end_editmesh(obedit->data, em); -} - - -/* is used for both read and write... */ -static void image_editcursor_buts(const bContext *C, View2D *v2d, uiBlock *block) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - static float ocent[2]; - int imx= 256, imy= 256; - int step, digits; - - if( is_uv_tface_editing_allowed_silent()==0 ) return; - - image_transform_but_attr(sima, &imx, &imy, &step, &digits); - - if(block) { // do the buttons - ocent[0]= v2d->cursor[0]; - ocent[1]= v2d->cursor[1]; - if (sima->flag & SI_COORDFLOATS) { - } else { - ocent[0] *= imx; - ocent[1] *= imy; - } - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor X:", 165, 120, 145, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, ""); - uiDefButF(block, NUM, B_CURSOR_IMAGE, "Cursor Y:", 165, 100, 145, 19, &ocent[1], -10*imy, 10.0*imy, step, digits, ""); - uiBlockEndAlign(block); - } - else { // apply event - if (sima->flag & SI_COORDFLOATS) { - v2d->cursor[0]= ocent[0]; - v2d->cursor[1]= ocent[1]; - } - else { - v2d->cursor[0]= ocent[0]/imx; - v2d->cursor[1]= ocent[1]/imy; - } - WM_event_add_notifier(C, NC_IMAGE, sima->image); - } -} - -static void image_panel_game_properties(const bContext *C, ARegion *ar) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - ImBuf *ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser); - uiBlock *block; - - block= uiBeginBlock(C, ar, "image_panel_game_properties", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Real-time Properties", "Image", 10, 10, 318, 204)==0) - return; - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - if (ibuf) { - char str[128]; - - image_info(sima->image, ibuf, str); - uiDefBut(block, LABEL, B_NOP, str, 10,180,300,19, 0, 0, 0, 0, 0, ""); - - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, IMA_TWINANIM, B_TWINANIM, "Anim", 10,150,140,19, &sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of animated texture"); - uiDefButS(block, NUM, B_TWINANIM, "Start:", 10,130,140,19, &sima->image->twsta, 0.0, 128.0, 0, 0, "Displays the start frame of an animated texture"); - uiDefButS(block, NUM, B_TWINANIM, "End:", 10,110,140,19, &sima->image->twend, 0.0, 128.0, 0, 0, "Displays the end frame of an animated texture"); - uiDefButS(block, NUM, B_NOP, "Speed", 10,90,140,19, &sima->image->animspeed, 1.0, 100.0, 0, 0, "Displays Speed of the animation in frames per second"); - uiBlockEndAlign(block); - - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, IMA_TILES, B_SIMAGETILE, "Tiles", 160,150,140,19, &sima->image->tpageflag, 0, 0, 0, 0, "Toggles use of tilemode for faces (Shift LMB to pick the tile for selected faces)"); - uiDefButS(block, NUM, B_REDR, "X:", 160,130,70,19, &sima->image->xrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the X direction"); - uiDefButS(block, NUM, B_REDR, "Y:", 230,130,70,19, &sima->image->yrep, 1.0, 16.0, 0, 0, "Sets the degree of repetition in the Y direction"); - uiBlockBeginAlign(block); - - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, IMA_CLAMP_U, B_REDR, "ClampX", 160,100,70,19, &sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating horizontaly"); - uiDefButBitS(block, TOG, IMA_CLAMP_V, B_REDR, "ClampY", 230,100,70,19, &sima->image->tpageflag, 0, 0, 0, 0, "Disable texture repeating vertically"); - uiBlockEndAlign(block); - } -} - -static void image_panel_view_properties(const bContext *C, ARegion *ar) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - Object *obedit= CTX_data_edit_object(C); - uiBlock *block; - - block= uiBeginBlock(C, ar, "image_view_properties", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "View Properties", "Image", 10, 30, 318, 204)==0) - return; - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - uiDefButBitI(block, TOG, SI_DRAW_TILE, B_REDR, "Repeat Image", 10,160,140,19, &sima->flag, 0, 0, 0, 0, "Repeat/Tile the image display"); - uiDefButBitI(block, TOG, SI_COORDFLOATS, B_REDR, "Normalized Coords", 165,160,145,19, &sima->flag, 0, 0, 0, 0, "Display coords from 0.0 to 1.0 rather then in pixels"); - - if (sima->image) { - uiDefBut(block, LABEL, B_NOP, "Image Display:", 10,140,140,19, 0, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_REDR, "AspX:", 10,120,140,19, &sima->image->aspx, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect renderingm 0 disables."); - uiDefButF(block, NUM, B_REDR, "AspY:", 10,100,140,19, &sima->image->aspy, 0.1, 5000.0, 100, 0, "X Display Aspect for this image, does not affect rendering 0 disables."); - uiBlockEndAlign(block); - } - - if (obedit && obedit->type==OB_MESH) { - Mesh *me= obedit->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - - if(EM_texFaceCheck(em)) { - uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 80,120,19, 0, 0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButC(block, ROW, B_REDR, "Outline", 10,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "Dash", 68, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "Black", 126, 60,58,19, &sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype"); - uiDefButC(block, ROW, B_REDR, "White", 184,60,58,19, &sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype"); - - uiBlockEndAlign(block); - uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth", 250,60,60,19, &sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view"); - - - uiDefButBitI(block, TOG, ME_DRAWFACES, B_REDR, "Faces", 10,30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays all faces as shades in the 3d view and UV editor"); - uiDefButBitI(block, TOG, ME_DRAWEDGES, B_REDR, "Edges", 70, 30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays selected edges using hilights in the 3d view and UV editor"); - - uiDefButBitI(block, TOG, SI_DRAWSHADOW, B_REDR, "Final Shadow", 130, 30,110,19, &sima->flag, 0, 0, 0, 0, "Draw the final result from the objects modifiers"); - uiDefButBitI(block, TOG, SI_DRAW_OTHER, B_REDR, "Other Objs", 230, 30, 80, 19, &sima->flag, 0, 0, 0, 0, "Also draw all 3d view selected mesh objects that use this image"); - - uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)"); - if (sima->flag & SI_DRAW_STRETCH) { - uiBlockBeginAlign(block); - uiDefButC(block, ROW, B_REDR, "Area", 120,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_AREA, 0, 0, "Area distortion between UV's and 3D coords"); - uiDefButC(block, ROW, B_REDR, "Angle", 180,0,60,19, &sima->dt_uvstretch, 0.0, SI_UVDT_STRETCH_ANGLE, 0, 0, "Angle distortion between UV's and 3D coords"); - uiBlockEndAlign(block); - } - } - - BKE_mesh_end_editmesh(me, em); - } - image_editcursor_buts(C, &ar->v2d, block); -} - -void brush_buttons(const bContext *C, uiBlock *block, short fromsima, - int evt_nop, int evt_change, - int evt_browse, int evt_local, - int evt_del, int evt_keepdata, - int evt_texbrowse, int evt_texdel) -{ -// SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - ToolSettings *settings= CTX_data_tool_settings(C); - Brush *brush= settings->imapaint.brush; - ID *id; - int yco, xco, butw, but_idx; -// short *menupoin = &(sima->menunr); // XXX : &(G.buts->menunr); - short do_project = settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE ? 0:1; - - yco= 160; - - butw = fromsima ? 80 : 106; - - uiBlockBeginAlign(block); - but_idx = 0; - uiDefButS(block, ROW, evt_change, "Draw", butw*(but_idx++),yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_DRAW, 0, 0, "Draw brush"); - if (fromsima || do_project==0) - uiDefButS(block, ROW, evt_change, "Soften", butw*(but_idx++), yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SOFTEN, 0, 0, "Soften brush"); - uiDefButS(block, ROW, evt_change, "Smear", butw*(but_idx++), yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_SMEAR, 0, 0, "Smear brush"); - if (fromsima || do_project) - uiDefButS(block, ROW, evt_change, "Clone", butw*(but_idx++), yco,butw,19, &settings->imapaint.tool, 7.0, PAINT_TOOL_CLONE, 0, 0, "Clone brush, use RMB to drag source image"); - - uiBlockEndAlign(block); - yco -= 30; - - id= (ID*)settings->imapaint.brush; - xco= 200; // std_libbuttons(block, 0, yco, 0, NULL, evt_browse, ID_BR, 0, id, NULL, menupoin, 0, evt_local, evt_del, 0, evt_keepdata); - - if(brush && !brush->id.lib) { - - butw= 320-(xco+10); - - uiDefButS(block, MENU, evt_nop, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5|Erase Alpha %x6|Add Alpha %x7", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes"); - - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG|BIT, BRUSH_AIRBRUSH, evt_change, "Airbrush", xco+10,yco-25,butw/2,19, &brush->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse (spray)"); - uiDefButF(block, NUM, evt_nop, "", xco+10 + butw/2,yco-25,butw/2,19, &brush->rate, 0.01, 1.0, 0, 0, "Number of paints per second for Airbrush"); - uiBlockEndAlign(block); - - if (fromsima) { - uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, evt_change, "Wrap", xco+10,yco-45,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping"); - yco -= 25; - } - else { - yco -= 25; - uiBlockBeginAlign(block); - uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_DISABLE, B_REDR, "Project Paint", xco+10,yco-25,butw,19, &settings->imapaint.flag, 0, 0, 0, 0, "Use projection painting for improved consistency in the brush strokes"); - - if ((settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0) { - /* Projection Painting */ - - uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_XRAY, B_NOP, "Occlude", xco+10,yco-45,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Only paint onto the faces directly under the brush (slower)"); - uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_BACKFACE, B_NOP, "Cull", xco+10+butw/2,yco-45,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Ignore faces pointing away from the view (faster)"); - - uiDefButBitS(block, TOGN|BIT, IMAGEPAINT_PROJECT_FLAT, B_NOP, "Normal", xco+10,yco-65,butw/2,19, &settings->imapaint.flag, 0, 0, 0, 0, "Paint most on faces pointing towards the view"); - uiDefButS(block, NUM, B_NOP, "", xco+10 +(butw/2),yco-65,butw/2,19, &settings->imapaint.normal_angle, 10.0, 90.0, 0, 0, "Paint most on faces pointing towards the view acording to this angle"); - - uiDefButS(block, NUM, B_NOP, "Bleed: ", xco+10,yco-85,butw,19, &settings->imapaint.seam_bleed, 0.0, 8.0, 0, 0, "Extend paint beyond the faces UVs to reduce seams (in pixels, slower)"); - uiBlockEndAlign(block); - - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK, B_NOP, "Stencil Layer", xco+10,yco-110,butw-30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Set the mask layer from the UV layer buttons"); - uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_MASK_INV, B_NOP, "Inv", xco+10 + butw-30,yco-110,30,19, &settings->imapaint.flag, 0, 0, 0, 0, "Invert the mask"); - uiBlockEndAlign(block); - - } - uiBlockEndAlign(block); - } - - uiBlockBeginAlign(block); - uiDefButF(block, COL, B_VPCOLSLI, "", 0,yco,200,19, brush->rgb, 0, 0, 0, 0, ""); - uiDefButF(block, NUMSLI, evt_nop, "Opacity ", 0,yco-20,180,19, &brush->alpha, 0.0, 1.0, 0, 0, "The amount of pressure on the brush"); - uiDefButBitS(block, TOG|BIT, BRUSH_ALPHA_PRESSURE, evt_nop, "P", 180,yco-20,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); - uiDefButI(block, NUMSLI, evt_nop, "Size ", 0,yco-40,180,19, &brush->size, 1, 200, 0, 0, "The size of the brush"); - uiDefButBitS(block, TOG|BIT, BRUSH_SIZE_PRESSURE, evt_nop, "P", 180,yco-40,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); - uiDefButF(block, NUMSLI, evt_nop, "Falloff ", 0,yco-60,180,19, &brush->innerradius, 0.0, 1.0, 0, 0, "The fall off radius of the brush"); - uiDefButBitS(block, TOG|BIT, BRUSH_RAD_PRESSURE, evt_nop, "P", 180,yco-60,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); - uiDefButF(block, NUMSLI, evt_nop, "Spacing ",0,yco-80,180,19, &brush->spacing, 1.0, 100.0, 0, 0, "Repeating paint on %% of brush diameter"); - uiDefButBitS(block, TOG|BIT, BRUSH_SPACING_PRESSURE, evt_nop, "P", 180,yco-80,20,19, &brush->flag, 0, 0, 0, 0, "Enables pressure sensitivity for tablets"); - uiBlockEndAlign(block); - - yco -= 110; - - if(fromsima && settings->imapaint.tool == PAINT_TOOL_CLONE) { - id= (ID*)brush->clone.image; - xco= 200; // std_libbuttons(block, 0, yco, 0, NULL, B_SIMACLONEBROWSE, ID_IM, 0, id, 0, menupoin, 0, 0, B_SIMACLONEDELETE, 0, 0); - if(id) { - butw= 320-(xco+5); - uiDefButF(block, NUMSLI, evt_change, "B ",xco+5,yco,butw,19, &brush->clone.alpha , 0.0, 1.0, 0, 0, "Opacity of clone image display"); - } - } - else { - if ( - (fromsima==0) && /* 3D View */ - (settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)==0 && /* Projection Painting */ - (settings->imapaint.tool == PAINT_TOOL_CLONE) - ) { - butw = 130; - uiDefButBitS(block, TOG|BIT, IMAGEPAINT_PROJECT_LAYER_CLONE, B_REDR, "Clone Layer", 0,yco,butw,20, &settings->imapaint.flag, 0, 0, 0, 0, "Use another UV layer as clone source, otherwise use 3D the cursor as the source"); - } - else { - MTex *mtex= brush->mtex[brush->texact]; - - id= (mtex)? (ID*)mtex->tex: NULL; - xco= 200; // std_libbuttons(block, 0, yco, 0, NULL, evt_texbrowse, ID_TE, 0, id, NULL, menupoin, 0, 0, evt_texdel, 0, 0); - /*uiDefButBitS(block, TOG|BIT, BRUSH_FIXED_TEX, evt_change, "Fixed", xco+5,yco,butw,19, &brush->flag, 0, 0, 0, 0, "Keep texture origin in fixed position");*/ - } - } - } - -#if 0 - uiDefButBitS(block, TOG|BIT, IMAGEPAINT_DRAW_TOOL_DRAWING, B_SIMABRUSHCHANGE, "TD", 0,1,50,19, &settings->imapaint.flag.flag, 0, 0, 0, 0, "Enables brush shape while drawing"); - uiDefButBitS(block, TOG|BIT, IMAGEPAINT_DRAW_TOOL, B_SIMABRUSHCHANGE, "TP", 50,1,50,19, &settings->imapaint.flag.flag, 0, 0, 0, 0, "Enables brush shape while not drawing"); -#endif -} - -static void image_panel_paintcolor(const bContext *C, ARegion *ar) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - ToolSettings *settings= CTX_data_tool_settings(C); - Brush *brush= settings->imapaint.brush; - uiBlock *block; - static float hsv[3], old[3]; // used as temp mem for picker - static char hexcol[128]; - - block= uiBeginBlock(C, ar, "image_panel_paintcolor", UI_EMBOSS); - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - if(uiNewPanel(C, ar, block, "Paint Color", "Image", 10, 22, 318, 204)==0) - return; - - if ( (brush && sima->image && (sima->flag & SI_DRAWTOOL))==0) { - uiNewPanelHeight(block, 0); - return; - } - uiNewPanelHeight(block, 204); - - uiBlockPickerButtons(block, brush->rgb, hsv, old, hexcol, 'f', B_REDR); -} - - - -static void image_panel_paint(const bContext *C, ARegion *ar) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - uiBlock *block; - - block= uiBeginBlock(C, ar, "image_panel_paint", UI_EMBOSS); - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - if(uiNewPanel(C, ar, block, "Image Paint", "Image", 10, 20, 318, 204)==0) - return; - - if ((sima->image && (sima->flag & SI_DRAWTOOL))==0) { - uiNewPanelHeight(block, 0); - return; - } - uiNewPanelHeight(block, 204); - - brush_buttons(C, block, 1, B_SIMANOTHING, B_SIMABRUSHCHANGE, B_SIMABRUSHBROWSE, B_SIMABRUSHLOCAL, B_SIMABRUSHDELETE, B_KEEPDATA, B_SIMABTEXBROWSE, B_SIMABTEXDELETE); -} - -static void image_panel_curves_reset(bContext *C, void *cumap_v, void *ibuf_v) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - CurveMapping *cumap = cumap_v; - int a; - - for(a=0; acm+a, &cumap->clipr); - - cumap->black[0]=cumap->black[1]=cumap->black[2]= 0.0f; - cumap->white[0]=cumap->white[1]=cumap->white[2]= 1.0f; - curvemapping_set_black_white(cumap, NULL, NULL); - - curvemapping_changed(cumap, 0); - curvemapping_do_ibuf(cumap, ibuf_v); - - WM_event_add_notifier(C, NC_IMAGE, sima->image); -} - - -static void image_panel_curves(const bContext *C, ARegion *ar) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - ImBuf *ibuf; - uiBlock *block; - uiBut *bt; - - /* and we check for spare */ - ibuf= ED_space_image_buffer(sima); - - block= uiBeginBlock(C, ar, "image_panel_curves", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Curves", "Image", 10, 40, 318, 204)==0) - return; - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - if (ibuf) { - rctf rect; - - if(sima->cumap==NULL) - sima->cumap= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); - - rect.xmin= 110; rect.xmax= 310; - rect.ymin= 10; rect.ymax= 200; - curvemap_buttons(block, sima->cumap, 'c', B_SIMACURVES, B_REDR, &rect); - - /* curvemap min/max only works for RGBA */ - if(ibuf->channels==4) { - bt=uiDefBut(block, BUT, B_SIMARANGE, "Reset", 10, 160, 90, 19, NULL, 0.0f, 0.0f, 0, 0, "Reset Black/White point and curves"); - uiButSetFunc(bt, image_panel_curves_reset, sima->cumap, ibuf); - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_SIMARANGE, "Min R:", 10, 120, 90, 19, sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level"); - uiDefButF(block, NUM, B_SIMARANGE, "Min G:", 10, 100, 90, 19, sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level"); - uiDefButF(block, NUM, B_SIMARANGE, "Min B:", 10, 80, 90, 19, sima->cumap->black+2, -1000.0f, 1000.0f, 10, 2, "Black level"); - - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_SIMARANGE, "Max R:", 10, 50, 90, 19, sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level"); - uiDefButF(block, NUM, B_SIMARANGE, "Max G:", 10, 30, 90, 19, sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level"); - uiDefButF(block, NUM, B_SIMARANGE, "Max B:", 10, 10, 90, 19, sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level"); - } - } -} - -#if 0 -/* 0: disable preview - otherwise refresh preview -*/ -void image_preview_event(int event) -{ - int exec= 0; - - if(event==0) { - G.scene->r.scemode &= ~R_COMP_CROP; - exec= 1; - } - else { - if(image_preview_active(curarea, NULL, NULL)) { - G.scene->r.scemode |= R_COMP_CROP; - exec= 1; - } - else - G.scene->r.scemode &= ~R_COMP_CROP; - } - - if(exec && G.scene->nodetree) { - /* should work when no node editor in screen..., so we execute right away */ - - ntreeCompositTagGenerators(G.scene->nodetree); - - G.afbreek= 0; - G.scene->nodetree->timecursor= set_timecursor; - G.scene->nodetree->test_break= blender_test_break; - - BIF_store_spare(); - - ntreeCompositExecTree(G.scene->nodetree, &G.scene->r, 1); /* 1 is do_previews */ - - G.scene->nodetree->timecursor= NULL; - G.scene->nodetree->test_break= NULL; - - scrarea_do_windraw(curarea); - waitcursor(0); - - WM_event_add_notifier(C, NC_IMAGE, ima_v); - } -} - - -/* nothing drawn here, we use it to store values */ -static void preview_cb(struct ScrArea *sa, struct uiBlock *block) -{ - SpaceImage *sima= sa->spacedata.first; - rctf dispf; - rcti *disprect= &G.scene->r.disprect; - int winx= (G.scene->r.size*G.scene->r.xsch)/100; - int winy= (G.scene->r.size*G.scene->r.ysch)/100; - short mval[2]; - - if(G.scene->r.mode & R_BORDER) { - winx*= (G.scene->r.border.xmax - G.scene->r.border.xmin); - winy*= (G.scene->r.border.ymax - G.scene->r.border.ymin); - } - - /* while dragging we need to update the rects, otherwise it doesn't end with correct one */ - - BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f); - ui_graphics_to_window_rct(sa->win, &dispf, disprect); - - /* correction for gla draw */ - BLI_translate_rcti(disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); - - calc_image_view(sima, 'p'); -// printf("winrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); - /* map to image space coordinates */ - mval[0]= disprect->xmin; mval[1]= disprect->ymin; - areamouseco_to_ipoco(v2d, mval, &dispf.xmin, &dispf.ymin); - mval[0]= disprect->xmax; mval[1]= disprect->ymax; - areamouseco_to_ipoco(v2d, mval, &dispf.xmax, &dispf.ymax); - - /* map to render coordinates */ - disprect->xmin= dispf.xmin; - disprect->xmax= dispf.xmax; - disprect->ymin= dispf.ymin; - disprect->ymax= dispf.ymax; - - CLAMP(disprect->xmin, 0, winx); - CLAMP(disprect->xmax, 0, winx); - CLAMP(disprect->ymin, 0, winy); - CLAMP(disprect->ymax, 0, winy); -// printf("drawrct %d %d %d %d\n", disprect->xmin, disprect->ymin,disprect->xmax, disprect->ymax); - -} - -static int is_preview_allowed(ScrArea *cur) -{ - SpaceImage *sima= cur->spacedata.first; - ScrArea *sa; - - /* check if another areawindow has preview set */ - for(sa=G.curscreen->areabase.first; sa; sa= sa->next) { - if(sa!=cur && sa->spacetype==SPACE_IMAGE) { - if(image_preview_active(sa, NULL, NULL)) - return 0; - } - } - /* check image type */ - if(sima->image==NULL || sima->image->type!=IMA_TYPE_COMPOSITE) - return 0; - - return 1; -} - - -static void image_panel_preview(ScrArea *sa, short cntrl) // IMAGE_HANDLER_PREVIEW -{ - uiBlock *block; - SpaceImage *sima= sa->spacedata.first; - int ofsx, ofsy; - - if(is_preview_allowed(sa)==0) { - rem_blockhandler(sa, IMAGE_HANDLER_PREVIEW); - G.scene->r.scemode &= ~R_COMP_CROP; /* quite weak */ - return; - } - - block= uiBeginBlock(C, ar, "image_panel_preview", UI_EMBOSS); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); - uiSetPanelHandler(IMAGE_HANDLER_PREVIEW); // for close and esc - - ofsx= -150+(sa->winx/2)/sima->blockscale; - ofsy= -100+(sa->winy/2)/sima->blockscale; - if(uiNewPanel(C, ar, block, "Preview", "Image", ofsx, ofsy, 300, 200)==0) return; - - uiBlockSetDrawExtraFunc(block, preview_cb); - -} - -static void image_panel_gpencil(short cntrl) // IMAGE_HANDLER_GREASEPENCIL -{ - uiBlock *block; - SpaceImage *sima; - - sima= curarea->spacedata.first; - - block= uiBeginBlock(C, ar, "image_panel_gpencil", UI_EMBOSS); - uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); - uiSetPanelHandler(IMAGE_HANDLER_GREASEPENCIL); // for close and esc - if (uiNewPanel(C, ar, block, "Grease Pencil", "SpaceImage", 100, 30, 318, 204)==0) return; - - /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */ - if (sima->flag & SI_DISPGP) { - if (sima->gpd == NULL) - gpencil_data_setactive(curarea, gpencil_data_addnew()); - } - - if (sima->flag & SI_DISPGP) { - bGPdata *gpd= sima->gpd; - short newheight; - - /* this is a variable height panel, newpanel doesnt force new size on existing panels */ - /* so first we make it default height */ - uiNewPanelHeight(block, 204); - - /* draw button for showing gpencil settings and drawings */ - uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor (draw using Shift-LMB)"); - - /* extend the panel if the contents won't fit */ - newheight= draw_gpencil_panel(block, gpd, curarea); - uiNewPanelHeight(block, newheight); - } - else { - uiDefButBitI(block, TOG, SI_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sima->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Image/UV Editor"); - uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, ""); - } -} -#endif - - -/* ********************* callbacks for standard image buttons *************** */ - -/* called from fileselect or button */ -static void load_image_cb(bContext *C, char *str, void *ima_pp_v, void *iuser_v) -{ - Image **ima_pp= (Image **)ima_pp_v; - Image *ima= NULL; - - ima= BKE_add_image_file(str, 0); - if(ima) { - if(*ima_pp) { - (*ima_pp)->id.us--; - } - *ima_pp= ima; - - BKE_image_signal(ima, iuser_v, IMA_SIGNAL_RELOAD); - WM_event_add_notifier(C, NC_IMAGE, ima); - - /* button event gets lost when it goes via filewindow */ -// if(G.buts && G.buts->lockpoin) { -// Tex *tex= G.buts->lockpoin; -// if(GS(tex->id.name)==ID_TE) { -// BIF_preview_changed(ID_TE); -// allqueue(REDRAWBUTSSHADING, 0); -// allqueue(REDRAWVIEW3D, 0); -// allqueue(REDRAWOOPS, 0); -// } -// } - } - - ED_undo_push(C, "Load image"); -} - -static char *layer_menu(RenderResult *rr, short *curlay) -{ - RenderLayer *rl; - int len= 64 + 32*BLI_countlist(&rr->layers); - short a, nr= 0; - char *str= MEM_callocN(len, "menu layers"); - - strcpy(str, "Layer %t"); - a= strlen(str); - - /* compo result */ - if(rr->rectf) { - a+= sprintf(str+a, "|Composite %%x0"); - nr= 1; - } - for(rl= rr->layers.first; rl; rl= rl->next, nr++) { - a+= sprintf(str+a, "|%s %%x%d", rl->name, nr); - } - - /* no curlay clip here, on render (redraws) the amount of layers can be 1 fir single-layer render */ - - return str; -} - -/* rl==NULL means composite result */ -static char *pass_menu(RenderLayer *rl, short *curpass) -{ - RenderPass *rpass; - int len= 64 + 32*(rl?BLI_countlist(&rl->passes):1); - short a, nr= 0; - char *str= MEM_callocN(len, "menu layers"); - - strcpy(str, "Pass %t"); - a= strlen(str); - - /* rendered results don't have a Combined pass */ - if(rl==NULL || rl->rectf) { - a+= sprintf(str+a, "|Combined %%x0"); - nr= 1; - } - - if(rl) - for(rpass= rl->passes.first; rpass; rpass= rpass->next, nr++) - a+= sprintf(str+a, "|%s %%x%d", rpass->name, nr); - - if(*curpass >= nr) - *curpass= 0; - - return str; -} - -static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v) -{ - Scene *scene= CTX_data_scene(C); - Image *ima= ima_v; - ImageUser *iuser= iuser_v; - - if(ima->anim) { - iuser->frames = IMB_anim_get_duration(ima->anim); - BKE_image_user_calc_imanr(iuser, scene->r.cfra, 0); - } -} - -static void image_src_change_cb(bContext *C, void *ima_v, void *iuser_v) -{ - BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_SRC_CHANGE); -} - -/* buttons have 2 arg callbacks, filewindow has 3 args... so thats why the wrapper below */ -static void image_browse_cb1(bContext *C, void *ima_pp_v, void *iuser_v) -{ - Image **ima_pp= (Image **)ima_pp_v; - ImageUser *iuser= iuser_v; - - if(ima_pp) { - Image *ima= *ima_pp; - - if(iuser->menunr== -2) { - // XXX activate_databrowse_args(&ima->id, ID_IM, 0, &iuser->menunr, image_browse_cb1, ima_pp, iuser); - } - else if (iuser->menunr>0) { - Image *newima= (Image*) BLI_findlink(&CTX_data_main(C)->image, iuser->menunr-1); - - if (newima && newima!=ima) { - *ima_pp= newima; - id_us_plus(&newima->id); - if(ima) ima->id.us--; - - BKE_image_signal(newima, iuser, IMA_SIGNAL_USER_NEW_IMAGE); - - ED_undo_push(C, "Browse image"); - } - } - } -} - -static void image_browse_cb(bContext *C, void *ima_pp_v, void *iuser_v) -{ - image_browse_cb1(C, ima_pp_v, iuser_v); -} - -static void image_reload_cb(bContext *C, void *ima_v, void *iuser_v) -{ - if(ima_v) { - BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_RELOAD); - } -} - -static void image_field_test(bContext *C, void *ima_v, void *iuser_v) -{ - Image *ima= ima_v; - - if(ima) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); - if(ibuf) { - short nr= 0; - if( !(ima->flag & IMA_FIELDS) && (ibuf->flags & IB_fields) ) nr= 1; - if( (ima->flag & IMA_FIELDS) && !(ibuf->flags & IB_fields) ) nr= 1; - if(nr) { - BKE_image_signal(ima, iuser_v, IMA_SIGNAL_FREE); - } - } - } -} - -static void image_unlink_cb(bContext *C, void *ima_pp_v, void *unused) -{ - Image **ima_pp= (Image **)ima_pp_v; - - if(ima_pp && *ima_pp) { - Image *ima= *ima_pp; - /* (for time being, texturefaces are no users, conflict in design...) */ - if(ima->id.us>1) - ima->id.us--; - *ima_pp= NULL; - } -} - -static void image_load_fs_cb(bContext *C, void *ima_pp_v, void *iuser_v) -{ - ScrArea *sa= CTX_wm_area(C); -// Image **ima_pp= (Image **)ima_pp_v; - - if(sa->spacetype==SPACE_IMAGE) - WM_operator_name_call(C, "IMAGE_OT_open", WM_OP_INVOKE_REGION_WIN, NULL); - else - printf("not supported yet\n"); -} - -/* 5 layer button callbacks... */ -static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) -{ - BKE_image_multilayer_index(rr_v, iuser_v); -} -static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) -{ - RenderResult *rr= rr_v; - ImageUser *iuser= iuser_v; - int tot= BLI_countlist(&rr->layers) + (rr->rectf?1:0); /* fake compo result layer */ - if(iuser->layerlayer++; - BKE_image_multilayer_index(rr, iuser); -} -static void image_multi_declay_cb(bContext *C, void *rr_v, void *iuser_v) -{ - ImageUser *iuser= iuser_v; - if(iuser->layer>0) - iuser->layer--; - BKE_image_multilayer_index(rr_v, iuser); -} -static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v) -{ - RenderResult *rr= rr_v; - ImageUser *iuser= iuser_v; - RenderLayer *rl= BLI_findlink(&rr->layers, iuser->layer); - if(rl) { - int tot= BLI_countlist(&rl->passes) + (rl->rectf?1:0); /* builtin render result has no combined pass in list */ - if(iuser->passpass++; - BKE_image_multilayer_index(rr, iuser); - } - } -} -static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v) -{ - ImageUser *iuser= iuser_v; - if(iuser->pass>0) { - iuser->pass--; - BKE_image_multilayer_index(rr_v, iuser); - } -} - -static void image_pack_cb(bContext *C, void *ima_v, void *iuser_v) -{ - if(ima_v) { - Image *ima= ima_v; - if(ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE) { - if (ima->packedfile) { - if (G.fileflags & G_AUTOPACK) { - if (okee("Disable AutoPack ?")) { - G.fileflags &= ~G_AUTOPACK; - } - } - - if ((G.fileflags & G_AUTOPACK) == 0) { - unpackImage(ima, PF_ASK); - ED_undo_push(C, "Unpack image"); - } - } - else { - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); - if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) { - // XXX error("Can't pack painted image. Save image or use Repack as PNG."); - } else { - ima->packedfile = newPackedFile(ima->name); - ED_undo_push(C, "Pack image"); - } - } - } - } -} - -static void image_load_cb(bContext *C, void *ima_pp_v, void *iuser_v) -{ - if(ima_pp_v) { - Image *ima= *((Image **)ima_pp_v); - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser_v); - char str[FILE_MAX]; - - /* name in ima has been changed by button! */ - BLI_strncpy(str, ima->name, FILE_MAX); - if(ibuf) BLI_strncpy(ima->name, ibuf->name, FILE_MAX); - - load_image_cb(C, str, ima_pp_v, iuser_v); - } -} - -static void image_freecache_cb(bContext *C, void *ima_v, void *unused) -{ - Scene *scene= CTX_data_scene(C); - BKE_image_free_anim_ibufs(ima_v, scene->r.cfra); - WM_event_add_notifier(C, NC_IMAGE, ima_v); -} - -static void image_generated_change_cb(bContext *C, void *ima_v, void *iuser_v) -{ - BKE_image_signal(ima_v, iuser_v, IMA_SIGNAL_FREE); -} - -static void image_user_change(bContext *C, void *iuser_v, void *unused) -{ - Scene *scene= CTX_data_scene(C); - BKE_image_user_calc_imanr(iuser_v, scene->r.cfra, 0); -} - -static void uiblock_layer_pass_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int event, int x, int y, int w) -{ - uiBut *but; - RenderLayer *rl= NULL; - int wmenu1, wmenu2; - char *strp; - - /* layer menu is 1/3 larger than pass */ - wmenu1= (3*w)/5; - wmenu2= (2*w)/5; - - /* menu buts */ - strp= layer_menu(rr, &iuser->layer); - but= uiDefButS(block, MENU, event, strp, x, y, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer"); - uiButSetFunc(but, image_multi_cb, rr, iuser); - MEM_freeN(strp); - - rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */ - strp= pass_menu(rl, &iuser->pass); - but= uiDefButS(block, MENU, event, strp, x+wmenu1, y, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass"); - uiButSetFunc(but, image_multi_cb, rr, iuser); - MEM_freeN(strp); -} - -static void uiblock_layer_pass_arrow_buttons(uiBlock *block, RenderResult *rr, ImageUser *iuser, int imagechanged) -{ - uiBut *but; - - if(rr==NULL || iuser==NULL) - return; - if(rr->layers.first==NULL) { - uiDefBut(block, LABEL, 0, "No Layers in Render Result,", 10, 107, 300, 20, NULL, 1, 0, 0, 0, ""); - return; - } - - uiBlockBeginAlign(block); - - /* decrease, increase arrows */ - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 10,107,17,20, NULL, 0, 0, 0, 0, "Previous Layer"); - uiButSetFunc(but, image_multi_declay_cb, rr, iuser); - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 27,107,18,20, NULL, 0, 0, 0, 0, "Next Layer"); - uiButSetFunc(but, image_multi_inclay_cb, rr, iuser); - - uiblock_layer_pass_buttons(block, rr, iuser, imagechanged, 45, 107, 230); - - /* decrease, increase arrows */ - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_LEFT, 275,107,17,20, NULL, 0, 0, 0, 0, "Previous Pass"); - uiButSetFunc(but, image_multi_decpass_cb, rr, iuser); - but= uiDefIconBut(block, BUT, imagechanged, ICON_TRIA_RIGHT, 292,107,18,20, NULL, 0, 0, 0, 0, "Next Pass"); - uiButSetFunc(but, image_multi_incpass_cb, rr, iuser); - - uiBlockEndAlign(block); - -} - -// XXX HACK! -static int packdummy=0; - -/* The general Image panel with the loadsa callbacks! */ -void ED_image_uiblock_panel(const bContext *C, uiBlock *block, Image **ima_pp, ImageUser *iuser, - short redraw, short imagechanged) -{ - Scene *scene= CTX_data_scene(C); - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - Image *ima= *ima_pp; - uiBut *but; - char str[128], *strp; - - /* different stuff when we show viewer */ - if(ima && ima->source==IMA_SRC_VIEWER) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser); - - image_info(ima, ibuf, str); - uiDefBut(block, LABEL, 0, ima->id.name+2, 10, 180, 300, 20, NULL, 1, 0, 0, 0, ""); - uiDefBut(block, LABEL, 0, str, 10, 160, 300, 20, NULL, 1, 0, 0, 0, ""); - - if(ima->type==IMA_TYPE_COMPOSITE) { - iuser= ntree_get_active_iuser(scene->nodetree); - if(iuser) { - uiBlockBeginAlign(block); - uiDefIconTextBut(block, BUT, B_SIMA_RECORD, ICON_REC, "Record", 10,120,100,20, 0, 0, 0, 0, 0, ""); - uiDefIconTextBut(block, BUT, B_SIMA_PLAY, ICON_PLAY, "Play", 110,120,100,20, 0, 0, 0, 0, 0, ""); - but= uiDefBut(block, BUT, B_NOP, "Free Cache", 210,120,100,20, 0, 0, 0, 0, 0, ""); - uiButSetFunc(but, image_freecache_cb, ima, NULL); - - if(iuser->frames) - sprintf(str, "(%d) Frames:", iuser->framenr); - else strcpy(str, "Frames:"); - uiBlockBeginAlign(block); - uiDefButI(block, NUM, imagechanged, str, 10, 90,150, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - uiDefButI(block, NUM, imagechanged, "StartFr:", 160,90,150,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); - } - } - else if(ima->type==IMA_TYPE_R_RESULT) { - /* browse layer/passes */ - uiblock_layer_pass_arrow_buttons(block, RE_GetResult(RE_GetRender(scene->id.name)), iuser, imagechanged); - } - return; - } - - /* the main ima source types */ - if(ima) { -// XXX uiSetButLock(ima->id.lib!=NULL, ERROR_LIBDATA_MESSAGE); - uiBlockBeginAlign(block); - uiBlockSetFunc(block, image_src_change_cb, ima, iuser); - uiDefButS(block, ROW, imagechanged, "Still", 10, 180, 60, 20, &ima->source, 0.0, IMA_SRC_FILE, 0, 0, "Single Image file"); - uiDefButS(block, ROW, imagechanged, "Movie", 70, 180, 60, 20, &ima->source, 0.0, IMA_SRC_MOVIE, 0, 0, "Movie file"); - uiDefButS(block, ROW, imagechanged, "Sequence", 130, 180, 90, 20, &ima->source, 0.0, IMA_SRC_SEQUENCE, 0, 0, "Multiple Image files, as a sequence"); - uiDefButS(block, ROW, imagechanged, "Generated", 220, 180, 90, 20, &ima->source, 0.0, IMA_SRC_GENERATED, 0, 0, "Generated Image"); - uiBlockSetFunc(block, NULL, NULL, NULL); - } - else - uiDefBut(block, LABEL, 0, " ", 10, 180, 300, 20, 0, 0, 0, 0, 0, ""); /* for align in panel */ - - /* Browse */ - IMAnames_to_pupstring(&strp, NULL, NULL, &(CTX_data_main(C)->image), NULL, &iuser->menunr); - - uiBlockBeginAlign(block); - but= uiDefButS(block, MENU, imagechanged, strp, 10,155,23,20, &iuser->menunr, 0, 0, 0, 0, "Selects an existing Image or Movie"); - uiButSetFunc(but, image_browse_cb, ima_pp, iuser); - - MEM_freeN(strp); - - /* name + options, or only load */ - if(ima) { - int drawpack= (ima->source!=IMA_SRC_SEQUENCE && ima->source!=IMA_SRC_MOVIE && ima->ok); - - but= uiDefBut(block, TEX, B_IDNAME, "IM:", 33, 155, 177, 20, ima->id.name+2, 0.0, 21.0, 0, 0, "Current Image Datablock name."); - uiButSetFunc(but, test_idbutton_cb, ima->id.name, NULL); - but= uiDefBut(block, BUT, imagechanged, "Reload", 210, 155, 60, 20, NULL, 0, 0, 0, 0, "Reloads Image or Movie"); - uiButSetFunc(but, image_reload_cb, ima, iuser); - - but= uiDefIconBut(block, BUT, imagechanged, ICON_X, 270,155,20,20, 0, 0, 0, 0, 0, "Unlink Image block"); - uiButSetFunc(but, image_unlink_cb, ima_pp, NULL); - sprintf(str, "%d", ima->id.us); - uiDefBut(block, BUT, B_NOP, str, 290,155,20,20, 0, 0, 0, 0, 0, "Only displays number of users of Image block"); - - but= uiDefIconBut(block, BUT, imagechanged, ICON_FILESEL, 10, 135, 23, 20, 0, 0, 0, 0, 0, "Open Fileselect to load new Image"); - uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser); - but= uiDefBut(block, TEX, imagechanged, "", 33,135,257+(drawpack?0:20),20, ima->name, 0.0, 239.0, 0, 0, "Image/Movie file name, change to load new"); - uiButSetFunc(but, image_load_cb, ima_pp, iuser); - - if(drawpack) { - if (ima->packedfile) packdummy = 1; - else packdummy = 0; - but= uiDefIconButBitI(block, TOG, 1, redraw, ICON_PACKAGE, 290,135,20,20, &packdummy, 0, 0, 0, 0, "Toggles Packed status of this Image"); - uiButSetFunc(but, image_pack_cb, ima, iuser); - } - - } - else { - but= uiDefBut(block, BUT, imagechanged, "Load", 33, 155, 100,20, NULL, 0, 0, 0, 0, "Load new Image of Movie"); - uiButSetFunc(but, image_load_fs_cb, ima_pp, iuser); - } - uiBlockEndAlign(block); - - if(ima) { - ImBuf *ibuf= BKE_image_get_ibuf(ima, iuser); - - /* check for re-render, only buttons */ - if(imagechanged==B_IMAGECHANGED) { - if(iuser->flag & IMA_ANIM_REFRESHED) { - iuser->flag &= ~IMA_ANIM_REFRESHED; - WM_event_add_notifier(C, NC_IMAGE, ima); - } - } - - /* multilayer? */ - if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { - uiblock_layer_pass_arrow_buttons(block, ima->rr, iuser, imagechanged); - } - else { - image_info(ima, ibuf, str); - uiDefBut(block, LABEL, 0, str, 10, 112, 300, 20, NULL, 1, 0, 0, 0, ""); - } - - /* exception, let's do because we only use this panel 3 times in blender... but not real good code! */ - if( (FACESEL_PAINT_TEST) && sima && &sima->iuser==iuser) - return; - /* left side default per-image options, right half the additional options */ - - /* fields */ - uiBlockBeginAlign(block); - but= uiDefButBitS(block, TOGBUT, IMA_FIELDS, imagechanged, "Fields", 10, 70, 65, 20, &ima->flag, 0, 0, 0, 0, "Click to enable use of fields in Image"); - uiButSetFunc(but, image_field_test, ima, iuser); - uiDefButBitS(block, TOGBUT, IMA_STD_FIELD, B_NOP, "Odd", 75, 70, 45, 20, &ima->flag, 0, 0, 0, 0, "Standard Field Toggle"); - - uiBlockSetFunc(block, image_reload_cb, ima, iuser); - uiDefButBitS(block, TOGBUT, IMA_ANTIALI, B_NOP, "Anti", 10, 50, 45, 20, &ima->flag, 0, 0, 0, 0, "Toggles Image anti-aliasing, only works with solid colors"); - uiDefButBitS(block, TOGBUT, IMA_DO_PREMUL, imagechanged, "Premul", 55, 50, 65, 20, &ima->flag, 0, 0, 0, 0, "Toggles premultiplying alpha"); - uiBlockEndAlign(block); - - if( ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - sprintf(str, "(%d) Frames:", iuser->framenr); - - uiBlockBeginAlign(block); - uiBlockSetFunc(block, image_user_change, iuser, NULL); - uiDefButBitS(block, TOG, IMA_ANIM_ALWAYS, B_NOP, "Auto Refresh", 120, 70, 190, 20, &iuser->flag, 0, 0, 0, 0, "Always refresh Image on frame changes"); - - if(ima->anim) { - uiDefButI(block, NUM, imagechanged, str, 120, 50,170, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - but= uiDefBut(block, BUT, redraw, "<", 290, 50, 20, 20, 0, 0, 0, 0, 0, "Copies number of frames in movie file to Frames: button"); - uiButSetFunc(but, set_frames_cb, ima, iuser); - } - else - uiDefButI(block, NUM, imagechanged, str, 120, 50,190, 20, &iuser->frames, 0.0, MAXFRAMEF, 0, 0, "Sets the number of images of a movie to use"); - - uiDefButI(block, NUM, imagechanged, "Offs:", 120,30,100,20, &iuser->offset, -MAXFRAMEF, MAXFRAMEF, 0, 0, "Offsets the number of the frame to use in the animation"); - uiDefButS(block, NUM, imagechanged, "Fie/Ima:", 220,30,90,20, &iuser->fie_ima, 1.0, 200.0, 0, 0, "The number of fields per rendered frame (2 fields is 1 image)"); - - uiDefButI(block, NUM, imagechanged, "StartFr:", 120,10,100,20, &iuser->sfra, 1.0, MAXFRAMEF, 0, 0, "Sets the global starting frame of the movie"); - uiDefButS(block, TOG, imagechanged, "Cyclic", 220,10,90,20, &iuser->cycl, 0.0, 1.0, 0, 0, "Cycle the images in the movie"); - - uiBlockSetFunc(block, NULL, iuser, NULL); - } - else if(ima->source==IMA_SRC_GENERATED) { - - uiBlockBeginAlign(block); - uiBlockSetFunc(block, image_generated_change_cb, ima, iuser); - uiDefButS(block, NUM, imagechanged, "SizeX:", 120,70,100,20, &ima->gen_x, 1.0, 5000.0, 0, 0, "Image size x"); - uiDefButS(block, NUM, imagechanged, "SizeY:", 220,70,90,20, &ima->gen_y, 1.0, 5000.0, 0, 0, "Image size y"); - uiDefButS(block, TOGBUT, imagechanged, "UV Test grid",120,50,190,20, &ima->gen_type, 0.0, 1.0, 0, 0, ""); - uiBlockSetFunc(block, NULL, NULL, NULL); - } - } - uiBlockEndAlign(block); -} - - -static void image_panel_properties(const bContext *C, ARegion *ar) -{ - SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); - uiBlock *block; - - block= uiBeginBlock(C, ar, "image_panel_properties", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Image Properties", "Image", 10, 50, 318, 204)==0) - return; - uiBlockSetHandleFunc(block, do_image_panel_events, NULL); - - /* note, it draws no bottom half in facemode, for vertex buttons */ - ED_image_uiblock_panel(C, block, &sima->image, &sima->iuser, B_REDR, B_REDR); - image_editvertex_buts(C, block); - - uiEndBlock(C, block); -} - - - -void image_buttons_area_defbuts(const bContext *C, ARegion *ar) -{ - uiBeginPanels(C, ar); - - image_panel_properties(C, ar); - image_panel_game_properties(C, ar); - image_panel_view_properties(C, ar); - image_panel_paint(C, ar); - image_panel_paintcolor(C, ar); - image_panel_curves(C, ar); - - uiEndPanels(C, ar); -} - - -static int image_properties(bContext *C, wmOperator *op) -{ - ScrArea *sa= CTX_wm_area(C); - ARegion *ar= image_has_buttons_region(sa); - - if(ar) { - ar->flag ^= RGN_FLAG_HIDDEN; - ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */ - - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa); - ED_area_tag_redraw(sa); - } - return OPERATOR_FINISHED; -} - -void IMAGE_OT_properties(wmOperatorType *ot) -{ - ot->name= "Properties"; - ot->idname= "IMAGE_OT_properties"; - - ot->exec= image_properties; - ot->poll= ED_operator_image_active; - - /* flags */ - ot->flag= 0; -} - - - diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 5f743afd65d..c82018a3aac 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -483,32 +483,16 @@ static void image_main_area_listener(ARegion *ar, wmNotifier *wmn) static void image_buttons_area_init(wmWindowManager *wm, ARegion *ar) { ListBase *keymap; + + ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST_UI, ar->winx, ar->winy); } static void image_buttons_area_draw(const bContext *C, ARegion *ar) { - float col[3]; - - /* clear */ - UI_GetThemeColor3fv(TH_PANEL, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - image_buttons_area_defbuts(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + ED_region_panels(C, ar, 1, NULL); } static void image_buttons_area_listener(ARegion *ar, wmNotifier *wmn) @@ -590,6 +574,8 @@ void ED_spacetype_image(void) art->draw= image_buttons_area_draw; BLI_addhead(&st->regiontypes, art); + image_buttons_register(art); + /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype image region"); art->regionid = RGN_TYPE_HEADER; diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 33fa85dbb5d..384ad3e919c 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -348,8 +348,7 @@ static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void text_header_area_init(wmWindowManager *wm, ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); - ar->v2d.flag &= ~(V2D_PIXELOFS_X|V2D_PIXELOFS_Y); // XXX temporary + ED_region_header_init(ar); } static void text_header_area_draw(const bContext *C, ARegion *ar) @@ -362,7 +361,7 @@ static void text_header_area_draw(const bContext *C, ARegion *ar) /* add handlers, stuff you only do once or on area/region changes */ static void text_properties_area_init(wmWindowManager *wm, ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy); + ED_region_panels_init(wm, ar); } static void text_properties_area_draw(const bContext *C, ARegion *ar) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 9ed7dd50d2e..3b3fd5109cf 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -487,32 +487,16 @@ static void view3d_header_area_listener(ARegion *ar, wmNotifier *wmn) static void view3d_buttons_area_init(wmWindowManager *wm, ARegion *ar) { ListBase *keymap; + + ED_region_panels_init(wm, ar); - keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST_UI, ar->winx, ar->winy); } static void view3d_buttons_area_draw(const bContext *C, ARegion *ar) { - float col[3]; - - /* clear */ - UI_GetThemeColor3fv(TH_BACK, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - view3d_buttons_area_defbuts(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + ED_region_panels(C, ar, 1, NULL); } static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) @@ -549,35 +533,17 @@ static void view3d_tools_area_init(wmWindowManager *wm, ARegion *ar) { ListBase *keymap; - keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); + ED_region_panels_init(wm, ar); + keymap= WM_keymap_listbase(wm, "View3D Generic", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - // XXX +20 temp... need init for this - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx+20, ar->winy); } - static void view3d_tools_area_draw(const bContext *C, ARegion *ar) { - float col[3]; - - /* clear */ - UI_GetThemeColor3fv(TH_BACK, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(C, &ar->v2d); - - view3d_tools_area_defbuts(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); + ED_region_panels(C, ar, 1, NULL); } - /* * Returns true if the Object is a from an external blend file (libdata) */ @@ -850,6 +816,8 @@ void ED_spacetype_view3d(void) art->draw= view3d_buttons_area_draw; BLI_addhead(&st->regiontypes, art); + view3d_buttons_register(art); + /* regions: tool(bar) */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); art->regionid = RGN_TYPE_TOOLS; @@ -861,6 +829,7 @@ void ED_spacetype_view3d(void) art->draw= view3d_tools_area_draw; BLI_addhead(&st->regiontypes, art); + view3d_toolbar_register(art); /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 5dad3f8cc7d..95abb4d59a5 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -947,7 +947,7 @@ void selectTransformOrientation_func(bContext *C, void *target, void *unused) BIF_selectTransformOrientation(C, (TransformOrientation *) target); } -static void view3d_panel_transform_spaces(const bContext *C, ARegion *ar, short cntrl) +static void view3d_panel_transform_spaces(const bContext *C, Panel *pa) { Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); @@ -956,13 +956,10 @@ static void view3d_panel_transform_spaces(const bContext *C, ARegion *ar, short TransformOrientation *ts = transform_spaces->first; uiBlock *block; uiBut *but; - int xco = 20, yco = 70, height = 140; + int xco = 20, yco = 70; int index; - block= uiBeginBlock(C, ar, "view3d_panel_transform", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Transform Orientations", "View3d", 1000, 0, 318, height)==0) return; - - uiNewPanelHeight(block, height); + block= uiLayoutFreeBlock(pa->layout); uiBlockBeginAlign(block); @@ -999,9 +996,6 @@ static void view3d_panel_transform_spaces(const bContext *C, ARegion *ar, short yco -= 25; } uiBlockEndAlign(block); - - if(yco < 0) uiNewPanelHeight(block, height-yco); - uiEndBlock(C, block); } static void weight_paint_buttons(Scene *scene, uiBlock *block) @@ -1103,19 +1097,23 @@ static void brush_idpoin_handle(bContext *C, ID *id, int event) } } -static void view3d_panel_brush(const bContext *C, ARegion *ar, short cntrl) +static int view3d_panel_brush_poll(const bContext *C, PanelType *pt) +{ + Brush **brp = current_brush_source(CTX_data_scene(C)); + + return ((G.f & (G_SCULPTMODE|G_TEXTUREPAINT|G_VERTEXPAINT|G_WEIGHTPAINT)) && brp); +} + +static void view3d_panel_brush(const bContext *C, Panel *pa) { uiBlock *block; Brush **brp = current_brush_source(CTX_data_scene(C)), *br; short w = 268, h = 400, cx = 10, cy = h; rctf rect; - if(!brp) - return; br = *brp; - block= uiBeginBlock(C, ar, "view3d_panel_brush", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Brush", "View3d", 340, 10, 318, h)==0) return; + block= uiLayoutFreeBlock(pa->layout); uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); uiBlockBeginAlign(block); @@ -1164,8 +1162,6 @@ static void view3d_panel_brush(const bContext *C, ARegion *ar, short cntrl) uiBlockBeginAlign(block); curvemap_buttons(block, br->curve, (char)0, B_NOP, 0, &rect); uiBlockEndAlign(block); - - uiEndBlock(C, block); } static void sculptmode_draw_interface_tools(Scene *scene, uiBlock *block, unsigned short cx, unsigned short cy) @@ -1203,12 +1199,12 @@ static void sculptmode_draw_interface_tools(Scene *scene, uiBlock *block, unsign } -static void view3d_panel_object(const bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_OBJECT +static void view3d_panel_object(const bContext *C, Panel *pa) { + uiBlock *block; Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); View3D *v3d= CTX_wm_view3d(C); - uiBlock *block; uiBut *bt; Object *ob= OBACT; TransformProperties *tfp; @@ -1222,19 +1218,8 @@ static void view3d_panel_object(const bContext *C, ARegion *ar, short cntrl) // v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties"); tfp= v3d->properties_storage; - block= uiBeginBlock(C, ar, "view3d_panel_object", UI_EMBOSS); + block= uiLayoutFreeBlock(pa->layout); uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); - - if((G.f & G_SCULPTMODE) && !obedit) { - if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 234)) - return; - } else if(G.f & G_PARTICLEEDIT && !obedit){ - if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 234)) - return; - } else { - if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 204)) - return; - } // XXX uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE); @@ -1269,24 +1254,24 @@ static void view3d_panel_object(const bContext *C, ARegion *ar, short cntrl) // v3d_posearmature_buts(block, v3d, ob, lim); } else if(G.f & G_WEIGHTPAINT) { - uiNewPanelTitle(block, "Weight Paint Properties"); + BLI_strncpy(pa->drawname, "Weight Paint Properties", sizeof(pa->drawname)); weight_paint_buttons(scene, block); } else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT)) { static float hsv[3], old[3]; // used as temp mem for picker Brush **br = current_brush_source(scene); - uiNewPanelTitle(block, "Paint Properties"); + BLI_strncpy(pa->drawname, "Paint Properties", sizeof(pa->drawname)); if(br && *br) /* 'f' is for floating panel */ uiBlockPickerButtons(block, (*br)->rgb, hsv, old, hexcol, 'f', B_REDR); } else if(G.f & G_SCULPTMODE) { - uiNewPanelTitle(block, "Sculpt Properties"); + BLI_strncpy(pa->drawname, "Sculpt Properties", sizeof(pa->drawname)); sculptmode_draw_interface_tools(scene, block, 10, 150); } else if(G.f & G_PARTICLEEDIT){ - uiNewPanelTitle(block, "Particle Edit Properties"); + BLI_strncpy(pa->drawname, "Particle Edit Properties", sizeof(pa->drawname)); // XXX particle_edit_buttons(block); } else { @@ -1364,17 +1349,14 @@ static void view3d_panel_object(const bContext *C, ARegion *ar, short cntrl) // uiBlockEndAlign(block); } } -// XXX uiClearButLock(); - uiEndBlock(C, block); } -static void view3d_panel_background(const bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_BACKGROUND +static void view3d_panel_background(const bContext *C, Panel *pa) { View3D *v3d= CTX_wm_view3d(C); uiBlock *block; - block= uiBeginBlock(C, ar, "view3d_panel_background", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Background Image", "View3d", 340, 10, 318, 204)==0) return; + block= uiLayoutFreeBlock(pa->layout); uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); if(v3d->flag & V3D_DISPBGPIC) { @@ -1403,11 +1385,10 @@ static void view3d_panel_background(const bContext *C, ARegion *ar, short cntrl) ED_image_uiblock_panel(C, block, &v3d->bgpic->ima, &v3d->bgpic->iuser, B_REDR, B_REDR); uiBlockEndAlign(block); } - uiEndBlock(C, block); } -static void view3d_panel_properties(const bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_SETTINGS +static void view3d_panel_properties(const bContext *C, Panel *pa) { ScrArea *sa= CTX_wm_area(C); ARegion *arlast; @@ -1417,13 +1398,9 @@ static void view3d_panel_properties(const bContext *C, ARegion *ar, short cntrl) uiBlock *block; float *curs; - block= uiBeginBlock(C, ar, "view3d_panel_properties", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "View Properties", "View3d", 340, 30, 318, 254)==0) return; + block= uiLayoutFreeBlock(pa->layout); uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); - /* to force height */ - uiNewPanelHeight(block, 264); - uiDefBut(block, LABEL, 1, "Grid:", 10, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_REDR, "Spacing:", 10, 200, 140, 19, &v3d->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines"); @@ -1497,8 +1474,6 @@ static void view3d_panel_properties(const bContext *C, ARegion *ar, short cntrl) // uiDefButBitS(block, TOGN, ANIMFILTER_NOSKEY, B_REDR, "ShapeKey",235, -42, 75, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for any available Shape Keys"); // } uiBlockEndAlign(block); - - uiEndBlock(C, block); } #if 0 @@ -1527,13 +1502,12 @@ static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3 } #endif -static void view3d_panel_gpencil(const bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_GREASEPENCIL +static void view3d_panel_gpencil(const bContext *C, Panel *pa) { View3D *v3d= CTX_wm_view3d(C); uiBlock *block; - block= uiBeginBlock(C, ar, "view3d_panel_gpencil", UI_EMBOSS); - if (uiNewPanel(C, ar, block, "Grease Pencil", "View3d", 100, 30, 318, 204)==0) return; + block= uiLayoutFreeBlock(pa->layout); /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */ if (v3d->flag2 & V3D_DISPGP) { @@ -1543,24 +1517,14 @@ static void view3d_panel_gpencil(const bContext *C, ARegion *ar, short cntrl) // if (v3d->flag2 & V3D_DISPGP) { // XXX bGPdata *gpd= v3d->gpd; - short newheight; - - /* this is a variable height panel, newpanel doesnt force new size on existing panels */ - /* so first we make it default height */ - uiNewPanelHeight(block, 204); /* draw button for showing gpencil settings and drawings */ uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View (draw using Shift-LMB)"); - - /* extend the panel if the contents won't fit */ -// newheight= draw_gpencil_panel(block, gpd, ar); - uiNewPanelHeight(block, newheight); } else { uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View"); uiDefBut(block, LABEL, 1, " ", 160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, ""); } - uiEndBlock(C, block); } static void delete_sketch_armature(bContext *C, void *arg1, void *arg2) @@ -1578,126 +1542,123 @@ static void assign_template_sketch_armature(bContext *C, void *arg1, void *arg2) int index = *(int*)arg1; BIF_setTemplate(C, index); } -static void view3d_panel_bonesketch_spaces(const bContext *C, ARegion *ar, short cntrl) + +static int view3d_panel_bonesketch_spaces_poll(const bContext *C, PanelType *pt) { Object *obedit = CTX_data_edit_object(C); + + /* replace with check call to sketching lib */ + return (obedit && obedit->type == OB_ARMATURE); +} +static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa) +{ Scene *scene = CTX_data_scene(C); static int template_index; static char joint_label[128]; uiBlock *block; uiBut *but; char *bone_name; - int yco = 130, height = 140; + int yco = 130; int nb_joints; + static char subdiv_tooltip[4][64] = { + "Subdivide arcs based on a fixed number of bones", + "Subdivide arcs in bones of equal length", + "Subdivide arcs based on correlation", + "Retarget template to stroke" + }; - /* replace with check call to sketching lib */ - if (obedit && obedit->type == OB_ARMATURE) - { - static char subdiv_tooltip[4][64] = { - "Subdivide arcs based on a fixed number of bones", - "Subdivide arcs in bones of equal length", - "Subdivide arcs based on correlation", - "Retarget template to stroke" - }; + + block= uiLayoutFreeBlock(pa->layout); + uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); - - block= uiBeginBlock(C, ar, "view3d_panel_bonesketch_spaces", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Bone Sketching", "View3d", 340, 10, 318, height)==0) return; - uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); + uiBlockBeginAlign(block); + + /* use real flag instead of 1 */ + uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones"); + uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them"); + uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end"); + yco -= 20; + + but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature"); + uiButSetFunc(but, convert_sketch_armature, NULL, NULL); + + but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch"); + uiButSetFunc(but, delete_sketch_armature, NULL, NULL); + yco -= 20; - uiNewPanelHeight(block, height); + uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)scene->toolsettings->bone_sketching_convert]); + + switch(scene->toolsettings->bone_sketching_convert) + { + case SK_CONVERT_CUT_LENGTH: + uiDefButF(block, NUM, B_REDR, "Lim:", 70, yco, 140, 19, &scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the subdivided bones"); + yco -= 20; + break; + case SK_CONVERT_CUT_ADAPTATIVE: + uiDefButF(block, NUM, B_REDR, "Thres:", 70, yco, 140, 19, &scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Correlation threshold for subdivision"); + yco -= 20; + break; + default: + case SK_CONVERT_CUT_FIXED: + uiDefButC(block, NUM, B_REDR, "Num:", 70, yco, 140, 19, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones"); + yco -= 20; + break; + case SK_CONVERT_RETARGET: + uiDefButC(block, ROW, B_NOP, "No", 70, yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0, "No special roll treatment"); + uiDefButC(block, ROW, B_NOP, "View", 110, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0, "Roll bones perpendicular to view"); + uiDefButC(block, ROW, B_NOP, "Joint", 160, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0, "Roll bones relative to joint bend"); + yco -= 30; + + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + /* button here to select what to do (copy or not), template, ...*/ + + BIF_makeListTemplates(C); + template_index = BIF_currentTemplate(C); + + but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template"); + uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL); - /* use real flag instead of 1 */ - uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones"); - uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them"); - uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end"); yco -= 20; - but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature"); - uiButSetFunc(but, convert_sketch_armature, NULL, NULL); - - but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch"); - uiButSetFunc(but, delete_sketch_armature, NULL, NULL); + uiDefButF(block, NUM, B_NOP, "A:", 10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight"); + uiDefButF(block, NUM, B_NOP, "L:", 76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight"); + uiDefButF(block, NUM, B_NOP, "D:", 143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight"); yco -= 20; - uiBlockEndAlign(block); + uiDefBut(block, TEX,B_REDR,"S:", 10, yco, 90, 20, scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with"); + uiDefBut(block, TEX,B_REDR,"N:", 100, yco, 90, 20, scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with"); + uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_NOP, ICON_AUTO,190,yco,20,20, &scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming"); + yco -= 20; - uiBlockBeginAlign(block); + /* auto renaming magic */ + uiBlockEndAlign(block); - uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)scene->toolsettings->bone_sketching_convert]); + nb_joints = BIF_nbJointsTemplate(C); - switch(scene->toolsettings->bone_sketching_convert) + if (nb_joints == -1) { - case SK_CONVERT_CUT_LENGTH: - uiDefButF(block, NUM, B_REDR, "Lim:", 70, yco, 140, 19, &scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the subdivided bones"); - yco -= 20; - break; - case SK_CONVERT_CUT_ADAPTATIVE: - uiDefButF(block, NUM, B_REDR, "Thres:", 70, yco, 140, 19, &scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Correlation threshold for subdivision"); - yco -= 20; - break; - default: - case SK_CONVERT_CUT_FIXED: - uiDefButC(block, NUM, B_REDR, "Num:", 70, yco, 140, 19, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones"); - yco -= 20; - break; - case SK_CONVERT_RETARGET: - uiDefButC(block, ROW, B_NOP, "No", 70, yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0, "No special roll treatment"); - uiDefButC(block, ROW, B_NOP, "View", 110, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0, "Roll bones perpendicular to view"); - uiDefButC(block, ROW, B_NOP, "Joint", 160, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0, "Roll bones relative to joint bend"); - yco -= 30; - - uiBlockEndAlign(block); - - uiBlockBeginAlign(block); - /* button here to select what to do (copy or not), template, ...*/ - - BIF_makeListTemplates(C); - template_index = BIF_currentTemplate(C); - - but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template"); - uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL); - - yco -= 20; - - uiDefButF(block, NUM, B_NOP, "A:", 10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight"); - uiDefButF(block, NUM, B_NOP, "L:", 76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight"); - uiDefButF(block, NUM, B_NOP, "D:", 143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight"); - yco -= 20; - - uiDefBut(block, TEX,B_REDR,"S:", 10, yco, 90, 20, scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with"); - uiDefBut(block, TEX,B_REDR,"N:", 100, yco, 90, 20, scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with"); - uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_NOP, ICON_AUTO,190,yco,20,20, &scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming"); - yco -= 20; - - /* auto renaming magic */ - uiBlockEndAlign(block); - - nb_joints = BIF_nbJointsTemplate(C); - - if (nb_joints == -1) - { - //XXX - //nb_joints = G.totvertsel; - } - - bone_name = BIF_nameBoneTemplate(C); - - BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name); - - uiDefBut(block, LABEL, 1, joint_label, 10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, ""); - yco -= 20; - break; + //XXX + //nb_joints = G.totvertsel; } - - uiBlockEndAlign(block); - uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_NOP, "Peel Objects", 10, yco, 200, 20, &scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one"); - - if(yco < 0) uiNewPanelHeight(block, height-yco); + bone_name = BIF_nameBoneTemplate(C); + + BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name); + + uiDefBut(block, LABEL, 1, joint_label, 10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, ""); + yco -= 20; + break; } + + uiBlockEndAlign(block); + + uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_NOP, "Peel Objects", 10, yco, 200, 20, &scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one"); } @@ -1719,16 +1680,14 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2) } } -static void view3d_panel_operator_redo(const bContext *C, ARegion *ar, short cntrl) +static void view3d_panel_operator_redo(const bContext *C, Panel *pa) { wmWindowManager *wm= CTX_wm_manager(C); wmOperator *op; PointerRNA ptr; uiBlock *block; - int height = 0; - block= uiBeginBlock(C, ar, "view3d_panel_operator_redo", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Last Operator", "View3d", 340, 10, 318, height)==0) return; + block= uiLayoutBlock(pa->layout); /* only for operators that are registered and did an undo push */ for(op= wm->operators.last; op; op= op->prev) @@ -1746,36 +1705,66 @@ static void view3d_panel_operator_redo(const bContext *C, ARegion *ar, short cnt } RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - height= uiDefAutoButsRNA(C, block, &ptr); - - uiNewPanelHeight(block, height); - - uiEndBlock(C, block); + uiDefAutoButsRNA(C, pa->layout, &ptr); } - -void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar) +void view3d_buttons_register(ARegionType *art) { - uiBeginPanels(C, ar); - - view3d_panel_object(C, ar, 0); - view3d_panel_properties(C, ar, 0); - view3d_panel_background(C, ar, 0); - if(G.f & (G_SCULPTMODE|G_TEXTUREPAINT|G_VERTEXPAINT|G_WEIGHTPAINT)) - view3d_panel_brush(C, ar, 0); + PanelType *pt; + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel object"); + strcpy(pt->idname, "VIEW3D_PT_object"); + strcpy(pt->label, "Transform Properties"); + pt->draw= view3d_panel_object; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel properties"); + strcpy(pt->idname, "VIEW3D_PT_properties"); + strcpy(pt->label, "View Properties"); + pt->draw= view3d_panel_properties; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel background"); + strcpy(pt->idname, "VIEW3D_PT_background"); + strcpy(pt->label, "Background Image"); + pt->draw= view3d_panel_background; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel brush"); + strcpy(pt->idname, "VIEW3D_PT_brush"); + strcpy(pt->label, "Brush"); + pt->draw= view3d_panel_brush; + pt->poll= view3d_panel_brush_poll; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel transform spaces"); + strcpy(pt->idname, "VIEW3D_PT_transform spaces"); + strcpy(pt->label, "Transform Orientations"); + pt->draw= view3d_panel_transform_spaces; + BLI_addtail(&art->paneltypes, pt); + + /*pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil"); + strcpy(pt->idname, "VIEW3D_PT_gpencil"); + strcpy(pt->label, "Greas Pencil"); + pt->draw= view3d_panel_gpencil; + BLI_addtail(&art->paneltypes, pt);*/ + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces"); + strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces"); + strcpy(pt->label, "Bone Sketching"); + pt->draw= view3d_panel_bonesketch_spaces; + pt->poll= view3d_panel_bonesketch_spaces_poll; + BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo"); + strcpy(pt->idname, "VIEW3D_PT_redo"); + strcpy(pt->label, "Last Operator"); + pt->draw= view3d_panel_operator_redo; + BLI_addtail(&art->paneltypes, pt); + // XXX view3d_panel_preview(C, ar, 0); - view3d_panel_transform_spaces(C, ar, 0); - if(0) - view3d_panel_gpencil(C, ar, 0); - - view3d_panel_bonesketch_spaces(C, ar, 0); - - view3d_panel_operator_redo(C, ar, 0); - - uiEndPanels(C, ar); } - static int view3d_properties(bContext *C, wmOperator *op) { ScrArea *sa= CTX_wm_area(C); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 2fd453c9ff7..da201195288 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -3359,7 +3359,7 @@ static void view3d_edit_curvemenu(bContext *C, uiLayout *layout, void *arg_unuse uiItemS(layout); - uiItemR(layout, NULL, 0, &sceneptr, "proportional_editing", 0); // |O + uiItemR(layout, NULL, 0, &sceneptr, "proportional_editing", 0, 0); // |O uiItemMenuEnumR(layout, NULL, 0, &sceneptr, "proportional_editing_falloff"); uiItemS(layout); @@ -4533,12 +4533,12 @@ static void view3d_sculpt_menu(bContext *C, uiLayout *layout, void *arg_unused) RNA_pointer_create(&sc->id, &RNA_Sculpt, s, &rna); - uiItemR(layout, NULL, 0, &rna, "symmetry_x", 0); - uiItemR(layout, NULL, 0, &rna, "symmetry_y", 0); - uiItemR(layout, NULL, 0, &rna, "symmetry_z", 0); - uiItemR(layout, NULL, 0, &rna, "lock_x", 0); - uiItemR(layout, NULL, 0, &rna, "lock_y", 0); - uiItemR(layout, NULL, 0, &rna, "lock_z", 0); + uiItemR(layout, NULL, 0, &rna, "symmetry_x", 0, 0); + uiItemR(layout, NULL, 0, &rna, "symmetry_y", 0, 0); + uiItemR(layout, NULL, 0, &rna, "symmetry_z", 0, 0); + uiItemR(layout, NULL, 0, &rna, "lock_x", 0, 0); + uiItemR(layout, NULL, 0, &rna, "lock_y", 0, 0); + uiItemR(layout, NULL, 0, &rna, "lock_z", 0, 0); /* Brush settings */ RNA_pointer_create(&sc->id, &RNA_Brush, s->brush, &rna); @@ -4551,12 +4551,12 @@ static void view3d_sculpt_menu(bContext *C, uiLayout *layout, void *arg_unused) uiItemS(layout); - uiItemR(layout, NULL, 0, &rna, "airbrush", 0); - uiItemR(layout, NULL, 0, &rna, "rake", 0); - uiItemR(layout, NULL, 0, &rna, "anchored", 0); - uiItemR(layout, NULL, 0, &rna, "space", 0); + uiItemR(layout, NULL, 0, &rna, "airbrush", 0, 0); + uiItemR(layout, NULL, 0, &rna, "rake", 0, 0); + uiItemR(layout, NULL, 0, &rna, "anchored", 0, 0); + uiItemR(layout, NULL, 0, &rna, "space", 0, 0); - uiItemR(layout, NULL, 0, &rna, "flip_direction", 0); + uiItemR(layout, NULL, 0, &rna, "flip_direction", 0, 0); } uiBlock *view3d_sculptmenu(bContext *C, ARegion *ar, void *arg_unused) diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 9f162c5327b..ab705cb32fb 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -42,6 +42,7 @@ struct bContext; struct wmWindowManager; struct EditMesh; struct ViewContext; +struct ARegionType; #define BL_NEAR_CLIP 0.001 @@ -131,11 +132,11 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d); /* view3d_buttons.c */ void VIEW3D_OT_properties(struct wmOperatorType *ot); -void view3d_buttons_area_defbuts(const struct bContext *C, ARegion *ar); +void view3d_buttons_register(struct ARegionType *art); /* view3d_buttons.c */ void VIEW3D_OT_toolbar(struct wmOperatorType *ot); -void view3d_tools_area_defbuts(const struct bContext *C, ARegion *ar); +void view3d_toolbar_register(struct ARegionType *art); /* view3d_snap.c */ int minmax_verts(Object *obedit, float *min, float *max); diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 9f16e124f77..c7cd5a92ebf 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -118,18 +118,16 @@ static void redo_cb(bContext *C, void *arg_op, void *arg2) } } -static void view3d_panel_operator_redo(const bContext *C, ARegion *ar, short cntrl) +static void view3d_panel_operator_redo(const bContext *C, Panel *pa) { /* XXX temp */ - extern int uiDefAutoButsRNA_single(const bContext *C, uiBlock *block, PointerRNA *ptr); + extern void uiDefAutoButsRNA_single(const bContext *C, uiLayout *layout, PointerRNA *ptr); wmWindowManager *wm= CTX_wm_manager(C); wmOperator *op; PointerRNA ptr; uiBlock *block; - int height = 0; - block= uiBeginBlock(C, ar, "view3d_panel_operator_redo", UI_EMBOSS); - if(uiNewPanel(C, ar, block, "Operator", "View3d", 0, 10, 120, height)==0) return; + block= uiLayoutBlock(pa->layout); /* only for operators that are registered and did an undo push */ for(op= wm->operators.last; op; op= op->prev) @@ -149,23 +147,19 @@ static void view3d_panel_operator_redo(const bContext *C, ARegion *ar, short cnt } RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - height= uiDefAutoButsRNA_single(C, block, &ptr); - - uiNewPanelHeight(block, height); - - uiEndBlock(C, block); + uiDefAutoButsRNA_single(C, pa->layout, &ptr); } - -void view3d_tools_area_defbuts(const bContext *C, ARegion *ar) +void view3d_toolbar_register(ARegionType *art) { - uiBeginPanels(C, ar); - - view3d_panel_operator_redo(C, ar, 0); - - uiEndPanels(C, ar); -} + PanelType *pt; + pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel last operator"); + strcpy(pt->idname, "VIEW3D_PT_last_operator"); + strcpy(pt->label, "Last Operator"); + pt->draw= view3d_panel_operator_redo; + BLI_addtail(&art->paneltypes, pt); +} static int view3d_toolbar(bContext *C, wmOperator *op) { diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 7a6e48f2ca9..4a39744c1dc 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -91,8 +91,8 @@ typedef struct ScrEdge { typedef struct Panel { /* the part from uiBlock that needs saved in file */ struct Panel *next, *prev; - struct PanelType *type; /* runtime */ - struct uiLayout *layout; /* runtime for drawing */ + struct PanelType *type; /* runtime */ + struct uiLayout *layout; /* runtime for drawing */ char panelname[64], tabname[64]; /* defined as UI_MAX_NAME_STR */ char drawname[64]; /* panelname is identifier for restoring location */ diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index cfe1778db41..6698335e1cb 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -63,15 +63,21 @@ void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr) void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr) { PointerRNA tmp; - StructRNA *idtype= NULL; + StructRNA *type, *idtype= NULL; if(id) { memset(&tmp, 0, sizeof(tmp)); tmp.data= id; idtype= rna_ID_refine(&tmp); - if(idtype->refine) - idtype= idtype->refine(&tmp); + while(idtype->refine) { + type= idtype->refine(&tmp); + + if(type == idtype) + break; + else + idtype= type; + } } r_ptr->id.data= id; @@ -121,8 +127,14 @@ PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *da result.type= type; rna_pointer_inherit_id(type, ptr, &result); - if(type->refine) - result.type= type->refine(&result); + while(result.type->refine) { + type= result.type->refine(&result); + + if(type == result.type) + break; + else + result.type= type; + } } else memset(&result, 0, sizeof(result)); diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 405ae9a0f74..a3e48f629cb 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -111,6 +111,22 @@ static void panel_draw(const bContext *C, Panel *pnl) RNA_parameter_list_free(list); } +static void panel_draw_header(const bContext *C, Panel *pnl) +{ + PointerRNA ptr; + ParameterList *list; + FunctionRNA *func; + + RNA_pointer_create(&CTX_wm_screen(C)->id, pnl->type->py_srna, pnl, &ptr); + func= RNA_struct_find_function(&ptr, "draw_header"); + + list= RNA_parameter_list_create(&ptr, func); + RNA_parameter_set_lookup(list, "context", &C); + pnl->type->py_call(&ptr, func, list); + + RNA_parameter_list_free(list); +} + static void rna_Panel_unregister(const bContext *C, StructRNA *type) { ARegionType *art; @@ -169,6 +185,7 @@ static StructRNA *rna_Panel_register(const bContext *C, ReportList *reports, voi pt->poll= (have_function[0])? panel_poll: NULL; pt->draw= (have_function[1])? panel_draw: NULL; + pt->draw_header= (have_function[2])? panel_draw_header: NULL; BLI_addtail(&art->paneltypes, pt); @@ -429,6 +446,11 @@ static void rna_def_panel(BlenderRNA *brna) RNA_def_function_flag(func, FUNC_REGISTER); RNA_def_pointer(func, "context", "Context", "", ""); + func= RNA_def_function(srna, "draw_header", NULL); + RNA_def_function_ui_description(func, "Draw buttons into the panel header UI layout."); + RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_pointer(func, "context", "Context", "", ""); + prop= RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "UILayout"); diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c index 471263d9d63..0f2142f4b62 100644 --- a/source/blender/python/intern/bpy_ui.c +++ b/source/blender/python/intern/bpy_ui.c @@ -179,32 +179,6 @@ static PyObject *Method_drawBlock( PyObject * self, PyObject * args ) Py_RETURN_NONE; } -static PyObject *Method_beginPanels( PyObject * self, PyObject * args ) -{ - bContext *C; - PyObject *py_context; - - if( !PyArg_ParseTuple( args, "O!i:beginPanels", &PyCObject_Type, &py_context) ) - return NULL; - - C= PyCObject_AsVoidPtr(py_context); - uiBeginPanels(C, CTX_wm_region(C)); - Py_RETURN_NONE; -} - -static PyObject *Method_endPanels( PyObject * self, PyObject * args ) -{ - bContext *C; - PyObject *py_context; - - if( !PyArg_ParseTuple( args, "O!:endPanels", &PyCObject_Type, &py_context) ) - return NULL; - - C= PyCObject_AsVoidPtr(py_context); - uiEndPanels(C, CTX_wm_region(C)); - Py_RETURN_NONE; -} - static PyObject *Method_popupBoundsBlock( PyObject * self, PyObject * args ) { PyObject *py_block; @@ -251,18 +225,6 @@ static PyObject *Method_blockSetFlag( PyObject * self, PyObject * args ) Py_RETURN_NONE; } -static PyObject *Method_newPanel( PyObject * self, PyObject * args ) -{ - PyObject *py_context, *py_area, *py_block; - char *panelname, *tabname; - int ofsx, ofsy, sizex, sizey; - - if( !PyArg_ParseTuple( args, "O!O!O!ssiiii:newPanel", &PyCObject_Type, &py_context, &PyCObject_Type, &py_area, &PyCObject_Type, &py_block, &panelname, &tabname, &ofsx, &ofsy, &sizex, &sizey)) - return NULL; - - return PyLong_FromSsize_t(uiNewPanel(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_area), PyCObject_AsVoidPtr(py_block), panelname, tabname, ofsx, ofsy, sizex, sizey)); -} - /* similar to Draw.c */ static PyObject *Method_register( PyObject * self, PyObject * args ) { @@ -402,9 +364,6 @@ static struct PyMethodDef ui_methods[] = { {"blockBeginAlign", (PyCFunction)Method_blockBeginAlign, METH_VARARGS, ""}, {"blockEndAlign", (PyCFunction)Method_blockEndAlign, METH_VARARGS, ""}, {"blockSetFlag", (PyCFunction)Method_blockSetFlag, METH_VARARGS, ""}, - {"newPanel", (PyCFunction)Method_newPanel, METH_VARARGS, ""}, - {"beginPanels", (PyCFunction)Method_beginPanels, METH_VARARGS, ""}, - {"endPanels", (PyCFunction)Method_endPanels, METH_VARARGS, ""}, {"register", (PyCFunction)Method_register, METH_VARARGS, ""}, // XXX not sure about this - registers current script with the ScriptSpace, like Draw.Register() {"registerKey", (PyCFunction)Method_registerKey, METH_VARARGS, ""}, // XXX could have this in another place too diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 34baf672d5e..9c0fc4d8e9e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -276,7 +276,8 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) wmOperator *op= arg_op; PointerRNA ptr; uiBlock *block; - int height; + uiLayout *layout; + uiStyle *style= U.uistyles.first; block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); @@ -289,7 +290,8 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) } RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr); - height= uiDefAutoButsRNA(C, block, &ptr); + layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 300, 20, style); + uiDefAutoButsRNA(C, layout, &ptr); uiPopupBoundsBlock(block, 4.0f, 0, 0); uiEndBlock(C, block); -- cgit v1.2.3