Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/interface/interface.c
| Show First 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "BPY_extern.h" | #include "BPY_extern.h" | ||||
| #include "IMB_colormanagement.h" | #include "IMB_colormanagement.h" | ||||
| #include "interface_intern.h" | #include "interface_intern.h" | ||||
| /* avoid unneeded calls to ui_get_but_val */ | /* avoid unneeded calls to ui_but_value_get */ | ||||
| #define UI_BUT_VALUE_UNSET DBL_MAX | #define UI_BUT_VALUE_UNSET DBL_MAX | ||||
| #define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) { (_value) = ui_get_but_val(_but); } (void)0 | #define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) { (_value) = ui_but_value_get(_but); } (void)0 | ||||
| #define B_NOP -1 | #define B_NOP -1 | ||||
| /* | /* | ||||
| * a full doc with API notes can be found in bf-blender/trunk/blender/doc/guides/interface_API.txt | * a full doc with API notes can be found in bf-blender/trunk/blender/doc/guides/interface_API.txt | ||||
| * | * | ||||
| * uiBlahBlah() external function | * uiBlahBlah() external function | ||||
| * ui_blah_blah() internal function | * ui_blah_blah() internal function | ||||
| */ | */ | ||||
| static void ui_free_but(const bContext *C, uiBut *but); | static void ui_but_free(const bContext *C, uiBut *but); | ||||
| bool ui_block_is_menu(const uiBlock *block) | bool ui_block_is_menu(const uiBlock *block) | ||||
| { | { | ||||
| return (((block->flag & UI_BLOCK_LOOP) != 0) && | return (((block->flag & UI_BLOCK_LOOP) != 0) && | ||||
| /* non-menu popups use keep-open, so check this is off */ | /* non-menu popups use keep-open, so check this is off */ | ||||
| ((block->flag & UI_BLOCK_KEEP_OPEN) == 0)); | ((block->flag & UI_BLOCK_KEEP_OPEN) == 0)); | ||||
| } | } | ||||
| bool ui_block_is_pie_menu(const uiBlock *block) | bool ui_block_is_pie_menu(const uiBlock *block) | ||||
| { | { | ||||
| return ((block->flag & UI_BLOCK_RADIAL) != 0); | return ((block->flag & UI_BLOCK_RADIAL) != 0); | ||||
| } | } | ||||
| static bool ui_is_but_unit_radians_ex(UnitSettings *unit, const int unit_type) | static bool ui_but_is_unit_radians_ex(UnitSettings *unit, const int unit_type) | ||||
| { | { | ||||
| return (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION); | return (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION); | ||||
| } | } | ||||
| static bool ui_is_but_unit_radians(const uiBut *but) | static bool ui_but_is_unit_radians(const uiBut *but) | ||||
| { | { | ||||
| UnitSettings *unit = but->block->unit; | UnitSettings *unit = but->block->unit; | ||||
| const int unit_type = uiButGetUnitType(but); | const int unit_type = UI_but_unit_type_get(but); | ||||
| return ui_is_but_unit_radians_ex(unit, unit_type); | return ui_but_is_unit_radians_ex(unit, unit_type); | ||||
| } | } | ||||
| /* ************* window matrix ************** */ | /* ************* window matrix ************** */ | ||||
| void ui_block_to_window_fl(const ARegion *ar, uiBlock *block, float *x, float *y) | void ui_block_to_window_fl(const ARegion *ar, uiBlock *block, float *x, float *y) | ||||
| { | { | ||||
| float gx, gy; | float gx, gy; | ||||
| int sx, sy, getsizex, getsizey; | int sx, sy, getsizex, getsizey; | ||||
| ▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | void ui_block_translate(uiBlock *block, int x, int y) | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| BLI_rctf_translate(&but->rect, x, y); | BLI_rctf_translate(&but->rect, x, y); | ||||
| } | } | ||||
| BLI_rctf_translate(&block->rect, x, y); | BLI_rctf_translate(&block->rect, x, y); | ||||
| } | } | ||||
| static void ui_text_bounds_block(uiBlock *block, float offset) | static void ui_block_bounds_calc_text(uiBlock *block, float offset) | ||||
| { | { | ||||
| uiStyle *style = UI_GetStyle(); | uiStyle *style = UI_style_get(); | ||||
| uiBut *bt, *init_col_bt, *col_bt; | uiBut *bt, *init_col_bt, *col_bt; | ||||
| int i = 0, j, x1addval = offset; | int i = 0, j, x1addval = offset; | ||||
| uiStyleFontSet(&style->widget); | UI_fontstyle_set(&style->widget); | ||||
| for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) { | for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) { | ||||
| if (!ELEM(bt->type, SEPR, SEPRLINE)) { | if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) { | ||||
| j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr)); | j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr)); | ||||
| if (j > i) | if (j > i) | ||||
| i = j; | i = j; | ||||
| } | } | ||||
| if (bt->next && bt->rect.xmin < bt->next->rect.xmin) { | if (bt->next && bt->rect.xmin < bt->next->rect.xmin) { | ||||
| /* End of this column, and it’s not the last one. */ | /* End of this column, and it’s not the last one. */ | ||||
| for (col_bt = init_col_bt; col_bt->prev != bt; col_bt = col_bt->next) { | for (col_bt = init_col_bt; col_bt->prev != bt; col_bt = col_bt->next) { | ||||
| col_bt->rect.xmin = x1addval; | col_bt->rect.xmin = x1addval; | ||||
| col_bt->rect.xmax = x1addval + i + block->bounds; | col_bt->rect.xmax = x1addval + i + block->bounds; | ||||
| ui_check_but(col_bt); /* clips text again */ | ui_but_update(col_bt); /* clips text again */ | ||||
| } | } | ||||
| /* And we prepare next column. */ | /* And we prepare next column. */ | ||||
| x1addval += i + block->bounds; | x1addval += i + block->bounds; | ||||
| i = 0; | i = 0; | ||||
| init_col_bt = col_bt; | init_col_bt = col_bt; | ||||
| } | } | ||||
| } | } | ||||
| /* Last column. */ | /* Last column. */ | ||||
| for (col_bt = init_col_bt; col_bt; col_bt = col_bt->next) { | for (col_bt = init_col_bt; col_bt; col_bt = col_bt->next) { | ||||
| col_bt->rect.xmin = x1addval; | col_bt->rect.xmin = x1addval; | ||||
| col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds); | col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds); | ||||
| ui_check_but(col_bt); /* clips text again */ | ui_but_update(col_bt); /* clips text again */ | ||||
| } | } | ||||
| } | } | ||||
| void ui_bounds_block(uiBlock *block) | void ui_block_bounds_calc(uiBlock *block) | ||||
| { | { | ||||
| uiBut *bt; | uiBut *bt; | ||||
| int xof; | int xof; | ||||
| if (BLI_listbase_is_empty(&block->buttons)) { | if (BLI_listbase_is_empty(&block->buttons)) { | ||||
| if (block->panel) { | if (block->panel) { | ||||
| block->rect.xmin = 0.0; block->rect.xmax = block->panel->sizex; | block->rect.xmin = 0.0; block->rect.xmax = block->panel->sizex; | ||||
| block->rect.ymin = 0.0; block->rect.ymax = block->panel->sizey; | block->rect.ymin = 0.0; block->rect.ymax = block->panel->sizey; | ||||
| Show All 21 Lines | void ui_block_bounds_calc(uiBlock *block) | ||||
| else xof = 40; | else xof = 40; | ||||
| block->safety.xmin = block->rect.xmin - xof; | block->safety.xmin = block->rect.xmin - xof; | ||||
| block->safety.ymin = block->rect.ymin - xof; | block->safety.ymin = block->rect.ymin - xof; | ||||
| block->safety.xmax = block->rect.xmax + xof; | block->safety.xmax = block->rect.xmax + xof; | ||||
| block->safety.ymax = block->rect.ymax + xof; | block->safety.ymax = block->rect.ymax + xof; | ||||
| } | } | ||||
| static void ui_centered_bounds_block(wmWindow *window, uiBlock *block) | static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block) | ||||
| { | { | ||||
| int xmax, ymax; | int xmax, ymax; | ||||
| int startx, starty; | int startx, starty; | ||||
| int width, height; | int width, height; | ||||
| /* note: this is used for the splash where window bounds event has not been | /* note: this is used for the splash where window bounds event has not been | ||||
| * updated by ghost, get the window bounds from ghost directly */ | * updated by ghost, get the window bounds from ghost directly */ | ||||
| xmax = WM_window_pixels_x(window); | xmax = WM_window_pixels_x(window); | ||||
| ymax = WM_window_pixels_y(window); | ymax = WM_window_pixels_y(window); | ||||
| ui_bounds_block(block); | ui_block_bounds_calc(block); | ||||
| width = BLI_rctf_size_x(&block->rect); | width = BLI_rctf_size_x(&block->rect); | ||||
| height = BLI_rctf_size_y(&block->rect); | height = BLI_rctf_size_y(&block->rect); | ||||
| startx = (xmax * 0.5f) - (width * 0.5f); | startx = (xmax * 0.5f) - (width * 0.5f); | ||||
| starty = (ymax * 0.5f) - (height * 0.5f); | starty = (ymax * 0.5f) - (height * 0.5f); | ||||
| ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin); | ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin); | ||||
| /* now recompute bounds and safety */ | /* now recompute bounds and safety */ | ||||
| ui_bounds_block(block); | ui_block_bounds_calc(block); | ||||
| } | } | ||||
| static void ui_centered_pie_bounds_block(uiBlock *block) | static void ui_block_bounds_calc_centered_pie(uiBlock *block) | ||||
| { | { | ||||
| const int xy[2] = { | const int xy[2] = { | ||||
| block->pie_data.pie_center_spawned[0], | block->pie_data.pie_center_spawned[0], | ||||
| block->pie_data.pie_center_spawned[1] | block->pie_data.pie_center_spawned[1] | ||||
| }; | }; | ||||
| ui_block_translate(block, xy[0], xy[1]); | ui_block_translate(block, xy[0], xy[1]); | ||||
| /* now recompute bounds and safety */ | /* now recompute bounds and safety */ | ||||
| ui_bounds_block(block); | ui_block_bounds_calc(block); | ||||
| } | } | ||||
| static void ui_popup_bounds_block(wmWindow *window, uiBlock *block, | static void ui_block_bounds_calc_popup( | ||||
| wmWindow *window, uiBlock *block, | |||||
| eBlockBoundsCalc bounds_calc, const int xy[2]) | eBlockBoundsCalc bounds_calc, const int xy[2]) | ||||
| { | { | ||||
| int startx, starty, endx, endy, width, height, oldwidth, oldheight; | int startx, starty, endx, endy, width, height, oldwidth, oldheight; | ||||
| int oldbounds, xmax, ymax; | int oldbounds, xmax, ymax; | ||||
| const int margin = UI_SCREEN_MARGIN; | const int margin = UI_SCREEN_MARGIN; | ||||
| oldbounds = block->bounds; | oldbounds = block->bounds; | ||||
| /* compute mouse position with user defined offset */ | /* compute mouse position with user defined offset */ | ||||
| ui_bounds_block(block); | ui_block_bounds_calc(block); | ||||
| xmax = WM_window_pixels_x(window); | xmax = WM_window_pixels_x(window); | ||||
| ymax = WM_window_pixels_y(window); | ymax = WM_window_pixels_y(window); | ||||
| oldwidth = BLI_rctf_size_x(&block->rect); | oldwidth = BLI_rctf_size_x(&block->rect); | ||||
| oldheight = BLI_rctf_size_y(&block->rect); | oldheight = BLI_rctf_size_y(&block->rect); | ||||
| /* first we ensure wide enough text bounds */ | /* first we ensure wide enough text bounds */ | ||||
| if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) { | if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) { | ||||
| if (block->flag & UI_BLOCK_LOOP) { | if (block->flag & UI_BLOCK_LOOP) { | ||||
| block->bounds = 2.5f * UI_UNIT_X; | block->bounds = 2.5f * UI_UNIT_X; | ||||
| ui_text_bounds_block(block, block->rect.xmin); | ui_block_bounds_calc_text(block, block->rect.xmin); | ||||
| } | } | ||||
| } | } | ||||
| /* next we recompute bounds */ | /* next we recompute bounds */ | ||||
| block->bounds = oldbounds; | block->bounds = oldbounds; | ||||
| ui_bounds_block(block); | ui_block_bounds_calc(block); | ||||
| /* and we adjust the position to fit within window */ | /* and we adjust the position to fit within window */ | ||||
| width = BLI_rctf_size_x(&block->rect); | width = BLI_rctf_size_x(&block->rect); | ||||
| height = BLI_rctf_size_y(&block->rect); | height = BLI_rctf_size_y(&block->rect); | ||||
| /* avoid divide by zero below, caused by calling with no UI, but better not crash */ | /* avoid divide by zero below, caused by calling with no UI, but better not crash */ | ||||
| oldwidth = oldwidth > 0 ? oldwidth : MAX2(1, width); | oldwidth = oldwidth > 0 ? oldwidth : MAX2(1, width); | ||||
| oldheight = oldheight > 0 ? oldheight : MAX2(1, height); | oldheight = oldheight > 0 ? oldheight : MAX2(1, height); | ||||
| /* offset block based on mouse position, user offset is scaled | /* offset block based on mouse position, user offset is scaled | ||||
| * along in case we resized the block in ui_text_bounds_block */ | * along in case we resized the block in ui_block_bounds_calc_text */ | ||||
| startx = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth; | startx = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth; | ||||
| starty = xy[1] + block->rect.ymin + (block->my * height) / oldheight; | starty = xy[1] + block->rect.ymin + (block->my * height) / oldheight; | ||||
| if (startx < margin) | if (startx < margin) | ||||
| startx = margin; | startx = margin; | ||||
| if (starty < margin) | if (starty < margin) | ||||
| starty = margin; | starty = margin; | ||||
| endx = startx + width; | endx = startx + width; | ||||
| endy = starty + height; | endy = starty + height; | ||||
| if (endx > xmax) { | if (endx > xmax) { | ||||
| endx = xmax - margin; | endx = xmax - margin; | ||||
| startx = endx - width; | startx = endx - width; | ||||
| } | } | ||||
| if (endy > ymax - margin) { | if (endy > ymax - margin) { | ||||
| endy = ymax - margin; | endy = ymax - margin; | ||||
| starty = endy - height; | starty = endy - height; | ||||
| } | } | ||||
| ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin); | ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin); | ||||
| /* now recompute bounds and safety */ | /* now recompute bounds and safety */ | ||||
| ui_bounds_block(block); | ui_block_bounds_calc(block); | ||||
| } | } | ||||
| /* used for various cases */ | /* used for various cases */ | ||||
| void uiBoundsBlock(uiBlock *block, int addval) | void UI_block_bounds_set_normal(uiBlock *block, int addval) | ||||
| { | { | ||||
| if (block == NULL) | if (block == NULL) | ||||
| return; | return; | ||||
| block->bounds = addval; | block->bounds = addval; | ||||
| block->bounds_type = UI_BLOCK_BOUNDS; | block->bounds_type = UI_BLOCK_BOUNDS; | ||||
| } | } | ||||
| /* used for pulldowns */ | /* used for pulldowns */ | ||||
| void uiTextBoundsBlock(uiBlock *block, int addval) | void UI_block_bounds_set_text(uiBlock *block, int addval) | ||||
| { | { | ||||
| block->bounds = addval; | block->bounds = addval; | ||||
| block->bounds_type = UI_BLOCK_BOUNDS_TEXT; | block->bounds_type = UI_BLOCK_BOUNDS_TEXT; | ||||
| } | } | ||||
| /* used for block popups */ | /* used for block popups */ | ||||
| void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my) | void UI_block_bounds_set_popup(uiBlock *block, int addval, int mx, int my) | ||||
| { | { | ||||
| block->bounds = addval; | block->bounds = addval; | ||||
| block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MOUSE; | block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MOUSE; | ||||
| block->mx = mx; | block->mx = mx; | ||||
| block->my = my; | block->my = my; | ||||
| } | } | ||||
| /* used for menu popups */ | /* used for menu popups */ | ||||
| void uiMenuPopupBoundsBlock(uiBlock *block, int addval, int mx, int my) | void UI_block_bounds_set_menu(uiBlock *block, int addval, int mx, int my) | ||||
| { | { | ||||
| block->bounds = addval; | block->bounds = addval; | ||||
| block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MENU; | block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MENU; | ||||
| block->mx = mx; | block->mx = mx; | ||||
| block->my = my; | block->my = my; | ||||
| } | } | ||||
| /* used for centered popups, i.e. splash */ | /* used for centered popups, i.e. splash */ | ||||
| void uiCenteredBoundsBlock(uiBlock *block, int addval) | void UI_block_bounds_set_centered(uiBlock *block, int addval) | ||||
| { | { | ||||
| block->bounds = addval; | block->bounds = addval; | ||||
| block->bounds_type = UI_BLOCK_BOUNDS_POPUP_CENTER; | block->bounds_type = UI_BLOCK_BOUNDS_POPUP_CENTER; | ||||
| } | } | ||||
| void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int maxy) | void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy) | ||||
| { | { | ||||
| block->rect.xmin = minx; | block->rect.xmin = minx; | ||||
| block->rect.ymin = miny; | block->rect.ymin = miny; | ||||
| block->rect.xmax = maxx; | block->rect.xmax = maxx; | ||||
| block->rect.ymax = maxy; | block->rect.ymax = maxy; | ||||
| block->bounds_type = UI_BLOCK_BOUNDS_NONE; | block->bounds_type = UI_BLOCK_BOUNDS_NONE; | ||||
| } | } | ||||
| static int ui_but_float_precision(uiBut *but, double value) | static int ui_but_calc_float_precision(uiBut *but, double value) | ||||
| { | { | ||||
| int prec = (int)but->a2; | int prec = (int)but->a2; | ||||
| /* first check for various special cases: | /* first check for various special cases: | ||||
| * * If button is radians, we want additional precision (see T39861). | * * If button is radians, we want additional precision (see T39861). | ||||
| * * If prec is not set, we fallback to a simple default */ | * * If prec is not set, we fallback to a simple default */ | ||||
| if (ui_is_but_unit_radians(but) && prec < 5) { | if (ui_but_is_unit_radians(but) && prec < 5) { | ||||
| prec = 5; | prec = 5; | ||||
| } | } | ||||
| else if (prec == -1) { | else if (prec == -1) { | ||||
| prec = (but->hardmax < 10.001f) ? 3 : 2; | prec = (but->hardmax < 10.001f) ? 3 : 2; | ||||
| } | } | ||||
| return uiFloatPrecisionCalc(prec, value); | return UI_calc_float_precision(prec, value); | ||||
| } | } | ||||
| /* ************** LINK LINE DRAWING ************* */ | /* ************** LINK LINE DRAWING ************* */ | ||||
| /* link line drawing is not part of buttons or theme.. so we stick with it here */ | /* link line drawing is not part of buttons or theme.. so we stick with it here */ | ||||
| static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines, int dashInactiveLines) | static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines, int dashInactiveLines) | ||||
| { | { | ||||
| Show All 25 Lines | static void ui_draw_links(uiBlock *block) | ||||
| /* Draw the grey out lines. Do this first so they appear at the | /* Draw the grey out lines. Do this first so they appear at the | ||||
| * bottom of inactive or active lines. | * bottom of inactive or active lines. | ||||
| * As we go, remember if we see any active or selected lines. */ | * As we go, remember if we see any active or selected lines. */ | ||||
| bool found_selectline = false; | bool found_selectline = false; | ||||
| bool found_activeline = false; | bool found_activeline = false; | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| if (but->type == LINK && but->link) { | if (but->type == UI_BTYPE_LINK && but->link) { | ||||
| for (line = but->link->lines.first; line; line = line->next) { | for (line = but->link->lines.first; line; line = line->next) { | ||||
| if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) { | if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) { | ||||
| if (line->deactive) | if (line->deactive) | ||||
| ui_draw_linkline(line, 0, true); | ui_draw_linkline(line, 0, true); | ||||
| } | } | ||||
| else | else | ||||
| found_activeline = true; | found_activeline = true; | ||||
| if ((line->from->flag & UI_SELECT) || (line->to->flag & UI_SELECT)) | if ((line->from->flag & UI_SELECT) || (line->to->flag & UI_SELECT)) | ||||
| found_selectline = true; | found_selectline = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Draw the inactive lines (lines with neither button being hovered over) */ | /* Draw the inactive lines (lines with neither button being hovered over) */ | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| if (but->type == LINK && but->link) { | if (but->type == UI_BTYPE_LINK && but->link) { | ||||
| for (line = but->link->lines.first; line; line = line->next) { | for (line = but->link->lines.first; line; line = line->next) { | ||||
| if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) { | if (!(line->from->flag & UI_ACTIVE) && !(line->to->flag & UI_ACTIVE)) { | ||||
| if (!line->deactive) | if (!line->deactive) | ||||
| ui_draw_linkline(line, 0, false); | ui_draw_linkline(line, 0, false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Draw any active lines (lines with either button being hovered over). | /* Draw any active lines (lines with either button being hovered over). | ||||
| * Do this last so they appear on top of inactive and grey out lines. */ | * Do this last so they appear on top of inactive and grey out lines. */ | ||||
| if (found_activeline) { | if (found_activeline) { | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| if (but->type == LINK && but->link) { | if (but->type == UI_BTYPE_LINK && but->link) { | ||||
| for (line = but->link->lines.first; line; line = line->next) { | for (line = but->link->lines.first; line; line = line->next) { | ||||
| if ((line->from->flag & UI_ACTIVE) || (line->to->flag & UI_ACTIVE)) | if ((line->from->flag & UI_ACTIVE) || (line->to->flag & UI_ACTIVE)) | ||||
| ui_draw_linkline(line, !found_selectline, false); | ui_draw_linkline(line, !found_selectline, false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* oldbut is being inserted in new block, so we use the lines from new button, and replace button pointers */ | /* oldbut is being inserted in new block, so we use the lines from new button, and replace button pointers */ | ||||
| static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut) | static void ui_but_update_linklines(uiBlock *block, uiBut *oldbut, uiBut *newbut) | ||||
| { | { | ||||
| uiLinkLine *line; | uiLinkLine *line; | ||||
| uiBut *but; | uiBut *but; | ||||
| /* if active button is LINK */ | /* if active button is UI_BTYPE_LINK */ | ||||
| if (newbut->type == LINK && newbut->link) { | if (newbut->type == UI_BTYPE_LINK && newbut->link) { | ||||
| SWAP(uiLink *, oldbut->link, newbut->link); | SWAP(uiLink *, oldbut->link, newbut->link); | ||||
| for (line = oldbut->link->lines.first; line; line = line->next) { | for (line = oldbut->link->lines.first; line; line = line->next) { | ||||
| if (line->to == newbut) | if (line->to == newbut) | ||||
| line->to = oldbut; | line->to = oldbut; | ||||
| if (line->from == newbut) | if (line->from == newbut) | ||||
| line->from = oldbut; | line->from = oldbut; | ||||
| } | } | ||||
| } | } | ||||
| /* check all other button links */ | /* check all other button links */ | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| if (but != newbut && but->type == LINK && but->link) { | if (but != newbut && but->type == UI_BTYPE_LINK && but->link) { | ||||
| for (line = but->link->lines.first; line; line = line->next) { | for (line = but->link->lines.first; line; line = line->next) { | ||||
| if (line->to == newbut) | if (line->to == newbut) | ||||
| line->to = oldbut; | line->to = oldbut; | ||||
| if (line->from == newbut) | if (line->from == newbut) | ||||
| line->from = oldbut; | line->from = oldbut; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | if (oldbut->poin != (char *)oldbut) { | ||||
| SWAP(void *, oldbut->func_argN, but->func_argN); | SWAP(void *, oldbut->func_argN, but->func_argN); | ||||
| } | } | ||||
| oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); | oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); | ||||
| oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); | oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); | ||||
| /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position | /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position | ||||
| * when scrolling without moving mouse (see [#28432]) */ | * when scrolling without moving mouse (see [#28432]) */ | ||||
| if (ELEM(oldbut->type, ROW, LISTROW)) | if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) | ||||
| oldbut->hardmax = but->hardmax; | oldbut->hardmax = but->hardmax; | ||||
| ui_but_update_linklines(block, oldbut, but); | ui_but_update_linklines(block, oldbut, but); | ||||
| /* move/copy string from the new button to the old */ | /* move/copy string from the new button to the old */ | ||||
| /* needed for alt+mouse wheel over enums */ | /* needed for alt+mouse wheel over enums */ | ||||
| if (but->str != but->strdata) { | if (but->str != but->strdata) { | ||||
| if (oldbut->str != oldbut->strdata) { | if (oldbut->str != oldbut->strdata) { | ||||
| SWAP(char *, but->str, oldbut->str); | SWAP(char *, but->str, oldbut->str); | ||||
| } | } | ||||
| else { | else { | ||||
| oldbut->str = but->str; | oldbut->str = but->str; | ||||
| but->str = but->strdata; | but->str = but->strdata; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (oldbut->str != oldbut->strdata) { | if (oldbut->str != oldbut->strdata) { | ||||
| MEM_freeN(oldbut->str); | MEM_freeN(oldbut->str); | ||||
| oldbut->str = oldbut->strdata; | oldbut->str = oldbut->strdata; | ||||
| } | } | ||||
| BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata)); | BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata)); | ||||
| } | } | ||||
| BLI_remlink(&block->buttons, but); | BLI_remlink(&block->buttons, but); | ||||
| ui_free_but(C, but); | ui_but_free(C, but); | ||||
| /* note: if layout hasn't been applied yet, it uses old button pointers... */ | /* note: if layout hasn't been applied yet, it uses old button pointers... */ | ||||
| } | } | ||||
| else { | else { | ||||
| const int flag_copy = UI_BUT_DRAG_MULTI; | const int flag_copy = UI_BUT_DRAG_MULTI; | ||||
| but->flag = (but->flag & ~flag_copy) | (oldbut->flag & flag_copy); | but->flag = (but->flag & ~flag_copy) | (oldbut->flag & flag_copy); | ||||
| /* ensures one button can get activated, and in case the buttons | /* ensures one button can get activated, and in case the buttons | ||||
| * draw are the same this gives O(1) lookup for each button */ | * draw are the same this gives O(1) lookup for each button */ | ||||
| BLI_remlink(&oldblock->buttons, oldbut); | BLI_remlink(&oldblock->buttons, oldbut); | ||||
| ui_free_but(C, oldbut); | ui_but_free(C, oldbut); | ||||
| } | } | ||||
| return found_active; | return found_active; | ||||
| } | } | ||||
| /* needed for temporarily rename buttons, such as in outliner or file-select, | /* needed for temporarily rename buttons, such as in outliner or file-select, | ||||
| * they should keep calling uiDefButs to keep them alive */ | * they should keep calling uiDefButs to keep them alive */ | ||||
| /* returns 0 when button removed */ | /* returns 0 when button removed */ | ||||
| bool uiButActiveOnly(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but) | bool UI_but_active_only(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but) | ||||
| { | { | ||||
| uiBlock *oldblock; | uiBlock *oldblock; | ||||
| uiBut *oldbut; | uiBut *oldbut; | ||||
| bool activate = false, found = false, isactive = false; | bool activate = false, found = false, isactive = false; | ||||
| oldblock = block->oldblock; | oldblock = block->oldblock; | ||||
| if (!oldblock) { | if (!oldblock) { | ||||
| activate = true; | activate = true; | ||||
| } | } | ||||
| else { | else { | ||||
| oldbut = ui_but_find_old(oldblock, but); | oldbut = ui_but_find_old(oldblock, but); | ||||
| if (oldbut) { | if (oldbut) { | ||||
| found = true; | found = true; | ||||
| if (oldbut->active) { | if (oldbut->active) { | ||||
| isactive = true; | isactive = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if ((activate == true) || (found == false)) { | if ((activate == true) || (found == false)) { | ||||
| ui_button_activate_do((bContext *)C, ar, but); | ui_but_activate_event((bContext *)C, ar, but); | ||||
| } | } | ||||
| else if ((found == true) && (isactive == false)) { | else if ((found == true) && (isactive == false)) { | ||||
| BLI_remlink(&block->buttons, but); | BLI_remlink(&block->buttons, but); | ||||
| ui_free_but(C, but); | ui_but_free(C, but); | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* simulate button click */ | /* simulate button click */ | ||||
| void uiButExecute(const bContext *C, uiBut *but) | void UI_but_execute(const bContext *C, uiBut *but) | ||||
| { | { | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| void *active_back; | void *active_back; | ||||
| ui_button_execute_begin((bContext *)C, ar, but, &active_back); | ui_but_execute_begin((bContext *)C, ar, but, &active_back); | ||||
| /* Value is applied in begin. No further action required. */ | /* Value is applied in begin. No further action required. */ | ||||
| ui_button_execute_end((bContext *)C, ar, but, active_back); | ui_but_execute_end((bContext *)C, ar, but, active_back); | ||||
| } | } | ||||
| /* use to check if we need to disable undo, but don't make any changes | /* use to check if we need to disable undo, but don't make any changes | ||||
| * returns false if undo needs to be disabled. */ | * returns false if undo needs to be disabled. */ | ||||
| static bool ui_is_but_rna_undo(const uiBut *but) | static bool ui_but_is_rna_undo(const uiBut *but) | ||||
| { | { | ||||
| if (but->rnapoin.id.data) { | if (but->rnapoin.id.data) { | ||||
| /* avoid undo push for buttons who's ID are screen or wm level | /* avoid undo push for buttons who's ID are screen or wm level | ||||
| * we could disable undo for buttons with no ID too but may have | * we could disable undo for buttons with no ID too but may have | ||||
| * unforeseen consequences, so best check for ID's we _know_ are not | * unforeseen consequences, so best check for ID's we _know_ are not | ||||
| * handled by undo - campbell */ | * handled by undo - campbell */ | ||||
| ID *id = but->rnapoin.id.data; | ID *id = but->rnapoin.id.data; | ||||
| if (ID_CHECK_UNDO(id) == false) { | if (ID_CHECK_UNDO(id) == false) { | ||||
| Show All 26 Lines | static void ui_menu_block_set_keyaccels(uiBlock *block) | ||||
| if (block->rect.xmin != block->rect.xmax) | if (block->rect.xmin != block->rect.xmax) | ||||
| return; | return; | ||||
| for (pass = 0; pass < 2; pass++) { | for (pass = 0; pass < 2; pass++) { | ||||
| /* 2 Passes, on for first letter only, second for any letter if first fails | /* 2 Passes, on for first letter only, second for any letter if first fails | ||||
| * fun first pass on all buttons so first word chars always get first priority */ | * fun first pass on all buttons so first word chars always get first priority */ | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| if (!ELEM(but->type, BUT, BUTM, MENU, BLOCK, PULLDOWN) || (but->flag & UI_HIDDEN)) { | if (!ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_BUT_MENU, UI_BTYPE_MENU, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN) || (but->flag & UI_HIDDEN)) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if (but->menu_key == '\0') { | else if (but->menu_key == '\0') { | ||||
| if (but->str) { | if (but->str) { | ||||
| for (str_pt = but->str; *str_pt; ) { | for (str_pt = but->str; *str_pt; ) { | ||||
| menu_key = tolower(*str_pt); | menu_key = tolower(*str_pt); | ||||
| if ((menu_key >= 'a' && menu_key <= 'z') && !(menu_key_mask & 1 << (menu_key - 'a'))) { | if ((menu_key >= 'a' && menu_key <= 'z') && !(menu_key_mask & 1 << (menu_key - 'a'))) { | ||||
| menu_key_mask |= 1 << (menu_key - 'a'); | menu_key_mask |= 1 << (menu_key - 'a'); | ||||
| ▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if (shortcut_str) { | ||||
| } | } | ||||
| BLI_snprintf(but->strdata, | BLI_snprintf(but->strdata, | ||||
| sizeof(but->strdata), | sizeof(but->strdata), | ||||
| "%s" UI_SEP_CHAR_S "%s", | "%s" UI_SEP_CHAR_S "%s", | ||||
| butstr_orig, shortcut_str); | butstr_orig, shortcut_str); | ||||
| MEM_freeN(butstr_orig); | MEM_freeN(butstr_orig); | ||||
| but->str = but->strdata; | but->str = but->strdata; | ||||
| but->flag |= UI_BUT_HAS_SEP_CHAR; | but->flag |= UI_BUT_HAS_SEP_CHAR; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| } | } | ||||
| } | } | ||||
| static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len) | static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len) | ||||
| { | { | ||||
| MenuType *mt; | MenuType *mt; | ||||
| bool found = false; | bool found = false; | ||||
| if (but->optype) { | if (but->optype) { | ||||
| IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; | IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; | ||||
| if (WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, true, | if (WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, true, | ||||
| buf, buf_len)) | buf, buf_len)) | ||||
| { | { | ||||
| found = true; | found = true; | ||||
| } | } | ||||
| } | } | ||||
| else if ((mt = uiButGetMenuType(but))) { | else if ((mt = UI_but_menutype_get(but))) { | ||||
| IDProperty *prop_menu; | IDProperty *prop_menu; | ||||
| IDProperty *prop_menu_name; | IDProperty *prop_menu_name; | ||||
| /* annoying, create a property */ | /* annoying, create a property */ | ||||
| IDPropertyTemplate val = {0}; | IDPropertyTemplate val = {0}; | ||||
| prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */ | prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */ | ||||
| IDP_AddToGroup(prop_menu, (prop_menu_name = IDP_NewString("", "name", sizeof(mt->idname)))); | IDP_AddToGroup(prop_menu, (prop_menu_name = IDP_NewString("", "name", sizeof(mt->idname)))); | ||||
| ▲ Show 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | for (but = block->buttons.first; but; but = but->next) { | ||||
| } | } | ||||
| else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { | else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { | ||||
| ui_but_add_shortcut(but, buf, false); | ui_but_add_shortcut(but, buf, false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void uiBlockUpdateFromOld(const bContext *C, uiBlock *block) | void UI_block_update_from_old(const bContext *C, uiBlock *block) | ||||
| { | { | ||||
| uiBut *but_old; | uiBut *but_old; | ||||
| uiBut *but; | uiBut *but; | ||||
| if (!block->oldblock) | if (!block->oldblock) | ||||
| return; | return; | ||||
| but_old = block->oldblock->buttons.first; | but_old = block->oldblock->buttons.first; | ||||
| if (BLI_listbase_is_empty(&block->oldblock->butstore) == false) { | if (BLI_listbase_is_empty(&block->oldblock->butstore) == false) { | ||||
| UI_butstore_update(block); | UI_butstore_update(block); | ||||
| } | } | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| if (ui_but_update_from_old_block(C, block, &but, &but_old)) { | if (ui_but_update_from_old_block(C, block, &but, &but_old)) { | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| } | } | ||||
| } | } | ||||
| block->auto_open = block->oldblock->auto_open; | block->auto_open = block->oldblock->auto_open; | ||||
| block->auto_open_last = block->oldblock->auto_open_last; | block->auto_open_last = block->oldblock->auto_open_last; | ||||
| block->tooltipdisabled = block->oldblock->tooltipdisabled; | block->tooltipdisabled = block->oldblock->tooltipdisabled; | ||||
| BLI_movelisttolist(&block->color_pickers.list, &block->oldblock->color_pickers.list); | BLI_movelisttolist(&block->color_pickers.list, &block->oldblock->color_pickers.list); | ||||
| block->oldblock = NULL; | block->oldblock = NULL; | ||||
| } | } | ||||
| void uiEndBlock_ex(const bContext *C, uiBlock *block, const int xy[2]) | void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2]) | ||||
| { | { | ||||
| wmWindow *window = CTX_wm_window(C); | wmWindow *window = CTX_wm_window(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| uiBut *but; | uiBut *but; | ||||
| BLI_assert(block->active); | BLI_assert(block->active); | ||||
| uiBlockUpdateFromOld(C, block); | UI_block_update_from_old(C, block); | ||||
| /* inherit flags from 'old' buttons that was drawn here previous, based | /* inherit flags from 'old' buttons that was drawn here previous, based | ||||
| * on matching buttons, we need this to make button event handling non | * on matching buttons, we need this to make button event handling non | ||||
| * blocking, while still allowing buttons to be remade each redraw as it | * blocking, while still allowing buttons to be remade each redraw as it | ||||
| * is expected by blender code */ | * is expected by blender code */ | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| /* temp? Proper check for graying out */ | /* temp? Proper check for graying out */ | ||||
| if (but->optype) { | if (but->optype) { | ||||
| Show All 13 Lines | for (but = block->buttons.first; but; but = but->next) { | ||||
| ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f); | ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f); | ||||
| } | } | ||||
| /* handle pending stuff */ | /* handle pending stuff */ | ||||
| if (block->layouts.first) { | if (block->layouts.first) { | ||||
| uiBlockLayoutResolve(block, NULL, NULL); | UI_block_layout_resolve(block, NULL, NULL); | ||||
| } | } | ||||
| ui_block_do_align(block); | ui_block_align_calc(block); | ||||
| if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) { | if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) { | ||||
| ui_menu_block_set_keyaccels(block); /* could use a different flag to check */ | ui_menu_block_set_keyaccels(block); /* could use a different flag to check */ | ||||
| } | } | ||||
| if (block->flag & UI_BLOCK_LOOP) { | if (block->flag & UI_BLOCK_LOOP) { | ||||
| ui_menu_block_set_keymaps(C, block); | ui_menu_block_set_keymaps(C, block); | ||||
| } | } | ||||
| /* after keymaps! */ | /* after keymaps! */ | ||||
| switch (block->bounds_type) { | switch (block->bounds_type) { | ||||
| case UI_BLOCK_BOUNDS_NONE: | case UI_BLOCK_BOUNDS_NONE: | ||||
| break; | break; | ||||
| case UI_BLOCK_BOUNDS: | case UI_BLOCK_BOUNDS: | ||||
| ui_bounds_block(block); | ui_block_bounds_calc(block); | ||||
| break; | break; | ||||
| case UI_BLOCK_BOUNDS_TEXT: | case UI_BLOCK_BOUNDS_TEXT: | ||||
| ui_text_bounds_block(block, 0.0f); | ui_block_bounds_calc_text(block, 0.0f); | ||||
| break; | break; | ||||
| case UI_BLOCK_BOUNDS_POPUP_CENTER: | case UI_BLOCK_BOUNDS_POPUP_CENTER: | ||||
| ui_centered_bounds_block(window, block); | ui_block_bounds_calc_centered(window, block); | ||||
| break; | break; | ||||
| case UI_BLOCK_BOUNDS_PIE_CENTER: | case UI_BLOCK_BOUNDS_PIE_CENTER: | ||||
| ui_centered_pie_bounds_block(block); | ui_block_bounds_calc_centered_pie(block); | ||||
| break; | break; | ||||
| /* fallback */ | /* fallback */ | ||||
| case UI_BLOCK_BOUNDS_POPUP_MOUSE: | case UI_BLOCK_BOUNDS_POPUP_MOUSE: | ||||
| case UI_BLOCK_BOUNDS_POPUP_MENU: | case UI_BLOCK_BOUNDS_POPUP_MENU: | ||||
| ui_popup_bounds_block(window, block, block->bounds_type, xy); | ui_block_bounds_calc_popup(window, block, block->bounds_type, xy); | ||||
| break; | break; | ||||
| } | } | ||||
| if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) { | if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) { | ||||
| uiBoundsBlock(block, 0); | UI_block_bounds_set_normal(block, 0); | ||||
| } | } | ||||
| if (block->flag & UI_BUT_ALIGN) { | if (block->flag & UI_BUT_ALIGN) { | ||||
| uiBlockEndAlign(block); | UI_block_align_end(block); | ||||
| } | } | ||||
| block->endblock = 1; | block->endblock = 1; | ||||
| } | } | ||||
| void uiEndBlock(const bContext *C, uiBlock *block) | void UI_block_end(const bContext *C, uiBlock *block) | ||||
| { | { | ||||
| wmWindow *window = CTX_wm_window(C); | wmWindow *window = CTX_wm_window(C); | ||||
| uiEndBlock_ex(C, block, &window->eventstate->x); | UI_block_end_ex(C, block, &window->eventstate->x); | ||||
| } | } | ||||
| /* ************** BLOCK DRAWING FUNCTION ************* */ | /* ************** BLOCK DRAWING FUNCTION ************* */ | ||||
| void ui_fontscale(short *points, float aspect) | void ui_fontscale(short *points, float aspect) | ||||
| { | { | ||||
| if (aspect < 0.9f || aspect > 1.1f) { | if (aspect < 0.9f || aspect > 1.1f) { | ||||
| float pointsf = *points; | float pointsf = *points; | ||||
| Show All 24 Lines | static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, uiBut *but) | ||||
| rect->xmin = floorf(rectf.xmin); | rect->xmin = floorf(rectf.xmin); | ||||
| rect->ymin = floorf(rectf.ymin); | rect->ymin = floorf(rectf.ymin); | ||||
| rect->xmax = floorf(rectf.xmax); | rect->xmax = floorf(rectf.xmax); | ||||
| rect->ymax = floorf(rectf.ymax); | rect->ymax = floorf(rectf.ymax); | ||||
| } | } | ||||
| /* uses local copy of style, to scale things down, and allow widgets to change stuff */ | /* uses local copy of style, to scale things down, and allow widgets to change stuff */ | ||||
| void uiDrawBlock(const bContext *C, uiBlock *block) | void UI_block_draw(const bContext *C, uiBlock *block) | ||||
| { | { | ||||
| uiStyle style = *UI_GetStyleDraw(); /* XXX pass on as arg */ | uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */ | ||||
| ARegion *ar; | ARegion *ar; | ||||
| uiBut *but; | uiBut *but; | ||||
| rcti rect; | rcti rect; | ||||
| int multisample_enabled; | int multisample_enabled; | ||||
| /* get menu region or area region */ | /* get menu region or area region */ | ||||
| ar = CTX_wm_menu(C); | ar = CTX_wm_menu(C); | ||||
| if (!ar) | if (!ar) | ||||
| ar = CTX_wm_region(C); | ar = CTX_wm_region(C); | ||||
| if (!block->endblock) | if (!block->endblock) | ||||
| uiEndBlock(C, block); | UI_block_end(C, block); | ||||
| /* disable AA, makes widgets too blurry */ | /* disable AA, makes widgets too blurry */ | ||||
| multisample_enabled = glIsEnabled(GL_MULTISAMPLE_ARB); | multisample_enabled = glIsEnabled(GL_MULTISAMPLE_ARB); | ||||
| if (multisample_enabled) | if (multisample_enabled) | ||||
| glDisable(GL_MULTISAMPLE_ARB); | glDisable(GL_MULTISAMPLE_ARB); | ||||
| /* we set this only once */ | /* we set this only once */ | ||||
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
| /* ************* EVENTS ************* */ | /* ************* EVENTS ************* */ | ||||
| /** | /** | ||||
| * Check if the button is pushed, this is only meaningful for some button types. | * Check if the button is pushed, this is only meaningful for some button types. | ||||
| * | * | ||||
| * \return (0 == UNSELECT), (1 == SELECT), (-1 == DO-NOTHING) | * \return (0 == UNSELECT), (1 == SELECT), (-1 == DO-NOTHING) | ||||
| */ | */ | ||||
| int ui_is_but_push_ex(uiBut *but, double *value) | int ui_but_is_pushed_ex(uiBut *but, double *value) | ||||
| { | { | ||||
| int is_push = 0; | int is_push = 0; | ||||
| if (but->bit) { | if (but->bit) { | ||||
| const bool state = ELEM(but->type, TOGN, ICONTOGN, OPTIONN) ? false : true; | const bool state = ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N) ? false : true; | ||||
| int lvalue; | int lvalue; | ||||
| UI_GET_BUT_VALUE_INIT(but, *value); | UI_GET_BUT_VALUE_INIT(but, *value); | ||||
| lvalue = (int)*value; | lvalue = (int)*value; | ||||
| if (UI_BITBUT_TEST(lvalue, (but->bitnr))) { | if (UI_BITBUT_TEST(lvalue, (but->bitnr))) { | ||||
| is_push = state; | is_push = state; | ||||
| } | } | ||||
| else { | else { | ||||
| is_push = !state; | is_push = !state; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| switch (but->type) { | switch (but->type) { | ||||
| case BUT: | case UI_BTYPE_BUT: | ||||
| case HOTKEYEVT: | case UI_BTYPE_HOTKEY_EVENT: | ||||
| case KEYEVT: | case UI_BTYPE_KEY_EVENT: | ||||
| case COLOR: | case UI_BTYPE_COLOR: | ||||
| is_push = -1; | is_push = -1; | ||||
| break; | break; | ||||
| case TOGBUT: | case UI_BTYPE_BUT_TOGGLE: | ||||
| case TOG: | case UI_BTYPE_TOGGLE: | ||||
| case ICONTOG: | case UI_BTYPE_ICON_TOGGLE: | ||||
| case OPTION: | case UI_BTYPE_CHECKBOX: | ||||
| UI_GET_BUT_VALUE_INIT(but, *value); | UI_GET_BUT_VALUE_INIT(but, *value); | ||||
| if (*value != (double)but->hardmin) is_push = true; | if (*value != (double)but->hardmin) is_push = true; | ||||
| break; | break; | ||||
| case ICONTOGN: | case UI_BTYPE_ICON_TOGGLE_N: | ||||
| case TOGN: | case UI_BTYPE_TOGGLE_N: | ||||
| case OPTIONN: | case UI_BTYPE_CHECKBOX_N: | ||||
| UI_GET_BUT_VALUE_INIT(but, *value); | UI_GET_BUT_VALUE_INIT(but, *value); | ||||
| if (*value == 0.0) is_push = true; | if (*value == 0.0) is_push = true; | ||||
| break; | break; | ||||
| case ROW: | case UI_BTYPE_ROW: | ||||
| case LISTROW: | case UI_BTYPE_LISTROW: | ||||
| UI_GET_BUT_VALUE_INIT(but, *value); | UI_GET_BUT_VALUE_INIT(but, *value); | ||||
| /* support for rna enum buts */ | /* support for rna enum buts */ | ||||
| if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) { | if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) { | ||||
| if ((int)*value & (int)but->hardmax) is_push = true; | if ((int)*value & (int)but->hardmax) is_push = true; | ||||
| } | } | ||||
| else { | else { | ||||
| if (*value == (double)but->hardmax) is_push = true; | if (*value == (double)but->hardmax) is_push = true; | ||||
| } | } | ||||
| break; | break; | ||||
| default: | default: | ||||
| is_push = -1; | is_push = -1; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| return is_push; | return is_push; | ||||
| } | } | ||||
| int ui_is_but_push(uiBut *but) | int ui_but_is_pushed(uiBut *but) | ||||
| { | { | ||||
| double value = UI_BUT_VALUE_UNSET; | double value = UI_BUT_VALUE_UNSET; | ||||
| return ui_is_but_push_ex(but, &value); | return ui_but_is_pushed_ex(but, &value); | ||||
| } | } | ||||
| static void ui_check_but_select(uiBut *but, double *value) | static void ui_but_update_select_flag(uiBut *but, double *value) | ||||
| { | { | ||||
| switch (ui_is_but_push_ex(but, value)) { | switch (ui_but_is_pushed_ex(but, value)) { | ||||
| case true: | case true: | ||||
| but->flag |= UI_SELECT; | but->flag |= UI_SELECT; | ||||
| break; | break; | ||||
| case false: | case false: | ||||
| but->flag &= ~UI_SELECT; | but->flag &= ~UI_SELECT; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| static uiBut *ui_find_inlink(uiBlock *block, void *poin) | static uiBut *ui_linkline_find_inlink(uiBlock *block, void *poin) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = block->buttons.first; | but = block->buttons.first; | ||||
| while (but) { | while (but) { | ||||
| if (but->type == INLINK) { | if (but->type == UI_BTYPE_INLINK) { | ||||
| if (but->poin == poin) return but; | if (but->poin == poin) return but; | ||||
| } | } | ||||
| but = but->next; | but = but->next; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt, short deactive) | static void ui_linkline_add(ListBase *listb, uiBut *but, uiBut *bt, short deactive) | ||||
| { | { | ||||
| uiLinkLine *line; | uiLinkLine *line; | ||||
| line = MEM_callocN(sizeof(uiLinkLine), "linkline"); | line = MEM_callocN(sizeof(uiLinkLine), "linkline"); | ||||
| BLI_addtail(listb, line); | BLI_addtail(listb, line); | ||||
| line->from = but; | line->from = but; | ||||
| line->to = bt; | line->to = bt; | ||||
| line->deactive = deactive; | line->deactive = deactive; | ||||
| } | } | ||||
| uiBut *uiFindInlink(uiBlock *block, void *poin) | uiBut *UI_block_links_find_inlink(uiBlock *block, void *poin) | ||||
| { | { | ||||
| return ui_find_inlink(block, poin); | return ui_linkline_find_inlink(block, poin); | ||||
| } | } | ||||
| void uiComposeLinks(uiBlock *block) | void UI_block_links_compose(uiBlock *block) | ||||
| { | { | ||||
| uiBut *but, *bt; | uiBut *but, *bt; | ||||
| uiLink *link; | uiLink *link; | ||||
| void ***ppoin; | void ***ppoin; | ||||
| int a; | int a; | ||||
| but = block->buttons.first; | but = block->buttons.first; | ||||
| while (but) { | while (but) { | ||||
| if (but->type == LINK) { | if (but->type == UI_BTYPE_LINK) { | ||||
| link = but->link; | link = but->link; | ||||
| /* for all pointers in the array */ | /* for all pointers in the array */ | ||||
| if (link) { | if (link) { | ||||
| if (link->ppoin) { | if (link->ppoin) { | ||||
| ppoin = link->ppoin; | ppoin = link->ppoin; | ||||
| for (a = 0; a < *(link->totlink); a++) { | for (a = 0; a < *(link->totlink); a++) { | ||||
| bt = ui_find_inlink(block, (*ppoin)[a]); | bt = ui_linkline_find_inlink(block, (*ppoin)[a]); | ||||
| if (bt) { | if (bt) { | ||||
| if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) { | if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) { | ||||
| ui_add_link_line(&link->lines, but, bt, true); | ui_linkline_add(&link->lines, but, bt, true); | ||||
| } | } | ||||
| else { | else { | ||||
| ui_add_link_line(&link->lines, but, bt, false); | ui_linkline_add(&link->lines, but, bt, false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (link->poin) { | else if (link->poin) { | ||||
| bt = ui_find_inlink(block, *link->poin); | bt = ui_linkline_find_inlink(block, *link->poin); | ||||
| if (bt) { | if (bt) { | ||||
| if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) { | if ((but->flag & UI_BUT_SCA_LINK_GREY) || (bt->flag & UI_BUT_SCA_LINK_GREY)) { | ||||
| ui_add_link_line(&link->lines, but, bt, true); | ui_linkline_add(&link->lines, but, bt, true); | ||||
| } | } | ||||
| else { | else { | ||||
| ui_add_link_line(&link->lines, but, bt, false); | ui_linkline_add(&link->lines, but, bt, false); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| but = but->next; | but = but->next; | ||||
| } | } | ||||
| } | } | ||||
| /* ************************************************ */ | /* ************************************************ */ | ||||
| void uiBlockSetButLock(uiBlock *block, bool val, const char *lockstr) | void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr) | ||||
| { | { | ||||
| if (val) { | if (val) { | ||||
| block->lock = val; | block->lock = val; | ||||
| block->lockstr = lockstr; | block->lockstr = lockstr; | ||||
| } | } | ||||
| } | } | ||||
| void uiBlockClearButLock(uiBlock *block) | void UI_block_lock_clear(uiBlock *block) | ||||
| { | { | ||||
| block->lock = false; | block->lock = false; | ||||
| block->lockstr = NULL; | block->lockstr = NULL; | ||||
| } | } | ||||
| /* *************************************************************** */ | /* *************************************************************** */ | ||||
| void ui_delete_linkline(uiLinkLine *line, uiBut *but) | void ui_linkline_remove(uiLinkLine *line, uiBut *but) | ||||
| { | { | ||||
| uiLink *link; | uiLink *link; | ||||
| int a, b; | int a, b; | ||||
| BLI_remlink(&but->link->lines, line); | BLI_remlink(&but->link->lines, line); | ||||
| link = line->from->link; | link = line->from->link; | ||||
| Show All 24 Lines | void ui_linkline_remove(uiLinkLine *line, uiBut *but) | ||||
| //REDRAW | //REDRAW | ||||
| } | } | ||||
| /* *********************** data get/set *********************** | /* *********************** data get/set *********************** | ||||
| * this either works with the pointed to data, or can work with | * this either works with the pointed to data, or can work with | ||||
| * an edit override pointer while dragging for example */ | * an edit override pointer while dragging for example */ | ||||
| /* for buttons pointing to color for example */ | /* for buttons pointing to color for example */ | ||||
| void ui_get_but_vectorf(uiBut *but, float vec[3]) | void ui_but_v3_get(uiBut *but, float vec[3]) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| int a; | int a; | ||||
| if (but->editvec) { | if (but->editvec) { | ||||
| copy_v3_v3(vec, but->editvec); | copy_v3_v3(vec, but->editvec); | ||||
| } | } | ||||
| Show All 29 Lines | void ui_but_v3_get(uiBut *but, float vec[3]) | ||||
| } | } | ||||
| else { | else { | ||||
| if (but->editvec == NULL) { | if (but->editvec == NULL) { | ||||
| fprintf(stderr, "%s: can't get color, should never happen\n", __func__); | fprintf(stderr, "%s: can't get color, should never happen\n", __func__); | ||||
| zero_v3(vec); | zero_v3(vec); | ||||
| } | } | ||||
| } | } | ||||
| if (but->type == BUT_NORMAL) { | if (but->type == UI_BTYPE_UNITVEC) { | ||||
| normalize_v3(vec); | normalize_v3(vec); | ||||
| } | } | ||||
| } | } | ||||
| /* for buttons pointing to color for example */ | /* for buttons pointing to color for example */ | ||||
| void ui_set_but_vectorf(uiBut *but, const float vec[3]) | void ui_but_v3_set(uiBut *but, const float vec[3]) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| if (but->editvec) { | if (but->editvec) { | ||||
| copy_v3_v3(but->editvec, vec); | copy_v3_v3(but->editvec, vec); | ||||
| } | } | ||||
| if (but->rnaprop) { | if (but->rnaprop) { | ||||
| Show All 23 Lines | else if (but->pointype == UI_BUT_POIN_CHAR) { | ||||
| cp[2] = (char)(0.5f + vec[2] * 255.0f); | cp[2] = (char)(0.5f + vec[2] * 255.0f); | ||||
| } | } | ||||
| else if (but->pointype == UI_BUT_POIN_FLOAT) { | else if (but->pointype == UI_BUT_POIN_FLOAT) { | ||||
| float *fp = (float *)but->poin; | float *fp = (float *)but->poin; | ||||
| copy_v3_v3(fp, vec); | copy_v3_v3(fp, vec); | ||||
| } | } | ||||
| } | } | ||||
| bool ui_is_but_float(const uiBut *but) | bool ui_but_is_float(const uiBut *but) | ||||
| { | { | ||||
| if (but->pointype == UI_BUT_POIN_FLOAT && but->poin) | if (but->pointype == UI_BUT_POIN_FLOAT && but->poin) | ||||
| return true; | return true; | ||||
| if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_FLOAT) | if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_FLOAT) | ||||
| return true; | return true; | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool ui_is_but_bool(const uiBut *but) | bool ui_but_is_bool(const uiBut *but) | ||||
| { | { | ||||
| if (ELEM(but->type, TOG, TOGN, ICONTOG, ICONTOGN)) | if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE, UI_BTYPE_ICON_TOGGLE_N)) | ||||
| return true; | return true; | ||||
| if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN) | if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN) | ||||
| return true; | return true; | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool ui_is_but_unit(const uiBut *but) | bool ui_but_is_unit(const uiBut *but) | ||||
| { | { | ||||
| UnitSettings *unit = but->block->unit; | UnitSettings *unit = but->block->unit; | ||||
| const int unit_type = uiButGetUnitType(but); | const int unit_type = UI_but_unit_type_get(but); | ||||
| if (unit_type == PROP_UNIT_NONE) | if (unit_type == PROP_UNIT_NONE) | ||||
| return false; | return false; | ||||
| #if 1 /* removed so angle buttons get correct snapping */ | #if 1 /* removed so angle buttons get correct snapping */ | ||||
| if (ui_is_but_unit_radians_ex(unit, unit_type)) | if (ui_but_is_unit_radians_ex(unit, unit_type)) | ||||
| return false; | return false; | ||||
| #endif | #endif | ||||
| /* for now disable time unit conversion */ | /* for now disable time unit conversion */ | ||||
| if (unit_type == PROP_UNIT_TIME) | if (unit_type == PROP_UNIT_TIME) | ||||
| return false; | return false; | ||||
| if (unit->system == USER_UNIT_NONE) { | if (unit->system == USER_UNIT_NONE) { | ||||
| if (unit_type != PROP_UNIT_ROTATION) { | if (unit_type != PROP_UNIT_ROTATION) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| /** | /** | ||||
| * Check if this button is similar enough to be grouped with another. | * Check if this button is similar enough to be grouped with another. | ||||
| */ | */ | ||||
| bool ui_is_but_compatible(const uiBut *but_a, const uiBut *but_b) | bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) | ||||
| { | { | ||||
| if (but_a->type != but_b->type) | if (but_a->type != but_b->type) | ||||
| return false; | return false; | ||||
| if (but_a->pointype != but_b->pointype) | if (but_a->pointype != but_b->pointype) | ||||
| return false; | return false; | ||||
| if (but_a->rnaprop) { | if (but_a->rnaprop) { | ||||
| /* skip 'rnapoin.data', 'rnapoin.id.data' | /* skip 'rnapoin.data', 'rnapoin.id.data' | ||||
| * allow different data to have the same props edited at once */ | * allow different data to have the same props edited at once */ | ||||
| if (but_a->rnapoin.type != but_b->rnapoin.type) | if (but_a->rnapoin.type != but_b->rnapoin.type) | ||||
| return false; | return false; | ||||
| if (RNA_property_type(but_a->rnaprop) != RNA_property_type(but_b->rnaprop)) | if (RNA_property_type(but_a->rnaprop) != RNA_property_type(but_b->rnaprop)) | ||||
| return false; | return false; | ||||
| if (RNA_property_subtype(but_a->rnaprop) != RNA_property_subtype(but_b->rnaprop)) | if (RNA_property_subtype(but_a->rnaprop) != RNA_property_subtype(but_b->rnaprop)) | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool ui_is_but_rna_valid(uiBut *but) | bool ui_but_is_rna_valid(uiBut *but) | ||||
| { | { | ||||
| if (but->rnaprop == NULL || RNA_struct_contains_property(&but->rnapoin, but->rnaprop)) { | if (but->rnaprop == NULL || RNA_struct_contains_property(&but->rnapoin, but->rnaprop)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| else { | else { | ||||
| printf("property removed %s: %p\n", but->drawstr, but->rnaprop); | printf("property removed %s: %p\n", but->drawstr, but->rnaprop); | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| double ui_get_but_val(uiBut *but) | double ui_but_value_get(uiBut *but) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| double value = 0.0; | double value = 0.0; | ||||
| if (but->editval) { return *(but->editval); } | if (but->editval) { return *(but->editval); } | ||||
| if (but->poin == NULL && but->rnapoin.data == NULL) return 0.0; | if (but->poin == NULL && but->rnapoin.data == NULL) return 0.0; | ||||
| if (but->rnaprop) { | if (but->rnaprop) { | ||||
| Show All 39 Lines | double ui_but_value_get(uiBut *but) | ||||
| } | } | ||||
| else if (but->pointype == UI_BUT_POIN_FLOAT) { | else if (but->pointype == UI_BUT_POIN_FLOAT) { | ||||
| value = *(float *)but->poin; | value = *(float *)but->poin; | ||||
| } | } | ||||
| return value; | return value; | ||||
| } | } | ||||
| void ui_set_but_val(uiBut *but, double value) | void ui_but_value_set(uiBut *but, double value) | ||||
| { | { | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| /* value is a hsv value: convert to rgb */ | /* value is a hsv value: convert to rgb */ | ||||
| if (but->rnaprop) { | if (but->rnaprop) { | ||||
| prop = but->rnaprop; | prop = but->rnaprop; | ||||
| if (RNA_property_editable(&but->rnapoin, prop)) { | if (RNA_property_editable(&but->rnapoin, prop)) { | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | else { | ||||
| else if (but->pointype == UI_BUT_POIN_SHORT) | else if (but->pointype == UI_BUT_POIN_SHORT) | ||||
| value = *((short *)but->poin) = (short)value; | value = *((short *)but->poin) = (short)value; | ||||
| else if (but->pointype == UI_BUT_POIN_INT) | else if (but->pointype == UI_BUT_POIN_INT) | ||||
| value = *((int *)but->poin) = (int)value; | value = *((int *)but->poin) = (int)value; | ||||
| else if (but->pointype == UI_BUT_POIN_FLOAT) | else if (but->pointype == UI_BUT_POIN_FLOAT) | ||||
| value = *((float *)but->poin) = (float)value; | value = *((float *)but->poin) = (float)value; | ||||
| } | } | ||||
| ui_check_but_select(but, &value); | ui_but_update_select_flag(but, &value); | ||||
| } | } | ||||
| int ui_get_but_string_max_length(uiBut *but) | int ui_but_string_get_max_length(uiBut *but) | ||||
| { | { | ||||
| if (ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) | if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) | ||||
| return but->hardmax; | return but->hardmax; | ||||
| else | else | ||||
| return UI_MAX_DRAW_STR; | return UI_MAX_DRAW_STR; | ||||
| } | } | ||||
| uiBut *ui_get_but_drag_multi_edit(uiBut *but) | uiBut *ui_but_drag_multi_edit_get(uiBut *but) | ||||
| { | { | ||||
| uiBut *but_iter; | uiBut *but_iter; | ||||
| BLI_assert(but->flag & UI_BUT_DRAG_MULTI); | BLI_assert(but->flag & UI_BUT_DRAG_MULTI); | ||||
| for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) { | for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) { | ||||
| if (but_iter->editstr) { | if (but_iter->editstr) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| return but_iter; | return but_iter; | ||||
| } | } | ||||
| static double ui_get_but_scale_unit(uiBut *but, double value) | static double ui_get_but_scale_unit(uiBut *but, double value) | ||||
| { | { | ||||
| UnitSettings *unit = but->block->unit; | UnitSettings *unit = but->block->unit; | ||||
| int unit_type = uiButGetUnitType(but); | int unit_type = UI_but_unit_type_get(but); | ||||
| /* Time unit is a bit special, not handled by BKE_scene_unit_scale() for now. */ | /* Time unit is a bit special, not handled by BKE_scene_unit_scale() for now. */ | ||||
| if (unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */ | if (unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */ | ||||
| Scene *scene = CTX_data_scene(but->block->evil_C); | Scene *scene = CTX_data_scene(but->block->evil_C); | ||||
| return FRA2TIME(value); | return FRA2TIME(value); | ||||
| } | } | ||||
| else { | else { | ||||
| return BKE_scene_unit_scale(unit, RNA_SUBTYPE_UNIT_VALUE(unit_type), value); | return BKE_scene_unit_scale(unit, RNA_SUBTYPE_UNIT_VALUE(unit_type), value); | ||||
| } | } | ||||
| } | } | ||||
| /* str will be overwritten */ | /* str will be overwritten */ | ||||
| void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) | void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) | ||||
| { | { | ||||
| if (ui_is_but_unit(but)) { | if (ui_but_is_unit(but)) { | ||||
| UnitSettings *unit = but->block->unit; | UnitSettings *unit = but->block->unit; | ||||
| int unit_type = uiButGetUnitType(but); | int unit_type = UI_but_unit_type_get(but); | ||||
| char *orig_str; | char *orig_str; | ||||
| orig_str = BLI_strdup(str); | orig_str = BLI_strdup(str); | ||||
| bUnit_ToUnitAltName(str, maxlen, orig_str, unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type)); | bUnit_ToUnitAltName(str, maxlen, orig_str, unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type)); | ||||
| MEM_freeN(orig_str); | MEM_freeN(orig_str); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * \param float_precision Override the button precision. | * \param float_precision Override the button precision. | ||||
| */ | */ | ||||
| static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, bool pad, int float_precision) | static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, bool pad, int float_precision) | ||||
| { | { | ||||
| UnitSettings *unit = but->block->unit; | UnitSettings *unit = but->block->unit; | ||||
| const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; | const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; | ||||
| int unit_type = uiButGetUnitType(but); | int unit_type = UI_but_unit_type_get(but); | ||||
| int precision; | int precision; | ||||
| if (unit->scale_length < 0.0001f) unit->scale_length = 1.0f; // XXX do_versions | if (unit->scale_length < 0.0001f) unit->scale_length = 1.0f; // XXX do_versions | ||||
| /* Use precision override? */ | /* Use precision override? */ | ||||
| if (float_precision == -1) { | if (float_precision == -1) { | ||||
| /* Sanity checks */ | /* Sanity checks */ | ||||
| precision = (int)but->a2; | precision = (int)but->a2; | ||||
| if (precision > UI_PRECISION_FLOAT_MAX) precision = UI_PRECISION_FLOAT_MAX; | if (precision > UI_PRECISION_FLOAT_MAX) precision = UI_PRECISION_FLOAT_MAX; | ||||
| else if (precision == -1) precision = 2; | else if (precision == -1) precision = 2; | ||||
| } | } | ||||
| else { | else { | ||||
| precision = float_precision; | precision = float_precision; | ||||
| } | } | ||||
| bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision, | bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision, | ||||
| unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type), do_split, pad); | unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type), do_split, pad); | ||||
| } | } | ||||
| static float ui_get_but_step_unit(uiBut *but, float step_default) | static float ui_get_but_step_unit(uiBut *but, float step_default) | ||||
| { | { | ||||
| int unit_type = RNA_SUBTYPE_UNIT_VALUE(uiButGetUnitType(but)); | int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); | ||||
| double step; | double step; | ||||
| step = bUnit_ClosestScalar(ui_get_but_scale_unit(but, step_default), but->block->unit->system, unit_type); | step = bUnit_ClosestScalar(ui_get_but_scale_unit(but, step_default), but->block->unit->system, unit_type); | ||||
| /* -1 is an error value */ | /* -1 is an error value */ | ||||
| if (step != -1.0) { | if (step != -1.0) { | ||||
| BLI_assert(step > 0.0); | BLI_assert(step > 0.0); | ||||
| return (float)(step / ui_get_but_scale_unit(but, 1.0)) * 100.0f; | return (float)(step / ui_get_but_scale_unit(but, 1.0)) * 100.0f; | ||||
| } | } | ||||
| else { | else { | ||||
| return step_default; | return step_default; | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * \param float_precision For number buttons the precision to use or -1 to fallback to the button default. | * \param float_precision For number buttons the precision to use or -1 to fallback to the button default. | ||||
| */ | */ | ||||
| void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) | void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) | ||||
| { | { | ||||
| if (but->rnaprop && ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { | if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { | ||||
| PropertyType type; | PropertyType type; | ||||
| const char *buf = NULL; | const char *buf = NULL; | ||||
| int buf_len; | int buf_len; | ||||
| type = RNA_property_type(but->rnaprop); | type = RNA_property_type(but->rnaprop); | ||||
| if (type == PROP_STRING) { | if (type == PROP_STRING) { | ||||
| /* RNA string */ | /* RNA string */ | ||||
| Show All 20 Lines | if (!buf) { | ||||
| str[0] = '\0'; | str[0] = '\0'; | ||||
| } | } | ||||
| else if (buf && buf != str) { | else if (buf && buf != str) { | ||||
| /* string was too long, we have to truncate */ | /* string was too long, we have to truncate */ | ||||
| memcpy(str, buf, MIN2(maxlen, (size_t)(buf_len + 1))); | memcpy(str, buf, MIN2(maxlen, (size_t)(buf_len + 1))); | ||||
| MEM_freeN((void *)buf); | MEM_freeN((void *)buf); | ||||
| } | } | ||||
| } | } | ||||
| else if (but->type == TEX) { | else if (but->type == UI_BTYPE_TEXT) { | ||||
| /* string */ | /* string */ | ||||
| BLI_strncpy(str, but->poin, maxlen); | BLI_strncpy(str, but->poin, maxlen); | ||||
| return; | return; | ||||
| } | } | ||||
| else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { | else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { | ||||
| /* string */ | /* string */ | ||||
| BLI_strncpy(str, but->poin, maxlen); | BLI_strncpy(str, but->poin, maxlen); | ||||
| return; | return; | ||||
| } | } | ||||
| else if (ui_but_anim_expression_get(but, str, maxlen)) { | else if (ui_but_anim_expression_get(but, str, maxlen)) { | ||||
| /* driver expression */ | /* driver expression */ | ||||
| } | } | ||||
| else { | else { | ||||
| /* number editing */ | /* number editing */ | ||||
| double value; | double value; | ||||
| value = ui_get_but_val(but); | value = ui_but_value_get(but); | ||||
| if (ui_is_but_float(but)) { | if (ui_but_is_float(but)) { | ||||
| if (ui_is_but_unit(but)) { | if (ui_but_is_unit(but)) { | ||||
| ui_get_but_string_unit(but, str, maxlen, value, false, float_precision); | ui_get_but_string_unit(but, str, maxlen, value, false, float_precision); | ||||
| } | } | ||||
| else { | else { | ||||
| const int prec = (float_precision == -1) ? ui_but_float_precision(but, value) : float_precision; | const int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision; | ||||
| BLI_snprintf(str, maxlen, "%.*f", prec, value); | BLI_snprintf(str, maxlen, "%.*f", prec, value); | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| BLI_snprintf(str, maxlen, "%d", (int)value); | BLI_snprintf(str, maxlen, "%d", (int)value); | ||||
| } | } | ||||
| } | } | ||||
| void ui_get_but_string(uiBut *but, char *str, const size_t maxlen) | void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) | ||||
| { | { | ||||
| ui_get_but_string_ex(but, str, maxlen, -1); | ui_but_string_get_ex(but, str, maxlen, -1); | ||||
| } | } | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *value) | static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *value) | ||||
| { | { | ||||
| char str_unit_convert[256]; | char str_unit_convert[256]; | ||||
| const int unit_type = uiButGetUnitType(but); | const int unit_type = UI_but_unit_type_get(but); | ||||
| BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert)); | BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert)); | ||||
| /* ugly, use the draw string to get the value, | /* ugly, use the draw string to get the value, | ||||
| * this could cause problems if it includes some text which resolves to a unit */ | * this could cause problems if it includes some text which resolves to a unit */ | ||||
| bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr, | bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr, | ||||
| ui_get_but_scale_unit(but, 1.0), but->block->unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type)); | ui_get_but_scale_unit(but, 1.0), but->block->unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type)); | ||||
| return (BPY_button_exec(C, str_unit_convert, value, true) != -1); | return (BPY_button_exec(C, str_unit_convert, value, true) != -1); | ||||
| } | } | ||||
| #endif /* WITH_PYTHON */ | #endif /* WITH_PYTHON */ | ||||
| bool ui_set_but_string_eval_num(bContext *C, uiBut *but, const char *str, double *value) | bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *value) | ||||
| { | { | ||||
| bool ok = false; | bool ok = false; | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| if (str[0] != '\0') { | if (str[0] != '\0') { | ||||
| bool is_unit_but = (ui_is_but_float(but) && ui_is_but_unit(but)); | bool is_unit_but = (ui_but_is_float(but) && ui_but_is_unit(but)); | ||||
| /* only enable verbose if we won't run again with units */ | /* only enable verbose if we won't run again with units */ | ||||
| if (BPY_button_exec(C, str, value, is_unit_but == false) != -1) { | if (BPY_button_exec(C, str, value, is_unit_but == false) != -1) { | ||||
| /* if the value parsed ok without unit conversion this button may still need a unit multiplier */ | /* if the value parsed ok without unit conversion this button may still need a unit multiplier */ | ||||
| if (is_unit_but) { | if (is_unit_but) { | ||||
| char str_new[128]; | char str_new[128]; | ||||
| BLI_snprintf(str_new, sizeof(str_new), "%f", *value); | BLI_snprintf(str_new, sizeof(str_new), "%f", *value); | ||||
| ok = ui_set_but_string_eval_num_unit(C, but, str_new, value); | ok = ui_set_but_string_eval_num_unit(C, but, str_new, value); | ||||
| Show All 17 Lines | #else /* WITH_PYTHON */ | ||||
| (void)but; | (void)but; | ||||
| #endif /* WITH_PYTHON */ | #endif /* WITH_PYTHON */ | ||||
| return ok; | return ok; | ||||
| } | } | ||||
| bool ui_set_but_string(bContext *C, uiBut *but, const char *str) | bool ui_but_string_set(bContext *C, uiBut *but, const char *str) | ||||
| { | { | ||||
| if (but->rnaprop && ELEM(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { | if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { | ||||
| if (RNA_property_editable(&but->rnapoin, but->rnaprop)) { | if (RNA_property_editable(&but->rnapoin, but->rnaprop)) { | ||||
| PropertyType type; | PropertyType type; | ||||
| type = RNA_property_type(but->rnaprop); | type = RNA_property_type(but->rnaprop); | ||||
| if (type == PROP_STRING) { | if (type == PROP_STRING) { | ||||
| /* RNA string */ | /* RNA string */ | ||||
| RNA_property_string_set(&but->rnapoin, but->rnaprop, str); | RNA_property_string_set(&but->rnapoin, but->rnaprop, str); | ||||
| Show All 28 Lines | if (RNA_property_editable(&but->rnapoin, but->rnaprop)) { | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (but->type == TEX) { | else if (but->type == UI_BTYPE_TEXT) { | ||||
| /* string */ | /* string */ | ||||
| if (ui_is_but_utf8(but)) BLI_strncpy_utf8(but->poin, str, but->hardmax); | if (ui_but_is_utf8(but)) BLI_strncpy_utf8(but->poin, str, but->hardmax); | ||||
| else BLI_strncpy(but->poin, str, but->hardmax); | else BLI_strncpy(but->poin, str, but->hardmax); | ||||
| return true; | return true; | ||||
| } | } | ||||
| else if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { | else if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) { | ||||
| /* string */ | /* string */ | ||||
| BLI_strncpy(but->poin, str, but->hardmax); | BLI_strncpy(but->poin, str, but->hardmax); | ||||
| return true; | return true; | ||||
| } | } | ||||
| else if (ui_but_anim_expression_set(but, str)) { | else if (ui_but_anim_expression_set(but, str)) { | ||||
| /* driver expression */ | /* driver expression */ | ||||
| return true; | return true; | ||||
| } | } | ||||
| else if (str[0] == '#') { | else if (str[0] == '#') { | ||||
| /* shortcut to create new driver expression (versus immediate Py-execution) */ | /* shortcut to create new driver expression (versus immediate Py-execution) */ | ||||
| return ui_but_anim_expression_create(but, str + 1); | return ui_but_anim_expression_create(but, str + 1); | ||||
| } | } | ||||
| else { | else { | ||||
| /* number editing */ | /* number editing */ | ||||
| double value; | double value; | ||||
| if (ui_set_but_string_eval_num(C, but, str, &value) == false) { | if (ui_but_string_set_eval_num(C, but, str, &value) == false) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (!ui_is_but_float(but)) value = (int)floor(value + 0.5); | if (!ui_but_is_float(but)) value = (int)floor(value + 0.5); | ||||
| /* not that we use hard limits here */ | /* not that we use hard limits here */ | ||||
| if (value < (double)but->hardmin) value = but->hardmin; | if (value < (double)but->hardmin) value = but->hardmin; | ||||
| if (value > (double)but->hardmax) value = but->hardmax; | if (value > (double)but->hardmax) value = but->hardmax; | ||||
| ui_set_but_val(but, value); | ui_but_value_set(but, value); | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void ui_set_but_default(bContext *C, const bool all, const bool use_afterfunc) | void ui_but_default_set(bContext *C, const bool all, const bool use_afterfunc) | ||||
| { | { | ||||
| const char *opstring = "UI_OT_reset_default_button"; | const char *opstring = "UI_OT_reset_default_button"; | ||||
| if (use_afterfunc) { | if (use_afterfunc) { | ||||
| PointerRNA *ptr; | PointerRNA *ptr; | ||||
| wmOperatorType *ot = WM_operatortype_find(opstring, 0); | wmOperatorType *ot = WM_operatortype_find(opstring, 0); | ||||
| ptr = ui_handle_afterfunc_add_operator(ot, WM_OP_EXEC_DEFAULT, true); | ptr = ui_handle_afterfunc_add_operator(ot, WM_OP_EXEC_DEFAULT, true); | ||||
| RNA_boolean_set(ptr, "all", all); | RNA_boolean_set(ptr, "all", all); | ||||
| ▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | if (value_max - 1e-10 > softmax) { | ||||
| if (softmax > (double)but->hardmax) | if (softmax > (double)but->hardmax) | ||||
| softmax = but->hardmax; | softmax = but->hardmax; | ||||
| } | } | ||||
| but->softmin = softmin; | but->softmin = softmin; | ||||
| but->softmax = softmax; | but->softmax = softmax; | ||||
| } | } | ||||
| else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) { | else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) { | ||||
| float value = ui_get_but_val(but); | float value = ui_but_value_get(but); | ||||
| CLAMP(value, but->hardmin, but->hardmax); | CLAMP(value, but->hardmin, but->hardmax); | ||||
| but->softmin = min_ff(but->softmin, value); | but->softmin = min_ff(but->softmin, value); | ||||
| but->softmax = max_ff(but->softmax, value); | but->softmax = max_ff(but->softmax, value); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| } | } | ||||
| } | } | ||||
| /* ******************* Free ********************/ | /* ******************* Free ********************/ | ||||
| static void ui_free_link(uiLink *link) | static void ui_free_link(uiLink *link) | ||||
| { | { | ||||
| if (link) { | if (link) { | ||||
| BLI_freelistN(&link->lines); | BLI_freelistN(&link->lines); | ||||
| MEM_freeN(link); | MEM_freeN(link); | ||||
| } | } | ||||
| } | } | ||||
| /* can be called with C==NULL */ | /* can be called with C==NULL */ | ||||
| static void ui_free_but(const bContext *C, uiBut *but) | static void ui_but_free(const bContext *C, uiBut *but) | ||||
| { | { | ||||
| if (but->opptr) { | if (but->opptr) { | ||||
| WM_operator_properties_free(but->opptr); | WM_operator_properties_free(but->opptr); | ||||
| MEM_freeN(but->opptr); | MEM_freeN(but->opptr); | ||||
| } | } | ||||
| if (but->func_argN) { | if (but->func_argN) { | ||||
| MEM_freeN(but->func_argN); | MEM_freeN(but->func_argN); | ||||
| } | } | ||||
| if (but->active) { | if (but->active) { | ||||
| /* XXX solve later, buttons should be free-able without context ideally, | /* XXX solve later, buttons should be free-able without context ideally, | ||||
| * however they may have open tooltips or popup windows, which need to | * however they may have open tooltips or popup windows, which need to | ||||
| * be closed using a context pointer */ | * be closed using a context pointer */ | ||||
| if (C) { | if (C) { | ||||
| ui_button_active_free(C, but); | ui_but_active_free(C, but); | ||||
| } | } | ||||
| else { | else { | ||||
| if (but->active) { | if (but->active) { | ||||
| MEM_freeN(but->active); | MEM_freeN(but->active); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (but->str && but->str != but->strdata) { | if (but->str && but->str != but->strdata) { | ||||
| MEM_freeN(but->str); | MEM_freeN(but->str); | ||||
| } | } | ||||
| ui_free_link(but->link); | ui_free_link(but->link); | ||||
| if ((but->type == BUT_IMAGE) && but->poin) { | if ((but->type == UI_BTYPE_IMAGE) && but->poin) { | ||||
| IMB_freeImBuf((struct ImBuf *)but->poin); | IMB_freeImBuf((struct ImBuf *)but->poin); | ||||
| } | } | ||||
| BLI_assert(UI_butstore_is_registered(but->block, but) == false); | BLI_assert(UI_butstore_is_registered(but->block, but) == false); | ||||
| MEM_freeN(but); | MEM_freeN(but); | ||||
| } | } | ||||
| /* can be called with C==NULL */ | /* can be called with C==NULL */ | ||||
| void uiFreeBlock(const bContext *C, uiBlock *block) | void UI_block_free(const bContext *C, uiBlock *block) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| UI_butstore_clear(block); | UI_butstore_clear(block); | ||||
| while ((but = BLI_pophead(&block->buttons))) { | while ((but = BLI_pophead(&block->buttons))) { | ||||
| ui_free_but(C, but); | ui_but_free(C, but); | ||||
| } | } | ||||
| if (block->unit) { | if (block->unit) { | ||||
| MEM_freeN(block->unit); | MEM_freeN(block->unit); | ||||
| } | } | ||||
| if (block->func_argN) { | if (block->func_argN) { | ||||
| MEM_freeN(block->func_argN); | MEM_freeN(block->func_argN); | ||||
| } | } | ||||
| CTX_store_free_list(&block->contexts); | CTX_store_free_list(&block->contexts); | ||||
| BLI_freelistN(&block->saferct); | BLI_freelistN(&block->saferct); | ||||
| BLI_freelistN(&block->color_pickers.list); | BLI_freelistN(&block->color_pickers.list); | ||||
| MEM_freeN(block); | MEM_freeN(block); | ||||
| } | } | ||||
| /* can be called with C==NULL */ | /* can be called with C==NULL */ | ||||
| void uiFreeBlocks(const bContext *C, ListBase *lb) | void UI_blocklist_free(const bContext *C, ListBase *lb) | ||||
| { | { | ||||
| uiBlock *block; | uiBlock *block; | ||||
| while ((block = BLI_pophead(lb))) { | while ((block = BLI_pophead(lb))) { | ||||
| uiFreeBlock(C, block); | UI_block_free(C, block); | ||||
| } | } | ||||
| } | } | ||||
| void uiFreeInactiveBlocks(const bContext *C, ListBase *lb) | void UI_blocklist_free_inactive(const bContext *C, ListBase *lb) | ||||
| { | { | ||||
| uiBlock *block, *nextblock; | uiBlock *block, *nextblock; | ||||
| for (block = lb->first; block; block = nextblock) { | for (block = lb->first; block; block = nextblock) { | ||||
| nextblock = block->next; | nextblock = block->next; | ||||
| if (!block->handle) { | if (!block->handle) { | ||||
| if (!block->active) { | if (!block->active) { | ||||
| BLI_remlink(lb, block); | BLI_remlink(lb, block); | ||||
| uiFreeBlock(C, block); | UI_block_free(C, block); | ||||
| } | } | ||||
| else | else | ||||
| block->active = 0; | block->active = 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void uiBlockSetRegion(uiBlock *block, ARegion *region) | void UI_block_region_set(uiBlock *block, ARegion *region) | ||||
| { | { | ||||
| ListBase *lb = ®ion->uiblocks; | ListBase *lb = ®ion->uiblocks; | ||||
| uiBlock *oldblock = NULL; | uiBlock *oldblock = NULL; | ||||
| /* each listbase only has one block with this name, free block | /* each listbase only has one block with this name, free block | ||||
| * if is already there so it can be rebuilt from scratch */ | * if is already there so it can be rebuilt from scratch */ | ||||
| if (lb) { | if (lb) { | ||||
| oldblock = BLI_findstring(lb, block->name, offsetof(uiBlock, name)); | oldblock = BLI_findstring(lb, block->name, offsetof(uiBlock, name)); | ||||
| if (oldblock) { | if (oldblock) { | ||||
| oldblock->active = 0; | oldblock->active = 0; | ||||
| oldblock->panel = NULL; | oldblock->panel = NULL; | ||||
| oldblock->handle = NULL; | oldblock->handle = NULL; | ||||
| } | } | ||||
| /* at the beginning of the list! for dynamical menus/blocks */ | /* at the beginning of the list! for dynamical menus/blocks */ | ||||
| BLI_addhead(lb, block); | BLI_addhead(lb, block); | ||||
| } | } | ||||
| block->oldblock = oldblock; | block->oldblock = oldblock; | ||||
| } | } | ||||
| uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, short dt) | uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, short dt) | ||||
| { | { | ||||
| uiBlock *block; | uiBlock *block; | ||||
| wmWindow *window; | wmWindow *window; | ||||
| Scene *scn; | Scene *scn; | ||||
| int getsizex, getsizey; | int getsizex, getsizey; | ||||
| window = CTX_wm_window(C); | window = CTX_wm_window(C); | ||||
| scn = CTX_data_scene(C); | scn = CTX_data_scene(C); | ||||
| Show All 16 Lines | if (scn) { | ||||
| /* copy to avoid crash when scene gets deleted with ui still open */ | /* copy to avoid crash when scene gets deleted with ui still open */ | ||||
| block->unit = MEM_mallocN(sizeof(scn->unit), "UI UnitSettings"); | block->unit = MEM_mallocN(sizeof(scn->unit), "UI UnitSettings"); | ||||
| memcpy(block->unit, &scn->unit, sizeof(scn->unit)); | memcpy(block->unit, &scn->unit, sizeof(scn->unit)); | ||||
| } | } | ||||
| BLI_strncpy(block->name, name, sizeof(block->name)); | BLI_strncpy(block->name, name, sizeof(block->name)); | ||||
| if (region) | if (region) | ||||
| uiBlockSetRegion(block, region); | UI_block_region_set(block, region); | ||||
| /* window matrix and aspect */ | /* window matrix and aspect */ | ||||
| if (region && region->swinid) { | if (region && region->swinid) { | ||||
| wm_subwindow_matrix_get(window, region->swinid, block->winmat); | wm_subwindow_matrix_get(window, region->swinid, block->winmat); | ||||
| wm_subwindow_size_get(window, region->swinid, &getsizex, &getsizey); | wm_subwindow_size_get(window, region->swinid, &getsizex, &getsizey); | ||||
| block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); | block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); | ||||
| } | } | ||||
| else { | else { | ||||
| /* no subwindow created yet, for menus for example, so we | /* no subwindow created yet, for menus for example, so we | ||||
| * use the main window instead, since buttons are created | * use the main window instead, since buttons are created | ||||
| * there anyway */ | * there anyway */ | ||||
| wm_subwindow_matrix_get(window, window->screen->mainwin, block->winmat); | wm_subwindow_matrix_get(window, window->screen->mainwin, block->winmat); | ||||
| wm_subwindow_size_get(window, window->screen->mainwin, &getsizex, &getsizey); | wm_subwindow_size_get(window, window->screen->mainwin, &getsizex, &getsizey); | ||||
| block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); | block->aspect = 2.0f / fabsf(getsizex * block->winmat[0][0]); | ||||
| block->auto_open = true; | block->auto_open = true; | ||||
| block->flag |= UI_BLOCK_LOOP; /* tag as menu */ | block->flag |= UI_BLOCK_LOOP; /* tag as menu */ | ||||
| } | } | ||||
| return block; | return block; | ||||
| } | } | ||||
| uiBlock *uiGetBlock(const char *name, ARegion *ar) | uiBlock *UI_block_find_in_region(const char *name, ARegion *ar) | ||||
| { | { | ||||
| return BLI_findstring(&ar->uiblocks, name, offsetof(uiBlock, name)); | return BLI_findstring(&ar->uiblocks, name, offsetof(uiBlock, name)); | ||||
| } | } | ||||
| void uiBlockSetEmboss(uiBlock *block, char dt) | void UI_block_emboss_set(uiBlock *block, char dt) | ||||
| { | { | ||||
| block->dt = dt; | block->dt = dt; | ||||
| } | } | ||||
| void ui_check_but(uiBut *but) | void ui_but_update(uiBut *but) | ||||
| { | { | ||||
| /* if something changed in the button */ | /* if something changed in the button */ | ||||
| double value = UI_BUT_VALUE_UNSET; | double value = UI_BUT_VALUE_UNSET; | ||||
| // float okwidth; // UNUSED | // float okwidth; // UNUSED | ||||
| ui_check_but_select(but, &value); | ui_but_update_select_flag(but, &value); | ||||
| /* only update soft range while not editing */ | /* only update soft range while not editing */ | ||||
| if (!(but->editval || but->editstr || but->editvec)) { | if (!(but->editval || but->editstr || but->editvec)) { | ||||
| if ((but->rnaprop != NULL) || | if ((but->rnaprop != NULL) || | ||||
| (but->poin && (but->pointype & UI_BUT_POIN_TYPES))) | (but->poin && (but->pointype & UI_BUT_POIN_TYPES))) | ||||
| { | { | ||||
| ui_set_but_soft_range(but); | ui_set_but_soft_range(but); | ||||
| } | } | ||||
| } | } | ||||
| /* test for min and max, icon sliders, etc */ | /* test for min and max, icon sliders, etc */ | ||||
| switch (but->type) { | switch (but->type) { | ||||
| case NUM: | case UI_BTYPE_NUM: | ||||
| case SCROLL: | case UI_BTYPE_SCROLL: | ||||
| case NUMSLI: | case UI_BTYPE_NUM_SLIDER: | ||||
| UI_GET_BUT_VALUE_INIT(but, value); | UI_GET_BUT_VALUE_INIT(but, value); | ||||
| if (value < (double)but->hardmin) ui_set_but_val(but, but->hardmin); | if (value < (double)but->hardmin) ui_but_value_set(but, but->hardmin); | ||||
| else if (value > (double)but->hardmax) ui_set_but_val(but, but->hardmax); | else if (value > (double)but->hardmax) ui_but_value_set(but, but->hardmax); | ||||
| break; | break; | ||||
| case ICONTOG: | case UI_BTYPE_ICON_TOGGLE: | ||||
| case ICONTOGN: | case UI_BTYPE_ICON_TOGGLE_N: | ||||
| if (!but->rnaprop || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) { | if (!but->rnaprop || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) { | ||||
| if (but->flag & UI_SELECT) but->iconadd = 1; | if (but->flag & UI_SELECT) but->iconadd = 1; | ||||
| else but->iconadd = 0; | else but->iconadd = 0; | ||||
| } | } | ||||
| break; | break; | ||||
| /* quiet warnings for unhandled types */ | /* quiet warnings for unhandled types */ | ||||
| default: | default: | ||||
| break; | break; | ||||
| } | } | ||||
| /* safety is 4 to enable small number buttons (like 'users') */ | /* safety is 4 to enable small number buttons (like 'users') */ | ||||
| // okwidth = -4 + (BLI_rcti_size_x(&but->rect)); // UNUSED | // okwidth = -4 + (BLI_rcti_size_x(&but->rect)); // UNUSED | ||||
| /* name: */ | /* name: */ | ||||
| switch (but->type) { | switch (but->type) { | ||||
| case MENU: | case UI_BTYPE_MENU: | ||||
| if (BLI_rctf_size_x(&but->rect) > 24.0f) { | if (BLI_rctf_size_x(&but->rect) > 24.0f) { | ||||
| /* only needed for menus in popup blocks that don't recreate buttons on redraw */ | /* only needed for menus in popup blocks that don't recreate buttons on redraw */ | ||||
| if (but->block->flag & UI_BLOCK_LOOP) { | if (but->block->flag & UI_BLOCK_LOOP) { | ||||
| if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) { | if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) { | ||||
| int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop); | int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop); | ||||
| const char *buf; | const char *buf; | ||||
| if (RNA_property_enum_name_gettexted(but->block->evil_C, | if (RNA_property_enum_name_gettexted(but->block->evil_C, | ||||
| &but->rnapoin, but->rnaprop, value, &buf)) | &but->rnapoin, but->rnaprop, value, &buf)) | ||||
| { | { | ||||
| BLI_strncpy(but->str, buf, sizeof(but->strdata)); | BLI_strncpy(but->str, buf, sizeof(but->strdata)); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| BLI_strncpy(but->drawstr, but->str, sizeof(but->drawstr)); | BLI_strncpy(but->drawstr, but->str, sizeof(but->drawstr)); | ||||
| } | } | ||||
| break; | break; | ||||
| case NUM: | case UI_BTYPE_NUM: | ||||
| case NUMSLI: | case UI_BTYPE_NUM_SLIDER: | ||||
| if (!but->editstr) { | if (!but->editstr) { | ||||
| const char *drawstr_suffix = NULL; | const char *drawstr_suffix = NULL; | ||||
| size_t slen; | size_t slen; | ||||
| UI_GET_BUT_VALUE_INIT(but, value); | UI_GET_BUT_VALUE_INIT(but, value); | ||||
| slen = BLI_strncpy_rlen(but->drawstr, but->str, sizeof(but->drawstr)); | slen = BLI_strncpy_rlen(but->drawstr, but->str, sizeof(but->drawstr)); | ||||
| if (ui_is_but_float(but)) { | if (ui_but_is_float(but)) { | ||||
| if (value == (double) FLT_MAX) { | if (value == (double) FLT_MAX) { | ||||
| slen += BLI_strncpy_rlen(but->drawstr + slen, "inf", sizeof(but->drawstr) - slen); | slen += BLI_strncpy_rlen(but->drawstr + slen, "inf", sizeof(but->drawstr) - slen); | ||||
| } | } | ||||
| else if (value == (double) -FLT_MAX) { | else if (value == (double) -FLT_MAX) { | ||||
| slen += BLI_strncpy_rlen(but->drawstr + slen, "-inf", sizeof(but->drawstr) - slen); | slen += BLI_strncpy_rlen(but->drawstr + slen, "-inf", sizeof(but->drawstr) - slen); | ||||
| } | } | ||||
| /* support length type buttons */ | /* support length type buttons */ | ||||
| else if (ui_is_but_unit(but)) { | else if (ui_but_is_unit(but)) { | ||||
| char new_str[sizeof(but->drawstr)]; | char new_str[sizeof(but->drawstr)]; | ||||
| ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1); | ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1); | ||||
| slen += BLI_strncpy_rlen(but->drawstr + slen, new_str, sizeof(but->drawstr) - slen); | slen += BLI_strncpy_rlen(but->drawstr + slen, new_str, sizeof(but->drawstr) - slen); | ||||
| } | } | ||||
| else { | else { | ||||
| const int prec = ui_but_float_precision(but, value); | const int prec = ui_but_calc_float_precision(but, value); | ||||
| slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value); | slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%d", (int)value); | slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%d", (int)value); | ||||
| } | } | ||||
| if (but->rnaprop) { | if (but->rnaprop) { | ||||
| Show All 9 Lines | case UI_BTYPE_NUM_SLIDER: | ||||
| if (drawstr_suffix) { | if (drawstr_suffix) { | ||||
| BLI_strncpy(but->drawstr + slen, drawstr_suffix, sizeof(but->drawstr) - slen); | BLI_strncpy(but->drawstr + slen, drawstr_suffix, sizeof(but->drawstr) - slen); | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| case LABEL: | case UI_BTYPE_LABEL: | ||||
| if (ui_is_but_float(but)) { | if (ui_but_is_float(but)) { | ||||
| int prec; | int prec; | ||||
| UI_GET_BUT_VALUE_INIT(but, value); | UI_GET_BUT_VALUE_INIT(but, value); | ||||
| prec = ui_but_float_precision(but, value); | prec = ui_but_calc_float_precision(but, value); | ||||
| BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); | BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); | BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); | ||||
| } | } | ||||
| break; | break; | ||||
| case TEX: | case UI_BTYPE_TEXT: | ||||
| case SEARCH_MENU: | case UI_BTYPE_SEARCH_MENU: | ||||
| case SEARCH_MENU_UNLINK: | case UI_BTYPE_SEARCH_MENU_UNLINK: | ||||
| if (!but->editstr) { | if (!but->editstr) { | ||||
| char str[UI_MAX_DRAW_STR]; | char str[UI_MAX_DRAW_STR]; | ||||
| ui_get_but_string(but, str, UI_MAX_DRAW_STR); | ui_but_string_get(but, str, UI_MAX_DRAW_STR); | ||||
| BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str); | BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str); | ||||
| } | } | ||||
| break; | break; | ||||
| case KEYEVT: | case UI_BTYPE_KEY_EVENT: | ||||
| { | { | ||||
| const char *str; | const char *str; | ||||
| if (but->flag & UI_SELECT) { | if (but->flag & UI_SELECT) { | ||||
| str = "Press a key"; | str = "Press a key"; | ||||
| } | } | ||||
| else { | else { | ||||
| UI_GET_BUT_VALUE_INIT(but, value); | UI_GET_BUT_VALUE_INIT(but, value); | ||||
| str = WM_key_event_string((short)value); | str = WM_key_event_string((short)value); | ||||
| } | } | ||||
| BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str); | BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str); | ||||
| break; | break; | ||||
| } | } | ||||
| case HOTKEYEVT: | case UI_BTYPE_HOTKEY_EVENT: | ||||
| if (but->flag & UI_SELECT) { | if (but->flag & UI_SELECT) { | ||||
| if (but->modifier_key) { | if (but->modifier_key) { | ||||
| char *str = but->drawstr; | char *str = but->drawstr; | ||||
| but->drawstr[0] = '\0'; | but->drawstr[0] = '\0'; | ||||
| if (but->modifier_key & KM_SHIFT) | if (but->modifier_key & KM_SHIFT) | ||||
| str += BLI_strcpy_rlen(str, "Shift "); | str += BLI_strcpy_rlen(str, "Shift "); | ||||
| Show All 10 Lines | case UI_BTYPE_HOTKEY_EVENT: | ||||
| BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR); | BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR); | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); | BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); | ||||
| break; | break; | ||||
| case HSVCUBE: | case UI_BTYPE_HSVCUBE: | ||||
| case HSVCIRCLE: | case UI_BTYPE_HSVCIRCLE: | ||||
| break; | break; | ||||
| default: | default: | ||||
| BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); | BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); | ||||
| break; | break; | ||||
| } | } | ||||
| /* if we are doing text editing, this will override the drawstr */ | /* if we are doing text editing, this will override the drawstr */ | ||||
| if (but->editstr) | if (but->editstr) | ||||
| but->drawstr[0] = '\0'; | but->drawstr[0] = '\0'; | ||||
| /* text clipping moved to widget drawing code itself */ | /* text clipping moved to widget drawing code itself */ | ||||
| } | } | ||||
| void uiBlockBeginAlign(uiBlock *block) | void UI_block_align_begin(uiBlock *block) | ||||
| { | { | ||||
| /* if other align was active, end it */ | /* if other align was active, end it */ | ||||
| if (block->flag & UI_BUT_ALIGN) uiBlockEndAlign(block); | if (block->flag & UI_BUT_ALIGN) UI_block_align_end(block); | ||||
| block->flag |= UI_BUT_ALIGN_DOWN; | block->flag |= UI_BUT_ALIGN_DOWN; | ||||
| block->alignnr++; | block->alignnr++; | ||||
| /* buttons declared after this call will get this align nr */ // XXX flag? | /* buttons declared after this call will get this align nr */ // XXX flag? | ||||
| } | } | ||||
| static bool buts_are_horiz(uiBut *but1, uiBut *but2) | static bool buts_are_horiz(uiBut *but1, uiBut *but2) | ||||
| Show All 9 Lines | static bool buts_are_horiz(uiBut *but1, uiBut *but2) | ||||
| } | } | ||||
| dx = fabsf(but1->rect.xmax - but2->rect.xmin); | dx = fabsf(but1->rect.xmax - but2->rect.xmin); | ||||
| dy = fabsf(but1->rect.ymin - but2->rect.ymax); | dy = fabsf(but1->rect.ymin - but2->rect.ymax); | ||||
| return (dx <= dy); | return (dx <= dy); | ||||
| } | } | ||||
| void uiBlockEndAlign(uiBlock *block) | void UI_block_align_end(uiBlock *block) | ||||
| { | { | ||||
| block->flag &= ~UI_BUT_ALIGN; /* all 4 flags */ | block->flag &= ~UI_BUT_ALIGN; /* all 4 flags */ | ||||
| } | } | ||||
| bool ui_but_can_align(uiBut *but) | bool ui_but_can_align(uiBut *but) | ||||
| { | { | ||||
| return !ELEM(but->type, LABEL, OPTION, OPTIONN, SEPR, SEPRLINE); | return !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE); | ||||
| } | } | ||||
| static void ui_block_do_align_but(uiBut *first, short nr) | static void ui_block_align_calc_but(uiBut *first, short nr) | ||||
| { | { | ||||
| uiBut *prev, *but = NULL, *next; | uiBut *prev, *but = NULL, *next; | ||||
| int flag = 0, cols = 0, rows = 0; | int flag = 0, cols = 0, rows = 0; | ||||
| /* auto align */ | /* auto align */ | ||||
| for (but = first; but && but->alignnr == nr; but = but->next) { | for (but = first; but && but->alignnr == nr; but = but->next) { | ||||
| if (but->next && but->next->alignnr == nr) { | if (but->next && but->next->alignnr == nr) { | ||||
| ▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | if (prev) { | ||||
| /* the previous button is not a single one in its row */ | /* the previous button is not a single one in its row */ | ||||
| but->rect.ymax = prev->rect.ymin; | but->rect.ymax = prev->rect.ymin; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void ui_block_do_align(uiBlock *block) | void ui_block_align_calc(uiBlock *block) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| short nr; | short nr; | ||||
| /* align buttons with same align nr */ | /* align buttons with same align nr */ | ||||
| for (but = block->buttons.first; but; ) { | for (but = block->buttons.first; but; ) { | ||||
| if (but->alignnr) { | if (but->alignnr) { | ||||
| nr = but->alignnr; | nr = but->alignnr; | ||||
| ui_block_do_align_but(but, nr); | ui_block_align_calc_but(but, nr); | ||||
| /* skip with same number */ | /* skip with same number */ | ||||
| for (; but && but->alignnr == nr; but = but->next) { | for (; but && but->alignnr == nr; but = but->next) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| if (!but) { | if (!but) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| but = but->next; | but = but->next; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| struct ColorManagedDisplay *ui_block_display_get(uiBlock *block) | struct ColorManagedDisplay *ui_block_cm_display_get(uiBlock *block) | ||||
| { | { | ||||
| return IMB_colormanagement_display_get_named(block->display_device); | return IMB_colormanagement_display_get_named(block->display_device); | ||||
| } | } | ||||
| void ui_block_to_display_space_v3(uiBlock *block, float pixel[3]) | void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]) | ||||
| { | { | ||||
| struct ColorManagedDisplay *display = ui_block_display_get(block); | struct ColorManagedDisplay *display = ui_block_cm_display_get(block); | ||||
| IMB_colormanagement_scene_linear_to_display_v3(pixel, display); | IMB_colormanagement_scene_linear_to_display_v3(pixel, display); | ||||
| } | } | ||||
| void ui_block_to_scene_linear_v3(uiBlock *block, float pixel[3]) | void ui_block_cm_to_scene_linear_v3(uiBlock *block, float pixel[3]) | ||||
| { | { | ||||
| struct ColorManagedDisplay *display = ui_block_display_get(block); | struct ColorManagedDisplay *display = ui_block_cm_display_get(block); | ||||
| IMB_colormanagement_display_to_scene_linear_v3(pixel, display); | IMB_colormanagement_display_to_scene_linear_v3(pixel, display); | ||||
| } | } | ||||
| /** | /** | ||||
| * \brief ui_def_but is the function that draws many button types | * \brief ui_def_but is the function that draws many button types | ||||
| * | * | ||||
| * \param x,y The lower left hand corner of the button (X axis) | * \param x,y The lower left hand corner of the button (X axis) | ||||
| Show All 9 Lines | static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, | ||||
| void *poin, float min, float max, float a1, float a2, const char *tip) | void *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| int slen; | int slen; | ||||
| BLI_assert(width >= 0 && height >= 0); | BLI_assert(width >= 0 && height >= 0); | ||||
| /* we could do some more error checks here */ | /* we could do some more error checks here */ | ||||
| if ((type & BUTTYPE) == LABEL) { | if ((type & BUTTYPE) == UI_BTYPE_LABEL) { | ||||
| BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == false); | BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == false); | ||||
| } | } | ||||
| if (type & UI_BUT_POIN_TYPES) { /* a pointer is required */ | if (type & UI_BUT_POIN_TYPES) { /* a pointer is required */ | ||||
| if (poin == NULL) { | if (poin == NULL) { | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, | ||||
| but->func_arg2 = block->func_arg2; | but->func_arg2 = block->func_arg2; | ||||
| but->funcN = block->funcN; | but->funcN = block->funcN; | ||||
| if (block->func_argN) | if (block->func_argN) | ||||
| but->func_argN = MEM_dupallocN(block->func_argN); | but->func_argN = MEM_dupallocN(block->func_argN); | ||||
| but->pos = -1; /* cursor invisible */ | but->pos = -1; /* cursor invisible */ | ||||
| if (ELEM(but->type, NUM, NUMSLI)) { /* add a space to name */ | if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* add a space to name */ | ||||
| /* slen remains unchanged from previous assignment, ensure this stays true */ | /* slen remains unchanged from previous assignment, ensure this stays true */ | ||||
| if (slen > 0 && slen < UI_MAX_NAME_STR - 2) { | if (slen > 0 && slen < UI_MAX_NAME_STR - 2) { | ||||
| if (but->str[slen - 1] != ' ') { | if (but->str[slen - 1] != ' ') { | ||||
| but->str[slen] = ' '; | but->str[slen] = ' '; | ||||
| but->str[slen + 1] = 0; | but->str[slen + 1] = 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (block->flag & UI_BLOCK_RADIAL) { | if (block->flag & UI_BLOCK_RADIAL) { | ||||
| but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); | but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); | ||||
| } | } | ||||
| else if ((block->flag & UI_BLOCK_LOOP) || | else if ((block->flag & UI_BLOCK_LOOP) || | ||||
| ELEM(but->type, MENU, TEX, LABEL, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK)) | ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_TEXT, UI_BTYPE_LABEL, UI_BTYPE_BLOCK, UI_BTYPE_BUT_MENU, UI_BTYPE_SEARCH_MENU, UI_BTYPE_PROGRESS_BAR, UI_BTYPE_SEARCH_MENU_UNLINK)) | ||||
| { | { | ||||
| but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); | but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); | ||||
| } | } | ||||
| #ifdef USE_NUMBUTS_LR_ALIGN | #ifdef USE_NUMBUTS_LR_ALIGN | ||||
| else if (ELEM(but->type, NUM, NUMSLI)) { | else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { | ||||
| but->drawflag |= UI_BUT_TEXT_LEFT; | but->drawflag |= UI_BUT_TEXT_LEFT; | ||||
| } | } | ||||
| #endif | #endif | ||||
| but->drawflag |= (block->flag & UI_BUT_ALIGN); | but->drawflag |= (block->flag & UI_BUT_ALIGN); | ||||
| if (but->lock == true) { | if (but->lock == true) { | ||||
| if (but->lockstr) { | if (but->lockstr) { | ||||
| but->flag |= UI_BUT_DISABLED; | but->flag |= UI_BUT_DISABLED; | ||||
| } | } | ||||
| } | } | ||||
| /* keep track of UI_interface.h */ | /* keep track of UI_interface.h */ | ||||
| if (ELEM(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR, SEPRLINE, GRIP)) {} | if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_BUT, UI_BTYPE_LABEL, UI_BTYPE_PULLDOWN, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX, UI_BTYPE_BUT_MENU, UI_BTYPE_SCROLL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_GRIP)) {} | ||||
| else if (but->type >= SEARCH_MENU) {} | else if (but->type >= UI_BTYPE_SEARCH_MENU) {} | ||||
| else but->flag |= UI_BUT_UNDO; | else but->flag |= UI_BUT_UNDO; | ||||
| BLI_addtail(&block->buttons, but); | BLI_addtail(&block->buttons, but); | ||||
| if (block->curlayout) | if (block->curlayout) | ||||
| ui_layout_add_but(block->curlayout, but); | ui_layout_add_but(block->curlayout, but); | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| Show All 25 Lines | static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p) | ||||
| uiLayout *split, *column = NULL; | uiLayout *split, *column = NULL; | ||||
| int totitems = 0; | int totitems = 0; | ||||
| int columns, rows, a, b; | int columns, rows, a, b; | ||||
| int column_start = 0, column_end = 0; | int column_start = 0, column_end = 0; | ||||
| int nbr_entries_nosepr = 0; | int nbr_entries_nosepr = 0; | ||||
| uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); | UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); | ||||
| RNA_property_enum_items_gettexted(block->evil_C, &but->rnapoin, but->rnaprop, &item_array, NULL, &free); | RNA_property_enum_items_gettexted(block->evil_C, &but->rnapoin, but->rnaprop, &item_array, NULL, &free); | ||||
| /* we dont want nested rows, cols in menus */ | /* we dont want nested rows, cols in menus */ | ||||
| uiBlockSetCurLayout(block, layout); | UI_block_layout_set_current(block, layout); | ||||
| for (item = item_array; item->identifier; item++, totitems++) { | for (item = item_array; item->identifier; item++, totitems++) { | ||||
| if (!item->identifier[0]) { | if (!item->identifier[0]) { | ||||
| /* inconsistent, but menus with labels do not look good flipped */ | /* inconsistent, but menus with labels do not look good flipped */ | ||||
| if (item->name) { | if (item->name) { | ||||
| block->flag |= UI_BLOCK_NO_FLIP; | block->flag |= UI_BLOCK_NO_FLIP; | ||||
| nbr_entries_nosepr++; | nbr_entries_nosepr++; | ||||
| } | } | ||||
| Show All 12 Lines | static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p) | ||||
| rows = totitems / columns; | rows = totitems / columns; | ||||
| if (rows < 1) | if (rows < 1) | ||||
| rows = 1; | rows = 1; | ||||
| while (rows * columns < totitems) | while (rows * columns < totitems) | ||||
| rows++; | rows++; | ||||
| /* Title */ | /* Title */ | ||||
| uiDefBut(block, LABEL, 0, RNA_property_ui_name(but->rnaprop), | uiDefBut(block, UI_BTYPE_LABEL, 0, RNA_property_ui_name(but->rnaprop), | ||||
| 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); | 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); | ||||
| uiItemS(layout); | uiItemS(layout); | ||||
| /* note, item_array[...] is reversed on access */ | /* note, item_array[...] is reversed on access */ | ||||
| /* create items */ | /* create items */ | ||||
| split = uiLayoutSplit(layout, 0.0f, false); | split = uiLayoutSplit(layout, 0.0f, false); | ||||
| Show All 26 Lines | for (a = 0; a < totitems; a++) { | ||||
| if (!item->identifier[0]) { | if (!item->identifier[0]) { | ||||
| if (item->name) { | if (item->name) { | ||||
| if (item->icon) { | if (item->icon) { | ||||
| uiItemL(column, item->name, item->icon); | uiItemL(column, item->name, item->icon); | ||||
| } | } | ||||
| else { | else { | ||||
| /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ | /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ | ||||
| uiDefBut(block, LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); | uiDefBut(block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| uiItemS(column); | uiItemS(column); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (item->icon) { | if (item->icon) { | ||||
| uiDefIconTextButI(block, BUTM, B_NOP, item->icon, item->name, 0, 0, | uiDefIconTextButI(block, UI_BTYPE_BUT_MENU, B_NOP, item->icon, item->name, 0, 0, | ||||
| UI_UNIT_X * 5, UI_UNIT_Y, &handle->retvalue, item->value, 0.0, 0, -1, item->description); | UI_UNIT_X * 5, UI_UNIT_Y, &handle->retvalue, item->value, 0.0, 0, -1, item->description); | ||||
| } | } | ||||
| else { | else { | ||||
| uiDefButI(block, BUTM, B_NOP, item->name, 0, 0, | uiDefButI(block, UI_BTYPE_BUT_MENU, B_NOP, item->name, 0, 0, | ||||
| UI_UNIT_X * 5, UI_UNIT_X, &handle->retvalue, item->value, 0.0, 0, -1, item->description); | UI_UNIT_X * 5, UI_UNIT_X, &handle->retvalue, item->value, 0.0, 0, -1, item->description); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| uiBlockSetCurLayout(block, layout); | UI_block_layout_set_current(block, layout); | ||||
| if (free) { | if (free) { | ||||
| MEM_freeN(item_array); | MEM_freeN(item_array); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * ui_def_but_rna_propname and ui_def_but_rna | * ui_def_but_rna_propname and ui_def_but_rna | ||||
| * both take the same args except for propname vs prop, this is done so we can | * both take the same args except for propname vs prop, this is done so we can | ||||
| * avoid an extra lookup on 'prop' when its already available. | * avoid an extra lookup on 'prop' when its already available. | ||||
| * | * | ||||
| * When this kind of change won't disrupt branches, best look into making more | * When this kind of change won't disrupt branches, best look into making more | ||||
| * of our UI functions take prop rather then propname. | * of our UI functions take prop rather then propname. | ||||
| */ | */ | ||||
| static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, | static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, | ||||
| int x, int y, short width, short height, | int x, int y, short width, short height, | ||||
| PointerRNA *ptr, PropertyRNA *prop, int index, | PointerRNA *ptr, PropertyRNA *prop, int index, | ||||
| float min, float max, float a1, float a2, const char *tip) | float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| const PropertyType proptype = RNA_property_type(prop); | const PropertyType proptype = RNA_property_type(prop); | ||||
| uiBut *but; | uiBut *but; | ||||
| int icon = 0; | int icon = 0; | ||||
| uiMenuCreateFunc func = NULL; | uiMenuCreateFunc func = NULL; | ||||
| if (ELEM(type, COLOR, HSVCIRCLE, HSVCUBE)) { | if (ELEM(type, UI_BTYPE_COLOR, UI_BTYPE_HSVCIRCLE, UI_BTYPE_HSVCUBE)) { | ||||
| BLI_assert(index == -1); | BLI_assert(index == -1); | ||||
| } | } | ||||
| /* use rna values if parameters are not specified */ | /* use rna values if parameters are not specified */ | ||||
| if ((proptype == PROP_ENUM) && ELEM(type, MENU, ROW, LISTROW)) { | if ((proptype == PROP_ENUM) && ELEM(type, UI_BTYPE_MENU, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { | ||||
| /* MENU is handled a little differently here */ | /* UI_BTYPE_MENU is handled a little differently here */ | ||||
| EnumPropertyItem *item; | EnumPropertyItem *item; | ||||
| int value; | int value; | ||||
| bool free; | bool free; | ||||
| int i; | int i; | ||||
| RNA_property_enum_items(block->evil_C, ptr, prop, &item, NULL, &free); | RNA_property_enum_items(block->evil_C, ptr, prop, &item, NULL, &free); | ||||
| if (type == MENU) { | if (type == UI_BTYPE_MENU) { | ||||
| value = RNA_property_enum_get(ptr, prop); | value = RNA_property_enum_get(ptr, prop); | ||||
| } | } | ||||
| else { | else { | ||||
| value = (int)max; | value = (int)max; | ||||
| } | } | ||||
| i = RNA_enum_from_value(item, value); | i = RNA_enum_from_value(item, value); | ||||
| if (i != -1) { | if (i != -1) { | ||||
| if (!str) { | if (!str) { | ||||
| str = item[i].name; | str = item[i].name; | ||||
| #ifdef WITH_INTERNATIONAL | #ifdef WITH_INTERNATIONAL | ||||
| str = CTX_IFACE_(RNA_property_translation_context(prop), str); | str = CTX_IFACE_(RNA_property_translation_context(prop), str); | ||||
| #endif | #endif | ||||
| } | } | ||||
| icon = item[i].icon; | icon = item[i].icon; | ||||
| } | } | ||||
| else { | else { | ||||
| if (!str) { | if (!str) { | ||||
| if (type == MENU) { | if (type == UI_BTYPE_MENU) { | ||||
| str = ""; | str = ""; | ||||
| } | } | ||||
| else { | else { | ||||
| str = RNA_property_ui_name(prop); | str = RNA_property_ui_name(prop); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (type == MENU) { | if (type == UI_BTYPE_MENU) { | ||||
| func = ui_def_but_rna__menu; | func = ui_def_but_rna__menu; | ||||
| } | } | ||||
| if (free) { | if (free) { | ||||
| MEM_freeN(item); | MEM_freeN(item); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (!str) { | if (!str) { | ||||
| str = RNA_property_ui_name(prop); | str = RNA_property_ui_name(prop); | ||||
| } | } | ||||
| icon = RNA_property_ui_icon(prop); | icon = RNA_property_ui_icon(prop); | ||||
| } | } | ||||
| if (!tip && proptype != PROP_ENUM) | if (!tip && proptype != PROP_ENUM) | ||||
| tip = RNA_property_ui_description(prop); | tip = RNA_property_ui_description(prop); | ||||
| if (min == max || a1 == -1 || a2 == -1) { | if (min == max || a1 == -1 || a2 == -1) { | ||||
| if (proptype == PROP_INT) { | if (proptype == PROP_INT) { | ||||
| int hardmin, hardmax, softmin, softmax, step; | int hardmin, hardmax, softmin, softmax, step; | ||||
| RNA_property_int_range(ptr, prop, &hardmin, &hardmax); | RNA_property_int_range(ptr, prop, &hardmin, &hardmax); | ||||
| RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step); | RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step); | ||||
| if (!ELEM(type, ROW, LISTROW) && min == max) { | if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) { | ||||
| min = hardmin; | min = hardmin; | ||||
| max = hardmax; | max = hardmax; | ||||
| } | } | ||||
| if (a1 == -1) | if (a1 == -1) | ||||
| a1 = step; | a1 = step; | ||||
| if (a2 == -1) | if (a2 == -1) | ||||
| a2 = 0; | a2 = 0; | ||||
| } | } | ||||
| else if (proptype == PROP_FLOAT) { | else if (proptype == PROP_FLOAT) { | ||||
| float hardmin, hardmax, softmin, softmax, step, precision; | float hardmin, hardmax, softmin, softmax, step, precision; | ||||
| RNA_property_float_range(ptr, prop, &hardmin, &hardmax); | RNA_property_float_range(ptr, prop, &hardmin, &hardmax); | ||||
| RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); | RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); | ||||
| if (!ELEM(type, ROW, LISTROW) && min == max) { | if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) { | ||||
| min = hardmin; | min = hardmin; | ||||
| max = hardmax; | max = hardmax; | ||||
| } | } | ||||
| if (a1 == -1) | if (a1 == -1) | ||||
| a1 = step; | a1 = step; | ||||
| if (a2 == -1) | if (a2 == -1) | ||||
| a2 = precision; | a2 = precision; | ||||
| } | } | ||||
| Show All 19 Lines | #endif | ||||
| if (icon) { | if (icon) { | ||||
| but->icon = (BIFIconID)icon; | but->icon = (BIFIconID)icon; | ||||
| but->flag |= UI_HAS_ICON; | but->flag |= UI_HAS_ICON; | ||||
| if (str[0]) { | if (str[0]) { | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| } | } | ||||
| } | } | ||||
| if ((type == MENU) && (but->dt == UI_EMBOSSP)) { | if ((type == UI_BTYPE_MENU) && (but->dt == UI_EMBOSS_PULLDOWN)) { | ||||
| but->flag |= UI_ICON_SUBMENU; | but->flag |= UI_BUT_ICON_SUBMENU; | ||||
| } | } | ||||
| if (!RNA_property_editable(&but->rnapoin, prop)) { | if (!RNA_property_editable(&but->rnapoin, prop)) { | ||||
| ui_def_but_rna__disable(but); | ui_def_but_rna__disable(but); | ||||
| } | } | ||||
| if (but->flag & UI_BUT_UNDO && (ui_is_but_rna_undo(but) == false)) { | if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) { | ||||
| but->flag &= ~UI_BUT_UNDO; | but->flag &= ~UI_BUT_UNDO; | ||||
| } | } | ||||
| /* If this button uses units, calculate the step from this */ | /* If this button uses units, calculate the step from this */ | ||||
| if ((proptype == PROP_FLOAT) && ui_is_but_unit(but)) { | if ((proptype == PROP_FLOAT) && ui_but_is_unit(but)) { | ||||
| but->a1 = ui_get_but_step_unit(but, but->a1); | but->a1 = ui_get_but_step_unit(but, but->a1); | ||||
| } | } | ||||
| if (func) { | if (func) { | ||||
| but->menu_create_func = func; | but->menu_create_func = func; | ||||
| but->poin = (char *)but; | but->poin = (char *)but; | ||||
| } | } | ||||
| Show All 30 Lines | static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| if ((!tip || tip[0] == '\0') && ot && ot->srna) { | if ((!tip || tip[0] == '\0') && ot && ot->srna) { | ||||
| tip = RNA_struct_ui_description(ot->srna); | tip = RNA_struct_ui_description(ot->srna); | ||||
| } | } | ||||
| but = ui_def_but(block, type, -1, str, x, y, width, height, NULL, 0, 0, 0, 0, tip); | but = ui_def_but(block, type, -1, str, x, y, width, height, NULL, 0, 0, 0, 0, tip); | ||||
| but->optype = ot; | but->optype = ot; | ||||
| but->opcontext = opcontext; | but->opcontext = opcontext; | ||||
| but->flag &= ~UI_BUT_UNDO; /* no need for ui_is_but_rna_undo(), we never need undo here */ | but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_rna_undo(), we never need undo here */ | ||||
| if (!ot) { | if (!ot) { | ||||
| but->flag |= UI_BUT_DISABLED; | but->flag |= UI_BUT_DISABLED; | ||||
| but->lock = true; | but->lock = true; | ||||
| but->lockstr = ""; | but->lockstr = ""; | ||||
| } | } | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); | uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| /** | /** | ||||
| * if \a _x_ is a power of two (only one bit) return the power, | * if \a _x_ is a power of two (only one bit) return the power, | ||||
| * otherwise return -1. | * otherwise return -1. | ||||
| * | * | ||||
| Show All 23 Lines | |||||
| /* autocomplete helper functions */ | /* autocomplete helper functions */ | ||||
| struct AutoComplete { | struct AutoComplete { | ||||
| size_t maxlen; | size_t maxlen; | ||||
| int matches; | int matches; | ||||
| char *truncate; | char *truncate; | ||||
| const char *startname; | const char *startname; | ||||
| }; | }; | ||||
| AutoComplete *autocomplete_begin(const char *startname, size_t maxlen) | AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen) | ||||
| { | { | ||||
| AutoComplete *autocpl; | AutoComplete *autocpl; | ||||
| autocpl = MEM_callocN(sizeof(AutoComplete), "AutoComplete"); | autocpl = MEM_callocN(sizeof(AutoComplete), "AutoComplete"); | ||||
| autocpl->maxlen = maxlen; | autocpl->maxlen = maxlen; | ||||
| autocpl->matches = 0; | autocpl->matches = 0; | ||||
| autocpl->truncate = MEM_callocN(sizeof(char) * maxlen, "AutoCompleteTruncate"); | autocpl->truncate = MEM_callocN(sizeof(char) * maxlen, "AutoCompleteTruncate"); | ||||
| autocpl->startname = startname; | autocpl->startname = startname; | ||||
| return autocpl; | return autocpl; | ||||
| } | } | ||||
| void autocomplete_do_name(AutoComplete *autocpl, const char *name) | void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name) | ||||
| { | { | ||||
| char *truncate = autocpl->truncate; | char *truncate = autocpl->truncate; | ||||
| const char *startname = autocpl->startname; | const char *startname = autocpl->startname; | ||||
| int a; | int a; | ||||
| for (a = 0; a < autocpl->maxlen - 1; a++) { | for (a = 0; a < autocpl->maxlen - 1; a++) { | ||||
| if (startname[a] == 0 || startname[a] != name[a]) | if (startname[a] == 0 || startname[a] != name[a]) | ||||
| break; | break; | ||||
| Show All 13 Lines | else { | ||||
| } | } | ||||
| else if (truncate[a] != name[a]) | else if (truncate[a] != name[a]) | ||||
| truncate[a] = 0; | truncate[a] = 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| int autocomplete_end(AutoComplete *autocpl, char *autoname) | int UI_autocomplete_end(AutoComplete *autocpl, char *autoname) | ||||
| { | { | ||||
| int match = AUTOCOMPLETE_NO_MATCH; | int match = AUTOCOMPLETE_NO_MATCH; | ||||
| if (autocpl->truncate[0]) { | if (autocpl->truncate[0]) { | ||||
| if (autocpl->matches == 1) { | if (autocpl->matches == 1) { | ||||
| match = AUTOCOMPLETE_FULL_MATCH; | match = AUTOCOMPLETE_FULL_MATCH; | ||||
| } | } | ||||
| else { | else { | ||||
| match = AUTOCOMPLETE_PARTIAL_MATCH; | match = AUTOCOMPLETE_PARTIAL_MATCH; | ||||
| } | } | ||||
| BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen); | BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen); | ||||
| } | } | ||||
| else { | else { | ||||
| if (autoname != autocpl->startname) { /* don't copy a string over its self */ | if (autoname != autocpl->startname) { /* don't copy a string over its self */ | ||||
| BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen); | BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen); | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(autocpl->truncate); | MEM_freeN(autocpl->truncate); | ||||
| MEM_freeN(autocpl); | MEM_freeN(autocpl); | ||||
| return match; | return match; | ||||
| } | } | ||||
| static void ui_check_but_and_iconize(uiBut *but, int icon) | static void ui_but_update_and_icon_set(uiBut *but, int icon) | ||||
| { | { | ||||
| if (icon) { | if (icon) { | ||||
| but->icon = (BIFIconID) icon; | but->icon = (BIFIconID) icon; | ||||
| but->flag |= UI_HAS_ICON; | but->flag |= UI_HAS_ICON; | ||||
| } | } | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| } | } | ||||
| static uiBut *uiDefButBit(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | static uiBut *uiDefButBit(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| int bitIdx = findBitIndex(bit); | int bitIdx = findBitIndex(bit); | ||||
| if (bitIdx == -1) { | if (bitIdx == -1) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| Show All 32 Lines | |||||
| uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, char *poin, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, char *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| return uiDefButBit(block, type | UI_BUT_POIN_CHAR, bit, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip); | return uiDefButBit(block, type | UI_BUT_POIN_CHAR, bit, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip); | ||||
| } | } | ||||
| uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); | but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); | but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); | but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| wmOperatorType *ot = WM_operatortype_find(opname, 0); | wmOperatorType *ot = WM_operatortype_find(opname, 0); | ||||
| if (str == NULL && ot == NULL) str = opname; | if (str == NULL && ot == NULL) str = opname; | ||||
| return uiDefButO_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); | return uiDefButO_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); | ||||
| } | } | ||||
| /* if a1==1.0 then a2 is an extra icon blending factor (alpha 0.0 - 1.0) */ | /* if a1==1.0 then a2 is an extra icon blending factor (alpha 0.0 - 1.0) */ | ||||
| uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, type, retval, "", x, y, width, height, poin, min, max, a1, a2, tip); | uiBut *but = ui_def_but(block, type, retval, "", x, y, width, height, poin, min, max, a1, a2, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| return but; | return but; | ||||
| } | } | ||||
| static uiBut *uiDefIconButBit(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | static uiBut *uiDefIconButBit(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| int bitIdx = findBitIndex(bit); | int bitIdx = findBitIndex(bit); | ||||
| if (bitIdx == -1) { | if (bitIdx == -1) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| Show All 33 Lines | |||||
| uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, char *poin, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, char *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| return uiDefIconButBit(block, type | UI_BUT_POIN_CHAR, bit, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip); | return uiDefIconButBit(block, type | UI_BUT_POIN_CHAR, bit, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip); | ||||
| } | } | ||||
| uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_rna_propname(block, type, retval, "", x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); | but = ui_def_but_rna_propname(block, type, retval, "", x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_rna(block, type, retval, "", x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); | but = ui_def_but_rna(block, type, retval, "", x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_operator_ptr(block, type, ot, opcontext, "", x, y, width, height, tip); | but = ui_def_but_operator_ptr(block, type, ot, opcontext, "", x, y, width, height, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| wmOperatorType *ot = WM_operatortype_find(opname, 0); | wmOperatorType *ot = WM_operatortype_find(opname, 0); | ||||
| return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, tip); | return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, tip); | ||||
| } | } | ||||
| /* Button containing both string label and icon */ | /* Button containing both string label and icon */ | ||||
| uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); | uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| return but; | return but; | ||||
| } | } | ||||
| static uiBut *uiDefIconTextButBit(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | static uiBut *uiDefIconTextButBit(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| int bitIdx = findBitIndex(bit); | int bitIdx = findBitIndex(bit); | ||||
| if (bitIdx == -1) { | if (bitIdx == -1) { | ||||
| return NULL; | return NULL; | ||||
| Show All 34 Lines | |||||
| uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, char *poin, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, char *poin, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| return uiDefIconTextButBit(block, type | UI_BUT_POIN_CHAR, bit, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip); | return uiDefIconTextButBit(block, type | UI_BUT_POIN_CHAR, bit, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip); | ||||
| } | } | ||||
| uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); | but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) | uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); | but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); | but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); | ||||
| ui_check_but_and_iconize(but, icon); | ui_but_update_and_icon_set(but, icon); | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| wmOperatorType *ot = WM_operatortype_find(opname, 0); | wmOperatorType *ot = WM_operatortype_find(opname, 0); | ||||
| return uiDefIconTextButO_ptr(block, type, ot, opcontext, icon, str, x, y, width, height, tip); | return uiDefIconTextButO_ptr(block, type, ot, opcontext, icon, str, x, y, width, height, tip); | ||||
| } | } | ||||
| /* END Button containing both string label and icon */ | /* END Button containing both string label and icon */ | ||||
| void uiSetButLink(uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to) | void UI_but_link_set(uiBut *but, void **poin, void ***ppoin, short *tot, int from, int to) | ||||
| { | { | ||||
| uiLink *link; | uiLink *link; | ||||
| link = but->link = MEM_callocN(sizeof(uiLink), "new uilink"); | link = but->link = MEM_callocN(sizeof(uiLink), "new uilink"); | ||||
| link->poin = poin; | link->poin = poin; | ||||
| link->ppoin = ppoin; | link->ppoin = ppoin; | ||||
| link->totlink = tot; | link->totlink = tot; | ||||
| link->fromcode = from; | link->fromcode = from; | ||||
| link->tocode = to; | link->tocode = to; | ||||
| } | } | ||||
| /* cruft to make uiBlock and uiBut private */ | /* cruft to make uiBlock and uiBut private */ | ||||
| int uiBlocksGetYMin(ListBase *lb) | int UI_blocklist_min_y_get(ListBase *lb) | ||||
| { | { | ||||
| uiBlock *block; | uiBlock *block; | ||||
| int min = 0; | int min = 0; | ||||
| for (block = lb->first; block; block = block->next) | for (block = lb->first; block; block = block->next) | ||||
| if (block == lb->first || block->rect.ymin < min) | if (block == lb->first || block->rect.ymin < min) | ||||
| min = block->rect.ymin; | min = block->rect.ymin; | ||||
| return min; | return min; | ||||
| } | } | ||||
| void uiBlockSetDirection(uiBlock *block, char direction) | void UI_block_direction_set(uiBlock *block, char direction) | ||||
| { | { | ||||
| block->direction = direction; | block->direction = direction; | ||||
| } | } | ||||
| /* this call escapes if there's alignment flags */ | /* this call escapes if there's alignment flags */ | ||||
| void uiBlockFlipOrder(uiBlock *block) | void UI_block_order_flip(uiBlock *block) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| float centy, miny = 10000, maxy = -10000; | float centy, miny = 10000, maxy = -10000; | ||||
| if (U.uiflag & USER_MENUFIXEDORDER) | if (U.uiflag & USER_MENUFIXEDORDER) | ||||
| return; | return; | ||||
| else if (block->flag & UI_BLOCK_NO_FLIP) | else if (block->flag & UI_BLOCK_NO_FLIP) | ||||
| return; | return; | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| if (but->drawflag & UI_BUT_ALIGN) return; | if (but->drawflag & UI_BUT_ALIGN) return; | ||||
| if (but->rect.ymin < miny) miny = but->rect.ymin; | if (but->rect.ymin < miny) miny = but->rect.ymin; | ||||
| if (but->rect.ymax > maxy) maxy = but->rect.ymax; | if (but->rect.ymax > maxy) maxy = but->rect.ymax; | ||||
| } | } | ||||
| /* mirror trick */ | /* mirror trick */ | ||||
| centy = (miny + maxy) / 2.0f; | centy = (miny + maxy) / 2.0f; | ||||
| for (but = block->buttons.first; but; but = but->next) { | for (but = block->buttons.first; but; but = but->next) { | ||||
| but->rect.ymin = centy - (but->rect.ymin - centy); | but->rect.ymin = centy - (but->rect.ymin - centy); | ||||
| but->rect.ymax = centy - (but->rect.ymax - centy); | but->rect.ymax = centy - (but->rect.ymax - centy); | ||||
| SWAP(float, but->rect.ymin, but->rect.ymax); | SWAP(float, but->rect.ymin, but->rect.ymax); | ||||
| } | } | ||||
| } | } | ||||
| void uiBlockSetFlag(uiBlock *block, int flag) | void UI_block_flag_enable(uiBlock *block, int flag) | ||||
| { | { | ||||
| block->flag |= flag; | block->flag |= flag; | ||||
| } | } | ||||
| void uiBlockClearFlag(uiBlock *block, int flag) | void UI_block_flag_disable(uiBlock *block, int flag) | ||||
| { | { | ||||
| block->flag &= ~flag; | block->flag &= ~flag; | ||||
| } | } | ||||
| void uiButSetFlag(uiBut *but, int flag) | void UI_but_flag_enable(uiBut *but, int flag) | ||||
| { | { | ||||
| but->flag |= flag; | but->flag |= flag; | ||||
| } | } | ||||
| void uiButClearFlag(uiBut *but, int flag) | void UI_but_flag_disable(uiBut *but, int flag) | ||||
| { | { | ||||
| but->flag &= ~flag; | but->flag &= ~flag; | ||||
| } | } | ||||
| void uiButSetDrawFlag(uiBut *but, int flag) | void UI_but_drawflag_enable(uiBut *but, int flag) | ||||
| { | { | ||||
| but->drawflag |= flag; | but->drawflag |= flag; | ||||
| } | } | ||||
| void uiButClearDrawFlag(uiBut *but, int flag) | void UI_but_drawflag_disable(uiBut *but, int flag) | ||||
| { | { | ||||
| but->drawflag &= ~flag; | but->drawflag &= ~flag; | ||||
| } | } | ||||
| void uiButSetMenuFromPulldown(uiBut *but) | void UI_but_type_set_menu_from_pulldown(uiBut *but) | ||||
| { | { | ||||
| BLI_assert(but->type == PULLDOWN); | BLI_assert(but->type == UI_BTYPE_PULLDOWN); | ||||
| but->type = MENU; | but->type = UI_BTYPE_MENU; | ||||
| uiButClearDrawFlag(but, UI_BUT_TEXT_RIGHT); | UI_but_drawflag_disable(but, UI_BUT_TEXT_RIGHT); | ||||
| uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT); | UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT); | ||||
| } | } | ||||
| int uiButGetRetVal(uiBut *but) | int UI_but_return_value_get(uiBut *but) | ||||
| { | { | ||||
| return but->retval; | return but->retval; | ||||
| } | } | ||||
| void uiButSetDragID(uiBut *but, ID *id) | void UI_but_drag_set_id(uiBut *but, ID *id) | ||||
| { | { | ||||
| but->dragtype = WM_DRAG_ID; | but->dragtype = WM_DRAG_ID; | ||||
| but->dragpoin = (void *)id; | but->dragpoin = (void *)id; | ||||
| } | } | ||||
| void uiButSetDragRNA(uiBut *but, PointerRNA *ptr) | void UI_but_drag_set_rna(uiBut *but, PointerRNA *ptr) | ||||
| { | { | ||||
| but->dragtype = WM_DRAG_RNA; | but->dragtype = WM_DRAG_RNA; | ||||
| but->dragpoin = (void *)ptr; | but->dragpoin = (void *)ptr; | ||||
| } | } | ||||
| void uiButSetDragPath(uiBut *but, const char *path) | void UI_but_drag_set_path(uiBut *but, const char *path) | ||||
| { | { | ||||
| but->dragtype = WM_DRAG_PATH; | but->dragtype = WM_DRAG_PATH; | ||||
| but->dragpoin = (void *)path; | but->dragpoin = (void *)path; | ||||
| } | } | ||||
| void uiButSetDragName(uiBut *but, const char *name) | void UI_but_drag_set_name(uiBut *but, const char *name) | ||||
| { | { | ||||
| but->dragtype = WM_DRAG_NAME; | but->dragtype = WM_DRAG_NAME; | ||||
| but->dragpoin = (void *)name; | but->dragpoin = (void *)name; | ||||
| } | } | ||||
| /* value from button itself */ | /* value from button itself */ | ||||
| void uiButSetDragValue(uiBut *but) | void UI_but_drag_set_value(uiBut *but) | ||||
| { | { | ||||
| but->dragtype = WM_DRAG_VALUE; | but->dragtype = WM_DRAG_VALUE; | ||||
| } | } | ||||
| void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale) | void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale) | ||||
| { | { | ||||
| but->dragtype = WM_DRAG_PATH; | but->dragtype = WM_DRAG_PATH; | ||||
| but->icon = icon; /* no flag UI_HAS_ICON, so icon doesnt draw in button */ | but->icon = icon; /* no flag UI_HAS_ICON, so icon doesnt draw in button */ | ||||
| but->dragpoin = (void *)path; | but->dragpoin = (void *)path; | ||||
| but->imb = imb; | but->imb = imb; | ||||
| but->imb_scale = scale; | but->imb_scale = scale; | ||||
| } | } | ||||
| PointerRNA *uiButGetOperatorPtrRNA(uiBut *but) | PointerRNA *UI_but_operator_ptr_get(uiBut *but) | ||||
| { | { | ||||
| if (but->optype && !but->opptr) { | if (but->optype && !but->opptr) { | ||||
| but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr"); | but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr"); | ||||
| WM_operator_properties_create_ptr(but->opptr, but->optype); | WM_operator_properties_create_ptr(but->opptr, but->optype); | ||||
| } | } | ||||
| return but->opptr; | return but->opptr; | ||||
| } | } | ||||
| void uiButSetUnitType(uiBut *but, const int unit_type) | void UI_but_unit_type_set(uiBut *but, const int unit_type) | ||||
| { | { | ||||
| but->unit_type = (unsigned char)(RNA_SUBTYPE_UNIT_VALUE(unit_type)); | but->unit_type = (unsigned char)(RNA_SUBTYPE_UNIT_VALUE(unit_type)); | ||||
| } | } | ||||
| int uiButGetUnitType(const uiBut *but) | int UI_but_unit_type_get(const uiBut *but) | ||||
| { | { | ||||
| int ownUnit = (int)but->unit_type; | int ownUnit = (int)but->unit_type; | ||||
| /* own unit define always takes precedence over RNA provided, allowing for overriding | /* own unit define always takes precedence over RNA provided, allowing for overriding | ||||
| * default value provided in RNA in a few special cases (i.e. Active Keyframe in Graph Edit) | * default value provided in RNA in a few special cases (i.e. Active Keyframe in Graph Edit) | ||||
| */ | */ | ||||
| /* XXX: this doesn't allow clearing unit completely, though the same could be said for icons */ | /* XXX: this doesn't allow clearing unit completely, though the same could be said for icons */ | ||||
| if ((ownUnit != 0) || (but->rnaprop == NULL)) { | if ((ownUnit != 0) || (but->rnaprop == NULL)) { | ||||
| return ownUnit << 16; | return ownUnit << 16; | ||||
| } | } | ||||
| else { | else { | ||||
| return RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop)); | return RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop)); | ||||
| } | } | ||||
| } | } | ||||
| void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg) | void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg) | ||||
| { | { | ||||
| block->handle_func = func; | block->handle_func = func; | ||||
| block->handle_func_arg = arg; | block->handle_func_arg = arg; | ||||
| } | } | ||||
| void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg) | void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg) | ||||
| { | { | ||||
| block->butm_func = func; | block->butm_func = func; | ||||
| block->butm_func_arg = arg; | block->butm_func_arg = arg; | ||||
| } | } | ||||
| void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2) | void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2) | ||||
| { | { | ||||
| block->func = func; | block->func = func; | ||||
| block->func_arg1 = arg1; | block->func_arg1 = arg1; | ||||
| block->func_arg2 = arg2; | block->func_arg2 = arg2; | ||||
| } | } | ||||
| void uiBlockSetNFunc(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2) | void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2) | ||||
| { | { | ||||
| if (block->func_argN) { | if (block->func_argN) { | ||||
| MEM_freeN(block->func_argN); | MEM_freeN(block->func_argN); | ||||
| } | } | ||||
| block->funcN = funcN; | block->funcN = funcN; | ||||
| block->func_argN = argN; | block->func_argN = argN; | ||||
| block->func_arg2 = arg2; | block->func_arg2 = arg2; | ||||
| } | } | ||||
| void uiButSetRenameFunc(uiBut *but, uiButHandleRenameFunc func, void *arg1) | void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1) | ||||
| { | { | ||||
| but->rename_func = func; | but->rename_func = func; | ||||
| but->rename_arg1 = arg1; | but->rename_arg1 = arg1; | ||||
| } | } | ||||
| void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const bContext *C, void *idv, void *arg1, void *arg2, rcti *rect), void *arg1, void *arg2) | void UI_but_func_drawextra_set(uiBlock *block, void (*func)(const bContext *C, void *idv, void *arg1, void *arg2, rcti *rect), void *arg1, void *arg2) | ||||
| { | { | ||||
| block->drawextra = func; | block->drawextra = func; | ||||
| block->drawextra_arg1 = arg1; | block->drawextra_arg1 = arg1; | ||||
| block->drawextra_arg2 = arg2; | block->drawextra_arg2 = arg2; | ||||
| } | } | ||||
| void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2) | void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2) | ||||
| { | { | ||||
| but->func = func; | but->func = func; | ||||
| but->func_arg1 = arg1; | but->func_arg1 = arg1; | ||||
| but->func_arg2 = arg2; | but->func_arg2 = arg2; | ||||
| } | } | ||||
| void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) | void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2) | ||||
| { | { | ||||
| if (but->func_argN) { | if (but->func_argN) { | ||||
| MEM_freeN(but->func_argN); | MEM_freeN(but->func_argN); | ||||
| } | } | ||||
| but->funcN = funcN; | but->funcN = funcN; | ||||
| but->func_argN = argN; | but->func_argN = argN; | ||||
| but->func_arg2 = arg2; | but->func_arg2 = arg2; | ||||
| } | } | ||||
| void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg) | void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg) | ||||
| { | { | ||||
| but->autocomplete_func = func; | but->autocomplete_func = func; | ||||
| but->autofunc_arg = arg; | but->autofunc_arg = arg; | ||||
| } | } | ||||
| uiBut *uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->block_create_func = func; | but->block_create_func = func; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, NULL, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, NULL, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->block_create_func = func; | but->block_create_func = func; | ||||
| if (but->func_argN) { | if (but->func_argN) { | ||||
| MEM_freeN(but->func_argN); | MEM_freeN(but->func_argN); | ||||
| } | } | ||||
| but->func_argN = argN; | but->func_argN = argN; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->block_create_func = func; | but->block_create_func = func; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->menu_create_func = func; | but->menu_create_func = func; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->icon = (BIFIconID) icon; | but->icon = (BIFIconID) icon; | ||||
| but->flag |= UI_HAS_ICON; | but->flag |= UI_HAS_ICON; | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| but->flag |= UI_ICON_SUBMENU; | but->flag |= UI_BUT_ICON_SUBMENU; | ||||
| but->menu_create_func = func; | but->menu_create_func = func; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->icon = (BIFIconID) icon; | but->icon = (BIFIconID) icon; | ||||
| but->flag |= UI_HAS_ICON; | but->flag |= UI_HAS_ICON; | ||||
| but->drawflag &= ~UI_BUT_ICON_LEFT; | but->drawflag &= ~UI_BUT_ICON_LEFT; | ||||
| but->menu_create_func = func; | but->menu_create_func = func; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| /* Block button containing both string label and icon */ | /* Block button containing both string label and icon */ | ||||
| uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| /* XXX temp, old menu calls pass on icon arrow, which is now UI_ICON_SUBMENU flag */ | /* XXX temp, old menu calls pass on icon arrow, which is now UI_BUT_ICON_SUBMENU flag */ | ||||
| if (icon != ICON_RIGHTARROW_THIN) { | if (icon != ICON_RIGHTARROW_THIN) { | ||||
| but->icon = (BIFIconID) icon; | but->icon = (BIFIconID) icon; | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| } | } | ||||
| but->flag |= UI_HAS_ICON; | but->flag |= UI_HAS_ICON; | ||||
| but->flag |= UI_ICON_SUBMENU; | but->flag |= UI_BUT_ICON_SUBMENU; | ||||
| but->block_create_func = func; | but->block_create_func = func; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| /* Block button containing icon */ | /* Block button containing icon */ | ||||
| uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, int x, int y, short width, short height, const char *tip) | uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, int x, int y, short width, short height, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->icon = (BIFIconID) icon; | but->icon = (BIFIconID) icon; | ||||
| but->flag |= UI_HAS_ICON; | but->flag |= UI_HAS_ICON; | ||||
| but->drawflag |= UI_BUT_ICON_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT; | ||||
| but->block_create_func = func; | but->block_create_func = func; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| uiBut *uiDefKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *spoin, const char *tip) | uiBut *uiDefKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *spoin, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, KEYEVT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, spoin, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_KEY_EVENT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, spoin, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| /* short pointers hardcoded */ | /* short pointers hardcoded */ | ||||
| /* modkeypoin will be set to KM_SHIFT, KM_ALT, KM_CTRL, KM_OSKEY bits */ | /* modkeypoin will be set to KM_SHIFT, KM_ALT, KM_CTRL, KM_OSKEY bits */ | ||||
| uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *keypoin, short *modkeypoin, const char *tip) | uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, const char *str, int x, int y, short width, short height, short *keypoin, short *modkeypoin, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, HOTKEYEVT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, keypoin, 0.0, 0.0, 0.0, 0.0, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_HOTKEY_EVENT | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, keypoin, 0.0, 0.0, 0.0, 0.0, tip); | ||||
| but->modifier_key = *modkeypoin; | but->modifier_key = *modkeypoin; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| /* arg is pointer to string/name, use uiButSetSearchFunc() below to make this work */ | /* arg is pointer to string/name, use UI_but_func_search_set() below to make this work */ | ||||
| /* here a1 and a2, if set, control thumbnail preview rows/cols */ | /* here a1 and a2, if set, control thumbnail preview rows/cols */ | ||||
| uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x, int y, short width, short height, float a1, float a2, const char *tip) | uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x, int y, short width, short height, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but = ui_def_but(block, SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip); | uiBut *but = ui_def_but(block, UI_BTYPE_SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip); | ||||
| but->icon = (BIFIconID) icon; | but->icon = (BIFIconID) icon; | ||||
| but->flag |= UI_HAS_ICON; | but->flag |= UI_HAS_ICON; | ||||
| but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; | but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; | ||||
| ui_check_but(but); | ui_but_update(but); | ||||
| return but; | return but; | ||||
| } | } | ||||
| /* arg is user value, searchfunc and handlefunc both get it as arg */ | /* arg is user value, searchfunc and handlefunc both get it as arg */ | ||||
| /* if active set, button opens with this item visible and selected */ | /* if active set, button opens with this item visible and selected */ | ||||
| void uiButSetSearchFunc(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active) | void UI_but_func_search_set(uiBut *but, uiButSearchFunc sfunc, void *arg, uiButHandleFunc bfunc, void *active) | ||||
| { | { | ||||
| but->search_func = sfunc; | but->search_func = sfunc; | ||||
| but->search_arg = arg; | but->search_arg = arg; | ||||
| uiButSetFunc(but, bfunc, arg, active); | UI_but_func_set(but, bfunc, arg, active); | ||||
| /* search buttons show red-alert if item doesn't exist, not for menus */ | /* search buttons show red-alert if item doesn't exist, not for menus */ | ||||
| if (0 == (but->block->flag & UI_BLOCK_LOOP)) { | if (0 == (but->block->flag & UI_BLOCK_LOOP)) { | ||||
| /* skip empty buttons, not all buttons need input, we only show invalid */ | /* skip empty buttons, not all buttons need input, we only show invalid */ | ||||
| if (but->drawstr[0]) | if (but->drawstr[0]) | ||||
| ui_but_search_test(but); | ui_but_search_refresh(but); | ||||
| } | } | ||||
| } | } | ||||
| /* Callbacks for operator search button. */ | /* Callbacks for operator search button. */ | ||||
| static void operator_enum_search_cb(const struct bContext *C, void *but, const char *str, uiSearchItems *items) | static void operator_enum_search_cb(const struct bContext *C, void *but, const char *str, uiSearchItems *items) | ||||
| { | { | ||||
| wmOperatorType *ot = ((uiBut *)but)->optype; | wmOperatorType *ot = ((uiBut *)but)->optype; | ||||
| PropertyRNA *prop = ot->prop; | PropertyRNA *prop = ot->prop; | ||||
| if (prop == NULL) { | if (prop == NULL) { | ||||
| printf("%s: %s has no enum property set\n", | printf("%s: %s has no enum property set\n", | ||||
| __func__, ot->idname); | __func__, ot->idname); | ||||
| } | } | ||||
| else if (RNA_property_type(prop) != PROP_ENUM) { | else if (RNA_property_type(prop) != PROP_ENUM) { | ||||
| printf("%s: %s \"%s\" is not an enum property\n", | printf("%s: %s \"%s\" is not an enum property\n", | ||||
| __func__, ot->idname, RNA_property_identifier(prop)); | __func__, ot->idname, RNA_property_identifier(prop)); | ||||
| } | } | ||||
| else { | else { | ||||
| PointerRNA *ptr = uiButGetOperatorPtrRNA(but); /* Will create it if needed! */ | PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */ | ||||
| EnumPropertyItem *item, *item_array; | EnumPropertyItem *item, *item_array; | ||||
| bool do_free; | bool do_free; | ||||
| RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, NULL, &do_free); | RNA_property_enum_items((bContext *)C, ptr, prop, &item_array, NULL, &do_free); | ||||
| for (item = item_array; item->identifier; item++) { | for (item = item_array; item->identifier; item++) { | ||||
| /* note: need to give the index rather than the identifier because the enum can be freed */ | /* note: need to give the index rather than the identifier because the enum can be freed */ | ||||
| if (BLI_strcasestr(item->name, str)) { | if (BLI_strcasestr(item->name, str)) { | ||||
| if (false == uiSearchItemAdd(items, item->name, SET_INT_IN_POINTER(item->value), 0)) | if (false == UI_search_item_add(items, item->name, SET_INT_IN_POINTER(item->value), 0)) | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (do_free) | if (do_free) | ||||
| MEM_freeN(item_array); | MEM_freeN(item_array); | ||||
| } | } | ||||
| } | } | ||||
| static void operator_enum_call_cb(struct bContext *UNUSED(C), void *but, void *arg2) | static void operator_enum_call_cb(struct bContext *UNUSED(C), void *but, void *arg2) | ||||
| { | { | ||||
| wmOperatorType *ot = ((uiBut *)but)->optype; | wmOperatorType *ot = ((uiBut *)but)->optype; | ||||
| PointerRNA *opptr = uiButGetOperatorPtrRNA(but); /* Will create it if needed! */ | PointerRNA *opptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */ | ||||
| if (ot) { | if (ot) { | ||||
| if (ot->prop) { | if (ot->prop) { | ||||
| RNA_property_enum_set(opptr, ot->prop, GET_INT_FROM_POINTER(arg2)); | RNA_property_enum_set(opptr, ot->prop, GET_INT_FROM_POINTER(arg2)); | ||||
| /* We do not call op from here, will be called by button code. | /* We do not call op from here, will be called by button code. | ||||
| * ui_apply_but_funcs_after() (in interface_handlers.c) called this func before checking operators, | * ui_apply_but_funcs_after() (in interface_handlers.c) called this func before checking operators, | ||||
| * because one of its parameters is the button itself! | * because one of its parameters is the button itself! | ||||
| */ | */ | ||||
| } | } | ||||
| else { | else { | ||||
| printf("%s: op->prop for '%s' is NULL\n", __func__, ot->idname); | printf("%s: op->prop for '%s' is NULL\n", __func__, ot->idname); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Same parameters as for uiDefSearchBut, with additional operator type and properties, used by callback | /* Same parameters as for uiDefSearchBut, with additional operator type and properties, used by callback | ||||
| * to call again the right op with the right options (properties values). */ | * to call again the right op with the right options (properties values). */ | ||||
| uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *properties, | uiBut *uiDefSearchButO_ptr(uiBlock *block, wmOperatorType *ot, IDProperty *properties, | ||||
| void *arg, int retval, int icon, int maxlen, int x, int y, | void *arg, int retval, int icon, int maxlen, int x, int y, | ||||
| short width, short height, float a1, float a2, const char *tip) | short width, short height, float a1, float a2, const char *tip) | ||||
| { | { | ||||
| uiBut *but; | uiBut *but; | ||||
| but = uiDefSearchBut(block, arg, retval, icon, maxlen, x, y, width, height, a1, a2, tip); | but = uiDefSearchBut(block, arg, retval, icon, maxlen, x, y, width, height, a1, a2, tip); | ||||
| uiButSetSearchFunc(but, operator_enum_search_cb, but, operator_enum_call_cb, NULL); | UI_but_func_search_set(but, operator_enum_search_cb, but, operator_enum_call_cb, NULL); | ||||
| but->optype = ot; | but->optype = ot; | ||||
| but->opcontext = WM_OP_EXEC_DEFAULT; | but->opcontext = WM_OP_EXEC_DEFAULT; | ||||
| if (properties) { | if (properties) { | ||||
| PointerRNA *ptr = uiButGetOperatorPtrRNA(but); | PointerRNA *ptr = UI_but_operator_ptr_get(but); | ||||
| /* Copy idproperties. */ | /* Copy idproperties. */ | ||||
| ptr->data = IDP_CopyProperty(properties); | ptr->data = IDP_CopyProperty(properties); | ||||
| } | } | ||||
| return but; | return but; | ||||
| } | } | ||||
| /* push a new event onto event queue to activate the given button | /* push a new event onto event queue to activate the given button | ||||
| * (usually a text-field) upon entering a popup | * (usually a text-field) upon entering a popup | ||||
| */ | */ | ||||
| void uiButSetFocusOnEnter(wmWindow *win, uiBut *but) | void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but) | ||||
| { | { | ||||
| wmEvent event; | wmEvent event; | ||||
| wm_event_init_from_window(win, &event); | wm_event_init_from_window(win, &event); | ||||
| event.type = EVT_BUT_OPEN; | event.type = EVT_BUT_OPEN; | ||||
| event.val = KM_PRESS; | event.val = KM_PRESS; | ||||
| event.customdata = but; | event.customdata = but; | ||||
| event.customdatafree = false; | event.customdatafree = false; | ||||
| wm_event_add(win, &event); | wm_event_add(win, &event); | ||||
| } | } | ||||
| void uiButGetStrInfo(bContext *C, uiBut *but, ...) | void UI_but_string_info_get(bContext *C, uiBut *but, ...) | ||||
| { | { | ||||
| va_list args; | va_list args; | ||||
| uiStringInfo *si; | uiStringInfo *si; | ||||
| EnumPropertyItem *items = NULL, *item = NULL; | EnumPropertyItem *items = NULL, *item = NULL; | ||||
| int totitems; | int totitems; | ||||
| bool free_items = false; | bool free_items = false; | ||||
| Show All 21 Lines | if (type == BUT_GET_RNAPROP_IDENTIFIER) { | ||||
| if (but->rnaprop) | if (but->rnaprop) | ||||
| tmp = BLI_strdup(RNA_property_identifier(but->rnaprop)); | tmp = BLI_strdup(RNA_property_identifier(but->rnaprop)); | ||||
| } | } | ||||
| else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) { | else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) { | ||||
| if (but->rnaprop) | if (but->rnaprop) | ||||
| tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type)); | tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type)); | ||||
| else if (but->optype) | else if (but->optype) | ||||
| tmp = BLI_strdup(but->optype->idname); | tmp = BLI_strdup(but->optype->idname); | ||||
| else if (ELEM(but->type, MENU, PULLDOWN)) { | else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { | ||||
| MenuType *mt = uiButGetMenuType(but); | MenuType *mt = UI_but_menutype_get(but); | ||||
| if (mt) | if (mt) | ||||
| tmp = BLI_strdup(mt->idname); | tmp = BLI_strdup(mt->idname); | ||||
| } | } | ||||
| } | } | ||||
| else if (ELEM(type, BUT_GET_RNA_LABEL, BUT_GET_RNA_TIP)) { | else if (ELEM(type, BUT_GET_RNA_LABEL, BUT_GET_RNA_TIP)) { | ||||
| if (but->rnaprop) { | if (but->rnaprop) { | ||||
| if (type == BUT_GET_RNA_LABEL) | if (type == BUT_GET_RNA_LABEL) | ||||
| tmp = BLI_strdup(RNA_property_ui_name(but->rnaprop)); | tmp = BLI_strdup(RNA_property_ui_name(but->rnaprop)); | ||||
| else { | else { | ||||
| const char *t = RNA_property_ui_description(but->rnaprop); | const char *t = RNA_property_ui_description(but->rnaprop); | ||||
| if (t && t[0]) | if (t && t[0]) | ||||
| tmp = BLI_strdup(t); | tmp = BLI_strdup(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (but->optype) { | else if (but->optype) { | ||||
| if (type == BUT_GET_RNA_LABEL) | if (type == BUT_GET_RNA_LABEL) | ||||
| tmp = BLI_strdup(RNA_struct_ui_name(but->optype->srna)); | tmp = BLI_strdup(RNA_struct_ui_name(but->optype->srna)); | ||||
| else { | else { | ||||
| const char *t = RNA_struct_ui_description(but->optype->srna); | const char *t = RNA_struct_ui_description(but->optype->srna); | ||||
| if (t && t[0]) | if (t && t[0]) | ||||
| tmp = BLI_strdup(t); | tmp = BLI_strdup(t); | ||||
| } | } | ||||
| } | } | ||||
| else if (ELEM(but->type, MENU, PULLDOWN)) { | else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { | ||||
| MenuType *mt = uiButGetMenuType(but); | MenuType *mt = UI_but_menutype_get(but); | ||||
| if (mt) { | if (mt) { | ||||
| /* not all menus are from python */ | /* not all menus are from python */ | ||||
| if (mt->ext.srna) { | if (mt->ext.srna) { | ||||
| if (type == BUT_GET_RNA_LABEL) | if (type == BUT_GET_RNA_LABEL) | ||||
| tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna)); | tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna)); | ||||
| else { | else { | ||||
| const char *t = RNA_struct_ui_description(mt->ext.srna); | const char *t = RNA_struct_ui_description(mt->ext.srna); | ||||
| if (t && t[0]) | if (t && t[0]) | ||||
| tmp = BLI_strdup(t); | tmp = BLI_strdup(t); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (type == BUT_GET_RNA_LABEL_CONTEXT) { | else if (type == BUT_GET_RNA_LABEL_CONTEXT) { | ||||
| const char *_tmp = BLF_I18NCONTEXT_DEFAULT; | const char *_tmp = BLF_I18NCONTEXT_DEFAULT; | ||||
| if (but->rnaprop) | if (but->rnaprop) | ||||
| _tmp = RNA_property_translation_context(but->rnaprop); | _tmp = RNA_property_translation_context(but->rnaprop); | ||||
| else if (but->optype) | else if (but->optype) | ||||
| _tmp = RNA_struct_translation_context(but->optype->srna); | _tmp = RNA_struct_translation_context(but->optype->srna); | ||||
| else if (ELEM(but->type, MENU, PULLDOWN)) { | else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) { | ||||
| MenuType *mt = uiButGetMenuType(but); | MenuType *mt = UI_but_menutype_get(but); | ||||
| if (mt) | if (mt) | ||||
| _tmp = RNA_struct_translation_context(mt->ext.srna); | _tmp = RNA_struct_translation_context(mt->ext.srna); | ||||
| } | } | ||||
| if (BLF_is_default_context(_tmp)) { | if (BLF_is_default_context(_tmp)) { | ||||
| _tmp = BLF_I18NCONTEXT_DEFAULT_BPYRNA; | _tmp = BLF_I18NCONTEXT_DEFAULT_BPYRNA; | ||||
| } | } | ||||
| tmp = BLI_strdup(_tmp); | tmp = BLI_strdup(_tmp); | ||||
| } | } | ||||
| else if (ELEM(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) { | else if (ELEM(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) { | ||||
| PointerRNA *ptr = NULL; | PointerRNA *ptr = NULL; | ||||
| PropertyRNA *prop = NULL; | PropertyRNA *prop = NULL; | ||||
| int value = 0; | int value = 0; | ||||
| /* get the enum property... */ | /* get the enum property... */ | ||||
| if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { | if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { | ||||
| /* enum property */ | /* enum property */ | ||||
| ptr = &but->rnapoin; | ptr = &but->rnapoin; | ||||
| prop = but->rnaprop; | prop = but->rnaprop; | ||||
| value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); | value = (but->type == UI_BTYPE_ROW) ? (int)but->hardmax : (int)ui_but_value_get(but); | ||||
| } | } | ||||
| else if (but->optype) { | else if (but->optype) { | ||||
| PointerRNA *opptr = uiButGetOperatorPtrRNA(but); | PointerRNA *opptr = UI_but_operator_ptr_get(but); | ||||
| wmOperatorType *ot = but->optype; | wmOperatorType *ot = but->optype; | ||||
| /* if the default property of the operator is enum and it is set, | /* if the default property of the operator is enum and it is set, | ||||
| * fetch the tooltip of the selected value so that "Snap" and "Mirror" | * fetch the tooltip of the selected value so that "Snap" and "Mirror" | ||||
| * operator menus in the Anim Editors will show tooltips for the different | * operator menus in the Anim Editors will show tooltips for the different | ||||
| * operations instead of the meaningless generic operator tooltip | * operations instead of the meaningless generic operator tooltip | ||||
| */ | */ | ||||
| if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { | if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { | ||||
| ▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
| void UI_reinit_font(void) | void UI_reinit_font(void) | ||||
| { | { | ||||
| uiStyleInit(); | uiStyleInit(); | ||||
| } | } | ||||
| void UI_exit(void) | void UI_exit(void) | ||||
| { | { | ||||
| ui_resources_free(); | ui_resources_free(); | ||||
| ui_button_clipboard_free(); | ui_but_clipboard_free(); | ||||
| } | } | ||||