Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r--source/blender/editors/interface/CMakeLists.txt128
-rw-r--r--source/blender/editors/interface/interface.c9467
-rw-r--r--source/blender/editors/interface/interface_align.c1152
-rw-r--r--source/blender/editors/interface/interface_anim.c538
-rw-r--r--source/blender/editors/interface/interface_context_menu.c1703
-rw-r--r--source/blender/editors/interface/interface_draw.c4246
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c147
-rw-r--r--source/blender/editors/interface/interface_eyedropper_color.c450
-rw-r--r--source/blender/editors/interface/interface_eyedropper_colorband.c477
-rw-r--r--source/blender/editors/interface/interface_eyedropper_datablock.c409
-rw-r--r--source/blender/editors/interface/interface_eyedropper_depth.c510
-rw-r--r--source/blender/editors/interface/interface_eyedropper_driver.c284
-rw-r--r--source/blender/editors/interface/interface_eyedropper_intern.h24
-rw-r--r--source/blender/editors/interface/interface_handlers.c17190
-rw-r--r--source/blender/editors/interface/interface_icons.c3160
-rw-r--r--source/blender/editors/interface/interface_icons_event.c382
-rw-r--r--source/blender/editors/interface/interface_intern.h1005
-rw-r--r--source/blender/editors/interface/interface_layout.c8034
-rw-r--r--source/blender/editors/interface/interface_ops.c2363
-rw-r--r--source/blender/editors/interface/interface_panel.c4248
-rw-r--r--source/blender/editors/interface/interface_query.c595
-rw-r--r--source/blender/editors/interface/interface_region_color_picker.c1239
-rw-r--r--source/blender/editors/interface/interface_region_hud.c473
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.c496
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.c921
-rw-r--r--source/blender/editors/interface/interface_region_popover.c538
-rw-r--r--source/blender/editors/interface/interface_region_popup.c1328
-rw-r--r--source/blender/editors/interface/interface_region_search.c1275
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c2257
-rw-r--r--source/blender/editors/interface/interface_regions.c30
-rw-r--r--source/blender/editors/interface/interface_regions_intern.h4
-rw-r--r--source/blender/editors/interface/interface_style.c878
-rw-r--r--source/blender/editors/interface/interface_templates.c10223
-rw-r--r--source/blender/editors/interface/interface_utils.c1056
-rw-r--r--source/blender/editors/interface/interface_widgets.c8403
-rw-r--r--source/blender/editors/interface/resources.c2170
-rw-r--r--source/blender/editors/interface/view2d.c4461
-rw-r--r--source/blender/editors/interface/view2d_ops.c3333
38 files changed, 50218 insertions, 45379 deletions
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index fd6b0e4a0c5..622f89b1f87 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -16,95 +16,95 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenfont
- ../../blenkernel
- ../../blenlib
- ../../blenloader
- ../../blentranslation
- ../../depsgraph
- ../../draw
- ../../gpu
- ../../imbuf
- ../../makesdna
- ../../makesrna
- ../../python
- ../../windowmanager
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
+ ../include
+ ../../blenfont
+ ../../blenkernel
+ ../../blenlib
+ ../../blenloader
+ ../../blentranslation
+ ../../depsgraph
+ ../../draw
+ ../../gpu
+ ../../imbuf
+ ../../makesdna
+ ../../makesrna
+ ../../python
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- interface.c
- interface_align.c
- interface_anim.c
- interface_context_menu.c
- interface_draw.c
- interface_eyedropper.c
- interface_eyedropper_color.c
- interface_eyedropper_colorband.c
- interface_eyedropper_datablock.c
- interface_eyedropper_depth.c
- interface_eyedropper_driver.c
- interface_handlers.c
- interface_icons.c
- interface_icons_event.c
- interface_layout.c
- interface_ops.c
- interface_panel.c
- interface_query.c
- interface_region_color_picker.c
- interface_region_hud.c
- interface_region_menu_pie.c
- interface_region_menu_popup.c
- interface_region_popover.c
- interface_region_popup.c
- interface_region_search.c
- interface_region_tooltip.c
- interface_regions.c
- interface_style.c
- interface_templates.c
- interface_utils.c
- interface_widgets.c
- resources.c
- view2d.c
- view2d_ops.c
+ interface.c
+ interface_align.c
+ interface_anim.c
+ interface_context_menu.c
+ interface_draw.c
+ interface_eyedropper.c
+ interface_eyedropper_color.c
+ interface_eyedropper_colorband.c
+ interface_eyedropper_datablock.c
+ interface_eyedropper_depth.c
+ interface_eyedropper_driver.c
+ interface_handlers.c
+ interface_icons.c
+ interface_icons_event.c
+ interface_layout.c
+ interface_ops.c
+ interface_panel.c
+ interface_query.c
+ interface_region_color_picker.c
+ interface_region_hud.c
+ interface_region_menu_pie.c
+ interface_region_menu_popup.c
+ interface_region_popover.c
+ interface_region_popup.c
+ interface_region_search.c
+ interface_region_tooltip.c
+ interface_regions.c
+ interface_style.c
+ interface_templates.c
+ interface_utils.c
+ interface_widgets.c
+ resources.c
+ view2d.c
+ view2d_ops.c
- interface_eyedropper_intern.h
- interface_intern.h
- interface_regions_intern.h
+ interface_eyedropper_intern.h
+ interface_intern.h
+ interface_regions_intern.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
- bf_editor_datafiles
+ bf_blenkernel
+ bf_blenlib
+ bf_editor_datafiles
)
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
if(WITH_HEADLESS)
- add_definitions(-DWITH_HEADLESS)
+ add_definitions(-DWITH_HEADLESS)
endif()
if(WITH_CYCLES)
- add_definitions(-DWITH_CYCLES)
+ add_definitions(-DWITH_CYCLES)
endif()
if(WITH_PYTHON)
- add_definitions(-DWITH_PYTHON)
+ add_definitions(-DWITH_PYTHON)
endif()
if(WIN32)
- if(WITH_INPUT_IME)
- add_definitions(-DWITH_INPUT_IME)
- endif()
+ if(WITH_INPUT_IME)
+ add_definitions(-DWITH_INPUT_IME)
+ endif()
endif()
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index b76be4cf4d8..06b0634f6fb 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -21,13 +21,12 @@
* \ingroup edinterface
*/
-
#include <float.h>
#include <limits.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
-#include <stddef.h> /* offsetof() */
+#include <stddef.h> /* offsetof() */
#include "MEM_guardedalloc.h"
@@ -83,7 +82,10 @@
#include "interface_intern.h"
/* prototypes. */
-static void ui_but_to_pixelrect(struct rcti *rect, const struct ARegion *ar, struct uiBlock *block, struct uiBut *but);
+static void ui_but_to_pixelrect(struct rcti *rect,
+ const struct ARegion *ar,
+ struct uiBlock *block,
+ struct uiBut *but);
static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p);
static void ui_def_but_rna__panel_type(bContext *UNUSED(C), uiLayout *layout, void *but_p);
static void ui_def_but_rna__menu_type(bContext *UNUSED(C), uiLayout *layout, void *but_p);
@@ -91,222 +93,225 @@ static void ui_def_but_rna__menu_type(bContext *UNUSED(C), uiLayout *layout, voi
/* avoid unneeded calls to ui_but_value_get */
#define UI_BUT_VALUE_UNSET DBL_MAX
#define UI_GET_BUT_VALUE_INIT(_but, _value) \
- if (_value == DBL_MAX) { \
- (_value) = ui_but_value_get(_but); \
- } ((void)0)
+ if (_value == DBL_MAX) { \
+ (_value) = ui_but_value_get(_but); \
+ } \
+ ((void)0)
#define B_NOP -1
/**
* a full doc with API notes can be found in 'blender/doc/guides/interface_API.txt'
*
- * `uiBlahBlah()` external function.
- * `ui_blah_blah()` internal function.
+ * `uiBlahBlah()` external function.
+ * `ui_blah_blah()` internal function.
*/
static void ui_but_free(const bContext *C, uiBut *but);
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_but_is_unit_radians(const uiBut *but)
{
- UnitSettings *unit = but->block->unit;
- const int unit_type = UI_but_unit_type_get(but);
+ UnitSettings *unit = but->block->unit;
+ const int unit_type = UI_but_unit_type_get(but);
- return ui_but_is_unit_radians_ex(unit, unit_type);
+ return ui_but_is_unit_radians_ex(unit, unit_type);
}
/* ************* window matrix ************** */
void ui_block_to_window_fl(const ARegion *ar, uiBlock *block, float *x, float *y)
{
- float gx, gy;
- int sx, sy, getsizex, getsizey;
+ float gx, gy;
+ int sx, sy, getsizex, getsizey;
- getsizex = BLI_rcti_size_x(&ar->winrct) + 1;
- getsizey = BLI_rcti_size_y(&ar->winrct) + 1;
- sx = ar->winrct.xmin;
- sy = ar->winrct.ymin;
+ getsizex = BLI_rcti_size_x(&ar->winrct) + 1;
+ getsizey = BLI_rcti_size_y(&ar->winrct) + 1;
+ sx = ar->winrct.xmin;
+ sy = ar->winrct.ymin;
- gx = *x;
- gy = *y;
+ gx = *x;
+ gy = *y;
- if (block->panel) {
- gx += block->panel->ofsx;
- gy += block->panel->ofsy;
- }
+ if (block->panel) {
+ gx += block->panel->ofsx;
+ gy += block->panel->ofsy;
+ }
- *x = ((float)sx) + ((float)getsizex) * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] + block->winmat[3][0]));
- *y = ((float)sy) + ((float)getsizey) * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] + block->winmat[3][1]));
+ *x = ((float)sx) +
+ ((float)getsizex) * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] +
+ block->winmat[3][0]));
+ *y = ((float)sy) +
+ ((float)getsizey) * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] +
+ block->winmat[3][1]));
}
void ui_block_to_window(const ARegion *ar, uiBlock *block, int *x, int *y)
{
- float fx, fy;
+ float fx, fy;
- fx = *x;
- fy = *y;
+ fx = *x;
+ fy = *y;
- ui_block_to_window_fl(ar, block, &fx, &fy);
+ ui_block_to_window_fl(ar, block, &fx, &fy);
- *x = (int)(fx + 0.5f);
- *y = (int)(fy + 0.5f);
+ *x = (int)(fx + 0.5f);
+ *y = (int)(fy + 0.5f);
}
void ui_block_to_window_rctf(const ARegion *ar, uiBlock *block, rctf *rct_dst, const rctf *rct_src)
{
- *rct_dst = *rct_src;
- ui_block_to_window_fl(ar, block, &rct_dst->xmin, &rct_dst->ymin);
- ui_block_to_window_fl(ar, block, &rct_dst->xmax, &rct_dst->ymax);
+ *rct_dst = *rct_src;
+ ui_block_to_window_fl(ar, block, &rct_dst->xmin, &rct_dst->ymin);
+ ui_block_to_window_fl(ar, block, &rct_dst->xmax, &rct_dst->ymax);
}
float ui_block_to_window_scale(const ARegion *ar, uiBlock *block)
{
- /* We could have function for this to avoid dummy arg. */
- float dummy_x;
- float min_y = 0, max_y = 1;
- dummy_x = 0.0f;
- ui_block_to_window_fl(ar, block, &dummy_x, &min_y);
- dummy_x = 0.0f;
- ui_block_to_window_fl(ar, block, &dummy_x, &max_y);
- return max_y - min_y;
+ /* We could have function for this to avoid dummy arg. */
+ float dummy_x;
+ float min_y = 0, max_y = 1;
+ dummy_x = 0.0f;
+ ui_block_to_window_fl(ar, block, &dummy_x, &min_y);
+ dummy_x = 0.0f;
+ ui_block_to_window_fl(ar, block, &dummy_x, &max_y);
+ return max_y - min_y;
}
/* for mouse cursor */
void ui_window_to_block_fl(const ARegion *ar, uiBlock *block, float *x, float *y)
{
- float a, b, c, d, e, f, px, py;
- int sx, sy, getsizex, getsizey;
+ float a, b, c, d, e, f, px, py;
+ int sx, sy, getsizex, getsizey;
- getsizex = BLI_rcti_size_x(&ar->winrct) + 1;
- getsizey = BLI_rcti_size_y(&ar->winrct) + 1;
- sx = ar->winrct.xmin;
- sy = ar->winrct.ymin;
+ getsizex = BLI_rcti_size_x(&ar->winrct) + 1;
+ getsizey = BLI_rcti_size_y(&ar->winrct) + 1;
+ sx = ar->winrct.xmin;
+ sy = ar->winrct.ymin;
- a = 0.5f * ((float)getsizex) * block->winmat[0][0];
- b = 0.5f * ((float)getsizex) * block->winmat[1][0];
- c = 0.5f * ((float)getsizex) * (1.0f + block->winmat[3][0]);
+ a = 0.5f * ((float)getsizex) * block->winmat[0][0];
+ b = 0.5f * ((float)getsizex) * block->winmat[1][0];
+ c = 0.5f * ((float)getsizex) * (1.0f + block->winmat[3][0]);
- d = 0.5f * ((float)getsizey) * block->winmat[0][1];
- e = 0.5f * ((float)getsizey) * block->winmat[1][1];
- f = 0.5f * ((float)getsizey) * (1.0f + block->winmat[3][1]);
+ d = 0.5f * ((float)getsizey) * block->winmat[0][1];
+ e = 0.5f * ((float)getsizey) * block->winmat[1][1];
+ f = 0.5f * ((float)getsizey) * (1.0f + block->winmat[3][1]);
- px = *x - sx;
- py = *y - sy;
+ px = *x - sx;
+ py = *y - sy;
- *y = (a * (py - f) + d * (c - px)) / (a * e - d * b);
- *x = (px - b * (*y) - c) / a;
+ *y = (a * (py - f) + d * (c - px)) / (a * e - d * b);
+ *x = (px - b * (*y) - c) / a;
- if (block->panel) {
- *x -= block->panel->ofsx;
- *y -= block->panel->ofsy;
- }
+ if (block->panel) {
+ *x -= block->panel->ofsx;
+ *y -= block->panel->ofsy;
+ }
}
void ui_window_to_block(const ARegion *ar, uiBlock *block, int *x, int *y)
{
- float fx, fy;
+ float fx, fy;
- fx = *x;
- fy = *y;
+ fx = *x;
+ fy = *y;
- ui_window_to_block_fl(ar, block, &fx, &fy);
+ ui_window_to_block_fl(ar, block, &fx, &fy);
- *x = (int)(fx + 0.5f);
- *y = (int)(fy + 0.5f);
+ *x = (int)(fx + 0.5f);
+ *y = (int)(fy + 0.5f);
}
void ui_window_to_region(const ARegion *ar, int *x, int *y)
{
- *x -= ar->winrct.xmin;
- *y -= ar->winrct.ymin;
+ *x -= ar->winrct.xmin;
+ *y -= ar->winrct.ymin;
}
void ui_region_to_window(const ARegion *ar, int *x, int *y)
{
- *x += ar->winrct.xmin;
- *y += ar->winrct.ymin;
+ *x += ar->winrct.xmin;
+ *y += ar->winrct.ymin;
}
static void ui_update_flexible_spacing(const ARegion *region, uiBlock *block)
{
- int sepr_flex_len = 0;
- for (uiBut *but = block->buttons.first; but; but = but->next) {
- if (but->type == UI_BTYPE_SEPR_SPACER) {
- sepr_flex_len++;
- }
- }
-
- if (sepr_flex_len == 0) {
- return;
- }
-
- rcti rect;
- ui_but_to_pixelrect(&rect, region, block, block->buttons.last);
- const float buttons_width = (float)rect.xmax + UI_HEADER_OFFSET;
- const float region_width = (float)region->sizex * U.dpi_fac;
-
- if (region_width <= buttons_width) {
- return;
- }
-
- /* We could get rid of this loop if we agree on a max number of spacer */
- int *spacers_pos = alloca(sizeof(*spacers_pos) * (size_t)sepr_flex_len);
- int i = 0;
- for (uiBut *but = block->buttons.first; but; but = but->next) {
- if (but->type == UI_BTYPE_SEPR_SPACER) {
- ui_but_to_pixelrect(&rect, region, block, but);
- spacers_pos[i] = rect.xmax + UI_HEADER_OFFSET;
- i++;
- }
- }
-
- const float segment_width = region_width / (float)sepr_flex_len;
- float offset = 0, remaining_space = region_width - buttons_width;
- i = 0;
- for (uiBut *but = block->buttons.first; but; but = but->next) {
- BLI_rctf_translate(&but->rect, offset, 0);
- if (but->type == UI_BTYPE_SEPR_SPACER) {
- /* How much the next block overlap with the current segment */
- int overlap = (
- (i == sepr_flex_len - 1) ?
- buttons_width - spacers_pos[i] :
- (spacers_pos[i + 1] - spacers_pos[i]) / 2);
- int segment_end = segment_width * (i + 1);
- int spacer_end = segment_end - overlap;
- int spacer_sta = spacers_pos[i] + offset;
- if (spacer_end > spacer_sta) {
- float step = min_ff(remaining_space, spacer_end - spacer_sta);
- remaining_space -= step;
- offset += step;
- }
- i++;
- }
- }
- ui_block_bounds_calc(block);
+ int sepr_flex_len = 0;
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
+ if (but->type == UI_BTYPE_SEPR_SPACER) {
+ sepr_flex_len++;
+ }
+ }
+
+ if (sepr_flex_len == 0) {
+ return;
+ }
+
+ rcti rect;
+ ui_but_to_pixelrect(&rect, region, block, block->buttons.last);
+ const float buttons_width = (float)rect.xmax + UI_HEADER_OFFSET;
+ const float region_width = (float)region->sizex * U.dpi_fac;
+
+ if (region_width <= buttons_width) {
+ return;
+ }
+
+ /* We could get rid of this loop if we agree on a max number of spacer */
+ int *spacers_pos = alloca(sizeof(*spacers_pos) * (size_t)sepr_flex_len);
+ int i = 0;
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
+ if (but->type == UI_BTYPE_SEPR_SPACER) {
+ ui_but_to_pixelrect(&rect, region, block, but);
+ spacers_pos[i] = rect.xmax + UI_HEADER_OFFSET;
+ i++;
+ }
+ }
+
+ const float segment_width = region_width / (float)sepr_flex_len;
+ float offset = 0, remaining_space = region_width - buttons_width;
+ i = 0;
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
+ BLI_rctf_translate(&but->rect, offset, 0);
+ if (but->type == UI_BTYPE_SEPR_SPACER) {
+ /* How much the next block overlap with the current segment */
+ int overlap = ((i == sepr_flex_len - 1) ? buttons_width - spacers_pos[i] :
+ (spacers_pos[i + 1] - spacers_pos[i]) / 2);
+ int segment_end = segment_width * (i + 1);
+ int spacer_end = segment_end - overlap;
+ int spacer_sta = spacers_pos[i] + offset;
+ if (spacer_end > spacer_sta) {
+ float step = min_ff(remaining_space, spacer_end - spacer_sta);
+ remaining_space -= step;
+ offset += step;
+ }
+ i++;
+ }
+ }
+ ui_block_bounds_calc(block);
}
static void ui_update_window_matrix(const wmWindow *window, const ARegion *region, uiBlock *block)
{
- /* window matrix and aspect */
- if (region && region->visible) {
- /* Get projection matrix which includes View2D translation and zoom. */
- GPU_matrix_projection_get(block->winmat);
- block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]);
- }
- else {
- /* No subwindow created yet, for menus for example, so we use the main
- * window instead, since buttons are created there anyway. */
- int width = WM_window_pixels_x(window);
- int height = WM_window_pixels_y(window);
- rcti winrct = {0, width - 1, 0, height - 1};
+ /* window matrix and aspect */
+ if (region && region->visible) {
+ /* Get projection matrix which includes View2D translation and zoom. */
+ GPU_matrix_projection_get(block->winmat);
+ block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]);
+ }
+ else {
+ /* No subwindow created yet, for menus for example, so we use the main
+ * window instead, since buttons are created there anyway. */
+ int width = WM_window_pixels_x(window);
+ int height = WM_window_pixels_y(window);
+ rcti winrct = {0, width - 1, 0, height - 1};
- wmGetProjectionMatrix(block->winmat, &winrct);
- block->aspect = 2.0f / fabsf(width * block->winmat[0][0]);
- }
+ wmGetProjectionMatrix(block->winmat, &winrct);
+ block->aspect = 2.0f / fabsf(width * block->winmat[0][0]);
+ }
}
/**
@@ -315,303 +320,303 @@ static void ui_update_window_matrix(const wmWindow *window, const ARegion *regio
*/
void ui_region_winrct_get_no_margin(const struct ARegion *ar, struct rcti *r_rect)
{
- uiBlock *block = ar->uiblocks.first;
- if (block && (block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_RADIAL) == 0) {
- BLI_rcti_rctf_copy_floor(r_rect, &block->rect);
- BLI_rcti_translate(r_rect, ar->winrct.xmin, ar->winrct.ymin);
- }
- else {
- *r_rect = ar->winrct;
- }
+ uiBlock *block = ar->uiblocks.first;
+ if (block && (block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_RADIAL) == 0) {
+ BLI_rcti_rctf_copy_floor(r_rect, &block->rect);
+ BLI_rcti_translate(r_rect, ar->winrct.xmin, ar->winrct.ymin);
+ }
+ else {
+ *r_rect = ar->winrct;
+ }
}
/* ******************* block calc ************************* */
void UI_block_translate(uiBlock *block, int x, int y)
{
- uiBut *but;
+ uiBut *but;
- for (but = block->buttons.first; but; but = but->next) {
- BLI_rctf_translate(&but->rect, x, y);
- }
+ for (but = block->buttons.first; but; but = but->next) {
+ BLI_rctf_translate(&but->rect, x, y);
+ }
- BLI_rctf_translate(&block->rect, x, y);
+ BLI_rctf_translate(&block->rect, x, y);
}
static void ui_block_bounds_calc_text(uiBlock *block, float offset)
{
- uiStyle *style = UI_style_get();
- uiBut *bt, *init_col_bt, *col_bt;
- int i = 0, j, x1addval = offset;
+ uiStyle *style = UI_style_get();
+ uiBut *bt, *init_col_bt, *col_bt;
+ int i = 0, j, x1addval = offset;
- UI_fontstyle_set(&style->widget);
+ UI_fontstyle_set(&style->widget);
- for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) {
- if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) {
- j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr));
+ for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) {
+ if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) {
+ j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr));
- if (j > i) {
- i = j;
- }
- }
+ if (j > i) {
+ i = j;
+ }
+ }
- if (bt->next && bt->rect.xmin < bt->next->rect.xmin) {
- /* 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) {
- col_bt->rect.xmin = x1addval;
- col_bt->rect.xmax = x1addval + i + block->bounds;
+ if (bt->next && bt->rect.xmin < bt->next->rect.xmin) {
+ /* 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) {
+ col_bt->rect.xmin = x1addval;
+ col_bt->rect.xmax = x1addval + i + block->bounds;
- ui_but_update(col_bt); /* clips text again */
- }
+ ui_but_update(col_bt); /* clips text again */
+ }
- /* And we prepare next column. */
- x1addval += i + block->bounds;
- i = 0;
- init_col_bt = col_bt;
- }
- }
+ /* And we prepare next column. */
+ x1addval += i + block->bounds;
+ i = 0;
+ init_col_bt = col_bt;
+ }
+ }
- /* Last column. */
- for (col_bt = init_col_bt; col_bt; col_bt = col_bt->next) {
- col_bt->rect.xmin = x1addval;
- col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds);
+ /* Last column. */
+ for (col_bt = init_col_bt; col_bt; col_bt = col_bt->next) {
+ col_bt->rect.xmin = x1addval;
+ col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds);
- ui_but_update(col_bt); /* clips text again */
- }
+ ui_but_update(col_bt); /* clips text again */
+ }
}
void ui_block_bounds_calc(uiBlock *block)
{
- uiBut *bt;
- int xof;
+ uiBut *bt;
+ int xof;
- if (BLI_listbase_is_empty(&block->buttons)) {
- if (block->panel) {
- block->rect.xmin = 0.0; block->rect.xmax = block->panel->sizex;
- block->rect.ymin = 0.0; block->rect.ymax = block->panel->sizey;
- }
- }
- else {
+ if (BLI_listbase_is_empty(&block->buttons)) {
+ if (block->panel) {
+ block->rect.xmin = 0.0;
+ block->rect.xmax = block->panel->sizex;
+ block->rect.ymin = 0.0;
+ block->rect.ymax = block->panel->sizey;
+ }
+ }
+ else {
- BLI_rctf_init_minmax(&block->rect);
+ BLI_rctf_init_minmax(&block->rect);
- for (bt = block->buttons.first; bt; bt = bt->next) {
- BLI_rctf_union(&block->rect, &bt->rect);
- }
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ BLI_rctf_union(&block->rect, &bt->rect);
+ }
- block->rect.xmin -= block->bounds;
- block->rect.ymin -= block->bounds;
- block->rect.xmax += block->bounds;
- block->rect.ymax += block->bounds;
- }
+ block->rect.xmin -= block->bounds;
+ block->rect.ymin -= block->bounds;
+ block->rect.xmax += block->bounds;
+ block->rect.ymax += block->bounds;
+ }
- block->rect.xmax = block->rect.xmin + max_ff(BLI_rctf_size_x(&block->rect), block->minbounds);
+ block->rect.xmax = block->rect.xmin + max_ff(BLI_rctf_size_x(&block->rect), block->minbounds);
- /* hardcoded exception... but that one is annoying with larger safety */
- bt = block->buttons.first;
- if (bt && STREQLEN(bt->str, "ERROR", 5)) {
- xof = 10;
- }
- else {
- xof = 40;
- }
+ /* hardcoded exception... but that one is annoying with larger safety */
+ bt = block->buttons.first;
+ if (bt && STREQLEN(bt->str, "ERROR", 5)) {
+ xof = 10;
+ }
+ else {
+ xof = 40;
+ }
- block->safety.xmin = block->rect.xmin - xof;
- block->safety.ymin = block->rect.ymin - xof;
- block->safety.xmax = block->rect.xmax + xof;
- block->safety.ymax = block->rect.ymax + xof;
+ block->safety.xmin = block->rect.xmin - xof;
+ block->safety.ymin = block->rect.ymin - xof;
+ block->safety.xmax = block->rect.xmax + xof;
+ block->safety.ymax = block->rect.ymax + xof;
}
static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block)
{
- int xmax, ymax;
- int startx, starty;
- int width, height;
-
- /* note: this is used for the splash where window bounds event has not been
- * updated by ghost, get the window bounds from ghost directly */
+ int xmax, ymax;
+ int startx, starty;
+ int width, height;
- xmax = WM_window_pixels_x(window);
- ymax = WM_window_pixels_y(window);
+ /* note: this is used for the splash where window bounds event has not been
+ * updated by ghost, get the window bounds from ghost directly */
- ui_block_bounds_calc(block);
+ xmax = WM_window_pixels_x(window);
+ ymax = WM_window_pixels_y(window);
- width = BLI_rctf_size_x(&block->rect);
- height = BLI_rctf_size_y(&block->rect);
+ ui_block_bounds_calc(block);
- startx = (xmax * 0.5f) - (width * 0.5f);
- starty = (ymax * 0.5f) - (height * 0.5f);
+ width = BLI_rctf_size_x(&block->rect);
+ height = BLI_rctf_size_y(&block->rect);
- UI_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
+ startx = (xmax * 0.5f) - (width * 0.5f);
+ starty = (ymax * 0.5f) - (height * 0.5f);
- /* now recompute bounds and safety */
- ui_block_bounds_calc(block);
+ UI_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
+ /* now recompute bounds and safety */
+ ui_block_bounds_calc(block);
}
static void ui_block_bounds_calc_centered_pie(uiBlock *block)
{
- const int xy[2] = {
- block->pie_data.pie_center_spawned[0],
- block->pie_data.pie_center_spawned[1],
- };
+ const int xy[2] = {
+ block->pie_data.pie_center_spawned[0],
+ 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 */
- ui_block_bounds_calc(block);
+ /* now recompute bounds and safety */
+ ui_block_bounds_calc(block);
}
static void ui_block_bounds_calc_popup(
- wmWindow *window, uiBlock *block,
- eBlockBoundsCalc bounds_calc, const int xy[2], int r_xy[2])
+ wmWindow *window, uiBlock *block, eBlockBoundsCalc bounds_calc, const int xy[2], int r_xy[2])
{
- int width, height, oldwidth, oldheight;
- int oldbounds, xmax, ymax, raw_x, raw_y;
- const int margin = UI_SCREEN_MARGIN;
- rcti rect, rect_bounds;
- int ofs_dummy[2];
+ int width, height, oldwidth, oldheight;
+ int oldbounds, xmax, ymax, raw_x, raw_y;
+ const int margin = UI_SCREEN_MARGIN;
+ rcti rect, rect_bounds;
+ int ofs_dummy[2];
- oldbounds = block->bounds;
+ oldbounds = block->bounds;
- /* compute mouse position with user defined offset */
- ui_block_bounds_calc(block);
+ /* compute mouse position with user defined offset */
+ ui_block_bounds_calc(block);
- xmax = WM_window_pixels_x(window);
- ymax = WM_window_pixels_y(window);
+ xmax = WM_window_pixels_x(window);
+ ymax = WM_window_pixels_y(window);
- oldwidth = BLI_rctf_size_x(&block->rect);
- oldheight = BLI_rctf_size_y(&block->rect);
+ oldwidth = BLI_rctf_size_x(&block->rect);
+ oldheight = BLI_rctf_size_y(&block->rect);
- /* first we ensure wide enough text bounds */
- if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) {
- if (block->flag & UI_BLOCK_LOOP) {
- block->bounds = 2.5f * UI_UNIT_X;
- ui_block_bounds_calc_text(block, block->rect.xmin);
- }
- }
+ /* first we ensure wide enough text bounds */
+ if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) {
+ if (block->flag & UI_BLOCK_LOOP) {
+ block->bounds = 2.5f * UI_UNIT_X;
+ ui_block_bounds_calc_text(block, block->rect.xmin);
+ }
+ }
- /* next we recompute bounds */
- block->bounds = oldbounds;
- ui_block_bounds_calc(block);
+ /* next we recompute bounds */
+ block->bounds = oldbounds;
+ ui_block_bounds_calc(block);
- /* and we adjust the position to fit within window */
- width = BLI_rctf_size_x(&block->rect);
- height = BLI_rctf_size_y(&block->rect);
+ /* and we adjust the position to fit within window */
+ width = BLI_rctf_size_x(&block->rect);
+ height = BLI_rctf_size_y(&block->rect);
- /* avoid divide by zero below, caused by calling with no UI, but better not crash */
- oldwidth = oldwidth > 0 ? oldwidth : MAX2(1, width);
- oldheight = oldheight > 0 ? oldheight : MAX2(1, height);
+ /* avoid divide by zero below, caused by calling with no UI, but better not crash */
+ oldwidth = oldwidth > 0 ? oldwidth : MAX2(1, width);
+ oldheight = oldheight > 0 ? oldheight : MAX2(1, height);
- /* offset block based on mouse position, user offset is scaled
- * along in case we resized the block in ui_block_bounds_calc_text */
- raw_x = rect.xmin = xy[0] + block->rect.xmin + (block->bounds_offset[0] * width) / oldwidth;
- raw_y = rect.ymin = xy[1] + block->rect.ymin + (block->bounds_offset[1] * height) / oldheight;
- rect.xmax = rect.xmin + width;
- rect.ymax = rect.ymin + height;
+ /* offset block based on mouse position, user offset is scaled
+ * along in case we resized the block in ui_block_bounds_calc_text */
+ raw_x = rect.xmin = xy[0] + block->rect.xmin + (block->bounds_offset[0] * width) / oldwidth;
+ raw_y = rect.ymin = xy[1] + block->rect.ymin + (block->bounds_offset[1] * height) / oldheight;
+ rect.xmax = rect.xmin + width;
+ rect.ymax = rect.ymin + height;
- rect_bounds.xmin = margin;
- rect_bounds.ymin = margin;
- rect_bounds.xmax = xmax - margin;
- rect_bounds.ymax = ymax - UI_POPUP_MENU_TOP;
+ rect_bounds.xmin = margin;
+ rect_bounds.ymin = margin;
+ rect_bounds.xmax = xmax - margin;
+ rect_bounds.ymax = ymax - UI_POPUP_MENU_TOP;
- BLI_rcti_clamp(&rect, &rect_bounds, ofs_dummy);
- UI_block_translate(block, rect.xmin - block->rect.xmin, rect.ymin - block->rect.ymin);
+ BLI_rcti_clamp(&rect, &rect_bounds, ofs_dummy);
+ UI_block_translate(block, rect.xmin - block->rect.xmin, rect.ymin - block->rect.ymin);
- /* now recompute bounds and safety */
- ui_block_bounds_calc(block);
+ /* now recompute bounds and safety */
+ ui_block_bounds_calc(block);
- /* If given, adjust input coordinates such that they would generate real final popup position.
- * Needed to handle correctly floating panels once they have been dragged around,
- * see T52999. */
- if (r_xy) {
- r_xy[0] = xy[0] + block->rect.xmin - raw_x;
- r_xy[1] = xy[1] + block->rect.ymin - raw_y;
- }
+ /* If given, adjust input coordinates such that they would generate real final popup position.
+ * Needed to handle correctly floating panels once they have been dragged around,
+ * see T52999. */
+ if (r_xy) {
+ r_xy[0] = xy[0] + block->rect.xmin - raw_x;
+ r_xy[1] = xy[1] + block->rect.ymin - raw_y;
+ }
}
/* used for various cases */
void UI_block_bounds_set_normal(uiBlock *block, int addval)
{
- if (block == NULL) {
- return;
- }
+ if (block == NULL) {
+ return;
+ }
- block->bounds = addval;
- block->bounds_type = UI_BLOCK_BOUNDS;
+ block->bounds = addval;
+ block->bounds_type = UI_BLOCK_BOUNDS;
}
/* used for pulldowns */
void UI_block_bounds_set_text(uiBlock *block, int addval)
{
- block->bounds = addval;
- block->bounds_type = UI_BLOCK_BOUNDS_TEXT;
+ block->bounds = addval;
+ block->bounds_type = UI_BLOCK_BOUNDS_TEXT;
}
/* used for block popups */
void UI_block_bounds_set_popup(uiBlock *block, int addval, const int bounds_offset[2])
{
- block->bounds = addval;
- block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MOUSE;
- if (bounds_offset != NULL) {
- block->bounds_offset[0] = bounds_offset[0];
- block->bounds_offset[1] = bounds_offset[1];
- }
- else {
- block->bounds_offset[0] = 0;
- block->bounds_offset[1] = 0;
- }
+ block->bounds = addval;
+ block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MOUSE;
+ if (bounds_offset != NULL) {
+ block->bounds_offset[0] = bounds_offset[0];
+ block->bounds_offset[1] = bounds_offset[1];
+ }
+ else {
+ block->bounds_offset[0] = 0;
+ block->bounds_offset[1] = 0;
+ }
}
/* used for menu popups */
void UI_block_bounds_set_menu(uiBlock *block, int addval, const int bounds_offset[2])
{
- block->bounds = addval;
- block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MENU;
- if (bounds_offset != NULL) {
- block->bounds_offset[0] = bounds_offset[0];
- block->bounds_offset[1] = bounds_offset[1];
- }
- else {
- block->bounds_offset[0] = 0;
- block->bounds_offset[1] = 0;
- }
+ block->bounds = addval;
+ block->bounds_type = UI_BLOCK_BOUNDS_POPUP_MENU;
+ if (bounds_offset != NULL) {
+ block->bounds_offset[0] = bounds_offset[0];
+ block->bounds_offset[1] = bounds_offset[1];
+ }
+ else {
+ block->bounds_offset[0] = 0;
+ block->bounds_offset[1] = 0;
+ }
}
/* used for centered popups, i.e. splash */
void UI_block_bounds_set_centered(uiBlock *block, int addval)
{
- block->bounds = addval;
- block->bounds_type = UI_BLOCK_BOUNDS_POPUP_CENTER;
+ block->bounds = addval;
+ block->bounds_type = UI_BLOCK_BOUNDS_POPUP_CENTER;
}
void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy)
{
- block->rect.xmin = minx;
- block->rect.ymin = miny;
- block->rect.xmax = maxx;
- block->rect.ymax = maxy;
- block->bounds_type = UI_BLOCK_BOUNDS_NONE;
+ block->rect.xmin = minx;
+ block->rect.ymin = miny;
+ block->rect.xmax = maxx;
+ block->rect.ymax = maxy;
+ block->bounds_type = UI_BLOCK_BOUNDS_NONE;
}
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:
- * * If button is radians, we want additional precision (see T39861).
- * * If prec is not set, we fallback to a simple default */
- if (ui_but_is_unit_radians(but) && prec < 5) {
- prec = 5;
- }
- else if (prec == -1) {
- prec = (but->hardmax < 10.001f) ? 3 : 2;
- }
- else {
- CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
- }
+ /* first check for various special cases:
+ * * If button is radians, we want additional precision (see T39861).
+ * * If prec is not set, we fallback to a simple default */
+ if (ui_but_is_unit_radians(but) && prec < 5) {
+ prec = 5;
+ }
+ else if (prec == -1) {
+ prec = (but->hardmax < 10.001f) ? 3 : 2;
+ }
+ else {
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+ }
- return UI_calc_float_precision(prec, value);
+ return UI_calc_float_precision(prec, value);
}
/* ************** BLOCK ENDING FUNCTION ************* */
@@ -619,187 +624,206 @@ static int ui_but_calc_float_precision(uiBut *but, double value)
/* NOTE: if but->poin is allocated memory for every defbut, things fail... */
static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
{
- /* various properties are being compared here, hopefully sufficient
- * to catch all cases, but it is simple to add more checks later */
- if (but->retval != oldbut->retval) { return false; }
- if (but->rnapoin.data != oldbut->rnapoin.data) { return false; }
- if (but->rnaprop != oldbut->rnaprop || but->rnaindex != oldbut->rnaindex) { return false; }
- if (but->func != oldbut->func) { return false; }
- if (but->funcN != oldbut->funcN) { return false; }
- if (oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) { return false; }
- if (oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) { return false; }
- if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) ||
- (but->pointype != oldbut->pointype))) { return false; }
- if (but->optype != oldbut->optype) { return false; }
-
- return true;
+ /* various properties are being compared here, hopefully sufficient
+ * to catch all cases, but it is simple to add more checks later */
+ if (but->retval != oldbut->retval) {
+ return false;
+ }
+ if (but->rnapoin.data != oldbut->rnapoin.data) {
+ return false;
+ }
+ if (but->rnaprop != oldbut->rnaprop || but->rnaindex != oldbut->rnaindex) {
+ return false;
+ }
+ if (but->func != oldbut->func) {
+ return false;
+ }
+ if (but->funcN != oldbut->funcN) {
+ return false;
+ }
+ if (oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) {
+ return false;
+ }
+ if (oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) {
+ return false;
+ }
+ if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) ||
+ (but->pointype != oldbut->pointype))) {
+ return false;
+ }
+ if (but->optype != oldbut->optype) {
+ return false;
+ }
+
+ return true;
}
uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new)
{
- uiBut *but_old;
- for (but_old = block_old->buttons.first; but_old; but_old = but_old->next) {
- if (ui_but_equals_old(but_new, but_old)) {
- break;
- }
- }
- return but_old;
+ uiBut *but_old;
+ for (but_old = block_old->buttons.first; but_old; but_old = but_old->next) {
+ if (ui_but_equals_old(but_new, but_old)) {
+ break;
+ }
+ }
+ return but_old;
}
uiBut *ui_but_find_new(uiBlock *block_new, const uiBut *but_old)
{
- uiBut *but_new;
- for (but_new = block_new->buttons.first; but_new; but_new = but_new->next) {
- if (ui_but_equals_old(but_new, but_old)) {
- break;
- }
- }
- return but_new;
+ uiBut *but_new;
+ for (but_new = block_new->buttons.first; but_new; but_new = but_new->next) {
+ if (ui_but_equals_old(but_new, but_old)) {
+ break;
+ }
+ }
+ return but_new;
}
/**
* \return true when \a but_p is set (only done for active buttons).
*/
-static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut **but_p, uiBut **but_old_p)
+static bool ui_but_update_from_old_block(const bContext *C,
+ uiBlock *block,
+ uiBut **but_p,
+ uiBut **but_old_p)
{
- const int drawflag_copy = 0; /* None currently. */
-
- uiBlock *oldblock = block->oldblock;
- uiBut *oldbut = NULL, *but = *but_p;
- bool found_active = false;
+ const int drawflag_copy = 0; /* None currently. */
+ uiBlock *oldblock = block->oldblock;
+ uiBut *oldbut = NULL, *but = *but_p;
+ bool found_active = false;
#if 0
- /* simple/stupid - search every time */
- oldbut = ui_but_find_old(oldblock, but);
- (void)but_old_p;
+ /* simple/stupid - search every time */
+ oldbut = ui_but_find_old(oldblock, but);
+ (void)but_old_p;
#else
- BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1);
-
- /* fastpath - avoid loop-in-loop, calling 'ui_but_find_old'
- * as long as old/new buttons are aligned */
- if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) {
- oldbut = *but_old_p;
- }
- else {
- /* fallback to block search */
- oldbut = ui_but_find_old(oldblock, but);
- }
- (*but_old_p) = oldbut ? oldbut->next : NULL;
+ BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1);
+
+ /* fastpath - avoid loop-in-loop, calling 'ui_but_find_old'
+ * as long as old/new buttons are aligned */
+ if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) {
+ oldbut = *but_old_p;
+ }
+ else {
+ /* fallback to block search */
+ oldbut = ui_but_find_old(oldblock, but);
+ }
+ (*but_old_p) = oldbut ? oldbut->next : NULL;
#endif
+ if (!oldbut) {
+ return found_active;
+ }
- if (!oldbut) {
- return found_active;
- }
-
- if (oldbut->active) {
- /* flags from the buttons we want to refresh, may want to add more here... */
- const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
+ if (oldbut->active) {
+ /* flags from the buttons we want to refresh, may want to add more here... */
+ const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
- found_active = true;
+ found_active = true;
#if 0
- but->flag = oldbut->flag;
- but->active = oldbut->active;
- but->pos = oldbut->pos;
- but->ofs = oldbut->ofs;
- but->editstr = oldbut->editstr;
- but->editval = oldbut->editval;
- but->editvec = oldbut->editvec;
- but->editcoba = oldbut->editcoba;
- but->editcumap = oldbut->editcumap;
- but->selsta = oldbut->selsta;
- but->selend = oldbut->selend;
- but->softmin = oldbut->softmin;
- but->softmax = oldbut->softmax;
- oldbut->active = NULL;
+ but->flag = oldbut->flag;
+ but->active = oldbut->active;
+ but->pos = oldbut->pos;
+ but->ofs = oldbut->ofs;
+ but->editstr = oldbut->editstr;
+ but->editval = oldbut->editval;
+ but->editvec = oldbut->editvec;
+ but->editcoba = oldbut->editcoba;
+ but->editcumap = oldbut->editcumap;
+ but->selsta = oldbut->selsta;
+ but->selend = oldbut->selend;
+ but->softmin = oldbut->softmin;
+ but->softmax = oldbut->softmax;
+ oldbut->active = NULL;
#endif
- /* move button over from oldblock to new block */
- BLI_remlink(&oldblock->buttons, oldbut);
- BLI_insertlinkafter(&block->buttons, but, oldbut);
- oldbut->block = block;
- *but_p = oldbut;
-
- /* still stuff needs to be copied */
- oldbut->rect = but->rect;
- oldbut->context = but->context; /* set by Layout */
-
- /* drawing */
- oldbut->icon = but->icon;
- oldbut->iconadd = but->iconadd;
- oldbut->alignnr = but->alignnr;
-
- /* typically the same pointers, but not on undo/redo */
- /* XXX some menu buttons store button itself in but->poin. Ugly */
- if (oldbut->poin != (char *)oldbut) {
- SWAP(char *, oldbut->poin, but->poin);
- SWAP(void *, oldbut->func_argN, but->func_argN);
- }
-
- /* Move tooltip from new to old. */
- SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
- SWAP(void *, oldbut->tip_argN, but->tip_argN);
-
- oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
- oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
-
- /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
- * when scrolling without moving mouse (see [#28432]) */
- if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
- oldbut->hardmax = but->hardmax;
- }
-
- /* Selectively copy a1, a2 since their use differs across all button types
- * (and we'll probably split these out later) */
- if (ELEM(oldbut->type, UI_BTYPE_PROGRESS_BAR)) {
- oldbut->a1 = but->a1;
- }
-
- if (!BLI_listbase_is_empty(&block->butstore)) {
- UI_butstore_register_update(block, oldbut, but);
- }
-
- /* move/copy string from the new button to the old */
- /* needed for alt+mouse wheel over enums */
- if (but->str != but->strdata) {
- if (oldbut->str != oldbut->strdata) {
- SWAP(char *, but->str, oldbut->str);
- }
- else {
- oldbut->str = but->str;
- but->str = but->strdata;
- }
- }
- else {
- if (oldbut->str != oldbut->strdata) {
- MEM_freeN(oldbut->str);
- oldbut->str = oldbut->strdata;
- }
- BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
- }
-
- if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- SWAP(void *, but->dragpoin, oldbut->dragpoin);
- }
-
- BLI_remlink(&block->buttons, but);
- ui_but_free(C, but);
-
- /* note: if layout hasn't been applied yet, it uses old button pointers... */
- }
- else {
- const int flag_copy = UI_BUT_DRAG_MULTI;
-
- but->flag = (but->flag & ~flag_copy) | (oldbut->flag & flag_copy);
-
- /* ensures one button can get activated, and in case the buttons
- * draw are the same this gives O(1) lookup for each button */
- BLI_remlink(&oldblock->buttons, oldbut);
- ui_but_free(C, oldbut);
- }
-
- return found_active;
+ /* move button over from oldblock to new block */
+ BLI_remlink(&oldblock->buttons, oldbut);
+ BLI_insertlinkafter(&block->buttons, but, oldbut);
+ oldbut->block = block;
+ *but_p = oldbut;
+
+ /* still stuff needs to be copied */
+ oldbut->rect = but->rect;
+ oldbut->context = but->context; /* set by Layout */
+
+ /* drawing */
+ oldbut->icon = but->icon;
+ oldbut->iconadd = but->iconadd;
+ oldbut->alignnr = but->alignnr;
+
+ /* typically the same pointers, but not on undo/redo */
+ /* XXX some menu buttons store button itself in but->poin. Ugly */
+ if (oldbut->poin != (char *)oldbut) {
+ SWAP(char *, oldbut->poin, but->poin);
+ SWAP(void *, oldbut->func_argN, but->func_argN);
+ }
+
+ /* Move tooltip from new to old. */
+ SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
+ SWAP(void *, oldbut->tip_argN, but->tip_argN);
+
+ oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
+ oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
+
+ /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
+ * when scrolling without moving mouse (see [#28432]) */
+ if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
+ oldbut->hardmax = but->hardmax;
+ }
+
+ /* Selectively copy a1, a2 since their use differs across all button types
+ * (and we'll probably split these out later) */
+ if (ELEM(oldbut->type, UI_BTYPE_PROGRESS_BAR)) {
+ oldbut->a1 = but->a1;
+ }
+
+ if (!BLI_listbase_is_empty(&block->butstore)) {
+ UI_butstore_register_update(block, oldbut, but);
+ }
+
+ /* move/copy string from the new button to the old */
+ /* needed for alt+mouse wheel over enums */
+ if (but->str != but->strdata) {
+ if (oldbut->str != oldbut->strdata) {
+ SWAP(char *, but->str, oldbut->str);
+ }
+ else {
+ oldbut->str = but->str;
+ but->str = but->strdata;
+ }
+ }
+ else {
+ if (oldbut->str != oldbut->strdata) {
+ MEM_freeN(oldbut->str);
+ oldbut->str = oldbut->strdata;
+ }
+ BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
+ }
+
+ if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ SWAP(void *, but->dragpoin, oldbut->dragpoin);
+ }
+
+ BLI_remlink(&block->buttons, but);
+ ui_but_free(C, but);
+
+ /* note: if layout hasn't been applied yet, it uses old button pointers... */
+ }
+ else {
+ const int flag_copy = UI_BUT_DRAG_MULTI;
+
+ but->flag = (but->flag & ~flag_copy) | (oldbut->flag & flag_copy);
+
+ /* ensures one button can get activated, and in case the buttons
+ * draw are the same this gives O(1) lookup for each button */
+ BLI_remlink(&oldblock->buttons, oldbut);
+ ui_but_free(C, oldbut);
+ }
+
+ return found_active;
}
/* needed for temporarily rename buttons, such as in outliner or file-select,
@@ -807,165 +831,163 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
/* returns 0 when button removed */
bool UI_but_active_only(const bContext *C, ARegion *ar, uiBlock *block, uiBut *but)
{
- uiBlock *oldblock;
- uiBut *oldbut;
- bool activate = false, found = false, isactive = false;
-
- oldblock = block->oldblock;
- if (!oldblock) {
- activate = true;
- }
- else {
- oldbut = ui_but_find_old(oldblock, but);
- if (oldbut) {
- found = true;
-
- if (oldbut->active) {
- isactive = true;
- }
- }
- }
- if ((activate == true) || (found == false)) {
- ui_but_activate_event((bContext *)C, ar, but);
- }
- else if ((found == true) && (isactive == false)) {
- BLI_remlink(&block->buttons, but);
- ui_but_free(C, but);
- return false;
- }
-
- return true;
+ uiBlock *oldblock;
+ uiBut *oldbut;
+ bool activate = false, found = false, isactive = false;
+
+ oldblock = block->oldblock;
+ if (!oldblock) {
+ activate = true;
+ }
+ else {
+ oldbut = ui_but_find_old(oldblock, but);
+ if (oldbut) {
+ found = true;
+
+ if (oldbut->active) {
+ isactive = true;
+ }
+ }
+ }
+ if ((activate == true) || (found == false)) {
+ ui_but_activate_event((bContext *)C, ar, but);
+ }
+ else if ((found == true) && (isactive == false)) {
+ BLI_remlink(&block->buttons, but);
+ ui_but_free(C, but);
+ return false;
+ }
+
+ return true;
}
bool UI_block_active_only_flagged_buttons(const bContext *C, ARegion *ar, uiBlock *block)
{
- bool done = false;
- for (uiBut *but = block->buttons.first; but; but = but->next) {
- if (!done && ui_but_is_editable(but)) {
- if (but->flag & UI_BUT_ACTIVATE_ON_INIT) {
- if (UI_but_active_only(C, ar, block, but)) {
- done = true;
- }
- }
- }
- but->flag &= ~UI_BUT_ACTIVATE_ON_INIT;
- }
- return done;
+ bool done = false;
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
+ if (!done && ui_but_is_editable(but)) {
+ if (but->flag & UI_BUT_ACTIVATE_ON_INIT) {
+ if (UI_but_active_only(C, ar, block, but)) {
+ done = true;
+ }
+ }
+ }
+ but->flag &= ~UI_BUT_ACTIVATE_ON_INIT;
+ }
+ return done;
}
-
-
/* simulate button click */
void UI_but_execute(const bContext *C, uiBut *but)
{
- ARegion *ar = CTX_wm_region(C);
- void *active_back;
- ui_but_execute_begin((bContext *)C, ar, but, &active_back);
- /* Value is applied in begin. No further action required. */
- ui_but_execute_end((bContext *)C, ar, but, active_back);
+ ARegion *ar = CTX_wm_region(C);
+ void *active_back;
+ ui_but_execute_begin((bContext *)C, ar, but, &active_back);
+ /* Value is applied in begin. No further action required. */
+ 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
* returns false if undo needs to be disabled. */
static bool ui_but_is_rna_undo(const uiBut *but)
{
- if (but->rnapoin.id.data) {
- /* 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
- * unforeseen consequences, so best check for ID's we _know_ are not
- * handled by undo - campbell */
- ID *id = but->rnapoin.id.data;
- if (ID_CHECK_UNDO(id) == false) {
- return false;
- }
- else {
- return true;
- }
- }
- else if (but->rnapoin.type && !RNA_struct_undo_check(but->rnapoin.type)) {
- return false;
- }
-
- return true;
+ if (but->rnapoin.id.data) {
+ /* 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
+ * unforeseen consequences, so best check for ID's we _know_ are not
+ * handled by undo - campbell */
+ ID *id = but->rnapoin.id.data;
+ if (ID_CHECK_UNDO(id) == false) {
+ return false;
+ }
+ else {
+ return true;
+ }
+ }
+ else if (but->rnapoin.type && !RNA_struct_undo_check(but->rnapoin.type)) {
+ return false;
+ }
+
+ return true;
}
/* assigns automatic keybindings to menu items for fast access
* (underline key in menu) */
static void ui_menu_block_set_keyaccels(uiBlock *block)
{
- uiBut *but;
-
- uint menu_key_mask = 0;
- uchar menu_key;
- const char *str_pt;
- int pass;
- int tot_missing = 0;
-
- /* only do it before bounding */
- if (block->rect.xmin != block->rect.xmax) {
- return;
- }
-
- for (pass = 0; pass < 2; pass++) {
- /* 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 */
-
- for (but = block->buttons.first; but; but = but->next) {
- 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 */
- }
- else if (but->menu_key == '\0') {
- if (but->str) {
- for (str_pt = but->str; *str_pt; ) {
- menu_key = tolower(*str_pt);
- if ((menu_key >= 'a' && menu_key <= 'z') && !(menu_key_mask & 1 << (menu_key - 'a'))) {
- menu_key_mask |= 1 << (menu_key - 'a');
- break;
- }
-
- if (pass == 0) {
- /* Skip to next delimiter on first pass (be picky) */
- while (isalpha(*str_pt)) {
- str_pt++;
- }
-
- if (*str_pt) {
- str_pt++;
- }
- }
- else {
- /* just step over every char second pass and find first usable key */
- str_pt++;
- }
- }
-
- if (*str_pt) {
- but->menu_key = menu_key;
- }
- else {
- /* run second pass */
- tot_missing++;
- }
-
- /* if all keys have been used just exit, unlikely */
- if (menu_key_mask == (1 << 26) - 1) {
- return;
- }
- }
- }
- }
-
- /* check if second pass is needed */
- if (!tot_missing) {
- break;
- }
- }
+ uiBut *but;
+
+ uint menu_key_mask = 0;
+ uchar menu_key;
+ const char *str_pt;
+ int pass;
+ int tot_missing = 0;
+
+ /* only do it before bounding */
+ if (block->rect.xmin != block->rect.xmax) {
+ return;
+ }
+
+ for (pass = 0; pass < 2; pass++) {
+ /* 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 */
+
+ for (but = block->buttons.first; but; but = but->next) {
+ 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 */
+ }
+ else if (but->menu_key == '\0') {
+ if (but->str) {
+ for (str_pt = but->str; *str_pt;) {
+ menu_key = tolower(*str_pt);
+ if ((menu_key >= 'a' && menu_key <= 'z') && !(menu_key_mask & 1 << (menu_key - 'a'))) {
+ menu_key_mask |= 1 << (menu_key - 'a');
+ break;
+ }
+
+ if (pass == 0) {
+ /* Skip to next delimiter on first pass (be picky) */
+ while (isalpha(*str_pt)) {
+ str_pt++;
+ }
+
+ if (*str_pt) {
+ str_pt++;
+ }
+ }
+ else {
+ /* just step over every char second pass and find first usable key */
+ str_pt++;
+ }
+ }
+
+ if (*str_pt) {
+ but->menu_key = menu_key;
+ }
+ else {
+ /* run second pass */
+ tot_missing++;
+ }
+
+ /* if all keys have been used just exit, unlikely */
+ if (menu_key_mask == (1 << 26) - 1) {
+ return;
+ }
+ }
+ }
+ }
+
+ /* check if second pass is needed */
+ if (!tot_missing) {
+ break;
+ }
+ }
}
/* XXX, this code will shorten any allocated string to 'UI_MAX_NAME_STR'
@@ -973,35 +995,32 @@ static void ui_menu_block_set_keyaccels(uiBlock *block)
* but this could be supported */
void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_strip)
{
- if (do_strip && (but->flag & UI_BUT_HAS_SEP_CHAR)) {
- char *cpoin = strrchr(but->str, UI_SEP_CHAR);
- if (cpoin) {
- *cpoin = '\0';
- }
- but->flag &= ~UI_BUT_HAS_SEP_CHAR;
- }
-
- /* without this, just allow stripping of the shortcut */
- if (shortcut_str) {
- char *butstr_orig;
-
- if (but->str != but->strdata) {
- butstr_orig = but->str; /* free after using as source buffer */
- }
- else {
- butstr_orig = BLI_strdup(but->str);
- }
- BLI_snprintf(
- but->strdata,
- sizeof(but->strdata),
- "%s" UI_SEP_CHAR_S "%s",
- butstr_orig, shortcut_str);
- MEM_freeN(butstr_orig);
- but->str = but->strdata;
- but->flag |= UI_BUT_HAS_SEP_CHAR;
- but->drawflag |= UI_BUT_HAS_SHORTCUT;
- ui_but_update(but);
- }
+ if (do_strip && (but->flag & UI_BUT_HAS_SEP_CHAR)) {
+ char *cpoin = strrchr(but->str, UI_SEP_CHAR);
+ if (cpoin) {
+ *cpoin = '\0';
+ }
+ but->flag &= ~UI_BUT_HAS_SEP_CHAR;
+ }
+
+ /* without this, just allow stripping of the shortcut */
+ if (shortcut_str) {
+ char *butstr_orig;
+
+ if (but->str != but->strdata) {
+ butstr_orig = but->str; /* free after using as source buffer */
+ }
+ else {
+ butstr_orig = BLI_strdup(but->str);
+ }
+ BLI_snprintf(
+ but->strdata, sizeof(but->strdata), "%s" UI_SEP_CHAR_S "%s", butstr_orig, shortcut_str);
+ MEM_freeN(butstr_orig);
+ but->str = but->strdata;
+ but->flag |= UI_BUT_HAS_SEP_CHAR;
+ but->drawflag |= UI_BUT_HAS_SHORTCUT;
+ ui_but_update(but);
+ }
}
/* -------------------------------------------------------------------- */
@@ -1011,308 +1030,321 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str
* - #ui_but_event_property_operator_string
* \{ */
-static bool ui_but_event_operator_string_from_operator(
- const bContext *C, uiBut *but,
- char *buf, const size_t buf_len)
-{
- BLI_assert(but->optype != NULL);
- bool found = false;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
- if (WM_key_event_operator_string(
- C, but->optype->idname, but->opcontext, prop, true,
- buf, buf_len))
- {
- found = true;
- }
- return found;
-}
-
-static bool ui_but_event_operator_string_from_menu(
- const bContext *C, uiBut *but,
- char *buf, const size_t buf_len)
-{
- MenuType *mt = UI_but_menutype_get(but);
- BLI_assert(mt != NULL);
-
- bool found = false;
- IDProperty *prop_menu;
-
- /* annoying, create a property */
- IDPropertyTemplate val = {0};
- prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */
- IDP_AddToGroup(prop_menu, IDP_NewString(mt->idname, "name", sizeof(mt->idname)));
-
- if (WM_key_event_operator_string(
- C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, true,
- buf, buf_len))
- {
- found = true;
- }
-
- IDP_FreeProperty(prop_menu);
- MEM_freeN(prop_menu);
- return found;
-}
-
-static bool ui_but_event_operator_string_from_panel(
- const bContext *C, uiBut *but,
- char *buf, const size_t buf_len)
-{
- /** Nearly exact copy of #ui_but_event_operator_string_from_menu */
- PanelType *pt = UI_but_paneltype_get(but);
- BLI_assert(pt != NULL);
-
- bool found = false;
- IDProperty *prop_panel;
-
- /* annoying, create a property */
- IDPropertyTemplate val = {0};
- prop_panel = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */
- IDP_AddToGroup(prop_panel, IDP_NewString(pt->idname, "name", sizeof(pt->idname)));
- IDP_AddToGroup(prop_panel, IDP_New(IDP_INT, &(IDPropertyTemplate){ .i = pt->space_type, }, "space_type"));
- IDP_AddToGroup(prop_panel, IDP_New(IDP_INT, &(IDPropertyTemplate){ .i = pt->region_type, }, "region_type"));
-
- for (int i = 0; i < 2; i++) {
- /* FIXME(campbell): We can't reasonably search all configurations - long term. */
- IDP_ReplaceInGroup(prop_panel, IDP_New(IDP_INT, &(IDPropertyTemplate){ .i = i, }, "keep_open"));
- if (WM_key_event_operator_string(
- C, "WM_OT_call_panel", WM_OP_INVOKE_REGION_WIN, prop_panel, true,
- buf, buf_len))
- {
- found = true;
- break;
- }
- }
-
- IDP_FreeProperty(prop_panel);
- MEM_freeN(prop_panel);
- return found;
-}
-
-static bool ui_but_event_operator_string(
- const bContext *C, uiBut *but,
- char *buf, const size_t buf_len)
-{
- bool found = false;
-
- if (but->optype != NULL) {
- found = ui_but_event_operator_string_from_operator(C, but, buf, buf_len);
- }
- else if (UI_but_menutype_get(but) != NULL) {
- found = ui_but_event_operator_string_from_menu(C, but, buf, buf_len);
- }
- else if (UI_but_paneltype_get(but) != NULL) {
- found = ui_but_event_operator_string_from_panel(C, but, buf, buf_len);
- }
-
- return found;
-}
-
-static bool ui_but_event_property_operator_string(
- const bContext *C, uiBut *but,
- char *buf, const size_t buf_len)
-{
- /* context toggle operator names to check... */
-
- /* This function could use a refactor to generalize button type to operator relationship
- * as well as which operators use properties.
- * - Campbell
- * */
- const char *ctx_toggle_opnames[] = {
- "WM_OT_context_toggle",
- "WM_OT_context_toggle_enum",
- "WM_OT_context_cycle_int",
- "WM_OT_context_cycle_enum",
- "WM_OT_context_cycle_array",
- "WM_OT_context_menu_enum",
- NULL,
- };
-
- const char *ctx_enum_opnames[] = {
- "WM_OT_context_set_enum",
- NULL,
- };
-
- const char *ctx_enum_opnames_for_Area_ui_type[] = {
- "SCREEN_OT_space_type_set_or_cycle",
- NULL,
- };
-
- const char **opnames = ctx_toggle_opnames;
- int opnames_len = ARRAY_SIZE(ctx_toggle_opnames);
-
-
- int prop_enum_value = -1;
- bool prop_enum_value_ok = false;
- bool prop_enum_value_is_int = false;
- const char *prop_enum_value_id = "value";
- PointerRNA *ptr = &but->rnapoin;
- PropertyRNA *prop = but->rnaprop;
- if ((but->type == UI_BTYPE_BUT_MENU) && (but->block->handle != NULL)) {
- uiBut *but_parent = but->block->handle->popup_create_vars.but;
- if ((but->type == UI_BTYPE_BUT_MENU) &&
- (but_parent && but_parent->rnaprop) &&
- (RNA_property_type(but_parent->rnaprop) == PROP_ENUM) &&
- ELEM(but_parent->menu_create_func,
- ui_def_but_rna__menu,
- ui_def_but_rna__panel_type,
- ui_def_but_rna__menu_type))
- {
- prop_enum_value = (int)but->hardmin;
- ptr = &but_parent->rnapoin;
- prop = but_parent->rnaprop;
- prop_enum_value_ok = true;
-
- opnames = ctx_enum_opnames;
- opnames_len = ARRAY_SIZE(ctx_enum_opnames);
- }
- }
-
- bool found = false;
-
- /* Don't use the button again. */
- but = NULL;
-
- /* this version is only for finding hotkeys for properties
- * (which get set via context using operators) */
- if (prop) {
- /* to avoid massive slowdowns on property panels, for now, we only check the
- * hotkeys for Editor / Scene settings...
- *
- * TODO: userpref settings?
- */
- char *data_path = NULL;
-
- if (ptr->id.data) {
- ID *id = ptr->id.data;
-
- if (GS(id->name) == ID_SCR) {
- /* screen/editor property
- * NOTE: in most cases, there is actually no info for backwards tracing
- * how to get back to ID from the editor data we may be dealing with
- */
- if (RNA_struct_is_a(ptr->type, &RNA_Space)) {
- /* data should be directly on here... */
- data_path = BLI_sprintfN("space_data.%s", RNA_property_identifier(prop));
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_Area)) {
- /* data should be directly on here... */
- const char *prop_id = RNA_property_identifier(prop);
- /* Hack since keys access 'type', UI shows 'ui_type'. */
- if (STREQ(prop_id, "ui_type")) {
- prop_id = "type";
- prop_enum_value >>= 16;
- prop = RNA_struct_find_property(ptr, prop_id);
-
- opnames = ctx_enum_opnames_for_Area_ui_type;
- opnames_len = ARRAY_SIZE(ctx_enum_opnames_for_Area_ui_type);
- prop_enum_value_id = "space_type";
- prop_enum_value_is_int = true;
- }
- else {
- data_path = BLI_sprintfN("area.%s", prop_id);
- }
- }
- else {
- /* special exceptions for common nested data in editors... */
- if (RNA_struct_is_a(ptr->type, &RNA_DopeSheet)) {
- /* dopesheet filtering options... */
- data_path = BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(prop));
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_FileSelectParams)) {
- /* Filebrowser options... */
- data_path = BLI_sprintfN("space_data.params.%s", RNA_property_identifier(prop));
- }
- }
- }
- else if (GS(id->name) == ID_SCE) {
- if (RNA_struct_is_a(ptr->type, &RNA_ToolSettings)) {
- /* toolsettings property
- * NOTE: toolsettings is usually accessed directly (i.e. not through scene)
- */
- data_path = RNA_path_from_ID_to_property(ptr, prop);
- }
- else {
- /* scene property */
- char *path = RNA_path_from_ID_to_property(ptr, prop);
-
- if (path) {
- data_path = BLI_sprintfN("scene.%s", path);
- MEM_freeN(path);
- }
+static bool ui_but_event_operator_string_from_operator(const bContext *C,
+ uiBut *but,
+ char *buf,
+ const size_t buf_len)
+{
+ BLI_assert(but->optype != NULL);
+ bool found = false;
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+
+ if (WM_key_event_operator_string(
+ C, but->optype->idname, but->opcontext, prop, true, buf, buf_len)) {
+ found = true;
+ }
+ return found;
+}
+
+static bool ui_but_event_operator_string_from_menu(const bContext *C,
+ uiBut *but,
+ char *buf,
+ const size_t buf_len)
+{
+ MenuType *mt = UI_but_menutype_get(but);
+ BLI_assert(mt != NULL);
+
+ bool found = false;
+ IDProperty *prop_menu;
+
+ /* annoying, create a property */
+ IDPropertyTemplate val = {0};
+ prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */
+ IDP_AddToGroup(prop_menu, IDP_NewString(mt->idname, "name", sizeof(mt->idname)));
+
+ if (WM_key_event_operator_string(
+ C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, true, buf, buf_len)) {
+ found = true;
+ }
+
+ IDP_FreeProperty(prop_menu);
+ MEM_freeN(prop_menu);
+ return found;
+}
+
+static bool ui_but_event_operator_string_from_panel(const bContext *C,
+ uiBut *but,
+ char *buf,
+ const size_t buf_len)
+{
+ /** Nearly exact copy of #ui_but_event_operator_string_from_menu */
+ PanelType *pt = UI_but_paneltype_get(but);
+ BLI_assert(pt != NULL);
+
+ bool found = false;
+ IDProperty *prop_panel;
+
+ /* annoying, create a property */
+ IDPropertyTemplate val = {0};
+ prop_panel = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */
+ IDP_AddToGroup(prop_panel, IDP_NewString(pt->idname, "name", sizeof(pt->idname)));
+ IDP_AddToGroup(prop_panel,
+ IDP_New(IDP_INT,
+ &(IDPropertyTemplate){
+ .i = pt->space_type,
+ },
+ "space_type"));
+ IDP_AddToGroup(prop_panel,
+ IDP_New(IDP_INT,
+ &(IDPropertyTemplate){
+ .i = pt->region_type,
+ },
+ "region_type"));
+
+ for (int i = 0; i < 2; i++) {
+ /* FIXME(campbell): We can't reasonably search all configurations - long term. */
+ IDP_ReplaceInGroup(prop_panel,
+ IDP_New(IDP_INT,
+ &(IDPropertyTemplate){
+ .i = i,
+ },
+ "keep_open"));
+ if (WM_key_event_operator_string(
+ C, "WM_OT_call_panel", WM_OP_INVOKE_REGION_WIN, prop_panel, true, buf, buf_len)) {
+ found = true;
+ break;
+ }
+ }
+
+ IDP_FreeProperty(prop_panel);
+ MEM_freeN(prop_panel);
+ return found;
+}
+
+static bool ui_but_event_operator_string(const bContext *C,
+ uiBut *but,
+ char *buf,
+ const size_t buf_len)
+{
+ bool found = false;
+
+ if (but->optype != NULL) {
+ found = ui_but_event_operator_string_from_operator(C, but, buf, buf_len);
+ }
+ else if (UI_but_menutype_get(but) != NULL) {
+ found = ui_but_event_operator_string_from_menu(C, but, buf, buf_len);
+ }
+ else if (UI_but_paneltype_get(but) != NULL) {
+ found = ui_but_event_operator_string_from_panel(C, but, buf, buf_len);
+ }
+
+ return found;
+}
+
+static bool ui_but_event_property_operator_string(const bContext *C,
+ uiBut *but,
+ char *buf,
+ const size_t buf_len)
+{
+ /* context toggle operator names to check... */
+
+ /* This function could use a refactor to generalize button type to operator relationship
+ * as well as which operators use properties.
+ * - Campbell
+ * */
+ const char *ctx_toggle_opnames[] = {
+ "WM_OT_context_toggle",
+ "WM_OT_context_toggle_enum",
+ "WM_OT_context_cycle_int",
+ "WM_OT_context_cycle_enum",
+ "WM_OT_context_cycle_array",
+ "WM_OT_context_menu_enum",
+ NULL,
+ };
+
+ const char *ctx_enum_opnames[] = {
+ "WM_OT_context_set_enum",
+ NULL,
+ };
+
+ const char *ctx_enum_opnames_for_Area_ui_type[] = {
+ "SCREEN_OT_space_type_set_or_cycle",
+ NULL,
+ };
+
+ const char **opnames = ctx_toggle_opnames;
+ int opnames_len = ARRAY_SIZE(ctx_toggle_opnames);
+
+ int prop_enum_value = -1;
+ bool prop_enum_value_ok = false;
+ bool prop_enum_value_is_int = false;
+ const char *prop_enum_value_id = "value";
+ PointerRNA *ptr = &but->rnapoin;
+ PropertyRNA *prop = but->rnaprop;
+ if ((but->type == UI_BTYPE_BUT_MENU) && (but->block->handle != NULL)) {
+ uiBut *but_parent = but->block->handle->popup_create_vars.but;
+ if ((but->type == UI_BTYPE_BUT_MENU) && (but_parent && but_parent->rnaprop) &&
+ (RNA_property_type(but_parent->rnaprop) == PROP_ENUM) &&
+ ELEM(but_parent->menu_create_func,
+ ui_def_but_rna__menu,
+ ui_def_but_rna__panel_type,
+ ui_def_but_rna__menu_type)) {
+ prop_enum_value = (int)but->hardmin;
+ ptr = &but_parent->rnapoin;
+ prop = but_parent->rnaprop;
+ prop_enum_value_ok = true;
+
+ opnames = ctx_enum_opnames;
+ opnames_len = ARRAY_SIZE(ctx_enum_opnames);
+ }
+ }
+
+ bool found = false;
+
+ /* Don't use the button again. */
+ but = NULL;
+
+ /* this version is only for finding hotkeys for properties
+ * (which get set via context using operators) */
+ if (prop) {
+ /* to avoid massive slowdowns on property panels, for now, we only check the
+ * hotkeys for Editor / Scene settings...
+ *
+ * TODO: userpref settings?
+ */
+ char *data_path = NULL;
+
+ if (ptr->id.data) {
+ ID *id = ptr->id.data;
+
+ if (GS(id->name) == ID_SCR) {
+ /* screen/editor property
+ * NOTE: in most cases, there is actually no info for backwards tracing
+ * how to get back to ID from the editor data we may be dealing with
+ */
+ if (RNA_struct_is_a(ptr->type, &RNA_Space)) {
+ /* data should be directly on here... */
+ data_path = BLI_sprintfN("space_data.%s", RNA_property_identifier(prop));
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Area)) {
+ /* data should be directly on here... */
+ const char *prop_id = RNA_property_identifier(prop);
+ /* Hack since keys access 'type', UI shows 'ui_type'. */
+ if (STREQ(prop_id, "ui_type")) {
+ prop_id = "type";
+ prop_enum_value >>= 16;
+ prop = RNA_struct_find_property(ptr, prop_id);
+
+ opnames = ctx_enum_opnames_for_Area_ui_type;
+ opnames_len = ARRAY_SIZE(ctx_enum_opnames_for_Area_ui_type);
+ prop_enum_value_id = "space_type";
+ prop_enum_value_is_int = true;
+ }
+ else {
+ data_path = BLI_sprintfN("area.%s", prop_id);
+ }
+ }
+ else {
+ /* special exceptions for common nested data in editors... */
+ if (RNA_struct_is_a(ptr->type, &RNA_DopeSheet)) {
+ /* dopesheet filtering options... */
+ data_path = BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(prop));
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_FileSelectParams)) {
+ /* Filebrowser options... */
+ data_path = BLI_sprintfN("space_data.params.%s", RNA_property_identifier(prop));
+ }
+ }
+ }
+ else if (GS(id->name) == ID_SCE) {
+ if (RNA_struct_is_a(ptr->type, &RNA_ToolSettings)) {
+ /* toolsettings property
+ * NOTE: toolsettings is usually accessed directly (i.e. not through scene)
+ */
+ data_path = RNA_path_from_ID_to_property(ptr, prop);
+ }
+ else {
+ /* scene property */
+ char *path = RNA_path_from_ID_to_property(ptr, prop);
+
+ if (path) {
+ data_path = BLI_sprintfN("scene.%s", path);
+ MEM_freeN(path);
+ }
#if 0
- else {
- printf("ERROR in %s(): Couldn't get path for scene property - %s\n",
- __func__, RNA_property_identifier(prop));
- }
+ else {
+ printf("ERROR in %s(): Couldn't get path for scene property - %s\n",
+ __func__, RNA_property_identifier(prop));
+ }
#endif
- }
- }
- else {
- //puts("other id");
- }
-
- //printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(prop), data_path);
- }
-
- /* we have a datapath! */
- if (data_path || (prop_enum_value_ok && prop_enum_value_id)) {
- /* create a property to host the "datapath" property we're sending to the operators */
- IDProperty *prop_path;
-
- IDPropertyTemplate val = {0};
- prop_path = IDP_New(IDP_GROUP, &val, __func__);
- if (data_path) {
- IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path", strlen(data_path) + 1));
- }
- if (prop_enum_value_ok) {
- const EnumPropertyItem *item;
- bool free;
- RNA_property_enum_items((bContext *)C, ptr, prop, &item, NULL, &free);
- int index = RNA_enum_from_value(item, prop_enum_value);
- if (index != -1) {
- IDProperty *prop_value;
- if (prop_enum_value_is_int) {
- int value = item[index].value;
- prop_value = IDP_New(IDP_INT, &(IDPropertyTemplate){ .i = value, }, prop_enum_value_id);
- }
- else {
- const char *id = item[index].identifier;
- prop_value = IDP_NewString(id, prop_enum_value_id, strlen(id) + 1);
- }
- IDP_AddToGroup(prop_path, prop_value);
- }
- else {
- opnames_len = 0; /* Do nothing. */
- }
- if (free) {
- MEM_freeN((void *)item);
- }
- }
-
- /* check each until one works... */
-
- for (int i = 0; (i < opnames_len) && (opnames[i]); i++) {
- if (WM_key_event_operator_string(
- C, opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false,
- buf, buf_len))
- {
- found = true;
- break;
- }
- }
-
- /* cleanup */
- IDP_FreeProperty(prop_path);
- MEM_freeN(prop_path);
- if (data_path) {
- MEM_freeN(data_path);
- }
- }
- }
-
- return found;
+ }
+ }
+ else {
+ //puts("other id");
+ }
+
+ //printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(prop), data_path);
+ }
+
+ /* we have a datapath! */
+ if (data_path || (prop_enum_value_ok && prop_enum_value_id)) {
+ /* create a property to host the "datapath" property we're sending to the operators */
+ IDProperty *prop_path;
+
+ IDPropertyTemplate val = {0};
+ prop_path = IDP_New(IDP_GROUP, &val, __func__);
+ if (data_path) {
+ IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path", strlen(data_path) + 1));
+ }
+ if (prop_enum_value_ok) {
+ const EnumPropertyItem *item;
+ bool free;
+ RNA_property_enum_items((bContext *)C, ptr, prop, &item, NULL, &free);
+ int index = RNA_enum_from_value(item, prop_enum_value);
+ if (index != -1) {
+ IDProperty *prop_value;
+ if (prop_enum_value_is_int) {
+ int value = item[index].value;
+ prop_value = IDP_New(IDP_INT,
+ &(IDPropertyTemplate){
+ .i = value,
+ },
+ prop_enum_value_id);
+ }
+ else {
+ const char *id = item[index].identifier;
+ prop_value = IDP_NewString(id, prop_enum_value_id, strlen(id) + 1);
+ }
+ IDP_AddToGroup(prop_path, prop_value);
+ }
+ else {
+ opnames_len = 0; /* Do nothing. */
+ }
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+ }
+
+ /* check each until one works... */
+
+ for (int i = 0; (i < opnames_len) && (opnames[i]); i++) {
+ if (WM_key_event_operator_string(
+ C, opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false, buf, buf_len)) {
+ found = true;
+ break;
+ }
+ }
+
+ /* cleanup */
+ IDP_FreeProperty(prop_path);
+ MEM_freeN(prop_path);
+ if (data_path) {
+ MEM_freeN(data_path);
+ }
+ }
+ }
+
+ return found;
}
/** \} */
@@ -1342,356 +1374,359 @@ static bool ui_but_event_property_operator_string(
*
* --Matt 07/2006
*/
-const char ui_radial_dir_order[8] = {
- UI_RADIAL_W, UI_RADIAL_E, UI_RADIAL_S, UI_RADIAL_N,
- UI_RADIAL_NW, UI_RADIAL_NE, UI_RADIAL_SW, UI_RADIAL_SE};
-
-const char ui_radial_dir_to_numpad[8] = {8, 9, 6, 3, 2, 1, 4, 7};
-const short ui_radial_dir_to_angle[8] = {90, 45, 0, 315, 270, 225, 180, 135};
+const char ui_radial_dir_order[8] = {UI_RADIAL_W,
+ UI_RADIAL_E,
+ UI_RADIAL_S,
+ UI_RADIAL_N,
+ UI_RADIAL_NW,
+ UI_RADIAL_NE,
+ UI_RADIAL_SW,
+ UI_RADIAL_SE};
+
+const char ui_radial_dir_to_numpad[8] = {8, 9, 6, 3, 2, 1, 4, 7};
+const short ui_radial_dir_to_angle[8] = {90, 45, 0, 315, 270, 225, 180, 135};
static void ui_but_pie_direction_string(uiBut *but, char *buf, int size)
{
- BLI_assert(but->pie_dir < ARRAY_SIZE(ui_radial_dir_to_numpad));
- BLI_snprintf(buf, size, "%d", ui_radial_dir_to_numpad[but->pie_dir]);
+ BLI_assert(but->pie_dir < ARRAY_SIZE(ui_radial_dir_to_numpad));
+ BLI_snprintf(buf, size, "%d", ui_radial_dir_to_numpad[but->pie_dir]);
}
static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
{
- uiBut *but;
- char buf[128];
-
- BLI_assert(block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS));
-
- /* only do it before bounding */
- if (block->rect.xmin != block->rect.xmax) {
- return;
- }
- if (STREQ(block->name, "splash")) {
- return;
- }
-
- if (block->flag & UI_BLOCK_RADIAL) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but->pie_dir != UI_RADIAL_NONE) {
- ui_but_pie_direction_string(but, buf, sizeof(buf));
- ui_but_add_shortcut(but, buf, false);
- }
- }
- }
- else {
- for (but = block->buttons.first; but; but = but->next) {
- if (block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) {
- /* Skip icon-only buttons (as used in the toolbar). */
- if (but->drawstr[0] == '\0') {
- continue;
- }
- else if (((block->flag & UI_BLOCK_POPOVER) == 0) && UI_but_is_tool(but)) {
- /* For non-popovers, shown in shortcut only
- * (has special shortcut handling code). */
- continue;
- }
- }
- else if (but->dt != UI_EMBOSS_PULLDOWN) {
- continue;
- }
-
- if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
- ui_but_add_shortcut(but, buf, false);
- }
- else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) {
- ui_but_add_shortcut(but, buf, false);
- }
- }
- }
+ uiBut *but;
+ char buf[128];
+
+ BLI_assert(block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS));
+
+ /* only do it before bounding */
+ if (block->rect.xmin != block->rect.xmax) {
+ return;
+ }
+ if (STREQ(block->name, "splash")) {
+ return;
+ }
+
+ if (block->flag & UI_BLOCK_RADIAL) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->pie_dir != UI_RADIAL_NONE) {
+ ui_but_pie_direction_string(but, buf, sizeof(buf));
+ ui_but_add_shortcut(but, buf, false);
+ }
+ }
+ }
+ else {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) {
+ /* Skip icon-only buttons (as used in the toolbar). */
+ if (but->drawstr[0] == '\0') {
+ continue;
+ }
+ else if (((block->flag & UI_BLOCK_POPOVER) == 0) && UI_but_is_tool(but)) {
+ /* For non-popovers, shown in shortcut only
+ * (has special shortcut handling code). */
+ continue;
+ }
+ }
+ else if (but->dt != UI_EMBOSS_PULLDOWN) {
+ continue;
+ }
+
+ if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
+ ui_but_add_shortcut(but, buf, false);
+ }
+ else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) {
+ ui_but_add_shortcut(but, buf, false);
+ }
+ }
+ }
}
void ui_but_override_flag(uiBut *but)
{
- const int override_status = RNA_property_static_override_status(&but->rnapoin, but->rnaprop, but->rnaindex);
+ const int override_status = RNA_property_static_override_status(
+ &but->rnapoin, but->rnaprop, but->rnaindex);
- if (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN) {
- but->flag |= UI_BUT_OVERRIDEN;
- }
- else {
- but->flag &= ~UI_BUT_OVERRIDEN;
- }
+ if (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN) {
+ but->flag |= UI_BUT_OVERRIDEN;
+ }
+ else {
+ but->flag &= ~UI_BUT_OVERRIDEN;
+ }
}
void UI_block_update_from_old(const bContext *C, uiBlock *block)
{
- uiBut *but_old;
- uiBut *but;
+ uiBut *but_old;
+ uiBut *but;
- if (!block->oldblock) {
- return;
- }
+ if (!block->oldblock) {
+ return;
+ }
- but_old = block->oldblock->buttons.first;
+ but_old = block->oldblock->buttons.first;
- if (BLI_listbase_is_empty(&block->oldblock->butstore) == false) {
- UI_butstore_update(block);
- }
+ if (BLI_listbase_is_empty(&block->oldblock->butstore) == false) {
+ UI_butstore_update(block);
+ }
- for (but = block->buttons.first; but; but = but->next) {
- if (ui_but_update_from_old_block(C, block, &but, &but_old)) {
- ui_but_update(but);
+ for (but = block->buttons.first; but; but = but->next) {
+ if (ui_but_update_from_old_block(C, block, &but, &but_old)) {
+ ui_but_update(but);
- /* redraw dynamic tooltip if we have one open */
- if (but->tip_func) {
- UI_but_tooltip_refresh((bContext *)C, but);
- }
- }
- }
+ /* redraw dynamic tooltip if we have one open */
+ if (but->tip_func) {
+ UI_but_tooltip_refresh((bContext *)C, but);
+ }
+ }
+ }
- block->auto_open = block->oldblock->auto_open;
- block->auto_open_last = block->oldblock->auto_open_last;
- block->tooltipdisabled = block->oldblock->tooltipdisabled;
- BLI_movelisttolist(&block->color_pickers.list, &block->oldblock->color_pickers.list);
+ block->auto_open = block->oldblock->auto_open;
+ block->auto_open_last = block->oldblock->auto_open_last;
+ block->tooltipdisabled = block->oldblock->tooltipdisabled;
+ BLI_movelisttolist(&block->color_pickers.list, &block->oldblock->color_pickers.list);
- block->oldblock = NULL;
+ block->oldblock = NULL;
}
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
{
- wmWindow *window = CTX_wm_window(C);
- Scene *scene = CTX_data_scene(C);
- ARegion *region = CTX_wm_region(C);
- uiBut *but;
-
- BLI_assert(block->active);
-
- UI_block_update_from_old(C, block);
-
- /* inherit flags from 'old' buttons that was drawn here previous, based
- * on matching buttons, we need this to make button event handling non
- * blocking, while still allowing buttons to be remade each redraw as it
- * is expected by blender code */
- for (but = block->buttons.first; but; but = but->next) {
- /* temp? Proper check for graying out */
- if (but->optype) {
- wmOperatorType *ot = but->optype;
-
- if (but->context) {
- CTX_store_set((bContext *)C, but->context);
- }
-
- if (ot == NULL || WM_operator_poll_context((bContext *)C, ot, but->opcontext) == 0) {
- but->flag |= UI_BUT_DISABLED;
- }
-
- if (but->context) {
- CTX_store_set((bContext *)C, NULL);
- }
- }
-
- ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
- ui_but_override_flag(but);
- if (UI_but_is_decorator(but)) {
- ui_but_anim_decorate_update_from_flag(but);
- }
- }
-
-
-
- /* handle pending stuff */
- if (block->layouts.first) {
- UI_block_layout_resolve(block, NULL, NULL);
- }
- ui_block_align_calc(block, CTX_wm_region(C));
- if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) {
- ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
- }
-
- if (block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS)) {
- ui_menu_block_set_keymaps(C, block);
- }
-
- /* after keymaps! */
- switch (block->bounds_type) {
- case UI_BLOCK_BOUNDS_NONE:
- break;
- case UI_BLOCK_BOUNDS:
- ui_block_bounds_calc(block);
- break;
- case UI_BLOCK_BOUNDS_TEXT:
- ui_block_bounds_calc_text(block, 0.0f);
- break;
- case UI_BLOCK_BOUNDS_POPUP_CENTER:
- ui_block_bounds_calc_centered(window, block);
- break;
- case UI_BLOCK_BOUNDS_PIE_CENTER:
- ui_block_bounds_calc_centered_pie(block);
- break;
-
- /* fallback */
- case UI_BLOCK_BOUNDS_POPUP_MOUSE:
- case UI_BLOCK_BOUNDS_POPUP_MENU:
- ui_block_bounds_calc_popup(window, block, block->bounds_type, xy, r_xy);
- break;
- }
-
- if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
- UI_block_bounds_set_normal(block, 0);
- }
- if (block->flag & UI_BUT_ALIGN) {
- UI_block_align_end(block);
- }
-
- ui_update_flexible_spacing(region, block);
-
- block->endblock = 1;
+ wmWindow *window = CTX_wm_window(C);
+ Scene *scene = CTX_data_scene(C);
+ ARegion *region = CTX_wm_region(C);
+ uiBut *but;
+
+ BLI_assert(block->active);
+
+ UI_block_update_from_old(C, block);
+
+ /* inherit flags from 'old' buttons that was drawn here previous, based
+ * on matching buttons, we need this to make button event handling non
+ * blocking, while still allowing buttons to be remade each redraw as it
+ * is expected by blender code */
+ for (but = block->buttons.first; but; but = but->next) {
+ /* temp? Proper check for graying out */
+ if (but->optype) {
+ wmOperatorType *ot = but->optype;
+
+ if (but->context) {
+ CTX_store_set((bContext *)C, but->context);
+ }
+
+ if (ot == NULL || WM_operator_poll_context((bContext *)C, ot, but->opcontext) == 0) {
+ but->flag |= UI_BUT_DISABLED;
+ }
+
+ if (but->context) {
+ CTX_store_set((bContext *)C, NULL);
+ }
+ }
+
+ ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
+ ui_but_override_flag(but);
+ if (UI_but_is_decorator(but)) {
+ ui_but_anim_decorate_update_from_flag(but);
+ }
+ }
+
+ /* handle pending stuff */
+ if (block->layouts.first) {
+ UI_block_layout_resolve(block, NULL, NULL);
+ }
+ ui_block_align_calc(block, CTX_wm_region(C));
+ if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) {
+ ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
+ }
+
+ if (block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS)) {
+ ui_menu_block_set_keymaps(C, block);
+ }
+
+ /* after keymaps! */
+ switch (block->bounds_type) {
+ case UI_BLOCK_BOUNDS_NONE:
+ break;
+ case UI_BLOCK_BOUNDS:
+ ui_block_bounds_calc(block);
+ break;
+ case UI_BLOCK_BOUNDS_TEXT:
+ ui_block_bounds_calc_text(block, 0.0f);
+ break;
+ case UI_BLOCK_BOUNDS_POPUP_CENTER:
+ ui_block_bounds_calc_centered(window, block);
+ break;
+ case UI_BLOCK_BOUNDS_PIE_CENTER:
+ ui_block_bounds_calc_centered_pie(block);
+ break;
+
+ /* fallback */
+ case UI_BLOCK_BOUNDS_POPUP_MOUSE:
+ case UI_BLOCK_BOUNDS_POPUP_MENU:
+ ui_block_bounds_calc_popup(window, block, block->bounds_type, xy, r_xy);
+ break;
+ }
+
+ if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
+ UI_block_bounds_set_normal(block, 0);
+ }
+ if (block->flag & UI_BUT_ALIGN) {
+ UI_block_align_end(block);
+ }
+
+ ui_update_flexible_spacing(region, block);
+
+ block->endblock = 1;
}
void UI_block_end(const bContext *C, uiBlock *block)
{
- wmWindow *window = CTX_wm_window(C);
+ wmWindow *window = CTX_wm_window(C);
- UI_block_end_ex(C, block, &window->eventstate->x, NULL);
+ UI_block_end_ex(C, block, &window->eventstate->x, NULL);
}
/* ************** BLOCK DRAWING FUNCTION ************* */
void ui_fontscale(short *points, float aspect)
{
- if (aspect < 0.9f || aspect > 1.1f) {
- float pointsf = *points;
+ if (aspect < 0.9f || aspect > 1.1f) {
+ float pointsf = *points;
- /* for some reason scaling fonts goes too fast compared to widget size */
- /* XXX not true anymore? (ton) */
- //aspect = sqrt(aspect);
- pointsf /= aspect;
+ /* for some reason scaling fonts goes too fast compared to widget size */
+ /* XXX not true anymore? (ton) */
+ //aspect = sqrt(aspect);
+ pointsf /= aspect;
- if (aspect > 1.0f) {
- *points = ceilf(pointsf);
- }
- else {
- *points = floorf(pointsf);
- }
- }
+ if (aspect > 1.0f) {
+ *points = ceilf(pointsf);
+ }
+ else {
+ *points = floorf(pointsf);
+ }
+ }
}
/* project button or block (but==NULL) to pixels in regionspace */
static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, uiBut *but)
{
- rctf rectf;
+ rctf rectf;
- ui_block_to_window_rctf(ar, block, &rectf, (but) ? &but->rect : &block->rect);
- BLI_rcti_rctf_copy_round(rect, &rectf);
- BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
+ ui_block_to_window_rctf(ar, block, &rectf, (but) ? &but->rect : &block->rect);
+ BLI_rcti_rctf_copy_round(rect, &rectf);
+ BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
}
/* uses local copy of style, to scale things down, and allow widgets to change stuff */
void UI_block_draw(const bContext *C, uiBlock *block)
{
- uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */
- ARegion *ar;
- uiBut *but;
- rcti rect;
-
- /* get menu region or area region */
- ar = CTX_wm_menu(C);
- if (!ar) {
- ar = CTX_wm_region(C);
- }
-
- if (!block->endblock) {
- UI_block_end(C, block);
- }
-
- /* we set this only once */
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- /* scale fonts */
- ui_fontscale(&style.paneltitle.points, block->aspect);
- ui_fontscale(&style.grouplabel.points, block->aspect);
- ui_fontscale(&style.widgetlabel.points, block->aspect);
- ui_fontscale(&style.widget.points, block->aspect);
-
- /* scale block min/max to rect */
- ui_but_to_pixelrect(&rect, ar, block, NULL);
-
- /* pixel space for AA widgets */
- GPU_matrix_push_projection();
- GPU_matrix_push();
- GPU_matrix_identity_set();
-
- wmOrtho2_region_pixelspace(ar);
-
- /* back */
- if (block->flag & UI_BLOCK_RADIAL) {
- ui_draw_pie_center(block);
- }
- else if (block->flag & UI_BLOCK_POPOVER) {
- ui_draw_popover_back(ar, &style, block, &rect);
- }
- else if (block->flag & UI_BLOCK_LOOP) {
- ui_draw_menu_back(&style, block, &rect);
- }
- else if (block->panel) {
- bool show_background = ar->alignment != RGN_ALIGN_FLOAT;
- ui_draw_aligned_panel(
- &style, block, &rect,
- UI_panel_category_is_visible(ar), show_background);
- }
-
- BLF_batch_draw_begin();
- UI_icon_draw_cache_begin();
- UI_widgetbase_draw_cache_begin();
-
- /* widgets */
- for (but = block->buttons.first; but; but = but->next) {
- if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) {
- ui_but_to_pixelrect(&rect, ar, block, but);
-
- /* XXX: figure out why invalid coordinates happen when closing render window */
- /* and material preview is redrawn in main window (temp fix for bug #23848) */
- if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) {
- ui_draw_but(C, ar, &style, but, &rect);
- }
- }
- }
-
- UI_widgetbase_draw_cache_end();
- UI_icon_draw_cache_end();
- BLF_batch_draw_end();
-
- /* restore matrix */
- GPU_matrix_pop_projection();
- GPU_matrix_pop();
+ uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */
+ ARegion *ar;
+ uiBut *but;
+ rcti rect;
+
+ /* get menu region or area region */
+ ar = CTX_wm_menu(C);
+ if (!ar) {
+ ar = CTX_wm_region(C);
+ }
+
+ if (!block->endblock) {
+ UI_block_end(C, block);
+ }
+
+ /* we set this only once */
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ /* scale fonts */
+ ui_fontscale(&style.paneltitle.points, block->aspect);
+ ui_fontscale(&style.grouplabel.points, block->aspect);
+ ui_fontscale(&style.widgetlabel.points, block->aspect);
+ ui_fontscale(&style.widget.points, block->aspect);
+
+ /* scale block min/max to rect */
+ ui_but_to_pixelrect(&rect, ar, block, NULL);
+
+ /* pixel space for AA widgets */
+ GPU_matrix_push_projection();
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
+
+ wmOrtho2_region_pixelspace(ar);
+
+ /* back */
+ if (block->flag & UI_BLOCK_RADIAL) {
+ ui_draw_pie_center(block);
+ }
+ else if (block->flag & UI_BLOCK_POPOVER) {
+ ui_draw_popover_back(ar, &style, block, &rect);
+ }
+ else if (block->flag & UI_BLOCK_LOOP) {
+ ui_draw_menu_back(&style, block, &rect);
+ }
+ else if (block->panel) {
+ bool show_background = ar->alignment != RGN_ALIGN_FLOAT;
+ ui_draw_aligned_panel(&style, block, &rect, UI_panel_category_is_visible(ar), show_background);
+ }
+
+ BLF_batch_draw_begin();
+ UI_icon_draw_cache_begin();
+ UI_widgetbase_draw_cache_begin();
+
+ /* widgets */
+ for (but = block->buttons.first; but; but = but->next) {
+ if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) {
+ ui_but_to_pixelrect(&rect, ar, block, but);
+
+ /* XXX: figure out why invalid coordinates happen when closing render window */
+ /* and material preview is redrawn in main window (temp fix for bug #23848) */
+ if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) {
+ ui_draw_but(C, ar, &style, but, &rect);
+ }
+ }
+ }
+
+ UI_widgetbase_draw_cache_end();
+ UI_icon_draw_cache_end();
+ BLF_batch_draw_end();
+
+ /* restore matrix */
+ GPU_matrix_pop_projection();
+ GPU_matrix_pop();
}
static void ui_block_message_subscribe(ARegion *ar, struct wmMsgBus *mbus, uiBlock *block)
{
- uiBut *but_prev = NULL;
- /* possibly we should keep the region this block is contained in? */
- for (uiBut *but = block->buttons.first; but; but = but->next) {
- if (but->rnapoin.type && but->rnaprop) {
- /* quick check to avoid adding buttons representing a vector, multiple times. */
- if ((but_prev &&
- (but_prev->rnaprop == but->rnaprop) &&
- (but_prev->rnapoin.type == but->rnapoin.type) &&
- (but_prev->rnapoin.data == but->rnapoin.data) &&
- (but_prev->rnapoin.id.data == but->rnapoin.id.data)) == false)
- {
- /* TODO: could make this into utility function. */
- WM_msg_subscribe_rna(
- mbus, &but->rnapoin, but->rnaprop,
- &(const wmMsgSubscribeValue){
- .owner = ar,
- .user_data = ar,
- .notify = ED_region_do_msg_notify_tag_redraw,
- }, __func__);
- but_prev = but;
- }
- }
- }
+ uiBut *but_prev = NULL;
+ /* possibly we should keep the region this block is contained in? */
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
+ if (but->rnapoin.type && but->rnaprop) {
+ /* quick check to avoid adding buttons representing a vector, multiple times. */
+ if ((but_prev && (but_prev->rnaprop == but->rnaprop) &&
+ (but_prev->rnapoin.type == but->rnapoin.type) &&
+ (but_prev->rnapoin.data == but->rnapoin.data) &&
+ (but_prev->rnapoin.id.data == but->rnapoin.id.data)) == false) {
+ /* TODO: could make this into utility function. */
+ WM_msg_subscribe_rna(mbus,
+ &but->rnapoin,
+ but->rnaprop,
+ &(const wmMsgSubscribeValue){
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ },
+ __func__);
+ but_prev = but;
+ }
+ }
+ }
}
void UI_region_message_subscribe(ARegion *ar, struct wmMsgBus *mbus)
{
- for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
- ui_block_message_subscribe(ar, mbus, block);
- }
+ for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
+ ui_block_message_subscribe(ar, mbus, block);
+ }
}
/* ************* EVENTS ************* */
@@ -1703,116 +1738,117 @@ void UI_region_message_subscribe(ARegion *ar, struct wmMsgBus *mbus)
*/
int ui_but_is_pushed_ex(uiBut *but, double *value)
{
- int is_push = 0;
-
- if (but->bit) {
- const bool state = !ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N);
- int lvalue;
- UI_GET_BUT_VALUE_INIT(but, *value);
- lvalue = (int)*value;
- if (UI_BITBUT_TEST(lvalue, (but->bitnr))) {
- is_push = state;
- }
- else {
- is_push = !state;
- }
- }
- else {
- switch (but->type) {
- case UI_BTYPE_BUT:
- case UI_BTYPE_HOTKEY_EVENT:
- case UI_BTYPE_KEY_EVENT:
- case UI_BTYPE_COLOR:
- is_push = -1;
- break;
- case UI_BTYPE_BUT_TOGGLE:
- case UI_BTYPE_TOGGLE:
- case UI_BTYPE_ICON_TOGGLE:
- case UI_BTYPE_CHECKBOX:
- UI_GET_BUT_VALUE_INIT(but, *value);
- if (*value != (double)but->hardmin) {
- is_push = true;
- }
- break;
- case UI_BTYPE_ICON_TOGGLE_N:
- case UI_BTYPE_TOGGLE_N:
- case UI_BTYPE_CHECKBOX_N:
- UI_GET_BUT_VALUE_INIT(but, *value);
- if (*value == 0.0) {
- is_push = true;
- }
- break;
- case UI_BTYPE_ROW:
- case UI_BTYPE_LISTROW:
- case UI_BTYPE_TAB:
- if ((but->type == UI_BTYPE_TAB) && but->rnaprop && but->custom_data) {
- /* uiBut.custom_data points to data this tab represents (e.g. workspace).
- * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
- if (RNA_property_type(but->rnaprop) == PROP_POINTER) {
- PointerRNA active_ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
- if (active_ptr.data == but->custom_data) {
- is_push = true;
- }
- }
- break;
- }
- else if (but->optype) {
- break;
- }
-
- UI_GET_BUT_VALUE_INIT(but, *value);
- /* support for rna enum buts */
- if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
- if ((int)*value & (int)but->hardmax) {
- is_push = true;
- }
- }
- else {
- if (*value == (double)but->hardmax) {
- is_push = true;
- }
- }
- break;
- default:
- is_push = -1;
- break;
- }
- }
-
- return is_push;
+ int is_push = 0;
+
+ if (but->bit) {
+ const bool state = !ELEM(
+ but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N);
+ int lvalue;
+ UI_GET_BUT_VALUE_INIT(but, *value);
+ lvalue = (int)*value;
+ if (UI_BITBUT_TEST(lvalue, (but->bitnr))) {
+ is_push = state;
+ }
+ else {
+ is_push = !state;
+ }
+ }
+ else {
+ switch (but->type) {
+ case UI_BTYPE_BUT:
+ case UI_BTYPE_HOTKEY_EVENT:
+ case UI_BTYPE_KEY_EVENT:
+ case UI_BTYPE_COLOR:
+ is_push = -1;
+ break;
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_CHECKBOX:
+ UI_GET_BUT_VALUE_INIT(but, *value);
+ if (*value != (double)but->hardmin) {
+ is_push = true;
+ }
+ break;
+ case UI_BTYPE_ICON_TOGGLE_N:
+ case UI_BTYPE_TOGGLE_N:
+ case UI_BTYPE_CHECKBOX_N:
+ UI_GET_BUT_VALUE_INIT(but, *value);
+ if (*value == 0.0) {
+ is_push = true;
+ }
+ break;
+ case UI_BTYPE_ROW:
+ case UI_BTYPE_LISTROW:
+ case UI_BTYPE_TAB:
+ if ((but->type == UI_BTYPE_TAB) && but->rnaprop && but->custom_data) {
+ /* uiBut.custom_data points to data this tab represents (e.g. workspace).
+ * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
+ if (RNA_property_type(but->rnaprop) == PROP_POINTER) {
+ PointerRNA active_ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
+ if (active_ptr.data == but->custom_data) {
+ is_push = true;
+ }
+ }
+ break;
+ }
+ else if (but->optype) {
+ break;
+ }
+
+ UI_GET_BUT_VALUE_INIT(but, *value);
+ /* support for rna enum buts */
+ if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
+ if ((int)*value & (int)but->hardmax) {
+ is_push = true;
+ }
+ }
+ else {
+ if (*value == (double)but->hardmax) {
+ is_push = true;
+ }
+ }
+ break;
+ default:
+ is_push = -1;
+ break;
+ }
+ }
+
+ return is_push;
}
int ui_but_is_pushed(uiBut *but)
{
- double value = UI_BUT_VALUE_UNSET;
- return ui_but_is_pushed_ex(but, &value);
+ double value = UI_BUT_VALUE_UNSET;
+ return ui_but_is_pushed_ex(but, &value);
}
static void ui_but_update_select_flag(uiBut *but, double *value)
{
- switch (ui_but_is_pushed_ex(but, value)) {
- case true:
- but->flag |= UI_SELECT;
- break;
- case false:
- but->flag &= ~UI_SELECT;
- break;
- }
+ switch (ui_but_is_pushed_ex(but, value)) {
+ case true:
+ but->flag |= UI_SELECT;
+ break;
+ case false:
+ but->flag &= ~UI_SELECT;
+ break;
+ }
}
/* ************************************************ */
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
{
- if (val) {
- block->lock = val;
- block->lockstr = lockstr;
- }
+ if (val) {
+ block->lock = val;
+ block->lockstr = lockstr;
+ }
}
void UI_block_lock_clear(uiBlock *block)
{
- block->lock = false;
- block->lockstr = NULL;
+ block->lock = false;
+ block->lockstr = NULL;
}
/* *********************** data get/set ***********************
@@ -1822,154 +1858,159 @@ void UI_block_lock_clear(uiBlock *block)
/* for buttons pointing to color for example */
void ui_but_v3_get(uiBut *but, float vec[3])
{
- PropertyRNA *prop;
- int a;
-
- if (but->editvec) {
- copy_v3_v3(vec, but->editvec);
- }
-
- if (but->rnaprop) {
- prop = but->rnaprop;
-
- zero_v3(vec);
-
- if (RNA_property_type(prop) == PROP_FLOAT) {
- int tot = RNA_property_array_length(&but->rnapoin, prop);
- BLI_assert(tot > 0);
- if (tot == 3) {
- RNA_property_float_get_array(&but->rnapoin, prop, vec);
- }
- else {
- tot = min_ii(tot, 3);
- for (a = 0; a < tot; a++) {
- vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
- }
- }
- }
- }
- else if (but->pointype == UI_BUT_POIN_CHAR) {
- const char *cp = (char *)but->poin;
-
- vec[0] = ((float)cp[0]) / 255.0f;
- vec[1] = ((float)cp[1]) / 255.0f;
- vec[2] = ((float)cp[2]) / 255.0f;
- }
- else if (but->pointype == UI_BUT_POIN_FLOAT) {
- const float *fp = (float *)but->poin;
- copy_v3_v3(vec, fp);
- }
- else {
- if (but->editvec == NULL) {
- fprintf(stderr, "%s: can't get color, should never happen\n", __func__);
- zero_v3(vec);
- }
- }
-
- if (but->type == UI_BTYPE_UNITVEC) {
- normalize_v3(vec);
- }
+ PropertyRNA *prop;
+ int a;
+
+ if (but->editvec) {
+ copy_v3_v3(vec, but->editvec);
+ }
+
+ if (but->rnaprop) {
+ prop = but->rnaprop;
+
+ zero_v3(vec);
+
+ if (RNA_property_type(prop) == PROP_FLOAT) {
+ int tot = RNA_property_array_length(&but->rnapoin, prop);
+ BLI_assert(tot > 0);
+ if (tot == 3) {
+ RNA_property_float_get_array(&but->rnapoin, prop, vec);
+ }
+ else {
+ tot = min_ii(tot, 3);
+ for (a = 0; a < tot; a++) {
+ vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
+ }
+ }
+ }
+ }
+ else if (but->pointype == UI_BUT_POIN_CHAR) {
+ const char *cp = (char *)but->poin;
+
+ vec[0] = ((float)cp[0]) / 255.0f;
+ vec[1] = ((float)cp[1]) / 255.0f;
+ vec[2] = ((float)cp[2]) / 255.0f;
+ }
+ else if (but->pointype == UI_BUT_POIN_FLOAT) {
+ const float *fp = (float *)but->poin;
+ copy_v3_v3(vec, fp);
+ }
+ else {
+ if (but->editvec == NULL) {
+ fprintf(stderr, "%s: can't get color, should never happen\n", __func__);
+ zero_v3(vec);
+ }
+ }
+
+ if (but->type == UI_BTYPE_UNITVEC) {
+ normalize_v3(vec);
+ }
}
/* for buttons pointing to color for example */
void ui_but_v3_set(uiBut *but, const float vec[3])
{
- PropertyRNA *prop;
-
- if (but->editvec) {
- copy_v3_v3(but->editvec, vec);
- }
-
- if (but->rnaprop) {
- prop = but->rnaprop;
-
- if (RNA_property_type(prop) == PROP_FLOAT) {
- int tot;
- int a;
-
- tot = RNA_property_array_length(&but->rnapoin, prop);
- BLI_assert(tot > 0);
- if (tot == 3) {
- RNA_property_float_set_array(&but->rnapoin, prop, vec);
- }
- else {
- tot = min_ii(tot, 3);
- for (a = 0; a < tot; a++) {
- RNA_property_float_set_index(&but->rnapoin, prop, a, vec[a]);
- }
- }
- }
- }
- else if (but->pointype == UI_BUT_POIN_CHAR) {
- char *cp = (char *)but->poin;
- cp[0] = (char)(0.5f + vec[0] * 255.0f);
- cp[1] = (char)(0.5f + vec[1] * 255.0f);
- cp[2] = (char)(0.5f + vec[2] * 255.0f);
- }
- else if (but->pointype == UI_BUT_POIN_FLOAT) {
- float *fp = (float *)but->poin;
- copy_v3_v3(fp, vec);
- }
+ PropertyRNA *prop;
+
+ if (but->editvec) {
+ copy_v3_v3(but->editvec, vec);
+ }
+
+ if (but->rnaprop) {
+ prop = but->rnaprop;
+
+ if (RNA_property_type(prop) == PROP_FLOAT) {
+ int tot;
+ int a;
+
+ tot = RNA_property_array_length(&but->rnapoin, prop);
+ BLI_assert(tot > 0);
+ if (tot == 3) {
+ RNA_property_float_set_array(&but->rnapoin, prop, vec);
+ }
+ else {
+ tot = min_ii(tot, 3);
+ for (a = 0; a < tot; a++) {
+ RNA_property_float_set_index(&but->rnapoin, prop, a, vec[a]);
+ }
+ }
+ }
+ }
+ else if (but->pointype == UI_BUT_POIN_CHAR) {
+ char *cp = (char *)but->poin;
+ cp[0] = (char)(0.5f + vec[0] * 255.0f);
+ cp[1] = (char)(0.5f + vec[1] * 255.0f);
+ cp[2] = (char)(0.5f + vec[2] * 255.0f);
+ }
+ else if (but->pointype == UI_BUT_POIN_FLOAT) {
+ float *fp = (float *)but->poin;
+ copy_v3_v3(fp, vec);
+ }
}
bool ui_but_is_float(const uiBut *but)
{
- if (but->pointype == UI_BUT_POIN_FLOAT && but->poin) {
- return true;
- }
+ if (but->pointype == UI_BUT_POIN_FLOAT && but->poin) {
+ return true;
+ }
- if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_FLOAT) {
- return true;
- }
+ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_FLOAT) {
+ return true;
+ }
- return false;
+ return false;
}
bool ui_but_is_bool(const uiBut *but)
{
- if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_TAB)) {
- return true;
- }
+ if (ELEM(but->type,
+ UI_BTYPE_TOGGLE,
+ UI_BTYPE_TOGGLE_N,
+ UI_BTYPE_ICON_TOGGLE,
+ UI_BTYPE_ICON_TOGGLE_N,
+ UI_BTYPE_TAB)) {
+ return true;
+ }
- if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN) {
- return true;
- }
+ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN) {
+ return true;
+ }
- if ((but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) && (but->type == UI_BTYPE_ROW)) {
- return true;
- }
+ if ((but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) &&
+ (but->type == UI_BTYPE_ROW)) {
+ return true;
+ }
- return false;
+ return false;
}
-
bool ui_but_is_unit(const uiBut *but)
{
- UnitSettings *unit = but->block->unit;
- const int unit_type = UI_but_unit_type_get(but);
+ UnitSettings *unit = but->block->unit;
+ const int unit_type = UI_but_unit_type_get(but);
- if (unit_type == PROP_UNIT_NONE) {
- return false;
- }
+ if (unit_type == PROP_UNIT_NONE) {
+ return false;
+ }
#if 1 /* removed so angle buttons get correct snapping */
- if (ui_but_is_unit_radians_ex(unit, unit_type)) {
- return false;
- }
+ if (ui_but_is_unit_radians_ex(unit, unit_type)) {
+ return false;
+ }
#endif
- /* for now disable time unit conversion */
- if (unit_type == PROP_UNIT_TIME) {
- return false;
- }
+ /* for now disable time unit conversion */
+ if (unit_type == PROP_UNIT_TIME) {
+ return false;
+ }
- if (unit->system == USER_UNIT_NONE) {
- if (unit_type != PROP_UNIT_ROTATION) {
- return false;
- }
- }
+ if (unit->system == USER_UNIT_NONE) {
+ if (unit_type != PROP_UNIT_ROTATION) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
/**
@@ -1977,39 +2018,39 @@ bool ui_but_is_unit(const uiBut *but)
*/
bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b)
{
- if (but_a->type != but_b->type) {
- return false;
- }
- if (but_a->pointype != but_b->pointype) {
- return false;
- }
-
- if (but_a->rnaprop) {
- /* skip 'rnapoin.data', 'rnapoin.id.data'
- * allow different data to have the same props edited at once */
- if (but_a->rnapoin.type != but_b->rnapoin.type) {
- return false;
- }
- if (RNA_property_type(but_a->rnaprop) != RNA_property_type(but_b->rnaprop)) {
- return false;
- }
- if (RNA_property_subtype(but_a->rnaprop) != RNA_property_subtype(but_b->rnaprop)) {
- return false;
- }
- }
-
- return true;
+ if (but_a->type != but_b->type) {
+ return false;
+ }
+ if (but_a->pointype != but_b->pointype) {
+ return false;
+ }
+
+ if (but_a->rnaprop) {
+ /* skip 'rnapoin.data', 'rnapoin.id.data'
+ * allow different data to have the same props edited at once */
+ if (but_a->rnapoin.type != but_b->rnapoin.type) {
+ return false;
+ }
+ if (RNA_property_type(but_a->rnaprop) != RNA_property_type(but_b->rnaprop)) {
+ return false;
+ }
+ if (RNA_property_subtype(but_a->rnaprop) != RNA_property_subtype(but_b->rnaprop)) {
+ return false;
+ }
+ }
+
+ return true;
}
bool ui_but_is_rna_valid(uiBut *but)
{
- if (but->rnaprop == NULL || RNA_struct_contains_property(&but->rnapoin, but->rnaprop)) {
- return true;
- }
- else {
- printf("property removed %s: %p\n", but->drawstr, but->rnaprop);
- return false;
- }
+ if (but->rnaprop == NULL || RNA_struct_contains_property(&but->rnapoin, but->rnaprop)) {
+ return true;
+ }
+ else {
+ printf("property removed %s: %p\n", but->drawstr, but->rnaprop);
+ return false;
+ }
}
/**
@@ -2017,199 +2058,198 @@ bool ui_but_is_rna_valid(uiBut *but)
*/
bool ui_but_supports_cycling(const uiBut *but)
{
- return ((ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX)) ||
- (but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) ||
- (but->type == UI_BTYPE_COLOR && but->a1 != -1) ||
- (but->menu_step_func != NULL));
+ return ((ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX)) ||
+ (but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) ||
+ (but->type == UI_BTYPE_COLOR && but->a1 != -1) || (but->menu_step_func != NULL));
}
double ui_but_value_get(uiBut *but)
{
- PropertyRNA *prop;
- double value = 0.0;
-
- if (but->editval) {
- return *(but->editval);
- }
- if (but->poin == NULL && but->rnapoin.data == NULL) {
- return 0.0;
- }
-
- if (but->rnaprop) {
- prop = but->rnaprop;
-
- BLI_assert(but->rnaindex != -1);
-
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- if (RNA_property_array_check(prop)) {
- value = RNA_property_boolean_get_index(&but->rnapoin, prop, but->rnaindex);
- }
- else {
- value = RNA_property_boolean_get(&but->rnapoin, prop);
- }
- break;
- case PROP_INT:
- if (RNA_property_array_check(prop)) {
- value = RNA_property_int_get_index(&but->rnapoin, prop, but->rnaindex);
- }
- else {
- value = RNA_property_int_get(&but->rnapoin, prop);
- }
- break;
- case PROP_FLOAT:
- if (RNA_property_array_check(prop)) {
- value = RNA_property_float_get_index(&but->rnapoin, prop, but->rnaindex);
- }
- else {
- value = RNA_property_float_get(&but->rnapoin, prop);
- }
- break;
- case PROP_ENUM:
- value = RNA_property_enum_get(&but->rnapoin, prop);
- break;
- default:
- value = 0.0;
- break;
- }
- }
- else if (but->pointype == UI_BUT_POIN_CHAR) {
- value = *(char *)but->poin;
- }
- else if (but->pointype == UI_BUT_POIN_SHORT) {
- value = *(short *)but->poin;
- }
- else if (but->pointype == UI_BUT_POIN_INT) {
- value = *(int *)but->poin;
- }
- else if (but->pointype == UI_BUT_POIN_FLOAT) {
- value = *(float *)but->poin;
- }
-
- return value;
+ PropertyRNA *prop;
+ double value = 0.0;
+
+ if (but->editval) {
+ return *(but->editval);
+ }
+ if (but->poin == NULL && but->rnapoin.data == NULL) {
+ return 0.0;
+ }
+
+ if (but->rnaprop) {
+ prop = but->rnaprop;
+
+ BLI_assert(but->rnaindex != -1);
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ if (RNA_property_array_check(prop)) {
+ value = RNA_property_boolean_get_index(&but->rnapoin, prop, but->rnaindex);
+ }
+ else {
+ value = RNA_property_boolean_get(&but->rnapoin, prop);
+ }
+ break;
+ case PROP_INT:
+ if (RNA_property_array_check(prop)) {
+ value = RNA_property_int_get_index(&but->rnapoin, prop, but->rnaindex);
+ }
+ else {
+ value = RNA_property_int_get(&but->rnapoin, prop);
+ }
+ break;
+ case PROP_FLOAT:
+ if (RNA_property_array_check(prop)) {
+ value = RNA_property_float_get_index(&but->rnapoin, prop, but->rnaindex);
+ }
+ else {
+ value = RNA_property_float_get(&but->rnapoin, prop);
+ }
+ break;
+ case PROP_ENUM:
+ value = RNA_property_enum_get(&but->rnapoin, prop);
+ break;
+ default:
+ value = 0.0;
+ break;
+ }
+ }
+ else if (but->pointype == UI_BUT_POIN_CHAR) {
+ value = *(char *)but->poin;
+ }
+ else if (but->pointype == UI_BUT_POIN_SHORT) {
+ value = *(short *)but->poin;
+ }
+ else if (but->pointype == UI_BUT_POIN_INT) {
+ value = *(int *)but->poin;
+ }
+ else if (but->pointype == UI_BUT_POIN_FLOAT) {
+ value = *(float *)but->poin;
+ }
+
+ return value;
}
void ui_but_value_set(uiBut *but, double value)
{
- PropertyRNA *prop;
-
- /* value is a hsv value: convert to rgb */
- if (but->rnaprop) {
- prop = but->rnaprop;
-
- if (RNA_property_editable(&but->rnapoin, prop)) {
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- if (RNA_property_array_check(prop)) {
- RNA_property_boolean_set_index(&but->rnapoin, prop, but->rnaindex, value);
- }
- else {
- RNA_property_boolean_set(&but->rnapoin, prop, value);
- }
- break;
- case PROP_INT:
- if (RNA_property_array_check(prop)) {
- RNA_property_int_set_index(&but->rnapoin, prop, but->rnaindex, (int)value);
- }
- else {
- RNA_property_int_set(&but->rnapoin, prop, (int)value);
- }
- break;
- case PROP_FLOAT:
- if (RNA_property_array_check(prop)) {
- RNA_property_float_set_index(&but->rnapoin, prop, but->rnaindex, value);
- }
- else {
- RNA_property_float_set(&but->rnapoin, prop, value);
- }
- break;
- case PROP_ENUM:
- if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
- int ivalue = (int)value;
- /* toggle for enum/flag buttons */
- ivalue ^= RNA_property_enum_get(&but->rnapoin, prop);
- RNA_property_enum_set(&but->rnapoin, prop, ivalue);
- }
- else {
- RNA_property_enum_set(&but->rnapoin, prop, value);
- }
- break;
- default:
- break;
- }
- }
-
- /* we can't be sure what RNA set functions actually do,
- * so leave this unset */
- value = UI_BUT_VALUE_UNSET;
- }
- else if (but->pointype == 0) {
- /* pass */
- }
- else {
- /* first do rounding */
- if (but->pointype == UI_BUT_POIN_CHAR) {
- value = round_db_to_uchar_clamp(value);
- }
- else if (but->pointype == UI_BUT_POIN_SHORT) {
- value = round_db_to_short_clamp(value);
- }
- else if (but->pointype == UI_BUT_POIN_INT) {
- value = round_db_to_int_clamp(value);
- }
- else if (but->pointype == UI_BUT_POIN_FLOAT) {
- float fval = (float)value;
- if (fval >= -0.00001f && fval <= 0.00001f) {
- /* prevent negative zero */
- fval = 0.0f;
- }
- value = fval;
- }
-
- /* then set value with possible edit override */
- if (but->editval) {
- value = *but->editval = value;
- }
- else if (but->pointype == UI_BUT_POIN_CHAR) {
- value = *((char *)but->poin) = (char)value;
- }
- else if (but->pointype == UI_BUT_POIN_SHORT) {
- value = *((short *)but->poin) = (short)value;
- }
- else if (but->pointype == UI_BUT_POIN_INT) {
- value = *((int *)but->poin) = (int)value;
- }
- else if (but->pointype == UI_BUT_POIN_FLOAT) {
- value = *((float *)but->poin) = (float)value;
- }
- }
-
- ui_but_update_select_flag(but, &value);
+ PropertyRNA *prop;
+
+ /* value is a hsv value: convert to rgb */
+ if (but->rnaprop) {
+ prop = but->rnaprop;
+
+ if (RNA_property_editable(&but->rnapoin, prop)) {
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ if (RNA_property_array_check(prop)) {
+ RNA_property_boolean_set_index(&but->rnapoin, prop, but->rnaindex, value);
+ }
+ else {
+ RNA_property_boolean_set(&but->rnapoin, prop, value);
+ }
+ break;
+ case PROP_INT:
+ if (RNA_property_array_check(prop)) {
+ RNA_property_int_set_index(&but->rnapoin, prop, but->rnaindex, (int)value);
+ }
+ else {
+ RNA_property_int_set(&but->rnapoin, prop, (int)value);
+ }
+ break;
+ case PROP_FLOAT:
+ if (RNA_property_array_check(prop)) {
+ RNA_property_float_set_index(&but->rnapoin, prop, but->rnaindex, value);
+ }
+ else {
+ RNA_property_float_set(&but->rnapoin, prop, value);
+ }
+ break;
+ case PROP_ENUM:
+ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
+ int ivalue = (int)value;
+ /* toggle for enum/flag buttons */
+ ivalue ^= RNA_property_enum_get(&but->rnapoin, prop);
+ RNA_property_enum_set(&but->rnapoin, prop, ivalue);
+ }
+ else {
+ RNA_property_enum_set(&but->rnapoin, prop, value);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* we can't be sure what RNA set functions actually do,
+ * so leave this unset */
+ value = UI_BUT_VALUE_UNSET;
+ }
+ else if (but->pointype == 0) {
+ /* pass */
+ }
+ else {
+ /* first do rounding */
+ if (but->pointype == UI_BUT_POIN_CHAR) {
+ value = round_db_to_uchar_clamp(value);
+ }
+ else if (but->pointype == UI_BUT_POIN_SHORT) {
+ value = round_db_to_short_clamp(value);
+ }
+ else if (but->pointype == UI_BUT_POIN_INT) {
+ value = round_db_to_int_clamp(value);
+ }
+ else if (but->pointype == UI_BUT_POIN_FLOAT) {
+ float fval = (float)value;
+ if (fval >= -0.00001f && fval <= 0.00001f) {
+ /* prevent negative zero */
+ fval = 0.0f;
+ }
+ value = fval;
+ }
+
+ /* then set value with possible edit override */
+ if (but->editval) {
+ value = *but->editval = value;
+ }
+ else if (but->pointype == UI_BUT_POIN_CHAR) {
+ value = *((char *)but->poin) = (char)value;
+ }
+ else if (but->pointype == UI_BUT_POIN_SHORT) {
+ value = *((short *)but->poin) = (short)value;
+ }
+ else if (but->pointype == UI_BUT_POIN_INT) {
+ value = *((int *)but->poin) = (int)value;
+ }
+ else if (but->pointype == UI_BUT_POIN_FLOAT) {
+ value = *((float *)but->poin) = (float)value;
+ }
+ }
+
+ ui_but_update_select_flag(but, &value);
}
int ui_but_string_get_max_length(uiBut *but)
{
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- return but->hardmax;
- }
- else {
- return UI_MAX_DRAW_STR;
- }
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ return but->hardmax;
+ }
+ else {
+ return UI_MAX_DRAW_STR;
+ }
}
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) {
- if (but_iter->editstr) {
- break;
- }
- }
+ for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) {
+ if (but_iter->editstr) {
+ break;
+ }
+ }
- return but_iter;
+ return but_iter;
}
/** \name Check to show extra icons
@@ -2220,293 +2260,299 @@ uiBut *ui_but_drag_multi_edit_get(uiBut *but)
static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but)
{
- BLI_assert(but->type == UI_BTYPE_TEXT);
- return ((but->flag & UI_BUT_VALUE_CLEAR) && but->drawstr[0]);
+ BLI_assert(but->type == UI_BTYPE_TEXT);
+ return ((but->flag & UI_BUT_VALUE_CLEAR) && but->drawstr[0]);
}
static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but)
{
- BLI_assert(ELEM(but->type, UI_BTYPE_SEARCH_MENU));
- return ((but->editstr == NULL) &&
- (but->drawstr[0] != '\0') &&
- (but->flag & UI_BUT_VALUE_CLEAR));
+ BLI_assert(ELEM(but->type, UI_BTYPE_SEARCH_MENU));
+ return ((but->editstr == NULL) && (but->drawstr[0] != '\0') && (but->flag & UI_BUT_VALUE_CLEAR));
}
static bool ui_but_icon_extra_is_visible_search_eyedropper(uiBut *but)
{
- StructRNA *type;
- short idcode;
+ StructRNA *type;
+ short idcode;
- BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_VALUE_CLEAR));
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_VALUE_CLEAR));
- if (but->rnaprop == NULL) {
- return false;
- }
+ if (but->rnaprop == NULL) {
+ return false;
+ }
- type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
- idcode = RNA_type_to_ID_code(type);
+ type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
+ idcode = RNA_type_to_ID_code(type);
- return ((but->editstr == NULL) &&
- (idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode)));
+ return ((but->editstr == NULL) && (idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode)));
}
uiButExtraIconType ui_but_icon_extra_get(uiBut *but)
{
- switch (but->type) {
- case UI_BTYPE_TEXT:
- if (ui_but_icon_extra_is_visible_text_clear(but)) {
- return UI_BUT_ICONEXTRA_CLEAR;
- }
- break;
- case UI_BTYPE_SEARCH_MENU:
- if ((but->flag & UI_BUT_VALUE_CLEAR) == 0) {
- /* pass */
- }
- else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
- return UI_BUT_ICONEXTRA_CLEAR;
- }
- else if (ui_but_icon_extra_is_visible_search_eyedropper(but)) {
- return UI_BUT_ICONEXTRA_EYEDROPPER;
- }
- break;
- default:
- break;
- }
-
- return UI_BUT_ICONEXTRA_NONE;
+ switch (but->type) {
+ case UI_BTYPE_TEXT:
+ if (ui_but_icon_extra_is_visible_text_clear(but)) {
+ return UI_BUT_ICONEXTRA_CLEAR;
+ }
+ break;
+ case UI_BTYPE_SEARCH_MENU:
+ if ((but->flag & UI_BUT_VALUE_CLEAR) == 0) {
+ /* pass */
+ }
+ else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
+ return UI_BUT_ICONEXTRA_CLEAR;
+ }
+ else if (ui_but_icon_extra_is_visible_search_eyedropper(but)) {
+ return UI_BUT_ICONEXTRA_EYEDROPPER;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return UI_BUT_ICONEXTRA_NONE;
}
/** \} */
-
static double ui_get_but_scale_unit(uiBut *but, double value)
{
- UnitSettings *unit = but->block->unit;
- int unit_type = UI_but_unit_type_get(but);
+ UnitSettings *unit = but->block->unit;
+ int unit_type = UI_but_unit_type_get(but);
- /* 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 :| */
- Scene *scene = CTX_data_scene(but->block->evil_C);
- return FRA2TIME(value);
- }
- else {
- return BKE_scene_unit_scale(unit, RNA_SUBTYPE_UNIT_VALUE(unit_type), value);
- }
+ /* 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 :| */
+ Scene *scene = CTX_data_scene(but->block->evil_C);
+ return FRA2TIME(value);
+ }
+ else {
+ return BKE_scene_unit_scale(unit, RNA_SUBTYPE_UNIT_VALUE(unit_type), value);
+ }
}
/* str will be overwritten */
void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
{
- if (ui_but_is_unit(but)) {
- UnitSettings *unit = but->block->unit;
- int unit_type = UI_but_unit_type_get(but);
- char *orig_str;
+ if (ui_but_is_unit(but)) {
+ UnitSettings *unit = but->block->unit;
+ int unit_type = UI_but_unit_type_get(but);
+ 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.
*/
-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;
- int unit_type = UI_but_unit_type_get(but);
- int precision;
-
- if (unit->scale_length < 0.0001f) {
- unit->scale_length = 1.0f; // XXX do_versions
- }
-
- /* Use precision override? */
- if (float_precision == -1) {
- /* Sanity checks */
- precision = (int)but->a2;
- if (precision > UI_PRECISION_FLOAT_MAX) {
- precision = UI_PRECISION_FLOAT_MAX;
- }
- else if (precision == -1) {
- precision = 2;
- }
- }
- else {
- precision = float_precision;
- }
-
- bUnit_AsString2(
- str, len_max, ui_get_but_scale_unit(but, value), precision,
- RNA_SUBTYPE_UNIT_VALUE(unit_type), unit, pad);
+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;
+ int unit_type = UI_but_unit_type_get(but);
+ int precision;
+
+ if (unit->scale_length < 0.0001f) {
+ unit->scale_length = 1.0f; // XXX do_versions
+ }
+
+ /* Use precision override? */
+ if (float_precision == -1) {
+ /* Sanity checks */
+ precision = (int)but->a2;
+ if (precision > UI_PRECISION_FLOAT_MAX) {
+ precision = UI_PRECISION_FLOAT_MAX;
+ }
+ else if (precision == -1) {
+ precision = 2;
+ }
+ }
+ else {
+ precision = float_precision;
+ }
+
+ bUnit_AsString2(str,
+ len_max,
+ ui_get_but_scale_unit(but, value),
+ precision,
+ RNA_SUBTYPE_UNIT_VALUE(unit_type),
+ unit,
+ pad);
}
static float ui_get_but_step_unit(uiBut *but, float step_default)
{
- int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
- const double step_orig = step_default * UI_PRECISION_FLOAT_SCALE;
- /* Scaling up 'step_origg ' here is a bit arbitrary,
- * its just giving better scales from user POV */
- const double scale_step = ui_get_but_scale_unit(but, step_orig * 10);
- const double step = bUnit_ClosestScalar(scale_step, but->block->unit->system, unit_type);
+ int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
+ const double step_orig = step_default * UI_PRECISION_FLOAT_SCALE;
+ /* Scaling up 'step_origg ' here is a bit arbitrary,
+ * its just giving better scales from user POV */
+ const double scale_step = ui_get_but_scale_unit(but, step_orig * 10);
+ const double step = bUnit_ClosestScalar(scale_step, but->block->unit->system, unit_type);
- /* -1 is an error value */
- if (step != -1.0) {
- const double scale_unit = ui_get_but_scale_unit(but, 1.0);
- const double step_unit = bUnit_ClosestScalar(scale_unit, but->block->unit->system, unit_type);
- double step_final;
+ /* -1 is an error value */
+ if (step != -1.0) {
+ const double scale_unit = ui_get_but_scale_unit(but, 1.0);
+ const double step_unit = bUnit_ClosestScalar(scale_unit, but->block->unit->system, unit_type);
+ double step_final;
- BLI_assert(step > 0.0);
+ BLI_assert(step > 0.0);
- step_final = (step / scale_unit) / (double)UI_PRECISION_FLOAT_SCALE;
+ step_final = (step / scale_unit) / (double)UI_PRECISION_FLOAT_SCALE;
- if (step == step_unit) {
- /* Logic here is to scale by the original 'step_orig'
- * only when the unit step matches the scaled step.
- *
- * This is needed for units that don't have a wide range of scales (degrees for eg.).
- * Without this we can't select between a single degree, or a 10th of a degree.
- */
- step_final *= step_orig;
- }
+ if (step == step_unit) {
+ /* Logic here is to scale by the original 'step_orig'
+ * only when the unit step matches the scaled step.
+ *
+ * This is needed for units that don't have a wide range of scales (degrees for eg.).
+ * Without this we can't select between a single degree, or a 10th of a degree.
+ */
+ step_final *= step_orig;
+ }
- return (float)step_final;
- }
- else {
- return step_default;
- }
+ return (float)step_final;
+ }
+ else {
+ return step_default;
+ }
}
/**
* \param float_precision: For number buttons the precision to use or -1 to fallback to the button default.
* \param use_exp_float: Use exponent representation of floats when out of reasonable range (outside of 1e3/1e-3).
*/
-void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision, const bool use_exp_float, bool *r_use_exp_float)
-{
- if (r_use_exp_float) {
- *r_use_exp_float = false;
- }
-
- if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_TAB)) {
- PropertyType type;
- const char *buf = NULL;
- int buf_len;
-
- type = RNA_property_type(but->rnaprop);
-
- if ((but->type == UI_BTYPE_TAB) && (but->custom_data)) {
- StructRNA *ptr_type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
- PointerRNA ptr;
-
- /* uiBut.custom_data points to data this tab represents (e.g. workspace).
- * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
- RNA_pointer_create(but->rnapoin.id.data, ptr_type, but->custom_data, &ptr);
- buf = RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
- }
- else if (type == PROP_STRING) {
- /* RNA string */
- buf = RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, str, maxlen, &buf_len);
- }
- else if (type == PROP_ENUM) {
- /* RNA enum */
- int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
- if (RNA_property_enum_name(but->block->evil_C, &but->rnapoin, but->rnaprop, value, &buf)) {
- BLI_strncpy(str, buf, maxlen);
- buf = str;
- }
- }
- else if (type == PROP_POINTER) {
- /* RNA pointer */
- PointerRNA ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
- buf = RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
- }
- else {
- BLI_assert(0);
- }
-
- if (!buf) {
- str[0] = '\0';
- }
- else if (buf && buf != str) {
- BLI_assert(maxlen <= buf_len + 1);
- /* string was too long, we have to truncate */
- if (ui_but_is_utf8(but)) {
- BLI_strncpy_utf8(str, buf, maxlen);
- }
- else {
- BLI_strncpy(str, buf, maxlen);
- }
- MEM_freeN((void *)buf);
- }
- }
- else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- /* string */
- BLI_strncpy(str, but->poin, maxlen);
- return;
- }
- else if (ui_but_anim_expression_get(but, str, maxlen)) {
- /* driver expression */
- }
- else {
- /* number editing */
- double value;
-
- value = ui_but_value_get(but);
-
- PropertySubType subtype = PROP_NONE;
- if (but->rnaprop) {
- subtype = RNA_property_subtype(but->rnaprop);
- }
-
- if (ui_but_is_float(but)) {
- int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision;
-
- if (ui_but_is_unit(but)) {
- ui_get_but_string_unit(but, str, maxlen, value, false, prec);
- }
- else if (subtype == PROP_FACTOR) {
- if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
- BLI_snprintf(str, maxlen, "%.*f", prec, value);
- }
- else {
- BLI_snprintf(str, maxlen, "%.*f", MAX2(0, prec - 2), value * 100);
- }
-
- }
- else {
- if (use_exp_float) {
- const int int_digits_num = integer_digits_f(value);
- if (int_digits_num < -6 || int_digits_num > 12) {
- BLI_snprintf(str, maxlen, "%.*g", prec, value);
- if (r_use_exp_float) {
- *r_use_exp_float = true;
- }
- }
- else {
- prec -= int_digits_num;
- CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
- BLI_snprintf(str, maxlen, "%.*f", prec, value);
- }
- }
- else {
-#if 0 /* TODO, but will likely break some stuff, so better after 2.79 release. */
- prec -= int_digits_num;
- CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+void ui_but_string_get_ex(uiBut *but,
+ char *str,
+ const size_t maxlen,
+ const int float_precision,
+ const bool use_exp_float,
+ bool *r_use_exp_float)
+{
+ if (r_use_exp_float) {
+ *r_use_exp_float = false;
+ }
+
+ if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_TAB)) {
+ PropertyType type;
+ const char *buf = NULL;
+ int buf_len;
+
+ type = RNA_property_type(but->rnaprop);
+
+ if ((but->type == UI_BTYPE_TAB) && (but->custom_data)) {
+ StructRNA *ptr_type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
+ PointerRNA ptr;
+
+ /* uiBut.custom_data points to data this tab represents (e.g. workspace).
+ * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
+ RNA_pointer_create(but->rnapoin.id.data, ptr_type, but->custom_data, &ptr);
+ buf = RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
+ }
+ else if (type == PROP_STRING) {
+ /* RNA string */
+ buf = RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, str, maxlen, &buf_len);
+ }
+ else if (type == PROP_ENUM) {
+ /* RNA enum */
+ int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+ if (RNA_property_enum_name(but->block->evil_C, &but->rnapoin, but->rnaprop, value, &buf)) {
+ BLI_strncpy(str, buf, maxlen);
+ buf = str;
+ }
+ }
+ else if (type == PROP_POINTER) {
+ /* RNA pointer */
+ PointerRNA ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
+ buf = RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ if (!buf) {
+ str[0] = '\0';
+ }
+ else if (buf && buf != str) {
+ BLI_assert(maxlen <= buf_len + 1);
+ /* string was too long, we have to truncate */
+ if (ui_but_is_utf8(but)) {
+ BLI_strncpy_utf8(str, buf, maxlen);
+ }
+ else {
+ BLI_strncpy(str, buf, maxlen);
+ }
+ MEM_freeN((void *)buf);
+ }
+ }
+ else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ /* string */
+ BLI_strncpy(str, but->poin, maxlen);
+ return;
+ }
+ else if (ui_but_anim_expression_get(but, str, maxlen)) {
+ /* driver expression */
+ }
+ else {
+ /* number editing */
+ double value;
+
+ value = ui_but_value_get(but);
+
+ PropertySubType subtype = PROP_NONE;
+ if (but->rnaprop) {
+ subtype = RNA_property_subtype(but->rnaprop);
+ }
+
+ if (ui_but_is_float(but)) {
+ int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) :
+ float_precision;
+
+ if (ui_but_is_unit(but)) {
+ ui_get_but_string_unit(but, str, maxlen, value, false, prec);
+ }
+ else if (subtype == PROP_FACTOR) {
+ if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
+ BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ }
+ else {
+ BLI_snprintf(str, maxlen, "%.*f", MAX2(0, prec - 2), value * 100);
+ }
+ }
+ else {
+ if (use_exp_float) {
+ const int int_digits_num = integer_digits_f(value);
+ if (int_digits_num < -6 || int_digits_num > 12) {
+ BLI_snprintf(str, maxlen, "%.*g", prec, value);
+ if (r_use_exp_float) {
+ *r_use_exp_float = true;
+ }
+ }
+ else {
+ prec -= int_digits_num;
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+ BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ }
+ }
+ else {
+#if 0 /* TODO, but will likely break some stuff, so better after 2.79 release. */
+ prec -= int_digits_num;
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
#endif
- BLI_snprintf(str, maxlen, "%.*f", prec, value);
- }
- }
- }
- else {
- BLI_snprintf(str, maxlen, "%d", (int)value);
- }
- }
+ BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ }
+ }
+ }
+ else {
+ BLI_snprintf(str, maxlen, "%d", (int)value);
+ }
+ }
}
void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
{
- ui_but_string_get_ex(but, str, maxlen, -1, false, NULL);
+ ui_but_string_get_ex(but, str, maxlen, -1, false, NULL);
}
/**
@@ -2517,438 +2563,449 @@ void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
*/
char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
{
- char *str = NULL;
- *r_str_size = 1;
-
- if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- PropertyType type;
-
- type = RNA_property_type(but->rnaprop);
-
- if (type == PROP_STRING) {
- /* RNA string */
- str = RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, NULL, 0, r_str_size);
- (*r_str_size) += 1;
- }
- else if (type == PROP_ENUM) {
- /* RNA enum */
- int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
- const char *value_id;
- if (!RNA_property_enum_name(but->block->evil_C, &but->rnapoin, but->rnaprop, value, &value_id)) {
- value_id = "";
- }
-
- *r_str_size = strlen(value_id) + 1;
- str = BLI_strdupn(value_id, *r_str_size);
- }
- else if (type == PROP_POINTER) {
- /* RNA pointer */
- PointerRNA ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
- str = RNA_struct_name_get_alloc(&ptr, NULL, 0, r_str_size);
- (*r_str_size) += 1;
- }
- else {
- BLI_assert(0);
- }
- }
- else {
- BLI_assert(0);
- }
-
- if (UNLIKELY(str == NULL)) {
- /* should never happen, paranoid check */
- *r_str_size = 1;
- str = BLI_strdup("");
- BLI_assert(0);
-
- }
-
- return str;
-}
-
-static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *r_value)
-{
- const UnitSettings *unit = but->block->unit;
- int type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
- return user_string_to_number(C, str, unit, type, r_value);
+ char *str = NULL;
+ *r_str_size = 1;
+
+ if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ PropertyType type;
+
+ type = RNA_property_type(but->rnaprop);
+
+ if (type == PROP_STRING) {
+ /* RNA string */
+ str = RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, NULL, 0, r_str_size);
+ (*r_str_size) += 1;
+ }
+ else if (type == PROP_ENUM) {
+ /* RNA enum */
+ int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+ const char *value_id;
+ if (!RNA_property_enum_name(
+ but->block->evil_C, &but->rnapoin, but->rnaprop, value, &value_id)) {
+ value_id = "";
+ }
+
+ *r_str_size = strlen(value_id) + 1;
+ str = BLI_strdupn(value_id, *r_str_size);
+ }
+ else if (type == PROP_POINTER) {
+ /* RNA pointer */
+ PointerRNA ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
+ str = RNA_struct_name_get_alloc(&ptr, NULL, 0, r_str_size);
+ (*r_str_size) += 1;
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ if (UNLIKELY(str == NULL)) {
+ /* should never happen, paranoid check */
+ *r_str_size = 1;
+ str = BLI_strdup("");
+ BLI_assert(0);
+ }
+
+ return str;
+}
+
+static bool ui_set_but_string_eval_num_unit(bContext *C,
+ uiBut *but,
+ const char *str,
+ double *r_value)
+{
+ const UnitSettings *unit = but->block->unit;
+ int type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
+ return user_string_to_number(C, str, unit, type, r_value);
}
static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
{
#ifdef WITH_PYTHON
- return BPY_execute_string_as_number(C, NULL, str, true, r_value);
+ return BPY_execute_string_as_number(C, NULL, str, true, r_value);
#else
- *r_value = atof(str);
- return true;
+ *r_value = atof(str);
+ return true;
#endif
}
static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value)
{
- int len = strlen(str);
- if (BLI_strn_endswith(str, "%", len)) {
- char *str_new = BLI_strdupn(str, len - 1);
- bool success = ui_number_from_string(C, str_new, r_value);
- MEM_freeN(str_new);
- *r_value /= 100.0;
- return success;
- }
- else {
- if (!ui_number_from_string(C, str, r_value)) {
- return false;
- }
- if (U.factor_display_type == USER_FACTOR_AS_PERCENTAGE) {
- *r_value /= 100.0;
- }
- return true;
- }
+ int len = strlen(str);
+ if (BLI_strn_endswith(str, "%", len)) {
+ char *str_new = BLI_strdupn(str, len - 1);
+ bool success = ui_number_from_string(C, str_new, r_value);
+ MEM_freeN(str_new);
+ *r_value /= 100.0;
+ return success;
+ }
+ else {
+ if (!ui_number_from_string(C, str, r_value)) {
+ return false;
+ }
+ if (U.factor_display_type == USER_FACTOR_AS_PERCENTAGE) {
+ *r_value /= 100.0;
+ }
+ return true;
+ }
}
static bool ui_number_from_string_percentage(bContext *C, const char *str, double *r_value)
{
- int len = strlen(str);
- if (BLI_strn_endswith(str, "%", len)) {
- char *str_new = BLI_strdupn(str, len - 1);
- bool success = ui_number_from_string(C, str_new, r_value);
- MEM_freeN(str_new);
- return success;
- }
- else {
- return ui_number_from_string(C, str, r_value);
- }
+ int len = strlen(str);
+ if (BLI_strn_endswith(str, "%", len)) {
+ char *str_new = BLI_strdupn(str, len - 1);
+ bool success = ui_number_from_string(C, str_new, r_value);
+ MEM_freeN(str_new);
+ return success;
+ }
+ else {
+ return ui_number_from_string(C, str, r_value);
+ }
}
bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value)
{
- if (str[0] == '\0') {
- *r_value = 0.0;
- return true;
- }
-
- PropertySubType subtype = PROP_NONE;
- if (but->rnaprop) {
- subtype = RNA_property_subtype(but->rnaprop);
- }
-
- if (ui_but_is_float(but)) {
- if (ui_but_is_unit(but)) {
- return ui_set_but_string_eval_num_unit(C, but, str, r_value);
- }
- else if (subtype == PROP_FACTOR) {
- return ui_number_from_string_factor(C, str, r_value);
- }
- else if (subtype == PROP_PERCENTAGE) {
- return ui_number_from_string_percentage(C, str, r_value);
- }
- else {
- return ui_number_from_string(C, str, r_value);
- }
- }
- else {
- return ui_number_from_string(C, str, r_value);
- }
+ if (str[0] == '\0') {
+ *r_value = 0.0;
+ return true;
+ }
+
+ PropertySubType subtype = PROP_NONE;
+ if (but->rnaprop) {
+ subtype = RNA_property_subtype(but->rnaprop);
+ }
+
+ if (ui_but_is_float(but)) {
+ if (ui_but_is_unit(but)) {
+ return ui_set_but_string_eval_num_unit(C, but, str, r_value);
+ }
+ else if (subtype == PROP_FACTOR) {
+ return ui_number_from_string_factor(C, str, r_value);
+ }
+ else if (subtype == PROP_PERCENTAGE) {
+ return ui_number_from_string_percentage(C, str, r_value);
+ }
+ else {
+ return ui_number_from_string(C, str, r_value);
+ }
+ }
+ else {
+ return ui_number_from_string(C, str, r_value);
+ }
}
/* just the assignment/free part */
static void ui_but_string_set_internal(uiBut *but, const char *str, size_t str_len)
{
- BLI_assert(str_len == strlen(str));
- BLI_assert(but->str == NULL);
- str_len += 1;
+ BLI_assert(str_len == strlen(str));
+ BLI_assert(but->str == NULL);
+ str_len += 1;
- if (str_len > UI_MAX_NAME_STR) {
- but->str = MEM_mallocN(str_len, "ui_def_but str");
- }
- else {
- but->str = but->strdata;
- }
- memcpy(but->str, str, str_len);
+ if (str_len > UI_MAX_NAME_STR) {
+ but->str = MEM_mallocN(str_len, "ui_def_but str");
+ }
+ else {
+ but->str = but->strdata;
+ }
+ memcpy(but->str, str, str_len);
}
static void ui_but_string_free_internal(uiBut *but)
{
- if (but->str) {
- if (but->str != but->strdata) {
- MEM_freeN(but->str);
- }
- /* must call 'ui_but_string_set_internal' after */
- but->str = NULL;
- }
+ if (but->str) {
+ if (but->str != but->strdata) {
+ MEM_freeN(but->str);
+ }
+ /* must call 'ui_but_string_set_internal' after */
+ but->str = NULL;
+ }
}
bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
{
- if (but->rnaprop && but->rnapoin.data && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
- PropertyType type;
-
- type = RNA_property_type(but->rnaprop);
-
- if (type == PROP_STRING) {
- /* RNA string */
- RNA_property_string_set(&but->rnapoin, but->rnaprop, str);
- return true;
- }
- else if (type == PROP_POINTER) {
- if (str[0] == '\0') {
- RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL);
- return true;
- }
- else {
- /* RNA pointer */
- PointerRNA rptr;
- PointerRNA ptr = but->rnasearchpoin;
- PropertyRNA *prop = but->rnasearchprop;
-
- /* This is kind of hackish, in theory think we could only ever use the second member of
- * this if/else, since ui_searchbox_apply() is supposed to always set that pointer when
- * we are storing pointers... But keeping str search first for now, to try to break as little as
- * possible existing code. All this is band-aids anyway.
- * Fact remains, using editstr as main 'reference' over whole search button thingy is utterly weak
- * and should be redesigned imho, but that's not a simple task. */
- if (prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
- RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
- }
- else if (but->func_arg2 != NULL) {
- RNA_pointer_create(NULL, RNA_property_pointer_type(&but->rnapoin, but->rnaprop), but->func_arg2, &rptr);
- RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
- }
-
- return true;
- }
-
- return false;
- }
- else if (type == PROP_ENUM) {
- int value;
- if (RNA_property_enum_value(but->block->evil_C, &but->rnapoin, but->rnaprop, str, &value)) {
- RNA_property_enum_set(&but->rnapoin, but->rnaprop, value);
- return true;
- }
- return false;
- }
- else {
- BLI_assert(0);
- }
- }
- }
- else if (but->type == UI_BTYPE_TAB) {
- if (but->rnaprop && but->custom_data) {
- StructRNA *ptr_type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
- PointerRNA ptr;
- PropertyRNA *prop;
-
- /* uiBut.custom_data points to data this tab represents (e.g. workspace).
- * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
- RNA_pointer_create(but->rnapoin.id.data, ptr_type, but->custom_data, &ptr);
- prop = RNA_struct_name_property(ptr_type);
- if (RNA_property_editable(&ptr, prop)) {
- RNA_property_string_set(&ptr, prop, str);
- }
- }
- }
- else if (but->type == UI_BTYPE_TEXT) {
- /* string */
- if (!but->poin) {
- str = "";
- }
- else if (ui_but_is_utf8(but)) {
- BLI_strncpy_utf8(but->poin, str, but->hardmax);
- }
- else {
- BLI_strncpy(but->poin, str, but->hardmax);
- }
-
- return true;
- }
- else if (but->type == UI_BTYPE_SEARCH_MENU) {
- /* string */
- BLI_strncpy(but->poin, str, but->hardmax);
- return true;
- }
- else if (ui_but_anim_expression_set(but, str)) {
- /* driver expression */
- return true;
- }
- else if (str[0] == '#') {
- /* shortcut to create new driver expression (versus immediate Py-execution) */
- return ui_but_anim_expression_create(but, str + 1);
- }
- else {
- /* number editing */
- double value;
-
- if (ui_but_string_set_eval_num(C, but, str, &value) == false) {
- WM_report_banner_show();
- return false;
- }
-
- if (!ui_but_is_float(but)) {
- value = floor(value + 0.5);
- }
-
- /* not that we use hard limits here */
- if (value < (double)but->hardmin) { value = but->hardmin; }
- if (value > (double)but->hardmax) { value = but->hardmax; }
-
- ui_but_value_set(but, value);
- return true;
- }
-
- return false;
+ if (but->rnaprop && but->rnapoin.data && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
+ PropertyType type;
+
+ type = RNA_property_type(but->rnaprop);
+
+ if (type == PROP_STRING) {
+ /* RNA string */
+ RNA_property_string_set(&but->rnapoin, but->rnaprop, str);
+ return true;
+ }
+ else if (type == PROP_POINTER) {
+ if (str[0] == '\0') {
+ RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL);
+ return true;
+ }
+ else {
+ /* RNA pointer */
+ PointerRNA rptr;
+ PointerRNA ptr = but->rnasearchpoin;
+ PropertyRNA *prop = but->rnasearchprop;
+
+ /* This is kind of hackish, in theory think we could only ever use the second member of
+ * this if/else, since ui_searchbox_apply() is supposed to always set that pointer when
+ * we are storing pointers... But keeping str search first for now, to try to break as little as
+ * possible existing code. All this is band-aids anyway.
+ * Fact remains, using editstr as main 'reference' over whole search button thingy is utterly weak
+ * and should be redesigned imho, but that's not a simple task. */
+ if (prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
+ RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+ }
+ else if (but->func_arg2 != NULL) {
+ RNA_pointer_create(NULL,
+ RNA_property_pointer_type(&but->rnapoin, but->rnaprop),
+ but->func_arg2,
+ &rptr);
+ RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+ else if (type == PROP_ENUM) {
+ int value;
+ if (RNA_property_enum_value(
+ but->block->evil_C, &but->rnapoin, but->rnaprop, str, &value)) {
+ RNA_property_enum_set(&but->rnapoin, but->rnaprop, value);
+ return true;
+ }
+ return false;
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ }
+ else if (but->type == UI_BTYPE_TAB) {
+ if (but->rnaprop && but->custom_data) {
+ StructRNA *ptr_type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ /* uiBut.custom_data points to data this tab represents (e.g. workspace).
+ * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
+ RNA_pointer_create(but->rnapoin.id.data, ptr_type, but->custom_data, &ptr);
+ prop = RNA_struct_name_property(ptr_type);
+ if (RNA_property_editable(&ptr, prop)) {
+ RNA_property_string_set(&ptr, prop, str);
+ }
+ }
+ }
+ else if (but->type == UI_BTYPE_TEXT) {
+ /* string */
+ if (!but->poin) {
+ str = "";
+ }
+ else if (ui_but_is_utf8(but)) {
+ BLI_strncpy_utf8(but->poin, str, but->hardmax);
+ }
+ else {
+ BLI_strncpy(but->poin, str, but->hardmax);
+ }
+
+ return true;
+ }
+ else if (but->type == UI_BTYPE_SEARCH_MENU) {
+ /* string */
+ BLI_strncpy(but->poin, str, but->hardmax);
+ return true;
+ }
+ else if (ui_but_anim_expression_set(but, str)) {
+ /* driver expression */
+ return true;
+ }
+ else if (str[0] == '#') {
+ /* shortcut to create new driver expression (versus immediate Py-execution) */
+ return ui_but_anim_expression_create(but, str + 1);
+ }
+ else {
+ /* number editing */
+ double value;
+
+ if (ui_but_string_set_eval_num(C, but, str, &value) == false) {
+ WM_report_banner_show();
+ return false;
+ }
+
+ if (!ui_but_is_float(but)) {
+ value = floor(value + 0.5);
+ }
+
+ /* not that we use hard limits here */
+ if (value < (double)but->hardmin) {
+ value = but->hardmin;
+ }
+ if (value > (double)but->hardmax) {
+ value = but->hardmax;
+ }
+
+ ui_but_value_set(but, value);
+ return true;
+ }
+
+ return false;
}
void ui_but_default_set(bContext *C, const bool all, const bool use_afterfunc)
{
- wmOperatorType *ot = WM_operatortype_find("UI_OT_reset_default_button", true);
+ wmOperatorType *ot = WM_operatortype_find("UI_OT_reset_default_button", true);
- if (use_afterfunc) {
- PointerRNA *ptr;
- ptr = ui_handle_afterfunc_add_operator(ot, WM_OP_EXEC_DEFAULT, true);
- RNA_boolean_set(ptr, "all", all);
- }
- else {
- PointerRNA ptr;
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_boolean_set(&ptr, "all", all);
- WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &ptr);
- WM_operator_properties_free(&ptr);
- }
+ if (use_afterfunc) {
+ PointerRNA *ptr;
+ ptr = ui_handle_afterfunc_add_operator(ot, WM_OP_EXEC_DEFAULT, true);
+ RNA_boolean_set(ptr, "all", all);
+ }
+ else {
+ PointerRNA ptr;
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_boolean_set(&ptr, "all", all);
+ WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &ptr);
+ WM_operator_properties_free(&ptr);
+ }
}
static double soft_range_round_up(double value, double max)
{
- /* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, ..
- * checking for 0.0 prevents floating point exceptions */
- double newmax = (value != 0.0) ? pow(10.0, ceil(log(value) / M_LN10)) : 0.0;
+ /* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, ..
+ * checking for 0.0 prevents floating point exceptions */
+ double newmax = (value != 0.0) ? pow(10.0, ceil(log(value) / M_LN10)) : 0.0;
- if (newmax * 0.2 >= max && newmax * 0.2 >= value) {
- return newmax * 0.2;
- }
- else if (newmax * 0.5 >= max && newmax * 0.5 >= value) {
- return newmax * 0.5;
- }
- else {
- return newmax;
- }
+ if (newmax * 0.2 >= max && newmax * 0.2 >= value) {
+ return newmax * 0.2;
+ }
+ else if (newmax * 0.5 >= max && newmax * 0.5 >= value) {
+ return newmax * 0.5;
+ }
+ else {
+ return newmax;
+ }
}
static double soft_range_round_down(double value, double max)
{
- /* round down to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, ..
- * checking for 0.0 prevents floating point exceptions */
- double newmax = (value != 0.0) ? pow(10.0, floor(log(value) / M_LN10)) : 0.0;
+ /* round down to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, ..
+ * checking for 0.0 prevents floating point exceptions */
+ double newmax = (value != 0.0) ? pow(10.0, floor(log(value) / M_LN10)) : 0.0;
- if (newmax * 5.0 <= max && newmax * 5.0 <= value) {
- return newmax * 5.0;
- }
- else if (newmax * 2.0 <= max && newmax * 2.0 <= value) {
- return newmax * 2.0;
- }
- else {
- return newmax;
- }
+ if (newmax * 5.0 <= max && newmax * 5.0 <= value) {
+ return newmax * 5.0;
+ }
+ else if (newmax * 2.0 <= max && newmax * 2.0 <= value) {
+ return newmax * 2.0;
+ }
+ else {
+ return newmax;
+ }
}
/* note: this could be split up into functions which handle arrays and not */
static void ui_set_but_soft_range(uiBut *but)
{
- /* ideally we would not limit this but practically, its more than
- * enough worst case is very long vectors wont use a smart soft-range
- * which isn't so bad. */
-
- if (but->rnaprop) {
- const PropertyType type = RNA_property_type(but->rnaprop);
- double softmin, softmax /*, step, precision*/;
- double value_min;
- double value_max;
-
- /* clamp button range to something reasonable in case
- * we get -inf/inf from RNA properties */
- if (type == PROP_INT) {
- const bool is_array = RNA_property_array_check(but->rnaprop);
- int imin, imax, istep;
-
- RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
- softmin = (imin == INT_MIN) ? -1e4 : imin;
- softmax = (imin == INT_MAX) ? 1e4 : imax;
- /*step = istep;*/ /*UNUSED*/
- /*precision = 1;*/ /*UNUSED*/
-
- if (is_array) {
- int value_range[2];
- RNA_property_int_get_array_range(&but->rnapoin, but->rnaprop, value_range);
- value_min = (double)value_range[0];
- value_max = (double)value_range[1];
- }
- else {
- value_min = value_max = (double)RNA_property_int_get(&but->rnapoin, but->rnaprop);
- }
- }
- else if (type == PROP_FLOAT) {
- const bool is_array = RNA_property_array_check(but->rnaprop);
- float fmin, fmax, fstep, fprecision;
-
- RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
- softmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
- softmax = (fmax == FLT_MAX) ? (float)1e4 : fmax;
- /*step = fstep;*/ /*UNUSED*/
- /*precision = fprecision;*/ /*UNUSED*/
-
- if (is_array) {
- float value_range[2];
- RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
- value_min = (double)value_range[0];
- value_max = (double)value_range[1];
- }
- else {
- value_min = value_max = (double)RNA_property_float_get(&but->rnapoin, but->rnaprop);
- }
- }
- else {
- return;
- }
-
- /* if the value goes out of the soft/max range, adapt the range */
- if (value_min + 1e-10 < softmin) {
- if (value_min < 0.0) {
- softmin = -soft_range_round_up(-value_min, -softmin);
- }
- else {
- softmin = soft_range_round_down(value_min, softmin);
- }
-
- if (softmin < (double)but->hardmin) {
- softmin = (double)but->hardmin;
- }
- }
- if (value_max - 1e-10 > softmax) {
- if (value_max < 0.0) {
- softmax = -soft_range_round_down(-value_max, -softmax);
- }
- else {
- softmax = soft_range_round_up(value_max, softmax);
- }
-
- if (softmax > (double)but->hardmax) {
- softmax = but->hardmax;
- }
- }
-
- but->softmin = softmin;
- but->softmax = softmax;
- }
- else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) {
- float value = ui_but_value_get(but);
- if (isfinite(value)) {
- CLAMP(value, but->hardmin, but->hardmax);
- but->softmin = min_ff(but->softmin, value);
- but->softmax = max_ff(but->softmax, value);
- }
- }
- else {
- BLI_assert(0);
- }
+ /* ideally we would not limit this but practically, its more than
+ * enough worst case is very long vectors wont use a smart soft-range
+ * which isn't so bad. */
+
+ if (but->rnaprop) {
+ const PropertyType type = RNA_property_type(but->rnaprop);
+ double softmin, softmax /*, step, precision*/;
+ double value_min;
+ double value_max;
+
+ /* clamp button range to something reasonable in case
+ * we get -inf/inf from RNA properties */
+ if (type == PROP_INT) {
+ const bool is_array = RNA_property_array_check(but->rnaprop);
+ int imin, imax, istep;
+
+ RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
+ softmin = (imin == INT_MIN) ? -1e4 : imin;
+ softmax = (imin == INT_MAX) ? 1e4 : imax;
+ /*step = istep;*/ /*UNUSED*/
+ /*precision = 1;*/ /*UNUSED*/
+
+ if (is_array) {
+ int value_range[2];
+ RNA_property_int_get_array_range(&but->rnapoin, but->rnaprop, value_range);
+ value_min = (double)value_range[0];
+ value_max = (double)value_range[1];
+ }
+ else {
+ value_min = value_max = (double)RNA_property_int_get(&but->rnapoin, but->rnaprop);
+ }
+ }
+ else if (type == PROP_FLOAT) {
+ const bool is_array = RNA_property_array_check(but->rnaprop);
+ float fmin, fmax, fstep, fprecision;
+
+ RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
+ softmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
+ softmax = (fmax == FLT_MAX) ? (float)1e4 : fmax;
+ /*step = fstep;*/ /*UNUSED*/
+ /*precision = fprecision;*/ /*UNUSED*/
+
+ if (is_array) {
+ float value_range[2];
+ RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
+ value_min = (double)value_range[0];
+ value_max = (double)value_range[1];
+ }
+ else {
+ value_min = value_max = (double)RNA_property_float_get(&but->rnapoin, but->rnaprop);
+ }
+ }
+ else {
+ return;
+ }
+
+ /* if the value goes out of the soft/max range, adapt the range */
+ if (value_min + 1e-10 < softmin) {
+ if (value_min < 0.0) {
+ softmin = -soft_range_round_up(-value_min, -softmin);
+ }
+ else {
+ softmin = soft_range_round_down(value_min, softmin);
+ }
+
+ if (softmin < (double)but->hardmin) {
+ softmin = (double)but->hardmin;
+ }
+ }
+ if (value_max - 1e-10 > softmax) {
+ if (value_max < 0.0) {
+ softmax = -soft_range_round_down(-value_max, -softmax);
+ }
+ else {
+ softmax = soft_range_round_up(value_max, softmax);
+ }
+
+ if (softmax > (double)but->hardmax) {
+ softmax = but->hardmax;
+ }
+ }
+
+ but->softmin = softmin;
+ but->softmax = softmax;
+ }
+ else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) {
+ float value = ui_but_value_get(but);
+ if (isfinite(value)) {
+ CLAMP(value, but->hardmin, but->hardmax);
+ but->softmin = min_ff(but->softmin, value);
+ but->softmax = max_ff(but->softmax, value);
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
}
/* ******************* Free ********************/
@@ -2956,278 +3013,278 @@ static void ui_set_but_soft_range(uiBut *but)
/* can be called with C==NULL */
static void ui_but_free(const bContext *C, uiBut *but)
{
- if (but->opptr) {
- WM_operator_properties_free(but->opptr);
- MEM_freeN(but->opptr);
- }
-
- if (but->func_argN) {
- MEM_freeN(but->func_argN);
- }
-
- if (but->tip_argN) {
- MEM_freeN(but->tip_argN);
- }
-
- if (but->hold_argN) {
- MEM_freeN(but->hold_argN);
- }
-
- if (but->free_search_arg) {
- MEM_SAFE_FREE(but->search_arg);
- }
-
- if (but->active) {
- /* XXX solve later, buttons should be free-able without context ideally,
- * however they may have open tooltips or popup windows, which need to
- * be closed using a context pointer */
- if (C) {
- ui_but_active_free(C, but);
- }
- else {
- if (but->active) {
- MEM_freeN(but->active);
- }
- }
- }
- if (but->str && but->str != but->strdata) {
- MEM_freeN(but->str);
- }
-
- if ((but->type == UI_BTYPE_IMAGE) && but->poin) {
- IMB_freeImBuf((struct ImBuf *)but->poin);
- }
-
- if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- MEM_freeN(but->dragpoin);
- }
-
- BLI_assert(UI_butstore_is_registered(but->block, but) == false);
-
- MEM_freeN(but);
+ if (but->opptr) {
+ WM_operator_properties_free(but->opptr);
+ MEM_freeN(but->opptr);
+ }
+
+ if (but->func_argN) {
+ MEM_freeN(but->func_argN);
+ }
+
+ if (but->tip_argN) {
+ MEM_freeN(but->tip_argN);
+ }
+
+ if (but->hold_argN) {
+ MEM_freeN(but->hold_argN);
+ }
+
+ if (but->free_search_arg) {
+ MEM_SAFE_FREE(but->search_arg);
+ }
+
+ if (but->active) {
+ /* XXX solve later, buttons should be free-able without context ideally,
+ * however they may have open tooltips or popup windows, which need to
+ * be closed using a context pointer */
+ if (C) {
+ ui_but_active_free(C, but);
+ }
+ else {
+ if (but->active) {
+ MEM_freeN(but->active);
+ }
+ }
+ }
+ if (but->str && but->str != but->strdata) {
+ MEM_freeN(but->str);
+ }
+
+ if ((but->type == UI_BTYPE_IMAGE) && but->poin) {
+ IMB_freeImBuf((struct ImBuf *)but->poin);
+ }
+
+ if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ MEM_freeN(but->dragpoin);
+ }
+
+ BLI_assert(UI_butstore_is_registered(but->block, but) == false);
+
+ MEM_freeN(but);
}
/* can be called with C==NULL */
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))) {
- ui_but_free(C, but);
- }
+ while ((but = BLI_pophead(&block->buttons))) {
+ ui_but_free(C, but);
+ }
- if (block->unit) {
- MEM_freeN(block->unit);
- }
+ if (block->unit) {
+ MEM_freeN(block->unit);
+ }
- if (block->func_argN) {
- MEM_freeN(block->func_argN);
- }
+ if (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->color_pickers.list);
+ BLI_freelistN(&block->saferct);
+ BLI_freelistN(&block->color_pickers.list);
- MEM_freeN(block);
+ MEM_freeN(block);
}
void UI_blocklist_update_window_matrix(const bContext *C, const ListBase *lb)
{
- ARegion *region = CTX_wm_region(C);
- wmWindow *window = CTX_wm_window(C);
+ ARegion *region = CTX_wm_region(C);
+ wmWindow *window = CTX_wm_window(C);
- for (uiBlock *block = lb->first; block; block = block->next) {
- if (block->active) {
- ui_update_window_matrix(window, region, block);
- }
- }
+ for (uiBlock *block = lb->first; block; block = block->next) {
+ if (block->active) {
+ ui_update_window_matrix(window, region, block);
+ }
+ }
}
void UI_blocklist_draw(const bContext *C, const ListBase *lb)
{
- for (uiBlock *block = lb->first; block; block = block->next) {
- if (block->active) {
- UI_block_draw(C, block);
- }
- }
+ for (uiBlock *block = lb->first; block; block = block->next) {
+ if (block->active) {
+ UI_block_draw(C, block);
+ }
+ }
}
/* can be called with C==NULL */
void UI_blocklist_free(const bContext *C, ListBase *lb)
{
- uiBlock *block;
+ uiBlock *block;
- while ((block = BLI_pophead(lb))) {
- UI_block_free(C, block);
- }
+ while ((block = BLI_pophead(lb))) {
+ UI_block_free(C, block);
+ }
}
void UI_blocklist_free_inactive(const bContext *C, ListBase *lb)
{
- uiBlock *block, *nextblock;
+ uiBlock *block, *nextblock;
- for (block = lb->first; block; block = nextblock) {
- nextblock = block->next;
+ for (block = lb->first; block; block = nextblock) {
+ nextblock = block->next;
- if (!block->handle) {
- if (!block->active) {
- BLI_remlink(lb, block);
- UI_block_free(C, block);
- }
- else {
- block->active = 0;
- }
- }
- }
+ if (!block->handle) {
+ if (!block->active) {
+ BLI_remlink(lb, block);
+ UI_block_free(C, block);
+ }
+ else {
+ block->active = 0;
+ }
+ }
+ }
}
void UI_block_region_set(uiBlock *block, ARegion *region)
{
- ListBase *lb = &region->uiblocks;
- uiBlock *oldblock = NULL;
+ ListBase *lb = &region->uiblocks;
+ uiBlock *oldblock = NULL;
- /* each listbase only has one block with this name, free block
- * if is already there so it can be rebuilt from scratch */
- if (lb) {
- oldblock = BLI_findstring(lb, block->name, offsetof(uiBlock, name));
+ /* each listbase only has one block with this name, free block
+ * if is already there so it can be rebuilt from scratch */
+ if (lb) {
+ oldblock = BLI_findstring(lb, block->name, offsetof(uiBlock, name));
- if (oldblock) {
- oldblock->active = 0;
- oldblock->panel = NULL;
- oldblock->handle = NULL;
- }
+ if (oldblock) {
+ oldblock->active = 0;
+ oldblock->panel = NULL;
+ oldblock->handle = NULL;
+ }
- /* at the beginning of the list! for dynamical menus/blocks */
- BLI_addhead(lb, block);
- }
+ /* at the beginning of the list! for dynamical menus/blocks */
+ BLI_addhead(lb, block);
+ }
- block->oldblock = oldblock;
+ block->oldblock = oldblock;
}
uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, short dt)
{
- uiBlock *block;
- wmWindow *window;
- Scene *scn;
+ uiBlock *block;
+ wmWindow *window;
+ Scene *scn;
- window = CTX_wm_window(C);
- scn = CTX_data_scene(C);
+ window = CTX_wm_window(C);
+ scn = CTX_data_scene(C);
- block = MEM_callocN(sizeof(uiBlock), "uiBlock");
- block->active = 1;
- block->dt = dt;
- block->evil_C = (void *)C; /* XXX */
+ block = MEM_callocN(sizeof(uiBlock), "uiBlock");
+ block->active = 1;
+ block->dt = dt;
+ block->evil_C = (void *)C; /* XXX */
- if (scn) {
- /* store display device name, don't lookup for transformations yet
- * block could be used for non-color displays where looking up for transformation
- * would slow down redraw, so only lookup for actual transform when it's indeed
- * needed
- */
- STRNCPY(block->display_device, scn->display_settings.display_device);
+ if (scn) {
+ /* store display device name, don't lookup for transformations yet
+ * block could be used for non-color displays where looking up for transformation
+ * would slow down redraw, so only lookup for actual transform when it's indeed
+ * needed
+ */
+ STRNCPY(block->display_device, scn->display_settings.display_device);
- /* copy to avoid crash when scene gets deleted with ui still open */
- block->unit = MEM_mallocN(sizeof(scn->unit), "UI UnitSettings");
- memcpy(block->unit, &scn->unit, sizeof(scn->unit));
- }
- else {
- STRNCPY(block->display_device, IMB_colormanagement_display_get_default_name());
- }
+ /* copy to avoid crash when scene gets deleted with ui still open */
+ block->unit = MEM_mallocN(sizeof(scn->unit), "UI UnitSettings");
+ memcpy(block->unit, &scn->unit, sizeof(scn->unit));
+ }
+ else {
+ STRNCPY(block->display_device, IMB_colormanagement_display_get_default_name());
+ }
- BLI_strncpy(block->name, name, sizeof(block->name));
+ BLI_strncpy(block->name, name, sizeof(block->name));
- if (region) {
- UI_block_region_set(block, region);
- }
+ if (region) {
+ UI_block_region_set(block, region);
+ }
- /* Set window matrix and aspect for region and OpenGL state. */
- ui_update_window_matrix(window, region, block);
+ /* Set window matrix and aspect for region and OpenGL state. */
+ ui_update_window_matrix(window, region, block);
- /* Tag as popup menu if not created within a region. */
- if (!(region && region->visible)) {
- block->auto_open = true;
- block->flag |= UI_BLOCK_LOOP;
- }
+ /* Tag as popup menu if not created within a region. */
+ if (!(region && region->visible)) {
+ block->auto_open = true;
+ block->flag |= UI_BLOCK_LOOP;
+ }
- return block;
+ return block;
}
void UI_block_emboss_set(uiBlock *block, char dt)
{
- block->dt = dt;
+ block->dt = dt;
}
void UI_block_theme_style_set(uiBlock *block, char theme_style)
{
- block->theme_style = theme_style;
+ block->theme_style = theme_style;
}
static void ui_but_build_drawstr_float(uiBut *but, double value)
{
- size_t slen = 0;
- STR_CONCAT(but->drawstr, slen, but->str);
-
- PropertySubType subtype = PROP_NONE;
- if (but->rnaprop) {
- subtype = RNA_property_subtype(but->rnaprop);
- }
-
- if (value == (double)FLT_MAX) {
- STR_CONCAT(but->drawstr, slen, "inf");
- }
- else if (value == (double)-FLT_MIN) {
- STR_CONCAT(but->drawstr, slen, "-inf");
- }
- else if (subtype == PROP_PERCENTAGE) {
- int prec = ui_but_calc_float_precision(but, value);
- STR_CONCATF(but->drawstr, slen, "%.*f %%", prec, value);
- }
- else if (subtype == PROP_PIXEL) {
- int prec = ui_but_calc_float_precision(but, value);
- STR_CONCATF(but->drawstr, slen, "%.*f px", prec, value);
- }
- else if (subtype == PROP_FACTOR) {
- int precision = ui_but_calc_float_precision(but, value);
-
- if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
- STR_CONCATF(but->drawstr, slen, "%.*f", precision, value);
- }
- else {
- STR_CONCATF(but->drawstr, slen, "%.*f %%", MAX2(0, precision - 2), value * 100);
- }
- }
- else if (ui_but_is_unit(but)) {
- char new_str[sizeof(but->drawstr)];
- ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1);
- STR_CONCAT(but->drawstr, slen, new_str);
- }
- else {
- int prec = ui_but_calc_float_precision(but, value);
- STR_CONCATF(but->drawstr, slen, "%.*f", prec, value);
- }
+ size_t slen = 0;
+ STR_CONCAT(but->drawstr, slen, but->str);
+
+ PropertySubType subtype = PROP_NONE;
+ if (but->rnaprop) {
+ subtype = RNA_property_subtype(but->rnaprop);
+ }
+
+ if (value == (double)FLT_MAX) {
+ STR_CONCAT(but->drawstr, slen, "inf");
+ }
+ else if (value == (double)-FLT_MIN) {
+ STR_CONCAT(but->drawstr, slen, "-inf");
+ }
+ else if (subtype == PROP_PERCENTAGE) {
+ int prec = ui_but_calc_float_precision(but, value);
+ STR_CONCATF(but->drawstr, slen, "%.*f %%", prec, value);
+ }
+ else if (subtype == PROP_PIXEL) {
+ int prec = ui_but_calc_float_precision(but, value);
+ STR_CONCATF(but->drawstr, slen, "%.*f px", prec, value);
+ }
+ else if (subtype == PROP_FACTOR) {
+ int precision = ui_but_calc_float_precision(but, value);
+
+ if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
+ STR_CONCATF(but->drawstr, slen, "%.*f", precision, value);
+ }
+ else {
+ STR_CONCATF(but->drawstr, slen, "%.*f %%", MAX2(0, precision - 2), value * 100);
+ }
+ }
+ else if (ui_but_is_unit(but)) {
+ char new_str[sizeof(but->drawstr)];
+ ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1);
+ STR_CONCAT(but->drawstr, slen, new_str);
+ }
+ else {
+ int prec = ui_but_calc_float_precision(but, value);
+ STR_CONCATF(but->drawstr, slen, "%.*f", prec, value);
+ }
}
static void ui_but_build_drawstr_int(uiBut *but, int value)
{
- size_t slen = 0;
- STR_CONCAT(but->drawstr, slen, but->str);
+ size_t slen = 0;
+ STR_CONCAT(but->drawstr, slen, but->str);
- PropertySubType subtype = PROP_NONE;
- if (but->rnaprop) {
- subtype = RNA_property_subtype(but->rnaprop);
- }
+ PropertySubType subtype = PROP_NONE;
+ if (but->rnaprop) {
+ subtype = RNA_property_subtype(but->rnaprop);
+ }
- STR_CONCATF(but->drawstr, slen, "%d", value);
+ STR_CONCATF(but->drawstr, slen, "%d", value);
- if (subtype == PROP_PERCENTAGE) {
- STR_CONCAT(but->drawstr, slen, "%");
- }
- else if (subtype == PROP_PIXEL) {
- STR_CONCAT(but->drawstr, slen, " px");
- }
+ if (subtype == PROP_PERCENTAGE) {
+ STR_CONCAT(but->drawstr, slen, "%");
+ }
+ else if (subtype == PROP_PIXEL) {
+ STR_CONCAT(but->drawstr, slen, " px");
+ }
}
/**
@@ -3237,233 +3294,225 @@ static void ui_but_build_drawstr_int(uiBut *but, int value)
*/
static void ui_but_update_ex(uiBut *but, const bool validate)
{
- /* if something changed in the button */
- double value = UI_BUT_VALUE_UNSET;
-
- ui_but_update_select_flag(but, &value);
-
- /* only update soft range while not editing */
- if (!ui_but_is_editing(but)) {
- if ((but->rnaprop != NULL) ||
- (but->poin && (but->pointype & UI_BUT_POIN_TYPES)))
- {
- ui_set_but_soft_range(but);
- }
- }
-
- /* test for min and max, icon sliders, etc */
- switch (but->type) {
- case UI_BTYPE_NUM:
- case UI_BTYPE_SCROLL:
- case UI_BTYPE_NUM_SLIDER:
- if (validate) {
- UI_GET_BUT_VALUE_INIT(but, value);
- if (value < (double)but->hardmin) {
- ui_but_value_set(but, but->hardmin);
- }
- else if (value > (double)but->hardmax) {
- ui_but_value_set(but, but->hardmax);
- }
-
- /* max must never be smaller than min! Both being equal is allowed though */
- BLI_assert(but->softmin <= but->softmax &&
- but->hardmin <= but->hardmax);
- }
- break;
-
- case UI_BTYPE_ICON_TOGGLE:
- case UI_BTYPE_ICON_TOGGLE_N:
- if ((but->rnaprop == NULL) || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) {
- if (but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ICONS_REVERSE) {
- but->drawflag |= UI_BUT_ICON_REVERSE;
- }
-
- but->iconadd = (but->flag & UI_SELECT) ? 1 : 0;
- }
- break;
-
- /* quiet warnings for unhandled types */
- default:
- break;
- }
-
-
- /* safety is 4 to enable small number buttons (like 'users') */
- // okwidth = -4 + (BLI_rcti_size_x(&but->rect)); // UNUSED
-
- /* name: */
- switch (but->type) {
-
- case UI_BTYPE_MENU:
- if (BLI_rctf_size_x(&but->rect) >= (UI_UNIT_X * 2)) {
- /* only needed for menus in popup blocks that don't recreate buttons on redraw */
- if (but->block->flag & UI_BLOCK_LOOP) {
- if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) {
- int value_enum = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
-
- EnumPropertyItem item;
- if (RNA_property_enum_item_from_value_gettexted(
- but->block->evil_C,
- &but->rnapoin, but->rnaprop, value_enum, &item))
- {
- size_t slen = strlen(item.name);
- ui_but_string_free_internal(but);
- ui_but_string_set_internal(but, item.name, slen);
- but->icon = item.icon;
- }
- }
- }
- BLI_strncpy(but->drawstr, but->str, sizeof(but->drawstr));
- }
- break;
-
- case UI_BTYPE_NUM:
- case UI_BTYPE_NUM_SLIDER:
- if (but->editstr) {
- break;
- }
- UI_GET_BUT_VALUE_INIT(but, value);
- if (ui_but_is_float(but)) {
- ui_but_build_drawstr_float(but, value);
- }
- else {
- ui_but_build_drawstr_int(but, (int)value);
- }
- break;
-
- case UI_BTYPE_LABEL:
- if (ui_but_is_float(but)) {
- int prec;
- UI_GET_BUT_VALUE_INIT(but, value);
- prec = ui_but_calc_float_precision(but, value);
- BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
- }
- else {
- BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
- }
-
- break;
-
- case UI_BTYPE_TEXT:
- case UI_BTYPE_SEARCH_MENU:
- if (!but->editstr) {
- char 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);
- }
- break;
-
- case UI_BTYPE_KEY_EVENT:
- {
- const char *str;
- if (but->flag & UI_SELECT) {
- str = "Press a key";
- }
- else {
- UI_GET_BUT_VALUE_INIT(but, value);
- str = WM_key_event_string((short)value, false);
- }
- BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str);
- break;
- }
- case UI_BTYPE_HOTKEY_EVENT:
- if (but->flag & UI_SELECT) {
-
- if (but->modifier_key) {
- char *str = but->drawstr;
- but->drawstr[0] = '\0';
-
- if (but->modifier_key & KM_SHIFT) {
- str += BLI_strcpy_rlen(str, "Shift ");
- }
- if (but->modifier_key & KM_CTRL) {
- str += BLI_strcpy_rlen(str, "Ctrl ");
- }
- if (but->modifier_key & KM_ALT) {
- str += BLI_strcpy_rlen(str, "Alt ");
- }
- if (but->modifier_key & KM_OSKEY) {
- str += BLI_strcpy_rlen(str, "Cmd ");
- }
-
- (void)str; /* UNUSED */
- }
- else {
- BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR);
- }
- }
- else {
- BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
- }
-
- break;
-
- case UI_BTYPE_HSVCUBE:
- case UI_BTYPE_HSVCIRCLE:
- break;
- default:
- BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
- break;
-
- }
-
- /* if we are doing text editing, this will override the drawstr */
- if (but->editstr) {
- but->drawstr[0] = '\0';
- }
-
- /* text clipping moved to widget drawing code itself */
+ /* if something changed in the button */
+ double value = UI_BUT_VALUE_UNSET;
+
+ ui_but_update_select_flag(but, &value);
+
+ /* only update soft range while not editing */
+ if (!ui_but_is_editing(but)) {
+ if ((but->rnaprop != NULL) || (but->poin && (but->pointype & UI_BUT_POIN_TYPES))) {
+ ui_set_but_soft_range(but);
+ }
+ }
+
+ /* test for min and max, icon sliders, etc */
+ switch (but->type) {
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_SCROLL:
+ case UI_BTYPE_NUM_SLIDER:
+ if (validate) {
+ UI_GET_BUT_VALUE_INIT(but, value);
+ if (value < (double)but->hardmin) {
+ ui_but_value_set(but, but->hardmin);
+ }
+ else if (value > (double)but->hardmax) {
+ ui_but_value_set(but, but->hardmax);
+ }
+
+ /* max must never be smaller than min! Both being equal is allowed though */
+ BLI_assert(but->softmin <= but->softmax && but->hardmin <= but->hardmax);
+ }
+ break;
+
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE_N:
+ if ((but->rnaprop == NULL) || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) {
+ if (but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ICONS_REVERSE) {
+ but->drawflag |= UI_BUT_ICON_REVERSE;
+ }
+
+ but->iconadd = (but->flag & UI_SELECT) ? 1 : 0;
+ }
+ break;
+
+ /* quiet warnings for unhandled types */
+ default:
+ break;
+ }
+
+ /* safety is 4 to enable small number buttons (like 'users') */
+ // okwidth = -4 + (BLI_rcti_size_x(&but->rect)); // UNUSED
+
+ /* name: */
+ switch (but->type) {
+
+ case UI_BTYPE_MENU:
+ if (BLI_rctf_size_x(&but->rect) >= (UI_UNIT_X * 2)) {
+ /* only needed for menus in popup blocks that don't recreate buttons on redraw */
+ if (but->block->flag & UI_BLOCK_LOOP) {
+ if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) {
+ int value_enum = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+
+ EnumPropertyItem item;
+ if (RNA_property_enum_item_from_value_gettexted(
+ but->block->evil_C, &but->rnapoin, but->rnaprop, value_enum, &item)) {
+ size_t slen = strlen(item.name);
+ ui_but_string_free_internal(but);
+ ui_but_string_set_internal(but, item.name, slen);
+ but->icon = item.icon;
+ }
+ }
+ }
+ BLI_strncpy(but->drawstr, but->str, sizeof(but->drawstr));
+ }
+ break;
+
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_NUM_SLIDER:
+ if (but->editstr) {
+ break;
+ }
+ UI_GET_BUT_VALUE_INIT(but, value);
+ if (ui_but_is_float(but)) {
+ ui_but_build_drawstr_float(but, value);
+ }
+ else {
+ ui_but_build_drawstr_int(but, (int)value);
+ }
+ break;
+
+ case UI_BTYPE_LABEL:
+ if (ui_but_is_float(but)) {
+ int prec;
+ UI_GET_BUT_VALUE_INIT(but, value);
+ prec = ui_but_calc_float_precision(but, value);
+ BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
+ }
+ else {
+ BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
+ }
+
+ break;
+
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU:
+ if (!but->editstr) {
+ char 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);
+ }
+ break;
+
+ case UI_BTYPE_KEY_EVENT: {
+ const char *str;
+ if (but->flag & UI_SELECT) {
+ str = "Press a key";
+ }
+ else {
+ UI_GET_BUT_VALUE_INIT(but, value);
+ str = WM_key_event_string((short)value, false);
+ }
+ BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str);
+ break;
+ }
+ case UI_BTYPE_HOTKEY_EVENT:
+ if (but->flag & UI_SELECT) {
+
+ if (but->modifier_key) {
+ char *str = but->drawstr;
+ but->drawstr[0] = '\0';
+
+ if (but->modifier_key & KM_SHIFT) {
+ str += BLI_strcpy_rlen(str, "Shift ");
+ }
+ if (but->modifier_key & KM_CTRL) {
+ str += BLI_strcpy_rlen(str, "Ctrl ");
+ }
+ if (but->modifier_key & KM_ALT) {
+ str += BLI_strcpy_rlen(str, "Alt ");
+ }
+ if (but->modifier_key & KM_OSKEY) {
+ str += BLI_strcpy_rlen(str, "Cmd ");
+ }
+
+ (void)str; /* UNUSED */
+ }
+ else {
+ BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR);
+ }
+ }
+ else {
+ BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
+ }
+
+ break;
+
+ case UI_BTYPE_HSVCUBE:
+ case UI_BTYPE_HSVCIRCLE:
+ break;
+ default:
+ BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
+ break;
+ }
+
+ /* if we are doing text editing, this will override the drawstr */
+ if (but->editstr) {
+ but->drawstr[0] = '\0';
+ }
+
+ /* text clipping moved to widget drawing code itself */
}
void ui_but_update(uiBut *but)
{
- ui_but_update_ex(but, false);
+ ui_but_update_ex(but, false);
}
void ui_but_update_edited(uiBut *but)
{
- ui_but_update_ex(but, true);
+ ui_but_update_ex(but, true);
}
void UI_block_align_begin(uiBlock *block)
{
- /* if other align was active, end it */
- if (block->flag & UI_BUT_ALIGN) {
- UI_block_align_end(block);
- }
+ /* if other align was active, end it */
+ if (block->flag & UI_BUT_ALIGN) {
+ UI_block_align_end(block);
+ }
- block->flag |= UI_BUT_ALIGN_DOWN;
- block->alignnr++;
+ block->flag |= UI_BUT_ALIGN_DOWN;
+ 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?
}
void UI_block_align_end(uiBlock *block)
{
- block->flag &= ~UI_BUT_ALIGN; /* all 4 flags */
+ block->flag &= ~UI_BUT_ALIGN; /* all 4 flags */
}
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_cm_to_display_space_v3(uiBlock *block, float pixel[3])
{
- struct ColorManagedDisplay *display = ui_block_cm_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);
}
static uiBut *ui_but_alloc(const eButType type)
{
- switch (type) {
- case UI_BTYPE_TAB:
- return MEM_callocN(sizeof(uiButTab), "uiButTab");
- default:
- return MEM_callocN(sizeof(uiBut), "uiBut");
- }
+ switch (type) {
+ case UI_BTYPE_TAB:
+ return MEM_callocN(sizeof(uiButTab), "uiButTab");
+ default:
+ return MEM_callocN(sizeof(uiBut), "uiBut");
+ }
}
/**
@@ -3477,353 +3526,434 @@ static uiBut *ui_but_alloc(const eButType type)
* \param a2: Number of decimal point values to display. 0 defaults to 3 (0.000)
* 1,2,3, and a maximum of 4, all greater values will be clamped to 4.
*/
-static uiBut *ui_def_but(
- 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;
- int slen;
-
- BLI_assert(width >= 0 && height >= 0);
-
- /* we could do some more error checks here */
- 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);
- }
-
- if (type & UI_BUT_POIN_TYPES) { /* a pointer is required */
- if (poin == NULL) {
- BLI_assert(0);
- return NULL;
- }
- }
-
- but = ui_but_alloc(type & BUTTYPE);
-
- but->type = type & BUTTYPE;
- but->pointype = type & UI_BUT_POIN_TYPES;
- but->bit = type & UI_BUT_POIN_BIT;
- but->bitnr = type & 31;
- but->icon = ICON_NONE;
- but->iconadd = 0;
-
- but->retval = retval;
-
- slen = strlen(str);
- ui_but_string_set_internal(but, str, slen);
-
- but->rect.xmin = x;
- but->rect.ymin = y;
- but->rect.xmax = but->rect.xmin + width;
- but->rect.ymax = but->rect.ymin + height;
-
- but->poin = poin;
- but->hardmin = but->softmin = min;
- but->hardmax = but->softmax = max;
- but->a1 = a1;
- but->a2 = a2;
- but->tip = tip;
-
- but->disabled_info = block->lockstr;
- but->dt = block->dt;
- but->pie_dir = UI_RADIAL_NONE;
-
- but->block = block; /* pointer back, used for frontbuffer status, and picker */
-
- if ((block->flag & UI_BUT_ALIGN) && ui_but_can_align(but)) {
- but->alignnr = block->alignnr;
- }
-
- but->func = block->func;
- but->func_arg1 = block->func_arg1;
- but->func_arg2 = block->func_arg2;
-
- but->funcN = block->funcN;
- if (block->func_argN) {
- but->func_argN = MEM_dupallocN(block->func_argN);
- }
-
- but->pos = -1; /* cursor invisible */
-
- 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 */
- if (slen > 0 && slen < UI_MAX_NAME_STR - 2) {
- if (but->str[slen - 1] != ' ') {
- but->str[slen] = ' ';
- but->str[slen + 1] = 0;
- }
- }
- }
-
- if (block->flag & UI_BLOCK_RADIAL) {
- but->drawflag |= UI_BUT_TEXT_LEFT;
- if (but->str && but->str[0]) {
- but->drawflag |= UI_BUT_ICON_LEFT;
- }
- }
- else if (((block->flag & UI_BLOCK_LOOP) && !ui_block_is_popover(block)) ||
- 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_POPOVER))
- {
- but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
- }
+static uiBut *ui_def_but(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;
+ int slen;
+
+ BLI_assert(width >= 0 && height >= 0);
+
+ /* we could do some more error checks here */
+ 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);
+ }
+
+ if (type & UI_BUT_POIN_TYPES) { /* a pointer is required */
+ if (poin == NULL) {
+ BLI_assert(0);
+ return NULL;
+ }
+ }
+
+ but = ui_but_alloc(type & BUTTYPE);
+
+ but->type = type & BUTTYPE;
+ but->pointype = type & UI_BUT_POIN_TYPES;
+ but->bit = type & UI_BUT_POIN_BIT;
+ but->bitnr = type & 31;
+ but->icon = ICON_NONE;
+ but->iconadd = 0;
+
+ but->retval = retval;
+
+ slen = strlen(str);
+ ui_but_string_set_internal(but, str, slen);
+
+ but->rect.xmin = x;
+ but->rect.ymin = y;
+ but->rect.xmax = but->rect.xmin + width;
+ but->rect.ymax = but->rect.ymin + height;
+
+ but->poin = poin;
+ but->hardmin = but->softmin = min;
+ but->hardmax = but->softmax = max;
+ but->a1 = a1;
+ but->a2 = a2;
+ but->tip = tip;
+
+ but->disabled_info = block->lockstr;
+ but->dt = block->dt;
+ but->pie_dir = UI_RADIAL_NONE;
+
+ but->block = block; /* pointer back, used for frontbuffer status, and picker */
+
+ if ((block->flag & UI_BUT_ALIGN) && ui_but_can_align(but)) {
+ but->alignnr = block->alignnr;
+ }
+
+ but->func = block->func;
+ but->func_arg1 = block->func_arg1;
+ but->func_arg2 = block->func_arg2;
+
+ but->funcN = block->funcN;
+ if (block->func_argN) {
+ but->func_argN = MEM_dupallocN(block->func_argN);
+ }
+
+ but->pos = -1; /* cursor invisible */
+
+ 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 */
+ if (slen > 0 && slen < UI_MAX_NAME_STR - 2) {
+ if (but->str[slen - 1] != ' ') {
+ but->str[slen] = ' ';
+ but->str[slen + 1] = 0;
+ }
+ }
+ }
+
+ if (block->flag & UI_BLOCK_RADIAL) {
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ if (but->str && but->str[0]) {
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
+ }
+ else if (((block->flag & UI_BLOCK_LOOP) && !ui_block_is_popover(block)) ||
+ 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_POPOVER)) {
+ but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
+ }
#ifdef USE_NUMBUTS_LR_ALIGN
- else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
- if (slen != 0) {
- but->drawflag |= UI_BUT_TEXT_LEFT;
- }
- }
+ else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
+ if (slen != 0) {
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ }
+ }
#endif
- but->drawflag |= (block->flag & UI_BUT_ALIGN);
-
- if (block->lock == true) {
- but->flag |= UI_BUT_DISABLED;
- }
-
- /* keep track of UI_interface.h */
- 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_GRIP,
- UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE,
- UI_BTYPE_SEPR_SPACER) ||
- (but->type >= UI_BTYPE_SEARCH_MENU))
- {
- /* pass */
- }
- else {
- but->flag |= UI_BUT_UNDO;
- }
-
- BLI_addtail(&block->buttons, but);
-
- if (block->curlayout) {
- ui_layout_add_but(block->curlayout, but);
- }
+ but->drawflag |= (block->flag & UI_BUT_ALIGN);
+
+ if (block->lock == true) {
+ but->flag |= UI_BUT_DISABLED;
+ }
+
+ /* keep track of UI_interface.h */
+ 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_GRIP,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_SEPR_SPACER) ||
+ (but->type >= UI_BTYPE_SEARCH_MENU)) {
+ /* pass */
+ }
+ else {
+ but->flag |= UI_BUT_UNDO;
+ }
+
+ BLI_addtail(&block->buttons, but);
+
+ if (block->curlayout) {
+ ui_layout_add_but(block->curlayout, but);
+ }
#ifdef WITH_PYTHON
- /* if the 'UI_OT_editsource' is running, extract the source info from the button */
- if (UI_editsource_enable_check()) {
- UI_editsource_active_but_test(but);
- }
+ /* if the 'UI_OT_editsource' is running, extract the source info from the button */
+ if (UI_editsource_enable_check()) {
+ UI_editsource_active_but_test(but);
+ }
#endif
- return but;
+ return but;
}
void ui_def_but_icon(uiBut *but, const int icon, const int flag)
{
- if (icon) {
- ui_icon_ensure_deferred(but->block->evil_C, icon, (flag & UI_BUT_ICON_PREVIEW) != 0);
- }
- but->icon = (BIFIconID)icon;
- but->flag |= flag;
+ if (icon) {
+ ui_icon_ensure_deferred(but->block->evil_C, icon, (flag & UI_BUT_ICON_PREVIEW) != 0);
+ }
+ but->icon = (BIFIconID)icon;
+ but->flag |= flag;
- if (but->str && but->str[0]) {
- but->drawflag |= UI_BUT_ICON_LEFT;
- }
+ if (but->str && but->str[0]) {
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
}
static void ui_def_but_rna__disable(uiBut *but, const char *info)
{
- but->flag |= UI_BUT_DISABLED;
- but->disabled_info = info;
+ but->flag |= UI_BUT_DISABLED;
+ but->disabled_info = info;
}
static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p)
{
- uiBlock *block = uiLayoutGetBlock(layout);
- uiPopupBlockHandle *handle = block->handle;
- uiBut *but = (uiBut *)but_p;
-
- /* see comment in ui_item_enum_expand, re: uiname */
- const EnumPropertyItem *item, *item_array;
- bool free;
-
- uiLayout *split, *column = NULL;
-
- int totitems = 0;
- int columns, rows, a, b;
- int column_end = 0;
- int nbr_entries_nosepr = 0;
-
- 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);
-
-
- /* we dont want nested rows, cols in menus */
- UI_block_layout_set_current(block, layout);
-
- for (item = item_array; item->identifier; item++, totitems++) {
- if (!item->identifier[0]) {
- /* inconsistent, but menus with categories do not look good flipped */
- if (item->name) {
- block->flag |= UI_BLOCK_NO_FLIP;
- nbr_entries_nosepr++;
- }
- /* We do not want simple separators in nbr_entries_nosepr count */
- continue;
- }
- nbr_entries_nosepr++;
- }
-
- /* Columns and row estimation. Ignore simple separators here. */
- columns = (nbr_entries_nosepr + 20) / 20;
- if (columns < 1) {
- columns = 1;
- }
- if (columns > 8) {
- columns = (nbr_entries_nosepr + 25) / 25;
- }
-
- rows = totitems / columns;
- if (rows < 1) {
- rows = 1;
- }
- while (rows * columns < totitems) {
- rows++;
- }
-
- if (block->flag & UI_BLOCK_NO_FLIP) {
- /* Title at the top for menus with categories. */
- 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, "");
- uiItemS(layout);
- }
-
- /* note, item_array[...] is reversed on access */
-
- /* create items */
- split = uiLayoutSplit(layout, 0.0f, false);
-
- for (a = 0; a < totitems; a++) {
- if (a == column_end) {
- /* start new column, and find out where it ends in advance, so we
- * can flip the order of items properly per column */
- column_end = totitems;
-
- for (b = a + 1; b < totitems; b++) {
- item = &item_array[b];
-
- /* new column on N rows or on separation label */
- if (((b - a) % rows == 0) || (!item->identifier[0] && item->name)) {
- column_end = b;
- break;
- }
- }
-
- column = uiLayoutColumn(split, false);
- }
-
- item = &item_array[a];
-
- if (!item->identifier[0]) {
- if (item->name) {
- if (item->icon) {
- uiItemL(column, item->name, item->icon);
- }
- else {
- /* Do not use uiItemL here, as our root layout is a menu one,
- * it will add a fake blank icon! */
- 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 {
- uiItemS(column);
- }
- }
- else {
- if (item->icon) {
- 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);
- }
- else {
- 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);
- }
- }
- }
-
- if (!(block->flag & UI_BLOCK_NO_FLIP)) {
- /* Title at the bottom for menus without categories. */
- uiItemS(layout);
- 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, "");
- }
-
- UI_block_layout_set_current(block, layout);
-
- if (free) {
- MEM_freeN((void *)item_array);
- }
- BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0);
- block->flag |= UI_BLOCK_IS_FLIP;
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiPopupBlockHandle *handle = block->handle;
+ uiBut *but = (uiBut *)but_p;
+
+ /* see comment in ui_item_enum_expand, re: uiname */
+ const EnumPropertyItem *item, *item_array;
+ bool free;
+
+ uiLayout *split, *column = NULL;
+
+ int totitems = 0;
+ int columns, rows, a, b;
+ int column_end = 0;
+ int nbr_entries_nosepr = 0;
+
+ 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);
+
+ /* we dont want nested rows, cols in menus */
+ UI_block_layout_set_current(block, layout);
+
+ for (item = item_array; item->identifier; item++, totitems++) {
+ if (!item->identifier[0]) {
+ /* inconsistent, but menus with categories do not look good flipped */
+ if (item->name) {
+ block->flag |= UI_BLOCK_NO_FLIP;
+ nbr_entries_nosepr++;
+ }
+ /* We do not want simple separators in nbr_entries_nosepr count */
+ continue;
+ }
+ nbr_entries_nosepr++;
+ }
+
+ /* Columns and row estimation. Ignore simple separators here. */
+ columns = (nbr_entries_nosepr + 20) / 20;
+ if (columns < 1) {
+ columns = 1;
+ }
+ if (columns > 8) {
+ columns = (nbr_entries_nosepr + 25) / 25;
+ }
+
+ rows = totitems / columns;
+ if (rows < 1) {
+ rows = 1;
+ }
+ while (rows * columns < totitems) {
+ rows++;
+ }
+
+ if (block->flag & UI_BLOCK_NO_FLIP) {
+ /* Title at the top for menus with categories. */
+ 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,
+ "");
+ uiItemS(layout);
+ }
+
+ /* note, item_array[...] is reversed on access */
+
+ /* create items */
+ split = uiLayoutSplit(layout, 0.0f, false);
+
+ for (a = 0; a < totitems; a++) {
+ if (a == column_end) {
+ /* start new column, and find out where it ends in advance, so we
+ * can flip the order of items properly per column */
+ column_end = totitems;
+
+ for (b = a + 1; b < totitems; b++) {
+ item = &item_array[b];
+
+ /* new column on N rows or on separation label */
+ if (((b - a) % rows == 0) || (!item->identifier[0] && item->name)) {
+ column_end = b;
+ break;
+ }
+ }
+
+ column = uiLayoutColumn(split, false);
+ }
+
+ item = &item_array[a];
+
+ if (!item->identifier[0]) {
+ if (item->name) {
+ if (item->icon) {
+ uiItemL(column, item->name, item->icon);
+ }
+ else {
+ /* Do not use uiItemL here, as our root layout is a menu one,
+ * it will add a fake blank icon! */
+ 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 {
+ uiItemS(column);
+ }
+ }
+ else {
+ if (item->icon) {
+ 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);
+ }
+ else {
+ 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);
+ }
+ }
+ }
+
+ if (!(block->flag & UI_BLOCK_NO_FLIP)) {
+ /* Title at the bottom for menus without categories. */
+ uiItemS(layout);
+ 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,
+ "");
+ }
+
+ UI_block_layout_set_current(block, layout);
+
+ if (free) {
+ MEM_freeN((void *)item_array);
+ }
+ BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0);
+ block->flag |= UI_BLOCK_IS_FLIP;
}
static void ui_def_but_rna__panel_type(bContext *C, uiLayout *layout, void *but_p)
{
- uiBut *but = but_p;
- const char *panel_type = but->func_argN;
- PanelType *pt = WM_paneltype_find(panel_type, true);
- if (pt) {
- ui_item_paneltype_func(C, layout, pt);
- }
- else {
- char msg[256];
- SNPRINTF(msg, "Missing Panel: %s", panel_type);
- uiItemL(layout, msg, ICON_NONE);
- }
+ uiBut *but = but_p;
+ const char *panel_type = but->func_argN;
+ PanelType *pt = WM_paneltype_find(panel_type, true);
+ if (pt) {
+ ui_item_paneltype_func(C, layout, pt);
+ }
+ else {
+ char msg[256];
+ SNPRINTF(msg, "Missing Panel: %s", panel_type);
+ uiItemL(layout, msg, ICON_NONE);
+ }
}
void ui_but_rna_menu_convert_to_panel_type(uiBut *but, const char *panel_type)
{
- BLI_assert(but->type == UI_BTYPE_MENU);
- BLI_assert(but->menu_create_func == ui_def_but_rna__menu);
- BLI_assert((void *)but->poin == but);
- but->menu_create_func = ui_def_but_rna__panel_type;
- but->func_argN = BLI_strdup(panel_type);
+ BLI_assert(but->type == UI_BTYPE_MENU);
+ BLI_assert(but->menu_create_func == ui_def_but_rna__menu);
+ BLI_assert((void *)but->poin == but);
+ but->menu_create_func = ui_def_but_rna__panel_type;
+ but->func_argN = BLI_strdup(panel_type);
}
bool ui_but_menu_draw_as_popover(const uiBut *but)
{
- return (but->menu_create_func == ui_def_but_rna__panel_type);
+ return (but->menu_create_func == ui_def_but_rna__panel_type);
}
static void ui_def_but_rna__menu_type(bContext *C, uiLayout *layout, void *but_p)
{
- uiBut *but = but_p;
- const char *menu_type = but->func_argN;
- MenuType *mt = WM_menutype_find(menu_type, true);
- if (mt) {
- ui_item_menutype_func(C, layout, mt);
- }
- else {
- char msg[256];
- SNPRINTF(msg, "Missing Menu: %s", menu_type);
- uiItemL(layout, msg, ICON_NONE);
- }
+ uiBut *but = but_p;
+ const char *menu_type = but->func_argN;
+ MenuType *mt = WM_menutype_find(menu_type, true);
+ if (mt) {
+ ui_item_menutype_func(C, layout, mt);
+ }
+ else {
+ char msg[256];
+ SNPRINTF(msg, "Missing Menu: %s", menu_type);
+ uiItemL(layout, msg, ICON_NONE);
+ }
}
void ui_but_rna_menu_convert_to_menu_type(uiBut *but, const char *menu_type)
{
- BLI_assert(but->type == UI_BTYPE_MENU);
- BLI_assert(but->menu_create_func == ui_def_but_rna__menu);
- BLI_assert((void *)but->poin == but);
- but->menu_create_func = ui_def_but_rna__menu_type;
- but->func_argN = BLI_strdup(menu_type);
+ BLI_assert(but->type == UI_BTYPE_MENU);
+ BLI_assert(but->menu_create_func == ui_def_but_rna__menu);
+ BLI_assert((void *)but->poin == but);
+ but->menu_create_func = ui_def_but_rna__menu_type;
+ but->func_argN = BLI_strdup(menu_type);
}
static void ui_but_submenu_enable(uiBlock *block, uiBut *but)
{
- but->flag |= UI_BUT_ICON_SUBMENU;
- block->content_hints |= UI_BLOCK_CONTAINS_SUBMENU_BUT;
+ but->flag |= UI_BUT_ICON_SUBMENU;
+ block->content_hints |= UI_BLOCK_CONTAINS_SUBMENU_BUT;
}
/**
@@ -3834,227 +3964,278 @@ static void ui_but_submenu_enable(uiBlock *block, uiBut *but)
* When this kind of change won't disrupt branches, best look into making more
* of our UI functions take prop rather then propname.
*/
-static uiBut *ui_def_but_rna(
- 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)
-{
- const PropertyType proptype = RNA_property_type(prop);
- uiBut *but;
- int icon = 0;
- uiMenuCreateFunc func = NULL;
-
- if (ELEM(type, UI_BTYPE_COLOR, UI_BTYPE_HSVCIRCLE, UI_BTYPE_HSVCUBE)) {
- BLI_assert(index == -1);
- }
-
- /* use rna values if parameters are not specified */
- if ((proptype == PROP_ENUM) && ELEM(type, UI_BTYPE_MENU, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
- /* UI_BTYPE_MENU is handled a little differently here */
- const EnumPropertyItem *item;
- int value;
- bool free;
- int i;
-
- RNA_property_enum_items(block->evil_C, ptr, prop, &item, NULL, &free);
-
- if (type == UI_BTYPE_MENU) {
- value = RNA_property_enum_get(ptr, prop);
- }
- else {
- value = (int)max;
- }
-
- i = RNA_enum_from_value(item, value);
- if (i != -1) {
-
- if (!str) {
- str = item[i].name;
+static uiBut *ui_def_but_rna(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)
+{
+ const PropertyType proptype = RNA_property_type(prop);
+ uiBut *but;
+ int icon = 0;
+ uiMenuCreateFunc func = NULL;
+
+ if (ELEM(type, UI_BTYPE_COLOR, UI_BTYPE_HSVCIRCLE, UI_BTYPE_HSVCUBE)) {
+ BLI_assert(index == -1);
+ }
+
+ /* use rna values if parameters are not specified */
+ if ((proptype == PROP_ENUM) && ELEM(type, UI_BTYPE_MENU, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
+ /* UI_BTYPE_MENU is handled a little differently here */
+ const EnumPropertyItem *item;
+ int value;
+ bool free;
+ int i;
+
+ RNA_property_enum_items(block->evil_C, ptr, prop, &item, NULL, &free);
+
+ if (type == UI_BTYPE_MENU) {
+ value = RNA_property_enum_get(ptr, prop);
+ }
+ else {
+ value = (int)max;
+ }
+
+ i = RNA_enum_from_value(item, value);
+ if (i != -1) {
+
+ if (!str) {
+ str = item[i].name;
#ifdef WITH_INTERNATIONAL
- str = CTX_IFACE_(RNA_property_translation_context(prop), str);
+ str = CTX_IFACE_(RNA_property_translation_context(prop), str);
#endif
- }
-
- icon = item[i].icon;
- }
- else {
- if (!str) {
- if (type == UI_BTYPE_MENU) {
- str = "";
- }
- else {
- str = RNA_property_ui_name(prop);
- }
- }
- }
-
- if (type == UI_BTYPE_MENU) {
- func = ui_def_but_rna__menu;
- }
-
- if (free) {
- MEM_freeN((void *)item);
- }
- }
- else {
- if (!str) {
- str = RNA_property_ui_name(prop);
- }
- icon = RNA_property_ui_icon(prop);
- }
-
- if (!tip && proptype != PROP_ENUM) {
- tip = RNA_property_ui_description(prop);
- }
-
- if (min == max || a1 == -1 || a2 == -1) {
- if (proptype == PROP_INT) {
- int hardmin, hardmax, softmin, softmax, step;
-
- RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
- RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
-
- if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
- min = hardmin;
- max = hardmax;
- }
- if (a1 == -1) {
- a1 = step;
- }
- if (a2 == -1) {
- a2 = 0;
- }
- }
- else if (proptype == PROP_FLOAT) {
- float hardmin, hardmax, softmin, softmax, step, precision;
-
- RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
- RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
-
- if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
- min = hardmin;
- max = hardmax;
- }
- if (a1 == -1) {
- a1 = step;
- }
- if (a2 == -1) {
- a2 = precision;
- }
- }
- else if (proptype == PROP_STRING) {
- min = 0;
- max = RNA_property_string_maxlength(prop);
- /* note, 'max' may be zero (code for dynamically resized array) */
- }
- }
-
- /* now create button */
- but = ui_def_but(block, type, retval, str, x, y, width, height, NULL, min, max, a1, a2, tip);
-
- but->rnapoin = *ptr;
- but->rnaprop = prop;
-
- if (RNA_property_array_check(but->rnaprop)) {
- but->rnaindex = index;
- }
- else {
- but->rnaindex = 0;
- }
-
- if (icon) {
- ui_def_but_icon(but, icon, UI_HAS_ICON);
- }
-
- if (type == UI_BTYPE_MENU) {
- if (but->dt == UI_EMBOSS_PULLDOWN) {
- ui_but_submenu_enable(block, but);
- }
- }
- else if (type == UI_BTYPE_SEARCH_MENU) {
- if (proptype == PROP_POINTER) {
- /* Search buttons normally don't get undo, see: T54580. */
- but->flag |= UI_BUT_UNDO;
- }
- }
-
- const char *info;
- if (but->rnapoin.data && !RNA_property_editable_info(&but->rnapoin, prop, &info)) {
- ui_def_but_rna__disable(but, info);
- }
-
- if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) {
- but->flag &= ~UI_BUT_UNDO;
- }
-
- /* If this button uses units, calculate the step from this */
- if ((proptype == PROP_FLOAT) && ui_but_is_unit(but)) {
- but->a1 = ui_get_but_step_unit(but, but->a1);
- }
-
- if (func) {
- but->menu_create_func = func;
- but->poin = (char *)but;
- }
-
- return but;
-}
-
-static uiBut *ui_def_but_rna_propname(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)
-{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- uiBut *but;
-
- if (prop) {
- but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
- }
- else {
- but = ui_def_but(block, type, retval, propname, x, y, width, height, NULL, min, max, a1, a2, tip);
-
- ui_def_but_rna__disable(but, "Unknown Property.");
- }
-
- return but;
-}
-
-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)
-{
- uiBut *but;
-
- if (!str) {
- if (ot && ot->srna) {
- str = RNA_struct_ui_name(ot->srna);
- }
- else {
- str = "";
- }
- }
-
- if ((!tip || tip[0] == '\0') && ot && 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->optype = ot;
- but->opcontext = opcontext;
- but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_rna_undo(), we never need undo here */
-
- if (!ot) {
- but->flag |= UI_BUT_DISABLED;
- but->disabled_info = "";
- }
-
- 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 *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
-
- ui_but_update(but);
-
- return but;
+ }
+
+ icon = item[i].icon;
+ }
+ else {
+ if (!str) {
+ if (type == UI_BTYPE_MENU) {
+ str = "";
+ }
+ else {
+ str = RNA_property_ui_name(prop);
+ }
+ }
+ }
+
+ if (type == UI_BTYPE_MENU) {
+ func = ui_def_but_rna__menu;
+ }
+
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+ }
+ else {
+ if (!str) {
+ str = RNA_property_ui_name(prop);
+ }
+ icon = RNA_property_ui_icon(prop);
+ }
+
+ if (!tip && proptype != PROP_ENUM) {
+ tip = RNA_property_ui_description(prop);
+ }
+
+ if (min == max || a1 == -1 || a2 == -1) {
+ if (proptype == PROP_INT) {
+ int hardmin, hardmax, softmin, softmax, step;
+
+ RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
+ RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
+
+ if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
+ min = hardmin;
+ max = hardmax;
+ }
+ if (a1 == -1) {
+ a1 = step;
+ }
+ if (a2 == -1) {
+ a2 = 0;
+ }
+ }
+ else if (proptype == PROP_FLOAT) {
+ float hardmin, hardmax, softmin, softmax, step, precision;
+
+ RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
+ RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
+
+ if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
+ min = hardmin;
+ max = hardmax;
+ }
+ if (a1 == -1) {
+ a1 = step;
+ }
+ if (a2 == -1) {
+ a2 = precision;
+ }
+ }
+ else if (proptype == PROP_STRING) {
+ min = 0;
+ max = RNA_property_string_maxlength(prop);
+ /* note, 'max' may be zero (code for dynamically resized array) */
+ }
+ }
+
+ /* now create button */
+ but = ui_def_but(block, type, retval, str, x, y, width, height, NULL, min, max, a1, a2, tip);
+
+ but->rnapoin = *ptr;
+ but->rnaprop = prop;
+
+ if (RNA_property_array_check(but->rnaprop)) {
+ but->rnaindex = index;
+ }
+ else {
+ but->rnaindex = 0;
+ }
+
+ if (icon) {
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+ }
+
+ if (type == UI_BTYPE_MENU) {
+ if (but->dt == UI_EMBOSS_PULLDOWN) {
+ ui_but_submenu_enable(block, but);
+ }
+ }
+ else if (type == UI_BTYPE_SEARCH_MENU) {
+ if (proptype == PROP_POINTER) {
+ /* Search buttons normally don't get undo, see: T54580. */
+ but->flag |= UI_BUT_UNDO;
+ }
+ }
+
+ const char *info;
+ if (but->rnapoin.data && !RNA_property_editable_info(&but->rnapoin, prop, &info)) {
+ ui_def_but_rna__disable(but, info);
+ }
+
+ if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) {
+ but->flag &= ~UI_BUT_UNDO;
+ }
+
+ /* If this button uses units, calculate the step from this */
+ if ((proptype == PROP_FLOAT) && ui_but_is_unit(but)) {
+ but->a1 = ui_get_but_step_unit(but, but->a1);
+ }
+
+ if (func) {
+ but->menu_create_func = func;
+ but->poin = (char *)but;
+ }
+
+ return but;
+}
+
+static uiBut *ui_def_but_rna_propname(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)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ uiBut *but;
+
+ if (prop) {
+ but = ui_def_but_rna(
+ block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
+ }
+ else {
+ but = ui_def_but(
+ block, type, retval, propname, x, y, width, height, NULL, min, max, a1, a2, tip);
+
+ ui_def_but_rna__disable(but, "Unknown Property.");
+ }
+
+ return but;
+}
+
+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)
+{
+ uiBut *but;
+
+ if (!str) {
+ if (ot && ot->srna) {
+ str = RNA_struct_ui_name(ot->srna);
+ }
+ else {
+ str = "";
+ }
+ }
+
+ if ((!tip || tip[0] == '\0') && ot && 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->optype = ot;
+ but->opcontext = opcontext;
+ but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_rna_undo(), we never need undo here */
+
+ if (!ot) {
+ but->flag |= UI_BUT_DISABLED;
+ but->disabled_info = "";
+ }
+
+ 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 *but = ui_def_but(
+ block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
+
+ ui_but_update(but);
+
+ return but;
}
/**
@@ -4068,341 +4249,1285 @@ uiBut *uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, in
*/
static int findBitIndex(uint x)
{
- if (!x || !is_power_of_2_i(x)) { /* is_power_of_2_i(x) strips lowest bit */
- return -1;
- }
- else {
- int idx = 0;
-
- if (x & 0xFFFF0000) { idx += 16; x >>= 16; }
- if (x & 0xFF00) { idx += 8; x >>= 8; }
- if (x & 0xF0) { idx += 4; x >>= 4; }
- if (x & 0xC) { idx += 2; x >>= 2; }
- if (x & 0x2) { idx += 1; }
-
- return idx;
- }
+ if (!x || !is_power_of_2_i(x)) { /* is_power_of_2_i(x) strips lowest bit */
+ return -1;
+ }
+ else {
+ int idx = 0;
+
+ if (x & 0xFFFF0000) {
+ idx += 16;
+ x >>= 16;
+ }
+ if (x & 0xFF00) {
+ idx += 8;
+ x >>= 8;
+ }
+ if (x & 0xF0) {
+ idx += 4;
+ x >>= 4;
+ }
+ if (x & 0xC) {
+ idx += 2;
+ x >>= 2;
+ }
+ if (x & 0x2) {
+ idx += 1;
+ }
+
+ return idx;
+ }
}
/* autocomplete helper functions */
struct AutoComplete {
- size_t maxlen;
- int matches;
- char *truncate;
- const char *startname;
+ size_t maxlen;
+ int matches;
+ char *truncate;
+ const char *startname;
};
AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen)
{
- AutoComplete *autocpl;
+ AutoComplete *autocpl;
- autocpl = MEM_callocN(sizeof(AutoComplete), "AutoComplete");
- autocpl->maxlen = maxlen;
- autocpl->matches = 0;
- autocpl->truncate = MEM_callocN(sizeof(char) * maxlen, "AutoCompleteTruncate");
- autocpl->startname = startname;
+ autocpl = MEM_callocN(sizeof(AutoComplete), "AutoComplete");
+ autocpl->maxlen = maxlen;
+ autocpl->matches = 0;
+ autocpl->truncate = MEM_callocN(sizeof(char) * maxlen, "AutoCompleteTruncate");
+ autocpl->startname = startname;
- return autocpl;
+ return autocpl;
}
void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name)
{
- char *truncate = autocpl->truncate;
- const char *startname = autocpl->startname;
- int a;
-
- for (a = 0; a < autocpl->maxlen - 1; a++) {
- if (startname[a] == 0 || startname[a] != name[a]) {
- break;
- }
- }
- /* found a match */
- if (startname[a] == 0) {
- autocpl->matches++;
- /* first match */
- if (truncate[0] == 0) {
- BLI_strncpy(truncate, name, autocpl->maxlen);
- }
- else {
- /* remove from truncate what is not in bone->name */
- for (a = 0; a < autocpl->maxlen - 1; a++) {
- if (name[a] == 0) {
- truncate[a] = 0;
- break;
- }
- else if (truncate[a] != name[a]) {
- truncate[a] = 0;
- }
- }
- }
- }
+ char *truncate = autocpl->truncate;
+ const char *startname = autocpl->startname;
+ int a;
+
+ for (a = 0; a < autocpl->maxlen - 1; a++) {
+ if (startname[a] == 0 || startname[a] != name[a]) {
+ break;
+ }
+ }
+ /* found a match */
+ if (startname[a] == 0) {
+ autocpl->matches++;
+ /* first match */
+ if (truncate[0] == 0) {
+ BLI_strncpy(truncate, name, autocpl->maxlen);
+ }
+ else {
+ /* remove from truncate what is not in bone->name */
+ for (a = 0; a < autocpl->maxlen - 1; a++) {
+ if (name[a] == 0) {
+ truncate[a] = 0;
+ break;
+ }
+ else if (truncate[a] != name[a]) {
+ truncate[a] = 0;
+ }
+ }
+ }
+ }
}
int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
{
- int match = AUTOCOMPLETE_NO_MATCH;
- if (autocpl->truncate[0]) {
- if (autocpl->matches == 1) {
- match = AUTOCOMPLETE_FULL_MATCH;
- }
- else {
- match = AUTOCOMPLETE_PARTIAL_MATCH;
- }
- BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen);
- }
- else {
- if (autoname != autocpl->startname) { /* don't copy a string over its self */
- BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen);
- }
- }
-
- MEM_freeN(autocpl->truncate);
- MEM_freeN(autocpl);
- return match;
+ int match = AUTOCOMPLETE_NO_MATCH;
+ if (autocpl->truncate[0]) {
+ if (autocpl->matches == 1) {
+ match = AUTOCOMPLETE_FULL_MATCH;
+ }
+ else {
+ match = AUTOCOMPLETE_PARTIAL_MATCH;
+ }
+ BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen);
+ }
+ else {
+ if (autoname != autocpl->startname) { /* don't copy a string over its self */
+ BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen);
+ }
+ }
+
+ MEM_freeN(autocpl->truncate);
+ MEM_freeN(autocpl);
+ return match;
}
static void ui_but_update_and_icon_set(uiBut *but, int icon)
{
- if (icon) {
- ui_def_but_icon(but, icon, UI_HAS_ICON);
- }
-
- 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)
-{
- int bitIdx = findBitIndex(bit);
- if (bitIdx == -1) {
- return NULL;
- }
- else {
- return uiDefBut(block, type | UI_BUT_POIN_BIT | bitIdx, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
- }
-}
-uiBut *uiDefButF(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefBut(block, type | UI_BUT_POIN_FLOAT, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefButBitF(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefButBit(block, type | UI_BUT_POIN_FLOAT, bit, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefButI(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefBut(block, type | UI_BUT_POIN_INT, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefButBitI(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefButBit(block, type | UI_BUT_POIN_INT, bit, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefButS(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefBut(block, type | UI_BUT_POIN_SHORT, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefButBitS(uiBlock *block, int type, int bit, int retval, const char *str, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefButBit(block, type | UI_BUT_POIN_SHORT, bit, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefButC(uiBlock *block, int type, 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 uiDefBut(block, type | UI_BUT_POIN_CHAR, retval, str, x, y, width, height, (void *) poin, min, max, a1, a2, 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);
-}
-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;
- but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
- ui_but_update(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 *but;
- but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
- ui_but_update(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 *but;
- but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
- ui_but_update(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)
-{
- wmOperatorType *ot = WM_operatortype_find(opname, 0);
- if (str == NULL && ot == NULL) {
- str = opname;
- }
- return uiDefButO_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
+ if (icon) {
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+ }
+
+ 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)
+{
+ int bitIdx = findBitIndex(bit);
+ if (bitIdx == -1) {
+ return NULL;
+ }
+ else {
+ return uiDefBut(block,
+ type | UI_BUT_POIN_BIT | bitIdx,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+ }
+}
+uiBut *uiDefButF(uiBlock *block,
+ int type,
+ int retval,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ float *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefBut(block,
+ type | UI_BUT_POIN_FLOAT,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefButBitF(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ float *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefButBit(block,
+ type | UI_BUT_POIN_FLOAT,
+ bit,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefButI(uiBlock *block,
+ int type,
+ int retval,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ int *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefBut(block,
+ type | UI_BUT_POIN_INT,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefButBitI(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ int *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefButBit(block,
+ type | UI_BUT_POIN_INT,
+ bit,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefButS(uiBlock *block,
+ int type,
+ int retval,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ short *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefBut(block,
+ type | UI_BUT_POIN_SHORT,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefButBitS(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ short *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefButBit(block,
+ type | UI_BUT_POIN_SHORT,
+ bit,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefButC(uiBlock *block,
+ int type,
+ 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 uiDefBut(block,
+ type | UI_BUT_POIN_CHAR,
+ retval,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ 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);
+}
+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;
+ but = ui_def_but_rna_propname(
+ block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
+ ui_but_update(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 *but;
+ but = ui_def_but_rna(
+ block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
+ ui_but_update(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 *but;
+ but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
+ ui_but_update(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)
+{
+ wmOperatorType *ot = WM_operatortype_find(opname, 0);
+ if (str == NULL && ot == NULL) {
+ str = opname;
+ }
+ 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) */
-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);
- ui_but_update_and_icon_set(but, icon);
- 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)
-{
- int bitIdx = findBitIndex(bit);
- if (bitIdx == -1) {
- return NULL;
- }
- else {
- return uiDefIconBut(block, type | UI_BUT_POIN_BIT | bitIdx, retval, icon, x, y, width, height, poin, min, max, a1, a2, tip);
- }
-}
-
-uiBut *uiDefIconButF(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconBut(block, type | UI_BUT_POIN_FLOAT, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconButBitF(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconButBit(block, type | UI_BUT_POIN_FLOAT, bit, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconButI(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconBut(block, type | UI_BUT_POIN_INT, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconButBitI(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconButBit(block, type | UI_BUT_POIN_INT, bit, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconButS(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconBut(block, type | UI_BUT_POIN_SHORT, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconButBitS(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconButBit(block, type | UI_BUT_POIN_SHORT, bit, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconButC(uiBlock *block, int type, 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 uiDefIconBut(block, type | UI_BUT_POIN_CHAR, retval, icon, x, y, width, height, (void *) poin, min, max, a1, a2, 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);
-}
-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;
- but = ui_def_but_rna_propname(block, type, retval, "", x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
- ui_but_update_and_icon_set(but, icon);
- 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 *but;
- but = ui_def_but_rna(block, type, retval, "", x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
- ui_but_update_and_icon_set(but, icon);
- 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 *but;
- but = ui_def_but_operator_ptr(block, type, ot, opcontext, "", x, y, width, height, tip);
- ui_but_update_and_icon_set(but, icon);
- 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)
-{
- wmOperatorType *ot = WM_operatortype_find(opname, 0);
- return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, 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);
+ ui_but_update_and_icon_set(but, icon);
+ 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)
+{
+ int bitIdx = findBitIndex(bit);
+ if (bitIdx == -1) {
+ return NULL;
+ }
+ else {
+ return uiDefIconBut(block,
+ type | UI_BUT_POIN_BIT | bitIdx,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+ }
+}
+
+uiBut *uiDefIconButF(uiBlock *block,
+ int type,
+ int retval,
+ int icon,
+ int x,
+ int y,
+ short width,
+ short height,
+ float *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconBut(block,
+ type | UI_BUT_POIN_FLOAT,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconButBitF(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ int icon,
+ int x,
+ int y,
+ short width,
+ short height,
+ float *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconButBit(block,
+ type | UI_BUT_POIN_FLOAT,
+ bit,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconButI(uiBlock *block,
+ int type,
+ int retval,
+ int icon,
+ int x,
+ int y,
+ short width,
+ short height,
+ int *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconBut(block,
+ type | UI_BUT_POIN_INT,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconButBitI(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ int icon,
+ int x,
+ int y,
+ short width,
+ short height,
+ int *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconButBit(block,
+ type | UI_BUT_POIN_INT,
+ bit,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconButS(uiBlock *block,
+ int type,
+ int retval,
+ int icon,
+ int x,
+ int y,
+ short width,
+ short height,
+ short *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconBut(block,
+ type | UI_BUT_POIN_SHORT,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconButBitS(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ int icon,
+ int x,
+ int y,
+ short width,
+ short height,
+ short *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconButBit(block,
+ type | UI_BUT_POIN_SHORT,
+ bit,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconButC(uiBlock *block,
+ int type,
+ 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 uiDefIconBut(block,
+ type | UI_BUT_POIN_CHAR,
+ retval,
+ icon,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ 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);
+}
+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;
+ but = ui_def_but_rna_propname(
+ block, type, retval, "", x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
+ ui_but_update_and_icon_set(but, icon);
+ 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 *but;
+ but = ui_def_but_rna(
+ block, type, retval, "", x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
+ ui_but_update_and_icon_set(but, icon);
+ 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 *but;
+ but = ui_def_but_operator_ptr(block, type, ot, opcontext, "", x, y, width, height, tip);
+ ui_but_update_and_icon_set(but, icon);
+ 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)
+{
+ wmOperatorType *ot = WM_operatortype_find(opname, 0);
+ return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, tip);
}
/* 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 *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
- ui_but_update_and_icon_set(but, icon);
- but->drawflag |= UI_BUT_ICON_LEFT;
- 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)
-{
- int bitIdx = findBitIndex(bit);
- if (bitIdx == -1) {
- return NULL;
- }
- else {
- return uiDefIconTextBut(block, type | UI_BUT_POIN_BIT | bitIdx, retval, icon, str, x, y, width, height, poin, min, max, a1, a2, tip);
- }
-}
-
-uiBut *uiDefIconTextButF(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconTextBut(block, type | UI_BUT_POIN_FLOAT, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconTextButBitF(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, float *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconTextButBit(block, type | UI_BUT_POIN_FLOAT, bit, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconTextButI(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconTextBut(block, type | UI_BUT_POIN_INT, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconTextButBitI(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconTextButBit(block, type | UI_BUT_POIN_INT, bit, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconTextButS(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconTextBut(block, type | UI_BUT_POIN_SHORT, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconTextButBitS(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
-{
- return uiDefIconTextButBit(block, type | UI_BUT_POIN_SHORT, bit, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, tip);
-}
-uiBut *uiDefIconTextButC(uiBlock *block, int type, 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 uiDefIconTextBut(block, type | UI_BUT_POIN_CHAR, retval, icon, str, x, y, width, height, (void *) poin, min, max, a1, a2, 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);
-}
-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;
- but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
- ui_but_update_and_icon_set(but, icon);
- but->drawflag |= UI_BUT_ICON_LEFT;
- 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 *but;
- but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
- ui_but_update_and_icon_set(but, icon);
- but->drawflag |= UI_BUT_ICON_LEFT;
- 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 *but;
- but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
- ui_but_update_and_icon_set(but, icon);
- but->drawflag |= UI_BUT_ICON_LEFT;
- 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)
-{
- wmOperatorType *ot = WM_operatortype_find(opname, 0);
- if (str && str[0] == '\0') {
- return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, tip);
- }
- return uiDefIconTextButO_ptr(block, type, ot, opcontext, icon, str, x, y, width, height, 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);
+ ui_but_update_and_icon_set(but, icon);
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ 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)
+{
+ int bitIdx = findBitIndex(bit);
+ if (bitIdx == -1) {
+ return NULL;
+ }
+ else {
+ return uiDefIconTextBut(block,
+ type | UI_BUT_POIN_BIT | bitIdx,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+ }
+}
+
+uiBut *uiDefIconTextButF(uiBlock *block,
+ int type,
+ int retval,
+ int icon,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ float *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconTextBut(block,
+ type | UI_BUT_POIN_FLOAT,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconTextButBitF(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ int icon,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ float *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconTextButBit(block,
+ type | UI_BUT_POIN_FLOAT,
+ bit,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconTextButI(uiBlock *block,
+ int type,
+ int retval,
+ int icon,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ int *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconTextBut(block,
+ type | UI_BUT_POIN_INT,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconTextButBitI(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ int icon,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ int *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconTextButBit(block,
+ type | UI_BUT_POIN_INT,
+ bit,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconTextButS(uiBlock *block,
+ int type,
+ int retval,
+ int icon,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ short *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconTextBut(block,
+ type | UI_BUT_POIN_SHORT,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconTextButBitS(uiBlock *block,
+ int type,
+ int bit,
+ int retval,
+ int icon,
+ const char *str,
+ int x,
+ int y,
+ short width,
+ short height,
+ short *poin,
+ float min,
+ float max,
+ float a1,
+ float a2,
+ const char *tip)
+{
+ return uiDefIconTextButBit(block,
+ type | UI_BUT_POIN_SHORT,
+ bit,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ tip);
+}
+uiBut *uiDefIconTextButC(uiBlock *block,
+ int type,
+ 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 uiDefIconTextBut(block,
+ type | UI_BUT_POIN_CHAR,
+ retval,
+ icon,
+ str,
+ x,
+ y,
+ width,
+ height,
+ (void *)poin,
+ min,
+ max,
+ a1,
+ a2,
+ 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);
+}
+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;
+ but = ui_def_but_rna_propname(
+ block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
+ ui_but_update_and_icon_set(but, icon);
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ 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 *but;
+ but = ui_def_but_rna(
+ block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
+ ui_but_update_and_icon_set(but, icon);
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ 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 *but;
+ but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
+ ui_but_update_and_icon_set(but, icon);
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ 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)
+{
+ wmOperatorType *ot = WM_operatortype_find(opname, 0);
+ if (str && str[0] == '\0') {
+ return uiDefIconButO_ptr(block, type, ot, opcontext, icon, 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 */
@@ -4411,550 +5536,703 @@ uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcon
int UI_blocklist_min_y_get(ListBase *lb)
{
- uiBlock *block;
- int min = 0;
+ uiBlock *block;
+ int min = 0;
- for (block = lb->first; block; block = block->next) {
- if (block == lb->first || block->rect.ymin < min) {
- min = block->rect.ymin;
- }
- }
+ for (block = lb->first; block; block = block->next) {
+ if (block == lb->first || block->rect.ymin < min) {
+ min = block->rect.ymin;
+ }
+ }
- return min;
+ return min;
}
void UI_block_direction_set(uiBlock *block, char direction)
{
- block->direction = direction;
+ block->direction = direction;
}
/* this call escapes if there's alignment flags */
void UI_block_order_flip(uiBlock *block)
{
- uiBut *but;
- float centy, miny = 10000, maxy = -10000;
-
- if (U.uiflag & USER_MENUFIXEDORDER) {
- return;
- }
- else if (block->flag & UI_BLOCK_NO_FLIP) {
- return;
- }
-
- for (but = block->buttons.first; but; but = but->next) {
- if (but->drawflag & UI_BUT_ALIGN) {
- return;
- }
- if (but->rect.ymin < miny) {
- miny = but->rect.ymin;
- }
- if (but->rect.ymax > maxy) {
- maxy = but->rect.ymax;
- }
- }
- /* mirror trick */
- centy = (miny + maxy) / 2.0f;
- for (but = block->buttons.first; but; but = but->next) {
- but->rect.ymin = centy - (but->rect.ymin - centy);
- but->rect.ymax = centy - (but->rect.ymax - centy);
- SWAP(float, but->rect.ymin, but->rect.ymax);
- }
-
- block->flag ^= UI_BLOCK_IS_FLIP;
+ uiBut *but;
+ float centy, miny = 10000, maxy = -10000;
+
+ if (U.uiflag & USER_MENUFIXEDORDER) {
+ return;
+ }
+ else if (block->flag & UI_BLOCK_NO_FLIP) {
+ return;
+ }
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->drawflag & UI_BUT_ALIGN) {
+ return;
+ }
+ if (but->rect.ymin < miny) {
+ miny = but->rect.ymin;
+ }
+ if (but->rect.ymax > maxy) {
+ maxy = but->rect.ymax;
+ }
+ }
+ /* mirror trick */
+ centy = (miny + maxy) / 2.0f;
+ for (but = block->buttons.first; but; but = but->next) {
+ but->rect.ymin = centy - (but->rect.ymin - centy);
+ but->rect.ymax = centy - (but->rect.ymax - centy);
+ SWAP(float, but->rect.ymin, but->rect.ymax);
+ }
+
+ block->flag ^= UI_BLOCK_IS_FLIP;
}
-
void UI_block_flag_enable(uiBlock *block, int flag)
{
- block->flag |= flag;
+ block->flag |= flag;
}
void UI_block_flag_disable(uiBlock *block, int flag)
{
- block->flag &= ~flag;
+ block->flag &= ~flag;
}
void UI_but_flag_enable(uiBut *but, int flag)
{
- but->flag |= flag;
+ but->flag |= flag;
}
void UI_but_flag_disable(uiBut *but, int flag)
{
- but->flag &= ~flag;
+ but->flag &= ~flag;
}
bool UI_but_flag_is_set(uiBut *but, int flag)
{
- return (but->flag & flag) != 0;
+ return (but->flag & flag) != 0;
}
void UI_but_drawflag_enable(uiBut *but, int flag)
{
- but->drawflag |= flag;
+ but->drawflag |= flag;
}
void UI_but_drawflag_disable(uiBut *but, int flag)
{
- but->drawflag &= ~flag;
+ but->drawflag &= ~flag;
}
void UI_but_type_set_menu_from_pulldown(uiBut *but)
{
- BLI_assert(but->type == UI_BTYPE_PULLDOWN);
- but->type = UI_BTYPE_MENU;
- UI_but_drawflag_disable(but, UI_BUT_TEXT_RIGHT);
- UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT);
+ BLI_assert(but->type == UI_BTYPE_PULLDOWN);
+ but->type = UI_BTYPE_MENU;
+ UI_but_drawflag_disable(but, UI_BUT_TEXT_RIGHT);
+ UI_but_drawflag_enable(but, UI_BUT_TEXT_LEFT);
}
int UI_but_return_value_get(uiBut *but)
{
- return but->retval;
+ return but->retval;
}
void UI_but_drag_set_id(uiBut *but, ID *id)
{
- but->dragtype = WM_DRAG_ID;
- if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- MEM_SAFE_FREE(but->dragpoin);
- but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
- }
- but->dragpoin = (void *)id;
+ but->dragtype = WM_DRAG_ID;
+ if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ MEM_SAFE_FREE(but->dragpoin);
+ but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
+ }
+ but->dragpoin = (void *)id;
}
void UI_but_drag_set_rna(uiBut *but, PointerRNA *ptr)
{
- but->dragtype = WM_DRAG_RNA;
- if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- MEM_SAFE_FREE(but->dragpoin);
- but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
- }
- but->dragpoin = (void *)ptr;
+ but->dragtype = WM_DRAG_RNA;
+ if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ MEM_SAFE_FREE(but->dragpoin);
+ but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
+ }
+ but->dragpoin = (void *)ptr;
}
void UI_but_drag_set_path(uiBut *but, const char *path, const bool use_free)
{
- but->dragtype = WM_DRAG_PATH;
- if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- MEM_SAFE_FREE(but->dragpoin);
- but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
- }
- but->dragpoin = (void *)path;
- if (use_free) {
- but->dragflag |= UI_BUT_DRAGPOIN_FREE;
- }
+ but->dragtype = WM_DRAG_PATH;
+ if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ MEM_SAFE_FREE(but->dragpoin);
+ but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
+ }
+ but->dragpoin = (void *)path;
+ if (use_free) {
+ but->dragflag |= UI_BUT_DRAGPOIN_FREE;
+ }
}
void UI_but_drag_set_name(uiBut *but, const char *name)
{
- but->dragtype = WM_DRAG_NAME;
- if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- MEM_SAFE_FREE(but->dragpoin);
- but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
- }
- but->dragpoin = (void *)name;
+ but->dragtype = WM_DRAG_NAME;
+ if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ MEM_SAFE_FREE(but->dragpoin);
+ but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
+ }
+ but->dragpoin = (void *)name;
}
/* value from button itself */
void UI_but_drag_set_value(uiBut *but)
{
- but->dragtype = WM_DRAG_VALUE;
+ but->dragtype = WM_DRAG_VALUE;
}
-void UI_but_drag_set_image(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, const bool use_free)
+void UI_but_drag_set_image(
+ uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, const bool use_free)
{
- but->dragtype = WM_DRAG_PATH;
- ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */
- if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
- MEM_SAFE_FREE(but->dragpoin);
- but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
- }
- but->dragpoin = (void *)path;
- if (use_free) {
- but->dragflag |= UI_BUT_DRAGPOIN_FREE;
- }
- but->imb = imb;
- but->imb_scale = scale;
+ but->dragtype = WM_DRAG_PATH;
+ ui_def_but_icon(but, icon, 0); /* no flag UI_HAS_ICON, so icon doesn't draw in button */
+ if ((but->dragflag & UI_BUT_DRAGPOIN_FREE)) {
+ MEM_SAFE_FREE(but->dragpoin);
+ but->dragflag &= ~UI_BUT_DRAGPOIN_FREE;
+ }
+ but->dragpoin = (void *)path;
+ if (use_free) {
+ but->dragflag |= UI_BUT_DRAGPOIN_FREE;
+ }
+ but->imb = imb;
+ but->imb_scale = scale;
}
PointerRNA *UI_but_operator_ptr_get(uiBut *but)
{
- if (but->optype && !but->opptr) {
- but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr");
- WM_operator_properties_create_ptr(but->opptr, but->optype);
- }
+ if (but->optype && !but->opptr) {
+ but->opptr = MEM_callocN(sizeof(PointerRNA), "uiButOpPtr");
+ WM_operator_properties_create_ptr(but->opptr, but->optype);
+ }
- return but->opptr;
+ return but->opptr;
}
void UI_but_unit_type_set(uiBut *but, const int unit_type)
{
- but->unit_type = (uchar)(RNA_SUBTYPE_UNIT_VALUE(unit_type));
+ but->unit_type = (uchar)(RNA_SUBTYPE_UNIT_VALUE(unit_type));
}
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
- * 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 */
- if ((ownUnit != 0) || (but->rnaprop == NULL)) {
- return ownUnit << 16;
- }
- else {
- return RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop));
- }
+ /* 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)
+ */
+ /* XXX: this doesn't allow clearing unit completely, though the same could be said for icons */
+ if ((ownUnit != 0) || (but->rnaprop == NULL)) {
+ return ownUnit << 16;
+ }
+ else {
+ return RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop));
+ }
}
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
{
- block->handle_func = func;
- block->handle_func_arg = arg;
+ block->handle_func = func;
+ block->handle_func_arg = arg;
}
void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg)
{
- block->butm_func = func;
- block->butm_func_arg = arg;
+ block->butm_func = func;
+ block->butm_func_arg = arg;
}
void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
{
- block->func = func;
- block->func_arg1 = arg1;
- block->func_arg2 = arg2;
+ block->func = func;
+ block->func_arg1 = arg1;
+ block->func_arg2 = arg2;
}
void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2)
{
- if (block->func_argN) {
- MEM_freeN(block->func_argN);
- }
+ if (block->func_argN) {
+ MEM_freeN(block->func_argN);
+ }
- block->funcN = funcN;
- block->func_argN = argN;
- block->func_arg2 = arg2;
+ block->funcN = funcN;
+ block->func_argN = argN;
+ block->func_arg2 = arg2;
}
void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1)
{
- but->rename_func = func;
- but->rename_arg1 = arg1;
+ but->rename_func = func;
+ but->rename_arg1 = arg1;
}
-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)
+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_arg1 = arg1;
- block->drawextra_arg2 = arg2;
+ block->drawextra = func;
+ block->drawextra_arg1 = arg1;
+ block->drawextra_arg2 = arg2;
}
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
{
- but->func = func;
- but->func_arg1 = arg1;
- but->func_arg2 = arg2;
+ but->func = func;
+ but->func_arg1 = arg1;
+ but->func_arg2 = arg2;
}
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
{
- if (but->func_argN) {
- MEM_freeN(but->func_argN);
- }
+ if (but->func_argN) {
+ MEM_freeN(but->func_argN);
+ }
- but->funcN = funcN;
- but->func_argN = argN;
- but->func_arg2 = arg2;
+ but->funcN = funcN;
+ but->func_argN = argN;
+ but->func_arg2 = arg2;
}
void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg)
{
- but->autocomplete_func = func;
- but->autofunc_arg = arg;
+ but->autocomplete_func = func;
+ but->autofunc_arg = arg;
}
void UI_but_func_menu_step_set(uiBut *but, uiMenuStepFunc func)
{
- but->menu_step_func = func;
+ but->menu_step_func = func;
}
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN)
{
- but->tip_func = func;
- if (but->tip_argN) {
- MEM_freeN(but->tip_argN);
- }
- but->tip_argN = argN;
+ but->tip_func = func;
+ if (but->tip_argN) {
+ MEM_freeN(but->tip_argN);
+ }
+ but->tip_argN = argN;
}
void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, void *arg)
{
- but->pushed_state_func = func;
- but->pushed_state_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 *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;
- ui_but_update(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 *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;
- if (but->func_argN) {
- MEM_freeN(but->func_argN);
- }
- but->func_argN = argN;
- ui_but_update(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 *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;
- ui_but_update(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 *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;
- ui_but_update(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 *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
-
- ui_def_but_icon(but, icon, UI_HAS_ICON);
-
- but->drawflag |= UI_BUT_ICON_LEFT;
- ui_but_submenu_enable(block, but);
-
- but->menu_create_func = func;
- ui_but_update(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 *but = ui_def_but(block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
-
- ui_def_but_icon(but, icon, UI_HAS_ICON);
- but->drawflag &= ~UI_BUT_ICON_LEFT;
-
- but->menu_create_func = func;
- ui_but_update(but);
-
- return but;
+ but->pushed_state_func = func;
+ but->pushed_state_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 *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;
+ ui_but_update(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 *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;
+ if (but->func_argN) {
+ MEM_freeN(but->func_argN);
+ }
+ but->func_argN = argN;
+ ui_but_update(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 *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;
+ ui_but_update(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 *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;
+ ui_but_update(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 *but = ui_def_but(
+ block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ ui_but_submenu_enable(block, but);
+
+ but->menu_create_func = func;
+ ui_but_update(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 *but = ui_def_but(
+ block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+ but->drawflag &= ~UI_BUT_ICON_LEFT;
+
+ but->menu_create_func = func;
+ ui_but_update(but);
+
+ return but;
}
/* 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 *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_BUT_ICON_SUBMENU flag */
- if (icon != ICON_RIGHTARROW_THIN) {
- ui_def_but_icon(but, icon, 0);
- but->drawflag |= UI_BUT_ICON_LEFT;
- }
- but->flag |= UI_HAS_ICON;
- ui_but_submenu_enable(block, but);
-
- but->block_create_func = func;
- ui_but_update(but);
-
- return but;
+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, 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_BUT_ICON_SUBMENU flag */
+ if (icon != ICON_RIGHTARROW_THIN) {
+ ui_def_but_icon(but, icon, 0);
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
+ but->flag |= UI_HAS_ICON;
+ ui_but_submenu_enable(block, but);
+
+ but->block_create_func = func;
+ ui_but_update(but);
+
+ return but;
}
/* 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 *but = ui_def_but(block, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
-
- ui_def_but_icon(but, icon, UI_HAS_ICON);
-
- but->drawflag |= UI_BUT_ICON_LEFT;
-
- but->block_create_func = func;
- ui_but_update(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 *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_but_update(but);
- return but;
+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, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
+
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
+
+ but->drawflag |= UI_BUT_ICON_LEFT;
+
+ but->block_create_func = func;
+ ui_but_update(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 *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_but_update(but);
+ return but;
}
/* short pointers hardcoded */
/* 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 *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;
- ui_but_update(but);
- return but;
+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,
+ 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;
+ ui_but_update(but);
+ return but;
}
-
/* 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 */
-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, UI_BTYPE_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);
- ui_def_but_icon(but, icon, UI_HAS_ICON);
+ ui_def_but_icon(but, icon, UI_HAS_ICON);
- but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
+ but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
- ui_but_update(but);
+ ui_but_update(but);
- return but;
+ return but;
}
-
/**
* \param search_func, bfunc: both get it as \a arg.
* \param arg: user value,
* \param active: when set, button opens with this item visible and selected.
*/
-void UI_but_func_search_set(
- uiBut *but,
- uiButSearchCreateFunc search_create_func,
- uiButSearchFunc search_func, void *arg, bool free_arg,
- uiButHandleFunc bfunc, void *active)
-{
- /* needed since callers don't have access to internal functions
- * (as an alternative we could expose it) */
- if (search_create_func == NULL) {
- search_create_func = ui_searchbox_create_generic;
- }
-
- if (but->free_search_arg) {
- MEM_SAFE_FREE(but->search_arg);
- }
-
- but->search_create_func = search_create_func;
- but->search_func = search_func;
- but->search_arg = arg;
- but->free_search_arg = free_arg;
-
- if (bfunc) {
+void UI_but_func_search_set(uiBut *but,
+ uiButSearchCreateFunc search_create_func,
+ uiButSearchFunc search_func,
+ void *arg,
+ bool free_arg,
+ uiButHandleFunc bfunc,
+ void *active)
+{
+ /* needed since callers don't have access to internal functions
+ * (as an alternative we could expose it) */
+ if (search_create_func == NULL) {
+ search_create_func = ui_searchbox_create_generic;
+ }
+
+ if (but->free_search_arg) {
+ MEM_SAFE_FREE(but->search_arg);
+ }
+
+ but->search_create_func = search_create_func;
+ but->search_func = search_func;
+ but->search_arg = arg;
+ but->free_search_arg = free_arg;
+
+ if (bfunc) {
#ifdef DEBUG
- if (but->func) {
- /* watch this, can be cause of much confusion, see: T47691 */
- printf("%s: warning, overwriting button callback with search function callback!\n", __func__);
- }
+ if (but->func) {
+ /* watch this, can be cause of much confusion, see: T47691 */
+ printf("%s: warning, overwriting button callback with search function callback!\n",
+ __func__);
+ }
#endif
- UI_but_func_set(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 */
- if (0 == (but->block->flag & UI_BLOCK_LOOP)) {
- /* skip empty buttons, not all buttons need input, we only show invalid */
- if (but->drawstr[0]) {
- ui_but_search_refresh(but);
- }
- }
+ /* search buttons show red-alert if item doesn't exist, not for menus */
+ if (0 == (but->block->flag & UI_BLOCK_LOOP)) {
+ /* skip empty buttons, not all buttons need input, we only show invalid */
+ if (but->drawstr[0]) {
+ ui_but_search_refresh(but);
+ }
+ }
}
/* Callbacks for operator search button. */
-static void operator_enum_search_cb(const struct bContext *C, void *but, const char *str, uiSearchItems *items)
-{
- wmOperatorType *ot = ((uiBut *)but)->optype;
- PropertyRNA *prop = ot->prop;
-
- if (prop == NULL) {
- printf("%s: %s has no enum property set\n",
- __func__, ot->idname);
- }
- else if (RNA_property_type(prop) != PROP_ENUM) {
- printf("%s: %s \"%s\" is not an enum property\n",
- __func__, ot->idname, RNA_property_identifier(prop));
- }
- else {
- PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */
- const EnumPropertyItem *item, *item_array;
- bool do_free;
-
- RNA_property_enum_items_gettexted((bContext *)C, ptr, prop, &item_array, NULL, &do_free);
-
- for (item = item_array; item->identifier; item++) {
- /* note: need to give the index rather than the
- * identifier because the enum can be freed */
- if (BLI_strcasestr(item->name, str)) {
- if (false == UI_search_item_add(items, item->name, POINTER_FROM_INT(item->value), item->icon)) {
- break;
- }
- }
- }
-
- if (do_free) {
- MEM_freeN((void *)item_array);
- }
- }
+static void operator_enum_search_cb(const struct bContext *C,
+ void *but,
+ const char *str,
+ uiSearchItems *items)
+{
+ wmOperatorType *ot = ((uiBut *)but)->optype;
+ PropertyRNA *prop = ot->prop;
+
+ if (prop == NULL) {
+ printf("%s: %s has no enum property set\n", __func__, ot->idname);
+ }
+ else if (RNA_property_type(prop) != PROP_ENUM) {
+ printf("%s: %s \"%s\" is not an enum property\n",
+ __func__,
+ ot->idname,
+ RNA_property_identifier(prop));
+ }
+ else {
+ PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */
+ const EnumPropertyItem *item, *item_array;
+ bool do_free;
+
+ RNA_property_enum_items_gettexted((bContext *)C, ptr, prop, &item_array, NULL, &do_free);
+
+ for (item = item_array; item->identifier; item++) {
+ /* note: need to give the index rather than the
+ * identifier because the enum can be freed */
+ if (BLI_strcasestr(item->name, str)) {
+ if (false ==
+ UI_search_item_add(items, item->name, POINTER_FROM_INT(item->value), item->icon)) {
+ break;
+ }
+ }
+ }
+
+ if (do_free) {
+ MEM_freeN((void *)item_array);
+ }
+ }
}
static void operator_enum_call_cb(struct bContext *UNUSED(C), void *but, void *arg2)
{
- wmOperatorType *ot = ((uiBut *)but)->optype;
- PointerRNA *opptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */
+ wmOperatorType *ot = ((uiBut *)but)->optype;
+ PointerRNA *opptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */
- if (ot) {
- if (ot->prop) {
- RNA_property_enum_set(opptr, ot->prop, POINTER_AS_INT(arg2));
- /* 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,
- * because one of its parameters is the button itself!
- */
- }
- else {
- printf("%s: op->prop for '%s' is NULL\n", __func__, ot->idname);
- }
- }
+ if (ot) {
+ if (ot->prop) {
+ RNA_property_enum_set(opptr, ot->prop, POINTER_AS_INT(arg2));
+ /* 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,
+ * because one of its parameters is the button itself!
+ */
+ }
+ else {
+ 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
* to call again the right op with the right options (properties values).
*/
-uiBut *uiDefSearchButO_ptr(
- uiBlock *block, wmOperatorType *ot, IDProperty *properties,
- 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;
-
- but = uiDefSearchBut(block, arg, retval, icon, maxlen, x, y, width, height, a1, a2, tip);
- UI_but_func_search_set(
- but, ui_searchbox_create_generic, operator_enum_search_cb,
- but, false, operator_enum_call_cb, NULL);
-
- but->optype = ot;
- but->opcontext = WM_OP_EXEC_DEFAULT;
-
- if (properties) {
- PointerRNA *ptr = UI_but_operator_ptr_get(but);
- /* Copy idproperties. */
- ptr->data = IDP_CopyProperty(properties);
- }
-
- return but;
+uiBut *uiDefSearchButO_ptr(uiBlock *block,
+ wmOperatorType *ot,
+ IDProperty *properties,
+ 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;
+
+ but = uiDefSearchBut(block, arg, retval, icon, maxlen, x, y, width, height, a1, a2, tip);
+ UI_but_func_search_set(but,
+ ui_searchbox_create_generic,
+ operator_enum_search_cb,
+ but,
+ false,
+ operator_enum_call_cb,
+ NULL);
+
+ but->optype = ot;
+ but->opcontext = WM_OP_EXEC_DEFAULT;
+
+ if (properties) {
+ PointerRNA *ptr = UI_but_operator_ptr_get(but);
+ /* Copy idproperties. */
+ ptr->data = IDP_CopyProperty(properties);
+ }
+
+ return but;
}
/**
@@ -4963,260 +6241,259 @@ uiBut *uiDefSearchButO_ptr(
*/
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.val = KM_PRESS;
- event.customdata = but;
- event.customdatafree = false;
+ event.type = EVT_BUT_OPEN;
+ event.val = KM_PRESS;
+ event.customdata = but;
+ event.customdatafree = false;
- wm_event_add(win, &event);
+ wm_event_add(win, &event);
}
void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN)
{
- but->hold_func = func;
- but->hold_argN = argN;
+ but->hold_func = func;
+ but->hold_argN = argN;
}
void UI_but_string_info_get(bContext *C, uiBut *but, ...)
{
- va_list args;
- uiStringInfo *si;
-
- const EnumPropertyItem *items = NULL, *item = NULL;
- int totitems;
- bool free_items = false;
-
- va_start(args, but);
- while ((si = (uiStringInfo *) va_arg(args, void *))) {
- int type = si->type;
- char *tmp = NULL;
-
- if (type == BUT_GET_LABEL) {
- if (but->str) {
- const char *str_sep;
- size_t str_len;
-
- if ((but->flag & UI_BUT_HAS_SEP_CHAR) &&
- (str_sep = strrchr(but->str, UI_SEP_CHAR)))
- {
- str_len = (str_sep - but->str);
- }
- else {
- str_len = strlen(but->str);
- }
-
- tmp = BLI_strdupn(but->str, str_len);
- }
- else {
- type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */
- }
- }
- else if (type == BUT_GET_TIP) {
- if (but->tip_func) {
- tmp = but->tip_func(C, but->tip_argN, but->tip);
- }
- else if (but->tip && but->tip[0]) {
- tmp = BLI_strdup(but->tip);
- }
- else {
- type = BUT_GET_RNA_TIP; /* Fail-safe solution... */
- }
- }
-
- if (type == BUT_GET_RNAPROP_IDENTIFIER) {
- if (but->rnaprop) {
- tmp = BLI_strdup(RNA_property_identifier(but->rnaprop));
- }
- }
- else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) {
- if (but->rnaprop && but->rnapoin.data) {
- tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type));
- }
- else if (but->optype) {
- tmp = BLI_strdup(but->optype->idname);
- }
- else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
- MenuType *mt = UI_but_menutype_get(but);
- if (mt) {
- tmp = BLI_strdup(mt->idname);
- }
- }
- else if (but->type == UI_BTYPE_POPOVER) {
- PanelType *pt = UI_but_paneltype_get(but);
- if (pt) {
- tmp = BLI_strdup(pt->idname);
- }
- }
- }
- else if (ELEM(type, BUT_GET_RNA_LABEL, BUT_GET_RNA_TIP)) {
- if (but->rnaprop) {
- if (type == BUT_GET_RNA_LABEL) {
- tmp = BLI_strdup(RNA_property_ui_name(but->rnaprop));
- }
- else {
- const char *t = RNA_property_ui_description(but->rnaprop);
- if (t && t[0]) {
- tmp = BLI_strdup(t);
- }
- }
- }
- else if (but->optype) {
- if (type == BUT_GET_RNA_LABEL) {
- tmp = BLI_strdup(RNA_struct_ui_name(but->optype->srna));
- }
- else {
- const char *t = RNA_struct_ui_description(but->optype->srna);
- if (t && t[0]) {
- tmp = BLI_strdup(t);
- }
- }
- }
- else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
- MenuType *mt = UI_but_menutype_get(but);
- if (mt) {
- /* not all menus are from python */
- if (mt->ext.srna) {
- if (type == BUT_GET_RNA_LABEL) {
- tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna));
- }
- else {
- const char *t = RNA_struct_ui_description(mt->ext.srna);
- if (t && t[0]) {
- tmp = BLI_strdup(t);
- }
- }
- }
- }
- }
- }
- else if (type == BUT_GET_RNA_LABEL_CONTEXT) {
- const char *_tmp = BLT_I18NCONTEXT_DEFAULT;
- if (but->rnaprop) {
- _tmp = RNA_property_translation_context(but->rnaprop);
- }
- else if (but->optype) {
- _tmp = RNA_struct_translation_context(but->optype->srna);
- }
- else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
- MenuType *mt = UI_but_menutype_get(but);
- if (mt) {
- _tmp = RNA_struct_translation_context(mt->ext.srna);
- }
- }
- if (BLT_is_default_context(_tmp)) {
- _tmp = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
- }
- tmp = BLI_strdup(_tmp);
- }
- else if (ELEM(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) {
- PointerRNA *ptr = NULL;
- PropertyRNA *prop = NULL;
- int value = 0;
-
- /* get the enum property... */
- if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
- /* enum property */
- ptr = &but->rnapoin;
- prop = but->rnaprop;
- value = (ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB)) ? (int)but->hardmax : (int)ui_but_value_get(but);
- }
- else if (but->optype) {
- PointerRNA *opptr = UI_but_operator_ptr_get(but);
- wmOperatorType *ot = but->optype;
-
- /* so the context is passed to itemf functions */
- WM_operator_properties_sanitize(opptr, false);
-
- /* 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"
- * operator menus in the Anim Editors will show tooltips for the different
- * operations instead of the meaningless generic operator tooltip
- */
- if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) {
- if (RNA_struct_contains_property(opptr, ot->prop)) {
- ptr = opptr;
- prop = ot->prop;
- value = RNA_property_enum_get(opptr, ot->prop);
- }
- }
- }
-
- /* get strings from matching enum item */
- if (ptr && prop) {
- if (!item) {
- int i;
-
- RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items);
- for (i = 0, item = items; i < totitems; i++, item++) {
- if (item->identifier[0] && item->value == value) {
- break;
- }
- }
- }
- if (item && item->identifier) {
- if (type == BUT_GET_RNAENUM_IDENTIFIER) {
- tmp = BLI_strdup(item->identifier);
- }
- else if (type == BUT_GET_RNAENUM_LABEL) {
- tmp = BLI_strdup(item->name);
- }
- else if (item->description && item->description[0]) {
- tmp = BLI_strdup(item->description);
- }
- }
- }
- }
- else if (type == BUT_GET_OP_KEYMAP) {
- if (!ui_block_is_menu(but->block)) {
- char buf[128];
- if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
- tmp = BLI_strdup(buf);
- }
- }
- }
- else if (type == BUT_GET_PROP_KEYMAP) {
- /* for properties that are bound to one of the context cycle, etc. keys... */
- char buf[128];
- if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) {
- tmp = BLI_strdup(buf);
- }
- }
-
- si->strinfo = tmp;
- }
- va_end(args);
-
- if (free_items && items) {
- MEM_freeN((void *)items);
- }
+ va_list args;
+ uiStringInfo *si;
+
+ const EnumPropertyItem *items = NULL, *item = NULL;
+ int totitems;
+ bool free_items = false;
+
+ va_start(args, but);
+ while ((si = (uiStringInfo *)va_arg(args, void *))) {
+ int type = si->type;
+ char *tmp = NULL;
+
+ if (type == BUT_GET_LABEL) {
+ if (but->str) {
+ const char *str_sep;
+ size_t str_len;
+
+ if ((but->flag & UI_BUT_HAS_SEP_CHAR) && (str_sep = strrchr(but->str, UI_SEP_CHAR))) {
+ str_len = (str_sep - but->str);
+ }
+ else {
+ str_len = strlen(but->str);
+ }
+
+ tmp = BLI_strdupn(but->str, str_len);
+ }
+ else {
+ type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */
+ }
+ }
+ else if (type == BUT_GET_TIP) {
+ if (but->tip_func) {
+ tmp = but->tip_func(C, but->tip_argN, but->tip);
+ }
+ else if (but->tip && but->tip[0]) {
+ tmp = BLI_strdup(but->tip);
+ }
+ else {
+ type = BUT_GET_RNA_TIP; /* Fail-safe solution... */
+ }
+ }
+
+ if (type == BUT_GET_RNAPROP_IDENTIFIER) {
+ if (but->rnaprop) {
+ tmp = BLI_strdup(RNA_property_identifier(but->rnaprop));
+ }
+ }
+ else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) {
+ if (but->rnaprop && but->rnapoin.data) {
+ tmp = BLI_strdup(RNA_struct_identifier(but->rnapoin.type));
+ }
+ else if (but->optype) {
+ tmp = BLI_strdup(but->optype->idname);
+ }
+ else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
+ MenuType *mt = UI_but_menutype_get(but);
+ if (mt) {
+ tmp = BLI_strdup(mt->idname);
+ }
+ }
+ else if (but->type == UI_BTYPE_POPOVER) {
+ PanelType *pt = UI_but_paneltype_get(but);
+ if (pt) {
+ tmp = BLI_strdup(pt->idname);
+ }
+ }
+ }
+ else if (ELEM(type, BUT_GET_RNA_LABEL, BUT_GET_RNA_TIP)) {
+ if (but->rnaprop) {
+ if (type == BUT_GET_RNA_LABEL) {
+ tmp = BLI_strdup(RNA_property_ui_name(but->rnaprop));
+ }
+ else {
+ const char *t = RNA_property_ui_description(but->rnaprop);
+ if (t && t[0]) {
+ tmp = BLI_strdup(t);
+ }
+ }
+ }
+ else if (but->optype) {
+ if (type == BUT_GET_RNA_LABEL) {
+ tmp = BLI_strdup(RNA_struct_ui_name(but->optype->srna));
+ }
+ else {
+ const char *t = RNA_struct_ui_description(but->optype->srna);
+ if (t && t[0]) {
+ tmp = BLI_strdup(t);
+ }
+ }
+ }
+ else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
+ MenuType *mt = UI_but_menutype_get(but);
+ if (mt) {
+ /* not all menus are from python */
+ if (mt->ext.srna) {
+ if (type == BUT_GET_RNA_LABEL) {
+ tmp = BLI_strdup(RNA_struct_ui_name(mt->ext.srna));
+ }
+ else {
+ const char *t = RNA_struct_ui_description(mt->ext.srna);
+ if (t && t[0]) {
+ tmp = BLI_strdup(t);
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (type == BUT_GET_RNA_LABEL_CONTEXT) {
+ const char *_tmp = BLT_I18NCONTEXT_DEFAULT;
+ if (but->rnaprop) {
+ _tmp = RNA_property_translation_context(but->rnaprop);
+ }
+ else if (but->optype) {
+ _tmp = RNA_struct_translation_context(but->optype->srna);
+ }
+ else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
+ MenuType *mt = UI_but_menutype_get(but);
+ if (mt) {
+ _tmp = RNA_struct_translation_context(mt->ext.srna);
+ }
+ }
+ if (BLT_is_default_context(_tmp)) {
+ _tmp = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
+ }
+ tmp = BLI_strdup(_tmp);
+ }
+ else if (ELEM(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) {
+ PointerRNA *ptr = NULL;
+ PropertyRNA *prop = NULL;
+ int value = 0;
+
+ /* get the enum property... */
+ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
+ /* enum property */
+ ptr = &but->rnapoin;
+ prop = but->rnaprop;
+ value = (ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB)) ? (int)but->hardmax :
+ (int)ui_but_value_get(but);
+ }
+ else if (but->optype) {
+ PointerRNA *opptr = UI_but_operator_ptr_get(but);
+ wmOperatorType *ot = but->optype;
+
+ /* so the context is passed to itemf functions */
+ WM_operator_properties_sanitize(opptr, false);
+
+ /* 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"
+ * operator menus in the Anim Editors will show tooltips for the different
+ * operations instead of the meaningless generic operator tooltip
+ */
+ if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) {
+ if (RNA_struct_contains_property(opptr, ot->prop)) {
+ ptr = opptr;
+ prop = ot->prop;
+ value = RNA_property_enum_get(opptr, ot->prop);
+ }
+ }
+ }
+
+ /* get strings from matching enum item */
+ if (ptr && prop) {
+ if (!item) {
+ int i;
+
+ RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items);
+ for (i = 0, item = items; i < totitems; i++, item++) {
+ if (item->identifier[0] && item->value == value) {
+ break;
+ }
+ }
+ }
+ if (item && item->identifier) {
+ if (type == BUT_GET_RNAENUM_IDENTIFIER) {
+ tmp = BLI_strdup(item->identifier);
+ }
+ else if (type == BUT_GET_RNAENUM_LABEL) {
+ tmp = BLI_strdup(item->name);
+ }
+ else if (item->description && item->description[0]) {
+ tmp = BLI_strdup(item->description);
+ }
+ }
+ }
+ }
+ else if (type == BUT_GET_OP_KEYMAP) {
+ if (!ui_block_is_menu(but->block)) {
+ char buf[128];
+ if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
+ tmp = BLI_strdup(buf);
+ }
+ }
+ }
+ else if (type == BUT_GET_PROP_KEYMAP) {
+ /* for properties that are bound to one of the context cycle, etc. keys... */
+ char buf[128];
+ if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) {
+ tmp = BLI_strdup(buf);
+ }
+ }
+
+ si->strinfo = tmp;
+ }
+ va_end(args);
+
+ if (free_items && items) {
+ MEM_freeN((void *)items);
+ }
}
/* Program Init/Exit */
void UI_init(void)
{
- ui_resources_init();
+ ui_resources_init();
}
/* after reading userdef file */
void UI_init_userdef(Main *bmain)
{
- /* fix saved themes */
- init_userdef_do_versions(bmain);
- uiStyleInit();
+ /* fix saved themes */
+ init_userdef_do_versions(bmain);
+ uiStyleInit();
}
void UI_reinit_font(void)
{
- uiStyleInit();
+ uiStyleInit();
}
void UI_exit(void)
{
- ui_resources_free();
- ui_but_clipboard_free();
+ ui_resources_free();
+ ui_but_clipboard_free();
}
diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c
index 9e1563e6511..61f9005ce44 100644
--- a/source/blender/editors/interface/interface_align.c
+++ b/source/blender/editors/interface/interface_align.c
@@ -55,77 +55,87 @@
* but not sure we want to support such exotic cases anyway.
*/
typedef struct ButAlign {
- uiBut *but;
+ uiBut *but;
- /* Neighbor buttons */
- struct ButAlign *neighbors[4];
+ /* Neighbor buttons */
+ struct ButAlign *neighbors[4];
- /* Pointers to coordinates (rctf values) of the button. */
- float *borders[4];
+ /* Pointers to coordinates (rctf values) of the button. */
+ float *borders[4];
- /* Distances to the neighbors. */
- float dists[4];
+ /* Distances to the neighbors. */
+ float dists[4];
- /* Flags, used to mark whether we should 'stitch'
- * the corners of this button with its neighbors' ones. */
- char flags[4];
+ /* Flags, used to mark whether we should 'stitch'
+ * the corners of this button with its neighbors' ones. */
+ char flags[4];
} ButAlign;
/* Side-related enums and flags. */
enum {
- /* Sides (used as indices, order is **crucial**,
- * this allows us to factorize code in a loop over the four sides). */
- LEFT = 0,
- TOP = 1,
- RIGHT = 2,
- DOWN = 3,
- TOTSIDES = 4,
-
- /* Stitch flags, built from sides values. */
- STITCH_LEFT = 1 << LEFT,
- STITCH_TOP = 1 << TOP,
- STITCH_RIGHT = 1 << RIGHT,
- STITCH_DOWN = 1 << DOWN,
+ /* Sides (used as indices, order is **crucial**,
+ * this allows us to factorize code in a loop over the four sides). */
+ LEFT = 0,
+ TOP = 1,
+ RIGHT = 2,
+ DOWN = 3,
+ TOTSIDES = 4,
+
+ /* Stitch flags, built from sides values. */
+ STITCH_LEFT = 1 << LEFT,
+ STITCH_TOP = 1 << TOP,
+ STITCH_RIGHT = 1 << RIGHT,
+ STITCH_DOWN = 1 << DOWN,
};
/* Mapping between 'our' sides and 'public' UI_BUT_ALIGN flags, order must match enum above. */
-#define SIDE_TO_UI_BUT_ALIGN {UI_BUT_ALIGN_LEFT, UI_BUT_ALIGN_TOP, UI_BUT_ALIGN_RIGHT, UI_BUT_ALIGN_DOWN}
+# define SIDE_TO_UI_BUT_ALIGN \
+ { \
+ UI_BUT_ALIGN_LEFT, UI_BUT_ALIGN_TOP, UI_BUT_ALIGN_RIGHT, UI_BUT_ALIGN_DOWN \
+ }
/* Given one side, compute the three other ones */
-#define SIDE1(_s) (((_s) + 1) % TOTSIDES)
-#define OPPOSITE(_s) (((_s) + 2) % TOTSIDES)
-#define SIDE2(_s) (((_s) + 3) % TOTSIDES)
+# define SIDE1(_s) (((_s) + 1) % TOTSIDES)
+# define OPPOSITE(_s) (((_s) + 2) % TOTSIDES)
+# define SIDE2(_s) (((_s) + 3) % TOTSIDES)
/* 0: LEFT/RIGHT sides; 1 = TOP/DOWN sides. */
-#define IS_COLUMN(_s) ((_s) % 2)
+# define IS_COLUMN(_s) ((_s) % 2)
/* Stitch flag from side value. */
-#define STITCH(_s) (1 << (_s))
+# define STITCH(_s) (1 << (_s))
/* Max distance between to buttons for them to be 'mergeable'. */
-#define MAX_DELTA 0.45f * max_ii(UI_UNIT_Y, UI_UNIT_X)
+# define MAX_DELTA 0.45f * max_ii(UI_UNIT_Y, UI_UNIT_X)
bool ui_but_can_align(const uiBut *but)
{
- const bool btype_can_align = !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N,
- UI_BTYPE_TAB, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER);
- return (btype_can_align && (BLI_rctf_size_x(&but->rect) > 0.0f) && (BLI_rctf_size_y(&but->rect) > 0.0f));
+ const bool btype_can_align = !ELEM(but->type,
+ UI_BTYPE_LABEL,
+ UI_BTYPE_CHECKBOX,
+ UI_BTYPE_CHECKBOX_N,
+ UI_BTYPE_TAB,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_SEPR_SPACER);
+ return (btype_can_align && (BLI_rctf_size_x(&but->rect) > 0.0f) &&
+ (BLI_rctf_size_y(&but->rect) > 0.0f));
}
int ui_but_align_opposite_to_area_align_get(const ARegion *ar)
{
- switch (ar->alignment) {
- case RGN_ALIGN_TOP:
- return UI_BUT_ALIGN_DOWN;
- case RGN_ALIGN_BOTTOM:
- return UI_BUT_ALIGN_TOP;
- case RGN_ALIGN_LEFT:
- return UI_BUT_ALIGN_RIGHT;
- case RGN_ALIGN_RIGHT:
- return UI_BUT_ALIGN_LEFT;
- }
-
- return 0;
+ switch (ar->alignment) {
+ case RGN_ALIGN_TOP:
+ return UI_BUT_ALIGN_DOWN;
+ case RGN_ALIGN_BOTTOM:
+ return UI_BUT_ALIGN_TOP;
+ case RGN_ALIGN_LEFT:
+ return UI_BUT_ALIGN_RIGHT;
+ case RGN_ALIGN_RIGHT:
+ return UI_BUT_ALIGN_LEFT;
+ }
+
+ return 0;
}
/**
@@ -136,114 +146,115 @@ int ui_but_align_opposite_to_area_align_get(const ARegion *ar)
*/
static void block_align_proximity_compute(ButAlign *butal, ButAlign *butal_other)
{
- /* That's the biggest gap between two borders to consider them 'alignable'. */
- const float max_delta = MAX_DELTA;
- float delta, delta_side_opp;
- int side, side_opp;
-
- const bool butal_can_align = ui_but_can_align(butal->but);
- const bool butal_other_can_align = ui_but_can_align(butal_other->but);
-
- const bool buts_share[2] = {
- /* Sharing same line? */
- !((*butal->borders[DOWN] >= *butal_other->borders[TOP]) ||
- (*butal->borders[TOP] <= *butal_other->borders[DOWN])),
- /* Sharing same column? */
- !((*butal->borders[LEFT] >= *butal_other->borders[RIGHT]) ||
- (*butal->borders[RIGHT] <= *butal_other->borders[LEFT])),
- };
-
- /* Early out in case buttons share no column or line, or if none can align... */
- if (!(buts_share[0] || buts_share[1]) || !(butal_can_align || butal_other_can_align)) {
- return;
- }
-
- for (side = 0; side < RIGHT; side++) {
- /* We are only interested in buttons which share a same line
- * (LEFT/RIGHT sides) or column (TOP/DOWN sides). */
- if (buts_share[IS_COLUMN(side)]) {
- side_opp = OPPOSITE(side);
-
- /* We check both opposite sides at once, because with very small buttons,
- * delta could be below max_delta for the wrong side
- * (that is, in horizontal case, the total width of two buttons can be below max_delta).
- * We rely on exact zero value here as an 'already processed' flag,
- * so ensure we never actually set a zero value at this stage.
- * FLT_MIN is zero-enough for UI position computing. ;) */
- delta = max_ff(fabsf(*butal->borders[side] - *butal_other->borders[side_opp]), FLT_MIN);
- delta_side_opp = max_ff(fabsf(*butal->borders[side_opp] - *butal_other->borders[side]), FLT_MIN);
- if (delta_side_opp < delta) {
- SWAP(int, side, side_opp);
- delta = delta_side_opp;
- }
-
- if (delta < max_delta) {
- /* We are only interested in neighbors that are
- * at least as close as already found ones. */
- if (delta <= butal->dists[side]) {
- {
- /* We found an as close or closer neighbor.
- * If both buttons are alignable, we set them as each other neighbors.
- * Else, we have an unalignable one, we need to reset the others matching
- * neighbor to NULL if its 'proximity distance'
- * is really lower with current one.
- *
- * NOTE: We cannot only execute that piece of code in case we found a
- * **closer** neighbor, due to the limited way we represent neighbors
- * (buttons only know **one** neighbor on each side, when they can
- * actually have several ones), it would prevent some buttons to be
- * properly 'neighborly-initialized'. */
- if (butal_can_align && butal_other_can_align) {
- butal->neighbors[side] = butal_other;
- butal_other->neighbors[side_opp] = butal;
- }
- else if (butal_can_align && (delta < butal->dists[side])) {
- butal->neighbors[side] = NULL;
- }
- else if (butal_other_can_align && (delta < butal_other->dists[side_opp])) {
- butal_other->neighbors[side_opp] = NULL;
- }
- butal->dists[side] = butal_other->dists[side_opp] = delta;
- }
-
- if (butal_can_align && butal_other_can_align) {
- const int side_s1 = SIDE1(side);
- const int side_s2 = SIDE2(side);
-
- const int stitch = STITCH(side);
- const int stitch_opp = STITCH(side_opp);
-
- if (butal->neighbors[side] == NULL) {
- butal->neighbors[side] = butal_other;
- }
- if (butal_other->neighbors[side_opp] == NULL) {
- butal_other->neighbors[side_opp] = butal;
- }
-
- /* We have a pair of neighbors, we have to check whether we
- * can stitch their matching corners.
- * E.g. if butal_other is on the left of butal (that is, side == LEFT),
- * if both TOP (side_s1) coordinates of buttons are close enough,
- * we can stitch their upper matching corners,
- * and same for DOWN (side_s2) side. */
- delta = fabsf(*butal->borders[side_s1] - *butal_other->borders[side_s1]);
- if (delta < max_delta) {
- butal->flags[side_s1] |= stitch;
- butal_other->flags[side_s1] |= stitch_opp;
- }
- delta = fabsf(*butal->borders[side_s2] - *butal_other->borders[side_s2]);
- if (delta < max_delta) {
- butal->flags[side_s2] |= stitch;
- butal_other->flags[side_s2] |= stitch_opp;
- }
- }
- }
- /* We assume two buttons can only share one side at most - for until
- * we have sperical UI... */
- return;
- }
- }
- }
+ /* That's the biggest gap between two borders to consider them 'alignable'. */
+ const float max_delta = MAX_DELTA;
+ float delta, delta_side_opp;
+ int side, side_opp;
+
+ const bool butal_can_align = ui_but_can_align(butal->but);
+ const bool butal_other_can_align = ui_but_can_align(butal_other->but);
+
+ const bool buts_share[2] = {
+ /* Sharing same line? */
+ !((*butal->borders[DOWN] >= *butal_other->borders[TOP]) ||
+ (*butal->borders[TOP] <= *butal_other->borders[DOWN])),
+ /* Sharing same column? */
+ !((*butal->borders[LEFT] >= *butal_other->borders[RIGHT]) ||
+ (*butal->borders[RIGHT] <= *butal_other->borders[LEFT])),
+ };
+
+ /* Early out in case buttons share no column or line, or if none can align... */
+ if (!(buts_share[0] || buts_share[1]) || !(butal_can_align || butal_other_can_align)) {
+ return;
+ }
+
+ for (side = 0; side < RIGHT; side++) {
+ /* We are only interested in buttons which share a same line
+ * (LEFT/RIGHT sides) or column (TOP/DOWN sides). */
+ if (buts_share[IS_COLUMN(side)]) {
+ side_opp = OPPOSITE(side);
+
+ /* We check both opposite sides at once, because with very small buttons,
+ * delta could be below max_delta for the wrong side
+ * (that is, in horizontal case, the total width of two buttons can be below max_delta).
+ * We rely on exact zero value here as an 'already processed' flag,
+ * so ensure we never actually set a zero value at this stage.
+ * FLT_MIN is zero-enough for UI position computing. ;) */
+ delta = max_ff(fabsf(*butal->borders[side] - *butal_other->borders[side_opp]), FLT_MIN);
+ delta_side_opp = max_ff(fabsf(*butal->borders[side_opp] - *butal_other->borders[side]),
+ FLT_MIN);
+ if (delta_side_opp < delta) {
+ SWAP(int, side, side_opp);
+ delta = delta_side_opp;
+ }
+
+ if (delta < max_delta) {
+ /* We are only interested in neighbors that are
+ * at least as close as already found ones. */
+ if (delta <= butal->dists[side]) {
+ {
+ /* We found an as close or closer neighbor.
+ * If both buttons are alignable, we set them as each other neighbors.
+ * Else, we have an unalignable one, we need to reset the others matching
+ * neighbor to NULL if its 'proximity distance'
+ * is really lower with current one.
+ *
+ * NOTE: We cannot only execute that piece of code in case we found a
+ * **closer** neighbor, due to the limited way we represent neighbors
+ * (buttons only know **one** neighbor on each side, when they can
+ * actually have several ones), it would prevent some buttons to be
+ * properly 'neighborly-initialized'. */
+ if (butal_can_align && butal_other_can_align) {
+ butal->neighbors[side] = butal_other;
+ butal_other->neighbors[side_opp] = butal;
+ }
+ else if (butal_can_align && (delta < butal->dists[side])) {
+ butal->neighbors[side] = NULL;
+ }
+ else if (butal_other_can_align && (delta < butal_other->dists[side_opp])) {
+ butal_other->neighbors[side_opp] = NULL;
+ }
+ butal->dists[side] = butal_other->dists[side_opp] = delta;
+ }
+
+ if (butal_can_align && butal_other_can_align) {
+ const int side_s1 = SIDE1(side);
+ const int side_s2 = SIDE2(side);
+
+ const int stitch = STITCH(side);
+ const int stitch_opp = STITCH(side_opp);
+
+ if (butal->neighbors[side] == NULL) {
+ butal->neighbors[side] = butal_other;
+ }
+ if (butal_other->neighbors[side_opp] == NULL) {
+ butal_other->neighbors[side_opp] = butal;
+ }
+
+ /* We have a pair of neighbors, we have to check whether we
+ * can stitch their matching corners.
+ * E.g. if butal_other is on the left of butal (that is, side == LEFT),
+ * if both TOP (side_s1) coordinates of buttons are close enough,
+ * we can stitch their upper matching corners,
+ * and same for DOWN (side_s2) side. */
+ delta = fabsf(*butal->borders[side_s1] - *butal_other->borders[side_s1]);
+ if (delta < max_delta) {
+ butal->flags[side_s1] |= stitch;
+ butal_other->flags[side_s1] |= stitch_opp;
+ }
+ delta = fabsf(*butal->borders[side_s2] - *butal_other->borders[side_s2]);
+ if (delta < max_delta) {
+ butal->flags[side_s2] |= stitch;
+ butal_other->flags[side_s2] |= stitch_opp;
+ }
+ }
+ }
+ /* We assume two buttons can only share one side at most - for until
+ * we have sperical UI... */
+ return;
+ }
+ }
+ }
}
/**
@@ -265,47 +276,49 @@ static void block_align_proximity_compute(ButAlign *butal, ButAlign *butal_other
* \note To avoid doing this twice, some stitching flags are cleared to break the 'stitching connection'
* between neighbors.
*/
-static void block_align_stitch_neighbors(
- ButAlign *butal,
- const int side, const int side_opp, const int side_s1, const int side_s2,
- const int align, const int align_opp, const float co)
+static void block_align_stitch_neighbors(ButAlign *butal,
+ const int side,
+ const int side_opp,
+ const int side_s1,
+ const int side_s2,
+ const int align,
+ const int align_opp,
+ const float co)
{
- ButAlign *butal_neighbor;
-
- const int stitch_s1 = STITCH(side_s1);
- const int stitch_s2 = STITCH(side_s2);
-
- /* We have to check stitching flags on both sides of the stitching, since we only clear one of them flags to break
- * any future loop on same 'columns/side' case.
- * Also, if butal is spanning over several rows or columns of neighbors, it may have both of its stitching flags
- * set, but would not be the case of its immediate neighbor! */
- while ((butal->flags[side] & stitch_s1) &&
- (butal = butal->neighbors[side_s1]) &&
- (butal->flags[side] & stitch_s2))
- {
- butal_neighbor = butal->neighbors[side];
-
- /* If we actually do have a neighbor, we directly set its values accordingly, and clear its matching 'dist'
- * to prevent it being set again later... */
- if (butal_neighbor) {
- butal->but->drawflag |= align;
- butal_neighbor->but->drawflag |= align_opp;
- *butal_neighbor->borders[side_opp] = co;
- butal_neighbor->dists[side_opp] = 0.0f;
- }
- /* See definition of UI_BUT_ALIGN_STITCH_LEFT/TOP for reason of this... */
- else if (side == LEFT) {
- butal->but->drawflag |= UI_BUT_ALIGN_STITCH_LEFT;
- }
- else if (side == TOP) {
- butal->but->drawflag |= UI_BUT_ALIGN_STITCH_TOP;
- }
- *butal->borders[side] = co;
- butal->dists[side] = 0.0f;
- /* Clearing one of the 'flags pair' here is enough to prevent this loop running on
- * the same column, side and direction again. */
- butal->flags[side] &= ~stitch_s2;
- }
+ ButAlign *butal_neighbor;
+
+ const int stitch_s1 = STITCH(side_s1);
+ const int stitch_s2 = STITCH(side_s2);
+
+ /* We have to check stitching flags on both sides of the stitching, since we only clear one of them flags to break
+ * any future loop on same 'columns/side' case.
+ * Also, if butal is spanning over several rows or columns of neighbors, it may have both of its stitching flags
+ * set, but would not be the case of its immediate neighbor! */
+ while ((butal->flags[side] & stitch_s1) && (butal = butal->neighbors[side_s1]) &&
+ (butal->flags[side] & stitch_s2)) {
+ butal_neighbor = butal->neighbors[side];
+
+ /* If we actually do have a neighbor, we directly set its values accordingly, and clear its matching 'dist'
+ * to prevent it being set again later... */
+ if (butal_neighbor) {
+ butal->but->drawflag |= align;
+ butal_neighbor->but->drawflag |= align_opp;
+ *butal_neighbor->borders[side_opp] = co;
+ butal_neighbor->dists[side_opp] = 0.0f;
+ }
+ /* See definition of UI_BUT_ALIGN_STITCH_LEFT/TOP for reason of this... */
+ else if (side == LEFT) {
+ butal->but->drawflag |= UI_BUT_ALIGN_STITCH_LEFT;
+ }
+ else if (side == TOP) {
+ butal->but->drawflag |= UI_BUT_ALIGN_STITCH_TOP;
+ }
+ *butal->borders[side] = co;
+ butal->dists[side] = 0.0f;
+ /* Clearing one of the 'flags pair' here is enough to prevent this loop running on
+ * the same column, side and direction again. */
+ butal->flags[side] &= ~stitch_s2;
+ }
}
/**
@@ -316,61 +329,61 @@ static void block_align_stitch_neighbors(
*/
static int ui_block_align_butal_cmp(const void *a, const void *b)
{
- const ButAlign *butal = a;
- const ButAlign *butal_other = b;
-
- /* Sort by align group. */
- if (butal->but->alignnr != butal_other->but->alignnr) {
- return butal->but->alignnr - butal_other->but->alignnr;
- }
-
- /* Sort vertically.
- * Note that Y of buttons is decreasing (first buttons have higher Y value than later ones). */
- if (*butal->borders[TOP] != *butal_other->borders[TOP]) {
- return (*butal_other->borders[TOP] > *butal->borders[TOP]) ? 1 : -1;
- }
-
- /* Sort horizontally. */
- if (*butal->borders[LEFT] != *butal_other->borders[LEFT]) {
- return (*butal->borders[LEFT] > *butal_other->borders[LEFT]) ? 1 : -1;
- }
-
- /* XXX We cannot actually assert here, since in some very compressed space cases,
- * stupid UI code produces widgets which have the same TOP and LEFT positions...
- * We do not care really,
- * because this happens when UI is way too small to be usable anyway. */
- /* BLI_assert(0); */
- return 0;
+ const ButAlign *butal = a;
+ const ButAlign *butal_other = b;
+
+ /* Sort by align group. */
+ if (butal->but->alignnr != butal_other->but->alignnr) {
+ return butal->but->alignnr - butal_other->but->alignnr;
+ }
+
+ /* Sort vertically.
+ * Note that Y of buttons is decreasing (first buttons have higher Y value than later ones). */
+ if (*butal->borders[TOP] != *butal_other->borders[TOP]) {
+ return (*butal_other->borders[TOP] > *butal->borders[TOP]) ? 1 : -1;
+ }
+
+ /* Sort horizontally. */
+ if (*butal->borders[LEFT] != *butal_other->borders[LEFT]) {
+ return (*butal->borders[LEFT] > *butal_other->borders[LEFT]) ? 1 : -1;
+ }
+
+ /* XXX We cannot actually assert here, since in some very compressed space cases,
+ * stupid UI code produces widgets which have the same TOP and LEFT positions...
+ * We do not care really,
+ * because this happens when UI is way too small to be usable anyway. */
+ /* BLI_assert(0); */
+ return 0;
}
static void ui_block_align_but_to_region(uiBut *but, const ARegion *region)
{
- rctf *rect = &but->rect;
- const float but_width = BLI_rctf_size_x(rect);
- const float but_height = BLI_rctf_size_y(rect);
- const float outline_px = U.pixelsize; /* This may have to be made more variable. */
-
- switch (but->drawflag & UI_BUT_ALIGN) {
- case UI_BUT_ALIGN_TOP:
- rect->ymax = region->winy + outline_px;
- rect->ymin = but->rect.ymax - but_height;
- break;
- case UI_BUT_ALIGN_DOWN:
- rect->ymin = -outline_px;
- rect->ymax = rect->ymin + but_height;
- break;
- case UI_BUT_ALIGN_LEFT:
- rect->xmin = -outline_px;
- rect->xmax = rect->xmin + but_width;
- break;
- case UI_BUT_ALIGN_RIGHT:
- rect->xmax = region->winx + outline_px;
- rect->xmin = rect->xmax - but_width;
- break;
- default:
- BLI_assert(0);
- break;
- }
+ rctf *rect = &but->rect;
+ const float but_width = BLI_rctf_size_x(rect);
+ const float but_height = BLI_rctf_size_y(rect);
+ const float outline_px = U.pixelsize; /* This may have to be made more variable. */
+
+ switch (but->drawflag & UI_BUT_ALIGN) {
+ case UI_BUT_ALIGN_TOP:
+ rect->ymax = region->winy + outline_px;
+ rect->ymin = but->rect.ymax - but_height;
+ break;
+ case UI_BUT_ALIGN_DOWN:
+ rect->ymin = -outline_px;
+ rect->ymax = rect->ymin + but_height;
+ break;
+ case UI_BUT_ALIGN_LEFT:
+ rect->xmin = -outline_px;
+ rect->xmax = rect->xmin + but_width;
+ break;
+ case UI_BUT_ALIGN_RIGHT:
+ rect->xmax = region->winx + outline_px;
+ rect->xmin = rect->xmax - but_width;
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
}
/**
@@ -381,350 +394,355 @@ static void ui_block_align_but_to_region(uiBut *but, const ARegion *region)
*/
void ui_block_align_calc(uiBlock *block, const ARegion *region)
{
- uiBut *but;
- int num_buttons = 0;
-
- const int sides_to_ui_but_align_flags[4] = SIDE_TO_UI_BUT_ALIGN;
-
- ButAlign *butal_array;
- ButAlign *butal, *butal_other;
- int side;
- int i, j;
-
- /* First loop: we count number of buttons belonging to an align group, and clear their align flag.
- * Tabs get some special treatment here, they get aligned to region border. */
- for (but = block->buttons.first; but; but = but->next) {
- /* special case: tabs need to be aligned to a region border, drawflag tells which one */
- if (but->type == UI_BTYPE_TAB) {
- ui_block_align_but_to_region(but, region);
- }
- else {
- /* Clear old align flags. */
- but->drawflag &= ~UI_BUT_ALIGN_ALL;
- }
-
- if (but->alignnr != 0) {
- num_buttons++;
- }
- }
-
- if (num_buttons < 2) {
- /* No need to go further if we have nothing to align... */
- return;
- }
-
- butal_array = alloca(sizeof(*butal_array) * (size_t)num_buttons);
- memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons);
-
- /* Second loop: we initialize our ButAlign data for each button. */
- for (but = block->buttons.first, butal = butal_array; but; but = but->next) {
- if (but->alignnr != 0) {
- butal->but = but;
- butal->borders[LEFT] = &but->rect.xmin;
- butal->borders[RIGHT] = &but->rect.xmax;
- butal->borders[DOWN] = &but->rect.ymin;
- butal->borders[TOP] = &but->rect.ymax;
- copy_v4_fl(butal->dists, FLT_MAX);
- butal++;
- }
- }
-
- /* This will give us ButAlign items regrouped by align group, vertical and horizontal location.
- * Note that, given how buttons are defined in UI code,
- * butal_array shall already be "nearly sorted"... */
- qsort(butal_array, (size_t)num_buttons, sizeof(*butal_array), ui_block_align_butal_cmp);
-
- /* Third loop: for each pair of buttons in the same align group,
- * we compute their potential proximity. Note that each pair is checked only once, and that we
- * break early in case we know all remaining pairs will always be too far away. */
- for (i = 0, butal = butal_array; i < num_buttons; i++, butal++) {
- const short alignnr = butal->but->alignnr;
-
- for (j = i + 1, butal_other = &butal_array[i + 1]; j < num_buttons; j++, butal_other++) {
- const float max_delta = MAX_DELTA;
-
- /* Since they are sorted, buttons after current butal can only be of same or higher
- * group, and once they are not of same group, we know we can break this sub-loop and
- * start checking with next butal. */
- if (butal_other->but->alignnr != alignnr) {
- break;
- }
-
- /* Since they are sorted vertically first, buttons after current butal can only be at
- * same or lower height, and once they are lower than a given threshold, we know we can
- * break this sub-loop and start checking with next butal. */
- if ((*butal->borders[DOWN] - *butal_other->borders[TOP]) > max_delta) {
- break;
- }
-
- block_align_proximity_compute(butal, butal_other);
- }
- }
-
- /* Fourth loop: we have all our 'aligned' buttons as a 'map' in butal_array. We need to:
- * - update their relevant coordinates to stitch them.
- * - assign them valid flags.
- */
- for (i = 0; i < num_buttons; i++) {
- butal = &butal_array[i];
-
- for (side = 0; side < TOTSIDES; side++) {
- butal_other = butal->neighbors[side];
-
- if (butal_other) {
- const int side_opp = OPPOSITE(side);
- const int side_s1 = SIDE1(side);
- const int side_s2 = SIDE2(side);
-
- const int align = sides_to_ui_but_align_flags[side];
- const int align_opp = sides_to_ui_but_align_flags[side_opp];
-
- float co;
-
- butal->but->drawflag |= align;
- butal_other->but->drawflag |= align_opp;
- if (butal->dists[side]) {
- float *delta = &butal->dists[side];
-
- if (*butal->borders[side] < *butal_other->borders[side_opp]) {
- *delta *= 0.5f;
- }
- else {
- *delta *= -0.5f;
- }
- co = (*butal->borders[side] += *delta);
-
- if (butal_other->dists[side_opp]) {
- BLI_assert(butal_other->dists[side_opp] * 0.5f == fabsf(*delta));
- *butal_other->borders[side_opp] = co;
- butal_other->dists[side_opp] = 0.0f;
- }
- *delta = 0.0f;
- }
- else {
- co = *butal->borders[side];
- }
-
- block_align_stitch_neighbors(butal, side, side_opp, side_s1, side_s2, align, align_opp, co);
- block_align_stitch_neighbors(butal, side, side_opp, side_s2, side_s1, align, align_opp, co);
- }
- }
- }
+ uiBut *but;
+ int num_buttons = 0;
+
+ const int sides_to_ui_but_align_flags[4] = SIDE_TO_UI_BUT_ALIGN;
+
+ ButAlign *butal_array;
+ ButAlign *butal, *butal_other;
+ int side;
+ int i, j;
+
+ /* First loop: we count number of buttons belonging to an align group, and clear their align flag.
+ * Tabs get some special treatment here, they get aligned to region border. */
+ for (but = block->buttons.first; but; but = but->next) {
+ /* special case: tabs need to be aligned to a region border, drawflag tells which one */
+ if (but->type == UI_BTYPE_TAB) {
+ ui_block_align_but_to_region(but, region);
+ }
+ else {
+ /* Clear old align flags. */
+ but->drawflag &= ~UI_BUT_ALIGN_ALL;
+ }
+
+ if (but->alignnr != 0) {
+ num_buttons++;
+ }
+ }
+
+ if (num_buttons < 2) {
+ /* No need to go further if we have nothing to align... */
+ return;
+ }
+
+ butal_array = alloca(sizeof(*butal_array) * (size_t)num_buttons);
+ memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons);
+
+ /* Second loop: we initialize our ButAlign data for each button. */
+ for (but = block->buttons.first, butal = butal_array; but; but = but->next) {
+ if (but->alignnr != 0) {
+ butal->but = but;
+ butal->borders[LEFT] = &but->rect.xmin;
+ butal->borders[RIGHT] = &but->rect.xmax;
+ butal->borders[DOWN] = &but->rect.ymin;
+ butal->borders[TOP] = &but->rect.ymax;
+ copy_v4_fl(butal->dists, FLT_MAX);
+ butal++;
+ }
+ }
+
+ /* This will give us ButAlign items regrouped by align group, vertical and horizontal location.
+ * Note that, given how buttons are defined in UI code,
+ * butal_array shall already be "nearly sorted"... */
+ qsort(butal_array, (size_t)num_buttons, sizeof(*butal_array), ui_block_align_butal_cmp);
+
+ /* Third loop: for each pair of buttons in the same align group,
+ * we compute their potential proximity. Note that each pair is checked only once, and that we
+ * break early in case we know all remaining pairs will always be too far away. */
+ for (i = 0, butal = butal_array; i < num_buttons; i++, butal++) {
+ const short alignnr = butal->but->alignnr;
+
+ for (j = i + 1, butal_other = &butal_array[i + 1]; j < num_buttons; j++, butal_other++) {
+ const float max_delta = MAX_DELTA;
+
+ /* Since they are sorted, buttons after current butal can only be of same or higher
+ * group, and once they are not of same group, we know we can break this sub-loop and
+ * start checking with next butal. */
+ if (butal_other->but->alignnr != alignnr) {
+ break;
+ }
+
+ /* Since they are sorted vertically first, buttons after current butal can only be at
+ * same or lower height, and once they are lower than a given threshold, we know we can
+ * break this sub-loop and start checking with next butal. */
+ if ((*butal->borders[DOWN] - *butal_other->borders[TOP]) > max_delta) {
+ break;
+ }
+
+ block_align_proximity_compute(butal, butal_other);
+ }
+ }
+
+ /* Fourth loop: we have all our 'aligned' buttons as a 'map' in butal_array. We need to:
+ * - update their relevant coordinates to stitch them.
+ * - assign them valid flags.
+ */
+ for (i = 0; i < num_buttons; i++) {
+ butal = &butal_array[i];
+
+ for (side = 0; side < TOTSIDES; side++) {
+ butal_other = butal->neighbors[side];
+
+ if (butal_other) {
+ const int side_opp = OPPOSITE(side);
+ const int side_s1 = SIDE1(side);
+ const int side_s2 = SIDE2(side);
+
+ const int align = sides_to_ui_but_align_flags[side];
+ const int align_opp = sides_to_ui_but_align_flags[side_opp];
+
+ float co;
+
+ butal->but->drawflag |= align;
+ butal_other->but->drawflag |= align_opp;
+ if (butal->dists[side]) {
+ float *delta = &butal->dists[side];
+
+ if (*butal->borders[side] < *butal_other->borders[side_opp]) {
+ *delta *= 0.5f;
+ }
+ else {
+ *delta *= -0.5f;
+ }
+ co = (*butal->borders[side] += *delta);
+
+ if (butal_other->dists[side_opp]) {
+ BLI_assert(butal_other->dists[side_opp] * 0.5f == fabsf(*delta));
+ *butal_other->borders[side_opp] = co;
+ butal_other->dists[side_opp] = 0.0f;
+ }
+ *delta = 0.0f;
+ }
+ else {
+ co = *butal->borders[side];
+ }
+
+ block_align_stitch_neighbors(
+ butal, side, side_opp, side_s1, side_s2, align, align_opp, co);
+ block_align_stitch_neighbors(
+ butal, side, side_opp, side_s2, side_s1, align, align_opp, co);
+ }
+ }
+ }
}
-#undef SIDE_TO_UI_BUT_ALIGN
-#undef SIDE1
-#undef OPPOSITE
-#undef SIDE2
-#undef IS_COLUMN
-#undef STITCH
-#undef MAX_DELTA
+# undef SIDE_TO_UI_BUT_ALIGN
+# undef SIDE1
+# undef OPPOSITE
+# undef SIDE2
+# undef IS_COLUMN
+# undef STITCH
+# undef MAX_DELTA
#else
bool ui_but_can_align(uiBut *but)
{
- return !ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N,
- UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER);
+ return !ELEM(but->type,
+ UI_BTYPE_LABEL,
+ UI_BTYPE_CHECKBOX,
+ UI_BTYPE_CHECKBOX_N,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_SEPR_SPACER);
}
static bool buts_are_horiz(uiBut *but1, uiBut *but2)
{
- float dx, dy;
+ float dx, dy;
- /* simple case which can fail if buttons shift apart
- * with proportional layouts, see: [#38602] */
- if ((but1->rect.ymin == but2->rect.ymin) &&
- (but1->rect.xmin != but2->rect.xmin))
- {
- return true;
- }
+ /* simple case which can fail if buttons shift apart
+ * with proportional layouts, see: [#38602] */
+ if ((but1->rect.ymin == but2->rect.ymin) && (but1->rect.xmin != but2->rect.xmin)) {
+ return true;
+ }
- dx = fabsf(but1->rect.xmax - but2->rect.xmin);
- dy = fabsf(but1->rect.ymin - but2->rect.ymax);
+ dx = fabsf(but1->rect.xmax - but2->rect.xmin);
+ dy = fabsf(but1->rect.ymin - but2->rect.ymax);
- return (dx <= dy);
+ return (dx <= dy);
}
static void ui_block_align_calc_but(uiBut *first, short nr)
{
- uiBut *prev, *but = NULL, *next;
- int flag = 0, cols = 0, rows = 0;
-
- /* auto align */
-
- for (but = first; but && but->alignnr == nr; but = but->next) {
- if (but->next && but->next->alignnr == nr) {
- if (buts_are_horiz(but, but->next)) {
- cols++;
- }
- else {
- rows++;
- }
- }
- }
-
- /* rows == 0: 1 row, cols == 0: 1 column */
-
- /* note; how it uses 'flag' in loop below (either set it, or OR it) is confusing */
- for (but = first, prev = NULL; but && but->alignnr == nr; prev = but, but = but->next) {
- next = but->next;
- if (next && next->alignnr != nr) {
- next = NULL;
- }
-
- /* clear old flag */
- but->drawflag &= ~UI_BUT_ALIGN;
-
- if (flag == 0) { /* first case */
- if (next) {
- if (buts_are_horiz(but, next)) {
- if (rows == 0) {
- flag = UI_BUT_ALIGN_RIGHT;
- }
- else {
- flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT;
- }
- }
- else {
- flag = UI_BUT_ALIGN_DOWN;
- }
- }
- }
- else if (next == NULL) { /* last case */
- if (prev) {
- if (buts_are_horiz(prev, but)) {
- if (rows == 0) {
- flag = UI_BUT_ALIGN_LEFT;
- }
- else {
- flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT;
- }
- }
- else {
- flag = UI_BUT_ALIGN_TOP;
- }
- }
- }
- else if (buts_are_horiz(but, next)) {
- /* check if this is already second row */
- if (prev && buts_are_horiz(prev, but) == 0) {
- flag &= ~UI_BUT_ALIGN_LEFT;
- flag |= UI_BUT_ALIGN_TOP;
- /* exception case: bottom row */
- if (rows > 0) {
- uiBut *bt = but;
- while (bt && bt->alignnr == nr) {
- if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) {
- break;
- }
- bt = bt->next;
- }
- if (bt == NULL || bt->alignnr != nr) {
- flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT;
- }
- }
- }
- else {
- flag |= UI_BUT_ALIGN_LEFT;
- }
- }
- else {
- if (cols == 0) {
- flag |= UI_BUT_ALIGN_TOP;
- }
- else { /* next button switches to new row */
-
- if (prev && buts_are_horiz(prev, but)) {
- flag |= UI_BUT_ALIGN_LEFT;
- }
- else {
- flag &= ~UI_BUT_ALIGN_LEFT;
- flag |= UI_BUT_ALIGN_TOP;
- }
-
- if ((flag & UI_BUT_ALIGN_TOP) == 0) { /* still top row */
- if (prev) {
- if (next && buts_are_horiz(but, next)) {
- flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT;
- }
- else {
- /* last button in top row */
- flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT;
- }
- }
- else {
- flag |= UI_BUT_ALIGN_DOWN;
- }
- }
- else {
- flag |= UI_BUT_ALIGN_TOP;
- }
- }
- }
-
- but->drawflag |= flag;
-
- /* merge coordinates */
- if (prev) {
- /* simple cases */
- if (rows == 0) {
- but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
- prev->rect.xmax = but->rect.xmin;
- }
- else if (cols == 0) {
- but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
- prev->rect.ymin = but->rect.ymax;
- }
- else {
- if (buts_are_horiz(prev, but)) {
- but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
- prev->rect.xmax = but->rect.xmin;
- /* copy height too */
- but->rect.ymax = prev->rect.ymax;
- }
- else if (prev->prev && buts_are_horiz(prev->prev, prev) == 0) {
- /* the previous button is a single one in its row */
- but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
- prev->rect.ymin = but->rect.ymax;
-
- but->rect.xmin = prev->rect.xmin;
- if (next && buts_are_horiz(but, next) == 0) {
- but->rect.xmax = prev->rect.xmax;
- }
- }
- else {
- /* the previous button is not a single one in its row */
- but->rect.ymax = prev->rect.ymin;
- }
- }
- }
- }
+ uiBut *prev, *but = NULL, *next;
+ int flag = 0, cols = 0, rows = 0;
+
+ /* auto align */
+
+ for (but = first; but && but->alignnr == nr; but = but->next) {
+ if (but->next && but->next->alignnr == nr) {
+ if (buts_are_horiz(but, but->next)) {
+ cols++;
+ }
+ else {
+ rows++;
+ }
+ }
+ }
+
+ /* rows == 0: 1 row, cols == 0: 1 column */
+
+ /* note; how it uses 'flag' in loop below (either set it, or OR it) is confusing */
+ for (but = first, prev = NULL; but && but->alignnr == nr; prev = but, but = but->next) {
+ next = but->next;
+ if (next && next->alignnr != nr) {
+ next = NULL;
+ }
+
+ /* clear old flag */
+ but->drawflag &= ~UI_BUT_ALIGN;
+
+ if (flag == 0) { /* first case */
+ if (next) {
+ if (buts_are_horiz(but, next)) {
+ if (rows == 0) {
+ flag = UI_BUT_ALIGN_RIGHT;
+ }
+ else {
+ flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT;
+ }
+ }
+ else {
+ flag = UI_BUT_ALIGN_DOWN;
+ }
+ }
+ }
+ else if (next == NULL) { /* last case */
+ if (prev) {
+ if (buts_are_horiz(prev, but)) {
+ if (rows == 0) {
+ flag = UI_BUT_ALIGN_LEFT;
+ }
+ else {
+ flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT;
+ }
+ }
+ else {
+ flag = UI_BUT_ALIGN_TOP;
+ }
+ }
+ }
+ else if (buts_are_horiz(but, next)) {
+ /* check if this is already second row */
+ if (prev && buts_are_horiz(prev, but) == 0) {
+ flag &= ~UI_BUT_ALIGN_LEFT;
+ flag |= UI_BUT_ALIGN_TOP;
+ /* exception case: bottom row */
+ if (rows > 0) {
+ uiBut *bt = but;
+ while (bt && bt->alignnr == nr) {
+ if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) {
+ break;
+ }
+ bt = bt->next;
+ }
+ if (bt == NULL || bt->alignnr != nr) {
+ flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT;
+ }
+ }
+ }
+ else {
+ flag |= UI_BUT_ALIGN_LEFT;
+ }
+ }
+ else {
+ if (cols == 0) {
+ flag |= UI_BUT_ALIGN_TOP;
+ }
+ else { /* next button switches to new row */
+
+ if (prev && buts_are_horiz(prev, but)) {
+ flag |= UI_BUT_ALIGN_LEFT;
+ }
+ else {
+ flag &= ~UI_BUT_ALIGN_LEFT;
+ flag |= UI_BUT_ALIGN_TOP;
+ }
+
+ if ((flag & UI_BUT_ALIGN_TOP) == 0) { /* still top row */
+ if (prev) {
+ if (next && buts_are_horiz(but, next)) {
+ flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT;
+ }
+ else {
+ /* last button in top row */
+ flag = UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT;
+ }
+ }
+ else {
+ flag |= UI_BUT_ALIGN_DOWN;
+ }
+ }
+ else {
+ flag |= UI_BUT_ALIGN_TOP;
+ }
+ }
+ }
+
+ but->drawflag |= flag;
+
+ /* merge coordinates */
+ if (prev) {
+ /* simple cases */
+ if (rows == 0) {
+ but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
+ prev->rect.xmax = but->rect.xmin;
+ }
+ else if (cols == 0) {
+ but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
+ prev->rect.ymin = but->rect.ymax;
+ }
+ else {
+ if (buts_are_horiz(prev, but)) {
+ but->rect.xmin = (prev->rect.xmax + but->rect.xmin) / 2.0f;
+ prev->rect.xmax = but->rect.xmin;
+ /* copy height too */
+ but->rect.ymax = prev->rect.ymax;
+ }
+ else if (prev->prev && buts_are_horiz(prev->prev, prev) == 0) {
+ /* the previous button is a single one in its row */
+ but->rect.ymax = (prev->rect.ymin + but->rect.ymax) / 2.0f;
+ prev->rect.ymin = but->rect.ymax;
+
+ but->rect.xmin = prev->rect.xmin;
+ if (next && buts_are_horiz(but, next) == 0) {
+ but->rect.xmax = prev->rect.xmax;
+ }
+ }
+ else {
+ /* the previous button is not a single one in its row */
+ but->rect.ymax = prev->rect.ymin;
+ }
+ }
+ }
+ }
}
void ui_block_align_calc(uiBlock *block)
{
- uiBut *but;
- short nr;
-
- /* align buttons with same align nr */
- for (but = block->buttons.first; but; ) {
- if (but->alignnr) {
- nr = but->alignnr;
- ui_block_align_calc_but(but, nr);
-
- /* skip with same number */
- for (; but && but->alignnr == nr; but = but->next) {
- /* pass */
- }
-
- if (!but) {
- break;
- }
- }
- else {
- but = but->next;
- }
- }
+ uiBut *but;
+ short nr;
+
+ /* align buttons with same align nr */
+ for (but = block->buttons.first; but;) {
+ if (but->alignnr) {
+ nr = but->alignnr;
+ ui_block_align_calc_but(but, nr);
+
+ /* skip with same number */
+ for (; but && but->alignnr == nr; but = but->next) {
+ /* pass */
+ }
+
+ if (!but) {
+ break;
+ }
+ }
+ else {
+ but = but->next;
+ }
+ }
}
#endif
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index a4476b4d2f1..b9de504f3b2 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -52,83 +52,85 @@
#include "interface_intern.h"
-static FCurve *ui_but_get_fcurve(uiBut *but, AnimData **adt, bAction **action, bool *r_driven, bool *r_special)
+static FCurve *ui_but_get_fcurve(
+ uiBut *but, AnimData **adt, bAction **action, bool *r_driven, bool *r_special)
{
- /* for entire array buttons we check the first component, it's not perfect
- * but works well enough in typical cases */
- int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
+ /* for entire array buttons we check the first component, it's not perfect
+ * but works well enough in typical cases */
+ int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
- return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special);
+ return rna_get_fcurve_context_ui(
+ but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special);
}
void ui_but_anim_flag(uiBut *but, float cfra)
{
- AnimData *adt;
- bAction *act;
- FCurve *fcu;
- bool driven;
- bool special;
-
- but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN);
- but->drawflag &= ~UI_BUT_ANIMATED_CHANGED;
-
- /* NOTE: "special" is reserved for special F-Curves stored on the animation data
- * itself (which are used to animate properties of the animation data).
- * We count those as "animated" too for now
- */
- fcu = ui_but_get_fcurve(but, &adt, &act, &driven, &special);
-
- if (fcu) {
- if (!driven) {
- but->flag |= UI_BUT_ANIMATED;
-
- /* T41525 - When the active action is a NLA strip being edited,
- * we need to correct the frame number to "look inside" the
- * remapped action
- */
- if (adt) {
- cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
- }
-
- if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
- but->flag |= UI_BUT_ANIMATED_KEY;
- }
-
- /* XXX: this feature is totally broken and useless with NLA */
- if (adt == NULL || adt->nla_tracks.first == NULL) {
- if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, cfra)) {
- but->drawflag |= UI_BUT_ANIMATED_CHANGED;
- }
- }
- }
- else {
- but->flag |= UI_BUT_DRIVEN;
- }
- }
+ AnimData *adt;
+ bAction *act;
+ FCurve *fcu;
+ bool driven;
+ bool special;
+
+ but->flag &= ~(UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN);
+ but->drawflag &= ~UI_BUT_ANIMATED_CHANGED;
+
+ /* NOTE: "special" is reserved for special F-Curves stored on the animation data
+ * itself (which are used to animate properties of the animation data).
+ * We count those as "animated" too for now
+ */
+ fcu = ui_but_get_fcurve(but, &adt, &act, &driven, &special);
+
+ if (fcu) {
+ if (!driven) {
+ but->flag |= UI_BUT_ANIMATED;
+
+ /* T41525 - When the active action is a NLA strip being edited,
+ * we need to correct the frame number to "look inside" the
+ * remapped action
+ */
+ if (adt) {
+ cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
+ }
+
+ if (fcurve_frame_has_keyframe(fcu, cfra, 0)) {
+ but->flag |= UI_BUT_ANIMATED_KEY;
+ }
+
+ /* XXX: this feature is totally broken and useless with NLA */
+ if (adt == NULL || adt->nla_tracks.first == NULL) {
+ if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, cfra)) {
+ but->drawflag |= UI_BUT_ANIMATED_CHANGED;
+ }
+ }
+ }
+ else {
+ but->flag |= UI_BUT_DRIVEN;
+ }
+ }
}
void ui_but_anim_decorate_update_from_flag(uiBut *but)
{
- BLI_assert(UI_but_is_decorator(but) && but->prev);
- int flag = but->prev->flag;
- if (flag & UI_BUT_DRIVEN) {
- but->icon = ICON_DECORATE_DRIVER;
- }
- else if (flag & UI_BUT_ANIMATED_KEY) {
- but->icon = ICON_DECORATE_KEYFRAME;
- }
- else if (flag & UI_BUT_ANIMATED) {
- but->icon = ICON_DECORATE_ANIMATE;
- }
- else if (flag & UI_BUT_OVERRIDEN) {
- but->icon = ICON_DECORATE_OVERRIDE;
- }
- else {
- but->icon = ICON_DECORATE;
- }
-
- const int flag_copy = (UI_BUT_DISABLED | UI_BUT_INACTIVE);
- but->flag = (but->flag & ~flag_copy) | (flag & flag_copy);
+ BLI_assert(UI_but_is_decorator(but) && but->prev);
+ int flag = but->prev->flag;
+ if (flag & UI_BUT_DRIVEN) {
+ but->icon = ICON_DECORATE_DRIVER;
+ }
+ else if (flag & UI_BUT_ANIMATED_KEY) {
+ but->icon = ICON_DECORATE_KEYFRAME;
+ }
+ else if (flag & UI_BUT_ANIMATED) {
+ but->icon = ICON_DECORATE_ANIMATE;
+ }
+ else if (flag & UI_BUT_OVERRIDEN) {
+ but->icon = ICON_DECORATE_OVERRIDE;
+ }
+ else {
+ but->icon = ICON_DECORATE;
+ }
+
+ const int flag_copy = (UI_BUT_DISABLED | UI_BUT_INACTIVE);
+ but->flag = (but->flag & ~flag_copy) | (flag & flag_copy);
}
/**
@@ -137,233 +139,251 @@ void ui_but_anim_decorate_update_from_flag(uiBut *but)
*/
bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen)
{
- FCurve *fcu;
- ChannelDriver *driver;
- bool driven, special;
+ FCurve *fcu;
+ ChannelDriver *driver;
+ bool driven, special;
- fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
+ fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
- if (fcu && driven) {
- driver = fcu->driver;
+ if (fcu && driven) {
+ driver = fcu->driver;
- if (driver && driver->type == DRIVER_TYPE_PYTHON) {
- if (str) {
- BLI_strncpy(str, driver->expression, maxlen);
- }
- return true;
- }
- }
+ if (driver && driver->type == DRIVER_TYPE_PYTHON) {
+ if (str) {
+ BLI_strncpy(str, driver->expression, maxlen);
+ }
+ return true;
+ }
+ }
- return false;
+ return false;
}
bool ui_but_anim_expression_set(uiBut *but, const char *str)
{
- FCurve *fcu;
- ChannelDriver *driver;
- bool driven, special;
+ FCurve *fcu;
+ ChannelDriver *driver;
+ bool driven, special;
- fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
+ fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special);
- if (fcu && driven) {
- driver = fcu->driver;
+ if (fcu && driven) {
+ driver = fcu->driver;
- if (driver && (driver->type == DRIVER_TYPE_PYTHON)) {
- BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
+ if (driver && (driver->type == DRIVER_TYPE_PYTHON)) {
+ BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
- /* tag driver as needing to be recompiled */
- BKE_driver_invalidate_expression(driver, true, false);
+ /* tag driver as needing to be recompiled */
+ BKE_driver_invalidate_expression(driver, true, false);
- /* clear invalid flags which may prevent this from working */
- driver->flag &= ~DRIVER_FLAG_INVALID;
- fcu->flag &= ~FCURVE_DISABLED;
+ /* clear invalid flags which may prevent this from working */
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+ fcu->flag &= ~FCURVE_DISABLED;
- /* this notifier should update the Graph Editor and trigger depsgraph refresh? */
- WM_event_add_notifier(but->block->evil_C, NC_ANIMATION | ND_KEYFRAME, NULL);
+ /* this notifier should update the Graph Editor and trigger depsgraph refresh? */
+ WM_event_add_notifier(but->block->evil_C, NC_ANIMATION | ND_KEYFRAME, NULL);
- return true;
- }
- }
+ return true;
+ }
+ }
- return false;
+ return false;
}
/* create new expression for button (i.e. a "scripted driver"), if it can be created... */
bool ui_but_anim_expression_create(uiBut *but, const char *str)
{
- bContext *C = but->block->evil_C;
- ID *id;
- FCurve *fcu;
- char *path;
- bool ok = false;
-
- /* button must have RNA-pointer to a numeric-capable property */
- if (ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
- if (G.debug & G_DEBUG) {
- printf("ERROR: create expression failed - button has no RNA info attached\n");
- }
- return false;
- }
-
- if (RNA_property_array_check(but->rnaprop) != 0) {
- if (but->rnaindex == -1) {
- if (G.debug & G_DEBUG) {
- printf("ERROR: create expression failed - can't create expression for entire array\n");
- }
- return false;
- }
- }
-
- /* make sure we have animdata for this */
- /* FIXME: until materials can be handled by depsgraph,
- * don't allow drivers to be created for them */
- id = (ID *)but->rnapoin.id.data;
- if ((id == NULL) || (GS(id->name) == ID_MA) || (GS(id->name) == ID_TE)) {
- if (G.debug & G_DEBUG) {
- printf("ERROR: create expression failed - invalid data-block for adding drivers (%p)\n", id);
- }
- return false;
- }
-
- /* get path */
- path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
- if (path == NULL) {
- return false;
- }
-
- /* create driver */
- fcu = verify_driver_fcurve(id, path, but->rnaindex, 1);
- if (fcu) {
- ChannelDriver *driver = fcu->driver;
-
- if (driver) {
- /* set type of driver */
- driver->type = DRIVER_TYPE_PYTHON;
-
- /* set the expression */
- /* TODO: need some way of identifying variables used */
- BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
-
- /* updates */
- BKE_driver_invalidate_expression(driver, true, false);
- DEG_relations_tag_update(CTX_data_main(C));
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, NULL);
- ok = true;
- }
- }
-
- MEM_freeN(path);
-
- return ok;
+ bContext *C = but->block->evil_C;
+ ID *id;
+ FCurve *fcu;
+ char *path;
+ bool ok = false;
+
+ /* button must have RNA-pointer to a numeric-capable property */
+ if (ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
+ if (G.debug & G_DEBUG) {
+ printf("ERROR: create expression failed - button has no RNA info attached\n");
+ }
+ return false;
+ }
+
+ if (RNA_property_array_check(but->rnaprop) != 0) {
+ if (but->rnaindex == -1) {
+ if (G.debug & G_DEBUG) {
+ printf("ERROR: create expression failed - can't create expression for entire array\n");
+ }
+ return false;
+ }
+ }
+
+ /* make sure we have animdata for this */
+ /* FIXME: until materials can be handled by depsgraph,
+ * don't allow drivers to be created for them */
+ id = (ID *)but->rnapoin.id.data;
+ if ((id == NULL) || (GS(id->name) == ID_MA) || (GS(id->name) == ID_TE)) {
+ if (G.debug & G_DEBUG) {
+ printf("ERROR: create expression failed - invalid data-block for adding drivers (%p)\n", id);
+ }
+ return false;
+ }
+
+ /* get path */
+ path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
+ if (path == NULL) {
+ return false;
+ }
+
+ /* create driver */
+ fcu = verify_driver_fcurve(id, path, but->rnaindex, 1);
+ if (fcu) {
+ ChannelDriver *driver = fcu->driver;
+
+ if (driver) {
+ /* set type of driver */
+ driver->type = DRIVER_TYPE_PYTHON;
+
+ /* set the expression */
+ /* TODO: need some way of identifying variables used */
+ BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression));
+
+ /* updates */
+ BKE_driver_invalidate_expression(driver, true, false);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, NULL);
+ ok = true;
+ }
+ }
+
+ MEM_freeN(path);
+
+ return ok;
}
void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra)
{
- Main *bmain = CTX_data_main(C);
- ID *id;
- bAction *action;
- FCurve *fcu;
- bool driven;
- bool special;
-
- fcu = ui_but_get_fcurve(but, NULL, &action, &driven, &special);
-
- if (fcu == NULL) {
- return;
- }
-
- if (special) {
- /* NLA Strip property */
- if (IS_AUTOKEY_ON(scene)) {
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ReportList *reports = CTX_wm_reports(C);
- ToolSettings *ts = scene->toolsettings;
-
- insert_keyframe_direct(depsgraph, reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, NULL, 0);
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- }
- }
- else if (driven) {
- /* Driver - Try to insert keyframe using the driver's input as the frame,
- * making it easier to set up corrective drivers
- */
- if (IS_AUTOKEY_ON(scene)) {
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ReportList *reports = CTX_wm_reports(C);
- ToolSettings *ts = scene->toolsettings;
-
- insert_keyframe_direct(depsgraph, reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- }
- }
- else {
- id = but->rnapoin.id.data;
-
- /* TODO: this should probably respect the keyingset only option for anim */
- if (autokeyframe_cfra_can_key(scene, id)) {
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ReportList *reports = CTX_wm_reports(C);
- ToolSettings *ts = scene->toolsettings;
- short flag = ANIM_get_keyframing_flags(scene, 1);
-
- fcu->flag &= ~FCURVE_SELECTED;
-
- /* Note: We use but->rnaindex instead of fcu->array_index,
- * because a button may control all items of an array at once.
- * E.g., color wheels (see T42567). */
- BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
- insert_keyframe(bmain, depsgraph, reports, id, action,
- ((fcu->grp) ? (fcu->grp->name) : (NULL)),
- fcu->rna_path, but->rnaindex, cfra, ts->keyframe_type, NULL, flag);
-
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- }
- }
+ Main *bmain = CTX_data_main(C);
+ ID *id;
+ bAction *action;
+ FCurve *fcu;
+ bool driven;
+ bool special;
+
+ fcu = ui_but_get_fcurve(but, NULL, &action, &driven, &special);
+
+ if (fcu == NULL) {
+ return;
+ }
+
+ if (special) {
+ /* NLA Strip property */
+ if (IS_AUTOKEY_ON(scene)) {
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ReportList *reports = CTX_wm_reports(C);
+ ToolSettings *ts = scene->toolsettings;
+
+ insert_keyframe_direct(
+ depsgraph, reports, but->rnapoin, but->rnaprop, fcu, cfra, ts->keyframe_type, NULL, 0);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ }
+ }
+ else if (driven) {
+ /* Driver - Try to insert keyframe using the driver's input as the frame,
+ * making it easier to set up corrective drivers
+ */
+ if (IS_AUTOKEY_ON(scene)) {
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ReportList *reports = CTX_wm_reports(C);
+ ToolSettings *ts = scene->toolsettings;
+
+ insert_keyframe_direct(depsgraph,
+ reports,
+ but->rnapoin,
+ but->rnaprop,
+ fcu,
+ cfra,
+ ts->keyframe_type,
+ NULL,
+ INSERTKEY_DRIVER);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ }
+ }
+ else {
+ id = but->rnapoin.id.data;
+
+ /* TODO: this should probably respect the keyingset only option for anim */
+ if (autokeyframe_cfra_can_key(scene, id)) {
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ReportList *reports = CTX_wm_reports(C);
+ ToolSettings *ts = scene->toolsettings;
+ short flag = ANIM_get_keyframing_flags(scene, 1);
+
+ fcu->flag &= ~FCURVE_SELECTED;
+
+ /* Note: We use but->rnaindex instead of fcu->array_index,
+ * because a button may control all items of an array at once.
+ * E.g., color wheels (see T42567). */
+ BLI_assert((fcu->array_index == but->rnaindex) || (but->rnaindex == -1));
+ insert_keyframe(bmain,
+ depsgraph,
+ reports,
+ id,
+ action,
+ ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path,
+ but->rnaindex,
+ cfra,
+ ts->keyframe_type,
+ NULL,
+ flag);
+
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ }
+ }
}
void ui_but_anim_copy_driver(bContext *C)
{
- /* this operator calls UI_context_active_but_prop_get */
- WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
+ /* this operator calls UI_context_active_but_prop_get */
+ WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_paste_driver(bContext *C)
{
- /* this operator calls UI_context_active_but_prop_get */
- WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
+ /* this operator calls UI_context_active_but_prop_get */
+ WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL);
}
void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy))
{
- wmWindowManager *wm = CTX_wm_manager(C);
- uiBut *but = arg_but;
- but = but->prev;
-
- /* FIXME(campbell), swapping active pointer is weak. */
- SWAP(struct uiHandleButtonData *, but->active, but->next->active);
- wm->op_undo_depth++;
-
- if (but->flag & UI_BUT_DRIVEN) {
- /* pass */
- /* TODO: report? */
- }
- else if (but->flag & UI_BUT_ANIMATED_KEY) {
- PointerRNA props_ptr;
- wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_delete_button", false);
- WM_operator_properties_create_ptr(&props_ptr, ot);
- RNA_boolean_set(&props_ptr, "all", but->rnaindex == -1);
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
- WM_operator_properties_free(&props_ptr);
- }
- else {
- PointerRNA props_ptr;
- wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_insert_button", false);
- WM_operator_properties_create_ptr(&props_ptr, ot);
- RNA_boolean_set(&props_ptr, "all", but->rnaindex == -1);
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
- WM_operator_properties_free(&props_ptr);
- }
-
- SWAP(struct uiHandleButtonData *, but->active, but->next->active);
- wm->op_undo_depth--;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ uiBut *but = arg_but;
+ but = but->prev;
+
+ /* FIXME(campbell), swapping active pointer is weak. */
+ SWAP(struct uiHandleButtonData *, but->active, but->next->active);
+ wm->op_undo_depth++;
+
+ if (but->flag & UI_BUT_DRIVEN) {
+ /* pass */
+ /* TODO: report? */
+ }
+ else if (but->flag & UI_BUT_ANIMATED_KEY) {
+ PointerRNA props_ptr;
+ wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_delete_button", false);
+ WM_operator_properties_create_ptr(&props_ptr, ot);
+ RNA_boolean_set(&props_ptr, "all", but->rnaindex == -1);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
+ WM_operator_properties_free(&props_ptr);
+ }
+ else {
+ PointerRNA props_ptr;
+ wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_insert_button", false);
+ WM_operator_properties_create_ptr(&props_ptr, ot);
+ RNA_boolean_set(&props_ptr, "all", but->rnaindex == -1);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
+ WM_operator_properties_free(&props_ptr);
+ }
+
+ SWAP(struct uiHandleButtonData *, but->active, but->next->active);
+ wm->op_undo_depth--;
}
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 4ca92fbb386..afa1b5c87e1 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -60,59 +60,65 @@
static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
{
- uiBut *but = (uiBut *)arg1;
-
- if (but->optype) {
- char shortcut_str[128];
-
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
- /* complex code to change name of button */
- if (WM_key_event_operator_string(
- C, but->optype->idname, but->opcontext, prop, true,
- shortcut_str, sizeof(shortcut_str)))
- {
- ui_but_add_shortcut(but, shortcut_str, true);
- }
- else {
- /* simply strip the shortcut */
- ui_but_add_shortcut(but, NULL, true);
- }
- }
+ uiBut *but = (uiBut *)arg1;
+
+ if (but->optype) {
+ char shortcut_str[128];
+
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+
+ /* complex code to change name of button */
+ if (WM_key_event_operator_string(C,
+ but->optype->idname,
+ but->opcontext,
+ prop,
+ true,
+ shortcut_str,
+ sizeof(shortcut_str))) {
+ ui_but_add_shortcut(but, shortcut_str, true);
+ }
+ else {
+ /* simply strip the shortcut */
+ ui_but_add_shortcut(but, NULL, true);
+ }
+ }
}
static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- uiBlock *block;
- uiBut *but = (uiBut *)arg;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
- PointerRNA ptr;
- uiLayout *layout;
- uiStyle *style = UI_style_get_dpi();
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
- kmi = WM_key_event_operator(
- C, but->optype->idname, but->opcontext, prop,
- EVT_TYPE_MASK_HOTKEY_INCLUDE, EVT_TYPE_MASK_HOTKEY_EXCLUDE,
- &km);
- BLI_assert(kmi != NULL);
-
- RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
-
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
- UI_block_func_handle_set(block, but_shortcut_name_func, but);
- UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
- UI_block_direction_set(block, UI_DIR_CENTER_Y);
-
- layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
-
- uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
-
- UI_block_bounds_set_popup(block, 6, (const int[2]){-50, 26});
-
- return block;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ uiBlock *block;
+ uiBut *but = (uiBut *)arg;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ PointerRNA ptr;
+ uiLayout *layout;
+ uiStyle *style = UI_style_get_dpi();
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+
+ kmi = WM_key_event_operator(C,
+ but->optype->idname,
+ but->opcontext,
+ prop,
+ EVT_TYPE_MASK_HOTKEY_INCLUDE,
+ EVT_TYPE_MASK_HOTKEY_EXCLUDE,
+ &km);
+ BLI_assert(kmi != NULL);
+
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
+
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_func_handle_set(block, but_shortcut_name_func, but);
+ UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
+ UI_block_direction_set(block, UI_DIR_CENTER_Y);
+
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
+
+ uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
+
+ UI_block_bounds_set_popup(block, 6, (const int[2]){-50, 26});
+
+ return block;
}
#ifdef USE_KEYMAP_ADD_HACK
@@ -121,743 +127,944 @@ static int g_kmi_id_hack;
static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- uiBlock *block;
- uiBut *but = (uiBut *)arg;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
- PointerRNA ptr;
- uiLayout *layout;
- uiStyle *style = UI_style_get_dpi();
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
- int kmi_id;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ uiBlock *block;
+ uiBut *but = (uiBut *)arg;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ PointerRNA ptr;
+ uiLayout *layout;
+ uiStyle *style = UI_style_get_dpi();
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ int kmi_id;
- /* XXX this guess_opname can potentially return a different keymap
- * than being found on adding later... */
- km = WM_keymap_guess_opname(C, but->optype->idname);
- kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
- kmi_id = kmi->id;
+ /* XXX this guess_opname can potentially return a different keymap
+ * than being found on adding later... */
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
+ kmi_id = kmi->id;
- /* copy properties, prop can be NULL for reset */
- if (prop) {
- prop = IDP_CopyProperty(prop);
- }
- WM_keymap_properties_reset(kmi, prop);
+ /* copy properties, prop can be NULL for reset */
+ if (prop) {
+ prop = IDP_CopyProperty(prop);
+ }
+ WM_keymap_properties_reset(kmi, prop);
- /* update and get pointers again */
- WM_keyconfig_update(wm);
+ /* update and get pointers again */
+ WM_keyconfig_update(wm);
- km = WM_keymap_guess_opname(C, but->optype->idname);
- kmi = WM_keymap_item_find_id(km, kmi_id);
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi = WM_keymap_item_find_id(km, kmi_id);
- RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
- UI_block_func_handle_set(block, but_shortcut_name_func, but);
- UI_block_direction_set(block, UI_DIR_CENTER_Y);
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS);
+ UI_block_func_handle_set(block, but_shortcut_name_func, but);
+ UI_block_direction_set(block, UI_DIR_CENTER_Y);
- layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
+ layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, 200, 20, 0, style);
- uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
+ uiItemR(layout, &ptr, "type", UI_ITEM_R_FULL_EVENT | UI_ITEM_R_IMMEDIATE, "", ICON_NONE);
- UI_block_bounds_set_popup(block, 6, (const int[2]){-50, 26});
+ UI_block_bounds_set_popup(block, 6, (const int[2]){-50, 26});
#ifdef USE_KEYMAP_ADD_HACK
- g_kmi_id_hack = kmi_id;
+ g_kmi_id_hack = kmi_id;
#endif
- return block;
+ return block;
}
static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
{
- uiBut *but = (uiBut *)arg1;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
+ uiBut *but = (uiBut *)arg1;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
#ifndef USE_KEYMAP_ADD_HACK
- IDProperty *prop;
+ IDProperty *prop;
#endif
- int kmi_id;
+ int kmi_id;
#ifdef USE_KEYMAP_ADD_HACK
- km = WM_keymap_guess_opname(C, but->optype->idname);
- kmi_id = g_kmi_id_hack;
- UNUSED_VARS(but);
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi_id = g_kmi_id_hack;
+ UNUSED_VARS(but);
#else
- prop = (but->opptr) ? but->opptr->data : NULL;
- kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
+ prop = (but->opptr) ? but->opptr->data : NULL;
+ kmi_id = WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, true, &km);
#endif
- kmi = WM_keymap_item_find_id(km, kmi_id);
- WM_keymap_remove_item(km, kmi);
+ kmi = WM_keymap_item_find_id(km, kmi_id);
+ WM_keymap_remove_item(km, kmi);
}
static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
- uiBut *but = (uiBut *)arg1;
- UI_popup_block_invoke(C, menu_change_shortcut, but);
+ uiBut *but = (uiBut *)arg1;
+ UI_popup_block_invoke(C, menu_change_shortcut, but);
}
static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
- uiBut *but = (uiBut *)arg1;
- wmKeyMap *km;
- wmKeyMapItem *kmi;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
- kmi = WM_key_event_operator(
- C, but->optype->idname, but->opcontext, prop,
- EVT_TYPE_MASK_HOTKEY_INCLUDE, EVT_TYPE_MASK_HOTKEY_EXCLUDE,
- &km);
- BLI_assert(kmi != NULL);
-
- WM_keymap_remove_item(km, kmi);
-
- but_shortcut_name_func(C, but, 0);
+ uiBut *but = (uiBut *)arg1;
+ wmKeyMap *km;
+ wmKeyMapItem *kmi;
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+
+ kmi = WM_key_event_operator(C,
+ but->optype->idname,
+ but->opcontext,
+ prop,
+ EVT_TYPE_MASK_HOTKEY_INCLUDE,
+ EVT_TYPE_MASK_HOTKEY_EXCLUDE,
+ &km);
+ BLI_assert(kmi != NULL);
+
+ WM_keymap_remove_item(km, kmi);
+
+ but_shortcut_name_func(C, but, 0);
}
static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
- uiBut *but = (uiBut *)arg1;
- UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
+ uiBut *but = (uiBut *)arg1;
+ UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
}
static bool ui_but_is_user_menu_compatible(bContext *C, uiBut *but)
{
- return (but->optype ||
- (but->rnaprop &&
- (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) &&
- (WM_context_member_from_ptr(C, &but->rnapoin) != NULL)) ||
- UI_but_menutype_get(but));
+ return (but->optype ||
+ (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_BOOLEAN) &&
+ (WM_context_member_from_ptr(C, &but->rnapoin) != NULL)) ||
+ UI_but_menutype_get(but));
}
static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *um)
{
- MenuType *mt = NULL;
- if (but->optype) {
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
- return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
- &um->items, but->optype, prop, but->opcontext);
- }
- else if (but->rnaprop) {
- const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
- const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
- const char *member_id_data_path = member_id;
- if (data_path) {
- member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
- }
- const char *prop_id = RNA_property_identifier(but->rnaprop);
- bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
- &um->items, member_id_data_path, prop_id, but->rnaindex);
- if (data_path) {
- MEM_freeN((void *)data_path);
- }
- if (member_id != member_id_data_path) {
- MEM_freeN((void *)member_id_data_path);
- }
- return umi;
- }
- else if ((mt = UI_but_menutype_get(but))) {
- return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(
- &um->items, mt);
- }
- else {
- return NULL;
- }
+ MenuType *mt = NULL;
+ if (but->optype) {
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ return (bUserMenuItem *)ED_screen_user_menu_item_find_operator(
+ &um->items, but->optype, prop, but->opcontext);
+ }
+ else if (but->rnaprop) {
+ const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
+ const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
+ const char *member_id_data_path = member_id;
+ if (data_path) {
+ member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
+ }
+ const char *prop_id = RNA_property_identifier(but->rnaprop);
+ bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
+ &um->items, member_id_data_path, prop_id, but->rnaindex);
+ if (data_path) {
+ MEM_freeN((void *)data_path);
+ }
+ if (member_id != member_id_data_path) {
+ MEM_freeN((void *)member_id_data_path);
+ }
+ return umi;
+ }
+ else if ((mt = UI_but_menutype_get(but))) {
+ return (bUserMenuItem *)ED_screen_user_menu_item_find_menu(&um->items, mt);
+ }
+ else {
+ return NULL;
+ }
}
static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
{
- BLI_assert(ui_but_is_user_menu_compatible(C, but));
-
- char drawstr[sizeof(but->drawstr)];
- STRNCPY(drawstr, but->drawstr);
- if (but->flag & UI_BUT_HAS_SEP_CHAR) {
- char *sep = strrchr(drawstr, UI_SEP_CHAR);
- if (sep) {
- *sep = '\0';
- }
- }
-
- MenuType *mt = NULL;
- if (but->optype) {
- if (drawstr[0] == '\0') {
- /* Hard code overrides for generic operators. */
- if (UI_but_is_tool(but)) {
- RNA_string_get(but->opptr, "name", drawstr);
- }
- }
- ED_screen_user_menu_item_add_operator(
- &um->items, drawstr,
- but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
- }
- else if (but->rnaprop) {
- /* Note: 'member_id' may be a path. */
- const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
- const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
- const char *member_id_data_path = member_id;
- if (data_path) {
- member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
- }
- const char *prop_id = RNA_property_identifier(but->rnaprop);
- /* Note, ignore 'drawstr', use property idname always. */
- ED_screen_user_menu_item_add_prop(
- &um->items, "",
- member_id_data_path, prop_id, but->rnaindex);
- if (data_path) {
- MEM_freeN((void *)data_path);
- }
- if (member_id != member_id_data_path) {
- MEM_freeN((void *)member_id_data_path);
- }
- }
- else if ((mt = UI_but_menutype_get(but))) {
- ED_screen_user_menu_item_add_menu(
- &um->items, drawstr,
- mt);
- }
+ BLI_assert(ui_but_is_user_menu_compatible(C, but));
+
+ char drawstr[sizeof(but->drawstr)];
+ STRNCPY(drawstr, but->drawstr);
+ if (but->flag & UI_BUT_HAS_SEP_CHAR) {
+ char *sep = strrchr(drawstr, UI_SEP_CHAR);
+ if (sep) {
+ *sep = '\0';
+ }
+ }
+
+ MenuType *mt = NULL;
+ if (but->optype) {
+ if (drawstr[0] == '\0') {
+ /* Hard code overrides for generic operators. */
+ if (UI_but_is_tool(but)) {
+ RNA_string_get(but->opptr, "name", drawstr);
+ }
+ }
+ ED_screen_user_menu_item_add_operator(
+ &um->items, drawstr, but->optype, but->opptr ? but->opptr->data : NULL, but->opcontext);
+ }
+ else if (but->rnaprop) {
+ /* Note: 'member_id' may be a path. */
+ const char *member_id = WM_context_member_from_ptr(C, &but->rnapoin);
+ const char *data_path = RNA_path_from_ID_to_struct(&but->rnapoin);
+ const char *member_id_data_path = member_id;
+ if (data_path) {
+ member_id_data_path = BLI_sprintfN("%s.%s", member_id, data_path);
+ }
+ const char *prop_id = RNA_property_identifier(but->rnaprop);
+ /* Note, ignore 'drawstr', use property idname always. */
+ ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex);
+ if (data_path) {
+ MEM_freeN((void *)data_path);
+ }
+ if (member_id != member_id_data_path) {
+ MEM_freeN((void *)member_id_data_path);
+ }
+ }
+ else if ((mt = UI_but_menutype_get(but))) {
+ ED_screen_user_menu_item_add_menu(&um->items, drawstr, mt);
+ }
}
static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
- uiBut *but = arg1;
- bUserMenu *um = ED_screen_user_menu_ensure(C);
- ui_but_user_menu_add(C, but, um);
+ uiBut *but = arg1;
+ bUserMenu *um = ED_screen_user_menu_ensure(C);
+ ui_but_user_menu_add(C, but, um);
}
static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void *arg2)
{
- bUserMenu *um = arg1;
- bUserMenuItem *umi = arg2;
- ED_screen_user_menu_item_remove(&um->items, umi);
+ bUserMenu *um = arg1;
+ bUserMenuItem *umi = arg2;
+ ED_screen_user_menu_item_remove(&um->items, umi);
}
static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop)
{
- const PropertySubType subtype = RNA_property_subtype(prop);
- wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
- char filepath[FILE_MAX];
- char dir[FILE_MAXDIR];
- char file[FILE_MAXFILE];
- PointerRNA props_ptr;
-
- BLI_assert(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH));
- UNUSED_VARS_NDEBUG(subtype);
-
- RNA_property_string_get(ptr, prop, filepath);
- BLI_split_dirfile(filepath, dir, file, sizeof(dir), sizeof(file));
-
- if (file[0]) {
- BLI_assert(subtype == PROP_FILEPATH);
- uiItemFullO_ptr(
- layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"),
- ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr);
- RNA_string_set(&props_ptr, "filepath", filepath);
- }
-
- uiItemFullO_ptr(
- layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"),
- ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr);
- RNA_string_set(&props_ptr, "filepath", dir);
+ const PropertySubType subtype = RNA_property_subtype(prop);
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
+ char filepath[FILE_MAX];
+ char dir[FILE_MAXDIR];
+ char file[FILE_MAXFILE];
+ PointerRNA props_ptr;
+
+ BLI_assert(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH));
+ UNUSED_VARS_NDEBUG(subtype);
+
+ RNA_property_string_get(ptr, prop, filepath);
+ BLI_split_dirfile(filepath, dir, file, sizeof(dir), sizeof(file));
+
+ if (file[0]) {
+ BLI_assert(subtype == PROP_FILEPATH);
+ uiItemFullO_ptr(layout,
+ ot,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"),
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &props_ptr);
+ RNA_string_set(&props_ptr, "filepath", filepath);
+ }
+
+ uiItemFullO_ptr(layout,
+ ot,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"),
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &props_ptr);
+ RNA_string_set(&props_ptr, "filepath", dir);
}
bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
{
- /* having this menu for some buttons makes no sense */
- if (but->type == UI_BTYPE_IMAGE) {
- return false;
- }
-
- uiPopupMenu *pup;
- uiLayout *layout;
-
- {
- uiStringInfo label = {BUT_GET_LABEL, NULL};
-
- /* highly unlikely getting the label ever fails */
- UI_but_string_info_get(C, but, &label, NULL);
-
- pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- if (label.strinfo) {
- MEM_freeN(label.strinfo);
- }
- uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
- }
-
- const bool is_disabled = but->flag & UI_BUT_DISABLED;
-
- if (is_disabled) {
- /* Suppress editing commands. */
- }
- else if (but->type == UI_BTYPE_TAB) {
- uiButTab *tab = (uiButTab *)but;
- if (tab->menu) {
- UI_menutype_draw(C, tab->menu, layout);
- uiItemS(layout);
- }
- }
- else if (but->rnapoin.data && but->rnaprop) {
- PointerRNA *ptr = &but->rnapoin;
- PropertyRNA *prop = but->rnaprop;
- const PropertyType type = RNA_property_type(prop);
- const PropertySubType subtype = RNA_property_subtype(prop);
- bool is_anim = RNA_property_animateable(ptr, prop);
- bool is_editable = RNA_property_editable(ptr, prop);
- bool is_idprop = RNA_property_is_idprop(prop);
- bool is_set = RNA_property_is_set(ptr, prop);
-
- /* second slower test,
- * saved people finding keyframe items in menus when its not possible */
- if (is_anim) {
- is_anim = RNA_property_path_from_ID_check(&but->rnapoin, but->rnaprop);
- }
-
- /* determine if we can key a single component of an array */
- const bool is_array = RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0;
- const bool is_array_component = (is_array && but->rnaindex != -1);
-
- const int override_status = RNA_property_static_override_status(ptr, prop, -1);
- const bool is_overridable = (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
-
- /* Set the (button_pointer, button_prop)
- * and pointer data for Python access to the hovered ui element. */
- uiLayoutSetContextFromBut(layout, but);
-
- /* Keyframes */
- if (but->flag & UI_BUT_ANIMATED_KEY) {
- /* replace/delete keyfraemes */
- if (is_array_component) {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframes"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Single Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframes"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 0);
- }
- else {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframe"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_delete_button", "all", 1);
- }
-
- /* keyframe settings */
- uiItemS(layout);
-
-
- }
- else if (but->flag & UI_BUT_DRIVEN) {
- /* pass */
- }
- else if (is_anim) {
- if (is_array_component) {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"),
- ICON_NONE, "ANIM_OT_keyframe_insert_button", "all", 0);
- }
- else {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"),
- ICON_KEY_HLT, "ANIM_OT_keyframe_insert_button", "all", 1);
- }
- }
-
- if ((but->flag & UI_BUT_ANIMATED) && (but->rnapoin.type != &RNA_NlaStrip)) {
- if (is_array_component) {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
- ICON_KEY_DEHLT, "ANIM_OT_keyframe_clear_button", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Single Keyframes"),
- ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 0);
- }
- else {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
- ICON_KEY_DEHLT, "ANIM_OT_keyframe_clear_button", "all", 1);
- }
- }
-
- /* Drivers */
- if (but->flag & UI_BUT_DRIVEN) {
- uiItemS(layout);
-
- if (is_array_component) {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Drivers"),
- ICON_X, "ANIM_OT_driver_button_remove", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"),
- ICON_NONE, "ANIM_OT_driver_button_remove", "all", 0);
- }
- else {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"),
- ICON_X, "ANIM_OT_driver_button_remove", "all", 1);
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"),
- ICON_NONE, "ANIM_OT_copy_driver_button");
- if (ANIM_driver_can_paste()) {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
- ICON_NONE, "ANIM_OT_paste_driver_button");
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Edit Driver"),
- ICON_DRIVER, "ANIM_OT_driver_button_edit");
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
- ICON_NONE, "SCREEN_OT_drivers_editor_show");
- }
- else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) {
- /* pass */
- }
- else if (is_anim) {
- uiItemS(layout);
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"),
- ICON_DRIVER, "ANIM_OT_driver_button_add");
-
- if (ANIM_driver_can_paste()) {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
- ICON_NONE, "ANIM_OT_paste_driver_button");
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
- ICON_NONE, "SCREEN_OT_drivers_editor_show");
- }
-
- /* Keying Sets */
- /* TODO: check on modifyability of Keying Set when doing this */
- if (is_anim) {
- uiItemS(layout);
-
- if (is_array_component) {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add All to Keying Set"),
- ICON_KEYINGSET, "ANIM_OT_keyingset_button_add", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single to Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_add", "all", 0);
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_remove");
- }
- else {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Keying Set"),
- ICON_KEYINGSET, "ANIM_OT_keyingset_button_add", "all", 1);
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
- ICON_NONE, "ANIM_OT_keyingset_button_remove");
- }
- }
-
- if (is_overridable) {
- wmOperatorType *ot;
- PointerRNA op_ptr;
- /* Override Operators */
- uiItemS(layout);
-
- if (but->flag & UI_BUT_OVERRIDEN) {
- if (is_array_component) {
-#if 0 /* Disabled for now. */
- ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
- uiItemFullO_ptr(
- layout, ot, "Overrides Type", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", true);
- uiItemFullO_ptr(
- layout, ot, "Single Override Type", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
+ /* having this menu for some buttons makes no sense */
+ if (but->type == UI_BTYPE_IMAGE) {
+ return false;
+ }
+
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ {
+ uiStringInfo label = {BUT_GET_LABEL, NULL};
+
+ /* highly unlikely getting the label ever fails */
+ UI_but_string_info_get(C, but, &label, NULL);
+
+ pup = UI_popup_menu_begin(C, label.strinfo ? label.strinfo : "", ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ if (label.strinfo) {
+ MEM_freeN(label.strinfo);
+ }
+ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
+ }
+
+ const bool is_disabled = but->flag & UI_BUT_DISABLED;
+
+ if (is_disabled) {
+ /* Suppress editing commands. */
+ }
+ else if (but->type == UI_BTYPE_TAB) {
+ uiButTab *tab = (uiButTab *)but;
+ if (tab->menu) {
+ UI_menutype_draw(C, tab->menu, layout);
+ uiItemS(layout);
+ }
+ }
+ else if (but->rnapoin.data && but->rnaprop) {
+ PointerRNA *ptr = &but->rnapoin;
+ PropertyRNA *prop = but->rnaprop;
+ const PropertyType type = RNA_property_type(prop);
+ const PropertySubType subtype = RNA_property_subtype(prop);
+ bool is_anim = RNA_property_animateable(ptr, prop);
+ bool is_editable = RNA_property_editable(ptr, prop);
+ bool is_idprop = RNA_property_is_idprop(prop);
+ bool is_set = RNA_property_is_set(ptr, prop);
+
+ /* second slower test,
+ * saved people finding keyframe items in menus when its not possible */
+ if (is_anim) {
+ is_anim = RNA_property_path_from_ID_check(&but->rnapoin, but->rnaprop);
+ }
+
+ /* determine if we can key a single component of an array */
+ const bool is_array = RNA_property_array_length(&but->rnapoin, but->rnaprop) != 0;
+ const bool is_array_component = (is_array && but->rnaindex != -1);
+
+ const int override_status = RNA_property_static_override_status(ptr, prop, -1);
+ const bool is_overridable = (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE) != 0;
+
+ /* Set the (button_pointer, button_prop)
+ * and pointer data for Python access to the hovered ui element. */
+ uiLayoutSetContextFromBut(layout, but);
+
+ /* Keyframes */
+ if (but->flag & UI_BUT_ANIMATED_KEY) {
+ /* replace/delete keyfraemes */
+ if (is_array_component) {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframes"),
+ ICON_KEY_HLT,
+ "ANIM_OT_keyframe_insert_button",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Single Keyframe"),
+ ICON_NONE,
+ "ANIM_OT_keyframe_insert_button",
+ "all",
+ 0);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframes"),
+ ICON_NONE,
+ "ANIM_OT_keyframe_delete_button",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Keyframe"),
+ ICON_NONE,
+ "ANIM_OT_keyframe_delete_button",
+ "all",
+ 0);
+ }
+ else {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Replace Keyframe"),
+ ICON_KEY_HLT,
+ "ANIM_OT_keyframe_insert_button",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Keyframe"),
+ ICON_NONE,
+ "ANIM_OT_keyframe_delete_button",
+ "all",
+ 1);
+ }
+
+ /* keyframe settings */
+ uiItemS(layout);
+ }
+ else if (but->flag & UI_BUT_DRIVEN) {
+ /* pass */
+ }
+ else if (is_anim) {
+ if (is_array_component) {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframes"),
+ ICON_KEY_HLT,
+ "ANIM_OT_keyframe_insert_button",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Single Keyframe"),
+ ICON_NONE,
+ "ANIM_OT_keyframe_insert_button",
+ "all",
+ 0);
+ }
+ else {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Insert Keyframe"),
+ ICON_KEY_HLT,
+ "ANIM_OT_keyframe_insert_button",
+ "all",
+ 1);
+ }
+ }
+
+ if ((but->flag & UI_BUT_ANIMATED) && (but->rnapoin.type != &RNA_NlaStrip)) {
+ if (is_array_component) {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
+ ICON_KEY_DEHLT,
+ "ANIM_OT_keyframe_clear_button",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Single Keyframes"),
+ ICON_NONE,
+ "ANIM_OT_keyframe_clear_button",
+ "all",
+ 0);
+ }
+ else {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
+ ICON_KEY_DEHLT,
+ "ANIM_OT_keyframe_clear_button",
+ "all",
+ 1);
+ }
+ }
+
+ /* Drivers */
+ if (but->flag & UI_BUT_DRIVEN) {
+ uiItemS(layout);
+
+ if (is_array_component) {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Drivers"),
+ ICON_X,
+ "ANIM_OT_driver_button_remove",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Single Driver"),
+ ICON_NONE,
+ "ANIM_OT_driver_button_remove",
+ "all",
+ 0);
+ }
+ else {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Delete Driver"),
+ ICON_X,
+ "ANIM_OT_driver_button_remove",
+ "all",
+ 1);
+ }
+
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Driver"),
+ ICON_NONE,
+ "ANIM_OT_copy_driver_button");
+ if (ANIM_driver_can_paste()) {
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
+ ICON_NONE,
+ "ANIM_OT_paste_driver_button");
+ }
+
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Edit Driver"),
+ ICON_DRIVER,
+ "ANIM_OT_driver_button_edit");
+
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
+ ICON_NONE,
+ "SCREEN_OT_drivers_editor_show");
+ }
+ else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) {
+ /* pass */
+ }
+ else if (is_anim) {
+ uiItemS(layout);
+
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Driver"),
+ ICON_DRIVER,
+ "ANIM_OT_driver_button_add");
+
+ if (ANIM_driver_can_paste()) {
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Paste Driver"),
+ ICON_NONE,
+ "ANIM_OT_paste_driver_button");
+ }
+
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
+ ICON_NONE,
+ "SCREEN_OT_drivers_editor_show");
+ }
+
+ /* Keying Sets */
+ /* TODO: check on modifyability of Keying Set when doing this */
+ if (is_anim) {
+ uiItemS(layout);
+
+ if (is_array_component) {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add All to Keying Set"),
+ ICON_KEYINGSET,
+ "ANIM_OT_keyingset_button_add",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add Single to Keying Set"),
+ ICON_NONE,
+ "ANIM_OT_keyingset_button_add",
+ "all",
+ 0);
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
+ ICON_NONE,
+ "ANIM_OT_keyingset_button_remove");
+ }
+ else {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Keying Set"),
+ ICON_KEYINGSET,
+ "ANIM_OT_keyingset_button_add",
+ "all",
+ 1);
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Keying Set"),
+ ICON_NONE,
+ "ANIM_OT_keyingset_button_remove");
+ }
+ }
+
+ if (is_overridable) {
+ wmOperatorType *ot;
+ PointerRNA op_ptr;
+ /* Override Operators */
+ uiItemS(layout);
+
+ if (but->flag & UI_BUT_OVERRIDEN) {
+ if (is_array_component) {
+#if 0 /* Disabled for now. */
+ ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
+ uiItemFullO_ptr(
+ layout, ot, "Overrides Type", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", true);
+ uiItemFullO_ptr(
+ layout, ot, "Single Override Type", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
#endif
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Overrides"),
- ICON_X, "UI_OT_override_remove_button", "all", true);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Single Override"),
- ICON_X, "UI_OT_override_remove_button", "all", false);
- }
- else {
-#if 0 /* Disabled for now. */
- uiItemFullO(
- layout, "UI_OT_override_type_set_button", "Override Type", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Overrides"),
+ ICON_X,
+ "UI_OT_override_remove_button",
+ "all",
+ true);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Single Override"),
+ ICON_X,
+ "UI_OT_override_remove_button",
+ "all",
+ false);
+ }
+ else {
+#if 0 /* Disabled for now. */
+ uiItemFullO(
+ layout, "UI_OT_override_type_set_button", "Override Type", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
#endif
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Override"),
- ICON_X, "UI_OT_override_remove_button", "all", true);
- }
- }
- else {
- if (is_array_component) {
- ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
- uiItemFullO_ptr(
- layout, ot, "Define Overrides", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", true);
- uiItemFullO_ptr(
- layout, ot, "Define Single Override", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
- }
- else {
- uiItemFullO(
- layout, "UI_OT_override_type_set_button", "Define Override", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_boolean_set(&op_ptr, "all", false);
- }
- }
- }
-
- uiItemS(layout);
-
- /* Property Operators */
-
- /* Copy Property Value
- * Paste Property Value */
-
- if (is_array_component) {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset All to Default Values"),
- ICON_LOOP_BACK, "UI_OT_reset_default_button", "all", 1);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"),
- ICON_NONE, "UI_OT_reset_default_button", "all", 0);
- }
- else {
- uiItemBooleanO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
- ICON_LOOP_BACK, "UI_OT_reset_default_button", "all", 1);
- }
- if (is_editable /*&& is_idprop*/ && is_set) {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Unset"),
- ICON_NONE, "UI_OT_unset_property_button");
- }
-
- if (is_idprop && !is_array_component && ELEM(type, PROP_INT, PROP_FLOAT)) {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Value as Default"),
- ICON_NONE, "UI_OT_assign_default_button");
-
- uiItemS(layout);
- }
-
- if (is_array_component) {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy All To Selected"),
- ICON_NONE, "UI_OT_copy_to_selected_button", "all", true);
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Single To Selected"),
- ICON_NONE, "UI_OT_copy_to_selected_button", "all", false);
- }
- else {
- uiItemBooleanO(
- layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy To Selected"),
- ICON_NONE, "UI_OT_copy_to_selected_button", "all", true);
- }
-
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
- ICON_NONE, "UI_OT_copy_data_path_button");
-
- uiItemS(layout);
-
- if (type == PROP_STRING && ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH)) {
- ui_but_menu_add_path_operators(layout, ptr, prop);
- uiItemS(layout);
- }
- }
-
- /* Pointer properties and string properties with
- * prop_search support jumping to target object/bone. */
- if (but->rnapoin.data && but->rnaprop) {
- const PropertyType prop_type = RNA_property_type(but->rnaprop);
- if (((prop_type == PROP_POINTER) ||
- (prop_type == PROP_STRING &&
- but->type == UI_BTYPE_SEARCH_MENU &&
- but->search_func == ui_rna_collection_search_cb)) &&
- ui_jump_to_target_button_poll(C))
- {
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Jump To Target"),
- ICON_NONE, "UI_OT_jump_to_target_button");
- uiItemS(layout);
- }
- }
-
- /* Favorites Menu */
- if (ui_but_is_user_menu_compatible(C, but)) {
- uiBlock *block = uiLayoutGetBlock(layout);
- const int w = uiLayoutGetWidth(layout);
- uiBut *but2;
- bool item_found = false;
-
- uint um_array_len;
- bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len);
- for (int um_index = 0; um_index < um_array_len; um_index++) {
- bUserMenu *um = um_array[um_index];
- if (um == NULL) {
- continue;
- }
- bUserMenuItem *umi = ui_but_user_menu_find(C, but, um);
- if (umi != NULL) {
- but2 = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_MENU_PANEL,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Quick Favorites"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- UI_but_func_set(but2, popup_user_menu_remove_func, um, umi);
- item_found = true;
- }
- }
- if (um_array) {
- MEM_freeN(um_array);
- }
-
- if (!item_found) {
- but2 = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_MENU_PANEL,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Quick Favorites"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- "Add to a user defined context menu (stored in the user preferences)");
- UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, NULL);
- }
-
- uiItemS(layout);
- }
-
- /* Operator buttons */
- if (but->optype) {
- uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but2;
- IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
- int w = uiLayoutGetWidth(layout);
- wmKeyMap *km;
- /* We want to know if this op has a shortcut, be it hotkey or not. */
- wmKeyMapItem *kmi = WM_key_event_operator(
- C, but->optype->idname, but->opcontext, prop,
- EVT_TYPE_MASK_ALL, 0,
- &km);
-
- /* We do have a shortcut, but only keyboard ones are editable that way... */
- if (kmi) {
- if (ISKEYBOARD(kmi->type)) {
-#if 0 /* would rather use a block but, but gets weirdly positioned... */
- uiDefBlockBut(
- block, menu_change_shortcut, but, "Change Shortcut",
- 0, 0, uiLayoutGetWidth(layout), UI_UNIT_Y, "");
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Override"),
+ ICON_X,
+ "UI_OT_override_remove_button",
+ "all",
+ true);
+ }
+ }
+ else {
+ if (is_array_component) {
+ ot = WM_operatortype_find("UI_OT_override_type_set_button", false);
+ uiItemFullO_ptr(
+ layout, ot, "Define Overrides", ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", true);
+ uiItemFullO_ptr(layout,
+ ot,
+ "Define Single Override",
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
+ }
+ else {
+ uiItemFullO(layout,
+ "UI_OT_override_type_set_button",
+ "Define Override",
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ &op_ptr);
+ RNA_boolean_set(&op_ptr, "all", false);
+ }
+ }
+ }
+
+ uiItemS(layout);
+
+ /* Property Operators */
+
+ /* Copy Property Value
+ * Paste Property Value */
+
+ if (is_array_component) {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset All to Default Values"),
+ ICON_LOOP_BACK,
+ "UI_OT_reset_default_button",
+ "all",
+ 1);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset Single to Default Value"),
+ ICON_NONE,
+ "UI_OT_reset_default_button",
+ "all",
+ 0);
+ }
+ else {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Reset to Default Value"),
+ ICON_LOOP_BACK,
+ "UI_OT_reset_default_button",
+ "all",
+ 1);
+ }
+ if (is_editable /*&& is_idprop*/ && is_set) {
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Unset"),
+ ICON_NONE,
+ "UI_OT_unset_property_button");
+ }
+
+ if (is_idprop && !is_array_component && ELEM(type, PROP_INT, PROP_FLOAT)) {
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Value as Default"),
+ ICON_NONE,
+ "UI_OT_assign_default_button");
+
+ uiItemS(layout);
+ }
+
+ if (is_array_component) {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy All To Selected"),
+ ICON_NONE,
+ "UI_OT_copy_to_selected_button",
+ "all",
+ true);
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Single To Selected"),
+ ICON_NONE,
+ "UI_OT_copy_to_selected_button",
+ "all",
+ false);
+ }
+ else {
+ uiItemBooleanO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy To Selected"),
+ ICON_NONE,
+ "UI_OT_copy_to_selected_button",
+ "all",
+ true);
+ }
+
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy Data Path"),
+ ICON_NONE,
+ "UI_OT_copy_data_path_button");
+
+ uiItemS(layout);
+
+ if (type == PROP_STRING && ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH)) {
+ ui_but_menu_add_path_operators(layout, ptr, prop);
+ uiItemS(layout);
+ }
+ }
+
+ /* Pointer properties and string properties with
+ * prop_search support jumping to target object/bone. */
+ if (but->rnapoin.data && but->rnaprop) {
+ const PropertyType prop_type = RNA_property_type(but->rnaprop);
+ if (((prop_type == PROP_POINTER) ||
+ (prop_type == PROP_STRING && but->type == UI_BTYPE_SEARCH_MENU &&
+ but->search_func == ui_rna_collection_search_cb)) &&
+ ui_jump_to_target_button_poll(C)) {
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Jump To Target"),
+ ICON_NONE,
+ "UI_OT_jump_to_target_button");
+ uiItemS(layout);
+ }
+ }
+
+ /* Favorites Menu */
+ if (ui_but_is_user_menu_compatible(C, but)) {
+ uiBlock *block = uiLayoutGetBlock(layout);
+ const int w = uiLayoutGetWidth(layout);
+ uiBut *but2;
+ bool item_found = false;
+
+ uint um_array_len;
+ bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len);
+ for (int um_index = 0; um_index < um_array_len; um_index++) {
+ bUserMenu *um = um_array[um_index];
+ if (um == NULL) {
+ continue;
+ }
+ bUserMenuItem *umi = ui_but_user_menu_find(C, but, um);
+ if (umi != NULL) {
+ but2 = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_MENU_PANEL,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove from Quick Favorites"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ UI_but_func_set(but2, popup_user_menu_remove_func, um, umi);
+ item_found = true;
+ }
+ }
+ if (um_array) {
+ MEM_freeN(um_array);
+ }
+
+ if (!item_found) {
+ but2 = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_MENU_PANEL,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Add to Quick Favorites"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "Add to a user defined context menu (stored in the user preferences)");
+ UI_but_func_set(but2, popup_user_menu_add_or_replace_func, but, NULL);
+ }
+
+ uiItemS(layout);
+ }
+
+ /* Operator buttons */
+ if (but->optype) {
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but2;
+ IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
+ int w = uiLayoutGetWidth(layout);
+ wmKeyMap *km;
+ /* We want to know if this op has a shortcut, be it hotkey or not. */
+ wmKeyMapItem *kmi = WM_key_event_operator(
+ C, but->optype->idname, but->opcontext, prop, EVT_TYPE_MASK_ALL, 0, &km);
+
+ /* We do have a shortcut, but only keyboard ones are editable that way... */
+ if (kmi) {
+ if (ISKEYBOARD(kmi->type)) {
+#if 0 /* would rather use a block but, but gets weirdly positioned... */
+ uiDefBlockBut(
+ block, menu_change_shortcut, but, "Change Shortcut",
+ 0, 0, uiLayoutGetWidth(layout), UI_UNIT_Y, "");
#endif
- but2 = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_HAND,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- UI_but_func_set(but2, popup_change_shortcut_func, but, NULL);
-
- but2 = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_BLANK1,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- UI_but_func_set(but2, remove_shortcut_func, but, NULL);
- }
- else {
- but2 = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_HAND, IFACE_("Non-Keyboard Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Only keyboard shortcuts can be edited that way, "
- "please use User Preferences otherwise"));
- UI_but_flag_enable(but2, UI_BUT_DISABLED);
- }
- }
- /* only show 'assign' if there's a suitable key map for it to go in */
- else if (WM_keymap_guess_opname(C, but->optype->idname)) {
- but2 = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_HAND,
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"),
- 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
- }
-
- /* Set the operator pointer for python access */
- uiLayoutSetContextFromBut(layout, but);
-
- uiItemS(layout);
- }
-
- { /* Docs */
- char buf[512];
-
- if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
- PointerRNA ptr_props;
- uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
- ICON_URL, "WM_OT_doc_view_manual_ui_context");
-
- if (U.flag & USER_DEVELOPER_UI) {
- uiItemFullO(
- layout, "WM_OT_doc_view",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"),
- ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr_props);
- RNA_string_set(&ptr_props, "doc_id", buf);
- }
-
- /* XXX inactive option, not for public! */
+ but2 = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_HAND,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Change Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ UI_but_func_set(but2, popup_change_shortcut_func, but, NULL);
+
+ but2 = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_BLANK1,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Remove Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ UI_but_func_set(but2, remove_shortcut_func, but, NULL);
+ }
+ else {
+ but2 = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_HAND,
+ IFACE_("Non-Keyboard Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Only keyboard shortcuts can be edited that way, "
+ "please use User Preferences otherwise"));
+ UI_but_flag_enable(but2, UI_BUT_DISABLED);
+ }
+ }
+ /* only show 'assign' if there's a suitable key map for it to go in */
+ else if (WM_keymap_guess_opname(C, but->optype->idname)) {
+ but2 = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_HAND,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Assign Shortcut"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
+ }
+
+ /* Set the operator pointer for python access */
+ uiLayoutSetContextFromBut(layout, but);
+
+ uiItemS(layout);
+ }
+
+ { /* Docs */
+ char buf[512];
+
+ if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
+ PointerRNA ptr_props;
+ uiItemO(layout,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
+ ICON_URL,
+ "WM_OT_doc_view_manual_ui_context");
+
+ if (U.flag & USER_DEVELOPER_UI) {
+ uiItemFullO(layout,
+ "WM_OT_doc_view",
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"),
+ ICON_NONE,
+ NULL,
+ WM_OP_EXEC_DEFAULT,
+ 0,
+ &ptr_props);
+ RNA_string_set(&ptr_props, "doc_id", buf);
+ }
+
+ /* XXX inactive option, not for public! */
#if 0
- uiItemFullO(
- layout, "WM_OT_doc_edit", "Submit Description", ICON_NONE,
- NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr_props);
- RNA_string_set(&ptr_props, "doc_id", buf);
- RNA_string_set(&ptr_props, "doc_new", RNA_property_description(but->rnaprop));
+ uiItemFullO(
+ layout, "WM_OT_doc_edit", "Submit Description", ICON_NONE,
+ NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr_props);
+ RNA_string_set(&ptr_props, "doc_id", buf);
+ RNA_string_set(&ptr_props, "doc_new", RNA_property_description(but->rnaprop));
#endif
- }
- }
-
- if (but->optype && U.flag & USER_DEVELOPER_UI) {
- uiItemO(layout, NULL,
- ICON_NONE, "UI_OT_copy_python_command_button");
- }
-
- /* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
- if (U.flag & USER_DEVELOPER_UI) {
- if (ui_block_is_menu(but->block) == false) {
- uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
- }
- }
-
- if (BKE_addon_find(&U.addons, "ui_translate")) {
- uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
- }
-
- /* Show header tools for header buttons. */
- if (ui_block_is_popup_any(but->block) == false) {
- const ARegion *ar = CTX_wm_region(C);
-
- if (!ar) {
- /* skip */
- }
- else if (ar->regiontype == RGN_TYPE_HEADER) {
- uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
- }
- else if (ar->regiontype == RGN_TYPE_NAV_BAR) {
- uiItemMenuF(layout, IFACE_("Navigation Bar"), ICON_NONE, ED_screens_navigation_bar_tools_menu_create, NULL);
- }
- else if (ar->regiontype == RGN_TYPE_FOOTER) {
- uiItemMenuF(layout, IFACE_("Footer"), ICON_NONE, ED_screens_footer_tools_menu_create, NULL);
- }
- }
-
- MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
- if (mt) {
- UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
- }
-
- return UI_popup_menu_end_or_cancel(C, pup);
+ }
+ }
+
+ if (but->optype && U.flag & USER_DEVELOPER_UI) {
+ uiItemO(layout, NULL, ICON_NONE, "UI_OT_copy_python_command_button");
+ }
+
+ /* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
+ if (U.flag & USER_DEVELOPER_UI) {
+ if (ui_block_is_menu(but->block) == false) {
+ uiItemFullO(
+ layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
+ }
+ }
+
+ if (BKE_addon_find(&U.addons, "ui_translate")) {
+ uiItemFullO(layout,
+ "UI_OT_edittranslation_init",
+ NULL,
+ ICON_NONE,
+ NULL,
+ WM_OP_INVOKE_DEFAULT,
+ 0,
+ NULL);
+ }
+
+ /* Show header tools for header buttons. */
+ if (ui_block_is_popup_any(but->block) == false) {
+ const ARegion *ar = CTX_wm_region(C);
+
+ if (!ar) {
+ /* skip */
+ }
+ else if (ar->regiontype == RGN_TYPE_HEADER) {
+ uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
+ }
+ else if (ar->regiontype == RGN_TYPE_NAV_BAR) {
+ uiItemMenuF(layout,
+ IFACE_("Navigation Bar"),
+ ICON_NONE,
+ ED_screens_navigation_bar_tools_menu_create,
+ NULL);
+ }
+ else if (ar->regiontype == RGN_TYPE_FOOTER) {
+ uiItemMenuF(layout, IFACE_("Footer"), ICON_NONE, ED_screens_footer_tools_menu_create, NULL);
+ }
+ }
+
+ MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
+ if (mt) {
+ UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
+ }
+
+ return UI_popup_menu_end_or_cancel(C, pup);
}
/** \} */
@@ -871,35 +1078,39 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
*/
void ui_popup_context_menu_for_panel(bContext *C, ARegion *ar, Panel *pa)
{
- bScreen *sc = CTX_wm_screen(C);
- const bool has_panel_category = UI_panel_category_is_visible(ar);
- const bool any_item_visible = has_panel_category;
- PointerRNA ptr;
- uiPopupMenu *pup;
- uiLayout *layout;
-
- if (!any_item_visible) {
- return;
- }
-
- RNA_pointer_create(&sc->id, &RNA_Panel, pa, &ptr);
-
- pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
-
- if (has_panel_category) {
- char tmpstr[80];
- BLI_snprintf(tmpstr, sizeof(tmpstr), "%s" UI_SEP_CHAR_S "%s", IFACE_("Pin"), IFACE_("Shift+Left Mouse"));
- uiItemR(layout, &ptr, "use_pin", 0, tmpstr, ICON_NONE);
-
- /* evil, force shortcut flag */
- {
- uiBlock *block = uiLayoutGetBlock(layout);
- uiBut *but = block->buttons.last;
- but->flag |= UI_BUT_HAS_SEP_CHAR;
- }
- }
- UI_popup_menu_end(C, pup);
+ bScreen *sc = CTX_wm_screen(C);
+ const bool has_panel_category = UI_panel_category_is_visible(ar);
+ const bool any_item_visible = has_panel_category;
+ PointerRNA ptr;
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ if (!any_item_visible) {
+ return;
+ }
+
+ RNA_pointer_create(&sc->id, &RNA_Panel, pa, &ptr);
+
+ pup = UI_popup_menu_begin(C, IFACE_("Panel"), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+
+ if (has_panel_category) {
+ char tmpstr[80];
+ BLI_snprintf(tmpstr,
+ sizeof(tmpstr),
+ "%s" UI_SEP_CHAR_S "%s",
+ IFACE_("Pin"),
+ IFACE_("Shift+Left Mouse"));
+ uiItemR(layout, &ptr, "use_pin", 0, tmpstr, ICON_NONE);
+
+ /* evil, force shortcut flag */
+ {
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiBut *but = block->buttons.last;
+ but->flag |= UI_BUT_HAS_SEP_CHAR;
+ }
+ }
+ UI_popup_menu_end(C, pup);
}
/** \} */
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 4185339cc92..0517278a149 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
#include <math.h>
#include <string.h>
@@ -39,7 +38,6 @@
#include "BKE_node.h"
#include "BKE_tracking.h"
-
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_colormanagement.h"
@@ -60,619 +58,668 @@
/* own include */
#include "interface_intern.h"
-
static int roundboxtype = UI_CNR_ALL;
void UI_draw_roundbox_corner_set(int type)
{
- /* Not sure the roundbox function is the best place to change this
- * if this is undone, it's not that big a deal, only makes curves edges
- * square for the */
- roundboxtype = type;
+ /* Not sure the roundbox function is the best place to change this
+ * if this is undone, it's not that big a deal, only makes curves edges
+ * square for the */
+ roundboxtype = type;
}
#if 0 /* unused */
int UI_draw_roundbox_corner_get(void)
{
- return roundboxtype;
+ return roundboxtype;
}
#endif
-void UI_draw_roundbox_3ubAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const uchar col[3], uchar alpha)
+void UI_draw_roundbox_3ubAlpha(bool filled,
+ float minx,
+ float miny,
+ float maxx,
+ float maxy,
+ float rad,
+ const uchar col[3],
+ uchar alpha)
{
- float colv[4];
- colv[0] = ((float)col[0]) / 255;
- colv[1] = ((float)col[1]) / 255;
- colv[2] = ((float)col[2]) / 255;
- colv[3] = ((float)alpha) / 255;
- UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
+ float colv[4];
+ colv[0] = ((float)col[0]) / 255;
+ colv[1] = ((float)col[1]) / 255;
+ colv[2] = ((float)col[2]) / 255;
+ colv[3] = ((float)alpha) / 255;
+ UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
}
-void UI_draw_roundbox_3fvAlpha(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[3], float alpha)
+void UI_draw_roundbox_3fvAlpha(bool filled,
+ float minx,
+ float miny,
+ float maxx,
+ float maxy,
+ float rad,
+ const float col[3],
+ float alpha)
{
- float colv[4];
- colv[0] = col[0];
- colv[1] = col[1];
- colv[2] = col[2];
- colv[3] = alpha;
- UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
+ float colv[4];
+ colv[0] = col[0];
+ colv[1] = col[1];
+ colv[2] = col[2];
+ colv[3] = alpha;
+ UI_draw_roundbox_4fv(filled, minx, miny, maxx, maxy, rad, colv);
}
-void UI_draw_roundbox_aa(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4])
+void UI_draw_roundbox_aa(
+ bool filled, float minx, float miny, float maxx, float maxy, float rad, const float color[4])
{
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx, .recti.ymin = miny,
- .recti.xmax = maxx, .recti.ymax = maxy,
- .radi = rad,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = color[0], .color_inner2[0] = color[0],
- .color_inner1[1] = color[1], .color_inner2[1] = color[1],
- .color_inner1[2] = color[2], .color_inner2[2] = color[2],
- .color_inner1[3] = color[3], .color_inner2[3] = color[3],
- .alpha_discard = 1.0f,
- };
-
- GPU_blend(true);
-
- if (filled) {
- /* plain antialiased filled box */
- widget_params.color_inner1[3] *= 0.125f;
- widget_params.color_inner2[3] *= 0.125f;
-
- /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
- * If it has been scaled, then it's no longer valid. */
- GPUBatch *batch = ui_batch_roundbox_get(filled, true);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GPU_batch_draw(batch);
- }
- else {
- /* plain antialiased unfilled box */
- GPU_line_smooth(true);
-
- GPUBatch *batch = ui_batch_roundbox_get(filled, false);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GPU_batch_draw(batch);
-
- GPU_line_smooth(false);
- }
-
- GPU_blend(false);
+ uiWidgetBaseParameters widget_params = {
+ .recti.xmin = minx,
+ .recti.ymin = miny,
+ .recti.xmax = maxx,
+ .recti.ymax = maxy,
+ .radi = rad,
+ .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
+ .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
+ .color_inner1[0] = color[0],
+ .color_inner2[0] = color[0],
+ .color_inner1[1] = color[1],
+ .color_inner2[1] = color[1],
+ .color_inner1[2] = color[2],
+ .color_inner2[2] = color[2],
+ .color_inner1[3] = color[3],
+ .color_inner2[3] = color[3],
+ .alpha_discard = 1.0f,
+ };
+
+ GPU_blend(true);
+
+ if (filled) {
+ /* plain antialiased filled box */
+ widget_params.color_inner1[3] *= 0.125f;
+ widget_params.color_inner2[3] *= 0.125f;
+
+ /* WATCH: This is assuming the ModelViewProjectionMatrix is area pixel space.
+ * If it has been scaled, then it's no longer valid. */
+ GPUBatch *batch = ui_batch_roundbox_get(filled, true);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_draw(batch);
+ }
+ else {
+ /* plain antialiased unfilled box */
+ GPU_line_smooth(true);
+
+ GPUBatch *batch = ui_batch_roundbox_get(filled, false);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_draw(batch);
+
+ GPU_line_smooth(false);
+ }
+
+ GPU_blend(false);
}
-void UI_draw_roundbox_4fv(bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4])
+void UI_draw_roundbox_4fv(
+ bool filled, float minx, float miny, float maxx, float maxy, float rad, const float col[4])
{
#if 0
- float vec[7][2] = {
- {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
- {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805},
- };
- int a;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- uint vert_len = 0;
- vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(col);
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_len);
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- immVertex2f(pos, maxx - rad, miny);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- immVertex2f(pos, maxx, maxy - rad);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- immVertex2f(pos, minx + rad, maxy);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- immVertex2f(pos, minx, miny + rad);
- for (a = 0; a < 7; a++) {
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- immVertex2f(pos, minx, miny);
- }
-
- immEnd();
- immUnbindProgram();
+ float vec[7][2] = {
+ {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
+ {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805},
+ };
+ int a;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ /* mult */
+ for (a = 0; a < 7; a++) {
+ mul_v2_fl(vec[a], rad);
+ }
+
+ uint vert_len = 0;
+ vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
+ vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
+ vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
+ vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(col);
+
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_len);
+ /* start with corner right-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
+ immVertex2f(pos, maxx - rad, miny);
+ for (a = 0; a < 7; a++) {
+ immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
+ }
+ immVertex2f(pos, maxx, miny + rad);
+ }
+ else {
+ immVertex2f(pos, maxx, miny);
+ }
+
+ /* corner right-top */
+ if (roundboxtype & UI_CNR_TOP_RIGHT) {
+ immVertex2f(pos, maxx, maxy - rad);
+ for (a = 0; a < 7; a++) {
+ immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
+ }
+ immVertex2f(pos, maxx - rad, maxy);
+ }
+ else {
+ immVertex2f(pos, maxx, maxy);
+ }
+
+ /* corner left-top */
+ if (roundboxtype & UI_CNR_TOP_LEFT) {
+ immVertex2f(pos, minx + rad, maxy);
+ for (a = 0; a < 7; a++) {
+ immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
+ }
+ immVertex2f(pos, minx, maxy - rad);
+ }
+ else {
+ immVertex2f(pos, minx, maxy);
+ }
+
+ /* corner left-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
+ immVertex2f(pos, minx, miny + rad);
+ for (a = 0; a < 7; a++) {
+ immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
+ }
+ immVertex2f(pos, minx + rad, miny);
+ }
+ else {
+ immVertex2f(pos, minx, miny);
+ }
+
+ immEnd();
+ immUnbindProgram();
#endif
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx, .recti.ymin = miny,
- .recti.xmax = maxx, .recti.ymax = maxy,
- .radi = rad,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = col[0], .color_inner2[0] = col[0],
- .color_inner1[1] = col[1], .color_inner2[1] = col[1],
- .color_inner1[2] = col[2], .color_inner2[2] = col[2],
- .color_inner1[3] = col[3], .color_inner2[3] = col[3],
- .alpha_discard = 1.0f,
- };
-
- GPUBatch *batch = ui_batch_roundbox_get(filled, false);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GPU_batch_draw(batch);
+ uiWidgetBaseParameters widget_params = {
+ .recti.xmin = minx,
+ .recti.ymin = miny,
+ .recti.xmax = maxx,
+ .recti.ymax = maxy,
+ .radi = rad,
+ .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
+ .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
+ .color_inner1[0] = col[0],
+ .color_inner2[0] = col[0],
+ .color_inner1[1] = col[1],
+ .color_inner2[1] = col[1],
+ .color_inner1[2] = col[2],
+ .color_inner2[2] = col[2],
+ .color_inner1[3] = col[3],
+ .color_inner2[3] = col[3],
+ .alpha_discard = 1.0f,
+ };
+
+ GPUBatch *batch = ui_batch_roundbox_get(filled, false);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_draw(batch);
}
#if 0
static void round_box_shade_col(uint attr, const float col1[3], float const col2[3], const float fac)
{
- float col[4] = {
- fac * col1[0] + (1.0f - fac) * col2[0],
- fac * col1[1] + (1.0f - fac) * col2[1],
- fac * col1[2] + (1.0f - fac) * col2[2],
- 1.0f,
- };
- immAttr4fv(attr, col);
+ float col[4] = {
+ fac * col1[0] + (1.0f - fac) * col2[0],
+ fac * col1[1] + (1.0f - fac) * col2[1],
+ fac * col1[2] + (1.0f - fac) * col2[2],
+ 1.0f,
+ };
+ immAttr4fv(attr, col);
}
#endif
/* linear horizontal shade within button or in outline */
/* view2d scrollers use it */
-void UI_draw_roundbox_shade_x(
- bool filled, float minx, float miny, float maxx, float maxy,
- float rad, float shadetop, float shadedown, const float col[4])
+void UI_draw_roundbox_shade_x(bool filled,
+ float minx,
+ float miny,
+ float maxx,
+ float maxy,
+ float rad,
+ float shadetop,
+ float shadedown,
+ const float col[4])
{
#if 0
- float vec[7][2] = {
- {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
- {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805},
- };
- const float div = maxy - miny;
- const float idiv = 1.0f / div;
- float coltop[3], coldown[3];
- int vert_count = 0;
- int a;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- /* 'shade' defines strength of shading */
- coltop[0] = min_ff(1.0f, col[0] + shadetop);
- coltop[1] = min_ff(1.0f, col[1] + shadetop);
- coltop[2] = min_ff(1.0f, col[2] + shadetop);
- coldown[0] = max_ff(0.0f, col[0] + shadedown);
- coldown[1] = max_ff(0.0f, col[1] + shadedown);
- coldown[2] = max_ff(0.0f, col[2] + shadedown);
-
- vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
-
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
-
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, maxx - rad, miny);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, vec[a][1] * idiv);
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
-
- round_box_shade_col(color, coltop, coldown, rad * idiv);
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
-
- round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
- immVertex2f(pos, maxx, maxy - rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (div - rad + vec[a][1]) * idiv);
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
-
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, minx + rad, maxy);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (div - vec[a][1]) * idiv);
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
-
- round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 1.0);
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
-
- round_box_shade_col(color, coltop, coldown, rad * idiv);
- immVertex2f(pos, minx, miny + rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, coltop, coldown, (rad - vec[a][1]) * idiv);
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
-
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- round_box_shade_col(color, coltop, coldown, 0.0);
- immVertex2f(pos, minx, miny);
- }
-
- immEnd();
- immUnbindProgram();
+ float vec[7][2] = {
+ {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
+ {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805},
+ };
+ const float div = maxy - miny;
+ const float idiv = 1.0f / div;
+ float coltop[3], coldown[3];
+ int vert_count = 0;
+ int a;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ /* mult */
+ for (a = 0; a < 7; a++) {
+ mul_v2_fl(vec[a], rad);
+ }
+
+ /* 'shade' defines strength of shading */
+ coltop[0] = min_ff(1.0f, col[0] + shadetop);
+ coltop[1] = min_ff(1.0f, col[1] + shadetop);
+ coltop[2] = min_ff(1.0f, col[2] + shadetop);
+ coldown[0] = max_ff(0.0f, col[0] + shadedown);
+ coldown[1] = max_ff(0.0f, col[1] + shadedown);
+ coldown[2] = max_ff(0.0f, col[2] + shadedown);
+
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
+
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
+
+ /* start with corner right-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
+
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, maxx - rad, miny);
+
+ for (a = 0; a < 7; a++) {
+ round_box_shade_col(color, coltop, coldown, vec[a][1] * idiv);
+ immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
+ }
+
+ round_box_shade_col(color, coltop, coldown, rad * idiv);
+ immVertex2f(pos, maxx, miny + rad);
+ }
+ else {
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, maxx, miny);
+ }
+
+ /* corner right-top */
+ if (roundboxtype & UI_CNR_TOP_RIGHT) {
+
+ round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
+ immVertex2f(pos, maxx, maxy - rad);
+
+ for (a = 0; a < 7; a++) {
+ round_box_shade_col(color, coltop, coldown, (div - rad + vec[a][1]) * idiv);
+ immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
+ }
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, maxx - rad, maxy);
+ }
+ else {
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, maxx, maxy);
+ }
+
+ /* corner left-top */
+ if (roundboxtype & UI_CNR_TOP_LEFT) {
+
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, minx + rad, maxy);
+
+ for (a = 0; a < 7; a++) {
+ round_box_shade_col(color, coltop, coldown, (div - vec[a][1]) * idiv);
+ immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
+ }
+
+ round_box_shade_col(color, coltop, coldown, (div - rad) * idiv);
+ immVertex2f(pos, minx, maxy - rad);
+ }
+ else {
+ round_box_shade_col(color, coltop, coldown, 1.0);
+ immVertex2f(pos, minx, maxy);
+ }
+
+ /* corner left-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
+
+ round_box_shade_col(color, coltop, coldown, rad * idiv);
+ immVertex2f(pos, minx, miny + rad);
+
+ for (a = 0; a < 7; a++) {
+ round_box_shade_col(color, coltop, coldown, (rad - vec[a][1]) * idiv);
+ immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
+ }
+
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, minx + rad, miny);
+ }
+ else {
+ round_box_shade_col(color, coltop, coldown, 0.0);
+ immVertex2f(pos, minx, miny);
+ }
+
+ immEnd();
+ immUnbindProgram();
#endif
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = minx, .recti.ymin = miny,
- .recti.xmax = maxx, .recti.ymax = maxy,
- .radi = rad,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .color_inner1[0] = min_ff(1.0f, col[0] + shadetop),
- .color_inner2[0] = max_ff(0.0f, col[0] + shadedown),
- .color_inner1[1] = min_ff(1.0f, col[1] + shadetop),
- .color_inner2[1] = max_ff(0.0f, col[1] + shadedown),
- .color_inner1[2] = min_ff(1.0f, col[2] + shadetop),
- .color_inner2[2] = max_ff(0.0f, col[2] + shadedown),
- .color_inner1[3] = 1.0f,
- .color_inner2[3] = 1.0f,
- .alpha_discard = 1.0f,
- };
-
- GPUBatch *batch = ui_batch_roundbox_get(filled, false);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
- GPU_batch_draw(batch);
+ uiWidgetBaseParameters widget_params = {
+ .recti.xmin = minx,
+ .recti.ymin = miny,
+ .recti.xmax = maxx,
+ .recti.ymax = maxy,
+ .radi = rad,
+ .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
+ .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
+ .color_inner1[0] = min_ff(1.0f, col[0] + shadetop),
+ .color_inner2[0] = max_ff(0.0f, col[0] + shadedown),
+ .color_inner1[1] = min_ff(1.0f, col[1] + shadetop),
+ .color_inner2[1] = max_ff(0.0f, col[1] + shadedown),
+ .color_inner1[2] = min_ff(1.0f, col[2] + shadetop),
+ .color_inner2[2] = max_ff(0.0f, col[2] + shadedown),
+ .color_inner1[3] = 1.0f,
+ .color_inner2[3] = 1.0f,
+ .alpha_discard = 1.0f,
+ };
+
+ GPUBatch *batch = ui_batch_roundbox_get(filled, false);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_draw(batch);
}
-#if 0 /* unused */
+#if 0 /* unused */
/* linear vertical shade within button or in outline */
/* view2d scrollers use it */
void UI_draw_roundbox_shade_y(
bool filled, float minx, float miny, float maxx, float maxy,
float rad, float shadeleft, float shaderight, const float col[4])
{
- float vec[7][2] = {
- {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
- {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805},
- };
- const float div = maxx - minx;
- const float idiv = 1.0f / div;
- float colLeft[3], colRight[3];
- int vert_count = 0;
- int a;
-
- /* mult */
- for (a = 0; a < 7; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- /* 'shade' defines strength of shading */
- colLeft[0] = min_ff(1.0f, col[0] + shadeleft);
- colLeft[1] = min_ff(1.0f, col[1] + shadeleft);
- colLeft[2] = min_ff(1.0f, col[2] + shadeleft);
- colRight[0] = max_ff(0.0f, col[0] + shaderight);
- colRight[1] = max_ff(0.0f, col[1] + shaderight);
- colRight[2] = max_ff(0.0f, col[2] + shaderight);
-
-
- vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
- vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
-
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
-
- /* start with corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx - rad, miny);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, vec[a][0] * idiv);
- immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
- }
-
- round_box_shade_col(color, colLeft, colRight, rad * idiv);
- immVertex2f(pos, maxx, miny + rad);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, maxy - rad);
-
- for (a = 0; a < 7; a++) {
-
- round_box_shade_col(color, colLeft, colRight, (div - rad - vec[a][0]) * idiv);
- immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
- }
- round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
- immVertex2f(pos, maxx - rad, maxy);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 0.0);
- immVertex2f(pos, maxx, maxy);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
- immVertex2f(pos, minx + rad, maxy);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, (div - rad + vec[a][0]) * idiv);
- immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
- }
-
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, maxy - rad);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, miny + rad);
-
- for (a = 0; a < 7; a++) {
- round_box_shade_col(color, colLeft, colRight, (vec[a][0]) * idiv);
- immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
- }
-
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx + rad, miny);
- }
- else {
- round_box_shade_col(color, colLeft, colRight, 1.0);
- immVertex2f(pos, minx, miny);
- }
-
- immEnd();
- immUnbindProgram();
+ float vec[7][2] = {
+ {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
+ {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805},
+ };
+ const float div = maxx - minx;
+ const float idiv = 1.0f / div;
+ float colLeft[3], colRight[3];
+ int vert_count = 0;
+ int a;
+
+ /* mult */
+ for (a = 0; a < 7; a++) {
+ mul_v2_fl(vec[a], rad);
+ }
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ /* 'shade' defines strength of shading */
+ colLeft[0] = min_ff(1.0f, col[0] + shadeleft);
+ colLeft[1] = min_ff(1.0f, col[1] + shadeleft);
+ colLeft[2] = min_ff(1.0f, col[2] + shadeleft);
+ colRight[0] = max_ff(0.0f, col[0] + shaderight);
+ colRight[1] = max_ff(0.0f, col[1] + shaderight);
+ colRight[2] = max_ff(0.0f, col[2] + shaderight);
+
+
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_RIGHT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_TOP_LEFT) ? 9 : 1;
+ vert_count += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 9 : 1;
+
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, vert_count);
+
+ /* start with corner right-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx - rad, miny);
+
+ for (a = 0; a < 7; a++) {
+ round_box_shade_col(color, colLeft, colRight, vec[a][0] * idiv);
+ immVertex2f(pos, maxx - rad + vec[a][0], miny + vec[a][1]);
+ }
+
+ round_box_shade_col(color, colLeft, colRight, rad * idiv);
+ immVertex2f(pos, maxx, miny + rad);
+ }
+ else {
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx, miny);
+ }
+
+ /* corner right-top */
+ if (roundboxtype & UI_CNR_TOP_RIGHT) {
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx, maxy - rad);
+
+ for (a = 0; a < 7; a++) {
+
+ round_box_shade_col(color, colLeft, colRight, (div - rad - vec[a][0]) * idiv);
+ immVertex2f(pos, maxx - vec[a][1], maxy - rad + vec[a][0]);
+ }
+ round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
+ immVertex2f(pos, maxx - rad, maxy);
+ }
+ else {
+ round_box_shade_col(color, colLeft, colRight, 0.0);
+ immVertex2f(pos, maxx, maxy);
+ }
+
+ /* corner left-top */
+ if (roundboxtype & UI_CNR_TOP_LEFT) {
+ round_box_shade_col(color, colLeft, colRight, (div - rad) * idiv);
+ immVertex2f(pos, minx + rad, maxy);
+
+ for (a = 0; a < 7; a++) {
+ round_box_shade_col(color, colLeft, colRight, (div - rad + vec[a][0]) * idiv);
+ immVertex2f(pos, minx + rad - vec[a][0], maxy - vec[a][1]);
+ }
+
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, maxy - rad);
+ }
+ else {
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, maxy);
+ }
+
+ /* corner left-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, miny + rad);
+
+ for (a = 0; a < 7; a++) {
+ round_box_shade_col(color, colLeft, colRight, (vec[a][0]) * idiv);
+ immVertex2f(pos, minx + vec[a][1], miny + rad - vec[a][0]);
+ }
+
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx + rad, miny);
+ }
+ else {
+ round_box_shade_col(color, colLeft, colRight, 1.0);
+ immVertex2f(pos, minx, miny);
+ }
+
+ immEnd();
+ immUnbindProgram();
}
#endif /* unused */
void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4])
{
- int ofs_y = 4 * U.pixelsize;
+ int ofs_y = 4 * U.pixelsize;
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(color);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
- immRecti(pos, pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
- immUnbindProgram();
+ immRecti(pos, pos_x, pos_y - ofs_y, pos_x + len, pos_y - ofs_y + (height * U.pixelsize));
+ immUnbindProgram();
}
/* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
/* based on UI_draw_roundbox_gl_mode,
* check on making a version which allows us to skip some sides */
-void ui_draw_but_TAB_outline(const rcti *rect, float rad, uchar highlight[3], uchar highlight_fade[3])
+void ui_draw_but_TAB_outline(const rcti *rect,
+ float rad,
+ uchar highlight[3],
+ uchar highlight_fade[3])
{
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
- /* add a 1px offset, looks nicer */
- const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
- const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
- int a;
- float vec[4][2] = {
- {0.195, 0.02},
- {0.55, 0.169},
- {0.831, 0.45},
- {0.98, 0.805},
- };
-
-
- /* mult */
- for (a = 0; a < 4; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBeginAtMost(GPU_PRIM_LINE_STRIP, 25);
-
- immAttr3ubv(col, highlight);
-
- /* start with corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- immVertex2f(pos, minx, maxy - rad);
- for (a = 0; a < 4; a++) {
- immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
- }
- immVertex2f(pos, minx + rad, maxy);
- }
- else {
- immVertex2f(pos, minx, maxy);
- }
-
- /* corner right-top */
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- immVertex2f(pos, maxx - rad, maxy);
- for (a = 0; a < 4; a++) {
- immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
- }
- immVertex2f(pos, maxx, maxy - rad);
- }
- else {
- immVertex2f(pos, maxx, maxy);
- }
-
- immAttr3ubv(col, highlight_fade);
-
- /* corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- immVertex2f(pos, maxx, miny + rad);
- for (a = 0; a < 4; a++) {
- immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
- }
- immVertex2f(pos, maxx - rad, miny);
- }
- else {
- immVertex2f(pos, maxx, miny);
- }
-
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- immVertex2f(pos, minx + rad, miny);
- for (a = 0; a < 4; a++) {
- immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
- }
- immVertex2f(pos, minx, miny + rad);
- }
- else {
- immVertex2f(pos, minx, miny);
- }
-
- immAttr3ubv(col, highlight);
-
- /* back to corner left-top */
- immVertex2f(pos, minx, (roundboxtype & UI_CNR_TOP_LEFT) ? (maxy - rad) : maxy);
-
- immEnd();
- immUnbindProgram();
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ /* add a 1px offset, looks nicer */
+ const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize;
+ const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize;
+ int a;
+ float vec[4][2] = {
+ {0.195, 0.02},
+ {0.55, 0.169},
+ {0.831, 0.45},
+ {0.98, 0.805},
+ };
+
+ /* mult */
+ for (a = 0; a < 4; a++) {
+ mul_v2_fl(vec[a], rad);
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, 25);
+
+ immAttr3ubv(col, highlight);
+
+ /* start with corner left-top */
+ if (roundboxtype & UI_CNR_TOP_LEFT) {
+ immVertex2f(pos, minx, maxy - rad);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, minx + vec[a][1], maxy - rad + vec[a][0]);
+ }
+ immVertex2f(pos, minx + rad, maxy);
+ }
+ else {
+ immVertex2f(pos, minx, maxy);
+ }
+
+ /* corner right-top */
+ if (roundboxtype & UI_CNR_TOP_RIGHT) {
+ immVertex2f(pos, maxx - rad, maxy);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, maxx - rad + vec[a][0], maxy - vec[a][1]);
+ }
+ immVertex2f(pos, maxx, maxy - rad);
+ }
+ else {
+ immVertex2f(pos, maxx, maxy);
+ }
+
+ immAttr3ubv(col, highlight_fade);
+
+ /* corner right-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
+ immVertex2f(pos, maxx, miny + rad);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, maxx - vec[a][1], miny + rad - vec[a][0]);
+ }
+ immVertex2f(pos, maxx - rad, miny);
+ }
+ else {
+ immVertex2f(pos, maxx, miny);
+ }
+
+ /* corner left-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
+ immVertex2f(pos, minx + rad, miny);
+ for (a = 0; a < 4; a++) {
+ immVertex2f(pos, minx + rad - vec[a][0], miny + vec[a][1]);
+ }
+ immVertex2f(pos, minx, miny + rad);
+ }
+ else {
+ immVertex2f(pos, minx, miny);
+ }
+
+ immAttr3ubv(col, highlight);
+
+ /* back to corner left-top */
+ immVertex2f(pos, minx, (roundboxtype & UI_CNR_TOP_LEFT) ? (maxy - rad) : maxy);
+
+ immEnd();
+ immUnbindProgram();
}
-void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, const uiWidgetColors *UNUSED(wcol), const rcti *rect)
+void ui_draw_but_IMAGE(ARegion *UNUSED(ar),
+ uiBut *but,
+ const uiWidgetColors *UNUSED(wcol),
+ const rcti *rect)
{
#ifdef WITH_HEADLESS
- (void)rect;
- (void)but;
+ (void)rect;
+ (void)but;
#else
- ImBuf *ibuf = (ImBuf *)but->poin;
-
- if (!ibuf) {
- return;
- }
-
- float facx = 1.0f;
- float facy = 1.0f;
-
- int w = BLI_rcti_size_x(rect);
- int h = BLI_rcti_size_y(rect);
-
- /* scissor doesn't seem to be doing the right thing...? */
-#if 0
- /* prevent drawing outside widget area */
- int scissor[4];
- GPU_scissor_get_i(scissor);
- GPU_scissor(rect->xmin, rect->ymin, w, h);
-#endif
-
- GPU_blend(true);
-
- if (w != ibuf->x || h != ibuf->y) {
- facx = (float)w / (float)ibuf->x;
- facy = (float)h / (float)ibuf->y;
- }
-
- IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(
- &state, (float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect,
- facx, facy, NULL);
-
- GPU_blend(false);
-
-#if 0
- // restore scissortest
- GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
-#endif
+ ImBuf *ibuf = (ImBuf *)but->poin;
+
+ if (!ibuf) {
+ return;
+ }
+
+ float facx = 1.0f;
+ float facy = 1.0f;
+
+ int w = BLI_rcti_size_x(rect);
+ int h = BLI_rcti_size_y(rect);
+
+ /* scissor doesn't seem to be doing the right thing...? */
+# if 0
+ /* prevent drawing outside widget area */
+ int scissor[4];
+ GPU_scissor_get_i(scissor);
+ GPU_scissor(rect->xmin, rect->ymin, w, h);
+# endif
+
+ GPU_blend(true);
+
+ if (w != ibuf->x || h != ibuf->y) {
+ facx = (float)w / (float)ibuf->x;
+ facy = (float)h / (float)ibuf->y;
+ }
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state,
+ (float)rect->xmin,
+ (float)rect->ymin,
+ ibuf->x,
+ ibuf->y,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ GL_NEAREST,
+ ibuf->rect,
+ facx,
+ facy,
+ NULL);
+
+ GPU_blend(false);
+
+# if 0
+ // restore scissortest
+ GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+# endif
#endif
}
@@ -687,1468 +734,1599 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, const uiWidgetColors *UN
*
* The next 4 parameters are the offsets for the view, not the zones.
*/
-void UI_draw_safe_areas(
- uint pos, float x1, float x2, float y1, float y2,
- const float title_aspect[2], const float action_aspect[2])
+void UI_draw_safe_areas(uint pos,
+ float x1,
+ float x2,
+ float y1,
+ float y2,
+ const float title_aspect[2],
+ const float action_aspect[2])
{
- const float size_x_half = (x2 - x1) * 0.5f;
- const float size_y_half = (y2 - y1) * 0.5f;
+ const float size_x_half = (x2 - x1) * 0.5f;
+ const float size_y_half = (y2 - y1) * 0.5f;
- const float *safe_areas[] = {title_aspect, action_aspect};
- const int safe_len = ARRAY_SIZE(safe_areas);
+ const float *safe_areas[] = {title_aspect, action_aspect};
+ const int safe_len = ARRAY_SIZE(safe_areas);
- for (int i = 0; i < safe_len; i++) {
- if (safe_areas[i][0] || safe_areas[i][1]) {
- float margin_x = safe_areas[i][0] * size_x_half;
- float margin_y = safe_areas[i][1] * size_y_half;
+ for (int i = 0; i < safe_len; i++) {
+ if (safe_areas[i][0] || safe_areas[i][1]) {
+ float margin_x = safe_areas[i][0] * size_x_half;
+ float margin_y = safe_areas[i][1] * size_y_half;
- float minx = x1 + margin_x;
- float miny = y1 + margin_y;
- float maxx = x2 - margin_x;
- float maxy = y2 - margin_y;
+ float minx = x1 + margin_x;
+ float miny = y1 + margin_y;
+ float maxx = x2 - margin_x;
+ float maxy = y2 - margin_y;
- imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
- }
- }
+ imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
+ }
+ }
}
-
static void draw_scope_end(const rctf *rect, GLint *scissor)
{
- /* restore scissortest */
- GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+ /* restore scissortest */
+ GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- /* outline */
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
- UI_draw_roundbox_4fv(false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color);
+ /* outline */
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
+ UI_draw_roundbox_4fv(
+ false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color);
}
-static void histogram_draw_one(
- float r, float g, float b, float alpha,
- float x, float y, float w, float h, const float *data, int res, const bool is_line,
- uint pos_attr)
+static void histogram_draw_one(float r,
+ float g,
+ float b,
+ float alpha,
+ float x,
+ float y,
+ float w,
+ float h,
+ const float *data,
+ int res,
+ const bool is_line,
+ uint pos_attr)
{
- float color[4] = {r, g, b, alpha};
-
- /* that can happen */
- if (res == 0) {
- return;
- }
-
- GPU_line_smooth(true);
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
-
- immUniformColor4fv(color);
-
- if (is_line) {
- /* curve outline */
- GPU_line_width(1.5);
-
- immBegin(GPU_PRIM_LINE_STRIP, res);
- for (int i = 0; i < res; i++) {
- float x2 = x + i * (w / (float)res);
- immVertex2f(pos_attr, x2, y + (data[i] * h));
- }
- immEnd();
- }
- else {
- /* under the curve */
- immBegin(GPU_PRIM_TRI_STRIP, res * 2);
- immVertex2f(pos_attr, x, y);
- immVertex2f(pos_attr, x, y + (data[0] * h));
- for (int i = 1; i < res; i++) {
- float x2 = x + i * (w / (float)res);
- immVertex2f(pos_attr, x2, y + (data[i] * h));
- immVertex2f(pos_attr, x2, y);
- }
- immEnd();
-
- /* curve outline */
- immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
-
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- immBegin(GPU_PRIM_LINE_STRIP, res);
- for (int i = 0; i < res; i++) {
- float x2 = x + i * (w / (float)res);
- immVertex2f(pos_attr, x2, y + (data[i] * h));
- }
- immEnd();
- }
-
- GPU_line_smooth(false);
+ float color[4] = {r, g, b, alpha};
+
+ /* that can happen */
+ if (res == 0) {
+ return;
+ }
+
+ GPU_line_smooth(true);
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
+
+ immUniformColor4fv(color);
+
+ if (is_line) {
+ /* curve outline */
+ GPU_line_width(1.5);
+
+ immBegin(GPU_PRIM_LINE_STRIP, res);
+ for (int i = 0; i < res; i++) {
+ float x2 = x + i * (w / (float)res);
+ immVertex2f(pos_attr, x2, y + (data[i] * h));
+ }
+ immEnd();
+ }
+ else {
+ /* under the curve */
+ immBegin(GPU_PRIM_TRI_STRIP, res * 2);
+ immVertex2f(pos_attr, x, y);
+ immVertex2f(pos_attr, x, y + (data[0] * h));
+ for (int i = 1; i < res; i++) {
+ float x2 = x + i * (w / (float)res);
+ immVertex2f(pos_attr, x2, y + (data[i] * h));
+ immVertex2f(pos_attr, x2, y);
+ }
+ immEnd();
+
+ /* curve outline */
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
+
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ immBegin(GPU_PRIM_LINE_STRIP, res);
+ for (int i = 0; i < res; i++) {
+ float x2 = x + i * (w / (float)res);
+ immVertex2f(pos_attr, x2, y + (data[i] * h));
+ }
+ immEnd();
+ }
+
+ GPU_line_smooth(false);
}
#define HISTOGRAM_TOT_GRID_LINES 4
-void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar), uiBut *but, const uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_HISTOGRAM(ARegion *UNUSED(ar),
+ uiBut *but,
+ const uiWidgetColors *UNUSED(wcol),
+ const rcti *recti)
{
- Histogram *hist = (Histogram *)but->poin;
- int res = hist->x_resolution;
- const bool is_line = (hist->flag & HISTO_FLAG_LINE) != 0;
-
- rctf rect = {
- .xmin = (float)recti->xmin + 1,
- .xmax = (float)recti->xmax - 1,
- .ymin = (float)recti->ymin + 1,
- .ymax = (float)recti->ymax - 1,
- };
-
- float w = BLI_rctf_size_x(&rect);
- float h = BLI_rctf_size_y(&rect) * hist->ymax;
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- float color[4];
- UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
-
- /* need scissor test, histogram can draw outside of boundary */
- int scissor[4];
- GPU_scissor_get_i(scissor);
- GPU_scissor(
- (rect.xmin - 1),
- (rect.ymin - 1),
- (rect.xmax + 1) - (rect.xmin - 1),
- (rect.ymax + 1) - (rect.ymin - 1));
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
- /* draw grid lines here */
- for (int i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
- const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES;
-
- /* so we can tell the 1.0 color point */
- if (i == HISTOGRAM_TOT_GRID_LINES) {
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
- }
-
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(pos, rect.xmin, rect.ymin + fac * h);
- immVertex2f(pos, rect.xmax, rect.ymin + fac * h);
-
- immVertex2f(pos, rect.xmin + fac * w, rect.ymin);
- immVertex2f(pos, rect.xmin + fac * w, rect.ymax);
-
- immEnd();
- }
-
- if (hist->mode == HISTO_MODE_LUMA) {
- histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line, pos);
- }
- else if (hist->mode == HISTO_MODE_ALPHA) {
- histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos);
- }
- else {
- if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R) {
- histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos);
- }
- if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G) {
- histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos);
- }
- if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B) {
- histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos);
- }
- }
-
- immUnbindProgram();
-
- /* outline */
- draw_scope_end(&rect, scissor);
+ Histogram *hist = (Histogram *)but->poin;
+ int res = hist->x_resolution;
+ const bool is_line = (hist->flag & HISTO_FLAG_LINE) != 0;
+
+ rctf rect = {
+ .xmin = (float)recti->xmin + 1,
+ .xmax = (float)recti->xmax - 1,
+ .ymin = (float)recti->ymin + 1,
+ .ymax = (float)recti->ymax - 1,
+ };
+
+ float w = BLI_rctf_size_x(&rect);
+ float h = BLI_rctf_size_y(&rect) * hist->ymax;
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ float color[4];
+ UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(
+ true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+
+ /* need scissor test, histogram can draw outside of boundary */
+ int scissor[4];
+ GPU_scissor_get_i(scissor);
+ GPU_scissor((rect.xmin - 1),
+ (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
+ /* draw grid lines here */
+ for (int i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
+ const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES;
+
+ /* so we can tell the 1.0 color point */
+ if (i == HISTOGRAM_TOT_GRID_LINES) {
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
+ }
+
+ immBegin(GPU_PRIM_LINES, 4);
+
+ immVertex2f(pos, rect.xmin, rect.ymin + fac * h);
+ immVertex2f(pos, rect.xmax, rect.ymin + fac * h);
+
+ immVertex2f(pos, rect.xmin + fac * w, rect.ymin);
+ immVertex2f(pos, rect.xmin + fac * w, rect.ymax);
+
+ immEnd();
+ }
+
+ if (hist->mode == HISTO_MODE_LUMA) {
+ histogram_draw_one(
+ 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line, pos);
+ }
+ else if (hist->mode == HISTO_MODE_ALPHA) {
+ histogram_draw_one(
+ 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos);
+ }
+ else {
+ if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R) {
+ histogram_draw_one(
+ 1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos);
+ }
+ if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G) {
+ histogram_draw_one(
+ 0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos);
+ }
+ if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B) {
+ histogram_draw_one(
+ 0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos);
+ }
+ }
+
+ immUnbindProgram();
+
+ /* outline */
+ draw_scope_end(&rect, scissor);
}
#undef HISTOGRAM_TOT_GRID_LINES
static void waveform_draw_one(float *waveform, int nbr, const float col[3])
{
- GPUVertFormat format = {0};
- uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPUVertFormat format = {0};
+ uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, nbr);
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, nbr);
- GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
+ GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
- /* TODO store the GPUBatch inside the scope */
- GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
- GPU_batch_draw(batch);
+ /* TODO store the GPUBatch inside the scope */
+ GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
+ GPU_batch_draw(batch);
- GPU_batch_discard(batch);
+ GPU_batch_discard(batch);
}
-void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar), uiBut *but, const uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_WAVEFORM(ARegion *UNUSED(ar),
+ uiBut *but,
+ const uiWidgetColors *UNUSED(wcol),
+ const rcti *recti)
{
- Scopes *scopes = (Scopes *)but->poin;
- int scissor[4];
- float colors[3][3];
- float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
- /* colors pre multiplied by alpha for speed up */
- float colors_alpha[3][3], colorsycc_alpha[3][3];
- float min, max;
-
- if (scopes == NULL) {
- return;
- }
-
- rctf rect = {
- .xmin = (float)recti->xmin + 1,
- .xmax = (float)recti->xmax - 1,
- .ymin = (float)recti->ymin + 1,
- .ymax = (float)recti->ymax - 1,
- };
-
- if (scopes->wavefrm_yfac < 0.5f) {
- scopes->wavefrm_yfac = 0.98f;
- }
- float w = BLI_rctf_size_x(&rect) - 7;
- float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
- float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f;
- float w3 = w / 3.0f;
-
- /* log scale for alpha */
- float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha;
-
- unit_m3(colors);
-
- for (int c = 0; c < 3; c++) {
- for (int i = 0; i < 3; i++) {
- colors_alpha[c][i] = colors[c][i] * alpha;
- colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
- }
- }
-
- /* Flush text cache before changing scissors. */
- BLF_batch_draw_flush();
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- float color[4];
- UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
-
- /* need scissor test, waveform can draw outside of boundary */
- GPU_scissor_get_i(scissor);
- GPU_scissor(
- (rect.xmin - 1),
- (rect.ymin - 1),
- (rect.xmax + 1) - (rect.xmin - 1),
- (rect.ymax + 1) - (rect.ymin - 1));
-
- /* draw scale numbers first before binding any shader */
- for (int i = 0; i < 6; i++) {
- char str[4];
- BLI_snprintf(str, sizeof(str), "%-3d", i * 20);
- str[3] = '\0';
- BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f);
- BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1);
- }
-
- /* Flush text cache before drawing things on top. */
- BLF_batch_draw_flush();
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
-
- /* draw grid lines here */
- immBegin(GPU_PRIM_LINES, 12);
-
- for (int i = 0; i < 6; i++) {
- immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
- immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h);
- }
-
- immEnd();
-
- /* 3 vertical separation */
- if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
- immBegin(GPU_PRIM_LINES, 4);
-
- for (int i = 1; i < 3; i++) {
- immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
- immVertex2f(pos, rect.xmin + i * w3, rect.ymax);
- }
-
- immEnd();
- }
-
- /* separate min max zone on the right */
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, rect.xmin + w, rect.ymin);
- immVertex2f(pos, rect.xmin + w, rect.ymax);
- immEnd();
-
- /* 16-235-240 level in case of ITU-R BT601/709 */
- immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
- if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) {
- immBegin(GPU_PRIM_LINES, 8);
-
- immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
- immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
-
- immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f);
- immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
-
- immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f);
- immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
-
- immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f);
- immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
-
- immEnd();
- }
- /* 7.5 IRE black point level for NTSC */
- if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
- immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
- immEnd();
- }
-
- if (scopes->ok && scopes->waveform_1 != NULL) {
- glBlendFunc(GL_ONE, GL_ONE);
- GPU_point_size(1.0);
-
- /* LUMA (1 channel) */
- if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
- float col[3] = {alpha, alpha, alpha};
-
- GPU_matrix_push();
- GPU_matrix_translate_2f(rect.xmin, yofs);
- GPU_matrix_scale_2f(w, h);
-
- waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
-
- GPU_matrix_pop();
-
- /* min max */
- immUniformColor3f(0.5f, 0.5f, 0.5f);
- min = yofs + scopes->minmax[0][0] * h;
- max = yofs + scopes->minmax[0][1] * h;
- CLAMP(min, rect.ymin, rect.ymax);
- CLAMP(max, rect.ymin, rect.ymax);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, rect.xmax - 3, min);
- immVertex2f(pos, rect.xmax - 3, max);
- immEnd();
- }
- /* RGB (3 channel) */
- else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
- GPU_matrix_push();
- GPU_matrix_translate_2f(rect.xmin, yofs);
- GPU_matrix_scale_2f(w, h);
-
- waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]);
- waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]);
- waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]);
-
- GPU_matrix_pop();
- }
- /* PARADE / YCC (3 channels) */
- else if (ELEM(scopes->wavefrm_mode,
- SCOPES_WAVEFRM_RGB_PARADE,
- SCOPES_WAVEFRM_YCC_601,
- SCOPES_WAVEFRM_YCC_709,
- SCOPES_WAVEFRM_YCC_JPEG
- ))
- {
- int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE);
-
- GPU_matrix_push();
- GPU_matrix_translate_2f(rect.xmin, yofs);
- GPU_matrix_scale_2f(w3, h);
-
- waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
-
- GPU_matrix_translate_2f(1.0f, 0.0f);
- waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
-
- GPU_matrix_translate_2f(1.0f, 0.0f);
- waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
-
- GPU_matrix_pop();
- }
-
- /* min max */
- if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA ) {
- for (int c = 0; c < 3; c++) {
- if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB_PARADE, SCOPES_WAVEFRM_RGB)) {
- immUniformColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
- }
- else {
- immUniformColor3f(colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
- }
- min = yofs + scopes->minmax[c][0] * h;
- max = yofs + scopes->minmax[c][1] * h;
- CLAMP(min, rect.ymin, rect.ymax);
- CLAMP(max, rect.ymin, rect.ymax);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, rect.xmin + w + 2 + c * 2, min);
- immVertex2f(pos, rect.xmin + w + 2 + c * 2, max);
- immEnd();
- }
- }
- }
-
- immUnbindProgram();
-
- /* outline */
- draw_scope_end(&rect, scissor);
-
- GPU_blend(false);
+ Scopes *scopes = (Scopes *)but->poin;
+ int scissor[4];
+ float colors[3][3];
+ float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
+ /* colors pre multiplied by alpha for speed up */
+ float colors_alpha[3][3], colorsycc_alpha[3][3];
+ float min, max;
+
+ if (scopes == NULL) {
+ return;
+ }
+
+ rctf rect = {
+ .xmin = (float)recti->xmin + 1,
+ .xmax = (float)recti->xmax - 1,
+ .ymin = (float)recti->ymin + 1,
+ .ymax = (float)recti->ymax - 1,
+ };
+
+ if (scopes->wavefrm_yfac < 0.5f) {
+ scopes->wavefrm_yfac = 0.98f;
+ }
+ float w = BLI_rctf_size_x(&rect) - 7;
+ float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
+ float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f;
+ float w3 = w / 3.0f;
+
+ /* log scale for alpha */
+ float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha;
+
+ unit_m3(colors);
+
+ for (int c = 0; c < 3; c++) {
+ for (int i = 0; i < 3; i++) {
+ colors_alpha[c][i] = colors[c][i] * alpha;
+ colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
+ }
+ }
+
+ /* Flush text cache before changing scissors. */
+ BLF_batch_draw_flush();
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ float color[4];
+ UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(
+ true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+
+ /* need scissor test, waveform can draw outside of boundary */
+ GPU_scissor_get_i(scissor);
+ GPU_scissor((rect.xmin - 1),
+ (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
+
+ /* draw scale numbers first before binding any shader */
+ for (int i = 0; i < 6; i++) {
+ char str[4];
+ BLI_snprintf(str, sizeof(str), "%-3d", i * 20);
+ str[3] = '\0';
+ BLF_color4f(BLF_default(), 1.0f, 1.0f, 1.0f, 0.08f);
+ BLF_draw_default(rect.xmin + 1, yofs - 5 + (i * 0.2f) * h, 0, str, sizeof(str) - 1);
+ }
+
+ /* Flush text cache before drawing things on top. */
+ BLF_batch_draw_flush();
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
+
+ /* draw grid lines here */
+ immBegin(GPU_PRIM_LINES, 12);
+
+ for (int i = 0; i < 6; i++) {
+ immVertex2f(pos, rect.xmin + 22, yofs + (i * 0.2f) * h);
+ immVertex2f(pos, rect.xmax + 1, yofs + (i * 0.2f) * h);
+ }
+
+ immEnd();
+
+ /* 3 vertical separation */
+ if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
+ immBegin(GPU_PRIM_LINES, 4);
+
+ for (int i = 1; i < 3; i++) {
+ immVertex2f(pos, rect.xmin + i * w3, rect.ymin);
+ immVertex2f(pos, rect.xmin + i * w3, rect.ymax);
+ }
+
+ immEnd();
+ }
+
+ /* separate min max zone on the right */
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmin + w, rect.ymin);
+ immVertex2f(pos, rect.xmin + w, rect.ymax);
+ immEnd();
+
+ /* 16-235-240 level in case of ITU-R BT601/709 */
+ immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
+ if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) {
+ immBegin(GPU_PRIM_LINES, 8);
+
+ immVertex2f(pos, rect.xmin + 22, yofs + h * 16.0f / 255.0f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
+
+ immVertex2f(pos, rect.xmin + 22, yofs + h * 235.0f / 255.0f);
+ immVertex2f(pos, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
+
+ immVertex2f(pos, rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
+
+ immVertex2f(pos, rect.xmin + w3, yofs + h * 240.0f / 255.0f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
+
+ immEnd();
+ }
+ /* 7.5 IRE black point level for NTSC */
+ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmin, yofs + h * 0.075f);
+ immVertex2f(pos, rect.xmax + 1, yofs + h * 0.075f);
+ immEnd();
+ }
+
+ if (scopes->ok && scopes->waveform_1 != NULL) {
+ glBlendFunc(GL_ONE, GL_ONE);
+ GPU_point_size(1.0);
+
+ /* LUMA (1 channel) */
+ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
+ float col[3] = {alpha, alpha, alpha};
+
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(rect.xmin, yofs);
+ GPU_matrix_scale_2f(w, h);
+
+ waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, col);
+
+ GPU_matrix_pop();
+
+ /* min max */
+ immUniformColor3f(0.5f, 0.5f, 0.5f);
+ min = yofs + scopes->minmax[0][0] * h;
+ max = yofs + scopes->minmax[0][1] * h;
+ CLAMP(min, rect.ymin, rect.ymax);
+ CLAMP(max, rect.ymin, rect.ymax);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmax - 3, min);
+ immVertex2f(pos, rect.xmax - 3, max);
+ immEnd();
+ }
+ /* RGB (3 channel) */
+ else if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(rect.xmin, yofs);
+ GPU_matrix_scale_2f(w, h);
+
+ waveform_draw_one(scopes->waveform_1, scopes->waveform_tot, colors_alpha[0]);
+ waveform_draw_one(scopes->waveform_2, scopes->waveform_tot, colors_alpha[1]);
+ waveform_draw_one(scopes->waveform_3, scopes->waveform_tot, colors_alpha[2]);
+
+ GPU_matrix_pop();
+ }
+ /* PARADE / YCC (3 channels) */
+ else if (ELEM(scopes->wavefrm_mode,
+ SCOPES_WAVEFRM_RGB_PARADE,
+ SCOPES_WAVEFRM_YCC_601,
+ SCOPES_WAVEFRM_YCC_709,
+ SCOPES_WAVEFRM_YCC_JPEG)) {
+ int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE);
+
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(rect.xmin, yofs);
+ GPU_matrix_scale_2f(w3, h);
+
+ waveform_draw_one(
+ scopes->waveform_1, scopes->waveform_tot, (rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
+
+ GPU_matrix_translate_2f(1.0f, 0.0f);
+ waveform_draw_one(
+ scopes->waveform_2, scopes->waveform_tot, (rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
+
+ GPU_matrix_translate_2f(1.0f, 0.0f);
+ waveform_draw_one(
+ scopes->waveform_3, scopes->waveform_tot, (rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
+
+ GPU_matrix_pop();
+ }
+
+ /* min max */
+ if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
+ for (int c = 0; c < 3; c++) {
+ if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB_PARADE, SCOPES_WAVEFRM_RGB)) {
+ immUniformColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
+ }
+ else {
+ immUniformColor3f(
+ colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
+ }
+ min = yofs + scopes->minmax[c][0] * h;
+ max = yofs + scopes->minmax[c][1] * h;
+ CLAMP(min, rect.ymin, rect.ymax);
+ CLAMP(max, rect.ymin, rect.ymax);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, rect.xmin + w + 2 + c * 2, min);
+ immVertex2f(pos, rect.xmin + w + 2 + c * 2, max);
+ immEnd();
+ }
+ }
+ }
+
+ immUnbindProgram();
+
+ /* outline */
+ draw_scope_end(&rect, scissor);
+
+ GPU_blend(false);
}
static float polar_to_x(float center, float diam, float ampli, float angle)
{
- return center + diam * ampli * cosf(angle);
+ return center + diam * ampli * cosf(angle);
}
static float polar_to_y(float center, float diam, float ampli, float angle)
{
- return center + diam * ampli * sinf(angle);
+ return center + diam * ampli * sinf(angle);
}
-static void vectorscope_draw_target(uint pos, float centerx, float centery, float diam, const float colf[3])
+static void vectorscope_draw_target(
+ uint pos, float centerx, float centery, float diam, const float colf[3])
{
- float y, u, v;
- float tangle = 0.0f, tampli;
- float dangle, dampli, dangle2, dampli2;
-
- rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709);
-
- if (u > 0 && v >= 0) {
- tangle = atanf(v / u);
- }
- else if (u > 0 && v < 0) {
- tangle = atanf(v / u) + 2.0f * (float)M_PI;
- }
- else if (u < 0) {
- tangle = atanf(v / u) + (float)M_PI;
- }
- else if (u == 0 && v > 0.0f) {
- tangle = M_PI_2;
- }
- else if (u == 0 && v < 0.0f) {
- tangle = -M_PI_2;
- }
- tampli = sqrtf(u * u + v * v);
-
- /* small target vary by 2.5 degree and 2.5 IRE unit */
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
- dangle = DEG2RADF(2.5f);
- dampli = 2.5f / 200.0f;
- immBegin(GPU_PRIM_LINE_LOOP, 4);
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
- immEnd();
- /* big target vary by 10 degree and 20% amplitude */
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
- dangle = DEG2RADF(10.0f);
- dampli = 0.2f * tampli;
- dangle2 = DEG2RADF(5.0f);
- dampli2 = 0.5f * dampli;
- immBegin(GPU_PRIM_LINE_STRIP, 3);
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle), polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2));
- immEnd();
- immBegin(GPU_PRIM_LINE_STRIP, 3);
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle), polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2), polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2));
- immEnd();
- immBegin(GPU_PRIM_LINE_STRIP, 3);
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle), polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle), polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2));
- immEnd();
- immBegin(GPU_PRIM_LINE_STRIP, 3);
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle), polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle), polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
- immVertex2f(pos, polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2), polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2));
- immEnd();
+ float y, u, v;
+ float tangle = 0.0f, tampli;
+ float dangle, dampli, dangle2, dampli2;
+
+ rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v, BLI_YUV_ITU_BT709);
+
+ if (u > 0 && v >= 0) {
+ tangle = atanf(v / u);
+ }
+ else if (u > 0 && v < 0) {
+ tangle = atanf(v / u) + 2.0f * (float)M_PI;
+ }
+ else if (u < 0) {
+ tangle = atanf(v / u) + (float)M_PI;
+ }
+ else if (u == 0 && v > 0.0f) {
+ tangle = M_PI_2;
+ }
+ else if (u == 0 && v < 0.0f) {
+ tangle = -M_PI_2;
+ }
+ tampli = sqrtf(u * u + v * v);
+
+ /* small target vary by 2.5 degree and 2.5 IRE unit */
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
+ dangle = DEG2RADF(2.5f);
+ dampli = 2.5f / 200.0f;
+ immBegin(GPU_PRIM_LINE_LOOP, 4);
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli, tangle + dangle),
+ polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli, tangle + dangle),
+ polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli, tangle - dangle),
+ polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli, tangle - dangle),
+ polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
+ immEnd();
+ /* big target vary by 10 degree and 20% amplitude */
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.12f);
+ dangle = DEG2RADF(10.0f);
+ dampli = 0.2f * tampli;
+ dangle2 = DEG2RADF(5.0f);
+ dampli2 = 0.5f * dampli;
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle + dangle),
+ polar_to_y(centery, diam, tampli + dampli - dampli2, tangle + dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli, tangle + dangle),
+ polar_to_y(centery, diam, tampli + dampli, tangle + dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli, tangle + dangle - dangle2),
+ polar_to_y(centery, diam, tampli + dampli, tangle + dangle - dangle2));
+ immEnd();
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle + dangle),
+ polar_to_y(centery, diam, tampli - dampli + dampli2, tangle + dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli, tangle + dangle),
+ polar_to_y(centery, diam, tampli - dampli, tangle + dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli, tangle + dangle - dangle2),
+ polar_to_y(centery, diam, tampli - dampli, tangle + dangle - dangle2));
+ immEnd();
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli + dampli2, tangle - dangle),
+ polar_to_y(centery, diam, tampli - dampli + dampli2, tangle - dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli, tangle - dangle),
+ polar_to_y(centery, diam, tampli - dampli, tangle - dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli - dampli, tangle - dangle + dangle2),
+ polar_to_y(centery, diam, tampli - dampli, tangle - dangle + dangle2));
+ immEnd();
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli - dampli2, tangle - dangle),
+ polar_to_y(centery, diam, tampli + dampli - dampli2, tangle - dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli, tangle - dangle),
+ polar_to_y(centery, diam, tampli + dampli, tangle - dangle));
+ immVertex2f(pos,
+ polar_to_x(centerx, diam, tampli + dampli, tangle - dangle + dangle2),
+ polar_to_y(centery, diam, tampli + dampli, tangle - dangle + dangle2));
+ immEnd();
}
-void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar), uiBut *but, const uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(ar),
+ uiBut *but,
+ const uiWidgetColors *UNUSED(wcol),
+ const rcti *recti)
{
- const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
- Scopes *scopes = (Scopes *)but->poin;
-
- const float colors[6][3] = {
- {0.75, 0.0, 0.0}, {0.75, 0.75, 0.0}, {0.0, 0.75, 0.0},
- {0.0, 0.75, 0.75}, {0.0, 0.0, 0.75}, {0.75, 0.0, 0.75}};
-
- rctf rect = {
- .xmin = (float)recti->xmin + 1,
- .xmax = (float)recti->xmax - 1,
- .ymin = (float)recti->ymin + 1,
- .ymax = (float)recti->ymax - 1,
- };
-
- float w = BLI_rctf_size_x(&rect);
- float h = BLI_rctf_size_y(&rect);
- float centerx = rect.xmin + w * 0.5f;
- float centery = rect.ymin + h * 0.5f;
- float diam = (w < h) ? w : h;
-
- float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- float color[4];
- UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
-
- /* need scissor test, hvectorscope can draw outside of boundary */
- int scissor[4];
- GPU_scissor_get_i(scissor);
- GPU_scissor(
- (rect.xmin - 1),
- (rect.ymin - 1),
- (rect.xmax + 1) - (rect.xmin - 1),
- (rect.ymax + 1) - (rect.ymin - 1));
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
- /* draw grid elements */
- /* cross */
- immBegin(GPU_PRIM_LINES, 4);
-
- immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
- immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
-
- immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5);
- immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5);
-
- immEnd();
-
- /* circles */
- for (int j = 0; j < 5; j++) {
- const int increment = 15;
- immBegin(GPU_PRIM_LINE_LOOP, (int)(360 / increment));
- for (int i = 0; i <= 360 - increment; i += increment) {
- const float a = DEG2RADF((float)i);
- const float r = (j + 1) * 0.1f;
- immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
- }
- immEnd();
- }
- /* skin tone line */
- immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
- immVertex2f(pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
- immEnd();
-
- /* saturation points */
- for (int i = 0; i < 6; i++) {
- vectorscope_draw_target(pos, centerx, centery, diam, colors[i]);
- }
-
- if (scopes->ok && scopes->vecscope != NULL) {
- /* pixel point cloud */
- float col[3] = {alpha, alpha, alpha};
-
- glBlendFunc(GL_ONE, GL_ONE);
- GPU_point_size(1.0);
-
- GPU_matrix_push();
- GPU_matrix_translate_2f(centerx, centery);
- GPU_matrix_scale_1f(diam);
-
- waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
-
- GPU_matrix_pop();
- }
-
- immUnbindProgram();
-
- /* outline */
- draw_scope_end(&rect, scissor);
-
- GPU_blend(false);
+ const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
+ Scopes *scopes = (Scopes *)but->poin;
+
+ const float colors[6][3] = {{0.75, 0.0, 0.0},
+ {0.75, 0.75, 0.0},
+ {0.0, 0.75, 0.0},
+ {0.0, 0.75, 0.75},
+ {0.0, 0.0, 0.75},
+ {0.75, 0.0, 0.75}};
+
+ rctf rect = {
+ .xmin = (float)recti->xmin + 1,
+ .xmax = (float)recti->xmax - 1,
+ .ymin = (float)recti->ymin + 1,
+ .ymax = (float)recti->ymax - 1,
+ };
+
+ float w = BLI_rctf_size_x(&rect);
+ float h = BLI_rctf_size_y(&rect);
+ float centerx = rect.xmin + w * 0.5f;
+ float centery = rect.ymin + h * 0.5f;
+ float diam = (w < h) ? w : h;
+
+ float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ float color[4];
+ UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(
+ true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+
+ /* need scissor test, hvectorscope can draw outside of boundary */
+ int scissor[4];
+ GPU_scissor_get_i(scissor);
+ GPU_scissor((rect.xmin - 1),
+ (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.08f);
+ /* draw grid elements */
+ /* cross */
+ immBegin(GPU_PRIM_LINES, 4);
+
+ immVertex2f(pos, centerx - (diam * 0.5f) - 5, centery);
+ immVertex2f(pos, centerx + (diam * 0.5f) + 5, centery);
+
+ immVertex2f(pos, centerx, centery - (diam * 0.5f) - 5);
+ immVertex2f(pos, centerx, centery + (diam * 0.5f) + 5);
+
+ immEnd();
+
+ /* circles */
+ for (int j = 0; j < 5; j++) {
+ const int increment = 15;
+ immBegin(GPU_PRIM_LINE_LOOP, (int)(360 / increment));
+ for (int i = 0; i <= 360 - increment; i += increment) {
+ const float a = DEG2RADF((float)i);
+ const float r = (j + 1) * 0.1f;
+ immVertex2f(pos, polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
+ }
+ immEnd();
+ }
+ /* skin tone line */
+ immUniformColor4f(1.0f, 0.4f, 0.0f, 0.2f);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(
+ pos, polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5f, skin_rad));
+ immVertex2f(
+ pos, polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1f, skin_rad));
+ immEnd();
+
+ /* saturation points */
+ for (int i = 0; i < 6; i++) {
+ vectorscope_draw_target(pos, centerx, centery, diam, colors[i]);
+ }
+
+ if (scopes->ok && scopes->vecscope != NULL) {
+ /* pixel point cloud */
+ float col[3] = {alpha, alpha, alpha};
+
+ glBlendFunc(GL_ONE, GL_ONE);
+ GPU_point_size(1.0);
+
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(centerx, centery);
+ GPU_matrix_scale_1f(diam);
+
+ waveform_draw_one(scopes->vecscope, scopes->waveform_tot, col);
+
+ GPU_matrix_pop();
+ }
+
+ immUnbindProgram();
+
+ /* outline */
+ draw_scope_end(&rect, scissor);
+
+ GPU_blend(false);
}
-static void ui_draw_colorband_handle_tri_hlight(uint pos, float x1, float y1, float halfwidth, float height)
+static void ui_draw_colorband_handle_tri_hlight(
+ uint pos, float x1, float y1, float halfwidth, float height)
{
- GPU_line_smooth(true);
+ GPU_line_smooth(true);
- immBegin(GPU_PRIM_LINE_STRIP, 3);
- immVertex2f(pos, x1 + halfwidth, y1);
- immVertex2f(pos, x1, y1 + height);
- immVertex2f(pos, x1 - halfwidth, y1);
- immEnd();
+ immBegin(GPU_PRIM_LINE_STRIP, 3);
+ immVertex2f(pos, x1 + halfwidth, y1);
+ immVertex2f(pos, x1, y1 + height);
+ immVertex2f(pos, x1 - halfwidth, y1);
+ immEnd();
- GPU_line_smooth(false);
+ GPU_line_smooth(false);
}
-static void ui_draw_colorband_handle_tri(uint pos, float x1, float y1, float halfwidth, float height, bool fill)
+static void ui_draw_colorband_handle_tri(
+ uint pos, float x1, float y1, float halfwidth, float height, bool fill)
{
- if (fill) {
- GPU_polygon_smooth(true);
- }
- else {
- GPU_line_smooth(true);
- }
-
- immBegin(fill ? GPU_PRIM_TRIS : GPU_PRIM_LINE_LOOP, 3);
- immVertex2f(pos, x1 + halfwidth, y1);
- immVertex2f(pos, x1, y1 + height);
- immVertex2f(pos, x1 - halfwidth, y1);
- immEnd();
-
- if (fill) {
- GPU_polygon_smooth(false);
- }
- else {
- GPU_line_smooth(false);
- }
+ if (fill) {
+ GPU_polygon_smooth(true);
+ }
+ else {
+ GPU_line_smooth(true);
+ }
+
+ immBegin(fill ? GPU_PRIM_TRIS : GPU_PRIM_LINE_LOOP, 3);
+ immVertex2f(pos, x1 + halfwidth, y1);
+ immVertex2f(pos, x1, y1 + height);
+ immVertex2f(pos, x1 - halfwidth, y1);
+ immEnd();
+
+ if (fill) {
+ GPU_polygon_smooth(false);
+ }
+ else {
+ GPU_line_smooth(false);
+ }
}
-static void ui_draw_colorband_handle_box(uint pos, float x1, float y1, float x2, float y2, bool fill)
+static void ui_draw_colorband_handle_box(
+ uint pos, float x1, float y1, float x2, float y2, bool fill)
{
- immBegin(fill ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4);
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x1, y2);
- immVertex2f(pos, x2, y2);
- immVertex2f(pos, x2, y1);
- immEnd();
+ immBegin(fill ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_LOOP, 4);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x2, y1);
+ immEnd();
}
-static void ui_draw_colorband_handle(
- uint shdr_pos, const rcti *rect, float x,
- const float rgb[3], struct ColorManagedDisplay *display,
- bool active)
+static void ui_draw_colorband_handle(uint shdr_pos,
+ const rcti *rect,
+ float x,
+ const float rgb[3],
+ struct ColorManagedDisplay *display,
+ bool active)
{
- const float sizey = BLI_rcti_size_y(rect);
- const float min_width = 3.0f;
- float colf[3] = {UNPACK3(rgb)};
+ const float sizey = BLI_rcti_size_y(rect);
+ const float min_width = 3.0f;
+ float colf[3] = {UNPACK3(rgb)};
- float half_width = floorf(sizey / 3.5f);
- float height = half_width * 1.4f;
+ float half_width = floorf(sizey / 3.5f);
+ float height = half_width * 1.4f;
- float y1 = rect->ymin + (sizey * 0.16f);
- float y2 = rect->ymax;
+ float y1 = rect->ymin + (sizey * 0.16f);
+ float y2 = rect->ymax;
- /* align to pixels */
- x = floorf(x + 0.5f);
- y1 = floorf(y1 + 0.5f);
+ /* align to pixels */
+ x = floorf(x + 0.5f);
+ y1 = floorf(y1 + 0.5f);
- if (active || half_width < min_width) {
- immUnbindProgram();
+ if (active || half_width < min_width) {
+ immUnbindProgram();
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- immUniform1i("colors_len", 2); /* "advanced" mode */
- immUniformArray4fv("colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
- immUniform1f("dash_width", active ? 4.0f : 2.0f);
+ immUniform1i("colors_len", 2); /* "advanced" mode */
+ immUniformArray4fv(
+ "colors", (float *)(float[][4]){{0.8f, 0.8f, 0.8f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
+ immUniform1f("dash_width", active ? 4.0f : 2.0f);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(shdr_pos, x, y1);
- immVertex2f(shdr_pos, x, y2);
- immEnd();
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(shdr_pos, x, y1);
+ immVertex2f(shdr_pos, x, y2);
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* hide handles when zoomed out too far */
- if (half_width < min_width) {
- return;
- }
- }
+ /* hide handles when zoomed out too far */
+ if (half_width < min_width) {
+ return;
+ }
+ }
- /* shift handle down */
- y1 -= half_width;
+ /* shift handle down */
+ y1 -= half_width;
- immUniformColor3ub(0, 0, 0);
- ui_draw_colorband_handle_box(shdr_pos, x - half_width, y1 - 1, x + half_width, y1 + height, false);
+ immUniformColor3ub(0, 0, 0);
+ ui_draw_colorband_handle_box(
+ shdr_pos, x - half_width, y1 - 1, x + half_width, y1 + height, false);
- /* draw all triangles blended */
- GPU_blend(true);
+ /* draw all triangles blended */
+ GPU_blend(true);
- ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true);
+ ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true);
- if (active) {
- immUniformColor3ub(196, 196, 196);
- }
- else {
- immUniformColor3ub(96, 96, 96);
- }
- ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true);
+ if (active) {
+ immUniformColor3ub(196, 196, 196);
+ }
+ else {
+ immUniformColor3ub(96, 96, 96);
+ }
+ ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true);
- if (active) {
- immUniformColor3ub(255, 255, 255);
- }
- else {
- immUniformColor3ub(128, 128, 128);
- }
- ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height - 1, (half_width - 1), (half_width - 1));
+ if (active) {
+ immUniformColor3ub(255, 255, 255);
+ }
+ else {
+ immUniformColor3ub(128, 128, 128);
+ }
+ ui_draw_colorband_handle_tri_hlight(
+ shdr_pos, x, y1 + height - 1, (half_width - 1), (half_width - 1));
- immUniformColor3ub(0, 0, 0);
- ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height, half_width, half_width);
+ immUniformColor3ub(0, 0, 0);
+ ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height, half_width, half_width);
- GPU_blend(false);
+ GPU_blend(false);
- immUniformColor3ub(128, 128, 128);
- ui_draw_colorband_handle_box(shdr_pos, x - (half_width - 1), y1, x + (half_width - 1), y1 + height, true);
+ immUniformColor3ub(128, 128, 128);
+ ui_draw_colorband_handle_box(
+ shdr_pos, x - (half_width - 1), y1, x + (half_width - 1), y1 + height, true);
- if (display) {
- IMB_colormanagement_scene_linear_to_display_v3(colf, display);
- }
+ if (display) {
+ IMB_colormanagement_scene_linear_to_display_v3(colf, display);
+ }
- immUniformColor3fv(colf);
- ui_draw_colorband_handle_box(shdr_pos, x - (half_width - 2), y1 + 1, x + (half_width - 2), y1 + height - 2, true);
+ immUniformColor3fv(colf);
+ ui_draw_colorband_handle_box(
+ shdr_pos, x - (half_width - 2), y1 + 1, x + (half_width - 2), y1 + height - 2, true);
}
void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const rcti *rect)
{
- struct ColorManagedDisplay *display = ui_block_cm_display_get(but->block);
- uint pos_id, col_id;
-
- ColorBand *coba = (ColorBand *)(but->editcoba ? but->editcoba : but->poin);
- if (coba == NULL) {
- return;
- }
-
- float x1 = rect->xmin;
- float sizex = rect->xmax - x1;
- float sizey = BLI_rcti_size_y(rect);
- float sizey_solid = sizey * 0.25f;
- float y1 = rect->ymin;
-
- GPUVertFormat *format = immVertexFormat();
- pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
-
- /* Drawing the checkerboard. */
- immUniform4f("color1", UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, 1.0f);
- immUniform4f("color2", UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 1.0f);
- immUniform1i("size", 8);
- immRectf(pos_id, x1, y1, x1 + sizex, rect->ymax);
- immUnbindProgram();
-
- /* New format */
- format = immVertexFormat();
- pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- col_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- /* layer: color ramp */
- GPU_blend(true);
-
- CBData *cbd = coba->data;
-
- float v1[2], v2[2];
- float colf[4] = {0, 0, 0, 0}; /* initialize in case the colorband isn't valid */
-
- v1[1] = y1 + sizey_solid;
- v2[1] = rect->ymax;
-
- immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
- for (int a = 0; a <= sizex; a++) {
- float pos = ((float)a) / sizex;
- BKE_colorband_evaluate(coba, pos, colf);
- if (display) {
- IMB_colormanagement_scene_linear_to_display_v3(colf, display);
- }
-
- v1[0] = v2[0] = x1 + a;
-
- immAttr4fv(col_id, colf);
- immVertex2fv(pos_id, v1);
- immVertex2fv(pos_id, v2);
- }
- immEnd();
-
- /* layer: color ramp without alpha for reference when manipulating ramp properties */
- v1[1] = y1;
- v2[1] = y1 + sizey_solid;
-
- immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
- for (int a = 0; a <= sizex; a++) {
- float pos = ((float)a) / sizex;
- BKE_colorband_evaluate(coba, pos, colf);
- if (display) {
- IMB_colormanagement_scene_linear_to_display_v3(colf, display);
- }
-
- v1[0] = v2[0] = x1 + a;
-
- immAttr4f(col_id, colf[0], colf[1], colf[2], 1.0f);
- immVertex2fv(pos_id, v1);
- immVertex2fv(pos_id, v2);
- }
- immEnd();
-
- immUnbindProgram();
-
- GPU_blend(false);
-
- /* New format */
- format = immVertexFormat();
- pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* layer: box outline */
- immUniformColor4f(0.0f, 0.0f, 0.0f, 1.0f);
- imm_draw_box_wire_2d(pos_id, x1, y1, x1 + sizex, rect->ymax);
-
- /* layer: box outline */
- GPU_blend(true);
- immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos_id, x1, y1);
- immVertex2f(pos_id, x1 + sizex, y1);
- immEnd();
-
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos_id, x1, y1 - 1);
- immVertex2f(pos_id, x1 + sizex, y1 - 1);
- immEnd();
-
- GPU_blend(false);
-
- /* layer: draw handles */
- for (int a = 0; a < coba->tot; a++, cbd++) {
- if (a != coba->cur) {
- float pos = x1 + cbd->pos * (sizex - 1) + 1;
- ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, false);
- }
- }
-
- /* layer: active handle */
- if (coba->tot != 0) {
- cbd = &coba->data[coba->cur];
- float pos = x1 + cbd->pos * (sizex - 1) + 1;
- ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, true);
- }
-
- immUnbindProgram();
+ struct ColorManagedDisplay *display = ui_block_cm_display_get(but->block);
+ uint pos_id, col_id;
+
+ ColorBand *coba = (ColorBand *)(but->editcoba ? but->editcoba : but->poin);
+ if (coba == NULL) {
+ return;
+ }
+
+ float x1 = rect->xmin;
+ float sizex = rect->xmax - x1;
+ float sizey = BLI_rcti_size_y(rect);
+ float sizey_solid = sizey * 0.25f;
+ float y1 = rect->ymin;
+
+ GPUVertFormat *format = immVertexFormat();
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
+
+ /* Drawing the checkerboard. */
+ immUniform4f("color1",
+ UI_ALPHA_CHECKER_DARK / 255.0f,
+ UI_ALPHA_CHECKER_DARK / 255.0f,
+ UI_ALPHA_CHECKER_DARK / 255.0f,
+ 1.0f);
+ immUniform4f("color2",
+ UI_ALPHA_CHECKER_LIGHT / 255.0f,
+ UI_ALPHA_CHECKER_LIGHT / 255.0f,
+ UI_ALPHA_CHECKER_LIGHT / 255.0f,
+ 1.0f);
+ immUniform1i("size", 8);
+ immRectf(pos_id, x1, y1, x1 + sizex, rect->ymax);
+ immUnbindProgram();
+
+ /* New format */
+ format = immVertexFormat();
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ col_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ /* layer: color ramp */
+ GPU_blend(true);
+
+ CBData *cbd = coba->data;
+
+ float v1[2], v2[2];
+ float colf[4] = {0, 0, 0, 0}; /* initialize in case the colorband isn't valid */
+
+ v1[1] = y1 + sizey_solid;
+ v2[1] = rect->ymax;
+
+ immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
+ for (int a = 0; a <= sizex; a++) {
+ float pos = ((float)a) / sizex;
+ BKE_colorband_evaluate(coba, pos, colf);
+ if (display) {
+ IMB_colormanagement_scene_linear_to_display_v3(colf, display);
+ }
+
+ v1[0] = v2[0] = x1 + a;
+
+ immAttr4fv(col_id, colf);
+ immVertex2fv(pos_id, v1);
+ immVertex2fv(pos_id, v2);
+ }
+ immEnd();
+
+ /* layer: color ramp without alpha for reference when manipulating ramp properties */
+ v1[1] = y1;
+ v2[1] = y1 + sizey_solid;
+
+ immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2);
+ for (int a = 0; a <= sizex; a++) {
+ float pos = ((float)a) / sizex;
+ BKE_colorband_evaluate(coba, pos, colf);
+ if (display) {
+ IMB_colormanagement_scene_linear_to_display_v3(colf, display);
+ }
+
+ v1[0] = v2[0] = x1 + a;
+
+ immAttr4f(col_id, colf[0], colf[1], colf[2], 1.0f);
+ immVertex2fv(pos_id, v1);
+ immVertex2fv(pos_id, v2);
+ }
+ immEnd();
+
+ immUnbindProgram();
+
+ GPU_blend(false);
+
+ /* New format */
+ format = immVertexFormat();
+ pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* layer: box outline */
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+ imm_draw_box_wire_2d(pos_id, x1, y1, x1 + sizex, rect->ymax);
+
+ /* layer: box outline */
+ GPU_blend(true);
+ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos_id, x1, y1);
+ immVertex2f(pos_id, x1 + sizex, y1);
+ immEnd();
+
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.25f);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos_id, x1, y1 - 1);
+ immVertex2f(pos_id, x1 + sizex, y1 - 1);
+ immEnd();
+
+ GPU_blend(false);
+
+ /* layer: draw handles */
+ for (int a = 0; a < coba->tot; a++, cbd++) {
+ if (a != coba->cur) {
+ float pos = x1 + cbd->pos * (sizex - 1) + 1;
+ ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, false);
+ }
+ }
+
+ /* layer: active handle */
+ if (coba->tot != 0) {
+ cbd = &coba->data[coba->cur];
+ float pos = x1 + cbd->pos * (sizex - 1) + 1;
+ ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, true);
+ }
+
+ immUnbindProgram();
}
void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
{
- /* sphere color */
- float diffuse[3] = {1.0f, 1.0f, 1.0f};
- float light[3];
- float size;
-
- /* backdrop */
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_3ubAlpha(true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, (uchar *)wcol->inner, 255);
-
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
-
- /* setup lights */
- ui_but_v3_get(but, light);
-
- /* transform to button */
- GPU_matrix_push();
-
- if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect)) {
- size = 0.5f * BLI_rcti_size_x(rect);
- }
- else {
- size = 0.5f * BLI_rcti_size_y(rect);
- }
-
- GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect));
- GPU_matrix_scale_1f(size);
-
- GPUBatch *sphere = GPU_batch_preset_sphere(2);
- GPU_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
- GPU_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f);
- GPU_batch_uniform_3fv(sphere, "light", light);
- GPU_batch_draw(sphere);
-
- /* restore */
- glDisable(GL_CULL_FACE);
-
- /* AA circle */
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3ubv((uchar *)wcol->inner);
-
- GPU_blend(true);
- GPU_line_smooth(true);
- imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32);
- GPU_blend(false);
- GPU_line_smooth(false);
-
- /* matrix after circle */
- GPU_matrix_pop();
-
- immUnbindProgram();
+ /* sphere color */
+ float diffuse[3] = {1.0f, 1.0f, 1.0f};
+ float light[3];
+ float size;
+
+ /* backdrop */
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_3ubAlpha(
+ true, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f, (uchar *)wcol->inner, 255);
+
+ glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
+
+ /* setup lights */
+ ui_but_v3_get(but, light);
+
+ /* transform to button */
+ GPU_matrix_push();
+
+ if (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect)) {
+ size = 0.5f * BLI_rcti_size_x(rect);
+ }
+ else {
+ size = 0.5f * BLI_rcti_size_y(rect);
+ }
+
+ GPU_matrix_translate_2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect),
+ rect->ymin + 0.5f * BLI_rcti_size_y(rect));
+ GPU_matrix_scale_1f(size);
+
+ GPUBatch *sphere = GPU_batch_preset_sphere(2);
+ GPU_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+ GPU_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f);
+ GPU_batch_uniform_3fv(sphere, "light", light);
+ GPU_batch_draw(sphere);
+
+ /* restore */
+ glDisable(GL_CULL_FACE);
+
+ /* AA circle */
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ubv((uchar *)wcol->inner);
+
+ GPU_blend(true);
+ GPU_line_smooth(true);
+ imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32);
+ GPU_blend(false);
+ GPU_line_smooth(false);
+
+ /* matrix after circle */
+ GPU_matrix_pop();
+
+ immUnbindProgram();
}
-static void ui_draw_but_curve_grid(uint pos, const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step)
+static void ui_draw_but_curve_grid(
+ uint pos, const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step)
{
- float dx = step * zoomx;
- float fx = rect->xmin + zoomx * (-offsx);
- if (fx > rect->xmin) {
- fx -= dx * (floorf(fx - rect->xmin));
- }
-
- float dy = step * zoomy;
- float fy = rect->ymin + zoomy * (-offsy);
- if (fy > rect->ymin) {
- fy -= dy * (floorf(fy - rect->ymin));
- }
-
- float line_count = (
- floorf((rect->xmax - fx) / dx) + 1.0f +
- floorf((rect->ymax - fy) / dy) + 1.0f);
-
- immBegin(GPU_PRIM_LINES, (int)line_count * 2);
- while (fx < rect->xmax) {
- immVertex2f(pos, fx, rect->ymin);
- immVertex2f(pos, fx, rect->ymax);
- fx += dx;
- }
- while (fy < rect->ymax) {
- immVertex2f(pos, rect->xmin, fy);
- immVertex2f(pos, rect->xmax, fy);
- fy += dy;
- }
- immEnd();
-
+ float dx = step * zoomx;
+ float fx = rect->xmin + zoomx * (-offsx);
+ if (fx > rect->xmin) {
+ fx -= dx * (floorf(fx - rect->xmin));
+ }
+
+ float dy = step * zoomy;
+ float fy = rect->ymin + zoomy * (-offsy);
+ if (fy > rect->ymin) {
+ fy -= dy * (floorf(fy - rect->ymin));
+ }
+
+ float line_count = (floorf((rect->xmax - fx) / dx) + 1.0f + floorf((rect->ymax - fy) / dy) +
+ 1.0f);
+
+ immBegin(GPU_PRIM_LINES, (int)line_count * 2);
+ while (fx < rect->xmax) {
+ immVertex2f(pos, fx, rect->ymin);
+ immVertex2f(pos, fx, rect->ymax);
+ fx += dx;
+ }
+ while (fy < rect->ymax) {
+ immVertex2f(pos, rect->xmin, fy);
+ immVertex2f(pos, rect->xmax, fy);
+ fy += dy;
+ }
+ immEnd();
}
-
static void gl_shaded_color_get(const uchar color[3], int shade, uchar r_color[3])
{
- r_color[0] = color[0] - shade > 0 ? color[0] - shade : 0;
- r_color[1] = color[1] - shade > 0 ? color[1] - shade : 0;
- r_color[2] = color[2] - shade > 0 ? color[2] - shade : 0;
+ r_color[0] = color[0] - shade > 0 ? color[0] - shade : 0;
+ r_color[1] = color[1] - shade > 0 ? color[1] - shade : 0;
+ r_color[2] = color[2] - shade > 0 ? color[2] - shade : 0;
}
static void gl_shaded_color_get_fl(const uchar *color, int shade, float r_color[3])
{
- uchar color_shaded[3];
- gl_shaded_color_get(color, shade, color_shaded);
- rgb_uchar_to_float(r_color, color_shaded);
+ uchar color_shaded[3];
+ gl_shaded_color_get(color, shade, color_shaded);
+ rgb_uchar_to_float(r_color, color_shaded);
}
static void gl_shaded_color(uchar *color, int shade)
{
- uchar color_shaded[3];
- gl_shaded_color_get(color, shade, color_shaded);
- immUniformColor3ubv(color_shaded);
+ uchar color_shaded[3];
+ gl_shaded_color_get(color, shade, color_shaded);
+ immUniformColor3ubv(color_shaded);
}
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
{
- CurveMapping *cumap;
-
- if (but->editcumap) {
- cumap = but->editcumap;
- }
- else {
- cumap = (CurveMapping *)but->poin;
- }
-
- CurveMap *cuma = &cumap->cm[cumap->cur];
-
- /* need scissor test, curve can draw outside of boundary */
- int scissor[4];
- GPU_scissor_get_i(scissor);
- rcti scissor_new = {
- .xmin = rect->xmin,
- .ymin = rect->ymin,
- .xmax = rect->xmax,
- .ymax = rect->ymax,
- };
- rcti scissor_region = {0, ar->winx, 0, ar->winy};
- BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
- GPU_scissor(
- scissor_new.xmin,
- scissor_new.ymin,
- BLI_rcti_size_x(&scissor_new),
- BLI_rcti_size_y(&scissor_new));
-
- /* calculate offset and zoom */
- float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&cumap->curr);
- float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&cumap->curr);
- float offsx = cumap->curr.xmin - (1.0f / zoomx);
- float offsy = cumap->curr.ymin - (1.0f / zoomy);
-
- /* Do this first to not mess imm context */
- if (but->a1 == UI_GRAD_H) {
- /* magic trigger for curve backgrounds */
- float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
-
- rcti grid = {
- .xmin = rect->xmin + zoomx * (-offsx),
- .xmax = grid.xmin + zoomx,
- .ymin = rect->ymin + zoomy * (-offsy),
- .ymax = grid.ymin + zoomy,
- };
-
- ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f);
- }
-
- GPU_line_width(1.0f);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* backdrop */
- float color_backdrop[4] = {0, 0, 0, 1};
-
- if (but->a1 == UI_GRAD_H) {
- /* grid, hsv uses different grid */
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0);
- immUniformColor4fv(color_backdrop);
- ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
- GPU_blend(false);
- }
- else {
- if (cumap->flag & CUMA_DO_CLIP) {
- gl_shaded_color_get_fl((uchar *)wcol->inner, -20, color_backdrop);
- immUniformColor3fv(color_backdrop);
- immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- immUniformColor3ubv((uchar *)wcol->inner);
- immRectf(pos,
- rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
- rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
- rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
- rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
- }
- else {
- rgb_uchar_to_float(color_backdrop, (const uchar *)wcol->inner);
- immUniformColor3fv(color_backdrop);
- immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- }
-
- /* grid, every 0.25 step */
- gl_shaded_color((uchar *)wcol->inner, -16);
- ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
- /* grid, every 1.0 step */
- gl_shaded_color((uchar *)wcol->inner, -24);
- ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
- /* axes */
- gl_shaded_color((uchar *)wcol->inner, -50);
- immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy));
- immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy));
- immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin);
- immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymax);
- immEnd();
- }
-
- /* cfra option */
- /* XXX 2.48 */
+ CurveMapping *cumap;
+
+ if (but->editcumap) {
+ cumap = but->editcumap;
+ }
+ else {
+ cumap = (CurveMapping *)but->poin;
+ }
+
+ CurveMap *cuma = &cumap->cm[cumap->cur];
+
+ /* need scissor test, curve can draw outside of boundary */
+ int scissor[4];
+ GPU_scissor_get_i(scissor);
+ rcti scissor_new = {
+ .xmin = rect->xmin,
+ .ymin = rect->ymin,
+ .xmax = rect->xmax,
+ .ymax = rect->ymax,
+ };
+ rcti scissor_region = {0, ar->winx, 0, ar->winy};
+ BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
+ GPU_scissor(scissor_new.xmin,
+ scissor_new.ymin,
+ BLI_rcti_size_x(&scissor_new),
+ BLI_rcti_size_y(&scissor_new));
+
+ /* calculate offset and zoom */
+ float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&cumap->curr);
+ float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&cumap->curr);
+ float offsx = cumap->curr.xmin - (1.0f / zoomx);
+ float offsy = cumap->curr.ymin - (1.0f / zoomy);
+
+ /* Do this first to not mess imm context */
+ if (but->a1 == UI_GRAD_H) {
+ /* magic trigger for curve backgrounds */
+ float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
+
+ rcti grid = {
+ .xmin = rect->xmin + zoomx * (-offsx),
+ .xmax = grid.xmin + zoomx,
+ .ymin = rect->ymin + zoomy * (-offsy),
+ .ymax = grid.ymin + zoomy,
+ };
+
+ ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f);
+ }
+
+ GPU_line_width(1.0f);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* backdrop */
+ float color_backdrop[4] = {0, 0, 0, 1};
+
+ if (but->a1 == UI_GRAD_H) {
+ /* grid, hsv uses different grid */
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0);
+ immUniformColor4fv(color_backdrop);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
+ GPU_blend(false);
+ }
+ else {
+ if (cumap->flag & CUMA_DO_CLIP) {
+ gl_shaded_color_get_fl((uchar *)wcol->inner, -20, color_backdrop);
+ immUniformColor3fv(color_backdrop);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ immUniformColor3ubv((uchar *)wcol->inner);
+ immRectf(pos,
+ rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
+ rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
+ rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
+ rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
+ }
+ else {
+ rgb_uchar_to_float(color_backdrop, (const uchar *)wcol->inner);
+ immUniformColor3fv(color_backdrop);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ }
+
+ /* grid, every 0.25 step */
+ gl_shaded_color((uchar *)wcol->inner, -16);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.25f);
+ /* grid, every 1.0 step */
+ gl_shaded_color((uchar *)wcol->inner, -24);
+ ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 1.0f);
+ /* axes */
+ gl_shaded_color((uchar *)wcol->inner, -50);
+ immBegin(GPU_PRIM_LINES, 4);
+ immVertex2f(pos, rect->xmin, rect->ymin + zoomy * (-offsy));
+ immVertex2f(pos, rect->xmax, rect->ymin + zoomy * (-offsy));
+ immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (-offsx), rect->ymax);
+ immEnd();
+ }
+
+ /* cfra option */
+ /* XXX 2.48 */
#if 0
- if (cumap->flag & CUMA_DRAW_CFRA) {
- immUniformColor3ub(0x60, 0xc0, 0x40);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
- immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
- immEnd();
- }
+ if (cumap->flag & CUMA_DRAW_CFRA) {
+ immUniformColor3ub(0x60, 0xc0, 0x40);
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
+ immEnd();
+ }
#endif
- /* sample option */
-
- if (cumap->flag & CUMA_DRAW_SAMPLE) {
- immBegin(GPU_PRIM_LINES, 2); /* will draw one of the following 3 lines */
- if (but->a1 == UI_GRAD_H) {
- float tsample[3];
- float hsv[3];
- linearrgb_to_srgb_v3_v3(tsample, cumap->sample);
- rgb_to_hsv_v(tsample, hsv);
- immUniformColor3ub(240, 240, 240);
-
- immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
- immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
- }
- else if (cumap->cur == 3) {
- float lum = IMB_colormanagement_get_luminance(cumap->sample);
- immUniformColor3ub(240, 240, 240);
-
- immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin);
- immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax);
- }
- else {
- if (cumap->cur == 0) {
- immUniformColor3ub(240, 100, 100);
- }
- else if (cumap->cur == 1) {
- immUniformColor3ub(100, 240, 100);
- }
- else {
- immUniformColor3ub(100, 100, 240);
- }
-
- immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
- immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
- }
- immEnd();
- }
- immUnbindProgram();
-
-
-
- if (cuma->table == NULL) {
- curvemapping_changed(cumap, false);
- }
-
- CurveMapPoint *cmp = cuma->table;
- rctf line_range;
-
- /* First curve point. */
- if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
- line_range.xmin = rect->xmin;
- line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy);
- }
- else {
- line_range.xmin = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]);
- line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
- }
- /* Last curve point. */
- if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
- line_range.xmax = rect->xmax;
- line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy);
- }
- else {
- line_range.xmax = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
- line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
- }
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
-
- /* Curve filled. */
- immUniformColor3ubvAlpha((uchar *)wcol->item, 128);
- GPU_polygon_smooth(true);
- immBegin(GPU_PRIM_TRI_STRIP, (CM_TABLE * 2 + 2) + 4);
- immVertex2f(pos, line_range.xmin, rect->ymin);
- immVertex2f(pos, line_range.xmin, line_range.ymin);
- for (int a = 0; a <= CM_TABLE; a++) {
- float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
- float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
- immVertex2f(pos, fx, rect->ymin);
- immVertex2f(pos, fx, fy);
- }
- immVertex2f(pos, line_range.xmax, rect->ymin);
- immVertex2f(pos, line_range.xmax, line_range.ymax);
- immEnd();
- GPU_polygon_smooth(false);
-
- /* Curve line. */
- GPU_line_width(1.0f);
- immUniformColor3ubvAlpha((uchar *)wcol->item, 255);
- GPU_line_smooth(true);
- immBegin(GPU_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2);
- immVertex2f(pos, line_range.xmin, line_range.ymin);
- for (int a = 0; a <= CM_TABLE; a++) {
- float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
- float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
- immVertex2f(pos, fx, fy);
- }
- immVertex2f(pos, line_range.xmax, line_range.ymax);
- immEnd();
-
- /* Reset state for fill & line. */
- GPU_line_smooth(false);
- GPU_blend(false);
- immUnbindProgram();
-
- /* The points, use aspect to make them visible on edges. */
- format = immVertexFormat();
- pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-
- /* Calculate vertex colors based on text theme. */
- float color_vert[4], color_vert_select[4];
- UI_GetThemeColor4fv(TH_TEXT_HI, color_vert);
- UI_GetThemeColor4fv(TH_TEXT, color_vert_select);
- if (len_squared_v3v3(color_vert, color_vert_select) < 0.1f) {
- interp_v3_v3v3(color_vert, color_vert_select, color_backdrop, 0.75f);
- }
- if (len_squared_v3(color_vert) > len_squared_v3(color_vert_select)) {
- /* Ensure brightest text color is used for selection. */
- swap_v3_v3(color_vert, color_vert_select);
- }
-
- cmp = cuma->curve;
- GPU_point_size(max_ff(1.0f, min_ff(UI_DPI_FAC / but->block->aspect * 4.0f, 4.0f)));
- immBegin(GPU_PRIM_POINTS, cuma->totpoint);
- for (int a = 0; a < cuma->totpoint; a++) {
- float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
- float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
- immAttr4fv(col, (cmp[a].flag & CUMA_SELECT) ? color_vert_select : color_vert);
- immVertex2f(pos, fx, fy);
- }
- immEnd();
- immUnbindProgram();
-
- /* restore scissortest */
- GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
-
- /* outline */
- format = immVertexFormat();
- pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor3ubv((uchar *)wcol->outline);
- imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
-
- immUnbindProgram();
+ /* sample option */
+
+ if (cumap->flag & CUMA_DRAW_SAMPLE) {
+ immBegin(GPU_PRIM_LINES, 2); /* will draw one of the following 3 lines */
+ if (but->a1 == UI_GRAD_H) {
+ float tsample[3];
+ float hsv[3];
+ linearrgb_to_srgb_v3_v3(tsample, cumap->sample);
+ rgb_to_hsv_v(tsample, hsv);
+ immUniformColor3ub(240, 240, 240);
+
+ immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
+ }
+ else if (cumap->cur == 3) {
+ float lum = IMB_colormanagement_get_luminance(cumap->sample);
+ immUniformColor3ub(240, 240, 240);
+
+ immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymax);
+ }
+ else {
+ if (cumap->cur == 0) {
+ immUniformColor3ub(240, 100, 100);
+ }
+ else if (cumap->cur == 1) {
+ immUniformColor3ub(100, 240, 100);
+ }
+ else {
+ immUniformColor3ub(100, 100, 240);
+ }
+
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
+ immVertex2f(pos, rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
+ }
+ immEnd();
+ }
+ immUnbindProgram();
+
+ if (cuma->table == NULL) {
+ curvemapping_changed(cumap, false);
+ }
+
+ CurveMapPoint *cmp = cuma->table;
+ rctf line_range;
+
+ /* First curve point. */
+ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
+ line_range.xmin = rect->xmin;
+ line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy);
+ }
+ else {
+ line_range.xmin = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]);
+ line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
+ }
+ /* Last curve point. */
+ if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
+ line_range.xmax = rect->xmax;
+ line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy);
+ }
+ else {
+ line_range.xmax = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
+ line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_blend(true);
+
+ /* Curve filled. */
+ immUniformColor3ubvAlpha((uchar *)wcol->item, 128);
+ GPU_polygon_smooth(true);
+ immBegin(GPU_PRIM_TRI_STRIP, (CM_TABLE * 2 + 2) + 4);
+ immVertex2f(pos, line_range.xmin, rect->ymin);
+ immVertex2f(pos, line_range.xmin, line_range.ymin);
+ for (int a = 0; a <= CM_TABLE; a++) {
+ float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
+ float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
+ immVertex2f(pos, fx, rect->ymin);
+ immVertex2f(pos, fx, fy);
+ }
+ immVertex2f(pos, line_range.xmax, rect->ymin);
+ immVertex2f(pos, line_range.xmax, line_range.ymax);
+ immEnd();
+ GPU_polygon_smooth(false);
+
+ /* Curve line. */
+ GPU_line_width(1.0f);
+ immUniformColor3ubvAlpha((uchar *)wcol->item, 255);
+ GPU_line_smooth(true);
+ immBegin(GPU_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2);
+ immVertex2f(pos, line_range.xmin, line_range.ymin);
+ for (int a = 0; a <= CM_TABLE; a++) {
+ float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
+ float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
+ immVertex2f(pos, fx, fy);
+ }
+ immVertex2f(pos, line_range.xmax, line_range.ymax);
+ immEnd();
+
+ /* Reset state for fill & line. */
+ GPU_line_smooth(false);
+ GPU_blend(false);
+ immUnbindProgram();
+
+ /* The points, use aspect to make them visible on edges. */
+ format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ /* Calculate vertex colors based on text theme. */
+ float color_vert[4], color_vert_select[4];
+ UI_GetThemeColor4fv(TH_TEXT_HI, color_vert);
+ UI_GetThemeColor4fv(TH_TEXT, color_vert_select);
+ if (len_squared_v3v3(color_vert, color_vert_select) < 0.1f) {
+ interp_v3_v3v3(color_vert, color_vert_select, color_backdrop, 0.75f);
+ }
+ if (len_squared_v3(color_vert) > len_squared_v3(color_vert_select)) {
+ /* Ensure brightest text color is used for selection. */
+ swap_v3_v3(color_vert, color_vert_select);
+ }
+
+ cmp = cuma->curve;
+ GPU_point_size(max_ff(1.0f, min_ff(UI_DPI_FAC / but->block->aspect * 4.0f, 4.0f)));
+ immBegin(GPU_PRIM_POINTS, cuma->totpoint);
+ for (int a = 0; a < cuma->totpoint; a++) {
+ float fx = rect->xmin + zoomx * (cmp[a].x - offsx);
+ float fy = rect->ymin + zoomy * (cmp[a].y - offsy);
+ immAttr4fv(col, (cmp[a].flag & CUMA_SELECT) ? color_vert_select : color_vert);
+ immVertex2f(pos, fx, fy);
+ }
+ immEnd();
+ immUnbindProgram();
+
+ /* restore scissortest */
+ GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+
+ /* outline */
+ format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3ubv((uchar *)wcol->outline);
+ imm_draw_box_wire_2d(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ immUnbindProgram();
}
-void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar), uiBut *but, const uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(ar),
+ uiBut *but,
+ const uiWidgetColors *UNUSED(wcol),
+ const rcti *recti)
{
- bool ok = false;
- MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
-
- rctf rect = {
- .xmin = (float)recti->xmin + 1,
- .xmax = (float)recti->xmax - 1,
- .ymin = (float)recti->ymin + 1,
- .ymax = (float)recti->ymax - 1,
- };
-
- int width = BLI_rctf_size_x(&rect) + 1;
- int height = BLI_rctf_size_y(&rect);
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- /* need scissor test, preview image can draw outside of boundary */
- int scissor[4];
- GPU_scissor_get_i(scissor);
- GPU_scissor(
- (rect.xmin - 1),
- (rect.ymin - 1),
- (rect.xmax + 1) - (rect.xmin - 1),
- (rect.ymax + 1) - (rect.ymin - 1));
-
- if (scopes->track_disabled) {
- float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
-
- ok = true;
- }
- else if ((scopes->track_search) &&
- ((!scopes->track_preview) ||
- (scopes->track_preview->x != width || scopes->track_preview->y != height)))
- {
- if (scopes->track_preview) {
- IMB_freeImBuf(scopes->track_preview);
- }
-
- ImBuf *tmpibuf = BKE_tracking_sample_pattern(
- scopes->frame_width, scopes->frame_height,
- scopes->track_search, scopes->track,
- &scopes->undist_marker, true, scopes->use_track_mask,
- width, height, scopes->track_pos);
- if (tmpibuf) {
- if (tmpibuf->rect_float) {
- IMB_rect_from_float(tmpibuf);
- }
-
- if (tmpibuf->rect) {
- scopes->track_preview = tmpibuf;
- }
- else {
- IMB_freeImBuf(tmpibuf);
- }
- }
- }
-
- if (!ok && scopes->track_preview) {
- GPU_matrix_push();
-
- /* draw content of pattern area */
- GPU_scissor(rect.xmin, rect.ymin, scissor[2], scissor[3]);
-
- if (width > 0 && height > 0) {
- ImBuf *drawibuf = scopes->track_preview;
- float col_sel[4], col_outline[4];
-
- if (scopes->use_track_mask) {
- float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
- }
-
- IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(&state, rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, drawibuf->rect, 1.0f, 1.0f, NULL);
-
- /* draw cross for pixel position */
- GPU_matrix_translate_2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
- GPU_scissor(
- rect.xmin,
- rect.ymin,
- BLI_rctf_size_x(&rect),
- BLI_rctf_size_y(&rect));
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-
- UI_GetThemeColor4fv(TH_SEL_MARKER, col_sel);
- UI_GetThemeColor4fv(TH_MARKER_OUTLINE, col_outline);
-
- /* Do stipple cross with geometry */
- immBegin(GPU_PRIM_LINES, 7 * 2 * 2);
- float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
- for (int axe = 0; axe < 2; ++axe) {
- for (int i = 0; i < 7; ++i) {
- float x1 = pos_sel[i] * (1 - axe);
- float y1 = pos_sel[i] * axe;
- float x2 = pos_sel[i + 1] * (1 - axe);
- float y2 = pos_sel[i + 1] * axe;
-
- if (i % 2 == 1) {
- immAttr4fv(col, col_sel);
- }
- else {
- immAttr4fv(col, col_outline);
- }
-
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x2, y2);
- }
- }
- immEnd();
-
- immUnbindProgram();
- }
-
- GPU_matrix_pop();
-
- ok = true;
- }
-
- if (!ok) {
- float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_4fv(true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
- }
-
- /* outline */
- draw_scope_end(&rect, scissor);
-
- GPU_blend(false);
+ bool ok = false;
+ MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
+
+ rctf rect = {
+ .xmin = (float)recti->xmin + 1,
+ .xmax = (float)recti->xmax - 1,
+ .ymin = (float)recti->ymin + 1,
+ .ymax = (float)recti->ymax - 1,
+ };
+
+ int width = BLI_rctf_size_x(&rect) + 1;
+ int height = BLI_rctf_size_y(&rect);
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ /* need scissor test, preview image can draw outside of boundary */
+ int scissor[4];
+ GPU_scissor_get_i(scissor);
+ GPU_scissor((rect.xmin - 1),
+ (rect.ymin - 1),
+ (rect.xmax + 1) - (rect.xmin - 1),
+ (rect.ymax + 1) - (rect.ymin - 1));
+
+ if (scopes->track_disabled) {
+ float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(
+ true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+
+ ok = true;
+ }
+ else if ((scopes->track_search) &&
+ ((!scopes->track_preview) ||
+ (scopes->track_preview->x != width || scopes->track_preview->y != height))) {
+ if (scopes->track_preview) {
+ IMB_freeImBuf(scopes->track_preview);
+ }
+
+ ImBuf *tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width,
+ scopes->frame_height,
+ scopes->track_search,
+ scopes->track,
+ &scopes->undist_marker,
+ true,
+ scopes->use_track_mask,
+ width,
+ height,
+ scopes->track_pos);
+ if (tmpibuf) {
+ if (tmpibuf->rect_float) {
+ IMB_rect_from_float(tmpibuf);
+ }
+
+ if (tmpibuf->rect) {
+ scopes->track_preview = tmpibuf;
+ }
+ else {
+ IMB_freeImBuf(tmpibuf);
+ }
+ }
+ }
+
+ if (!ok && scopes->track_preview) {
+ GPU_matrix_push();
+
+ /* draw content of pattern area */
+ GPU_scissor(rect.xmin, rect.ymin, scissor[2], scissor[3]);
+
+ if (width > 0 && height > 0) {
+ ImBuf *drawibuf = scopes->track_preview;
+ float col_sel[4], col_outline[4];
+
+ if (scopes->use_track_mask) {
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(
+ true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ }
+
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
+ immDrawPixelsTex(&state,
+ rect.xmin,
+ rect.ymin + 1,
+ drawibuf->x,
+ drawibuf->y,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ GL_LINEAR,
+ drawibuf->rect,
+ 1.0f,
+ 1.0f,
+ NULL);
+
+ /* draw cross for pixel position */
+ GPU_matrix_translate_2f(rect.xmin + scopes->track_pos[0], rect.ymin + scopes->track_pos[1]);
+ GPU_scissor(rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect));
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ UI_GetThemeColor4fv(TH_SEL_MARKER, col_sel);
+ UI_GetThemeColor4fv(TH_MARKER_OUTLINE, col_outline);
+
+ /* Do stipple cross with geometry */
+ immBegin(GPU_PRIM_LINES, 7 * 2 * 2);
+ float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
+ for (int axe = 0; axe < 2; ++axe) {
+ for (int i = 0; i < 7; ++i) {
+ float x1 = pos_sel[i] * (1 - axe);
+ float y1 = pos_sel[i] * axe;
+ float x2 = pos_sel[i + 1] * (1 - axe);
+ float y2 = pos_sel[i + 1] * axe;
+
+ if (i % 2 == 1) {
+ immAttr4fv(col, col_sel);
+ }
+ else {
+ immAttr4fv(col, col_outline);
+ }
+
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
+ }
+ }
+ immEnd();
+
+ immUnbindProgram();
+ }
+
+ GPU_matrix_pop();
+
+ ok = true;
+ }
+
+ if (!ok) {
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_4fv(
+ true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
+ }
+
+ /* outline */
+ draw_scope_end(&rect, scissor);
+
+ GPU_blend(false);
}
-void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, const uiWidgetColors *UNUSED(wcol), const rcti *recti)
+void ui_draw_but_NODESOCKET(ARegion *ar,
+ uiBut *but,
+ const uiWidgetColors *UNUSED(wcol),
+ const rcti *recti)
{
- static const float size = 5.0f;
-
- /* 16 values of sin function */
- const float si[16] = {
- 0.00000000f, 0.39435585f, 0.72479278f, 0.93775213f,
- 0.99871650f, 0.89780453f, 0.65137248f, 0.29936312f,
- -0.10116832f, -0.48530196f, -0.79077573f, -0.96807711f,
- -0.98846832f, -0.84864425f, -0.57126821f, -0.20129852f,
- };
- /* 16 values of cos function */
- const float co[16] = {
- 1.00000000f, 0.91895781f, 0.68896691f, 0.34730525f,
- -0.05064916f, -0.44039415f, -0.75875812f, -0.95413925f,
- -0.99486932f, -0.87434661f, -0.61210598f, -0.25065253f,
- 0.15142777f, 0.52896401f, 0.82076344f, 0.97952994f,
- };
-
- int scissor[4];
-
- /* need scissor test, can draw outside of boundary */
- GPU_scissor_get_i(scissor);
-
- rcti scissor_new = {
- .xmin = recti->xmin,
- .ymin = recti->ymin,
- .xmax = recti->xmax,
- .ymax = recti->ymax,
- };
-
- rcti scissor_region = {0, ar->winx, 0, ar->winy};
-
- BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
- GPU_scissor(
- scissor_new.xmin,
- scissor_new.ymin,
- BLI_rcti_size_x(&scissor_new),
- BLI_rcti_size_y(&scissor_new));
-
- float x = 0.5f * (recti->xmin + recti->xmax);
- float y = 0.5f * (recti->ymin + recti->ymax);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4ubv(but->col);
-
- GPU_blend(true);
- immBegin(GPU_PRIM_TRI_FAN, 16);
- for (int a = 0; a < 16; a++) {
- immVertex2f(pos, x + size * si[a], y + size * co[a]);
- }
- immEnd();
-
- immUniformColor4ub(0, 0, 0, 150);
- GPU_line_width(1);
- GPU_line_smooth(true);
- immBegin(GPU_PRIM_LINE_LOOP, 16);
- for (int a = 0; a < 16; a++) {
- immVertex2f(pos, x + size * si[a], y + size * co[a]);
- }
- immEnd();
- GPU_line_smooth(false);
- GPU_blend(false);
-
- immUnbindProgram();
-
- /* restore scissortest */
- GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+ static const float size = 5.0f;
+
+ /* 16 values of sin function */
+ const float si[16] = {
+ 0.00000000f,
+ 0.39435585f,
+ 0.72479278f,
+ 0.93775213f,
+ 0.99871650f,
+ 0.89780453f,
+ 0.65137248f,
+ 0.29936312f,
+ -0.10116832f,
+ -0.48530196f,
+ -0.79077573f,
+ -0.96807711f,
+ -0.98846832f,
+ -0.84864425f,
+ -0.57126821f,
+ -0.20129852f,
+ };
+ /* 16 values of cos function */
+ const float co[16] = {
+ 1.00000000f,
+ 0.91895781f,
+ 0.68896691f,
+ 0.34730525f,
+ -0.05064916f,
+ -0.44039415f,
+ -0.75875812f,
+ -0.95413925f,
+ -0.99486932f,
+ -0.87434661f,
+ -0.61210598f,
+ -0.25065253f,
+ 0.15142777f,
+ 0.52896401f,
+ 0.82076344f,
+ 0.97952994f,
+ };
+
+ int scissor[4];
+
+ /* need scissor test, can draw outside of boundary */
+ GPU_scissor_get_i(scissor);
+
+ rcti scissor_new = {
+ .xmin = recti->xmin,
+ .ymin = recti->ymin,
+ .xmax = recti->xmax,
+ .ymax = recti->ymax,
+ };
+
+ rcti scissor_region = {0, ar->winx, 0, ar->winy};
+
+ BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new);
+ GPU_scissor(scissor_new.xmin,
+ scissor_new.ymin,
+ BLI_rcti_size_x(&scissor_new),
+ BLI_rcti_size_y(&scissor_new));
+
+ float x = 0.5f * (recti->xmin + recti->xmax);
+ float y = 0.5f * (recti->ymin + recti->ymax);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv(but->col);
+
+ GPU_blend(true);
+ immBegin(GPU_PRIM_TRI_FAN, 16);
+ for (int a = 0; a < 16; a++) {
+ immVertex2f(pos, x + size * si[a], y + size * co[a]);
+ }
+ immEnd();
+
+ immUniformColor4ub(0, 0, 0, 150);
+ GPU_line_width(1);
+ GPU_line_smooth(true);
+ immBegin(GPU_PRIM_LINE_LOOP, 16);
+ for (int a = 0; a < 16; a++) {
+ immVertex2f(pos, x + size * si[a], y + size * co[a]);
+ }
+ immEnd();
+ GPU_line_smooth(false);
+ GPU_blend(false);
+
+ immUnbindProgram();
+
+ /* restore scissortest */
+ GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
}
/* ****************************************************** */
@@ -2157,157 +2335,175 @@ void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, const uiWidgetColors *UNUSE
* would replace / modify the following 3 functions - merwin
*/
-static void ui_shadowbox(uint pos, uint color, float minx, float miny, float maxx, float maxy, float shadsize, uchar alpha)
+static void ui_shadowbox(uint pos,
+ uint color,
+ float minx,
+ float miny,
+ float maxx,
+ float maxy,
+ float shadsize,
+ uchar alpha)
{
- /**
- * <pre>
- * v1-_
- * | -_v2
- * | |
- * | |
- * | |
- * v7_______v3____v4
- * \ | /
- * \ | _v5
- * v8______v6_-
- * </pre>
- */
- const float v1[2] = {maxx, maxy - 0.3f * shadsize};
- const float v2[2] = {maxx + shadsize, maxy - 0.75f * shadsize};
- const float v3[2] = {maxx, miny};
- const float v4[2] = {maxx + shadsize, miny};
-
- const float v5[2] = {maxx + 0.7f * shadsize, miny - 0.7f * shadsize};
-
- const float v6[2] = {maxx, miny - shadsize};
- const float v7[2] = {minx + 0.3f * shadsize, miny};
- const float v8[2] = {minx + 0.5f * shadsize, miny - shadsize};
-
- /* right quad */
- immAttr4ub(color, 0, 0, 0, alpha);
- immVertex2fv(pos, v3);
- immVertex2fv(pos, v1);
- immAttr4ub(color, 0, 0, 0, 0);
- immVertex2fv(pos, v2);
-
- immVertex2fv(pos, v2);
- immVertex2fv(pos, v4);
- immAttr4ub(color, 0, 0, 0, alpha);
- immVertex2fv(pos, v3);
-
- /* corner shape */
- /* immAttr4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */
- immVertex2fv(pos, v3);
- immAttr4ub(color, 0, 0, 0, 0);
- immVertex2fv(pos, v4);
- immVertex2fv(pos, v5);
-
- immVertex2fv(pos, v5);
- immVertex2fv(pos, v6);
- immAttr4ub(color, 0, 0, 0, alpha);
- immVertex2fv(pos, v3);
-
- /* bottom quad */
- /* immAttr4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */
- immVertex2fv(pos, v3);
- immAttr4ub(color, 0, 0, 0, 0);
- immVertex2fv(pos, v6);
- immVertex2fv(pos, v8);
-
- immVertex2fv(pos, v8);
- immAttr4ub(color, 0, 0, 0, alpha);
- immVertex2fv(pos, v7);
- immVertex2fv(pos, v3);
+ /**
+ * <pre>
+ * v1-_
+ * | -_v2
+ * | |
+ * | |
+ * | |
+ * v7_______v3____v4
+ * \ | /
+ * \ | _v5
+ * v8______v6_-
+ * </pre>
+ */
+ const float v1[2] = {maxx, maxy - 0.3f * shadsize};
+ const float v2[2] = {maxx + shadsize, maxy - 0.75f * shadsize};
+ const float v3[2] = {maxx, miny};
+ const float v4[2] = {maxx + shadsize, miny};
+
+ const float v5[2] = {maxx + 0.7f * shadsize, miny - 0.7f * shadsize};
+
+ const float v6[2] = {maxx, miny - shadsize};
+ const float v7[2] = {minx + 0.3f * shadsize, miny};
+ const float v8[2] = {minx + 0.5f * shadsize, miny - shadsize};
+
+ /* right quad */
+ immAttr4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v3);
+ immVertex2fv(pos, v1);
+ immAttr4ub(color, 0, 0, 0, 0);
+ immVertex2fv(pos, v2);
+
+ immVertex2fv(pos, v2);
+ immVertex2fv(pos, v4);
+ immAttr4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v3);
+
+ /* corner shape */
+ /* immAttr4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */
+ immVertex2fv(pos, v3);
+ immAttr4ub(color, 0, 0, 0, 0);
+ immVertex2fv(pos, v4);
+ immVertex2fv(pos, v5);
+
+ immVertex2fv(pos, v5);
+ immVertex2fv(pos, v6);
+ immAttr4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v3);
+
+ /* bottom quad */
+ /* immAttr4ub(color, 0, 0, 0, alpha); */ /* Not needed, done above in previous tri */
+ immVertex2fv(pos, v3);
+ immAttr4ub(color, 0, 0, 0, 0);
+ immVertex2fv(pos, v6);
+ immVertex2fv(pos, v8);
+
+ immVertex2fv(pos, v8);
+ immAttr4ub(color, 0, 0, 0, alpha);
+ immVertex2fv(pos, v7);
+ immVertex2fv(pos, v3);
}
void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float maxy)
{
- GPU_blend(true);
+ GPU_blend(true);
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(
+ format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBegin(GPU_PRIM_TRIS, 54);
+ immBegin(GPU_PRIM_TRIS, 54);
- /* accumulated outline boxes to make shade not linear, is more pleasant */
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
- ui_shadowbox(pos, color, minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
+ /* accumulated outline boxes to make shade not linear, is more pleasant */
+ ui_shadowbox(pos, color, minx, miny, maxx, maxy, 11.0, (20 * alpha) >> 8);
+ ui_shadowbox(pos, color, minx, miny, maxx, maxy, 7.0, (40 * alpha) >> 8);
+ ui_shadowbox(pos, color, minx, miny, maxx, maxy, 5.0, (80 * alpha) >> 8);
- immEnd();
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(false);
}
-
-void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select))
+void ui_draw_dropshadow(
+ const rctf *rct, float radius, float aspect, float alpha, int UNUSED(select))
{
- float rad;
+ float rad;
- if (radius > (BLI_rctf_size_y(rct) - 10.0f) * 0.5f) {
- rad = (BLI_rctf_size_y(rct) - 10.0f) * 0.5f;
- }
- else {
- rad = radius;
- }
+ if (radius > (BLI_rctf_size_y(rct) - 10.0f) * 0.5f) {
+ rad = (BLI_rctf_size_y(rct) - 10.0f) * 0.5f;
+ }
+ else {
+ rad = radius;
+ }
- int a, i = 12;
+ int a, i = 12;
#if 0
- if (select) {
- a = i * aspect; /* same as below */
- }
- else
+ if (select) {
+ a = i * aspect; /* same as below */
+ }
+ else
#endif
- {
- a = i * aspect;
- }
-
- GPU_blend(true);
- const float dalpha = alpha * 2.0f / 255.0f;
- float calpha = dalpha;
- float visibility = 1.0f;
- for (; i--;) {
- /* alpha ranges from 2 to 20 or so */
+ {
+ a = i * aspect;
+ }
+
+ GPU_blend(true);
+ const float dalpha = alpha * 2.0f / 255.0f;
+ float calpha = dalpha;
+ float visibility = 1.0f;
+ for (; i--;) {
+ /* alpha ranges from 2 to 20 or so */
#if 0 /* Old Method (pre 2.8) */
- float color[4] = {0.0f, 0.0f, 0.0f, calpha};
- UI_draw_roundbox_4fv(true, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a, color);
+ float color[4] = {0.0f, 0.0f, 0.0f, calpha};
+ UI_draw_roundbox_4fv(true, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax - 10.0f + a, rad + a, color);
#endif
- /* Compute final visibility to match old method result. */
- /* TODO we could just find a better fit function inside the shader instead of this. */
- visibility = visibility * (1.0f - calpha);
- calpha += dalpha;
- }
-
- uiWidgetBaseParameters widget_params = {
- .recti.xmin = rct->xmin, .recti.ymin = rct->ymin,
- .recti.xmax = rct->xmax, .recti.ymax = rct->ymax - 10.0f,
- .rect.xmin = rct->xmin - a, .rect.ymin = rct->ymin - a,
- .rect.xmax = rct->xmax + a, .rect.ymax = rct->ymax - 10.0f + a,
- .radi = rad,
- .rad = rad + a,
- .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
- .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
- .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
- .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
- .alpha_discard = 1.0f,
- };
-
- GPUBatch *batch = ui_batch_roundbox_shadow_get();
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW);
- GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params);
- GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility);
- GPU_batch_draw(batch);
-
- /* outline emphasis */
- GPU_line_smooth(true);
- float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
- UI_draw_roundbox_4fv(false, rct->xmin - 0.5f, rct->ymin - 0.5f, rct->xmax + 0.5f, rct->ymax + 0.5f, radius + 0.5f, color);
- GPU_line_smooth(false);
-
- GPU_blend(false);
+ /* Compute final visibility to match old method result. */
+ /* TODO we could just find a better fit function inside the shader instead of this. */
+ visibility = visibility * (1.0f - calpha);
+ calpha += dalpha;
+ }
+
+ uiWidgetBaseParameters widget_params = {
+ .recti.xmin = rct->xmin,
+ .recti.ymin = rct->ymin,
+ .recti.xmax = rct->xmax,
+ .recti.ymax = rct->ymax - 10.0f,
+ .rect.xmin = rct->xmin - a,
+ .rect.ymin = rct->ymin - a,
+ .rect.xmax = rct->xmax + a,
+ .rect.ymax = rct->ymax - 10.0f + a,
+ .radi = rad,
+ .rad = rad + a,
+ .round_corners[0] = (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f,
+ .round_corners[1] = (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[2] = (roundboxtype & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f,
+ .round_corners[3] = (roundboxtype & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f,
+ .alpha_discard = 1.0f,
+ };
+
+ GPUBatch *batch = ui_batch_roundbox_shadow_get();
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params);
+ GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility);
+ GPU_batch_draw(batch);
+
+ /* outline emphasis */
+ GPU_line_smooth(true);
+ float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
+ UI_draw_roundbox_4fv(false,
+ rct->xmin - 0.5f,
+ rct->ymin - 0.5f,
+ rct->xmax + 0.5f,
+ rct->ymax + 0.5f,
+ radius + 0.5f,
+ color);
+ GPU_line_smooth(false);
+
+ GPU_blend(false);
}
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 0f0d2c355e8..3c26c37b610 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -36,7 +36,7 @@
#include "interface_intern.h"
-#include "interface_eyedropper_intern.h" /* own include */
+#include "interface_eyedropper_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/* Keymap
@@ -44,62 +44,61 @@
/** \name Modal Keymap
* \{ */
-
wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items[] = {
- {EYE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
- {EYE_MODAL_SAMPLE_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
- {EYE_MODAL_SAMPLE_BEGIN, "SAMPLE_BEGIN", 0, "Start Sampling", ""},
- {EYE_MODAL_SAMPLE_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Eyedropper Modal Map");
-
- /* this function is called for each spacetype, only needs to add map once */
- if (keymap && keymap->modal_items) {
- return NULL;
- }
-
- keymap = WM_modalkeymap_add(keyconf, "Eyedropper Modal Map", modal_items);
-
- /* assign to operators */
- WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorramp");
- WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color");
- WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id");
- WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth");
- WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver");
-
- return keymap;
+ static const EnumPropertyItem modal_items[] = {
+ {EYE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {EYE_MODAL_SAMPLE_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
+ {EYE_MODAL_SAMPLE_BEGIN, "SAMPLE_BEGIN", 0, "Start Sampling", ""},
+ {EYE_MODAL_SAMPLE_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Eyedropper Modal Map");
+
+ /* this function is called for each spacetype, only needs to add map once */
+ if (keymap && keymap->modal_items) {
+ return NULL;
+ }
+
+ keymap = WM_modalkeymap_add(keyconf, "Eyedropper Modal Map", modal_items);
+
+ /* assign to operators */
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorramp");
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color");
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id");
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth");
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver");
+
+ return keymap;
}
wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf)
{
- static const EnumPropertyItem modal_items_point[] = {
- {EYE_MODAL_POINT_CANCEL, "CANCEL", 0, "Cancel", ""},
- {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a point", ""},
- {EYE_MODAL_POINT_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
- {EYE_MODAL_POINT_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
- {0, NULL, 0, NULL, NULL},
- };
-
- wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Eyedropper ColorRamp PointSampling Map");
- if (keymap && keymap->modal_items) {
- return keymap;
- }
-
- keymap = WM_modalkeymap_add(keyconf, "Eyedropper ColorRamp PointSampling Map", modal_items_point);
-
- /* assign to operators */
- WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorramp_point");
-
- return keymap;
+ static const EnumPropertyItem modal_items_point[] = {
+ {EYE_MODAL_POINT_CANCEL, "CANCEL", 0, "Cancel", ""},
+ {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a point", ""},
+ {EYE_MODAL_POINT_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""},
+ {EYE_MODAL_POINT_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Eyedropper ColorRamp PointSampling Map");
+ if (keymap && keymap->modal_items) {
+ return keymap;
+ }
+
+ keymap = WM_modalkeymap_add(
+ keyconf, "Eyedropper ColorRamp PointSampling Map", modal_items_point);
+
+ /* assign to operators */
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_colorramp_point");
+
+ return keymap;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Utility Functions
*/
@@ -108,29 +107,25 @@ wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf)
void eyedropper_draw_cursor_text(const struct bContext *C, const ARegion *ar, const char *name)
{
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- wmWindow *win = CTX_wm_window(C);
- int x = win->eventstate->x;
- int y = win->eventstate->y;
- const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ wmWindow *win = CTX_wm_window(C);
+ int x = win->eventstate->x;
+ int y = win->eventstate->y;
+ const float col_fg[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float col_bg[4] = {0.0f, 0.0f, 0.0f, 0.2f};
+ if ((name[0] == '\0') || (BLI_rcti_isect_pt(&ar->winrct, x, y) == false)) {
+ return;
+ }
- if ((name[0] == '\0') ||
- (BLI_rcti_isect_pt(&ar->winrct, x, y) == false))
- {
- return;
- }
+ x = x - ar->winrct.xmin;
+ y = y - ar->winrct.ymin;
- x = x - ar->winrct.xmin;
- y = y - ar->winrct.ymin;
+ y += U.widget_unit;
- y += U.widget_unit;
-
- UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, col_fg, col_bg);
+ UI_fontstyle_draw_simple_backdrop(fstyle, x, y, name, col_fg, col_bg);
}
-
/**
* Utility to retrieve a button representing a RNA property that is currently under the cursor.
*
@@ -142,18 +137,18 @@ void eyedropper_draw_cursor_text(const struct bContext *C, const ARegion *ar, co
*/
uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event)
{
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y);
- ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_ANY, event->x, event->y);
-
- uiBut *but = ui_but_find_mouse_over(ar, event);
-
- if (ELEM(NULL, but, but->rnapoin.data, but->rnaprop)) {
- return NULL;
- }
- else {
- return but;
- }
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event->x, event->y);
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_ANY, event->x, event->y);
+
+ uiBut *but = ui_but_find_mouse_over(ar, event);
+
+ if (ELEM(NULL, but, but->rnapoin.data, but->rnaprop)) {
+ return NULL;
+ }
+ else {
+ return but;
+ }
}
/** \} */
diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c
index e2f85c4d7cc..68c12fe7652 100644
--- a/source/blender/editors/interface/interface_eyedropper_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_color.c
@@ -59,70 +59,68 @@
#include "interface_eyedropper_intern.h"
typedef struct Eyedropper {
- struct ColorManagedDisplay *display;
+ struct ColorManagedDisplay *display;
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
- bool is_undo;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+ bool is_undo;
- bool is_set;
- float init_col[3]; /* for resetting on cancel */
+ bool is_set;
+ float init_col[3]; /* for resetting on cancel */
- bool accum_start; /* has mouse been pressed */
- float accum_col[3];
- int accum_tot;
+ bool accum_start; /* has mouse been pressed */
+ float accum_col[3];
+ int accum_tot;
- bool use_accum;
+ bool use_accum;
} Eyedropper;
static bool eyedropper_init(bContext *C, wmOperator *op)
{
- Eyedropper *eye = MEM_callocN(sizeof(Eyedropper), __func__);
- eye->use_accum = RNA_boolean_get(op->ptr, "use_accumulate");
-
- uiBut *but = UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index);
-
- if ((eye->ptr.data == NULL) ||
- (eye->prop == NULL) ||
- (RNA_property_editable(&eye->ptr, eye->prop) == false) ||
- (RNA_property_array_length(&eye->ptr, eye->prop) < 3) ||
- (RNA_property_type(eye->prop) != PROP_FLOAT))
- {
- MEM_freeN(eye);
- return false;
- }
- op->customdata = eye;
-
- eye->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
-
- float col[4];
- RNA_property_float_get_array(&eye->ptr, eye->prop, col);
- if (RNA_property_subtype(eye->prop) != PROP_COLOR) {
- Scene *scene = CTX_data_scene(C);
- const char *display_device;
-
- display_device = scene->display_settings.display_device;
- eye->display = IMB_colormanagement_display_get_named(display_device);
-
- /* store initial color */
- if (eye->display) {
- IMB_colormanagement_display_to_scene_linear_v3(col, eye->display);
- }
- }
- copy_v3_v3(eye->init_col, col);
-
- return true;
+ Eyedropper *eye = MEM_callocN(sizeof(Eyedropper), __func__);
+ eye->use_accum = RNA_boolean_get(op->ptr, "use_accumulate");
+
+ uiBut *but = UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index);
+
+ if ((eye->ptr.data == NULL) || (eye->prop == NULL) ||
+ (RNA_property_editable(&eye->ptr, eye->prop) == false) ||
+ (RNA_property_array_length(&eye->ptr, eye->prop) < 3) ||
+ (RNA_property_type(eye->prop) != PROP_FLOAT)) {
+ MEM_freeN(eye);
+ return false;
+ }
+ op->customdata = eye;
+
+ eye->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
+
+ float col[4];
+ RNA_property_float_get_array(&eye->ptr, eye->prop, col);
+ if (RNA_property_subtype(eye->prop) != PROP_COLOR) {
+ Scene *scene = CTX_data_scene(C);
+ const char *display_device;
+
+ display_device = scene->display_settings.display_device;
+ eye->display = IMB_colormanagement_display_get_named(display_device);
+
+ /* store initial color */
+ if (eye->display) {
+ IMB_colormanagement_display_to_scene_linear_v3(col, eye->display);
+ }
+ }
+ copy_v3_v3(eye->init_col, col);
+
+ return true;
}
static void eyedropper_exit(bContext *C, wmOperator *op)
{
- WM_cursor_modal_restore(CTX_wm_window(C));
+ WM_cursor_modal_restore(CTX_wm_window(C));
- if (op->customdata) {
- MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
}
/* *** eyedropper_color_ helper functions *** */
@@ -136,224 +134,220 @@ static void eyedropper_exit(bContext *C, wmOperator *op)
*/
void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3])
{
- /* we could use some clever */
- Main *bmain = CTX_data_main(C);
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
- const char *display_device = CTX_data_scene(C)->display_settings.display_device;
- struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
-
- if (sa) {
- if (sa->spacetype == SPACE_IMAGE) {
- ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
- if (ar) {
- SpaceImage *sima = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
- return;
- }
- }
- }
- else if (sa->spacetype == SPACE_NODE) {
- ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
- if (ar) {
- SpaceNode *snode = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_node_color_sample(bmain, snode, ar, mval, r_col)) {
- return;
- }
- }
- }
- else if (sa->spacetype == SPACE_CLIP) {
- ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
- if (ar) {
- SpaceClip *sc = sa->spacedata.first;
- int mval[2] = {mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
-
- if (ED_space_clip_color_sample(sc, ar, mval, r_col)) {
- return;
- }
- }
- }
- }
-
- /* fallback to simple opengl picker */
- glReadBuffer(GL_FRONT);
- glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col);
- glReadBuffer(GL_BACK);
-
- IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
+ /* we could use some clever */
+ Main *bmain = CTX_data_main(C);
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
+ const char *display_device = CTX_data_scene(C)->display_settings.display_device;
+ struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
+
+ if (sa) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
+ SpaceImage *sima = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
+
+ if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
+ return;
+ }
+ }
+ }
+ else if (sa->spacetype == SPACE_NODE) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
+ SpaceNode *snode = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
+
+ if (ED_space_node_color_sample(bmain, snode, ar, mval, r_col)) {
+ return;
+ }
+ }
+ }
+ else if (sa->spacetype == SPACE_CLIP) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
+ SpaceClip *sc = sa->spacedata.first;
+ int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
+
+ if (ED_space_clip_color_sample(sc, ar, mval, r_col)) {
+ return;
+ }
+ }
+ }
+ }
+
+ /* fallback to simple opengl picker */
+ glReadBuffer(GL_FRONT);
+ glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col);
+ glReadBuffer(GL_BACK);
+
+ IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
}
/* sets the sample color RGB, maintaining A */
static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3])
{
- float col_conv[4];
+ float col_conv[4];
- /* to maintain alpha */
- RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv);
+ /* to maintain alpha */
+ RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv);
- /* convert from linear rgb space to display space */
- if (eye->display) {
- copy_v3_v3(col_conv, col);
- IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display);
- }
- else {
- copy_v3_v3(col_conv, col);
- }
+ /* convert from linear rgb space to display space */
+ if (eye->display) {
+ copy_v3_v3(col_conv, col);
+ IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display);
+ }
+ else {
+ copy_v3_v3(col_conv, col);
+ }
- RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv);
- eye->is_set = true;
+ RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv);
+ eye->is_set = true;
- RNA_property_update(C, &eye->ptr, eye->prop);
+ RNA_property_update(C, &eye->ptr, eye->prop);
}
static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my)
{
- /* Accumulate color. */
- float col[3];
- eyedropper_color_sample_fl(C, mx, my, col);
-
- if (eye->use_accum) {
- add_v3_v3(eye->accum_col, col);
- eye->accum_tot++;
- }
- else {
- copy_v3_v3(eye->accum_col, col);
- eye->accum_tot = 1;
- }
-
- /* Apply to property. */
- float accum_col[3];
- if (eye->accum_tot > 1) {
- mul_v3_v3fl(accum_col, eye->accum_col, 1.0f / (float)eye->accum_tot);
- }
- else {
- copy_v3_v3(accum_col, eye->accum_col);
- }
- eyedropper_color_set(C, eye, accum_col);
+ /* Accumulate color. */
+ float col[3];
+ eyedropper_color_sample_fl(C, mx, my, col);
+
+ if (eye->use_accum) {
+ add_v3_v3(eye->accum_col, col);
+ eye->accum_tot++;
+ }
+ else {
+ copy_v3_v3(eye->accum_col, col);
+ eye->accum_tot = 1;
+ }
+
+ /* Apply to property. */
+ float accum_col[3];
+ if (eye->accum_tot > 1) {
+ mul_v3_v3fl(accum_col, eye->accum_col, 1.0f / (float)eye->accum_tot);
+ }
+ else {
+ copy_v3_v3(accum_col, eye->accum_col);
+ }
+ eyedropper_color_set(C, eye, accum_col);
}
static void eyedropper_cancel(bContext *C, wmOperator *op)
{
- Eyedropper *eye = op->customdata;
- if (eye->is_set) {
- eyedropper_color_set(C, eye, eye->init_col);
- }
- eyedropper_exit(C, op);
+ Eyedropper *eye = op->customdata;
+ if (eye->is_set) {
+ eyedropper_color_set(C, eye, eye->init_col);
+ }
+ eyedropper_exit(C, op);
}
/* main modal status check */
static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- Eyedropper *eye = (Eyedropper *)op->customdata;
-
- /* handle modal keymap */
- if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case EYE_MODAL_CANCEL:
- eyedropper_cancel(C, op);
- return OPERATOR_CANCELLED;
- case EYE_MODAL_SAMPLE_CONFIRM:
- {
- const bool is_undo = eye->is_undo;
- if (eye->accum_tot == 0) {
- eyedropper_color_sample(C, eye, event->x, event->y);
- }
- eyedropper_exit(C, op);
- /* Could support finished & undo-skip. */
- return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
- }
- case EYE_MODAL_SAMPLE_BEGIN:
- /* enable accum and make first sample */
- eye->accum_start = true;
- eyedropper_color_sample(C, eye, event->x, event->y);
- break;
- case EYE_MODAL_SAMPLE_RESET:
- eye->accum_tot = 0;
- zero_v3(eye->accum_col);
- eyedropper_color_sample(C, eye, event->x, event->y);
- break;
- }
- }
- else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
- if (eye->accum_start) {
- /* button is pressed so keep sampling */
- eyedropper_color_sample(C, eye, event->x, event->y);
- }
- }
-
- return OPERATOR_RUNNING_MODAL;
+ Eyedropper *eye = (Eyedropper *)op->customdata;
+
+ /* handle modal keymap */
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EYE_MODAL_CANCEL:
+ eyedropper_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ case EYE_MODAL_SAMPLE_CONFIRM: {
+ const bool is_undo = eye->is_undo;
+ if (eye->accum_tot == 0) {
+ eyedropper_color_sample(C, eye, event->x, event->y);
+ }
+ eyedropper_exit(C, op);
+ /* Could support finished & undo-skip. */
+ return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ }
+ case EYE_MODAL_SAMPLE_BEGIN:
+ /* enable accum and make first sample */
+ eye->accum_start = true;
+ eyedropper_color_sample(C, eye, event->x, event->y);
+ break;
+ case EYE_MODAL_SAMPLE_RESET:
+ eye->accum_tot = 0;
+ zero_v3(eye->accum_col);
+ eyedropper_color_sample(C, eye, event->x, event->y);
+ break;
+ }
+ }
+ else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ if (eye->accum_start) {
+ /* button is pressed so keep sampling */
+ eyedropper_color_sample(C, eye, event->x, event->y);
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
/* Modal Operator init */
static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- /* init */
- if (eyedropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- else {
- return OPERATOR_PASS_THROUGH;
- }
+ /* init */
+ if (eyedropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
}
/* Repeat operator */
static int eyedropper_exec(bContext *C, wmOperator *op)
{
- /* init */
- if (eyedropper_init(C, op)) {
+ /* init */
+ if (eyedropper_init(C, op)) {
- /* do something */
+ /* do something */
- /* cleanup */
- eyedropper_exit(C, op);
+ /* cleanup */
+ eyedropper_exit(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_PASS_THROUGH;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
}
static bool eyedropper_poll(bContext *C)
{
- /* Actual test for active button happens later, since we don't
- * know which one is active until mouse over. */
- return (CTX_wm_window(C) != NULL);
+ /* Actual test for active button happens later, since we don't
+ * know which one is active until mouse over. */
+ return (CTX_wm_window(C) != NULL);
}
void UI_OT_eyedropper_color(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Eyedropper";
- ot->idname = "UI_OT_eyedropper_color";
- ot->description = "Sample a color from the Blender Window to store in a property";
-
- /* api callbacks */
- ot->invoke = eyedropper_invoke;
- ot->modal = eyedropper_modal;
- ot->cancel = eyedropper_cancel;
- ot->exec = eyedropper_exec;
- ot->poll = eyedropper_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
- /* properties */
- PropertyRNA *prop;
-
- /* Needed for color picking with crypto-matte. */
- prop = RNA_def_boolean(ot->srna, "use_accumulate", true, "Accumulate", "");
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ /* identifiers */
+ ot->name = "Eyedropper";
+ ot->idname = "UI_OT_eyedropper_color";
+ ot->description = "Sample a color from the Blender Window to store in a property";
+
+ /* api callbacks */
+ ot->invoke = eyedropper_invoke;
+ ot->modal = eyedropper_modal;
+ ot->cancel = eyedropper_cancel;
+ ot->exec = eyedropper_exec;
+ ot->poll = eyedropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
+ PropertyRNA *prop;
+
+ /* Needed for color picking with crypto-matte. */
+ prop = RNA_def_boolean(ot->srna, "use_accumulate", true, "Accumulate", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/interface/interface_eyedropper_colorband.c b/source/blender/editors/interface/interface_eyedropper_colorband.c
index 6c60640b428..67e5a6c806c 100644
--- a/source/blender/editors/interface/interface_eyedropper_colorband.c
+++ b/source/blender/editors/interface/interface_eyedropper_colorband.c
@@ -53,307 +53,312 @@
#include "interface_eyedropper_intern.h"
typedef struct Colorband_RNAUpdateCb {
- PointerRNA ptr;
- PropertyRNA *prop;
+ PointerRNA ptr;
+ PropertyRNA *prop;
} Colorband_RNAUpdateCb;
typedef struct EyedropperColorband {
- int last_x, last_y;
- /* Alpha is currently fixed at 1.0, may support in future. */
- float (*color_buffer)[4];
- int color_buffer_alloc;
- int color_buffer_len;
- bool sample_start;
- ColorBand init_color_band;
- ColorBand *color_band;
- PointerRNA ptr;
- PropertyRNA *prop;
- bool is_undo;
- bool is_set;
+ int last_x, last_y;
+ /* Alpha is currently fixed at 1.0, may support in future. */
+ float (*color_buffer)[4];
+ int color_buffer_alloc;
+ int color_buffer_len;
+ bool sample_start;
+ ColorBand init_color_band;
+ ColorBand *color_band;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ bool is_undo;
+ bool is_set;
} EyedropperColorband;
/* For user-data only. */
struct EyedropperColorband_Context {
- bContext *context;
- EyedropperColorband *eye;
+ bContext *context;
+ EyedropperColorband *eye;
};
static bool eyedropper_colorband_init(bContext *C, wmOperator *op)
{
- ColorBand *band = NULL;
-
- uiBut *but = UI_context_active_but_get(C);
-
- if (but == NULL) {
- /* pass */
- }
- else if (but->type == UI_BTYPE_COLORBAND) {
- /* When invoked with a hotkey, we can find the band in 'but->poin'. */
- band = (ColorBand *)but->poin;
- }
- else {
- /* When invoked from a button it's in custom_data field. */
- band = (ColorBand *)but->custom_data;
- }
-
- if (!band) {
- PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp);
- if (ptr.data != NULL) {
- band = ptr.data;
- }
- }
-
- if (!band) {
- return false;
- }
-
- EyedropperColorband *eye = MEM_callocN(sizeof(EyedropperColorband), __func__);
- eye->color_buffer_alloc = 16;
- eye->color_buffer = MEM_mallocN(sizeof(*eye->color_buffer) * eye->color_buffer_alloc, __func__);
- eye->color_buffer_len = 0;
- eye->color_band = band;
- eye->init_color_band = *eye->color_band;
- eye->ptr = ((Colorband_RNAUpdateCb *)but->func_argN)->ptr;
- eye->prop = ((Colorband_RNAUpdateCb *)but->func_argN)->prop;
- eye->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
-
- op->customdata = eye;
-
- return true;
+ ColorBand *band = NULL;
+
+ uiBut *but = UI_context_active_but_get(C);
+
+ if (but == NULL) {
+ /* pass */
+ }
+ else if (but->type == UI_BTYPE_COLORBAND) {
+ /* When invoked with a hotkey, we can find the band in 'but->poin'. */
+ band = (ColorBand *)but->poin;
+ }
+ else {
+ /* When invoked from a button it's in custom_data field. */
+ band = (ColorBand *)but->custom_data;
+ }
+
+ if (!band) {
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp);
+ if (ptr.data != NULL) {
+ band = ptr.data;
+ }
+ }
+
+ if (!band) {
+ return false;
+ }
+
+ EyedropperColorband *eye = MEM_callocN(sizeof(EyedropperColorband), __func__);
+ eye->color_buffer_alloc = 16;
+ eye->color_buffer = MEM_mallocN(sizeof(*eye->color_buffer) * eye->color_buffer_alloc, __func__);
+ eye->color_buffer_len = 0;
+ eye->color_band = band;
+ eye->init_color_band = *eye->color_band;
+ eye->ptr = ((Colorband_RNAUpdateCb *)but->func_argN)->ptr;
+ eye->prop = ((Colorband_RNAUpdateCb *)but->func_argN)->prop;
+ eye->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
+
+ op->customdata = eye;
+
+ return true;
}
-static void eyedropper_colorband_sample_point(bContext *C, EyedropperColorband *eye, int mx, int my)
+static void eyedropper_colorband_sample_point(bContext *C,
+ EyedropperColorband *eye,
+ int mx,
+ int my)
{
- if (eye->last_x != mx || eye->last_y != my) {
- float col[4];
- col[3] = 1.0f; /* TODO: sample alpha */
- eyedropper_color_sample_fl(C, mx, my, col);
- if (eye->color_buffer_len + 1 == eye->color_buffer_alloc) {
- eye->color_buffer_alloc *= 2;
- eye->color_buffer = MEM_reallocN(eye->color_buffer, sizeof(*eye->color_buffer) * eye->color_buffer_alloc);
- }
- copy_v4_v4(eye->color_buffer[eye->color_buffer_len], col);
- eye->color_buffer_len += 1;
- eye->last_x = mx;
- eye->last_y = my;
- eye->is_set = true;
- }
+ if (eye->last_x != mx || eye->last_y != my) {
+ float col[4];
+ col[3] = 1.0f; /* TODO: sample alpha */
+ eyedropper_color_sample_fl(C, mx, my, col);
+ if (eye->color_buffer_len + 1 == eye->color_buffer_alloc) {
+ eye->color_buffer_alloc *= 2;
+ eye->color_buffer = MEM_reallocN(eye->color_buffer,
+ sizeof(*eye->color_buffer) * eye->color_buffer_alloc);
+ }
+ copy_v4_v4(eye->color_buffer[eye->color_buffer_len], col);
+ eye->color_buffer_len += 1;
+ eye->last_x = mx;
+ eye->last_y = my;
+ eye->is_set = true;
+ }
}
static bool eyedropper_colorband_sample_callback(int mx, int my, void *userdata)
{
- struct EyedropperColorband_Context *data = userdata;
- bContext *C = data->context;
- EyedropperColorband *eye = data->eye;
- eyedropper_colorband_sample_point(C, eye, mx, my);
- return true;
+ struct EyedropperColorband_Context *data = userdata;
+ bContext *C = data->context;
+ EyedropperColorband *eye = data->eye;
+ eyedropper_colorband_sample_point(C, eye, mx, my);
+ return true;
}
-static void eyedropper_colorband_sample_segment(bContext *C, EyedropperColorband *eye, int mx, int my)
+static void eyedropper_colorband_sample_segment(bContext *C,
+ EyedropperColorband *eye,
+ int mx,
+ int my)
{
- /* Since the mouse tends to move rather rapidly we use #BLI_bitmap_draw_2d_line_v2v2i
- * to interpolate between the reported coordinates */
- struct EyedropperColorband_Context userdata = {C, eye};
- int p1[2] = {eye->last_x, eye->last_y};
- int p2[2] = {mx, my};
- BLI_bitmap_draw_2d_line_v2v2i(p1, p2, eyedropper_colorband_sample_callback, &userdata);
+ /* Since the mouse tends to move rather rapidly we use #BLI_bitmap_draw_2d_line_v2v2i
+ * to interpolate between the reported coordinates */
+ struct EyedropperColorband_Context userdata = {C, eye};
+ int p1[2] = {eye->last_x, eye->last_y};
+ int p2[2] = {mx, my};
+ BLI_bitmap_draw_2d_line_v2v2i(p1, p2, eyedropper_colorband_sample_callback, &userdata);
}
static void eyedropper_colorband_exit(bContext *C, wmOperator *op)
{
- WM_cursor_modal_restore(CTX_wm_window(C));
-
- if (op->customdata) {
- EyedropperColorband *eye = op->customdata;
- MEM_freeN(eye->color_buffer);
- MEM_freeN(eye);
- op->customdata = NULL;
- }
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ if (op->customdata) {
+ EyedropperColorband *eye = op->customdata;
+ MEM_freeN(eye->color_buffer);
+ MEM_freeN(eye);
+ op->customdata = NULL;
+ }
}
static void eyedropper_colorband_apply(bContext *C, wmOperator *op)
{
- EyedropperColorband *eye = op->customdata;
- /* Always filter, avoids noise in resulting color-band. */
- bool filter_samples = true;
- BKE_colorband_init_from_table_rgba(eye->color_band, eye->color_buffer, eye->color_buffer_len, filter_samples);
- eye->is_set = true;
- RNA_property_update(C, &eye->ptr, eye->prop);
+ EyedropperColorband *eye = op->customdata;
+ /* Always filter, avoids noise in resulting color-band. */
+ bool filter_samples = true;
+ BKE_colorband_init_from_table_rgba(
+ eye->color_band, eye->color_buffer, eye->color_buffer_len, filter_samples);
+ eye->is_set = true;
+ RNA_property_update(C, &eye->ptr, eye->prop);
}
static void eyedropper_colorband_cancel(bContext *C, wmOperator *op)
{
- EyedropperColorband *eye = op->customdata;
- if (eye->is_set) {
- *eye->color_band = eye->init_color_band;
- RNA_property_update(C, &eye->ptr, eye->prop);
- }
- eyedropper_colorband_exit(C, op);
+ EyedropperColorband *eye = op->customdata;
+ if (eye->is_set) {
+ *eye->color_band = eye->init_color_band;
+ RNA_property_update(C, &eye->ptr, eye->prop);
+ }
+ eyedropper_colorband_exit(C, op);
}
/* main modal status check */
static int eyedropper_colorband_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- EyedropperColorband *eye = op->customdata;
- /* handle modal keymap */
- if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case EYE_MODAL_CANCEL:
- eyedropper_colorband_cancel(C, op);
- return OPERATOR_CANCELLED;
- case EYE_MODAL_SAMPLE_CONFIRM:
- {
- const bool is_undo = eye->is_undo;
- eyedropper_colorband_sample_segment(C, eye, event->x, event->y);
- eyedropper_colorband_apply(C, op);
- eyedropper_colorband_exit(C, op);
- /* Could support finished & undo-skip. */
- return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
- }
- case EYE_MODAL_SAMPLE_BEGIN:
- /* enable accum and make first sample */
- eye->sample_start = true;
- eyedropper_colorband_sample_point(C, eye, event->x, event->y);
- eyedropper_colorband_apply(C, op);
- eye->last_x = event->x;
- eye->last_y = event->y;
- break;
- case EYE_MODAL_SAMPLE_RESET:
- break;
- }
- }
- else if (event->type == MOUSEMOVE) {
- if (eye->sample_start) {
- eyedropper_colorband_sample_segment(C, eye, event->x, event->y);
- eyedropper_colorband_apply(C, op);
- }
- }
- return OPERATOR_RUNNING_MODAL;
+ EyedropperColorband *eye = op->customdata;
+ /* handle modal keymap */
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EYE_MODAL_CANCEL:
+ eyedropper_colorband_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ case EYE_MODAL_SAMPLE_CONFIRM: {
+ const bool is_undo = eye->is_undo;
+ eyedropper_colorband_sample_segment(C, eye, event->x, event->y);
+ eyedropper_colorband_apply(C, op);
+ eyedropper_colorband_exit(C, op);
+ /* Could support finished & undo-skip. */
+ return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ }
+ case EYE_MODAL_SAMPLE_BEGIN:
+ /* enable accum and make first sample */
+ eye->sample_start = true;
+ eyedropper_colorband_sample_point(C, eye, event->x, event->y);
+ eyedropper_colorband_apply(C, op);
+ eye->last_x = event->x;
+ eye->last_y = event->y;
+ break;
+ case EYE_MODAL_SAMPLE_RESET:
+ break;
+ }
+ }
+ else if (event->type == MOUSEMOVE) {
+ if (eye->sample_start) {
+ eyedropper_colorband_sample_segment(C, eye, event->x, event->y);
+ eyedropper_colorband_apply(C, op);
+ }
+ }
+ return OPERATOR_RUNNING_MODAL;
}
static int eyedropper_colorband_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- EyedropperColorband *eye = op->customdata;
- /* handle modal keymap */
- if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case EYE_MODAL_POINT_CANCEL:
- eyedropper_colorband_cancel(C, op);
- return OPERATOR_CANCELLED;
- case EYE_MODAL_POINT_CONFIRM:
- eyedropper_colorband_apply(C, op);
- eyedropper_colorband_exit(C, op);
- return OPERATOR_FINISHED;
- case EYE_MODAL_POINT_REMOVE_LAST:
- if (eye->color_buffer_len > 0) {
- eye->color_buffer_len -= 1;
- eyedropper_colorband_apply(C, op);
- }
- break;
- case EYE_MODAL_POINT_SAMPLE:
- eyedropper_colorband_sample_point(C, eye, event->x, event->y);
- eyedropper_colorband_apply(C, op);
- if (eye->color_buffer_len == MAXCOLORBAND ) {
- eyedropper_colorband_exit(C, op);
- return OPERATOR_FINISHED;
- }
- break;
- case EYE_MODAL_SAMPLE_RESET:
- *eye->color_band = eye->init_color_band;
- RNA_property_update(C, &eye->ptr, eye->prop);
- eye->color_buffer_len = 0;
- break;
- }
- }
- return OPERATOR_RUNNING_MODAL;
+ EyedropperColorband *eye = op->customdata;
+ /* handle modal keymap */
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EYE_MODAL_POINT_CANCEL:
+ eyedropper_colorband_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ case EYE_MODAL_POINT_CONFIRM:
+ eyedropper_colorband_apply(C, op);
+ eyedropper_colorband_exit(C, op);
+ return OPERATOR_FINISHED;
+ case EYE_MODAL_POINT_REMOVE_LAST:
+ if (eye->color_buffer_len > 0) {
+ eye->color_buffer_len -= 1;
+ eyedropper_colorband_apply(C, op);
+ }
+ break;
+ case EYE_MODAL_POINT_SAMPLE:
+ eyedropper_colorband_sample_point(C, eye, event->x, event->y);
+ eyedropper_colorband_apply(C, op);
+ if (eye->color_buffer_len == MAXCOLORBAND) {
+ eyedropper_colorband_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ case EYE_MODAL_SAMPLE_RESET:
+ *eye->color_band = eye->init_color_band;
+ RNA_property_update(C, &eye->ptr, eye->prop);
+ eye->color_buffer_len = 0;
+ break;
+ }
+ }
+ return OPERATOR_RUNNING_MODAL;
}
-
/* Modal Operator init */
static int eyedropper_colorband_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- /* init */
- if (eyedropper_colorband_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* init */
+ if (eyedropper_colorband_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
/* Repeat operator */
static int eyedropper_colorband_exec(bContext *C, wmOperator *op)
{
- /* init */
- if (eyedropper_colorband_init(C, op)) {
+ /* init */
+ if (eyedropper_colorband_init(C, op)) {
- /* do something */
+ /* do something */
- /* cleanup */
- eyedropper_colorband_exit(C, op);
+ /* cleanup */
+ eyedropper_colorband_exit(C, op);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static bool eyedropper_colorband_poll(bContext *C)
{
- uiBut *but = UI_context_active_but_get(C);
- if (but && but->type == UI_BTYPE_COLORBAND) {
- return true;
- }
- PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp);
- if (ptr.data != NULL) {
- return true;
- }
- return false;
+ uiBut *but = UI_context_active_but_get(C);
+ if (but && but->type == UI_BTYPE_COLORBAND) {
+ return true;
+ }
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp);
+ if (ptr.data != NULL) {
+ return true;
+ }
+ return false;
}
-
void UI_OT_eyedropper_colorramp(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Eyedropper colorband";
- ot->idname = "UI_OT_eyedropper_colorramp";
- ot->description = "Sample a color band";
-
- /* api callbacks */
- ot->invoke = eyedropper_colorband_invoke;
- ot->modal = eyedropper_colorband_modal;
- ot->cancel = eyedropper_colorband_cancel;
- ot->exec = eyedropper_colorband_exec;
- ot->poll = eyedropper_colorband_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
- /* properties */
+ /* identifiers */
+ ot->name = "Eyedropper colorband";
+ ot->idname = "UI_OT_eyedropper_colorramp";
+ ot->description = "Sample a color band";
+
+ /* api callbacks */
+ ot->invoke = eyedropper_colorband_invoke;
+ ot->modal = eyedropper_colorband_modal;
+ ot->cancel = eyedropper_colorband_cancel;
+ ot->exec = eyedropper_colorband_exec;
+ ot->poll = eyedropper_colorband_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
}
void UI_OT_eyedropper_colorramp_point(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Eyedropper colorband (points)";
- ot->idname = "UI_OT_eyedropper_colorramp_point";
- ot->description = "Point-sample a color band";
-
- /* api callbacks */
- ot->invoke = eyedropper_colorband_invoke;
- ot->modal = eyedropper_colorband_point_modal;
- ot->cancel = eyedropper_colorband_cancel;
- ot->exec = eyedropper_colorband_exec;
- ot->poll = eyedropper_colorband_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
- /* properties */
+ /* identifiers */
+ ot->name = "Eyedropper colorband (points)";
+ ot->idname = "UI_OT_eyedropper_colorramp_point";
+ ot->description = "Point-sample a color band";
+
+ /* api callbacks */
+ ot->invoke = eyedropper_colorband_invoke;
+ ot->modal = eyedropper_colorband_point_modal;
+ ot->cancel = eyedropper_colorband_cancel;
+ ot->exec = eyedropper_colorband_exec;
+ ot->poll = eyedropper_colorband_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
}
diff --git a/source/blender/editors/interface/interface_eyedropper_datablock.c b/source/blender/editors/interface/interface_eyedropper_datablock.c
index ffd8f672622..1d90139eade 100644
--- a/source/blender/editors/interface/interface_eyedropper_datablock.c
+++ b/source/blender/editors/interface/interface_eyedropper_datablock.c
@@ -59,87 +59,84 @@
* \note #DataDropper is only internal name to avoid confusion with other kinds of eye-droppers.
*/
typedef struct DataDropper {
- PointerRNA ptr;
- PropertyRNA *prop;
- short idcode;
- const char *idcode_name;
- bool is_undo;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ short idcode;
+ const char *idcode_name;
+ bool is_undo;
- ID *init_id; /* for resetting on cancel */
+ ID *init_id; /* for resetting on cancel */
- ARegionType *art;
- void *draw_handle_pixel;
- char name[200];
+ ARegionType *art;
+ void *draw_handle_pixel;
+ char name[200];
} DataDropper;
-
static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg)
{
- DataDropper *ddr = arg;
- eyedropper_draw_cursor_text(C, ar, ddr->name);
+ DataDropper *ddr = arg;
+ eyedropper_draw_cursor_text(C, ar, ddr->name);
}
-
static int datadropper_init(bContext *C, wmOperator *op)
{
- int index_dummy;
- StructRNA *type;
+ int index_dummy;
+ StructRNA *type;
- SpaceType *st;
- ARegionType *art;
+ SpaceType *st;
+ ARegionType *art;
- st = BKE_spacetype_from_id(SPACE_VIEW3D);
- art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);
+ st = BKE_spacetype_from_id(SPACE_VIEW3D);
+ art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);
- DataDropper *ddr = MEM_callocN(sizeof(DataDropper), __func__);
+ DataDropper *ddr = MEM_callocN(sizeof(DataDropper), __func__);
- uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
+ uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
- if ((ddr->ptr.data == NULL) ||
- (ddr->prop == NULL) ||
- (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
- (RNA_property_type(ddr->prop) != PROP_POINTER))
- {
- MEM_freeN(ddr);
- return false;
- }
- op->customdata = ddr;
+ if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) ||
+ (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
+ (RNA_property_type(ddr->prop) != PROP_POINTER)) {
+ MEM_freeN(ddr);
+ return false;
+ }
+ op->customdata = ddr;
- ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
+ ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
- ddr->art = art;
- ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, datadropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
+ ddr->art = art;
+ ddr->draw_handle_pixel = ED_region_draw_cb_activate(
+ art, datadropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
- type = RNA_property_pointer_type(&ddr->ptr, ddr->prop);
- ddr->idcode = RNA_type_to_ID_code(type);
- BLI_assert(ddr->idcode != 0);
- /* Note we can translate here (instead of on draw time),
- * because this struct has very short lifetime. */
- ddr->idcode_name = TIP_(BKE_idcode_to_name(ddr->idcode));
+ type = RNA_property_pointer_type(&ddr->ptr, ddr->prop);
+ ddr->idcode = RNA_type_to_ID_code(type);
+ BLI_assert(ddr->idcode != 0);
+ /* Note we can translate here (instead of on draw time),
+ * because this struct has very short lifetime. */
+ ddr->idcode_name = TIP_(BKE_idcode_to_name(ddr->idcode));
- PointerRNA ptr = RNA_property_pointer_get(&ddr->ptr, ddr->prop);
- ddr->init_id = ptr.id.data;
+ PointerRNA ptr = RNA_property_pointer_get(&ddr->ptr, ddr->prop);
+ ddr->init_id = ptr.id.data;
- return true;
+ return true;
}
static void datadropper_exit(bContext *C, wmOperator *op)
{
- WM_cursor_modal_restore(CTX_wm_window(C));
+ WM_cursor_modal_restore(CTX_wm_window(C));
- if (op->customdata) {
- DataDropper *ddr = (DataDropper *)op->customdata;
+ if (op->customdata) {
+ DataDropper *ddr = (DataDropper *)op->customdata;
- if (ddr->art) {
- ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel);
- }
+ if (ddr->art) {
+ ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel);
+ }
- MEM_freeN(op->customdata);
+ MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
+ op->customdata = NULL;
+ }
- WM_event_add_mousemove(C);
+ WM_event_add_mousemove(C);
}
/* *** datadropper id helper functions *** */
@@ -148,204 +145,198 @@ static void datadropper_exit(bContext *C, wmOperator *op)
*/
static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id)
{
- /* we could use some clever */
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = BKE_screen_find_area_xy(screen, -1, mx, my);
-
- ScrArea *area_prev = CTX_wm_area(C);
- ARegion *ar_prev = CTX_wm_region(C);
-
- ddr->name[0] = '\0';
-
- if (sa) {
- if (sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
- if (ar) {
- const int mval[2] = {
- mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
- Base *base;
-
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
-
- /* grr, always draw else we leave stale text */
- ED_region_tag_redraw(ar);
-
- base = ED_view3d_give_base_under_cursor(C, mval);
- if (base) {
- Object *ob = base->object;
- ID *id = NULL;
- if (ddr->idcode == ID_OB) {
- id = (ID *)ob;
- }
- else if (ob->data) {
- if (GS(((ID *)ob->data)->name) == ddr->idcode) {
- id = (ID *)ob->data;
- }
- else {
- BLI_snprintf(ddr->name, sizeof(ddr->name), "Incompatible, expected a %s",
- ddr->idcode_name);
- }
- }
-
- PointerRNA idptr;
- RNA_id_pointer_create(id, &idptr);
-
- if (id && RNA_property_pointer_poll(&ddr->ptr, ddr->prop, &idptr)) {
- BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s",
- ddr->idcode_name, id->name + 2);
- *r_id = id;
- }
- }
- }
- }
- }
-
- CTX_wm_area_set(C, area_prev);
- CTX_wm_region_set(C, ar_prev);
+ /* we could use some clever */
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = BKE_screen_find_area_xy(screen, -1, mx, my);
+
+ ScrArea *area_prev = CTX_wm_area(C);
+ ARegion *ar_prev = CTX_wm_region(C);
+
+ ddr->name[0] = '\0';
+
+ if (sa) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
+ const int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
+ Base *base;
+
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ /* grr, always draw else we leave stale text */
+ ED_region_tag_redraw(ar);
+
+ base = ED_view3d_give_base_under_cursor(C, mval);
+ if (base) {
+ Object *ob = base->object;
+ ID *id = NULL;
+ if (ddr->idcode == ID_OB) {
+ id = (ID *)ob;
+ }
+ else if (ob->data) {
+ if (GS(((ID *)ob->data)->name) == ddr->idcode) {
+ id = (ID *)ob->data;
+ }
+ else {
+ BLI_snprintf(
+ ddr->name, sizeof(ddr->name), "Incompatible, expected a %s", ddr->idcode_name);
+ }
+ }
+
+ PointerRNA idptr;
+ RNA_id_pointer_create(id, &idptr);
+
+ if (id && RNA_property_pointer_poll(&ddr->ptr, ddr->prop, &idptr)) {
+ BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s", ddr->idcode_name, id->name + 2);
+ *r_id = id;
+ }
+ }
+ }
+ }
+ }
+
+ CTX_wm_area_set(C, area_prev);
+ CTX_wm_region_set(C, ar_prev);
}
/* sets the ID, returns success */
static bool datadropper_id_set(bContext *C, DataDropper *ddr, ID *id)
{
- PointerRNA ptr_value;
+ PointerRNA ptr_value;
- RNA_id_pointer_create(id, &ptr_value);
+ RNA_id_pointer_create(id, &ptr_value);
- RNA_property_pointer_set(&ddr->ptr, ddr->prop, ptr_value);
+ RNA_property_pointer_set(&ddr->ptr, ddr->prop, ptr_value);
- RNA_property_update(C, &ddr->ptr, ddr->prop);
+ RNA_property_update(C, &ddr->ptr, ddr->prop);
- ptr_value = RNA_property_pointer_get(&ddr->ptr, ddr->prop);
+ ptr_value = RNA_property_pointer_get(&ddr->ptr, ddr->prop);
- return (ptr_value.id.data == id);
+ return (ptr_value.id.data == id);
}
/* single point sample & set */
static bool datadropper_id_sample(bContext *C, DataDropper *ddr, int mx, int my)
{
- ID *id = NULL;
+ ID *id = NULL;
- datadropper_id_sample_pt(C, ddr, mx, my, &id);
- return datadropper_id_set(C, ddr, id);
+ datadropper_id_sample_pt(C, ddr, mx, my, &id);
+ return datadropper_id_set(C, ddr, id);
}
static void datadropper_cancel(bContext *C, wmOperator *op)
{
- DataDropper *ddr = op->customdata;
- datadropper_id_set(C, ddr, ddr->init_id);
- datadropper_exit(C, op);
+ DataDropper *ddr = op->customdata;
+ datadropper_id_set(C, ddr, ddr->init_id);
+ datadropper_exit(C, op);
}
/* main modal status check */
static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- DataDropper *ddr = (DataDropper *)op->customdata;
-
- /* handle modal keymap */
- if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case EYE_MODAL_CANCEL:
- datadropper_cancel(C, op);
- return OPERATOR_CANCELLED;
- case EYE_MODAL_SAMPLE_CONFIRM:
- {
- const bool is_undo = ddr->is_undo;
- const bool success = datadropper_id_sample(C, ddr, event->x, event->y);
- datadropper_exit(C, op);
- if (success) {
- /* Could support finished & undo-skip. */
- return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
- }
- else {
- BKE_report(op->reports, RPT_WARNING, "Failed to set value");
- return OPERATOR_CANCELLED;
- }
- }
- }
- }
- else if (event->type == MOUSEMOVE) {
- ID *id = NULL;
- datadropper_id_sample_pt(C, ddr, event->x, event->y, &id);
- }
-
- return OPERATOR_RUNNING_MODAL;
+ DataDropper *ddr = (DataDropper *)op->customdata;
+
+ /* handle modal keymap */
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EYE_MODAL_CANCEL:
+ datadropper_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ case EYE_MODAL_SAMPLE_CONFIRM: {
+ const bool is_undo = ddr->is_undo;
+ const bool success = datadropper_id_sample(C, ddr, event->x, event->y);
+ datadropper_exit(C, op);
+ if (success) {
+ /* Could support finished & undo-skip. */
+ return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ }
+ else {
+ BKE_report(op->reports, RPT_WARNING, "Failed to set value");
+ return OPERATOR_CANCELLED;
+ }
+ }
+ }
+ }
+ else if (event->type == MOUSEMOVE) {
+ ID *id = NULL;
+ datadropper_id_sample_pt(C, ddr, event->x, event->y, &id);
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
/* Modal Operator init */
static int datadropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- /* init */
- if (datadropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* init */
+ if (datadropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
/* Repeat operator */
static int datadropper_exec(bContext *C, wmOperator *op)
{
- /* init */
- if (datadropper_init(C, op)) {
- /* cleanup */
- datadropper_exit(C, op);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* init */
+ if (datadropper_init(C, op)) {
+ /* cleanup */
+ datadropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static bool datadropper_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index_dummy;
- uiBut *but;
-
- /* data dropper only supports object data */
- if ((CTX_wm_window(C) != NULL) &&
- (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
- (but->type == UI_BTYPE_SEARCH_MENU) &&
- (but->flag & UI_BUT_VALUE_CLEAR))
- {
- if (prop && RNA_property_type(prop) == PROP_POINTER) {
- StructRNA *type = RNA_property_pointer_type(&ptr, prop);
- const short idcode = RNA_type_to_ID_code(type);
- if ((idcode == ID_OB) || OB_DATA_SUPPORT_ID(idcode)) {
- return 1;
- }
- }
- }
-
- return 0;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index_dummy;
+ uiBut *but;
+
+ /* data dropper only supports object data */
+ if ((CTX_wm_window(C) != NULL) &&
+ (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
+ (but->type == UI_BTYPE_SEARCH_MENU) && (but->flag & UI_BUT_VALUE_CLEAR)) {
+ if (prop && RNA_property_type(prop) == PROP_POINTER) {
+ StructRNA *type = RNA_property_pointer_type(&ptr, prop);
+ const short idcode = RNA_type_to_ID_code(type);
+ if ((idcode == ID_OB) || OB_DATA_SUPPORT_ID(idcode)) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
}
void UI_OT_eyedropper_id(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Eyedropper Data-Block";
- ot->idname = "UI_OT_eyedropper_id";
- ot->description = "Sample a data-block from the 3D View to store in a property";
-
- /* api callbacks */
- ot->invoke = datadropper_invoke;
- ot->modal = datadropper_modal;
- ot->cancel = datadropper_cancel;
- ot->exec = datadropper_exec;
- ot->poll = datadropper_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
- /* properties */
+ /* identifiers */
+ ot->name = "Eyedropper Data-Block";
+ ot->idname = "UI_OT_eyedropper_id";
+ ot->description = "Sample a data-block from the 3D View to store in a property";
+
+ /* api callbacks */
+ ot->invoke = datadropper_invoke;
+ ot->modal = datadropper_modal;
+ ot->cancel = datadropper_cancel;
+ ot->exec = datadropper_exec;
+ ot->poll = datadropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
}
diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c
index 9e559f65335..adb317f488c 100644
--- a/source/blender/editors/interface/interface_eyedropper_depth.c
+++ b/source/blender/editors/interface/interface_eyedropper_depth.c
@@ -60,334 +60,328 @@
* \note #DepthDropper is only internal name to avoid confusion with other kinds of eye-droppers.
*/
typedef struct DepthDropper {
- PointerRNA ptr;
- PropertyRNA *prop;
- bool is_undo;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ bool is_undo;
- bool is_set;
- float init_depth; /* for resetting on cancel */
+ bool is_set;
+ float init_depth; /* for resetting on cancel */
- bool accum_start; /* has mouse been presed */
- float accum_depth;
- int accum_tot;
+ bool accum_start; /* has mouse been presed */
+ float accum_depth;
+ int accum_tot;
- ARegionType *art;
- void *draw_handle_pixel;
- char name[200];
+ ARegionType *art;
+ void *draw_handle_pixel;
+ char name[200];
} DepthDropper;
-
static void depthdropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg)
{
- DepthDropper *ddr = arg;
- eyedropper_draw_cursor_text(C, ar, ddr->name);
+ DepthDropper *ddr = arg;
+ eyedropper_draw_cursor_text(C, ar, ddr->name);
}
-
static int depthdropper_init(bContext *C, wmOperator *op)
{
- int index_dummy;
-
- SpaceType *st;
- ARegionType *art;
-
- st = BKE_spacetype_from_id(SPACE_VIEW3D);
- art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);
-
- DepthDropper *ddr = MEM_callocN(sizeof(DepthDropper), __func__);
-
- uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
-
- /* fallback to the active camera's dof */
- if (ddr->prop == NULL) {
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d && rv3d->persp == RV3D_CAMOB) {
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) {
- RNA_id_pointer_create(v3d->camera->data, &ddr->ptr);
- ddr->prop = RNA_struct_find_property(&ddr->ptr, "dof_distance");
- ddr->is_undo = true;
- }
- }
- }
- else {
- ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
- }
-
- if ((ddr->ptr.data == NULL) ||
- (ddr->prop == NULL) ||
- (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
- (RNA_property_type(ddr->prop) != PROP_FLOAT))
- {
- MEM_freeN(ddr);
- return false;
- }
- op->customdata = ddr;
-
- ddr->art = art;
- ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, depthdropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
- ddr->init_depth = RNA_property_float_get(&ddr->ptr, ddr->prop);
-
- return true;
+ int index_dummy;
+
+ SpaceType *st;
+ ARegionType *art;
+
+ st = BKE_spacetype_from_id(SPACE_VIEW3D);
+ art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);
+
+ DepthDropper *ddr = MEM_callocN(sizeof(DepthDropper), __func__);
+
+ uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
+
+ /* fallback to the active camera's dof */
+ if (ddr->prop == NULL) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (rv3d && rv3d->persp == RV3D_CAMOB) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) {
+ RNA_id_pointer_create(v3d->camera->data, &ddr->ptr);
+ ddr->prop = RNA_struct_find_property(&ddr->ptr, "dof_distance");
+ ddr->is_undo = true;
+ }
+ }
+ }
+ else {
+ ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
+ }
+
+ if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) ||
+ (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
+ (RNA_property_type(ddr->prop) != PROP_FLOAT)) {
+ MEM_freeN(ddr);
+ return false;
+ }
+ op->customdata = ddr;
+
+ ddr->art = art;
+ ddr->draw_handle_pixel = ED_region_draw_cb_activate(
+ art, depthdropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
+ ddr->init_depth = RNA_property_float_get(&ddr->ptr, ddr->prop);
+
+ return true;
}
static void depthdropper_exit(bContext *C, wmOperator *op)
{
- WM_cursor_modal_restore(CTX_wm_window(C));
+ WM_cursor_modal_restore(CTX_wm_window(C));
- if (op->customdata) {
- DepthDropper *ddr = (DepthDropper *)op->customdata;
+ if (op->customdata) {
+ DepthDropper *ddr = (DepthDropper *)op->customdata;
- if (ddr->art) {
- ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel);
- }
+ if (ddr->art) {
+ ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel);
+ }
- MEM_freeN(op->customdata);
+ MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
+ op->customdata = NULL;
+ }
}
/* *** depthdropper id helper functions *** */
/**
* \brief get the ID from the screen.
*/
-static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth)
+static void depthdropper_depth_sample_pt(
+ bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth)
{
- /* we could use some clever */
- bScreen *screen = CTX_wm_screen(C);
- ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
- Scene *scene = CTX_data_scene(C);
-
- ScrArea *area_prev = CTX_wm_area(C);
- ARegion *ar_prev = CTX_wm_region(C);
-
- ddr->name[0] = '\0';
-
- if (sa) {
- if (sa->spacetype == SPACE_VIEW3D) {
- ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
- if (ar) {
- struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
- View3D *v3d = sa->spacedata.first;
- RegionView3D *rv3d = ar->regiondata;
- /* weak, we could pass in some reference point */
- const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3];
- const int mval[2] = {
- mx - ar->winrct.xmin,
- my - ar->winrct.ymin};
- float co[3];
-
- CTX_wm_area_set(C, sa);
- CTX_wm_region_set(C, ar);
-
- /* grr, always draw else we leave stale text */
- ED_region_tag_redraw(ar);
-
- view3d_operator_needs_opengl(C);
-
- if (ED_view3d_autodist(depsgraph, ar, v3d, mval, co, true, NULL)) {
- const float mval_center_fl[2] = {
- (float)ar->winx / 2,
- (float)ar->winy / 2};
- float co_align[3];
-
- /* quick way to get view-center aligned point */
- ED_view3d_win_to_3d(v3d, ar, co, mval_center_fl, co_align);
-
- *r_depth = len_v3v3(view_co, co_align);
-
- bUnit_AsString2(
- ddr->name, sizeof(ddr->name), (double)*r_depth,
- 4, B_UNIT_LENGTH, &scene->unit, false);
- }
- else {
- BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name));
- }
- }
- }
- }
-
- CTX_wm_area_set(C, area_prev);
- CTX_wm_region_set(C, ar_prev);
+ /* we could use some clever */
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
+ Scene *scene = CTX_data_scene(C);
+
+ ScrArea *area_prev = CTX_wm_area(C);
+ ARegion *ar_prev = CTX_wm_region(C);
+
+ ddr->name[0] = '\0';
+
+ if (sa) {
+ if (sa->spacetype == SPACE_VIEW3D) {
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my);
+ if (ar) {
+ struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ View3D *v3d = sa->spacedata.first;
+ RegionView3D *rv3d = ar->regiondata;
+ /* weak, we could pass in some reference point */
+ const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3];
+ const int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin};
+ float co[3];
+
+ CTX_wm_area_set(C, sa);
+ CTX_wm_region_set(C, ar);
+
+ /* grr, always draw else we leave stale text */
+ ED_region_tag_redraw(ar);
+
+ view3d_operator_needs_opengl(C);
+
+ if (ED_view3d_autodist(depsgraph, ar, v3d, mval, co, true, NULL)) {
+ const float mval_center_fl[2] = {(float)ar->winx / 2, (float)ar->winy / 2};
+ float co_align[3];
+
+ /* quick way to get view-center aligned point */
+ ED_view3d_win_to_3d(v3d, ar, co, mval_center_fl, co_align);
+
+ *r_depth = len_v3v3(view_co, co_align);
+
+ bUnit_AsString2(ddr->name,
+ sizeof(ddr->name),
+ (double)*r_depth,
+ 4,
+ B_UNIT_LENGTH,
+ &scene->unit,
+ false);
+ }
+ else {
+ BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name));
+ }
+ }
+ }
+ }
+
+ CTX_wm_area_set(C, area_prev);
+ CTX_wm_region_set(C, ar_prev);
}
/* sets the sample depth RGB, maintaining A */
static void depthdropper_depth_set(bContext *C, DepthDropper *ddr, const float depth)
{
- RNA_property_float_set(&ddr->ptr, ddr->prop, depth);
- ddr->is_set = true;
- RNA_property_update(C, &ddr->ptr, ddr->prop);
+ RNA_property_float_set(&ddr->ptr, ddr->prop, depth);
+ ddr->is_set = true;
+ RNA_property_update(C, &ddr->ptr, ddr->prop);
}
/* set sample from accumulated values */
static void depthdropper_depth_set_accum(bContext *C, DepthDropper *ddr)
{
- float depth = ddr->accum_depth;
- if (ddr->accum_tot) {
- depth /= (float)ddr->accum_tot;
- }
- depthdropper_depth_set(C, ddr, depth);
+ float depth = ddr->accum_depth;
+ if (ddr->accum_tot) {
+ depth /= (float)ddr->accum_tot;
+ }
+ depthdropper_depth_set(C, ddr, depth);
}
/* single point sample & set */
static void depthdropper_depth_sample(bContext *C, DepthDropper *ddr, int mx, int my)
{
- float depth = -1.0f;
- if (depth != -1.0f) {
- depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
- depthdropper_depth_set(C, ddr, depth);
- }
+ float depth = -1.0f;
+ if (depth != -1.0f) {
+ depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
+ depthdropper_depth_set(C, ddr, depth);
+ }
}
static void depthdropper_depth_sample_accum(bContext *C, DepthDropper *ddr, int mx, int my)
{
- float depth = -1.0f;
- depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
- if (depth != -1.0f) {
- ddr->accum_depth += depth;
- ddr->accum_tot++;
- }
+ float depth = -1.0f;
+ depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
+ if (depth != -1.0f) {
+ ddr->accum_depth += depth;
+ ddr->accum_tot++;
+ }
}
static void depthdropper_cancel(bContext *C, wmOperator *op)
{
- DepthDropper *ddr = op->customdata;
- if (ddr->is_set) {
- depthdropper_depth_set(C, ddr, ddr->init_depth);
- }
- depthdropper_exit(C, op);
+ DepthDropper *ddr = op->customdata;
+ if (ddr->is_set) {
+ depthdropper_depth_set(C, ddr, ddr->init_depth);
+ }
+ depthdropper_exit(C, op);
}
/* main modal status check */
static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- DepthDropper *ddr = (DepthDropper *)op->customdata;
-
- /* handle modal keymap */
- if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case EYE_MODAL_CANCEL:
- depthdropper_cancel(C, op);
- return OPERATOR_CANCELLED;
- case EYE_MODAL_SAMPLE_CONFIRM:
- {
- const bool is_undo = ddr->is_undo;
- if (ddr->accum_tot == 0) {
- depthdropper_depth_sample(C, ddr, event->x, event->y);
- }
- else {
- depthdropper_depth_set_accum(C, ddr);
- }
- depthdropper_exit(C, op);
- /* Could support finished & undo-skip. */
- return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
- }
- case EYE_MODAL_SAMPLE_BEGIN:
- /* enable accum and make first sample */
- ddr->accum_start = true;
- depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
- break;
- case EYE_MODAL_SAMPLE_RESET:
- ddr->accum_tot = 0;
- ddr->accum_depth = 0.0f;
- depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
- depthdropper_depth_set_accum(C, ddr);
- break;
- }
- }
- else if (event->type == MOUSEMOVE) {
- if (ddr->accum_start) {
- /* button is pressed so keep sampling */
- depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
- depthdropper_depth_set_accum(C, ddr);
- }
- }
-
- return OPERATOR_RUNNING_MODAL;
+ DepthDropper *ddr = (DepthDropper *)op->customdata;
+
+ /* handle modal keymap */
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EYE_MODAL_CANCEL:
+ depthdropper_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ case EYE_MODAL_SAMPLE_CONFIRM: {
+ const bool is_undo = ddr->is_undo;
+ if (ddr->accum_tot == 0) {
+ depthdropper_depth_sample(C, ddr, event->x, event->y);
+ }
+ else {
+ depthdropper_depth_set_accum(C, ddr);
+ }
+ depthdropper_exit(C, op);
+ /* Could support finished & undo-skip. */
+ return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ }
+ case EYE_MODAL_SAMPLE_BEGIN:
+ /* enable accum and make first sample */
+ ddr->accum_start = true;
+ depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+ break;
+ case EYE_MODAL_SAMPLE_RESET:
+ ddr->accum_tot = 0;
+ ddr->accum_depth = 0.0f;
+ depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+ depthdropper_depth_set_accum(C, ddr);
+ break;
+ }
+ }
+ else if (event->type == MOUSEMOVE) {
+ if (ddr->accum_start) {
+ /* button is pressed so keep sampling */
+ depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+ depthdropper_depth_set_accum(C, ddr);
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
/* Modal Operator init */
static int depthdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- /* init */
- if (depthdropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* init */
+ if (depthdropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
/* Repeat operator */
static int depthdropper_exec(bContext *C, wmOperator *op)
{
- /* init */
- if (depthdropper_init(C, op)) {
- /* cleanup */
- depthdropper_exit(C, op);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* init */
+ if (depthdropper_init(C, op)) {
+ /* cleanup */
+ depthdropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static bool depthdropper_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index_dummy;
- uiBut *but;
-
- /* check if there's an active button taking depth value */
- if ((CTX_wm_window(C) != NULL) &&
- (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
- (but->type == UI_BTYPE_NUM) &&
- (prop != NULL))
- {
- if ((RNA_property_type(prop) == PROP_FLOAT) &&
- (RNA_property_subtype(prop) & PROP_UNIT_LENGTH) &&
- (RNA_property_array_check(prop) == false))
- {
- return 1;
- }
- }
- else {
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
- if (rv3d && rv3d->persp == RV3D_CAMOB) {
- View3D *v3d = CTX_wm_view3d(C);
- if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) {
- return 1;
- }
- }
- }
-
- return 0;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index_dummy;
+ uiBut *but;
+
+ /* check if there's an active button taking depth value */
+ if ((CTX_wm_window(C) != NULL) &&
+ (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
+ (but->type == UI_BTYPE_NUM) && (prop != NULL)) {
+ if ((RNA_property_type(prop) == PROP_FLOAT) &&
+ (RNA_property_subtype(prop) & PROP_UNIT_LENGTH) &&
+ (RNA_property_array_check(prop) == false)) {
+ return 1;
+ }
+ }
+ else {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ if (rv3d && rv3d->persp == RV3D_CAMOB) {
+ View3D *v3d = CTX_wm_view3d(C);
+ if (v3d->camera && v3d->camera->data && !ID_IS_LINKED(v3d->camera->data)) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
}
void UI_OT_eyedropper_depth(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Eyedropper Depth";
- ot->idname = "UI_OT_eyedropper_depth";
- ot->description = "Sample depth from the 3D view";
-
- /* api callbacks */
- ot->invoke = depthdropper_invoke;
- ot->modal = depthdropper_modal;
- ot->cancel = depthdropper_cancel;
- ot->exec = depthdropper_exec;
- ot->poll = depthdropper_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
- /* properties */
+ /* identifiers */
+ ot->name = "Eyedropper Depth";
+ ot->idname = "UI_OT_eyedropper_depth";
+ ot->description = "Sample depth from the 3D view";
+
+ /* api callbacks */
+ ot->invoke = depthdropper_invoke;
+ ot->modal = depthdropper_modal;
+ ot->cancel = depthdropper_cancel;
+ ot->exec = depthdropper_exec;
+ ot->poll = depthdropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
}
diff --git a/source/blender/editors/interface/interface_eyedropper_driver.c b/source/blender/editors/interface/interface_eyedropper_driver.c
index dd2656e7fa1..c1aee190cd3 100644
--- a/source/blender/editors/interface/interface_eyedropper_driver.c
+++ b/source/blender/editors/interface/interface_eyedropper_driver.c
@@ -32,7 +32,6 @@
#include "DNA_screen_types.h"
#include "DNA_object_types.h"
-
#include "BKE_context.h"
#include "BKE_animsys.h"
@@ -53,188 +52,193 @@
#include "interface_eyedropper_intern.h"
typedef struct DriverDropper {
- /* Destination property (i.e. where we'll add a driver) */
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
- bool is_undo;
+ /* Destination property (i.e. where we'll add a driver) */
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+ bool is_undo;
- // TODO: new target?
+ // TODO: new target?
} DriverDropper;
static bool driverdropper_init(bContext *C, wmOperator *op)
{
- DriverDropper *ddr = MEM_callocN(sizeof(DriverDropper), __func__);
+ DriverDropper *ddr = MEM_callocN(sizeof(DriverDropper), __func__);
- uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &ddr->index);
+ uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &ddr->index);
- if ((ddr->ptr.data == NULL) ||
- (ddr->prop == NULL) ||
- (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
- (RNA_property_animateable(&ddr->ptr, ddr->prop) == false) ||
- (but->flag & UI_BUT_DRIVEN))
- {
- MEM_freeN(ddr);
- return false;
- }
- op->customdata = ddr;
+ if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) ||
+ (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
+ (RNA_property_animateable(&ddr->ptr, ddr->prop) == false) || (but->flag & UI_BUT_DRIVEN)) {
+ MEM_freeN(ddr);
+ return false;
+ }
+ op->customdata = ddr;
- ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
+ ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);
- return true;
+ return true;
}
static void driverdropper_exit(bContext *C, wmOperator *op)
{
- WM_cursor_modal_restore(CTX_wm_window(C));
+ WM_cursor_modal_restore(CTX_wm_window(C));
- if (op->customdata) {
- MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
}
static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *event)
{
- DriverDropper *ddr = (DriverDropper *)op->customdata;
- uiBut *but = eyedropper_get_property_button_under_mouse(C, event);
-
- short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
- short flag = 0;
-
- /* we can only add a driver if we know what RNA property it corresponds to */
- if (but == NULL) {
- return;
- }
- else {
- /* Get paths for src... */
- PointerRNA *target_ptr = &but->rnapoin;
- PropertyRNA *target_prop = but->rnaprop;
- int target_index = but->rnaindex;
-
- char *target_path = RNA_path_from_ID_to_property(target_ptr, target_prop);
-
- /* ... and destination */
- char *dst_path = BKE_animdata_driver_path_hack(C, &ddr->ptr, ddr->prop, NULL);
-
- /* Now create driver(s) */
- if (target_path && dst_path) {
- int success = ANIM_add_driver_with_target(op->reports,
- ddr->ptr.id.data, dst_path, ddr->index,
- target_ptr->id.data, target_path, target_index,
- flag, DRIVER_TYPE_PYTHON, mapping_type);
-
- if (success) {
- /* send updates */
- UI_context_update_anim_flag(C);
- DEG_relations_tag_update(CTX_data_main(C));
- DEG_id_tag_update(ddr->ptr.id.data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
- }
- }
-
- /* cleanup */
- if (target_path) {
- MEM_freeN(target_path);
- }
- if (dst_path) {
- MEM_freeN(dst_path);
- }
- }
+ DriverDropper *ddr = (DriverDropper *)op->customdata;
+ uiBut *but = eyedropper_get_property_button_under_mouse(C, event);
+
+ short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
+ short flag = 0;
+
+ /* we can only add a driver if we know what RNA property it corresponds to */
+ if (but == NULL) {
+ return;
+ }
+ else {
+ /* Get paths for src... */
+ PointerRNA *target_ptr = &but->rnapoin;
+ PropertyRNA *target_prop = but->rnaprop;
+ int target_index = but->rnaindex;
+
+ char *target_path = RNA_path_from_ID_to_property(target_ptr, target_prop);
+
+ /* ... and destination */
+ char *dst_path = BKE_animdata_driver_path_hack(C, &ddr->ptr, ddr->prop, NULL);
+
+ /* Now create driver(s) */
+ if (target_path && dst_path) {
+ int success = ANIM_add_driver_with_target(op->reports,
+ ddr->ptr.id.data,
+ dst_path,
+ ddr->index,
+ target_ptr->id.data,
+ target_path,
+ target_index,
+ flag,
+ DRIVER_TYPE_PYTHON,
+ mapping_type);
+
+ if (success) {
+ /* send updates */
+ UI_context_update_anim_flag(C);
+ DEG_relations_tag_update(CTX_data_main(C));
+ DEG_id_tag_update(ddr->ptr.id.data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
+ }
+ }
+
+ /* cleanup */
+ if (target_path) {
+ MEM_freeN(target_path);
+ }
+ if (dst_path) {
+ MEM_freeN(dst_path);
+ }
+ }
}
static void driverdropper_cancel(bContext *C, wmOperator *op)
{
- driverdropper_exit(C, op);
+ driverdropper_exit(C, op);
}
/* main modal status check */
static int driverdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- DriverDropper *ddr = op->customdata;
-
- /* handle modal keymap */
- if (event->type == EVT_MODAL_MAP) {
- switch (event->val) {
- case EYE_MODAL_CANCEL:
- {
- driverdropper_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- case EYE_MODAL_SAMPLE_CONFIRM:
- {
- const bool is_undo = ddr->is_undo;
- driverdropper_sample(C, op, event);
- driverdropper_exit(C, op);
- /* Could support finished & undo-skip. */
- return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
- }
- }
- }
-
- return OPERATOR_RUNNING_MODAL;
+ DriverDropper *ddr = op->customdata;
+
+ /* handle modal keymap */
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EYE_MODAL_CANCEL: {
+ driverdropper_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ case EYE_MODAL_SAMPLE_CONFIRM: {
+ const bool is_undo = ddr->is_undo;
+ driverdropper_sample(C, op, event);
+ driverdropper_exit(C, op);
+ /* Could support finished & undo-skip. */
+ return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ }
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
/* Modal Operator init */
static int driverdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- /* init */
- if (driverdropper_init(C, op)) {
- WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* init */
+ if (driverdropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
/* Repeat operator */
static int driverdropper_exec(bContext *C, wmOperator *op)
{
- /* init */
- if (driverdropper_init(C, op)) {
- /* cleanup */
- driverdropper_exit(C, op);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ /* init */
+ if (driverdropper_init(C, op)) {
+ /* cleanup */
+ driverdropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static bool driverdropper_poll(bContext *C)
{
- if (!CTX_wm_window(C)) {
- return 0;
- }
- else {
- return 1;
- }
+ if (!CTX_wm_window(C)) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
}
void UI_OT_eyedropper_driver(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Eyedropper Driver";
- ot->idname = "UI_OT_eyedropper_driver";
- ot->description = "Pick a property to use as a driver target";
-
- /* api callbacks */
- ot->invoke = driverdropper_invoke;
- ot->modal = driverdropper_modal;
- ot->cancel = driverdropper_cancel;
- ot->exec = driverdropper_exec;
- ot->poll = driverdropper_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
-
- /* properties */
- RNA_def_enum(ot->srna, "mapping_type", prop_driver_create_mapping_types, 0,
- "Mapping Type", "Method used to match target and driven properties");
+ /* identifiers */
+ ot->name = "Eyedropper Driver";
+ ot->idname = "UI_OT_eyedropper_driver";
+ ot->description = "Pick a property to use as a driver target";
+
+ /* api callbacks */
+ ot->invoke = driverdropper_invoke;
+ ot->modal = driverdropper_modal;
+ ot->cancel = driverdropper_cancel;
+ ot->exec = driverdropper_exec;
+ ot->poll = driverdropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
+ RNA_def_enum(ot->srna,
+ "mapping_type",
+ prop_driver_create_mapping_types,
+ 0,
+ "Mapping Type",
+ "Method used to match target and driven properties");
}
diff --git a/source/blender/editors/interface/interface_eyedropper_intern.h b/source/blender/editors/interface/interface_eyedropper_intern.h
index 1ce0cb6d3e1..d9ec0657bfe 100644
--- a/source/blender/editors/interface/interface_eyedropper_intern.h
+++ b/source/blender/editors/interface/interface_eyedropper_intern.h
@@ -24,7 +24,9 @@
#define __INTERFACE_EYEDROPPER_INTERN_H__
/* interface_eyedropper.c */
-void eyedropper_draw_cursor_text(const struct bContext *C, const struct ARegion *ar, const char *name);
+void eyedropper_draw_cursor_text(const struct bContext *C,
+ const struct ARegion *ar,
+ const char *name);
uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event);
/* interface_eyedropper_color.c (expose for color-band picker) */
@@ -32,19 +34,19 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]);
/* Used for most eye-dropper operators. */
enum {
- EYE_MODAL_CANCEL = 1,
- EYE_MODAL_SAMPLE_CONFIRM,
- EYE_MODAL_SAMPLE_BEGIN,
- EYE_MODAL_SAMPLE_RESET,
+ EYE_MODAL_CANCEL = 1,
+ EYE_MODAL_SAMPLE_CONFIRM,
+ EYE_MODAL_SAMPLE_BEGIN,
+ EYE_MODAL_SAMPLE_RESET,
};
/* Color-band point sample. */
enum {
- EYE_MODAL_POINT_CANCEL = 1,
- EYE_MODAL_POINT_SAMPLE,
- EYE_MODAL_POINT_CONFIRM,
- EYE_MODAL_POINT_RESET,
- EYE_MODAL_POINT_REMOVE_LAST,
+ EYE_MODAL_POINT_CANCEL = 1,
+ EYE_MODAL_POINT_SAMPLE,
+ EYE_MODAL_POINT_CONFIRM,
+ EYE_MODAL_POINT_RESET,
+ EYE_MODAL_POINT_REMOVE_LAST,
};
-#endif /* __INTERFACE_EYEDROPPER_INTERN_H__ */
+#endif /* __INTERFACE_EYEDROPPER_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 86a225bf3bd..0fe12b21636 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -102,7 +102,10 @@
#define UI_MAX_PASSWORD_STR 128
/* proto */
-static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, const wmEvent *event);
+static int ui_do_but_EXIT(bContext *C,
+ uiBut *but,
+ struct uiHandleButtonData *data,
+ const wmEvent *event);
static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b);
static void ui_textedit_string_set(uiBut *but, struct uiHandleButtonData *data, const char *str);
@@ -115,289 +118,289 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve
/** \name Structs & Defines
* \{ */
-#define BUTTON_FLASH_DELAY 0.020
-#define MENU_SCROLL_INTERVAL 0.1
-#define PIE_MENU_INTERVAL 0.01
-#define BUTTON_AUTO_OPEN_THRESH 0.2
+#define BUTTON_FLASH_DELAY 0.020
+#define MENU_SCROLL_INTERVAL 0.1
+#define PIE_MENU_INTERVAL 0.01
+#define BUTTON_AUTO_OPEN_THRESH 0.2
#define BUTTON_MOUSE_TOWARDS_THRESH 1.0
/* pixels to move the cursor to get out of keyboard navigation */
-#define BUTTON_KEYNAV_PX_LIMIT 8
+#define BUTTON_KEYNAV_PX_LIMIT 8
-#define MENU_TOWARDS_MARGIN 20 /* margin in pixels */
-#define MENU_TOWARDS_WIGGLE_ROOM 64 /* tolerance in pixels */
+#define MENU_TOWARDS_MARGIN 20 /* margin in pixels */
+#define MENU_TOWARDS_WIGGLE_ROOM 64 /* tolerance in pixels */
/* drag-lock distance threshold in pixels */
-#define BUTTON_DRAGLOCK_THRESH 3
+#define BUTTON_DRAGLOCK_THRESH 3
typedef enum uiButtonActivateType {
- BUTTON_ACTIVATE_OVER,
- BUTTON_ACTIVATE,
- BUTTON_ACTIVATE_APPLY,
- BUTTON_ACTIVATE_TEXT_EDITING,
- BUTTON_ACTIVATE_OPEN,
+ BUTTON_ACTIVATE_OVER,
+ BUTTON_ACTIVATE,
+ BUTTON_ACTIVATE_APPLY,
+ BUTTON_ACTIVATE_TEXT_EDITING,
+ BUTTON_ACTIVATE_OPEN,
} uiButtonActivateType;
typedef enum uiHandleButtonState {
- BUTTON_STATE_INIT,
- BUTTON_STATE_HIGHLIGHT,
- BUTTON_STATE_WAIT_FLASH,
- BUTTON_STATE_WAIT_RELEASE,
- BUTTON_STATE_WAIT_KEY_EVENT,
- BUTTON_STATE_NUM_EDITING,
- BUTTON_STATE_TEXT_EDITING,
- BUTTON_STATE_TEXT_SELECTING,
- BUTTON_STATE_MENU_OPEN,
- BUTTON_STATE_WAIT_DRAG,
- BUTTON_STATE_EXIT,
+ BUTTON_STATE_INIT,
+ BUTTON_STATE_HIGHLIGHT,
+ BUTTON_STATE_WAIT_FLASH,
+ BUTTON_STATE_WAIT_RELEASE,
+ BUTTON_STATE_WAIT_KEY_EVENT,
+ BUTTON_STATE_NUM_EDITING,
+ BUTTON_STATE_TEXT_EDITING,
+ BUTTON_STATE_TEXT_SELECTING,
+ BUTTON_STATE_MENU_OPEN,
+ BUTTON_STATE_WAIT_DRAG,
+ BUTTON_STATE_EXIT,
} uiHandleButtonState;
-
#ifdef USE_ALLSELECT
/* Unfortunately there's no good way handle more generally:
* (propagate single clicks on layer buttons to other objects) */
-#define USE_ALLSELECT_LAYER_HACK
+# define USE_ALLSELECT_LAYER_HACK
typedef struct uiSelectContextElem {
- PointerRNA ptr;
- union {
- bool val_b;
- int val_i;
- float val_f;
- };
+ PointerRNA ptr;
+ union {
+ bool val_b;
+ int val_i;
+ float val_f;
+ };
} uiSelectContextElem;
typedef struct uiSelectContextStore {
- uiSelectContextElem *elems;
- int elems_len;
- bool do_free;
- bool is_enabled;
- /* When set, simply copy values (don't apply difference).
- * Rules are:
- * - dragging numbers uses delta.
- * - typing in values will assign to all. */
- bool is_copy;
+ uiSelectContextElem *elems;
+ int elems_len;
+ bool do_free;
+ bool is_enabled;
+ /* When set, simply copy values (don't apply difference).
+ * Rules are:
+ * - dragging numbers uses delta.
+ * - typing in values will assign to all. */
+ bool is_copy;
} uiSelectContextStore;
-static bool ui_selectcontext_begin(
- bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data);
-static void ui_selectcontext_end(
- uiBut *but, uiSelectContextStore *selctx_data);
-static void ui_selectcontext_apply(
- bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data,
- const double value, const double value_orig);
+static bool ui_selectcontext_begin(bContext *C,
+ uiBut *but,
+ struct uiSelectContextStore *selctx_data);
+static void ui_selectcontext_end(uiBut *but, uiSelectContextStore *selctx_data);
+static void ui_selectcontext_apply(bContext *C,
+ uiBut *but,
+ struct uiSelectContextStore *selctx_data,
+ const double value,
+ const double value_orig);
-#define IS_ALLSELECT_EVENT(event) ((event)->alt != 0)
+# define IS_ALLSELECT_EVENT(event) ((event)->alt != 0)
/** just show a tinted color so users know its activated */
-#define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE
-
-#endif /* USE_ALLSELECT */
+# define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE
+#endif /* USE_ALLSELECT */
#ifdef USE_DRAG_MULTINUM
/**
* how far to drag before we check for gesture direction (in pixels),
* note: half the height of a button is about right... */
-#define DRAG_MULTINUM_THRESHOLD_DRAG_X (UI_UNIT_Y / 4)
+# define DRAG_MULTINUM_THRESHOLD_DRAG_X (UI_UNIT_Y / 4)
/**
* how far to drag horizontally before we stop checking which buttons the gesture spans (in pixels),
* locking down the buttons so we can drag freely without worrying about vertical movement. */
-#define DRAG_MULTINUM_THRESHOLD_DRAG_Y (UI_UNIT_Y / 4)
+# define DRAG_MULTINUM_THRESHOLD_DRAG_Y (UI_UNIT_Y / 4)
/**
* how strict to be when detecting a vertical gesture, [0.5 == sloppy], [0.9 == strict], (unsigned dot-product)
* note: we should be quite strict here, since doing a vertical gesture by accident should be avoided,
* however with some care a user should be able to do a vertical movement without *missing*. */
-#define DRAG_MULTINUM_THRESHOLD_VERTICAL (0.75f)
-
+# define DRAG_MULTINUM_THRESHOLD_VERTICAL (0.75f)
/* a simple version of uiHandleButtonData when accessing multiple buttons */
typedef struct uiButMultiState {
- double origvalue;
- uiBut *but;
+ double origvalue;
+ uiBut *but;
-#ifdef USE_ALLSELECT
- uiSelectContextStore select_others;
-#endif
+# ifdef USE_ALLSELECT
+ uiSelectContextStore select_others;
+# endif
} uiButMultiState;
typedef struct uiHandleButtonMulti {
- enum {
- /** gesture direction unknown, wait until mouse has moved enough... */
- BUTTON_MULTI_INIT_UNSET = 0,
- /** vertical gesture detected, flag buttons interactively (UI_BUT_DRAG_MULTI) */
- BUTTON_MULTI_INIT_SETUP,
- /** flag buttons finished, apply horizontal motion to active and flagged */
- BUTTON_MULTI_INIT_ENABLE,
- /** vertical gesture _not_ detected, take no further action */
- BUTTON_MULTI_INIT_DISABLE,
- } init;
-
- bool has_mbuts; /* any buttons flagged UI_BUT_DRAG_MULTI */
- LinkNode *mbuts;
- uiButStore *bs_mbuts;
-
- bool is_proportional;
-
- /* In some cases we directly apply the changes to multiple buttons,
- * so we don't want to do it twice. */
- bool skip;
-
- /* before activating, we need to check gesture direction accumulate signed cursor movement
- * here so we can tell if this is a vertical motion or not. */
- float drag_dir[2];
-
- /* values copied direct from event->x,y
- * used to detect buttons between the current and initial mouse position */
- int drag_start[2];
-
- /* store x location once BUTTON_MULTI_INIT_SETUP is set,
- * moving outside this sets BUTTON_MULTI_INIT_ENABLE */
- int drag_lock_x;
+ enum {
+ /** gesture direction unknown, wait until mouse has moved enough... */
+ BUTTON_MULTI_INIT_UNSET = 0,
+ /** vertical gesture detected, flag buttons interactively (UI_BUT_DRAG_MULTI) */
+ BUTTON_MULTI_INIT_SETUP,
+ /** flag buttons finished, apply horizontal motion to active and flagged */
+ BUTTON_MULTI_INIT_ENABLE,
+ /** vertical gesture _not_ detected, take no further action */
+ BUTTON_MULTI_INIT_DISABLE,
+ } init;
+
+ bool has_mbuts; /* any buttons flagged UI_BUT_DRAG_MULTI */
+ LinkNode *mbuts;
+ uiButStore *bs_mbuts;
+
+ bool is_proportional;
+
+ /* In some cases we directly apply the changes to multiple buttons,
+ * so we don't want to do it twice. */
+ bool skip;
+
+ /* before activating, we need to check gesture direction accumulate signed cursor movement
+ * here so we can tell if this is a vertical motion or not. */
+ float drag_dir[2];
+
+ /* values copied direct from event->x,y
+ * used to detect buttons between the current and initial mouse position */
+ int drag_start[2];
+
+ /* store x location once BUTTON_MULTI_INIT_SETUP is set,
+ * moving outside this sets BUTTON_MULTI_INIT_ENABLE */
+ int drag_lock_x;
} uiHandleButtonMulti;
-#endif /* USE_DRAG_MULTINUM */
+#endif /* USE_DRAG_MULTINUM */
typedef struct uiHandleButtonData {
- wmWindowManager *wm;
- wmWindow *window;
- ARegion *region;
-
- bool interactive;
-
- /* overall state */
- uiHandleButtonState state;
- int retval;
- /* booleans (could be made into flags) */
- bool cancel, escapecancel;
- bool applied, applied_interactive;
- bool changed_cursor;
- wmTimer *flashtimer;
-
- /* edited value */
- /* use 'ui_textedit_string_set' to assign new strings */
- char *str;
- char *origstr;
- double value, origvalue, startvalue;
- float vec[3], origvec[3];
-#if 0 /* UNUSED */
- int togdual, togonly;
+ wmWindowManager *wm;
+ wmWindow *window;
+ ARegion *region;
+
+ bool interactive;
+
+ /* overall state */
+ uiHandleButtonState state;
+ int retval;
+ /* booleans (could be made into flags) */
+ bool cancel, escapecancel;
+ bool applied, applied_interactive;
+ bool changed_cursor;
+ wmTimer *flashtimer;
+
+ /* edited value */
+ /* use 'ui_textedit_string_set' to assign new strings */
+ char *str;
+ char *origstr;
+ double value, origvalue, startvalue;
+ float vec[3], origvec[3];
+#if 0 /* UNUSED */
+ int togdual, togonly;
#endif
- ColorBand *coba;
-
- /* tooltip */
- uint tooltip_force : 1;
-
- /* auto open */
- bool used_mouse;
- wmTimer *autoopentimer;
-
- /* auto open (hold) */
- wmTimer *hold_action_timer;
-
- /* text selection/editing */
- /* size of 'str' (including terminator) */
- int maxlen;
- /* Button text selection:
- * extension direction, selextend, inside ui_do_but_TEX */
- enum {
- EXTEND_NONE = 0,
- EXTEND_LEFT = 1,
- EXTEND_RIGHT = 2,
- } selextend;
- float selstartx;
- /* allow to realloc str/editstr and use 'maxlen' to track alloc size (maxlen + 1) */
- bool is_str_dynamic;
-
- /* number editing / dragging */
- /* coords are Window/uiBlock relative (depends on the button) */
- int draglastx, draglasty;
- int dragstartx, dragstarty;
- int draglastvalue;
- int dragstartvalue;
- bool dragchange, draglock;
- int dragsel;
- float dragf, dragfstart;
- CBData *dragcbd;
+ ColorBand *coba;
+
+ /* tooltip */
+ uint tooltip_force : 1;
+
+ /* auto open */
+ bool used_mouse;
+ wmTimer *autoopentimer;
+
+ /* auto open (hold) */
+ wmTimer *hold_action_timer;
+
+ /* text selection/editing */
+ /* size of 'str' (including terminator) */
+ int maxlen;
+ /* Button text selection:
+ * extension direction, selextend, inside ui_do_but_TEX */
+ enum {
+ EXTEND_NONE = 0,
+ EXTEND_LEFT = 1,
+ EXTEND_RIGHT = 2,
+ } selextend;
+ float selstartx;
+ /* allow to realloc str/editstr and use 'maxlen' to track alloc size (maxlen + 1) */
+ bool is_str_dynamic;
+
+ /* number editing / dragging */
+ /* coords are Window/uiBlock relative (depends on the button) */
+ int draglastx, draglasty;
+ int dragstartx, dragstarty;
+ int draglastvalue;
+ int dragstartvalue;
+ bool dragchange, draglock;
+ int dragsel;
+ float dragf, dragfstart;
+ CBData *dragcbd;
#ifdef USE_CONT_MOUSE_CORRECT
- /* when ungrabbing buttons which are #ui_but_is_cursor_warp(),
- * we may want to position them.
- * FLT_MAX signifies do-nothing, use #ui_block_to_window_fl()
- * to get this into a usable space. */
- float ungrab_mval[2];
+ /* when ungrabbing buttons which are #ui_but_is_cursor_warp(),
+ * we may want to position them.
+ * FLT_MAX signifies do-nothing, use #ui_block_to_window_fl()
+ * to get this into a usable space. */
+ float ungrab_mval[2];
#endif
- /* menu open (watch UI_screen_free_active_but) */
- uiPopupBlockHandle *menu;
- int menuretval;
+ /* menu open (watch UI_screen_free_active_but) */
+ uiPopupBlockHandle *menu;
+ int menuretval;
- /* search box (watch UI_screen_free_active_but) */
- ARegion *searchbox;
+ /* search box (watch UI_screen_free_active_but) */
+ ARegion *searchbox;
#ifdef USE_KEYNAV_LIMIT
- struct uiKeyNavLock searchbox_keynav_state;
+ struct uiKeyNavLock searchbox_keynav_state;
#endif
#ifdef USE_DRAG_MULTINUM
- /* Multi-buttons will be updated in unison with the active button. */
- uiHandleButtonMulti multi_data;
+ /* Multi-buttons will be updated in unison with the active button. */
+ uiHandleButtonMulti multi_data;
#endif
#ifdef USE_ALLSELECT
- uiSelectContextStore select_others;
+ uiSelectContextStore select_others;
#endif
- /* post activate */
- uiButtonActivateType posttype;
- uiBut *postbut;
+ /* post activate */
+ uiButtonActivateType posttype;
+ uiBut *postbut;
} uiHandleButtonData;
typedef struct uiAfterFunc {
- struct uiAfterFunc *next, *prev;
+ struct uiAfterFunc *next, *prev;
- uiButHandleFunc func;
- void *func_arg1;
- void *func_arg2;
+ uiButHandleFunc func;
+ void *func_arg1;
+ void *func_arg2;
- uiButHandleNFunc funcN;
- void *func_argN;
+ uiButHandleNFunc funcN;
+ void *func_argN;
- uiButHandleRenameFunc rename_func;
- void *rename_arg1;
- void *rename_orig;
+ uiButHandleRenameFunc rename_func;
+ void *rename_arg1;
+ void *rename_orig;
- uiBlockHandleFunc handle_func;
- void *handle_func_arg;
- int retval;
+ uiBlockHandleFunc handle_func;
+ void *handle_func_arg;
+ int retval;
- uiMenuHandleFunc butm_func;
- void *butm_func_arg;
- int a2;
+ uiMenuHandleFunc butm_func;
+ void *butm_func_arg;
+ int a2;
- wmOperator *popup_op;
- wmOperatorType *optype;
- int opcontext;
- PointerRNA *opptr;
+ wmOperator *popup_op;
+ wmOperatorType *optype;
+ int opcontext;
+ PointerRNA *opptr;
- PointerRNA rnapoin;
- PropertyRNA *rnaprop;
+ PointerRNA rnapoin;
+ PropertyRNA *rnaprop;
- bContextStore *context;
+ bContextStore *context;
- char undostr[BKE_UNDO_STR_MAX];
+ char undostr[BKE_UNDO_STR_MAX];
} uiAfterFunc;
-
static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
static void button_activate_exit(
- bContext *C, uiBut *but, uiHandleButtonData *data,
- const bool mousemove, const bool onfree);
+ bContext *C, uiBut *but, uiHandleButtonData *data, const bool mousemove, const bool onfree);
static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userdata);
-static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
+static void ui_handle_button_activate(bContext *C,
+ ARegion *ar,
+ uiBut *but,
+ uiButtonActivateType type);
#ifdef USE_DRAG_MULTINUM
static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block);
@@ -411,60 +414,57 @@ static bool but_copypaste_curve_alive = false;
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name UI Queries
* \{ */
bool ui_but_is_editing(const uiBut *but)
{
- uiHandleButtonData *data = but->active;
- return (data && ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING));
+ uiHandleButtonData *data = but->active;
+ return (data && ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING));
}
/* assumes event type is MOUSEPAN */
void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
{
- static int lastdy = 0;
- int dy = event->prevy - event->y;
+ static int lastdy = 0;
+ int dy = event->prevy - event->y;
- /* This event should be originally from event->type,
- * converting wrong event into wheel is bad, see [#33803] */
- BLI_assert(*type == MOUSEPAN);
+ /* This event should be originally from event->type,
+ * converting wrong event into wheel is bad, see [#33803] */
+ BLI_assert(*type == MOUSEPAN);
- /* sign differs, reset */
- if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0)) {
- lastdy = dy;
- }
- else {
- lastdy += dy;
+ /* sign differs, reset */
+ if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0)) {
+ lastdy = dy;
+ }
+ else {
+ lastdy += dy;
- if (ABS(lastdy) > (int)UI_UNIT_Y) {
- if (U.uiflag2 & USER_TRACKPAD_NATURAL) {
- dy = -dy;
- }
+ if (ABS(lastdy) > (int)UI_UNIT_Y) {
+ if (U.uiflag2 & USER_TRACKPAD_NATURAL) {
+ dy = -dy;
+ }
- *val = KM_PRESS;
+ *val = KM_PRESS;
- if (dy > 0) {
- *type = WHEELUPMOUSE;
- }
- else {
- *type = WHEELDOWNMOUSE;
- }
+ if (dy > 0) {
+ *type = WHEELUPMOUSE;
+ }
+ else {
+ *type = WHEELDOWNMOUSE;
+ }
- lastdy = 0;
- }
- }
+ lastdy = 0;
+ }
+ }
}
static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b)
{
- return ((but_a->type == but_b->type) &&
- (but_a->alignnr == but_b->alignnr) &&
- (but_a->poin == but_b->poin) &&
- (but_a->rnapoin.type == but_b->rnapoin.type) &&
- (but_a->rnaprop == but_b->rnaprop));
+ return ((but_a->type == but_b->type) && (but_a->alignnr == but_b->alignnr) &&
+ (but_a->poin == but_b->poin) && (but_a->rnapoin.type == but_b->rnapoin.type) &&
+ (but_a->rnaprop == but_b->rnaprop));
}
/**
@@ -474,43 +474,44 @@ static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but
*/
uiBut *ui_but_find_select_in_enum(uiBut *but, int direction)
{
- uiBut *but_iter = but;
- uiBut *but_found = NULL;
- BLI_assert(ELEM(direction, -1, 1));
+ uiBut *but_iter = but;
+ uiBut *but_found = NULL;
+ BLI_assert(ELEM(direction, -1, 1));
- while ((but_iter->prev) &&
- ui_but_find_select_in_enum__cmp(but_iter->prev, but))
- {
- but_iter = but_iter->prev;
- }
+ while ((but_iter->prev) && ui_but_find_select_in_enum__cmp(but_iter->prev, but)) {
+ but_iter = but_iter->prev;
+ }
- while (but_iter && ui_but_find_select_in_enum__cmp(but_iter, but)) {
- if (but_iter->flag & UI_SELECT) {
- but_found = but_iter;
- if (direction == 1) {
- break;
- }
- }
- but_iter = but_iter->next;
- }
+ while (but_iter && ui_but_find_select_in_enum__cmp(but_iter, but)) {
+ if (but_iter->flag & UI_SELECT) {
+ but_found = but_iter;
+ if (direction == 1) {
+ break;
+ }
+ }
+ but_iter = but_iter->next;
+ }
- return but_found;
+ return but_found;
}
static float ui_mouse_scale_warp_factor(const bool shift)
{
- return shift ? 0.05f : 1.0f;
+ return shift ? 0.05f : 1.0f;
}
-static void ui_mouse_scale_warp(
- uiHandleButtonData *data, const float mx, const float my,
- float *r_mx, float *r_my, const bool shift)
+static void ui_mouse_scale_warp(uiHandleButtonData *data,
+ const float mx,
+ const float my,
+ float *r_mx,
+ float *r_my,
+ const bool shift)
{
- const float fac = ui_mouse_scale_warp_factor(shift);
+ const float fac = ui_mouse_scale_warp_factor(shift);
- /* slow down the mouse, this is fairly picky */
- *r_mx = (data->dragstartx * (1.0f - fac) + mx * fac);
- *r_my = (data->dragstarty * (1.0f - fac) + my * fac);
+ /* slow down the mouse, this is fairly picky */
+ *r_mx = (data->dragstartx * (1.0f - fac) + mx * fac);
+ *r_my = (data->dragstarty * (1.0f - fac) + my * fac);
}
/** \} */
@@ -524,24 +525,24 @@ static void ui_mouse_scale_warp(
*/
static bool ui_but_dragedit_update_mval(uiHandleButtonData *data, int mx)
{
- if (mx == data->draglastx) {
- return false;
- }
+ if (mx == data->draglastx) {
+ return false;
+ }
- if (data->draglock) {
- if (ABS(mx - data->dragstartx) <= BUTTON_DRAGLOCK_THRESH) {
- return false;
- }
+ if (data->draglock) {
+ if (ABS(mx - data->dragstartx) <= BUTTON_DRAGLOCK_THRESH) {
+ return false;
+ }
#ifdef USE_DRAG_MULTINUM
- if (ELEM(data->multi_data.init, BUTTON_MULTI_INIT_UNSET, BUTTON_MULTI_INIT_SETUP)) {
- return false;
- }
+ if (ELEM(data->multi_data.init, BUTTON_MULTI_INIT_UNSET, BUTTON_MULTI_INIT_SETUP)) {
+ return false;
+ }
#endif
- data->draglock = false;
- data->dragstartx = mx; /* ignore mouse movement within drag-lock */
- }
+ data->draglock = false;
+ data->dragstartx = mx; /* ignore mouse movement within drag-lock */
+ }
- return true;
+ return true;
}
/** \} */
@@ -552,27 +553,27 @@ static bool ui_but_dragedit_update_mval(uiHandleButtonData *data, int mx)
* \{ */
enum eSnapType {
- SNAP_OFF = 0,
- SNAP_ON,
- SNAP_ON_SMALL,
+ SNAP_OFF = 0,
+ SNAP_ON,
+ SNAP_ON_SMALL,
};
static enum eSnapType ui_event_to_snap(const wmEvent *event)
{
- return (event->ctrl) ? (event->shift) ? SNAP_ON_SMALL : SNAP_ON : SNAP_OFF;
+ return (event->ctrl) ? (event->shift) ? SNAP_ON_SMALL : SNAP_ON : SNAP_OFF;
}
static bool ui_event_is_snap(const wmEvent *event)
{
- return (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY) ||
- ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY));
+ return (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY) ||
+ ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY));
}
static void ui_color_snap_hue(const enum eSnapType snap, float *r_hue)
{
- const float snap_increment = (snap == SNAP_ON_SMALL) ? 24 : 12;
- BLI_assert(snap != SNAP_OFF);
- *r_hue = roundf((*r_hue) * snap_increment) / snap_increment;
+ const float snap_increment = (snap == SNAP_ON_SMALL) ? 24 : 12;
+ BLI_assert(snap != SNAP_OFF);
+ *r_hue = roundf((*r_hue) * snap_increment) / snap_increment;
}
/** \} */
@@ -585,13 +586,13 @@ static ListBase UIAfterFuncs = {NULL, NULL};
static uiAfterFunc *ui_afterfunc_new(void)
{
- uiAfterFunc *after;
+ uiAfterFunc *after;
- after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
+ after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
- BLI_addtail(&UIAfterFuncs, after);
+ BLI_addtail(&UIAfterFuncs, after);
- return after;
+ return after;
}
/**
@@ -602,26 +603,26 @@ static uiAfterFunc *ui_afterfunc_new(void)
*/
PointerRNA *ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext, bool create_props)
{
- PointerRNA *ptr = NULL;
- uiAfterFunc *after = ui_afterfunc_new();
+ PointerRNA *ptr = NULL;
+ uiAfterFunc *after = ui_afterfunc_new();
- after->optype = ot;
- after->opcontext = opcontext;
+ after->optype = ot;
+ after->opcontext = opcontext;
- if (create_props) {
- ptr = MEM_callocN(sizeof(PointerRNA), __func__);
- WM_operator_properties_create_ptr(ptr, ot);
- after->opptr = ptr;
- }
+ if (create_props) {
+ ptr = MEM_callocN(sizeof(PointerRNA), __func__);
+ WM_operator_properties_create_ptr(ptr, ot);
+ after->opptr = ptr;
+ }
- return ptr;
+ return ptr;
}
static void popup_check(bContext *C, wmOperator *op)
{
- if (op && op->type->check) {
- op->type->check(C, op);
- }
+ if (op && op->type->check) {
+ op->type->check(C, op);
+ }
}
/**
@@ -629,362 +630,362 @@ static void popup_check(bContext *C, wmOperator *op)
*/
static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but)
{
- return (but->func || but->funcN || but->rename_func || but->optype || but->rnaprop || block->handle_func ||
- (but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
- (block->handle && block->handle->popup_op));
+ return (but->func || but->funcN || but->rename_func || but->optype || but->rnaprop ||
+ block->handle_func || (but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
+ (block->handle && block->handle->popup_op));
}
static void ui_apply_but_func(bContext *C, uiBut *but)
{
- uiAfterFunc *after;
- uiBlock *block = but->block;
+ uiAfterFunc *after;
+ uiBlock *block = but->block;
- /* these functions are postponed and only executed after all other
- * handling is done, i.e. menus are closed, in order to avoid conflicts
- * with these functions removing the buttons we are working with */
+ /* these functions are postponed and only executed after all other
+ * handling is done, i.e. menus are closed, in order to avoid conflicts
+ * with these functions removing the buttons we are working with */
- if (ui_afterfunc_check(block, but)) {
- after = ui_afterfunc_new();
+ if (ui_afterfunc_check(block, but)) {
+ after = ui_afterfunc_new();
- if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) {
- /* exception, this will crash due to removed button otherwise */
- but->func(C, but->func_arg1, but->func_arg2);
- }
- else {
- after->func = but->func;
- }
+ if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) {
+ /* exception, this will crash due to removed button otherwise */
+ but->func(C, but->func_arg1, but->func_arg2);
+ }
+ else {
+ after->func = but->func;
+ }
- after->func_arg1 = but->func_arg1;
- after->func_arg2 = but->func_arg2;
+ after->func_arg1 = but->func_arg1;
+ after->func_arg2 = but->func_arg2;
- after->funcN = but->funcN;
- after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : NULL;
+ after->funcN = but->funcN;
+ after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : NULL;
- after->rename_func = but->rename_func;
- after->rename_arg1 = but->rename_arg1;
- after->rename_orig = but->rename_orig; /* needs free! */
+ after->rename_func = but->rename_func;
+ after->rename_arg1 = but->rename_arg1;
+ after->rename_orig = but->rename_orig; /* needs free! */
- after->handle_func = block->handle_func;
- after->handle_func_arg = block->handle_func_arg;
- after->retval = but->retval;
+ after->handle_func = block->handle_func;
+ after->handle_func_arg = block->handle_func_arg;
+ after->retval = but->retval;
- if (but->type == UI_BTYPE_BUT_MENU) {
- after->butm_func = block->butm_func;
- after->butm_func_arg = block->butm_func_arg;
- after->a2 = but->a2;
- }
+ if (but->type == UI_BTYPE_BUT_MENU) {
+ after->butm_func = block->butm_func;
+ after->butm_func_arg = block->butm_func_arg;
+ after->a2 = but->a2;
+ }
- if (block->handle) {
- after->popup_op = block->handle->popup_op;
- }
+ if (block->handle) {
+ after->popup_op = block->handle->popup_op;
+ }
- after->optype = but->optype;
- after->opcontext = but->opcontext;
- after->opptr = but->opptr;
+ after->optype = but->optype;
+ after->opcontext = but->opcontext;
+ after->opptr = but->opptr;
- after->rnapoin = but->rnapoin;
- after->rnaprop = but->rnaprop;
+ after->rnapoin = but->rnapoin;
+ after->rnaprop = but->rnaprop;
- if (but->context) {
- after->context = CTX_store_copy(but->context);
- }
+ if (but->context) {
+ after->context = CTX_store_copy(but->context);
+ }
- but->optype = NULL;
- but->opcontext = 0;
- but->opptr = NULL;
- }
+ but->optype = NULL;
+ but->opcontext = 0;
+ but->opptr = NULL;
+ }
}
/* typically call ui_apply_but_undo(), ui_apply_but_autokey() */
static void ui_apply_but_undo(uiBut *but)
{
- uiAfterFunc *after;
+ uiAfterFunc *after;
- if (but->flag & UI_BUT_UNDO) {
- const char *str = NULL;
+ if (but->flag & UI_BUT_UNDO) {
+ const char *str = NULL;
- /* define which string to use for undo */
- if (but->type == UI_BTYPE_MENU) {
- str = but->drawstr;
- }
- else if (but->drawstr[0]) {
- str = but->drawstr;
- }
- else {
- str = but->tip;
- }
+ /* define which string to use for undo */
+ if (but->type == UI_BTYPE_MENU) {
+ str = but->drawstr;
+ }
+ else if (but->drawstr[0]) {
+ str = but->drawstr;
+ }
+ else {
+ str = but->tip;
+ }
- /* fallback, else we don't get an undo! */
- if (str == NULL || str[0] == '\0') {
- str = "Unknown Action";
- }
+ /* fallback, else we don't get an undo! */
+ if (str == NULL || str[0] == '\0') {
+ str = "Unknown Action";
+ }
- /* delayed, after all other funcs run, popups are closed, etc */
- after = ui_afterfunc_new();
- BLI_strncpy(after->undostr, str, sizeof(after->undostr));
- }
+ /* delayed, after all other funcs run, popups are closed, etc */
+ after = ui_afterfunc_new();
+ BLI_strncpy(after->undostr, str, sizeof(after->undostr));
+ }
}
static void ui_apply_but_autokey(bContext *C, uiBut *but)
{
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- /* try autokey */
- ui_but_anim_autokey(C, but, scene, scene->r.cfra);
+ /* try autokey */
+ ui_but_anim_autokey(C, but, scene, scene->r.cfra);
- /* make a little report about what we've done! */
- if (but->rnaprop) {
- char *buf;
+ /* make a little report about what we've done! */
+ if (but->rnaprop) {
+ char *buf;
- if (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD) {
- return;
- }
+ if (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD) {
+ return;
+ }
- buf = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex);
- if (buf) {
- BKE_report(CTX_wm_reports(C), RPT_PROPERTY, buf);
- MEM_freeN(buf);
+ buf = WM_prop_pystring_assign(C, &but->rnapoin, but->rnaprop, but->rnaindex);
+ if (buf) {
+ BKE_report(CTX_wm_reports(C), RPT_PROPERTY, buf);
+ MEM_freeN(buf);
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
- }
- }
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
+ }
+ }
}
static void ui_apply_but_funcs_after(bContext *C)
{
- uiAfterFunc *afterf, after;
- PointerRNA opptr;
- ListBase funcs;
-
- /* copy to avoid recursive calls */
- funcs = UIAfterFuncs;
- BLI_listbase_clear(&UIAfterFuncs);
-
- for (afterf = funcs.first; afterf; afterf = after.next) {
- after = *afterf; /* copy to avoid memleak on exit() */
- BLI_freelinkN(&funcs, afterf);
-
- if (after.context) {
- CTX_store_set(C, after.context);
- }
-
- if (after.popup_op) {
- popup_check(C, after.popup_op);
- }
-
- if (after.opptr) {
- /* free in advance to avoid leak on exit */
- opptr = *after.opptr;
- MEM_freeN(after.opptr);
- }
-
- if (after.optype) {
- WM_operator_name_call_ptr(C, after.optype, after.opcontext, (after.opptr) ? &opptr : NULL);
- }
-
- if (after.opptr) {
- WM_operator_properties_free(&opptr);
- }
-
- if (after.rnapoin.data) {
- RNA_property_update(C, &after.rnapoin, after.rnaprop);
- }
-
- if (after.context) {
- CTX_store_set(C, NULL);
- CTX_store_free(after.context);
- }
-
- if (after.func) {
- after.func(C, after.func_arg1, after.func_arg2);
- }
- if (after.funcN) {
- after.funcN(C, after.func_argN, after.func_arg2);
- }
- if (after.func_argN) {
- MEM_freeN(after.func_argN);
- }
-
- if (after.handle_func) {
- after.handle_func(C, after.handle_func_arg, after.retval);
- }
- if (after.butm_func) {
- after.butm_func(C, after.butm_func_arg, after.a2);
- }
-
- if (after.rename_func) {
- after.rename_func(C, after.rename_arg1, after.rename_orig);
- }
- if (after.rename_orig) {
- MEM_freeN(after.rename_orig);
- }
-
- if (after.undostr[0]) {
- ED_undo_push(C, after.undostr);
- }
- }
+ uiAfterFunc *afterf, after;
+ PointerRNA opptr;
+ ListBase funcs;
+
+ /* copy to avoid recursive calls */
+ funcs = UIAfterFuncs;
+ BLI_listbase_clear(&UIAfterFuncs);
+
+ for (afterf = funcs.first; afterf; afterf = after.next) {
+ after = *afterf; /* copy to avoid memleak on exit() */
+ BLI_freelinkN(&funcs, afterf);
+
+ if (after.context) {
+ CTX_store_set(C, after.context);
+ }
+
+ if (after.popup_op) {
+ popup_check(C, after.popup_op);
+ }
+
+ if (after.opptr) {
+ /* free in advance to avoid leak on exit */
+ opptr = *after.opptr;
+ MEM_freeN(after.opptr);
+ }
+
+ if (after.optype) {
+ WM_operator_name_call_ptr(C, after.optype, after.opcontext, (after.opptr) ? &opptr : NULL);
+ }
+
+ if (after.opptr) {
+ WM_operator_properties_free(&opptr);
+ }
+
+ if (after.rnapoin.data) {
+ RNA_property_update(C, &after.rnapoin, after.rnaprop);
+ }
+
+ if (after.context) {
+ CTX_store_set(C, NULL);
+ CTX_store_free(after.context);
+ }
+
+ if (after.func) {
+ after.func(C, after.func_arg1, after.func_arg2);
+ }
+ if (after.funcN) {
+ after.funcN(C, after.func_argN, after.func_arg2);
+ }
+ if (after.func_argN) {
+ MEM_freeN(after.func_argN);
+ }
+
+ if (after.handle_func) {
+ after.handle_func(C, after.handle_func_arg, after.retval);
+ }
+ if (after.butm_func) {
+ after.butm_func(C, after.butm_func_arg, after.a2);
+ }
+
+ if (after.rename_func) {
+ after.rename_func(C, after.rename_arg1, after.rename_orig);
+ }
+ if (after.rename_orig) {
+ MEM_freeN(after.rename_orig);
+ }
+
+ if (after.undostr[0]) {
+ ED_undo_push(C, after.undostr);
+ }
+ }
}
static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_apply_but_func(C, but);
+ ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_but_value_set(but, but->hardmin);
- ui_apply_but_func(C, but);
+ ui_but_value_set(but, but->hardmin);
+ ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- if (but->type == UI_BTYPE_MENU) {
- ui_but_value_set(but, data->value);
- }
+ if (but->type == UI_BTYPE_MENU) {
+ ui_but_value_set(but, data->value);
+ }
- ui_but_update_edited(but);
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ ui_but_update_edited(but);
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- const double value = ui_but_value_get(but);
- int value_toggle;
- if (but->bit) {
- value_toggle = UI_BITBUT_VALUE_TOGGLED((int)value, but->bitnr);
- }
- else {
- value_toggle = (value == 0.0);
- if (ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N)) {
- value_toggle = !value_toggle;
- }
- }
+ const double value = ui_but_value_get(but);
+ int value_toggle;
+ if (but->bit) {
+ value_toggle = UI_BITBUT_VALUE_TOGGLED((int)value, but->bitnr);
+ }
+ else {
+ value_toggle = (value == 0.0);
+ if (ELEM(but->type, UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX_N)) {
+ value_toggle = !value_toggle;
+ }
+ }
- ui_but_value_set(but, (double)value_toggle);
- if (but->type == UI_BTYPE_ICON_TOGGLE || but->type == UI_BTYPE_ICON_TOGGLE_N) {
- ui_but_update_edited(but);
- }
+ ui_but_value_set(but, (double)value_toggle);
+ if (but->type == UI_BTYPE_ICON_TOGGLE || but->type == UI_BTYPE_ICON_TOGGLE_N) {
+ ui_but_update_edited(but);
+ }
- ui_apply_but_func(C, but);
+ ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
- uiBut *bt;
+ uiBut *bt;
- ui_but_value_set(but, but->hardmax);
+ ui_but_value_set(but, but->hardmax);
- ui_apply_but_func(C, but);
+ ui_apply_but_func(C, but);
- /* states of other row buttons */
- for (bt = block->buttons.first; bt; bt = bt->next) {
- if (bt != but && bt->poin == but->poin && ELEM(bt->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
- ui_but_update_edited(bt);
- }
- }
+ /* states of other row buttons */
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (bt != but && bt->poin == but->poin && ELEM(bt->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
+ ui_but_update_edited(bt);
+ }
+ }
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- if (!data->str) {
- return;
- }
+ if (!data->str) {
+ return;
+ }
- ui_but_string_set(C, but, data->str);
- ui_but_update_edited(but);
+ ui_but_string_set(C, but, data->str);
+ ui_but_update_edited(but);
- /* give butfunc a copy of the original text too.
- * feature used for bone renaming, channels, etc.
- * afterfunc frees rename_orig */
- if (data->origstr && (but->flag & UI_BUT_TEXTEDIT_UPDATE)) {
- /* In this case, we need to keep origstr available, to restore real org string in case we cancel after
- * having typed something already. */
- but->rename_orig = BLI_strdup(data->origstr);
- }
- /* only if there are afterfuncs, otherwise 'renam_orig' isn't freed */
- else if (ui_afterfunc_check(but->block, but)) {
- but->rename_orig = data->origstr;
- data->origstr = NULL;
- }
- ui_apply_but_func(C, but);
+ /* give butfunc a copy of the original text too.
+ * feature used for bone renaming, channels, etc.
+ * afterfunc frees rename_orig */
+ if (data->origstr && (but->flag & UI_BUT_TEXTEDIT_UPDATE)) {
+ /* In this case, we need to keep origstr available, to restore real org string in case we cancel after
+ * having typed something already. */
+ but->rename_orig = BLI_strdup(data->origstr);
+ }
+ /* only if there are afterfuncs, otherwise 'renam_orig' isn't freed */
+ else if (ui_afterfunc_check(but->block, but)) {
+ but->rename_orig = data->origstr;
+ data->origstr = NULL;
+ }
+ ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_TAB(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- if (data->str) {
- ui_but_string_set(C, but, data->str);
- ui_but_update_edited(but);
- }
- else {
- ui_but_value_set(but, but->hardmax);
- ui_apply_but_func(C, but);
- }
+ if (data->str) {
+ ui_but_string_set(C, but, data->str);
+ ui_but_update_edited(but);
+ }
+ else {
+ ui_but_value_set(but, but->hardmax);
+ ui_apply_but_func(C, but);
+ }
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- if (data->str) {
- if (ui_but_string_set(C, but, data->str)) {
- data->value = ui_but_value_get(but);
- }
- else {
- data->cancel = true;
- return;
- }
- }
- else {
- ui_but_value_set(but, data->value);
- }
+ if (data->str) {
+ if (ui_but_string_set(C, but, data->str)) {
+ data->value = ui_but_value_get(but);
+ }
+ else {
+ data->cancel = true;
+ return;
+ }
+ }
+ else {
+ ui_but_value_set(but, data->value);
+ }
- ui_but_update_edited(but);
- ui_apply_but_func(C, but);
+ ui_but_update_edited(but);
+ ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_VEC(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_but_v3_set(but, data->vec);
- ui_but_update_edited(but);
- ui_apply_but_func(C, but);
+ ui_but_v3_set(but, data->vec);
+ ui_but_update_edited(but);
+ ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_COLORBAND(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_CURVE(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
}
/** \} */
@@ -998,245 +999,240 @@ static void ui_apply_but_CURVE(bContext *C, uiBut *but, uiHandleButtonData *data
/* small multi-but api */
static void ui_multibut_add(uiHandleButtonData *data, uiBut *but)
{
- uiButMultiState *mbut_state;
+ uiButMultiState *mbut_state;
- BLI_assert(but->flag & UI_BUT_DRAG_MULTI);
- BLI_assert(data->multi_data.has_mbuts);
+ BLI_assert(but->flag & UI_BUT_DRAG_MULTI);
+ BLI_assert(data->multi_data.has_mbuts);
+ mbut_state = MEM_callocN(sizeof(*mbut_state), __func__);
+ mbut_state->but = but;
+ mbut_state->origvalue = ui_but_value_get(but);
- mbut_state = MEM_callocN(sizeof(*mbut_state), __func__);
- mbut_state->but = but;
- mbut_state->origvalue = ui_but_value_get(but);
+ BLI_linklist_prepend(&data->multi_data.mbuts, mbut_state);
- BLI_linklist_prepend(&data->multi_data.mbuts, mbut_state);
-
- UI_butstore_register(data->multi_data.bs_mbuts, &mbut_state->but);
+ UI_butstore_register(data->multi_data.bs_mbuts, &mbut_state->but);
}
static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut *but)
{
- LinkNode *l;
+ LinkNode *l;
- for (l = data->multi_data.mbuts; l; l = l->next) {
- uiButMultiState *mbut_state;
+ for (l = data->multi_data.mbuts; l; l = l->next) {
+ uiButMultiState *mbut_state;
- mbut_state = l->link;
+ mbut_state = l->link;
- if (mbut_state->but == but) {
- return mbut_state;
- }
- }
+ if (mbut_state->but == but) {
+ return mbut_state;
+ }
+ }
- return NULL;
+ return NULL;
}
static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block)
{
- uiBut *but;
-
- for (but = block->buttons.first; but; but = but->next) {
- if (but->flag & UI_BUT_DRAG_MULTI) {
- uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
- if (mbut_state) {
- ui_but_value_set(but, mbut_state->origvalue);
-
-#ifdef USE_ALLSELECT
- if (mbut_state->select_others.elems_len > 0) {
- ui_selectcontext_apply(
- C, but, &mbut_state->select_others,
- mbut_state->origvalue, mbut_state->origvalue);
- }
-#else
- UNUSED_VARS(C);
-#endif
- }
- }
- }
+ uiBut *but;
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->flag & UI_BUT_DRAG_MULTI) {
+ uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
+ if (mbut_state) {
+ ui_but_value_set(but, mbut_state->origvalue);
+
+# ifdef USE_ALLSELECT
+ if (mbut_state->select_others.elems_len > 0) {
+ ui_selectcontext_apply(
+ C, but, &mbut_state->select_others, mbut_state->origvalue, mbut_state->origvalue);
+ }
+# else
+ UNUSED_VARS(C);
+# endif
+ }
+ }
+ }
}
static void ui_multibut_free(uiHandleButtonData *data, uiBlock *block)
{
-#ifdef USE_ALLSELECT
- if (data->multi_data.mbuts) {
- LinkNode *list = data->multi_data.mbuts;
- while (list) {
- LinkNode *next = list->next;
- uiButMultiState *mbut_state = list->link;
-
- if (mbut_state->select_others.elems) {
- MEM_freeN(mbut_state->select_others.elems);
- }
-
- MEM_freeN(list->link);
- MEM_freeN(list);
- list = next;
- }
- }
-#else
- BLI_linklist_freeN(data->multi_data.mbuts);
-#endif
+# ifdef USE_ALLSELECT
+ if (data->multi_data.mbuts) {
+ LinkNode *list = data->multi_data.mbuts;
+ while (list) {
+ LinkNode *next = list->next;
+ uiButMultiState *mbut_state = list->link;
+
+ if (mbut_state->select_others.elems) {
+ MEM_freeN(mbut_state->select_others.elems);
+ }
+
+ MEM_freeN(list->link);
+ MEM_freeN(list);
+ list = next;
+ }
+ }
+# else
+ BLI_linklist_freeN(data->multi_data.mbuts);
+# endif
- data->multi_data.mbuts = NULL;
+ data->multi_data.mbuts = NULL;
- if (data->multi_data.bs_mbuts) {
- UI_butstore_free(block, data->multi_data.bs_mbuts);
- data->multi_data.bs_mbuts = NULL;
- }
+ if (data->multi_data.bs_mbuts) {
+ UI_butstore_free(block, data->multi_data.bs_mbuts);
+ data->multi_data.bs_mbuts = NULL;
+ }
}
-static bool ui_multibut_states_tag(
- uiBut *but_active,
- uiHandleButtonData *data, const wmEvent *event)
+static bool ui_multibut_states_tag(uiBut *but_active,
+ uiHandleButtonData *data,
+ const wmEvent *event)
{
- uiBut *but;
- float seg[2][2];
- bool changed = false;
+ uiBut *but;
+ float seg[2][2];
+ bool changed = false;
- seg[0][0] = data->multi_data.drag_start[0];
- seg[0][1] = data->multi_data.drag_start[1];
+ seg[0][0] = data->multi_data.drag_start[0];
+ seg[0][1] = data->multi_data.drag_start[1];
- seg[1][0] = event->x;
- seg[1][1] = event->y;
+ seg[1][0] = event->x;
+ seg[1][1] = event->y;
- BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_SETUP);
+ BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_SETUP);
- ui_window_to_block_fl(data->region, but_active->block, &seg[0][0], &seg[0][1]);
- ui_window_to_block_fl(data->region, but_active->block, &seg[1][0], &seg[1][1]);
+ ui_window_to_block_fl(data->region, but_active->block, &seg[0][0], &seg[0][1]);
+ ui_window_to_block_fl(data->region, but_active->block, &seg[1][0], &seg[1][1]);
- data->multi_data.has_mbuts = false;
+ data->multi_data.has_mbuts = false;
- /* follow ui_but_find_mouse_over_ex logic */
- for (but = but_active->block->buttons.first; but; but = but->next) {
- bool drag_prev = false;
- bool drag_curr = false;
+ /* follow ui_but_find_mouse_over_ex logic */
+ for (but = but_active->block->buttons.first; but; but = but->next) {
+ bool drag_prev = false;
+ bool drag_curr = false;
- /* re-set each time */
- if (but->flag & UI_BUT_DRAG_MULTI) {
- but->flag &= ~UI_BUT_DRAG_MULTI;
- drag_prev = true;
- }
+ /* re-set each time */
+ if (but->flag & UI_BUT_DRAG_MULTI) {
+ but->flag &= ~UI_BUT_DRAG_MULTI;
+ drag_prev = true;
+ }
- if (ui_but_is_interactive(but, false)) {
+ if (ui_but_is_interactive(but, false)) {
- /* drag checks */
- if (but_active != but) {
- if (ui_but_is_compatible(but_active, but)) {
+ /* drag checks */
+ if (but_active != but) {
+ if (ui_but_is_compatible(but_active, but)) {
- BLI_assert(but->active == NULL);
+ BLI_assert(but->active == NULL);
- /* finally check for overlap */
- if (BLI_rctf_isect_segment(&but->rect, seg[0], seg[1])) {
+ /* finally check for overlap */
+ if (BLI_rctf_isect_segment(&but->rect, seg[0], seg[1])) {
- but->flag |= UI_BUT_DRAG_MULTI;
- data->multi_data.has_mbuts = true;
- drag_curr = true;
- }
- }
- }
- }
+ but->flag |= UI_BUT_DRAG_MULTI;
+ data->multi_data.has_mbuts = true;
+ drag_curr = true;
+ }
+ }
+ }
+ }
- changed |= (drag_prev != drag_curr);
- }
+ changed |= (drag_prev != drag_curr);
+ }
- return changed;
+ return changed;
}
static void ui_multibut_states_create(uiBut *but_active, uiHandleButtonData *data)
{
- BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_SETUP);
- BLI_assert(data->multi_data.has_mbuts);
-
- data->multi_data.bs_mbuts = UI_butstore_create(but_active->block);
+ BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_SETUP);
+ BLI_assert(data->multi_data.has_mbuts);
- for (uiBut *but = but_active->block->buttons.first; but; but = but->next) {
- if (but->flag & UI_BUT_DRAG_MULTI) {
- ui_multibut_add(data, but);
- }
- }
+ data->multi_data.bs_mbuts = UI_butstore_create(but_active->block);
- /* edit buttons proportionally to eachother
- * note: if we mix buttons which are proportional and others which are not,
- * this may work a bit strangely */
- if ((but_active->rnaprop && (RNA_property_flag(but_active->rnaprop) & PROP_PROPORTIONAL)) ||
- ELEM(but_active->unit_type, PROP_UNIT_LENGTH))
- {
- if (data->origvalue != 0.0) {
- data->multi_data.is_proportional = true;
- }
- }
+ for (uiBut *but = but_active->block->buttons.first; but; but = but->next) {
+ if (but->flag & UI_BUT_DRAG_MULTI) {
+ ui_multibut_add(data, but);
+ }
+ }
+ /* edit buttons proportionally to eachother
+ * note: if we mix buttons which are proportional and others which are not,
+ * this may work a bit strangely */
+ if ((but_active->rnaprop && (RNA_property_flag(but_active->rnaprop) & PROP_PROPORTIONAL)) ||
+ ELEM(but_active->unit_type, PROP_UNIT_LENGTH)) {
+ if (data->origvalue != 0.0) {
+ data->multi_data.is_proportional = true;
+ }
+ }
}
static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBlock *block)
{
- ARegion *ar = data->region;
- const double value_delta = data->value - data->origvalue;
- const double value_scale = data->multi_data.is_proportional ? (data->value / data->origvalue) : 0.0;
- uiBut *but;
-
- BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_ENABLE);
- BLI_assert(data->multi_data.skip == false);
-
- for (but = block->buttons.first; but; but = but->next) {
- if (but->flag & UI_BUT_DRAG_MULTI) {
- /* mbut_states for delta */
- uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
-
- if (mbut_state) {
- void *active_back;
-
- ui_but_execute_begin(C, ar, but, &active_back);
-
-#ifdef USE_ALLSELECT
- if (data->select_others.is_enabled) {
- /* init once! */
- if (mbut_state->select_others.elems_len == 0) {
- ui_selectcontext_begin(C, but, &mbut_state->select_others);
- }
- if (mbut_state->select_others.elems_len == 0) {
- mbut_state->select_others.elems_len = -1;
- }
- }
-
- /* needed so we apply the right deltas */
- but->active->origvalue = mbut_state->origvalue;
- but->active->select_others = mbut_state->select_others;
- but->active->select_others.do_free = false;
-#endif
-
- BLI_assert(active_back == NULL);
- /* no need to check 'data->state' here */
- if (data->str) {
- /* entering text (set all) */
- but->active->value = data->value;
- ui_but_string_set(C, but, data->str);
- }
- else {
- /* dragging (use delta) */
- if (data->multi_data.is_proportional) {
- but->active->value = mbut_state->origvalue * value_scale;
- }
- else {
- but->active->value = mbut_state->origvalue + value_delta;
- }
-
- /* clamp based on soft limits, see: T40154 */
- CLAMP(but->active->value, (double)but->softmin, (double)but->softmax);
- }
- ui_but_execute_end(C, ar, but, active_back);
- }
- else {
- /* highly unlikely */
- printf("%s: cant find button\n", __func__);
- }
- /* end */
-
- }
- }
-}
-
-#endif /* USE_DRAG_MULTINUM */
+ ARegion *ar = data->region;
+ const double value_delta = data->value - data->origvalue;
+ const double value_scale = data->multi_data.is_proportional ? (data->value / data->origvalue) :
+ 0.0;
+ uiBut *but;
+
+ BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_ENABLE);
+ BLI_assert(data->multi_data.skip == false);
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->flag & UI_BUT_DRAG_MULTI) {
+ /* mbut_states for delta */
+ uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
+
+ if (mbut_state) {
+ void *active_back;
+
+ ui_but_execute_begin(C, ar, but, &active_back);
+
+# ifdef USE_ALLSELECT
+ if (data->select_others.is_enabled) {
+ /* init once! */
+ if (mbut_state->select_others.elems_len == 0) {
+ ui_selectcontext_begin(C, but, &mbut_state->select_others);
+ }
+ if (mbut_state->select_others.elems_len == 0) {
+ mbut_state->select_others.elems_len = -1;
+ }
+ }
+
+ /* needed so we apply the right deltas */
+ but->active->origvalue = mbut_state->origvalue;
+ but->active->select_others = mbut_state->select_others;
+ but->active->select_others.do_free = false;
+# endif
+ BLI_assert(active_back == NULL);
+ /* no need to check 'data->state' here */
+ if (data->str) {
+ /* entering text (set all) */
+ but->active->value = data->value;
+ ui_but_string_set(C, but, data->str);
+ }
+ else {
+ /* dragging (use delta) */
+ if (data->multi_data.is_proportional) {
+ but->active->value = mbut_state->origvalue * value_scale;
+ }
+ else {
+ but->active->value = mbut_state->origvalue + value_delta;
+ }
+
+ /* clamp based on soft limits, see: T40154 */
+ CLAMP(but->active->value, (double)but->softmin, (double)but->softmax);
+ }
+ ui_but_execute_end(C, ar, but, active_back);
+ }
+ else {
+ /* highly unlikely */
+ printf("%s: cant find button\n", __func__);
+ }
+ /* end */
+ }
+ }
+}
+
+#endif /* USE_DRAG_MULTINUM */
/** \} */
@@ -1250,488 +1246,478 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
static bool ui_drag_toggle_but_is_supported(const uiBut *but)
{
- if (ui_but_is_bool(but)) {
- return true;
- }
- else if (UI_but_is_decorator(but)) {
- return ELEM(but->icon, ICON_DECORATE, ICON_DECORATE_KEYFRAME, ICON_DECORATE_ANIMATE, ICON_DECORATE_OVERRIDE);
- }
- else {
- return false;
- }
+ if (ui_but_is_bool(but)) {
+ return true;
+ }
+ else if (UI_but_is_decorator(but)) {
+ return ELEM(but->icon,
+ ICON_DECORATE,
+ ICON_DECORATE_KEYFRAME,
+ ICON_DECORATE_ANIMATE,
+ ICON_DECORATE_OVERRIDE);
+ }
+ else {
+ return false;
+ }
}
/* Button pushed state to compare if other buttons match. Can be more
* then just true or false for toggle buttons with more than 2 states. */
static int ui_drag_toggle_but_pushed_state(bContext *C, uiBut *but)
{
- if (but->rnapoin.data == NULL && but->poin == NULL && but->icon) {
- if (but->pushed_state_func) {
- return but->pushed_state_func(C, but->pushed_state_arg);
- }
- else {
- /* Assume icon identifies a unique state, for buttons that
- * work though functions callbacks and don't have an boolean
- * value that indicates the state. */
- return but->icon + but->iconadd;
- }
- }
- else if (ui_but_is_bool(but)) {
- return ui_but_is_pushed(but);
- }
- else {
- return 0;
- }
+ if (but->rnapoin.data == NULL && but->poin == NULL && but->icon) {
+ if (but->pushed_state_func) {
+ return but->pushed_state_func(C, but->pushed_state_arg);
+ }
+ else {
+ /* Assume icon identifies a unique state, for buttons that
+ * work though functions callbacks and don't have an boolean
+ * value that indicates the state. */
+ return but->icon + but->iconadd;
+ }
+ }
+ else if (ui_but_is_bool(but)) {
+ return ui_but_is_pushed(but);
+ }
+ else {
+ return 0;
+ }
}
typedef struct uiDragToggleHandle {
- /* init */
- int pushed_state;
- float but_cent_start[2];
+ /* init */
+ int pushed_state;
+ float but_cent_start[2];
- bool is_xy_lock_init;
- bool xy_lock[2];
+ bool is_xy_lock_init;
+ bool xy_lock[2];
- int xy_init[2];
- int xy_last[2];
+ int xy_init[2];
+ int xy_last[2];
} uiDragToggleHandle;
static bool ui_drag_toggle_set_xy_xy(
- bContext *C, ARegion *ar, const int pushed_state,
- const int xy_src[2], const int xy_dst[2])
-{
- /* popups such as layers won't re-evaluate on redraw */
- const bool do_check = (ar->regiontype == RGN_TYPE_TEMPORARY);
- bool changed = false;
- uiBlock *block;
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- uiBut *but;
-
- float xy_a_block[2] = {UNPACK2(xy_src)};
- float xy_b_block[2] = {UNPACK2(xy_dst)};
-
- ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
- ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]);
-
- for (but = block->buttons.first; but; but = but->next) {
- /* Note: ctrl is always true here because (at least for now) we always want to consider text control
- * in this case, even when not embossed. */
- if (ui_but_is_interactive(but, true)) {
- if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
-
- /* execute the button */
- if (ui_drag_toggle_but_is_supported(but)) {
- /* is it pressed? */
- int pushed_state_but = ui_drag_toggle_but_pushed_state(C, but);
- if (pushed_state_but != pushed_state) {
- UI_but_execute(C, but);
- if (do_check) {
- ui_but_update_edited(but);
- }
- changed = true;
- }
- }
- /* done */
-
- }
- }
- }
- }
- if (changed) {
- /* apply now, not on release (or if handlers are canceled for whatever reason) */
- ui_apply_but_funcs_after(C);
- }
-
- return changed;
+ bContext *C, ARegion *ar, const int pushed_state, const int xy_src[2], const int xy_dst[2])
+{
+ /* popups such as layers won't re-evaluate on redraw */
+ const bool do_check = (ar->regiontype == RGN_TYPE_TEMPORARY);
+ bool changed = false;
+ uiBlock *block;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ uiBut *but;
+
+ float xy_a_block[2] = {UNPACK2(xy_src)};
+ float xy_b_block[2] = {UNPACK2(xy_dst)};
+
+ ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
+ ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]);
+
+ for (but = block->buttons.first; but; but = but->next) {
+ /* Note: ctrl is always true here because (at least for now) we always want to consider text control
+ * in this case, even when not embossed. */
+ if (ui_but_is_interactive(but, true)) {
+ if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) {
+
+ /* execute the button */
+ if (ui_drag_toggle_but_is_supported(but)) {
+ /* is it pressed? */
+ int pushed_state_but = ui_drag_toggle_but_pushed_state(C, but);
+ if (pushed_state_but != pushed_state) {
+ UI_but_execute(C, but);
+ if (do_check) {
+ ui_but_update_edited(but);
+ }
+ changed = true;
+ }
+ }
+ /* done */
+ }
+ }
+ }
+ }
+ if (changed) {
+ /* apply now, not on release (or if handlers are canceled for whatever reason) */
+ ui_apply_but_funcs_after(C);
+ }
+
+ return changed;
}
static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const int xy_input[2])
{
- ARegion *ar = CTX_wm_region(C);
- bool do_draw = false;
- int xy[2];
-
- /**
- * Initialize Locking:
- *
- * Check if we need to initialize the lock axis by finding if the first
- * button we mouse over is X or Y aligned, then lock the mouse to that axis after.
- */
- if (drag_info->is_xy_lock_init == false) {
- /* first store the buttons original coords */
- uiBut *but = ui_but_find_mouse_over_ex(ar, xy_input[0], xy_input[1], true);
-
- if (but) {
- if (but->flag & UI_BUT_DRAG_LOCK) {
- const float but_cent_new[2] = {
- BLI_rctf_cent_x(&but->rect),
- BLI_rctf_cent_y(&but->rect),
- };
-
- /* check if this is a different button,
- * chances are high the button wont move about :) */
- if (len_manhattan_v2v2(drag_info->but_cent_start, but_cent_new) > 1.0f) {
- if (fabsf(drag_info->but_cent_start[0] - but_cent_new[0]) <
- fabsf(drag_info->but_cent_start[1] - but_cent_new[1]))
- {
- drag_info->xy_lock[0] = true;
- }
- else {
- drag_info->xy_lock[1] = true;
- }
- drag_info->is_xy_lock_init = true;
- }
- }
- else {
- drag_info->is_xy_lock_init = true;
- }
- }
- }
- /* done with axis locking */
-
-
- xy[0] = (drag_info->xy_lock[0] == false) ? xy_input[0] : drag_info->xy_last[0];
- xy[1] = (drag_info->xy_lock[1] == false) ? xy_input[1] : drag_info->xy_last[1];
-
-
- /* touch all buttons between last mouse coord and this one */
- do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->pushed_state, drag_info->xy_last, xy);
-
- if (do_draw) {
- ED_region_tag_redraw(ar);
- }
-
- copy_v2_v2_int(drag_info->xy_last, xy);
+ ARegion *ar = CTX_wm_region(C);
+ bool do_draw = false;
+ int xy[2];
+
+ /**
+ * Initialize Locking:
+ *
+ * Check if we need to initialize the lock axis by finding if the first
+ * button we mouse over is X or Y aligned, then lock the mouse to that axis after.
+ */
+ if (drag_info->is_xy_lock_init == false) {
+ /* first store the buttons original coords */
+ uiBut *but = ui_but_find_mouse_over_ex(ar, xy_input[0], xy_input[1], true);
+
+ if (but) {
+ if (but->flag & UI_BUT_DRAG_LOCK) {
+ const float but_cent_new[2] = {
+ BLI_rctf_cent_x(&but->rect),
+ BLI_rctf_cent_y(&but->rect),
+ };
+
+ /* check if this is a different button,
+ * chances are high the button wont move about :) */
+ if (len_manhattan_v2v2(drag_info->but_cent_start, but_cent_new) > 1.0f) {
+ if (fabsf(drag_info->but_cent_start[0] - but_cent_new[0]) <
+ fabsf(drag_info->but_cent_start[1] - but_cent_new[1])) {
+ drag_info->xy_lock[0] = true;
+ }
+ else {
+ drag_info->xy_lock[1] = true;
+ }
+ drag_info->is_xy_lock_init = true;
+ }
+ }
+ else {
+ drag_info->is_xy_lock_init = true;
+ }
+ }
+ }
+ /* done with axis locking */
+
+ xy[0] = (drag_info->xy_lock[0] == false) ? xy_input[0] : drag_info->xy_last[0];
+ xy[1] = (drag_info->xy_lock[1] == false) ? xy_input[1] : drag_info->xy_last[1];
+
+ /* touch all buttons between last mouse coord and this one */
+ do_draw = ui_drag_toggle_set_xy_xy(C, ar, drag_info->pushed_state, drag_info->xy_last, xy);
+
+ if (do_draw) {
+ ED_region_tag_redraw(ar);
+ }
+
+ copy_v2_v2_int(drag_info->xy_last, xy);
}
static void ui_handler_region_drag_toggle_remove(bContext *UNUSED(C), void *userdata)
{
- uiDragToggleHandle *drag_info = userdata;
- MEM_freeN(drag_info);
+ uiDragToggleHandle *drag_info = userdata;
+ MEM_freeN(drag_info);
}
static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void *userdata)
{
- uiDragToggleHandle *drag_info = userdata;
- bool done = false;
-
- switch (event->type) {
- case LEFTMOUSE:
- {
- if (event->val == KM_RELEASE) {
- done = true;
- }
- break;
- }
- case MOUSEMOVE:
- {
- ui_drag_toggle_set(C, drag_info, &event->x);
- break;
- }
- }
-
- if (done) {
- wmWindow *win = CTX_wm_window(C);
- ARegion *ar = CTX_wm_region(C);
- uiBut *but = ui_but_find_mouse_over_ex(ar, drag_info->xy_init[0], drag_info->xy_init[1], true);
-
- if (but) {
- ui_apply_but_undo(but);
- }
-
- WM_event_remove_ui_handler(
- &win->modalhandlers,
- ui_handler_region_drag_toggle,
- ui_handler_region_drag_toggle_remove,
- drag_info, false);
- ui_handler_region_drag_toggle_remove(C, drag_info);
-
- WM_event_add_mousemove(C);
- return WM_UI_HANDLER_BREAK;
- }
- else {
- return WM_UI_HANDLER_CONTINUE;
- }
+ uiDragToggleHandle *drag_info = userdata;
+ bool done = false;
+
+ switch (event->type) {
+ case LEFTMOUSE: {
+ if (event->val == KM_RELEASE) {
+ done = true;
+ }
+ break;
+ }
+ case MOUSEMOVE: {
+ ui_drag_toggle_set(C, drag_info, &event->x);
+ break;
+ }
+ }
+
+ if (done) {
+ wmWindow *win = CTX_wm_window(C);
+ ARegion *ar = CTX_wm_region(C);
+ uiBut *but = ui_but_find_mouse_over_ex(ar, drag_info->xy_init[0], drag_info->xy_init[1], true);
+
+ if (but) {
+ ui_apply_but_undo(but);
+ }
+
+ WM_event_remove_ui_handler(&win->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info,
+ false);
+ ui_handler_region_drag_toggle_remove(C, drag_info);
+
+ WM_event_add_mousemove(C);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else {
+ return WM_UI_HANDLER_CONTINUE;
+ }
}
static bool ui_but_is_drag_toggle(const uiBut *but)
{
- return ((ui_drag_toggle_but_is_supported(but) == true) &&
- /* menu check is importnt so the button dragged over isn't removed instantly */
- (ui_block_is_menu(but->block) == false));
+ return ((ui_drag_toggle_but_is_supported(but) == true) &&
+ /* menu check is importnt so the button dragged over isn't removed instantly */
+ (ui_block_is_menu(but->block) == false));
}
-#endif /* USE_DRAG_TOGGLE */
-
+#endif /* USE_DRAG_TOGGLE */
#ifdef USE_ALLSELECT
-static bool ui_selectcontext_begin(
- bContext *C, uiBut *but, uiSelectContextStore *selctx_data)
-{
- PointerRNA ptr, lptr, idptr;
- PropertyRNA *prop, *lprop;
- bool success = false;
- int index;
-
- char *path = NULL;
- ListBase lb = {NULL};
-
- ptr = but->rnapoin;
- prop = but->rnaprop;
- index = but->rnaindex;
-
- /* for now don't support whole colors */
- if (index == -1) {
- return false;
- }
-
- /* if there is a valid property that is editable... */
- if (ptr.data && prop) {
- CollectionPointerLink *link;
- bool use_path_from_id;
- int i;
-
- /* some facts we want to know */
- const bool is_array = RNA_property_array_check(prop);
- const int rna_type = RNA_property_type(prop);
-
- if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
- !BLI_listbase_is_empty(&lb))
- {
- selctx_data->elems_len = BLI_listbase_count(&lb);
- selctx_data->elems = MEM_mallocN(sizeof(uiSelectContextElem) * selctx_data->elems_len, __func__);
-
- for (i = 0, link = lb.first; i < selctx_data->elems_len; i++, link = link->next) {
- uiSelectContextElem *other = &selctx_data->elems[i];
- /* TODO,. de-duplicate copy_to_selected_button */
- if (link->ptr.data != ptr.data) {
- if (use_path_from_id) {
- /* Path relative to ID. */
- lprop = NULL;
- RNA_id_pointer_create(link->ptr.id.data, &idptr);
- RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
- }
- else if (path) {
- /* Path relative to elements from list. */
- lprop = NULL;
- RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
- }
- else {
- lptr = link->ptr;
- lprop = prop;
- }
-
- /* lptr might not be the same as link->ptr! */
- if ((lptr.data != ptr.data) &&
- (lprop == prop) &&
- RNA_property_editable(&lptr, lprop))
- {
- other->ptr = lptr;
- if (is_array) {
- if (rna_type == PROP_FLOAT) {
- other->val_f = RNA_property_float_get_index(&lptr, lprop, index);
- }
- else if (rna_type == PROP_INT) {
- other->val_i = RNA_property_int_get_index(&lptr, lprop, index);
- }
- /* ignored for now */
-#if 0
- else if (rna_type == PROP_BOOLEAN) {
- other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
- }
-#endif
- }
- else {
- if (rna_type == PROP_FLOAT) {
- other->val_f = RNA_property_float_get(&lptr, lprop);
- }
- else if (rna_type == PROP_INT) {
- other->val_i = RNA_property_int_get(&lptr, lprop);
- }
- /* ignored for now */
-#if 0
- else if (rna_type == PROP_BOOLEAN) {
- other->val_b = RNA_property_boolean_get(&lptr, lprop);
- }
- else if (rna_type == PROP_ENUM) {
- other->val_i = RNA_property_enum_get(&lptr, lprop);
- }
-#endif
- }
-
- continue;
- }
- }
-
- selctx_data->elems_len -= 1;
- i -= 1;
- }
-
- success = (selctx_data->elems_len != 0);
- }
- }
-
- if (selctx_data->elems_len == 0) {
- MEM_SAFE_FREE(selctx_data->elems);
- }
-
- MEM_SAFE_FREE(path);
- BLI_freelistN(&lb);
-
- /* caller can clear */
- selctx_data->do_free = true;
-
- if (success) {
- but->flag |= UI_BUT_IS_SELECT_CONTEXT;
- }
-
- return success;
-}
-
-static void ui_selectcontext_end(
- uiBut *but, uiSelectContextStore *selctx_data)
-{
- if (selctx_data->do_free) {
- if (selctx_data->elems) {
- MEM_freeN(selctx_data->elems);
- }
- }
-
- but->flag &= ~UI_BUT_IS_SELECT_CONTEXT;
-}
-
-static void ui_selectcontext_apply(
- bContext *C, uiBut *but, uiSelectContextStore *selctx_data,
- const double value, const double value_orig)
-{
- if (selctx_data->elems) {
- PropertyRNA *prop = but->rnaprop;
- PropertyRNA *lprop = but->rnaprop;
- int index = but->rnaindex;
- int i;
- const bool use_delta = (selctx_data->is_copy == false);
-
- union {
- bool b;
- int i;
- float f;
- PointerRNA p;
- } delta, min, max;
-
- const bool is_array = RNA_property_array_check(prop);
- const int rna_type = RNA_property_type(prop);
-
- if (rna_type == PROP_FLOAT) {
- delta.f = use_delta ? (value - value_orig) : value;
- RNA_property_float_range(&but->rnapoin, prop, &min.f, &max.f);
- }
- else if (rna_type == PROP_INT) {
- delta.i = use_delta ? ((int)value - (int)value_orig) : (int)value;
- RNA_property_int_range(&but->rnapoin, prop, &min.i, &max.i);
- }
- else if (rna_type == PROP_ENUM) {
- /* not a delta infact */
- delta.i = RNA_property_enum_get(&but->rnapoin, prop);
- }
- else if (rna_type == PROP_BOOLEAN) {
- if (is_array) {
- /* not a delta infact */
- delta.b = RNA_property_boolean_get_index(&but->rnapoin, prop, index);
- }
- else {
- /* not a delta infact */
- delta.b = RNA_property_boolean_get(&but->rnapoin, prop);
- }
- }
- else if (rna_type == PROP_POINTER) {
- /* not a delta infact */
- delta.p = RNA_property_pointer_get(&but->rnapoin, prop);
- }
-
-#ifdef USE_ALLSELECT_LAYER_HACK
- /* make up for not having 'handle_layer_buttons' */
- {
- PropertySubType subtype = RNA_property_subtype(prop);
-
- if ((rna_type == PROP_BOOLEAN) &&
- ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER) &&
- is_array &&
- /* could check for 'handle_layer_buttons' */
- but->func)
- {
- wmWindow *win = CTX_wm_window(C);
- if (!win->eventstate->shift) {
- const int len = RNA_property_array_length(&but->rnapoin, prop);
- bool *tmparray = MEM_callocN(sizeof(bool) * len, __func__);
-
- tmparray[index] = true;
-
- for (i = 0; i < selctx_data->elems_len; i++) {
- uiSelectContextElem *other = &selctx_data->elems[i];
- PointerRNA lptr = other->ptr;
- RNA_property_boolean_set_array(&lptr, lprop, tmparray);
- RNA_property_update(C, &lptr, lprop);
- }
-
- MEM_freeN(tmparray);
-
- return;
- }
- }
- }
-#endif
+static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore *selctx_data)
+{
+ PointerRNA ptr, lptr, idptr;
+ PropertyRNA *prop, *lprop;
+ bool success = false;
+ int index;
+
+ char *path = NULL;
+ ListBase lb = {NULL};
+
+ ptr = but->rnapoin;
+ prop = but->rnaprop;
+ index = but->rnaindex;
+
+ /* for now don't support whole colors */
+ if (index == -1) {
+ return false;
+ }
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop) {
+ CollectionPointerLink *link;
+ bool use_path_from_id;
+ int i;
+
+ /* some facts we want to know */
+ const bool is_array = RNA_property_array_check(prop);
+ const int rna_type = RNA_property_type(prop);
+
+ if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
+ !BLI_listbase_is_empty(&lb)) {
+ selctx_data->elems_len = BLI_listbase_count(&lb);
+ selctx_data->elems = MEM_mallocN(sizeof(uiSelectContextElem) * selctx_data->elems_len,
+ __func__);
+
+ for (i = 0, link = lb.first; i < selctx_data->elems_len; i++, link = link->next) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ /* TODO,. de-duplicate copy_to_selected_button */
+ if (link->ptr.data != ptr.data) {
+ if (use_path_from_id) {
+ /* Path relative to ID. */
+ lprop = NULL;
+ RNA_id_pointer_create(link->ptr.id.data, &idptr);
+ RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
+ }
+ else if (path) {
+ /* Path relative to elements from list. */
+ lprop = NULL;
+ RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
+ }
+ else {
+ lptr = link->ptr;
+ lprop = prop;
+ }
+
+ /* lptr might not be the same as link->ptr! */
+ if ((lptr.data != ptr.data) && (lprop == prop) && RNA_property_editable(&lptr, lprop)) {
+ other->ptr = lptr;
+ if (is_array) {
+ if (rna_type == PROP_FLOAT) {
+ other->val_f = RNA_property_float_get_index(&lptr, lprop, index);
+ }
+ else if (rna_type == PROP_INT) {
+ other->val_i = RNA_property_int_get_index(&lptr, lprop, index);
+ }
+ /* ignored for now */
+# if 0
+ else if (rna_type == PROP_BOOLEAN) {
+ other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
+ }
+# endif
+ }
+ else {
+ if (rna_type == PROP_FLOAT) {
+ other->val_f = RNA_property_float_get(&lptr, lprop);
+ }
+ else if (rna_type == PROP_INT) {
+ other->val_i = RNA_property_int_get(&lptr, lprop);
+ }
+ /* ignored for now */
+# if 0
+ else if (rna_type == PROP_BOOLEAN) {
+ other->val_b = RNA_property_boolean_get(&lptr, lprop);
+ }
+ else if (rna_type == PROP_ENUM) {
+ other->val_i = RNA_property_enum_get(&lptr, lprop);
+ }
+# endif
+ }
+
+ continue;
+ }
+ }
+
+ selctx_data->elems_len -= 1;
+ i -= 1;
+ }
+
+ success = (selctx_data->elems_len != 0);
+ }
+ }
+
+ if (selctx_data->elems_len == 0) {
+ MEM_SAFE_FREE(selctx_data->elems);
+ }
+
+ MEM_SAFE_FREE(path);
+ BLI_freelistN(&lb);
+
+ /* caller can clear */
+ selctx_data->do_free = true;
+
+ if (success) {
+ but->flag |= UI_BUT_IS_SELECT_CONTEXT;
+ }
+
+ return success;
+}
+
+static void ui_selectcontext_end(uiBut *but, uiSelectContextStore *selctx_data)
+{
+ if (selctx_data->do_free) {
+ if (selctx_data->elems) {
+ MEM_freeN(selctx_data->elems);
+ }
+ }
+
+ but->flag &= ~UI_BUT_IS_SELECT_CONTEXT;
+}
+
+static void ui_selectcontext_apply(bContext *C,
+ uiBut *but,
+ uiSelectContextStore *selctx_data,
+ const double value,
+ const double value_orig)
+{
+ if (selctx_data->elems) {
+ PropertyRNA *prop = but->rnaprop;
+ PropertyRNA *lprop = but->rnaprop;
+ int index = but->rnaindex;
+ int i;
+ const bool use_delta = (selctx_data->is_copy == false);
+
+ union {
+ bool b;
+ int i;
+ float f;
+ PointerRNA p;
+ } delta, min, max;
+
+ const bool is_array = RNA_property_array_check(prop);
+ const int rna_type = RNA_property_type(prop);
+
+ if (rna_type == PROP_FLOAT) {
+ delta.f = use_delta ? (value - value_orig) : value;
+ RNA_property_float_range(&but->rnapoin, prop, &min.f, &max.f);
+ }
+ else if (rna_type == PROP_INT) {
+ delta.i = use_delta ? ((int)value - (int)value_orig) : (int)value;
+ RNA_property_int_range(&but->rnapoin, prop, &min.i, &max.i);
+ }
+ else if (rna_type == PROP_ENUM) {
+ /* not a delta infact */
+ delta.i = RNA_property_enum_get(&but->rnapoin, prop);
+ }
+ else if (rna_type == PROP_BOOLEAN) {
+ if (is_array) {
+ /* not a delta infact */
+ delta.b = RNA_property_boolean_get_index(&but->rnapoin, prop, index);
+ }
+ else {
+ /* not a delta infact */
+ delta.b = RNA_property_boolean_get(&but->rnapoin, prop);
+ }
+ }
+ else if (rna_type == PROP_POINTER) {
+ /* not a delta infact */
+ delta.p = RNA_property_pointer_get(&but->rnapoin, prop);
+ }
+
+# ifdef USE_ALLSELECT_LAYER_HACK
+ /* make up for not having 'handle_layer_buttons' */
+ {
+ PropertySubType subtype = RNA_property_subtype(prop);
+
+ if ((rna_type == PROP_BOOLEAN) && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER) && is_array &&
+ /* could check for 'handle_layer_buttons' */
+ but->func) {
+ wmWindow *win = CTX_wm_window(C);
+ if (!win->eventstate->shift) {
+ const int len = RNA_property_array_length(&but->rnapoin, prop);
+ bool *tmparray = MEM_callocN(sizeof(bool) * len, __func__);
+
+ tmparray[index] = true;
+
+ for (i = 0; i < selctx_data->elems_len; i++) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ PointerRNA lptr = other->ptr;
+ RNA_property_boolean_set_array(&lptr, lprop, tmparray);
+ RNA_property_update(C, &lptr, lprop);
+ }
+
+ MEM_freeN(tmparray);
+
+ return;
+ }
+ }
+ }
+# endif
- for (i = 0; i < selctx_data->elems_len; i++) {
- uiSelectContextElem *other = &selctx_data->elems[i];
- PointerRNA lptr = other->ptr;
-
- if (rna_type == PROP_FLOAT) {
- float other_value = use_delta ? (other->val_f + delta.f) : delta.f;
- CLAMP(other_value, min.f, max.f);
- if (is_array) {
- RNA_property_float_set_index(&lptr, lprop, index, other_value);
- }
- else {
- RNA_property_float_set(&lptr, lprop, other_value);
- }
- }
- else if (rna_type == PROP_INT) {
- int other_value = use_delta ? (other->val_i + delta.i) : delta.i;
- CLAMP(other_value, min.i, max.i);
- if (is_array) {
- RNA_property_int_set_index(&lptr, lprop, index, other_value);
- }
- else {
- RNA_property_int_set(&lptr, lprop, other_value);
- }
- }
- else if (rna_type == PROP_BOOLEAN) {
- const bool other_value = delta.b;
- if (is_array) {
- RNA_property_boolean_set_index(&lptr, lprop, index, other_value);
- }
- else {
- RNA_property_boolean_set(&lptr, lprop, delta.b);
- }
- }
- else if (rna_type == PROP_ENUM) {
- const int other_value = delta.i;
- BLI_assert(!is_array);
- RNA_property_enum_set(&lptr, lprop, other_value);
- }
- else if (rna_type == PROP_POINTER) {
- const PointerRNA other_value = delta.p;
- RNA_property_pointer_set(&lptr, lprop, other_value);
- }
-
- RNA_property_update(C, &lptr, prop);
- }
- }
-}
-
-#endif /* USE_ALLSELECT */
+ for (i = 0; i < selctx_data->elems_len; i++) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ PointerRNA lptr = other->ptr;
+
+ if (rna_type == PROP_FLOAT) {
+ float other_value = use_delta ? (other->val_f + delta.f) : delta.f;
+ CLAMP(other_value, min.f, max.f);
+ if (is_array) {
+ RNA_property_float_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_float_set(&lptr, lprop, other_value);
+ }
+ }
+ else if (rna_type == PROP_INT) {
+ int other_value = use_delta ? (other->val_i + delta.i) : delta.i;
+ CLAMP(other_value, min.i, max.i);
+ if (is_array) {
+ RNA_property_int_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_int_set(&lptr, lprop, other_value);
+ }
+ }
+ else if (rna_type == PROP_BOOLEAN) {
+ const bool other_value = delta.b;
+ if (is_array) {
+ RNA_property_boolean_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_boolean_set(&lptr, lprop, delta.b);
+ }
+ }
+ else if (rna_type == PROP_ENUM) {
+ const int other_value = delta.i;
+ BLI_assert(!is_array);
+ RNA_property_enum_set(&lptr, lprop, other_value);
+ }
+ else if (rna_type == PROP_POINTER) {
+ const PointerRNA other_value = delta.p;
+ RNA_property_pointer_set(&lptr, lprop, other_value);
+ }
+
+ RNA_property_update(C, &lptr, prop);
+ }
+ }
+}
+
+#endif /* USE_ALLSELECT */
/** \} */
@@ -1739,112 +1725,114 @@ static void ui_selectcontext_apply(
/** \name Button Drag
* \{ */
-static bool ui_but_drag_init(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
+static bool ui_but_drag_init(bContext *C,
+ uiBut *but,
+ uiHandleButtonData *data,
+ const wmEvent *event)
{
- /* prevent other WM gestures to start while we try to drag */
- WM_gestures_remove(C);
+ /* prevent other WM gestures to start while we try to drag */
+ WM_gestures_remove(C);
- /* Clamp the maximum to half the UI unit size so a high user preference
- * doesn't require the user to drag more then half the default button height. */
- const int drag_threshold = min_ii(
- U.tweak_threshold * U.dpi_fac,
- (int)((UI_UNIT_Y / 2) * ui_block_to_window_scale(data->region, but->block)));
+ /* Clamp the maximum to half the UI unit size so a high user preference
+ * doesn't require the user to drag more then half the default button height. */
+ const int drag_threshold = min_ii(
+ U.tweak_threshold * U.dpi_fac,
+ (int)((UI_UNIT_Y / 2) * ui_block_to_window_scale(data->region, but->block)));
- if (ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > drag_threshold) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- data->cancel = true;
+ if (ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > drag_threshold) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ data->cancel = true;
#ifdef USE_DRAG_TOGGLE
- if (ui_drag_toggle_but_is_supported(but)) {
- uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
- ARegion *ar_prev;
-
- /* call here because regular mouse-up event wont run,
- * typically 'button_activate_exit()' handles this */
- ui_apply_but_autokey(C, but);
-
- drag_info->pushed_state = ui_drag_toggle_but_pushed_state(C, but);
- drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
- drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
- copy_v2_v2_int(drag_info->xy_init, &event->x);
- copy_v2_v2_int(drag_info->xy_last, &event->x);
-
- /* needed for toggle drag on popups */
- ar_prev = CTX_wm_region(C);
- CTX_wm_region_set(C, data->region);
-
- WM_event_add_ui_handler(
- C, &data->window->modalhandlers,
- ui_handler_region_drag_toggle,
- ui_handler_region_drag_toggle_remove,
- drag_info, WM_HANDLER_BLOCKING);
-
- CTX_wm_region_set(C, ar_prev);
-
- /* Initialize alignment for single row/column regions,
- * otherwise we use the relative position of the first other button dragged over. */
- if (ELEM(data->region->regiontype, RGN_TYPE_NAV_BAR, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
- int lock_axis = -1;
- if (ELEM(data->region->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
- lock_axis = 0;
- }
- else if (ELEM(data->region->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
- lock_axis = 1;
- }
- if (lock_axis != -1) {
- drag_info->xy_lock[lock_axis] = true;
- drag_info->is_xy_lock_init = true;
- }
- }
- }
- else
+ if (ui_drag_toggle_but_is_supported(but)) {
+ uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
+ ARegion *ar_prev;
+
+ /* call here because regular mouse-up event wont run,
+ * typically 'button_activate_exit()' handles this */
+ ui_apply_but_autokey(C, but);
+
+ drag_info->pushed_state = ui_drag_toggle_but_pushed_state(C, but);
+ drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect);
+ drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect);
+ copy_v2_v2_int(drag_info->xy_init, &event->x);
+ copy_v2_v2_int(drag_info->xy_last, &event->x);
+
+ /* needed for toggle drag on popups */
+ ar_prev = CTX_wm_region(C);
+ CTX_wm_region_set(C, data->region);
+
+ WM_event_add_ui_handler(C,
+ &data->window->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info,
+ WM_HANDLER_BLOCKING);
+
+ CTX_wm_region_set(C, ar_prev);
+
+ /* Initialize alignment for single row/column regions,
+ * otherwise we use the relative position of the first other button dragged over. */
+ if (ELEM(data->region->regiontype, RGN_TYPE_NAV_BAR, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
+ int lock_axis = -1;
+ if (ELEM(data->region->alignment, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) {
+ lock_axis = 0;
+ }
+ else if (ELEM(data->region->alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) {
+ lock_axis = 1;
+ }
+ if (lock_axis != -1) {
+ drag_info->xy_lock[lock_axis] = true;
+ drag_info->is_xy_lock_init = true;
+ }
+ }
+ }
+ else
#endif
- if (but->type == UI_BTYPE_COLOR) {
- bool valid = false;
- uiDragColorHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
-
- /* TODO support more button pointer types */
- if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- ui_but_v3_get(but, drag_info->color);
- drag_info->gamma_corrected = true;
- valid = true;
- }
- else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
- ui_but_v3_get(but, drag_info->color);
- drag_info->gamma_corrected = false;
- valid = true;
- }
- else if (ELEM(but->pointype, UI_BUT_POIN_FLOAT, UI_BUT_POIN_CHAR)) {
- ui_but_v3_get(but, drag_info->color);
- copy_v3_v3(drag_info->color, (float *)but->poin);
- valid = true;
- }
-
- if (valid) {
- WM_event_start_drag(C, ICON_COLOR, WM_DRAG_COLOR, drag_info, 0.0, WM_DRAG_FREE_DATA);
- }
- else {
- MEM_freeN(drag_info);
- return false;
- }
- }
- else {
- wmDrag *drag = WM_event_start_drag(
- C, but->icon, but->dragtype, but->dragpoin,
- ui_but_value_get(but), WM_DRAG_NOP);
-
- if (but->imb) {
- WM_event_drag_image(
- drag, but->imb, but->imb_scale,
- BLI_rctf_size_x(&but->rect),
- BLI_rctf_size_y(&but->rect));
- }
- }
- return true;
- }
-
- return false;
+ if (but->type == UI_BTYPE_COLOR) {
+ bool valid = false;
+ uiDragColorHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__);
+
+ /* TODO support more button pointer types */
+ if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ ui_but_v3_get(but, drag_info->color);
+ drag_info->gamma_corrected = true;
+ valid = true;
+ }
+ else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
+ ui_but_v3_get(but, drag_info->color);
+ drag_info->gamma_corrected = false;
+ valid = true;
+ }
+ else if (ELEM(but->pointype, UI_BUT_POIN_FLOAT, UI_BUT_POIN_CHAR)) {
+ ui_but_v3_get(but, drag_info->color);
+ copy_v3_v3(drag_info->color, (float *)but->poin);
+ valid = true;
+ }
+
+ if (valid) {
+ WM_event_start_drag(C, ICON_COLOR, WM_DRAG_COLOR, drag_info, 0.0, WM_DRAG_FREE_DATA);
+ }
+ else {
+ MEM_freeN(drag_info);
+ return false;
+ }
+ }
+ else {
+ wmDrag *drag = WM_event_start_drag(
+ C, but->icon, but->dragtype, but->dragpoin, ui_but_value_get(but), WM_DRAG_NOP);
+
+ if (but->imb) {
+ WM_event_drag_image(drag,
+ but->imb,
+ but->imb_scale,
+ BLI_rctf_size_x(&but->rect),
+ BLI_rctf_size_y(&but->rect));
+ }
+ }
+ return true;
+ }
+
+ return false;
}
/** \} */
@@ -1855,210 +1843,208 @@ static bool ui_but_drag_init(
static void ui_apply_but_IMAGE(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_HISTOGRAM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_WAVEFORM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
}
static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_apply_but_func(C, but);
- data->retval = but->retval;
- data->applied = true;
-}
-
-
-static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive)
-{
- char *editstr;
- double *editval;
- float *editvec;
- ColorBand *editcoba;
- CurveMapping *editcumap;
-
- data->retval = 0;
-
- /* if we cancel and have not applied yet, there is nothing to do,
- * otherwise we have to restore the original value again */
- if (data->cancel) {
- if (!data->applied) {
- return;
- }
-
- if (data->str) {
- MEM_freeN(data->str);
- }
- data->str = data->origstr;
- data->origstr = NULL;
- data->value = data->origvalue;
- copy_v3_v3(data->vec, data->origvec);
- /* postpone clearing origdata */
- }
- else {
- /* we avoid applying interactive edits a second time
- * at the end with the appliedinteractive flag */
- if (interactive) {
- data->applied_interactive = true;
- }
- else if (data->applied_interactive) {
- return;
- }
+ ui_apply_but_func(C, but);
+ data->retval = but->retval;
+ data->applied = true;
+}
+
+static void ui_apply_but(
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive)
+{
+ char *editstr;
+ double *editval;
+ float *editvec;
+ ColorBand *editcoba;
+ CurveMapping *editcumap;
+
+ data->retval = 0;
+
+ /* if we cancel and have not applied yet, there is nothing to do,
+ * otherwise we have to restore the original value again */
+ if (data->cancel) {
+ if (!data->applied) {
+ return;
+ }
+
+ if (data->str) {
+ MEM_freeN(data->str);
+ }
+ data->str = data->origstr;
+ data->origstr = NULL;
+ data->value = data->origvalue;
+ copy_v3_v3(data->vec, data->origvec);
+ /* postpone clearing origdata */
+ }
+ else {
+ /* we avoid applying interactive edits a second time
+ * at the end with the appliedinteractive flag */
+ if (interactive) {
+ data->applied_interactive = true;
+ }
+ else if (data->applied_interactive) {
+ return;
+ }
#ifdef USE_ALLSELECT
# ifdef USE_DRAG_MULTINUM
- if (but->flag & UI_BUT_DRAG_MULTI) {
- /* pass */
- }
- else
+ if (but->flag & UI_BUT_DRAG_MULTI) {
+ /* pass */
+ }
+ else
# endif
- if (data->select_others.elems_len == 0) {
- wmWindow *win = CTX_wm_window(C);
- /* may have been enabled before activating */
- if (data->select_others.is_enabled || IS_ALLSELECT_EVENT(win->eventstate)) {
- ui_selectcontext_begin(C, but, &data->select_others);
- data->select_others.is_enabled = true;
- }
- }
- if (data->select_others.elems_len == 0) {
- /* dont check again */
- data->select_others.elems_len = -1;
- }
+ if (data->select_others.elems_len == 0) {
+ wmWindow *win = CTX_wm_window(C);
+ /* may have been enabled before activating */
+ if (data->select_others.is_enabled || IS_ALLSELECT_EVENT(win->eventstate)) {
+ ui_selectcontext_begin(C, but, &data->select_others);
+ data->select_others.is_enabled = true;
+ }
+ }
+ if (data->select_others.elems_len == 0) {
+ /* dont check again */
+ data->select_others.elems_len = -1;
+ }
#endif
- }
-
- /* ensures we are writing actual values */
- editstr = but->editstr;
- editval = but->editval;
- editvec = but->editvec;
- editcoba = but->editcoba;
- editcumap = but->editcumap;
- but->editstr = NULL;
- but->editval = NULL;
- but->editvec = NULL;
- but->editcoba = NULL;
- but->editcumap = NULL;
-
- /* handle different types */
- switch (but->type) {
- case UI_BTYPE_BUT:
- ui_apply_but_BUT(C, but, data);
- break;
- case UI_BTYPE_TEXT:
- case UI_BTYPE_SEARCH_MENU:
- ui_apply_but_TEX(C, but, data);
- break;
- case UI_BTYPE_BUT_TOGGLE:
- case UI_BTYPE_TOGGLE:
- case UI_BTYPE_TOGGLE_N:
- case UI_BTYPE_ICON_TOGGLE:
- case UI_BTYPE_ICON_TOGGLE_N:
- case UI_BTYPE_CHECKBOX:
- case UI_BTYPE_CHECKBOX_N:
- ui_apply_but_TOG(C, but, data);
- break;
- case UI_BTYPE_ROW:
- case UI_BTYPE_LISTROW:
- ui_apply_but_ROW(C, block, but, data);
- break;
- case UI_BTYPE_TAB:
- ui_apply_but_TAB(C, but, data);
- break;
- case UI_BTYPE_SCROLL:
- case UI_BTYPE_GRIP:
- case UI_BTYPE_NUM:
- case UI_BTYPE_NUM_SLIDER:
- ui_apply_but_NUM(C, but, data);
- break;
- case UI_BTYPE_MENU:
- case UI_BTYPE_BLOCK:
- case UI_BTYPE_PULLDOWN:
- ui_apply_but_BLOCK(C, but, data);
- break;
- case UI_BTYPE_COLOR:
- if (data->cancel) {
- ui_apply_but_VEC(C, but, data);
- }
- else {
- ui_apply_but_BLOCK(C, but, data);
- }
- break;
- case UI_BTYPE_BUT_MENU:
- ui_apply_but_BUTM(C, but, data);
- break;
- case UI_BTYPE_UNITVEC:
- case UI_BTYPE_HSVCUBE:
- case UI_BTYPE_HSVCIRCLE:
- ui_apply_but_VEC(C, but, data);
- break;
- case UI_BTYPE_COLORBAND:
- ui_apply_but_COLORBAND(C, but, data);
- break;
- case UI_BTYPE_CURVE:
- ui_apply_but_CURVE(C, but, data);
- break;
- case UI_BTYPE_KEY_EVENT:
- case UI_BTYPE_HOTKEY_EVENT:
- ui_apply_but_BUT(C, but, data);
- break;
- case UI_BTYPE_IMAGE:
- ui_apply_but_IMAGE(C, but, data);
- break;
- case UI_BTYPE_HISTOGRAM:
- ui_apply_but_HISTOGRAM(C, but, data);
- break;
- case UI_BTYPE_WAVEFORM:
- ui_apply_but_WAVEFORM(C, but, data);
- break;
- case UI_BTYPE_TRACK_PREVIEW:
- ui_apply_but_TRACKPREVIEW(C, but, data);
- break;
- default:
- break;
- }
+ }
+
+ /* ensures we are writing actual values */
+ editstr = but->editstr;
+ editval = but->editval;
+ editvec = but->editvec;
+ editcoba = but->editcoba;
+ editcumap = but->editcumap;
+ but->editstr = NULL;
+ but->editval = NULL;
+ but->editvec = NULL;
+ but->editcoba = NULL;
+ but->editcumap = NULL;
+
+ /* handle different types */
+ switch (but->type) {
+ case UI_BTYPE_BUT:
+ ui_apply_but_BUT(C, but, data);
+ break;
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU:
+ ui_apply_but_TEX(C, but, data);
+ break;
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_TOGGLE_N:
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE_N:
+ case UI_BTYPE_CHECKBOX:
+ case UI_BTYPE_CHECKBOX_N:
+ ui_apply_but_TOG(C, but, data);
+ break;
+ case UI_BTYPE_ROW:
+ case UI_BTYPE_LISTROW:
+ ui_apply_but_ROW(C, block, but, data);
+ break;
+ case UI_BTYPE_TAB:
+ ui_apply_but_TAB(C, but, data);
+ break;
+ case UI_BTYPE_SCROLL:
+ case UI_BTYPE_GRIP:
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_NUM_SLIDER:
+ ui_apply_but_NUM(C, but, data);
+ break;
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_BLOCK:
+ case UI_BTYPE_PULLDOWN:
+ ui_apply_but_BLOCK(C, but, data);
+ break;
+ case UI_BTYPE_COLOR:
+ if (data->cancel) {
+ ui_apply_but_VEC(C, but, data);
+ }
+ else {
+ ui_apply_but_BLOCK(C, but, data);
+ }
+ break;
+ case UI_BTYPE_BUT_MENU:
+ ui_apply_but_BUTM(C, but, data);
+ break;
+ case UI_BTYPE_UNITVEC:
+ case UI_BTYPE_HSVCUBE:
+ case UI_BTYPE_HSVCIRCLE:
+ ui_apply_but_VEC(C, but, data);
+ break;
+ case UI_BTYPE_COLORBAND:
+ ui_apply_but_COLORBAND(C, but, data);
+ break;
+ case UI_BTYPE_CURVE:
+ ui_apply_but_CURVE(C, but, data);
+ break;
+ case UI_BTYPE_KEY_EVENT:
+ case UI_BTYPE_HOTKEY_EVENT:
+ ui_apply_but_BUT(C, but, data);
+ break;
+ case UI_BTYPE_IMAGE:
+ ui_apply_but_IMAGE(C, but, data);
+ break;
+ case UI_BTYPE_HISTOGRAM:
+ ui_apply_but_HISTOGRAM(C, but, data);
+ break;
+ case UI_BTYPE_WAVEFORM:
+ ui_apply_but_WAVEFORM(C, but, data);
+ break;
+ case UI_BTYPE_TRACK_PREVIEW:
+ ui_apply_but_TRACKPREVIEW(C, but, data);
+ break;
+ default:
+ break;
+ }
#ifdef USE_DRAG_MULTINUM
- if (data->multi_data.has_mbuts) {
- if ((data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) &&
- (data->multi_data.skip == false))
- {
- if (data->cancel) {
- ui_multibut_restore(C, data, block);
- }
- else {
- ui_multibut_states_apply(C, data, block);
- }
- }
- }
+ if (data->multi_data.has_mbuts) {
+ if ((data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) && (data->multi_data.skip == false)) {
+ if (data->cancel) {
+ ui_multibut_restore(C, data, block);
+ }
+ else {
+ ui_multibut_states_apply(C, data, block);
+ }
+ }
+ }
#endif
#ifdef USE_ALLSELECT
- ui_selectcontext_apply(C, but, &data->select_others, data->value, data->origvalue);
+ ui_selectcontext_apply(C, but, &data->select_others, data->value, data->origvalue);
#endif
- if (data->cancel) {
- data->origvalue = 0.0;
- zero_v3(data->origvec);
- }
+ if (data->cancel) {
+ data->origvalue = 0.0;
+ zero_v3(data->origvec);
+ }
- but->editstr = editstr;
- but->editval = editval;
- but->editvec = editvec;
- but->editcoba = editcoba;
- but->editcumap = editcumap;
+ but->editstr = editstr;
+ but->editval = editval;
+ but->editvec = editvec;
+ but->editcoba = editcoba;
+ but->editcumap = editcumap;
}
/** \} */
@@ -2070,28 +2056,28 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
/* only call if event type is EVT_DROP */
static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data)
{
- wmDrag *wmd;
- ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
+ wmDrag *wmd;
+ ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
- for (wmd = drags->first; wmd; wmd = wmd->next) {
- if (wmd->type == WM_DRAG_ID) {
- /* align these types with UI_but_active_drop_name */
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- ID *id = WM_drag_ID(wmd, 0);
+ for (wmd = drags->first; wmd; wmd = wmd->next) {
+ if (wmd->type == WM_DRAG_ID) {
+ /* align these types with UI_but_active_drop_name */
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ ID *id = WM_drag_ID(wmd, 0);
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- ui_textedit_string_set(but, data, id->name + 2);
+ ui_textedit_string_set(but, data, id->name + 2);
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU)) {
- but->changed = true;
- ui_searchbox_update(C, data->searchbox, but, true);
- }
+ if (ELEM(but->type, UI_BTYPE_SEARCH_MENU)) {
+ but->changed = true;
+ ui_searchbox_update(C, data->searchbox, but, true);
+ }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ }
}
/** \} */
@@ -2102,435 +2088,446 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
static void ui_but_get_pasted_text_from_clipboard(char **buf_paste, int *buf_len)
{
- char *text;
- int length;
- /* get only first line even if the clipboard contains multiple lines */
- text = WM_clipboard_text_get_firstline(false, &length);
+ char *text;
+ int length;
+ /* get only first line even if the clipboard contains multiple lines */
+ text = WM_clipboard_text_get_firstline(false, &length);
- if (text) {
- *buf_paste = text;
- *buf_len = length;
- }
- else {
- *buf_paste = MEM_callocN(sizeof(char), __func__);
- *buf_len = 0;
- }
+ if (text) {
+ *buf_paste = text;
+ *buf_len = length;
+ }
+ else {
+ *buf_paste = MEM_callocN(sizeof(char), __func__);
+ *buf_len = 0;
+ }
}
static int get_but_property_array_length(uiBut *but)
{
- return RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ return RNA_property_array_length(&but->rnapoin, but->rnaprop);
}
-static void ui_but_set_float_array(bContext *C, uiBut *but, uiHandleButtonData *data, float *values, int array_length)
+static void ui_but_set_float_array(
+ bContext *C, uiBut *but, uiHandleButtonData *data, float *values, int array_length)
{
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- for (int i = 0; i < array_length; i++) {
- RNA_property_float_set_index(&but->rnapoin, but->rnaprop, i, values[i]);
- }
- if (data) {
- data->value = values[but->rnaindex];
- }
+ for (int i = 0; i < array_length; i++) {
+ RNA_property_float_set_index(&but->rnapoin, but->rnaprop, i, values[i]);
+ }
+ if (data) {
+ data->value = values[but->rnaindex];
+ }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
}
-static void float_array_to_string(float *values, int array_length, char *output, int output_len_max)
+static void float_array_to_string(float *values,
+ int array_length,
+ char *output,
+ int output_len_max)
{
- /* to avoid buffer overflow attacks; numbers are quite arbitrary */
- BLI_assert(output_len_max > 15);
- output_len_max -= 10;
+ /* to avoid buffer overflow attacks; numbers are quite arbitrary */
+ BLI_assert(output_len_max > 15);
+ output_len_max -= 10;
- int current_index = 0;
- output[current_index] = '[';
- current_index++;
+ int current_index = 0;
+ output[current_index] = '[';
+ current_index++;
- for (int i = 0; i < array_length; i++) {
- int length = BLI_snprintf(output + current_index, output_len_max - current_index, "%f", values[i]);
- current_index += length;
+ for (int i = 0; i < array_length; i++) {
+ int length = BLI_snprintf(
+ output + current_index, output_len_max - current_index, "%f", values[i]);
+ current_index += length;
- if (i < array_length - 1) {
- if (current_index < output_len_max) {
- output[current_index + 0] = ',';
- output[current_index + 1] = ' ';
- current_index += 2;
- }
- }
- }
+ if (i < array_length - 1) {
+ if (current_index < output_len_max) {
+ output[current_index + 0] = ',';
+ output[current_index + 1] = ' ';
+ current_index += 2;
+ }
+ }
+ }
- output[current_index + 0] = ']';
- output[current_index + 1] = '\0';
+ output[current_index + 0] = ']';
+ output[current_index + 1] = '\0';
}
static void ui_but_copy_numeric_array(uiBut *but, char *output, int output_len_max)
{
- int array_length = get_but_property_array_length(but);
- float *values = alloca(array_length * sizeof(float));
- RNA_property_float_get_array(&but->rnapoin, but->rnaprop, values);
- float_array_to_string(values, array_length, output, output_len_max);
+ int array_length = get_but_property_array_length(but);
+ float *values = alloca(array_length * sizeof(float));
+ RNA_property_float_get_array(&but->rnapoin, but->rnaprop, values);
+ float_array_to_string(values, array_length, output, output_len_max);
}
static bool parse_float_array(char *text, float *values, int expected_length)
{
- /* can parse max 4 floats for now */
- BLI_assert(0 <= expected_length && expected_length <= 4);
+ /* can parse max 4 floats for now */
+ BLI_assert(0 <= expected_length && expected_length <= 4);
- float v[5];
- int actual_length = sscanf(text, "[%f, %f, %f, %f, %f]", &v[0], &v[1], &v[2], &v[3], &v[4]);
+ float v[5];
+ int actual_length = sscanf(text, "[%f, %f, %f, %f, %f]", &v[0], &v[1], &v[2], &v[3], &v[4]);
- if (actual_length == expected_length) {
- memcpy(values, v, sizeof(float) * expected_length);
- return true;
- }
- else {
- return false;
- }
+ if (actual_length == expected_length) {
+ memcpy(values, v, sizeof(float) * expected_length);
+ return true;
+ }
+ else {
+ return false;
+ }
}
-static void ui_but_paste_numeric_array(bContext *C, uiBut *but, uiHandleButtonData *data, char *buf_paste)
+static void ui_but_paste_numeric_array(bContext *C,
+ uiBut *but,
+ uiHandleButtonData *data,
+ char *buf_paste)
{
- int array_length = get_but_property_array_length(but);
- if (array_length > 4) {
- // not supported for now
- return;
- }
+ int array_length = get_but_property_array_length(but);
+ if (array_length > 4) {
+ // not supported for now
+ return;
+ }
- float *values = alloca(sizeof(float) * array_length);
+ float *values = alloca(sizeof(float) * array_length);
- if (parse_float_array(buf_paste, values, array_length)) {
- ui_but_set_float_array(C, but, data, values, array_length);
- }
- else {
- WM_report(RPT_ERROR, "Expected an array of numbers: [n, n, ...]");
- }
+ if (parse_float_array(buf_paste, values, array_length)) {
+ ui_but_set_float_array(C, but, data, values, array_length);
+ }
+ else {
+ WM_report(RPT_ERROR, "Expected an array of numbers: [n, n, ...]");
+ }
}
static void ui_but_copy_numeric_value(uiBut *but, char *output, int output_len_max)
{
- /* Get many decimal places, then strip trailing zeros.
- * note: too high values start to give strange results */
- ui_but_string_get_ex(but, output, output_len_max, UI_PRECISION_FLOAT_MAX, false, NULL);
- BLI_str_rstrip_float_zero(output, '\0');
+ /* Get many decimal places, then strip trailing zeros.
+ * note: too high values start to give strange results */
+ ui_but_string_get_ex(but, output, output_len_max, UI_PRECISION_FLOAT_MAX, false, NULL);
+ BLI_str_rstrip_float_zero(output, '\0');
}
-static void ui_but_paste_numeric_value(bContext *C, uiBut *but, uiHandleButtonData *data, char *buf_paste)
+static void ui_but_paste_numeric_value(bContext *C,
+ uiBut *but,
+ uiHandleButtonData *data,
+ char *buf_paste)
{
- double value;
+ double value;
- if (ui_but_string_set_eval_num(C, but, buf_paste, &value)) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- data->value = value;
- ui_but_string_set(C, but, buf_paste);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- WM_report(RPT_ERROR, "Expected a number");
- }
+ if (ui_but_string_set_eval_num(C, but, buf_paste, &value)) {
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ data->value = value;
+ ui_but_string_set(C, but, buf_paste);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ WM_report(RPT_ERROR, "Expected a number");
+ }
}
static void ui_but_paste_normalized_vector(bContext *C, uiBut *but, char *buf_paste)
{
- float xyz[3];
- if (parse_float_array(buf_paste, xyz, 3)) {
- if (normalize_v3(xyz) == 0.0f) {
- /* better set Z up then have a zero vector */
- xyz[2] = 1.0;
- }
- ui_but_set_float_array(C, but, NULL, xyz, 3);
- }
- else {
- WM_report(RPT_ERROR, "Paste expected 3 numbers, formatted: '[n, n, n]'");
- }
+ float xyz[3];
+ if (parse_float_array(buf_paste, xyz, 3)) {
+ if (normalize_v3(xyz) == 0.0f) {
+ /* better set Z up then have a zero vector */
+ xyz[2] = 1.0;
+ }
+ ui_but_set_float_array(C, but, NULL, xyz, 3);
+ }
+ else {
+ WM_report(RPT_ERROR, "Paste expected 3 numbers, formatted: '[n, n, n]'");
+ }
}
static void ui_but_copy_color(uiBut *but, char *output, int output_len_max)
{
- float rgba[4];
+ float rgba[4];
- if (but->rnaprop && get_but_property_array_length(but) == 4) {
- rgba[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
- }
- else {
- rgba[3] = 1.0f;
- }
+ if (but->rnaprop && get_but_property_array_length(but) == 4) {
+ rgba[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
+ }
+ else {
+ rgba[3] = 1.0f;
+ }
- ui_but_v3_get(but, rgba);
+ ui_but_v3_get(but, rgba);
- /* convert to linear color to do compatible copy between gamma and non-gamma */
- if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- srgb_to_linearrgb_v3_v3(rgba, rgba);
- }
+ /* convert to linear color to do compatible copy between gamma and non-gamma */
+ if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ srgb_to_linearrgb_v3_v3(rgba, rgba);
+ }
- float_array_to_string(rgba, 4, output, output_len_max);
+ float_array_to_string(rgba, 4, output, output_len_max);
}
static void ui_but_paste_color(bContext *C, uiBut *but, char *buf_paste)
{
- float rgba[4];
- if (parse_float_array(buf_paste, rgba, 4)) {
- if (but->rnaprop) {
- /* Assume linear colors in buffer. */
- if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- linearrgb_to_srgb_v3_v3(rgba, rgba);
- }
-
- /* Some color properties are RGB, not RGBA. */
- int array_len = get_but_property_array_length(but);
- BLI_assert(ELEM(array_len, 3, 4));
- ui_but_set_float_array(C, but, NULL, rgba, array_len);
- }
- }
- else {
- WM_report(RPT_ERROR, "Paste expected 4 numbers, formatted: '[n, n, n, n]'");
- }
+ float rgba[4];
+ if (parse_float_array(buf_paste, rgba, 4)) {
+ if (but->rnaprop) {
+ /* Assume linear colors in buffer. */
+ if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ linearrgb_to_srgb_v3_v3(rgba, rgba);
+ }
+
+ /* Some color properties are RGB, not RGBA. */
+ int array_len = get_but_property_array_length(but);
+ BLI_assert(ELEM(array_len, 3, 4));
+ ui_but_set_float_array(C, but, NULL, rgba, array_len);
+ }
+ }
+ else {
+ WM_report(RPT_ERROR, "Paste expected 4 numbers, formatted: '[n, n, n, n]'");
+ }
}
static void ui_but_copy_text(uiBut *but, char *output, int output_len_max)
{
- ui_but_string_get(but, output, output_len_max);
+ ui_but_string_get(but, output, output_len_max);
}
static void ui_but_paste_text(bContext *C, uiBut *but, uiHandleButtonData *data, char *buf_paste)
{
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- ui_textedit_string_set(but, but->active, buf_paste);
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ ui_textedit_string_set(but, but->active, buf_paste);
- if (but->type == UI_BTYPE_SEARCH_MENU) {
- but->changed = true;
- ui_searchbox_update(C, data->searchbox, but, true);
- }
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
+ but->changed = true;
+ ui_searchbox_update(C, data->searchbox, but, true);
+ }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
}
static void ui_but_copy_colorband(uiBut *but)
{
- if (but->poin != NULL) {
- memcpy(&but_copypaste_coba, but->poin, sizeof(ColorBand));
- }
+ if (but->poin != NULL) {
+ memcpy(&but_copypaste_coba, but->poin, sizeof(ColorBand));
+ }
}
static void ui_but_paste_colorband(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- if (but_copypaste_coba.tot != 0) {
- if (!but->poin) {
- but->poin = MEM_callocN(sizeof(ColorBand), "colorband");
- }
+ if (but_copypaste_coba.tot != 0) {
+ if (!but->poin) {
+ but->poin = MEM_callocN(sizeof(ColorBand), "colorband");
+ }
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- memcpy(data->coba, &but_copypaste_coba, sizeof(ColorBand));
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ memcpy(data->coba, &but_copypaste_coba, sizeof(ColorBand));
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
}
static void ui_but_copy_curvemapping(uiBut *but)
{
- if (but->poin != NULL) {
- but_copypaste_curve_alive = true;
- curvemapping_free_data(&but_copypaste_curve);
- curvemapping_copy_data(&but_copypaste_curve, (CurveMapping *) but->poin);
- }
+ if (but->poin != NULL) {
+ but_copypaste_curve_alive = true;
+ curvemapping_free_data(&but_copypaste_curve);
+ curvemapping_copy_data(&but_copypaste_curve, (CurveMapping *)but->poin);
+ }
}
static void ui_but_paste_curvemapping(bContext *C, uiBut *but)
{
- if (but_copypaste_curve_alive) {
- if (!but->poin) {
- but->poin = MEM_callocN(sizeof(CurveMapping), "curvemapping");
- }
+ if (but_copypaste_curve_alive) {
+ if (!but->poin) {
+ but->poin = MEM_callocN(sizeof(CurveMapping), "curvemapping");
+ }
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- curvemapping_free_data((CurveMapping *) but->poin);
- curvemapping_copy_data((CurveMapping *) but->poin, &but_copypaste_curve);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ curvemapping_free_data((CurveMapping *)but->poin);
+ curvemapping_copy_data((CurveMapping *)but->poin, &but_copypaste_curve);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
}
static void ui_but_copy_operator(bContext *C, uiBut *but, char *output, int output_len_max)
{
- PointerRNA *opptr;
- opptr = UI_but_operator_ptr_get(but);
+ PointerRNA *opptr;
+ opptr = UI_but_operator_ptr_get(but);
- char *str;
- str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr);
- BLI_strncpy(output, str, output_len_max);
- MEM_freeN(str);
+ char *str;
+ str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr);
+ BLI_strncpy(output, str, output_len_max);
+ MEM_freeN(str);
}
static bool ui_but_copy_menu(uiBut *but, char *output, int output_len_max)
{
- MenuType *mt = UI_but_menutype_get(but);
- if (mt) {
- BLI_snprintf(output, output_len_max, "bpy.ops.wm.call_menu(name=\"%s\")", mt->idname);
- return true;
- }
- return false;
+ MenuType *mt = UI_but_menutype_get(but);
+ if (mt) {
+ BLI_snprintf(output, output_len_max, "bpy.ops.wm.call_menu(name=\"%s\")", mt->idname);
+ return true;
+ }
+ return false;
}
static bool ui_but_copy_popover(uiBut *but, char *output, int output_len_max)
{
- PanelType *pt = UI_but_paneltype_get(but);
- if (pt) {
- BLI_snprintf(output, output_len_max, "bpy.ops.wm.call_panel(name=\"%s\")", pt->idname);
- return true;
- }
- return false;
+ PanelType *pt = UI_but_paneltype_get(but);
+ if (pt) {
+ BLI_snprintf(output, output_len_max, "bpy.ops.wm.call_panel(name=\"%s\")", pt->idname);
+ return true;
+ }
+ return false;
}
static void ui_but_copy(bContext *C, uiBut *but, const bool copy_array)
{
- if (ui_but_contains_password(but)) {
- return;
- }
-
- /* Arbitrary large value (allow for paths: 'PATH_MAX') */
- char buf[4096] = {0};
- const int buf_max_len = sizeof(buf);
-
- /* Left false for copying internal data (color-band for eg). */
- bool is_buf_set = false;
-
- bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL);
-
- switch (but->type) {
- case UI_BTYPE_NUM:
- case UI_BTYPE_NUM_SLIDER:
- if (!has_required_data) {
- break;
- }
- if (copy_array && ui_but_has_array_value(but)) {
- ui_but_copy_numeric_array(but, buf, buf_max_len);
- }
- else {
- ui_but_copy_numeric_value(but, buf, buf_max_len);
- }
- is_buf_set = true;
- break;
-
- case UI_BTYPE_UNITVEC:
- if (!has_required_data) {
- break;
- }
- ui_but_copy_numeric_array(but, buf, buf_max_len);
- is_buf_set = true;
- break;
-
- case UI_BTYPE_COLOR:
- if (!has_required_data) {
- break;
- }
- ui_but_copy_color(but, buf, buf_max_len);
- is_buf_set = true;
- break;
-
- case UI_BTYPE_TEXT:
- case UI_BTYPE_SEARCH_MENU:
- if (!has_required_data) {
- break;
- }
- ui_but_copy_text(but, buf, buf_max_len);
- is_buf_set = true;
- break;
-
- case UI_BTYPE_COLORBAND:
- ui_but_copy_colorband(but);
- break;
-
- case UI_BTYPE_CURVE:
- ui_but_copy_curvemapping(but);
- break;
-
- case UI_BTYPE_BUT:
- ui_but_copy_operator(C, but, buf, buf_max_len);
- is_buf_set = true;
- break;
-
- case UI_BTYPE_MENU:
- case UI_BTYPE_PULLDOWN:
- if (ui_but_copy_menu(but, buf, buf_max_len)) {
- is_buf_set = true;
- }
- break;
- case UI_BTYPE_POPOVER:
- if (ui_but_copy_popover(but, buf, buf_max_len)) {
- is_buf_set = true;
- }
- break;
-
- default:
- break;
- }
-
- if (is_buf_set) {
- WM_clipboard_text_set(buf, 0);
- }
+ if (ui_but_contains_password(but)) {
+ return;
+ }
+
+ /* Arbitrary large value (allow for paths: 'PATH_MAX') */
+ char buf[4096] = {0};
+ const int buf_max_len = sizeof(buf);
+
+ /* Left false for copying internal data (color-band for eg). */
+ bool is_buf_set = false;
+
+ bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL);
+
+ switch (but->type) {
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_NUM_SLIDER:
+ if (!has_required_data) {
+ break;
+ }
+ if (copy_array && ui_but_has_array_value(but)) {
+ ui_but_copy_numeric_array(but, buf, buf_max_len);
+ }
+ else {
+ ui_but_copy_numeric_value(but, buf, buf_max_len);
+ }
+ is_buf_set = true;
+ break;
+
+ case UI_BTYPE_UNITVEC:
+ if (!has_required_data) {
+ break;
+ }
+ ui_but_copy_numeric_array(but, buf, buf_max_len);
+ is_buf_set = true;
+ break;
+
+ case UI_BTYPE_COLOR:
+ if (!has_required_data) {
+ break;
+ }
+ ui_but_copy_color(but, buf, buf_max_len);
+ is_buf_set = true;
+ break;
+
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU:
+ if (!has_required_data) {
+ break;
+ }
+ ui_but_copy_text(but, buf, buf_max_len);
+ is_buf_set = true;
+ break;
+
+ case UI_BTYPE_COLORBAND:
+ ui_but_copy_colorband(but);
+ break;
+
+ case UI_BTYPE_CURVE:
+ ui_but_copy_curvemapping(but);
+ break;
+
+ case UI_BTYPE_BUT:
+ ui_but_copy_operator(C, but, buf, buf_max_len);
+ is_buf_set = true;
+ break;
+
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_PULLDOWN:
+ if (ui_but_copy_menu(but, buf, buf_max_len)) {
+ is_buf_set = true;
+ }
+ break;
+ case UI_BTYPE_POPOVER:
+ if (ui_but_copy_popover(but, buf, buf_max_len)) {
+ is_buf_set = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (is_buf_set) {
+ WM_clipboard_text_set(buf, 0);
+ }
}
static void ui_but_paste(bContext *C, uiBut *but, uiHandleButtonData *data, const bool paste_array)
{
- BLI_assert((but->flag & UI_BUT_DISABLED) == 0); /* caller should check */
-
- int buf_paste_len = 0;
- char *buf_paste;
- ui_but_get_pasted_text_from_clipboard(&buf_paste, &buf_paste_len);
-
- bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL);
-
- switch (but->type) {
- case UI_BTYPE_NUM:
- case UI_BTYPE_NUM_SLIDER:
- if (!has_required_data) {
- break;
- }
- if (paste_array && ui_but_has_array_value(but)) {
- ui_but_paste_numeric_array(C, but, data, buf_paste);
- }
- else {
- ui_but_paste_numeric_value(C, but, data, buf_paste);
- }
- break;
-
- case UI_BTYPE_UNITVEC:
- if (!has_required_data) {
- break;
- }
- ui_but_paste_normalized_vector(C, but, buf_paste);
- break;
-
- case UI_BTYPE_COLOR:
- if (!has_required_data) {
- break;
- }
- ui_but_paste_color(C, but, buf_paste);
- break;
-
- case UI_BTYPE_TEXT:
- case UI_BTYPE_SEARCH_MENU:
- if (!has_required_data) {
- break;
- }
- ui_but_paste_text(C, but, data, buf_paste);
- break;
-
- case UI_BTYPE_COLORBAND:
- ui_but_paste_colorband(C, but, data);
- break;
-
- case UI_BTYPE_CURVE:
- ui_but_paste_curvemapping(C, but);
- break;
-
- default:
- break;
- }
-
- MEM_freeN((void *)buf_paste);
+ BLI_assert((but->flag & UI_BUT_DISABLED) == 0); /* caller should check */
+
+ int buf_paste_len = 0;
+ char *buf_paste;
+ ui_but_get_pasted_text_from_clipboard(&buf_paste, &buf_paste_len);
+
+ bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL);
+
+ switch (but->type) {
+ case UI_BTYPE_NUM:
+ case UI_BTYPE_NUM_SLIDER:
+ if (!has_required_data) {
+ break;
+ }
+ if (paste_array && ui_but_has_array_value(but)) {
+ ui_but_paste_numeric_array(C, but, data, buf_paste);
+ }
+ else {
+ ui_but_paste_numeric_value(C, but, data, buf_paste);
+ }
+ break;
+
+ case UI_BTYPE_UNITVEC:
+ if (!has_required_data) {
+ break;
+ }
+ ui_but_paste_normalized_vector(C, but, buf_paste);
+ break;
+
+ case UI_BTYPE_COLOR:
+ if (!has_required_data) {
+ break;
+ }
+ ui_but_paste_color(C, but, buf_paste);
+ break;
+
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU:
+ if (!has_required_data) {
+ break;
+ }
+ ui_but_paste_text(C, but, data, buf_paste);
+ break;
+
+ case UI_BTYPE_COLORBAND:
+ ui_but_paste_colorband(C, but, data);
+ break;
+
+ case UI_BTYPE_CURVE:
+ ui_but_paste_curvemapping(C, but);
+ break;
+
+ default:
+ break;
+ }
+
+ MEM_freeN((void *)buf_paste);
}
void ui_but_clipboard_free(void)
{
- curvemapping_free_data(&but_copypaste_curve);
+ curvemapping_free_data(&but_copypaste_curve);
}
/** \} */
@@ -2550,61 +2547,63 @@ void ui_but_clipboard_free(void)
static int ui_text_position_from_hidden(uiBut *but, int pos)
{
- const char *strpos, *butstr;
- int i;
+ const char *strpos, *butstr;
+ int i;
- butstr = (but->editstr) ? but->editstr : but->drawstr;
+ butstr = (but->editstr) ? but->editstr : but->drawstr;
- for (i = 0, strpos = butstr; i < pos; i++) {
- strpos = BLI_str_find_next_char_utf8(strpos, NULL);
- }
+ for (i = 0, strpos = butstr; i < pos; i++) {
+ strpos = BLI_str_find_next_char_utf8(strpos, NULL);
+ }
- return (strpos - butstr);
+ return (strpos - butstr);
}
static int ui_text_position_to_hidden(uiBut *but, int pos)
{
- const char *butstr = (but->editstr) ? but->editstr : but->drawstr;
- return BLI_strnlen_utf8(butstr, pos);
+ const char *butstr = (but->editstr) ? but->editstr : but->drawstr;
+ return BLI_strnlen_utf8(butstr, pos);
}
-void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *but, const bool restore)
+void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR],
+ uiBut *but,
+ const bool restore)
{
- char *butstr;
+ char *butstr;
- if (!(but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) {
- return;
- }
+ if (!(but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) {
+ return;
+ }
- butstr = (but->editstr) ? but->editstr : but->drawstr;
+ butstr = (but->editstr) ? but->editstr : but->drawstr;
- if (restore) {
- /* restore original string */
- BLI_strncpy(butstr, password_str, UI_MAX_PASSWORD_STR);
+ if (restore) {
+ /* restore original string */
+ BLI_strncpy(butstr, password_str, UI_MAX_PASSWORD_STR);
- /* remap cursor positions */
- if (but->pos >= 0) {
- but->pos = ui_text_position_from_hidden(but, but->pos);
- but->selsta = ui_text_position_from_hidden(but, but->selsta);
- but->selend = ui_text_position_from_hidden(but, but->selend);
- }
- }
- else {
- /* convert text to hidden text using asterisks (e.g. pass -> ****) */
- const size_t len = BLI_strlen_utf8(butstr);
+ /* remap cursor positions */
+ if (but->pos >= 0) {
+ but->pos = ui_text_position_from_hidden(but, but->pos);
+ but->selsta = ui_text_position_from_hidden(but, but->selsta);
+ but->selend = ui_text_position_from_hidden(but, but->selend);
+ }
+ }
+ else {
+ /* convert text to hidden text using asterisks (e.g. pass -> ****) */
+ const size_t len = BLI_strlen_utf8(butstr);
- /* remap cursor positions */
- if (but->pos >= 0) {
- but->pos = ui_text_position_to_hidden(but, but->pos);
- but->selsta = ui_text_position_to_hidden(but, but->selsta);
- but->selend = ui_text_position_to_hidden(but, but->selend);
- }
+ /* remap cursor positions */
+ if (but->pos >= 0) {
+ but->pos = ui_text_position_to_hidden(but, but->pos);
+ but->selsta = ui_text_position_to_hidden(but, but->selsta);
+ but->selend = ui_text_position_to_hidden(but, but->selend);
+ }
- /* save original string */
- BLI_strncpy(password_str, butstr, UI_MAX_PASSWORD_STR);
- memset(butstr, '*', len);
- butstr[len] = '\0';
- }
+ /* save original string */
+ BLI_strncpy(password_str, butstr, UI_MAX_PASSWORD_STR);
+ memset(butstr, '*', len);
+ butstr[len] = '\0';
+ }
}
/** \} */
@@ -2615,54 +2614,53 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *bu
static void ui_textedit_string_clear_and_exit(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- /* most likely NULL, but let's check, and give it temp zero string */
- if (!data->str) {
- data->str = MEM_callocN(1, "temp str");
- }
- data->str[0] = 0;
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (!data->str) {
+ data->str = MEM_callocN(1, "temp str");
+ }
+ data->str[0] = 0;
- ui_apply_but_TEX(C, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
}
static void ui_textedit_string_ensure_max_length(uiBut *but, uiHandleButtonData *data, int maxlen)
{
- BLI_assert(data->is_str_dynamic);
- BLI_assert(data->str == but->editstr);
+ BLI_assert(data->is_str_dynamic);
+ BLI_assert(data->str == but->editstr);
- if (maxlen > data->maxlen) {
- data->str = but->editstr = MEM_reallocN(data->str, sizeof(char) * maxlen);
- data->maxlen = maxlen;
- }
+ if (maxlen > data->maxlen) {
+ data->str = but->editstr = MEM_reallocN(data->str, sizeof(char) * maxlen);
+ data->maxlen = maxlen;
+ }
}
static void ui_textedit_string_set(uiBut *but, uiHandleButtonData *data, const char *str)
{
- if (data->is_str_dynamic) {
- ui_textedit_string_ensure_max_length(but, data, strlen(str) + 1);
- }
+ if (data->is_str_dynamic) {
+ ui_textedit_string_ensure_max_length(but, data, strlen(str) + 1);
+ }
- if (ui_but_is_utf8(but)) {
- BLI_strncpy_utf8(data->str, str, data->maxlen);
- }
- else {
- BLI_strncpy(data->str, str, data->maxlen);
- }
+ if (ui_but_is_utf8(but)) {
+ BLI_strncpy_utf8(data->str, str, data->maxlen);
+ }
+ else {
+ BLI_strncpy(data->str, str, data->maxlen);
+ }
}
-
static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
{
- char *str = data->str;
- const int len = strlen(str);
- bool changed = false;
- if (but->selsta != but->selend && len) {
- memmove(str + but->selsta, str + but->selend, (len - but->selend) + 1);
- changed = true;
- }
+ char *str = data->str;
+ const int len = strlen(str);
+ bool changed = false;
+ if (but->selsta != but->selend && len) {
+ memmove(str + but->selsta, str + but->selend, (len - but->selend) + 1);
+ changed = true;
+ }
- but->pos = but->selend = but->selsta;
- return changed;
+ but->pos = but->selend = but->selsta;
+ return changed;
}
/**
@@ -2672,123 +2670,131 @@ static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data)
*/
static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, const float x)
{
- uiStyle *style = UI_style_get(); // XXX pass on as arg
- uiFontStyle *fstyle = &style->widget;
- const float aspect = but->block->aspect;
- const short fstyle_points_prev = fstyle->points;
-
- float startx = but->rect.xmin;
- float starty_dummy = 0.0f;
- char password_str[UI_MAX_PASSWORD_STR];
- /* treat 'str_last' as null terminator for str, no need to modify in-place */
- const char *str = but->editstr, *str_last;
-
- ui_block_to_window_fl(data->region, but->block, &startx, &starty_dummy);
-
- ui_fontscale(&fstyle->points, aspect);
-
- UI_fontstyle_set(fstyle);
-
- if (fstyle->kerning == 1) {
- /* for BLF_width */
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- ui_but_text_password_hide(password_str, but, false);
-
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- if (but->flag & UI_HAS_ICON) {
- startx += UI_DPI_ICON_SIZE / aspect;
- }
- }
- /* but this extra .05 makes clicks inbetween characters feel nicer */
- startx += ((UI_TEXT_MARGIN_X + 0.05f) * U.widget_unit) / aspect;
-
- /* mouse dragged outside the widget to the left */
- if (x < startx) {
- int i = but->ofs;
-
- str_last = &str[but->ofs];
-
- while (i > 0) {
- if (BLI_str_cursor_step_prev_utf8(str, but->ofs, &i)) {
- /* 0.25 == scale factor for less sensitivity */
- if (BLF_width(fstyle->uifont_id, str + i, (str_last - str) - i) > (startx - x) * 0.25f) {
- break;
- }
- }
- else {
- break; /* unlikely but possible */
- }
- }
- but->ofs = i;
- but->pos = but->ofs;
- }
- /* mouse inside the widget, mouse coords mapped in widget space */
- else { /* (x >= startx) */
- int pos_i;
-
- /* keep track of previous distance from the cursor to the char */
- float cdist, cdist_prev = 0.0f;
- short pos_prev;
-
- str_last = &str[strlen(str)];
-
- but->pos = pos_prev = ((str_last - str) - but->ofs);
-
- while (true) {
- cdist = startx + BLF_width(fstyle->uifont_id, str + but->ofs, (str_last - str) - but->ofs);
-
- /* check if position is found */
- if (cdist < x) {
- /* check is previous location was in fact closer */
- if ((x - cdist) > (cdist_prev - x)) {
- but->pos = pos_prev;
- }
- break;
- }
- cdist_prev = cdist;
- pos_prev = but->pos;
- /* done with tricky distance checks */
-
- pos_i = but->pos;
- if (but->pos <= 0) {
- break;
- }
- if (BLI_str_cursor_step_prev_utf8(str, but->ofs, &pos_i)) {
- but->pos = pos_i;
- str_last = &str[but->pos + but->ofs];
- }
- else {
- break; /* unlikely but possible */
- }
- }
- but->pos += but->ofs;
- if (but->pos < 0) {
- but->pos = 0;
- }
- }
-
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- ui_but_text_password_hide(password_str, but, true);
-
- fstyle->points = fstyle_points_prev;
+ uiStyle *style = UI_style_get(); // XXX pass on as arg
+ uiFontStyle *fstyle = &style->widget;
+ const float aspect = but->block->aspect;
+ const short fstyle_points_prev = fstyle->points;
+
+ float startx = but->rect.xmin;
+ float starty_dummy = 0.0f;
+ char password_str[UI_MAX_PASSWORD_STR];
+ /* treat 'str_last' as null terminator for str, no need to modify in-place */
+ const char *str = but->editstr, *str_last;
+
+ ui_block_to_window_fl(data->region, but->block, &startx, &starty_dummy);
+
+ ui_fontscale(&fstyle->points, aspect);
+
+ UI_fontstyle_set(fstyle);
+
+ if (fstyle->kerning == 1) {
+ /* for BLF_width */
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ ui_but_text_password_hide(password_str, but, false);
+
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ if (but->flag & UI_HAS_ICON) {
+ startx += UI_DPI_ICON_SIZE / aspect;
+ }
+ }
+ /* but this extra .05 makes clicks inbetween characters feel nicer */
+ startx += ((UI_TEXT_MARGIN_X + 0.05f) * U.widget_unit) / aspect;
+
+ /* mouse dragged outside the widget to the left */
+ if (x < startx) {
+ int i = but->ofs;
+
+ str_last = &str[but->ofs];
+
+ while (i > 0) {
+ if (BLI_str_cursor_step_prev_utf8(str, but->ofs, &i)) {
+ /* 0.25 == scale factor for less sensitivity */
+ if (BLF_width(fstyle->uifont_id, str + i, (str_last - str) - i) > (startx - x) * 0.25f) {
+ break;
+ }
+ }
+ else {
+ break; /* unlikely but possible */
+ }
+ }
+ but->ofs = i;
+ but->pos = but->ofs;
+ }
+ /* mouse inside the widget, mouse coords mapped in widget space */
+ else { /* (x >= startx) */
+ int pos_i;
+
+ /* keep track of previous distance from the cursor to the char */
+ float cdist, cdist_prev = 0.0f;
+ short pos_prev;
+
+ str_last = &str[strlen(str)];
+
+ but->pos = pos_prev = ((str_last - str) - but->ofs);
+
+ while (true) {
+ cdist = startx + BLF_width(fstyle->uifont_id, str + but->ofs, (str_last - str) - but->ofs);
+
+ /* check if position is found */
+ if (cdist < x) {
+ /* check is previous location was in fact closer */
+ if ((x - cdist) > (cdist_prev - x)) {
+ but->pos = pos_prev;
+ }
+ break;
+ }
+ cdist_prev = cdist;
+ pos_prev = but->pos;
+ /* done with tricky distance checks */
+
+ pos_i = but->pos;
+ if (but->pos <= 0) {
+ break;
+ }
+ if (BLI_str_cursor_step_prev_utf8(str, but->ofs, &pos_i)) {
+ but->pos = pos_i;
+ str_last = &str[but->pos + but->ofs];
+ }
+ else {
+ break; /* unlikely but possible */
+ }
+ }
+ but->pos += but->ofs;
+ if (but->pos < 0) {
+ but->pos = 0;
+ }
+ }
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ ui_but_text_password_hide(password_str, but, true);
+
+ fstyle->points = fstyle_points_prev;
}
static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, const float x)
{
- if (x > data->selstartx) { data->selextend = EXTEND_RIGHT; }
- else if (x < data->selstartx) { data->selextend = EXTEND_LEFT; }
+ if (x > data->selstartx) {
+ data->selextend = EXTEND_RIGHT;
+ }
+ else if (x < data->selstartx) {
+ data->selextend = EXTEND_LEFT;
+ }
- ui_textedit_set_cursor_pos(but, data, x);
+ ui_textedit_set_cursor_pos(but, data, x);
- if (data->selextend == EXTEND_RIGHT) { but->selend = but->pos; }
- else if (data->selextend == EXTEND_LEFT) { but->selsta = but->pos; }
+ if (data->selextend == EXTEND_RIGHT) {
+ but->selend = but->pos;
+ }
+ else if (data->selextend == EXTEND_LEFT) {
+ but->selsta = but->pos;
+ }
- ui_but_update(but);
+ ui_but_update(but);
}
/**
@@ -2796,841 +2802,839 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data,
*
* For unicode buttons, \a buf is treated as unicode.
*/
-static bool ui_textedit_insert_buf(
- uiBut *but, uiHandleButtonData *data,
- const char *buf, int buf_len)
-{
- int len = strlen(data->str);
- int len_new = len - (but->selend - but->selsta) + 1;
- bool changed = false;
-
- if (data->is_str_dynamic) {
- ui_textedit_string_ensure_max_length(but, data, len_new + buf_len);
- }
-
- if (len_new <= data->maxlen) {
- char *str = data->str;
- size_t step = buf_len;
-
- /* type over the current selection */
- if ((but->selend - but->selsta) > 0) {
- changed = ui_textedit_delete_selection(but, data);
- len = strlen(str);
- }
-
- if ((len + step >= data->maxlen) && (data->maxlen - (len + 1) > 0)) {
- if (ui_but_is_utf8(but)) {
- /* shorten 'step' to a utf8 aligned size that fits */
- BLI_strnlen_utf8_ex(buf, data->maxlen - (len + 1), &step);
- }
- else {
- step = data->maxlen - (len + 1);
- }
- }
-
- if (step && (len + step < data->maxlen)) {
- memmove(&str[but->pos + step], &str[but->pos], (len + 1) - but->pos);
- memcpy(&str[but->pos], buf, step * sizeof(char));
- but->pos += step;
- changed = true;
- }
- }
-
- return changed;
+static bool ui_textedit_insert_buf(uiBut *but,
+ uiHandleButtonData *data,
+ const char *buf,
+ int buf_len)
+{
+ int len = strlen(data->str);
+ int len_new = len - (but->selend - but->selsta) + 1;
+ bool changed = false;
+
+ if (data->is_str_dynamic) {
+ ui_textedit_string_ensure_max_length(but, data, len_new + buf_len);
+ }
+
+ if (len_new <= data->maxlen) {
+ char *str = data->str;
+ size_t step = buf_len;
+
+ /* type over the current selection */
+ if ((but->selend - but->selsta) > 0) {
+ changed = ui_textedit_delete_selection(but, data);
+ len = strlen(str);
+ }
+
+ if ((len + step >= data->maxlen) && (data->maxlen - (len + 1) > 0)) {
+ if (ui_but_is_utf8(but)) {
+ /* shorten 'step' to a utf8 aligned size that fits */
+ BLI_strnlen_utf8_ex(buf, data->maxlen - (len + 1), &step);
+ }
+ else {
+ step = data->maxlen - (len + 1);
+ }
+ }
+
+ if (step && (len + step < data->maxlen)) {
+ memmove(&str[but->pos + step], &str[but->pos], (len + 1) - but->pos);
+ memcpy(&str[but->pos], buf, step * sizeof(char));
+ but->pos += step;
+ changed = true;
+ }
+ }
+
+ return changed;
}
static bool ui_textedit_insert_ascii(uiBut *but, uiHandleButtonData *data, char ascii)
{
- char buf[2] = {ascii, '\0'};
-
- if (ui_but_is_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
- printf("%s: entering invalid ascii char into an ascii key (%d)\n",
- __func__, (int)(uchar)ascii);
-
- return false;
- }
-
- /* in some cases we want to allow invalid utf8 chars */
- return ui_textedit_insert_buf(but, data, buf, 1);
-}
-
-static void ui_textedit_move(
- uiBut *but, uiHandleButtonData *data, eStrCursorJumpDirection direction,
- const bool select, eStrCursorJumpType jump)
-{
- const char *str = data->str;
- const int len = strlen(str);
- const int pos_prev = but->pos;
- const bool has_sel = (but->selend - but->selsta) > 0;
-
- ui_but_update(but);
-
- /* special case, quit selection and set cursor */
- if (has_sel && !select) {
- if (jump == STRCUR_JUMP_ALL) {
- but->selsta = but->selend = but->pos = direction ? len : 0;
- }
- else {
- if (direction) {
- but->selsta = but->pos = but->selend;
- }
- else {
- but->pos = but->selend = but->selsta;
- }
- }
- data->selextend = EXTEND_NONE;
- }
- else {
- int pos_i = but->pos;
- BLI_str_cursor_step_utf8(str, len, &pos_i, direction, jump, true);
- but->pos = pos_i;
-
- if (select) {
- /* existing selection */
- if (has_sel) {
-
- if (data->selextend == EXTEND_NONE) {
- data->selextend = EXTEND_RIGHT;
- }
-
- if (direction) {
- if (data->selextend == EXTEND_RIGHT) {
- but->selend = but->pos;
- }
- else {
- but->selsta = but->pos;
- }
- }
- else {
- if (data->selextend == EXTEND_LEFT) {
- but->selsta = but->pos;
- }
- else {
- but->selend = but->pos;
- }
- }
-
- if (but->selend < but->selsta) {
- SWAP(short, but->selsta, but->selend);
- data->selextend = (data->selextend == EXTEND_RIGHT) ? EXTEND_LEFT : EXTEND_RIGHT;
- }
-
- } /* new selection */
- else {
- if (direction) {
- data->selextend = EXTEND_RIGHT;
- but->selend = but->pos;
- but->selsta = pos_prev;
- }
- else {
- data->selextend = EXTEND_LEFT;
- but->selend = pos_prev;
- but->selsta = but->pos;
- }
- }
- }
- }
-}
-
-static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, eStrCursorJumpType jump)
-{
- char *str = data->str;
- const int len = strlen(str);
-
- bool changed = false;
-
- if (jump == STRCUR_JUMP_ALL) {
- if (len) {
- changed = true;
- }
- str[0] = '\0';
- but->pos = 0;
- }
- else if (direction) { /* delete */
- if ((but->selend - but->selsta) > 0) {
- changed = ui_textedit_delete_selection(but, data);
- }
- else if (but->pos >= 0 && but->pos < len) {
- int pos = but->pos;
- int step;
- BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
- step = pos - but->pos;
- memmove(&str[but->pos], &str[but->pos + step], (len + 1) - (but->pos + step));
- changed = true;
- }
- }
- else { /* backspace */
- if (len != 0) {
- if ((but->selend - but->selsta) > 0) {
- changed = ui_textedit_delete_selection(but, data);
- }
- else if (but->pos > 0) {
- int pos = but->pos;
- int step;
-
- BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
- step = but->pos - pos;
- memmove(&str[but->pos - step], &str[but->pos], (len + 1) - but->pos);
- but->pos -= step;
- changed = true;
- }
- }
- }
-
- return changed;
+ char buf[2] = {ascii, '\0'};
+
+ if (ui_but_is_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
+ printf(
+ "%s: entering invalid ascii char into an ascii key (%d)\n", __func__, (int)(uchar)ascii);
+
+ return false;
+ }
+
+ /* in some cases we want to allow invalid utf8 chars */
+ return ui_textedit_insert_buf(but, data, buf, 1);
+}
+
+static void ui_textedit_move(uiBut *but,
+ uiHandleButtonData *data,
+ eStrCursorJumpDirection direction,
+ const bool select,
+ eStrCursorJumpType jump)
+{
+ const char *str = data->str;
+ const int len = strlen(str);
+ const int pos_prev = but->pos;
+ const bool has_sel = (but->selend - but->selsta) > 0;
+
+ ui_but_update(but);
+
+ /* special case, quit selection and set cursor */
+ if (has_sel && !select) {
+ if (jump == STRCUR_JUMP_ALL) {
+ but->selsta = but->selend = but->pos = direction ? len : 0;
+ }
+ else {
+ if (direction) {
+ but->selsta = but->pos = but->selend;
+ }
+ else {
+ but->pos = but->selend = but->selsta;
+ }
+ }
+ data->selextend = EXTEND_NONE;
+ }
+ else {
+ int pos_i = but->pos;
+ BLI_str_cursor_step_utf8(str, len, &pos_i, direction, jump, true);
+ but->pos = pos_i;
+
+ if (select) {
+ /* existing selection */
+ if (has_sel) {
+
+ if (data->selextend == EXTEND_NONE) {
+ data->selextend = EXTEND_RIGHT;
+ }
+
+ if (direction) {
+ if (data->selextend == EXTEND_RIGHT) {
+ but->selend = but->pos;
+ }
+ else {
+ but->selsta = but->pos;
+ }
+ }
+ else {
+ if (data->selextend == EXTEND_LEFT) {
+ but->selsta = but->pos;
+ }
+ else {
+ but->selend = but->pos;
+ }
+ }
+
+ if (but->selend < but->selsta) {
+ SWAP(short, but->selsta, but->selend);
+ data->selextend = (data->selextend == EXTEND_RIGHT) ? EXTEND_LEFT : EXTEND_RIGHT;
+ }
+
+ } /* new selection */
+ else {
+ if (direction) {
+ data->selextend = EXTEND_RIGHT;
+ but->selend = but->pos;
+ but->selsta = pos_prev;
+ }
+ else {
+ data->selextend = EXTEND_LEFT;
+ but->selend = pos_prev;
+ but->selsta = but->pos;
+ }
+ }
+ }
+ }
+}
+
+static bool ui_textedit_delete(uiBut *but,
+ uiHandleButtonData *data,
+ int direction,
+ eStrCursorJumpType jump)
+{
+ char *str = data->str;
+ const int len = strlen(str);
+
+ bool changed = false;
+
+ if (jump == STRCUR_JUMP_ALL) {
+ if (len) {
+ changed = true;
+ }
+ str[0] = '\0';
+ but->pos = 0;
+ }
+ else if (direction) { /* delete */
+ if ((but->selend - but->selsta) > 0) {
+ changed = ui_textedit_delete_selection(but, data);
+ }
+ else if (but->pos >= 0 && but->pos < len) {
+ int pos = but->pos;
+ int step;
+ BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
+ step = pos - but->pos;
+ memmove(&str[but->pos], &str[but->pos + step], (len + 1) - (but->pos + step));
+ changed = true;
+ }
+ }
+ else { /* backspace */
+ if (len != 0) {
+ if ((but->selend - but->selsta) > 0) {
+ changed = ui_textedit_delete_selection(but, data);
+ }
+ else if (but->pos > 0) {
+ int pos = but->pos;
+ int step;
+
+ BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true);
+ step = but->pos - pos;
+ memmove(&str[but->pos - step], &str[but->pos], (len + 1) - but->pos);
+ but->pos -= step;
+ changed = true;
+ }
+ }
+ }
+
+ return changed;
}
static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- char *str;
- int changed;
+ char *str;
+ int changed;
- str = data->str;
+ str = data->str;
- if (data->searchbox) {
- changed = ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
- }
- else {
- changed = but->autocomplete_func(C, str, but->autofunc_arg);
- }
+ if (data->searchbox) {
+ changed = ui_searchbox_autocomplete(C, data->searchbox, but, data->str);
+ }
+ else {
+ changed = but->autocomplete_func(C, str, but->autofunc_arg);
+ }
- but->pos = strlen(str);
- but->selsta = but->selend = but->pos;
+ but->pos = strlen(str);
+ but->selsta = but->selend = but->pos;
- return changed;
+ return changed;
}
/* mode for ui_textedit_copypaste() */
enum {
- UI_TEXTEDIT_PASTE = 1,
- UI_TEXTEDIT_COPY,
- UI_TEXTEDIT_CUT,
+ UI_TEXTEDIT_PASTE = 1,
+ UI_TEXTEDIT_COPY,
+ UI_TEXTEDIT_CUT,
};
static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const int mode)
{
- char *pbuf;
- bool changed = false;
- int buf_len;
+ char *pbuf;
+ bool changed = false;
+ int buf_len;
- /* paste */
- if (mode == UI_TEXTEDIT_PASTE) {
- /* extract the first line from the clipboard */
- pbuf = WM_clipboard_text_get_firstline(false, &buf_len);
+ /* paste */
+ if (mode == UI_TEXTEDIT_PASTE) {
+ /* extract the first line from the clipboard */
+ pbuf = WM_clipboard_text_get_firstline(false, &buf_len);
- if (pbuf) {
- if (ui_but_is_utf8(but)) {
- buf_len -= BLI_utf8_invalid_strip(pbuf, (size_t)buf_len);
- }
+ if (pbuf) {
+ if (ui_but_is_utf8(but)) {
+ buf_len -= BLI_utf8_invalid_strip(pbuf, (size_t)buf_len);
+ }
- ui_textedit_insert_buf(but, data, pbuf, buf_len);
+ ui_textedit_insert_buf(but, data, pbuf, buf_len);
- changed = true;
+ changed = true;
- MEM_freeN(pbuf);
- }
- }
- /* cut & copy */
- else if (ELEM(mode, UI_TEXTEDIT_COPY, UI_TEXTEDIT_CUT)) {
- /* copy the contents to the copypaste buffer */
- int sellen = but->selend - but->selsta;
- char *buf = MEM_mallocN(sizeof(char) * (sellen + 1), "ui_textedit_copypaste");
+ MEM_freeN(pbuf);
+ }
+ }
+ /* cut & copy */
+ else if (ELEM(mode, UI_TEXTEDIT_COPY, UI_TEXTEDIT_CUT)) {
+ /* copy the contents to the copypaste buffer */
+ int sellen = but->selend - but->selsta;
+ char *buf = MEM_mallocN(sizeof(char) * (sellen + 1), "ui_textedit_copypaste");
- BLI_strncpy(buf, data->str + but->selsta, sellen + 1);
- WM_clipboard_text_set(buf, 0);
- MEM_freeN(buf);
+ BLI_strncpy(buf, data->str + but->selsta, sellen + 1);
+ WM_clipboard_text_set(buf, 0);
+ MEM_freeN(buf);
- /* for cut only, delete the selection afterwards */
- if (mode == UI_TEXTEDIT_CUT) {
- if ((but->selend - but->selsta) > 0) {
- changed = ui_textedit_delete_selection(but, data);
- }
- }
- }
+ /* for cut only, delete the selection afterwards */
+ if (mode == UI_TEXTEDIT_CUT) {
+ if ((but->selend - but->selsta) > 0) {
+ changed = ui_textedit_delete_selection(but, data);
+ }
+ }
+ }
- return changed;
+ return changed;
}
#ifdef WITH_INPUT_IME
/* enable ime, and set up uibut ime data */
static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but))
{
- /* XXX Is this really needed? */
- int x, y;
+ /* XXX Is this really needed? */
+ int x, y;
- BLI_assert(win->ime_data == NULL);
+ BLI_assert(win->ime_data == NULL);
- /* enable IME and position to cursor, it's a trick */
- x = win->eventstate->x;
- /* flip y and move down a bit, prevent the IME panel cover the edit button */
- y = win->eventstate->y - 12;
+ /* enable IME and position to cursor, it's a trick */
+ x = win->eventstate->x;
+ /* flip y and move down a bit, prevent the IME panel cover the edit button */
+ y = win->eventstate->y - 12;
- wm_window_IME_begin(win, x, y, 0, 0, true);
+ wm_window_IME_begin(win, x, y, 0, 0, true);
}
/* disable ime, and clear uibut ime data */
static void ui_textedit_ime_end(wmWindow *win, uiBut *UNUSED(but))
{
- wm_window_IME_end(win);
+ wm_window_IME_end(win);
}
void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete)
{
- BLI_assert(but->active);
+ BLI_assert(but->active);
- ui_region_to_window(but->active->region, &x, &y);
- wm_window_IME_begin(but->active->window, x, y - 4, 0, 0, complete);
+ ui_region_to_window(but->active->region, &x, &y);
+ wm_window_IME_begin(but->active->window, x, y - 4, 0, 0, complete);
}
wmIMEData *ui_but_ime_data_get(uiBut *but)
{
- if (but->active && but->active->window) {
- return but->active->window->ime_data;
- }
- else {
- return NULL;
- }
+ if (but->active && but->active->window) {
+ return but->active->window->ime_data;
+ }
+ else {
+ return NULL;
+ }
}
-#endif /* WITH_INPUT_IME */
+#endif /* WITH_INPUT_IME */
static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- wmWindow *win = CTX_wm_window(C);
- int len;
- const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER);
- bool no_zero_strip = false;
+ wmWindow *win = CTX_wm_window(C);
+ int len;
+ const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER);
+ bool no_zero_strip = false;
- if (data->str) {
- MEM_freeN(data->str);
- data->str = NULL;
- }
+ if (data->str) {
+ MEM_freeN(data->str);
+ data->str = NULL;
+ }
#ifdef USE_DRAG_MULTINUM
- /* this can happen from multi-drag */
- if (data->applied_interactive) {
- /* remove any small changes so canceling edit doesn't restore invalid value: T40538 */
- data->cancel = true;
- ui_apply_but(C, but->block, but, data, true);
- data->cancel = false;
-
- data->applied_interactive = false;
- }
+ /* this can happen from multi-drag */
+ if (data->applied_interactive) {
+ /* remove any small changes so canceling edit doesn't restore invalid value: T40538 */
+ data->cancel = true;
+ ui_apply_but(C, but->block, but, data, true);
+ data->cancel = false;
+
+ data->applied_interactive = false;
+ }
#endif
#ifdef USE_ALLSELECT
- if (is_num_but) {
- if (IS_ALLSELECT_EVENT(win->eventstate)) {
- data->select_others.is_enabled = true;
- data->select_others.is_copy = true;
-
- }
- }
+ if (is_num_but) {
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ data->select_others.is_copy = true;
+ }
+ }
#endif
- /* retrieve string */
- data->maxlen = ui_but_string_get_max_length(but);
- if (data->maxlen != 0) {
- data->str = MEM_callocN(sizeof(char) * data->maxlen, "textedit str");
- /* We do not want to truncate precision to default here, it's nice to show value,
- * not to edit it - way too much precision is lost then. */
- ui_but_string_get_ex(but, data->str, data->maxlen, UI_PRECISION_FLOAT_MAX, true, &no_zero_strip);
- }
- else {
- data->is_str_dynamic = true;
- data->str = ui_but_string_get_dynamic(but, &data->maxlen);
- }
-
- if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0) && !no_zero_strip) {
- BLI_str_rstrip_float_zero(data->str, '\0');
- }
-
- if (is_num_but) {
- BLI_assert(data->is_str_dynamic == false);
- ui_but_convert_to_unit_alt_name(but, data->str, data->maxlen);
- }
-
- /* won't change from now on */
- len = strlen(data->str);
-
- data->origstr = BLI_strdupn(data->str, len);
- data->selextend = EXTEND_NONE;
- data->selstartx = 0.0f;
-
- /* set cursor pos to the end of the text */
- but->editstr = data->str;
- but->pos = len;
- but->selsta = 0;
- but->selend = len;
-
- /* optional searchbox */
- if (but->type == UI_BTYPE_SEARCH_MENU) {
- data->searchbox = but->search_create_func(C, data->region, but);
- ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
- }
-
- /* reset alert flag (avoid confusion, will refresh on exit) */
- but->flag &= ~UI_BUT_REDALERT;
-
- ui_but_update(but);
-
- WM_cursor_modal_set(win, BC_TEXTEDITCURSOR);
+ /* retrieve string */
+ data->maxlen = ui_but_string_get_max_length(but);
+ if (data->maxlen != 0) {
+ data->str = MEM_callocN(sizeof(char) * data->maxlen, "textedit str");
+ /* We do not want to truncate precision to default here, it's nice to show value,
+ * not to edit it - way too much precision is lost then. */
+ ui_but_string_get_ex(
+ but, data->str, data->maxlen, UI_PRECISION_FLOAT_MAX, true, &no_zero_strip);
+ }
+ else {
+ data->is_str_dynamic = true;
+ data->str = ui_but_string_get_dynamic(but, &data->maxlen);
+ }
+
+ if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0) &&
+ !no_zero_strip) {
+ BLI_str_rstrip_float_zero(data->str, '\0');
+ }
+
+ if (is_num_but) {
+ BLI_assert(data->is_str_dynamic == false);
+ ui_but_convert_to_unit_alt_name(but, data->str, data->maxlen);
+ }
+
+ /* won't change from now on */
+ len = strlen(data->str);
+
+ data->origstr = BLI_strdupn(data->str, len);
+ data->selextend = EXTEND_NONE;
+ data->selstartx = 0.0f;
+
+ /* set cursor pos to the end of the text */
+ but->editstr = data->str;
+ but->pos = len;
+ but->selsta = 0;
+ but->selend = len;
+
+ /* optional searchbox */
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
+ data->searchbox = but->search_create_func(C, data->region, but);
+ ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
+ }
+
+ /* reset alert flag (avoid confusion, will refresh on exit) */
+ but->flag &= ~UI_BUT_REDALERT;
+
+ ui_but_update(but);
+
+ WM_cursor_modal_set(win, BC_TEXTEDITCURSOR);
#ifdef WITH_INPUT_IME
- if (is_num_but == false && BLT_lang_is_ime_supported()) {
- ui_textedit_ime_begin(win, but);
- }
+ if (is_num_but == false && BLT_lang_is_ime_supported()) {
+ ui_textedit_ime_begin(win, but);
+ }
#endif
}
static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- wmWindow *win = CTX_wm_window(C);
+ wmWindow *win = CTX_wm_window(C);
- if (but) {
- if (ui_but_is_utf8(but)) {
- int strip = BLI_utf8_invalid_strip(but->editstr, strlen(but->editstr));
- /* not a file?, strip non utf-8 chars */
- if (strip) {
- /* wont happen often so isn't that annoying to keep it here for a while */
- printf("%s: invalid utf8 - stripped chars %d\n", __func__, strip);
- }
- }
+ if (but) {
+ if (ui_but_is_utf8(but)) {
+ int strip = BLI_utf8_invalid_strip(but->editstr, strlen(but->editstr));
+ /* not a file?, strip non utf-8 chars */
+ if (strip) {
+ /* wont happen often so isn't that annoying to keep it here for a while */
+ printf("%s: invalid utf8 - stripped chars %d\n", __func__, strip);
+ }
+ }
- if (data->searchbox) {
- if (data->cancel == false) {
- if ((ui_searchbox_apply(but, data->searchbox) == false) &&
- (ui_searchbox_find_index(data->searchbox, but->editstr) == -1))
- {
- data->cancel = true;
+ if (data->searchbox) {
+ if (data->cancel == false) {
+ if ((ui_searchbox_apply(but, data->searchbox) == false) &&
+ (ui_searchbox_find_index(data->searchbox, but->editstr) == -1)) {
+ data->cancel = true;
- /* ensure menu (popup) too is closed! */
- data->escapecancel = true;
- }
- }
+ /* ensure menu (popup) too is closed! */
+ data->escapecancel = true;
+ }
+ }
- ui_searchbox_free(C, data->searchbox);
- data->searchbox = NULL;
- }
+ ui_searchbox_free(C, data->searchbox);
+ data->searchbox = NULL;
+ }
- but->editstr = NULL;
- but->pos = -1;
- }
+ but->editstr = NULL;
+ but->pos = -1;
+ }
- WM_cursor_modal_restore(win);
+ WM_cursor_modal_restore(win);
#ifdef WITH_INPUT_IME
- if (win->ime_data) {
- ui_textedit_ime_end(win, but);
- }
+ if (win->ime_data) {
+ ui_textedit_ime_end(win, but);
+ }
#endif
}
static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data)
{
- uiBut *but;
-
- /* label and roundbox can overlap real buttons (backdrops...) */
- if (ELEM(actbut->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX)) {
- return;
- }
-
- for (but = actbut->next; but; but = but->next) {
- if (ui_but_is_editable_as_text(but)) {
- if (!(but->flag & UI_BUT_DISABLED)) {
- data->postbut = but;
- data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
- return;
- }
- }
- }
- for (but = block->buttons.first; but != actbut; but = but->next) {
- if (ui_but_is_editable_as_text(but)) {
- if (!(but->flag & UI_BUT_DISABLED)) {
- data->postbut = but;
- data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
- return;
- }
- }
- }
+ uiBut *but;
+
+ /* label and roundbox can overlap real buttons (backdrops...) */
+ if (ELEM(actbut->type,
+ UI_BTYPE_LABEL,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_ROUNDBOX,
+ UI_BTYPE_LISTBOX)) {
+ return;
+ }
+
+ for (but = actbut->next; but; but = but->next) {
+ if (ui_but_is_editable_as_text(but)) {
+ if (!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut = but;
+ data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
+ }
+ }
+ for (but = block->buttons.first; but != actbut; but = but->next) {
+ if (ui_but_is_editable_as_text(but)) {
+ if (!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut = but;
+ data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
+ }
+ }
}
static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data)
{
- uiBut *but;
-
- /* label and roundbox can overlap real buttons (backdrops...) */
- if (ELEM(actbut->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX)) {
- return;
- }
-
- for (but = actbut->prev; but; but = but->prev) {
- if (ui_but_is_editable_as_text(but)) {
- if (!(but->flag & UI_BUT_DISABLED)) {
- data->postbut = but;
- data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
- return;
- }
- }
- }
- for (but = block->buttons.last; but != actbut; but = but->prev) {
- if (ui_but_is_editable_as_text(but)) {
- if (!(but->flag & UI_BUT_DISABLED)) {
- data->postbut = but;
- data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
- return;
- }
- }
- }
+ uiBut *but;
+
+ /* label and roundbox can overlap real buttons (backdrops...) */
+ if (ELEM(actbut->type,
+ UI_BTYPE_LABEL,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_ROUNDBOX,
+ UI_BTYPE_LISTBOX)) {
+ return;
+ }
+
+ for (but = actbut->prev; but; but = but->prev) {
+ if (ui_but_is_editable_as_text(but)) {
+ if (!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut = but;
+ data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
+ }
+ }
+ for (but = block->buttons.last; but != actbut; but = but->prev) {
+ if (ui_but_is_editable_as_text(but)) {
+ if (!(but->flag & UI_BUT_DISABLED)) {
+ data->postbut = but;
+ data->posttype = BUTTON_ACTIVATE_TEXT_EDITING;
+ return;
+ }
+ }
+ }
}
-
static void ui_do_but_textedit(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
- int retval = WM_UI_HANDLER_CONTINUE;
- bool changed = false, inbox = false, update = false;
+ int retval = WM_UI_HANDLER_CONTINUE;
+ bool changed = false, inbox = false, update = false;
#ifdef WITH_INPUT_IME
- wmWindow *win = CTX_wm_window(C);
- wmIMEData *ime_data = win->ime_data;
- bool is_ime_composing = ime_data && ime_data->is_ime_composing;
+ wmWindow *win = CTX_wm_window(C);
+ wmIMEData *ime_data = win->ime_data;
+ bool is_ime_composing = ime_data && ime_data->is_ime_composing;
#else
- bool is_ime_composing = false;
+ bool is_ime_composing = false;
#endif
- switch (event->type) {
- case MOUSEMOVE:
- case MOUSEPAN:
- if (data->searchbox) {
+ switch (event->type) {
+ case MOUSEMOVE:
+ case MOUSEPAN:
+ if (data->searchbox) {
#ifdef USE_KEYNAV_LIMIT
- if ((event->type == MOUSEMOVE) && ui_mouse_motion_keynav_test(&data->searchbox_keynav_state, event)) {
- /* pass */
- }
- else {
- ui_searchbox_event(C, data->searchbox, but, event);
- }
+ if ((event->type == MOUSEMOVE) &&
+ ui_mouse_motion_keynav_test(&data->searchbox_keynav_state, event)) {
+ /* pass */
+ }
+ else {
+ ui_searchbox_event(C, data->searchbox, but, event);
+ }
#else
- ui_searchbox_event(C, data->searchbox, but, event);
+ ui_searchbox_event(C, data->searchbox, but, event);
#endif
- }
+ }
- break;
- case RIGHTMOUSE:
- case ESCKEY:
- if (event->val == KM_PRESS) {
+ break;
+ case RIGHTMOUSE:
+ case ESCKEY:
+ if (event->val == KM_PRESS) {
#ifdef WITH_INPUT_IME
- /* skips button handling since it is not wanted */
- if (is_ime_composing) {
- break;
- }
+ /* skips button handling since it is not wanted */
+ if (is_ime_composing) {
+ break;
+ }
#endif
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- }
- break;
- case LEFTMOUSE:
- {
- bool had_selection = but->selsta != but->selend;
-
- /* exit on LMB only on RELEASE for searchbox, to mimic other popups,
- * and allow multiple menu levels */
- if (data->searchbox) {
- inbox = ui_searchbox_inside(data->searchbox, event->x, event->y);
- }
-
- /* for double click: we do a press again for when you first click on button
- * (selects all text, no cursor pos) */
- if (event->val == KM_PRESS || event->val == KM_DBL_CLICK) {
- float mx, my;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block_fl(data->region, block, &mx, &my);
-
- if (ui_but_contains_pt(but, mx, my)) {
- ui_textedit_set_cursor_pos(but, data, event->x);
- but->selsta = but->selend = but->pos;
- data->selstartx = event->x;
-
- button_activate_state(C, but, BUTTON_STATE_TEXT_SELECTING);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (inbox == false) {
- /* if searchbox, click outside will cancel */
- if (data->searchbox) {
- data->cancel = data->escapecancel = true;
- }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
-
- /* only select a word in button if there was no selection before */
- if (event->val == KM_DBL_CLICK && had_selection == false) {
- ui_textedit_move(but, data, STRCUR_DIR_PREV, false, STRCUR_JUMP_DELIM);
- ui_textedit_move(but, data, STRCUR_DIR_NEXT, true, STRCUR_JUMP_DELIM);
- retval = WM_UI_HANDLER_BREAK;
- changed = true;
- }
- else if (inbox) {
- /* if we allow activation on key press,
- * it gives problems launching operators T35713. */
- if (event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- break;
- }
- }
-
- if (event->val == KM_PRESS && !is_ime_composing) {
- switch (event->type) {
- case VKEY:
- case XKEY:
- case CKEY:
- if (IS_EVENT_MOD(event, ctrl, oskey)) {
- if (event->type == VKEY) {
- changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_PASTE);
- }
- else if (event->type == CKEY) {
- changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_COPY);
- }
- else if (event->type == XKEY) {
- changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_CUT);
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
- break;
- case RIGHTARROWKEY:
- ui_textedit_move(
- but, data, STRCUR_DIR_NEXT,
- event->shift != 0, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
- retval = WM_UI_HANDLER_BREAK;
- break;
- case LEFTARROWKEY:
- ui_textedit_move(
- but, data, STRCUR_DIR_PREV,
- event->shift != 0, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
- retval = WM_UI_HANDLER_BREAK;
- break;
- case WHEELDOWNMOUSE:
- case DOWNARROWKEY:
- if (data->searchbox) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ break;
+ case LEFTMOUSE: {
+ bool had_selection = but->selsta != but->selend;
+
+ /* exit on LMB only on RELEASE for searchbox, to mimic other popups,
+ * and allow multiple menu levels */
+ if (data->searchbox) {
+ inbox = ui_searchbox_inside(data->searchbox, event->x, event->y);
+ }
+
+ /* for double click: we do a press again for when you first click on button
+ * (selects all text, no cursor pos) */
+ if (event->val == KM_PRESS || event->val == KM_DBL_CLICK) {
+ float mx, my;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block_fl(data->region, block, &mx, &my);
+
+ if (ui_but_contains_pt(but, mx, my)) {
+ ui_textedit_set_cursor_pos(but, data, event->x);
+ but->selsta = but->selend = but->pos;
+ data->selstartx = event->x;
+
+ button_activate_state(C, but, BUTTON_STATE_TEXT_SELECTING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (inbox == false) {
+ /* if searchbox, click outside will cancel */
+ if (data->searchbox) {
+ data->cancel = data->escapecancel = true;
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ /* only select a word in button if there was no selection before */
+ if (event->val == KM_DBL_CLICK && had_selection == false) {
+ ui_textedit_move(but, data, STRCUR_DIR_PREV, false, STRCUR_JUMP_DELIM);
+ ui_textedit_move(but, data, STRCUR_DIR_NEXT, true, STRCUR_JUMP_DELIM);
+ retval = WM_UI_HANDLER_BREAK;
+ changed = true;
+ }
+ else if (inbox) {
+ /* if we allow activation on key press,
+ * it gives problems launching operators T35713. */
+ if (event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ break;
+ }
+ }
+
+ if (event->val == KM_PRESS && !is_ime_composing) {
+ switch (event->type) {
+ case VKEY:
+ case XKEY:
+ case CKEY:
+ if (IS_EVENT_MOD(event, ctrl, oskey)) {
+ if (event->type == VKEY) {
+ changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_PASTE);
+ }
+ else if (event->type == CKEY) {
+ changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_COPY);
+ }
+ else if (event->type == XKEY) {
+ changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_CUT);
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ break;
+ case RIGHTARROWKEY:
+ ui_textedit_move(but,
+ data,
+ STRCUR_DIR_NEXT,
+ event->shift != 0,
+ event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ case LEFTARROWKEY:
+ ui_textedit_move(but,
+ data,
+ STRCUR_DIR_PREV,
+ event->shift != 0,
+ event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ case WHEELDOWNMOUSE:
+ case DOWNARROWKEY:
+ if (data->searchbox) {
#ifdef USE_KEYNAV_LIMIT
- ui_mouse_motion_keynav_init(&data->searchbox_keynav_state, event);
+ ui_mouse_motion_keynav_init(&data->searchbox_keynav_state, event);
#endif
- ui_searchbox_event(C, data->searchbox, but, event);
- break;
- }
- if (event->type == WHEELDOWNMOUSE) {
- break;
- }
- ATTR_FALLTHROUGH;
- case ENDKEY:
- ui_textedit_move(
- but, data, STRCUR_DIR_NEXT,
- event->shift != 0, STRCUR_JUMP_ALL);
- retval = WM_UI_HANDLER_BREAK;
- break;
- case WHEELUPMOUSE:
- case UPARROWKEY:
- if (data->searchbox) {
+ ui_searchbox_event(C, data->searchbox, but, event);
+ break;
+ }
+ if (event->type == WHEELDOWNMOUSE) {
+ break;
+ }
+ ATTR_FALLTHROUGH;
+ case ENDKEY:
+ ui_textedit_move(but, data, STRCUR_DIR_NEXT, event->shift != 0, STRCUR_JUMP_ALL);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ case WHEELUPMOUSE:
+ case UPARROWKEY:
+ if (data->searchbox) {
#ifdef USE_KEYNAV_LIMIT
- ui_mouse_motion_keynav_init(&data->searchbox_keynav_state, event);
+ ui_mouse_motion_keynav_init(&data->searchbox_keynav_state, event);
#endif
- ui_searchbox_event(C, data->searchbox, but, event);
- break;
- }
- if (event->type == WHEELUPMOUSE) {
- break;
- }
- ATTR_FALLTHROUGH;
- case HOMEKEY:
- ui_textedit_move(
- but, data, STRCUR_DIR_PREV,
- event->shift != 0, STRCUR_JUMP_ALL);
- retval = WM_UI_HANDLER_BREAK;
- break;
- case PADENTER:
- case RETKEY:
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- break;
- case DELKEY:
- changed = ui_textedit_delete(
- but, data, 1,
- event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
- retval = WM_UI_HANDLER_BREAK;
- break;
-
- case BACKSPACEKEY:
- changed = ui_textedit_delete(
- but, data, 0,
- event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
- retval = WM_UI_HANDLER_BREAK;
- break;
-
- case AKEY:
-
- /* Ctrl + A: Select all */
+ ui_searchbox_event(C, data->searchbox, but, event);
+ break;
+ }
+ if (event->type == WHEELUPMOUSE) {
+ break;
+ }
+ ATTR_FALLTHROUGH;
+ case HOMEKEY:
+ ui_textedit_move(but, data, STRCUR_DIR_PREV, event->shift != 0, STRCUR_JUMP_ALL);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ case PADENTER:
+ case RETKEY:
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ case DELKEY:
+ changed = ui_textedit_delete(
+ but, data, 1, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+
+ case BACKSPACEKEY:
+ changed = ui_textedit_delete(
+ but, data, 0, event->ctrl ? STRCUR_JUMP_DELIM : STRCUR_JUMP_NONE);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+
+ case AKEY:
+
+ /* Ctrl + A: Select all */
#if defined(__APPLE__)
- /* OSX uses cmd-a systemwide, so add it */
- if ((event->oskey && !IS_EVENT_MOD(event, shift, alt, ctrl)) ||
- (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey)))
+ /* OSX uses cmd-a systemwide, so add it */
+ if ((event->oskey && !IS_EVENT_MOD(event, shift, alt, ctrl)) ||
+ (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey)))
#else
- if (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey))
+ if (event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey))
#endif
- {
- ui_textedit_move(
- but, data, STRCUR_DIR_PREV,
- false, STRCUR_JUMP_ALL);
- ui_textedit_move(
- but, data, STRCUR_DIR_NEXT,
- true, STRCUR_JUMP_ALL);
- retval = WM_UI_HANDLER_BREAK;
- }
- break;
-
- case TABKEY:
- /* there is a key conflict here, we can't tab with autocomplete */
- if (but->autocomplete_func || data->searchbox) {
- int autocomplete = ui_textedit_autocomplete(C, but, data);
- changed = autocomplete != AUTOCOMPLETE_NO_MATCH;
-
- if (autocomplete == AUTOCOMPLETE_FULL_MATCH) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- /* the hotkey here is not well defined, was G.qual so we check all */
- else if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
- ui_textedit_prev_but(block, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- ui_textedit_next_but(block, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
-
- if ((event->ascii || event->utf8_buf[0]) &&
- (retval == WM_UI_HANDLER_CONTINUE)
+ {
+ ui_textedit_move(but, data, STRCUR_DIR_PREV, false, STRCUR_JUMP_ALL);
+ ui_textedit_move(but, data, STRCUR_DIR_NEXT, true, STRCUR_JUMP_ALL);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ break;
+
+ case TABKEY:
+ /* there is a key conflict here, we can't tab with autocomplete */
+ if (but->autocomplete_func || data->searchbox) {
+ int autocomplete = ui_textedit_autocomplete(C, but, data);
+ changed = autocomplete != AUTOCOMPLETE_NO_MATCH;
+
+ if (autocomplete == AUTOCOMPLETE_FULL_MATCH) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ /* the hotkey here is not well defined, was G.qual so we check all */
+ else if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
+ ui_textedit_prev_but(block, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ ui_textedit_next_but(block, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+
+ if ((event->ascii || event->utf8_buf[0]) && (retval == WM_UI_HANDLER_CONTINUE)
#ifdef WITH_INPUT_IME
- &&
- !is_ime_composing &&
- (!WM_event_is_ime_switch(event) || !BLT_lang_is_ime_supported())
+ && !is_ime_composing && (!WM_event_is_ime_switch(event) || !BLT_lang_is_ime_supported())
#endif
- )
- {
- char ascii = event->ascii;
- const char *utf8_buf = event->utf8_buf;
-
- /* exception that's useful for number buttons, some keyboard
- * numpads have a comma instead of a period */
- if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* could use data->min*/
- if (event->type == PADPERIOD && ascii == ',') {
- ascii = '.';
- utf8_buf = NULL; /* force ascii fallback */
- }
- }
-
- if (utf8_buf && utf8_buf[0]) {
- int utf8_buf_len = BLI_str_utf8_size(utf8_buf);
- /* keep this printf until utf8 is well tested */
- if (utf8_buf_len != 1) {
- printf("%s: utf8 char '%.*s'\n", __func__, utf8_buf_len, utf8_buf);
- }
-
- // strcpy(utf8_buf, "12345");
- changed = ui_textedit_insert_buf(but, data, event->utf8_buf, utf8_buf_len);
- }
- else {
- changed = ui_textedit_insert_ascii(but, data, ascii);
- }
-
- retval = WM_UI_HANDLER_BREAK;
-
- }
- /* textbutton with this flag: do live update (e.g. for search buttons) */
- if (but->flag & UI_BUT_TEXTEDIT_UPDATE) {
- update = true;
- }
- }
+ ) {
+ char ascii = event->ascii;
+ const char *utf8_buf = event->utf8_buf;
+
+ /* exception that's useful for number buttons, some keyboard
+ * numpads have a comma instead of a period */
+ if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* could use data->min*/
+ if (event->type == PADPERIOD && ascii == ',') {
+ ascii = '.';
+ utf8_buf = NULL; /* force ascii fallback */
+ }
+ }
+
+ if (utf8_buf && utf8_buf[0]) {
+ int utf8_buf_len = BLI_str_utf8_size(utf8_buf);
+ /* keep this printf until utf8 is well tested */
+ if (utf8_buf_len != 1) {
+ printf("%s: utf8 char '%.*s'\n", __func__, utf8_buf_len, utf8_buf);
+ }
+
+ // strcpy(utf8_buf, "12345");
+ changed = ui_textedit_insert_buf(but, data, event->utf8_buf, utf8_buf_len);
+ }
+ else {
+ changed = ui_textedit_insert_ascii(but, data, ascii);
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ /* textbutton with this flag: do live update (e.g. for search buttons) */
+ if (but->flag & UI_BUT_TEXTEDIT_UPDATE) {
+ update = true;
+ }
+ }
#ifdef WITH_INPUT_IME
- if (event->type == WM_IME_COMPOSITE_START || event->type == WM_IME_COMPOSITE_EVENT) {
- changed = true;
-
- if (event->type == WM_IME_COMPOSITE_START && but->selend > but->selsta) {
- ui_textedit_delete_selection(but, data);
- }
- if (event->type == WM_IME_COMPOSITE_EVENT && ime_data->result_len) {
- ui_textedit_insert_buf(
- but, data,
- ime_data->str_result,
- ime_data->result_len);
- }
- }
- else if (event->type == WM_IME_COMPOSITE_END) {
- changed = true;
- }
+ if (event->type == WM_IME_COMPOSITE_START || event->type == WM_IME_COMPOSITE_EVENT) {
+ changed = true;
+
+ if (event->type == WM_IME_COMPOSITE_START && but->selend > but->selsta) {
+ ui_textedit_delete_selection(but, data);
+ }
+ if (event->type == WM_IME_COMPOSITE_EVENT && ime_data->result_len) {
+ ui_textedit_insert_buf(but, data, ime_data->str_result, ime_data->result_len);
+ }
+ }
+ else if (event->type == WM_IME_COMPOSITE_END) {
+ changed = true;
+ }
#endif
- if (changed) {
- /* only do live update when but flag request it (UI_BUT_TEXTEDIT_UPDATE). */
- if (update && data->interactive) {
- ui_apply_but(C, block, but, data, true);
- }
- else {
- ui_but_update_edited(but);
- }
- but->changed = true;
+ if (changed) {
+ /* only do live update when but flag request it (UI_BUT_TEXTEDIT_UPDATE). */
+ if (update && data->interactive) {
+ ui_apply_but(C, block, but, data, true);
+ }
+ else {
+ ui_but_update_edited(but);
+ }
+ but->changed = true;
- if (data->searchbox) {
- ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
- }
- }
+ if (data->searchbox) {
+ ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
+ }
+ }
- if (changed || (retval == WM_UI_HANDLER_BREAK)) {
- ED_region_tag_redraw(data->region);
- }
+ if (changed || (retval == WM_UI_HANDLER_BREAK)) {
+ ED_region_tag_redraw(data->region);
+ }
}
static void ui_do_but_textedit_select(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my, retval = WM_UI_HANDLER_CONTINUE;
-
- switch (event->type) {
- case MOUSEMOVE:
- {
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- ui_textedit_set_cursor_select(but, data, event->x);
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
- case LEFTMOUSE:
- if (event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- }
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
-
- if (retval == WM_UI_HANDLER_BREAK) {
- ui_but_update(but);
- ED_region_tag_redraw(data->region);
- }
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my, retval = WM_UI_HANDLER_CONTINUE;
+
+ switch (event->type) {
+ case MOUSEMOVE: {
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ ui_textedit_set_cursor_select(but, data, event->x);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ }
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+
+ if (retval == WM_UI_HANDLER_BREAK) {
+ ui_but_update(but);
+ ED_region_tag_redraw(data->region);
+ }
}
/** \} */
@@ -3641,62 +3645,66 @@ static void ui_do_but_textedit_select(
static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
{
- if (but->type == UI_BTYPE_CURVE) {
- but->editcumap = (CurveMapping *)but->poin;
- }
- else if (but->type == UI_BTYPE_COLORBAND) {
- data->coba = (ColorBand *)but->poin;
- but->editcoba = data->coba;
- }
- else if (ELEM(but->type, UI_BTYPE_UNITVEC, UI_BTYPE_HSVCUBE, UI_BTYPE_HSVCIRCLE, UI_BTYPE_COLOR)) {
- ui_but_v3_get(but, data->origvec);
- copy_v3_v3(data->vec, data->origvec);
- but->editvec = data->vec;
- }
- else {
- float softrange, softmin, softmax;
-
- data->startvalue = ui_but_value_get(but);
- data->origvalue = data->startvalue;
- data->value = data->origvalue;
- but->editval = &data->value;
-
- softmin = but->softmin;
- softmax = but->softmax;
- softrange = softmax - softmin;
-
- data->dragfstart = (softrange == 0.0f) ? 0.0f : ((float)data->value - softmin) / softrange;
- data->dragf = data->dragfstart;
- }
-
- data->dragchange = false;
- data->draglock = true;
+ if (but->type == UI_BTYPE_CURVE) {
+ but->editcumap = (CurveMapping *)but->poin;
+ }
+ else if (but->type == UI_BTYPE_COLORBAND) {
+ data->coba = (ColorBand *)but->poin;
+ but->editcoba = data->coba;
+ }
+ else if (ELEM(but->type,
+ UI_BTYPE_UNITVEC,
+ UI_BTYPE_HSVCUBE,
+ UI_BTYPE_HSVCIRCLE,
+ UI_BTYPE_COLOR)) {
+ ui_but_v3_get(but, data->origvec);
+ copy_v3_v3(data->vec, data->origvec);
+ but->editvec = data->vec;
+ }
+ else {
+ float softrange, softmin, softmax;
+
+ data->startvalue = ui_but_value_get(but);
+ data->origvalue = data->startvalue;
+ data->value = data->origvalue;
+ but->editval = &data->value;
+
+ softmin = but->softmin;
+ softmax = but->softmax;
+ softrange = softmax - softmin;
+
+ data->dragfstart = (softrange == 0.0f) ? 0.0f : ((float)data->value - softmin) / softrange;
+ data->dragf = data->dragfstart;
+ }
+
+ data->dragchange = false;
+ data->draglock = true;
}
static void ui_numedit_end(uiBut *but, uiHandleButtonData *data)
{
- but->editval = NULL;
- but->editvec = NULL;
- but->editcoba = NULL;
- but->editcumap = NULL;
+ but->editval = NULL;
+ but->editvec = NULL;
+ but->editcoba = NULL;
+ but->editcumap = NULL;
- data->dragstartx = 0;
- data->draglastx = 0;
- data->dragchange = false;
- data->dragcbd = NULL;
- data->dragsel = 0;
+ data->dragstartx = 0;
+ data->draglastx = 0;
+ data->dragchange = false;
+ data->dragcbd = NULL;
+ data->dragsel = 0;
}
static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
- if (data->interactive) {
- ui_apply_but(C, block, but, data, true);
- }
- else {
- ui_but_update(but);
- }
+ if (data->interactive) {
+ ui_apply_but(C, block, but, data, true);
+ }
+ else {
+ ui_but_update(but);
+ }
- ED_region_tag_redraw(data->region);
+ ED_region_tag_redraw(data->region);
}
/** \} */
@@ -3707,131 +3715,133 @@ static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- uiBlockCreateFunc func = NULL;
- uiBlockHandleCreateFunc handlefunc = NULL;
- uiMenuCreateFunc menufunc = NULL;
- uiMenuCreateFunc popoverfunc = NULL;
- void *arg = NULL;
-
- switch (but->type) {
- case UI_BTYPE_BLOCK:
- case UI_BTYPE_PULLDOWN:
- if (but->menu_create_func) {
- menufunc = but->menu_create_func;
- arg = but->poin;
- }
- else {
- func = but->block_create_func;
- arg = but->poin ? but->poin : but->func_argN;
- }
- break;
- case UI_BTYPE_MENU:
- case UI_BTYPE_POPOVER:
- BLI_assert(but->menu_create_func);
- if ((but->type == UI_BTYPE_POPOVER) || ui_but_menu_draw_as_popover(but)) {
- popoverfunc = but->menu_create_func;
- }
- else {
- menufunc = but->menu_create_func;
- }
- arg = but->poin;
- break;
- case UI_BTYPE_COLOR:
- ui_but_v3_get(but, data->origvec);
- copy_v3_v3(data->vec, data->origvec);
- but->editvec = data->vec;
-
- handlefunc = ui_block_func_COLOR;
- arg = but;
- break;
-
- /* quiet warnings for unhandled types */
- default:
- break;
- }
-
- if (func || handlefunc) {
- data->menu = ui_popup_block_create(C, data->region, but, func, handlefunc, arg);
- if (but->block->handle) {
- data->menu->popup = but->block->handle->popup;
- }
- }
- else if (menufunc) {
- data->menu = ui_popup_menu_create(C, data->region, but, menufunc, arg);
- if (but->block->handle) {
- data->menu->popup = but->block->handle->popup;
- }
- }
- else if (popoverfunc) {
- data->menu = ui_popover_panel_create(C, data->region, but, popoverfunc, arg);
- if (but->block->handle) {
- data->menu->popup = but->block->handle->popup;
- }
- }
+ uiBlockCreateFunc func = NULL;
+ uiBlockHandleCreateFunc handlefunc = NULL;
+ uiMenuCreateFunc menufunc = NULL;
+ uiMenuCreateFunc popoverfunc = NULL;
+ void *arg = NULL;
+
+ switch (but->type) {
+ case UI_BTYPE_BLOCK:
+ case UI_BTYPE_PULLDOWN:
+ if (but->menu_create_func) {
+ menufunc = but->menu_create_func;
+ arg = but->poin;
+ }
+ else {
+ func = but->block_create_func;
+ arg = but->poin ? but->poin : but->func_argN;
+ }
+ break;
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_POPOVER:
+ BLI_assert(but->menu_create_func);
+ if ((but->type == UI_BTYPE_POPOVER) || ui_but_menu_draw_as_popover(but)) {
+ popoverfunc = but->menu_create_func;
+ }
+ else {
+ menufunc = but->menu_create_func;
+ }
+ arg = but->poin;
+ break;
+ case UI_BTYPE_COLOR:
+ ui_but_v3_get(but, data->origvec);
+ copy_v3_v3(data->vec, data->origvec);
+ but->editvec = data->vec;
+
+ handlefunc = ui_block_func_COLOR;
+ arg = but;
+ break;
+
+ /* quiet warnings for unhandled types */
+ default:
+ break;
+ }
+
+ if (func || handlefunc) {
+ data->menu = ui_popup_block_create(C, data->region, but, func, handlefunc, arg);
+ if (but->block->handle) {
+ data->menu->popup = but->block->handle->popup;
+ }
+ }
+ else if (menufunc) {
+ data->menu = ui_popup_menu_create(C, data->region, but, menufunc, arg);
+ if (but->block->handle) {
+ data->menu->popup = but->block->handle->popup;
+ }
+ }
+ else if (popoverfunc) {
+ data->menu = ui_popover_panel_create(C, data->region, but, popoverfunc, arg);
+ if (but->block->handle) {
+ data->menu->popup = but->block->handle->popup;
+ }
+ }
#ifdef USE_ALLSELECT
- {
- wmWindow *win = CTX_wm_window(C);
- if (IS_ALLSELECT_EVENT(win->eventstate)) {
- data->select_others.is_enabled = true;
- }
- }
+ {
+ wmWindow *win = CTX_wm_window(C);
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ }
+ }
#endif
- /* this makes adjacent blocks auto open from now on */
- //if (but->block->auto_open == 0) {
- // but->block->auto_open = 1;
- //}
+ /* this makes adjacent blocks auto open from now on */
+ //if (but->block->auto_open == 0) {
+ // but->block->auto_open = 1;
+ //}
}
static void ui_block_open_end(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- if (but) {
- but->editval = NULL;
- but->editvec = NULL;
+ if (but) {
+ but->editval = NULL;
+ but->editvec = NULL;
- but->block->auto_open_last = PIL_check_seconds_timer();
- }
+ but->block->auto_open_last = PIL_check_seconds_timer();
+ }
- if (data->menu) {
- ui_popup_block_free(C, data->menu);
- data->menu = NULL;
- }
+ if (data->menu) {
+ ui_popup_block_free(C, data->menu);
+ data->menu = NULL;
+ }
}
int ui_but_menu_direction(uiBut *but)
{
- uiHandleButtonData *data = but->active;
+ uiHandleButtonData *data = but->active;
- if (data && data->menu) {
- return data->menu->direction;
- }
+ if (data && data->menu) {
+ return data->menu->direction;
+ }
- return 0;
+ return 0;
}
/**
* Hack for #uiList #UI_BTYPE_LISTROW buttons to "give" events to overlaying #UI_BTYPE_TEXT buttons
* (Ctrl-Click rename feature & co).
*/
-static uiBut *ui_but_list_row_text_activate(
- bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event,
- uiButtonActivateType activate_type)
+static uiBut *ui_but_list_row_text_activate(bContext *C,
+ uiBut *but,
+ uiHandleButtonData *data,
+ const wmEvent *event,
+ uiButtonActivateType activate_type)
{
- ARegion *ar = CTX_wm_region(C);
- uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true);
+ ARegion *ar = CTX_wm_region(C);
+ uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true);
- if (labelbut && labelbut->type == UI_BTYPE_TEXT && !(labelbut->flag & UI_BUT_DISABLED)) {
- /* exit listrow */
- data->cancel = true;
- button_activate_exit(C, but, data, false, false);
+ if (labelbut && labelbut->type == UI_BTYPE_TEXT && !(labelbut->flag & UI_BUT_DISABLED)) {
+ /* exit listrow */
+ data->cancel = true;
+ button_activate_exit(C, but, data, false, false);
- /* Activate the text button. */
- button_activate_init(C, ar, labelbut, activate_type);
+ /* Activate the text button. */
+ button_activate_init(C, ar, labelbut, activate_type);
- return labelbut;
- }
- return NULL;
+ return labelbut;
+ }
+ return NULL;
}
/** \} */
@@ -3843,3247 +3853,3256 @@ static uiBut *ui_but_list_row_text_activate(
#ifdef USE_DRAG_TOGGLE
/* Shared by any button that supports drag-toggle. */
static bool ui_do_but_ANY_drag_toggle(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event,
- int *r_retval)
-{
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_but_is_drag_toggle(but)) {
-#if 0 /* UNUSED */
- data->togdual = event->ctrl;
- data->togonly = !event->shift;
-#endif
- ui_apply_but(C, but->block, but, data, true);
- button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- *r_retval = WM_UI_HANDLER_BREAK;
- return true;
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_DRAG) {
- /* note: the 'BUTTON_STATE_WAIT_DRAG' part of 'ui_do_but_EXIT' could be refactored into
- * its own function */
- data->applied = false;
- *r_retval = ui_do_but_EXIT(C, but, data, event);
- return true;
- }
- return false;
-}
-#endif /* USE_DRAG_TOGGLE */
-
-static int ui_do_but_BUT(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
+ bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event, int *r_retval)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS && ui_but_is_drag_toggle(but)) {
+# if 0 /* UNUSED */
+ data->togdual = event->ctrl;
+ data->togonly = !event->shift;
+# endif
+ ui_apply_but(C, but->block, but, data, true);
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ *r_retval = WM_UI_HANDLER_BREAK;
+ return true;
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_DRAG) {
+ /* note: the 'BUTTON_STATE_WAIT_DRAG' part of 'ui_do_but_EXIT' could be refactored into
+ * its own function */
+ data->applied = false;
+ *r_retval = ui_do_but_EXIT(C, but, data, event);
+ return true;
+ }
+ return false;
+}
+#endif /* USE_DRAG_TOGGLE */
+
+static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
#ifdef USE_DRAG_TOGGLE
- {
- int retval;
- if (ui_do_but_ANY_drag_toggle(C, but, data, event, &retval)) {
- return retval;
- }
- }
+ {
+ int retval;
+ if (ui_do_but_ANY_drag_toggle(C, but, data, event, &retval)) {
+ return retval;
+ }
+ }
#endif
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_RELEASE);
- return WM_UI_HANDLER_BREAK;
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE && but->block->handle) {
- /* regular buttons will be 'UI_SELECT', menu items 'UI_ACTIVE' */
- if (!(but->flag & (UI_SELECT | UI_ACTIVE))) {
- data->cancel = true;
- }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
- if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if (!(but->flag & UI_SELECT)) {
- data->cancel = true;
- }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- }
-
- return WM_UI_HANDLER_CONTINUE;
-}
-
-static int ui_do_but_HOTKEYEVT(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
- but->drawstr[0] = 0;
- but->modifier_key = 0;
- button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) {
- if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
- return WM_UI_HANDLER_CONTINUE;
- }
-
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- /* only cancel if click outside the button */
- if (ui_but_contains_point_px(but, but->active->region, event->x, event->y) == 0) {
- /* data->cancel doesn't work, this button opens immediate */
- if (but->flag & UI_BUT_IMMEDIATE) {
- ui_but_value_set(but, 0);
- }
- else {
- data->cancel = true;
- }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- }
-
- /* always set */
- but->modifier_key = 0;
- if (event->shift) {
- but->modifier_key |= KM_SHIFT;
- }
- if (event->alt) {
- but->modifier_key |= KM_ALT;
- }
- if (event->ctrl) {
- but->modifier_key |= KM_CTRL;
- }
- if (event->oskey) {
- but->modifier_key |= KM_OSKEY;
- }
-
- ui_but_update(but);
- ED_region_tag_redraw(data->region);
-
- if (event->val == KM_PRESS) {
- if (ISHOTKEY(event->type) && (event->type != ESCKEY)) {
- if (WM_key_event_string(event->type, false)[0]) {
- ui_but_value_set(but, event->type);
- }
- else {
- data->cancel = true;
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- else if (event->type == ESCKEY) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
-
- }
- }
-
- return WM_UI_HANDLER_CONTINUE;
-}
-
-static int ui_do_but_KEYEVT(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) {
- if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
- return WM_UI_HANDLER_CONTINUE;
- }
-
- if (event->val == KM_PRESS) {
- if (WM_key_event_string(event->type, false)[0]) {
- ui_but_value_set(but, event->type);
- }
- else {
- data->cancel = true;
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
-
- return WM_UI_HANDLER_CONTINUE;
-}
-
-static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, const int mouse_xy[2])
-{
- int x = mouse_xy[0], y = mouse_xy[1];
- rcti icon_rect;
-
- BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE);
-
- ui_window_to_block(region, but->block, &x, &y);
-
- BLI_rcti_rctf_copy(&icon_rect, &but->rect);
- icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect));
-
- return BLI_rcti_isect_pt(&icon_rect, x, y);
-}
-
-static int ui_do_but_TAB(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
-{
- const bool is_property = (but->rnaprop != NULL);
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_RELEASE);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE && but->block->handle) {
+ /* regular buttons will be 'UI_SELECT', menu items 'UI_ACTIVE' */
+ if (!(but->flag & (UI_SELECT | UI_ACTIVE))) {
+ data->cancel = true;
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ if (!(but->flag & UI_SELECT)) {
+ data->cancel = true;
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
+static int ui_do_but_HOTKEYEVT(bContext *C,
+ uiBut *but,
+ uiHandleButtonData *data,
+ const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ but->drawstr[0] = 0;
+ but->modifier_key = 0;
+ button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) {
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ /* only cancel if click outside the button */
+ if (ui_but_contains_point_px(but, but->active->region, event->x, event->y) == 0) {
+ /* data->cancel doesn't work, this button opens immediate */
+ if (but->flag & UI_BUT_IMMEDIATE) {
+ ui_but_value_set(but, 0);
+ }
+ else {
+ data->cancel = true;
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ /* always set */
+ but->modifier_key = 0;
+ if (event->shift) {
+ but->modifier_key |= KM_SHIFT;
+ }
+ if (event->alt) {
+ but->modifier_key |= KM_ALT;
+ }
+ if (event->ctrl) {
+ but->modifier_key |= KM_CTRL;
+ }
+ if (event->oskey) {
+ but->modifier_key |= KM_OSKEY;
+ }
+
+ ui_but_update(but);
+ ED_region_tag_redraw(data->region);
+
+ if (event->val == KM_PRESS) {
+ if (ISHOTKEY(event->type) && (event->type != ESCKEY)) {
+ if (WM_key_event_string(event->type, false)[0]) {
+ ui_but_value_set(but, event->type);
+ }
+ else {
+ data->cancel = true;
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (event->type == ESCKEY) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ }
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
+static int ui_do_but_KEYEVT(bContext *C,
+ uiBut *but,
+ uiHandleButtonData *data,
+ const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) {
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+
+ if (event->val == KM_PRESS) {
+ if (WM_key_event_string(event->type, false)[0]) {
+ ui_but_value_set(but, event->type);
+ }
+ else {
+ data->cancel = true;
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
+static bool ui_but_is_mouse_over_icon_extra(const ARegion *region,
+ uiBut *but,
+ const int mouse_xy[2])
+{
+ int x = mouse_xy[0], y = mouse_xy[1];
+ rcti icon_rect;
+
+ BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE);
+
+ ui_window_to_block(region, but->block, &x, &y);
+
+ BLI_rcti_rctf_copy(&icon_rect, &but->rect);
+ icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect));
+
+ return BLI_rcti_isect_pt(&icon_rect, x, y);
+}
+
+static int ui_do_but_TAB(
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ const bool is_property = (but->rnaprop != NULL);
#ifdef USE_DRAG_TOGGLE
- if (is_property) {
- int retval;
- if (ui_do_but_ANY_drag_toggle(C, but, data, event, &retval)) {
- return retval;
- }
- }
+ if (is_property) {
+ int retval;
+ if (ui_do_but_ANY_drag_toggle(C, but, data, event, &retval)) {
+ return retval;
+ }
+ }
#endif
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- const int rna_type = but->rnaprop ? RNA_property_type(but->rnaprop) : 0;
-
- if (is_property &&
- ELEM(rna_type, PROP_POINTER, PROP_STRING) &&
- (but->custom_data != NULL) &&
- (event->type == LEFTMOUSE) &&
- ((event->val == KM_DBL_CLICK) || event->ctrl))
- {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- return WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY)) {
- int event_val = (is_property) ? KM_PRESS : KM_CLICK;
- if (event->val == event_val) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- }
- }
- else if (data->state == BUTTON_STATE_TEXT_EDITING) {
- ui_do_but_textedit(C, block, but, data, event);
- return WM_UI_HANDLER_BREAK;
- }
- else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
- ui_do_but_textedit_select(C, block, but, data, event);
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ const int rna_type = but->rnaprop ? RNA_property_type(but->rnaprop) : 0;
+
+ if (is_property && ELEM(rna_type, PROP_POINTER, PROP_STRING) && (but->custom_data != NULL) &&
+ (event->type == LEFTMOUSE) && ((event->val == KM_DBL_CLICK) || event->ctrl)) {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY)) {
+ int event_val = (is_property) ? KM_PRESS : KM_CLICK;
+ if (event->val == event_val) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ else if (data->state == BUTTON_STATE_TEXT_EDITING) {
+ ui_do_but_textedit(C, block, but, data, event);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
+ ui_do_but_textedit_select(C, block, but, data, event);
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
static int ui_do_but_TEX(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) {
- if (ELEM(event->type, PADENTER, RETKEY) && (!ui_but_is_utf8(but))) {
- /* pass - allow filesel, enter to execute */
- }
- else if (but->dt == UI_EMBOSS_NONE && !event->ctrl) {
- /* pass */
- }
- else {
- const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR;
-
- if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) {
- ui_textedit_string_clear_and_exit(C, but, data);
- }
- else {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- }
- return WM_UI_HANDLER_BREAK;
- }
- }
- }
- else if (data->state == BUTTON_STATE_TEXT_EDITING) {
- ui_do_but_textedit(C, block, but, data, event);
- return WM_UI_HANDLER_BREAK;
- }
- else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
- ui_do_but_textedit_select(C, block, but, data, event);
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ if (ELEM(event->type, PADENTER, RETKEY) && (!ui_but_is_utf8(but))) {
+ /* pass - allow filesel, enter to execute */
+ }
+ else if (but->dt == UI_EMBOSS_NONE && !event->ctrl) {
+ /* pass */
+ }
+ else {
+ const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR;
+
+ if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) {
+ ui_textedit_string_clear_and_exit(C, but, data);
+ }
+ else {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ else if (data->state == BUTTON_STATE_TEXT_EDITING) {
+ ui_do_but_textedit(C, block, but, data, event);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
+ ui_do_but_textedit_select(C, block, but, data, event);
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
static int ui_do_but_SEARCH_UNLINK(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
- const bool has_icon_extra = (extra_icon_type != UI_BUT_ICONEXTRA_NONE);
-
- /* unlink icon is on right */
- if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) &&
- (has_icon_extra == true) &&
- (ui_but_is_mouse_over_icon_extra(data->region, but, &event->x) == true))
- {
- /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
- if (event->val == KM_RELEASE) {
- /* unlink */
- if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
- ui_textedit_string_clear_and_exit(C, but, data);
- }
- /* eyedropper */
- else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
- WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
- }
- else {
- BLI_assert(0);
- }
- }
- return WM_UI_HANDLER_BREAK;
- }
- return ui_do_but_TEX(C, block, but, data, event);
-}
-
-static int ui_do_but_TOG(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
+ const bool has_icon_extra = (extra_icon_type != UI_BUT_ICONEXTRA_NONE);
+
+ /* unlink icon is on right */
+ if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) && (has_icon_extra == true) &&
+ (ui_but_is_mouse_over_icon_extra(data->region, but, &event->x) == true)) {
+ /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
+ if (event->val == KM_RELEASE) {
+ /* unlink */
+ if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
+ ui_textedit_string_clear_and_exit(C, but, data);
+ }
+ /* eyedropper */
+ else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
+ WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+ return ui_do_but_TEX(C, block, but, data, event);
+}
+
+static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
#ifdef USE_DRAG_TOGGLE
- {
- int retval;
- if (ui_do_but_ANY_drag_toggle(C, but, data, event, &retval)) {
- return retval;
- }
- }
+ {
+ int retval;
+ if (ui_do_but_ANY_drag_toggle(C, but, data, event, &retval)) {
+ return retval;
+ }
+ }
#endif
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- bool do_activate = false;
- if (ELEM(event->type, PADENTER, RETKEY)) {
- if (event->val == KM_PRESS) {
- do_activate = true;
- }
- }
- else if (event->type == LEFTMOUSE) {
- if (ui_block_is_menu(but->block)) {
- /* Behave like other menu items. */
- do_activate = (event->val == KM_RELEASE);
- }
- else {
- do_activate = (event->val == KM_PRESS);
- }
- }
-
- if (do_activate) {
-#if 0 /* UNUSED */
- data->togdual = event->ctrl;
- data->togonly = !event->shift;
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ bool do_activate = false;
+ if (ELEM(event->type, PADENTER, RETKEY)) {
+ if (event->val == KM_PRESS) {
+ do_activate = true;
+ }
+ }
+ else if (event->type == LEFTMOUSE) {
+ if (ui_block_is_menu(but->block)) {
+ /* Behave like other menu items. */
+ do_activate = (event->val == KM_RELEASE);
+ }
+ else {
+ do_activate = (event->val == KM_PRESS);
+ }
+ }
+
+ if (do_activate) {
+#if 0 /* UNUSED */
+ data->togdual = event->ctrl;
+ data->togonly = !event->shift;
#endif
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- /* Support alt+wheel on expanded enum rows */
- if (but->type == UI_BTYPE_ROW) {
- const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
- uiBut *but_select = ui_but_find_select_in_enum(but, direction);
- if (but_select) {
- uiBut *but_other = (direction == -1) ? but_select->next : but_select->prev;
- if (but_other && ui_but_find_select_in_enum__cmp(but, but_other)) {
- ARegion *ar = data->region;
-
- data->cancel = true;
- button_activate_exit(C, but, data, false, false);
-
- /* Activate the text button. */
- button_activate_init(C, ar, but_other, BUTTON_ACTIVATE_OVER);
- data = but_other->active;
- if (data) {
- ui_apply_but(C, but->block, but_other, but_other->active, true);
- button_activate_exit(C, but_other, data, false, false);
-
- /* restore active button */
- button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
- }
- else {
- /* shouldn't happen */
- BLI_assert(0);
- }
- }
- }
- return WM_UI_HANDLER_BREAK;
- }
- }
- }
- return WM_UI_HANDLER_CONTINUE;
-}
-
-static int ui_do_but_EXIT(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
-
- /* first handle click on icondrag type button */
- if (event->type == LEFTMOUSE && but->dragpoin) {
- if (ui_but_contains_point_px_icon(but, data->region, event)) {
-
- /* tell the button to wait and keep checking further events to
- * see if it should start dragging */
- button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- return WM_UI_HANDLER_CONTINUE;
- }
- }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ /* Support alt+wheel on expanded enum rows */
+ if (but->type == UI_BTYPE_ROW) {
+ const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
+ uiBut *but_select = ui_but_find_select_in_enum(but, direction);
+ if (but_select) {
+ uiBut *but_other = (direction == -1) ? but_select->next : but_select->prev;
+ if (but_other && ui_but_find_select_in_enum__cmp(but, but_other)) {
+ ARegion *ar = data->region;
+
+ data->cancel = true;
+ button_activate_exit(C, but, data, false, false);
+
+ /* Activate the text button. */
+ button_activate_init(C, ar, but_other, BUTTON_ACTIVATE_OVER);
+ data = but_other->active;
+ if (data) {
+ ui_apply_but(C, but->block, but_other, but_other->active, true);
+ button_activate_exit(C, but_other, data, false, false);
+
+ /* restore active button */
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ }
+ else {
+ /* shouldn't happen */
+ BLI_assert(0);
+ }
+ }
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ return WM_UI_HANDLER_CONTINUE;
+}
+
+static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+
+ /* first handle click on icondrag type button */
+ if (event->type == LEFTMOUSE && but->dragpoin) {
+ if (ui_but_contains_point_px_icon(but, data->region, event)) {
+
+ /* tell the button to wait and keep checking further events to
+ * see if it should start dragging */
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_CONTINUE;
+ }
+ }
#ifdef USE_DRAG_TOGGLE
- if (event->type == LEFTMOUSE && ui_but_is_drag_toggle(but)) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- return WM_UI_HANDLER_CONTINUE;
- }
+ if (event->type == LEFTMOUSE && ui_but_is_drag_toggle(but)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_CONTINUE;
+ }
#endif
- if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
- int ret = WM_UI_HANDLER_BREAK;
- /* XXX (a bit ugly) Special case handling for filebrowser drag button */
- if (but->dragpoin && but->imb && ui_but_contains_point_px_icon(but, data->region, event)) {
- ret = WM_UI_HANDLER_CONTINUE;
- }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return ret;
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_DRAG) {
-
- /* this function also ends state */
- if (ui_but_drag_init(C, but, data, event)) {
- return WM_UI_HANDLER_BREAK;
- }
-
- /* If the mouse has been pressed and released, getting to
- * this point without triggering a drag, then clear the
- * drag state for this button and continue to pass on the event */
- if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_CONTINUE;
- }
-
- /* while waiting for a drag to be triggered, always block
- * other events from getting handled */
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ int ret = WM_UI_HANDLER_BREAK;
+ /* XXX (a bit ugly) Special case handling for filebrowser drag button */
+ if (but->dragpoin && but->imb && ui_but_contains_point_px_icon(but, data->region, event)) {
+ ret = WM_UI_HANDLER_CONTINUE;
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return ret;
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_DRAG) {
+
+ /* this function also ends state */
+ if (ui_but_drag_init(C, but, data, event)) {
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ /* If the mouse has been pressed and released, getting to
+ * this point without triggering a drag, then clear the
+ * drag state for this button and continue to pass on the event */
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_CONTINUE;
+ }
+
+ /* while waiting for a drag to be triggered, always block
+ * other events from getting handled */
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
/* var names match ui_numedit_but_NUM */
-static float ui_numedit_apply_snapf(
- uiBut *but, float tempf, float softmin, float softmax, float softrange,
- const enum eSnapType snap)
-{
- if (tempf == softmin || tempf == softmax || snap == SNAP_OFF) {
- /* pass */
- }
- else {
- float fac = 1.0f;
-
- if (ui_but_is_unit(but)) {
- UnitSettings *unit = but->block->unit;
- int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
-
- if (bUnit_IsValid(unit->system, unit_type)) {
- fac = (float)bUnit_BaseScalar(unit->system, unit_type);
- if (ELEM(unit_type, B_UNIT_LENGTH, B_UNIT_AREA, B_UNIT_VOLUME)) {
- fac /= unit->scale_length;
- }
- }
- }
-
- if (fac != 1.0f) {
- /* snap in unit-space */
- tempf /= fac;
- /* softmin /= fac; */ /* UNUSED */
- /* softmax /= fac; */ /* UNUSED */
- softrange /= fac;
- }
-
- /* workaround, too high snapping values */
- /* snapping by 10's for float buttons is quite annoying (location, scale...),
- * but allow for rotations */
- if (softrange >= 21.0f) {
- UnitSettings *unit = but->block->unit;
- int unit_type = UI_but_unit_type_get(but);
- if ((unit_type == PROP_UNIT_ROTATION) && (unit->system_rotation != USER_UNIT_ROT_RADIANS)) {
- /* pass (degrees)*/
- }
- else {
- softrange = 20.0f;
- }
- }
-
- if (snap == SNAP_ON) {
- if (softrange < 2.10f) { tempf = roundf(tempf * 10.0f) * 0.1f; }
- else if (softrange < 21.0f) { tempf = roundf(tempf); }
- else { tempf = roundf(tempf * 0.1f) * 10.0f; }
- }
- else if (snap == SNAP_ON_SMALL) {
- if (softrange < 2.10f) { tempf = roundf(tempf * 100.0f) * 0.01f; }
- else if (softrange < 21.0f) { tempf = roundf(tempf * 10.0f) * 0.1f; }
- else { tempf = roundf(tempf); }
- }
- else {
- BLI_assert(0);
- }
-
- if (fac != 1.0f) {
- tempf *= fac;
- }
- }
-
- return tempf;
-}
-
-static float ui_numedit_apply_snap(
- int temp, float softmin, float softmax,
- const enum eSnapType snap)
-{
- if (temp == softmin || temp == softmax) {
- return temp;
- }
-
- switch (snap) {
- case SNAP_OFF:
- break;
- case SNAP_ON:
- temp = 10 * (temp / 10);
- break;
- case SNAP_ON_SMALL:
- temp = 100 * (temp / 100);
- break;
- }
-
- return temp;
-}
-
-static bool ui_numedit_but_NUM(
- uiBut *but, uiHandleButtonData *data,
- int mx, const bool is_motion,
- const enum eSnapType snap, float fac)
-{
- float deler, tempf, softmin, softmax, softrange;
- int lvalue, temp;
- bool changed = false;
- const bool is_float = ui_but_is_float(but);
-
- /* prevent unwanted drag adjustments, test motion so modifier keys refresh. */
- if ((is_motion || data->draglock) &&
- (ui_but_dragedit_update_mval(data, mx) == false))
- {
- return changed;
- }
-
- softmin = but->softmin;
- softmax = but->softmax;
- softrange = softmax - softmin;
-
- if (ui_but_is_cursor_warp(but)) {
- /* Mouse location isn't screen clamped to the screen so use a linear mapping
- * 2px == 1-int, or 1px == 1-ClickStep */
- if (is_float) {
- fac *= 0.01f * but->a1;
- tempf = (float)data->startvalue + ((float)(mx - data->dragstartx) * fac);
- tempf = ui_numedit_apply_snapf(but, tempf, softmin, softmax, softrange, snap);
-
-#if 1 /* fake moving the click start, nicer for dragging back after passing the limit */
- if (tempf < softmin) {
- data->dragstartx -= (softmin - tempf) / fac;
- tempf = softmin;
- }
- else if (tempf > softmax) {
- data->dragstartx += (tempf - softmax) / fac;
- tempf = softmax;
- }
+static float ui_numedit_apply_snapf(uiBut *but,
+ float tempf,
+ float softmin,
+ float softmax,
+ float softrange,
+ const enum eSnapType snap)
+{
+ if (tempf == softmin || tempf == softmax || snap == SNAP_OFF) {
+ /* pass */
+ }
+ else {
+ float fac = 1.0f;
+
+ if (ui_but_is_unit(but)) {
+ UnitSettings *unit = but->block->unit;
+ int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
+
+ if (bUnit_IsValid(unit->system, unit_type)) {
+ fac = (float)bUnit_BaseScalar(unit->system, unit_type);
+ if (ELEM(unit_type, B_UNIT_LENGTH, B_UNIT_AREA, B_UNIT_VOLUME)) {
+ fac /= unit->scale_length;
+ }
+ }
+ }
+
+ if (fac != 1.0f) {
+ /* snap in unit-space */
+ tempf /= fac;
+ /* softmin /= fac; */ /* UNUSED */
+ /* softmax /= fac; */ /* UNUSED */
+ softrange /= fac;
+ }
+
+ /* workaround, too high snapping values */
+ /* snapping by 10's for float buttons is quite annoying (location, scale...),
+ * but allow for rotations */
+ if (softrange >= 21.0f) {
+ UnitSettings *unit = but->block->unit;
+ int unit_type = UI_but_unit_type_get(but);
+ if ((unit_type == PROP_UNIT_ROTATION) && (unit->system_rotation != USER_UNIT_ROT_RADIANS)) {
+ /* pass (degrees)*/
+ }
+ else {
+ softrange = 20.0f;
+ }
+ }
+
+ if (snap == SNAP_ON) {
+ if (softrange < 2.10f) {
+ tempf = roundf(tempf * 10.0f) * 0.1f;
+ }
+ else if (softrange < 21.0f) {
+ tempf = roundf(tempf);
+ }
+ else {
+ tempf = roundf(tempf * 0.1f) * 10.0f;
+ }
+ }
+ else if (snap == SNAP_ON_SMALL) {
+ if (softrange < 2.10f) {
+ tempf = roundf(tempf * 100.0f) * 0.01f;
+ }
+ else if (softrange < 21.0f) {
+ tempf = roundf(tempf * 10.0f) * 0.1f;
+ }
+ else {
+ tempf = roundf(tempf);
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ if (fac != 1.0f) {
+ tempf *= fac;
+ }
+ }
+
+ return tempf;
+}
+
+static float ui_numedit_apply_snap(int temp,
+ float softmin,
+ float softmax,
+ const enum eSnapType snap)
+{
+ if (temp == softmin || temp == softmax) {
+ return temp;
+ }
+
+ switch (snap) {
+ case SNAP_OFF:
+ break;
+ case SNAP_ON:
+ temp = 10 * (temp / 10);
+ break;
+ case SNAP_ON_SMALL:
+ temp = 100 * (temp / 100);
+ break;
+ }
+
+ return temp;
+}
+
+static bool ui_numedit_but_NUM(uiBut *but,
+ uiHandleButtonData *data,
+ int mx,
+ const bool is_motion,
+ const enum eSnapType snap,
+ float fac)
+{
+ float deler, tempf, softmin, softmax, softrange;
+ int lvalue, temp;
+ bool changed = false;
+ const bool is_float = ui_but_is_float(but);
+
+ /* prevent unwanted drag adjustments, test motion so modifier keys refresh. */
+ if ((is_motion || data->draglock) && (ui_but_dragedit_update_mval(data, mx) == false)) {
+ return changed;
+ }
+
+ softmin = but->softmin;
+ softmax = but->softmax;
+ softrange = softmax - softmin;
+
+ if (ui_but_is_cursor_warp(but)) {
+ /* Mouse location isn't screen clamped to the screen so use a linear mapping
+ * 2px == 1-int, or 1px == 1-ClickStep */
+ if (is_float) {
+ fac *= 0.01f * but->a1;
+ tempf = (float)data->startvalue + ((float)(mx - data->dragstartx) * fac);
+ tempf = ui_numedit_apply_snapf(but, tempf, softmin, softmax, softrange, snap);
+
+#if 1 /* fake moving the click start, nicer for dragging back after passing the limit */
+ if (tempf < softmin) {
+ data->dragstartx -= (softmin - tempf) / fac;
+ tempf = softmin;
+ }
+ else if (tempf > softmax) {
+ data->dragstartx += (tempf - softmax) / fac;
+ tempf = softmax;
+ }
#else
- CLAMP(tempf, softmin, softmax);
+ CLAMP(tempf, softmin, softmax);
#endif
- if (tempf != (float)data->value) {
- data->dragchange = true;
- data->value = tempf;
- changed = true;
- }
- }
- else {
- if (softrange > 256) { fac = 1.0; } /* 1px == 1 */
- else if (softrange > 32) { fac = 1.0 / 2.0; } /* 2px == 1 */
- else { fac = 1.0 / 16.0; } /* 16px == 1? */
-
- temp = data->startvalue + (((double)mx - data->dragstartx) * (double)fac);
- temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
-
-#if 1 /* fake moving the click start, nicer for dragging back after passing the limit */
- if (temp < softmin) {
- data->dragstartx -= (softmin - temp) / fac;
- temp = softmin;
- }
- else if (temp > softmax) {
- data->dragstartx += (temp - softmax) / fac;
- temp = softmax;
- }
+ if (tempf != (float)data->value) {
+ data->dragchange = true;
+ data->value = tempf;
+ changed = true;
+ }
+ }
+ else {
+ if (softrange > 256) {
+ fac = 1.0;
+ } /* 1px == 1 */
+ else if (softrange > 32) {
+ fac = 1.0 / 2.0;
+ } /* 2px == 1 */
+ else {
+ fac = 1.0 / 16.0;
+ } /* 16px == 1? */
+
+ temp = data->startvalue + (((double)mx - data->dragstartx) * (double)fac);
+ temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
+
+#if 1 /* fake moving the click start, nicer for dragging back after passing the limit */
+ if (temp < softmin) {
+ data->dragstartx -= (softmin - temp) / fac;
+ temp = softmin;
+ }
+ else if (temp > softmax) {
+ data->dragstartx += (temp - softmax) / fac;
+ temp = softmax;
+ }
#else
- CLAMP(temp, softmin, softmax);
+ CLAMP(temp, softmin, softmax);
#endif
- if (temp != data->value) {
- data->dragchange = true;
- data->value = temp;
- changed = true;
- }
- }
-
- data->draglastx = mx;
- }
- else {
- float non_linear_range_limit;
- float non_linear_pixel_map;
- float non_linear_scale;
-
- /* Use a non-linear mapping of the mouse drag especially for large floats
- * (normal behavior) */
- deler = 500;
- if (is_float) {
- /* not needed for smaller float buttons */
- non_linear_range_limit = 11.0f;
- non_linear_pixel_map = 500.0f;
- }
- else {
- /* only scale large int buttons */
- non_linear_range_limit = 129.0f;
- /* larger for ints, we dont need to fine tune them */
- non_linear_pixel_map = 250.0f;
-
- /* prevent large ranges from getting too out of control */
- if (softrange > 600) { deler = powf(softrange, 0.75f); }
- else if (softrange < 25) { deler = 50.0; }
- else if (softrange < 100) { deler = 100.0; }
- }
- deler /= fac;
-
- if (softrange > non_linear_range_limit) {
- non_linear_scale = (float)abs(mx - data->dragstartx) / non_linear_pixel_map;
- }
- else {
- non_linear_scale = 1.0f;
- }
-
- if (is_float == false) {
- /* at minimum, moving cursor 2 pixels should change an int button. */
- CLAMP_MIN(non_linear_scale, 0.5f * U.pixelsize);
- }
-
- data->dragf += (((float)(mx - data->draglastx)) / deler) * non_linear_scale;
-
- CLAMP(data->dragf, 0.0f, 1.0f);
- data->draglastx = mx;
- tempf = (softmin + data->dragf * softrange);
-
-
- if (!is_float) {
- temp = round_fl_to_int(tempf);
-
- temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
-
- CLAMP(temp, softmin, softmax);
- lvalue = (int)data->value;
-
- if (temp != lvalue) {
- data->dragchange = true;
- data->value = (double)temp;
- changed = true;
- }
- }
- else {
- temp = 0;
- tempf = ui_numedit_apply_snapf(but, tempf, softmin, softmax, softrange, snap);
-
- CLAMP(tempf, softmin, softmax);
-
- if (tempf != (float)data->value) {
- data->dragchange = true;
- data->value = tempf;
- changed = true;
- }
- }
- }
-
-
- return changed;
+ if (temp != data->value) {
+ data->dragchange = true;
+ data->value = temp;
+ changed = true;
+ }
+ }
+
+ data->draglastx = mx;
+ }
+ else {
+ float non_linear_range_limit;
+ float non_linear_pixel_map;
+ float non_linear_scale;
+
+ /* Use a non-linear mapping of the mouse drag especially for large floats
+ * (normal behavior) */
+ deler = 500;
+ if (is_float) {
+ /* not needed for smaller float buttons */
+ non_linear_range_limit = 11.0f;
+ non_linear_pixel_map = 500.0f;
+ }
+ else {
+ /* only scale large int buttons */
+ non_linear_range_limit = 129.0f;
+ /* larger for ints, we dont need to fine tune them */
+ non_linear_pixel_map = 250.0f;
+
+ /* prevent large ranges from getting too out of control */
+ if (softrange > 600) {
+ deler = powf(softrange, 0.75f);
+ }
+ else if (softrange < 25) {
+ deler = 50.0;
+ }
+ else if (softrange < 100) {
+ deler = 100.0;
+ }
+ }
+ deler /= fac;
+
+ if (softrange > non_linear_range_limit) {
+ non_linear_scale = (float)abs(mx - data->dragstartx) / non_linear_pixel_map;
+ }
+ else {
+ non_linear_scale = 1.0f;
+ }
+
+ if (is_float == false) {
+ /* at minimum, moving cursor 2 pixels should change an int button. */
+ CLAMP_MIN(non_linear_scale, 0.5f * U.pixelsize);
+ }
+
+ data->dragf += (((float)(mx - data->draglastx)) / deler) * non_linear_scale;
+
+ CLAMP(data->dragf, 0.0f, 1.0f);
+ data->draglastx = mx;
+ tempf = (softmin + data->dragf * softrange);
+
+ if (!is_float) {
+ temp = round_fl_to_int(tempf);
+
+ temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
+
+ CLAMP(temp, softmin, softmax);
+ lvalue = (int)data->value;
+
+ if (temp != lvalue) {
+ data->dragchange = true;
+ data->value = (double)temp;
+ changed = true;
+ }
+ }
+ else {
+ temp = 0;
+ tempf = ui_numedit_apply_snapf(but, tempf, softmin, softmax, softrange, snap);
+
+ CLAMP(tempf, softmin, softmax);
+
+ if (tempf != (float)data->value) {
+ data->dragchange = true;
+ data->value = tempf;
+ changed = true;
+ }
+ }
+ }
+
+ return changed;
}
static void ui_numedit_set_active(uiBut *but)
{
- int oldflag = but->drawflag;
- but->drawflag &= ~(UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT);
-
- uiHandleButtonData *data = but->active;
- if (!data) {
- return;
- }
-
- /* Ignore once we start dragging. */
- if (data->dragchange == false) {
- const float handle_width = min_ff(BLI_rctf_size_x(&but->rect) / 3, BLI_rctf_size_y(&but->rect) * 0.7f);
- /* we can click on the side arrows to increment/decrement,
- * or click inside to edit the value directly */
- int mx = data->window->eventstate->x;
- int my = data->window->eventstate->y;
- ui_window_to_block(data->region, but->block, &mx, &my);
-
- if (mx < (but->rect.xmin + handle_width)) {
- but->drawflag |= UI_BUT_ACTIVE_LEFT;
- }
- else if (mx > (but->rect.xmax - handle_width)) {
- but->drawflag |= UI_BUT_ACTIVE_RIGHT;
- }
- }
-
- /* Don't change the cursor once pressed. */
- if ((but->flag & UI_SELECT) == 0) {
- if ((but->drawflag & (UI_BUT_ACTIVE_LEFT)) || (but->drawflag & (UI_BUT_ACTIVE_RIGHT))) {
- if (data->changed_cursor) {
- WM_cursor_modal_restore(data->window);
- data->changed_cursor = false;
- }
- }
- else {
- if (data->changed_cursor == false) {
- WM_cursor_modal_set(data->window, CURSOR_X_MOVE);
- data->changed_cursor = true;
- }
- }
- }
-
- if (but->drawflag != oldflag) {
- ED_region_tag_redraw(data->region);
- }
+ int oldflag = but->drawflag;
+ but->drawflag &= ~(UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT);
+
+ uiHandleButtonData *data = but->active;
+ if (!data) {
+ return;
+ }
+
+ /* Ignore once we start dragging. */
+ if (data->dragchange == false) {
+ const float handle_width = min_ff(BLI_rctf_size_x(&but->rect) / 3,
+ BLI_rctf_size_y(&but->rect) * 0.7f);
+ /* we can click on the side arrows to increment/decrement,
+ * or click inside to edit the value directly */
+ int mx = data->window->eventstate->x;
+ int my = data->window->eventstate->y;
+ ui_window_to_block(data->region, but->block, &mx, &my);
+
+ if (mx < (but->rect.xmin + handle_width)) {
+ but->drawflag |= UI_BUT_ACTIVE_LEFT;
+ }
+ else if (mx > (but->rect.xmax - handle_width)) {
+ but->drawflag |= UI_BUT_ACTIVE_RIGHT;
+ }
+ }
+
+ /* Don't change the cursor once pressed. */
+ if ((but->flag & UI_SELECT) == 0) {
+ if ((but->drawflag & (UI_BUT_ACTIVE_LEFT)) || (but->drawflag & (UI_BUT_ACTIVE_RIGHT))) {
+ if (data->changed_cursor) {
+ WM_cursor_modal_restore(data->window);
+ data->changed_cursor = false;
+ }
+ }
+ else {
+ if (data->changed_cursor == false) {
+ WM_cursor_modal_set(data->window, CURSOR_X_MOVE);
+ data->changed_cursor = true;
+ }
+ }
+ }
+
+ if (but->drawflag != oldflag) {
+ ED_region_tag_redraw(data->region);
+ }
}
static int ui_do_but_NUM(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my; /* mouse location scaled to fit the UI */
- int screen_mx, screen_my; /* mouse location kept at screen pixel coords */
- int click = 0;
- int retval = WM_UI_HANDLER_CONTINUE;
-
- mx = screen_mx = event->x;
- my = screen_my = event->y;
-
- ui_window_to_block(data->region, block, &mx, &my);
- ui_numedit_set_active(but);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- int type = event->type, val = event->val;
-
- if (type == MOUSEPAN) {
- ui_pan_to_scroll(event, &type, &val);
- }
-
- /* XXX hardcoded keymap check.... */
- if (type == MOUSEPAN && event->alt) {
- /* allow accumulating values, otherwise scrolling gets preference */
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (type == WHEELDOWNMOUSE && event->ctrl) {
- mx = but->rect.xmin;
- but->drawflag &= ~UI_BUT_ACTIVE_RIGHT;
- but->drawflag |= UI_BUT_ACTIVE_LEFT;
- click = 1;
- }
- else if (type == WHEELUPMOUSE && event->ctrl) {
- mx = but->rect.xmax;
- but->drawflag &= ~UI_BUT_ACTIVE_LEFT;
- but->drawflag |= UI_BUT_ACTIVE_RIGHT;
- click = 1;
- }
- else if (event->val == KM_PRESS) {
- if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->ctrl) {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (event->type == LEFTMOUSE) {
- data->dragstartx = data->draglastx = ui_but_is_cursor_warp(but) ? screen_mx : mx;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
- click = 1;
- }
- else if (event->type == MINUSKEY && event->val == KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- data->value = -data->value;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- }
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my; /* mouse location scaled to fit the UI */
+ int screen_mx, screen_my; /* mouse location kept at screen pixel coords */
+ int click = 0;
+ int retval = WM_UI_HANDLER_CONTINUE;
+
+ mx = screen_mx = event->x;
+ my = screen_my = event->y;
+
+ ui_window_to_block(data->region, block, &mx, &my);
+ ui_numedit_set_active(but);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
+ /* XXX hardcoded keymap check.... */
+ if (type == MOUSEPAN && event->alt) {
+ /* allow accumulating values, otherwise scrolling gets preference */
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (type == WHEELDOWNMOUSE && event->ctrl) {
+ mx = but->rect.xmin;
+ but->drawflag &= ~UI_BUT_ACTIVE_RIGHT;
+ but->drawflag |= UI_BUT_ACTIVE_LEFT;
+ click = 1;
+ }
+ else if (type == WHEELUPMOUSE && event->ctrl) {
+ mx = but->rect.xmax;
+ but->drawflag &= ~UI_BUT_ACTIVE_LEFT;
+ but->drawflag |= UI_BUT_ACTIVE_RIGHT;
+ click = 1;
+ }
+ else if (event->val == KM_PRESS) {
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->ctrl) {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (event->type == LEFTMOUSE) {
+ data->dragstartx = data->draglastx = ui_but_is_cursor_warp(but) ? screen_mx : mx;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ click = 1;
+ }
+ else if (event->type == MINUSKEY && event->val == KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ data->value = -data->value;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ }
#ifdef USE_DRAG_MULTINUM
- copy_v2_v2_int(data->multi_data.drag_start, &event->x);
+ copy_v2_v2_int(data->multi_data.drag_start, &event->x);
#endif
- }
-
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if (data->dragchange) {
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
- /* if we started multibutton but didn't drag, then edit */
- if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
- click = 1;
- }
- else
+ /* if we started multibutton but didn't drag, then edit */
+ if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ click = 1;
+ }
+ else
#endif
- {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else {
- click = 1;
- }
- }
- else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
- const bool is_motion = (event->type == MOUSEMOVE);
- const enum eSnapType snap = ui_event_to_snap(event);
- float fac;
+ {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else {
+ click = 1;
+ }
+ }
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ const bool is_motion = (event->type == MOUSEMOVE);
+ const enum eSnapType snap = ui_event_to_snap(event);
+ float fac;
#ifdef USE_DRAG_MULTINUM
- data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
- data->multi_data.drag_dir[1] += abs(data->draglasty - my);
+ data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
+ data->multi_data.drag_dir[1] += abs(data->draglasty - my);
#endif
- fac = 1.0f;
- if (event->shift) {
- fac /= 10.0f;
- }
+ fac = 1.0f;
+ if (event->shift) {
+ fac /= 10.0f;
+ }
- if (ui_numedit_but_NUM(but, data, (ui_but_is_cursor_warp(but) ? screen_mx : mx), is_motion, snap, fac)) {
- ui_numedit_apply(C, block, but, data);
- }
+ if (ui_numedit_but_NUM(
+ but, data, (ui_but_is_cursor_warp(but) ? screen_mx : mx), is_motion, snap, fac)) {
+ ui_numedit_apply(C, block, but, data);
+ }
#ifdef USE_DRAG_MULTINUM
- else if (data->multi_data.has_mbuts) {
- if (data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) {
- ui_multibut_states_apply(C, data, block);
- }
- }
+ else if (data->multi_data.has_mbuts) {
+ if (data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) {
+ ui_multibut_states_apply(C, data, block);
+ }
+ }
#endif
- }
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (data->state == BUTTON_STATE_TEXT_EDITING) {
- ui_do_but_textedit(C, block, but, data, event);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
- ui_do_but_textedit_select(C, block, but, data, event);
- retval = WM_UI_HANDLER_BREAK;
- }
-
- if (click) {
- /* we can click on the side arrows to increment/decrement,
- * or click inside to edit the value directly */
- float tempf, softmin, softmax;
- int temp;
-
- softmin = but->softmin;
- softmax = but->softmax;
-
- if (!ui_but_is_float(but)) {
- if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- temp = (int)data->value - 1;
- if (temp >= softmin && temp <= softmax) {
- data->value = (double)temp;
- }
- else {
- data->cancel = true;
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- temp = (int)data->value + 1;
- if (temp >= softmin && temp <= softmax) {
- data->value = (double)temp;
- }
- else {
- data->cancel = true;
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- }
- }
- else {
- if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- tempf = (float)data->value - (UI_PRECISION_FLOAT_SCALE * but->a1);
- if (tempf < softmin) {
- tempf = softmin;
- }
- data->value = tempf;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- tempf = (float)data->value + (UI_PRECISION_FLOAT_SCALE * but->a1);
- if (tempf > softmax) {
- tempf = softmax;
- }
- data->value = tempf;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- }
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
-
- data->draglastx = mx;
- data->draglasty = my;
-
- return retval;
-}
-
-static bool ui_numedit_but_SLI(
- uiBut *but, uiHandleButtonData *data,
- int mx, const bool is_horizontal, const bool is_motion,
- const bool snap, const bool shift)
-{
- float cursor_x_range, f, tempf, softmin, softmax, softrange;
- int temp, lvalue;
- bool changed = false;
- float mx_fl, my_fl;
-
- /* prevent unwanted drag adjustments, test motion so modifier keys refresh. */
- if ((but->type != UI_BTYPE_SCROLL) &&
- (is_motion || data->draglock) &&
- (ui_but_dragedit_update_mval(data, mx) == false))
- {
- return changed;
- }
-
- softmin = but->softmin;
- softmax = but->softmax;
- softrange = softmax - softmin;
-
- /* yes, 'mx' as both x/y is intentional */
- ui_mouse_scale_warp(data, mx, mx, &mx_fl, &my_fl, shift);
-
- if (but->type == UI_BTYPE_NUM_SLIDER) {
- cursor_x_range = BLI_rctf_size_x(&but->rect);
- }
- else if (but->type == UI_BTYPE_SCROLL) {
- const float size = (is_horizontal) ? BLI_rctf_size_x(&but->rect) : -BLI_rctf_size_y(&but->rect);
- cursor_x_range = size * (but->softmax - but->softmin) / (but->softmax - but->softmin + but->a1);
- }
- else {
- float offs = (BLI_rctf_size_y(&but->rect) / 2.0f);
- cursor_x_range = (BLI_rctf_size_x(&but->rect) - offs);
- }
-
- f = (mx_fl - data->dragstartx) / cursor_x_range + data->dragfstart;
- CLAMP(f, 0.0f, 1.0f);
-
-
- /* deal with mouse correction */
+ }
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_TEXT_EDITING) {
+ ui_do_but_textedit(C, block, but, data, event);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
+ ui_do_but_textedit_select(C, block, but, data, event);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ if (click) {
+ /* we can click on the side arrows to increment/decrement,
+ * or click inside to edit the value directly */
+ float tempf, softmin, softmax;
+ int temp;
+
+ softmin = but->softmin;
+ softmax = but->softmax;
+
+ if (!ui_but_is_float(but)) {
+ if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ temp = (int)data->value - 1;
+ if (temp >= softmin && temp <= softmax) {
+ data->value = (double)temp;
+ }
+ else {
+ data->cancel = true;
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ temp = (int)data->value + 1;
+ if (temp >= softmin && temp <= softmax) {
+ data->value = (double)temp;
+ }
+ else {
+ data->cancel = true;
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ }
+ }
+ else {
+ if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ tempf = (float)data->value - (UI_PRECISION_FLOAT_SCALE * but->a1);
+ if (tempf < softmin) {
+ tempf = softmin;
+ }
+ data->value = tempf;
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ tempf = (float)data->value + (UI_PRECISION_FLOAT_SCALE * but->a1);
+ if (tempf > softmax) {
+ tempf = softmax;
+ }
+ data->value = tempf;
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ }
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ data->draglastx = mx;
+ data->draglasty = my;
+
+ return retval;
+}
+
+static bool ui_numedit_but_SLI(uiBut *but,
+ uiHandleButtonData *data,
+ int mx,
+ const bool is_horizontal,
+ const bool is_motion,
+ const bool snap,
+ const bool shift)
+{
+ float cursor_x_range, f, tempf, softmin, softmax, softrange;
+ int temp, lvalue;
+ bool changed = false;
+ float mx_fl, my_fl;
+
+ /* prevent unwanted drag adjustments, test motion so modifier keys refresh. */
+ if ((but->type != UI_BTYPE_SCROLL) && (is_motion || data->draglock) &&
+ (ui_but_dragedit_update_mval(data, mx) == false)) {
+ return changed;
+ }
+
+ softmin = but->softmin;
+ softmax = but->softmax;
+ softrange = softmax - softmin;
+
+ /* yes, 'mx' as both x/y is intentional */
+ ui_mouse_scale_warp(data, mx, mx, &mx_fl, &my_fl, shift);
+
+ if (but->type == UI_BTYPE_NUM_SLIDER) {
+ cursor_x_range = BLI_rctf_size_x(&but->rect);
+ }
+ else if (but->type == UI_BTYPE_SCROLL) {
+ const float size = (is_horizontal) ? BLI_rctf_size_x(&but->rect) :
+ -BLI_rctf_size_y(&but->rect);
+ cursor_x_range = size * (but->softmax - but->softmin) /
+ (but->softmax - but->softmin + but->a1);
+ }
+ else {
+ float offs = (BLI_rctf_size_y(&but->rect) / 2.0f);
+ cursor_x_range = (BLI_rctf_size_x(&but->rect) - offs);
+ }
+
+ f = (mx_fl - data->dragstartx) / cursor_x_range + data->dragfstart;
+ CLAMP(f, 0.0f, 1.0f);
+
+ /* deal with mouse correction */
#ifdef USE_CONT_MOUSE_CORRECT
- if (ui_but_is_cursor_warp(but)) {
- /* OK but can go outside bounds */
- if (is_horizontal) {
- data->ungrab_mval[0] = but->rect.xmin + (f * cursor_x_range);
- data->ungrab_mval[1] = BLI_rctf_cent_y(&but->rect);
- }
- else {
- data->ungrab_mval[1] = but->rect.ymin + (f * cursor_x_range);
- data->ungrab_mval[0] = BLI_rctf_cent_x(&but->rect);
- }
- BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
- }
+ if (ui_but_is_cursor_warp(but)) {
+ /* OK but can go outside bounds */
+ if (is_horizontal) {
+ data->ungrab_mval[0] = but->rect.xmin + (f * cursor_x_range);
+ data->ungrab_mval[1] = BLI_rctf_cent_y(&but->rect);
+ }
+ else {
+ data->ungrab_mval[1] = but->rect.ymin + (f * cursor_x_range);
+ data->ungrab_mval[0] = BLI_rctf_cent_x(&but->rect);
+ }
+ BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+ }
#endif
- /* done correcting mouse */
-
-
- tempf = softmin + f * softrange;
- temp = round_fl_to_int(tempf);
-
- if (snap) {
- if (tempf == softmin || tempf == softmax) {
- /* pass */
- }
- else if (ui_but_is_float(but)) {
-
- if (shift) {
- if (tempf == softmin || tempf == softmax) {}
- else if (softrange < 2.10f) { tempf = roundf(tempf * 100.0f) * 0.01f; }
- else if (softrange < 21.0f) { tempf = roundf(tempf * 10.0f) * 0.1f; }
- else { tempf = roundf(tempf); }
- }
- else {
- if (softrange < 2.10f) { tempf = roundf(tempf * 10.0f) * 0.1f; }
- else if (softrange < 21.0f) { tempf = roundf(tempf); }
- else { tempf = roundf(tempf * 0.1f) * 10.0f; }
- }
- }
- else {
- temp = 10 * (temp / 10);
- tempf = temp;
- }
- }
-
- if (!ui_but_is_float(but)) {
- lvalue = round(data->value);
-
- CLAMP(temp, softmin, softmax);
-
- if (temp != lvalue) {
- data->value = temp;
- data->dragchange = true;
- changed = true;
- }
- }
- else {
- CLAMP(tempf, softmin, softmax);
-
- if (tempf != (float)data->value) {
- data->value = tempf;
- data->dragchange = true;
- changed = true;
- }
- }
-
- return changed;
+ /* done correcting mouse */
+
+ tempf = softmin + f * softrange;
+ temp = round_fl_to_int(tempf);
+
+ if (snap) {
+ if (tempf == softmin || tempf == softmax) {
+ /* pass */
+ }
+ else if (ui_but_is_float(but)) {
+
+ if (shift) {
+ if (tempf == softmin || tempf == softmax) {
+ }
+ else if (softrange < 2.10f) {
+ tempf = roundf(tempf * 100.0f) * 0.01f;
+ }
+ else if (softrange < 21.0f) {
+ tempf = roundf(tempf * 10.0f) * 0.1f;
+ }
+ else {
+ tempf = roundf(tempf);
+ }
+ }
+ else {
+ if (softrange < 2.10f) {
+ tempf = roundf(tempf * 10.0f) * 0.1f;
+ }
+ else if (softrange < 21.0f) {
+ tempf = roundf(tempf);
+ }
+ else {
+ tempf = roundf(tempf * 0.1f) * 10.0f;
+ }
+ }
+ }
+ else {
+ temp = 10 * (temp / 10);
+ tempf = temp;
+ }
+ }
+
+ if (!ui_but_is_float(but)) {
+ lvalue = round(data->value);
+
+ CLAMP(temp, softmin, softmax);
+
+ if (temp != lvalue) {
+ data->value = temp;
+ data->dragchange = true;
+ changed = true;
+ }
+ }
+ else {
+ CLAMP(tempf, softmin, softmax);
+
+ if (tempf != (float)data->value) {
+ data->value = tempf;
+ data->dragchange = true;
+ changed = true;
+ }
+ }
+
+ return changed;
}
static int ui_do_but_SLI(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my, click = 0;
- int retval = WM_UI_HANDLER_CONTINUE;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- int type = event->type, val = event->val;
-
- if (type == MOUSEPAN) {
- ui_pan_to_scroll(event, &type, &val);
- }
-
- /* XXX hardcoded keymap check.... */
- if (type == MOUSEPAN && event->alt) {
- /* allow accumulating values, otherwise scrolling gets preference */
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (type == WHEELDOWNMOUSE && event->ctrl) {
- mx = but->rect.xmin;
- click = 2;
- }
- else if (type == WHEELUPMOUSE && event->ctrl) {
- mx = but->rect.xmax;
- click = 2;
- }
- else if (event->val == KM_PRESS) {
- if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->ctrl) {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my, click = 0;
+ int retval = WM_UI_HANDLER_CONTINUE;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
+ /* XXX hardcoded keymap check.... */
+ if (type == MOUSEPAN && event->alt) {
+ /* allow accumulating values, otherwise scrolling gets preference */
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (type == WHEELDOWNMOUSE && event->ctrl) {
+ mx = but->rect.xmin;
+ click = 2;
+ }
+ else if (type == WHEELUPMOUSE && event->ctrl) {
+ mx = but->rect.xmax;
+ click = 2;
+ }
+ else if (event->val == KM_PRESS) {
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->ctrl) {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
#ifndef USE_ALLSELECT
- /* alt-click on sides to get "arrows" like in UI_BTYPE_NUM buttons,
- * and match wheel usage above */
- else if (event->type == LEFTMOUSE && event->alt) {
- int halfpos = BLI_rctf_cent_x(&but->rect);
- click = 2;
- if (mx < halfpos) {
- mx = but->rect.xmin;
- }
- else {
- mx = but->rect.xmax;
- }
- }
+ /* alt-click on sides to get "arrows" like in UI_BTYPE_NUM buttons,
+ * and match wheel usage above */
+ else if (event->type == LEFTMOUSE && event->alt) {
+ int halfpos = BLI_rctf_cent_x(&but->rect);
+ click = 2;
+ if (mx < halfpos) {
+ mx = but->rect.xmin;
+ }
+ else {
+ mx = but->rect.xmax;
+ }
+ }
#endif
- else if (event->type == LEFTMOUSE) {
- data->dragstartx = mx;
- data->draglastx = mx;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
- click = 1;
- }
- else if (event->type == MINUSKEY && event->val == KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- data->value = -data->value;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
+ else if (event->type == LEFTMOUSE) {
+ data->dragstartx = mx;
+ data->draglastx = mx;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ click = 1;
+ }
+ else if (event->type == MINUSKEY && event->val == KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ data->value = -data->value;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
#ifdef USE_DRAG_MULTINUM
- copy_v2_v2_int(data->multi_data.drag_start, &event->x);
+ copy_v2_v2_int(data->multi_data.drag_start, &event->x);
#endif
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if (data->dragchange) {
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ if (data->dragchange) {
#ifdef USE_DRAG_MULTINUM
- /* if we started multibutton but didn't drag, then edit */
- if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
- click = 1;
- }
- else
+ /* if we started multibutton but didn't drag, then edit */
+ if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ click = 1;
+ }
+ else
#endif
- {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else {
+ {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else {
#ifdef USE_CONT_MOUSE_CORRECT
- /* reset! */
- copy_v2_fl(data->ungrab_mval, FLT_MAX);
+ /* reset! */
+ copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- click = 1;
- }
- }
- else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
- const bool is_motion = (event->type == MOUSEMOVE);
+ click = 1;
+ }
+ }
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ const bool is_motion = (event->type == MOUSEMOVE);
#ifdef USE_DRAG_MULTINUM
- data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
- data->multi_data.drag_dir[1] += abs(data->draglasty - my);
+ data->multi_data.drag_dir[0] += abs(data->draglastx - mx);
+ data->multi_data.drag_dir[1] += abs(data->draglasty - my);
#endif
- if (ui_numedit_but_SLI(but, data, mx, true, is_motion, event->ctrl != 0, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
+ if (ui_numedit_but_SLI(
+ but, data, mx, true, is_motion, event->ctrl != 0, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
#ifdef USE_DRAG_MULTINUM
- else if (data->multi_data.has_mbuts) {
- if (data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) {
- ui_multibut_states_apply(C, data, block);
- }
- }
+ else if (data->multi_data.has_mbuts) {
+ if (data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) {
+ ui_multibut_states_apply(C, data, block);
+ }
+ }
#endif
- }
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (data->state == BUTTON_STATE_TEXT_EDITING) {
- ui_do_but_textedit(C, block, but, data, event);
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
- ui_do_but_textedit_select(C, block, but, data, event);
- retval = WM_UI_HANDLER_BREAK;
- }
-
- if (click) {
- if (click == 2) {
- /* nudge slider to the left or right */
- float f, tempf, softmin, softmax, softrange;
- int temp;
-
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- softmin = but->softmin;
- softmax = but->softmax;
- softrange = softmax - softmin;
-
- tempf = data->value;
- temp = (int)data->value;
+ }
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_TEXT_EDITING) {
+ ui_do_but_textedit(C, block, but, data, event);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_TEXT_SELECTING) {
+ ui_do_but_textedit_select(C, block, but, data, event);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ if (click) {
+ if (click == 2) {
+ /* nudge slider to the left or right */
+ float f, tempf, softmin, softmax, softrange;
+ int temp;
+
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ softmin = but->softmin;
+ softmax = but->softmax;
+ softrange = softmax - softmin;
+
+ tempf = data->value;
+ temp = (int)data->value;
#if 0
- if (but->type == SLI) {
- /* same as below */
- f = (float)(mx - but->rect.xmin) / (BLI_rctf_size_x(&but->rect));
- }
- else
+ if (but->type == SLI) {
+ /* same as below */
+ f = (float)(mx - but->rect.xmin) / (BLI_rctf_size_x(&but->rect));
+ }
+ else
#endif
- {
- f = (float)(mx - but->rect.xmin) / (BLI_rctf_size_x(&but->rect));
- }
-
- f = softmin + f * softrange;
-
- if (!ui_but_is_float(but)) {
- if (f < temp) {
- temp--;
- }
- else {
- temp++;
- }
-
- if (temp >= softmin && temp <= softmax) {
- data->value = temp;
- }
- else {
- data->cancel = true;
- }
- }
- else {
- if (f < tempf) {
- tempf -= 0.01f;
- }
- else {
- tempf += 0.01f;
- }
-
- if (tempf >= softmin && tempf <= softmax) {
- data->value = tempf;
- }
- else {
- data->cancel = true;
- }
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- }
- else {
- /* edit the value directly */
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
-
- data->draglastx = mx;
- data->draglasty = my;
-
- return retval;
+ {
+ f = (float)(mx - but->rect.xmin) / (BLI_rctf_size_x(&but->rect));
+ }
+
+ f = softmin + f * softrange;
+
+ if (!ui_but_is_float(but)) {
+ if (f < temp) {
+ temp--;
+ }
+ else {
+ temp++;
+ }
+
+ if (temp >= softmin && temp <= softmax) {
+ data->value = temp;
+ }
+ else {
+ data->cancel = true;
+ }
+ }
+ else {
+ if (f < tempf) {
+ tempf -= 0.01f;
+ }
+ else {
+ tempf += 0.01f;
+ }
+
+ if (tempf >= softmin && tempf <= softmax) {
+ data->value = tempf;
+ }
+ else {
+ data->cancel = true;
+ }
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else {
+ /* edit the value directly */
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ data->draglastx = mx;
+ data->draglasty = my;
+
+ return retval;
}
static int ui_do_but_SCROLL(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my /*, click = 0 */;
- int retval = WM_UI_HANDLER_CONTINUE;
- bool horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->val == KM_PRESS) {
- if (event->type == LEFTMOUSE) {
- if (horizontal) {
- data->dragstartx = mx;
- data->draglastx = mx;
- }
- else {
- data->dragstartx = my;
- data->draglastx = my;
- }
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
- /* UNUSED - otherwise code is ok, add back if needed */
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my /*, click = 0 */;
+ int retval = WM_UI_HANDLER_CONTINUE;
+ bool horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect));
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->val == KM_PRESS) {
+ if (event->type == LEFTMOUSE) {
+ if (horizontal) {
+ data->dragstartx = mx;
+ data->draglastx = mx;
+ }
+ else {
+ data->dragstartx = my;
+ data->draglastx = my;
+ }
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ /* UNUSED - otherwise code is ok, add back if needed */
#if 0
- else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
- click = 1;
- }
+ else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ click = 1;
+ }
#endif
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (event->type == MOUSEMOVE) {
- const bool is_motion = (event->type == MOUSEMOVE);
- if (ui_numedit_but_SLI(but, data, (horizontal) ? mx : my, horizontal, is_motion, false, false)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
-
- return retval;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if (event->type == MOUSEMOVE) {
+ const bool is_motion = (event->type == MOUSEMOVE);
+ if (ui_numedit_but_SLI(
+ but, data, (horizontal) ? mx : my, horizontal, is_motion, false, false)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ return retval;
}
static int ui_do_but_GRIP(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my;
- int retval = WM_UI_HANDLER_CONTINUE;
- const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
-
- /* Note: Having to store org point in window space and recompute it to block "space" each time
- * is not ideal, but this is a way to hack around behavior of ui_window_to_block(), which
- * returns different results when the block is inside a panel or not...
- * See T37739.
- */
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->val == KM_PRESS) {
- if (event->type == LEFTMOUSE) {
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (event->type == MOUSEMOVE) {
- int dragstartx = data->dragstartx;
- int dragstarty = data->dragstarty;
- ui_window_to_block(data->region, block, &dragstartx, &dragstarty);
- data->value = data->origvalue + (horizontal ? mx - dragstartx : dragstarty - my);
- ui_numedit_apply(C, block, but, data);
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
-
- return retval;
-}
-
-static int ui_do_but_LISTROW(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- /* hack to pass on ctrl+click and double click to overlapping text
- * editing field for editing list item names
- */
- if ((ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS && event->ctrl) ||
- (event->type == LEFTMOUSE && event->val == KM_DBL_CLICK))
- {
- uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_TEXT_EDITING);
- if (labelbut) {
- /* Nothing else to do. */
- return WM_UI_HANDLER_BREAK;
- }
- }
- }
-
- return ui_do_but_EXIT(C, but, data, event);
-}
-
-static int ui_do_but_BLOCK(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
-
- /* first handle click on icondrag type button */
- if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
- if (ui_but_contains_point_px_icon(but, data->region, event)) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- return WM_UI_HANDLER_BREAK;
- }
- }
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my;
+ int retval = WM_UI_HANDLER_CONTINUE;
+ const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
+
+ /* Note: Having to store org point in window space and recompute it to block "space" each time
+ * is not ideal, but this is a way to hack around behavior of ui_window_to_block(), which
+ * returns different results when the block is inside a panel or not...
+ * See T37739.
+ */
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->val == KM_PRESS) {
+ if (event->type == LEFTMOUSE) {
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if (event->type == MOUSEMOVE) {
+ int dragstartx = data->dragstartx;
+ int dragstarty = data->dragstarty;
+ ui_window_to_block(data->region, block, &dragstartx, &dragstarty);
+ data->value = data->origvalue + (horizontal ? mx - dragstartx : dragstarty - my);
+ ui_numedit_apply(C, block, but, data);
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ return retval;
+}
+
+static int ui_do_but_LISTROW(bContext *C,
+ uiBut *but,
+ uiHandleButtonData *data,
+ const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ /* hack to pass on ctrl+click and double click to overlapping text
+ * editing field for editing list item names
+ */
+ if ((ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS &&
+ event->ctrl) ||
+ (event->type == LEFTMOUSE && event->val == KM_DBL_CLICK)) {
+ uiBut *labelbut = ui_but_list_row_text_activate(
+ C, but, data, event, BUTTON_ACTIVATE_TEXT_EDITING);
+ if (labelbut) {
+ /* Nothing else to do. */
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+
+ return ui_do_but_EXIT(C, but, data, event);
+}
+
+static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+
+ /* first handle click on icondrag type button */
+ if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
+ if (ui_but_contains_point_px_icon(but, data->region, event)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
#ifdef USE_DRAG_TOGGLE
- if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_but_is_drag_toggle(but))) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- return WM_UI_HANDLER_BREAK;
- }
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS && (ui_but_is_drag_toggle(but))) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_BREAK;
+ }
#endif
- /* regular open menu */
- if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
- button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
- return WM_UI_HANDLER_BREAK;
- }
- else if (but->type == UI_BTYPE_MENU) {
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
-
- data->value = ui_but_menu_step(but, direction);
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_but(C, but->block, but, data, true);
-
- /* button's state need to be changed to EXIT so moving mouse away from this mouse wouldn't lead
- * to cancel changes made to this button, but changing state to EXIT also makes no button active for
- * a while which leads to triggering operator when doing fast scrolling mouse wheel.
- * using post activate stuff from button allows to make button be active again after checking for all
- * all that mouse leave and cancel stuff, so quick scroll wouldn't be an issue anymore.
- * same goes for scrolling wheel in another direction below (sergey)
- */
- data->postbut = but;
- data->posttype = BUTTON_ACTIVATE_OVER;
-
- /* without this, a new interface that draws as result of the menu change
- * won't register that the mouse is over it, eg:
- * Alt+MouseWheel over the render slots, without this,
- * the slot menu fails to switch a second time.
- *
- * The active state of the button could be maintained some other way
- * and remove this mousemove event.
- */
- WM_event_add_mousemove(C);
-
- return WM_UI_HANDLER_BREAK;
- }
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_DRAG) {
-
- /* this function also ends state */
- if (ui_but_drag_init(C, but, data, event)) {
- return WM_UI_HANDLER_BREAK;
- }
-
- /* outside icon quit, not needed if drag activated */
- if (0 == ui_but_contains_point_px_icon(but, data->region, event)) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- data->cancel = true;
- return WM_UI_HANDLER_BREAK;
- }
-
- if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
- return WM_UI_HANDLER_BREAK;
- }
-
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ /* regular open menu */
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (but->type == UI_BTYPE_MENU) {
+ if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
+
+ data->value = ui_but_menu_step(but, direction);
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_but(C, but->block, but, data, true);
+
+ /* button's state need to be changed to EXIT so moving mouse away from this mouse wouldn't lead
+ * to cancel changes made to this button, but changing state to EXIT also makes no button active for
+ * a while which leads to triggering operator when doing fast scrolling mouse wheel.
+ * using post activate stuff from button allows to make button be active again after checking for all
+ * all that mouse leave and cancel stuff, so quick scroll wouldn't be an issue anymore.
+ * same goes for scrolling wheel in another direction below (sergey)
+ */
+ data->postbut = but;
+ data->posttype = BUTTON_ACTIVATE_OVER;
+
+ /* without this, a new interface that draws as result of the menu change
+ * won't register that the mouse is over it, eg:
+ * Alt+MouseWheel over the render slots, without this,
+ * the slot menu fails to switch a second time.
+ *
+ * The active state of the button could be maintained some other way
+ * and remove this mousemove event.
+ */
+ WM_event_add_mousemove(C);
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_DRAG) {
+
+ /* this function also ends state */
+ if (ui_but_drag_init(C, but, data, event)) {
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ /* outside icon quit, not needed if drag activated */
+ if (0 == ui_but_contains_point_px_icon(but, data->region, event)) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ data->cancel = true;
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
static bool ui_numedit_but_UNITVEC(
- uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const enum eSnapType snap)
-{
- float dx, dy, rad, radsq, mrad, *fp;
- int mdx, mdy;
- bool changed = true;
-
- /* button is presumed square */
- /* if mouse moves outside of sphere, it does negative normal */
-
- /* note that both data->vec and data->origvec should be normalized
- * else we'll get a harmless but annoying jump when first clicking */
-
- fp = data->origvec;
- rad = BLI_rctf_size_x(&but->rect);
- radsq = rad * rad;
-
- if (fp[2] > 0.0f) {
- mdx = (rad * fp[0]);
- mdy = (rad * fp[1]);
- }
- else if (fp[2] > -1.0f) {
- mrad = rad / sqrtf(fp[0] * fp[0] + fp[1] * fp[1]);
-
- mdx = 2.0f * mrad * fp[0] - (rad * fp[0]);
- mdy = 2.0f * mrad * fp[1] - (rad * fp[1]);
- }
- else {
- mdx = mdy = 0;
- }
-
- dx = (float)(mx + mdx - data->dragstartx);
- dy = (float)(my + mdy - data->dragstarty);
-
- fp = data->vec;
- mrad = dx * dx + dy * dy;
- if (mrad < radsq) { /* inner circle */
- fp[0] = dx;
- fp[1] = dy;
- fp[2] = sqrtf(radsq - dx * dx - dy * dy);
- }
- else { /* outer circle */
-
- mrad = rad / sqrtf(mrad); // veclen
-
- dx *= (2.0f * mrad - 1.0f);
- dy *= (2.0f * mrad - 1.0f);
-
- mrad = dx * dx + dy * dy;
- if (mrad < radsq) {
- fp[0] = dx;
- fp[1] = dy;
- fp[2] = -sqrtf(radsq - dx * dx - dy * dy);
- }
- }
- normalize_v3(fp);
-
- if (snap != SNAP_OFF) {
- const int snap_steps = (snap == SNAP_ON) ? 4 : 12; /* 45 or 15 degree increments */
- const float snap_steps_angle = M_PI / snap_steps;
- float angle, angle_snap;
- int i;
-
- /* round each axis of 'fp' to the next increment
- * do this in "angle" space - this gives increments of same size */
- for (i = 0; i < 3; i++) {
- angle = asinf(fp[i]);
- angle_snap = roundf((angle / snap_steps_angle)) * snap_steps_angle;
- fp[i] = sinf(angle_snap);
- }
- normalize_v3(fp);
- changed = !compare_v3v3(fp, data->origvec, FLT_EPSILON);
- }
-
- data->draglastx = mx;
- data->draglasty = my;
-
- return changed;
+ uiBut *but, uiHandleButtonData *data, int mx, int my, const enum eSnapType snap)
+{
+ float dx, dy, rad, radsq, mrad, *fp;
+ int mdx, mdy;
+ bool changed = true;
+
+ /* button is presumed square */
+ /* if mouse moves outside of sphere, it does negative normal */
+
+ /* note that both data->vec and data->origvec should be normalized
+ * else we'll get a harmless but annoying jump when first clicking */
+
+ fp = data->origvec;
+ rad = BLI_rctf_size_x(&but->rect);
+ radsq = rad * rad;
+
+ if (fp[2] > 0.0f) {
+ mdx = (rad * fp[0]);
+ mdy = (rad * fp[1]);
+ }
+ else if (fp[2] > -1.0f) {
+ mrad = rad / sqrtf(fp[0] * fp[0] + fp[1] * fp[1]);
+
+ mdx = 2.0f * mrad * fp[0] - (rad * fp[0]);
+ mdy = 2.0f * mrad * fp[1] - (rad * fp[1]);
+ }
+ else {
+ mdx = mdy = 0;
+ }
+
+ dx = (float)(mx + mdx - data->dragstartx);
+ dy = (float)(my + mdy - data->dragstarty);
+
+ fp = data->vec;
+ mrad = dx * dx + dy * dy;
+ if (mrad < radsq) { /* inner circle */
+ fp[0] = dx;
+ fp[1] = dy;
+ fp[2] = sqrtf(radsq - dx * dx - dy * dy);
+ }
+ else { /* outer circle */
+
+ mrad = rad / sqrtf(mrad); // veclen
+
+ dx *= (2.0f * mrad - 1.0f);
+ dy *= (2.0f * mrad - 1.0f);
+
+ mrad = dx * dx + dy * dy;
+ if (mrad < radsq) {
+ fp[0] = dx;
+ fp[1] = dy;
+ fp[2] = -sqrtf(radsq - dx * dx - dy * dy);
+ }
+ }
+ normalize_v3(fp);
+
+ if (snap != SNAP_OFF) {
+ const int snap_steps = (snap == SNAP_ON) ? 4 : 12; /* 45 or 15 degree increments */
+ const float snap_steps_angle = M_PI / snap_steps;
+ float angle, angle_snap;
+ int i;
+
+ /* round each axis of 'fp' to the next increment
+ * do this in "angle" space - this gives increments of same size */
+ for (i = 0; i < 3; i++) {
+ angle = asinf(fp[i]);
+ angle_snap = roundf((angle / snap_steps_angle)) * snap_steps_angle;
+ fp[i] = sinf(angle_snap);
+ }
+ normalize_v3(fp);
+ changed = !compare_v3v3(fp, data->origvec, FLT_EPSILON);
+ }
+
+ data->draglastx = mx;
+ data->draglasty = my;
+
+ return changed;
}
static void ui_palette_set_active(uiBut *but)
{
- if ((int)(but->a1) == UI_PALETTE_COLOR) {
- Palette *palette = but->rnapoin.id.data;
- PaletteColor *color = but->rnapoin.data;
- palette->active_color = BLI_findindex(&palette->colors, color);
- }
-}
-
-static int ui_do_but_COLOR(
- bContext *C, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- /* first handle click on icondrag type button */
- if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
- ui_palette_set_active(but);
- if (ui_but_contains_point_px_icon(but, data->region, event)) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- return WM_UI_HANDLER_BREAK;
- }
- }
+ if ((int)(but->a1) == UI_PALETTE_COLOR) {
+ Palette *palette = but->rnapoin.id.data;
+ PaletteColor *color = but->rnapoin.data;
+ palette->active_color = BLI_findindex(&palette->colors, color);
+ }
+}
+
+static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ /* first handle click on icondrag type button */
+ if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
+ ui_palette_set_active(but);
+ if (ui_but_contains_point_px_icon(but, data->region, event)) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
#ifdef USE_DRAG_TOGGLE
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- ui_palette_set_active(but);
- button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- return WM_UI_HANDLER_BREAK;
- }
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ ui_palette_set_active(but);
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ return WM_UI_HANDLER_BREAK;
+ }
#endif
- /* regular open menu */
- if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
- ui_palette_set_active(but);
- button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
- return WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
- ColorPicker *cpicker = but->custom_data;
- float hsv_static[3] = {0.0f};
- float *hsv = cpicker ? cpicker->color_data : hsv_static;
- float col[3];
-
- ui_but_v3_get(but, col);
- rgb_to_hsv_compat_v(col, hsv);
-
- if (event->type == WHEELDOWNMOUSE) {
- hsv[2] = clamp_f(hsv[2] - 0.05f, 0.0f, 1.0f);
- }
- else if (event->type == WHEELUPMOUSE) {
- hsv[2] = clamp_f(hsv[2] + 0.05f, 0.0f, 1.0f);
- }
- else {
- float fac = 0.005 * (event->y - event->prevy);
- hsv[2] = clamp_f(hsv[2] + fac, 0.0f, 1.0f);
- }
-
- hsv_to_rgb_v(hsv, data->vec);
- ui_but_v3_set(but, data->vec);
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_but(C, but->block, but, data, true);
- return WM_UI_HANDLER_BREAK;
- }
- else if ((int)(but->a1) == UI_PALETTE_COLOR &&
- event->type == DELKEY && event->val == KM_PRESS)
- {
- Palette *palette = but->rnapoin.id.data;
- PaletteColor *color = but->rnapoin.data;
-
- BKE_palette_color_remove(palette, color);
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
-
- /* this is risky. it works OK for now,
- * but if it gives trouble we should delay execution */
- but->rnapoin = PointerRNA_NULL;
- but->rnaprop = NULL;
-
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_WAIT_DRAG) {
-
- /* this function also ends state */
- if (ui_but_drag_init(C, but, data, event)) {
- return WM_UI_HANDLER_BREAK;
- }
-
- /* outside icon quit, not needed if drag activated */
- if (0 == ui_but_contains_point_px_icon(but, data->region, event)) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- data->cancel = true;
- return WM_UI_HANDLER_BREAK;
- }
-
- if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if ((int)(but->a1) == UI_PALETTE_COLOR) {
- if (!event->ctrl) {
- float color[3];
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Paint *paint = BKE_paint_get_active(scene, view_layer);
- Brush *brush = BKE_paint_brush(paint);
-
- if (brush->flag & BRUSH_USE_GRADIENT) {
- float *target = &brush->gradient->data[brush->gradient->cur].r;
-
- if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
- IMB_colormanagement_srgb_to_scene_linear_v3(target);
- }
- else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
- RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
- }
- }
- else {
- if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
- BKE_brush_color_set(scene, brush, color);
- }
- else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
- RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
- IMB_colormanagement_scene_linear_to_srgb_v3(color);
- BKE_brush_color_set(scene, brush, color);
- }
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
- }
- }
- else {
- button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ /* regular open menu */
+ if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ ui_palette_set_active(but);
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
+ ColorPicker *cpicker = but->custom_data;
+ float hsv_static[3] = {0.0f};
+ float *hsv = cpicker ? cpicker->color_data : hsv_static;
+ float col[3];
+
+ ui_but_v3_get(but, col);
+ rgb_to_hsv_compat_v(col, hsv);
+
+ if (event->type == WHEELDOWNMOUSE) {
+ hsv[2] = clamp_f(hsv[2] - 0.05f, 0.0f, 1.0f);
+ }
+ else if (event->type == WHEELUPMOUSE) {
+ hsv[2] = clamp_f(hsv[2] + 0.05f, 0.0f, 1.0f);
+ }
+ else {
+ float fac = 0.005 * (event->y - event->prevy);
+ hsv[2] = clamp_f(hsv[2] + fac, 0.0f, 1.0f);
+ }
+
+ hsv_to_rgb_v(hsv, data->vec);
+ ui_but_v3_set(but, data->vec);
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_but(C, but->block, but, data, true);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if ((int)(but->a1) == UI_PALETTE_COLOR && event->type == DELKEY &&
+ event->val == KM_PRESS) {
+ Palette *palette = but->rnapoin.id.data;
+ PaletteColor *color = but->rnapoin.data;
+
+ BKE_palette_color_remove(palette, color);
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+
+ /* this is risky. it works OK for now,
+ * but if it gives trouble we should delay execution */
+ but->rnapoin = PointerRNA_NULL;
+ but->rnaprop = NULL;
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_WAIT_DRAG) {
+
+ /* this function also ends state */
+ if (ui_but_drag_init(C, but, data, event)) {
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ /* outside icon quit, not needed if drag activated */
+ if (0 == ui_but_contains_point_px_icon(but, data->region, event)) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ data->cancel = true;
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ if ((int)(but->a1) == UI_PALETTE_COLOR) {
+ if (!event->ctrl) {
+ float color[3];
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Paint *paint = BKE_paint_get_active(scene, view_layer);
+ Brush *brush = BKE_paint_brush(paint);
+
+ if (brush->flag & BRUSH_USE_GRADIENT) {
+ float *target = &brush->gradient->data[brush->gradient->cur].r;
+
+ if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
+ IMB_colormanagement_srgb_to_scene_linear_v3(target);
+ }
+ else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
+ RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target);
+ }
+ }
+ else {
+ if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
+ BKE_brush_color_set(scene, brush, color);
+ }
+ else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
+ RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
+ IMB_colormanagement_scene_linear_to_srgb_v3(color);
+ BKE_brush_color_set(scene, brush, color);
+ }
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ }
+ }
+ else {
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
static int ui_do_but_UNITVEC(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- const enum eSnapType snap = ui_event_to_snap(event);
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- /* also do drag the first time */
- if (ui_numedit_but_UNITVEC(but, data, mx, my, snap)) {
- ui_numedit_apply(C, block, but, data);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
- if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
- const enum eSnapType snap = ui_event_to_snap(event);
- if (ui_numedit_but_UNITVEC(but, data, mx, my, snap)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ const enum eSnapType snap = ui_event_to_snap(event);
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if (ui_numedit_but_UNITVEC(but, data, mx, my, snap)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
+ const enum eSnapType snap = ui_event_to_snap(event);
+ if (ui_numedit_but_UNITVEC(but, data, mx, my, snap)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
/* scales a vector so no axis exceeds max
* (could become BLI_math func) */
static void clamp_axis_max_v3(float v[3], const float max)
{
- const float v_max = max_fff(v[0], v[1], v[2]);
- if (v_max > max) {
- mul_v3_fl(v, max / v_max);
- if (v[0] > max) {
- v[0] = max;
- }
- if (v[1] > max) {
- v[1] = max;
- }
- if (v[2] > max) {
- v[2] = max;
- }
- }
+ const float v_max = max_fff(v[0], v[1], v[2]);
+ if (v_max > max) {
+ mul_v3_fl(v, max / v_max);
+ if (v[0] > max) {
+ v[0] = max;
+ }
+ if (v[1] > max) {
+ v[1] = max;
+ }
+ if (v[2] > max) {
+ v[2] = max;
+ }
+ }
}
static void ui_rgb_to_color_picker_HSVCUBE_compat_v(uiBut *but, const float rgb[3], float hsv[3])
{
- if (but->a1 == UI_GRAD_L_ALT) {
- rgb_to_hsl_compat_v(rgb, hsv);
- }
- else {
- rgb_to_hsv_compat_v(rgb, hsv);
- }
+ if (but->a1 == UI_GRAD_L_ALT) {
+ rgb_to_hsl_compat_v(rgb, hsv);
+ }
+ else {
+ rgb_to_hsv_compat_v(rgb, hsv);
+ }
}
static void ui_rgb_to_color_picker_HSVCUBE_v(uiBut *but, const float rgb[3], float hsv[3])
{
- if (but->a1 == UI_GRAD_L_ALT) {
- rgb_to_hsl_v(rgb, hsv);
- }
- else {
- rgb_to_hsv_v(rgb, hsv);
- }
+ if (but->a1 == UI_GRAD_L_ALT) {
+ rgb_to_hsl_v(rgb, hsv);
+ }
+ else {
+ rgb_to_hsv_v(rgb, hsv);
+ }
}
static void ui_color_picker_to_rgb_HSVCUBE_v(uiBut *but, const float hsv[3], float rgb[3])
{
- if (but->a1 == UI_GRAD_L_ALT) {
- hsl_to_rgb_v(hsv, rgb);
- }
- else {
- hsv_to_rgb_v(hsv, rgb);
- }
+ if (but->a1 == UI_GRAD_L_ALT) {
+ hsl_to_rgb_v(hsv, rgb);
+ }
+ else {
+ hsv_to_rgb_v(hsv, rgb);
+ }
}
-static bool ui_numedit_but_HSVCUBE(
- uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const enum eSnapType snap, const bool shift)
+static bool ui_numedit_but_HSVCUBE(uiBut *but,
+ uiHandleButtonData *data,
+ int mx,
+ int my,
+ const enum eSnapType snap,
+ const bool shift)
{
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
- float rgb[3];
- float x, y;
- float mx_fl, my_fl;
- bool changed = true;
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ float rgb[3];
+ float x, y;
+ float mx_fl, my_fl;
+ bool changed = true;
- ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
+ ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
#ifdef USE_CONT_MOUSE_CORRECT
- if (ui_but_is_cursor_warp(but)) {
- /* OK but can go outside bounds */
- data->ungrab_mval[0] = mx_fl;
- data->ungrab_mval[1] = my_fl;
- BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
- }
+ if (ui_but_is_cursor_warp(but)) {
+ /* OK but can go outside bounds */
+ data->ungrab_mval[0] = mx_fl;
+ data->ungrab_mval[1] = my_fl;
+ BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+ }
#endif
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
-
- ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
-
- /* only apply the delta motion, not absolute */
- if (shift) {
- rcti rect_i;
- float xpos, ypos, hsvo[3];
-
- BLI_rcti_rctf_copy(&rect_i, &but->rect);
-
- /* calculate original hsv again */
- copy_v3_v3(rgb, data->origvec);
- ui_scene_linear_to_color_picker_space(but, rgb);
-
- copy_v3_v3(hsvo, hsv);
-
- ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsvo);
-
- /* and original position */
- ui_hsvcube_pos_from_vals(but, &rect_i, hsvo, &xpos, &ypos);
-
- mx_fl = xpos - (data->dragstartx - mx_fl);
- my_fl = ypos - (data->dragstarty - my_fl);
- }
-
- /* relative position within box */
- x = ((float)mx_fl - but->rect.xmin) / BLI_rctf_size_x(&but->rect);
- y = ((float)my_fl - but->rect.ymin) / BLI_rctf_size_y(&but->rect);
- CLAMP(x, 0.0f, 1.0f);
- CLAMP(y, 0.0f, 1.0f);
-
- switch ((int)but->a1) {
- case UI_GRAD_SV:
- hsv[1] = x;
- hsv[2] = y;
- break;
- case UI_GRAD_HV:
- hsv[0] = x;
- hsv[2] = y;
- break;
- case UI_GRAD_HS:
- hsv[0] = x;
- hsv[1] = y;
- break;
- case UI_GRAD_H:
- hsv[0] = x;
- break;
- case UI_GRAD_S:
- hsv[1] = x;
- break;
- case UI_GRAD_V:
- hsv[2] = x;
- break;
- case UI_GRAD_L_ALT:
- hsv[2] = y;
- break;
- case UI_GRAD_V_ALT:
- {
- /* vertical 'value' strip */
- float min = but->softmin, max = but->softmax;
- /* exception only for value strip - use the range set in but->min/max */
- hsv[2] = y * (max - min) + min;
- break;
- }
- default:
- BLI_assert(0);
- break;
- }
-
- if (snap != SNAP_OFF) {
- if (ELEM((int)but->a1, UI_GRAD_HV, UI_GRAD_HS, UI_GRAD_H)) {
- ui_color_snap_hue(snap, &hsv[0]);
- }
- }
-
- ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
- ui_color_picker_to_scene_linear_space(but, rgb);
-
- /* clamp because with color conversion we can exceed range [#34295] */
- if (but->a1 == UI_GRAD_V_ALT) {
- clamp_axis_max_v3(rgb, but->softmax);
- }
-
- copy_v3_v3(data->vec, rgb);
-
- data->draglastx = mx;
- data->draglasty = my;
-
- return changed;
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
+
+ /* only apply the delta motion, not absolute */
+ if (shift) {
+ rcti rect_i;
+ float xpos, ypos, hsvo[3];
+
+ BLI_rcti_rctf_copy(&rect_i, &but->rect);
+
+ /* calculate original hsv again */
+ copy_v3_v3(rgb, data->origvec);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+
+ copy_v3_v3(hsvo, hsv);
+
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsvo);
+
+ /* and original position */
+ ui_hsvcube_pos_from_vals(but, &rect_i, hsvo, &xpos, &ypos);
+
+ mx_fl = xpos - (data->dragstartx - mx_fl);
+ my_fl = ypos - (data->dragstarty - my_fl);
+ }
+
+ /* relative position within box */
+ x = ((float)mx_fl - but->rect.xmin) / BLI_rctf_size_x(&but->rect);
+ y = ((float)my_fl - but->rect.ymin) / BLI_rctf_size_y(&but->rect);
+ CLAMP(x, 0.0f, 1.0f);
+ CLAMP(y, 0.0f, 1.0f);
+
+ switch ((int)but->a1) {
+ case UI_GRAD_SV:
+ hsv[1] = x;
+ hsv[2] = y;
+ break;
+ case UI_GRAD_HV:
+ hsv[0] = x;
+ hsv[2] = y;
+ break;
+ case UI_GRAD_HS:
+ hsv[0] = x;
+ hsv[1] = y;
+ break;
+ case UI_GRAD_H:
+ hsv[0] = x;
+ break;
+ case UI_GRAD_S:
+ hsv[1] = x;
+ break;
+ case UI_GRAD_V:
+ hsv[2] = x;
+ break;
+ case UI_GRAD_L_ALT:
+ hsv[2] = y;
+ break;
+ case UI_GRAD_V_ALT: {
+ /* vertical 'value' strip */
+ float min = but->softmin, max = but->softmax;
+ /* exception only for value strip - use the range set in but->min/max */
+ hsv[2] = y * (max - min) + min;
+ break;
+ }
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ if (snap != SNAP_OFF) {
+ if (ELEM((int)but->a1, UI_GRAD_HV, UI_GRAD_HS, UI_GRAD_H)) {
+ ui_color_snap_hue(snap, &hsv[0]);
+ }
+ }
+
+ ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
+ ui_color_picker_to_scene_linear_space(but, rgb);
+
+ /* clamp because with color conversion we can exceed range [#34295] */
+ if (but->a1 == UI_GRAD_V_ALT) {
+ clamp_axis_max_v3(rgb, but->softmax);
+ }
+
+ copy_v3_v3(data->vec, rgb);
+
+ data->draglastx = mx;
+ data->draglasty = my;
+
+ return changed;
}
#ifdef WITH_INPUT_NDOF
-static void ui_ndofedit_but_HSVCUBE(
- uiBut *but, uiHandleButtonData *data,
- const wmNDOFMotionData *ndof,
- const enum eSnapType snap, const bool shift)
-{
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
- const float hsv_v_max = max_ff(hsv[2], but->softmax);
- float rgb[3];
- float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt;
-
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
- ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
-
- switch ((int)but->a1) {
- case UI_GRAD_SV:
- hsv[1] += ndof->rvec[2] * sensitivity;
- hsv[2] += ndof->rvec[0] * sensitivity;
- break;
- case UI_GRAD_HV:
- hsv[0] += ndof->rvec[2] * sensitivity;
- hsv[2] += ndof->rvec[0] * sensitivity;
- break;
- case UI_GRAD_HS:
- hsv[0] += ndof->rvec[2] * sensitivity;
- hsv[1] += ndof->rvec[0] * sensitivity;
- break;
- case UI_GRAD_H:
- hsv[0] += ndof->rvec[2] * sensitivity;
- break;
- case UI_GRAD_S:
- hsv[1] += ndof->rvec[2] * sensitivity;
- break;
- case UI_GRAD_V:
- hsv[2] += ndof->rvec[2] * sensitivity;
- break;
- case UI_GRAD_V_ALT:
- case UI_GRAD_L_ALT:
- /* vertical 'value' strip */
-
- /* exception only for value strip - use the range set in but->min/max */
- hsv[2] += ndof->rvec[0] * sensitivity;
-
- CLAMP(hsv[2], but->softmin, but->softmax);
- break;
- default:
- assert(!"invalid hsv type");
- break;
- }
-
- if (snap != SNAP_OFF) {
- if (ELEM((int)but->a1, UI_GRAD_HV, UI_GRAD_HS, UI_GRAD_H)) {
- ui_color_snap_hue(snap, &hsv[0]);
- }
- }
-
- /* ndof specific: the changes above aren't clamping */
- hsv_clamp_v(hsv, hsv_v_max);
-
- ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
- ui_color_picker_to_scene_linear_space(but, rgb);
-
- copy_v3_v3(data->vec, rgb);
- ui_but_v3_set(but, data->vec);
+static void ui_ndofedit_but_HSVCUBE(uiBut *but,
+ uiHandleButtonData *data,
+ const wmNDOFMotionData *ndof,
+ const enum eSnapType snap,
+ const bool shift)
+{
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ const float hsv_v_max = max_ff(hsv[2], but->softmax);
+ float rgb[3];
+ float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt;
+
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
+
+ switch ((int)but->a1) {
+ case UI_GRAD_SV:
+ hsv[1] += ndof->rvec[2] * sensitivity;
+ hsv[2] += ndof->rvec[0] * sensitivity;
+ break;
+ case UI_GRAD_HV:
+ hsv[0] += ndof->rvec[2] * sensitivity;
+ hsv[2] += ndof->rvec[0] * sensitivity;
+ break;
+ case UI_GRAD_HS:
+ hsv[0] += ndof->rvec[2] * sensitivity;
+ hsv[1] += ndof->rvec[0] * sensitivity;
+ break;
+ case UI_GRAD_H:
+ hsv[0] += ndof->rvec[2] * sensitivity;
+ break;
+ case UI_GRAD_S:
+ hsv[1] += ndof->rvec[2] * sensitivity;
+ break;
+ case UI_GRAD_V:
+ hsv[2] += ndof->rvec[2] * sensitivity;
+ break;
+ case UI_GRAD_V_ALT:
+ case UI_GRAD_L_ALT:
+ /* vertical 'value' strip */
+
+ /* exception only for value strip - use the range set in but->min/max */
+ hsv[2] += ndof->rvec[0] * sensitivity;
+
+ CLAMP(hsv[2], but->softmin, but->softmax);
+ break;
+ default:
+ assert(!"invalid hsv type");
+ break;
+ }
+
+ if (snap != SNAP_OFF) {
+ if (ELEM((int)but->a1, UI_GRAD_HV, UI_GRAD_HS, UI_GRAD_H)) {
+ ui_color_snap_hue(snap, &hsv[0]);
+ }
+ }
+
+ /* ndof specific: the changes above aren't clamping */
+ hsv_clamp_v(hsv, hsv_v_max);
+
+ ui_color_picker_to_rgb_HSVCUBE_v(but, hsv, rgb);
+ ui_color_picker_to_scene_linear_space(but, rgb);
+
+ copy_v3_v3(data->vec, rgb);
+ ui_but_v3_set(but, data->vec);
}
#endif /* WITH_INPUT_NDOF */
static int ui_do_but_HSVCUBE(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
- int mx, my;
+ int mx, my;
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- const enum eSnapType snap = ui_event_to_snap(event);
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ const enum eSnapType snap = ui_event_to_snap(event);
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- /* also do drag the first time */
- if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
+ /* also do drag the first time */
+ if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
- return WM_UI_HANDLER_BREAK;
- }
+ return WM_UI_HANDLER_BREAK;
+ }
#ifdef WITH_INPUT_NDOF
- else if (event->type == NDOF_MOTION) {
- const wmNDOFMotionData *ndof = event->customdata;
- const enum eSnapType snap = ui_event_to_snap(event);
+ else if (event->type == NDOF_MOTION) {
+ const wmNDOFMotionData *ndof = event->customdata;
+ const enum eSnapType snap = ui_event_to_snap(event);
- ui_ndofedit_but_HSVCUBE(but, data, ndof, snap, event->shift != 0);
+ ui_ndofedit_but_HSVCUBE(but, data, ndof, snap, event->shift != 0);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_but(C, but->block, but, data, true);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_but(C, but->block, but, data, true);
- return WM_UI_HANDLER_BREAK;
- }
+ return WM_UI_HANDLER_BREAK;
+ }
#endif /* WITH_INPUT_NDOF */
- /* XXX hardcoded keymap check.... */
- else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
- if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) {
- int len;
-
- /* reset only value */
-
- len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
- if (ELEM(len, 3, 4)) {
- float rgb[3], def_hsv[3];
- float def[4];
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
-
- RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
- ui_rgb_to_color_picker_HSVCUBE_v(but, def, def_hsv);
-
- ui_but_v3_get(but, rgb);
- ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
-
- def_hsv[0] = hsv[0];
- def_hsv[1] = hsv[1];
-
- ui_color_picker_to_rgb_HSVCUBE_v(but, def_hsv, rgb);
- ui_but_v3_set(but, rgb);
-
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
- return WM_UI_HANDLER_BREAK;
- }
- }
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
- if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
- const enum eSnapType snap = ui_event_to_snap(event);
-
- if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
-}
-
-static bool ui_numedit_but_HSVCIRCLE(
- uiBut *but, uiHandleButtonData *data,
- float mx, float my,
- const enum eSnapType snap, const bool shift)
-{
- rcti rect;
- bool changed = true;
- float mx_fl, my_fl;
- float rgb[3];
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
-
- ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
+ /* XXX hardcoded keymap check.... */
+ else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
+ if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) {
+ int len;
+
+ /* reset only value */
+
+ len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ if (ELEM(len, 3, 4)) {
+ float rgb[3], def_hsv[3];
+ float def[4];
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+
+ RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
+ ui_rgb_to_color_picker_HSVCUBE_v(but, def, def_hsv);
+
+ ui_but_v3_get(but, rgb);
+ ui_rgb_to_color_picker_HSVCUBE_compat_v(but, rgb, hsv);
+
+ def_hsv[0] = hsv[0];
+ def_hsv[1] = hsv[1];
+
+ ui_color_picker_to_rgb_HSVCUBE_v(but, def_hsv, rgb);
+ ui_but_v3_set(but, rgb);
+
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
+ const enum eSnapType snap = ui_event_to_snap(event);
+
+ if (ui_numedit_but_HSVCUBE(but, data, mx, my, snap, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
+static bool ui_numedit_but_HSVCIRCLE(uiBut *but,
+ uiHandleButtonData *data,
+ float mx,
+ float my,
+ const enum eSnapType snap,
+ const bool shift)
+{
+ rcti rect;
+ bool changed = true;
+ float mx_fl, my_fl;
+ float rgb[3];
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+
+ ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift);
#ifdef USE_CONT_MOUSE_CORRECT
- if (ui_but_is_cursor_warp(but)) {
- /* OK but can go outside bounds */
- data->ungrab_mval[0] = mx_fl;
- data->ungrab_mval[1] = my_fl;
- { /* clamp */
- const float radius = min_ff(BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)) / 2.0f;
- const float cent[2] = {BLI_rctf_cent_x(&but->rect), BLI_rctf_cent_y(&but->rect)};
- const float len = len_v2v2(cent, data->ungrab_mval);
- if (len > radius) {
- dist_ensure_v2_v2fl(data->ungrab_mval, cent, radius);
- }
- }
- }
+ if (ui_but_is_cursor_warp(but)) {
+ /* OK but can go outside bounds */
+ data->ungrab_mval[0] = mx_fl;
+ data->ungrab_mval[1] = my_fl;
+ { /* clamp */
+ const float radius = min_ff(BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)) / 2.0f;
+ const float cent[2] = {BLI_rctf_cent_x(&but->rect), BLI_rctf_cent_y(&but->rect)};
+ const float len = len_v2v2(cent, data->ungrab_mval);
+ if (len > radius) {
+ dist_ensure_v2_v2fl(data->ungrab_mval, cent, radius);
+ }
+ }
+ }
#endif
- BLI_rcti_rctf_copy(&rect, &but->rect);
-
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
- ui_rgb_to_color_picker_compat_v(rgb, hsv);
+ BLI_rcti_rctf_copy(&rect, &but->rect);
- /* exception, when using color wheel in 'locked' value state:
- * allow choosing a hue for black values, by giving a tiny increment */
- if (cpicker->use_color_lock) {
- if (U.color_picker_type == USER_CP_CIRCLE_HSV) { // lock
- if (hsv[2] == 0.f) {
- hsv[2] = 0.0001f;
- }
- }
- else {
- if (hsv[2] == 0.0f) {
- hsv[2] = 0.0001f;
- }
- if (hsv[2] >= 0.9999f) {
- hsv[2] = 0.9999f;
- }
- }
- }
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
- /* only apply the delta motion, not absolute */
- if (shift) {
- float xpos, ypos, hsvo[3], rgbo[3];
+ /* exception, when using color wheel in 'locked' value state:
+ * allow choosing a hue for black values, by giving a tiny increment */
+ if (cpicker->use_color_lock) {
+ if (U.color_picker_type == USER_CP_CIRCLE_HSV) { // lock
+ if (hsv[2] == 0.f) {
+ hsv[2] = 0.0001f;
+ }
+ }
+ else {
+ if (hsv[2] == 0.0f) {
+ hsv[2] = 0.0001f;
+ }
+ if (hsv[2] >= 0.9999f) {
+ hsv[2] = 0.9999f;
+ }
+ }
+ }
- /* calculate original hsv again */
- copy_v3_v3(hsvo, hsv);
- copy_v3_v3(rgbo, data->origvec);
- ui_scene_linear_to_color_picker_space(but, rgbo);
- ui_rgb_to_color_picker_compat_v(rgbo, hsvo);
+ /* only apply the delta motion, not absolute */
+ if (shift) {
+ float xpos, ypos, hsvo[3], rgbo[3];
- /* and original position */
- ui_hsvcircle_pos_from_vals(cpicker, &rect, hsvo, &xpos, &ypos);
+ /* calculate original hsv again */
+ copy_v3_v3(hsvo, hsv);
+ copy_v3_v3(rgbo, data->origvec);
+ ui_scene_linear_to_color_picker_space(but, rgbo);
+ ui_rgb_to_color_picker_compat_v(rgbo, hsvo);
- mx_fl = xpos - (data->dragstartx - mx_fl);
- my_fl = ypos - (data->dragstarty - my_fl);
+ /* and original position */
+ ui_hsvcircle_pos_from_vals(cpicker, &rect, hsvo, &xpos, &ypos);
- }
+ mx_fl = xpos - (data->dragstartx - mx_fl);
+ my_fl = ypos - (data->dragstarty - my_fl);
+ }
- ui_hsvcircle_vals_from_pos(&rect, mx_fl, my_fl, hsv, hsv + 1);
+ ui_hsvcircle_vals_from_pos(&rect, mx_fl, my_fl, hsv, hsv + 1);
- if ((cpicker->use_color_cubic) && (U.color_picker_type == USER_CP_CIRCLE_HSV)) {
- hsv[1] = 1.0f - sqrt3f(1.0f - hsv[1]);
- }
+ if ((cpicker->use_color_cubic) && (U.color_picker_type == USER_CP_CIRCLE_HSV)) {
+ hsv[1] = 1.0f - sqrt3f(1.0f - hsv[1]);
+ }
- if (snap != SNAP_OFF) {
- ui_color_snap_hue(snap, &hsv[0]);
- }
+ if (snap != SNAP_OFF) {
+ ui_color_snap_hue(snap, &hsv[0]);
+ }
- ui_color_picker_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_rgb_v(hsv, rgb);
- if ((cpicker->use_luminosity_lock)) {
- if (!is_zero_v3(rgb)) {
- normalize_v3_length(rgb, cpicker->luminosity_lock_value);
- }
- }
+ if ((cpicker->use_luminosity_lock)) {
+ if (!is_zero_v3(rgb)) {
+ normalize_v3_length(rgb, cpicker->luminosity_lock_value);
+ }
+ }
- ui_color_picker_to_scene_linear_space(but, rgb);
- ui_but_v3_set(but, rgb);
+ ui_color_picker_to_scene_linear_space(but, rgb);
+ ui_but_v3_set(but, rgb);
- data->draglastx = mx;
- data->draglasty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
- return changed;
+ return changed;
}
#ifdef WITH_INPUT_NDOF
-static void ui_ndofedit_but_HSVCIRCLE(
- uiBut *but, uiHandleButtonData *data,
- const wmNDOFMotionData *ndof,
- const enum eSnapType snap, const bool shift)
-{
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
- float rgb[3];
- float phi, r /*, sqr */ /* UNUSED */, v[2];
- float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt;
-
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
- ui_rgb_to_color_picker_compat_v(rgb, hsv);
-
- /* Convert current color on hue/sat disc to circular coordinates phi, r */
- phi = fmodf(hsv[0] + 0.25f, 1.0f) * -2.0f * (float)M_PI;
- r = hsv[1];
- /* sqr = r > 0.0f ? sqrtf(r) : 1; */ /* UNUSED */
-
- /* Convert to 2d vectors */
- v[0] = r * cosf(phi);
- v[1] = r * sinf(phi);
-
- /* Use ndof device y and x rotation to move the vector in 2d space */
- v[0] += ndof->rvec[2] * sensitivity;
- v[1] += ndof->rvec[0] * sensitivity;
-
- /* convert back to polar coords on circle */
- phi = atan2f(v[0], v[1]) / (2.0f * (float)M_PI) + 0.5f;
-
- /* use ndof Y rotation to additionally rotate hue */
- phi += ndof->rvec[1] * sensitivity * 0.5f;
- r = len_v2(v);
-
- /* convert back to hsv values, in range [0,1] */
- hsv[0] = phi;
- hsv[1] = r;
-
- /* exception, when using color wheel in 'locked' value state:
- * allow choosing a hue for black values, by giving a tiny increment */
- if (cpicker->use_color_lock) {
- if (U.color_picker_type == USER_CP_CIRCLE_HSV) { // lock
- if (hsv[2] == 0.f) {
- hsv[2] = 0.0001f;
- }
- }
- else {
- if (hsv[2] == 0.f) {
- hsv[2] = 0.0001f;
- }
- if (hsv[2] == 1.f) {
- hsv[2] = 0.9999f;
- }
- }
- }
-
- if (snap != SNAP_OFF) {
- ui_color_snap_hue(snap, &hsv[0]);
- }
-
- hsv_clamp_v(hsv, FLT_MAX);
-
- ui_color_picker_to_rgb_v(hsv, data->vec);
-
- if (cpicker->use_luminosity_lock) {
- if (!is_zero_v3(data->vec)) {
- normalize_v3_length(data->vec, cpicker->luminosity_lock_value);
- }
- }
-
- ui_color_picker_to_scene_linear_space(but, data->vec);
- ui_but_v3_set(but, data->vec);
+static void ui_ndofedit_but_HSVCIRCLE(uiBut *but,
+ uiHandleButtonData *data,
+ const wmNDOFMotionData *ndof,
+ const enum eSnapType snap,
+ const bool shift)
+{
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ float rgb[3];
+ float phi, r /*, sqr */ /* UNUSED */, v[2];
+ float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt;
+
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
+ /* Convert current color on hue/sat disc to circular coordinates phi, r */
+ phi = fmodf(hsv[0] + 0.25f, 1.0f) * -2.0f * (float)M_PI;
+ r = hsv[1];
+ /* sqr = r > 0.0f ? sqrtf(r) : 1; */ /* UNUSED */
+
+ /* Convert to 2d vectors */
+ v[0] = r * cosf(phi);
+ v[1] = r * sinf(phi);
+
+ /* Use ndof device y and x rotation to move the vector in 2d space */
+ v[0] += ndof->rvec[2] * sensitivity;
+ v[1] += ndof->rvec[0] * sensitivity;
+
+ /* convert back to polar coords on circle */
+ phi = atan2f(v[0], v[1]) / (2.0f * (float)M_PI) + 0.5f;
+
+ /* use ndof Y rotation to additionally rotate hue */
+ phi += ndof->rvec[1] * sensitivity * 0.5f;
+ r = len_v2(v);
+
+ /* convert back to hsv values, in range [0,1] */
+ hsv[0] = phi;
+ hsv[1] = r;
+
+ /* exception, when using color wheel in 'locked' value state:
+ * allow choosing a hue for black values, by giving a tiny increment */
+ if (cpicker->use_color_lock) {
+ if (U.color_picker_type == USER_CP_CIRCLE_HSV) { // lock
+ if (hsv[2] == 0.f) {
+ hsv[2] = 0.0001f;
+ }
+ }
+ else {
+ if (hsv[2] == 0.f) {
+ hsv[2] = 0.0001f;
+ }
+ if (hsv[2] == 1.f) {
+ hsv[2] = 0.9999f;
+ }
+ }
+ }
+
+ if (snap != SNAP_OFF) {
+ ui_color_snap_hue(snap, &hsv[0]);
+ }
+
+ hsv_clamp_v(hsv, FLT_MAX);
+
+ ui_color_picker_to_rgb_v(hsv, data->vec);
+
+ if (cpicker->use_luminosity_lock) {
+ if (!is_zero_v3(data->vec)) {
+ normalize_v3_length(data->vec, cpicker->luminosity_lock_value);
+ }
+ }
+
+ ui_color_picker_to_scene_linear_space(but, data->vec);
+ ui_but_v3_set(but, data->vec);
}
#endif /* WITH_INPUT_NDOF */
static int ui_do_but_HSVCIRCLE(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
- int mx, my;
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- const enum eSnapType snap = ui_event_to_snap(event);
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- /* also do drag the first time */
- if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ int mx, my;
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ const enum eSnapType snap = ui_event_to_snap(event);
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
#ifdef WITH_INPUT_NDOF
- else if (event->type == NDOF_MOTION) {
- const enum eSnapType snap = ui_event_to_snap(event);
- const wmNDOFMotionData *ndof = event->customdata;
+ else if (event->type == NDOF_MOTION) {
+ const enum eSnapType snap = ui_event_to_snap(event);
+ const wmNDOFMotionData *ndof = event->customdata;
- ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->shift != 0);
+ ui_ndofedit_but_HSVCIRCLE(but, data, ndof, snap, event->shift != 0);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- ui_apply_but(C, but->block, but, data, true);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_but(C, but->block, but, data, true);
- return WM_UI_HANDLER_BREAK;
- }
+ return WM_UI_HANDLER_BREAK;
+ }
#endif /* WITH_INPUT_NDOF */
- /* XXX hardcoded keymap check.... */
- else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
- int len;
-
- /* reset only saturation */
-
- len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
- if (len >= 3) {
- float rgb[3], def_hsv[3];
- float *def;
- def = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
-
- RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
- ui_color_picker_to_rgb_v(def, def_hsv);
-
- ui_but_v3_get(but, rgb);
- ui_rgb_to_color_picker_compat_v(rgb, hsv);
-
- def_hsv[0] = hsv[0];
- def_hsv[2] = hsv[2];
-
- hsv_to_rgb_v(def_hsv, rgb);
- ui_but_v3_set(but, rgb);
-
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
-
- MEM_freeN(def);
- }
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- /* XXX hardcoded keymap check.... */
- else if (event->type == WHEELDOWNMOUSE) {
- hsv[2] = clamp_f(hsv[2] - 0.05f, 0.0f, 1.0f);
- ui_but_hsv_set(but); /* converts to rgb */
- ui_numedit_apply(C, block, but, data);
- }
- else if (event->type == WHEELUPMOUSE) {
- hsv[2] = clamp_f(hsv[2] + 0.05f, 0.0f, 1.0f);
- ui_but_hsv_set(but); /* converts to rgb */
- ui_numedit_apply(C, block, but, data);
- }
- else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
- if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
- const enum eSnapType snap = ui_event_to_snap(event);
-
- if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ /* XXX hardcoded keymap check.... */
+ else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
+ int len;
+
+ /* reset only saturation */
+
+ len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ if (len >= 3) {
+ float rgb[3], def_hsv[3];
+ float *def;
+ def = MEM_callocN(sizeof(float) * len, "reset_defaults - float");
+
+ RNA_property_float_get_default_array(&but->rnapoin, but->rnaprop, def);
+ ui_color_picker_to_rgb_v(def, def_hsv);
+
+ ui_but_v3_get(but, rgb);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
+ def_hsv[0] = hsv[0];
+ def_hsv[2] = hsv[2];
+
+ hsv_to_rgb_v(def_hsv, rgb);
+ ui_but_v3_set(but, rgb);
+
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+
+ MEM_freeN(def);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY || event->type == RIGHTMOUSE) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ /* XXX hardcoded keymap check.... */
+ else if (event->type == WHEELDOWNMOUSE) {
+ hsv[2] = clamp_f(hsv[2] - 0.05f, 0.0f, 1.0f);
+ ui_but_hsv_set(but); /* converts to rgb */
+ ui_numedit_apply(C, block, but, data);
+ }
+ else if (event->type == WHEELUPMOUSE) {
+ hsv[2] = clamp_f(hsv[2] + 0.05f, 0.0f, 1.0f);
+ ui_but_hsv_set(but); /* converts to rgb */
+ ui_numedit_apply(C, block, but, data);
+ }
+ else if ((event->type == MOUSEMOVE) || ui_event_is_snap(event)) {
+ if (mx != data->draglastx || my != data->draglasty || event->type != MOUSEMOVE) {
+ const enum eSnapType snap = ui_event_to_snap(event);
+
+ if (ui_numedit_but_HSVCIRCLE(but, data, mx, my, snap, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
-
static bool ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx)
{
- float dx;
- bool changed = false;
+ float dx;
+ bool changed = false;
- if (data->draglastx == mx) {
- return changed;
- }
+ if (data->draglastx == mx) {
+ return changed;
+ }
- if (data->coba->tot == 0) {
- return changed;
- }
+ if (data->coba->tot == 0) {
+ return changed;
+ }
- dx = ((float)(mx - data->draglastx)) / BLI_rctf_size_x(&but->rect);
- data->dragcbd->pos += dx;
- CLAMP(data->dragcbd->pos, 0.0f, 1.0f);
+ dx = ((float)(mx - data->draglastx)) / BLI_rctf_size_x(&but->rect);
+ data->dragcbd->pos += dx;
+ CLAMP(data->dragcbd->pos, 0.0f, 1.0f);
- BKE_colorband_update_sort(data->coba);
- data->dragcbd = data->coba->data + data->coba->cur; /* because qsort */
+ BKE_colorband_update_sort(data->coba);
+ data->dragcbd = data->coba->data + data->coba->cur; /* because qsort */
- data->draglastx = mx;
- changed = true;
+ data->draglastx = mx;
+ changed = true;
- return changed;
+ return changed;
}
static int ui_do_but_COLORBAND(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- ColorBand *coba;
- CBData *cbd;
- /* ignore zoom-level for mindist */
- int mindist = (50 * UI_DPI_FAC) * block->aspect;
- int mx, my, a, xco;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- coba = (ColorBand *)but->poin;
-
- if (event->ctrl) {
- /* insert new key on mouse location */
- float pos = ((float)(mx - but->rect.xmin)) / BLI_rctf_size_x(&but->rect);
- BKE_colorband_element_add(coba, pos);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
-
- /* activate new key when mouse is close */
- for (a = 0, cbd = coba->data; a < coba->tot; a++, cbd++) {
- xco = but->rect.xmin + (cbd->pos * BLI_rctf_size_x(&but->rect));
- xco = ABS(xco - mx);
- if (a == coba->cur) {
- /* Selected one disadvantage. */
- xco += 5;
- }
- if (xco < mindist) {
- coba->cur = a;
- mindist = xco;
- }
- }
-
- data->dragcbd = coba->data + coba->cur;
- data->dragfstart = data->dragcbd->pos;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
- if (ui_numedit_but_COLORBAND(but, data, mx)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) {
- if (event->val == KM_PRESS) {
- data->dragcbd->pos = data->dragfstart;
- BKE_colorband_update_sort(data->coba);
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
-}
-
-static bool ui_numedit_but_CURVE(
- uiBlock *block, uiBut *but, uiHandleButtonData *data,
- int evtx, int evty,
- bool snap, const bool shift)
-{
- CurveMapping *cumap = (CurveMapping *)but->poin;
- CurveMap *cuma = cumap->cm + cumap->cur;
- CurveMapPoint *cmp = cuma->curve;
- float fx, fy, zoomx, zoomy;
- int mx, my, dragx, dragy;
- int a;
- bool changed = false;
-
- /* evtx evty and drag coords are absolute mousecoords,
- * prevents errors when editing when layout changes */
- mx = evtx;
- my = evty;
- ui_window_to_block(data->region, block, &mx, &my);
- dragx = data->draglastx;
- dragy = data->draglasty;
- ui_window_to_block(data->region, block, &dragx, &dragy);
-
- zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr);
- zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr);
-
- if (snap) {
- float d[2];
-
- d[0] = mx - data->dragstartx;
- d[1] = my - data->dragstarty;
-
- if (len_squared_v2(d) < (3.0f * 3.0f)) {
- snap = false;
- }
- }
-
- if (data->dragsel != -1) {
- CurveMapPoint *cmp_last = NULL;
- const float mval_factor = ui_mouse_scale_warp_factor(shift);
- bool moved_point = false; /* for ctrl grid, can't use orig coords because of sorting */
-
- fx = (mx - dragx) / zoomx;
- fy = (my - dragy) / zoomy;
-
- fx *= mval_factor;
- fy *= mval_factor;
-
- for (a = 0; a < cuma->totpoint; a++) {
- if (cmp[a].flag & CUMA_SELECT) {
- float origx = cmp[a].x, origy = cmp[a].y;
- cmp[a].x += fx;
- cmp[a].y += fy;
- if (snap) {
- cmp[a].x = 0.125f * roundf(8.0f * cmp[a].x);
- cmp[a].y = 0.125f * roundf(8.0f * cmp[a].y);
- }
- if (cmp[a].x != origx || cmp[a].y != origy) {
- moved_point = true;
- }
-
- cmp_last = &cmp[a];
- }
- }
-
- curvemapping_changed(cumap, false);
-
- if (moved_point) {
- data->draglastx = evtx;
- data->draglasty = evty;
- changed = true;
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ ColorBand *coba;
+ CBData *cbd;
+ /* ignore zoom-level for mindist */
+ int mindist = (50 * UI_DPI_FAC) * block->aspect;
+ int mx, my, a, xco;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ coba = (ColorBand *)but->poin;
+
+ if (event->ctrl) {
+ /* insert new key on mouse location */
+ float pos = ((float)(mx - but->rect.xmin)) / BLI_rctf_size_x(&but->rect);
+ BKE_colorband_element_add(coba, pos);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+
+ /* activate new key when mouse is close */
+ for (a = 0, cbd = coba->data; a < coba->tot; a++, cbd++) {
+ xco = but->rect.xmin + (cbd->pos * BLI_rctf_size_x(&but->rect));
+ xco = ABS(xco - mx);
+ if (a == coba->cur) {
+ /* Selected one disadvantage. */
+ xco += 5;
+ }
+ if (xco < mindist) {
+ coba->cur = a;
+ mindist = xco;
+ }
+ }
+
+ data->dragcbd = coba->data + coba->cur;
+ data->dragfstart = data->dragcbd->pos;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == MOUSEMOVE) {
+ if (mx != data->draglastx || my != data->draglasty) {
+ if (ui_numedit_but_COLORBAND(but, data, mx)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if (ELEM(event->type, ESCKEY, RIGHTMOUSE)) {
+ if (event->val == KM_PRESS) {
+ data->dragcbd->pos = data->dragfstart;
+ BKE_colorband_update_sort(data->coba);
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
+static bool ui_numedit_but_CURVE(uiBlock *block,
+ uiBut *but,
+ uiHandleButtonData *data,
+ int evtx,
+ int evty,
+ bool snap,
+ const bool shift)
+{
+ CurveMapping *cumap = (CurveMapping *)but->poin;
+ CurveMap *cuma = cumap->cm + cumap->cur;
+ CurveMapPoint *cmp = cuma->curve;
+ float fx, fy, zoomx, zoomy;
+ int mx, my, dragx, dragy;
+ int a;
+ bool changed = false;
+
+ /* evtx evty and drag coords are absolute mousecoords,
+ * prevents errors when editing when layout changes */
+ mx = evtx;
+ my = evty;
+ ui_window_to_block(data->region, block, &mx, &my);
+ dragx = data->draglastx;
+ dragy = data->draglasty;
+ ui_window_to_block(data->region, block, &dragx, &dragy);
+
+ zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr);
+ zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr);
+
+ if (snap) {
+ float d[2];
+
+ d[0] = mx - data->dragstartx;
+ d[1] = my - data->dragstarty;
+
+ if (len_squared_v2(d) < (3.0f * 3.0f)) {
+ snap = false;
+ }
+ }
+
+ if (data->dragsel != -1) {
+ CurveMapPoint *cmp_last = NULL;
+ const float mval_factor = ui_mouse_scale_warp_factor(shift);
+ bool moved_point = false; /* for ctrl grid, can't use orig coords because of sorting */
+
+ fx = (mx - dragx) / zoomx;
+ fy = (my - dragy) / zoomy;
+
+ fx *= mval_factor;
+ fy *= mval_factor;
+
+ for (a = 0; a < cuma->totpoint; a++) {
+ if (cmp[a].flag & CUMA_SELECT) {
+ float origx = cmp[a].x, origy = cmp[a].y;
+ cmp[a].x += fx;
+ cmp[a].y += fy;
+ if (snap) {
+ cmp[a].x = 0.125f * roundf(8.0f * cmp[a].x);
+ cmp[a].y = 0.125f * roundf(8.0f * cmp[a].y);
+ }
+ if (cmp[a].x != origx || cmp[a].y != origy) {
+ moved_point = true;
+ }
+
+ cmp_last = &cmp[a];
+ }
+ }
+
+ curvemapping_changed(cumap, false);
+
+ if (moved_point) {
+ data->draglastx = evtx;
+ data->draglasty = evty;
+ changed = true;
#ifdef USE_CONT_MOUSE_CORRECT
- /* note: using 'cmp_last' is weak since there may be multiple points selected,
- * but in practice this isnt really an issue */
- if (ui_but_is_cursor_warp(but)) {
- /* OK but can go outside bounds */
- data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx);
- data->ungrab_mval[1] = but->rect.ymin + ((cmp_last->y - cumap->curr.ymin) * zoomy);
- BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
- }
+ /* note: using 'cmp_last' is weak since there may be multiple points selected,
+ * but in practice this isnt really an issue */
+ if (ui_but_is_cursor_warp(but)) {
+ /* OK but can go outside bounds */
+ data->ungrab_mval[0] = but->rect.xmin + ((cmp_last->x - cumap->curr.xmin) * zoomx);
+ data->ungrab_mval[1] = but->rect.ymin + ((cmp_last->y - cumap->curr.ymin) * zoomy);
+ BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
+ }
#endif
-
- }
-
- data->dragchange = true; /* mark for selection */
- }
- else {
- fx = (mx - dragx) / zoomx;
- fy = (my - dragy) / zoomy;
-
- /* clamp for clip */
- if (cumap->flag & CUMA_DO_CLIP) {
- if (cumap->curr.xmin - fx < cumap->clipr.xmin) {
- fx = cumap->curr.xmin - cumap->clipr.xmin;
- }
- else if (cumap->curr.xmax - fx > cumap->clipr.xmax) {
- fx = cumap->curr.xmax - cumap->clipr.xmax;
- }
- if (cumap->curr.ymin - fy < cumap->clipr.ymin) {
- fy = cumap->curr.ymin - cumap->clipr.ymin;
- }
- else if (cumap->curr.ymax - fy > cumap->clipr.ymax) {
- fy = cumap->curr.ymax - cumap->clipr.ymax;
- }
- }
-
- cumap->curr.xmin -= fx;
- cumap->curr.ymin -= fy;
- cumap->curr.xmax -= fx;
- cumap->curr.ymax -= fy;
-
- data->draglastx = evtx;
- data->draglasty = evty;
-
- changed = true;
- }
-
- return changed;
+ }
+
+ data->dragchange = true; /* mark for selection */
+ }
+ else {
+ fx = (mx - dragx) / zoomx;
+ fy = (my - dragy) / zoomy;
+
+ /* clamp for clip */
+ if (cumap->flag & CUMA_DO_CLIP) {
+ if (cumap->curr.xmin - fx < cumap->clipr.xmin) {
+ fx = cumap->curr.xmin - cumap->clipr.xmin;
+ }
+ else if (cumap->curr.xmax - fx > cumap->clipr.xmax) {
+ fx = cumap->curr.xmax - cumap->clipr.xmax;
+ }
+ if (cumap->curr.ymin - fy < cumap->clipr.ymin) {
+ fy = cumap->curr.ymin - cumap->clipr.ymin;
+ }
+ else if (cumap->curr.ymax - fy > cumap->clipr.ymax) {
+ fy = cumap->curr.ymax - cumap->clipr.ymax;
+ }
+ }
+
+ cumap->curr.xmin -= fx;
+ cumap->curr.ymin -= fy;
+ cumap->curr.xmax -= fx;
+ cumap->curr.ymax -= fy;
+
+ data->draglastx = evtx;
+ data->draglasty = evty;
+
+ changed = true;
+ }
+
+ return changed;
}
static int ui_do_but_CURVE(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my, a;
- bool changed = false;
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- CurveMapping *cumap = (CurveMapping *)but->poin;
- CurveMap *cuma = cumap->cm + cumap->cur;
- CurveMapPoint *cmp;
- const float m_xy[2] = {mx, my};
- float dist_min_sq = SQUARE(14.0f); /* 14 pixels radius */
- int sel = -1;
-
- if (event->ctrl) {
- float f_xy[2];
- BLI_rctf_transform_pt_v(&cumap->curr, &but->rect, f_xy, m_xy);
-
- curvemap_insert(cuma, f_xy[0], f_xy[1]);
- curvemapping_changed(cumap, false);
- changed = true;
- }
-
- /* check for selecting of a point */
- cmp = cuma->curve; /* ctrl adds point, new malloc */
- for (a = 0; a < cuma->totpoint; a++) {
- float f_xy[2];
- BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[a].x);
- const float dist_sq = len_squared_v2v2(m_xy, f_xy);
- if (dist_sq < dist_min_sq) {
- sel = a;
- dist_min_sq = dist_sq;
- }
- }
-
- if (sel == -1) {
- int i;
- float f_xy[2], f_xy_prev[2];
-
- /* if the click didn't select anything, check if it's clicked on the
- * curve itself, and if so, add a point */
- cmp = cuma->table;
-
- BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[0].x);
-
- /* with 160px height 8px should translate to the old 0.05 coefficient at no zoom */
- dist_min_sq = SQUARE(8.0f);
-
- /* loop through the curve segment table and find what's near the mouse. */
- for (i = 1; i <= CM_TABLE; i++) {
- copy_v2_v2(f_xy_prev, f_xy);
- BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[i].x);
-
- if (dist_squared_to_line_segment_v2(m_xy, f_xy_prev, f_xy) < dist_min_sq) {
- BLI_rctf_transform_pt_v(&cumap->curr, &but->rect, f_xy, m_xy);
-
- curvemap_insert(cuma, f_xy[0], f_xy[1]);
- curvemapping_changed(cumap, false);
-
- changed = true;
-
- /* reset cmp back to the curve points again,
- * rather than drawing segments */
- cmp = cuma->curve;
-
- /* find newly added point and make it 'sel' */
- for (a = 0; a < cuma->totpoint; a++) {
- if (cmp[a].x == f_xy[0]) {
- sel = a;
- }
- }
- break;
- }
- }
- }
-
- if (sel != -1) {
- /* ok, we move a point */
- /* deselect all if this one is deselect. except if we hold shift */
- if (!event->shift) {
- for (a = 0; a < cuma->totpoint; a++) {
- cmp[a].flag &= ~CUMA_SELECT;
- }
- cmp[sel].flag |= CUMA_SELECT;
- }
- else {
- cmp[sel].flag ^= CUMA_SELECT;
- }
- }
- else {
- /* move the view */
- data->cancel = true;
- }
-
- data->dragsel = sel;
-
- data->dragstartx = event->x;
- data->dragstarty = event->y;
- data->draglastx = event->x;
- data->draglasty = event->y;
-
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == MOUSEMOVE) {
- if (event->x != data->draglastx || event->y != data->draglasty) {
-
- if (ui_numedit_but_CURVE(block, but, data, event->x, event->y, event->ctrl != 0, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if (data->dragsel != -1) {
- CurveMapping *cumap = (CurveMapping *)but->poin;
- CurveMap *cuma = cumap->cm + cumap->cur;
- CurveMapPoint *cmp = cuma->curve;
-
- if (data->dragchange == false) {
- /* deselect all, select one */
- if (!event->shift) {
- for (a = 0; a < cuma->totpoint; a++) {
- cmp[a].flag &= ~CUMA_SELECT;
- }
- cmp[data->dragsel].flag |= CUMA_SELECT;
- }
- }
- else {
- curvemapping_changed(cumap, true); /* remove doubles */
- BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap);
- }
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
-
- /* UNUSED but keep for now */
- (void)changed;
-
- return WM_UI_HANDLER_CONTINUE;
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my, a;
+ bool changed = false;
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ CurveMapping *cumap = (CurveMapping *)but->poin;
+ CurveMap *cuma = cumap->cm + cumap->cur;
+ CurveMapPoint *cmp;
+ const float m_xy[2] = {mx, my};
+ float dist_min_sq = SQUARE(14.0f); /* 14 pixels radius */
+ int sel = -1;
+
+ if (event->ctrl) {
+ float f_xy[2];
+ BLI_rctf_transform_pt_v(&cumap->curr, &but->rect, f_xy, m_xy);
+
+ curvemap_insert(cuma, f_xy[0], f_xy[1]);
+ curvemapping_changed(cumap, false);
+ changed = true;
+ }
+
+ /* check for selecting of a point */
+ cmp = cuma->curve; /* ctrl adds point, new malloc */
+ for (a = 0; a < cuma->totpoint; a++) {
+ float f_xy[2];
+ BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[a].x);
+ const float dist_sq = len_squared_v2v2(m_xy, f_xy);
+ if (dist_sq < dist_min_sq) {
+ sel = a;
+ dist_min_sq = dist_sq;
+ }
+ }
+
+ if (sel == -1) {
+ int i;
+ float f_xy[2], f_xy_prev[2];
+
+ /* if the click didn't select anything, check if it's clicked on the
+ * curve itself, and if so, add a point */
+ cmp = cuma->table;
+
+ BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[0].x);
+
+ /* with 160px height 8px should translate to the old 0.05 coefficient at no zoom */
+ dist_min_sq = SQUARE(8.0f);
+
+ /* loop through the curve segment table and find what's near the mouse. */
+ for (i = 1; i <= CM_TABLE; i++) {
+ copy_v2_v2(f_xy_prev, f_xy);
+ BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[i].x);
+
+ if (dist_squared_to_line_segment_v2(m_xy, f_xy_prev, f_xy) < dist_min_sq) {
+ BLI_rctf_transform_pt_v(&cumap->curr, &but->rect, f_xy, m_xy);
+
+ curvemap_insert(cuma, f_xy[0], f_xy[1]);
+ curvemapping_changed(cumap, false);
+
+ changed = true;
+
+ /* reset cmp back to the curve points again,
+ * rather than drawing segments */
+ cmp = cuma->curve;
+
+ /* find newly added point and make it 'sel' */
+ for (a = 0; a < cuma->totpoint; a++) {
+ if (cmp[a].x == f_xy[0]) {
+ sel = a;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (sel != -1) {
+ /* ok, we move a point */
+ /* deselect all if this one is deselect. except if we hold shift */
+ if (!event->shift) {
+ for (a = 0; a < cuma->totpoint; a++) {
+ cmp[a].flag &= ~CUMA_SELECT;
+ }
+ cmp[sel].flag |= CUMA_SELECT;
+ }
+ else {
+ cmp[sel].flag ^= CUMA_SELECT;
+ }
+ }
+ else {
+ /* move the view */
+ data->cancel = true;
+ }
+
+ data->dragsel = sel;
+
+ data->dragstartx = event->x;
+ data->dragstarty = event->y;
+ data->draglastx = event->x;
+ data->draglasty = event->y;
+
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == MOUSEMOVE) {
+ if (event->x != data->draglastx || event->y != data->draglasty) {
+
+ if (ui_numedit_but_CURVE(
+ block, but, data, event->x, event->y, event->ctrl != 0, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ if (data->dragsel != -1) {
+ CurveMapping *cumap = (CurveMapping *)but->poin;
+ CurveMap *cuma = cumap->cm + cumap->cur;
+ CurveMapPoint *cmp = cuma->curve;
+
+ if (data->dragchange == false) {
+ /* deselect all, select one */
+ if (!event->shift) {
+ for (a = 0; a < cuma->totpoint; a++) {
+ cmp[a].flag &= ~CUMA_SELECT;
+ }
+ cmp[data->dragsel].flag |= CUMA_SELECT;
+ }
+ }
+ else {
+ curvemapping_changed(cumap, true); /* remove doubles */
+ BKE_paint_invalidate_cursor_overlay(scene, view_layer, cumap);
+ }
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ /* UNUSED but keep for now */
+ (void)changed;
+
+ return WM_UI_HANDLER_CONTINUE;
}
static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
- Histogram *hist = (Histogram *)but->poin;
- bool changed = true;
- float dy = my - data->draglasty;
+ Histogram *hist = (Histogram *)but->poin;
+ bool changed = true;
+ float dy = my - data->draglasty;
- /* scale histogram values (dy / 10 for better control) */
- const float yfac = min_ff(pow2f(hist->ymax), 1.0f) * 0.5f;
- hist->ymax += (dy * 0.1f) * yfac;
+ /* scale histogram values (dy / 10 for better control) */
+ const float yfac = min_ff(pow2f(hist->ymax), 1.0f) * 0.5f;
+ hist->ymax += (dy * 0.1f) * yfac;
- /* 0.1 allows us to see HDR colors up to 10 */
- CLAMP(hist->ymax, 0.1f, 100.f);
+ /* 0.1 allows us to see HDR colors up to 10 */
+ CLAMP(hist->ymax, 0.1f, 100.f);
- data->draglastx = mx;
- data->draglasty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
- return changed;
+ return changed;
}
static int ui_do_but_HISTOGRAM(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- /* also do drag the first time */
- if (ui_numedit_but_HISTOGRAM(but, data, mx, my)) {
- ui_numedit_apply(C, block, but, data);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
- /* XXX hardcoded keymap check.... */
- else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
- Histogram *hist = (Histogram *)but->poin;
- hist->ymax = 1.f;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
- if (ui_numedit_but_HISTOGRAM(but, data, mx, my)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if (ui_numedit_but_HISTOGRAM(but, data, mx, my)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ /* XXX hardcoded keymap check.... */
+ else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
+ Histogram *hist = (Histogram *)but->poin;
+ hist->ymax = 1.f;
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if (event->type == MOUSEMOVE) {
+ if (mx != data->draglastx || my != data->draglasty) {
+ if (ui_numedit_but_HISTOGRAM(but, data, mx, my)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
static bool ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, int my)
{
- Scopes *scopes = (Scopes *)but->poin;
- bool changed = true;
- float dy;
+ Scopes *scopes = (Scopes *)but->poin;
+ bool changed = true;
+ float dy;
- dy = my - data->draglasty;
+ dy = my - data->draglasty;
- /* scale waveform values */
- scopes->wavefrm_yfac += dy / 200.0f;
+ /* scale waveform values */
+ scopes->wavefrm_yfac += dy / 200.0f;
- CLAMP(scopes->wavefrm_yfac, 0.5f, 2.0f);
+ CLAMP(scopes->wavefrm_yfac, 0.5f, 2.0f);
- data->draglastx = mx;
- data->draglasty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
- return changed;
+ return changed;
}
static int ui_do_but_WAVEFORM(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- /* also do drag the first time */
- if (ui_numedit_but_WAVEFORM(but, data, mx, my)) {
- ui_numedit_apply(C, block, but, data);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
- /* XXX hardcoded keymap check.... */
- else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
- Scopes *scopes = (Scopes *)but->poin;
- scopes->wavefrm_yfac = 1.f;
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
- if (ui_numedit_but_WAVEFORM(but, data, mx, my)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if (ui_numedit_but_WAVEFORM(but, data, mx, my)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ /* XXX hardcoded keymap check.... */
+ else if (event->type == BACKSPACEKEY && event->val == KM_PRESS) {
+ Scopes *scopes = (Scopes *)but->poin;
+ scopes->wavefrm_yfac = 1.f;
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if (event->type == MOUSEMOVE) {
+ if (mx != data->draglastx || my != data->draglasty) {
+ if (ui_numedit_but_WAVEFORM(but, data, mx, my)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
static bool ui_numedit_but_TRACKPREVIEW(
- bContext *C, uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const bool shift)
+ bContext *C, uiBut *but, uiHandleButtonData *data, int mx, int my, const bool shift)
{
- MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
- bool changed = true;
- float dx, dy;
+ MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
+ bool changed = true;
+ float dx, dy;
- dx = mx - data->draglastx;
- dy = my - data->draglasty;
+ dx = mx - data->draglastx;
+ dy = my - data->draglasty;
- if (shift) {
- dx /= 5.0f;
- dy /= 5.0f;
- }
+ if (shift) {
+ dx /= 5.0f;
+ dy /= 5.0f;
+ }
- if (!scopes->track_locked) {
- if (scopes->marker->framenr != scopes->framenr) {
- scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr);
- }
+ if (!scopes->track_locked) {
+ if (scopes->marker->framenr != scopes->framenr) {
+ scopes->marker = BKE_tracking_marker_ensure(scopes->track, scopes->framenr);
+ }
- scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
- scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / BLI_rctf_size_x(&but->block->rect);
- scopes->marker->pos[1] += -dy * scopes->slide_scale[1] / BLI_rctf_size_y(&but->block->rect);
+ scopes->marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
+ scopes->marker->pos[0] += -dx * scopes->slide_scale[0] / BLI_rctf_size_x(&but->block->rect);
+ scopes->marker->pos[1] += -dy * scopes->slide_scale[1] / BLI_rctf_size_y(&but->block->rect);
- WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL);
- }
+ WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL);
+ }
- scopes->ok = 0;
+ scopes->ok = 0;
- data->draglastx = mx;
- data->draglasty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
- return changed;
+ return changed;
}
static int ui_do_but_TRACKPREVIEW(
- bContext *C, uiBlock *block, uiBut *but,
- uiHandleButtonData *data, const wmEvent *event)
-{
- int mx, my;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(data->region, block, &mx, &my);
-
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- data->dragstartx = mx;
- data->dragstarty = my;
- data->draglastx = mx;
- data->draglasty = my;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- /* also do drag the first time */
- if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
-
- return WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- if (event->type == ESCKEY) {
- if (event->val == KM_PRESS) {
- data->cancel = true;
- data->escapecancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- else if (event->type == MOUSEMOVE) {
- if (mx != data->draglastx || my != data->draglasty) {
- if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) {
- ui_numedit_apply(C, block, but, data);
- }
- }
- }
- else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
+{
+ int mx, my;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ data->dragstartx = mx;
+ data->dragstarty = my;
+ data->draglastx = mx;
+ data->draglasty = my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ if (event->type == ESCKEY) {
+ if (event->val == KM_PRESS) {
+ data->cancel = true;
+ data->escapecancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ }
+ else if (event->type == MOUSEMOVE) {
+ if (mx != data->draglastx || my != data->draglasty) {
+ if (ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift != 0)) {
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ }
+ else if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event)
{
- uiHandleButtonData *data;
- int retval;
-
- data = but->active;
- retval = WM_UI_HANDLER_CONTINUE;
-
- bool is_disabled = but->flag & UI_BUT_DISABLED;
-
- /* if but->pointype is set, but->poin should be too */
- BLI_assert(!but->pointype || but->poin);
-
- /* Only hard-coded stuff here, button interactions with configurable
- * keymaps are handled using operators (see #ED_keymap_ui). */
-
- if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) {
-
- /* handle copy and paste */
- bool is_press_ctrl_but_no_shift = event->val == KM_PRESS && IS_EVENT_MOD(event, ctrl, oskey) && !event->shift;
- bool do_copy = event->type == CKEY && is_press_ctrl_but_no_shift;
- bool do_paste = event->type == VKEY && is_press_ctrl_but_no_shift;
-
- /* Specific handling for listrows, we try to find their overlapping tex button. */
- if ((do_copy || do_paste) && but->type == UI_BTYPE_LISTROW) {
- uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_OVER);
- if (labelbut) {
- but = labelbut;
- data = but->active;
- }
- }
-
- /* do copy first, because it is the only allowed operator when disabled */
- if (do_copy) {
- ui_but_copy(C, but, event->alt);
- return WM_UI_HANDLER_BREAK;
- }
-
- /* handle menu */
- if ((event->type == RIGHTMOUSE) &&
- !IS_EVENT_MOD(event, shift, ctrl, alt, oskey) &&
- (event->val == KM_PRESS))
- {
- /* RMB has two options now */
- if (ui_popup_context_menu_for_button(C, but)) {
- return WM_UI_HANDLER_BREAK;
- }
- }
-
- if (is_disabled) {
- return WM_UI_HANDLER_CONTINUE;
- }
-
- if (do_paste) {
- ui_but_paste(C, but, data, event->alt);
- return WM_UI_HANDLER_BREAK;
- }
-
- /* handle drop */
- if (event->type == EVT_DROP) {
- ui_but_drop(C, event, but, data);
- }
- }
-
- if (but->flag & UI_BUT_DISABLED) {
- return WM_UI_HANDLER_CONTINUE;
- }
-
- switch (but->type) {
- case UI_BTYPE_BUT:
- retval = ui_do_but_BUT(C, but, data, event);
- break;
- case UI_BTYPE_KEY_EVENT:
- retval = ui_do_but_KEYEVT(C, but, data, event);
- break;
- case UI_BTYPE_HOTKEY_EVENT:
- retval = ui_do_but_HOTKEYEVT(C, but, data, event);
- break;
- case UI_BTYPE_TAB:
- retval = ui_do_but_TAB(C, block, but, data, event);
- break;
- case UI_BTYPE_BUT_TOGGLE:
- case UI_BTYPE_TOGGLE:
- case UI_BTYPE_ICON_TOGGLE:
- case UI_BTYPE_ICON_TOGGLE_N:
- case UI_BTYPE_TOGGLE_N:
- case UI_BTYPE_CHECKBOX:
- case UI_BTYPE_CHECKBOX_N:
- case UI_BTYPE_ROW:
- retval = ui_do_but_TOG(C, but, data, event);
- break;
- case UI_BTYPE_SCROLL:
- retval = ui_do_but_SCROLL(C, block, but, data, event);
- break;
- case UI_BTYPE_GRIP:
- retval = ui_do_but_GRIP(C, block, but, data, event);
- break;
- case UI_BTYPE_NUM:
- retval = ui_do_but_NUM(C, block, but, data, event);
- break;
- case UI_BTYPE_NUM_SLIDER:
- retval = ui_do_but_SLI(C, block, but, data, event);
- break;
- case UI_BTYPE_LISTBOX:
- /* Nothing to do! */
- break;
- case UI_BTYPE_LISTROW:
- retval = ui_do_but_LISTROW(C, but, data, event);
- break;
- case UI_BTYPE_ROUNDBOX:
- case UI_BTYPE_LABEL:
- case UI_BTYPE_IMAGE:
- case UI_BTYPE_PROGRESS_BAR:
- case UI_BTYPE_NODE_SOCKET:
- retval = ui_do_but_EXIT(C, but, data, event);
- break;
- case UI_BTYPE_HISTOGRAM:
- retval = ui_do_but_HISTOGRAM(C, block, but, data, event);
- break;
- case UI_BTYPE_WAVEFORM:
- retval = ui_do_but_WAVEFORM(C, block, but, data, event);
- break;
- case UI_BTYPE_VECTORSCOPE:
- /* Nothing to do! */
- break;
- case UI_BTYPE_TEXT:
- case UI_BTYPE_SEARCH_MENU:
- if ((but->type == UI_BTYPE_SEARCH_MENU) &&
- (but->flag & UI_BUT_VALUE_CLEAR))
- {
- retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
- if (retval & WM_UI_HANDLER_BREAK) {
- break;
- }
- }
- retval = ui_do_but_TEX(C, block, but, data, event);
- break;
- case UI_BTYPE_MENU:
- case UI_BTYPE_POPOVER:
- case UI_BTYPE_BLOCK:
- case UI_BTYPE_PULLDOWN:
- retval = ui_do_but_BLOCK(C, but, data, event);
- break;
- case UI_BTYPE_BUT_MENU:
- retval = ui_do_but_BUT(C, but, data, event);
- break;
- case UI_BTYPE_COLOR:
- if (but->a1 == -1) {
- /* signal to prevent calling up color picker */
- retval = ui_do_but_EXIT(C, but, data, event);
- }
- else {
- retval = ui_do_but_COLOR(C, but, data, event);
- }
- break;
- case UI_BTYPE_UNITVEC:
- retval = ui_do_but_UNITVEC(C, block, but, data, event);
- break;
- case UI_BTYPE_COLORBAND:
- retval = ui_do_but_COLORBAND(C, block, but, data, event);
- break;
- case UI_BTYPE_CURVE:
- retval = ui_do_but_CURVE(C, block, but, data, event);
- break;
- case UI_BTYPE_HSVCUBE:
- retval = ui_do_but_HSVCUBE(C, block, but, data, event);
- break;
- case UI_BTYPE_HSVCIRCLE:
- retval = ui_do_but_HSVCIRCLE(C, block, but, data, event);
- break;
- case UI_BTYPE_TRACK_PREVIEW:
- retval = ui_do_but_TRACKPREVIEW(C, block, but, data, event);
- break;
-
- /* quiet warnings for unhandled types */
- case UI_BTYPE_SEPR:
- case UI_BTYPE_SEPR_LINE:
- case UI_BTYPE_SEPR_SPACER:
- case UI_BTYPE_EXTRA:
- break;
- }
-
-
- /* reset to default (generic function, only use if not handled by switch above) */
- /* XXX hardcoded keymap check.... */
- data = but->active;
- if (data && data->state == BUTTON_STATE_HIGHLIGHT) {
- if ((retval == WM_UI_HANDLER_CONTINUE) &&
- (event->type == BACKSPACEKEY && event->val == KM_PRESS))
- {
- /* ctrl+backspace = reset active button; backspace = reset a whole array*/
- ui_but_default_set(C, !event->ctrl, true);
- ED_region_tag_redraw(data->region);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
+ uiHandleButtonData *data;
+ int retval;
+
+ data = but->active;
+ retval = WM_UI_HANDLER_CONTINUE;
+
+ bool is_disabled = but->flag & UI_BUT_DISABLED;
+
+ /* if but->pointype is set, but->poin should be too */
+ BLI_assert(!but->pointype || but->poin);
+
+ /* Only hard-coded stuff here, button interactions with configurable
+ * keymaps are handled using operators (see #ED_keymap_ui). */
+
+ if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) {
+
+ /* handle copy and paste */
+ bool is_press_ctrl_but_no_shift = event->val == KM_PRESS && IS_EVENT_MOD(event, ctrl, oskey) &&
+ !event->shift;
+ bool do_copy = event->type == CKEY && is_press_ctrl_but_no_shift;
+ bool do_paste = event->type == VKEY && is_press_ctrl_but_no_shift;
+
+ /* Specific handling for listrows, we try to find their overlapping tex button. */
+ if ((do_copy || do_paste) && but->type == UI_BTYPE_LISTROW) {
+ uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_OVER);
+ if (labelbut) {
+ but = labelbut;
+ data = but->active;
+ }
+ }
+
+ /* do copy first, because it is the only allowed operator when disabled */
+ if (do_copy) {
+ ui_but_copy(C, but, event->alt);
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ /* handle menu */
+ if ((event->type == RIGHTMOUSE) && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey) &&
+ (event->val == KM_PRESS)) {
+ /* RMB has two options now */
+ if (ui_popup_context_menu_for_button(C, but)) {
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ if (is_disabled) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+
+ if (do_paste) {
+ ui_but_paste(C, but, data, event->alt);
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ /* handle drop */
+ if (event->type == EVT_DROP) {
+ ui_but_drop(C, event, but, data);
+ }
+ }
+
+ if (but->flag & UI_BUT_DISABLED) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+
+ switch (but->type) {
+ case UI_BTYPE_BUT:
+ retval = ui_do_but_BUT(C, but, data, event);
+ break;
+ case UI_BTYPE_KEY_EVENT:
+ retval = ui_do_but_KEYEVT(C, but, data, event);
+ break;
+ case UI_BTYPE_HOTKEY_EVENT:
+ retval = ui_do_but_HOTKEYEVT(C, but, data, event);
+ break;
+ case UI_BTYPE_TAB:
+ retval = ui_do_but_TAB(C, block, but, data, event);
+ break;
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE:
+ case UI_BTYPE_ICON_TOGGLE_N:
+ case UI_BTYPE_TOGGLE_N:
+ case UI_BTYPE_CHECKBOX:
+ case UI_BTYPE_CHECKBOX_N:
+ case UI_BTYPE_ROW:
+ retval = ui_do_but_TOG(C, but, data, event);
+ break;
+ case UI_BTYPE_SCROLL:
+ retval = ui_do_but_SCROLL(C, block, but, data, event);
+ break;
+ case UI_BTYPE_GRIP:
+ retval = ui_do_but_GRIP(C, block, but, data, event);
+ break;
+ case UI_BTYPE_NUM:
+ retval = ui_do_but_NUM(C, block, but, data, event);
+ break;
+ case UI_BTYPE_NUM_SLIDER:
+ retval = ui_do_but_SLI(C, block, but, data, event);
+ break;
+ case UI_BTYPE_LISTBOX:
+ /* Nothing to do! */
+ break;
+ case UI_BTYPE_LISTROW:
+ retval = ui_do_but_LISTROW(C, but, data, event);
+ break;
+ case UI_BTYPE_ROUNDBOX:
+ case UI_BTYPE_LABEL:
+ case UI_BTYPE_IMAGE:
+ case UI_BTYPE_PROGRESS_BAR:
+ case UI_BTYPE_NODE_SOCKET:
+ retval = ui_do_but_EXIT(C, but, data, event);
+ break;
+ case UI_BTYPE_HISTOGRAM:
+ retval = ui_do_but_HISTOGRAM(C, block, but, data, event);
+ break;
+ case UI_BTYPE_WAVEFORM:
+ retval = ui_do_but_WAVEFORM(C, block, but, data, event);
+ break;
+ case UI_BTYPE_VECTORSCOPE:
+ /* Nothing to do! */
+ break;
+ case UI_BTYPE_TEXT:
+ case UI_BTYPE_SEARCH_MENU:
+ if ((but->type == UI_BTYPE_SEARCH_MENU) && (but->flag & UI_BUT_VALUE_CLEAR)) {
+ retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
+ if (retval & WM_UI_HANDLER_BREAK) {
+ break;
+ }
+ }
+ retval = ui_do_but_TEX(C, block, but, data, event);
+ break;
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_POPOVER:
+ case UI_BTYPE_BLOCK:
+ case UI_BTYPE_PULLDOWN:
+ retval = ui_do_but_BLOCK(C, but, data, event);
+ break;
+ case UI_BTYPE_BUT_MENU:
+ retval = ui_do_but_BUT(C, but, data, event);
+ break;
+ case UI_BTYPE_COLOR:
+ if (but->a1 == -1) {
+ /* signal to prevent calling up color picker */
+ retval = ui_do_but_EXIT(C, but, data, event);
+ }
+ else {
+ retval = ui_do_but_COLOR(C, but, data, event);
+ }
+ break;
+ case UI_BTYPE_UNITVEC:
+ retval = ui_do_but_UNITVEC(C, block, but, data, event);
+ break;
+ case UI_BTYPE_COLORBAND:
+ retval = ui_do_but_COLORBAND(C, block, but, data, event);
+ break;
+ case UI_BTYPE_CURVE:
+ retval = ui_do_but_CURVE(C, block, but, data, event);
+ break;
+ case UI_BTYPE_HSVCUBE:
+ retval = ui_do_but_HSVCUBE(C, block, but, data, event);
+ break;
+ case UI_BTYPE_HSVCIRCLE:
+ retval = ui_do_but_HSVCIRCLE(C, block, but, data, event);
+ break;
+ case UI_BTYPE_TRACK_PREVIEW:
+ retval = ui_do_but_TRACKPREVIEW(C, block, but, data, event);
+ break;
+
+ /* quiet warnings for unhandled types */
+ case UI_BTYPE_SEPR:
+ case UI_BTYPE_SEPR_LINE:
+ case UI_BTYPE_SEPR_SPACER:
+ case UI_BTYPE_EXTRA:
+ break;
+ }
+
+ /* reset to default (generic function, only use if not handled by switch above) */
+ /* XXX hardcoded keymap check.... */
+ data = but->active;
+ if (data && data->state == BUTTON_STATE_HIGHLIGHT) {
+ if ((retval == WM_UI_HANDLER_CONTINUE) &&
+ (event->type == BACKSPACEKEY && event->val == KM_PRESS)) {
+ /* ctrl+backspace = reset active button; backspace = reset a whole array*/
+ ui_but_default_set(C, !event->ctrl, true);
+ ED_region_tag_redraw(data->region);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
#ifdef USE_DRAG_MULTINUM
- if (data) {
- if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) ||
- /* if we started dragging, progress on any event */
- (data->multi_data.init == BUTTON_MULTI_INIT_SETUP))
- {
- if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
- ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING))
- {
- /* initialize! */
- if (data->multi_data.init == BUTTON_MULTI_INIT_UNSET) {
- /* --> (BUTTON_MULTI_INIT_SETUP | BUTTON_MULTI_INIT_DISABLE) */
-
- const float margin_y = DRAG_MULTINUM_THRESHOLD_DRAG_Y / sqrtf(block->aspect);
-
- /* check if we have a vertical gesture */
- if (len_squared_v2(data->multi_data.drag_dir) > (margin_y * margin_y)) {
- const float dir_nor_y[2] = {0.0, 1.0f};
- float dir_nor_drag[2];
-
- normalize_v2_v2(dir_nor_drag, data->multi_data.drag_dir);
-
- if (fabsf(dot_v2v2(dir_nor_drag, dir_nor_y)) > DRAG_MULTINUM_THRESHOLD_VERTICAL) {
- data->multi_data.init = BUTTON_MULTI_INIT_SETUP;
- data->multi_data.drag_lock_x = event->x;
- }
- else {
- data->multi_data.init = BUTTON_MULTI_INIT_DISABLE;
- }
- }
- }
- else if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
- /* --> (BUTTON_MULTI_INIT_ENABLE) */
- const float margin_x = DRAG_MULTINUM_THRESHOLD_DRAG_X / sqrtf(block->aspect);
- /* check if we're dont setting buttons */
- if ((data->str && ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING)) ||
- ((abs(data->multi_data.drag_lock_x - event->x) > margin_x) &&
- /* just to be sure, check we're dragging more hoz then virt */
- abs(event->prevx - event->x) > abs(event->prevy - event->y)))
- {
- if (data->multi_data.has_mbuts) {
- ui_multibut_states_create(but, data);
- data->multi_data.init = BUTTON_MULTI_INIT_ENABLE;
- }
- else {
- data->multi_data.init = BUTTON_MULTI_INIT_DISABLE;
- }
- }
- }
-
- if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
- if (ui_multibut_states_tag(but, data, event)) {
- ED_region_tag_redraw(data->region);
- }
- }
- }
- }
- }
-#endif /* USE_DRAG_MULTINUM */
-
- return retval;
+ if (data) {
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) ||
+ /* if we started dragging, progress on any event */
+ (data->multi_data.init == BUTTON_MULTI_INIT_SETUP)) {
+ if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
+ ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING)) {
+ /* initialize! */
+ if (data->multi_data.init == BUTTON_MULTI_INIT_UNSET) {
+ /* --> (BUTTON_MULTI_INIT_SETUP | BUTTON_MULTI_INIT_DISABLE) */
+
+ const float margin_y = DRAG_MULTINUM_THRESHOLD_DRAG_Y / sqrtf(block->aspect);
+
+ /* check if we have a vertical gesture */
+ if (len_squared_v2(data->multi_data.drag_dir) > (margin_y * margin_y)) {
+ const float dir_nor_y[2] = {0.0, 1.0f};
+ float dir_nor_drag[2];
+
+ normalize_v2_v2(dir_nor_drag, data->multi_data.drag_dir);
+
+ if (fabsf(dot_v2v2(dir_nor_drag, dir_nor_y)) > DRAG_MULTINUM_THRESHOLD_VERTICAL) {
+ data->multi_data.init = BUTTON_MULTI_INIT_SETUP;
+ data->multi_data.drag_lock_x = event->x;
+ }
+ else {
+ data->multi_data.init = BUTTON_MULTI_INIT_DISABLE;
+ }
+ }
+ }
+ else if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ /* --> (BUTTON_MULTI_INIT_ENABLE) */
+ const float margin_x = DRAG_MULTINUM_THRESHOLD_DRAG_X / sqrtf(block->aspect);
+ /* check if we're dont setting buttons */
+ if ((data->str &&
+ ELEM(data->state, BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_NUM_EDITING)) ||
+ ((abs(data->multi_data.drag_lock_x - event->x) > margin_x) &&
+ /* just to be sure, check we're dragging more hoz then virt */
+ abs(event->prevx - event->x) > abs(event->prevy - event->y))) {
+ if (data->multi_data.has_mbuts) {
+ ui_multibut_states_create(but, data);
+ data->multi_data.init = BUTTON_MULTI_INIT_ENABLE;
+ }
+ else {
+ data->multi_data.init = BUTTON_MULTI_INIT_DISABLE;
+ }
+ }
+ }
+
+ if (data->multi_data.init == BUTTON_MULTI_INIT_SETUP) {
+ if (ui_multibut_states_tag(but, data, event)) {
+ ED_region_tag_redraw(data->region);
+ }
+ }
+ }
+ }
+ }
+#endif /* USE_DRAG_MULTINUM */
+
+ return retval;
}
/** \} */
@@ -7094,17 +7113,17 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
static void ui_blocks_set_tooltips(ARegion *ar, const bool enable)
{
- uiBlock *block;
+ uiBlock *block;
- if (!ar) {
- return;
- }
+ if (!ar) {
+ return;
+ }
- /* we disabled buttons when when they were already shown, and
- * re-enable them on mouse move */
- for (block = ar->uiblocks.first; block; block = block->next) {
- block->tooltipdisabled = !enable;
- }
+ /* we disabled buttons when when they were already shown, and
+ * re-enable them on mouse move */
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ block->tooltipdisabled = !enable;
+ }
}
/**
@@ -7112,75 +7131,74 @@ static void ui_blocks_set_tooltips(ARegion *ar, const bool enable)
*/
void UI_but_tooltip_refresh(bContext *C, uiBut *but)
{
- uiHandleButtonData *data = but->active;
- if (data) {
- bScreen *sc = WM_window_get_active_screen(data->window);
- if (sc->tool_tip && sc->tool_tip->region) {
- WM_tooltip_refresh(C, data->window);
- }
- }
+ uiHandleButtonData *data = but->active;
+ if (data) {
+ bScreen *sc = WM_window_get_active_screen(data->window);
+ if (sc->tool_tip && sc->tool_tip->region) {
+ WM_tooltip_refresh(C, data->window);
+ }
+ }
}
/* removes tooltip timer from active but
* (meaning tooltip is disabled until it's reenabled again) */
void UI_but_tooltip_timer_remove(bContext *C, uiBut *but)
{
- uiHandleButtonData *data;
+ uiHandleButtonData *data;
- data = but->active;
- if (data) {
- if (data->autoopentimer) {
- WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
- data->autoopentimer = NULL;
- }
+ data = but->active;
+ if (data) {
+ if (data->autoopentimer) {
+ WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
+ data->autoopentimer = NULL;
+ }
- if (data->window) {
- WM_tooltip_clear(C, data->window);
- }
- }
+ if (data->window) {
+ WM_tooltip_clear(C, data->window);
+ }
+ }
}
static ARegion *ui_but_tooltip_init(
- bContext *C, ARegion *ar,
- int *pass, double *r_pass_delay, bool *r_exit_on_event)
+ bContext *C, ARegion *ar, int *pass, double *r_pass_delay, bool *r_exit_on_event)
{
- bool is_label = false;
- if (*pass == 1) {
- is_label = true;
- (*pass)--;
- (*r_pass_delay) = UI_TOOLTIP_DELAY - UI_TOOLTIP_DELAY_LABEL;
- }
+ bool is_label = false;
+ if (*pass == 1) {
+ is_label = true;
+ (*pass)--;
+ (*r_pass_delay) = UI_TOOLTIP_DELAY - UI_TOOLTIP_DELAY_LABEL;
+ }
- uiBut *but = UI_region_active_but_get(ar);
- *r_exit_on_event = false;
- if (but) {
- return UI_tooltip_create_from_button(C, ar, but, is_label);
- }
- return NULL;
+ uiBut *but = UI_region_active_but_get(ar);
+ *r_exit_on_event = false;
+ if (but) {
+ return UI_tooltip_create_from_button(C, ar, but, is_label);
+ }
+ return NULL;
}
static void button_tooltip_timer_reset(bContext *C, uiBut *but)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- uiHandleButtonData *data = but->active;
+ wmWindowManager *wm = CTX_wm_manager(C);
+ uiHandleButtonData *data = but->active;
- WM_tooltip_timer_clear(C, data->window);
+ WM_tooltip_timer_clear(C, data->window);
- if ((U.flag & USER_TOOLTIPS) || (data->tooltip_force)) {
- if (!but->block->tooltipdisabled) {
- if (!wm->drags.first) {
- bool is_label = UI_but_has_tooltip_label(but);
- double delay = is_label ? UI_TOOLTIP_DELAY_LABEL : UI_TOOLTIP_DELAY;
- WM_tooltip_timer_init_ex(C, data->window, data->region, ui_but_tooltip_init, delay);
- if (is_label) {
- bScreen *sc = WM_window_get_active_screen(data->window);
- if (sc->tool_tip) {
- sc->tool_tip->pass = 1;
- }
- }
- }
- }
- }
+ if ((U.flag & USER_TOOLTIPS) || (data->tooltip_force)) {
+ if (!but->block->tooltipdisabled) {
+ if (!wm->drags.first) {
+ bool is_label = UI_but_has_tooltip_label(but);
+ double delay = is_label ? UI_TOOLTIP_DELAY_LABEL : UI_TOOLTIP_DELAY;
+ WM_tooltip_timer_init_ex(C, data->window, data->region, ui_but_tooltip_init, delay);
+ if (is_label) {
+ bScreen *sc = WM_window_get_active_screen(data->window);
+ if (sc->tool_tip) {
+ sc->tool_tip->pass = 1;
+ }
+ }
+ }
+ }
+ }
}
/** \} */
@@ -7191,473 +7209,475 @@ static void button_tooltip_timer_reset(bContext *C, uiBut *but)
static bool button_modal_state(uiHandleButtonState state)
{
- return ELEM(state,
- BUTTON_STATE_WAIT_RELEASE,
- BUTTON_STATE_WAIT_KEY_EVENT,
- BUTTON_STATE_NUM_EDITING,
- BUTTON_STATE_TEXT_EDITING,
- BUTTON_STATE_TEXT_SELECTING,
- BUTTON_STATE_MENU_OPEN);
+ return ELEM(state,
+ BUTTON_STATE_WAIT_RELEASE,
+ BUTTON_STATE_WAIT_KEY_EVENT,
+ BUTTON_STATE_NUM_EDITING,
+ BUTTON_STATE_TEXT_EDITING,
+ BUTTON_STATE_TEXT_SELECTING,
+ BUTTON_STATE_MENU_OPEN);
}
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state)
{
- uiHandleButtonData *data;
-
- data = but->active;
- if (data->state == state) {
- return;
- }
-
- /* highlight has timers for tooltips and auto open */
- if (state == BUTTON_STATE_HIGHLIGHT) {
- but->flag &= ~UI_SELECT;
-
- button_tooltip_timer_reset(C, but);
-
- /* automatic open pulldown block timer */
- if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) {
- if (data->used_mouse && !data->autoopentimer) {
- int time;
-
- if (but->block->auto_open == true) { /* test for toolbox */
- time = 1;
- }
- else if ((but->block->flag & UI_BLOCK_LOOP && but->type != UI_BTYPE_BLOCK) ||
- (but->block->auto_open == true))
- {
- time = 5 * U.menuthreshold2;
- }
- else if (U.uiflag & USER_MENUOPENAUTO) {
- time = 5 * U.menuthreshold1;
- }
- else {
- time = -1; /* do nothing */
- }
-
- if (time >= 0) {
- data->autoopentimer = WM_event_add_timer(data->wm, data->window, TIMER, 0.02 * (double)time);
- }
- }
- }
- }
- else {
- but->flag |= UI_SELECT;
- UI_but_tooltip_timer_remove(C, but);
- }
-
- /* text editing */
- if (state == BUTTON_STATE_TEXT_EDITING && data->state != BUTTON_STATE_TEXT_SELECTING) {
- ui_textedit_begin(C, but, data);
- }
- else if (data->state == BUTTON_STATE_TEXT_EDITING && state != BUTTON_STATE_TEXT_SELECTING) {
- ui_textedit_end(C, but, data);
- }
- else if (data->state == BUTTON_STATE_TEXT_SELECTING && state != BUTTON_STATE_TEXT_EDITING) {
- ui_textedit_end(C, but, data);
- }
-
- /* number editing */
- if (state == BUTTON_STATE_NUM_EDITING) {
- if (ui_but_is_cursor_warp(but)) {
- WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL);
- }
- ui_numedit_begin(but, data);
- }
- else if (data->state == BUTTON_STATE_NUM_EDITING) {
- ui_numedit_end(but, data);
-
- if (but->flag & UI_BUT_DRIVEN) {
- /* Only warn when editing stepping/dragging the value.
- * No warnings should show for editing driver expressions though!
- */
- if (state != BUTTON_STATE_TEXT_EDITING) {
- WM_report(RPT_INFO, "Can't edit driven number value, see graph editor for the driver setup.");
- }
- }
-
- if (ui_but_is_cursor_warp(but)) {
+ uiHandleButtonData *data;
+
+ data = but->active;
+ if (data->state == state) {
+ return;
+ }
+
+ /* highlight has timers for tooltips and auto open */
+ if (state == BUTTON_STATE_HIGHLIGHT) {
+ but->flag &= ~UI_SELECT;
+
+ button_tooltip_timer_reset(C, but);
+
+ /* automatic open pulldown block timer */
+ if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) {
+ if (data->used_mouse && !data->autoopentimer) {
+ int time;
+
+ if (but->block->auto_open == true) { /* test for toolbox */
+ time = 1;
+ }
+ else if ((but->block->flag & UI_BLOCK_LOOP && but->type != UI_BTYPE_BLOCK) ||
+ (but->block->auto_open == true)) {
+ time = 5 * U.menuthreshold2;
+ }
+ else if (U.uiflag & USER_MENUOPENAUTO) {
+ time = 5 * U.menuthreshold1;
+ }
+ else {
+ time = -1; /* do nothing */
+ }
+
+ if (time >= 0) {
+ data->autoopentimer = WM_event_add_timer(
+ data->wm, data->window, TIMER, 0.02 * (double)time);
+ }
+ }
+ }
+ }
+ else {
+ but->flag |= UI_SELECT;
+ UI_but_tooltip_timer_remove(C, but);
+ }
+
+ /* text editing */
+ if (state == BUTTON_STATE_TEXT_EDITING && data->state != BUTTON_STATE_TEXT_SELECTING) {
+ ui_textedit_begin(C, but, data);
+ }
+ else if (data->state == BUTTON_STATE_TEXT_EDITING && state != BUTTON_STATE_TEXT_SELECTING) {
+ ui_textedit_end(C, but, data);
+ }
+ else if (data->state == BUTTON_STATE_TEXT_SELECTING && state != BUTTON_STATE_TEXT_EDITING) {
+ ui_textedit_end(C, but, data);
+ }
+
+ /* number editing */
+ if (state == BUTTON_STATE_NUM_EDITING) {
+ if (ui_but_is_cursor_warp(but)) {
+ WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL);
+ }
+ ui_numedit_begin(but, data);
+ }
+ else if (data->state == BUTTON_STATE_NUM_EDITING) {
+ ui_numedit_end(but, data);
+
+ if (but->flag & UI_BUT_DRIVEN) {
+ /* Only warn when editing stepping/dragging the value.
+ * No warnings should show for editing driver expressions though!
+ */
+ if (state != BUTTON_STATE_TEXT_EDITING) {
+ WM_report(RPT_INFO,
+ "Can't edit driven number value, see graph editor for the driver setup.");
+ }
+ }
+
+ if (ui_but_is_cursor_warp(but)) {
#ifdef USE_CONT_MOUSE_CORRECT
- /* stereo3d has issues with changing cursor location so rather avoid */
- if (data->ungrab_mval[0] != FLT_MAX && !WM_stereo3d_enabled(data->window, false)) {
- int mouse_ungrab_xy[2];
- ui_block_to_window_fl(data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]);
- mouse_ungrab_xy[0] = data->ungrab_mval[0];
- mouse_ungrab_xy[1] = data->ungrab_mval[1];
-
- WM_cursor_grab_disable(data->window, mouse_ungrab_xy);
- }
- else {
- WM_cursor_grab_disable(data->window, NULL);
- }
+ /* stereo3d has issues with changing cursor location so rather avoid */
+ if (data->ungrab_mval[0] != FLT_MAX && !WM_stereo3d_enabled(data->window, false)) {
+ int mouse_ungrab_xy[2];
+ ui_block_to_window_fl(
+ data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]);
+ mouse_ungrab_xy[0] = data->ungrab_mval[0];
+ mouse_ungrab_xy[1] = data->ungrab_mval[1];
+
+ WM_cursor_grab_disable(data->window, mouse_ungrab_xy);
+ }
+ else {
+ WM_cursor_grab_disable(data->window, NULL);
+ }
#else
- WM_cursor_grab_disable(data->window, NULL);
+ WM_cursor_grab_disable(data->window, NULL);
#endif
- }
- }
- /* menu open */
- if (state == BUTTON_STATE_MENU_OPEN) {
- ui_block_open_begin(C, but, data);
- }
- else if (data->state == BUTTON_STATE_MENU_OPEN) {
- ui_block_open_end(C, but, data);
- }
-
- /* add a short delay before exiting, to ensure there is some feedback */
- if (state == BUTTON_STATE_WAIT_FLASH) {
- data->flashtimer = WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_FLASH_DELAY);
- }
- else if (data->flashtimer) {
- WM_event_remove_timer(data->wm, data->window, data->flashtimer);
- data->flashtimer = NULL;
- }
-
- /* add hold timer if it's used */
- if (state == BUTTON_STATE_WAIT_RELEASE && (but->hold_func != NULL)) {
- data->hold_action_timer = WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_AUTO_OPEN_THRESH);
- }
- else if (data->hold_action_timer) {
- WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
- data->hold_action_timer = NULL;
- }
-
- /* add a blocking ui handler at the window handler for blocking, modal states
- * but not for popups, because we already have a window level handler*/
- if (!(but->block->handle && but->block->handle->popup)) {
- if (button_modal_state(state)) {
- if (!button_modal_state(data->state)) {
- WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data, 0);
- }
- }
- else {
- if (button_modal_state(data->state)) {
- /* true = postpone free */
- WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, true);
- }
- }
- }
-
- /* wait for mousemove to enable drag */
- if (state == BUTTON_STATE_WAIT_DRAG) {
- but->flag &= ~UI_SELECT;
- }
-
- data->state = state;
-
- if (state != BUTTON_STATE_EXIT) {
- /* When objects for eg. are removed, running ui_but_update() can access
- * the removed data - so disable update on exit. Also in case of
- * highlight when not in a popup menu, we remove because data used in
- * button below popup might have been removed by action of popup. Needs
- * a more reliable solution... */
- if (state != BUTTON_STATE_HIGHLIGHT || (but->block->flag & UI_BLOCK_LOOP)) {
- ui_but_update(but);
- }
- }
-
- /* redraw */
- ED_region_tag_redraw(data->region);
+ }
+ }
+ /* menu open */
+ if (state == BUTTON_STATE_MENU_OPEN) {
+ ui_block_open_begin(C, but, data);
+ }
+ else if (data->state == BUTTON_STATE_MENU_OPEN) {
+ ui_block_open_end(C, but, data);
+ }
+
+ /* add a short delay before exiting, to ensure there is some feedback */
+ if (state == BUTTON_STATE_WAIT_FLASH) {
+ data->flashtimer = WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_FLASH_DELAY);
+ }
+ else if (data->flashtimer) {
+ WM_event_remove_timer(data->wm, data->window, data->flashtimer);
+ data->flashtimer = NULL;
+ }
+
+ /* add hold timer if it's used */
+ if (state == BUTTON_STATE_WAIT_RELEASE && (but->hold_func != NULL)) {
+ data->hold_action_timer = WM_event_add_timer(
+ data->wm, data->window, TIMER, BUTTON_AUTO_OPEN_THRESH);
+ }
+ else if (data->hold_action_timer) {
+ WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
+ data->hold_action_timer = NULL;
+ }
+
+ /* add a blocking ui handler at the window handler for blocking, modal states
+ * but not for popups, because we already have a window level handler*/
+ if (!(but->block->handle && but->block->handle->popup)) {
+ if (button_modal_state(state)) {
+ if (!button_modal_state(data->state)) {
+ WM_event_add_ui_handler(
+ C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data, 0);
+ }
+ }
+ else {
+ if (button_modal_state(data->state)) {
+ /* true = postpone free */
+ WM_event_remove_ui_handler(
+ &data->window->modalhandlers, ui_handler_region_menu, NULL, data, true);
+ }
+ }
+ }
+
+ /* wait for mousemove to enable drag */
+ if (state == BUTTON_STATE_WAIT_DRAG) {
+ but->flag &= ~UI_SELECT;
+ }
+
+ data->state = state;
+
+ if (state != BUTTON_STATE_EXIT) {
+ /* When objects for eg. are removed, running ui_but_update() can access
+ * the removed data - so disable update on exit. Also in case of
+ * highlight when not in a popup menu, we remove because data used in
+ * button below popup might have been removed by action of popup. Needs
+ * a more reliable solution... */
+ if (state != BUTTON_STATE_HIGHLIGHT || (but->block->flag & UI_BLOCK_LOOP)) {
+ ui_but_update(but);
+ }
+ }
+
+ /* redraw */
+ ED_region_tag_redraw(data->region);
}
static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type)
{
- uiHandleButtonData *data;
+ uiHandleButtonData *data;
- /* setup struct */
- data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
- data->wm = CTX_wm_manager(C);
- data->window = CTX_wm_window(C);
- data->region = ar;
+ /* setup struct */
+ data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
+ data->wm = CTX_wm_manager(C);
+ data->window = CTX_wm_window(C);
+ data->region = ar;
#ifdef USE_CONT_MOUSE_CORRECT
- copy_v2_fl(data->ungrab_mval, FLT_MAX);
+ copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU)) {
- /* XXX curve is temp */
- }
- else {
- if ((but->flag & UI_BUT_UPDATE_DELAY) == 0) {
- data->interactive = true;
- }
- }
-
- data->state = BUTTON_STATE_INIT;
-
- /* activate button */
- but->flag |= UI_ACTIVE;
-
- but->active = data;
-
- /* we disable auto_open in the block after a threshold, because we still
- * want to allow auto opening adjacent menus even if no button is activated
- * in between going over to the other button, but only for a short while */
- if (type == BUTTON_ACTIVATE_OVER && but->block->auto_open == true) {
- if (but->block->auto_open_last + BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer()) {
- but->block->auto_open = false;
- }
- }
-
- if (type == BUTTON_ACTIVATE_OVER) {
- data->used_mouse = true;
- }
- button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
-
- /* activate right away */
- if (but->flag & UI_BUT_IMMEDIATE) {
- if (but->type == UI_BTYPE_HOTKEY_EVENT) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
- }
- /* .. more to be added here */
- }
-
- if (type == BUTTON_ACTIVATE_OPEN) {
- button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
-
- /* activate first button in submenu */
- if (data->menu && data->menu->region) {
- ARegion *subar = data->menu->region;
- uiBlock *subblock = subar->uiblocks.first;
- uiBut *subbut;
-
- if (subblock) {
- subbut = ui_but_first(subblock);
-
- if (subbut) {
- ui_handle_button_activate(C, subar, subbut, BUTTON_ACTIVATE);
- }
- }
- }
- }
- else if (type == BUTTON_ACTIVATE_TEXT_EDITING) {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- }
- else if (type == BUTTON_ACTIVATE_APPLY) {
- button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
- }
-
- if (but->type == UI_BTYPE_GRIP) {
- const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
- WM_cursor_modal_set(data->window, horizontal ? CURSOR_X_MOVE : CURSOR_Y_MOVE);
- }
- else if (but->type == UI_BTYPE_NUM) {
- ui_numedit_set_active(but);
- }
-
- if (UI_but_has_tooltip_label(but)) {
- /* Show a label for this button. */
- bScreen *sc = WM_window_get_active_screen(data->window);
- if ((PIL_check_seconds_timer() - WM_tooltip_time_closed()) < 0.1) {
- WM_tooltip_immediate_init(
- C, CTX_wm_window(C), ar,
- ui_but_tooltip_init);
- if (sc->tool_tip) {
- sc->tool_tip->pass = 1;
- }
- }
- }
+ if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU)) {
+ /* XXX curve is temp */
+ }
+ else {
+ if ((but->flag & UI_BUT_UPDATE_DELAY) == 0) {
+ data->interactive = true;
+ }
+ }
+
+ data->state = BUTTON_STATE_INIT;
+
+ /* activate button */
+ but->flag |= UI_ACTIVE;
+
+ but->active = data;
+
+ /* we disable auto_open in the block after a threshold, because we still
+ * want to allow auto opening adjacent menus even if no button is activated
+ * in between going over to the other button, but only for a short while */
+ if (type == BUTTON_ACTIVATE_OVER && but->block->auto_open == true) {
+ if (but->block->auto_open_last + BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer()) {
+ but->block->auto_open = false;
+ }
+ }
+
+ if (type == BUTTON_ACTIVATE_OVER) {
+ data->used_mouse = true;
+ }
+ button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
+
+ /* activate right away */
+ if (but->flag & UI_BUT_IMMEDIATE) {
+ if (but->type == UI_BTYPE_HOTKEY_EVENT) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_KEY_EVENT);
+ }
+ /* .. more to be added here */
+ }
+
+ if (type == BUTTON_ACTIVATE_OPEN) {
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+
+ /* activate first button in submenu */
+ if (data->menu && data->menu->region) {
+ ARegion *subar = data->menu->region;
+ uiBlock *subblock = subar->uiblocks.first;
+ uiBut *subbut;
+
+ if (subblock) {
+ subbut = ui_but_first(subblock);
+
+ if (subbut) {
+ ui_handle_button_activate(C, subar, subbut, BUTTON_ACTIVATE);
+ }
+ }
+ }
+ }
+ else if (type == BUTTON_ACTIVATE_TEXT_EDITING) {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ }
+ else if (type == BUTTON_ACTIVATE_APPLY) {
+ button_activate_state(C, but, BUTTON_STATE_WAIT_FLASH);
+ }
+
+ if (but->type == UI_BTYPE_GRIP) {
+ const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect));
+ WM_cursor_modal_set(data->window, horizontal ? CURSOR_X_MOVE : CURSOR_Y_MOVE);
+ }
+ else if (but->type == UI_BTYPE_NUM) {
+ ui_numedit_set_active(but);
+ }
+
+ if (UI_but_has_tooltip_label(but)) {
+ /* Show a label for this button. */
+ bScreen *sc = WM_window_get_active_screen(data->window);
+ if ((PIL_check_seconds_timer() - WM_tooltip_time_closed()) < 0.1) {
+ WM_tooltip_immediate_init(C, CTX_wm_window(C), ar, ui_but_tooltip_init);
+ if (sc->tool_tip) {
+ sc->tool_tip->pass = 1;
+ }
+ }
+ }
}
static void button_activate_exit(
- bContext *C, uiBut *but, uiHandleButtonData *data,
- const bool mousemove, const bool onfree)
+ bContext *C, uiBut *but, uiHandleButtonData *data, const bool mousemove, const bool onfree)
{
- uiBlock *block = but->block;
- uiBut *bt;
+ uiBlock *block = but->block;
+ uiBut *bt;
- if (but->type == UI_BTYPE_GRIP) {
- WM_cursor_modal_restore(data->window);
- }
+ if (but->type == UI_BTYPE_GRIP) {
+ WM_cursor_modal_restore(data->window);
+ }
- /* ensure we are in the exit state */
- if (data->state != BUTTON_STATE_EXIT) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
+ /* ensure we are in the exit state */
+ if (data->state != BUTTON_STATE_EXIT) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
- /* apply the button action or value */
- if (!onfree) {
- ui_apply_but(C, block, but, data, false);
- }
+ /* apply the button action or value */
+ if (!onfree) {
+ ui_apply_but(C, block, but, data, false);
+ }
#ifdef USE_DRAG_MULTINUM
- if (data->multi_data.has_mbuts) {
- for (bt = block->buttons.first; bt; bt = bt->next) {
- if (bt->flag & UI_BUT_DRAG_MULTI) {
- bt->flag &= ~UI_BUT_DRAG_MULTI;
-
- if (!data->cancel) {
- ui_apply_but_autokey(C, bt);
- }
- }
- }
-
- ui_multibut_free(data, block);
- }
+ if (data->multi_data.has_mbuts) {
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (bt->flag & UI_BUT_DRAG_MULTI) {
+ bt->flag &= ~UI_BUT_DRAG_MULTI;
+
+ if (!data->cancel) {
+ ui_apply_but_autokey(C, bt);
+ }
+ }
+ }
+
+ ui_multibut_free(data, block);
+ }
#endif
- /* if this button is in a menu, this will set the button return
- * value to the button value and the menu return value to ok, the
- * menu return value will be picked up and the menu will close */
- if (block->handle && !(block->flag & UI_BLOCK_KEEP_OPEN)) {
- if (!data->cancel || data->escapecancel) {
- uiPopupBlockHandle *menu;
+ /* if this button is in a menu, this will set the button return
+ * value to the button value and the menu return value to ok, the
+ * menu return value will be picked up and the menu will close */
+ if (block->handle && !(block->flag & UI_BLOCK_KEEP_OPEN)) {
+ if (!data->cancel || data->escapecancel) {
+ uiPopupBlockHandle *menu;
- menu = block->handle;
- menu->butretval = data->retval;
- menu->menuretval = (data->cancel) ? UI_RETURN_CANCEL : UI_RETURN_OK;
- }
- }
+ menu = block->handle;
+ menu->butretval = data->retval;
+ menu->menuretval = (data->cancel) ? UI_RETURN_CANCEL : UI_RETURN_OK;
+ }
+ }
- if (!onfree && !data->cancel) {
- /* autokey & undo push */
- ui_apply_but_undo(but);
- ui_apply_but_autokey(C, but);
+ if (!onfree && !data->cancel) {
+ /* autokey & undo push */
+ ui_apply_but_undo(but);
+ ui_apply_but_autokey(C, but);
#ifdef USE_ALLSELECT
- {
- /* only RNA from this button is used */
- uiBut but_temp = *but;
- uiSelectContextStore *selctx_data = &data->select_others;
- for (int i = 0; i < selctx_data->elems_len; i++) {
- uiSelectContextElem *other = &selctx_data->elems[i];
- but_temp.rnapoin = other->ptr;
- ui_apply_but_autokey(C, &but_temp);
- }
- }
+ {
+ /* only RNA from this button is used */
+ uiBut but_temp = *but;
+ uiSelectContextStore *selctx_data = &data->select_others;
+ for (int i = 0; i < selctx_data->elems_len; i++) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ but_temp.rnapoin = other->ptr;
+ ui_apply_but_autokey(C, &but_temp);
+ }
+ }
#endif
- /* popup menu memory */
- if (block->flag & UI_BLOCK_POPUP_MEMORY) {
- ui_popup_menu_memory_set(block, but);
- }
- }
+ /* popup menu memory */
+ if (block->flag & UI_BLOCK_POPUP_MEMORY) {
+ ui_popup_menu_memory_set(block, but);
+ }
+ }
- /* disable tooltips until mousemove + last active flag */
- for (block = data->region->uiblocks.first; block; block = block->next) {
- for (bt = block->buttons.first; bt; bt = bt->next) {
- bt->flag &= ~UI_BUT_LAST_ACTIVE;
- }
+ /* disable tooltips until mousemove + last active flag */
+ for (block = data->region->uiblocks.first; block; block = block->next) {
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ bt->flag &= ~UI_BUT_LAST_ACTIVE;
+ }
- block->tooltipdisabled = 1;
- }
+ block->tooltipdisabled = 1;
+ }
- ui_blocks_set_tooltips(data->region, false);
+ ui_blocks_set_tooltips(data->region, false);
- /* clean up */
- if (data->str) {
- MEM_freeN(data->str);
- }
- if (data->origstr) {
- MEM_freeN(data->origstr);
- }
+ /* clean up */
+ if (data->str) {
+ MEM_freeN(data->str);
+ }
+ if (data->origstr) {
+ MEM_freeN(data->origstr);
+ }
#ifdef USE_ALLSELECT
- ui_selectcontext_end(but, &data->select_others);
+ ui_selectcontext_end(but, &data->select_others);
#endif
- if (data->changed_cursor) {
- WM_cursor_modal_restore(data->window);
- }
+ if (data->changed_cursor) {
+ WM_cursor_modal_restore(data->window);
+ }
- /* redraw and refresh (for popups) */
- ED_region_tag_redraw(data->region);
- ED_region_tag_refresh_ui(data->region);
+ /* redraw and refresh (for popups) */
+ ED_region_tag_redraw(data->region);
+ ED_region_tag_refresh_ui(data->region);
- /* clean up button */
- if (but->active) {
- MEM_freeN(but->active);
- but->active = NULL;
- }
+ /* clean up button */
+ if (but->active) {
+ MEM_freeN(but->active);
+ but->active = NULL;
+ }
- but->flag &= ~(UI_ACTIVE | UI_SELECT);
- but->flag |= UI_BUT_LAST_ACTIVE;
- if (!onfree) {
- ui_but_update(but);
- }
+ but->flag &= ~(UI_ACTIVE | UI_SELECT);
+ but->flag |= UI_BUT_LAST_ACTIVE;
+ if (!onfree) {
+ ui_but_update(but);
+ }
- /* adds empty mousemove in queue for re-init handler, in case mouse is
- * still over a button. We cannot just check for this ourselves because
- * at this point the mouse may be over a button in another region */
- if (mousemove) {
- WM_event_add_mousemove(C);
- }
+ /* adds empty mousemove in queue for re-init handler, in case mouse is
+ * still over a button. We cannot just check for this ourselves because
+ * at this point the mouse may be over a button in another region */
+ if (mousemove) {
+ WM_event_add_mousemove(C);
+ }
}
void ui_but_active_free(const bContext *C, uiBut *but)
{
- uiHandleButtonData *data;
+ uiHandleButtonData *data;
- /* this gets called when the button somehow disappears while it is still
- * active, this is bad for user interaction, but we need to handle this
- * case cleanly anyway in case it happens */
- if (but->active) {
- data = but->active;
- data->cancel = true;
- button_activate_exit((bContext *)C, but, data, false, true);
- }
+ /* this gets called when the button somehow disappears while it is still
+ * active, this is bad for user interaction, but we need to handle this
+ * case cleanly anyway in case it happens */
+ if (but->active) {
+ data = but->active;
+ data->cancel = true;
+ button_activate_exit((bContext *)C, but, data, false, true);
+ }
}
/* returns the active button with an optional checking function */
static uiBut *ui_context_button_active(ARegion *ar, bool (*but_check_cb)(uiBut *))
{
- uiBut *but_found = NULL;
-
- while (ar) {
- uiBlock *block;
- uiBut *but, *activebut = NULL;
-
- /* find active button */
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but->active) {
- activebut = but;
- }
- else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) {
- activebut = but;
- }
- }
- }
-
- if (activebut && (but_check_cb == NULL || but_check_cb(activebut))) {
- uiHandleButtonData *data = activebut->active;
-
- but_found = activebut;
-
- /* recurse into opened menu, like colorpicker case */
- if (data && data->menu && (ar != data->menu->region)) {
- ar = data->menu->region;
- }
- else {
- return but_found;
- }
- }
- else {
- /* no active button */
- return but_found;
- }
- }
-
- return but_found;
+ uiBut *but_found = NULL;
+
+ while (ar) {
+ uiBlock *block;
+ uiBut *but, *activebut = NULL;
+
+ /* find active button */
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->active) {
+ activebut = but;
+ }
+ else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) {
+ activebut = but;
+ }
+ }
+ }
+
+ if (activebut && (but_check_cb == NULL || but_check_cb(activebut))) {
+ uiHandleButtonData *data = activebut->active;
+
+ but_found = activebut;
+
+ /* recurse into opened menu, like colorpicker case */
+ if (data && data->menu && (ar != data->menu->region)) {
+ ar = data->menu->region;
+ }
+ else {
+ return but_found;
+ }
+ }
+ else {
+ /* no active button */
+ return but_found;
+ }
+ }
+
+ return but_found;
}
static bool ui_context_rna_button_active_test(uiBut *but)
{
- return (but->rnapoin.data != NULL);
+ return (but->rnapoin.data != NULL);
}
static uiBut *ui_context_rna_button_active(const bContext *C)
{
- return ui_context_button_active(CTX_wm_region(C), ui_context_rna_button_active_test);
+ return ui_context_button_active(CTX_wm_region(C), ui_context_rna_button_active_test);
}
uiBut *UI_context_active_but_get(const struct bContext *C)
{
- return ui_context_button_active(CTX_wm_region(C), NULL);
+ return ui_context_button_active(CTX_wm_region(C), NULL);
}
uiBut *UI_region_active_but_get(ARegion *ar)
{
- return ui_context_button_active(ar, NULL);
+ return ui_context_button_active(ar, NULL);
}
/**
@@ -7666,123 +7686,124 @@ uiBut *UI_region_active_but_get(ARegion *ar)
*
* \return active button, NULL if none found or if it doesn't contain valid RNA data.
*/
-uiBut *UI_context_active_but_prop_get(
- const bContext *C,
- struct PointerRNA *r_ptr, struct PropertyRNA **r_prop, int *r_index)
+uiBut *UI_context_active_but_prop_get(const bContext *C,
+ struct PointerRNA *r_ptr,
+ struct PropertyRNA **r_prop,
+ int *r_index)
{
- uiBut *activebut = ui_context_rna_button_active(C);
+ uiBut *activebut = ui_context_rna_button_active(C);
- if (activebut && activebut->rnapoin.data) {
- *r_ptr = activebut->rnapoin;
- *r_prop = activebut->rnaprop;
- *r_index = activebut->rnaindex;
- }
- else {
- memset(r_ptr, 0, sizeof(*r_ptr));
- *r_prop = NULL;
- *r_index = 0;
- }
+ if (activebut && activebut->rnapoin.data) {
+ *r_ptr = activebut->rnapoin;
+ *r_prop = activebut->rnaprop;
+ *r_index = activebut->rnaindex;
+ }
+ else {
+ memset(r_ptr, 0, sizeof(*r_ptr));
+ *r_prop = NULL;
+ *r_index = 0;
+ }
- return activebut;
+ return activebut;
}
void UI_context_active_but_prop_handle(bContext *C)
{
- uiBut *activebut = ui_context_rna_button_active(C);
- if (activebut) {
- /* TODO, look into a better way to handle the button change
- * currently this is mainly so reset defaults works for the
- * operator redo panel - campbell */
- uiBlock *block = activebut->block;
- if (block->handle_func) {
- block->handle_func(C, block->handle_func_arg, activebut->retval);
- }
- }
+ uiBut *activebut = ui_context_rna_button_active(C);
+ if (activebut) {
+ /* TODO, look into a better way to handle the button change
+ * currently this is mainly so reset defaults works for the
+ * operator redo panel - campbell */
+ uiBlock *block = activebut->block;
+ if (block->handle_func) {
+ block->handle_func(C, block->handle_func_arg, activebut->retval);
+ }
+ }
}
wmOperator *UI_context_active_operator_get(const struct bContext *C)
{
- ARegion *ar_ctx = CTX_wm_region(C);
- uiBlock *block;
-
- /* background mode */
- if (ar_ctx == NULL) {
- return NULL;
- }
-
- /* scan active regions ui */
- for (block = ar_ctx->uiblocks.first; block; block = block->next) {
- if (block->ui_operator) {
- return block->ui_operator;
- }
- }
-
- /* scan popups */
- {
- bScreen *sc = CTX_wm_screen(C);
- ARegion *ar;
-
- for (ar = sc->regionbase.first; ar; ar = ar->next) {
- if (ar == ar_ctx) {
- continue;
- }
- for (block = ar->uiblocks.first; block; block = block->next) {
- if (block->ui_operator) {
- return block->ui_operator;
- }
- }
- }
- }
-
- return NULL;
+ ARegion *ar_ctx = CTX_wm_region(C);
+ uiBlock *block;
+
+ /* background mode */
+ if (ar_ctx == NULL) {
+ return NULL;
+ }
+
+ /* scan active regions ui */
+ for (block = ar_ctx->uiblocks.first; block; block = block->next) {
+ if (block->ui_operator) {
+ return block->ui_operator;
+ }
+ }
+
+ /* scan popups */
+ {
+ bScreen *sc = CTX_wm_screen(C);
+ ARegion *ar;
+
+ for (ar = sc->regionbase.first; ar; ar = ar->next) {
+ if (ar == ar_ctx) {
+ continue;
+ }
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ if (block->ui_operator) {
+ return block->ui_operator;
+ }
+ }
+ }
+ }
+
+ return NULL;
}
/* helper function for insert keyframe, reset to default, etc operators */
void UI_context_update_anim_flag(const bContext *C)
{
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
- uiBlock *block;
- uiBut *but, *activebut;
-
- while (ar) {
- /* find active button */
- activebut = NULL;
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
- ui_but_override_flag(but);
- if (UI_but_is_decorator(but)) {
- ui_but_anim_decorate_update_from_flag(but);
- }
-
- ED_region_tag_redraw(ar);
-
- if (but->active) {
- activebut = but;
- }
- else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) {
- activebut = but;
- }
- }
- }
-
- if (activebut) {
- /* always recurse into opened menu, so all buttons update (like colorpicker) */
- uiHandleButtonData *data = activebut->active;
- if (data && data->menu) {
- ar = data->menu->region;
- }
- else {
- return;
- }
- }
- else {
- /* no active button */
- return;
- }
- }
+ Scene *scene = CTX_data_scene(C);
+ ARegion *ar = CTX_wm_region(C);
+ uiBlock *block;
+ uiBut *but, *activebut;
+
+ while (ar) {
+ /* find active button */
+ activebut = NULL;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ for (but = block->buttons.first; but; but = but->next) {
+ ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f);
+ ui_but_override_flag(but);
+ if (UI_but_is_decorator(but)) {
+ ui_but_anim_decorate_update_from_flag(but);
+ }
+
+ ED_region_tag_redraw(ar);
+
+ if (but->active) {
+ activebut = but;
+ }
+ else if (!activebut && (but->flag & UI_BUT_LAST_ACTIVE)) {
+ activebut = but;
+ }
+ }
+ }
+
+ if (activebut) {
+ /* always recurse into opened menu, so all buttons update (like colorpicker) */
+ uiHandleButtonData *data = activebut->active;
+ if (data && data->menu) {
+ ar = data->menu->region;
+ }
+ else {
+ return;
+ }
+ }
+ else {
+ /* no active button */
+ return;
+ }
+ }
}
/** \} */
@@ -7793,60 +7814,60 @@ void UI_context_update_anim_flag(const bContext *C)
static uiBut *ui_but_find_open_event(ARegion *ar, const wmEvent *event)
{
- uiBlock *block;
- uiBut *but;
+ uiBlock *block;
+ uiBut *but;
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but == event->customdata) {
- return but;
- }
- }
- }
- return NULL;
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but == event->customdata) {
+ return but;
+ }
+ }
+ }
+ return NULL;
}
static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar)
{
- uiBut *but;
+ uiBut *but;
- if (event->type == MOUSEMOVE) {
- but = ui_but_find_mouse_over(ar, event);
- if (but) {
- button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ if (event->type == MOUSEMOVE) {
+ but = ui_but_find_mouse_over(ar, event);
+ if (but) {
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
- if (event->alt && but->active) {
- /* display tooltips if holding alt on mouseover when tooltips are off in prefs */
- but->active->tooltip_force = true;
- }
- }
- }
- else if (event->type == EVT_BUT_OPEN) {
- but = ui_but_find_open_event(ar, event);
- if (but) {
- button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
- ui_do_button(C, but->block, but, event);
- }
- }
+ if (event->alt && but->active) {
+ /* display tooltips if holding alt on mouseover when tooltips are off in prefs */
+ but->active->tooltip_force = true;
+ }
+ }
+ }
+ else if (event->type == EVT_BUT_OPEN) {
+ but = ui_but_find_open_event(ar, event);
+ if (but) {
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ ui_do_button(C, but->block, but, event);
+ }
+ }
- return WM_UI_HANDLER_CONTINUE;
+ return WM_UI_HANDLER_CONTINUE;
}
/* exported to interface.c: UI_but_active_only() */
void ui_but_activate_event(bContext *C, ARegion *ar, uiBut *but)
{
- wmWindow *win = CTX_wm_window(C);
- wmEvent event;
+ wmWindow *win = CTX_wm_window(C);
+ wmEvent event;
- button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
- wm_event_init_from_window(win, &event);
- event.type = EVT_BUT_OPEN;
- event.val = KM_PRESS;
- event.customdata = but;
- event.customdatafree = false;
+ wm_event_init_from_window(win, &event);
+ event.type = EVT_BUT_OPEN;
+ event.val = KM_PRESS;
+ event.customdata = but;
+ event.customdatafree = false;
- ui_do_button(C, but->block, but, &event);
+ ui_do_button(C, but->block, but, &event);
}
/**
@@ -7857,45 +7878,54 @@ void ui_but_activate_event(bContext *C, ARegion *ar, uiBut *but)
*/
void ui_but_activate_over(bContext *C, ARegion *ar, uiBut *but)
{
- button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
}
-void ui_but_execute_begin(struct bContext *UNUSED(C), struct ARegion *ar, uiBut *but, void **active_back)
+void ui_but_execute_begin(struct bContext *UNUSED(C),
+ struct ARegion *ar,
+ uiBut *but,
+ void **active_back)
{
- /* note: ideally we would not have to change 'but->active' however
- * some functions we call don't use data (as they should be doing) */
- uiHandleButtonData *data;
- *active_back = but->active;
- data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData_Fake");
- but->active = data;
- data->region = ar;
+ /* note: ideally we would not have to change 'but->active' however
+ * some functions we call don't use data (as they should be doing) */
+ uiHandleButtonData *data;
+ *active_back = but->active;
+ data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData_Fake");
+ but->active = data;
+ data->region = ar;
}
-void ui_but_execute_end(struct bContext *C, struct ARegion *UNUSED(ar), uiBut *but, void *active_back)
+void ui_but_execute_end(struct bContext *C,
+ struct ARegion *UNUSED(ar),
+ uiBut *but,
+ void *active_back)
{
- ui_apply_but(C, but->block, but, but->active, true);
+ ui_apply_but(C, but->block, but, but->active, true);
- if ((but->flag & UI_BUT_DRAG_MULTI) == 0) {
- ui_apply_but_autokey(C, but);
- }
- /* use onfree event so undo is handled by caller and apply is already done above */
- button_activate_exit((bContext *)C, but, but->active, false, true);
- but->active = active_back;
+ if ((but->flag & UI_BUT_DRAG_MULTI) == 0) {
+ ui_apply_but_autokey(C, but);
+ }
+ /* use onfree event so undo is handled by caller and apply is already done above */
+ button_activate_exit((bContext *)C, but, but->active, false, true);
+ but->active = active_back;
}
-static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type)
+static void ui_handle_button_activate(bContext *C,
+ ARegion *ar,
+ uiBut *but,
+ uiButtonActivateType type)
{
- uiBut *oldbut;
- uiHandleButtonData *data;
+ uiBut *oldbut;
+ uiHandleButtonData *data;
- oldbut = ui_region_find_active_but(ar);
- if (oldbut) {
- data = oldbut->active;
- data->cancel = true;
- button_activate_exit(C, oldbut, data, false, false);
- }
+ oldbut = ui_region_find_active_but(ar);
+ if (oldbut) {
+ data = oldbut->active;
+ data->cancel = true;
+ button_activate_exit(C, oldbut, data, false, false);
+ }
- button_activate_init(C, ar, but, type);
+ button_activate_init(C, ar, but, type);
}
/**
@@ -7903,25 +7933,25 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
*/
static bool ui_handle_button_activate_by_type(bContext *C, ARegion *ar, uiBut *but)
{
- if (but->type == UI_BTYPE_BUT_MENU) {
- /* mainly for operator buttons */
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_APPLY);
- }
- else if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) {
- /* open sub-menus (like right arrow key) */
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
- }
- else if (but->type == UI_BTYPE_MENU) {
- /* activate menu items */
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
- }
- else {
+ if (but->type == UI_BTYPE_BUT_MENU) {
+ /* mainly for operator buttons */
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_APPLY);
+ }
+ else if (ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) {
+ /* open sub-menus (like right arrow key) */
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
+ }
+ else if (but->type == UI_BTYPE_MENU) {
+ /* activate menu items */
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
+ }
+ else {
#ifdef DEBUG
- printf("%s: error, unhandled type: %u\n", __func__, but->type);
+ printf("%s: error, unhandled type: %u\n", __func__, but->type);
#endif
- return false;
- }
- return true;
+ return false;
+ }
+ return true;
}
/** \} */
@@ -7932,502 +7962,494 @@ static bool ui_handle_button_activate_by_type(bContext *C, ARegion *ar, uiBut *b
static bool ui_button_value_default(uiBut *but, double *r_value)
{
- if (but->rnaprop != NULL && ui_but_is_rna_valid(but)) {
- int type = RNA_property_type(but->rnaprop);
- if (ELEM(type, PROP_FLOAT, PROP_INT)) {
- double default_value;
- switch (type) {
- case PROP_INT:
- if (RNA_property_array_check(but->rnaprop)) {
- default_value = (double)RNA_property_int_get_default_index(&but->rnapoin, but->rnaprop, but->rnaindex);
- }
- else {
- default_value = (double)RNA_property_int_get_default(&but->rnapoin, but->rnaprop);
- }
- break;
- case PROP_FLOAT:
- if (RNA_property_array_check(but->rnaprop)) {
- default_value = (double)RNA_property_float_get_default_index(&but->rnapoin, but->rnaprop, but->rnaindex);
- }
- else {
- default_value = (double)RNA_property_float_get_default(&but->rnapoin, but->rnaprop);
- }
- break;
- }
- *r_value = default_value;
- return true;
- }
- }
- return false;
+ if (but->rnaprop != NULL && ui_but_is_rna_valid(but)) {
+ int type = RNA_property_type(but->rnaprop);
+ if (ELEM(type, PROP_FLOAT, PROP_INT)) {
+ double default_value;
+ switch (type) {
+ case PROP_INT:
+ if (RNA_property_array_check(but->rnaprop)) {
+ default_value = (double)RNA_property_int_get_default_index(
+ &but->rnapoin, but->rnaprop, but->rnaindex);
+ }
+ else {
+ default_value = (double)RNA_property_int_get_default(&but->rnapoin, but->rnaprop);
+ }
+ break;
+ case PROP_FLOAT:
+ if (RNA_property_array_check(but->rnaprop)) {
+ default_value = (double)RNA_property_float_get_default_index(
+ &but->rnapoin, but->rnaprop, but->rnaindex);
+ }
+ else {
+ default_value = (double)RNA_property_float_get_default(&but->rnapoin, but->rnaprop);
+ }
+ break;
+ }
+ *r_value = default_value;
+ return true;
+ }
+ }
+ return false;
}
static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
{
- uiHandleButtonData *data = but->active;
- const uiHandleButtonState state_orig = data->state;
- uiBlock *block;
- ARegion *ar;
- int retval;
+ uiHandleButtonData *data = but->active;
+ const uiHandleButtonState state_orig = data->state;
+ uiBlock *block;
+ ARegion *ar;
+ int retval;
- block = but->block;
- ar = data->region;
+ block = but->block;
+ ar = data->region;
- retval = WM_UI_HANDLER_CONTINUE;
+ retval = WM_UI_HANDLER_CONTINUE;
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- switch (event->type) {
- case WINDEACTIVATE:
- case EVT_BUT_CANCEL:
- data->cancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- break;
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ switch (event->type) {
+ case WINDEACTIVATE:
+ case EVT_BUT_CANCEL:
+ data->cancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ break;
#ifdef USE_UI_POPOVER_ONCE
- case LEFTMOUSE:
- {
- if (event->val == KM_RELEASE) {
- if (block->flag & UI_BLOCK_POPOVER_ONCE) {
- if (!(but->flag & UI_BUT_DISABLED)) {
- if (ui_but_is_popover_once_compat(but)) {
- data->cancel = false;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval = WM_UI_HANDLER_BREAK;
- /* Cancel because this `but` handles all events and we don't want
- * the parent button's update function to do anything.
- *
- * Causes issues with buttons defined by #uiItemFullR_with_popover. */
- block->handle->menuretval = UI_RETURN_CANCEL;
- }
- else if (ui_but_is_editable_as_text(but)) {
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_TEXT_EDITING);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- }
- }
- break;
- }
+ case LEFTMOUSE: {
+ if (event->val == KM_RELEASE) {
+ if (block->flag & UI_BLOCK_POPOVER_ONCE) {
+ if (!(but->flag & UI_BUT_DISABLED)) {
+ if (ui_but_is_popover_once_compat(but)) {
+ data->cancel = false;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval = WM_UI_HANDLER_BREAK;
+ /* Cancel because this `but` handles all events and we don't want
+ * the parent button's update function to do anything.
+ *
+ * Causes issues with buttons defined by #uiItemFullR_with_popover. */
+ block->handle->menuretval = UI_RETURN_CANCEL;
+ }
+ else if (ui_but_is_editable_as_text(but)) {
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_TEXT_EDITING);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ }
+ break;
+ }
#endif
- case MOUSEMOVE:
- {
- uiBut *but_other = ui_but_find_mouse_over(ar, event);
- bool exit = false;
-
- /* always deactivate button for pie menus,
- * else moving to blank space will leave activated */
- if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(block)) &&
- !ui_but_contains_point_px(but, ar, event->x, event->y))
- {
- exit = true;
- }
- else if (but_other && ui_but_is_editable(but_other) && (but_other != but)) {
- exit = true;
- }
-
- if (exit) {
- data->cancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else if (event->x != event->prevx || event->y != event->prevy) {
- /* re-enable tooltip on mouse move */
- ui_blocks_set_tooltips(ar, true);
- button_tooltip_timer_reset(C, but);
- }
-
- break;
- }
- case TIMER:
- {
- /* Handle menu auto open timer. */
- if (event->customdata == data->autoopentimer) {
- WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
- data->autoopentimer = NULL;
-
- if (ui_but_contains_point_px(but, ar, event->x, event->y) || but->active) {
- button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
- }
- }
-
- break;
- }
- /* XXX hardcoded keymap check... but anyway,
- * while view changes, tooltips should be removed */
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- case MIDDLEMOUSE:
- case MOUSEPAN:
- UI_but_tooltip_timer_remove(C, but);
- ATTR_FALLTHROUGH;
- default:
- break;
- }
-
- /* handle button type specific events */
- retval = ui_do_button(C, block, but, event);
- }
- else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
- switch (event->type) {
- case WINDEACTIVATE:
- data->cancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- break;
-
- case TIMER:
- {
- if (event->customdata == data->hold_action_timer) {
- if (true) {
- data->cancel = true;
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- else {
- /* Do this so we can still mouse-up, closing the menu and running the button.
- * This is nice to support but there are times when the button gets left pressed.
- * Keep disavled for now. */
- WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
- data->hold_action_timer = NULL;
- }
- retval = WM_UI_HANDLER_CONTINUE;
- but->hold_func(C, data->region, but);
- }
- break;
- }
- case MOUSEMOVE:
- {
- /* deselect the button when moving the mouse away */
- /* also de-activate for buttons that only show highlights */
- if (ui_but_contains_point_px(but, ar, event->x, event->y)) {
-
- /* Drag on a hold button (used in the toolbar) now opens it immediately. */
- if (data->hold_action_timer) {
- if (but->flag & UI_SELECT) {
- if (len_manhattan_v2v2_int(&event->x, &event->prevx) <= WM_EVENT_CURSOR_MOTION_THRESHOLD) {
- /* pass */
- }
- else {
- WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
- data->hold_action_timer = WM_event_add_timer(data->wm, data->window, TIMER, 0.0f);
- }
- }
- }
-
- if (!(but->flag & UI_SELECT)) {
- but->flag |= (UI_SELECT | UI_ACTIVE);
- data->cancel = false;
- ED_region_tag_redraw(data->region);
- }
- }
- else {
- if (but->flag & UI_SELECT) {
- but->flag &= ~(UI_SELECT | UI_ACTIVE);
- data->cancel = true;
- ED_region_tag_redraw(data->region);
- }
- }
- break;
- }
- default:
- /* otherwise catch mouse release event */
- ui_do_button(C, block, but, event);
- break;
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (data->state == BUTTON_STATE_WAIT_FLASH) {
- switch (event->type) {
- case TIMER:
- {
- if (event->customdata == data->flashtimer) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- break;
- }
- }
-
- retval = WM_UI_HANDLER_CONTINUE;
- }
- else if (data->state == BUTTON_STATE_MENU_OPEN) {
- /* check for exit because of mouse-over another button */
- switch (event->type) {
- case MOUSEMOVE:
- {
- uiBut *bt;
-
- if (data->menu && data->menu->region) {
- if (ui_region_contains_point_px(data->menu->region, event->x, event->y)) {
- break;
- }
- }
-
- bt = ui_but_find_mouse_over(ar, event);
-
- if (bt && bt->active != data) {
- if (but->type != UI_BTYPE_COLOR) { /* exception */
- data->cancel = true;
- }
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- break;
- }
- case RIGHTMOUSE:
- {
- if (event->val == KM_PRESS) {
- uiBut *bt = ui_but_find_mouse_over(ar, event);
- if (bt && bt->active == data) {
- button_activate_state(C, bt, BUTTON_STATE_HIGHLIGHT);
- }
- }
- break;
- }
-
- }
-
- ui_do_button(C, block, but, event);
- retval = WM_UI_HANDLER_CONTINUE;
- }
- else {
- retval = ui_do_button(C, block, but, event);
- // retval = WM_UI_HANDLER_BREAK; XXX why ?
- }
-
- /* may have been re-allocated above (eyedropper for eg) */
- data = but->active;
- if (data && data->state == BUTTON_STATE_EXIT) {
- uiBut *post_but = data->postbut;
- uiButtonActivateType post_type = data->posttype;
-
- /* Reset the button value when empty text is typed. */
- if ((data->cancel == false) && (data->str != NULL) && (data->str[0] == '\0') &&
- (but->rnaprop && ELEM(RNA_property_type(but->rnaprop), PROP_FLOAT, PROP_INT)))
- {
- MEM_SAFE_FREE(data->str);
- ui_button_value_default(but, &data->value);
+ case MOUSEMOVE: {
+ uiBut *but_other = ui_but_find_mouse_over(ar, event);
+ bool exit = false;
+
+ /* always deactivate button for pie menus,
+ * else moving to blank space will leave activated */
+ if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(block)) &&
+ !ui_but_contains_point_px(but, ar, event->x, event->y)) {
+ exit = true;
+ }
+ else if (but_other && ui_but_is_editable(but_other) && (but_other != but)) {
+ exit = true;
+ }
+
+ if (exit) {
+ data->cancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if (event->x != event->prevx || event->y != event->prevy) {
+ /* re-enable tooltip on mouse move */
+ ui_blocks_set_tooltips(ar, true);
+ button_tooltip_timer_reset(C, but);
+ }
+
+ break;
+ }
+ case TIMER: {
+ /* Handle menu auto open timer. */
+ if (event->customdata == data->autoopentimer) {
+ WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
+ data->autoopentimer = NULL;
+
+ if (ui_but_contains_point_px(but, ar, event->x, event->y) || but->active) {
+ button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
+ }
+ }
+
+ break;
+ }
+ /* XXX hardcoded keymap check... but anyway,
+ * while view changes, tooltips should be removed */
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE:
+ case MIDDLEMOUSE:
+ case MOUSEPAN:
+ UI_but_tooltip_timer_remove(C, but);
+ ATTR_FALLTHROUGH;
+ default:
+ break;
+ }
+
+ /* handle button type specific events */
+ retval = ui_do_button(C, block, but, event);
+ }
+ else if (data->state == BUTTON_STATE_WAIT_RELEASE) {
+ switch (event->type) {
+ case WINDEACTIVATE:
+ data->cancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ break;
+
+ case TIMER: {
+ if (event->customdata == data->hold_action_timer) {
+ if (true) {
+ data->cancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ /* Do this so we can still mouse-up, closing the menu and running the button.
+ * This is nice to support but there are times when the button gets left pressed.
+ * Keep disavled for now. */
+ WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
+ data->hold_action_timer = NULL;
+ }
+ retval = WM_UI_HANDLER_CONTINUE;
+ but->hold_func(C, data->region, but);
+ }
+ break;
+ }
+ case MOUSEMOVE: {
+ /* deselect the button when moving the mouse away */
+ /* also de-activate for buttons that only show highlights */
+ if (ui_but_contains_point_px(but, ar, event->x, event->y)) {
+
+ /* Drag on a hold button (used in the toolbar) now opens it immediately. */
+ if (data->hold_action_timer) {
+ if (but->flag & UI_SELECT) {
+ if (len_manhattan_v2v2_int(&event->x, &event->prevx) <=
+ WM_EVENT_CURSOR_MOTION_THRESHOLD) {
+ /* pass */
+ }
+ else {
+ WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
+ data->hold_action_timer = WM_event_add_timer(data->wm, data->window, TIMER, 0.0f);
+ }
+ }
+ }
+
+ if (!(but->flag & UI_SELECT)) {
+ but->flag |= (UI_SELECT | UI_ACTIVE);
+ data->cancel = false;
+ ED_region_tag_redraw(data->region);
+ }
+ }
+ else {
+ if (but->flag & UI_SELECT) {
+ but->flag &= ~(UI_SELECT | UI_ACTIVE);
+ data->cancel = true;
+ ED_region_tag_redraw(data->region);
+ }
+ }
+ break;
+ }
+ default:
+ /* otherwise catch mouse release event */
+ ui_do_button(C, block, but, event);
+ break;
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (data->state == BUTTON_STATE_WAIT_FLASH) {
+ switch (event->type) {
+ case TIMER: {
+ if (event->customdata == data->flashtimer) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ break;
+ }
+ }
+
+ retval = WM_UI_HANDLER_CONTINUE;
+ }
+ else if (data->state == BUTTON_STATE_MENU_OPEN) {
+ /* check for exit because of mouse-over another button */
+ switch (event->type) {
+ case MOUSEMOVE: {
+ uiBut *bt;
+
+ if (data->menu && data->menu->region) {
+ if (ui_region_contains_point_px(data->menu->region, event->x, event->y)) {
+ break;
+ }
+ }
+
+ bt = ui_but_find_mouse_over(ar, event);
+
+ if (bt && bt->active != data) {
+ if (but->type != UI_BTYPE_COLOR) { /* exception */
+ data->cancel = true;
+ }
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ break;
+ }
+ case RIGHTMOUSE: {
+ if (event->val == KM_PRESS) {
+ uiBut *bt = ui_but_find_mouse_over(ar, event);
+ if (bt && bt->active == data) {
+ button_activate_state(C, bt, BUTTON_STATE_HIGHLIGHT);
+ }
+ }
+ break;
+ }
+ }
+
+ ui_do_button(C, block, but, event);
+ retval = WM_UI_HANDLER_CONTINUE;
+ }
+ else {
+ retval = ui_do_button(C, block, but, event);
+ // retval = WM_UI_HANDLER_BREAK; XXX why ?
+ }
+
+ /* may have been re-allocated above (eyedropper for eg) */
+ data = but->active;
+ if (data && data->state == BUTTON_STATE_EXIT) {
+ uiBut *post_but = data->postbut;
+ uiButtonActivateType post_type = data->posttype;
+
+ /* Reset the button value when empty text is typed. */
+ if ((data->cancel == false) && (data->str != NULL) && (data->str[0] == '\0') &&
+ (but->rnaprop && ELEM(RNA_property_type(but->rnaprop), PROP_FLOAT, PROP_INT))) {
+ MEM_SAFE_FREE(data->str);
+ ui_button_value_default(but, &data->value);
#ifdef USE_DRAG_MULTINUM
- if (data->multi_data.mbuts) {
- for (LinkNode *l = data->multi_data.mbuts; l; l = l->next) {
- uiButMultiState *state = l->link;
- uiBut *but_iter = state->but;
- double default_value;
-
- if (ui_button_value_default(but_iter, &default_value)) {
- ui_but_value_set(but_iter, default_value);
- }
- }
- }
- data->multi_data.skip = true;
+ if (data->multi_data.mbuts) {
+ for (LinkNode *l = data->multi_data.mbuts; l; l = l->next) {
+ uiButMultiState *state = l->link;
+ uiBut *but_iter = state->but;
+ double default_value;
+
+ if (ui_button_value_default(but_iter, &default_value)) {
+ ui_but_value_set(but_iter, default_value);
+ }
+ }
+ }
+ data->multi_data.skip = true;
#endif
- }
-
- button_activate_exit(C, but, data, (post_but == NULL), false);
-
- /* for jumping to the next button with tab while text editing */
- if (post_but) {
- button_activate_init(C, ar, post_but, post_type);
- }
- else {
- /* XXX issue is because WM_event_add_mousemove(C) is a bad hack and not reliable,
- * if that gets coded better this bypass can go away too.
- *
- * This is needed to make sure if a button was active,
- * it stays active while the mouse is over it.
- * This avoids adding mousemoves, see: [#33466] */
- if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT)) {
- if (ui_but_find_mouse_over(ar, event) == but) {
- button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
- }
- }
- }
- }
-
- return retval;
+ }
+
+ button_activate_exit(C, but, data, (post_but == NULL), false);
+
+ /* for jumping to the next button with tab while text editing */
+ if (post_but) {
+ button_activate_init(C, ar, post_but, post_type);
+ }
+ else {
+ /* XXX issue is because WM_event_add_mousemove(C) is a bad hack and not reliable,
+ * if that gets coded better this bypass can go away too.
+ *
+ * This is needed to make sure if a button was active,
+ * it stays active while the mouse is over it.
+ * This avoids adding mousemoves, see: [#33466] */
+ if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT)) {
+ if (ui_but_find_mouse_over(ar, event) == but) {
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
+ }
+ }
+ }
+ }
+
+ return retval;
}
static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar, uiBut *listbox)
{
- uiList *ui_list;
- uiListDyn *dyn_data;
- int retval = WM_UI_HANDLER_CONTINUE;
- int type = event->type, val = event->val;
- bool redraw = false;
- int mx, my;
-
- ui_list = listbox->custom_data;
- if (!ui_list || !ui_list->dyn_data) {
- return retval;
- }
- dyn_data = ui_list->dyn_data;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(ar, listbox->block, &mx, &my);
-
- /* convert pan to scrollwheel */
- if (type == MOUSEPAN) {
- ui_pan_to_scroll(event, &type, &val);
-
- /* if type still is mousepan, we call it handled, since delta-y accumulate */
- /* also see wm_event_system.c do_wheel_ui hack */
- if (type == MOUSEPAN) {
- retval = WM_UI_HANDLER_BREAK;
- }
- }
-
- if (val == KM_PRESS) {
- if ((ELEM(type, UPARROWKEY, DOWNARROWKEY) && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) ||
- ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->ctrl && !IS_EVENT_MOD(event, shift, alt, oskey))))
- {
- const int value_orig = RNA_property_int_get(&listbox->rnapoin, listbox->rnaprop);
- int value, min, max, inc;
-
- /* activate up/down the list */
- value = value_orig;
- if ((ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0) {
- inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? 1 : -1;
- }
- else {
- inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? -1 : 1;
- }
-
- if (dyn_data->items_filter_neworder || dyn_data->items_filter_flags) {
- /* If we have a display order different from
- * collection order, we have some work! */
- int *org_order = MEM_mallocN(dyn_data->items_shown * sizeof(int), __func__);
- const int *new_order = dyn_data->items_filter_neworder;
- int i, org_idx = -1, len = dyn_data->items_len;
- int current_idx = -1;
- int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
-
- for (i = 0; i < len; i++) {
- if (!dyn_data->items_filter_flags ||
- ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude))
- {
- org_order[new_order ? new_order[++org_idx] : ++org_idx] = i;
- if (i == value) {
- current_idx = new_order ? new_order[org_idx] : org_idx;
- }
- }
- else if (i == value && org_idx >= 0) {
- current_idx = -(new_order ? new_order[org_idx] : org_idx) - 1;
- }
- }
- /* Now, org_order maps displayed indices to real indices,
- * and current_idx either contains the displayed index of active value (positive),
- * or its more-nearest one (negated).
- */
- if (current_idx < 0) {
- current_idx = (current_idx * -1) + (inc < 0 ? inc : inc - 1);
- }
- else {
- current_idx += inc;
- }
- CLAMP(current_idx, 0, dyn_data->items_shown - 1);
- value = org_order[current_idx];
- MEM_freeN(org_order);
- }
- else {
- value += inc;
- }
-
- CLAMP(value, 0, dyn_data->items_len - 1);
-
- RNA_property_int_range(&listbox->rnapoin, listbox->rnaprop, &min, &max);
- CLAMP(value, min, max);
-
- if (value != value_orig) {
- RNA_property_int_set(&listbox->rnapoin, listbox->rnaprop, value);
- RNA_property_update(C, &listbox->rnapoin, listbox->rnaprop);
-
- ui_apply_but_undo(listbox);
-
- ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
- redraw = true;
- }
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
- /* We now have proper grip, but keep this anyway! */
- if (ui_list->list_grip < (dyn_data->visual_height_min - UI_LIST_AUTO_SIZE_THRESHOLD)) {
- ui_list->list_grip = dyn_data->visual_height;
- }
- ui_list->list_grip += (type == WHEELUPMOUSE) ? -1 : 1;
-
- ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
-
- redraw = true;
- retval = WM_UI_HANDLER_BREAK;
- }
- else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
- if (dyn_data->height > dyn_data->visual_height) {
- /* list template will clamp */
- ui_list->list_scroll += (type == WHEELUPMOUSE) ? -1 : 1;
-
- redraw = true;
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- }
-
- if (redraw) {
- ED_region_tag_redraw(ar);
- ED_region_tag_refresh_ui(ar);
- }
-
- return retval;
+ uiList *ui_list;
+ uiListDyn *dyn_data;
+ int retval = WM_UI_HANDLER_CONTINUE;
+ int type = event->type, val = event->val;
+ bool redraw = false;
+ int mx, my;
+
+ ui_list = listbox->custom_data;
+ if (!ui_list || !ui_list->dyn_data) {
+ return retval;
+ }
+ dyn_data = ui_list->dyn_data;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(ar, listbox->block, &mx, &my);
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+
+ /* if type still is mousepan, we call it handled, since delta-y accumulate */
+ /* also see wm_event_system.c do_wheel_ui hack */
+ if (type == MOUSEPAN) {
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+
+ if (val == KM_PRESS) {
+ if ((ELEM(type, UPARROWKEY, DOWNARROWKEY) && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) ||
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->ctrl &&
+ !IS_EVENT_MOD(event, shift, alt, oskey)))) {
+ const int value_orig = RNA_property_int_get(&listbox->rnapoin, listbox->rnaprop);
+ int value, min, max, inc;
+
+ /* activate up/down the list */
+ value = value_orig;
+ if ((ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0) {
+ inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? 1 : -1;
+ }
+ else {
+ inc = ELEM(type, UPARROWKEY, WHEELUPMOUSE) ? -1 : 1;
+ }
+
+ if (dyn_data->items_filter_neworder || dyn_data->items_filter_flags) {
+ /* If we have a display order different from
+ * collection order, we have some work! */
+ int *org_order = MEM_mallocN(dyn_data->items_shown * sizeof(int), __func__);
+ const int *new_order = dyn_data->items_filter_neworder;
+ int i, org_idx = -1, len = dyn_data->items_len;
+ int current_idx = -1;
+ int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
+
+ for (i = 0; i < len; i++) {
+ if (!dyn_data->items_filter_flags ||
+ ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)) {
+ org_order[new_order ? new_order[++org_idx] : ++org_idx] = i;
+ if (i == value) {
+ current_idx = new_order ? new_order[org_idx] : org_idx;
+ }
+ }
+ else if (i == value && org_idx >= 0) {
+ current_idx = -(new_order ? new_order[org_idx] : org_idx) - 1;
+ }
+ }
+ /* Now, org_order maps displayed indices to real indices,
+ * and current_idx either contains the displayed index of active value (positive),
+ * or its more-nearest one (negated).
+ */
+ if (current_idx < 0) {
+ current_idx = (current_idx * -1) + (inc < 0 ? inc : inc - 1);
+ }
+ else {
+ current_idx += inc;
+ }
+ CLAMP(current_idx, 0, dyn_data->items_shown - 1);
+ value = org_order[current_idx];
+ MEM_freeN(org_order);
+ }
+ else {
+ value += inc;
+ }
+
+ CLAMP(value, 0, dyn_data->items_len - 1);
+
+ RNA_property_int_range(&listbox->rnapoin, listbox->rnaprop, &min, &max);
+ CLAMP(value, min, max);
+
+ if (value != value_orig) {
+ RNA_property_int_set(&listbox->rnapoin, listbox->rnaprop, value);
+ RNA_property_update(C, &listbox->rnapoin, listbox->rnaprop);
+
+ ui_apply_but_undo(listbox);
+
+ ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+ redraw = true;
+ }
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
+ /* We now have proper grip, but keep this anyway! */
+ if (ui_list->list_grip < (dyn_data->visual_height_min - UI_LIST_AUTO_SIZE_THRESHOLD)) {
+ ui_list->list_grip = dyn_data->visual_height;
+ }
+ ui_list->list_grip += (type == WHEELUPMOUSE) ? -1 : 1;
+
+ ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+
+ redraw = true;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else if (ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ if (dyn_data->height > dyn_data->visual_height) {
+ /* list template will clamp */
+ ui_list->list_scroll += (type == WHEELUPMOUSE) ? -1 : 1;
+
+ redraw = true;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+
+ if (redraw) {
+ ED_region_tag_redraw(ar);
+ ED_region_tag_refresh_ui(ar);
+ }
+
+ return retval;
}
static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, uiBut *but)
{
- uiHandleButtonData *data;
- uiPopupBlockHandle *menu;
-
- data = but->active;
- menu = data->menu;
-
- /* copy over return values from the closing menu */
- if ((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_UPDATE)) {
- if (but->type == UI_BTYPE_COLOR) {
- copy_v3_v3(data->vec, menu->retvec);
- }
- else if (but->type == UI_BTYPE_MENU) {
- data->value = menu->retvalue;
- }
- }
-
- if (menu->menuretval & UI_RETURN_UPDATE) {
- if (data->interactive) {
- ui_apply_but(C, but->block, but, data, true);
- }
- else {
- ui_but_update(but);
- }
-
- menu->menuretval = 0;
- }
-
- /* now change button state or exit, which will close the submenu */
- if ((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_CANCEL)) {
- if (menu->menuretval != UI_RETURN_OK) {
- data->cancel = true;
- }
-
- button_activate_exit(C, but, data, true, false);
- }
- else if (menu->menuretval & UI_RETURN_OUT) {
- if (event->type == MOUSEMOVE && ui_but_contains_point_px(but, data->region, event->x, event->y)) {
- button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
- }
- else {
- if (ISKEYBOARD(event->type)) {
- /* keyboard menu hierarchy navigation, going back to previous level */
- but->active->used_mouse = false;
- button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
- }
- else {
- data->cancel = true;
- button_activate_exit(C, but, data, true, false);
- }
- }
- }
+ uiHandleButtonData *data;
+ uiPopupBlockHandle *menu;
+
+ data = but->active;
+ menu = data->menu;
+
+ /* copy over return values from the closing menu */
+ if ((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_UPDATE)) {
+ if (but->type == UI_BTYPE_COLOR) {
+ copy_v3_v3(data->vec, menu->retvec);
+ }
+ else if (but->type == UI_BTYPE_MENU) {
+ data->value = menu->retvalue;
+ }
+ }
+
+ if (menu->menuretval & UI_RETURN_UPDATE) {
+ if (data->interactive) {
+ ui_apply_but(C, but->block, but, data, true);
+ }
+ else {
+ ui_but_update(but);
+ }
+
+ menu->menuretval = 0;
+ }
+
+ /* now change button state or exit, which will close the submenu */
+ if ((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_CANCEL)) {
+ if (menu->menuretval != UI_RETURN_OK) {
+ data->cancel = true;
+ }
+
+ button_activate_exit(C, but, data, true, false);
+ }
+ else if (menu->menuretval & UI_RETURN_OUT) {
+ if (event->type == MOUSEMOVE &&
+ ui_but_contains_point_px(but, data->region, event->x, event->y)) {
+ button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
+ }
+ else {
+ if (ISKEYBOARD(event->type)) {
+ /* keyboard menu hierarchy navigation, going back to previous level */
+ but->active->used_mouse = false;
+ button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
+ }
+ else {
+ data->cancel = true;
+ button_activate_exit(C, but, data, true, false);
+ }
+ }
+ }
}
/** \} */
@@ -8446,124 +8468,122 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u
* - only for 1 second.
*/
-static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu, const int xy[2], const bool force)
+static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu,
+ const int xy[2],
+ const bool force)
{
- BLI_assert(((uiBlock *)menu->region->uiblocks.first)->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER));
+ BLI_assert(((uiBlock *)menu->region->uiblocks.first)->flag &
+ (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER));
- if (!menu->dotowards || force) {
- menu->dotowards = true;
- menu->towards_xy[0] = xy[0];
- menu->towards_xy[1] = xy[1];
+ if (!menu->dotowards || force) {
+ menu->dotowards = true;
+ menu->towards_xy[0] = xy[0];
+ menu->towards_xy[1] = xy[1];
- if (force) {
- menu->towardstime = DBL_MAX; /* unlimited time */
- }
- else {
- menu->towardstime = PIL_check_seconds_timer();
- }
- }
+ if (force) {
+ menu->towardstime = DBL_MAX; /* unlimited time */
+ }
+ else {
+ menu->towardstime = PIL_check_seconds_timer();
+ }
+ }
}
static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, const int xy[2])
{
- ui_mouse_motion_towards_init_ex(menu, xy, false);
+ ui_mouse_motion_towards_init_ex(menu, xy, false);
}
static void ui_mouse_motion_towards_reinit(uiPopupBlockHandle *menu, const int xy[2])
{
- ui_mouse_motion_towards_init_ex(menu, xy, true);
+ ui_mouse_motion_towards_init_ex(menu, xy, true);
}
-static bool ui_mouse_motion_towards_check(
- uiBlock *block, uiPopupBlockHandle *menu, const int xy[2],
- const bool use_wiggle_room)
+static bool ui_mouse_motion_towards_check(uiBlock *block,
+ uiPopupBlockHandle *menu,
+ const int xy[2],
+ const bool use_wiggle_room)
{
- float p1[2], p2[2], p3[2], p4[2];
- float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]};
- const float newp[2] = {xy[0], xy[1]};
- bool closer;
- const float margin = MENU_TOWARDS_MARGIN;
- rctf rect_px;
-
- BLI_assert(block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER));
-
+ float p1[2], p2[2], p3[2], p4[2];
+ float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]};
+ const float newp[2] = {xy[0], xy[1]};
+ bool closer;
+ const float margin = MENU_TOWARDS_MARGIN;
+ rctf rect_px;
- /* annoying fix for [#36269], this is a bit odd but in fact works quite well
- * don't mouse-out of a menu if another menu has been created after it.
- * if this causes problems we could remove it and check on a different fix - campbell */
- if (menu->region->next) {
- /* am I the last menu (test) */
- ARegion *ar = menu->region->next;
- do {
- uiBlock *block_iter = ar->uiblocks.first;
- if (block_iter && ui_block_is_menu(block_iter)) {
- return true;
- }
- } while ((ar = ar->next));
- }
- /* annoying fix end! */
+ BLI_assert(block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER));
+ /* annoying fix for [#36269], this is a bit odd but in fact works quite well
+ * don't mouse-out of a menu if another menu has been created after it.
+ * if this causes problems we could remove it and check on a different fix - campbell */
+ if (menu->region->next) {
+ /* am I the last menu (test) */
+ ARegion *ar = menu->region->next;
+ do {
+ uiBlock *block_iter = ar->uiblocks.first;
+ if (block_iter && ui_block_is_menu(block_iter)) {
+ return true;
+ }
+ } while ((ar = ar->next));
+ }
+ /* annoying fix end! */
- if (!menu->dotowards) {
- return false;
- }
+ if (!menu->dotowards) {
+ return false;
+ }
- if (len_squared_v2v2(oldp, newp) < (4.0f * 4.0f)) {
- return menu->dotowards;
- }
+ if (len_squared_v2v2(oldp, newp) < (4.0f * 4.0f)) {
+ return menu->dotowards;
+ }
- /* verify that we are moving towards one of the edges of the
- * menu block, in other words, in the triangle formed by the
- * initial mouse location and two edge points. */
- ui_block_to_window_rctf(menu->region, block, &rect_px, &block->rect);
+ /* verify that we are moving towards one of the edges of the
+ * menu block, in other words, in the triangle formed by the
+ * initial mouse location and two edge points. */
+ ui_block_to_window_rctf(menu->region, block, &rect_px, &block->rect);
- p1[0] = rect_px.xmin - margin;
- p1[1] = rect_px.ymin - margin;
+ p1[0] = rect_px.xmin - margin;
+ p1[1] = rect_px.ymin - margin;
- p2[0] = rect_px.xmax + margin;
- p2[1] = rect_px.ymin - margin;
+ p2[0] = rect_px.xmax + margin;
+ p2[1] = rect_px.ymin - margin;
- p3[0] = rect_px.xmax + margin;
- p3[1] = rect_px.ymax + margin;
+ p3[0] = rect_px.xmax + margin;
+ p3[1] = rect_px.ymax + margin;
- p4[0] = rect_px.xmin - margin;
- p4[1] = rect_px.ymax + margin;
+ p4[0] = rect_px.xmin - margin;
+ p4[1] = rect_px.ymax + margin;
- /* allow for some wiggle room, if the user moves a few pixels away,
- * don't immediately quit (only for top level menus) */
- if (use_wiggle_room) {
- const float cent[2] = {
- BLI_rctf_cent_x(&rect_px),
- BLI_rctf_cent_y(&rect_px)};
- float delta[2];
+ /* allow for some wiggle room, if the user moves a few pixels away,
+ * don't immediately quit (only for top level menus) */
+ if (use_wiggle_room) {
+ const float cent[2] = {BLI_rctf_cent_x(&rect_px), BLI_rctf_cent_y(&rect_px)};
+ float delta[2];
- sub_v2_v2v2(delta, oldp, cent);
- normalize_v2_length(delta, MENU_TOWARDS_WIGGLE_ROOM);
- add_v2_v2(oldp, delta);
- }
+ sub_v2_v2v2(delta, oldp, cent);
+ normalize_v2_length(delta, MENU_TOWARDS_WIGGLE_ROOM);
+ add_v2_v2(oldp, delta);
+ }
- closer = (isect_point_tri_v2(newp, oldp, p1, p2) ||
- isect_point_tri_v2(newp, oldp, p2, p3) ||
- isect_point_tri_v2(newp, oldp, p3, p4) ||
- isect_point_tri_v2(newp, oldp, p4, p1));
+ closer = (isect_point_tri_v2(newp, oldp, p1, p2) || isect_point_tri_v2(newp, oldp, p2, p3) ||
+ isect_point_tri_v2(newp, oldp, p3, p4) || isect_point_tri_v2(newp, oldp, p4, p1));
- if (!closer) {
- menu->dotowards = false;
- }
+ if (!closer) {
+ menu->dotowards = false;
+ }
- /* 1 second timer */
- if (PIL_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH) {
- menu->dotowards = false;
- }
+ /* 1 second timer */
+ if (PIL_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH) {
+ menu->dotowards = false;
+ }
- return menu->dotowards;
+ return menu->dotowards;
}
#ifdef USE_KEYNAV_LIMIT
static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEvent *event)
{
- keynav->is_keynav = true;
- copy_v2_v2_int(keynav->event_xy, &event->x);
+ keynav->is_keynav = true;
+ copy_v2_v2_int(keynav->event_xy, &event->x);
}
/**
* Return true if keyinput isn't blocking mouse-motion,
@@ -8571,13 +8591,14 @@ static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEve
*/
static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEvent *event)
{
- if (keynav->is_keynav && (len_manhattan_v2v2_int(keynav->event_xy, &event->x) > BUTTON_KEYNAV_PX_LIMIT)) {
- keynav->is_keynav = false;
- }
+ if (keynav->is_keynav &&
+ (len_manhattan_v2v2_int(keynav->event_xy, &event->x) > BUTTON_KEYNAV_PX_LIMIT)) {
+ keynav->is_keynav = false;
+ }
- return keynav->is_keynav;
+ return keynav->is_keynav;
}
-#endif /* USE_KEYNAV_LIMIT */
+#endif /* USE_KEYNAV_LIMIT */
/** \} */
@@ -8587,120 +8608,120 @@ static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEve
static char ui_menu_scroll_test(uiBlock *block, int my)
{
- if (block->flag & (UI_BLOCK_CLIPTOP | UI_BLOCK_CLIPBOTTOM)) {
- if (block->flag & UI_BLOCK_CLIPTOP) {
- if (my > block->rect.ymax - UI_MENU_SCROLL_MOUSE) {
- return 't';
- }
- }
- if (block->flag & UI_BLOCK_CLIPBOTTOM) {
- if (my < block->rect.ymin + UI_MENU_SCROLL_MOUSE) {
- return 'b';
- }
- }
- }
- return 0;
+ if (block->flag & (UI_BLOCK_CLIPTOP | UI_BLOCK_CLIPBOTTOM)) {
+ if (block->flag & UI_BLOCK_CLIPTOP) {
+ if (my > block->rect.ymax - UI_MENU_SCROLL_MOUSE) {
+ return 't';
+ }
+ }
+ if (block->flag & UI_BLOCK_CLIPBOTTOM) {
+ if (my < block->rect.ymin + UI_MENU_SCROLL_MOUSE) {
+ return 'b';
+ }
+ }
+ }
+ return 0;
}
static void ui_menu_scroll_apply_offset_y(ARegion *ar, uiBlock *block, float dy)
{
- BLI_assert(dy != 0.0f);
- if (dy < 0.0f) {
- /* stop at top item, extra 0.5 unit Y makes it snap nicer */
- float ymax = -FLT_MAX;
- for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
- ymax = max_ff(ymax, bt->rect.ymax);
- }
- if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD) {
- dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD;
- }
- }
- else {
- /* stop at bottom item, extra 0.5 unit Y makes it snap nicer */
- float ymin = FLT_MAX;
- for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
- ymin = min_ff(ymin, bt->rect.ymin);
- }
- if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD) {
- dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD;
- }
- }
-
- /* remember scroll offset for refreshes */
- block->handle->scrolloffset += dy;
-
- /* apply scroll offset */
- for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
- bt->rect.ymin += dy;
- bt->rect.ymax += dy;
- }
-
- /* set flags again */
- ui_popup_block_scrolltest(block);
-
- ED_region_tag_redraw(ar);
+ BLI_assert(dy != 0.0f);
+ if (dy < 0.0f) {
+ /* stop at top item, extra 0.5 unit Y makes it snap nicer */
+ float ymax = -FLT_MAX;
+ for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
+ ymax = max_ff(ymax, bt->rect.ymax);
+ }
+ if (ymax + dy - UI_UNIT_Y * 0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD) {
+ dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD;
+ }
+ }
+ else {
+ /* stop at bottom item, extra 0.5 unit Y makes it snap nicer */
+ float ymin = FLT_MAX;
+ for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
+ ymin = min_ff(ymin, bt->rect.ymin);
+ }
+ if (ymin + dy + UI_UNIT_Y * 0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD) {
+ dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD;
+ }
+ }
+
+ /* remember scroll offset for refreshes */
+ block->handle->scrolloffset += dy;
+
+ /* apply scroll offset */
+ for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
+ bt->rect.ymin += dy;
+ bt->rect.ymax += dy;
+ }
+
+ /* set flags again */
+ ui_popup_block_scrolltest(block);
+
+ ED_region_tag_redraw(ar);
}
/** Scroll to activated button. */
static bool ui_menu_scroll_to_but(ARegion *ar, uiBlock *block, uiBut *but_target)
{
- float dy = 0.0;
- if (block->flag & UI_BLOCK_CLIPTOP) {
- if (but_target->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) {
- dy = block->rect.ymax - but_target->rect.ymax - UI_MENU_SCROLL_ARROW;
- }
- }
- if (block->flag & UI_BLOCK_CLIPBOTTOM) {
- if (but_target->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) {
- dy = block->rect.ymin - but_target->rect.ymin + UI_MENU_SCROLL_ARROW;
- }
- }
- if (dy != 0.0f) {
- ui_menu_scroll_apply_offset_y(ar, block, dy);
- return true;
- }
- return false;
+ float dy = 0.0;
+ if (block->flag & UI_BLOCK_CLIPTOP) {
+ if (but_target->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) {
+ dy = block->rect.ymax - but_target->rect.ymax - UI_MENU_SCROLL_ARROW;
+ }
+ }
+ if (block->flag & UI_BLOCK_CLIPBOTTOM) {
+ if (but_target->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) {
+ dy = block->rect.ymin - but_target->rect.ymin + UI_MENU_SCROLL_ARROW;
+ }
+ }
+ if (dy != 0.0f) {
+ ui_menu_scroll_apply_offset_y(ar, block, dy);
+ return true;
+ }
+ return false;
}
/** Scroll to y location (in block space, see #ui_window_to_block). */
static bool ui_menu_scroll_to_y(ARegion *ar, uiBlock *block, int y)
{
- const char test = ui_menu_scroll_test(block, y);
- float dy = 0.0f;
- if (test == 't') {
- dy = -UI_UNIT_Y; /* scroll to the top */
- }
- else if (test == 'b') {
- dy = UI_UNIT_Y; /* scroll to the bottom */
- }
- if (dy != 0.0f) {
- ui_menu_scroll_apply_offset_y(ar, block, dy);
- return true;
- }
- return false;
+ const char test = ui_menu_scroll_test(block, y);
+ float dy = 0.0f;
+ if (test == 't') {
+ dy = -UI_UNIT_Y; /* scroll to the top */
+ }
+ else if (test == 'b') {
+ dy = UI_UNIT_Y; /* scroll to the bottom */
+ }
+ if (dy != 0.0f) {
+ ui_menu_scroll_apply_offset_y(ar, block, dy);
+ return true;
+ }
+ return false;
}
static bool ui_menu_scroll_step(ARegion *ar, uiBlock *block, const int scroll_dir)
{
- int my;
- if (scroll_dir == 1) {
- if ((block->flag & UI_BLOCK_CLIPTOP) == 0) {
- return false;
- }
- my = block->rect.ymax + UI_UNIT_Y;
- }
- else if (scroll_dir == -1) {
- if ((block->flag & UI_BLOCK_CLIPBOTTOM) == 0) {
- return false;
- }
- my = block->rect.ymin - UI_UNIT_Y;
- }
- else {
- BLI_assert(0);
- return false;
- }
-
- return ui_menu_scroll_to_y(ar, block, my);
+ int my;
+ if (scroll_dir == 1) {
+ if ((block->flag & UI_BLOCK_CLIPTOP) == 0) {
+ return false;
+ }
+ my = block->rect.ymax + UI_UNIT_Y;
+ }
+ else if (scroll_dir == -1) {
+ if ((block->flag & UI_BLOCK_CLIPBOTTOM) == 0) {
+ return false;
+ }
+ my = block->rect.ymin - UI_UNIT_Y;
+ }
+ else {
+ BLI_assert(0);
+ return false;
+ }
+
+ return ui_menu_scroll_to_y(ar, block, my);
}
/** \} */
@@ -8718,1144 +8739,1169 @@ static bool ui_menu_scroll_step(ARegion *ar, uiBlock *block, const int scroll_di
*
* Without this keyboard navigation from menu's wont work.
*/
-static bool ui_menu_pass_event_to_parent_if_nonactive(
- uiPopupBlockHandle *menu, const uiBut *but,
- const int level, const int retval)
-{
- if ((level != 0) && (but == NULL)) {
- menu->menuretval = UI_RETURN_OUT | UI_RETURN_OUT_PARENT;
- (void) retval; /* so release builds with strict flags are happy as well */
- BLI_assert(retval == WM_UI_HANDLER_CONTINUE);
- return true;
- }
- else {
- return false;
- }
+static bool ui_menu_pass_event_to_parent_if_nonactive(uiPopupBlockHandle *menu,
+ const uiBut *but,
+ const int level,
+ const int retval)
+{
+ if ((level != 0) && (but == NULL)) {
+ menu->menuretval = UI_RETURN_OUT | UI_RETURN_OUT_PARENT;
+ (void)retval; /* so release builds with strict flags are happy as well */
+ BLI_assert(retval == WM_UI_HANDLER_CONTINUE);
+ return true;
+ }
+ else {
+ return false;
+ }
}
static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
{
- ARegion *ar = menu->region;
- uiBut *but = ui_region_find_active_but(ar);
- int retval;
-
- if (but) {
- /* Its possible there is an active menu item NOT under the mouse,
- * in this case ignore mouse clicks outside the button (but Enter etc is accepted) */
- if (event->val == KM_RELEASE) {
- /* pass, needed so we can exit active menu-items when click-dragging out of them */
- }
- else if (!ui_block_is_menu(but->block) || ui_block_is_pie_menu(but->block)) {
- /* pass, skip for dialogs */
- }
- else if (!ui_region_contains_point_px(but->active->region, event->x, event->y)) {
- /* pass, needed to click-exit outside of non-flaoting menus */
- }
- else if ((!ELEM(event->type, MOUSEMOVE, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN)) && ISMOUSE(event->type)) {
- if (!ui_but_contains_point_px(but, but->active->region, event->x, event->y)) {
- but = NULL;
- }
- }
- }
-
- if (but) {
- ScrArea *ctx_area = CTX_wm_area(C);
- ARegion *ctx_region = CTX_wm_region(C);
-
- if (menu->ctx_area) {
- CTX_wm_area_set(C, menu->ctx_area);
- }
- if (menu->ctx_region) {
- CTX_wm_region_set(C, menu->ctx_region);
- }
-
- retval = ui_handle_button_event(C, event, but);
-
- if (menu->ctx_area) {
- CTX_wm_area_set(C, ctx_area);
- }
- if (menu->ctx_region) {
- CTX_wm_region_set(C, ctx_region);
- }
- }
- else {
- retval = ui_handle_button_over(C, event, ar);
- }
-
- return retval;
+ ARegion *ar = menu->region;
+ uiBut *but = ui_region_find_active_but(ar);
+ int retval;
+
+ if (but) {
+ /* Its possible there is an active menu item NOT under the mouse,
+ * in this case ignore mouse clicks outside the button (but Enter etc is accepted) */
+ if (event->val == KM_RELEASE) {
+ /* pass, needed so we can exit active menu-items when click-dragging out of them */
+ }
+ else if (!ui_block_is_menu(but->block) || ui_block_is_pie_menu(but->block)) {
+ /* pass, skip for dialogs */
+ }
+ else if (!ui_region_contains_point_px(but->active->region, event->x, event->y)) {
+ /* pass, needed to click-exit outside of non-flaoting menus */
+ }
+ else if ((!ELEM(event->type, MOUSEMOVE, WHEELUPMOUSE, WHEELDOWNMOUSE, MOUSEPAN)) &&
+ ISMOUSE(event->type)) {
+ if (!ui_but_contains_point_px(but, but->active->region, event->x, event->y)) {
+ but = NULL;
+ }
+ }
+ }
+
+ if (but) {
+ ScrArea *ctx_area = CTX_wm_area(C);
+ ARegion *ctx_region = CTX_wm_region(C);
+
+ if (menu->ctx_area) {
+ CTX_wm_area_set(C, menu->ctx_area);
+ }
+ if (menu->ctx_region) {
+ CTX_wm_region_set(C, menu->ctx_region);
+ }
+
+ retval = ui_handle_button_event(C, event, but);
+
+ if (menu->ctx_area) {
+ CTX_wm_area_set(C, ctx_area);
+ }
+ if (menu->ctx_region) {
+ CTX_wm_region_set(C, ctx_region);
+ }
+ }
+ else {
+ retval = ui_handle_button_over(C, event, ar);
+ }
+
+ return retval;
}
float ui_block_calc_pie_segment(uiBlock *block, const float event_xy[2])
{
- float seg1[2];
- float seg2[2];
- float len;
+ float seg1[2];
+ float seg2[2];
+ float len;
- if (block->pie_data.flags & UI_PIE_INITIAL_DIRECTION) {
- copy_v2_v2(seg1, block->pie_data.pie_center_init);
- }
- else {
- copy_v2_v2(seg1, block->pie_data.pie_center_spawned);
- }
+ if (block->pie_data.flags & UI_PIE_INITIAL_DIRECTION) {
+ copy_v2_v2(seg1, block->pie_data.pie_center_init);
+ }
+ else {
+ copy_v2_v2(seg1, block->pie_data.pie_center_spawned);
+ }
- sub_v2_v2v2(seg2, event_xy, seg1);
+ sub_v2_v2v2(seg2, event_xy, seg1);
- len = normalize_v2_v2(block->pie_data.pie_dir, seg2);
+ len = normalize_v2_v2(block->pie_data.pie_dir, seg2);
- if (len < U.pie_menu_threshold * U.dpi_fac) {
- block->pie_data.flags |= UI_PIE_INVALID_DIR;
- }
- else {
- block->pie_data.flags &= ~UI_PIE_INVALID_DIR;
- }
+ if (len < U.pie_menu_threshold * U.dpi_fac) {
+ block->pie_data.flags |= UI_PIE_INVALID_DIR;
+ }
+ else {
+ block->pie_data.flags &= ~UI_PIE_INVALID_DIR;
+ }
- return len;
+ return len;
}
-static int ui_handle_menu_event(
- bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
- int level, const bool is_parent_inside, const bool is_parent_menu, const bool is_floating)
+static int ui_handle_menu_event(bContext *C,
+ const wmEvent *event,
+ uiPopupBlockHandle *menu,
+ int level,
+ const bool is_parent_inside,
+ const bool is_parent_menu,
+ const bool is_floating)
{
- ARegion *ar;
- uiBlock *block;
- uiBut *but;
- int mx, my, retval;
- bool inside;
- bool inside_title; /* check for title dragging */
+ ARegion *ar;
+ uiBlock *block;
+ uiBut *but;
+ int mx, my, retval;
+ bool inside;
+ bool inside_title; /* check for title dragging */
- ar = menu->region;
- block = ar->uiblocks.first;
+ ar = menu->region;
+ block = ar->uiblocks.first;
- retval = WM_UI_HANDLER_CONTINUE;
+ retval = WM_UI_HANDLER_CONTINUE;
- mx = event->x;
- my = event->y;
- ui_window_to_block(ar, block, &mx, &my);
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(ar, block, &mx, &my);
- /* check if mouse is inside block */
- inside = BLI_rctf_isect_pt(&block->rect, mx, my);
- inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.ymax);
+ /* check if mouse is inside block */
+ inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+ inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.ymax);
- /* if there's an active modal button, don't check events or outside, except for search menu */
- but = ui_region_find_active_but(ar);
+ /* if there's an active modal button, don't check events or outside, except for search menu */
+ but = ui_region_find_active_but(ar);
#ifdef USE_DRAG_POPUP
- if (menu->is_grab) {
- if (event->type == LEFTMOUSE) {
- menu->is_grab = false;
- retval = WM_UI_HANDLER_BREAK;
- }
- else {
- if (event->type == MOUSEMOVE) {
- int mdiff[2];
-
- sub_v2_v2v2_int(mdiff, &event->x, menu->grab_xy_prev);
- copy_v2_v2_int(menu->grab_xy_prev, &event->x);
-
- add_v2_v2v2_int(menu->popup_create_vars.event_xy, menu->popup_create_vars.event_xy, mdiff);
-
- ui_popup_translate(ar, mdiff);
- }
-
- return retval;
- }
- }
+ if (menu->is_grab) {
+ if (event->type == LEFTMOUSE) {
+ menu->is_grab = false;
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else {
+ if (event->type == MOUSEMOVE) {
+ int mdiff[2];
+
+ sub_v2_v2v2_int(mdiff, &event->x, menu->grab_xy_prev);
+ copy_v2_v2_int(menu->grab_xy_prev, &event->x);
+
+ add_v2_v2v2_int(menu->popup_create_vars.event_xy, menu->popup_create_vars.event_xy, mdiff);
+
+ ui_popup_translate(ar, mdiff);
+ }
+
+ return retval;
+ }
+ }
#endif
- if (but && button_modal_state(but->active->state)) {
- if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
- /* if a button is activated modal, always reset the start mouse
- * position of the towards mechanism to avoid losing focus,
- * and don't handle events */
- ui_mouse_motion_towards_reinit(menu, &event->x);
- }
- }
- else if (event->type == TIMER) {
- if (event->customdata == menu->scrolltimer) {
- ui_menu_scroll_to_y(ar, block, my);
- }
- }
- else {
- /* for ui_mouse_motion_towards_block */
- if (event->type == MOUSEMOVE) {
- if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
- ui_mouse_motion_towards_init(menu, &event->x);
- }
-
- /* add menu scroll timer, if needed */
- if (ui_menu_scroll_test(block, my)) {
- if (menu->scrolltimer == NULL) {
- menu->scrolltimer =
- WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, MENU_SCROLL_INTERVAL);
- }
- }
- }
-
- /* first block own event func */
- if (block->block_event_func && block->block_event_func(C, block, event)) {
- /* pass */
- } /* events not for active search menu button */
- else {
- int act = 0;
-
- switch (event->type) {
-
- /* Closing sub-levels of pull-downs.
- *
- * The actual event is handled by the button under the cursor.
- * This is done so we can right click on menu items even when they have sub-menus open. */
- case RIGHTMOUSE:
- if (inside == false) {
- if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) {
- if (block->saferct.first) {
- /* Currently right clicking on a top level pull-down (typically in the header)
- * just closes the menu and doesn't support immediately handling the RMB event.
- *
- * To support we would need UI_RETURN_OUT_PARENT to be handled by
- * top-level buttons, not just menus. Note that this isn't very important
- * since it's easy to manually close these menus by clicking on them. */
- menu->menuretval = (level > 0) ? UI_RETURN_OUT_PARENT : UI_RETURN_OUT;
-
- }
- }
- retval = WM_UI_HANDLER_BREAK;
- }
- break;
-
- /* Closing sub-levels of pull-downs. */
- case LEFTARROWKEY:
- if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) {
- if (block->saferct.first) {
- menu->menuretval = UI_RETURN_OUT;
- }
- }
-
- retval = WM_UI_HANDLER_BREAK;
- break;
-
- /* Opening sub-levels of pull-downs. */
- case RIGHTARROWKEY:
- if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) {
-
- if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
- break;
- }
-
- but = ui_region_find_active_but(ar);
-
- if (!but) {
- /* no item active, we make first active */
- if (block->direction & UI_DIR_UP) {
- but = ui_but_last(block);
- }
- else {
- but = ui_but_first(block);
- }
- }
-
- if (but && ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) {
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
- }
- }
-
- retval = WM_UI_HANDLER_BREAK;
- break;
-
- case WHEELUPMOUSE:
- case WHEELDOWNMOUSE:
- {
- if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
- /* pass */
- }
- else if (!ui_block_is_menu(block)) {
- const int scroll_dir = (event->type == WHEELUPMOUSE) ? 1 : -1;
- if (ui_menu_scroll_step(ar, block, scroll_dir)) {
- if (but) {
- but->active->cancel = true;
- button_activate_exit(C, but, but->active, false, false);
- }
- WM_event_add_mousemove(C);
- }
- break;
- }
- ATTR_FALLTHROUGH;
- }
- case UPARROWKEY:
- case DOWNARROWKEY:
- case MOUSEPAN:
- /* arrowkeys: only handle for block_loop blocks */
- if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
- /* pass */
- }
- else if (inside || (block->flag & UI_BLOCK_LOOP)) {
- int type = event->type;
- int val = event->val;
-
- /* convert pan to scrollwheel */
- if (type == MOUSEPAN) {
- ui_pan_to_scroll(event, &type, &val);
- }
-
- if (val == KM_PRESS) {
- const bool is_next =
- (ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE) ==
- ((block->flag & UI_BLOCK_IS_FLIP) != 0));
-
- if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
- break;
- }
+ if (but && button_modal_state(but->active->state)) {
+ if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
+ /* if a button is activated modal, always reset the start mouse
+ * position of the towards mechanism to avoid losing focus,
+ * and don't handle events */
+ ui_mouse_motion_towards_reinit(menu, &event->x);
+ }
+ }
+ else if (event->type == TIMER) {
+ if (event->customdata == menu->scrolltimer) {
+ ui_menu_scroll_to_y(ar, block, my);
+ }
+ }
+ else {
+ /* for ui_mouse_motion_towards_block */
+ if (event->type == MOUSEMOVE) {
+ if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
+ ui_mouse_motion_towards_init(menu, &event->x);
+ }
+
+ /* add menu scroll timer, if needed */
+ if (ui_menu_scroll_test(block, my)) {
+ if (menu->scrolltimer == NULL) {
+ menu->scrolltimer = WM_event_add_timer(
+ CTX_wm_manager(C), CTX_wm_window(C), TIMER, MENU_SCROLL_INTERVAL);
+ }
+ }
+ }
+
+ /* first block own event func */
+ if (block->block_event_func && block->block_event_func(C, block, event)) {
+ /* pass */
+ } /* events not for active search menu button */
+ else {
+ int act = 0;
+
+ switch (event->type) {
+
+ /* Closing sub-levels of pull-downs.
+ *
+ * The actual event is handled by the button under the cursor.
+ * This is done so we can right click on menu items even when they have sub-menus open. */
+ case RIGHTMOUSE:
+ if (inside == false) {
+ if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) {
+ if (block->saferct.first) {
+ /* Currently right clicking on a top level pull-down (typically in the header)
+ * just closes the menu and doesn't support immediately handling the RMB event.
+ *
+ * To support we would need UI_RETURN_OUT_PARENT to be handled by
+ * top-level buttons, not just menus. Note that this isn't very important
+ * since it's easy to manually close these menus by clicking on them. */
+ menu->menuretval = (level > 0) ? UI_RETURN_OUT_PARENT : UI_RETURN_OUT;
+ }
+ }
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ break;
+
+ /* Closing sub-levels of pull-downs. */
+ case LEFTARROWKEY:
+ if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) {
+ if (block->saferct.first) {
+ menu->menuretval = UI_RETURN_OUT;
+ }
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+
+ /* Opening sub-levels of pull-downs. */
+ case RIGHTARROWKEY:
+ if (event->val == KM_PRESS && (block->flag & UI_BLOCK_LOOP)) {
+
+ if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
+ break;
+ }
+
+ but = ui_region_find_active_but(ar);
+
+ if (!but) {
+ /* no item active, we make first active */
+ if (block->direction & UI_DIR_UP) {
+ but = ui_but_last(block);
+ }
+ else {
+ but = ui_but_first(block);
+ }
+ }
+
+ if (but && ELEM(but->type, UI_BTYPE_BLOCK, UI_BTYPE_PULLDOWN)) {
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
+ }
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+
+ case WHEELUPMOUSE:
+ case WHEELDOWNMOUSE: {
+ if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
+ /* pass */
+ }
+ else if (!ui_block_is_menu(block)) {
+ const int scroll_dir = (event->type == WHEELUPMOUSE) ? 1 : -1;
+ if (ui_menu_scroll_step(ar, block, scroll_dir)) {
+ if (but) {
+ but->active->cancel = true;
+ button_activate_exit(C, but, but->active, false, false);
+ }
+ WM_event_add_mousemove(C);
+ }
+ break;
+ }
+ ATTR_FALLTHROUGH;
+ }
+ case UPARROWKEY:
+ case DOWNARROWKEY:
+ case MOUSEPAN:
+ /* arrowkeys: only handle for block_loop blocks */
+ if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
+ /* pass */
+ }
+ else if (inside || (block->flag & UI_BLOCK_LOOP)) {
+ int type = event->type;
+ int val = event->val;
+
+ /* convert pan to scrollwheel */
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
+ if (val == KM_PRESS) {
+ const bool is_next = (ELEM(type, DOWNARROWKEY, WHEELDOWNMOUSE) ==
+ ((block->flag & UI_BLOCK_IS_FLIP) != 0));
+
+ if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
+ break;
+ }
#ifdef USE_KEYNAV_LIMIT
- ui_mouse_motion_keynav_init(&menu->keynav_state, event);
+ ui_mouse_motion_keynav_init(&menu->keynav_state, event);
#endif
- but = ui_region_find_active_but(ar);
- if (but) {
- /* next button */
- but = is_next ? ui_but_next(but) : ui_but_prev(but);
- }
-
- if (!but) {
- /* wrap button */
- uiBut *but_wrap;
- but_wrap = is_next ? ui_but_first(block) : ui_but_last(block);
- if (but_wrap) {
- but = but_wrap;
- }
- }
-
- if (but) {
- ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
- ui_menu_scroll_to_but(ar, block, but);
- }
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
-
- break;
-
- case ONEKEY: case PAD1:
- act = 1;
- ATTR_FALLTHROUGH;
- case TWOKEY: case PAD2:
- if (act == 0) {
- act = 2;
- }
- ATTR_FALLTHROUGH;
- case THREEKEY: case PAD3:
- if (act == 0) {
- act = 3;
- }
- ATTR_FALLTHROUGH;
- case FOURKEY: case PAD4:
- if (act == 0) {
- act = 4;
- }
- ATTR_FALLTHROUGH;
- case FIVEKEY: case PAD5:
- if (act == 0) {
- act = 5;
- }
- ATTR_FALLTHROUGH;
- case SIXKEY: case PAD6:
- if (act == 0) {
- act = 6;
- }
- ATTR_FALLTHROUGH;
- case SEVENKEY: case PAD7:
- if (act == 0) {
- act = 7;
- }
- ATTR_FALLTHROUGH;
- case EIGHTKEY: case PAD8:
- if (act == 0) {
- act = 8;
- }
- ATTR_FALLTHROUGH;
- case NINEKEY: case PAD9:
- if (act == 0) {
- act = 9;
- }
- ATTR_FALLTHROUGH;
- case ZEROKEY: case PAD0:
- if (act == 0) {
- act = 10;
- }
-
- if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) {
- int count;
-
- if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
- break;
- }
-
- if (event->alt) {
- act += 10;
- }
-
- count = 0;
- for (but = block->buttons.first; but; but = but->next) {
- bool doit = false;
-
- if (!ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
- count++;
- }
-
- /* exception for rna layer buts */
- if (but->rnapoin.data && but->rnaprop &&
- ELEM(RNA_property_subtype(but->rnaprop), PROP_LAYER, PROP_LAYER_MEMBER))
- {
- if (but->rnaindex == act - 1) {
- doit = true;
- }
- }
- else if (ELEM(but->type,
- UI_BTYPE_BUT,
- UI_BTYPE_BUT_MENU,
- UI_BTYPE_MENU, UI_BTYPE_BLOCK,
- UI_BTYPE_PULLDOWN) &&
- count == act)
- {
- doit = true;
- }
-
- if (!(but->flag & UI_BUT_DISABLED) && doit) {
- /* activate buttons but open menu's */
- uiButtonActivateType activate;
- if (but->type == UI_BTYPE_PULLDOWN) {
- activate = BUTTON_ACTIVATE_OPEN;
- }
- else {
- activate = BUTTON_ACTIVATE_APPLY;
- }
-
- ui_handle_button_activate(C, ar, but, activate);
- break;
- }
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
- break;
-
- /* Handle keystrokes on menu items */
- case AKEY:
- case BKEY:
- case CKEY:
- case DKEY:
- case EKEY:
- case FKEY:
- case GKEY:
- case HKEY:
- case IKEY:
- case JKEY:
- case KKEY:
- case LKEY:
- case MKEY:
- case NKEY:
- case OKEY:
- case PKEY:
- case QKEY:
- case RKEY:
- case SKEY:
- case TKEY:
- case UKEY:
- case VKEY:
- case WKEY:
- case XKEY:
- case YKEY:
- case ZKEY:
- {
- if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
- !IS_EVENT_MOD(event, shift, ctrl, oskey))
- {
- if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
- break;
- }
-
- for (but = block->buttons.first; but; but = but->next) {
- if (!(but->flag & UI_BUT_DISABLED) && but->menu_key == event->type) {
- if (but->type == UI_BTYPE_BUT) {
- UI_but_execute(C, but);
- }
- else {
- ui_handle_button_activate_by_type(C, ar, but);
- }
- break;
- }
- }
-
- retval = WM_UI_HANDLER_BREAK;
- }
- break;
- }
- }
- }
-
- /* here we check return conditions for menus */
- if (block->flag & UI_BLOCK_LOOP) {
- /* If we click outside the block, verify if we clicked on the
- * button that opened us, otherwise we need to close,
- *
- * note that there is an exception for root level menus and
- * popups which you can click again to close.
- *
- * Events handled above may have already set the return value,
- * don't overwrite them, see: T61015.
- */
- if ((inside == 0) && (menu->menuretval == 0)) {
- uiSafetyRct *saferct = block->saferct.first;
-
- if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
- if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) {
- if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
- /* for root menus, allow clicking to close */
- if (block->flag & (UI_BLOCK_OUT_1)) {
- menu->menuretval = UI_RETURN_OK;
- }
- else {
- menu->menuretval = UI_RETURN_OUT;
- }
- }
- else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
- if (block->flag & (UI_BLOCK_OUT_1)) {
- menu->menuretval = UI_RETURN_OK;
- }
- else {
- menu->menuretval = UI_RETURN_OUT;
- }
- }
- }
- else if (ELEM(event->val, KM_RELEASE, KM_CLICK)) {
- /* For buttons that use a hold function,
- * exit when mouse-up outside the menu. */
- if (block->flag & UI_BLOCK_POPUP_HOLD) {
- /* Note, we could check the cursor is over the parent button. */
- menu->menuretval = UI_RETURN_CANCEL;
- retval = WM_UI_HANDLER_CONTINUE;
- }
- }
- }
- }
-
- if (menu->menuretval) {
- /* pass */
- }
+ but = ui_region_find_active_but(ar);
+ if (but) {
+ /* next button */
+ but = is_next ? ui_but_next(but) : ui_but_prev(but);
+ }
+
+ if (!but) {
+ /* wrap button */
+ uiBut *but_wrap;
+ but_wrap = is_next ? ui_but_first(block) : ui_but_last(block);
+ if (but_wrap) {
+ but = but_wrap;
+ }
+ }
+
+ if (but) {
+ ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
+ ui_menu_scroll_to_but(ar, block, but);
+ }
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+
+ break;
+
+ case ONEKEY:
+ case PAD1:
+ act = 1;
+ ATTR_FALLTHROUGH;
+ case TWOKEY:
+ case PAD2:
+ if (act == 0) {
+ act = 2;
+ }
+ ATTR_FALLTHROUGH;
+ case THREEKEY:
+ case PAD3:
+ if (act == 0) {
+ act = 3;
+ }
+ ATTR_FALLTHROUGH;
+ case FOURKEY:
+ case PAD4:
+ if (act == 0) {
+ act = 4;
+ }
+ ATTR_FALLTHROUGH;
+ case FIVEKEY:
+ case PAD5:
+ if (act == 0) {
+ act = 5;
+ }
+ ATTR_FALLTHROUGH;
+ case SIXKEY:
+ case PAD6:
+ if (act == 0) {
+ act = 6;
+ }
+ ATTR_FALLTHROUGH;
+ case SEVENKEY:
+ case PAD7:
+ if (act == 0) {
+ act = 7;
+ }
+ ATTR_FALLTHROUGH;
+ case EIGHTKEY:
+ case PAD8:
+ if (act == 0) {
+ act = 8;
+ }
+ ATTR_FALLTHROUGH;
+ case NINEKEY:
+ case PAD9:
+ if (act == 0) {
+ act = 9;
+ }
+ ATTR_FALLTHROUGH;
+ case ZEROKEY:
+ case PAD0:
+ if (act == 0) {
+ act = 10;
+ }
+
+ if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) {
+ int count;
+
+ if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
+ break;
+ }
+
+ if (event->alt) {
+ act += 10;
+ }
+
+ count = 0;
+ for (but = block->buttons.first; but; but = but->next) {
+ bool doit = false;
+
+ if (!ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
+ count++;
+ }
+
+ /* exception for rna layer buts */
+ if (but->rnapoin.data && but->rnaprop &&
+ ELEM(RNA_property_subtype(but->rnaprop), PROP_LAYER, PROP_LAYER_MEMBER)) {
+ if (but->rnaindex == act - 1) {
+ doit = true;
+ }
+ }
+ else if (ELEM(but->type,
+ UI_BTYPE_BUT,
+ UI_BTYPE_BUT_MENU,
+ UI_BTYPE_MENU,
+ UI_BTYPE_BLOCK,
+ UI_BTYPE_PULLDOWN) &&
+ count == act) {
+ doit = true;
+ }
+
+ if (!(but->flag & UI_BUT_DISABLED) && doit) {
+ /* activate buttons but open menu's */
+ uiButtonActivateType activate;
+ if (but->type == UI_BTYPE_PULLDOWN) {
+ activate = BUTTON_ACTIVATE_OPEN;
+ }
+ else {
+ activate = BUTTON_ACTIVATE_APPLY;
+ }
+
+ ui_handle_button_activate(C, ar, but, activate);
+ break;
+ }
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ break;
+
+ /* Handle keystrokes on menu items */
+ case AKEY:
+ case BKEY:
+ case CKEY:
+ case DKEY:
+ case EKEY:
+ case FKEY:
+ case GKEY:
+ case HKEY:
+ case IKEY:
+ case JKEY:
+ case KKEY:
+ case LKEY:
+ case MKEY:
+ case NKEY:
+ case OKEY:
+ case PKEY:
+ case QKEY:
+ case RKEY:
+ case SKEY:
+ case TKEY:
+ case UKEY:
+ case VKEY:
+ case WKEY:
+ case XKEY:
+ case YKEY:
+ case ZKEY: {
+ if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
+ !IS_EVENT_MOD(event, shift, ctrl, oskey)) {
+ if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
+ break;
+ }
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (!(but->flag & UI_BUT_DISABLED) && but->menu_key == event->type) {
+ if (but->type == UI_BTYPE_BUT) {
+ UI_but_execute(C, but);
+ }
+ else {
+ ui_handle_button_activate_by_type(C, ar, but);
+ }
+ break;
+ }
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ break;
+ }
+ }
+ }
+
+ /* here we check return conditions for menus */
+ if (block->flag & UI_BLOCK_LOOP) {
+ /* If we click outside the block, verify if we clicked on the
+ * button that opened us, otherwise we need to close,
+ *
+ * note that there is an exception for root level menus and
+ * popups which you can click again to close.
+ *
+ * Events handled above may have already set the return value,
+ * don't overwrite them, see: T61015.
+ */
+ if ((inside == 0) && (menu->menuretval == 0)) {
+ uiSafetyRct *saferct = block->saferct.first;
+
+ if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
+ if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) {
+ if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
+ /* for root menus, allow clicking to close */
+ if (block->flag & (UI_BLOCK_OUT_1)) {
+ menu->menuretval = UI_RETURN_OK;
+ }
+ else {
+ menu->menuretval = UI_RETURN_OUT;
+ }
+ }
+ else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
+ if (block->flag & (UI_BLOCK_OUT_1)) {
+ menu->menuretval = UI_RETURN_OK;
+ }
+ else {
+ menu->menuretval = UI_RETURN_OUT;
+ }
+ }
+ }
+ else if (ELEM(event->val, KM_RELEASE, KM_CLICK)) {
+ /* For buttons that use a hold function,
+ * exit when mouse-up outside the menu. */
+ if (block->flag & UI_BLOCK_POPUP_HOLD) {
+ /* Note, we could check the cursor is over the parent button. */
+ menu->menuretval = UI_RETURN_CANCEL;
+ retval = WM_UI_HANDLER_CONTINUE;
+ }
+ }
+ }
+ }
+
+ if (menu->menuretval) {
+ /* pass */
+ }
#ifdef USE_KEYNAV_LIMIT
- else if ((event->type == MOUSEMOVE) && ui_mouse_motion_keynav_test(&menu->keynav_state, event)) {
- /* Don't handle the mouse-move if we're using key-navigation. */
- retval = WM_UI_HANDLER_BREAK;
- }
+ else if ((event->type == MOUSEMOVE) &&
+ ui_mouse_motion_keynav_test(&menu->keynav_state, event)) {
+ /* Don't handle the mouse-move if we're using key-navigation. */
+ retval = WM_UI_HANDLER_BREAK;
+ }
#endif
- else if (event->type == ESCKEY && event->val == KM_PRESS) {
- /* Escape cancels this and all preceding menus. */
- menu->menuretval = UI_RETURN_CANCEL;
- }
- else if (ELEM(event->type, RETKEY, PADENTER) && event->val == KM_PRESS) {
- uiBut *but_default = ui_region_find_first_but_test_flag(ar, UI_BUT_ACTIVE_DEFAULT, UI_HIDDEN);
- if ((but_default != NULL) && (but_default->active == NULL)) {
- if (but_default->type == UI_BTYPE_BUT) {
- UI_but_execute(C, but_default);
- }
- else {
- ui_handle_button_activate_by_type(C, ar, but_default);
- }
- }
- else {
- uiBut *but_active = ui_region_find_active_but(ar);
-
- /* enter will always close this block, we let the event
- * get handled by the button if it is activated, otherwise we cancel */
- if (but_active == NULL) {
- menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
- }
- }
- }
+ else if (event->type == ESCKEY && event->val == KM_PRESS) {
+ /* Escape cancels this and all preceding menus. */
+ menu->menuretval = UI_RETURN_CANCEL;
+ }
+ else if (ELEM(event->type, RETKEY, PADENTER) && event->val == KM_PRESS) {
+ uiBut *but_default = ui_region_find_first_but_test_flag(
+ ar, UI_BUT_ACTIVE_DEFAULT, UI_HIDDEN);
+ if ((but_default != NULL) && (but_default->active == NULL)) {
+ if (but_default->type == UI_BTYPE_BUT) {
+ UI_but_execute(C, but_default);
+ }
+ else {
+ ui_handle_button_activate_by_type(C, ar, but_default);
+ }
+ }
+ else {
+ uiBut *but_active = ui_region_find_active_but(ar);
+
+ /* enter will always close this block, we let the event
+ * get handled by the button if it is activated, otherwise we cancel */
+ if (but_active == NULL) {
+ menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK;
+ }
+ }
+ }
#ifdef USE_DRAG_POPUP
- else if ((event->type == LEFTMOUSE) && (event->val == KM_PRESS) &&
- (inside && is_floating && inside_title))
- {
- if (!but || !ui_but_contains_point_px(but, ar, event->x, event->y)) {
- if (but) {
- UI_but_tooltip_timer_remove(C, but);
- }
-
- menu->is_grab = true;
- copy_v2_v2_int(menu->grab_xy_prev, &event->x);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
+ else if ((event->type == LEFTMOUSE) && (event->val == KM_PRESS) &&
+ (inside && is_floating && inside_title)) {
+ if (!but || !ui_but_contains_point_px(but, ar, event->x, event->y)) {
+ if (but) {
+ UI_but_tooltip_timer_remove(C, but);
+ }
+
+ menu->is_grab = true;
+ copy_v2_v2_int(menu->grab_xy_prev, &event->x);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
#endif
- else {
-
- /* check mouse moving outside of the menu */
- if (inside == 0 && (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER))) {
- uiSafetyRct *saferct;
-
- ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
-
- /* check for all parent rects, enables arrowkeys to be used */
- for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
- /* for mouse move we only check our own rect, for other
- * events we check all preceding block rects too to make
- * arrow keys navigation work */
- if (event->type != MOUSEMOVE || saferct == block->saferct.first) {
- if (BLI_rctf_isect_pt(&saferct->parent, (float)event->x, (float)event->y)) {
- break;
- }
- if (BLI_rctf_isect_pt(&saferct->safety, (float)event->x, (float)event->y)) {
- break;
- }
- }
- }
-
- /* strict check, and include the parent rect */
- if (!menu->dotowards && !saferct) {
- if (block->flag & (UI_BLOCK_OUT_1)) {
- menu->menuretval = UI_RETURN_OK;
- }
- else {
- menu->menuretval = UI_RETURN_OUT;
- }
- }
- else if (menu->dotowards && event->type == MOUSEMOVE) {
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- }
-
- /* end switch */
- }
- }
-
- /* if we are didn't handle the event yet, lets pass it on to
- * buttons inside this region. disabled inside check .. not sure
- * anymore why it was there? but it meant enter didn't work
- * for example when mouse was not over submenu */
- if ((event->type == TIMER) ||
- (/*inside &&*/ (!menu->menuretval || (menu->menuretval & UI_RETURN_UPDATE)) && retval == WM_UI_HANDLER_CONTINUE))
- {
- retval = ui_handle_menu_button(C, event, menu);
- }
+ else {
+
+ /* check mouse moving outside of the menu */
+ if (inside == 0 && (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER))) {
+ uiSafetyRct *saferct;
+
+ ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false);
+
+ /* check for all parent rects, enables arrowkeys to be used */
+ for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
+ /* for mouse move we only check our own rect, for other
+ * events we check all preceding block rects too to make
+ * arrow keys navigation work */
+ if (event->type != MOUSEMOVE || saferct == block->saferct.first) {
+ if (BLI_rctf_isect_pt(&saferct->parent, (float)event->x, (float)event->y)) {
+ break;
+ }
+ if (BLI_rctf_isect_pt(&saferct->safety, (float)event->x, (float)event->y)) {
+ break;
+ }
+ }
+ }
+
+ /* strict check, and include the parent rect */
+ if (!menu->dotowards && !saferct) {
+ if (block->flag & (UI_BLOCK_OUT_1)) {
+ menu->menuretval = UI_RETURN_OK;
+ }
+ else {
+ menu->menuretval = UI_RETURN_OUT;
+ }
+ }
+ else if (menu->dotowards && event->type == MOUSEMOVE) {
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+
+ /* end switch */
+ }
+ }
+
+ /* if we are didn't handle the event yet, lets pass it on to
+ * buttons inside this region. disabled inside check .. not sure
+ * anymore why it was there? but it meant enter didn't work
+ * for example when mouse was not over submenu */
+ if ((event->type == TIMER) ||
+ (/*inside &&*/ (!menu->menuretval || (menu->menuretval & UI_RETURN_UPDATE)) &&
+ retval == WM_UI_HANDLER_CONTINUE)) {
+ retval = ui_handle_menu_button(C, event, menu);
+ }
#ifdef USE_UI_POPOVER_ONCE
- if (block->flag & UI_BLOCK_POPOVER_ONCE) {
- if ((event->type == LEFTMOUSE) && (event->val == KM_RELEASE)) {
- UI_popover_once_clear(menu->popup_create_vars.arg);
- block->flag &= ~UI_BLOCK_POPOVER_ONCE;
- }
- }
+ if (block->flag & UI_BLOCK_POPOVER_ONCE) {
+ if ((event->type == LEFTMOUSE) && (event->val == KM_RELEASE)) {
+ UI_popover_once_clear(menu->popup_create_vars.arg);
+ block->flag &= ~UI_BLOCK_POPOVER_ONCE;
+ }
+ }
#endif
- /* Don't handle double click events, rehandle as regular press/release. */
- if (retval == WM_UI_HANDLER_CONTINUE && event->val == KM_DBL_CLICK) {
- return retval;
- }
-
- /* if we set a menu return value, ensure we continue passing this on to
- * lower menus and buttons, so always set continue then, and if we are
- * inside the region otherwise, ensure we swallow the event */
- if (menu->menuretval) {
- return WM_UI_HANDLER_CONTINUE;
- }
- else if (inside) {
- return WM_UI_HANDLER_BREAK;
- }
- else {
- return retval;
- }
-}
-
-static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
-{
- ARegion *ar;
- uiBut *but;
- uiBlock *block;
- uiHandleButtonData *data;
- uiPopupBlockHandle *submenu;
-
- ar = menu->region;
- block = ar->uiblocks.first;
-
- but = ui_region_find_active_but(ar);
-
- BLI_assert(but);
-
- data = but->active;
- submenu = data->menu;
-
- if (submenu->menuretval) {
- bool update;
-
- /* first decide if we want to close our own menu cascading, if
- * so pass on the sub menu return value to our own menu handle */
- if ((submenu->menuretval & UI_RETURN_OK) || (submenu->menuretval & UI_RETURN_CANCEL)) {
- if (!(block->flag & UI_BLOCK_KEEP_OPEN)) {
- menu->menuretval = submenu->menuretval;
- menu->butretval = data->retval;
- }
- }
-
- update = (submenu->menuretval & UI_RETURN_UPDATE) != 0;
-
- /* now let activated button in this menu exit, which
- * will actually close the submenu too */
- ui_handle_button_return_submenu(C, event, but);
-
- if (update) {
- submenu->menuretval = 0;
- }
- }
-
- if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
- /* for cases where close does not cascade, allow the user to
- * move the mouse back towards the menu without closing */
- ui_mouse_motion_towards_reinit(menu, &event->x);
- }
-
- if (menu->menuretval) {
- return WM_UI_HANDLER_CONTINUE;
- }
- else {
- return WM_UI_HANDLER_BREAK;
- }
+ /* Don't handle double click events, rehandle as regular press/release. */
+ if (retval == WM_UI_HANDLER_CONTINUE && event->val == KM_DBL_CLICK) {
+ return retval;
+ }
+
+ /* if we set a menu return value, ensure we continue passing this on to
+ * lower menus and buttons, so always set continue then, and if we are
+ * inside the region otherwise, ensure we swallow the event */
+ if (menu->menuretval) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+ else if (inside) {
+ return WM_UI_HANDLER_BREAK;
+ }
+ else {
+ return retval;
+ }
+}
+
+static int ui_handle_menu_return_submenu(bContext *C,
+ const wmEvent *event,
+ uiPopupBlockHandle *menu)
+{
+ ARegion *ar;
+ uiBut *but;
+ uiBlock *block;
+ uiHandleButtonData *data;
+ uiPopupBlockHandle *submenu;
+
+ ar = menu->region;
+ block = ar->uiblocks.first;
+
+ but = ui_region_find_active_but(ar);
+
+ BLI_assert(but);
+
+ data = but->active;
+ submenu = data->menu;
+
+ if (submenu->menuretval) {
+ bool update;
+
+ /* first decide if we want to close our own menu cascading, if
+ * so pass on the sub menu return value to our own menu handle */
+ if ((submenu->menuretval & UI_RETURN_OK) || (submenu->menuretval & UI_RETURN_CANCEL)) {
+ if (!(block->flag & UI_BLOCK_KEEP_OPEN)) {
+ menu->menuretval = submenu->menuretval;
+ menu->butretval = data->retval;
+ }
+ }
+
+ update = (submenu->menuretval & UI_RETURN_UPDATE) != 0;
+
+ /* now let activated button in this menu exit, which
+ * will actually close the submenu too */
+ ui_handle_button_return_submenu(C, event, but);
+
+ if (update) {
+ submenu->menuretval = 0;
+ }
+ }
+
+ if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
+ /* for cases where close does not cascade, allow the user to
+ * move the mouse back towards the menu without closing */
+ ui_mouse_motion_towards_reinit(menu, &event->x);
+ }
+
+ if (menu->menuretval) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+ else {
+ return WM_UI_HANDLER_BREAK;
+ }
}
static bool ui_but_pie_menu_supported_apply(uiBut *but)
{
- return (!ELEM(but->type, UI_BTYPE_NUM_SLIDER, UI_BTYPE_NUM));
+ return (!ELEM(but->type, UI_BTYPE_NUM_SLIDER, UI_BTYPE_NUM));
}
-static int ui_but_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, uiBut *but, bool force_close)
+static int ui_but_pie_menu_apply(bContext *C,
+ uiPopupBlockHandle *menu,
+ uiBut *but,
+ bool force_close)
{
- int retval = WM_UI_HANDLER_BREAK;
+ int retval = WM_UI_HANDLER_BREAK;
- if (but && ui_but_pie_menu_supported_apply(but)) {
- if (but->type == UI_BTYPE_MENU) {
- /* forcing the pie menu to close will not handle menus */
- if (!force_close) {
- uiBut *active_but = ui_region_find_active_but(menu->region);
+ if (but && ui_but_pie_menu_supported_apply(but)) {
+ if (but->type == UI_BTYPE_MENU) {
+ /* forcing the pie menu to close will not handle menus */
+ if (!force_close) {
+ uiBut *active_but = ui_region_find_active_but(menu->region);
- if (active_but) {
- button_activate_exit(C, active_but, active_but->active, false, false);
- }
+ if (active_but) {
+ button_activate_exit(C, active_but, active_but->active, false, false);
+ }
- button_activate_init(C, menu->region, but, BUTTON_ACTIVATE_OPEN);
- return retval;
- }
- else {
- menu->menuretval = UI_RETURN_CANCEL;
- }
- }
- else {
- ui_apply_but(C, but->block, but, but->active, false);
- button_activate_exit((bContext *)C, but, but->active, false, true);
+ button_activate_init(C, menu->region, but, BUTTON_ACTIVATE_OPEN);
+ return retval;
+ }
+ else {
+ menu->menuretval = UI_RETURN_CANCEL;
+ }
+ }
+ else {
+ ui_apply_but(C, but->block, but, but->active, false);
+ button_activate_exit((bContext *)C, but, but->active, false, true);
- menu->menuretval = UI_RETURN_OK;
- }
- }
- else {
- menu->menuretval = UI_RETURN_CANCEL;
+ menu->menuretval = UI_RETURN_OK;
+ }
+ }
+ else {
+ menu->menuretval = UI_RETURN_CANCEL;
- ED_region_tag_redraw(menu->region);
- }
+ ED_region_tag_redraw(menu->region);
+ }
- return retval;
+ return retval;
}
static uiBut *ui_block_pie_dir_activate(uiBlock *block, const wmEvent *event, RadialDirection dir)
{
- uiBut *but;
+ uiBut *but;
- if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but->pie_dir == dir && !ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
- return but;
- }
- }
- }
+ if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->pie_dir == dir && !ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
+ return but;
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
static int ui_but_pie_button_activate(bContext *C, uiBut *but, uiPopupBlockHandle *menu)
{
- uiBut *active_but;
+ uiBut *active_but;
- if (but == NULL) {
- return WM_UI_HANDLER_BREAK;
- }
+ if (but == NULL) {
+ return WM_UI_HANDLER_BREAK;
+ }
- active_but = ui_region_find_active_but(menu->region);
+ active_but = ui_region_find_active_but(menu->region);
- if (active_but) {
- button_activate_exit(C, active_but, active_but->active, false, false);
- }
+ if (active_but) {
+ button_activate_exit(C, active_but, active_but->active, false, false);
+ }
- button_activate_init(C, menu->region, but, BUTTON_ACTIVATE_OVER);
- return ui_but_pie_menu_apply(C, menu, but, false);
+ button_activate_init(C, menu->region, but, BUTTON_ACTIVATE_OVER);
+ return ui_but_pie_menu_apply(C, menu, but, false);
}
static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
{
- ARegion *ar;
- uiBlock *block;
- uiBut *but;
- float event_xy[2];
- double duration;
- bool is_click_style;
- float dist;
-
- /* we block all events, this is modal interaction,
- * except for drop events which is described below */
- int retval = WM_UI_HANDLER_BREAK;
-
- if (event->type == EVT_DROP) {
- /* may want to leave this here for later if we support pie ovens */
-
- retval = WM_UI_HANDLER_CONTINUE;
- }
-
- ar = menu->region;
- block = ar->uiblocks.first;
-
- is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE);
-
- /* if there's an active modal button, don't check events or outside, except for search menu */
- but = ui_region_find_active_but(ar);
-
- if (menu->scrolltimer == NULL) {
- menu->scrolltimer =
- WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, PIE_MENU_INTERVAL);
- menu->scrolltimer->duration = 0.0;
- }
-
- duration = menu->scrolltimer->duration;
-
- event_xy[0] = event->x;
- event_xy[1] = event->y;
-
- ui_window_to_block_fl(ar, block, &event_xy[0], &event_xy[1]);
-
- /* Distance from initial point. */
- dist = ui_block_calc_pie_segment(block, event_xy);
-
- if (but && button_modal_state(but->active->state)) {
- retval = ui_handle_menu_button(C, event, menu);
- }
- else {
- if (event->type == TIMER) {
- if (event->customdata == menu->scrolltimer) {
- /* deactivate initial direction after a while */
- if (duration > 0.01 * U.pie_initial_timeout) {
- block->pie_data.flags &= ~UI_PIE_INITIAL_DIRECTION;
- }
-
- /* handle animation */
- if (!(block->pie_data.flags & UI_PIE_ANIMATION_FINISHED)) {
- double final_time = 0.01 * U.pie_animation_timeout;
- float fac = duration / final_time;
- float pie_radius = U.pie_menu_radius * UI_DPI_FAC;
-
- if (fac > 1.0f) {
- fac = 1.0f;
- block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED;
- }
-
- for (but = block->buttons.first; but; but = but->next) {
- if (but->pie_dir != UI_RADIAL_NONE) {
- float vec[2];
- float center[2];
-
- ui_but_pie_dir(but->pie_dir, vec);
-
- center[0] = (vec[0] > 0.01f) ? 0.5f : ((vec[0] < -0.01f) ? -0.5f : 0.0f);
- center[1] = (vec[1] > 0.99f) ? 0.5f : ((vec[1] < -0.99f) ? -0.5f : 0.0f);
-
- center[0] *= BLI_rctf_size_x(&but->rect);
- center[1] *= BLI_rctf_size_y(&but->rect);
-
- mul_v2_fl(vec, pie_radius);
- add_v2_v2(vec, center);
- mul_v2_fl(vec, fac);
- add_v2_v2(vec, block->pie_data.pie_center_spawned);
-
- BLI_rctf_recenter(&but->rect, vec[0], vec[1]);
- }
- }
- block->pie_data.alphafac = fac;
-
- ED_region_tag_redraw(ar);
- }
- }
-
- /* check pie velociy here if gesture has ended */
- if (block->pie_data.flags & UI_PIE_GESTURE_END_WAIT) {
- float len_sq = 10;
-
- /* use a time threshold to ensure we leave time to the mouse to move */
- if (duration - block->pie_data.duration_gesture > 0.02) {
- len_sq = len_squared_v2v2(event_xy, block->pie_data.last_pos);
- copy_v2_v2(block->pie_data.last_pos, event_xy);
- block->pie_data.duration_gesture = duration;
- }
-
- if (len_sq < 1.0f) {
- but = ui_region_find_active_but(menu->region);
-
- if (but) {
- return ui_but_pie_menu_apply(C, menu, but, true);
- }
- }
- }
- }
-
- if (event->type == block->pie_data.event && !is_click_style) {
- if (event->val != KM_RELEASE) {
- ui_handle_menu_button(C, event, menu);
-
- if (len_squared_v2v2(event_xy, block->pie_data.pie_center_init) > PIE_CLICK_THRESHOLD_SQ) {
- block->pie_data.flags |= UI_PIE_DRAG_STYLE;
- }
- /* why redraw here? It's simple, we are getting many double click events here.
- * Those operate like mouse move events almost */
- ED_region_tag_redraw(ar);
- }
- else {
- if ((duration < 0.01 * U.pie_tap_timeout) &&
- !(block->pie_data.flags & UI_PIE_DRAG_STYLE))
- {
- block->pie_data.flags |= UI_PIE_CLICK_STYLE;
- }
- else {
- but = ui_region_find_active_but(menu->region);
-
- if (but && (U.pie_menu_confirm > 0) &&
- (dist >= U.dpi_fac * (U.pie_menu_threshold + U.pie_menu_confirm)))
- {
- if (but) {
- return ui_but_pie_menu_apply(C, menu, but, true);
- }
- }
-
- retval = ui_but_pie_menu_apply(C, menu, but, true);
-
- }
- }
- }
- else {
- /* direction from numpad */
- RadialDirection num_dir = UI_RADIAL_NONE;
-
- switch (event->type) {
- case MOUSEMOVE:
- if (!is_click_style) {
- float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init);
-
- /* here we use the initial position explicitly */
- if (len_sq > PIE_CLICK_THRESHOLD_SQ) {
- block->pie_data.flags |= UI_PIE_DRAG_STYLE;
- }
-
- /* here instead, we use the offset location to account for the initial
- * direction timeout */
- if ((U.pie_menu_confirm > 0) &&
- (dist >= U.dpi_fac * (U.pie_menu_threshold + U.pie_menu_confirm)))
- {
- block->pie_data.flags |= UI_PIE_GESTURE_END_WAIT;
- copy_v2_v2(block->pie_data.last_pos, event_xy);
- block->pie_data.duration_gesture = duration;
- }
- }
-
- ui_handle_menu_button(C, event, menu);
-
- /* mouse move should always refresh the area for pie menus */
- ED_region_tag_redraw(ar);
- break;
-
- case LEFTMOUSE:
- if (is_click_style) {
- if (block->pie_data.flags & UI_PIE_INVALID_DIR) {
- menu->menuretval = UI_RETURN_CANCEL;
- }
- else {
- retval = ui_handle_menu_button(C, event, menu);
- }
- }
- break;
-
- case ESCKEY:
- case RIGHTMOUSE:
- menu->menuretval = UI_RETURN_CANCEL;
- break;
-
- case AKEY:
- case BKEY:
- case CKEY:
- case DKEY:
- case EKEY:
- case FKEY:
- case GKEY:
- case HKEY:
- case IKEY:
- case JKEY:
- case KKEY:
- case LKEY:
- case MKEY:
- case NKEY:
- case OKEY:
- case PKEY:
- case QKEY:
- case RKEY:
- case SKEY:
- case TKEY:
- case UKEY:
- case VKEY:
- case WKEY:
- case XKEY:
- case YKEY:
- case ZKEY:
- {
- if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
- !IS_EVENT_MOD(event, shift, ctrl, oskey))
- {
- for (but = block->buttons.first; but; but = but->next) {
- if (but->menu_key == event->type) {
- ui_but_pie_button_activate(C, but, menu);
- }
- }
- }
- break;
- }
+ ARegion *ar;
+ uiBlock *block;
+ uiBut *but;
+ float event_xy[2];
+ double duration;
+ bool is_click_style;
+ float dist;
+
+ /* we block all events, this is modal interaction,
+ * except for drop events which is described below */
+ int retval = WM_UI_HANDLER_BREAK;
+
+ if (event->type == EVT_DROP) {
+ /* may want to leave this here for later if we support pie ovens */
+
+ retval = WM_UI_HANDLER_CONTINUE;
+ }
+
+ ar = menu->region;
+ block = ar->uiblocks.first;
+
+ is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE);
+
+ /* if there's an active modal button, don't check events or outside, except for search menu */
+ but = ui_region_find_active_but(ar);
+
+ if (menu->scrolltimer == NULL) {
+ menu->scrolltimer = WM_event_add_timer(
+ CTX_wm_manager(C), CTX_wm_window(C), TIMER, PIE_MENU_INTERVAL);
+ menu->scrolltimer->duration = 0.0;
+ }
+
+ duration = menu->scrolltimer->duration;
+
+ event_xy[0] = event->x;
+ event_xy[1] = event->y;
+
+ ui_window_to_block_fl(ar, block, &event_xy[0], &event_xy[1]);
+
+ /* Distance from initial point. */
+ dist = ui_block_calc_pie_segment(block, event_xy);
+
+ if (but && button_modal_state(but->active->state)) {
+ retval = ui_handle_menu_button(C, event, menu);
+ }
+ else {
+ if (event->type == TIMER) {
+ if (event->customdata == menu->scrolltimer) {
+ /* deactivate initial direction after a while */
+ if (duration > 0.01 * U.pie_initial_timeout) {
+ block->pie_data.flags &= ~UI_PIE_INITIAL_DIRECTION;
+ }
+
+ /* handle animation */
+ if (!(block->pie_data.flags & UI_PIE_ANIMATION_FINISHED)) {
+ double final_time = 0.01 * U.pie_animation_timeout;
+ float fac = duration / final_time;
+ float pie_radius = U.pie_menu_radius * UI_DPI_FAC;
+
+ if (fac > 1.0f) {
+ fac = 1.0f;
+ block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED;
+ }
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->pie_dir != UI_RADIAL_NONE) {
+ float vec[2];
+ float center[2];
+
+ ui_but_pie_dir(but->pie_dir, vec);
+
+ center[0] = (vec[0] > 0.01f) ? 0.5f : ((vec[0] < -0.01f) ? -0.5f : 0.0f);
+ center[1] = (vec[1] > 0.99f) ? 0.5f : ((vec[1] < -0.99f) ? -0.5f : 0.0f);
+
+ center[0] *= BLI_rctf_size_x(&but->rect);
+ center[1] *= BLI_rctf_size_y(&but->rect);
+
+ mul_v2_fl(vec, pie_radius);
+ add_v2_v2(vec, center);
+ mul_v2_fl(vec, fac);
+ add_v2_v2(vec, block->pie_data.pie_center_spawned);
+
+ BLI_rctf_recenter(&but->rect, vec[0], vec[1]);
+ }
+ }
+ block->pie_data.alphafac = fac;
+
+ ED_region_tag_redraw(ar);
+ }
+ }
+
+ /* check pie velociy here if gesture has ended */
+ if (block->pie_data.flags & UI_PIE_GESTURE_END_WAIT) {
+ float len_sq = 10;
+
+ /* use a time threshold to ensure we leave time to the mouse to move */
+ if (duration - block->pie_data.duration_gesture > 0.02) {
+ len_sq = len_squared_v2v2(event_xy, block->pie_data.last_pos);
+ copy_v2_v2(block->pie_data.last_pos, event_xy);
+ block->pie_data.duration_gesture = duration;
+ }
+
+ if (len_sq < 1.0f) {
+ but = ui_region_find_active_but(menu->region);
+
+ if (but) {
+ return ui_but_pie_menu_apply(C, menu, but, true);
+ }
+ }
+ }
+ }
+
+ if (event->type == block->pie_data.event && !is_click_style) {
+ if (event->val != KM_RELEASE) {
+ ui_handle_menu_button(C, event, menu);
+
+ if (len_squared_v2v2(event_xy, block->pie_data.pie_center_init) > PIE_CLICK_THRESHOLD_SQ) {
+ block->pie_data.flags |= UI_PIE_DRAG_STYLE;
+ }
+ /* why redraw here? It's simple, we are getting many double click events here.
+ * Those operate like mouse move events almost */
+ ED_region_tag_redraw(ar);
+ }
+ else {
+ if ((duration < 0.01 * U.pie_tap_timeout) &&
+ !(block->pie_data.flags & UI_PIE_DRAG_STYLE)) {
+ block->pie_data.flags |= UI_PIE_CLICK_STYLE;
+ }
+ else {
+ but = ui_region_find_active_but(menu->region);
+
+ if (but && (U.pie_menu_confirm > 0) &&
+ (dist >= U.dpi_fac * (U.pie_menu_threshold + U.pie_menu_confirm))) {
+ if (but) {
+ return ui_but_pie_menu_apply(C, menu, but, true);
+ }
+ }
+
+ retval = ui_but_pie_menu_apply(C, menu, but, true);
+ }
+ }
+ }
+ else {
+ /* direction from numpad */
+ RadialDirection num_dir = UI_RADIAL_NONE;
+
+ switch (event->type) {
+ case MOUSEMOVE:
+ if (!is_click_style) {
+ float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init);
+
+ /* here we use the initial position explicitly */
+ if (len_sq > PIE_CLICK_THRESHOLD_SQ) {
+ block->pie_data.flags |= UI_PIE_DRAG_STYLE;
+ }
+
+ /* here instead, we use the offset location to account for the initial
+ * direction timeout */
+ if ((U.pie_menu_confirm > 0) &&
+ (dist >= U.dpi_fac * (U.pie_menu_threshold + U.pie_menu_confirm))) {
+ block->pie_data.flags |= UI_PIE_GESTURE_END_WAIT;
+ copy_v2_v2(block->pie_data.last_pos, event_xy);
+ block->pie_data.duration_gesture = duration;
+ }
+ }
+
+ ui_handle_menu_button(C, event, menu);
+
+ /* mouse move should always refresh the area for pie menus */
+ ED_region_tag_redraw(ar);
+ break;
+
+ case LEFTMOUSE:
+ if (is_click_style) {
+ if (block->pie_data.flags & UI_PIE_INVALID_DIR) {
+ menu->menuretval = UI_RETURN_CANCEL;
+ }
+ else {
+ retval = ui_handle_menu_button(C, event, menu);
+ }
+ }
+ break;
+
+ case ESCKEY:
+ case RIGHTMOUSE:
+ menu->menuretval = UI_RETURN_CANCEL;
+ break;
+
+ case AKEY:
+ case BKEY:
+ case CKEY:
+ case DKEY:
+ case EKEY:
+ case FKEY:
+ case GKEY:
+ case HKEY:
+ case IKEY:
+ case JKEY:
+ case KKEY:
+ case LKEY:
+ case MKEY:
+ case NKEY:
+ case OKEY:
+ case PKEY:
+ case QKEY:
+ case RKEY:
+ case SKEY:
+ case TKEY:
+ case UKEY:
+ case VKEY:
+ case WKEY:
+ case XKEY:
+ case YKEY:
+ case ZKEY: {
+ if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
+ !IS_EVENT_MOD(event, shift, ctrl, oskey)) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->menu_key == event->type) {
+ ui_but_pie_button_activate(C, but, menu);
+ }
+ }
+ }
+ break;
+ }
#define CASE_NUM_TO_DIR(n, d) \
- case (ZEROKEY + n): case (PAD0 + n): \
- { if (num_dir == UI_RADIAL_NONE) num_dir = d; } (void)0
-
- CASE_NUM_TO_DIR(1, UI_RADIAL_SW); ATTR_FALLTHROUGH;
- CASE_NUM_TO_DIR(2, UI_RADIAL_S); ATTR_FALLTHROUGH;
- CASE_NUM_TO_DIR(3, UI_RADIAL_SE); ATTR_FALLTHROUGH;
- CASE_NUM_TO_DIR(4, UI_RADIAL_W); ATTR_FALLTHROUGH;
- CASE_NUM_TO_DIR(6, UI_RADIAL_E); ATTR_FALLTHROUGH;
- CASE_NUM_TO_DIR(7, UI_RADIAL_NW); ATTR_FALLTHROUGH;
- CASE_NUM_TO_DIR(8, UI_RADIAL_N); ATTR_FALLTHROUGH;
- CASE_NUM_TO_DIR(9, UI_RADIAL_NE);
- {
- but = ui_block_pie_dir_activate(block, event, num_dir);
- retval = ui_but_pie_button_activate(C, but, menu);
- break;
- }
+ case (ZEROKEY + n): \
+ case (PAD0 + n): { \
+ if (num_dir == UI_RADIAL_NONE) \
+ num_dir = d; \
+ } \
+ (void)0
+
+ CASE_NUM_TO_DIR(1, UI_RADIAL_SW);
+ ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(2, UI_RADIAL_S);
+ ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(3, UI_RADIAL_SE);
+ ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(4, UI_RADIAL_W);
+ ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(6, UI_RADIAL_E);
+ ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(7, UI_RADIAL_NW);
+ ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(8, UI_RADIAL_N);
+ ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(9, UI_RADIAL_NE);
+ {
+ but = ui_block_pie_dir_activate(block, event, num_dir);
+ retval = ui_but_pie_button_activate(C, but, menu);
+ break;
+ }
#undef CASE_NUM_TO_DIR
- default:
- retval = ui_handle_menu_button(C, event, menu);
- break;
- }
- }
- }
-
- return retval;
-}
-
-static int ui_handle_menus_recursive(
- bContext *C, const wmEvent *event, uiPopupBlockHandle *menu,
- int level, const bool is_parent_inside, const bool is_parent_menu, const bool is_floating)
-{
- uiBut *but;
- uiHandleButtonData *data;
- uiPopupBlockHandle *submenu;
- int retval = WM_UI_HANDLER_CONTINUE;
- bool do_towards_reinit = false;
-
- /* check if we have a submenu, and handle events for it first */
- but = ui_region_find_active_but(menu->region);
- data = (but) ? but->active : NULL;
- submenu = (data) ? data->menu : NULL;
-
- if (submenu) {
- uiBlock *block = menu->region->uiblocks.first;
- const bool is_menu = ui_block_is_menu(block);
- bool inside = false;
- /* root pie menus accept the key that spawned
- * them as double click to improve responsiveness */
- bool do_recursion = (!(block->flag & UI_BLOCK_RADIAL) || event->type != block->pie_data.event);
-
- if (do_recursion) {
- if (is_parent_inside == false) {
- int mx, my;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(menu->region, block, &mx, &my);
- inside = BLI_rctf_isect_pt(&block->rect, mx, my);
- }
-
- retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside, is_menu, false);
- }
- }
-
- /* now handle events for our own menu */
- if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- const bool do_but_search = (but && (but->type == UI_BTYPE_SEARCH_MENU));
- if (submenu && submenu->menuretval) {
- const bool do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT) != 0;
- retval = ui_handle_menu_return_submenu(C, event, menu);
- submenu = NULL; /* hint not to use this, it may be freed by call above */
- (void)submenu;
- /* we may want to quit the submenu and handle the even in this menu,
- * if its important to use it, check 'data->menu' first */
- if (((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) == 0) {
- /* skip applying the event */
- return retval;
- }
- }
-
- if (do_but_search) {
- uiBlock *block = menu->region->uiblocks.first;
-
- retval = ui_handle_menu_button(C, event, menu);
-
- if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
- /* when there is a active search button and we close it,
- * we need to reinit the mouse coords [#35346] */
- if (ui_region_find_active_but(menu->region) != but) {
- do_towards_reinit = true;
- }
- }
- }
- else {
- uiBlock *block = menu->region->uiblocks.first;
- uiBut *listbox = ui_list_find_mouse_over(menu->region, event);
-
- if (block->flag & UI_BLOCK_RADIAL) {
- retval = ui_pie_handler(C, event, menu);
- }
- else if (event->type == LEFTMOUSE || event->val != KM_DBL_CLICK) {
- bool handled = false;
-
- if (listbox) {
- int retval_test = ui_handle_list_event(C, event, menu->region, listbox);
- if (retval_test != WM_UI_HANDLER_CONTINUE) {
- retval = retval_test;
- handled = true;
- }
- }
-
- if (handled == false) {
- retval = ui_handle_menu_event(
- C, event, menu, level,
- is_parent_inside, is_parent_menu, is_floating);
- }
- }
- }
- }
-
- if (do_towards_reinit) {
- ui_mouse_motion_towards_reinit(menu, &event->x);
- }
-
- return retval;
+ default:
+ retval = ui_handle_menu_button(C, event, menu);
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
+
+static int ui_handle_menus_recursive(bContext *C,
+ const wmEvent *event,
+ uiPopupBlockHandle *menu,
+ int level,
+ const bool is_parent_inside,
+ const bool is_parent_menu,
+ const bool is_floating)
+{
+ uiBut *but;
+ uiHandleButtonData *data;
+ uiPopupBlockHandle *submenu;
+ int retval = WM_UI_HANDLER_CONTINUE;
+ bool do_towards_reinit = false;
+
+ /* check if we have a submenu, and handle events for it first */
+ but = ui_region_find_active_but(menu->region);
+ data = (but) ? but->active : NULL;
+ submenu = (data) ? data->menu : NULL;
+
+ if (submenu) {
+ uiBlock *block = menu->region->uiblocks.first;
+ const bool is_menu = ui_block_is_menu(block);
+ bool inside = false;
+ /* root pie menus accept the key that spawned
+ * them as double click to improve responsiveness */
+ bool do_recursion = (!(block->flag & UI_BLOCK_RADIAL) || event->type != block->pie_data.event);
+
+ if (do_recursion) {
+ if (is_parent_inside == false) {
+ int mx, my;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(menu->region, block, &mx, &my);
+ inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+ }
+
+ retval = ui_handle_menus_recursive(
+ C, event, submenu, level + 1, is_parent_inside || inside, is_menu, false);
+ }
+ }
+
+ /* now handle events for our own menu */
+ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
+ const bool do_but_search = (but && (but->type == UI_BTYPE_SEARCH_MENU));
+ if (submenu && submenu->menuretval) {
+ const bool do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT) != 0;
+ retval = ui_handle_menu_return_submenu(C, event, menu);
+ submenu = NULL; /* hint not to use this, it may be freed by call above */
+ (void)submenu;
+ /* we may want to quit the submenu and handle the even in this menu,
+ * if its important to use it, check 'data->menu' first */
+ if (((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) == 0) {
+ /* skip applying the event */
+ return retval;
+ }
+ }
+
+ if (do_but_search) {
+ uiBlock *block = menu->region->uiblocks.first;
+
+ retval = ui_handle_menu_button(C, event, menu);
+
+ if (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)) {
+ /* when there is a active search button and we close it,
+ * we need to reinit the mouse coords [#35346] */
+ if (ui_region_find_active_but(menu->region) != but) {
+ do_towards_reinit = true;
+ }
+ }
+ }
+ else {
+ uiBlock *block = menu->region->uiblocks.first;
+ uiBut *listbox = ui_list_find_mouse_over(menu->region, event);
+
+ if (block->flag & UI_BLOCK_RADIAL) {
+ retval = ui_pie_handler(C, event, menu);
+ }
+ else if (event->type == LEFTMOUSE || event->val != KM_DBL_CLICK) {
+ bool handled = false;
+
+ if (listbox) {
+ int retval_test = ui_handle_list_event(C, event, menu->region, listbox);
+ if (retval_test != WM_UI_HANDLER_CONTINUE) {
+ retval = retval_test;
+ handled = true;
+ }
+ }
+
+ if (handled == false) {
+ retval = ui_handle_menu_event(
+ C, event, menu, level, is_parent_inside, is_parent_menu, is_floating);
+ }
+ }
+ }
+ }
+
+ if (do_towards_reinit) {
+ ui_mouse_motion_towards_reinit(menu, &event->x);
+ }
+
+ return retval;
}
/**
@@ -9863,10 +9909,10 @@ static int ui_handle_menus_recursive(
*/
void UI_popup_menu_retval_set(const uiBlock *block, const int retval, const bool enable)
{
- uiPopupBlockHandle *menu = block->handle;
- if (menu) {
- menu->menuretval = enable ? (menu->menuretval | retval) : (menu->menuretval & retval);
- }
+ uiPopupBlockHandle *menu = block->handle;
+ if (menu) {
+ menu->menuretval = enable ? (menu->menuretval | retval) : (menu->menuretval & retval);
+ }
}
/** \} */
@@ -9877,391 +9923,387 @@ void UI_popup_menu_retval_set(const uiBlock *block, const int retval, const bool
static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
- ARegion *ar;
- uiBut *but, *listbox;
- int retval;
+ ARegion *ar;
+ uiBut *but, *listbox;
+ int retval;
- /* here we handle buttons at the region level, non-modal */
- ar = CTX_wm_region(C);
- retval = WM_UI_HANDLER_CONTINUE;
+ /* here we handle buttons at the region level, non-modal */
+ ar = CTX_wm_region(C);
+ retval = WM_UI_HANDLER_CONTINUE;
- if (ar == NULL || BLI_listbase_is_empty(&ar->uiblocks)) {
- return retval;
- }
+ if (ar == NULL || BLI_listbase_is_empty(&ar->uiblocks)) {
+ return retval;
+ }
- /* either handle events for already activated button or try to activate */
- but = ui_region_find_active_but(ar);
- listbox = ui_list_find_mouse_over(ar, event);
+ /* either handle events for already activated button or try to activate */
+ but = ui_region_find_active_but(ar);
+ listbox = ui_list_find_mouse_over(ar, event);
- retval = ui_handler_panel_region(C, event, ar, listbox ? listbox : but);
+ retval = ui_handler_panel_region(C, event, ar, listbox ? listbox : but);
- if (retval == WM_UI_HANDLER_CONTINUE && listbox) {
- retval = ui_handle_list_event(C, event, ar, listbox);
+ if (retval == WM_UI_HANDLER_CONTINUE && listbox) {
+ retval = ui_handle_list_event(C, event, ar, listbox);
- /* interactions with the listbox should disable tips */
- if (retval == WM_UI_HANDLER_BREAK) {
- if (but) {
- UI_but_tooltip_timer_remove(C, but);
- }
- }
- }
+ /* interactions with the listbox should disable tips */
+ if (retval == WM_UI_HANDLER_BREAK) {
+ if (but) {
+ UI_but_tooltip_timer_remove(C, but);
+ }
+ }
+ }
- if (retval == WM_UI_HANDLER_CONTINUE) {
- if (but) {
- retval = ui_handle_button_event(C, event, but);
- }
- else {
- retval = ui_handle_button_over(C, event, ar);
- }
- }
+ if (retval == WM_UI_HANDLER_CONTINUE) {
+ if (but) {
+ retval = ui_handle_button_event(C, event, but);
+ }
+ else {
+ retval = ui_handle_button_over(C, event, ar);
+ }
+ }
- /* re-enable tooltips */
- if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
- ui_blocks_set_tooltips(ar, true);
- }
+ /* re-enable tooltips */
+ if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
+ ui_blocks_set_tooltips(ar, true);
+ }
- /* delayed apply callbacks */
- ui_apply_but_funcs_after(C);
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
- return retval;
+ return retval;
}
static void ui_region_handler_remove(bContext *C, void *UNUSED(userdata))
{
- bScreen *sc;
- ARegion *ar;
+ bScreen *sc;
+ ARegion *ar;
- ar = CTX_wm_region(C);
- if (ar == NULL) {
- return;
- }
+ ar = CTX_wm_region(C);
+ if (ar == NULL) {
+ return;
+ }
- UI_blocklist_free(C, &ar->uiblocks);
+ UI_blocklist_free(C, &ar->uiblocks);
- sc = CTX_wm_screen(C);
- if (sc == NULL) {
- return;
- }
+ sc = CTX_wm_screen(C);
+ if (sc == NULL) {
+ return;
+ }
- /* delayed apply callbacks, but not for screen level regions, those
- * we rather do at the very end after closing them all, which will
- * be done in ui_region_handler/window */
- if (BLI_findindex(&sc->regionbase, ar) == -1) {
- ui_apply_but_funcs_after(C);
- }
+ /* delayed apply callbacks, but not for screen level regions, those
+ * we rather do at the very end after closing them all, which will
+ * be done in ui_region_handler/window */
+ if (BLI_findindex(&sc->regionbase, ar) == -1) {
+ ui_apply_but_funcs_after(C);
+ }
}
/* handle buttons at the window level, modal, for example while
* number sliding, text editing, or when a menu block is open */
static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSED(userdata))
{
- ARegion *ar;
- uiBut *but;
- int retval = WM_UI_HANDLER_CONTINUE;
-
- ar = CTX_wm_menu(C);
- if (!ar) {
- ar = CTX_wm_region(C);
- }
-
- but = ui_region_find_active_but(ar);
-
- if (but) {
- bScreen *screen = CTX_wm_screen(C);
- ARegion *ar_temp;
- uiBut *but_other;
- uiHandleButtonData *data;
- bool is_inside_menu = false;
-
- /* look for a popup menu containing the mouse */
- for (ar_temp = screen->regionbase.first; ar_temp; ar_temp = ar_temp->next) {
- rcti winrct;
-
- ui_region_winrct_get_no_margin(ar_temp, &winrct);
-
- if (BLI_rcti_isect_pt_v(&winrct, &event->x)) {
- BLI_assert(ar_temp->type->regionid == RGN_TYPE_TEMPORARY);
-
- is_inside_menu = true;
- break;
- }
- }
-
- /* handle activated button events */
- data = but->active;
-
- if ((data->state == BUTTON_STATE_MENU_OPEN) &&
- /* make sure mouse isn't inside another menu (see T43247) */
- (is_inside_menu == false) &&
- (ELEM(but->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) &&
- (but_other = ui_but_find_mouse_over(ar, event)) &&
- (but != but_other) &&
- (ELEM(but_other->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)))
- {
- /* if mouse moves to a different root-level menu button,
- * open it to replace the current menu */
- if ((but_other->flag & UI_BUT_DISABLED) == 0) {
- ui_handle_button_activate(C, ar, but_other, BUTTON_ACTIVATE_OVER);
- button_activate_state(C, but_other, BUTTON_STATE_MENU_OPEN);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- else if (data->state == BUTTON_STATE_MENU_OPEN) {
- /* handle events for menus and their buttons recursively,
- * this will handle events from the top to the bottom menu */
- if (data->menu) {
- retval = ui_handle_menus_recursive(C, event, data->menu, 0, false, false, false);
- }
-
- /* handle events for the activated button */
- if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) ||
- (event->type == TIMER))
- {
- if (data->menu && data->menu->menuretval) {
- ui_handle_button_return_submenu(C, event, but);
- retval = WM_UI_HANDLER_BREAK;
- }
- else {
- retval = ui_handle_button_event(C, event, but);
- }
- }
- }
- else {
- /* handle events for the activated button */
- retval = ui_handle_button_event(C, event, but);
- }
- }
-
- /* re-enable tooltips */
- if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
- ui_blocks_set_tooltips(ar, true);
- }
-
- /* delayed apply callbacks */
- ui_apply_but_funcs_after(C);
-
- /* Don't handle double-click events,
- * these will be converted into regular clicks which we handle. */
- if (retval == WM_UI_HANDLER_CONTINUE) {
- if (event->val == KM_DBL_CLICK) {
- return WM_UI_HANDLER_CONTINUE;
- }
- }
-
- /* we block all events, this is modal interaction */
- return WM_UI_HANDLER_BREAK;
+ ARegion *ar;
+ uiBut *but;
+ int retval = WM_UI_HANDLER_CONTINUE;
+
+ ar = CTX_wm_menu(C);
+ if (!ar) {
+ ar = CTX_wm_region(C);
+ }
+
+ but = ui_region_find_active_but(ar);
+
+ if (but) {
+ bScreen *screen = CTX_wm_screen(C);
+ ARegion *ar_temp;
+ uiBut *but_other;
+ uiHandleButtonData *data;
+ bool is_inside_menu = false;
+
+ /* look for a popup menu containing the mouse */
+ for (ar_temp = screen->regionbase.first; ar_temp; ar_temp = ar_temp->next) {
+ rcti winrct;
+
+ ui_region_winrct_get_no_margin(ar_temp, &winrct);
+
+ if (BLI_rcti_isect_pt_v(&winrct, &event->x)) {
+ BLI_assert(ar_temp->type->regionid == RGN_TYPE_TEMPORARY);
+
+ is_inside_menu = true;
+ break;
+ }
+ }
+
+ /* handle activated button events */
+ data = but->active;
+
+ if ((data->state == BUTTON_STATE_MENU_OPEN) &&
+ /* make sure mouse isn't inside another menu (see T43247) */
+ (is_inside_menu == false) && (ELEM(but->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER)) &&
+ (but_other = ui_but_find_mouse_over(ar, event)) && (but != but_other) &&
+ (ELEM(but_other->type, UI_BTYPE_PULLDOWN, UI_BTYPE_POPOVER))) {
+ /* if mouse moves to a different root-level menu button,
+ * open it to replace the current menu */
+ if ((but_other->flag & UI_BUT_DISABLED) == 0) {
+ ui_handle_button_activate(C, ar, but_other, BUTTON_ACTIVATE_OVER);
+ button_activate_state(C, but_other, BUTTON_STATE_MENU_OPEN);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if (data->state == BUTTON_STATE_MENU_OPEN) {
+ /* handle events for menus and their buttons recursively,
+ * this will handle events from the top to the bottom menu */
+ if (data->menu) {
+ retval = ui_handle_menus_recursive(C, event, data->menu, 0, false, false, false);
+ }
+
+ /* handle events for the activated button */
+ if ((data->menu && (retval == WM_UI_HANDLER_CONTINUE)) || (event->type == TIMER)) {
+ if (data->menu && data->menu->menuretval) {
+ ui_handle_button_return_submenu(C, event, but);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ else {
+ retval = ui_handle_button_event(C, event, but);
+ }
+ }
+ }
+ else {
+ /* handle events for the activated button */
+ retval = ui_handle_button_event(C, event, but);
+ }
+ }
+
+ /* re-enable tooltips */
+ if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
+ ui_blocks_set_tooltips(ar, true);
+ }
+
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
+
+ /* Don't handle double-click events,
+ * these will be converted into regular clicks which we handle. */
+ if (retval == WM_UI_HANDLER_CONTINUE) {
+ if (event->val == KM_DBL_CLICK) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+ }
+
+ /* we block all events, this is modal interaction */
+ return WM_UI_HANDLER_BREAK;
}
/* two types of popups, one with operator + enum, other with regular callbacks */
static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata)
{
- uiPopupBlockHandle *menu = userdata;
- struct ARegion *menu_region;
- /* we block all events, this is modal interaction,
- * except for drop events which is described below */
- int retval = WM_UI_HANDLER_BREAK;
- bool reset_pie = false;
-
- menu_region = CTX_wm_menu(C);
- CTX_wm_menu_set(C, menu->region);
-
- if (event->type == EVT_DROP || event->val == KM_DBL_CLICK) {
- /* EVT_DROP:
- * If we're handling drop event we'll want it to be handled by popup callee as well,
- * so it'll be possible to perform such operations as opening .blend files by dropping
- * them into blender, even if there's opened popup like splash screen (sergey).
- * KM_DBL_CLICK:
- * Continue in case of double click so wm_handlers_do calls handler again with KM_PRESS
- * event. This is needed to ensure correct button handling for fast clicking (T47532).
- */
-
- retval = WM_UI_HANDLER_CONTINUE;
- }
-
- ui_handle_menus_recursive(C, event, menu, 0, false, false, true);
-
- /* free if done, does not free handle itself */
- if (menu->menuretval) {
- wmWindow *win = CTX_wm_window(C);
- /* copy values, we have to free first (closes region) */
- uiPopupBlockHandle temp = *menu;
- uiBlock *block = menu->region->uiblocks.first;
-
- /* set last pie event to allow chained pie spawning */
- if (block->flag & UI_BLOCK_RADIAL) {
- win->last_pie_event = block->pie_data.event;
- reset_pie = true;
- }
-
- ui_popup_block_free(C, menu);
- UI_popup_handlers_remove(&win->modalhandlers, menu);
- CTX_wm_menu_set(C, NULL);
+ uiPopupBlockHandle *menu = userdata;
+ struct ARegion *menu_region;
+ /* we block all events, this is modal interaction,
+ * except for drop events which is described below */
+ int retval = WM_UI_HANDLER_BREAK;
+ bool reset_pie = false;
+
+ menu_region = CTX_wm_menu(C);
+ CTX_wm_menu_set(C, menu->region);
+
+ if (event->type == EVT_DROP || event->val == KM_DBL_CLICK) {
+ /* EVT_DROP:
+ * If we're handling drop event we'll want it to be handled by popup callee as well,
+ * so it'll be possible to perform such operations as opening .blend files by dropping
+ * them into blender, even if there's opened popup like splash screen (sergey).
+ * KM_DBL_CLICK:
+ * Continue in case of double click so wm_handlers_do calls handler again with KM_PRESS
+ * event. This is needed to ensure correct button handling for fast clicking (T47532).
+ */
+
+ retval = WM_UI_HANDLER_CONTINUE;
+ }
+
+ ui_handle_menus_recursive(C, event, menu, 0, false, false, true);
+
+ /* free if done, does not free handle itself */
+ if (menu->menuretval) {
+ wmWindow *win = CTX_wm_window(C);
+ /* copy values, we have to free first (closes region) */
+ uiPopupBlockHandle temp = *menu;
+ uiBlock *block = menu->region->uiblocks.first;
+
+ /* set last pie event to allow chained pie spawning */
+ if (block->flag & UI_BLOCK_RADIAL) {
+ win->last_pie_event = block->pie_data.event;
+ reset_pie = true;
+ }
+
+ ui_popup_block_free(C, menu);
+ UI_popup_handlers_remove(&win->modalhandlers, menu);
+ CTX_wm_menu_set(C, NULL);
#ifdef USE_DRAG_TOGGLE
- {
- WM_event_free_ui_handler_all(
- C, &win->modalhandlers,
- ui_handler_region_drag_toggle, ui_handler_region_drag_toggle_remove);
- }
+ {
+ WM_event_free_ui_handler_all(C,
+ &win->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove);
+ }
#endif
- if ((temp.menuretval & UI_RETURN_OK) || (temp.menuretval & UI_RETURN_POPUP_OK)) {
- if (temp.popup_func) {
- temp.popup_func(C, temp.popup_arg, temp.retvalue);
- }
- if (temp.optype) {
- WM_operator_name_call_ptr(C, temp.optype, temp.opcontext, NULL);
- }
- }
- else if (temp.cancel_func) {
- temp.cancel_func(C, temp.popup_arg);
- }
+ if ((temp.menuretval & UI_RETURN_OK) || (temp.menuretval & UI_RETURN_POPUP_OK)) {
+ if (temp.popup_func) {
+ temp.popup_func(C, temp.popup_arg, temp.retvalue);
+ }
+ if (temp.optype) {
+ WM_operator_name_call_ptr(C, temp.optype, temp.opcontext, NULL);
+ }
+ }
+ else if (temp.cancel_func) {
+ temp.cancel_func(C, temp.popup_arg);
+ }
- WM_event_add_mousemove(C);
- }
- else {
- /* re-enable tooltips */
- if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
- ui_blocks_set_tooltips(menu->region, true);
- }
- }
+ WM_event_add_mousemove(C);
+ }
+ else {
+ /* re-enable tooltips */
+ if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) {
+ ui_blocks_set_tooltips(menu->region, true);
+ }
+ }
- /* delayed apply callbacks */
- ui_apply_but_funcs_after(C);
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
- if (reset_pie) {
- /* reaqcuire window in case pie invalidates it somehow */
- wmWindow *win = CTX_wm_window(C);
+ if (reset_pie) {
+ /* reaqcuire window in case pie invalidates it somehow */
+ wmWindow *win = CTX_wm_window(C);
- if (win) {
- win->last_pie_event = EVENT_NONE;
- }
- }
+ if (win) {
+ win->last_pie_event = EVENT_NONE;
+ }
+ }
- CTX_wm_region_set(C, menu_region);
+ CTX_wm_region_set(C, menu_region);
- return retval;
+ return retval;
}
static void ui_popup_handler_remove(bContext *C, void *userdata)
{
- uiPopupBlockHandle *menu = userdata;
+ uiPopupBlockHandle *menu = userdata;
- /* More correct would be to expect UI_RETURN_CANCEL here, but not wanting to
- * cancel when removing handlers because of file exit is a rare exception.
- * So instead of setting cancel flag for all menus before removing handlers,
- * just explicitly flag menu with UI_RETURN_OK to avoid cancelling it. */
- if ((menu->menuretval & UI_RETURN_OK) == 0 && menu->cancel_func) {
- menu->cancel_func(C, menu->popup_arg);
- }
+ /* More correct would be to expect UI_RETURN_CANCEL here, but not wanting to
+ * cancel when removing handlers because of file exit is a rare exception.
+ * So instead of setting cancel flag for all menus before removing handlers,
+ * just explicitly flag menu with UI_RETURN_OK to avoid cancelling it. */
+ if ((menu->menuretval & UI_RETURN_OK) == 0 && menu->cancel_func) {
+ menu->cancel_func(C, menu->popup_arg);
+ }
- /* free menu block if window is closed for some reason */
- ui_popup_block_free(C, menu);
+ /* free menu block if window is closed for some reason */
+ ui_popup_block_free(C, menu);
- /* delayed apply callbacks */
- ui_apply_but_funcs_after(C);
+ /* delayed apply callbacks */
+ ui_apply_but_funcs_after(C);
}
void UI_region_handlers_add(ListBase *handlers)
{
- WM_event_remove_ui_handler(handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
- WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, 0);
+ WM_event_remove_ui_handler(handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
+ WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, 0);
}
-void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const char flag)
+void UI_popup_handlers_add(bContext *C,
+ ListBase *handlers,
+ uiPopupBlockHandle *popup,
+ const char flag)
{
- WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, flag);
+ WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, flag);
}
void UI_popup_handlers_remove(ListBase *handlers, uiPopupBlockHandle *popup)
{
- LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
- if (handler_base->type == WM_HANDLER_TYPE_UI) {
- wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base;
-
- if (handler->handle_fn == ui_popup_handler &&
- handler->remove_fn == ui_popup_handler_remove &&
- handler->user_data == popup)
- {
- /* tag refresh parent popup */
- wmEventHandler_UI *handler_next = (wmEventHandler_UI *)handler->head.next;
- if (handler_next &&
- handler_next->head.type == WM_HANDLER_TYPE_UI &&
- handler_next->handle_fn == ui_popup_handler &&
- handler_next->remove_fn == ui_popup_handler_remove)
- {
- uiPopupBlockHandle *parent_popup = handler_next->user_data;
- ED_region_tag_refresh_ui(parent_popup->region);
- }
- break;
- }
- }
- }
-
- WM_event_remove_ui_handler(handlers, ui_popup_handler, ui_popup_handler_remove, popup, false);
-}
+ LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) {
+ if (handler_base->type == WM_HANDLER_TYPE_UI) {
+ wmEventHandler_UI *handler = (wmEventHandler_UI *)handler_base;
-void UI_popup_handlers_remove_all(bContext *C, ListBase *handlers)
-{
- WM_event_free_ui_handler_all(C, handlers, ui_popup_handler, ui_popup_handler_remove);
+ if (handler->handle_fn == ui_popup_handler &&
+ handler->remove_fn == ui_popup_handler_remove && handler->user_data == popup) {
+ /* tag refresh parent popup */
+ wmEventHandler_UI *handler_next = (wmEventHandler_UI *)handler->head.next;
+ if (handler_next && handler_next->head.type == WM_HANDLER_TYPE_UI &&
+ handler_next->handle_fn == ui_popup_handler &&
+ handler_next->remove_fn == ui_popup_handler_remove) {
+ uiPopupBlockHandle *parent_popup = handler_next->user_data;
+ ED_region_tag_refresh_ui(parent_popup->region);
+ }
+ break;
+ }
+ }
+ }
+
+ WM_event_remove_ui_handler(handlers, ui_popup_handler, ui_popup_handler_remove, popup, false);
}
-bool UI_textbutton_activate_rna(
- const bContext *C, ARegion *ar,
- const void *rna_poin_data, const char *rna_prop_id)
+void UI_popup_handlers_remove_all(bContext *C, ListBase *handlers)
{
- uiBlock *block;
- uiBut *but = NULL;
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but->type == UI_BTYPE_TEXT) {
- if (but->rnaprop && but->rnapoin.data == rna_poin_data) {
- if (STREQ(RNA_property_identifier(but->rnaprop), rna_prop_id)) {
- break;
- }
- }
- }
- }
- if (but) {
- break;
- }
- }
-
- if (but) {
- UI_but_active_only(C, ar, block, but);
- return true;
- }
- else {
- return false;
- }
+ WM_event_free_ui_handler_all(C, handlers, ui_popup_handler, ui_popup_handler_remove);
+}
+
+bool UI_textbutton_activate_rna(const bContext *C,
+ ARegion *ar,
+ const void *rna_poin_data,
+ const char *rna_prop_id)
+{
+ uiBlock *block;
+ uiBut *but = NULL;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->type == UI_BTYPE_TEXT) {
+ if (but->rnaprop && but->rnapoin.data == rna_poin_data) {
+ if (STREQ(RNA_property_identifier(but->rnaprop), rna_prop_id)) {
+ break;
+ }
+ }
+ }
+ }
+ if (but) {
+ break;
+ }
+ }
+
+ if (but) {
+ UI_but_active_only(C, ar, block, but);
+ return true;
+ }
+ else {
+ return false;
+ }
}
bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut)
{
- ARegion *ar = CTX_wm_region(C);
- uiBlock *block;
- uiBut *but = NULL;
+ ARegion *ar = CTX_wm_region(C);
+ uiBlock *block;
+ uiBut *but = NULL;
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but == actbut && but->type == UI_BTYPE_TEXT) {
- break;
- }
- }
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but == actbut && but->type == UI_BTYPE_TEXT) {
+ break;
+ }
+ }
- if (but) {
- break;
- }
- }
+ if (but) {
+ break;
+ }
+ }
- if (but) {
- UI_but_active_only(C, ar, block, but);
- return true;
- }
- else {
- return false;
- }
+ if (but) {
+ UI_but_active_only(C, ar, block, but);
+ return true;
+ }
+ else {
+ return false;
+ }
}
/** \} */
@@ -10273,54 +10315,54 @@ bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut)
/* is called by notifier */
void UI_screen_free_active_but(const bContext *C, bScreen *screen)
{
- wmWindow *win = CTX_wm_window(C);
+ wmWindow *win = CTX_wm_window(C);
- ED_screen_areas_iter(win, screen, area) {
- for (ARegion *region = area->regionbase.first; region; region = region->next) {
- uiBut *but = ui_region_find_active_but(region);
- if (but) {
- uiHandleButtonData *data = but->active;
+ ED_screen_areas_iter(win, screen, area)
+ {
+ for (ARegion *region = area->regionbase.first; region; region = region->next) {
+ uiBut *but = ui_region_find_active_but(region);
+ if (but) {
+ uiHandleButtonData *data = but->active;
- if (data->menu == NULL && data->searchbox == NULL) {
- if (data->state == BUTTON_STATE_HIGHLIGHT) {
- ui_but_active_free(C, but);
- }
- }
- }
- }
- }
+ if (data->menu == NULL && data->searchbox == NULL) {
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
+ ui_but_active_free(C, but);
+ }
+ }
+ }
+ }
+ }
}
-
/* returns true if highlighted button allows drop of names */
/* called in region context */
bool UI_but_active_drop_name(bContext *C)
{
- ARegion *ar = CTX_wm_region(C);
- uiBut *but = ui_region_find_active_but(ar);
+ ARegion *ar = CTX_wm_region(C);
+ uiBut *but = ui_region_find_active_but(ar);
- if (but) {
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- return 1;
- }
- }
+ if (but) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ return 1;
+ }
+ }
- return 0;
+ return 0;
}
bool UI_but_active_drop_color(bContext *C)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *ar = CTX_wm_region(C);
- if (ar) {
- uiBut *but = ui_region_find_active_but(ar);
+ if (ar) {
+ uiBut *but = ui_region_find_active_but(ar);
- if (but && but->type == UI_BTYPE_COLOR) {
- return true;
- }
- }
+ if (but && but->type == UI_BTYPE_COLOR) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
/** \} */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index dcfeaf64699..e2a75abebd7 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -80,74 +80,74 @@
#include "interface_intern.h"
#ifndef WITH_HEADLESS
-#define ICON_GRID_COLS 26
-#define ICON_GRID_ROWS 30
+# define ICON_GRID_COLS 26
+# define ICON_GRID_ROWS 30
-#define ICON_GRID_MARGIN 10
-#define ICON_GRID_W 32
-#define ICON_GRID_H 32
-#endif /* WITH_HEADLESS */
+# define ICON_GRID_MARGIN 10
+# define ICON_GRID_W 32
+# define ICON_GRID_H 32
+#endif /* WITH_HEADLESS */
typedef struct IconImage {
- int w;
- int h;
- uint *rect;
- const uchar *datatoc_rect;
- int datatoc_size;
+ int w;
+ int h;
+ uint *rect;
+ const uchar *datatoc_rect;
+ int datatoc_size;
} IconImage;
typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
-#define ICON_TYPE_PREVIEW 0
-#define ICON_TYPE_COLOR_TEXTURE 1
-#define ICON_TYPE_MONO_TEXTURE 2
-#define ICON_TYPE_BUFFER 3
-#define ICON_TYPE_VECTOR 4
-#define ICON_TYPE_GEOM 5
-#define ICON_TYPE_EVENT 6 /* draw keymap entries using custom renderer. */
-#define ICON_TYPE_GPLAYER 7
-#define ICON_TYPE_BLANK 8
+#define ICON_TYPE_PREVIEW 0
+#define ICON_TYPE_COLOR_TEXTURE 1
+#define ICON_TYPE_MONO_TEXTURE 2
+#define ICON_TYPE_BUFFER 3
+#define ICON_TYPE_VECTOR 4
+#define ICON_TYPE_GEOM 5
+#define ICON_TYPE_EVENT 6 /* draw keymap entries using custom renderer. */
+#define ICON_TYPE_GPLAYER 7
+#define ICON_TYPE_BLANK 8
typedef struct DrawInfo {
- int type;
-
- union {
- /* type specific data */
- struct {
- VectorDrawFunc func;
- } vector;
- struct {
- ImBuf *image_cache;
- } geom;
- struct {
- IconImage *image;
- } buffer;
- struct {
- int x, y, w, h;
- int theme_color;
- } texture;
- struct {
- /* Can be packed into a single int. */
- short event_type;
- short event_value;
- int icon;
- /* Allow lookups. */
- struct DrawInfo *next;
- } input;
- } data;
+ int type;
+
+ union {
+ /* type specific data */
+ struct {
+ VectorDrawFunc func;
+ } vector;
+ struct {
+ ImBuf *image_cache;
+ } geom;
+ struct {
+ IconImage *image;
+ } buffer;
+ struct {
+ int x, y, w, h;
+ int theme_color;
+ } texture;
+ struct {
+ /* Can be packed into a single int. */
+ short event_type;
+ short event_value;
+ int icon;
+ /* Allow lookups. */
+ struct DrawInfo *next;
+ } input;
+ } data;
} DrawInfo;
typedef struct IconTexture {
- GLuint id;
- int w;
- int h;
- float invw;
- float invh;
+ GLuint id;
+ int w;
+ int h;
+ float invw;
+ float invh;
} IconTexture;
typedef struct IconType {
- int type;
- int theme_color;
+ int type;
+ int theme_color;
} IconType;
/* ******************* STATIC LOCAL VARS ******************* */
@@ -159,93 +159,95 @@ static IconTexture icongltex = {0, 0, 0, 0.0f, 0.0f};
#ifndef WITH_HEADLESS
static const IconType icontypes[] = {
-#define DEF_ICON(name) {ICON_TYPE_MONO_TEXTURE, 0},
-#define DEF_ICON_COLLECTION(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_COLLECTION},
-#define DEF_ICON_OBJECT(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_OBJECT},
-#define DEF_ICON_OBJECT_DATA(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_OBJECT_DATA},
-#define DEF_ICON_MODIFIER(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_MODIFIER},
-#define DEF_ICON_SHADING(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_SHADING},
-#define DEF_ICON_VECTOR(name) {ICON_TYPE_VECTOR, 0},
-#define DEF_ICON_COLOR(name) {ICON_TYPE_COLOR_TEXTURE, 0},
-#define DEF_ICON_BLANK(name) {ICON_TYPE_BLANK, 0},
-#include "UI_icons.h"
+# define DEF_ICON(name) {ICON_TYPE_MONO_TEXTURE, 0},
+# define DEF_ICON_COLLECTION(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_COLLECTION},
+# define DEF_ICON_OBJECT(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_OBJECT},
+# define DEF_ICON_OBJECT_DATA(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_OBJECT_DATA},
+# define DEF_ICON_MODIFIER(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_MODIFIER},
+# define DEF_ICON_SHADING(name) {ICON_TYPE_MONO_TEXTURE, TH_ICON_SHADING},
+# define DEF_ICON_VECTOR(name) {ICON_TYPE_VECTOR, 0},
+# define DEF_ICON_COLOR(name) {ICON_TYPE_COLOR_TEXTURE, 0},
+# define DEF_ICON_BLANK(name) {ICON_TYPE_BLANK, 0},
+# include "UI_icons.h"
};
/* **************************************************** */
-static DrawInfo *def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int size, int type, int theme_color)
+static DrawInfo *def_internal_icon(
+ ImBuf *bbuf, int icon_id, int xofs, int yofs, int size, int type, int theme_color)
{
- Icon *new_icon = NULL;
- IconImage *iimg = NULL;
- DrawInfo *di;
+ Icon *new_icon = NULL;
+ IconImage *iimg = NULL;
+ DrawInfo *di;
- new_icon = MEM_callocN(sizeof(Icon), "texicon");
+ new_icon = MEM_callocN(sizeof(Icon), "texicon");
- new_icon->obj = NULL; /* icon is not for library object */
- new_icon->id_type = 0;
+ new_icon->obj = NULL; /* icon is not for library object */
+ new_icon->id_type = 0;
- di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
- di->type = type;
+ di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
+ di->type = type;
- if (ELEM(type, ICON_TYPE_COLOR_TEXTURE, ICON_TYPE_MONO_TEXTURE)) {
- di->data.texture.theme_color = theme_color;
- di->data.texture.x = xofs;
- di->data.texture.y = yofs;
- di->data.texture.w = size;
- di->data.texture.h = size;
- }
- else if (type == ICON_TYPE_BUFFER) {
- iimg = MEM_callocN(sizeof(IconImage), "icon_img");
- iimg->w = size;
- iimg->h = size;
+ if (ELEM(type, ICON_TYPE_COLOR_TEXTURE, ICON_TYPE_MONO_TEXTURE)) {
+ di->data.texture.theme_color = theme_color;
+ di->data.texture.x = xofs;
+ di->data.texture.y = yofs;
+ di->data.texture.w = size;
+ di->data.texture.h = size;
+ }
+ else if (type == ICON_TYPE_BUFFER) {
+ iimg = MEM_callocN(sizeof(IconImage), "icon_img");
+ iimg->w = size;
+ iimg->h = size;
- /* icon buffers can get initialized runtime now, via datatoc */
- if (bbuf) {
- int y, imgsize;
+ /* icon buffers can get initialized runtime now, via datatoc */
+ if (bbuf) {
+ int y, imgsize;
- iimg->rect = MEM_mallocN(size * size * sizeof(uint), "icon_rect");
+ iimg->rect = MEM_mallocN(size * size * sizeof(uint), "icon_rect");
- /* Here we store the rect in the icon - same as before */
- if (size == bbuf->x && size == bbuf->y && xofs == 0 && yofs == 0) {
- memcpy(iimg->rect, bbuf->rect, size * size * sizeof(int));
- }
- else {
- /* this code assumes square images */
- imgsize = bbuf->x;
- for (y = 0; y < size; y++) {
- memcpy(&iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], size * sizeof(int));
- }
- }
- }
- di->data.buffer.image = iimg;
- }
+ /* Here we store the rect in the icon - same as before */
+ if (size == bbuf->x && size == bbuf->y && xofs == 0 && yofs == 0) {
+ memcpy(iimg->rect, bbuf->rect, size * size * sizeof(int));
+ }
+ else {
+ /* this code assumes square images */
+ imgsize = bbuf->x;
+ for (y = 0; y < size; y++) {
+ memcpy(
+ &iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], size * sizeof(int));
+ }
+ }
+ }
+ di->data.buffer.image = iimg;
+ }
- new_icon->drawinfo_free = UI_icons_free_drawinfo;
- new_icon->drawinfo = di;
+ new_icon->drawinfo_free = UI_icons_free_drawinfo;
+ new_icon->drawinfo = di;
- BKE_icon_set(icon_id, new_icon);
+ BKE_icon_set(icon_id, new_icon);
- return di;
+ return di;
}
static void def_internal_vicon(int icon_id, VectorDrawFunc drawFunc)
{
- Icon *new_icon = NULL;
- DrawInfo *di;
+ Icon *new_icon = NULL;
+ DrawInfo *di;
- new_icon = MEM_callocN(sizeof(Icon), "texicon");
+ new_icon = MEM_callocN(sizeof(Icon), "texicon");
- new_icon->obj = NULL; /* icon is not for library object */
- new_icon->id_type = 0;
+ new_icon->obj = NULL; /* icon is not for library object */
+ new_icon->id_type = 0;
- di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
- di->type = ICON_TYPE_VECTOR;
- di->data.vector.func = drawFunc;
+ di = MEM_callocN(sizeof(DrawInfo), "drawinfo");
+ di->type = ICON_TYPE_VECTOR;
+ di->data.vector.func = drawFunc;
- new_icon->drawinfo_free = NULL;
- new_icon->drawinfo = di;
+ new_icon->drawinfo_free = NULL;
+ new_icon->drawinfo = di;
- BKE_icon_set(icon_id, new_icon);
+ BKE_icon_set(icon_id, new_icon);
}
/* Vector Icon Drawing Routines */
@@ -254,168 +256,184 @@ static void def_internal_vicon(int icon_id, VectorDrawFunc drawFunc)
static void viconutil_set_point(GLint pt[2], int x, int y)
{
- pt[0] = x;
- pt[1] = y;
+ pt[0] = x;
+ pt[1] = y;
}
static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float alpha)
{
- GLint pts[3][2];
- int cx = x + w / 2 - 4;
- int cy = y + w / 2;
- int d = w / 5, d2 = w / 7;
-
- viconutil_set_point(pts[0], cx - d2, cy + d);
- viconutil_set_point(pts[1], cx - d2, cy - d);
- viconutil_set_point(pts[2], cx + d2, cy);
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4f(0.2f, 0.2f, 0.2f, alpha);
-
- immBegin(GPU_PRIM_TRIS, 3);
- immVertex2iv(pos, pts[0]);
- immVertex2iv(pos, pts[1]);
- immVertex2iv(pos, pts[2]);
- immEnd();
-
- immUnbindProgram();
-}
-
-static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, short key_type, short handle_type)
-{
- /* init dummy theme state for Action Editor - where these colors are defined
- * (since we're doing this offscreen, free from any particular space_id)
- */
- struct bThemeState theme_state;
-
- UI_Theme_Store(&theme_state);
- UI_SetTheme(SPACE_ACTION, RGN_TYPE_WINDOW);
-
- /* the "x" and "y" given are the bottom-left coordinates of the icon,
- * while the draw_keyframe_shape() function needs the midpoint for
- * the keyframe
- */
- float xco = x + w / 2 + 0.5f;
- float yco = y + h / 2 + 0.5f;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
-
- immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
- GPU_enable_program_point_size();
- immUniform2f("ViewportSize", -1.0f, -1.0f);
- immBegin(GPU_PRIM_POINTS, 1);
-
- /* draw keyframe
- * - size: (default icon size == 16, default dopesheet icon size == 10)
- * - sel: true unless in handletype icons (so that "keyframe" state shows the iconic yellow icon)
- */
- bool sel = (handle_type == KEYFRAME_HANDLE_NONE);
-
- draw_keyframe_shape(xco, yco, (10.0f / 16.0f) * h, sel, key_type, KEYFRAME_SHAPE_BOTH, alpha,
- pos_id, size_id, color_id, outline_color_id,
- flags_id, handle_type, KEYFRAME_EXTREME_NONE);
-
- immEnd();
- GPU_disable_program_point_size();
- immUnbindProgram();
-
- UI_Theme_Restore(&theme_state);
+ GLint pts[3][2];
+ int cx = x + w / 2 - 4;
+ int cy = y + w / 2;
+ int d = w / 5, d2 = w / 7;
+
+ viconutil_set_point(pts[0], cx - d2, cy + d);
+ viconutil_set_point(pts[1], cx - d2, cy - d);
+ viconutil_set_point(pts[2], cx + d2, cy);
+
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4f(0.2f, 0.2f, 0.2f, alpha);
+
+ immBegin(GPU_PRIM_TRIS, 3);
+ immVertex2iv(pos, pts[0]);
+ immVertex2iv(pos, pts[1]);
+ immVertex2iv(pos, pts[2]);
+ immEnd();
+
+ immUnbindProgram();
+}
+
+static void vicon_keytype_draw_wrapper(
+ int x, int y, int w, int h, float alpha, short key_type, short handle_type)
+{
+ /* init dummy theme state for Action Editor - where these colors are defined
+ * (since we're doing this offscreen, free from any particular space_id)
+ */
+ struct bThemeState theme_state;
+
+ UI_Theme_Store(&theme_state);
+ UI_SetTheme(SPACE_ACTION, RGN_TYPE_WINDOW);
+
+ /* the "x" and "y" given are the bottom-left coordinates of the icon,
+ * while the draw_keyframe_shape() function needs the midpoint for
+ * the keyframe
+ */
+ float xco = x + w / 2 + 0.5f;
+ float yco = y + h / 2 + 0.5f;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(
+ format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint outline_color_id = GPU_vertformat_attr_add(
+ format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
+
+ immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
+ GPU_enable_program_point_size();
+ immUniform2f("ViewportSize", -1.0f, -1.0f);
+ immBegin(GPU_PRIM_POINTS, 1);
+
+ /* draw keyframe
+ * - size: (default icon size == 16, default dopesheet icon size == 10)
+ * - sel: true unless in handletype icons (so that "keyframe" state shows the iconic yellow icon)
+ */
+ bool sel = (handle_type == KEYFRAME_HANDLE_NONE);
+
+ draw_keyframe_shape(xco,
+ yco,
+ (10.0f / 16.0f) * h,
+ sel,
+ key_type,
+ KEYFRAME_SHAPE_BOTH,
+ alpha,
+ pos_id,
+ size_id,
+ color_id,
+ outline_color_id,
+ flags_id,
+ handle_type,
+ KEYFRAME_EXTREME_NONE);
+
+ immEnd();
+ GPU_disable_program_point_size();
+ immUnbindProgram();
+
+ UI_Theme_Restore(&theme_state);
}
static void vicon_keytype_keyframe_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_NONE);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_NONE);
}
static void vicon_keytype_breakdown_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_BREAKDOWN, KEYFRAME_HANDLE_NONE);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_BREAKDOWN, KEYFRAME_HANDLE_NONE);
}
static void vicon_keytype_extreme_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_EXTREME, KEYFRAME_HANDLE_NONE);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_EXTREME, KEYFRAME_HANDLE_NONE);
}
static void vicon_keytype_jitter_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_JITTER, KEYFRAME_HANDLE_NONE);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_JITTER, KEYFRAME_HANDLE_NONE);
}
static void vicon_keytype_moving_hold_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_MOVEHOLD, KEYFRAME_HANDLE_NONE);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_MOVEHOLD, KEYFRAME_HANDLE_NONE);
}
static void vicon_handletype_free_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_FREE);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_FREE);
}
static void vicon_handletype_aligned_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_ALIGNED);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_ALIGNED);
}
static void vicon_handletype_vector_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_VECTOR);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_VECTOR);
}
static void vicon_handletype_auto_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_AUTO);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_AUTO);
}
static void vicon_handletype_auto_clamp_draw(int x, int y, int w, int h, float alpha)
{
- vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_AUTO_CLAMP);
+ vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_AUTO_CLAMP);
}
static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNUSED(alpha))
{
- bTheme *btheme = UI_GetTheme();
- ThemeWireColor *cs = &btheme->tarm[index];
+ bTheme *btheme = UI_GetTheme();
+ ThemeWireColor *cs = &btheme->tarm[index];
- /* Draw three bands of color: One per color
- * x-----a-----b-----c
- * | N | S | A |
- * x-----a-----b-----c
- */
- const int a = x + w / 3;
- const int b = x + w / 3 * 2;
- const int c = x + w;
+ /* Draw three bands of color: One per color
+ * x-----a-----b-----c
+ * | N | S | A |
+ * x-----a-----b-----c
+ */
+ const int a = x + w / 3;
+ const int b = x + w / 3 * 2;
+ const int c = x + w;
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* XXX: Include alpha into this... */
- /* normal */
- immUniformColor3ubv((uchar *)cs->solid);
- immRecti(pos, x, y, a, y + h);
+ /* XXX: Include alpha into this... */
+ /* normal */
+ immUniformColor3ubv((uchar *)cs->solid);
+ immRecti(pos, x, y, a, y + h);
- /* selected */
- immUniformColor3ubv((uchar *)cs->select);
- immRecti(pos, a, y, b, y + h);
+ /* selected */
+ immUniformColor3ubv((uchar *)cs->select);
+ immRecti(pos, a, y, b, y + h);
- /* active */
- immUniformColor3ubv((uchar *)cs->active);
- immRecti(pos, b, y, c, y + h);
+ /* active */
+ immUniformColor3ubv((uchar *)cs->active);
+ immRecti(pos, b, y, c, y + h);
- immUnbindProgram();
+ immUnbindProgram();
}
-#define DEF_ICON_VECTOR_COLORSET_DRAW_NTH(prefix, index) \
- static void vicon_colorset_draw_##prefix(int x, int y, int w, int h, float alpha) \
- { \
- vicon_colorset_draw(index, x, y, w, h, alpha); \
- }
+# define DEF_ICON_VECTOR_COLORSET_DRAW_NTH(prefix, index) \
+ static void vicon_colorset_draw_##prefix(int x, int y, int w, int h, float alpha) \
+ { \
+ vicon_colorset_draw(index, x, y, w, h, alpha); \
+ }
DEF_ICON_VECTOR_COLORSET_DRAW_NTH(01, 0)
DEF_ICON_VECTOR_COLORSET_DRAW_NTH(02, 1)
@@ -438,7 +456,7 @@ DEF_ICON_VECTOR_COLORSET_DRAW_NTH(18, 17)
DEF_ICON_VECTOR_COLORSET_DRAW_NTH(19, 18)
DEF_ICON_VECTOR_COLORSET_DRAW_NTH(20, 19)
-#undef DEF_ICON_VECTOR_COLORSET_DRAW_NTH
+# undef DEF_ICON_VECTOR_COLORSET_DRAW_NTH
/* Dynamically render icon instead of rendering a plain color to a texture/buffer
* This is mot strictly a "vicon", as it needs access to icon->obj to get the color info,
@@ -446,526 +464,559 @@ DEF_ICON_VECTOR_COLORSET_DRAW_NTH(20, 19)
*/
static void vicon_gplayer_color_draw(Icon *icon, int x, int y, int w, int h)
{
- bGPDlayer *gpl = (bGPDlayer *)icon->obj;
+ bGPDlayer *gpl = (bGPDlayer *)icon->obj;
- /* Just draw a colored rect - Like for vicon_colorset_draw() */
- /* TODO: Make this have rounded corners, and maybe be a bit smaller.
- * However, UI_draw_roundbox_aa() draws the colors too dark, so can't be used.
- */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ /* Just draw a colored rect - Like for vicon_colorset_draw() */
+ /* TODO: Make this have rounded corners, and maybe be a bit smaller.
+ * However, UI_draw_roundbox_aa() draws the colors too dark, so can't be used.
+ */
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3fv(gpl->color);
- immRecti(pos, x, y, x + w - 1, y + h - 1);
+ immUniformColor3fv(gpl->color);
+ immRecti(pos, x, y, x + w - 1, y + h - 1);
- immUnbindProgram();
+ immUnbindProgram();
}
-
-#ifndef WITH_HEADLESS
+# ifndef WITH_HEADLESS
static void init_brush_icons(void)
{
-#define INIT_BRUSH_ICON(icon_id, name) \
- { \
- uchar *rect = (uchar *)datatoc_ ##name## _png; \
- int size = datatoc_ ##name## _png_size; \
- DrawInfo *di; \
- \
- di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER, 0); \
- di->data.buffer.image->datatoc_rect = rect; \
- di->data.buffer.image->datatoc_size = size; \
- } ((void)0)
- /* end INIT_BRUSH_ICON */
-
- const int w = 96; /* warning, brush size hardcoded in C, but it gets scaled */
-
- INIT_BRUSH_ICON(ICON_BRUSH_BLOB, blob);
- INIT_BRUSH_ICON(ICON_BRUSH_BLUR, blur);
- INIT_BRUSH_ICON(ICON_BRUSH_CLAY, clay);
- INIT_BRUSH_ICON(ICON_BRUSH_CLAY_STRIPS, claystrips);
- INIT_BRUSH_ICON(ICON_BRUSH_CLONE, clone);
- INIT_BRUSH_ICON(ICON_BRUSH_CREASE, crease);
- INIT_BRUSH_ICON(ICON_BRUSH_SCULPT_DRAW, draw);
- INIT_BRUSH_ICON(ICON_BRUSH_FILL, fill);
- INIT_BRUSH_ICON(ICON_BRUSH_FLATTEN, flatten);
- INIT_BRUSH_ICON(ICON_BRUSH_GRAB, grab);
- INIT_BRUSH_ICON(ICON_BRUSH_INFLATE, inflate);
- INIT_BRUSH_ICON(ICON_BRUSH_LAYER, layer);
- INIT_BRUSH_ICON(ICON_BRUSH_MASK, mask);
- INIT_BRUSH_ICON(ICON_BRUSH_MIX, mix);
- INIT_BRUSH_ICON(ICON_BRUSH_NUDGE, nudge);
- INIT_BRUSH_ICON(ICON_BRUSH_PINCH, pinch);
- INIT_BRUSH_ICON(ICON_BRUSH_SCRAPE, scrape);
- INIT_BRUSH_ICON(ICON_BRUSH_SMEAR, smear);
- INIT_BRUSH_ICON(ICON_BRUSH_SMOOTH, smooth);
- INIT_BRUSH_ICON(ICON_BRUSH_SNAKE_HOOK, snake_hook);
- INIT_BRUSH_ICON(ICON_BRUSH_SOFTEN, soften);
- INIT_BRUSH_ICON(ICON_BRUSH_TEXDRAW, texdraw);
- INIT_BRUSH_ICON(ICON_BRUSH_TEXFILL, texfill);
- INIT_BRUSH_ICON(ICON_BRUSH_TEXMASK, texmask);
- INIT_BRUSH_ICON(ICON_BRUSH_THUMB, thumb);
- INIT_BRUSH_ICON(ICON_BRUSH_ROTATE, twist);
-
- /* grease pencil sculpt */
- INIT_BRUSH_ICON(ICON_GPBRUSH_SMOOTH, gp_brush_smooth);
- INIT_BRUSH_ICON(ICON_GPBRUSH_THICKNESS, gp_brush_thickness);
- INIT_BRUSH_ICON(ICON_GPBRUSH_STRENGTH, gp_brush_strength);
- INIT_BRUSH_ICON(ICON_GPBRUSH_GRAB, gp_brush_grab);
- INIT_BRUSH_ICON(ICON_GPBRUSH_PUSH, gp_brush_push);
- INIT_BRUSH_ICON(ICON_GPBRUSH_TWIST, gp_brush_twist);
- INIT_BRUSH_ICON(ICON_GPBRUSH_PINCH, gp_brush_pinch);
- INIT_BRUSH_ICON(ICON_GPBRUSH_RANDOMIZE, gp_brush_randomize);
- INIT_BRUSH_ICON(ICON_GPBRUSH_CLONE, gp_brush_clone);
- INIT_BRUSH_ICON(ICON_GPBRUSH_WEIGHT, gp_brush_weight);
-
- /* grease pencil drawing brushes */
- INIT_BRUSH_ICON(ICON_GPBRUSH_PENCIL, gp_brush_pencil);
- INIT_BRUSH_ICON(ICON_GPBRUSH_PEN, gp_brush_pen);
- INIT_BRUSH_ICON(ICON_GPBRUSH_INK, gp_brush_ink);
- INIT_BRUSH_ICON(ICON_GPBRUSH_INKNOISE, gp_brush_inknoise);
- INIT_BRUSH_ICON(ICON_GPBRUSH_BLOCK, gp_brush_block);
- INIT_BRUSH_ICON(ICON_GPBRUSH_MARKER, gp_brush_marker);
- INIT_BRUSH_ICON(ICON_GPBRUSH_FILL, gp_brush_fill);
- INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_SOFT, gp_brush_erase_soft);
- INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_HARD, gp_brush_erase_hard);
- INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_STROKE, gp_brush_erase_stroke);
-
-#undef INIT_BRUSH_ICON
+# define INIT_BRUSH_ICON(icon_id, name) \
+ { \
+ uchar *rect = (uchar *)datatoc_##name##_png; \
+ int size = datatoc_##name##_png_size; \
+ DrawInfo *di; \
+\
+ di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER, 0); \
+ di->data.buffer.image->datatoc_rect = rect; \
+ di->data.buffer.image->datatoc_size = size; \
+ } \
+ ((void)0)
+ /* end INIT_BRUSH_ICON */
+
+ const int w = 96; /* warning, brush size hardcoded in C, but it gets scaled */
+
+ INIT_BRUSH_ICON(ICON_BRUSH_BLOB, blob);
+ INIT_BRUSH_ICON(ICON_BRUSH_BLUR, blur);
+ INIT_BRUSH_ICON(ICON_BRUSH_CLAY, clay);
+ INIT_BRUSH_ICON(ICON_BRUSH_CLAY_STRIPS, claystrips);
+ INIT_BRUSH_ICON(ICON_BRUSH_CLONE, clone);
+ INIT_BRUSH_ICON(ICON_BRUSH_CREASE, crease);
+ INIT_BRUSH_ICON(ICON_BRUSH_SCULPT_DRAW, draw);
+ INIT_BRUSH_ICON(ICON_BRUSH_FILL, fill);
+ INIT_BRUSH_ICON(ICON_BRUSH_FLATTEN, flatten);
+ INIT_BRUSH_ICON(ICON_BRUSH_GRAB, grab);
+ INIT_BRUSH_ICON(ICON_BRUSH_INFLATE, inflate);
+ INIT_BRUSH_ICON(ICON_BRUSH_LAYER, layer);
+ INIT_BRUSH_ICON(ICON_BRUSH_MASK, mask);
+ INIT_BRUSH_ICON(ICON_BRUSH_MIX, mix);
+ INIT_BRUSH_ICON(ICON_BRUSH_NUDGE, nudge);
+ INIT_BRUSH_ICON(ICON_BRUSH_PINCH, pinch);
+ INIT_BRUSH_ICON(ICON_BRUSH_SCRAPE, scrape);
+ INIT_BRUSH_ICON(ICON_BRUSH_SMEAR, smear);
+ INIT_BRUSH_ICON(ICON_BRUSH_SMOOTH, smooth);
+ INIT_BRUSH_ICON(ICON_BRUSH_SNAKE_HOOK, snake_hook);
+ INIT_BRUSH_ICON(ICON_BRUSH_SOFTEN, soften);
+ INIT_BRUSH_ICON(ICON_BRUSH_TEXDRAW, texdraw);
+ INIT_BRUSH_ICON(ICON_BRUSH_TEXFILL, texfill);
+ INIT_BRUSH_ICON(ICON_BRUSH_TEXMASK, texmask);
+ INIT_BRUSH_ICON(ICON_BRUSH_THUMB, thumb);
+ INIT_BRUSH_ICON(ICON_BRUSH_ROTATE, twist);
+
+ /* grease pencil sculpt */
+ INIT_BRUSH_ICON(ICON_GPBRUSH_SMOOTH, gp_brush_smooth);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_THICKNESS, gp_brush_thickness);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_STRENGTH, gp_brush_strength);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_GRAB, gp_brush_grab);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PUSH, gp_brush_push);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_TWIST, gp_brush_twist);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PINCH, gp_brush_pinch);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_RANDOMIZE, gp_brush_randomize);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_CLONE, gp_brush_clone);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_WEIGHT, gp_brush_weight);
+
+ /* grease pencil drawing brushes */
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PENCIL, gp_brush_pencil);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_PEN, gp_brush_pen);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_INK, gp_brush_ink);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_INKNOISE, gp_brush_inknoise);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_BLOCK, gp_brush_block);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_MARKER, gp_brush_marker);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_FILL, gp_brush_fill);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_SOFT, gp_brush_erase_soft);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_HARD, gp_brush_erase_hard);
+ INIT_BRUSH_ICON(ICON_GPBRUSH_ERASE_STROKE, gp_brush_erase_stroke);
+
+# undef INIT_BRUSH_ICON
}
static DrawInfo *g_di_event_list = NULL;
int UI_icon_from_event_type(short event_type, short event_value)
{
- if (event_type == RIGHTSHIFTKEY) {
- event_type = LEFTSHIFTKEY;
- }
- else if (event_type == RIGHTCTRLKEY) {
- event_type = LEFTCTRLKEY;
- }
- else if (event_type == RIGHTALTKEY) {
- event_type = LEFTALTKEY;
- }
- else if (event_type == EVT_TWEAK_L) {
- event_type = LEFTMOUSE;
- event_value = KM_CLICK_DRAG;
- }
- else if (event_type == EVT_TWEAK_M) {
- event_type = MIDDLEMOUSE;
- event_value = KM_CLICK_DRAG;
- }
- else if (event_type == EVT_TWEAK_R) {
- event_type = RIGHTMOUSE;
- event_value = KM_CLICK_DRAG;
- }
-
- DrawInfo *di = g_di_event_list;
- do {
- if (di->data.input.event_type == event_type) {
- return di->data.input.icon;
- }
- } while ((di = di->data.input.next));
-
- if (event_type == LEFTMOUSE) {
- return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_LMB : ICON_MOUSE_LMB_DRAG;
- }
- else if (event_type == MIDDLEMOUSE) {
- return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_MMB : ICON_MOUSE_MMB_DRAG;
- }
- else if (event_type == RIGHTMOUSE) {
- return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_RMB : ICON_MOUSE_RMB_DRAG;
- }
-
- return ICON_NONE;
+ if (event_type == RIGHTSHIFTKEY) {
+ event_type = LEFTSHIFTKEY;
+ }
+ else if (event_type == RIGHTCTRLKEY) {
+ event_type = LEFTCTRLKEY;
+ }
+ else if (event_type == RIGHTALTKEY) {
+ event_type = LEFTALTKEY;
+ }
+ else if (event_type == EVT_TWEAK_L) {
+ event_type = LEFTMOUSE;
+ event_value = KM_CLICK_DRAG;
+ }
+ else if (event_type == EVT_TWEAK_M) {
+ event_type = MIDDLEMOUSE;
+ event_value = KM_CLICK_DRAG;
+ }
+ else if (event_type == EVT_TWEAK_R) {
+ event_type = RIGHTMOUSE;
+ event_value = KM_CLICK_DRAG;
+ }
+
+ DrawInfo *di = g_di_event_list;
+ do {
+ if (di->data.input.event_type == event_type) {
+ return di->data.input.icon;
+ }
+ } while ((di = di->data.input.next));
+
+ if (event_type == LEFTMOUSE) {
+ return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_LMB : ICON_MOUSE_LMB_DRAG;
+ }
+ else if (event_type == MIDDLEMOUSE) {
+ return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_MMB : ICON_MOUSE_MMB_DRAG;
+ }
+ else if (event_type == RIGHTMOUSE) {
+ return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_RMB : ICON_MOUSE_RMB_DRAG;
+ }
+
+ return ICON_NONE;
}
int UI_icon_from_keymap_item(const wmKeyMapItem *kmi, int r_icon_mod[4])
{
- if (r_icon_mod) {
- memset(r_icon_mod, 0x0, sizeof(int[4]));
- int i = 0;
- if (!ELEM(kmi->ctrl, KM_NOTHING, KM_ANY)) {
- r_icon_mod[i++] = ICON_EVENT_CTRL;
- }
- if (!ELEM(kmi->alt, KM_NOTHING, KM_ANY)) {
- r_icon_mod[i++] = ICON_EVENT_ALT;
- }
- if (!ELEM(kmi->shift, KM_NOTHING, KM_ANY)) {
- r_icon_mod[i++] = ICON_EVENT_SHIFT;
- }
- if (!ELEM(kmi->oskey, KM_NOTHING, KM_ANY)) {
- r_icon_mod[i++] = ICON_EVENT_OS;
- }
- }
- return UI_icon_from_event_type(kmi->type, kmi->val);
+ if (r_icon_mod) {
+ memset(r_icon_mod, 0x0, sizeof(int[4]));
+ int i = 0;
+ if (!ELEM(kmi->ctrl, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_CTRL;
+ }
+ if (!ELEM(kmi->alt, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_ALT;
+ }
+ if (!ELEM(kmi->shift, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_SHIFT;
+ }
+ if (!ELEM(kmi->oskey, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_OS;
+ }
+ }
+ return UI_icon_from_event_type(kmi->type, kmi->val);
}
static void init_event_icons(void)
{
- DrawInfo *di_next = NULL;
-
-#define INIT_EVENT_ICON(icon_id, type, value) \
- { \
- DrawInfo *di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_EVENT, 0); \
- di->data.input.event_type = type; \
- di->data.input.event_value = value; \
- di->data.input.icon = icon_id; \
- di->data.input.next = di_next; \
- di_next = di; \
- } ((void)0)
- /* end INIT_EVENT_ICON */
-
- const int w = 16; /* DUMMY */
-
- INIT_EVENT_ICON(ICON_EVENT_A, AKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_B, BKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_C, CKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_D, DKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_E, EKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F, FKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_G, GKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_H, HKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_I, IKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_J, JKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_K, KKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_L, LKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_M, MKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_N, NKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_O, OKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_P, PKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_Q, QKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_R, RKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_S, SKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_T, TKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_U, UKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_V, VKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_W, WKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_X, XKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_Y, YKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_Z, ZKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_SHIFT, LEFTSHIFTKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_CTRL, LEFTCTRLKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_ALT, LEFTALTKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_OS, OSKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F1, F1KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F2, F2KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F3, F3KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F4, F4KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F5, F5KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F6, F6KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F7, F7KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F8, F8KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F9, F9KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F10, F10KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F11, F11KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_F12, F12KEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_ESC, ESCKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_TAB, TABKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_PAGEUP, PAGEUPKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_PAGEDOWN, PAGEDOWNKEY, KM_ANY);
- INIT_EVENT_ICON(ICON_EVENT_RETURN, RETKEY, KM_ANY);
-
- g_di_event_list = di_next;
-
-#undef INIT_EVENT_ICON
+ DrawInfo *di_next = NULL;
+
+# define INIT_EVENT_ICON(icon_id, type, value) \
+ { \
+ DrawInfo *di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_EVENT, 0); \
+ di->data.input.event_type = type; \
+ di->data.input.event_value = value; \
+ di->data.input.icon = icon_id; \
+ di->data.input.next = di_next; \
+ di_next = di; \
+ } \
+ ((void)0)
+ /* end INIT_EVENT_ICON */
+
+ const int w = 16; /* DUMMY */
+
+ INIT_EVENT_ICON(ICON_EVENT_A, AKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_B, BKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_C, CKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_D, DKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_E, EKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F, FKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_G, GKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_H, HKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_I, IKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_J, JKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_K, KKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_L, LKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_M, MKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_N, NKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_O, OKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_P, PKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_Q, QKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_R, RKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_S, SKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_T, TKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_U, UKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_V, VKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_W, WKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_X, XKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_Y, YKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_Z, ZKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_SHIFT, LEFTSHIFTKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_CTRL, LEFTCTRLKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_ALT, LEFTALTKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_OS, OSKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F1, F1KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F2, F2KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F3, F3KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F4, F4KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F5, F5KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F6, F6KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F7, F7KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F8, F8KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F9, F9KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F10, F10KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F11, F11KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F12, F12KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_ESC, ESCKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_TAB, TABKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_PAGEUP, PAGEUPKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_PAGEDOWN, PAGEDOWNKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_RETURN, RETKEY, KM_ANY);
+
+ g_di_event_list = di_next;
+
+# undef INIT_EVENT_ICON
}
static void icon_verify_datatoc(IconImage *iimg)
{
- /* if it has own rect, things are all OK */
- if (iimg->rect) {
- return;
- }
+ /* if it has own rect, things are all OK */
+ if (iimg->rect) {
+ return;
+ }
- if (iimg->datatoc_rect) {
- ImBuf *bbuf = IMB_ibImageFromMemory(iimg->datatoc_rect,
- iimg->datatoc_size, IB_rect, NULL, "<matcap icon>");
- /* w and h were set on initialize */
- if (bbuf->x != iimg->h && bbuf->y != iimg->w) {
- IMB_scaleImBuf(bbuf, iimg->w, iimg->h);
- }
+ if (iimg->datatoc_rect) {
+ ImBuf *bbuf = IMB_ibImageFromMemory(
+ iimg->datatoc_rect, iimg->datatoc_size, IB_rect, NULL, "<matcap icon>");
+ /* w and h were set on initialize */
+ if (bbuf->x != iimg->h && bbuf->y != iimg->w) {
+ IMB_scaleImBuf(bbuf, iimg->w, iimg->h);
+ }
- iimg->rect = bbuf->rect;
- bbuf->rect = NULL;
- IMB_freeImBuf(bbuf);
- }
+ iimg->rect = bbuf->rect;
+ bbuf->rect = NULL;
+ IMB_freeImBuf(bbuf);
+ }
}
static void init_internal_icons(void)
{
-// bTheme *btheme = UI_GetTheme();
- ImBuf *b16buf = NULL, *b32buf = NULL;
- int x, y;
-
-#if 0 // temp disabled
- if ((btheme != NULL) && btheme->tui.iconfile[0]) {
- char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
- char iconfilestr[FILE_MAX];
-
- if (icondir) {
- BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
-
- /* if the image is missing bbuf will just be NULL */
- bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL);
-
- if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) {
- printf("\n***WARNING***\nIcons file %s too small.\nUsing built-in Icons instead\n", iconfilestr);
- IMB_freeImBuf(bbuf);
- bbuf = NULL;
- }
- }
- else {
- printf("%s: 'icons' data path not found, continuing\n", __func__);
- }
- }
-#endif
- if (b16buf == NULL) {
- b16buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons16_png,
- datatoc_blender_icons16_png_size, IB_rect, NULL, "<blender icons>");
- }
- if (b16buf) {
- IMB_premultiply_alpha(b16buf);
- }
-
- if (b32buf == NULL) {
- b32buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons32_png,
- datatoc_blender_icons32_png_size, IB_rect, NULL, "<blender icons>");
- }
- if (b32buf) {
- IMB_premultiply_alpha(b32buf);
- }
-
- if (b16buf && b32buf) {
- /* Free existing texture if any. */
- if (icongltex.id) {
- glDeleteTextures(1, &icongltex.id);
- icongltex.id = 0;
- }
-
- /* Allocate OpenGL texture. */
- glGenTextures(1, &icongltex.id);
-
- if (icongltex.id) {
- int level = 2;
-
- icongltex.w = b32buf->x;
- icongltex.h = b32buf->y;
- icongltex.invw = 1.0f / b32buf->x;
- icongltex.invh = 1.0f / b32buf->y;
-
- glBindTexture(GL_TEXTURE_2D, icongltex.id);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, b32buf->x, b32buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b32buf->rect);
- glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, b16buf->x, b16buf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, b16buf->rect);
-
- while (b16buf->x > 1) {
- ImBuf *nbuf = IMB_onehalf(b16buf);
- glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, nbuf->x, nbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nbuf->rect);
- level++;
- IMB_freeImBuf(b16buf);
- b16buf = nbuf;
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-
- /* Define icons. */
- for (y = 0; y < ICON_GRID_ROWS; y++) {
- /* Row W has monochrome icons. */
- for (x = 0; x < ICON_GRID_COLS; x++) {
- IconType icontype = icontypes[y * ICON_GRID_COLS + x];
- if (!ELEM(icontype.type, ICON_TYPE_COLOR_TEXTURE, ICON_TYPE_MONO_TEXTURE)) {
- continue;
- }
-
- def_internal_icon(b32buf, BIFICONID_FIRST + y * ICON_GRID_COLS + x,
- x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
- y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, ICON_GRID_W,
- icontype.type, icontype.theme_color);
- }
- }
- }
-
- def_internal_vicon(ICON_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw);
-
- def_internal_vicon(ICON_KEYTYPE_KEYFRAME_VEC, vicon_keytype_keyframe_draw);
- def_internal_vicon(ICON_KEYTYPE_BREAKDOWN_VEC, vicon_keytype_breakdown_draw);
- def_internal_vicon(ICON_KEYTYPE_EXTREME_VEC, vicon_keytype_extreme_draw);
- def_internal_vicon(ICON_KEYTYPE_JITTER_VEC, vicon_keytype_jitter_draw);
- def_internal_vicon(ICON_KEYTYPE_MOVING_HOLD_VEC, vicon_keytype_moving_hold_draw);
-
- def_internal_vicon(ICON_HANDLETYPE_FREE_VEC, vicon_handletype_free_draw);
- def_internal_vicon(ICON_HANDLETYPE_ALIGNED_VEC, vicon_handletype_aligned_draw);
- def_internal_vicon(ICON_HANDLETYPE_VECTOR_VEC, vicon_handletype_vector_draw);
- def_internal_vicon(ICON_HANDLETYPE_AUTO_VEC, vicon_handletype_auto_draw);
- def_internal_vicon(ICON_HANDLETYPE_AUTO_CLAMP_VEC, vicon_handletype_auto_clamp_draw);
-
- def_internal_vicon(ICON_COLORSET_01_VEC, vicon_colorset_draw_01);
- def_internal_vicon(ICON_COLORSET_02_VEC, vicon_colorset_draw_02);
- def_internal_vicon(ICON_COLORSET_03_VEC, vicon_colorset_draw_03);
- def_internal_vicon(ICON_COLORSET_04_VEC, vicon_colorset_draw_04);
- def_internal_vicon(ICON_COLORSET_05_VEC, vicon_colorset_draw_05);
- def_internal_vicon(ICON_COLORSET_06_VEC, vicon_colorset_draw_06);
- def_internal_vicon(ICON_COLORSET_07_VEC, vicon_colorset_draw_07);
- def_internal_vicon(ICON_COLORSET_08_VEC, vicon_colorset_draw_08);
- def_internal_vicon(ICON_COLORSET_09_VEC, vicon_colorset_draw_09);
- def_internal_vicon(ICON_COLORSET_10_VEC, vicon_colorset_draw_10);
- def_internal_vicon(ICON_COLORSET_11_VEC, vicon_colorset_draw_11);
- def_internal_vicon(ICON_COLORSET_12_VEC, vicon_colorset_draw_12);
- def_internal_vicon(ICON_COLORSET_13_VEC, vicon_colorset_draw_13);
- def_internal_vicon(ICON_COLORSET_14_VEC, vicon_colorset_draw_14);
- def_internal_vicon(ICON_COLORSET_15_VEC, vicon_colorset_draw_15);
- def_internal_vicon(ICON_COLORSET_16_VEC, vicon_colorset_draw_16);
- def_internal_vicon(ICON_COLORSET_17_VEC, vicon_colorset_draw_17);
- def_internal_vicon(ICON_COLORSET_18_VEC, vicon_colorset_draw_18);
- def_internal_vicon(ICON_COLORSET_19_VEC, vicon_colorset_draw_19);
- def_internal_vicon(ICON_COLORSET_20_VEC, vicon_colorset_draw_20);
-
- IMB_freeImBuf(b16buf);
- IMB_freeImBuf(b32buf);
-
-}
-#endif /* WITH_HEADLESS */
+ // bTheme *btheme = UI_GetTheme();
+ ImBuf *b16buf = NULL, *b32buf = NULL;
+ int x, y;
+
+# if 0 // temp disabled
+ if ((btheme != NULL) && btheme->tui.iconfile[0]) {
+ char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
+ char iconfilestr[FILE_MAX];
+
+ if (icondir) {
+ BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
+
+ /* if the image is missing bbuf will just be NULL */
+ bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL);
+
+ if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) {
+ printf("\n***WARNING***\nIcons file %s too small.\nUsing built-in Icons instead\n", iconfilestr);
+ IMB_freeImBuf(bbuf);
+ bbuf = NULL;
+ }
+ }
+ else {
+ printf("%s: 'icons' data path not found, continuing\n", __func__);
+ }
+ }
+# endif
+ if (b16buf == NULL) {
+ b16buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons16_png,
+ datatoc_blender_icons16_png_size,
+ IB_rect,
+ NULL,
+ "<blender icons>");
+ }
+ if (b16buf) {
+ IMB_premultiply_alpha(b16buf);
+ }
+
+ if (b32buf == NULL) {
+ b32buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons32_png,
+ datatoc_blender_icons32_png_size,
+ IB_rect,
+ NULL,
+ "<blender icons>");
+ }
+ if (b32buf) {
+ IMB_premultiply_alpha(b32buf);
+ }
+
+ if (b16buf && b32buf) {
+ /* Free existing texture if any. */
+ if (icongltex.id) {
+ glDeleteTextures(1, &icongltex.id);
+ icongltex.id = 0;
+ }
+
+ /* Allocate OpenGL texture. */
+ glGenTextures(1, &icongltex.id);
+
+ if (icongltex.id) {
+ int level = 2;
+
+ icongltex.w = b32buf->x;
+ icongltex.h = b32buf->y;
+ icongltex.invw = 1.0f / b32buf->x;
+ icongltex.invh = 1.0f / b32buf->y;
+
+ glBindTexture(GL_TEXTURE_2D, icongltex.id);
+
+ glTexImage2D(GL_TEXTURE_2D,
+ 0,
+ GL_RGBA8,
+ b32buf->x,
+ b32buf->y,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ b32buf->rect);
+ glTexImage2D(GL_TEXTURE_2D,
+ 1,
+ GL_RGBA8,
+ b16buf->x,
+ b16buf->y,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ b16buf->rect);
+
+ while (b16buf->x > 1) {
+ ImBuf *nbuf = IMB_onehalf(b16buf);
+ glTexImage2D(GL_TEXTURE_2D,
+ level,
+ GL_RGBA8,
+ nbuf->x,
+ nbuf->y,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ nbuf->rect);
+ level++;
+ IMB_freeImBuf(b16buf);
+ b16buf = nbuf;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ /* Define icons. */
+ for (y = 0; y < ICON_GRID_ROWS; y++) {
+ /* Row W has monochrome icons. */
+ for (x = 0; x < ICON_GRID_COLS; x++) {
+ IconType icontype = icontypes[y * ICON_GRID_COLS + x];
+ if (!ELEM(icontype.type, ICON_TYPE_COLOR_TEXTURE, ICON_TYPE_MONO_TEXTURE)) {
+ continue;
+ }
+
+ def_internal_icon(b32buf,
+ BIFICONID_FIRST + y * ICON_GRID_COLS + x,
+ x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
+ y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN,
+ ICON_GRID_W,
+ icontype.type,
+ icontype.theme_color);
+ }
+ }
+ }
+
+ def_internal_vicon(ICON_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw);
+
+ def_internal_vicon(ICON_KEYTYPE_KEYFRAME_VEC, vicon_keytype_keyframe_draw);
+ def_internal_vicon(ICON_KEYTYPE_BREAKDOWN_VEC, vicon_keytype_breakdown_draw);
+ def_internal_vicon(ICON_KEYTYPE_EXTREME_VEC, vicon_keytype_extreme_draw);
+ def_internal_vicon(ICON_KEYTYPE_JITTER_VEC, vicon_keytype_jitter_draw);
+ def_internal_vicon(ICON_KEYTYPE_MOVING_HOLD_VEC, vicon_keytype_moving_hold_draw);
+
+ def_internal_vicon(ICON_HANDLETYPE_FREE_VEC, vicon_handletype_free_draw);
+ def_internal_vicon(ICON_HANDLETYPE_ALIGNED_VEC, vicon_handletype_aligned_draw);
+ def_internal_vicon(ICON_HANDLETYPE_VECTOR_VEC, vicon_handletype_vector_draw);
+ def_internal_vicon(ICON_HANDLETYPE_AUTO_VEC, vicon_handletype_auto_draw);
+ def_internal_vicon(ICON_HANDLETYPE_AUTO_CLAMP_VEC, vicon_handletype_auto_clamp_draw);
+
+ def_internal_vicon(ICON_COLORSET_01_VEC, vicon_colorset_draw_01);
+ def_internal_vicon(ICON_COLORSET_02_VEC, vicon_colorset_draw_02);
+ def_internal_vicon(ICON_COLORSET_03_VEC, vicon_colorset_draw_03);
+ def_internal_vicon(ICON_COLORSET_04_VEC, vicon_colorset_draw_04);
+ def_internal_vicon(ICON_COLORSET_05_VEC, vicon_colorset_draw_05);
+ def_internal_vicon(ICON_COLORSET_06_VEC, vicon_colorset_draw_06);
+ def_internal_vicon(ICON_COLORSET_07_VEC, vicon_colorset_draw_07);
+ def_internal_vicon(ICON_COLORSET_08_VEC, vicon_colorset_draw_08);
+ def_internal_vicon(ICON_COLORSET_09_VEC, vicon_colorset_draw_09);
+ def_internal_vicon(ICON_COLORSET_10_VEC, vicon_colorset_draw_10);
+ def_internal_vicon(ICON_COLORSET_11_VEC, vicon_colorset_draw_11);
+ def_internal_vicon(ICON_COLORSET_12_VEC, vicon_colorset_draw_12);
+ def_internal_vicon(ICON_COLORSET_13_VEC, vicon_colorset_draw_13);
+ def_internal_vicon(ICON_COLORSET_14_VEC, vicon_colorset_draw_14);
+ def_internal_vicon(ICON_COLORSET_15_VEC, vicon_colorset_draw_15);
+ def_internal_vicon(ICON_COLORSET_16_VEC, vicon_colorset_draw_16);
+ def_internal_vicon(ICON_COLORSET_17_VEC, vicon_colorset_draw_17);
+ def_internal_vicon(ICON_COLORSET_18_VEC, vicon_colorset_draw_18);
+ def_internal_vicon(ICON_COLORSET_19_VEC, vicon_colorset_draw_19);
+ def_internal_vicon(ICON_COLORSET_20_VEC, vicon_colorset_draw_20);
+
+ IMB_freeImBuf(b16buf);
+ IMB_freeImBuf(b32buf);
+}
+# endif /* WITH_HEADLESS */
static void init_iconfile_list(struct ListBase *list)
{
- IconFile *ifile;
- struct direntry *dir;
- int totfile, i, index = 1;
- const char *icondir;
-
- BLI_listbase_clear(list);
- icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
-
- if (icondir == NULL) {
- return;
- }
-
- totfile = BLI_filelist_dir_contents(icondir, &dir);
-
- for (i = 0; i < totfile; i++) {
- if ((dir[i].type & S_IFREG)) {
- const char *filename = dir[i].relname;
-
- if (BLI_path_extension_check(filename, ".png")) {
- /* loading all icons on file start is overkill & slows startup
- * its possible they change size after blender load anyway. */
-#if 0
- int ifilex, ifiley;
- char iconfilestr[FILE_MAX + 16]; /* allow 256 chars for file+dir */
- ImBuf *bbuf = NULL;
- /* check to see if the image is the right size, continue if not */
- /* copying strings here should go ok, assuming that we never get back
- * a complete path to file longer than 256 chars */
- BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, filename);
- bbuf = IMB_loadiffname(iconfilestr, IB_rect);
-
- if (bbuf) {
- ifilex = bbuf->x;
- ifiley = bbuf->y;
- IMB_freeImBuf(bbuf);
- }
- else {
- ifilex = ifiley = 0;
- }
-
- /* bad size or failed to load */
- if ((ifilex != ICON_IMAGE_W) || (ifiley != ICON_IMAGE_H)) {
- printf("icon '%s' is wrong size %dx%d\n", iconfilestr, ifilex, ifiley);
- continue;
- }
-#endif /* removed */
-
- /* found a potential icon file, so make an entry for it in the cache list */
- ifile = MEM_callocN(sizeof(IconFile), "IconFile");
-
- BLI_strncpy(ifile->filename, filename, sizeof(ifile->filename));
- ifile->index = index;
-
- BLI_addtail(list, ifile);
-
- index++;
- }
- }
- }
-
- BLI_filelist_free(dir, totfile);
- dir = NULL;
+ IconFile *ifile;
+ struct direntry *dir;
+ int totfile, i, index = 1;
+ const char *icondir;
+
+ BLI_listbase_clear(list);
+ icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
+
+ if (icondir == NULL) {
+ return;
+ }
+
+ totfile = BLI_filelist_dir_contents(icondir, &dir);
+
+ for (i = 0; i < totfile; i++) {
+ if ((dir[i].type & S_IFREG)) {
+ const char *filename = dir[i].relname;
+
+ if (BLI_path_extension_check(filename, ".png")) {
+ /* loading all icons on file start is overkill & slows startup
+ * its possible they change size after blender load anyway. */
+# if 0
+ int ifilex, ifiley;
+ char iconfilestr[FILE_MAX + 16]; /* allow 256 chars for file+dir */
+ ImBuf *bbuf = NULL;
+ /* check to see if the image is the right size, continue if not */
+ /* copying strings here should go ok, assuming that we never get back
+ * a complete path to file longer than 256 chars */
+ BLI_join_dirfile(iconfilestr, sizeof(iconfilestr), icondir, filename);
+ bbuf = IMB_loadiffname(iconfilestr, IB_rect);
+
+ if (bbuf) {
+ ifilex = bbuf->x;
+ ifiley = bbuf->y;
+ IMB_freeImBuf(bbuf);
+ }
+ else {
+ ifilex = ifiley = 0;
+ }
+
+ /* bad size or failed to load */
+ if ((ifilex != ICON_IMAGE_W) || (ifiley != ICON_IMAGE_H)) {
+ printf("icon '%s' is wrong size %dx%d\n", iconfilestr, ifilex, ifiley);
+ continue;
+ }
+# endif /* removed */
+
+ /* found a potential icon file, so make an entry for it in the cache list */
+ ifile = MEM_callocN(sizeof(IconFile), "IconFile");
+
+ BLI_strncpy(ifile->filename, filename, sizeof(ifile->filename));
+ ifile->index = index;
+
+ BLI_addtail(list, ifile);
+
+ index++;
+ }
+ }
+ }
+
+ BLI_filelist_free(dir, totfile);
+ dir = NULL;
}
static void free_iconfile_list(struct ListBase *list)
{
- IconFile *ifile = NULL, *next_ifile = NULL;
+ IconFile *ifile = NULL, *next_ifile = NULL;
- for (ifile = list->first; ifile; ifile = next_ifile) {
- next_ifile = ifile->next;
- BLI_freelinkN(list, ifile);
- }
+ for (ifile = list->first; ifile; ifile = next_ifile) {
+ next_ifile = ifile->next;
+ BLI_freelinkN(list, ifile);
+ }
}
-#endif /* WITH_HEADLESS */
+#endif /* WITH_HEADLESS */
int UI_iconfile_get_index(const char *filename)
{
- IconFile *ifile;
- ListBase *list = &(iconfilelist);
+ IconFile *ifile;
+ ListBase *list = &(iconfilelist);
- for (ifile = list->first; ifile; ifile = ifile->next) {
- if (BLI_path_cmp(filename, ifile->filename) == 0) {
- return ifile->index;
- }
- }
+ for (ifile = list->first; ifile; ifile = ifile->next) {
+ if (BLI_path_cmp(filename, ifile->filename) == 0) {
+ return ifile->index;
+ }
+ }
- return 0;
+ return 0;
}
ListBase *UI_iconfile_list(void)
{
- ListBase *list = &(iconfilelist);
+ ListBase *list = &(iconfilelist);
- return list;
+ return list;
}
-
void UI_icons_free(void)
{
#ifndef WITH_HEADLESS
- if (icongltex.id) {
- glDeleteTextures(1, &icongltex.id);
- icongltex.id = 0;
- }
+ if (icongltex.id) {
+ glDeleteTextures(1, &icongltex.id);
+ icongltex.id = 0;
+ }
- free_iconfile_list(&iconfilelist);
- BKE_icons_free();
+ free_iconfile_list(&iconfilelist);
+ BKE_icons_free();
#endif
}
void UI_icons_free_drawinfo(void *drawinfo)
{
- DrawInfo *di = drawinfo;
+ DrawInfo *di = drawinfo;
- if (di) {
- if (di->type == ICON_TYPE_BUFFER) {
- if (di->data.buffer.image) {
- if (di->data.buffer.image->rect) {
- MEM_freeN(di->data.buffer.image->rect);
- }
- MEM_freeN(di->data.buffer.image);
- }
- }
- else if (di->type == ICON_TYPE_GEOM) {
- if (di->data.geom.image_cache) {
- IMB_freeImBuf(di->data.geom.image_cache);
- }
- }
+ if (di) {
+ if (di->type == ICON_TYPE_BUFFER) {
+ if (di->data.buffer.image) {
+ if (di->data.buffer.image->rect) {
+ MEM_freeN(di->data.buffer.image->rect);
+ }
+ MEM_freeN(di->data.buffer.image);
+ }
+ }
+ else if (di->type == ICON_TYPE_GEOM) {
+ if (di->data.geom.image_cache) {
+ IMB_freeImBuf(di->data.geom.image_cache);
+ }
+ }
- MEM_freeN(di);
- }
+ MEM_freeN(di);
+ }
}
/**
@@ -973,89 +1024,89 @@ void UI_icons_free_drawinfo(void *drawinfo)
*/
static DrawInfo *icon_create_drawinfo(Icon *icon)
{
- int icon_data_type = icon->obj_type;
- DrawInfo *di = NULL;
+ int icon_data_type = icon->obj_type;
+ DrawInfo *di = NULL;
- di = MEM_callocN(sizeof(DrawInfo), "di_icon");
+ di = MEM_callocN(sizeof(DrawInfo), "di_icon");
- if (ELEM(icon_data_type, ICON_DATA_ID, ICON_DATA_PREVIEW)) {
- di->type = ICON_TYPE_PREVIEW;
- }
- else if (icon_data_type == ICON_DATA_GEOM) {
- di->type = ICON_TYPE_GEOM;
- }
- else if (icon_data_type == ICON_DATA_STUDIOLIGHT) {
- di->type = ICON_TYPE_BUFFER;
- }
- else if (icon_data_type == ICON_DATA_GPLAYER) {
- di->type = ICON_TYPE_GPLAYER;
- }
- else {
- BLI_assert(0);
- }
+ if (ELEM(icon_data_type, ICON_DATA_ID, ICON_DATA_PREVIEW)) {
+ di->type = ICON_TYPE_PREVIEW;
+ }
+ else if (icon_data_type == ICON_DATA_GEOM) {
+ di->type = ICON_TYPE_GEOM;
+ }
+ else if (icon_data_type == ICON_DATA_STUDIOLIGHT) {
+ di->type = ICON_TYPE_BUFFER;
+ }
+ else if (icon_data_type == ICON_DATA_GPLAYER) {
+ di->type = ICON_TYPE_GPLAYER;
+ }
+ else {
+ BLI_assert(0);
+ }
- return di;
+ return di;
}
static DrawInfo *icon_ensure_drawinfo(Icon *icon)
{
- if (icon->drawinfo) {
- return icon->drawinfo;
- }
- DrawInfo *di = icon_create_drawinfo(icon);
- icon->drawinfo = di;
- icon->drawinfo_free = UI_icons_free_drawinfo;
- return di;
+ if (icon->drawinfo) {
+ return icon->drawinfo;
+ }
+ DrawInfo *di = icon_create_drawinfo(icon);
+ icon->drawinfo = di;
+ icon->drawinfo_free = UI_icons_free_drawinfo;
+ return di;
}
/* note!, returns unscaled by DPI */
int UI_icon_get_width(int icon_id)
{
- Icon *icon = NULL;
- DrawInfo *di = NULL;
+ Icon *icon = NULL;
+ DrawInfo *di = NULL;
- icon = BKE_icon_get(icon_id);
+ icon = BKE_icon_get(icon_id);
- if (icon == NULL) {
- if (G.debug & G_DEBUG) {
- printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
- }
- return 0;
- }
+ if (icon == NULL) {
+ if (G.debug & G_DEBUG) {
+ printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
+ }
+ return 0;
+ }
- di = icon_ensure_drawinfo(icon);
- if (di) {
- return ICON_DEFAULT_WIDTH;
- }
+ di = icon_ensure_drawinfo(icon);
+ if (di) {
+ return ICON_DEFAULT_WIDTH;
+ }
- return 0;
+ return 0;
}
int UI_icon_get_height(int icon_id)
{
- Icon *icon = BKE_icon_get(icon_id);
- if (icon == NULL) {
- if (G.debug & G_DEBUG) {
- printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
- }
- return 0;
- }
+ Icon *icon = BKE_icon_get(icon_id);
+ if (icon == NULL) {
+ if (G.debug & G_DEBUG) {
+ printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
+ }
+ return 0;
+ }
- DrawInfo *di = icon_ensure_drawinfo(icon);
- if (di) {
- return ICON_DEFAULT_HEIGHT;
- }
+ DrawInfo *di = icon_ensure_drawinfo(icon);
+ if (di) {
+ return ICON_DEFAULT_HEIGHT;
+ }
- return 0;
+ return 0;
}
void UI_icons_init()
{
#ifndef WITH_HEADLESS
- init_iconfile_list(&iconfilelist);
- init_internal_icons();
- init_brush_icons();
- init_event_icons();
+ init_iconfile_list(&iconfilelist);
+ init_internal_icons();
+ init_brush_icons();
+ init_event_icons();
#endif
}
@@ -1063,281 +1114,312 @@ void UI_icons_init()
*/
int UI_preview_render_size(enum eIconSizes size)
{
- switch (size) {
- case ICON_SIZE_ICON:
- return ICON_RENDER_DEFAULT_HEIGHT;
- case ICON_SIZE_PREVIEW:
- return PREVIEW_RENDER_DEFAULT_HEIGHT;
- default:
- return 0;
- }
+ switch (size) {
+ case ICON_SIZE_ICON:
+ return ICON_RENDER_DEFAULT_HEIGHT;
+ case ICON_SIZE_PREVIEW:
+ return PREVIEW_RENDER_DEFAULT_HEIGHT;
+ default:
+ return 0;
+ }
}
/* Create rect for the icon
*/
static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size)
{
- uint render_size = UI_preview_render_size(size);
+ uint render_size = UI_preview_render_size(size);
- if (!prv_img) {
- if (G.debug & G_DEBUG) {
- printf("%s, error: requested preview image does not exist", __func__);
- }
- }
- else if (!prv_img->rect[size]) {
- prv_img->w[size] = render_size;
- prv_img->h[size] = render_size;
- prv_img->flag[size] |= PRV_CHANGED;
- prv_img->changed_timestamp[size] = 0;
- prv_img->rect[size] = MEM_callocN(render_size * render_size * sizeof(uint), "prv_rect");
- }
+ if (!prv_img) {
+ if (G.debug & G_DEBUG) {
+ printf("%s, error: requested preview image does not exist", __func__);
+ }
+ }
+ else if (!prv_img->rect[size]) {
+ prv_img->w[size] = render_size;
+ prv_img->h[size] = render_size;
+ prv_img->flag[size] |= PRV_CHANGED;
+ prv_img->changed_timestamp[size] = 0;
+ prv_img->rect[size] = MEM_callocN(render_size * render_size * sizeof(uint), "prv_rect");
+ }
}
static void ui_id_preview_image_render_size(
- const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job);
+ const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job);
-static void ui_studiolight_icon_job_exec(void *customdata, short *UNUSED(stop), short *UNUSED(do_update), float *UNUSED(progress))
+static void ui_studiolight_icon_job_exec(void *customdata,
+ short *UNUSED(stop),
+ short *UNUSED(do_update),
+ float *UNUSED(progress))
{
- Icon **tmp = (Icon **)customdata;
- Icon *icon = *tmp;
- DrawInfo *di = icon_ensure_drawinfo(icon);
- StudioLight *sl = icon->obj;
- BKE_studiolight_preview(di->data.buffer.image->rect, sl, icon->id_type);
+ Icon **tmp = (Icon **)customdata;
+ Icon *icon = *tmp;
+ DrawInfo *di = icon_ensure_drawinfo(icon);
+ StudioLight *sl = icon->obj;
+ BKE_studiolight_preview(di->data.buffer.image->rect, sl, icon->id_type);
}
static void ui_studiolight_kill_icon_preview_job(wmWindowManager *wm, int icon_id)
{
- Icon *icon = BKE_icon_get(icon_id);
- WM_jobs_kill_type(wm, icon, WM_JOB_TYPE_STUDIOLIGHT);
- icon->obj = NULL;
+ Icon *icon = BKE_icon_get(icon_id);
+ WM_jobs_kill_type(wm, icon, WM_JOB_TYPE_STUDIOLIGHT);
+ icon->obj = NULL;
}
static void ui_studiolight_free_function(StudioLight *sl, void *data)
{
- wmWindowManager *wm = data;
+ wmWindowManager *wm = data;
- /* Happens if job was canceled or already finished. */
- if (wm == NULL) {
- return;
- }
+ /* Happens if job was canceled or already finished. */
+ if (wm == NULL) {
+ return;
+ }
- // get icons_id, get icons and kill wm jobs
- if (sl->icon_id_radiance) {
- ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_radiance);
- }
- if (sl->icon_id_irradiance) {
- ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_irradiance);
- }
- if (sl->icon_id_matcap) {
- ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_matcap);
- }
- if (sl->icon_id_matcap_flipped) {
- ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_matcap_flipped);
- }
+ // get icons_id, get icons and kill wm jobs
+ if (sl->icon_id_radiance) {
+ ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_radiance);
+ }
+ if (sl->icon_id_irradiance) {
+ ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_irradiance);
+ }
+ if (sl->icon_id_matcap) {
+ ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_matcap);
+ }
+ if (sl->icon_id_matcap_flipped) {
+ ui_studiolight_kill_icon_preview_job(wm, sl->icon_id_matcap_flipped);
+ }
}
static void ui_studiolight_icon_job_end(void *customdata)
{
- Icon **tmp = (Icon **)customdata;
- Icon *icon = *tmp;
- StudioLight *sl = icon->obj;
- BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, NULL);
+ Icon **tmp = (Icon **)customdata;
+ Icon *icon = *tmp;
+ StudioLight *sl = icon->obj;
+ BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, NULL);
}
void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big)
{
- Icon *icon = BKE_icon_get(icon_id);
-
- if (icon) {
- DrawInfo *di = icon_ensure_drawinfo(icon);
-
- if (di) {
- switch (di->type) {
- case ICON_TYPE_PREVIEW:
- {
- ID *id = (icon->id_type != 0) ? icon->obj : NULL;
- PreviewImage *prv = id ? BKE_previewimg_id_ensure(id) : icon->obj;
- /* Using jobs for screen previews crashes due to offscreen rendering.
- * XXX would be nicer if PreviewImage could store if it supports jobs */
- const bool use_jobs = !id || (GS(id->name) != ID_SCR);
-
- if (prv) {
- const int size = big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON;
-
- if (id || (prv->tag & PRV_TAG_DEFFERED) != 0) {
- ui_id_preview_image_render_size(C, NULL, id, prv, size, use_jobs);
- }
- }
- break;
- }
- case ICON_TYPE_BUFFER:
- {
- if (icon->obj_type == ICON_DATA_STUDIOLIGHT) {
- if (di->data.buffer.image == NULL) {
- wmWindowManager *wm = CTX_wm_manager(C);
- StudioLight *sl = icon->obj;
- BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, wm);
- IconImage *img = MEM_mallocN(sizeof(IconImage), __func__);
-
- img->w = STUDIOLIGHT_ICON_SIZE;
- img->h = STUDIOLIGHT_ICON_SIZE;
- size_t size = STUDIOLIGHT_ICON_SIZE * STUDIOLIGHT_ICON_SIZE * sizeof(uint);
- img->rect = MEM_mallocN(size, __func__);
- memset(img->rect, 0, size);
- di->data.buffer.image = img;
-
- wmJob *wm_job = WM_jobs_get(wm, CTX_wm_window(C), icon, "StudioLight Icon", 0, WM_JOB_TYPE_STUDIOLIGHT);
- Icon **tmp = MEM_callocN(sizeof(Icon *), __func__);
- *tmp = icon;
- WM_jobs_customdata_set(wm_job, tmp, MEM_freeN);
- WM_jobs_timer(wm_job, 0.01, 0, NC_WINDOW);
- WM_jobs_callbacks(wm_job, ui_studiolight_icon_job_exec, NULL, NULL, ui_studiolight_icon_job_end);
- WM_jobs_start(CTX_wm_manager(C), wm_job);
- }
- }
- break;
- }
- }
- }
- }
+ Icon *icon = BKE_icon_get(icon_id);
+
+ if (icon) {
+ DrawInfo *di = icon_ensure_drawinfo(icon);
+
+ if (di) {
+ switch (di->type) {
+ case ICON_TYPE_PREVIEW: {
+ ID *id = (icon->id_type != 0) ? icon->obj : NULL;
+ PreviewImage *prv = id ? BKE_previewimg_id_ensure(id) : icon->obj;
+ /* Using jobs for screen previews crashes due to offscreen rendering.
+ * XXX would be nicer if PreviewImage could store if it supports jobs */
+ const bool use_jobs = !id || (GS(id->name) != ID_SCR);
+
+ if (prv) {
+ const int size = big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON;
+
+ if (id || (prv->tag & PRV_TAG_DEFFERED) != 0) {
+ ui_id_preview_image_render_size(C, NULL, id, prv, size, use_jobs);
+ }
+ }
+ break;
+ }
+ case ICON_TYPE_BUFFER: {
+ if (icon->obj_type == ICON_DATA_STUDIOLIGHT) {
+ if (di->data.buffer.image == NULL) {
+ wmWindowManager *wm = CTX_wm_manager(C);
+ StudioLight *sl = icon->obj;
+ BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, wm);
+ IconImage *img = MEM_mallocN(sizeof(IconImage), __func__);
+
+ img->w = STUDIOLIGHT_ICON_SIZE;
+ img->h = STUDIOLIGHT_ICON_SIZE;
+ size_t size = STUDIOLIGHT_ICON_SIZE * STUDIOLIGHT_ICON_SIZE * sizeof(uint);
+ img->rect = MEM_mallocN(size, __func__);
+ memset(img->rect, 0, size);
+ di->data.buffer.image = img;
+
+ wmJob *wm_job = WM_jobs_get(
+ wm, CTX_wm_window(C), icon, "StudioLight Icon", 0, WM_JOB_TYPE_STUDIOLIGHT);
+ Icon **tmp = MEM_callocN(sizeof(Icon *), __func__);
+ *tmp = icon;
+ WM_jobs_customdata_set(wm_job, tmp, MEM_freeN);
+ WM_jobs_timer(wm_job, 0.01, 0, NC_WINDOW);
+ WM_jobs_callbacks(
+ wm_job, ui_studiolight_icon_job_exec, NULL, NULL, ui_studiolight_icon_job_end);
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
}
/* only called when icon has changed */
/* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(
- const bContext *C, Scene *scene, ID *id, PreviewImage *prv_img, enum eIconSizes size, const bool use_job)
-{
- if (!prv_img) {
- if (G.debug & G_DEBUG) {
- printf("%s: no preview image for this ID: %s\n", __func__, id->name);
- }
- return;
- }
-
- if (prv_img->flag[size] & PRV_USER_EDITED) {
- /* user-edited preview, do not auto-update! */
- return;
- }
-
- icon_create_rect(prv_img, size);
-
- if (use_job) {
- /* Job (background) version */
- ED_preview_icon_job(C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
- }
- else {
- if (!scene) {
- scene = CTX_data_scene(C);
- }
- /* Immediate version */
- ED_preview_icon_render(CTX_data_main(C), scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
- }
+static void icon_set_image(const bContext *C,
+ Scene *scene,
+ ID *id,
+ PreviewImage *prv_img,
+ enum eIconSizes size,
+ const bool use_job)
+{
+ if (!prv_img) {
+ if (G.debug & G_DEBUG) {
+ printf("%s: no preview image for this ID: %s\n", __func__, id->name);
+ }
+ return;
+ }
+
+ if (prv_img->flag[size] & PRV_USER_EDITED) {
+ /* user-edited preview, do not auto-update! */
+ return;
+ }
+
+ icon_create_rect(prv_img, size);
+
+ if (use_job) {
+ /* Job (background) version */
+ ED_preview_icon_job(C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
+ }
+ else {
+ if (!scene) {
+ scene = CTX_data_scene(C);
+ }
+ /* Immediate version */
+ ED_preview_icon_render(
+ CTX_data_main(C), scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
+ }
}
PreviewImage *UI_icon_to_preview(int icon_id)
{
- Icon *icon = BKE_icon_get(icon_id);
-
- if (icon) {
- DrawInfo *di = (DrawInfo *)icon->drawinfo;
- if (di) {
- if (di->type == ICON_TYPE_PREVIEW) {
- PreviewImage *prv = (icon->id_type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
-
- if (prv) {
- return BKE_previewimg_copy(prv);
- }
- }
- else if (di->data.buffer.image) {
- ImBuf *bbuf;
-
- bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size,
- IB_rect, NULL, __func__);
- if (bbuf) {
- PreviewImage *prv = BKE_previewimg_create();
-
- prv->rect[0] = bbuf->rect;
-
- prv->w[0] = bbuf->x;
- prv->h[0] = bbuf->y;
-
- bbuf->rect = NULL;
- IMB_freeImBuf(bbuf);
-
- return prv;
- }
- }
- }
- }
- return NULL;
-}
-
-static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect), int rw, int rh,
- uint *rect, float alpha, const float rgb[3], const float desaturate)
-{
- ImBuf *ima = NULL;
- int draw_w = w;
- int draw_h = h;
- int draw_x = x;
- int draw_y = y;
-
- /* sanity check */
- if (w <= 0 || h <= 0 || w > 2000 || h > 2000) {
- printf("%s: icons are %i x %i pixels?\n", __func__, w, h);
- BLI_assert(!"invalid icon size");
- return;
- }
- /* modulate color */
- float col[4] = {1.0f, 1.0f, 1.0f, alpha};
-
- if (rgb) {
- col[0] = rgb[0];
- col[1] = rgb[1];
- col[2] = rgb[2];
- }
-
- /* rect contains image in 'rendersize', we only scale if needed */
- if (rw != w || rh != h) {
- /* preserve aspect ratio and center */
- if (rw > rh) {
- draw_w = w;
- draw_h = (int)(((float)rh / (float)rw) * (float)w);
- draw_y += (h - draw_h) / 2;
- }
- else if (rw < rh) {
- draw_w = (int)(((float)rw / (float)rh) * (float)h);
- draw_h = h;
- draw_x += (w - draw_w) / 2;
- }
- /* if the image is squared, the draw_ initialization values are good */
-
- /* first allocate imbuf for scaling and copy preview into it */
- ima = IMB_allocImBuf(rw, rh, 32, IB_rect);
- memcpy(ima->rect, rect, rw * rh * sizeof(uint));
- IMB_scaleImBuf(ima, draw_w, draw_h); /* scale it */
- rect = ima->rect;
- }
-
- /* draw */
- eGPUBuiltinShader shader;
- if (desaturate != 0.0f) {
- shader = GPU_SHADER_2D_IMAGE_DESATURATE_COLOR;
- }
- else {
- shader = GPU_SHADER_2D_IMAGE_COLOR;
- }
- IMMDrawPixelsTexState state = immDrawPixelsTexSetup(shader);
-
- if (shader == GPU_SHADER_2D_IMAGE_DESATURATE_COLOR) {
- immUniform1f("factor", desaturate);
- }
-
- immDrawPixelsTex(&state, draw_x, draw_y, draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, rect,
- 1.0f, 1.0f, col);
-
- if (ima) {
- IMB_freeImBuf(ima);
- }
+ Icon *icon = BKE_icon_get(icon_id);
+
+ if (icon) {
+ DrawInfo *di = (DrawInfo *)icon->drawinfo;
+ if (di) {
+ if (di->type == ICON_TYPE_PREVIEW) {
+ PreviewImage *prv = (icon->id_type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) :
+ icon->obj;
+
+ if (prv) {
+ return BKE_previewimg_copy(prv);
+ }
+ }
+ else if (di->data.buffer.image) {
+ ImBuf *bbuf;
+
+ bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect,
+ di->data.buffer.image->datatoc_size,
+ IB_rect,
+ NULL,
+ __func__);
+ if (bbuf) {
+ PreviewImage *prv = BKE_previewimg_create();
+
+ prv->rect[0] = bbuf->rect;
+
+ prv->w[0] = bbuf->x;
+ prv->h[0] = bbuf->y;
+
+ bbuf->rect = NULL;
+ IMB_freeImBuf(bbuf);
+
+ return prv;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+static void icon_draw_rect(float x,
+ float y,
+ int w,
+ int h,
+ float UNUSED(aspect),
+ int rw,
+ int rh,
+ uint *rect,
+ float alpha,
+ const float rgb[3],
+ const float desaturate)
+{
+ ImBuf *ima = NULL;
+ int draw_w = w;
+ int draw_h = h;
+ int draw_x = x;
+ int draw_y = y;
+
+ /* sanity check */
+ if (w <= 0 || h <= 0 || w > 2000 || h > 2000) {
+ printf("%s: icons are %i x %i pixels?\n", __func__, w, h);
+ BLI_assert(!"invalid icon size");
+ return;
+ }
+ /* modulate color */
+ float col[4] = {1.0f, 1.0f, 1.0f, alpha};
+
+ if (rgb) {
+ col[0] = rgb[0];
+ col[1] = rgb[1];
+ col[2] = rgb[2];
+ }
+
+ /* rect contains image in 'rendersize', we only scale if needed */
+ if (rw != w || rh != h) {
+ /* preserve aspect ratio and center */
+ if (rw > rh) {
+ draw_w = w;
+ draw_h = (int)(((float)rh / (float)rw) * (float)w);
+ draw_y += (h - draw_h) / 2;
+ }
+ else if (rw < rh) {
+ draw_w = (int)(((float)rw / (float)rh) * (float)h);
+ draw_h = h;
+ draw_x += (w - draw_w) / 2;
+ }
+ /* if the image is squared, the draw_ initialization values are good */
+
+ /* first allocate imbuf for scaling and copy preview into it */
+ ima = IMB_allocImBuf(rw, rh, 32, IB_rect);
+ memcpy(ima->rect, rect, rw * rh * sizeof(uint));
+ IMB_scaleImBuf(ima, draw_w, draw_h); /* scale it */
+ rect = ima->rect;
+ }
+
+ /* draw */
+ eGPUBuiltinShader shader;
+ if (desaturate != 0.0f) {
+ shader = GPU_SHADER_2D_IMAGE_DESATURATE_COLOR;
+ }
+ else {
+ shader = GPU_SHADER_2D_IMAGE_COLOR;
+ }
+ IMMDrawPixelsTexState state = immDrawPixelsTexSetup(shader);
+
+ if (shader == GPU_SHADER_2D_IMAGE_DESATURATE_COLOR) {
+ immUniform1f("factor", desaturate);
+ }
+
+ immDrawPixelsTex(&state,
+ draw_x,
+ draw_y,
+ draw_w,
+ draw_h,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ GL_NEAREST,
+ rect,
+ 1.0f,
+ 1.0f,
+ col);
+
+ if (ima) {
+ IMB_freeImBuf(ima);
+ }
}
/* High enough to make a difference, low enough so that
@@ -1348,669 +1430,721 @@ static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect),
#define ICON_DRAW_CACHE_SIZE 16
typedef struct IconDrawCall {
- rctf pos;
- rctf tex;
- float color[4];
+ rctf pos;
+ rctf tex;
+ float color[4];
} IconDrawCall;
static struct {
- IconDrawCall drawcall_cache[ICON_DRAW_CACHE_SIZE];
- int calls; /* Number of calls batched together */
- bool enabled;
- float mat[4][4];
+ IconDrawCall drawcall_cache[ICON_DRAW_CACHE_SIZE];
+ int calls; /* Number of calls batched together */
+ bool enabled;
+ float mat[4][4];
} g_icon_draw_cache = {{{{0}}}};
void UI_icon_draw_cache_begin(void)
{
- BLI_assert(g_icon_draw_cache.enabled == false);
- g_icon_draw_cache.enabled = true;
+ BLI_assert(g_icon_draw_cache.enabled == false);
+ g_icon_draw_cache.enabled = true;
}
static void icon_draw_cache_flush_ex(void)
{
- if (g_icon_draw_cache.calls == 0) {
- return;
- }
+ if (g_icon_draw_cache.calls == 0) {
+ return;
+ }
- /* We need to flush widget base first to ensure correct ordering. */
- UI_widgetbase_draw_cache_flush();
+ /* We need to flush widget base first to ensure correct ordering. */
+ UI_widgetbase_draw_cache_flush();
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, icongltex.id);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, icongltex.id);
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR);
- GPU_shader_bind(shader);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR);
+ GPU_shader_bind(shader);
- int img_loc = GPU_shader_get_uniform_ensure(shader, "image");
- int data_loc = GPU_shader_get_uniform_ensure(shader, "calls_data[0]");
+ int img_loc = GPU_shader_get_uniform_ensure(shader, "image");
+ int data_loc = GPU_shader_get_uniform_ensure(shader, "calls_data[0]");
- glUniform1i(img_loc, 0);
- glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)g_icon_draw_cache.drawcall_cache);
+ glUniform1i(img_loc, 0);
+ glUniform4fv(data_loc, ICON_DRAW_CACHE_SIZE * 3, (float *)g_icon_draw_cache.drawcall_cache);
- GPU_draw_primitive(GPU_PRIM_TRIS, 6 * g_icon_draw_cache.calls);
+ GPU_draw_primitive(GPU_PRIM_TRIS, 6 * g_icon_draw_cache.calls);
- glBindTexture(GL_TEXTURE_2D, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
- g_icon_draw_cache.calls = 0;
+ g_icon_draw_cache.calls = 0;
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
void UI_icon_draw_cache_end(void)
{
- BLI_assert(g_icon_draw_cache.enabled == true);
- g_icon_draw_cache.enabled = false;
-
- /* Don't change blend state if it's not needed. */
- if (g_icon_draw_cache.calls == 0) {
- return;
- }
+ BLI_assert(g_icon_draw_cache.enabled == true);
+ g_icon_draw_cache.enabled = false;
+
+ /* Don't change blend state if it's not needed. */
+ if (g_icon_draw_cache.calls == 0) {
+ return;
+ }
- GPU_blend(true);
- icon_draw_cache_flush_ex();
- GPU_blend(false);
+ GPU_blend(true);
+ icon_draw_cache_flush_ex();
+ GPU_blend(false);
}
-static void icon_draw_texture_cached(
- float x, float y, float w, float h, int ix, int iy,
- int UNUSED(iw), int ih, float alpha, const float rgb[3])
+static void icon_draw_texture_cached(float x,
+ float y,
+ float w,
+ float h,
+ int ix,
+ int iy,
+ int UNUSED(iw),
+ int ih,
+ float alpha,
+ const float rgb[3])
{
- float mvp[4][4];
- GPU_matrix_model_view_projection_get(mvp);
+ float mvp[4][4];
+ GPU_matrix_model_view_projection_get(mvp);
- IconDrawCall *call = &g_icon_draw_cache.drawcall_cache[g_icon_draw_cache.calls];
- g_icon_draw_cache.calls++;
+ IconDrawCall *call = &g_icon_draw_cache.drawcall_cache[g_icon_draw_cache.calls];
+ g_icon_draw_cache.calls++;
- /* Manual mat4*vec2 */
- call->pos.xmin = x * mvp[0][0] + y * mvp[1][0] + mvp[3][0];
- call->pos.ymin = x * mvp[0][1] + y * mvp[1][1] + mvp[3][1];
- call->pos.xmax = call->pos.xmin + w * mvp[0][0] + h * mvp[1][0];
- call->pos.ymax = call->pos.ymin + w * mvp[0][1] + h * mvp[1][1];
+ /* Manual mat4*vec2 */
+ call->pos.xmin = x * mvp[0][0] + y * mvp[1][0] + mvp[3][0];
+ call->pos.ymin = x * mvp[0][1] + y * mvp[1][1] + mvp[3][1];
+ call->pos.xmax = call->pos.xmin + w * mvp[0][0] + h * mvp[1][0];
+ call->pos.ymax = call->pos.ymin + w * mvp[0][1] + h * mvp[1][1];
- call->tex.xmin = ix * icongltex.invw;
- call->tex.xmax = (ix + ih) * icongltex.invw;
- call->tex.ymin = iy * icongltex.invh;
- call->tex.ymax = (iy + ih) * icongltex.invh;
+ call->tex.xmin = ix * icongltex.invw;
+ call->tex.xmax = (ix + ih) * icongltex.invw;
+ call->tex.ymin = iy * icongltex.invh;
+ call->tex.ymax = (iy + ih) * icongltex.invh;
- if (rgb) {
- copy_v4_fl4(call->color, rgb[0], rgb[1], rgb[2], alpha);
- }
- else {
- copy_v4_fl(call->color, alpha);
- }
+ if (rgb) {
+ copy_v4_fl4(call->color, rgb[0], rgb[1], rgb[2], alpha);
+ }
+ else {
+ copy_v4_fl(call->color, alpha);
+ }
- if (g_icon_draw_cache.calls == ICON_DRAW_CACHE_SIZE) {
- icon_draw_cache_flush_ex();
- }
+ if (g_icon_draw_cache.calls == ICON_DRAW_CACHE_SIZE) {
+ icon_draw_cache_flush_ex();
+ }
}
-static void icon_draw_texture(
- float x, float y, float w, float h, int ix, int iy,
- int iw, int ih, float alpha, const float rgb[3])
+static void icon_draw_texture(float x,
+ float y,
+ float w,
+ float h,
+ int ix,
+ int iy,
+ int iw,
+ int ih,
+ float alpha,
+ const float rgb[3])
{
- if (g_icon_draw_cache.enabled) {
- icon_draw_texture_cached(x, y, w, h, ix, iy, iw, ih, alpha, rgb);
- return;
- }
+ if (g_icon_draw_cache.enabled) {
+ icon_draw_texture_cached(x, y, w, h, ix, iy, iw, ih, alpha, rgb);
+ return;
+ }
- /* We need to flush widget base first to ensure correct ordering. */
- UI_widgetbase_draw_cache_flush();
+ /* We need to flush widget base first to ensure correct ordering. */
+ UI_widgetbase_draw_cache_flush();
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- float x1, x2, y1, y2;
+ float x1, x2, y1, y2;
- x1 = ix * icongltex.invw;
- x2 = (ix + ih) * icongltex.invw;
- y1 = iy * icongltex.invh;
- y2 = (iy + ih) * icongltex.invh;
+ x1 = ix * icongltex.invw;
+ x2 = (ix + ih) * icongltex.invw;
+ y1 = iy * icongltex.invh;
+ y2 = (iy + ih) * icongltex.invh;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, icongltex.id);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, icongltex.id);
- GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
- GPU_shader_bind(shader);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
+ GPU_shader_bind(shader);
- if (rgb) {
- glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha);
- }
- else {
- glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
- }
+ if (rgb) {
+ glUniform4f(
+ GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), rgb[0], rgb[1], rgb[2], alpha);
+ }
+ else {
+ glUniform4f(
+ GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
+ }
- glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0);
- glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"), x1, y1, x2, y2);
- glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), x, y, x + w, y + h);
+ glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0);
+ glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"), x1, y1, x2, y2);
+ glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), x, y, x + w, y + h);
- GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
+ GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4);
- glBindTexture(GL_TEXTURE_2D, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
/* Drawing size for preview images */
static int get_draw_size(enum eIconSizes size)
{
- switch (size) {
- case ICON_SIZE_ICON:
- return ICON_DEFAULT_HEIGHT;
- case ICON_SIZE_PREVIEW:
- return PREVIEW_DEFAULT_HEIGHT;
- default:
- return 0;
- }
-}
-
-
-
-static void icon_draw_size(
- float x, float y, int icon_id, float aspect, float alpha, const float rgb[3],
- enum eIconSizes size, int draw_size, const float desaturate, const char mono_rgba[4])
-{
- bTheme *btheme = UI_GetTheme();
- Icon *icon = NULL;
- IconImage *iimg;
- const float fdraw_size = (float)draw_size;
- int w, h;
-
- icon = BKE_icon_get(icon_id);
- alpha *= btheme->tui.icon_alpha;
-
- if (icon == NULL) {
- if (G.debug & G_DEBUG) {
- printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
- }
- return;
- }
-
- /* scale width and height according to aspect */
- w = (int)(fdraw_size / aspect + 0.5f);
- h = (int)(fdraw_size / aspect + 0.5f);
-
- DrawInfo *di = icon_ensure_drawinfo(icon);
-
- /* We need to flush widget base first to ensure correct ordering. */
- UI_widgetbase_draw_cache_flush();
-
- if (di->type == ICON_TYPE_VECTOR) {
- /* vector icons use the uiBlock transformation, they are not drawn
- * with untransformed coordinates like the other icons */
- di->data.vector.func((int)x, (int)y, w, h, 1.0f);
- }
- else if (di->type == ICON_TYPE_GEOM) {
+ switch (size) {
+ case ICON_SIZE_ICON:
+ return ICON_DEFAULT_HEIGHT;
+ case ICON_SIZE_PREVIEW:
+ return PREVIEW_DEFAULT_HEIGHT;
+ default:
+ return 0;
+ }
+}
+
+static void icon_draw_size(float x,
+ float y,
+ int icon_id,
+ float aspect,
+ float alpha,
+ const float rgb[3],
+ enum eIconSizes size,
+ int draw_size,
+ const float desaturate,
+ const char mono_rgba[4])
+{
+ bTheme *btheme = UI_GetTheme();
+ Icon *icon = NULL;
+ IconImage *iimg;
+ const float fdraw_size = (float)draw_size;
+ int w, h;
+
+ icon = BKE_icon_get(icon_id);
+ alpha *= btheme->tui.icon_alpha;
+
+ if (icon == NULL) {
+ if (G.debug & G_DEBUG) {
+ printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id);
+ }
+ return;
+ }
+
+ /* scale width and height according to aspect */
+ w = (int)(fdraw_size / aspect + 0.5f);
+ h = (int)(fdraw_size / aspect + 0.5f);
+
+ DrawInfo *di = icon_ensure_drawinfo(icon);
+
+ /* We need to flush widget base first to ensure correct ordering. */
+ UI_widgetbase_draw_cache_flush();
+
+ if (di->type == ICON_TYPE_VECTOR) {
+ /* vector icons use the uiBlock transformation, they are not drawn
+ * with untransformed coordinates like the other icons */
+ di->data.vector.func((int)x, (int)y, w, h, 1.0f);
+ }
+ else if (di->type == ICON_TYPE_GEOM) {
#ifdef USE_UI_TOOLBAR_HACK
- /* TODO(campbell): scale icons up for toolbar,
- * we need a way to detect larger buttons and do this automatic. */
- {
- float scale = (float)ICON_DEFAULT_HEIGHT_TOOLBAR / (float)ICON_DEFAULT_HEIGHT;
- y = (y + (h / 2)) - ((h * scale) / 2);
- w *= scale;
- h *= scale;
- }
+ /* TODO(campbell): scale icons up for toolbar,
+ * we need a way to detect larger buttons and do this automatic. */
+ {
+ float scale = (float)ICON_DEFAULT_HEIGHT_TOOLBAR / (float)ICON_DEFAULT_HEIGHT;
+ y = (y + (h / 2)) - ((h * scale) / 2);
+ w *= scale;
+ h *= scale;
+ }
#endif
- /* This could re-generate often if rendered at different sizes in the one interface.
- * TODO(campbell): support caching multiple sizes. */
- ImBuf *ibuf = di->data.geom.image_cache;
- if ((ibuf == NULL) ||
- (ibuf->x != w) ||
- (ibuf->y != h))
- {
- if (ibuf) {
- IMB_freeImBuf(ibuf);
- }
- ibuf = BKE_icon_geom_rasterize(icon->obj, w, h);
- di->data.geom.image_cache = ibuf;
- }
-
- GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, rgb, desaturate);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- }
- else if (di->type == ICON_TYPE_EVENT) {
- const short event_type = di->data.input.event_type;
- const short event_value = di->data.input.event_value;
- icon_draw_rect_input(x, y, w, h, alpha, event_type, event_value);
- }
- else if (di->type == ICON_TYPE_COLOR_TEXTURE) {
- /* texture image use premul alpha for correct scaling */
- icon_draw_texture(x, y, (float)w, (float)h, di->data.texture.x, di->data.texture.y,
- di->data.texture.w, di->data.texture.h, alpha, rgb);
- }
- else if (di->type == ICON_TYPE_MONO_TEXTURE) {
- /* icon that matches text color, assumed to be white */
- float color[4];
- if (!UI_GetIconThemeColor4fv(di->data.texture.theme_color, color)) {
- if (mono_rgba) {
- rgba_uchar_to_float(color, (const uchar *)mono_rgba);
- }
- else {
- UI_GetThemeColor4fv(TH_TEXT, color);
- }
- }
-
- if (rgb) {
- mul_v3_v3(color, rgb);
- }
-
- mul_v4_fl(color, alpha);
-
- icon_draw_texture(x, y, (float)w, (float)h, di->data.texture.x, di->data.texture.y,
- di->data.texture.w, di->data.texture.h, color[3], color);
- }
-
- else if (di->type == ICON_TYPE_BUFFER) {
- /* it is a builtin icon */
- iimg = di->data.buffer.image;
+ /* This could re-generate often if rendered at different sizes in the one interface.
+ * TODO(campbell): support caching multiple sizes. */
+ ImBuf *ibuf = di->data.geom.image_cache;
+ if ((ibuf == NULL) || (ibuf->x != w) || (ibuf->y != h)) {
+ if (ibuf) {
+ IMB_freeImBuf(ibuf);
+ }
+ ibuf = BKE_icon_geom_rasterize(icon->obj, w, h);
+ di->data.geom.image_cache = ibuf;
+ }
+
+ GPU_blend_set_func_separate(
+ GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, rgb, desaturate);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ }
+ else if (di->type == ICON_TYPE_EVENT) {
+ const short event_type = di->data.input.event_type;
+ const short event_value = di->data.input.event_value;
+ icon_draw_rect_input(x, y, w, h, alpha, event_type, event_value);
+ }
+ else if (di->type == ICON_TYPE_COLOR_TEXTURE) {
+ /* texture image use premul alpha for correct scaling */
+ icon_draw_texture(x,
+ y,
+ (float)w,
+ (float)h,
+ di->data.texture.x,
+ di->data.texture.y,
+ di->data.texture.w,
+ di->data.texture.h,
+ alpha,
+ rgb);
+ }
+ else if (di->type == ICON_TYPE_MONO_TEXTURE) {
+ /* icon that matches text color, assumed to be white */
+ float color[4];
+ if (!UI_GetIconThemeColor4fv(di->data.texture.theme_color, color)) {
+ if (mono_rgba) {
+ rgba_uchar_to_float(color, (const uchar *)mono_rgba);
+ }
+ else {
+ UI_GetThemeColor4fv(TH_TEXT, color);
+ }
+ }
+
+ if (rgb) {
+ mul_v3_v3(color, rgb);
+ }
+
+ mul_v4_fl(color, alpha);
+
+ icon_draw_texture(x,
+ y,
+ (float)w,
+ (float)h,
+ di->data.texture.x,
+ di->data.texture.y,
+ di->data.texture.w,
+ di->data.texture.h,
+ color[3],
+ color);
+ }
+
+ else if (di->type == ICON_TYPE_BUFFER) {
+ /* it is a builtin icon */
+ iimg = di->data.buffer.image;
#ifndef WITH_HEADLESS
- icon_verify_datatoc(iimg);
+ icon_verify_datatoc(iimg);
#endif
- if (!iimg->rect) {
- /* something has gone wrong! */
- return;
- }
-
- icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, desaturate);
- }
- else if (di->type == ICON_TYPE_PREVIEW) {
- PreviewImage *pi = (icon->id_type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) : icon->obj;
-
- if (pi) {
- /* no create icon on this level in code */
- if (!pi->rect[size]) {
- /* Something has gone wrong! */
- return;
- }
-
- /* Preview images use premultiplied alpha. */
- GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- icon_draw_rect(x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, rgb, desaturate);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- }
- }
- else if (di->type == ICON_TYPE_GPLAYER) {
- BLI_assert(icon->obj != NULL);
-
- /* Just draw a colored rect - Like for vicon_colorset_draw() */
+ if (!iimg->rect) {
+ /* something has gone wrong! */
+ return;
+ }
+
+ icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, rgb, desaturate);
+ }
+ else if (di->type == ICON_TYPE_PREVIEW) {
+ PreviewImage *pi = (icon->id_type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) :
+ icon->obj;
+
+ if (pi) {
+ /* no create icon on this level in code */
+ if (!pi->rect[size]) {
+ /* Something has gone wrong! */
+ return;
+ }
+
+ /* Preview images use premultiplied alpha. */
+ GPU_blend_set_func_separate(
+ GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ icon_draw_rect(
+ x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, rgb, desaturate);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ }
+ }
+ else if (di->type == ICON_TYPE_GPLAYER) {
+ BLI_assert(icon->obj != NULL);
+
+ /* Just draw a colored rect - Like for vicon_colorset_draw() */
#ifndef WITH_HEADLESS
- vicon_gplayer_color_draw(icon, (int)x, (int)y, w, h);
+ vicon_gplayer_color_draw(icon, (int)x, (int)y, w, h);
#endif
- }
+ }
}
static void ui_id_preview_image_render_size(
- const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
+ const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
{
- /* changed only ever set by dynamic icons */
- if (((pi->flag[size] & PRV_CHANGED) || !pi->rect[size])) {
- /* create the rect if necessary */
- icon_set_image(C, scene, id, pi, size, use_job);
+ /* changed only ever set by dynamic icons */
+ if (((pi->flag[size] & PRV_CHANGED) || !pi->rect[size])) {
+ /* create the rect if necessary */
+ icon_set_image(C, scene, id, pi, size, use_job);
- pi->flag[size] &= ~PRV_CHANGED;
- }
+ pi->flag[size] &= ~PRV_CHANGED;
+ }
}
void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big, const bool use_job)
{
- PreviewImage *pi = BKE_previewimg_id_ensure(id);
+ PreviewImage *pi = BKE_previewimg_id_ensure(id);
- if (pi) {
- if (big) {
- /* bigger preview size */
- ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_PREVIEW, use_job);
- }
- else {
- /* icon size */
- ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_ICON, use_job);
- }
- }
+ if (pi) {
+ if (big) {
+ /* bigger preview size */
+ ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_PREVIEW, use_job);
+ }
+ else {
+ /* icon size */
+ ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_ICON, use_job);
+ }
+ }
}
static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs)
{
- PreviewImage *pi = BKE_previewimg_id_ensure(id);
- enum eIconSizes i;
+ PreviewImage *pi = BKE_previewimg_id_ensure(id);
+ enum eIconSizes i;
- if (!pi) {
- return;
- }
+ if (!pi) {
+ return;
+ }
- for (i = 0; i < NUM_ICON_SIZES; i++) {
- /* check if rect needs to be created; changed
- * only set by dynamic icons */
- if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
- icon_set_image(C, NULL, id, pi, i, use_jobs);
- pi->flag[i] &= ~PRV_CHANGED;
- }
- }
+ for (i = 0; i < NUM_ICON_SIZES; i++) {
+ /* check if rect needs to be created; changed
+ * only set by dynamic icons */
+ if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
+ icon_set_image(C, NULL, id, pi, i, use_jobs);
+ pi->flag[i] &= ~PRV_CHANGED;
+ }
+ }
}
-
static int ui_id_brush_get_icon(const bContext *C, ID *id)
{
- Brush *br = (Brush *)id;
-
- if (br->flag & BRUSH_CUSTOM_ICON) {
- BKE_icon_id_ensure(id);
- ui_id_icon_render(C, id, true);
- }
- else {
- WorkSpace *workspace = CTX_wm_workspace(C);
- Object *ob = CTX_data_active_object(C);
- const EnumPropertyItem *items = NULL;
- ePaintMode paint_mode = PAINT_MODE_INVALID;
- ScrArea *sa = CTX_wm_area(C);
- char space_type = sa->spacetype;
- /* When in an unsupported space. */
- if (!ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE)) {
- space_type = workspace->tools_space_type;
- }
-
- /* XXX: this is not nice, should probably make brushes
- * be strictly in one paint mode only to avoid
- * checking various context stuff here */
-
- if ((space_type == SPACE_VIEW3D) && ob) {
- if (ob->mode & OB_MODE_SCULPT) {
- paint_mode = PAINT_MODE_SCULPT;
- }
- else if (ob->mode & OB_MODE_VERTEX_PAINT) {
- paint_mode = PAINT_MODE_VERTEX;
- }
- else if (ob->mode & OB_MODE_WEIGHT_PAINT) {
- paint_mode = PAINT_MODE_WEIGHT;
- }
- else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
- paint_mode = PAINT_MODE_TEXTURE_3D;
- }
- }
- else if (space_type == SPACE_IMAGE) {
- int sima_mode;
- if (sa->spacetype == space_type) {
- SpaceImage *sima = sa->spacedata.first;
- sima_mode = sima->mode;
- }
- else {
- sima_mode = workspace->tools_mode;
- }
-
- if (sima_mode == SI_MODE_PAINT) {
- paint_mode = PAINT_MODE_TEXTURE_2D;
- }
- }
-
- /* reset the icon */
- if ((ob != NULL) &&
- (ob->mode & OB_MODE_PAINT_GPENCIL) &&
- (br->gpencil_settings != NULL))
- {
- switch (br->gpencil_settings->icon_id) {
- case GP_BRUSH_ICON_PENCIL:
- br->id.icon_id = ICON_GPBRUSH_PENCIL;
- break;
- case GP_BRUSH_ICON_PEN:
- br->id.icon_id = ICON_GPBRUSH_PEN;
- break;
- case GP_BRUSH_ICON_INK:
- br->id.icon_id = ICON_GPBRUSH_INK;
- break;
- case GP_BRUSH_ICON_INKNOISE:
- br->id.icon_id = ICON_GPBRUSH_INKNOISE;
- break;
- case GP_BRUSH_ICON_BLOCK:
- br->id.icon_id = ICON_GPBRUSH_BLOCK;
- break;
- case GP_BRUSH_ICON_MARKER:
- br->id.icon_id = ICON_GPBRUSH_MARKER;
- break;
- case GP_BRUSH_ICON_FILL:
- br->id.icon_id = ICON_GPBRUSH_FILL;
- break;
- case GP_BRUSH_ICON_ERASE_SOFT:
- br->id.icon_id = ICON_GPBRUSH_ERASE_SOFT;
- break;
- case GP_BRUSH_ICON_ERASE_HARD:
- br->id.icon_id = ICON_GPBRUSH_ERASE_HARD;
- break;
- case GP_BRUSH_ICON_ERASE_STROKE:
- br->id.icon_id = ICON_GPBRUSH_ERASE_STROKE;
- break;
- default:
- br->id.icon_id = ICON_GPBRUSH_PEN;
- break;
- }
- return id->icon_id;
- }
- else if (paint_mode != PAINT_MODE_INVALID) {
- items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
- const uint tool_offset = BKE_paint_get_brush_tool_offset_from_paintmode(paint_mode);
- const int tool_type = *(char *)POINTER_OFFSET(br, tool_offset);
- if (!items || !RNA_enum_icon_from_value(items, tool_type, &id->icon_id)) {
- id->icon_id = 0;
- }
- }
- else {
- id->icon_id = 0;
- }
- }
-
- return id->icon_id;
+ Brush *br = (Brush *)id;
+
+ if (br->flag & BRUSH_CUSTOM_ICON) {
+ BKE_icon_id_ensure(id);
+ ui_id_icon_render(C, id, true);
+ }
+ else {
+ WorkSpace *workspace = CTX_wm_workspace(C);
+ Object *ob = CTX_data_active_object(C);
+ const EnumPropertyItem *items = NULL;
+ ePaintMode paint_mode = PAINT_MODE_INVALID;
+ ScrArea *sa = CTX_wm_area(C);
+ char space_type = sa->spacetype;
+ /* When in an unsupported space. */
+ if (!ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE)) {
+ space_type = workspace->tools_space_type;
+ }
+
+ /* XXX: this is not nice, should probably make brushes
+ * be strictly in one paint mode only to avoid
+ * checking various context stuff here */
+
+ if ((space_type == SPACE_VIEW3D) && ob) {
+ if (ob->mode & OB_MODE_SCULPT) {
+ paint_mode = PAINT_MODE_SCULPT;
+ }
+ else if (ob->mode & OB_MODE_VERTEX_PAINT) {
+ paint_mode = PAINT_MODE_VERTEX;
+ }
+ else if (ob->mode & OB_MODE_WEIGHT_PAINT) {
+ paint_mode = PAINT_MODE_WEIGHT;
+ }
+ else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ paint_mode = PAINT_MODE_TEXTURE_3D;
+ }
+ }
+ else if (space_type == SPACE_IMAGE) {
+ int sima_mode;
+ if (sa->spacetype == space_type) {
+ SpaceImage *sima = sa->spacedata.first;
+ sima_mode = sima->mode;
+ }
+ else {
+ sima_mode = workspace->tools_mode;
+ }
+
+ if (sima_mode == SI_MODE_PAINT) {
+ paint_mode = PAINT_MODE_TEXTURE_2D;
+ }
+ }
+
+ /* reset the icon */
+ if ((ob != NULL) && (ob->mode & OB_MODE_PAINT_GPENCIL) && (br->gpencil_settings != NULL)) {
+ switch (br->gpencil_settings->icon_id) {
+ case GP_BRUSH_ICON_PENCIL:
+ br->id.icon_id = ICON_GPBRUSH_PENCIL;
+ break;
+ case GP_BRUSH_ICON_PEN:
+ br->id.icon_id = ICON_GPBRUSH_PEN;
+ break;
+ case GP_BRUSH_ICON_INK:
+ br->id.icon_id = ICON_GPBRUSH_INK;
+ break;
+ case GP_BRUSH_ICON_INKNOISE:
+ br->id.icon_id = ICON_GPBRUSH_INKNOISE;
+ break;
+ case GP_BRUSH_ICON_BLOCK:
+ br->id.icon_id = ICON_GPBRUSH_BLOCK;
+ break;
+ case GP_BRUSH_ICON_MARKER:
+ br->id.icon_id = ICON_GPBRUSH_MARKER;
+ break;
+ case GP_BRUSH_ICON_FILL:
+ br->id.icon_id = ICON_GPBRUSH_FILL;
+ break;
+ case GP_BRUSH_ICON_ERASE_SOFT:
+ br->id.icon_id = ICON_GPBRUSH_ERASE_SOFT;
+ break;
+ case GP_BRUSH_ICON_ERASE_HARD:
+ br->id.icon_id = ICON_GPBRUSH_ERASE_HARD;
+ break;
+ case GP_BRUSH_ICON_ERASE_STROKE:
+ br->id.icon_id = ICON_GPBRUSH_ERASE_STROKE;
+ break;
+ default:
+ br->id.icon_id = ICON_GPBRUSH_PEN;
+ break;
+ }
+ return id->icon_id;
+ }
+ else if (paint_mode != PAINT_MODE_INVALID) {
+ items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
+ const uint tool_offset = BKE_paint_get_brush_tool_offset_from_paintmode(paint_mode);
+ const int tool_type = *(char *)POINTER_OFFSET(br, tool_offset);
+ if (!items || !RNA_enum_icon_from_value(items, tool_type, &id->icon_id)) {
+ id->icon_id = 0;
+ }
+ }
+ else {
+ id->icon_id = 0;
+ }
+ }
+
+ return id->icon_id;
}
static int ui_id_screen_get_icon(const bContext *C, ID *id)
{
- BKE_icon_id_ensure(id);
- /* Don't use jobs here, offscreen rendering doesn't like this and crashes. */
- ui_id_icon_render(C, id, false);
+ BKE_icon_id_ensure(id);
+ /* Don't use jobs here, offscreen rendering doesn't like this and crashes. */
+ ui_id_icon_render(C, id, false);
- return id->icon_id;
+ return id->icon_id;
}
int ui_id_icon_get(const bContext *C, ID *id, const bool big)
{
- int iconid = 0;
-
- /* icon */
- switch (GS(id->name)) {
- case ID_BR:
- iconid = ui_id_brush_get_icon(C, id);
- break;
- case ID_MA: /* fall through */
- case ID_TE: /* fall through */
- case ID_IM: /* fall through */
- case ID_WO: /* fall through */
- case ID_LA: /* fall through */
- iconid = BKE_icon_id_ensure(id);
- /* checks if not exists, or changed */
- UI_id_icon_render(C, NULL, id, big, true);
- break;
- case ID_SCR:
- iconid = ui_id_screen_get_icon(C, id);
- break;
- default:
- break;
- }
-
- return iconid;
+ int iconid = 0;
+
+ /* icon */
+ switch (GS(id->name)) {
+ case ID_BR:
+ iconid = ui_id_brush_get_icon(C, id);
+ break;
+ case ID_MA: /* fall through */
+ case ID_TE: /* fall through */
+ case ID_IM: /* fall through */
+ case ID_WO: /* fall through */
+ case ID_LA: /* fall through */
+ iconid = BKE_icon_id_ensure(id);
+ /* checks if not exists, or changed */
+ UI_id_icon_render(C, NULL, id, big, true);
+ break;
+ case ID_SCR:
+ iconid = ui_id_screen_get_icon(C, id);
+ break;
+ default:
+ break;
+ }
+
+ return iconid;
}
int UI_rnaptr_icon_get(bContext *C, PointerRNA *ptr, int rnaicon, const bool big)
{
- ID *id = NULL;
-
- if (!ptr->data) {
- return rnaicon;
- }
-
- /* try ID, material, texture or dynapaint slot */
- if (RNA_struct_is_ID(ptr->type)) {
- id = ptr->id.data;
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_MaterialSlot)) {
- id = RNA_pointer_get(ptr, "material").data;
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_TextureSlot)) {
- id = RNA_pointer_get(ptr, "texture").data;
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_DynamicPaintSurface)) {
- DynamicPaintSurface *surface = ptr->data;
-
- if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) {
- return ICON_SHADING_TEXTURE;
- }
- else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
- return ICON_OUTLINER_DATA_MESH;
- }
- else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
- return ICON_FILE_IMAGE;
- }
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_StudioLight)) {
- StudioLight *sl = ptr->data;
- switch (sl->flag & STUDIOLIGHT_FLAG_ORIENTATIONS) {
- case STUDIOLIGHT_TYPE_STUDIO:
- return sl->icon_id_irradiance;
- case STUDIOLIGHT_TYPE_WORLD:
- default:
- return sl->icon_id_radiance;
- case STUDIOLIGHT_TYPE_MATCAP:
- return sl->icon_id_matcap;
- }
- }
-
- /* get icon from ID */
- if (id) {
- int icon = ui_id_icon_get(C, id, big);
-
- return icon ? icon : rnaicon;
- }
-
- return rnaicon;
+ ID *id = NULL;
+
+ if (!ptr->data) {
+ return rnaicon;
+ }
+
+ /* try ID, material, texture or dynapaint slot */
+ if (RNA_struct_is_ID(ptr->type)) {
+ id = ptr->id.data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_MaterialSlot)) {
+ id = RNA_pointer_get(ptr, "material").data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_TextureSlot)) {
+ id = RNA_pointer_get(ptr, "texture").data;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_DynamicPaintSurface)) {
+ DynamicPaintSurface *surface = ptr->data;
+
+ if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) {
+ return ICON_SHADING_TEXTURE;
+ }
+ else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
+ return ICON_OUTLINER_DATA_MESH;
+ }
+ else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
+ return ICON_FILE_IMAGE;
+ }
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_StudioLight)) {
+ StudioLight *sl = ptr->data;
+ switch (sl->flag & STUDIOLIGHT_FLAG_ORIENTATIONS) {
+ case STUDIOLIGHT_TYPE_STUDIO:
+ return sl->icon_id_irradiance;
+ case STUDIOLIGHT_TYPE_WORLD:
+ default:
+ return sl->icon_id_radiance;
+ case STUDIOLIGHT_TYPE_MATCAP:
+ return sl->icon_id_matcap;
+ }
+ }
+
+ /* get icon from ID */
+ if (id) {
+ int icon = ui_id_icon_get(C, id, big);
+
+ return icon ? icon : rnaicon;
+ }
+
+ return rnaicon;
}
int UI_idcode_icon_get(const int idcode)
{
- switch (idcode) {
- case ID_AC:
- return ICON_ACTION;
- case ID_AR:
- return ICON_ARMATURE_DATA;
- case ID_BR:
- return ICON_BRUSH_DATA;
- case ID_CA:
- return ICON_CAMERA_DATA;
- case ID_CF:
- return ICON_FILE;
- case ID_CU:
- return ICON_CURVE_DATA;
- case ID_GD:
- return ICON_GREASEPENCIL;
- case ID_GR:
- return ICON_GROUP;
- case ID_IM:
- return ICON_IMAGE_DATA;
- case ID_LA:
- return ICON_LIGHT_DATA;
- case ID_LS:
- return ICON_LINE_DATA;
- case ID_LT:
- return ICON_LATTICE_DATA;
- case ID_MA:
- return ICON_MATERIAL_DATA;
- case ID_MB:
- return ICON_META_DATA;
- case ID_MC:
- return ICON_TRACKER;
- case ID_ME:
- return ICON_MESH_DATA;
- case ID_MSK:
- return ICON_MOD_MASK; /* TODO! this would need its own icon! */
- case ID_NT:
- return ICON_NODETREE;
- case ID_OB:
- return ICON_OBJECT_DATA;
- case ID_PA:
- return ICON_PARTICLE_DATA;
- case ID_PAL:
- return ICON_COLOR; /* TODO! this would need its own icon! */
- case ID_PC:
- return ICON_CURVE_BEZCURVE; /* TODO! this would need its own icon! */
- case ID_LP:
- return ICON_LIGHTPROBE_CUBEMAP;
- case ID_SCE:
- return ICON_SCENE_DATA;
- case ID_SPK:
- return ICON_SPEAKER;
- case ID_SO:
- return ICON_SOUND;
- case ID_TE:
- return ICON_TEXTURE_DATA;
- case ID_TXT:
- return ICON_TEXT;
- case ID_VF:
- return ICON_FONT_DATA;
- case ID_WO:
- return ICON_WORLD_DATA;
- default:
- return ICON_NONE;
- }
-}
-
-static void icon_draw_at_size(
- float x, float y, int icon_id, float aspect, float alpha,
- enum eIconSizes size, const float desaturate, const char mono_color[4])
-{
- int draw_size = get_draw_size(size);
- icon_draw_size(x, y, icon_id, aspect, alpha, NULL, size, draw_size, desaturate, mono_color);
-}
-
-void UI_icon_draw_aspect(float x, float y, int icon_id, float aspect, float alpha, const char mono_color[4])
-{
- icon_draw_at_size(x, y, icon_id, aspect, alpha, ICON_SIZE_ICON, 0.0f, mono_color);
-}
-
-void UI_icon_draw_aspect_color(float x, float y, int icon_id, float aspect, const float rgb[3], const char mono_color[4])
-{
- int draw_size = get_draw_size(ICON_SIZE_ICON);
- icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, ICON_SIZE_ICON, draw_size, false, mono_color);
-}
-
-void UI_icon_draw_desaturate(float x, float y, int icon_id, float aspect, float alpha, float desaturate, const char mono_color[4])
-{
- icon_draw_at_size(x, y, icon_id, aspect, alpha, ICON_SIZE_ICON, desaturate, mono_color);
+ switch (idcode) {
+ case ID_AC:
+ return ICON_ACTION;
+ case ID_AR:
+ return ICON_ARMATURE_DATA;
+ case ID_BR:
+ return ICON_BRUSH_DATA;
+ case ID_CA:
+ return ICON_CAMERA_DATA;
+ case ID_CF:
+ return ICON_FILE;
+ case ID_CU:
+ return ICON_CURVE_DATA;
+ case ID_GD:
+ return ICON_GREASEPENCIL;
+ case ID_GR:
+ return ICON_GROUP;
+ case ID_IM:
+ return ICON_IMAGE_DATA;
+ case ID_LA:
+ return ICON_LIGHT_DATA;
+ case ID_LS:
+ return ICON_LINE_DATA;
+ case ID_LT:
+ return ICON_LATTICE_DATA;
+ case ID_MA:
+ return ICON_MATERIAL_DATA;
+ case ID_MB:
+ return ICON_META_DATA;
+ case ID_MC:
+ return ICON_TRACKER;
+ case ID_ME:
+ return ICON_MESH_DATA;
+ case ID_MSK:
+ return ICON_MOD_MASK; /* TODO! this would need its own icon! */
+ case ID_NT:
+ return ICON_NODETREE;
+ case ID_OB:
+ return ICON_OBJECT_DATA;
+ case ID_PA:
+ return ICON_PARTICLE_DATA;
+ case ID_PAL:
+ return ICON_COLOR; /* TODO! this would need its own icon! */
+ case ID_PC:
+ return ICON_CURVE_BEZCURVE; /* TODO! this would need its own icon! */
+ case ID_LP:
+ return ICON_LIGHTPROBE_CUBEMAP;
+ case ID_SCE:
+ return ICON_SCENE_DATA;
+ case ID_SPK:
+ return ICON_SPEAKER;
+ case ID_SO:
+ return ICON_SOUND;
+ case ID_TE:
+ return ICON_TEXTURE_DATA;
+ case ID_TXT:
+ return ICON_TEXT;
+ case ID_VF:
+ return ICON_FONT_DATA;
+ case ID_WO:
+ return ICON_WORLD_DATA;
+ default:
+ return ICON_NONE;
+ }
+}
+
+static void icon_draw_at_size(float x,
+ float y,
+ int icon_id,
+ float aspect,
+ float alpha,
+ enum eIconSizes size,
+ const float desaturate,
+ const char mono_color[4])
+{
+ int draw_size = get_draw_size(size);
+ icon_draw_size(x, y, icon_id, aspect, alpha, NULL, size, draw_size, desaturate, mono_color);
+}
+
+void UI_icon_draw_aspect(
+ float x, float y, int icon_id, float aspect, float alpha, const char mono_color[4])
+{
+ icon_draw_at_size(x, y, icon_id, aspect, alpha, ICON_SIZE_ICON, 0.0f, mono_color);
+}
+
+void UI_icon_draw_aspect_color(
+ float x, float y, int icon_id, float aspect, const float rgb[3], const char mono_color[4])
+{
+ int draw_size = get_draw_size(ICON_SIZE_ICON);
+ icon_draw_size(x, y, icon_id, aspect, 1.0f, rgb, ICON_SIZE_ICON, draw_size, false, mono_color);
+}
+
+void UI_icon_draw_desaturate(float x,
+ float y,
+ int icon_id,
+ float aspect,
+ float alpha,
+ float desaturate,
+ const char mono_color[4])
+{
+ icon_draw_at_size(x, y, icon_id, aspect, alpha, ICON_SIZE_ICON, desaturate, mono_color);
}
/* draws icon with dpi scale factor */
void UI_icon_draw(float x, float y, int icon_id)
{
- UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f, NULL);
+ UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, 1.0f, NULL);
}
void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha)
{
- UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, alpha, NULL);
+ UI_icon_draw_aspect(x, y, icon_id, 1.0f / UI_DPI_FAC, alpha, NULL);
}
void UI_icon_draw_size(float x, float y, int size, int icon_id, float alpha)
{
- icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, ICON_SIZE_ICON, size, false, NULL);
+ icon_draw_size(x, y, icon_id, 1.0f, alpha, NULL, ICON_SIZE_ICON, size, false, NULL);
}
void UI_icon_draw_preview(float x, float y, int icon_id)
{
- icon_draw_at_size(x, y, icon_id, 1.0f, 1.0f, ICON_SIZE_PREVIEW, false, NULL);
+ icon_draw_at_size(x, y, icon_id, 1.0f, 1.0f, ICON_SIZE_PREVIEW, false, NULL);
}
void UI_icon_draw_preview_aspect(float x, float y, int icon_id, float aspect)
{
- icon_draw_at_size(x, y, icon_id, aspect, 1.0f, ICON_SIZE_PREVIEW, false, NULL);
+ icon_draw_at_size(x, y, icon_id, aspect, 1.0f, ICON_SIZE_PREVIEW, false, NULL);
}
-void UI_icon_draw_preview_aspect_size(float x, float y, int icon_id, float aspect, float alpha, int size)
+void UI_icon_draw_preview_aspect_size(
+ float x, float y, int icon_id, float aspect, float alpha, int size)
{
- icon_draw_size(x, y, icon_id, aspect, alpha, NULL, ICON_SIZE_PREVIEW, size, false, NULL);
+ icon_draw_size(x, y, icon_id, aspect, alpha, NULL, ICON_SIZE_PREVIEW, size, false, NULL);
}
diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c
index 2af9bbf9e88..0992ee95fd7 100644
--- a/source/blender/editors/interface/interface_icons_event.c
+++ b/source/blender/editors/interface/interface_icons_event.c
@@ -77,212 +77,218 @@
#include "interface_intern.h"
static void icon_draw_rect_input_small_text_ex(
- const rctf *rect, const float color[4], const float margin[2], const char *str,
- int font_size)
+ const rctf *rect, const float color[4], const float margin[2], const char *str, int font_size)
{
- BLF_batch_draw_flush();
- const int font_id = BLF_default();
- BLF_color4fv(font_id, color);
- BLF_size(font_id, font_size * U.pixelsize, U.dpi);
- BLF_position(font_id, rect->xmin + margin[0] * 2, rect->ymin + margin[1] * 5, 0.0f);
- BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
- BLF_batch_draw_flush();
+ BLF_batch_draw_flush();
+ const int font_id = BLF_default();
+ BLF_color4fv(font_id, color);
+ BLF_size(font_id, font_size * U.pixelsize, U.dpi);
+ BLF_position(font_id, rect->xmin + margin[0] * 2, rect->ymin + margin[1] * 5, 0.0f);
+ BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_batch_draw_flush();
}
-static void icon_draw_rect_input_small_text(
- const rctf *rect, const float color[4], const float margin[2], const char *str)
+static void icon_draw_rect_input_small_text(const rctf *rect,
+ const float color[4],
+ const float margin[2],
+ const char *str)
{
- icon_draw_rect_input_small_text_ex(rect, color, margin, str, 8);
+ icon_draw_rect_input_small_text_ex(rect, color, margin, str, 8);
}
-static void icon_draw_rect_input_default_text(
- const rctf *rect,
- const float color[4], const float margin[2], const char *str)
+static void icon_draw_rect_input_default_text(const rctf *rect,
+ const float color[4],
+ const float margin[2],
+ const char *str)
{
- BLF_batch_draw_flush();
- const int font_id = BLF_default();
- BLF_color4fv(font_id, color);
- BLF_position(font_id, (int)(rect->xmin + margin[0] * 5), (int)(rect->ymin + margin[1] * 5), 0.0f);
- BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
- BLF_batch_draw_flush();
+ BLF_batch_draw_flush();
+ const int font_id = BLF_default();
+ BLF_color4fv(font_id, color);
+ BLF_position(
+ font_id, (int)(rect->xmin + margin[0] * 5), (int)(rect->ymin + margin[1] * 5), 0.0f);
+ BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_batch_draw_flush();
}
-static void icon_draw_rect_input_mono_text(
- const rctf *rect,
- const float color[4], const float margin[2], const char *str)
+static void icon_draw_rect_input_mono_text(const rctf *rect,
+ const float color[4],
+ const float margin[2],
+ const char *str)
{
- BLF_batch_draw_flush();
- const int font_id = blf_mono_font;
- BLF_color4fv(font_id, color);
- BLF_size(font_id, 20 * U.pixelsize, U.dpi);
- BLF_position(font_id, (int)(rect->xmin + margin[0] * 5), (int)(rect->ymin + margin[1] * 5), 0.0f);
- BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
- BLF_batch_draw_flush();
+ BLF_batch_draw_flush();
+ const int font_id = blf_mono_font;
+ BLF_color4fv(font_id, color);
+ BLF_size(font_id, 20 * U.pixelsize, U.dpi);
+ BLF_position(
+ font_id, (int)(rect->xmin + margin[0] * 5), (int)(rect->ymin + margin[1] * 5), 0.0f);
+ BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_batch_draw_flush();
}
static void icon_draw_rect_input_line_prim(
- const rctf *rect,
- const float color[4],
- const int prim,
- const char lines[][2], int lines_len)
+ const rctf *rect, const float color[4], const int prim, const char lines[][2], int lines_len)
{
- GPU_line_smooth(true);
- GPU_blend(true);
- BLI_assert(ELEM(prim, GPU_PRIM_LINE_LOOP, GPU_PRIM_LINE_STRIP));
- const uint pos_id = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(color);
- immBegin(prim, lines_len);
- float w_inv = BLI_rctf_size_x(rect) / 255.0f;
- float h_inv = BLI_rctf_size_y(rect) / 255.0f;
- for (int i = 0; i < lines_len; i++) {
- immVertex2f(
- pos_id,
- round_fl_to_int(rect->xmin + ((float)lines[i][0] * w_inv)),
- round_fl_to_int(rect->ymin + ((float)lines[i][1] * h_inv))
- );
- }
- immEnd();
- immUnbindProgram();
- GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_line_smooth(true);
+ GPU_blend(true);
+ BLI_assert(ELEM(prim, GPU_PRIM_LINE_LOOP, GPU_PRIM_LINE_STRIP));
+ const uint pos_id = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+ immBegin(prim, lines_len);
+ float w_inv = BLI_rctf_size_x(rect) / 255.0f;
+ float h_inv = BLI_rctf_size_y(rect) / 255.0f;
+ for (int i = 0; i < lines_len; i++) {
+ immVertex2f(pos_id,
+ round_fl_to_int(rect->xmin + ((float)lines[i][0] * w_inv)),
+ round_fl_to_int(rect->ymin + ((float)lines[i][1] * h_inv)));
+ }
+ immEnd();
+ immUnbindProgram();
+ GPU_line_smooth(false);
+ GPU_blend(false);
}
-void icon_draw_rect_input(
- float x, float y, int w, int h, float UNUSED(alpha),
- short event_type, short UNUSED(event_value))
+void icon_draw_rect_input(float x,
+ float y,
+ int w,
+ int h,
+ float UNUSED(alpha),
+ short event_type,
+ short UNUSED(event_value))
{
- float color[4];
- const float margin[2] = {w / 20.0f, h / 20.0f};
- GPU_line_width(1.0f);
- UI_GetThemeColor4fv(TH_TEXT, color);
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(
- false,
- (int)x,
- (int)y,
- (int)(x + w),
- (int)(y + h), 4.0f, color
- );
+ float color[4];
+ const float margin[2] = {w / 20.0f, h / 20.0f};
+ GPU_line_width(1.0f);
+ UI_GetThemeColor4fv(TH_TEXT, color);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(false, (int)x, (int)y, (int)(x + w), (int)(y + h), 4.0f, color);
- const rctf rect = {
- .xmin = x,
- .ymin = y,
- .xmax = x + w,
- .ymax = y + h,
- };
+ const rctf rect = {
+ .xmin = x,
+ .ymin = y,
+ .xmax = x + w,
+ .ymax = y + h,
+ };
- const bool simple_text = false;
+ const bool simple_text = false;
- if ((event_type >= AKEY) || (ZKEY <= event_type)) {
- char str[2] = {'A' + (event_type - AKEY), '\0'};
- icon_draw_rect_input_default_text(&rect, color, margin, str);
- }
- if ((event_type >= F1KEY) || (F12KEY <= event_type)) {
- char str[3] = {'F', '1' + (event_type - F1KEY), '\0'};
- icon_draw_rect_input_default_text(&rect, color, margin, str);
- }
- else if (event_type == LEFTSHIFTKEY) {
- if (simple_text) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Shift");
- }
- else {
- rctf rect_ofs = rect;
- BLI_rctf_translate(&rect_ofs, (w / -14.0f), (w / -14.0f));
- icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa7, 0x0});
- }
- }
- else if (event_type == LEFTCTRLKEY) {
- if (simple_text) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Ctrl");
- }
- else {
- rctf rect_ofs = rect;
- BLI_rctf_translate(&rect_ofs, (w / -16.0f), 0.0f);
- icon_draw_rect_input_default_text(&rect_ofs, color, margin, "^");
- }
- }
- else if (event_type == LEFTALTKEY) {
- if (simple_text) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Alt");
- }
- else {
- rctf rect_ofs = rect;
- BLI_rctf_translate(&rect_ofs, (w / -8.0f), 0.0f);
- icon_draw_rect_input_default_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x8c, 0xa5, 0x0});
- }
- }
- else if (event_type == OSKEY) {
- icon_draw_rect_input_small_text(&rect, color, margin, "OS");
- }
- else if (event_type == DELKEY) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Del");
- }
- else if (event_type == TABKEY) {
- if (simple_text) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Tab");
- }
- else {
- rctf rect_ofs = rect;
- BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
- icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x86, 0xb9, 0x0});
- }
- }
- else if (event_type == HOMEKEY) {
- if (simple_text) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Home");
- }
- else {
- rctf rect_ofs = rect;
- BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
- icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa4, 0x0});
- }
- }
- else if (event_type == ENDKEY) {
- if (simple_text) {
- icon_draw_rect_input_small_text(&rect, color, margin, "End");
- }
- else {
- rctf rect_ofs = rect;
- BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
- icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa5, 0x0});
- }
- }
- else if (event_type == RETKEY) {
- if (simple_text) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Ret");
- }
- else {
- rctf rect_ofs = rect;
- BLI_rctf_translate(&rect_ofs, (w / -8.0f), (w / -6.0f));
- icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x8f, 0x8e, 0x0});
- }
- }
- else if (event_type == ESCKEY) {
- icon_draw_rect_input_small_text(&rect, color, margin, "Esc");
- }
- else if (event_type == PAGEUPKEY) {
- icon_draw_rect_input_small_text_ex(&rect, color, margin, (const char[]){'P', 0xe2, 0x86, 0x91, 0x0}, 10);
- }
- else if (event_type == PAGEDOWNKEY) {
- icon_draw_rect_input_small_text_ex(&rect, color, margin, (const char[]){'P', 0xe2, 0x86, 0x93, 0x0}, 10);
- }
- else if (event_type == LEFTARROWKEY) {
- icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x90, 0x0});
- }
- else if (event_type == UPARROWKEY) {
- icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x91, 0x0});
- }
- else if (event_type == RIGHTARROWKEY) {
- icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x92, 0x0});
- }
- else if (event_type == DOWNARROWKEY) {
- icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x93, 0x0});
- }
- else if (event_type == SPACEKEY) {
- const uchar lines[] = {60, 118, 60, 60, 195, 60, 195, 118};
- icon_draw_rect_input_line_prim(
- &rect, color, GPU_PRIM_LINE_STRIP,
- (const void *)lines, ARRAY_SIZE(lines) / 2);
- }
+ if ((event_type >= AKEY) || (ZKEY <= event_type)) {
+ char str[2] = {'A' + (event_type - AKEY), '\0'};
+ icon_draw_rect_input_default_text(&rect, color, margin, str);
+ }
+ if ((event_type >= F1KEY) || (F12KEY <= event_type)) {
+ char str[3] = {'F', '1' + (event_type - F1KEY), '\0'};
+ icon_draw_rect_input_default_text(&rect, color, margin, str);
+ }
+ else if (event_type == LEFTSHIFTKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Shift");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -14.0f), (w / -14.0f));
+ icon_draw_rect_input_mono_text(
+ &rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa7, 0x0});
+ }
+ }
+ else if (event_type == LEFTCTRLKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Ctrl");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -16.0f), 0.0f);
+ icon_draw_rect_input_default_text(&rect_ofs, color, margin, "^");
+ }
+ }
+ else if (event_type == LEFTALTKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Alt");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -8.0f), 0.0f);
+ icon_draw_rect_input_default_text(
+ &rect_ofs, color, margin, (const char[]){0xe2, 0x8c, 0xa5, 0x0});
+ }
+ }
+ else if (event_type == OSKEY) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "OS");
+ }
+ else if (event_type == DELKEY) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Del");
+ }
+ else if (event_type == TABKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Tab");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
+ icon_draw_rect_input_mono_text(
+ &rect_ofs, color, margin, (const char[]){0xe2, 0x86, 0xb9, 0x0});
+ }
+ }
+ else if (event_type == HOMEKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Home");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
+ icon_draw_rect_input_mono_text(
+ &rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa4, 0x0});
+ }
+ }
+ else if (event_type == ENDKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "End");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
+ icon_draw_rect_input_mono_text(
+ &rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa5, 0x0});
+ }
+ }
+ else if (event_type == RETKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Ret");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -8.0f), (w / -6.0f));
+ icon_draw_rect_input_mono_text(
+ &rect_ofs, color, margin, (const char[]){0xe2, 0x8f, 0x8e, 0x0});
+ }
+ }
+ else if (event_type == ESCKEY) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Esc");
+ }
+ else if (event_type == PAGEUPKEY) {
+ icon_draw_rect_input_small_text_ex(
+ &rect, color, margin, (const char[]){'P', 0xe2, 0x86, 0x91, 0x0}, 10);
+ }
+ else if (event_type == PAGEDOWNKEY) {
+ icon_draw_rect_input_small_text_ex(
+ &rect, color, margin, (const char[]){'P', 0xe2, 0x86, 0x93, 0x0}, 10);
+ }
+ else if (event_type == LEFTARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x90, 0x0});
+ }
+ else if (event_type == UPARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x91, 0x0});
+ }
+ else if (event_type == RIGHTARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x92, 0x0});
+ }
+ else if (event_type == DOWNARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x93, 0x0});
+ }
+ else if (event_type == SPACEKEY) {
+ const uchar lines[] = {60, 118, 60, 60, 195, 60, 195, 118};
+ icon_draw_rect_input_line_prim(
+ &rect, color, GPU_PRIM_LINE_STRIP, (const void *)lines, ARRAY_SIZE(lines) / 2);
+ }
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 3580b2ff3a5..86ca2241881 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
#ifndef __INTERFACE_INTERN_H__
#define __INTERFACE_INTERN_H__
@@ -47,81 +46,82 @@ struct wmTimer;
/* ****************** general defines ************** */
-#define RNA_NO_INDEX -1
-#define RNA_ENUM_VALUE -2
+#define RNA_NO_INDEX -1
+#define RNA_ENUM_VALUE -2
#define UI_MENU_PADDING (int)(0.2f * UI_UNIT_Y)
-#define UI_MENU_WIDTH_MIN (UI_UNIT_Y * 9)
+#define UI_MENU_WIDTH_MIN (UI_UNIT_Y * 9)
/* some extra padding added to menus containing submenu icons */
#define UI_MENU_SUBMENU_PADDING (6 * UI_DPI_FAC)
/* menu scrolling */
-#define UI_MENU_SCROLL_ARROW 12
-#define UI_MENU_SCROLL_MOUSE (UI_MENU_SCROLL_ARROW + 2)
-#define UI_MENU_SCROLL_PAD 4
+#define UI_MENU_SCROLL_ARROW 12
+#define UI_MENU_SCROLL_MOUSE (UI_MENU_SCROLL_ARROW + 2)
+#define UI_MENU_SCROLL_PAD 4
/* panel limits */
-#define UI_PANEL_MINX 100
-#define UI_PANEL_MINY 70
+#define UI_PANEL_MINX 100
+#define UI_PANEL_MINY 70
/* popover width (multiplied by 'U.widget_unit') */
#define UI_POPOVER_WIDTH_UNITS 10
/* uiBut->flag */
enum {
- UI_SELECT = (1 << 0), /* use when the button is pressed */
- UI_SCROLLED = (1 << 1), /* temp hidden, scrolled away */
- UI_ACTIVE = (1 << 2),
- UI_HAS_ICON = (1 << 3),
- UI_HIDDEN = (1 << 4),
- UI_SELECT_DRAW = (1 << 5), /* Display selected, doesn't impact interaction. */
- /* warn: rest of uiBut->flag in UI_interface.h */
+ UI_SELECT = (1 << 0), /* use when the button is pressed */
+ UI_SCROLLED = (1 << 1), /* temp hidden, scrolled away */
+ UI_ACTIVE = (1 << 2),
+ UI_HAS_ICON = (1 << 3),
+ UI_HIDDEN = (1 << 4),
+ UI_SELECT_DRAW = (1 << 5), /* Display selected, doesn't impact interaction. */
+ /* warn: rest of uiBut->flag in UI_interface.h */
};
/* some buttons display icons only under special conditions
* (e.g. 'x' icon in search menu) - used with ui_but_icon_extra_get */
typedef enum uiButExtraIconType {
- UI_BUT_ICONEXTRA_NONE = 1,
- UI_BUT_ICONEXTRA_CLEAR,
- UI_BUT_ICONEXTRA_EYEDROPPER,
+ UI_BUT_ICONEXTRA_NONE = 1,
+ UI_BUT_ICONEXTRA_CLEAR,
+ UI_BUT_ICONEXTRA_EYEDROPPER,
} uiButExtraIconType;
/* uiBut->dragflag */
enum {
- UI_BUT_DRAGPOIN_FREE = (1 << 0),
+ UI_BUT_DRAGPOIN_FREE = (1 << 0),
};
/* but->pie_dir */
typedef enum RadialDirection {
- UI_RADIAL_NONE = -1,
- UI_RADIAL_N = 0,
- UI_RADIAL_NE = 1,
- UI_RADIAL_E = 2,
- UI_RADIAL_SE = 3,
- UI_RADIAL_S = 4,
- UI_RADIAL_SW = 5,
- UI_RADIAL_W = 6,
- UI_RADIAL_NW = 7,
+ UI_RADIAL_NONE = -1,
+ UI_RADIAL_N = 0,
+ UI_RADIAL_NE = 1,
+ UI_RADIAL_E = 2,
+ UI_RADIAL_SE = 3,
+ UI_RADIAL_S = 4,
+ UI_RADIAL_SW = 5,
+ UI_RADIAL_W = 6,
+ UI_RADIAL_NW = 7,
} RadialDirection;
-extern const char ui_radial_dir_order[8];
-extern const char ui_radial_dir_to_numpad[8];
+extern const char ui_radial_dir_order[8];
+extern const char ui_radial_dir_to_numpad[8];
extern const short ui_radial_dir_to_angle[8];
/* internal panel drawing defines */
-#define PNL_GRID (UI_UNIT_Y / 5) /* 4 default */
-#define PNL_HEADER (UI_UNIT_Y * 1.2) /* 24 default */
+#define PNL_GRID (UI_UNIT_Y / 5) /* 4 default */
+#define PNL_HEADER (UI_UNIT_Y * 1.2) /* 24 default */
/* bit button defines */
/* Bit operations */
-#define UI_BITBUT_TEST(a, b) (((a) & (1 << (b))) != 0)
-#define UI_BITBUT_VALUE_TOGGLED(a, b) ((a) ^ (1 << (b)))
-#define UI_BITBUT_VALUE_ENABLED(a, b) ((a) | (1 << (b)))
-#define UI_BITBUT_VALUE_DISABLED(a, b) ((a) & ~(1 << (b)))
+#define UI_BITBUT_TEST(a, b) (((a) & (1 << (b))) != 0)
+#define UI_BITBUT_VALUE_TOGGLED(a, b) ((a) ^ (1 << (b)))
+#define UI_BITBUT_VALUE_ENABLED(a, b) ((a) | (1 << (b)))
+#define UI_BITBUT_VALUE_DISABLED(a, b) ((a) & ~(1 << (b)))
/* bit-row */
-#define UI_BITBUT_ROW(min, max) (((max) >= 31 ? 0xFFFFFFFF : (1 << ((max) + 1)) - 1) - ((min) ? ((1 << (min)) - 1) : 0) )
+#define UI_BITBUT_ROW(min, max) \
+ (((max) >= 31 ? 0xFFFFFFFF : (1 << ((max) + 1)) - 1) - ((min) ? ((1 << (min)) - 1) : 0))
/* split numbuts by ':' and align l/r */
#define USE_NUMBUTS_LR_ALIGN
@@ -131,20 +131,20 @@ extern const short ui_radial_dir_to_angle[8];
/* PieMenuData->flags */
enum {
- /** pie menu item collision is detected at 90 degrees */
- UI_PIE_DEGREES_RANGE_LARGE = (1 << 0),
- /** use initial center of pie menu to calculate direction */
- UI_PIE_INITIAL_DIRECTION = (1 << 1),
- /** pie menu is drag style */
- UI_PIE_DRAG_STYLE = (1 << 2),
- /** mouse not far enough from center position */
- UI_PIE_INVALID_DIR = (1 << 3),
- /** pie menu changed to click style, click to confirm */
- UI_PIE_CLICK_STYLE = (1 << 4),
- /** pie animation finished, do not calculate any more motion */
- UI_PIE_ANIMATION_FINISHED = (1 << 5),
- /** pie gesture selection has been done, now wait for mouse motion to end */
- UI_PIE_GESTURE_END_WAIT = (1 << 6),
+ /** pie menu item collision is detected at 90 degrees */
+ UI_PIE_DEGREES_RANGE_LARGE = (1 << 0),
+ /** use initial center of pie menu to calculate direction */
+ UI_PIE_INITIAL_DIRECTION = (1 << 1),
+ /** pie menu is drag style */
+ UI_PIE_DRAG_STYLE = (1 << 2),
+ /** mouse not far enough from center position */
+ UI_PIE_INVALID_DIR = (1 << 3),
+ /** pie menu changed to click style, click to confirm */
+ UI_PIE_CLICK_STYLE = (1 << 4),
+ /** pie animation finished, do not calculate any more motion */
+ UI_PIE_ANIMATION_FINISHED = (1 << 5),
+ /** pie gesture selection has been done, now wait for mouse motion to end */
+ UI_PIE_GESTURE_END_WAIT = (1 << 6),
};
#define PIE_CLICK_THRESHOLD_SQ 50.0f
@@ -153,294 +153,294 @@ enum {
#define PIE_MAX_ITEMS 8
struct uiBut {
- struct uiBut *next, *prev;
- int flag, drawflag;
- eButType type;
- eButPointerType pointype;
- short bit, bitnr, retval, strwidth, alignnr;
- short ofs, pos, selsta, selend;
-
- char *str;
- char strdata[UI_MAX_NAME_STR];
- char drawstr[UI_MAX_DRAW_STR];
-
- rctf rect; /* block relative coords */
-
- char *poin;
- float hardmin, hardmax, softmin, softmax;
-
- /* both these values use depends on the button type
- * (polymorphic struct or union would be nicer for this stuff) */
-
- /* (type == UI_BTYPE_HSVCUBE), Use UI_GRAD_* values.
- * (type == UI_BTYPE_NUM), Use to store RNA 'step' value, for dragging and click-step.
- * (type == UI_BTYPE_LABEL), Use (a1 == 1.0f) to use a2 as a blending factor (wow, this is imaginative!).
- * (type == UI_BTYPE_SCROLL) Use as scroll size.
- * (type == UI_BTYPE_SEARCH_MENU) Use as number or rows.
- * (type == UI_BTYPE_COLOR) Use as indication of color palette
- * (type == UI_BTYPE_PROGRESS_BAR) Use to store progress (0..1).
- */
- float a1;
-
- /* (type == UI_BTYPE_HSVCIRCLE ), Use to store the luminosity.
- * (type == UI_BTYPE_NUM), Use to store RNA 'precision' value, for dragging and click-step.
- * (type == UI_BTYPE_LABEL), If (a1 == 1.0f) use a2 as a blending factor.
- * (type == UI_BTYPE_SEARCH_MENU) Use as number or columns.
- * (type == UI_BTYPE_COLOR) Use as index in palette (not so good, needs refactor)
- */
- float a2;
-
- uchar col[4];
-
- uiButHandleFunc func;
- void *func_arg1;
- void *func_arg2;
-
- uiButHandleNFunc funcN;
- void *func_argN;
-
- struct bContextStore *context;
-
- uiButCompleteFunc autocomplete_func;
- void *autofunc_arg;
-
- uiButSearchCreateFunc search_create_func;
- uiButSearchFunc search_func;
- bool free_search_arg;
- void *search_arg;
-
- uiButHandleRenameFunc rename_func;
- void *rename_arg1;
- void *rename_orig;
-
- /** Run an action when holding the button down. */
- uiButHandleHoldFunc hold_func;
- void *hold_argN;
-
- const char *tip;
- uiButToolTipFunc tip_func;
- void *tip_argN;
-
- /** info on why button is disabled, displayed in tooltip */
- const char *disabled_info;
-
- BIFIconID icon;
- /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */
- char dt;
- /** direction in a pie menu, used for collision detection (RadialDirection) */
- signed char pie_dir;
- /** could be made into a single flag */
- bool changed;
- /** so buttons can support unit systems which are not RNA */
- uchar unit_type;
- short modifier_key;
- short iconadd;
-
- /* UI_BTYPE_BLOCK data */
- uiBlockCreateFunc block_create_func;
-
- /* UI_BTYPE_PULLDOWN/UI_BTYPE_MENU data */
- uiMenuCreateFunc menu_create_func;
-
- uiMenuStepFunc menu_step_func;
-
- /* RNA data */
- struct PointerRNA rnapoin;
- struct PropertyRNA *rnaprop;
- int rnaindex;
-
- struct PointerRNA rnasearchpoin;
- struct PropertyRNA *rnasearchprop;
-
- /* Operator data */
- struct wmOperatorType *optype;
- struct PointerRNA *opptr;
- short opcontext;
- uchar menu_key; /* 'a'-'z', always lower case */
-
- /* Draggable data, type is WM_DRAG_... */
- char dragtype;
- short dragflag;
- void *dragpoin;
- struct ImBuf *imb;
- float imb_scale;
-
- /* active button data */
- struct uiHandleButtonData *active;
-
- /* Custom button data. */
- void *custom_data;
-
- char *editstr;
- double *editval;
- float *editvec;
- void *editcoba;
- void *editcumap;
-
- uiButPushedStateFunc pushed_state_func;
- void *pushed_state_arg;
-
- /* pointer back */
- uiBlock *block;
+ struct uiBut *next, *prev;
+ int flag, drawflag;
+ eButType type;
+ eButPointerType pointype;
+ short bit, bitnr, retval, strwidth, alignnr;
+ short ofs, pos, selsta, selend;
+
+ char *str;
+ char strdata[UI_MAX_NAME_STR];
+ char drawstr[UI_MAX_DRAW_STR];
+
+ rctf rect; /* block relative coords */
+
+ char *poin;
+ float hardmin, hardmax, softmin, softmax;
+
+ /* both these values use depends on the button type
+ * (polymorphic struct or union would be nicer for this stuff) */
+
+ /* (type == UI_BTYPE_HSVCUBE), Use UI_GRAD_* values.
+ * (type == UI_BTYPE_NUM), Use to store RNA 'step' value, for dragging and click-step.
+ * (type == UI_BTYPE_LABEL), Use (a1 == 1.0f) to use a2 as a blending factor (wow, this is imaginative!).
+ * (type == UI_BTYPE_SCROLL) Use as scroll size.
+ * (type == UI_BTYPE_SEARCH_MENU) Use as number or rows.
+ * (type == UI_BTYPE_COLOR) Use as indication of color palette
+ * (type == UI_BTYPE_PROGRESS_BAR) Use to store progress (0..1).
+ */
+ float a1;
+
+ /* (type == UI_BTYPE_HSVCIRCLE ), Use to store the luminosity.
+ * (type == UI_BTYPE_NUM), Use to store RNA 'precision' value, for dragging and click-step.
+ * (type == UI_BTYPE_LABEL), If (a1 == 1.0f) use a2 as a blending factor.
+ * (type == UI_BTYPE_SEARCH_MENU) Use as number or columns.
+ * (type == UI_BTYPE_COLOR) Use as index in palette (not so good, needs refactor)
+ */
+ float a2;
+
+ uchar col[4];
+
+ uiButHandleFunc func;
+ void *func_arg1;
+ void *func_arg2;
+
+ uiButHandleNFunc funcN;
+ void *func_argN;
+
+ struct bContextStore *context;
+
+ uiButCompleteFunc autocomplete_func;
+ void *autofunc_arg;
+
+ uiButSearchCreateFunc search_create_func;
+ uiButSearchFunc search_func;
+ bool free_search_arg;
+ void *search_arg;
+
+ uiButHandleRenameFunc rename_func;
+ void *rename_arg1;
+ void *rename_orig;
+
+ /** Run an action when holding the button down. */
+ uiButHandleHoldFunc hold_func;
+ void *hold_argN;
+
+ const char *tip;
+ uiButToolTipFunc tip_func;
+ void *tip_argN;
+
+ /** info on why button is disabled, displayed in tooltip */
+ const char *disabled_info;
+
+ BIFIconID icon;
+ /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */
+ char dt;
+ /** direction in a pie menu, used for collision detection (RadialDirection) */
+ signed char pie_dir;
+ /** could be made into a single flag */
+ bool changed;
+ /** so buttons can support unit systems which are not RNA */
+ uchar unit_type;
+ short modifier_key;
+ short iconadd;
+
+ /* UI_BTYPE_BLOCK data */
+ uiBlockCreateFunc block_create_func;
+
+ /* UI_BTYPE_PULLDOWN/UI_BTYPE_MENU data */
+ uiMenuCreateFunc menu_create_func;
+
+ uiMenuStepFunc menu_step_func;
+
+ /* RNA data */
+ struct PointerRNA rnapoin;
+ struct PropertyRNA *rnaprop;
+ int rnaindex;
+
+ struct PointerRNA rnasearchpoin;
+ struct PropertyRNA *rnasearchprop;
+
+ /* Operator data */
+ struct wmOperatorType *optype;
+ struct PointerRNA *opptr;
+ short opcontext;
+ uchar menu_key; /* 'a'-'z', always lower case */
+
+ /* Draggable data, type is WM_DRAG_... */
+ char dragtype;
+ short dragflag;
+ void *dragpoin;
+ struct ImBuf *imb;
+ float imb_scale;
+
+ /* active button data */
+ struct uiHandleButtonData *active;
+
+ /* Custom button data. */
+ void *custom_data;
+
+ char *editstr;
+ double *editval;
+ float *editvec;
+ void *editcoba;
+ void *editcumap;
+
+ uiButPushedStateFunc pushed_state_func;
+ void *pushed_state_arg;
+
+ /* pointer back */
+ uiBlock *block;
};
typedef struct uiButTab {
- uiBut but;
- struct MenuType *menu;
+ uiBut but;
+ struct MenuType *menu;
} uiButTab;
typedef struct ColorPicker {
- struct ColorPicker *next, *prev;
- /** Color data, may be HSV or HSL. */
- float color_data[3];
- /** Initial color data (detect changes). */
- float color_data_init[3];
- bool is_init;
- /** Cubic saturation for the color wheel. */
- bool use_color_cubic;
- bool use_color_lock;
- bool use_luminosity_lock;
- float luminosity_lock_value;
+ struct ColorPicker *next, *prev;
+ /** Color data, may be HSV or HSL. */
+ float color_data[3];
+ /** Initial color data (detect changes). */
+ float color_data_init[3];
+ bool is_init;
+ /** Cubic saturation for the color wheel. */
+ bool use_color_cubic;
+ bool use_color_lock;
+ bool use_luminosity_lock;
+ float luminosity_lock_value;
} ColorPicker;
typedef struct ColorPickerData {
- ListBase list;
+ ListBase list;
} ColorPickerData;
struct PieMenuData {
- /** store title and icon to allow access when pie levels are created */
- const char *title;
- int icon;
-
- float pie_dir[2];
- float pie_center_init[2];
- float pie_center_spawned[2];
- float last_pos[2];
- double duration_gesture;
- int flags;
- /** initial event used to fire the pie menu, store here so we can query for release */
- int event;
- float alphafac;
+ /** store title and icon to allow access when pie levels are created */
+ const char *title;
+ int icon;
+
+ float pie_dir[2];
+ float pie_center_init[2];
+ float pie_center_spawned[2];
+ float last_pos[2];
+ double duration_gesture;
+ int flags;
+ /** initial event used to fire the pie menu, store here so we can query for release */
+ int event;
+ float alphafac;
};
/* uiBlock.content_hints */
enum eBlockContentHints {
- /** In a menu block, if there is a single sub-menu button, we add some
- * padding to the right to put nicely aligned triangle icons there. */
- UI_BLOCK_CONTAINS_SUBMENU_BUT = (1 << 0),
+ /** In a menu block, if there is a single sub-menu button, we add some
+ * padding to the right to put nicely aligned triangle icons there. */
+ UI_BLOCK_CONTAINS_SUBMENU_BUT = (1 << 0),
};
struct uiBlock {
- uiBlock *next, *prev;
+ uiBlock *next, *prev;
- ListBase buttons;
- Panel *panel;
- uiBlock *oldblock;
+ ListBase buttons;
+ Panel *panel;
+ uiBlock *oldblock;
- ListBase butstore; /* UI_butstore_* runtime function */
+ ListBase butstore; /* UI_butstore_* runtime function */
- ListBase layouts;
- struct uiLayout *curlayout;
+ ListBase layouts;
+ struct uiLayout *curlayout;
- ListBase contexts;
+ ListBase contexts;
- char name[UI_MAX_NAME_STR];
+ char name[UI_MAX_NAME_STR];
- float winmat[4][4];
+ float winmat[4][4];
- rctf rect;
- float aspect;
+ rctf rect;
+ float aspect;
- uint puphash; /* popup menu hash for memory */
+ uint puphash; /* popup menu hash for memory */
- uiButHandleFunc func;
- void *func_arg1;
- void *func_arg2;
+ uiButHandleFunc func;
+ void *func_arg1;
+ void *func_arg2;
- uiButHandleNFunc funcN;
- void *func_argN;
+ uiButHandleNFunc funcN;
+ void *func_argN;
- uiMenuHandleFunc butm_func;
- void *butm_func_arg;
+ uiMenuHandleFunc butm_func;
+ void *butm_func_arg;
- uiBlockHandleFunc handle_func;
- void *handle_func_arg;
+ uiBlockHandleFunc handle_func;
+ void *handle_func_arg;
- /* custom extra handling */
- int (*block_event_func)(const struct bContext *C, struct uiBlock *, const struct wmEvent *);
+ /* custom extra handling */
+ int (*block_event_func)(const struct bContext *C, struct uiBlock *, const struct wmEvent *);
- /* extra draw function for custom blocks */
- void (*drawextra)(const struct bContext *C, void *idv, void *arg1, void *arg2, rcti *rect);
- void *drawextra_arg1;
- void *drawextra_arg2;
+ /* extra draw function for custom blocks */
+ void (*drawextra)(const struct bContext *C, void *idv, void *arg1, void *arg2, rcti *rect);
+ void *drawextra_arg1;
+ void *drawextra_arg2;
- int flag;
- short alignnr;
- /** Hints about the buttons of this block. Used to avoid iterating over
- * buttons to find out if some criteria is met by any. Instead, check this
- * criteria when adding the button and set a flag here if it's met. */
- short content_hints; /* eBlockContentHints */
+ int flag;
+ short alignnr;
+ /** Hints about the buttons of this block. Used to avoid iterating over
+ * buttons to find out if some criteria is met by any. Instead, check this
+ * criteria when adding the button and set a flag here if it's met. */
+ short content_hints; /* eBlockContentHints */
- char direction;
- /** UI_BLOCK_THEME_STYLE_* */
- char theme_style;
- /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */
- char dt;
- bool auto_open;
- char _pad[5];
- double auto_open_last;
+ char direction;
+ /** UI_BLOCK_THEME_STYLE_* */
+ char theme_style;
+ /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */
+ char dt;
+ bool auto_open;
+ char _pad[5];
+ double auto_open_last;
- const char *lockstr;
+ const char *lockstr;
- char lock;
- /** to keep blocks while drawing and free them afterwards */
- char active;
- /** to avoid tooltip after click */
- char tooltipdisabled;
- /** UI_block_end done? */
- char endblock;
+ char lock;
+ /** to keep blocks while drawing and free them afterwards */
+ char active;
+ /** to avoid tooltip after click */
+ char tooltipdisabled;
+ /** UI_block_end done? */
+ char endblock;
- /** for doing delayed */
- eBlockBoundsCalc bounds_type;
- /** Offset to use when calculating bounds (in pixels). */
- int bounds_offset[2];
- /** for doing delayed */
- int bounds, minbounds;
+ /** for doing delayed */
+ eBlockBoundsCalc bounds_type;
+ /** Offset to use when calculating bounds (in pixels). */
+ int bounds_offset[2];
+ /** for doing delayed */
+ int bounds, minbounds;
- /** pulldowns, to detect outside, can differ per case how it is created */
- rctf safety;
- /** uiSafetyRct list */
- ListBase saferct;
+ /** pulldowns, to detect outside, can differ per case how it is created */
+ rctf safety;
+ /** uiSafetyRct list */
+ ListBase saferct;
- uiPopupBlockHandle *handle; /* handle */
+ uiPopupBlockHandle *handle; /* handle */
- /** use so presets can find the operator,
- * across menus and from nested popups which fail for operator context. */
- struct wmOperator *ui_operator;
+ /** use so presets can find the operator,
+ * across menus and from nested popups which fail for operator context. */
+ struct wmOperator *ui_operator;
- /** XXX hack for dynamic operator enums */
- void *evil_C;
+ /** XXX hack for dynamic operator enums */
+ void *evil_C;
- /** unit system, used a lot for numeric buttons so include here
- * rather then fetching through the scene every time. */
- struct UnitSettings *unit;
- /** \note only accessed by color picker templates. */
- ColorPickerData color_pickers;
+ /** unit system, used a lot for numeric buttons so include here
+ * rather then fetching through the scene every time. */
+ struct UnitSettings *unit;
+ /** \note only accessed by color picker templates. */
+ ColorPickerData color_pickers;
- bool is_color_gamma_picker; /* Block for color picker with gamma baked in. */
+ bool is_color_gamma_picker; /* Block for color picker with gamma baked in. */
- /** display device name used to display this block,
- * used by color widgets to transform colors from/to scene linear
- */
- char display_device[64];
+ /** display device name used to display this block,
+ * used by color widgets to transform colors from/to scene linear
+ */
+ char display_device[64];
- struct PieMenuData pie_data;
+ struct PieMenuData pie_data;
};
typedef struct uiSafetyRct {
- struct uiSafetyRct *next, *prev;
- rctf parent;
- rctf safety;
+ struct uiSafetyRct *next, *prev;
+ rctf parent;
+ rctf safety;
} uiSafetyRct;
/* interface.c */
@@ -449,7 +449,10 @@ void ui_fontscale(short *points, float aspect);
extern void ui_block_to_window_fl(const struct ARegion *ar, uiBlock *block, float *x, float *y);
extern void ui_block_to_window(const struct ARegion *ar, uiBlock *block, int *x, int *y);
-extern void ui_block_to_window_rctf(const struct ARegion *ar, uiBlock *block, rctf *rct_dst, const rctf *rct_src);
+extern void ui_block_to_window_rctf(const struct ARegion *ar,
+ uiBlock *block,
+ rctf *rct_dst,
+ const rctf *rct_src);
extern float ui_block_to_window_scale(const struct ARegion *ar, uiBlock *block);
extern void ui_window_to_block_fl(const struct ARegion *ar, uiBlock *block, float *x, float *y);
extern void ui_window_to_block(const struct ARegion *ar, uiBlock *block, int *x, int *y);
@@ -464,20 +467,27 @@ extern void ui_but_v3_get(uiBut *but, float vec[3]);
extern void ui_but_v3_set(uiBut *but, const float vec[3]);
extern void ui_hsvcircle_vals_from_pos(
- const rcti *rect, const float mx, const float my,
- float *r_val_rad, float *r_val_dist);
-extern void ui_hsvcircle_pos_from_vals(const ColorPicker *cpicker, const rcti *rect, const float *hsv, float *xpos, float *ypos);
-extern void ui_hsvcube_pos_from_vals(const struct uiBut *but, const rcti *rect, const float *hsv, float *xp, float *yp);
-
-extern void ui_but_string_get_ex(
- uiBut *but, char *str, const size_t maxlen,
- const int float_precision, const bool use_exp_float, bool *r_use_exp_float) ATTR_NONNULL(1, 2);
+ const rcti *rect, const float mx, const float my, float *r_val_rad, float *r_val_dist);
+extern void ui_hsvcircle_pos_from_vals(
+ const ColorPicker *cpicker, const rcti *rect, const float *hsv, float *xpos, float *ypos);
+extern void ui_hsvcube_pos_from_vals(
+ const struct uiBut *but, const rcti *rect, const float *hsv, float *xp, float *yp);
+
+extern void ui_but_string_get_ex(uiBut *but,
+ char *str,
+ const size_t maxlen,
+ const int float_precision,
+ const bool use_exp_float,
+ bool *r_use_exp_float) ATTR_NONNULL(1, 2);
extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL();
extern char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size);
extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL();
extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL();
-extern bool ui_but_string_set_eval_num(struct bContext *C, uiBut *but, const char *str, double *value) ATTR_NONNULL();
-extern int ui_but_string_get_max_length(uiBut *but);
+extern bool ui_but_string_set_eval_num(struct bContext *C,
+ uiBut *but,
+ const char *str,
+ double *value) ATTR_NONNULL();
+extern int ui_but_string_get_max_length(uiBut *but);
extern uiBut *ui_but_drag_multi_edit_get(uiBut *but);
void ui_def_but_icon(uiBut *but, const int icon, const int flag);
@@ -498,8 +508,8 @@ extern bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WA
extern bool ui_but_is_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT;
extern bool ui_but_supports_cycling(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT;
-extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT;
+extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT;
+extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT;
void ui_but_override_flag(uiBut *but);
@@ -511,82 +521,84 @@ void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3]);
/* interface_regions.c */
struct uiKeyNavLock {
- /* set when we're using keyinput */
- bool is_keynav;
- /* only used to check if we've moved the cursor */
- int event_xy[2];
+ /* set when we're using keyinput */
+ bool is_keynav;
+ /* only used to check if we've moved the cursor */
+ int event_xy[2];
};
-typedef uiBlock * (*uiBlockHandleCreateFunc)(struct bContext *C, struct uiPopupBlockHandle *handle, void *arg1);
+typedef uiBlock *(*uiBlockHandleCreateFunc)(struct bContext *C,
+ struct uiPopupBlockHandle *handle,
+ void *arg1);
typedef void (*uiBlockHandleFreeFunc)(struct uiPopupBlockHandle *handle, void *arg1);
struct uiPopupBlockCreate {
- uiBlockCreateFunc create_func;
- uiBlockHandleCreateFunc handle_create_func;
- uiBlockHandleFreeFunc free_func;
- void *arg;
+ uiBlockCreateFunc create_func;
+ uiBlockHandleCreateFunc handle_create_func;
+ uiBlockHandleFreeFunc free_func;
+ void *arg;
- int event_xy[2];
+ int event_xy[2];
- /* when popup is initialized from a button */
- ARegion *butregion;
- uiBut *but;
+ /* when popup is initialized from a button */
+ ARegion *butregion;
+ uiBut *but;
};
struct uiPopupBlockHandle {
- /* internal */
- struct ARegion *region;
-
- /* use only for 'UI_BLOCK_MOVEMOUSE_QUIT' popups */
- float towards_xy[2];
- double towardstime;
- bool dotowards;
-
- bool popup;
- void (*popup_func)(struct bContext *C, void *arg, int event);
- void (*cancel_func)(struct bContext *C, void *arg);
- void *popup_arg;
-
- /* store data for refreshing popups */
- struct uiPopupBlockCreate popup_create_vars;
- /* true if we can re-create the popup using 'popup_create_vars' */
- bool can_refresh;
- bool refresh;
-
- struct wmTimer *scrolltimer;
- float scrolloffset;
-
- struct uiKeyNavLock keynav_state;
-
- /* for operator popups */
- struct wmOperator *popup_op;
- struct wmOperatorType *optype;
- ScrArea *ctx_area;
- ARegion *ctx_region;
- int opcontext;
-
- /* return values */
- int butretval;
- int menuretval;
- int retvalue;
- float retvec[4];
-
- /* menu direction */
- int direction;
-
- /* Previous values so we don't resize or reposition on refresh. */
- rctf prev_block_rect;
- rctf prev_butrct;
- short prev_dir1, prev_dir2;
- int prev_bounds_offset[2];
-
- /* Maximum estimated size to avoid having to reposition on refresh. */
- float max_size_x, max_size_y;
-
-/* #ifdef USE_DRAG_POPUP */
- bool is_grab;
- int grab_xy_prev[2];
-/* #endif */
+ /* internal */
+ struct ARegion *region;
+
+ /* use only for 'UI_BLOCK_MOVEMOUSE_QUIT' popups */
+ float towards_xy[2];
+ double towardstime;
+ bool dotowards;
+
+ bool popup;
+ void (*popup_func)(struct bContext *C, void *arg, int event);
+ void (*cancel_func)(struct bContext *C, void *arg);
+ void *popup_arg;
+
+ /* store data for refreshing popups */
+ struct uiPopupBlockCreate popup_create_vars;
+ /* true if we can re-create the popup using 'popup_create_vars' */
+ bool can_refresh;
+ bool refresh;
+
+ struct wmTimer *scrolltimer;
+ float scrolloffset;
+
+ struct uiKeyNavLock keynav_state;
+
+ /* for operator popups */
+ struct wmOperator *popup_op;
+ struct wmOperatorType *optype;
+ ScrArea *ctx_area;
+ ARegion *ctx_region;
+ int opcontext;
+
+ /* return values */
+ int butretval;
+ int menuretval;
+ int retvalue;
+ float retvec[4];
+
+ /* menu direction */
+ int direction;
+
+ /* Previous values so we don't resize or reposition on refresh. */
+ rctf prev_block_rect;
+ rctf prev_butrct;
+ short prev_dir1, prev_dir2;
+ int prev_bounds_offset[2];
+
+ /* Maximum estimated size to avoid having to reposition on refresh. */
+ float max_size_x, max_size_y;
+
+ /* #ifdef USE_DRAG_POPUP */
+ bool is_grab;
+ int grab_xy_prev[2];
+ /* #endif */
};
/* -------------------------------------------------------------------- */
@@ -614,41 +626,56 @@ ColorPicker *ui_block_colorpicker_create(struct uiBlock *block);
ARegion *ui_searchbox_create_generic(struct bContext *C, struct ARegion *butregion, uiBut *but);
ARegion *ui_searchbox_create_operator(struct bContext *C, struct ARegion *butregion, uiBut *but);
bool ui_searchbox_inside(struct ARegion *ar, int x, int y);
-int ui_searchbox_find_index(struct ARegion *ar, const char *name);
+int ui_searchbox_find_index(struct ARegion *ar, const char *name);
void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, const bool reset);
int ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str);
-void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event);
+void ui_searchbox_event(struct bContext *C,
+ struct ARegion *ar,
+ uiBut *but,
+ const struct wmEvent *event);
bool ui_searchbox_apply(uiBut *but, struct ARegion *ar);
void ui_searchbox_free(struct bContext *C, struct ARegion *ar);
void ui_but_search_refresh(uiBut *but);
/* interface_region_menu_popup.c */
-int ui_but_menu_step(uiBut *but, int step);
-bool ui_but_menu_step_poll(const uiBut *but);
+int ui_but_menu_step(uiBut *but, int step);
+bool ui_but_menu_step_poll(const uiBut *but);
uiBut *ui_popup_menu_memory_get(struct uiBlock *block);
-void ui_popup_menu_memory_set(uiBlock *block, struct uiBut *but);
-
-uiBlock *ui_popup_block_refresh(
- struct bContext *C, uiPopupBlockHandle *handle,
- ARegion *butregion, uiBut *but);
-
-uiPopupBlockHandle *ui_popup_block_create(
- struct bContext *C, struct ARegion *butregion, uiBut *but,
- uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
- void *arg);
-uiPopupBlockHandle *ui_popup_menu_create(
- struct bContext *C, struct ARegion *butregion, uiBut *but,
- uiMenuCreateFunc create_func, void *arg);
+void ui_popup_menu_memory_set(uiBlock *block, struct uiBut *but);
+
+uiBlock *ui_popup_block_refresh(struct bContext *C,
+ uiPopupBlockHandle *handle,
+ ARegion *butregion,
+ uiBut *but);
+
+uiPopupBlockHandle *ui_popup_block_create(struct bContext *C,
+ struct ARegion *butregion,
+ uiBut *but,
+ uiBlockCreateFunc create_func,
+ uiBlockHandleCreateFunc handle_create_func,
+ void *arg);
+uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C,
+ struct ARegion *butregion,
+ uiBut *but,
+ uiMenuCreateFunc create_func,
+ void *arg);
/* interface_region_popover.c */
-uiPopupBlockHandle *ui_popover_panel_create(
- struct bContext *C, struct ARegion *butregion, uiBut *but,
- uiMenuCreateFunc create_func, void *arg);
+uiPopupBlockHandle *ui_popover_panel_create(struct bContext *C,
+ struct ARegion *butregion,
+ uiBut *but,
+ uiMenuCreateFunc create_func,
+ void *arg);
/* interface_region_menu_pie.c */
-void ui_pie_menu_level_create(
- uiBlock *block, struct wmOperatorType *ot, const char *propname, IDProperty *properties,
- const EnumPropertyItem *items, int totitem, int context, int flag);
+void ui_pie_menu_level_create(uiBlock *block,
+ struct wmOperatorType *ot,
+ const char *propname,
+ IDProperty *properties,
+ const EnumPropertyItem *items,
+ int totitem,
+ int context,
+ int flag);
/* interface_region_popup.c */
void ui_popup_translate(struct ARegion *ar, const int mdiff[2]);
@@ -657,42 +684,78 @@ void ui_popup_block_scrolltest(struct uiBlock *block);
/* end interface_region_*.c */
-
/* interface_panel.c */
-extern int ui_handler_panel_region(
- struct bContext *C, const struct wmEvent *event,
- struct ARegion *ar, const uiBut *active_but);
-extern void ui_draw_aligned_panel(
- struct uiStyle *style, uiBlock *block, const rcti *rect,
- const bool show_pin, const bool show_background);
+extern int ui_handler_panel_region(struct bContext *C,
+ const struct wmEvent *event,
+ struct ARegion *ar,
+ const uiBut *active_but);
+extern void ui_draw_aligned_panel(struct uiStyle *style,
+ uiBlock *block,
+ const rcti *rect,
+ const bool show_pin,
+ const bool show_background);
/* interface_draw.c */
-extern void ui_draw_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select);
+extern void ui_draw_dropshadow(
+ const rctf *rct, float radius, float aspect, float alpha, int select);
void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha);
-
-void ui_draw_but_TAB_outline(const rcti *rect, float rad, uchar highlight[3], uchar highlight_fade[3]);
-void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
-void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
-void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
+void ui_draw_but_TAB_outline(const rcti *rect,
+ float rad,
+ uchar highlight[3],
+ uchar highlight_fade[3]);
+void ui_draw_but_HISTOGRAM(ARegion *ar,
+ uiBut *but,
+ const struct uiWidgetColors *wcol,
+ const rcti *rect);
+void ui_draw_but_WAVEFORM(ARegion *ar,
+ uiBut *but,
+ const struct uiWidgetColors *wcol,
+ const rcti *rect);
+void ui_draw_but_VECTORSCOPE(ARegion *ar,
+ uiBut *but,
+ const struct uiWidgetColors *wcol,
+ const rcti *rect);
void ui_draw_but_COLORBAND(uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
void ui_draw_but_UNITVEC(uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
-void ui_draw_but_CURVE(ARegion *ar, uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
-void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
-void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
-void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, const struct uiWidgetColors *wcol, const rcti *rect);
+void ui_draw_but_CURVE(ARegion *ar,
+ uiBut *but,
+ const struct uiWidgetColors *wcol,
+ const rcti *rect);
+void ui_draw_but_IMAGE(ARegion *ar,
+ uiBut *but,
+ const struct uiWidgetColors *wcol,
+ const rcti *rect);
+void ui_draw_but_TRACKPREVIEW(ARegion *ar,
+ uiBut *but,
+ const struct uiWidgetColors *wcol,
+ const rcti *rect);
+void ui_draw_but_NODESOCKET(ARegion *ar,
+ uiBut *but,
+ const struct uiWidgetColors *wcol,
+ const rcti *rect);
/* interface_handlers.c */
-PointerRNA *ui_handle_afterfunc_add_operator(struct wmOperatorType *ot, int opcontext, bool create_props);
+PointerRNA *ui_handle_afterfunc_add_operator(struct wmOperatorType *ot,
+ int opcontext,
+ bool create_props);
extern void ui_pan_to_scroll(const struct wmEvent *event, int *type, int *val);
extern void ui_but_activate_event(struct bContext *C, struct ARegion *ar, uiBut *but);
extern void ui_but_activate_over(struct bContext *C, struct ARegion *ar, uiBut *but);
-extern void ui_but_execute_begin(struct bContext *C, struct ARegion *ar, uiBut *but, void **active_back);
-extern void ui_but_execute_end(struct bContext *C, struct ARegion *ar, uiBut *but, void *active_back);
+extern void ui_but_execute_begin(struct bContext *C,
+ struct ARegion *ar,
+ uiBut *but,
+ void **active_back);
+extern void ui_but_execute_end(struct bContext *C,
+ struct ARegion *ar,
+ uiBut *but,
+ void *active_back);
extern void ui_but_active_free(const struct bContext *C, uiBut *but);
extern int ui_but_menu_direction(uiBut *but);
-extern void ui_but_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore);
+extern void ui_but_text_password_hide(char password_str[UI_MAX_DRAW_STR],
+ uiBut *but,
+ const bool restore);
extern uiBut *ui_but_find_select_in_enum(uiBut *but, int direction);
bool ui_but_is_editing(const uiBut *but);
float ui_block_calc_pie_segment(struct uiBlock *block, const float event_xy[2]);
@@ -711,32 +774,32 @@ struct wmIMEData *ui_but_ime_data_get(uiBut *but);
/* Widget shader parameters, must match the shader layout. */
typedef struct uiWidgetBaseParameters {
- rctf recti, rect;
- float radi, rad;
- float facxi, facyi;
- float round_corners[4];
- float color_inner1[4], color_inner2[4];
- float color_outline[4], color_emboss[4];
- float color_tria[4];
- float tria1_center[2], tria2_center[2];
- float tria1_size, tria2_size;
- float shade_dir;
- /* We pack alpha check and discard factor in alpha_discard.
- * If the value is negative then we do alpha check.
- * The absolute value itself is the discard factor.
- * Initialize value to 1.0.f if you don't want discard */
- float alpha_discard;
+ rctf recti, rect;
+ float radi, rad;
+ float facxi, facyi;
+ float round_corners[4];
+ float color_inner1[4], color_inner2[4];
+ float color_outline[4], color_emboss[4];
+ float color_tria[4];
+ float tria1_center[2], tria2_center[2];
+ float tria1_size, tria2_size;
+ float shade_dir;
+ /* We pack alpha check and discard factor in alpha_discard.
+ * If the value is negative then we do alpha check.
+ * The absolute value itself is the discard factor.
+ * Initialize value to 1.0.f if you don't want discard */
+ float alpha_discard;
} uiWidgetBaseParameters;
enum {
- ROUNDBOX_TRIA_NONE = 0,
- ROUNDBOX_TRIA_ARROWS,
- ROUNDBOX_TRIA_SCROLL,
- ROUNDBOX_TRIA_MENU,
- ROUNDBOX_TRIA_CHECK,
- ROUNDBOX_TRIA_HOLD_ACTION_ARROW,
-
- ROUNDBOX_TRIA_MAX, /* don't use */
+ ROUNDBOX_TRIA_NONE = 0,
+ ROUNDBOX_TRIA_ARROWS,
+ ROUNDBOX_TRIA_SCROLL,
+ ROUNDBOX_TRIA_MENU,
+ ROUNDBOX_TRIA_CHECK,
+ ROUNDBOX_TRIA_HOLD_ACTION_ARROW,
+
+ ROUNDBOX_TRIA_MAX, /* don't use */
};
struct GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased);
@@ -753,10 +816,17 @@ void ui_draw_widget_menu_back_color(const rcti *rect, bool use_shadow, const flo
void ui_draw_widget_menu_back(const rcti *rect, bool use_shadow);
void ui_draw_tooltip_background(struct uiStyle *UNUSED(style), uiBlock *block, rcti *rect);
-extern void ui_draw_but(const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
+extern void ui_draw_but(
+ const struct bContext *C, ARegion *ar, struct uiStyle *style, uiBut *but, rcti *rect);
-void ui_draw_menu_item(const struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state, bool use_sep);
-void ui_draw_preview_item(const struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
+void ui_draw_menu_item(const struct uiFontStyle *fstyle,
+ rcti *rect,
+ const char *name,
+ int iconid,
+ int state,
+ bool use_sep);
+void ui_draw_preview_item(
+ const struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
#define UI_TEXT_MARGIN_X 0.4f
#define UI_POPUP_MARGIN (UI_DPI_FAC * 12)
@@ -775,8 +845,7 @@ int ui_id_icon_get(const struct bContext *C, struct ID *id, const bool big);
/* interface_icons_event.c */
void icon_draw_rect_input(
- float x, float y, int w, int h, float alpha,
- short event_type, short event_value);
+ float x, float y, int w, int h, float alpha, short event_type, short event_value);
/* resources.c */
void init_userdef_do_versions(struct Main *bmain);
@@ -785,7 +854,11 @@ void ui_resources_free(void);
/* interface_layout.c */
void ui_layout_add_but(uiLayout *layout, uiBut *but);
-void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop);
+void ui_but_add_search(uiBut *but,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ PointerRNA *searchptr,
+ PropertyRNA *searchprop);
void ui_layout_list_set_labels_active(uiLayout *layout);
/* menu callback */
void ui_item_menutype_func(struct bContext *C, struct uiLayout *layout, void *arg_mt);
@@ -793,7 +866,7 @@ void ui_item_paneltype_func(struct bContext *C, struct uiLayout *layout, void *a
/* interface_align.c */
bool ui_but_can_align(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-int ui_but_align_opposite_to_area_align_get(const ARegion *ar) ATTR_WARN_UNUSED_RESULT;
+int ui_but_align_opposite_to_area_align_get(const ARegion *ar) ATTR_WARN_UNUSED_RESULT;
void ui_block_align_calc(uiBlock *block, const ARegion *region);
/* interface_anim.c */
@@ -820,17 +893,22 @@ void ui_but_pie_dir(RadialDirection dir, float vec[2]);
bool ui_but_is_cursor_warp(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
-bool ui_but_contains_pt(
- const uiBut *but, float mx, float my) ATTR_WARN_UNUSED_RESULT;
-bool ui_but_contains_point_px_icon(
- const uiBut *but, struct ARegion *ar, const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
-bool ui_but_contains_point_px(
- const uiBut *but, const struct ARegion *ar, int x, int y) ATTR_WARN_UNUSED_RESULT;
+bool ui_but_contains_pt(const uiBut *but, float mx, float my) ATTR_WARN_UNUSED_RESULT;
+bool ui_but_contains_point_px_icon(const uiBut *but,
+ struct ARegion *ar,
+ const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
+bool ui_but_contains_point_px(const uiBut *but, const struct ARegion *ar, int x, int y)
+ ATTR_WARN_UNUSED_RESULT;
-uiBut *ui_list_find_mouse_over(struct ARegion *ar, const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
+uiBut *ui_list_find_mouse_over(struct ARegion *ar,
+ const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
-uiBut *ui_but_find_mouse_over_ex(struct ARegion *ar, const int x, const int y, const bool labeledit) ATTR_WARN_UNUSED_RESULT;
-uiBut *ui_but_find_mouse_over(struct ARegion *ar, const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
+uiBut *ui_but_find_mouse_over_ex(struct ARegion *ar,
+ const int x,
+ const int y,
+ const bool labeledit) ATTR_WARN_UNUSED_RESULT;
+uiBut *ui_but_find_mouse_over(struct ARegion *ar,
+ const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
uiBut *ui_list_find_mouse_over_ex(struct ARegion *ar, int x, int y) ATTR_WARN_UNUSED_RESULT;
@@ -848,8 +926,7 @@ bool ui_block_is_popup_any(const uiBlock *block) ATTR_WARN_UNUSED_RESULT;
uiBut *ui_region_find_first_but_test_flag(struct ARegion *ar, int flag_include, int flag_exclude);
uiBut *ui_region_find_active_but(struct ARegion *ar) ATTR_WARN_UNUSED_RESULT;
-bool ui_region_contains_point_px(
- const struct ARegion *ar, int x, int y) ATTR_WARN_UNUSED_RESULT;
+bool ui_region_contains_point_px(const struct ARegion *ar, int x, int y) ATTR_WARN_UNUSED_RESULT;
/* interface_context_menu.c */
bool ui_popup_context_menu_for_button(struct bContext *C, uiBut *but);
@@ -881,18 +958,20 @@ void UI_OT_eyedropper_driver(struct wmOperatorType *ot);
* For use with #ui_rna_collection_search_cb.
*/
typedef struct uiRNACollectionSearch {
- PointerRNA target_ptr;
- PropertyRNA *target_prop;
+ PointerRNA target_ptr;
+ PropertyRNA *target_prop;
- PointerRNA search_ptr;
- PropertyRNA *search_prop;
+ PointerRNA search_ptr;
+ PropertyRNA *search_prop;
- bool *but_changed; /* pointer to uiBut.changed */
+ bool *but_changed; /* pointer to uiBut.changed */
} uiRNACollectionSearch;
-void ui_rna_collection_search_cb(const struct bContext *C, void *arg, const char *str, uiSearchItems *items);
+void ui_rna_collection_search_cb(const struct bContext *C,
+ void *arg,
+ const char *str,
+ uiSearchItems *items);
/* interface_ops.c */
bool ui_jump_to_target_button_poll(struct bContext *C);
-
-#endif /* __INTERFACE_INTERN_H__ */
+#endif /* __INTERFACE_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index fbfa2d11e45..8e463bf8447 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -18,7 +18,6 @@
* \ingroup edinterface
*/
-
#include <limits.h>
#include <math.h>
#include <stdlib.h>
@@ -52,7 +51,6 @@
#include "ED_armature.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -67,762 +65,834 @@
/************************ Structs and Defines *************************/
-#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \
- if (ot == NULL) { \
- ui_item_disabled(layout, _opname); \
- RNA_warning("'%s' unknown operator", _opname); \
- return_statement; \
- } (void)0 \
+#define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \
+ if (ot == NULL) { \
+ ui_item_disabled(layout, _opname); \
+ RNA_warning("'%s' unknown operator", _opname); \
+ return_statement; \
+ } \
+ (void)0
#define UI_ITEM_PROP_SEP_DIVIDE 0.5f
/* uiLayoutRoot */
typedef struct uiLayoutRoot {
- struct uiLayoutRoot *next, *prev;
+ struct uiLayoutRoot *next, *prev;
- int type;
- int opcontext;
+ int type;
+ int opcontext;
- int emw, emh;
- int padding;
+ int emw, emh;
+ int padding;
- uiMenuHandleFunc handlefunc;
- void *argv;
+ uiMenuHandleFunc handlefunc;
+ void *argv;
- uiStyle *style;
- uiBlock *block;
- uiLayout *layout;
+ uiStyle *style;
+ uiBlock *block;
+ uiLayout *layout;
} uiLayoutRoot;
/* Item */
typedef enum uiItemType {
- ITEM_BUTTON,
-
- ITEM_LAYOUT_ROW,
- ITEM_LAYOUT_COLUMN,
- ITEM_LAYOUT_COLUMN_FLOW,
- ITEM_LAYOUT_ROW_FLOW,
- ITEM_LAYOUT_GRID_FLOW,
- ITEM_LAYOUT_BOX,
- ITEM_LAYOUT_ABSOLUTE,
- ITEM_LAYOUT_SPLIT,
- ITEM_LAYOUT_OVERLAP,
- ITEM_LAYOUT_RADIAL,
-
- ITEM_LAYOUT_ROOT
+ ITEM_BUTTON,
+
+ ITEM_LAYOUT_ROW,
+ ITEM_LAYOUT_COLUMN,
+ ITEM_LAYOUT_COLUMN_FLOW,
+ ITEM_LAYOUT_ROW_FLOW,
+ ITEM_LAYOUT_GRID_FLOW,
+ ITEM_LAYOUT_BOX,
+ ITEM_LAYOUT_ABSOLUTE,
+ ITEM_LAYOUT_SPLIT,
+ ITEM_LAYOUT_OVERLAP,
+ ITEM_LAYOUT_RADIAL,
+
+ ITEM_LAYOUT_ROOT
#if 0
- TEMPLATE_COLUMN_FLOW,
- TEMPLATE_SPLIT,
- TEMPLATE_BOX,
+ TEMPLATE_COLUMN_FLOW,
+ TEMPLATE_SPLIT,
+ TEMPLATE_BOX,
- TEMPLATE_HEADER,
- TEMPLATE_HEADER_ID,
+ TEMPLATE_HEADER,
+ TEMPLATE_HEADER_ID,
#endif
} uiItemType;
typedef struct uiItem {
- void *next, *prev;
- uiItemType type;
- int flag;
+ void *next, *prev;
+ uiItemType type;
+ int flag;
} uiItem;
enum {
- UI_ITEM_FIXED = 1 << 0,
- UI_ITEM_MIN = 1 << 1,
-
- UI_ITEM_BOX_ITEM = 1 << 2, /* The item is "inside" a box item */
- UI_ITEM_PROP_SEP = 1 << 3,
- /* Show an icon button next to each property (to set keyframes, show status).
- * Enabled by default, depends on 'UI_ITEM_PROP_SEP'. */
- UI_ITEM_PROP_DECORATE = 1 << 4,
- UI_ITEM_PROP_DECORATE_NO_PAD = 1 << 5,
+ UI_ITEM_FIXED = 1 << 0,
+ UI_ITEM_MIN = 1 << 1,
+
+ UI_ITEM_BOX_ITEM = 1 << 2, /* The item is "inside" a box item */
+ UI_ITEM_PROP_SEP = 1 << 3,
+ /* Show an icon button next to each property (to set keyframes, show status).
+ * Enabled by default, depends on 'UI_ITEM_PROP_SEP'. */
+ UI_ITEM_PROP_DECORATE = 1 << 4,
+ UI_ITEM_PROP_DECORATE_NO_PAD = 1 << 5,
};
typedef struct uiButtonItem {
- uiItem item;
- uiBut *but;
+ uiItem item;
+ uiBut *but;
} uiButtonItem;
struct uiLayout {
- uiItem item;
-
- uiLayoutRoot *root;
- bContextStore *context;
- ListBase items;
-
- /** Sub layout to add child items, if not the layout itself. */
- uiLayout *child_items_layout;
-
- int x, y, w, h;
- float scale[2];
- short space;
- bool align;
- bool active;
- bool active_default;
- bool activate_init;
- bool enabled;
- bool redalert;
- bool keepaspect;
- /** For layouts inside gridflow, they and their items shall never have a fixed maximal size. */
- bool variable_size;
- char alignment;
- char emboss;
- /** for fixed width or height to avoid UI size changes */
- float units[2];
+ uiItem item;
+
+ uiLayoutRoot *root;
+ bContextStore *context;
+ ListBase items;
+
+ /** Sub layout to add child items, if not the layout itself. */
+ uiLayout *child_items_layout;
+
+ int x, y, w, h;
+ float scale[2];
+ short space;
+ bool align;
+ bool active;
+ bool active_default;
+ bool activate_init;
+ bool enabled;
+ bool redalert;
+ bool keepaspect;
+ /** For layouts inside gridflow, they and their items shall never have a fixed maximal size. */
+ bool variable_size;
+ char alignment;
+ char emboss;
+ /** for fixed width or height to avoid UI size changes */
+ float units[2];
};
typedef struct uiLayoutItemFlow {
- uiLayout litem;
- int number;
- int totcol;
+ uiLayout litem;
+ int number;
+ int totcol;
} uiLayoutItemFlow;
typedef struct uiLayoutItemGridFlow {
- uiLayout litem;
-
- /* Extra parameters */
- bool row_major; /* Fill first row first, instead of filling first column first. */
- bool even_columns; /* Same width for all columns. */
- bool even_rows; /* Same height for all rows. */
- /**
- * - If positive, absolute fixed number of columns.
- * - If 0, fully automatic (based on available width).
- * - If negative, automatic but only generates number of columns/rows
- * multiple of given (absolute) value.
- */
- int columns_len;
-
- /* Pure internal runtime storage. */
- int tot_items, tot_columns, tot_rows;
+ uiLayout litem;
+
+ /* Extra parameters */
+ bool row_major; /* Fill first row first, instead of filling first column first. */
+ bool even_columns; /* Same width for all columns. */
+ bool even_rows; /* Same height for all rows. */
+ /**
+ * - If positive, absolute fixed number of columns.
+ * - If 0, fully automatic (based on available width).
+ * - If negative, automatic but only generates number of columns/rows
+ * multiple of given (absolute) value.
+ */
+ int columns_len;
+
+ /* Pure internal runtime storage. */
+ int tot_items, tot_columns, tot_rows;
} uiLayoutItemGridFlow;
typedef struct uiLayoutItemBx {
- uiLayout litem;
- uiBut *roundbox;
+ uiLayout litem;
+ uiBut *roundbox;
} uiLayoutItemBx;
typedef struct uiLayoutItemSplit {
- uiLayout litem;
- float percentage;
+ uiLayout litem;
+ float percentage;
} uiLayoutItemSplit;
typedef struct uiLayoutItemRoot {
- uiLayout litem;
+ uiLayout litem;
} uiLayoutItemRoot;
/************************** Item ***************************/
static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_NAME_STR])
{
- int len = strlen(name);
-
- if (len != 0 && len + 1 < UI_MAX_NAME_STR) {
- memcpy(namestr, name, len);
- namestr[len] = ':';
- namestr[len + 1] = '\0';
- return namestr;
- }
-
- return name;
-}
-
-static int ui_item_fit(int item, int pos, int all, int available, bool is_last, int alignment, float *extra_pixel)
-{
- /* available == 0 is unlimited */
- if (ELEM(0, available, all)) {
- return item;
- }
-
- if (all > available) {
- /* contents is bigger than available space */
- if (is_last) {
- return available - pos;
- }
- else {
- float width = *extra_pixel + (item * available) / (float)all;
- *extra_pixel = width - (int)width;
- return (int)width;
- }
- }
- else {
- /* contents is smaller or equal to available space */
- if (alignment == UI_LAYOUT_ALIGN_EXPAND) {
- if (is_last) {
- return available - pos;
- }
- else {
- float width = *extra_pixel + (item * available) / (float)all;
- *extra_pixel = width - (int)width;
- return (int)width;
- }
- }
- else {
- return item;
- }
- }
+ int len = strlen(name);
+
+ if (len != 0 && len + 1 < UI_MAX_NAME_STR) {
+ memcpy(namestr, name, len);
+ namestr[len] = ':';
+ namestr[len + 1] = '\0';
+ return namestr;
+ }
+
+ return name;
+}
+
+static int ui_item_fit(
+ int item, int pos, int all, int available, bool is_last, int alignment, float *extra_pixel)
+{
+ /* available == 0 is unlimited */
+ if (ELEM(0, available, all)) {
+ return item;
+ }
+
+ if (all > available) {
+ /* contents is bigger than available space */
+ if (is_last) {
+ return available - pos;
+ }
+ else {
+ float width = *extra_pixel + (item * available) / (float)all;
+ *extra_pixel = width - (int)width;
+ return (int)width;
+ }
+ }
+ else {
+ /* contents is smaller or equal to available space */
+ if (alignment == UI_LAYOUT_ALIGN_EXPAND) {
+ if (is_last) {
+ return available - pos;
+ }
+ else {
+ float width = *extra_pixel + (item * available) / (float)all;
+ *extra_pixel = width - (int)width;
+ return (int)width;
+ }
+ }
+ else {
+ return item;
+ }
+ }
}
/* variable button size in which direction? */
-#define UI_ITEM_VARY_X 1
-#define UI_ITEM_VARY_Y 2
+#define UI_ITEM_VARY_X 1
+#define UI_ITEM_VARY_Y 2
static int ui_layout_vary_direction(uiLayout *layout)
{
- return ((ELEM(layout->root->type, UI_LAYOUT_HEADER, UI_LAYOUT_PIEMENU) ||
- (layout->alignment != UI_LAYOUT_ALIGN_EXPAND)) ?
- UI_ITEM_VARY_X : UI_ITEM_VARY_Y);
+ return ((ELEM(layout->root->type, UI_LAYOUT_HEADER, UI_LAYOUT_PIEMENU) ||
+ (layout->alignment != UI_LAYOUT_ALIGN_EXPAND)) ?
+ UI_ITEM_VARY_X :
+ UI_ITEM_VARY_Y);
}
static bool ui_layout_variable_size(uiLayout *layout)
{
- /* Note that this code is probably a bit flacky, we'd probably want to know whether it's
- * variable in X and/or Y, etc. But for now it mimics previous one,
- * with addition of variable flag set for children of gridflow layouts. */
- return ui_layout_vary_direction(layout) == UI_ITEM_VARY_X || layout->variable_size;
+ /* Note that this code is probably a bit flacky, we'd probably want to know whether it's
+ * variable in X and/or Y, etc. But for now it mimics previous one,
+ * with addition of variable flag set for children of gridflow layouts. */
+ return ui_layout_vary_direction(layout) == UI_ITEM_VARY_X || layout->variable_size;
}
/* estimated size of text + icon */
static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, bool compact)
{
- bool variable;
- const int unit_x = UI_UNIT_X * (layout->scale[0] ? layout->scale[0] : 1.0f);
-
- if (icon && !name[0]) {
- return unit_x; /* icon only */
- }
-
- variable = ui_layout_variable_size(layout);
-
- if (variable) {
- if (!icon && !name[0]) {
- return unit_x; /* No icon or name. */
- }
- if (layout->alignment != UI_LAYOUT_ALIGN_EXPAND) {
- layout->item.flag |= UI_ITEM_MIN;
- }
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- /* it may seem odd that the icon only adds (unit_x / 4)
- * but taking margins into account its fine */
- return (UI_fontstyle_string_width(fstyle, name) +
- (unit_x * ((compact ? 1.25f : 1.50f) +
- (icon ? 0.25f : 0.0f))));
- }
- else {
- return unit_x * 10;
- }
+ bool variable;
+ const int unit_x = UI_UNIT_X * (layout->scale[0] ? layout->scale[0] : 1.0f);
+
+ if (icon && !name[0]) {
+ return unit_x; /* icon only */
+ }
+
+ variable = ui_layout_variable_size(layout);
+
+ if (variable) {
+ if (!icon && !name[0]) {
+ return unit_x; /* No icon or name. */
+ }
+ if (layout->alignment != UI_LAYOUT_ALIGN_EXPAND) {
+ layout->item.flag |= UI_ITEM_MIN;
+ }
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ /* it may seem odd that the icon only adds (unit_x / 4)
+ * but taking margins into account its fine */
+ return (UI_fontstyle_string_width(fstyle, name) +
+ (unit_x * ((compact ? 1.25f : 1.50f) + (icon ? 0.25f : 0.0f))));
+ }
+ else {
+ return unit_x * 10;
+ }
}
static void ui_item_size(uiItem *item, int *r_w, int *r_h)
{
- if (item->type == ITEM_BUTTON) {
- uiButtonItem *bitem = (uiButtonItem *)item;
+ if (item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
- if (r_w) {
- *r_w = BLI_rctf_size_x(&bitem->but->rect);
- }
- if (r_h) {
- *r_h = BLI_rctf_size_y(&bitem->but->rect);
- }
- }
- else {
- uiLayout *litem = (uiLayout *)item;
+ if (r_w) {
+ *r_w = BLI_rctf_size_x(&bitem->but->rect);
+ }
+ if (r_h) {
+ *r_h = BLI_rctf_size_y(&bitem->but->rect);
+ }
+ }
+ else {
+ uiLayout *litem = (uiLayout *)item;
- if (r_w) {
- *r_w = litem->w;
- }
- if (r_h) {
- *r_h = litem->h;
- }
- }
+ if (r_w) {
+ *r_w = litem->w;
+ }
+ if (r_h) {
+ *r_h = litem->h;
+ }
+ }
}
static void ui_item_offset(uiItem *item, int *r_x, int *r_y)
{
- if (item->type == ITEM_BUTTON) {
- uiButtonItem *bitem = (uiButtonItem *)item;
-
- if (r_x) {
- *r_x = bitem->but->rect.xmin;
- }
- if (r_y) {
- *r_y = bitem->but->rect.ymin;
- }
- }
- else {
- if (r_x) {
- *r_x = 0;
- }
- if (r_y) {
- *r_y = 0;
- }
- }
+ if (item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
+
+ if (r_x) {
+ *r_x = bitem->but->rect.xmin;
+ }
+ if (r_y) {
+ *r_y = bitem->but->rect.ymin;
+ }
+ }
+ else {
+ if (r_x) {
+ *r_x = 0;
+ }
+ if (r_y) {
+ *r_y = 0;
+ }
+ }
}
static void ui_item_position(uiItem *item, int x, int y, int w, int h)
{
- if (item->type == ITEM_BUTTON) {
- uiButtonItem *bitem = (uiButtonItem *)item;
+ if (item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
- bitem->but->rect.xmin = x;
- bitem->but->rect.ymin = y;
- bitem->but->rect.xmax = x + w;
- bitem->but->rect.ymax = y + h;
+ bitem->but->rect.xmin = x;
+ bitem->but->rect.ymin = y;
+ bitem->but->rect.xmax = x + w;
+ bitem->but->rect.ymax = y + h;
- ui_but_update(bitem->but); /* for strlen */
- }
- else {
- uiLayout *litem = (uiLayout *)item;
+ ui_but_update(bitem->but); /* for strlen */
+ }
+ else {
+ uiLayout *litem = (uiLayout *)item;
- litem->x = x;
- litem->y = y + h;
- litem->w = w;
- litem->h = h;
- }
+ litem->x = x;
+ litem->y = y + h;
+ litem->w = w;
+ litem->h = h;
+ }
}
static void ui_item_move(uiItem *item, int delta_xmin, int delta_xmax)
{
- if (item->type == ITEM_BUTTON) {
- uiButtonItem *bitem = (uiButtonItem *)item;
+ if (item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
- bitem->but->rect.xmin += delta_xmin;
- bitem->but->rect.xmax += delta_xmax;
+ bitem->but->rect.xmin += delta_xmin;
+ bitem->but->rect.xmax += delta_xmax;
- ui_but_update(bitem->but); /* for strlen */
- }
- else {
- uiLayout *litem = (uiLayout *)item;
+ ui_but_update(bitem->but); /* for strlen */
+ }
+ else {
+ uiLayout *litem = (uiLayout *)item;
- if (delta_xmin > 0) {
- litem->x += delta_xmin;
- }
- else {
- litem->w += delta_xmax;
- }
- }
+ if (delta_xmin > 0) {
+ litem->x += delta_xmin;
+ }
+ else {
+ litem->w += delta_xmax;
+ }
+ }
}
/******************** Special RNA Items *********************/
int uiLayoutGetLocalDir(const uiLayout *layout)
{
- switch (layout->item.type) {
- case ITEM_LAYOUT_ROW:
- case ITEM_LAYOUT_ROOT:
- case ITEM_LAYOUT_OVERLAP:
- return UI_LAYOUT_HORIZONTAL;
- case ITEM_LAYOUT_COLUMN:
- case ITEM_LAYOUT_COLUMN_FLOW:
- case ITEM_LAYOUT_GRID_FLOW:
- case ITEM_LAYOUT_SPLIT:
- case ITEM_LAYOUT_ABSOLUTE:
- case ITEM_LAYOUT_BOX:
- default:
- return UI_LAYOUT_VERTICAL;
- }
+ switch (layout->item.type) {
+ case ITEM_LAYOUT_ROW:
+ case ITEM_LAYOUT_ROOT:
+ case ITEM_LAYOUT_OVERLAP:
+ return UI_LAYOUT_HORIZONTAL;
+ case ITEM_LAYOUT_COLUMN:
+ case ITEM_LAYOUT_COLUMN_FLOW:
+ case ITEM_LAYOUT_GRID_FLOW:
+ case ITEM_LAYOUT_SPLIT:
+ case ITEM_LAYOUT_ABSOLUTE:
+ case ITEM_LAYOUT_BOX:
+ default:
+ return UI_LAYOUT_VERTICAL;
+ }
}
static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, bool align)
{
- uiLayout *sub;
+ uiLayout *sub;
- if (uiLayoutGetLocalDir(test) == UI_LAYOUT_HORIZONTAL) {
- sub = uiLayoutRow(layout, align);
- }
- else {
- sub = uiLayoutColumn(layout, align);
- }
+ if (uiLayoutGetLocalDir(test) == UI_LAYOUT_HORIZONTAL) {
+ sub = uiLayoutRow(layout, align);
+ }
+ else {
+ sub = uiLayoutColumn(layout, align);
+ }
- sub->space = 0;
- return sub;
+ sub->space = 0;
+ return sub;
}
static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
{
- wmWindow *win = CTX_wm_window(C);
- uiBut *but = arg_but, *cbut;
- PointerRNA *ptr = &but->rnapoin;
- PropertyRNA *prop = but->rnaprop;
- int i, index = POINTER_AS_INT(arg_index);
- int shift = win->eventstate->shift;
- int len = RNA_property_array_length(ptr, prop);
+ wmWindow *win = CTX_wm_window(C);
+ uiBut *but = arg_but, *cbut;
+ PointerRNA *ptr = &but->rnapoin;
+ PropertyRNA *prop = but->rnaprop;
+ int i, index = POINTER_AS_INT(arg_index);
+ int shift = win->eventstate->shift;
+ int len = RNA_property_array_length(ptr, prop);
- if (!shift) {
- RNA_property_boolean_set_index(ptr, prop, index, true);
+ if (!shift) {
+ RNA_property_boolean_set_index(ptr, prop, index, true);
- for (i = 0; i < len; i++) {
- if (i != index) {
- RNA_property_boolean_set_index(ptr, prop, i, 0);
- }
- }
+ for (i = 0; i < len; i++) {
+ if (i != index) {
+ RNA_property_boolean_set_index(ptr, prop, i, 0);
+ }
+ }
- RNA_property_update(C, ptr, prop);
+ RNA_property_update(C, ptr, prop);
- for (cbut = but->block->buttons.first; cbut; cbut = cbut->next) {
- ui_but_update(cbut);
- }
- }
+ for (cbut = but->block->buttons.first; cbut; cbut = cbut->next) {
+ ui_but_update(cbut);
+ }
+ }
}
/* create buttons for an item with an RNA array */
-static void ui_item_array(
- uiLayout *layout, uiBlock *block, const char *name, int icon,
- PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h),
- bool expand, bool slider, bool toggle, bool icon_only, bool compact, bool show_text)
-{
- uiStyle *style = layout->root->style;
- uiBut *but;
- PropertyType type;
- PropertySubType subtype;
- uiLayout *sub;
- uint a, b;
-
- /* retrieve type and subtype */
- type = RNA_property_type(prop);
- subtype = RNA_property_subtype(prop);
-
- sub = ui_item_local_sublayout(layout, layout, 1);
- UI_block_layout_set_current(block, sub);
-
- /* create label */
- if (name[0] && show_text) {
- uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- }
-
- /* create buttons */
- if (type == PROP_BOOLEAN && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) {
- /* special check for layer layout */
- int butw, buth, unit;
- int cols = (len >= 20) ? 2 : 1;
- const uint colbuts = len / (2 * cols);
- uint layer_used = 0;
- uint layer_active = 0;
-
- UI_block_layout_set_current(block, uiLayoutAbsolute(layout, false));
-
- unit = UI_UNIT_X * 0.75;
- butw = unit;
- buth = unit;
-
- if (ptr->type == &RNA_Armature) {
- bArmature *arm = (bArmature *)ptr->data;
-
- layer_used = arm->layer_used;
-
- if (arm->edbo) {
- if (arm->act_edbone) {
- layer_active |= arm->act_edbone->layer;
- }
- }
- else {
- if (arm->act_bone) {
- layer_active |= arm->act_bone->layer;
- }
- }
- }
-
- for (b = 0; b < cols; b++) {
- UI_block_align_begin(block);
-
- for (a = 0; a < colbuts; a++) {
- const int layer_num = a + b * colbuts;
- const uint layer_flag = (1u << layer_num);
-
- if (layer_used & layer_flag) {
- if (layer_active & layer_flag) {
- icon = ICON_LAYER_ACTIVE;
- }
- else {
- icon = ICON_LAYER_USED;
- }
- }
- else {
- icon = ICON_BLANK1;
- }
-
- but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y + buth, butw, buth);
- if (subtype == PROP_LAYER_MEMBER) {
- UI_but_func_set(but, ui_layer_but_cb, but, POINTER_FROM_INT(layer_num));
- }
- }
- for (a = 0; a < colbuts; a++) {
- const int layer_num = a + len / 2 + b * colbuts;
- const uint layer_flag = (1u << layer_num);
-
- if (layer_used & layer_flag) {
- if (layer_active & layer_flag) {
- icon = ICON_LAYER_ACTIVE;
- }
- else {
- icon = ICON_LAYER_USED;
- }
- }
- else {
- icon = ICON_BLANK1;
- }
-
- but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y, butw, buth);
- if (subtype == PROP_LAYER_MEMBER) {
- UI_but_func_set(but, ui_layer_but_cb, but, POINTER_FROM_INT(layer_num));
- }
- }
- UI_block_align_end(block);
-
- x += colbuts * butw + style->buttonspacex;
- }
- }
- else if (subtype == PROP_MATRIX) {
- int totdim, dim_size[3]; /* 3 == RNA_MAX_ARRAY_DIMENSION */
- int row, col;
-
- UI_block_layout_set_current(block, uiLayoutAbsolute(layout, true));
-
- totdim = RNA_property_array_dimension(ptr, prop, dim_size);
- if (totdim != 2) {
- /* Only 2D matrices supported in UI so far. */
- return;
- }
-
- w /= dim_size[0];
- /* h /= dim_size[1]; */ /* UNUSED */
-
- for (a = 0; a < len; a++) {
- col = a % dim_size[0];
- row = a / dim_size[0];
-
- but = uiDefAutoButR(block, ptr, prop, a, "", ICON_NONE, x + w * col, y + (dim_size[1] * UI_UNIT_Y) - (row * UI_UNIT_Y), w, UI_UNIT_Y);
- if (slider && but->type == UI_BTYPE_NUM) {
- but->type = UI_BTYPE_NUM_SLIDER;
- }
- }
- }
- else if (subtype == PROP_DIRECTION && !expand) {
- uiDefButR_prop(block, UI_BTYPE_UNITVEC, 0, name, x, y, UI_UNIT_X * 3, UI_UNIT_Y * 3, ptr, prop, -1, 0, 0, -1, -1, NULL);
- }
- else {
- /* note, this block of code is a bit arbitrary and has just been made
- * to work with common cases, but may need to be re-worked */
-
- /* special case, boolean array in a menu, this could be used in a more generic way too */
- if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand) {
- uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, 0, 0, w, UI_UNIT_Y);
- }
- else {
- bool *boolarr = NULL;
-
- /* even if 'expand' is fale, expanding anyway */
-
- /* layout for known array subtypes */
- char str[3] = {'\0'};
-
- if (!icon_only && show_text) {
- if (type != PROP_BOOLEAN) {
- str[1] = ':';
- }
- }
-
- /* show checkboxes for rna on a non-emboss block (menu for eg) */
- if (type == PROP_BOOLEAN && ELEM(layout->root->block->dt, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
- boolarr = MEM_callocN(sizeof(bool) * len, __func__);
- RNA_property_boolean_get_array(ptr, prop, boolarr);
- }
-
- const char *str_buf = show_text ? str: "";
- for (a = 0; a < len; a++) {
- int width_item;
-
- if (!icon_only && show_text) {
- str[0] = RNA_property_array_item_char(prop, a);
- }
- if (boolarr) {
- icon = boolarr[a] ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
- }
-
- width_item = (
- (compact && type == PROP_BOOLEAN) ?
- min_ii(w, ui_text_icon_width(layout, str_buf, icon, false)) : w);
-
- but = uiDefAutoButR(block, ptr, prop, a, str_buf, icon, 0, 0, width_item, UI_UNIT_Y);
- if (slider && but->type == UI_BTYPE_NUM) {
- but->type = UI_BTYPE_NUM_SLIDER;
- }
- if (toggle && but->type == UI_BTYPE_CHECKBOX) {
- but->type = UI_BTYPE_TOGGLE;
- }
- if ((a == 0) && (subtype == PROP_AXISANGLE)) {
- UI_but_unit_type_set(but, PROP_UNIT_ROTATION);
- }
- }
-
- if (boolarr) {
- MEM_freeN(boolarr);
- }
- }
- }
-
- UI_block_layout_set_current(block, layout);
+static void ui_item_array(uiLayout *layout,
+ uiBlock *block,
+ const char *name,
+ int icon,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int len,
+ int x,
+ int y,
+ int w,
+ int UNUSED(h),
+ bool expand,
+ bool slider,
+ bool toggle,
+ bool icon_only,
+ bool compact,
+ bool show_text)
+{
+ uiStyle *style = layout->root->style;
+ uiBut *but;
+ PropertyType type;
+ PropertySubType subtype;
+ uiLayout *sub;
+ uint a, b;
+
+ /* retrieve type and subtype */
+ type = RNA_property_type(prop);
+ subtype = RNA_property_subtype(prop);
+
+ sub = ui_item_local_sublayout(layout, layout, 1);
+ UI_block_layout_set_current(block, sub);
+
+ /* create label */
+ if (name[0] && show_text) {
+ uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ }
+
+ /* create buttons */
+ if (type == PROP_BOOLEAN && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) {
+ /* special check for layer layout */
+ int butw, buth, unit;
+ int cols = (len >= 20) ? 2 : 1;
+ const uint colbuts = len / (2 * cols);
+ uint layer_used = 0;
+ uint layer_active = 0;
+
+ UI_block_layout_set_current(block, uiLayoutAbsolute(layout, false));
+
+ unit = UI_UNIT_X * 0.75;
+ butw = unit;
+ buth = unit;
+
+ if (ptr->type == &RNA_Armature) {
+ bArmature *arm = (bArmature *)ptr->data;
+
+ layer_used = arm->layer_used;
+
+ if (arm->edbo) {
+ if (arm->act_edbone) {
+ layer_active |= arm->act_edbone->layer;
+ }
+ }
+ else {
+ if (arm->act_bone) {
+ layer_active |= arm->act_bone->layer;
+ }
+ }
+ }
+
+ for (b = 0; b < cols; b++) {
+ UI_block_align_begin(block);
+
+ for (a = 0; a < colbuts; a++) {
+ const int layer_num = a + b * colbuts;
+ const uint layer_flag = (1u << layer_num);
+
+ if (layer_used & layer_flag) {
+ if (layer_active & layer_flag) {
+ icon = ICON_LAYER_ACTIVE;
+ }
+ else {
+ icon = ICON_LAYER_USED;
+ }
+ }
+ else {
+ icon = ICON_BLANK1;
+ }
+
+ but = uiDefAutoButR(
+ block, ptr, prop, layer_num, "", icon, x + butw * a, y + buth, butw, buth);
+ if (subtype == PROP_LAYER_MEMBER) {
+ UI_but_func_set(but, ui_layer_but_cb, but, POINTER_FROM_INT(layer_num));
+ }
+ }
+ for (a = 0; a < colbuts; a++) {
+ const int layer_num = a + len / 2 + b * colbuts;
+ const uint layer_flag = (1u << layer_num);
+
+ if (layer_used & layer_flag) {
+ if (layer_active & layer_flag) {
+ icon = ICON_LAYER_ACTIVE;
+ }
+ else {
+ icon = ICON_LAYER_USED;
+ }
+ }
+ else {
+ icon = ICON_BLANK1;
+ }
+
+ but = uiDefAutoButR(block, ptr, prop, layer_num, "", icon, x + butw * a, y, butw, buth);
+ if (subtype == PROP_LAYER_MEMBER) {
+ UI_but_func_set(but, ui_layer_but_cb, but, POINTER_FROM_INT(layer_num));
+ }
+ }
+ UI_block_align_end(block);
+
+ x += colbuts * butw + style->buttonspacex;
+ }
+ }
+ else if (subtype == PROP_MATRIX) {
+ int totdim, dim_size[3]; /* 3 == RNA_MAX_ARRAY_DIMENSION */
+ int row, col;
+
+ UI_block_layout_set_current(block, uiLayoutAbsolute(layout, true));
+
+ totdim = RNA_property_array_dimension(ptr, prop, dim_size);
+ if (totdim != 2) {
+ /* Only 2D matrices supported in UI so far. */
+ return;
+ }
+
+ w /= dim_size[0];
+ /* h /= dim_size[1]; */ /* UNUSED */
+
+ for (a = 0; a < len; a++) {
+ col = a % dim_size[0];
+ row = a / dim_size[0];
+
+ but = uiDefAutoButR(block,
+ ptr,
+ prop,
+ a,
+ "",
+ ICON_NONE,
+ x + w * col,
+ y + (dim_size[1] * UI_UNIT_Y) - (row * UI_UNIT_Y),
+ w,
+ UI_UNIT_Y);
+ if (slider && but->type == UI_BTYPE_NUM) {
+ but->type = UI_BTYPE_NUM_SLIDER;
+ }
+ }
+ }
+ else if (subtype == PROP_DIRECTION && !expand) {
+ uiDefButR_prop(block,
+ UI_BTYPE_UNITVEC,
+ 0,
+ name,
+ x,
+ y,
+ UI_UNIT_X * 3,
+ UI_UNIT_Y * 3,
+ ptr,
+ prop,
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ /* note, this block of code is a bit arbitrary and has just been made
+ * to work with common cases, but may need to be re-worked */
+
+ /* special case, boolean array in a menu, this could be used in a more generic way too */
+ if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand) {
+ uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, 0, 0, w, UI_UNIT_Y);
+ }
+ else {
+ bool *boolarr = NULL;
+
+ /* even if 'expand' is fale, expanding anyway */
+
+ /* layout for known array subtypes */
+ char str[3] = {'\0'};
+
+ if (!icon_only && show_text) {
+ if (type != PROP_BOOLEAN) {
+ str[1] = ':';
+ }
+ }
+
+ /* show checkboxes for rna on a non-emboss block (menu for eg) */
+ if (type == PROP_BOOLEAN &&
+ ELEM(layout->root->block->dt, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
+ boolarr = MEM_callocN(sizeof(bool) * len, __func__);
+ RNA_property_boolean_get_array(ptr, prop, boolarr);
+ }
+
+ const char *str_buf = show_text ? str : "";
+ for (a = 0; a < len; a++) {
+ int width_item;
+
+ if (!icon_only && show_text) {
+ str[0] = RNA_property_array_item_char(prop, a);
+ }
+ if (boolarr) {
+ icon = boolarr[a] ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ }
+
+ width_item = ((compact && type == PROP_BOOLEAN) ?
+ min_ii(w, ui_text_icon_width(layout, str_buf, icon, false)) :
+ w);
+
+ but = uiDefAutoButR(block, ptr, prop, a, str_buf, icon, 0, 0, width_item, UI_UNIT_Y);
+ if (slider && but->type == UI_BTYPE_NUM) {
+ but->type = UI_BTYPE_NUM_SLIDER;
+ }
+ if (toggle && but->type == UI_BTYPE_CHECKBOX) {
+ but->type = UI_BTYPE_TOGGLE;
+ }
+ if ((a == 0) && (subtype == PROP_AXISANGLE)) {
+ UI_but_unit_type_set(but, PROP_UNIT_ROTATION);
+ }
+ }
+
+ if (boolarr) {
+ MEM_freeN(boolarr);
+ }
+ }
+ }
+
+ UI_block_layout_set_current(block, layout);
}
static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2)
{
- wmWindow *win = CTX_wm_window(C);
-
- if (!win->eventstate->shift) {
- uiBut *but = (uiBut *)arg1;
- int enum_value = POINTER_AS_INT(arg2);
-
- int current_value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
- if (!(current_value & enum_value)) {
- current_value = enum_value;
- }
- else {
- current_value &= enum_value;
- }
- RNA_property_enum_set(&but->rnapoin, but->rnaprop, current_value);
- }
-}
-static void ui_item_enum_expand_exec(
- uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop,
- const char *uiname, int h, int but_type, bool icon_only)
-{
- /* XXX The way this function currently handles uiname parameter is insane and inconsistent with general UI API:
- * * uiname is the *enum property* label.
- * * when it is NULL or empty, we do not draw *enum items* labels, this doubles the icon_only parameter.
- * * we *never* draw (i.e. really use) the enum label uiname, it is just used as a mere flag!
- * Unfortunately, fixing this implies an API "soft break", so better to defer it for later... :/
- * --mont29
- */
-
- uiBut *but;
- uiLayout *layout_radial = NULL;
- const EnumPropertyItem *item, *item_array;
- const char *name;
- int itemw, icon, value;
- bool free;
- bool radial = (layout->root->type == UI_LAYOUT_PIEMENU);
-
- BLI_assert(RNA_property_type(prop) == PROP_ENUM);
-
- if (radial) {
- RNA_property_enum_items_gettexted_all(block->evil_C, ptr, prop, &item_array, NULL, &free);
- }
- else {
- RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item_array, NULL, &free);
- }
-
- /* we dont want nested rows, cols in menus */
- if (radial) {
- if (layout->root->layout == layout) {
- layout_radial = uiLayoutRadial(layout);
- UI_block_layout_set_current(block, layout_radial);
- }
- else {
- if (layout->item.type == ITEM_LAYOUT_RADIAL) {
- layout_radial = layout;
- }
- UI_block_layout_set_current(block, layout);
- }
- }
- else if (layout->root->type != UI_LAYOUT_MENU) {
- UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1));
- }
- else {
- UI_block_layout_set_current(block, layout);
- }
-
- for (item = item_array; item->identifier; item++) {
- const bool is_first = item == item_array;
-
- if (!item->identifier[0]) {
- const EnumPropertyItem *next_item = item + 1;
-
- /* Separate items, potentially with a label. */
- if (next_item->identifier) {
- /* Item without identifier but with name:
- * Add group label for the following items. */
- if (item->name) {
- if (!is_first) {
- uiItemS(block->curlayout);
- }
- uiItemL(block->curlayout, item->name, item->icon);
- }
- else if (radial && layout_radial) {
- uiItemS(layout_radial);
- }
- else {
- uiItemS(block->curlayout);
- }
- }
- continue;
- }
-
- name = (!uiname || uiname[0]) ? item->name : "";
- icon = item->icon;
- value = item->value;
- itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0);
-
- if (icon && name[0] && !icon_only) {
- but = uiDefIconTextButR_prop(block, but_type, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
- }
- else if (icon) {
- but = uiDefIconButR_prop(block, but_type, 0, icon, 0, 0, (is_first) ? itemw : ceilf(itemw - U.pixelsize), h, ptr, prop, -1, 0, value, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, but_type, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
- }
-
- if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
- /* If this is set, assert since we're clobbering someone elses callback. */
- BLI_assert(but->func == NULL);
- UI_but_func_set(but, ui_item_enum_expand_handle, but, POINTER_FROM_INT(value));
- }
-
- if (uiLayoutGetLocalDir(layout) != UI_LAYOUT_HORIZONTAL) {
- but->drawflag |= UI_BUT_TEXT_LEFT;
- }
-
- /* Allow quick, inaccurate swipe motions to switch tabs
- * (no need to keep cursor over them). */
- if (but_type == UI_BTYPE_TAB) {
- but->flag |= UI_BUT_DRAG_LOCK;
- }
- }
- UI_block_layout_set_current(block, layout);
-
- if (free) {
- MEM_freeN((void *)item_array);
- }
-}
-static void ui_item_enum_expand(
- uiLayout *layout, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop,
- const char *uiname, int h, bool icon_only)
-{
- ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_ROW, icon_only);
-}
-static void ui_item_enum_expand_tabs(
- uiLayout *layout, bContext *C, uiBlock *block, PointerRNA *ptr, PropertyRNA *prop,
- const char *uiname, int h, bool icon_only)
-{
- uiBut *last = block->buttons.last;
-
- ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_TAB, icon_only);
- BLI_assert(last != block->buttons.last);
- for (uiBut *tab = last ? last->next : block->buttons.first; tab; tab = tab->next) {
- UI_but_drawflag_enable(tab, ui_but_align_opposite_to_area_align_get(CTX_wm_region(C)));
- }
+ wmWindow *win = CTX_wm_window(C);
+
+ if (!win->eventstate->shift) {
+ uiBut *but = (uiBut *)arg1;
+ int enum_value = POINTER_AS_INT(arg2);
+
+ int current_value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+ if (!(current_value & enum_value)) {
+ current_value = enum_value;
+ }
+ else {
+ current_value &= enum_value;
+ }
+ RNA_property_enum_set(&but->rnapoin, but->rnaprop, current_value);
+ }
+}
+static void ui_item_enum_expand_exec(uiLayout *layout,
+ uiBlock *block,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ const char *uiname,
+ int h,
+ int but_type,
+ bool icon_only)
+{
+ /* XXX The way this function currently handles uiname parameter is insane and inconsistent with general UI API:
+ * * uiname is the *enum property* label.
+ * * when it is NULL or empty, we do not draw *enum items* labels, this doubles the icon_only parameter.
+ * * we *never* draw (i.e. really use) the enum label uiname, it is just used as a mere flag!
+ * Unfortunately, fixing this implies an API "soft break", so better to defer it for later... :/
+ * --mont29
+ */
+
+ uiBut *but;
+ uiLayout *layout_radial = NULL;
+ const EnumPropertyItem *item, *item_array;
+ const char *name;
+ int itemw, icon, value;
+ bool free;
+ bool radial = (layout->root->type == UI_LAYOUT_PIEMENU);
+
+ BLI_assert(RNA_property_type(prop) == PROP_ENUM);
+
+ if (radial) {
+ RNA_property_enum_items_gettexted_all(block->evil_C, ptr, prop, &item_array, NULL, &free);
+ }
+ else {
+ RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item_array, NULL, &free);
+ }
+
+ /* we dont want nested rows, cols in menus */
+ if (radial) {
+ if (layout->root->layout == layout) {
+ layout_radial = uiLayoutRadial(layout);
+ UI_block_layout_set_current(block, layout_radial);
+ }
+ else {
+ if (layout->item.type == ITEM_LAYOUT_RADIAL) {
+ layout_radial = layout;
+ }
+ UI_block_layout_set_current(block, layout);
+ }
+ }
+ else if (layout->root->type != UI_LAYOUT_MENU) {
+ UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1));
+ }
+ else {
+ UI_block_layout_set_current(block, layout);
+ }
+
+ for (item = item_array; item->identifier; item++) {
+ const bool is_first = item == item_array;
+
+ if (!item->identifier[0]) {
+ const EnumPropertyItem *next_item = item + 1;
+
+ /* Separate items, potentially with a label. */
+ if (next_item->identifier) {
+ /* Item without identifier but with name:
+ * Add group label for the following items. */
+ if (item->name) {
+ if (!is_first) {
+ uiItemS(block->curlayout);
+ }
+ uiItemL(block->curlayout, item->name, item->icon);
+ }
+ else if (radial && layout_radial) {
+ uiItemS(layout_radial);
+ }
+ else {
+ uiItemS(block->curlayout);
+ }
+ }
+ continue;
+ }
+
+ name = (!uiname || uiname[0]) ? item->name : "";
+ icon = item->icon;
+ value = item->value;
+ itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0);
+
+ if (icon && name[0] && !icon_only) {
+ but = uiDefIconTextButR_prop(
+ block, but_type, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ }
+ else if (icon) {
+ but = uiDefIconButR_prop(block,
+ but_type,
+ 0,
+ icon,
+ 0,
+ 0,
+ (is_first) ? itemw : ceilf(itemw - U.pixelsize),
+ h,
+ ptr,
+ prop,
+ -1,
+ 0,
+ value,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(
+ block, but_type, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ }
+
+ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
+ /* If this is set, assert since we're clobbering someone elses callback. */
+ BLI_assert(but->func == NULL);
+ UI_but_func_set(but, ui_item_enum_expand_handle, but, POINTER_FROM_INT(value));
+ }
+
+ if (uiLayoutGetLocalDir(layout) != UI_LAYOUT_HORIZONTAL) {
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ }
+
+ /* Allow quick, inaccurate swipe motions to switch tabs
+ * (no need to keep cursor over them). */
+ if (but_type == UI_BTYPE_TAB) {
+ but->flag |= UI_BUT_DRAG_LOCK;
+ }
+ }
+ UI_block_layout_set_current(block, layout);
+
+ if (free) {
+ MEM_freeN((void *)item_array);
+ }
+}
+static void ui_item_enum_expand(uiLayout *layout,
+ uiBlock *block,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ const char *uiname,
+ int h,
+ bool icon_only)
+{
+ ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_ROW, icon_only);
+}
+static void ui_item_enum_expand_tabs(uiLayout *layout,
+ bContext *C,
+ uiBlock *block,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ const char *uiname,
+ int h,
+ bool icon_only)
+{
+ uiBut *last = block->buttons.last;
+
+ ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_TAB, icon_only);
+ BLI_assert(last != block->buttons.last);
+ for (uiBut *tab = last ? last->next : block->buttons.first; tab; tab = tab->next) {
+ UI_but_drawflag_enable(tab, ui_but_align_opposite_to_area_align_get(CTX_wm_region(C)));
+ }
}
/* callback for keymap item change button */
static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_v))
{
- uiBut *but = but_v;
+ uiBut *but = but_v;
- RNA_boolean_set(&but->rnapoin, "shift", (but->modifier_key & KM_SHIFT) != 0);
- RNA_boolean_set(&but->rnapoin, "ctrl", (but->modifier_key & KM_CTRL) != 0);
- RNA_boolean_set(&but->rnapoin, "alt", (but->modifier_key & KM_ALT) != 0);
- RNA_boolean_set(&but->rnapoin, "oskey", (but->modifier_key & KM_OSKEY) != 0);
+ RNA_boolean_set(&but->rnapoin, "shift", (but->modifier_key & KM_SHIFT) != 0);
+ RNA_boolean_set(&but->rnapoin, "ctrl", (but->modifier_key & KM_CTRL) != 0);
+ RNA_boolean_set(&but->rnapoin, "alt", (but->modifier_key & KM_ALT) != 0);
+ RNA_boolean_set(&but->rnapoin, "oskey", (but->modifier_key & KM_OSKEY) != 0);
}
/**
@@ -831,130 +901,175 @@ static void ui_keymap_but_cb(bContext *UNUSED(C), void *but_v, void *UNUSED(key_
* \param w_hint: For varying width layout, this becomes the label width.
* Otherwise it's used to fit both items into it.
*/
-static uiBut *ui_item_with_label(
- uiLayout *layout, uiBlock *block, const char *name, int icon,
- PointerRNA *ptr, PropertyRNA *prop, int index,
- int x, int y, int w_hint, int h, int flag)
-{
- uiLayout *sub;
- uiBut *but = NULL;
- PropertyType type;
- PropertySubType subtype;
- int prop_but_width = w_hint;
- const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
-
- /* Always align item with label since text is already given enough space not to overlap. */
- sub = uiLayoutRow(layout, true);
- UI_block_layout_set_current(block, sub);
-
- if (name[0]) {
- int w_label;
-
- if (use_prop_sep) {
- w_label = (int)((w_hint * 2) * UI_ITEM_PROP_SEP_DIVIDE);
- }
- else {
- if (ui_layout_variable_size(layout)) {
- /* w_hint is width for label in this case.
- * Use a default width for property button(s) */
- prop_but_width = UI_UNIT_X * 5;
- w_label = w_hint;
- }
- else {
- w_label = w_hint / 3;
- }
- }
-
- uiBut *but_label = uiDefBut(block, UI_BTYPE_LABEL, 0, name, x, y, w_label, h, NULL, 0.0, 0.0, 0, 0, "");
- if (use_prop_sep) {
- but_label->drawflag |= UI_BUT_TEXT_RIGHT;
- but_label->drawflag &= ~UI_BUT_TEXT_LEFT;
- }
- }
-
- type = RNA_property_type(prop);
- subtype = RNA_property_subtype(prop);
-
- if (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
- UI_block_layout_set_current(block, uiLayoutRow(sub, true));
- but = uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, prop_but_width - UI_UNIT_X, h);
-
- /* BUTTONS_OT_file_browse calls UI_context_active_but_prop_get_filebrowser */
- uiDefIconButO(
- block, UI_BTYPE_BUT, subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" : "BUTTONS_OT_file_browse",
- WM_OP_INVOKE_DEFAULT, ICON_FILEBROWSER, x, y, UI_UNIT_X, h, NULL);
- }
- else if (flag & UI_ITEM_R_EVENT) {
- but = uiDefButR_prop(block, UI_BTYPE_KEY_EVENT, 0, name, x, y, prop_but_width, h, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else if (flag & UI_ITEM_R_FULL_EVENT) {
- if (RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) {
- char buf[128];
-
- WM_keymap_item_to_string(ptr->data, false, buf, sizeof(buf));
-
- but = uiDefButR_prop(block, UI_BTYPE_HOTKEY_EVENT, 0, buf, x, y, prop_but_width, h, ptr, prop, 0, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, ui_keymap_but_cb, but, NULL);
- if (flag & UI_ITEM_R_IMMEDIATE) {
- UI_but_flag_enable(but, UI_BUT_IMMEDIATE);
- }
- }
- }
- else {
- const char *str = (type == PROP_ENUM && !(flag & UI_ITEM_R_ICON_ONLY)) ? NULL : "";
- but = uiDefAutoButR(
- block, ptr, prop, index, str, icon,
- x, y, prop_but_width, h);
- }
+static uiBut *ui_item_with_label(uiLayout *layout,
+ uiBlock *block,
+ const char *name,
+ int icon,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int index,
+ int x,
+ int y,
+ int w_hint,
+ int h,
+ int flag)
+{
+ uiLayout *sub;
+ uiBut *but = NULL;
+ PropertyType type;
+ PropertySubType subtype;
+ int prop_but_width = w_hint;
+ const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
+
+ /* Always align item with label since text is already given enough space not to overlap. */
+ sub = uiLayoutRow(layout, true);
+ UI_block_layout_set_current(block, sub);
+
+ if (name[0]) {
+ int w_label;
+
+ if (use_prop_sep) {
+ w_label = (int)((w_hint * 2) * UI_ITEM_PROP_SEP_DIVIDE);
+ }
+ else {
+ if (ui_layout_variable_size(layout)) {
+ /* w_hint is width for label in this case.
+ * Use a default width for property button(s) */
+ prop_but_width = UI_UNIT_X * 5;
+ w_label = w_hint;
+ }
+ else {
+ w_label = w_hint / 3;
+ }
+ }
+
+ uiBut *but_label = uiDefBut(
+ block, UI_BTYPE_LABEL, 0, name, x, y, w_label, h, NULL, 0.0, 0.0, 0, 0, "");
+ if (use_prop_sep) {
+ but_label->drawflag |= UI_BUT_TEXT_RIGHT;
+ but_label->drawflag &= ~UI_BUT_TEXT_LEFT;
+ }
+ }
+
+ type = RNA_property_type(prop);
+ subtype = RNA_property_subtype(prop);
+
+ if (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) {
+ UI_block_layout_set_current(block, uiLayoutRow(sub, true));
+ but = uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, prop_but_width - UI_UNIT_X, h);
+
+ /* BUTTONS_OT_file_browse calls UI_context_active_but_prop_get_filebrowser */
+ uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" :
+ "BUTTONS_OT_file_browse",
+ WM_OP_INVOKE_DEFAULT,
+ ICON_FILEBROWSER,
+ x,
+ y,
+ UI_UNIT_X,
+ h,
+ NULL);
+ }
+ else if (flag & UI_ITEM_R_EVENT) {
+ but = uiDefButR_prop(block,
+ UI_BTYPE_KEY_EVENT,
+ 0,
+ name,
+ x,
+ y,
+ prop_but_width,
+ h,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else if (flag & UI_ITEM_R_FULL_EVENT) {
+ if (RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) {
+ char buf[128];
+
+ WM_keymap_item_to_string(ptr->data, false, buf, sizeof(buf));
+
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HOTKEY_EVENT,
+ 0,
+ buf,
+ x,
+ y,
+ prop_but_width,
+ h,
+ ptr,
+ prop,
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, ui_keymap_but_cb, but, NULL);
+ if (flag & UI_ITEM_R_IMMEDIATE) {
+ UI_but_flag_enable(but, UI_BUT_IMMEDIATE);
+ }
+ }
+ }
+ else {
+ const char *str = (type == PROP_ENUM && !(flag & UI_ITEM_R_ICON_ONLY)) ? NULL : "";
+ but = uiDefAutoButR(block, ptr, prop, index, str, icon, x, y, prop_but_width, h);
+ }
#ifdef UI_PROP_DECORATE
- /* Only for alignment. */
- if (layout->item.flag & UI_ITEM_PROP_SEP) {
- if ((layout->item.flag & UI_ITEM_PROP_DECORATE) &&
- (layout->item.flag & UI_ITEM_PROP_DECORATE_NO_PAD) == 0)
- {
- uiItemL(sub, NULL, ICON_BLANK1);
- }
- }
-#endif /* UI_PROP_DECORATE */
-
- UI_block_layout_set_current(block, layout);
- return but;
-}
-
-void UI_context_active_but_prop_get_filebrowser(
- const bContext *C,
- PointerRNA *r_ptr, PropertyRNA **r_prop, bool *r_is_undo)
-{
- ARegion *ar = CTX_wm_region(C);
- uiBlock *block;
- uiBut *but, *prevbut = NULL;
-
- memset(r_ptr, 0, sizeof(*r_ptr));
- *r_prop = NULL;
- *r_is_undo = false;
-
- if (!ar) {
- return;
- }
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but && but->rnapoin.data) {
- if (RNA_property_type(but->rnaprop) == PROP_STRING) {
- prevbut = but;
- }
- }
-
- /* find the button before the active one */
- if ((but->flag & UI_BUT_LAST_ACTIVE) && prevbut) {
- *r_ptr = prevbut->rnapoin;
- *r_prop = prevbut->rnaprop;
- *r_is_undo = (prevbut->flag & UI_BUT_UNDO) != 0;
- return;
- }
- }
- }
+ /* Only for alignment. */
+ if (layout->item.flag & UI_ITEM_PROP_SEP) {
+ if ((layout->item.flag & UI_ITEM_PROP_DECORATE) &&
+ (layout->item.flag & UI_ITEM_PROP_DECORATE_NO_PAD) == 0) {
+ uiItemL(sub, NULL, ICON_BLANK1);
+ }
+ }
+#endif /* UI_PROP_DECORATE */
+
+ UI_block_layout_set_current(block, layout);
+ return but;
+}
+
+void UI_context_active_but_prop_get_filebrowser(const bContext *C,
+ PointerRNA *r_ptr,
+ PropertyRNA **r_prop,
+ bool *r_is_undo)
+{
+ ARegion *ar = CTX_wm_region(C);
+ uiBlock *block;
+ uiBut *but, *prevbut = NULL;
+
+ memset(r_ptr, 0, sizeof(*r_ptr));
+ *r_prop = NULL;
+ *r_is_undo = false;
+
+ if (!ar) {
+ return;
+ }
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but && but->rnapoin.data) {
+ if (RNA_property_type(but->rnaprop) == PROP_STRING) {
+ prevbut = but;
+ }
+ }
+
+ /* find the button before the active one */
+ if ((but->flag & UI_BUT_LAST_ACTIVE) && prevbut) {
+ *r_ptr = prevbut->rnapoin;
+ *r_prop = prevbut->rnaprop;
+ *r_is_undo = (prevbut->flag & UI_BUT_UNDO) != 0;
+ return;
+ }
+ }
+ }
}
/********************* Button Items *************************/
@@ -964,31 +1079,31 @@ void UI_context_active_but_prop_get_filebrowser(
*/
static void ui_but_tip_from_enum_item(uiBut *but, const EnumPropertyItem *item)
{
- if (but->tip == NULL || but->tip[0] == '\0') {
- if (item->description && item->description[0]) {
- but->tip = item->description;
- }
- }
+ if (but->tip == NULL || but->tip[0] == '\0') {
+ if (item->description && item->description[0]) {
+ but->tip = item->description;
+ }
+ }
}
/* disabled item */
static void ui_item_disabled(uiLayout *layout, const char *name)
{
- uiBlock *block = layout->root->block;
- uiBut *but;
- int w;
+ uiBlock *block = layout->root->block;
+ uiBut *but;
+ int w;
- UI_block_layout_set_current(block, layout);
+ UI_block_layout_set_current(block, layout);
- if (!name) {
- name = "";
- }
+ if (!name) {
+ name = "";
+ }
- w = ui_text_icon_width(layout, name, 0, 0);
+ w = ui_text_icon_width(layout, name, 0, 0);
- but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- but->flag |= UI_BUT_DISABLED;
- but->disabled_info = "";
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but->flag |= UI_BUT_DISABLED;
+ but->disabled_info = "";
}
/**
@@ -996,231 +1111,259 @@ static void ui_item_disabled(uiLayout *layout, const char *name)
* \param r_opptr: Optional, initialize with operator properties when not NULL.
* Will always be written to even in the case of errors.
*/
-static uiBut *uiItemFullO_ptr_ex(
- uiLayout *layout, wmOperatorType *ot,
- const char *name, int icon, IDProperty *properties, int context, int flag,
- PointerRNA *r_opptr)
-{
- /* Take care to fill 'r_opptr' whatever happens. */
- uiBlock *block = layout->root->block;
- uiBut *but;
- int w;
-
- if (!name) {
- if (ot && ot->srna && (flag & UI_ITEM_R_ICON_ONLY) == 0) {
- name = RNA_struct_ui_name(ot->srna);
- }
- else {
- name = "";
- }
- }
-
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
-
- /* create button */
- UI_block_layout_set_current(block, layout);
-
- w = ui_text_icon_width(layout, name, icon, 0);
-
- int prev_emboss = layout->emboss;
- if (flag & UI_ITEM_R_NO_BG) {
- layout->emboss = UI_EMBOSS_NONE;
- }
-
- /* create the button */
- if (icon) {
- if (name[0]) {
- but = uiDefIconTextButO_ptr(block, UI_BTYPE_BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL);
- }
- else {
- but = uiDefIconButO_ptr(block, UI_BTYPE_BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL);
- }
- }
- else {
- but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL);
- }
-
- assert(but->optype != NULL);
-
- /* text alignment for toolbar buttons */
- if ((layout->root->type == UI_LAYOUT_TOOLBAR) && !icon) {
- but->drawflag |= UI_BUT_TEXT_LEFT;
- }
-
- if (flag & UI_ITEM_R_NO_BG) {
- layout->emboss = prev_emboss;
- }
-
- if (flag & UI_ITEM_O_DEPRESS) {
- but->flag |= UI_SELECT_DRAW;
- }
-
- if (layout->redalert) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
-
- if (layout->active_default) {
- UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
- }
-
- /* assign properties */
- if (properties || r_opptr) {
- PointerRNA *opptr = UI_but_operator_ptr_get(but);
- if (properties) {
- opptr->data = properties;
- }
- else {
- IDPropertyTemplate val = {0};
- opptr->data = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
- }
- if (r_opptr) {
- *r_opptr = *opptr;
- }
- }
-
- return but;
+static uiBut *uiItemFullO_ptr_ex(uiLayout *layout,
+ wmOperatorType *ot,
+ const char *name,
+ int icon,
+ IDProperty *properties,
+ int context,
+ int flag,
+ PointerRNA *r_opptr)
+{
+ /* Take care to fill 'r_opptr' whatever happens. */
+ uiBlock *block = layout->root->block;
+ uiBut *but;
+ int w;
+
+ if (!name) {
+ if (ot && ot->srna && (flag & UI_ITEM_R_ICON_ONLY) == 0) {
+ name = RNA_struct_ui_name(ot->srna);
+ }
+ else {
+ name = "";
+ }
+ }
+
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
+
+ /* create button */
+ UI_block_layout_set_current(block, layout);
+
+ w = ui_text_icon_width(layout, name, icon, 0);
+
+ int prev_emboss = layout->emboss;
+ if (flag & UI_ITEM_R_NO_BG) {
+ layout->emboss = UI_EMBOSS_NONE;
+ }
+
+ /* create the button */
+ if (icon) {
+ if (name[0]) {
+ but = uiDefIconTextButO_ptr(
+ block, UI_BTYPE_BUT, ot, context, icon, name, 0, 0, w, UI_UNIT_Y, NULL);
+ }
+ else {
+ but = uiDefIconButO_ptr(block, UI_BTYPE_BUT, ot, context, icon, 0, 0, w, UI_UNIT_Y, NULL);
+ }
+ }
+ else {
+ but = uiDefButO_ptr(block, UI_BTYPE_BUT, ot, context, name, 0, 0, w, UI_UNIT_Y, NULL);
+ }
+
+ assert(but->optype != NULL);
+
+ /* text alignment for toolbar buttons */
+ if ((layout->root->type == UI_LAYOUT_TOOLBAR) && !icon) {
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ }
+
+ if (flag & UI_ITEM_R_NO_BG) {
+ layout->emboss = prev_emboss;
+ }
+
+ if (flag & UI_ITEM_O_DEPRESS) {
+ but->flag |= UI_SELECT_DRAW;
+ }
+
+ if (layout->redalert) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+
+ if (layout->active_default) {
+ UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
+ }
+
+ /* assign properties */
+ if (properties || r_opptr) {
+ PointerRNA *opptr = UI_but_operator_ptr_get(but);
+ if (properties) {
+ opptr->data = properties;
+ }
+ else {
+ IDPropertyTemplate val = {0};
+ opptr->data = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
+ }
+ if (r_opptr) {
+ *r_opptr = *opptr;
+ }
+ }
+
+ return but;
}
static void ui_item_menu_hold(struct bContext *C, ARegion *butregion, uiBut *but)
{
- uiPopupMenu *pup = UI_popup_menu_begin(C, "", ICON_NONE);
- uiLayout *layout = UI_popup_menu_layout(pup);
- uiBlock *block = layout->root->block;
- UI_popup_menu_but_set(pup, butregion, but);
-
- block->flag |= UI_BLOCK_POPUP_HOLD;
- block->flag |= UI_BLOCK_IS_FLIP;
-
- char direction = UI_DIR_DOWN;
- if (!but->drawstr[0]) {
- if (butregion->alignment == RGN_ALIGN_LEFT) {
- direction = UI_DIR_RIGHT;
- }
- else if (butregion->alignment == RGN_ALIGN_RIGHT) {
- direction = UI_DIR_LEFT;
- }
- else if (butregion->alignment == RGN_ALIGN_BOTTOM) {
- direction = UI_DIR_UP;
- }
- else {
- direction = UI_DIR_DOWN;
- }
- }
- UI_block_direction_set(block, direction);
-
- const char *menu_id = but->hold_argN;
- MenuType *mt = WM_menutype_find(menu_id, true);
- if (mt) {
- uiLayoutSetContextFromBut(layout, but);
- UI_menutype_draw(C, mt, layout);
- }
- else {
- uiItemL(layout, "Menu Missing:", ICON_NONE);
- uiItemL(layout, menu_id, ICON_NONE);
- }
- UI_popup_menu_end(C, pup);
-}
-
-void uiItemFullO_ptr(
- uiLayout *layout, wmOperatorType *ot,
- const char *name, int icon, IDProperty *properties, int context, int flag,
- PointerRNA *r_opptr)
-{
- uiItemFullO_ptr_ex(layout, ot, name, icon, properties, context, flag, r_opptr);
-}
-
-void uiItemFullOMenuHold_ptr(
- uiLayout *layout, wmOperatorType *ot,
- const char *name, int icon, IDProperty *properties, int context, int flag,
- const char *menu_id,
- PointerRNA *r_opptr)
-{
- uiBut *but = uiItemFullO_ptr_ex(layout, ot, name, icon, properties, context, flag, r_opptr);
- UI_but_func_hold_set(but, ui_item_menu_hold, BLI_strdup(menu_id));
-}
-
-void uiItemFullO(
- uiLayout *layout, const char *opname,
- const char *name, int icon, IDProperty *properties, int context, int flag,
- PointerRNA *r_opptr)
-{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
-
- UI_OPERATOR_ERROR_RET(
- ot, opname, {
- if (r_opptr) {
- *r_opptr = PointerRNA_NULL;
- }
- return;
- });
+ uiPopupMenu *pup = UI_popup_menu_begin(C, "", ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+ uiBlock *block = layout->root->block;
+ UI_popup_menu_but_set(pup, butregion, but);
+
+ block->flag |= UI_BLOCK_POPUP_HOLD;
+ block->flag |= UI_BLOCK_IS_FLIP;
+
+ char direction = UI_DIR_DOWN;
+ if (!but->drawstr[0]) {
+ if (butregion->alignment == RGN_ALIGN_LEFT) {
+ direction = UI_DIR_RIGHT;
+ }
+ else if (butregion->alignment == RGN_ALIGN_RIGHT) {
+ direction = UI_DIR_LEFT;
+ }
+ else if (butregion->alignment == RGN_ALIGN_BOTTOM) {
+ direction = UI_DIR_UP;
+ }
+ else {
+ direction = UI_DIR_DOWN;
+ }
+ }
+ UI_block_direction_set(block, direction);
+
+ const char *menu_id = but->hold_argN;
+ MenuType *mt = WM_menutype_find(menu_id, true);
+ if (mt) {
+ uiLayoutSetContextFromBut(layout, but);
+ UI_menutype_draw(C, mt, layout);
+ }
+ else {
+ uiItemL(layout, "Menu Missing:", ICON_NONE);
+ uiItemL(layout, menu_id, ICON_NONE);
+ }
+ UI_popup_menu_end(C, pup);
+}
+
+void uiItemFullO_ptr(uiLayout *layout,
+ wmOperatorType *ot,
+ const char *name,
+ int icon,
+ IDProperty *properties,
+ int context,
+ int flag,
+ PointerRNA *r_opptr)
+{
+ uiItemFullO_ptr_ex(layout, ot, name, icon, properties, context, flag, r_opptr);
+}
+
+void uiItemFullOMenuHold_ptr(uiLayout *layout,
+ wmOperatorType *ot,
+ const char *name,
+ int icon,
+ IDProperty *properties,
+ int context,
+ int flag,
+ const char *menu_id,
+ PointerRNA *r_opptr)
+{
+ uiBut *but = uiItemFullO_ptr_ex(layout, ot, name, icon, properties, context, flag, r_opptr);
+ UI_but_func_hold_set(but, ui_item_menu_hold, BLI_strdup(menu_id));
+}
+
+void uiItemFullO(uiLayout *layout,
+ const char *opname,
+ const char *name,
+ int icon,
+ IDProperty *properties,
+ int context,
+ int flag,
+ PointerRNA *r_opptr)
+{
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+
+ UI_OPERATOR_ERROR_RET(ot, opname, {
+ if (r_opptr) {
+ *r_opptr = PointerRNA_NULL;
+ }
+ return;
+ });
+
+ uiItemFullO_ptr(layout, ot, name, icon, properties, context, flag, r_opptr);
+}
+
+static const char *ui_menu_enumpropname(uiLayout *layout,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int retval)
+{
+ const EnumPropertyItem *item;
+ bool free;
+ const char *name;
+
+ RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
+ if (RNA_enum_name(item, retval, &name)) {
+ name = CTX_IFACE_(RNA_property_translation_context(prop), name);
+ }
+ else {
+ name = "";
+ }
+
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+
+ return name;
+}
+
+void uiItemEnumO_ptr(uiLayout *layout,
+ wmOperatorType *ot,
+ const char *name,
+ int icon,
+ const char *propname,
+ int value)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ WM_operator_properties_create_ptr(&ptr, ot);
+
+ if ((prop = RNA_struct_find_property(&ptr, propname))) {
+ /* pass */
+ }
+ else {
+ RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
+ return;
+ }
+
+ RNA_property_enum_set(&ptr, prop, value);
+
+ if (!name) {
+ name = ui_menu_enumpropname(layout, &ptr, prop, value);
+ }
- uiItemFullO_ptr(layout, ot, name, icon, properties, context, flag, r_opptr);
+ uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
}
-
-static const char *ui_menu_enumpropname(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int retval)
+void uiItemEnumO(uiLayout *layout,
+ const char *opname,
+ const char *name,
+ int icon,
+ const char *propname,
+ int value)
{
- const EnumPropertyItem *item;
- bool free;
- const char *name;
-
- RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
- if (RNA_enum_name(item, retval, &name)) {
- name = CTX_IFACE_(RNA_property_translation_context(prop), name);
- }
- else {
- name = "";
- }
-
- if (free) {
- MEM_freeN((void *)item);
- }
-
- return name;
-}
-
-void uiItemEnumO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, const char *propname, int value)
-{
- PointerRNA ptr;
- PropertyRNA *prop;
-
- WM_operator_properties_create_ptr(&ptr, ot);
-
- if ((prop = RNA_struct_find_property(&ptr, propname))) {
- /* pass */
- }
- else {
- RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
- return;
- }
-
- RNA_property_enum_set(&ptr, prop, value);
-
- if (!name) {
- name = ui_menu_enumpropname(layout, &ptr, prop, value);
- }
-
- uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
-}
-void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value)
-{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
-
- if (ot) {
- uiItemEnumO_ptr(layout, ot, name, icon, propname, value);
- }
- else {
- ui_item_disabled(layout, opname);
- RNA_warning("unknown operator '%s'", opname);
- }
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ if (ot) {
+ uiItemEnumO_ptr(layout, ot, name, icon, propname, value);
+ }
+ else {
+ ui_item_disabled(layout, opname);
+ RNA_warning("unknown operator '%s'", opname);
+ }
}
BLI_INLINE bool ui_layout_is_radial(const uiLayout *layout)
{
- return (layout->item.type == ITEM_LAYOUT_RADIAL) ||
- ((layout->item.type == ITEM_LAYOUT_ROOT) && (layout->root->type == UI_LAYOUT_PIEMENU));
+ return (layout->item.type == ITEM_LAYOUT_RADIAL) ||
+ ((layout->item.type == ITEM_LAYOUT_ROOT) && (layout->root->type == UI_LAYOUT_PIEMENU));
}
/**
@@ -1228,1454 +1371,1657 @@ BLI_INLINE bool ui_layout_is_radial(const uiLayout *layout)
*
* A version of #uiItemsFullEnumO that takes pre-calculated item array.
*/
-void uiItemsFullEnumO_items(
- uiLayout *layout, wmOperatorType *ot, PointerRNA ptr, PropertyRNA *prop, IDProperty *properties,
- int context, int flag,
- const EnumPropertyItem *item_array, int totitem)
-{
- const char *propname = RNA_property_identifier(prop);
- if (RNA_property_type(prop) != PROP_ENUM) {
- RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
- return;
- }
-
- uiLayout *target, *split = NULL;
- const EnumPropertyItem *item;
- uiBlock *block = layout->root->block;
- const bool radial = ui_layout_is_radial(layout);
-
- if (radial) {
- target = uiLayoutRadial(layout);
- }
- else {
- split = uiLayoutSplit(layout, 0.0f, false);
- target = uiLayoutColumn(split, layout->align);
- }
-
-
- int i;
- bool last_iter = false;
-
- for (i = 1, item = item_array; item->identifier && !last_iter; i++, item++) {
- /* handle oversized pies */
- if (radial && (totitem > PIE_MAX_ITEMS) && (i >= PIE_MAX_ITEMS)) {
- if (item->name) { /* only visible items */
- const EnumPropertyItem *tmp;
-
- /* Check if there are more visible items for the next level. If not, we don't
- * add a new level and add the remaining item instead of the 'more' button. */
- for (tmp = item + 1; tmp->identifier; tmp++) {
- if (tmp->name) {
- break;
- }
- }
-
- if (tmp->identifier) { /* only true if loop above found item and did early-exit */
- ui_pie_menu_level_create(block, ot, propname, properties, item_array, totitem, context, flag);
- /* break since rest of items is handled in new pie level */
- break;
- }
- else {
- last_iter = true;
- }
- }
- else {
- continue;
- }
- }
-
- if (item->identifier[0]) {
- PointerRNA tptr;
-
- WM_operator_properties_create_ptr(&tptr, ot);
- if (properties) {
- if (tptr.data) {
- IDP_FreeProperty(tptr.data);
- MEM_freeN(tptr.data);
- }
- tptr.data = IDP_CopyProperty(properties);
- }
- RNA_property_enum_set(&tptr, prop, item->value);
-
- uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag, NULL);
-
- ui_but_tip_from_enum_item(block->buttons.last, item);
- }
- else {
- if (item->name) {
- uiBut *but;
-
- if (item != item_array && !radial) {
- target = uiLayoutColumn(split, layout->align);
-
- /* inconsistent, but menus with labels do not look good flipped */
- block->flag |= UI_BLOCK_NO_FLIP;
- }
-
- if (item->icon || radial) {
- uiItemL(target, item->name, item->icon);
-
- but = block->buttons.last;
- }
- else {
- /* Do not use uiItemL here, as our root layout is a menu one,
- * it will add a fake blank icon! */
- but = uiDefBut(
- block, UI_BTYPE_LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL,
- 0.0, 0.0, 0, 0, "");
- }
- ui_but_tip_from_enum_item(but, item);
- }
- else {
- if (radial) {
- /* invisible dummy button to ensure all items are
- * always at the same position */
- uiItemS(target);
- }
- else {
- /* XXX bug here, columns draw bottom item badly */
- uiItemS(target);
- }
- }
- }
- }
-}
-
-void uiItemsFullEnumO(
- uiLayout *layout, const char *opname, const char *propname, IDProperty *properties,
- int context, int flag)
-{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
-
- PointerRNA ptr;
- PropertyRNA *prop;
- uiBlock *block = layout->root->block;
-
- if (!ot || !ot->srna) {
- ui_item_disabled(layout, opname);
- RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
- return;
- }
-
- WM_operator_properties_create_ptr(&ptr, ot);
- /* so the context is passed to itemf functions (some need it) */
- WM_operator_properties_sanitize(&ptr, false);
- prop = RNA_struct_find_property(&ptr, propname);
-
- /* don't let bad properties slip through */
- BLI_assert((prop == NULL) || (RNA_property_type(prop) == PROP_ENUM));
-
- if (prop && RNA_property_type(prop) == PROP_ENUM) {
- const EnumPropertyItem *item_array = NULL;
- int totitem;
- bool free;
-
- if (ui_layout_is_radial(layout)) {
- /* XXX: While "_all()" guarantees spatial stability, it's bad when an enum has > 8 items total,
- * but only a small subset will ever be shown at once (e.g. Mode Switch menu, after the
- * introduction of GP editing modes)
- */
+void uiItemsFullEnumO_items(uiLayout *layout,
+ wmOperatorType *ot,
+ PointerRNA ptr,
+ PropertyRNA *prop,
+ IDProperty *properties,
+ int context,
+ int flag,
+ const EnumPropertyItem *item_array,
+ int totitem)
+{
+ const char *propname = RNA_property_identifier(prop);
+ if (RNA_property_type(prop) != PROP_ENUM) {
+ RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
+ return;
+ }
+
+ uiLayout *target, *split = NULL;
+ const EnumPropertyItem *item;
+ uiBlock *block = layout->root->block;
+ const bool radial = ui_layout_is_radial(layout);
+
+ if (radial) {
+ target = uiLayoutRadial(layout);
+ }
+ else {
+ split = uiLayoutSplit(layout, 0.0f, false);
+ target = uiLayoutColumn(split, layout->align);
+ }
+
+ int i;
+ bool last_iter = false;
+
+ for (i = 1, item = item_array; item->identifier && !last_iter; i++, item++) {
+ /* handle oversized pies */
+ if (radial && (totitem > PIE_MAX_ITEMS) && (i >= PIE_MAX_ITEMS)) {
+ if (item->name) { /* only visible items */
+ const EnumPropertyItem *tmp;
+
+ /* Check if there are more visible items for the next level. If not, we don't
+ * add a new level and add the remaining item instead of the 'more' button. */
+ for (tmp = item + 1; tmp->identifier; tmp++) {
+ if (tmp->name) {
+ break;
+ }
+ }
+
+ if (tmp->identifier) { /* only true if loop above found item and did early-exit */
+ ui_pie_menu_level_create(
+ block, ot, propname, properties, item_array, totitem, context, flag);
+ /* break since rest of items is handled in new pie level */
+ break;
+ }
+ else {
+ last_iter = true;
+ }
+ }
+ else {
+ continue;
+ }
+ }
+
+ if (item->identifier[0]) {
+ PointerRNA tptr;
+
+ WM_operator_properties_create_ptr(&tptr, ot);
+ if (properties) {
+ if (tptr.data) {
+ IDP_FreeProperty(tptr.data);
+ MEM_freeN(tptr.data);
+ }
+ tptr.data = IDP_CopyProperty(properties);
+ }
+ RNA_property_enum_set(&tptr, prop, item->value);
+
+ uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag, NULL);
+
+ ui_but_tip_from_enum_item(block->buttons.last, item);
+ }
+ else {
+ if (item->name) {
+ uiBut *but;
+
+ if (item != item_array && !radial) {
+ target = uiLayoutColumn(split, layout->align);
+
+ /* inconsistent, but menus with labels do not look good flipped */
+ block->flag |= UI_BLOCK_NO_FLIP;
+ }
+
+ if (item->icon || radial) {
+ uiItemL(target, item->name, item->icon);
+
+ but = block->buttons.last;
+ }
+ else {
+ /* Do not use uiItemL here, as our root layout is a menu one,
+ * it will add a fake blank icon! */
+ but = uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ item->name,
+ 0,
+ 0,
+ UI_UNIT_X * 5,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ }
+ ui_but_tip_from_enum_item(but, item);
+ }
+ else {
+ if (radial) {
+ /* invisible dummy button to ensure all items are
+ * always at the same position */
+ uiItemS(target);
+ }
+ else {
+ /* XXX bug here, columns draw bottom item badly */
+ uiItemS(target);
+ }
+ }
+ }
+ }
+}
+
+void uiItemsFullEnumO(uiLayout *layout,
+ const char *opname,
+ const char *propname,
+ IDProperty *properties,
+ int context,
+ int flag)
+{
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ uiBlock *block = layout->root->block;
+
+ if (!ot || !ot->srna) {
+ ui_item_disabled(layout, opname);
+ RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname);
+ return;
+ }
+
+ WM_operator_properties_create_ptr(&ptr, ot);
+ /* so the context is passed to itemf functions (some need it) */
+ WM_operator_properties_sanitize(&ptr, false);
+ prop = RNA_struct_find_property(&ptr, propname);
+
+ /* don't let bad properties slip through */
+ BLI_assert((prop == NULL) || (RNA_property_type(prop) == PROP_ENUM));
+
+ if (prop && RNA_property_type(prop) == PROP_ENUM) {
+ const EnumPropertyItem *item_array = NULL;
+ int totitem;
+ bool free;
+
+ if (ui_layout_is_radial(layout)) {
+ /* XXX: While "_all()" guarantees spatial stability, it's bad when an enum has > 8 items total,
+ * but only a small subset will ever be shown at once (e.g. Mode Switch menu, after the
+ * introduction of GP editing modes)
+ */
#if 0
- RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
+ RNA_property_enum_items_gettexted_all(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
#else
- RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
+ RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
#endif
- }
- else {
- RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
- }
-
- /* add items */
- uiItemsFullEnumO_items(
- layout, ot, ptr, prop, properties, context, flag,
- item_array, totitem);
-
- if (free) {
- MEM_freeN((void *)item_array);
- }
-
- /* intentionally don't touch UI_BLOCK_IS_FLIP here,
- * we don't know the context this is called in */
- }
- else if (prop && RNA_property_type(prop) != PROP_ENUM) {
- RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
- return;
- }
- else {
- RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
- return;
- }
+ }
+ else {
+ RNA_property_enum_items_gettexted(block->evil_C, &ptr, prop, &item_array, &totitem, &free);
+ }
+
+ /* add items */
+ uiItemsFullEnumO_items(layout, ot, ptr, prop, properties, context, flag, item_array, totitem);
+
+ if (free) {
+ MEM_freeN((void *)item_array);
+ }
+
+ /* intentionally don't touch UI_BLOCK_IS_FLIP here,
+ * we don't know the context this is called in */
+ }
+ else if (prop && RNA_property_type(prop) != PROP_ENUM) {
+ RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
+ return;
+ }
+ else {
+ RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
+ return;
+ }
}
void uiItemsEnumO(uiLayout *layout, const char *opname, const char *propname)
{
- uiItemsFullEnumO(layout, opname, propname, NULL, layout->root->opcontext, 0);
+ uiItemsFullEnumO(layout, opname, propname, NULL, layout->root->opcontext, 0);
}
/* for use in cases where we have */
-void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
+void uiItemEnumO_value(uiLayout *layout,
+ const char *name,
+ int icon,
+ const char *opname,
+ const char *propname,
+ int value)
{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
- PointerRNA ptr;
- PropertyRNA *prop;
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ PointerRNA ptr;
+ PropertyRNA *prop;
- UI_OPERATOR_ERROR_RET(ot, opname, return);
+ UI_OPERATOR_ERROR_RET(ot, opname, return );
- WM_operator_properties_create_ptr(&ptr, ot);
+ WM_operator_properties_create_ptr(&ptr, ot);
- /* enum lookup */
- if ((prop = RNA_struct_find_property(&ptr, propname))) {
- /* pass */
- }
- else {
- RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
- return;
- }
+ /* enum lookup */
+ if ((prop = RNA_struct_find_property(&ptr, propname))) {
+ /* pass */
+ }
+ else {
+ RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
+ return;
+ }
- RNA_property_enum_set(&ptr, prop, value);
+ RNA_property_enum_set(&ptr, prop, value);
- /* same as uiItemEnumO */
- if (!name) {
- name = ui_menu_enumpropname(layout, &ptr, prop, value);
- }
+ /* same as uiItemEnumO */
+ if (!name) {
+ name = ui_menu_enumpropname(layout, &ptr, prop, value);
+ }
- uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
+ uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
}
-void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value_str)
+void uiItemEnumO_string(uiLayout *layout,
+ const char *name,
+ int icon,
+ const char *opname,
+ const char *propname,
+ const char *value_str)
{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
- PointerRNA ptr;
- PropertyRNA *prop;
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ PointerRNA ptr;
+ PropertyRNA *prop;
- const EnumPropertyItem *item;
- int value;
- bool free;
+ const EnumPropertyItem *item;
+ int value;
+ bool free;
- UI_OPERATOR_ERROR_RET(ot, opname, return);
+ UI_OPERATOR_ERROR_RET(ot, opname, return );
- WM_operator_properties_create_ptr(&ptr, ot);
+ WM_operator_properties_create_ptr(&ptr, ot);
- /* enum lookup */
- if ((prop = RNA_struct_find_property(&ptr, propname))) {
- /* no need for translations here */
- RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
- if (item == NULL || RNA_enum_value_from_id(item, value_str, &value) == 0) {
- if (free) {
- MEM_freeN((void *)item);
- }
- RNA_warning("%s.%s, enum %s not found", RNA_struct_identifier(ptr.type), propname, value_str);
- return;
- }
+ /* enum lookup */
+ if ((prop = RNA_struct_find_property(&ptr, propname))) {
+ /* no need for translations here */
+ RNA_property_enum_items(layout->root->block->evil_C, &ptr, prop, &item, NULL, &free);
+ if (item == NULL || RNA_enum_value_from_id(item, value_str, &value) == 0) {
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+ RNA_warning(
+ "%s.%s, enum %s not found", RNA_struct_identifier(ptr.type), propname, value_str);
+ return;
+ }
- if (free) {
- MEM_freeN((void *)item);
- }
- }
- else {
- RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
- return;
- }
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+ }
+ else {
+ RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), propname);
+ return;
+ }
- RNA_property_enum_set(&ptr, prop, value);
+ RNA_property_enum_set(&ptr, prop, value);
- /* same as uiItemEnumO */
- if (!name) {
- name = ui_menu_enumpropname(layout, &ptr, prop, value);
- }
+ /* same as uiItemEnumO */
+ if (!name) {
+ name = ui_menu_enumpropname(layout, &ptr, prop, value);
+ }
- uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
+ uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
}
-void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
+void uiItemBooleanO(uiLayout *layout,
+ const char *name,
+ int icon,
+ const char *opname,
+ const char *propname,
+ int value)
{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
- PointerRNA ptr;
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return);
+ UI_OPERATOR_ERROR_RET(ot, opname, return );
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_boolean_set(&ptr, propname, value);
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_boolean_set(&ptr, propname, value);
- uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
+ uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
}
-void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
+void uiItemIntO(uiLayout *layout,
+ const char *name,
+ int icon,
+ const char *opname,
+ const char *propname,
+ int value)
{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
- PointerRNA ptr;
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return);
+ UI_OPERATOR_ERROR_RET(ot, opname, return );
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_int_set(&ptr, propname, value);
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_int_set(&ptr, propname, value);
- uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
+ uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
}
-void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value)
+void uiItemFloatO(uiLayout *layout,
+ const char *name,
+ int icon,
+ const char *opname,
+ const char *propname,
+ float value)
{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
- PointerRNA ptr;
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return);
+ UI_OPERATOR_ERROR_RET(ot, opname, return );
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_float_set(&ptr, propname, value);
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_float_set(&ptr, propname, value);
- uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
+ uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
}
-void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value)
+void uiItemStringO(uiLayout *layout,
+ const char *name,
+ int icon,
+ const char *opname,
+ const char *propname,
+ const char *value)
{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
- PointerRNA ptr;
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ PointerRNA ptr;
- UI_OPERATOR_ERROR_RET(ot, opname, return);
+ UI_OPERATOR_ERROR_RET(ot, opname, return );
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_string_set(&ptr, propname, value);
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_string_set(&ptr, propname, value);
- uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
+ uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL);
}
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
{
- uiItemFullO(layout, opname, name, icon, NULL, layout->root->opcontext, 0, NULL);
+ uiItemFullO(layout, opname, name, icon, NULL, layout->root->opcontext, 0, NULL);
}
/* RNA property items */
-static void ui_item_rna_size(
- uiLayout *layout, const char *name, int icon,
- PointerRNA *ptr, PropertyRNA *prop,
- int index, bool icon_only, bool compact,
- int *r_w, int *r_h)
-{
- PropertyType type;
- PropertySubType subtype;
- int len, w = 0, h;
-
- /* arbitrary extended width by type */
- type = RNA_property_type(prop);
- subtype = RNA_property_subtype(prop);
- len = RNA_property_array_length(ptr, prop);
-
- if (!name[0] && !icon_only) {
- if (ELEM(type, PROP_STRING, PROP_POINTER)) {
- name = "non-empty text";
- }
- else if (type == PROP_BOOLEAN) {
- icon = ICON_DOT;
- }
- else if (type == PROP_ENUM) {
- /* Find the longest enum item name, instead of using a dummy text! */
- const EnumPropertyItem *item, *item_array;
- bool free;
-
- RNA_property_enum_items_gettexted(layout->root->block->evil_C, ptr, prop, &item_array, NULL, &free);
- for (item = item_array; item->identifier; item++) {
- if (item->identifier[0]) {
- w = max_ii(w, ui_text_icon_width(layout, item->name, item->icon, compact));
- }
- }
- if (free) {
- MEM_freeN((void *)item_array);
- }
- }
- }
-
- if (!w) {
- if (type == PROP_ENUM && icon_only) {
- w = ui_text_icon_width(layout, "", ICON_BLANK1, compact);
- if (index != RNA_ENUM_VALUE) {
- w += 0.6f * UI_UNIT_X;
- }
- }
- else {
- /* not compact for float/int buttons, looks too squashed */
- w = ui_text_icon_width(layout, name, icon, ELEM(type, PROP_FLOAT, PROP_INT) ? false : compact);
- }
- }
- h = UI_UNIT_Y;
-
- /* increase height for arrays */
- if (index == RNA_NO_INDEX && len > 0) {
- if (!name[0] && icon == ICON_NONE) {
- h = 0;
- }
- if (layout->item.flag & UI_ITEM_PROP_SEP) {
- h = 0;
- }
- if (ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) {
- h += 2 * UI_UNIT_Y;
- }
- else if (subtype == PROP_MATRIX) {
- h += ceilf(sqrtf(len)) * UI_UNIT_Y;
- }
- else {
- h += len * UI_UNIT_Y;
- }
- }
- else if (ui_layout_variable_size(layout)) {
- if (type == PROP_BOOLEAN && name[0]) {
- w += UI_UNIT_X / 5;
- }
- else if (type == PROP_ENUM && !icon_only) {
- w += UI_UNIT_X / 4;
- }
- else if (type == PROP_FLOAT || type == PROP_INT) {
- w += UI_UNIT_X * 3;
- }
- }
-
- *r_w = w;
- *r_h = h;
-}
-
-void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int flag, const char *name, int icon)
-{
- uiBlock *block = layout->root->block;
- uiBut *but = NULL;
- PropertyType type;
- char namestr[UI_MAX_NAME_STR];
- int len, w, h;
- bool slider, toggle, expand, icon_only, no_bg, compact;
- bool is_array;
- const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
-
- /* By default 'use_prop_sep' uses a separate column for labels.
- * This is an exception for check-boxes otherwise only the small checkbox region is clickable.
- *
- * Keep using 'use_prop_sep' instead of disabling it entirely because
- * we need the ability to have decorators still. */
- bool use_prop_sep_split_label = use_prop_sep;
+static void ui_item_rna_size(uiLayout *layout,
+ const char *name,
+ int icon,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int index,
+ bool icon_only,
+ bool compact,
+ int *r_w,
+ int *r_h)
+{
+ PropertyType type;
+ PropertySubType subtype;
+ int len, w = 0, h;
+
+ /* arbitrary extended width by type */
+ type = RNA_property_type(prop);
+ subtype = RNA_property_subtype(prop);
+ len = RNA_property_array_length(ptr, prop);
+
+ if (!name[0] && !icon_only) {
+ if (ELEM(type, PROP_STRING, PROP_POINTER)) {
+ name = "non-empty text";
+ }
+ else if (type == PROP_BOOLEAN) {
+ icon = ICON_DOT;
+ }
+ else if (type == PROP_ENUM) {
+ /* Find the longest enum item name, instead of using a dummy text! */
+ const EnumPropertyItem *item, *item_array;
+ bool free;
+
+ RNA_property_enum_items_gettexted(
+ layout->root->block->evil_C, ptr, prop, &item_array, NULL, &free);
+ for (item = item_array; item->identifier; item++) {
+ if (item->identifier[0]) {
+ w = max_ii(w, ui_text_icon_width(layout, item->name, item->icon, compact));
+ }
+ }
+ if (free) {
+ MEM_freeN((void *)item_array);
+ }
+ }
+ }
+
+ if (!w) {
+ if (type == PROP_ENUM && icon_only) {
+ w = ui_text_icon_width(layout, "", ICON_BLANK1, compact);
+ if (index != RNA_ENUM_VALUE) {
+ w += 0.6f * UI_UNIT_X;
+ }
+ }
+ else {
+ /* not compact for float/int buttons, looks too squashed */
+ w = ui_text_icon_width(
+ layout, name, icon, ELEM(type, PROP_FLOAT, PROP_INT) ? false : compact);
+ }
+ }
+ h = UI_UNIT_Y;
+
+ /* increase height for arrays */
+ if (index == RNA_NO_INDEX && len > 0) {
+ if (!name[0] && icon == ICON_NONE) {
+ h = 0;
+ }
+ if (layout->item.flag & UI_ITEM_PROP_SEP) {
+ h = 0;
+ }
+ if (ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) {
+ h += 2 * UI_UNIT_Y;
+ }
+ else if (subtype == PROP_MATRIX) {
+ h += ceilf(sqrtf(len)) * UI_UNIT_Y;
+ }
+ else {
+ h += len * UI_UNIT_Y;
+ }
+ }
+ else if (ui_layout_variable_size(layout)) {
+ if (type == PROP_BOOLEAN && name[0]) {
+ w += UI_UNIT_X / 5;
+ }
+ else if (type == PROP_ENUM && !icon_only) {
+ w += UI_UNIT_X / 4;
+ }
+ else if (type == PROP_FLOAT || type == PROP_INT) {
+ w += UI_UNIT_X * 3;
+ }
+ }
+
+ *r_w = w;
+ *r_h = h;
+}
+
+void uiItemFullR(uiLayout *layout,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int index,
+ int value,
+ int flag,
+ const char *name,
+ int icon)
+{
+ uiBlock *block = layout->root->block;
+ uiBut *but = NULL;
+ PropertyType type;
+ char namestr[UI_MAX_NAME_STR];
+ int len, w, h;
+ bool slider, toggle, expand, icon_only, no_bg, compact;
+ bool is_array;
+ const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
+
+ /* By default 'use_prop_sep' uses a separate column for labels.
+ * This is an exception for check-boxes otherwise only the small checkbox region is clickable.
+ *
+ * Keep using 'use_prop_sep' instead of disabling it entirely because
+ * we need the ability to have decorators still. */
+ bool use_prop_sep_split_label = use_prop_sep;
#ifdef UI_PROP_DECORATE
- struct {
- bool use_prop_decorate;
- int len;
- uiLayout *layout;
- uiBut *but;
- } ui_decorate = {
- .use_prop_decorate = (
- ((layout->item.flag & UI_ITEM_PROP_DECORATE) != 0) &&
- (use_prop_sep && ptr->id.data && id_can_have_animdata(ptr->id.data))),
- };
-#endif /* UI_PROP_DECORATE */
-
- UI_block_layout_set_current(block, layout);
-
- /* retrieve info */
- type = RNA_property_type(prop);
- is_array = RNA_property_array_check(prop);
- len = (is_array) ? RNA_property_array_length(ptr, prop) : 0;
-
- icon_only = (flag & UI_ITEM_R_ICON_ONLY) != 0;
-
- /* set name and icon */
- if (!name) {
- if (!icon_only) {
- name = RNA_property_ui_name(prop);
- }
- else {
- name = "";
- }
- }
-
- if (icon == ICON_NONE) {
- icon = RNA_property_ui_icon(prop);
- }
-
- if (flag & UI_ITEM_R_ICON_ONLY) {
- /* pass */
- }
- else if (ELEM(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER)) {
- if (use_prop_sep == false) {
- name = ui_item_name_add_colon(name, namestr);
- }
- }
- else if (type == PROP_BOOLEAN && is_array && index == RNA_NO_INDEX) {
- if (use_prop_sep == false) {
- name = ui_item_name_add_colon(name, namestr);
- }
- }
- else if (type == PROP_ENUM && index != RNA_ENUM_VALUE) {
- if (flag & UI_ITEM_R_COMPACT) {
- name = "";
- }
- else {
- if (use_prop_sep == false) {
- name = ui_item_name_add_colon(name, namestr);
- }
- }
- }
+ struct {
+ bool use_prop_decorate;
+ int len;
+ uiLayout *layout;
+ uiBut *but;
+ } ui_decorate = {
+ .use_prop_decorate = (((layout->item.flag & UI_ITEM_PROP_DECORATE) != 0) &&
+ (use_prop_sep && ptr->id.data && id_can_have_animdata(ptr->id.data))),
+ };
+#endif /* UI_PROP_DECORATE */
+
+ UI_block_layout_set_current(block, layout);
+
+ /* retrieve info */
+ type = RNA_property_type(prop);
+ is_array = RNA_property_array_check(prop);
+ len = (is_array) ? RNA_property_array_length(ptr, prop) : 0;
+
+ icon_only = (flag & UI_ITEM_R_ICON_ONLY) != 0;
+
+ /* set name and icon */
+ if (!name) {
+ if (!icon_only) {
+ name = RNA_property_ui_name(prop);
+ }
+ else {
+ name = "";
+ }
+ }
+
+ if (icon == ICON_NONE) {
+ icon = RNA_property_ui_icon(prop);
+ }
+
+ if (flag & UI_ITEM_R_ICON_ONLY) {
+ /* pass */
+ }
+ else if (ELEM(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER)) {
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
+ }
+ else if (type == PROP_BOOLEAN && is_array && index == RNA_NO_INDEX) {
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
+ }
+ else if (type == PROP_ENUM && index != RNA_ENUM_VALUE) {
+ if (flag & UI_ITEM_R_COMPACT) {
+ name = "";
+ }
+ else {
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
+ }
+ }
#ifdef UI_PROP_SEP_ICON_WIDTH_EXCEPTION
- if (use_prop_sep) {
- if (type == PROP_BOOLEAN && (icon == ICON_NONE) && !icon_only) {
- use_prop_sep_split_label = false;
- }
- }
+ if (use_prop_sep) {
+ if (type == PROP_BOOLEAN && (icon == ICON_NONE) && !icon_only) {
+ use_prop_sep_split_label = false;
+ }
+ }
#endif
- /* menus and pie-menus don't show checkbox without this */
- if ((layout->root->type == UI_LAYOUT_MENU) ||
- /* use checkboxes only as a fallback in pie-menu's, when no icon is defined */
- ((layout->root->type == UI_LAYOUT_PIEMENU) && (icon == ICON_NONE)))
- {
- int prop_flag = RNA_property_flag(prop);
- if (type == PROP_BOOLEAN && ((is_array == false) || (index != RNA_NO_INDEX))) {
- if (prop_flag & PROP_ICONS_CONSECUTIVE) {
- icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
- }
- else if (is_array) {
- icon = (RNA_property_boolean_get_index(ptr, prop, index)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
- }
- else {
- icon = (RNA_property_boolean_get(ptr, prop)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
- }
- }
- else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
- int enum_value = RNA_property_enum_get(ptr, prop);
- if (prop_flag & PROP_ICONS_CONSECUTIVE) {
- icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
- }
- else if (prop_flag & PROP_ENUM_FLAG) {
- icon = (enum_value & value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
- }
- else {
- icon = (enum_value == value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
- }
- }
- }
-
- if ((type == PROP_ENUM) && (RNA_property_flag(prop) & PROP_ENUM_FLAG)) {
- flag |= UI_ITEM_R_EXPAND;
- }
-
- slider = (flag & UI_ITEM_R_SLIDER) != 0;
- toggle = (flag & UI_ITEM_R_TOGGLE) != 0;
- expand = (flag & UI_ITEM_R_EXPAND) != 0;
- no_bg = (flag & UI_ITEM_R_NO_BG) != 0;
- compact = (flag & UI_ITEM_R_COMPACT) != 0;
-
- /* get size */
- ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h);
-
- int prev_emboss = layout->emboss;
- if (no_bg) {
- layout->emboss = UI_EMBOSS_NONE;
- }
-
- /* Split the label / property. */
- uiLayout *layout_parent = layout;
- if (use_prop_sep) {
- uiLayout *layout_row = NULL;
+ /* menus and pie-menus don't show checkbox without this */
+ if ((layout->root->type == UI_LAYOUT_MENU) ||
+ /* use checkboxes only as a fallback in pie-menu's, when no icon is defined */
+ ((layout->root->type == UI_LAYOUT_PIEMENU) && (icon == ICON_NONE))) {
+ int prop_flag = RNA_property_flag(prop);
+ if (type == PROP_BOOLEAN && ((is_array == false) || (index != RNA_NO_INDEX))) {
+ if (prop_flag & PROP_ICONS_CONSECUTIVE) {
+ icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
+ }
+ else if (is_array) {
+ icon = (RNA_property_boolean_get_index(ptr, prop, index)) ? ICON_CHECKBOX_HLT :
+ ICON_CHECKBOX_DEHLT;
+ }
+ else {
+ icon = (RNA_property_boolean_get(ptr, prop)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ }
+ }
+ else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
+ int enum_value = RNA_property_enum_get(ptr, prop);
+ if (prop_flag & PROP_ICONS_CONSECUTIVE) {
+ icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
+ }
+ else if (prop_flag & PROP_ENUM_FLAG) {
+ icon = (enum_value & value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ }
+ else {
+ icon = (enum_value == value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ }
+ }
+ }
+
+ if ((type == PROP_ENUM) && (RNA_property_flag(prop) & PROP_ENUM_FLAG)) {
+ flag |= UI_ITEM_R_EXPAND;
+ }
+
+ slider = (flag & UI_ITEM_R_SLIDER) != 0;
+ toggle = (flag & UI_ITEM_R_TOGGLE) != 0;
+ expand = (flag & UI_ITEM_R_EXPAND) != 0;
+ no_bg = (flag & UI_ITEM_R_NO_BG) != 0;
+ compact = (flag & UI_ITEM_R_COMPACT) != 0;
+
+ /* get size */
+ ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h);
+
+ int prev_emboss = layout->emboss;
+ if (no_bg) {
+ layout->emboss = UI_EMBOSS_NONE;
+ }
+
+ /* Split the label / property. */
+ uiLayout *layout_parent = layout;
+ if (use_prop_sep) {
+ uiLayout *layout_row = NULL;
#ifdef UI_PROP_DECORATE
- if (ui_decorate.use_prop_decorate) {
- layout_row = uiLayoutRow(layout, true);
- layout_row->space = 0;
- ui_decorate.len = max_ii(1, len);
- }
-#endif /* UI_PROP_DECORATE */
-
- if ((name[0] == '\0') || (use_prop_sep_split_label == false)) {
- /* Ensure we get a column when text is not set. */
- layout = uiLayoutColumn(layout_row ? layout_row : layout, true);
- layout->space = 0;
- }
- else {
- const PropertySubType subtype = RNA_property_subtype(prop);
- uiLayout *layout_split = uiLayoutSplit(
- layout_row ? layout_row : layout,
- UI_ITEM_PROP_SEP_DIVIDE, true);
- layout_split->space = 0;
- uiLayout *layout_sub = uiLayoutColumn(layout_split, true);
- layout_sub->space = 0;
-
- if ((index == RNA_NO_INDEX && is_array) &&
- ((!expand && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA, PROP_DIRECTION)) == 0))
- {
- char name_with_suffix[UI_MAX_DRAW_STR + 2];
- char str[2] = {'\0'};
- for (int a = 0; a < len; a++) {
- str[0] = RNA_property_array_item_char(prop, a);
- const bool use_prefix = (a == 0 && name && name[0]);
- if (use_prefix) {
- char *s = name_with_suffix;
- s += STRNCPY_RLEN(name_with_suffix, name);
- *s++ = ' ';
- *s++ = str[0];
- *s++ = '\0';
- }
- but = uiDefBut(
- block, UI_BTYPE_LABEL, 0, use_prefix ? name_with_suffix : str,
- 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- but->drawflag |= UI_BUT_TEXT_RIGHT;
- but->drawflag &= ~UI_BUT_TEXT_LEFT;
- }
- }
- else {
- if (name) {
- but = uiDefBut(
- block, UI_BTYPE_LABEL, 0, name,
- 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- but->drawflag |= UI_BUT_TEXT_RIGHT;
- but->drawflag &= ~UI_BUT_TEXT_LEFT;
- }
- }
-
- /* Hack to add further items in a row into the second part of
- * the split layout, so the label part keeps a fixed size. */
- if (layout_parent && layout_parent->item.type == ITEM_LAYOUT_ROW) {
- layout_split = uiLayoutRow(layout_split, true);
- layout_parent->child_items_layout = layout_split;
- }
-
- /* Watch out! We can only write into the new layout now. */
- if ((type == PROP_ENUM) && (flag & UI_ITEM_R_EXPAND)) {
- /* Expanded enums each have their own name. */
-
- /* Often expanded enum's are better arranged into a row,
- * so check the existing layout. */
- if (uiLayoutGetLocalDir(layout) == UI_LAYOUT_HORIZONTAL) {
- layout = uiLayoutRow(layout_split, true);
- }
- else {
- layout = uiLayoutColumn(layout_split, true);
- }
- }
- else {
- name = "";
- layout = uiLayoutColumn(layout_split, true);
- }
- layout->space = 0;
- }
+ if (ui_decorate.use_prop_decorate) {
+ layout_row = uiLayoutRow(layout, true);
+ layout_row->space = 0;
+ ui_decorate.len = max_ii(1, len);
+ }
+#endif /* UI_PROP_DECORATE */
+
+ if ((name[0] == '\0') || (use_prop_sep_split_label == false)) {
+ /* Ensure we get a column when text is not set. */
+ layout = uiLayoutColumn(layout_row ? layout_row : layout, true);
+ layout->space = 0;
+ }
+ else {
+ const PropertySubType subtype = RNA_property_subtype(prop);
+ uiLayout *layout_split = uiLayoutSplit(
+ layout_row ? layout_row : layout, UI_ITEM_PROP_SEP_DIVIDE, true);
+ layout_split->space = 0;
+ uiLayout *layout_sub = uiLayoutColumn(layout_split, true);
+ layout_sub->space = 0;
+
+ if ((index == RNA_NO_INDEX && is_array) &&
+ ((!expand && ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA, PROP_DIRECTION)) == 0)) {
+ char name_with_suffix[UI_MAX_DRAW_STR + 2];
+ char str[2] = {'\0'};
+ for (int a = 0; a < len; a++) {
+ str[0] = RNA_property_array_item_char(prop, a);
+ const bool use_prefix = (a == 0 && name && name[0]);
+ if (use_prefix) {
+ char *s = name_with_suffix;
+ s += STRNCPY_RLEN(name_with_suffix, name);
+ *s++ = ' ';
+ *s++ = str[0];
+ *s++ = '\0';
+ }
+ but = uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ use_prefix ? name_with_suffix : str,
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
+ }
+ }
+ else {
+ if (name) {
+ but = uiDefBut(
+ block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
+ }
+ }
+
+ /* Hack to add further items in a row into the second part of
+ * the split layout, so the label part keeps a fixed size. */
+ if (layout_parent && layout_parent->item.type == ITEM_LAYOUT_ROW) {
+ layout_split = uiLayoutRow(layout_split, true);
+ layout_parent->child_items_layout = layout_split;
+ }
+
+ /* Watch out! We can only write into the new layout now. */
+ if ((type == PROP_ENUM) && (flag & UI_ITEM_R_EXPAND)) {
+ /* Expanded enums each have their own name. */
+
+ /* Often expanded enum's are better arranged into a row,
+ * so check the existing layout. */
+ if (uiLayoutGetLocalDir(layout) == UI_LAYOUT_HORIZONTAL) {
+ layout = uiLayoutRow(layout_split, true);
+ }
+ else {
+ layout = uiLayoutColumn(layout_split, true);
+ }
+ }
+ else {
+ name = "";
+ layout = uiLayoutColumn(layout_split, true);
+ }
+ layout->space = 0;
+ }
#ifdef UI_PROP_DECORATE
- if (ui_decorate.use_prop_decorate) {
- ui_decorate.layout = uiLayoutColumn(layout_row, true);
- ui_decorate.layout->space = 0;
- UI_block_layout_set_current(block, layout);
- ui_decorate.but = block->buttons.last;
-
- /* Clear after. */
- layout->item.flag |= UI_ITEM_PROP_DECORATE_NO_PAD;
- }
-#endif /* UI_PROP_DECORATE */
- }
- /* End split. */
-
- /* array property */
- if (index == RNA_NO_INDEX && is_array) {
- ui_item_array(
- layout, block, name, icon, ptr, prop, len, 0, 0, w, h,
- expand, slider, toggle, icon_only, compact, !use_prop_sep_split_label);
- }
- /* enum item */
- else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
- if (icon && name[0] && !icon_only) {
- uiDefIconTextButR_prop(block, UI_BTYPE_ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
- }
- else if (icon) {
- uiDefIconButR_prop(block, UI_BTYPE_ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
- }
- else {
- uiDefButR_prop(block, UI_BTYPE_ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
- }
- }
- /* expanded enum */
- else if (type == PROP_ENUM && expand) {
- ui_item_enum_expand(layout, block, ptr, prop, name, h, icon_only);
- }
- /* property with separate label */
- else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
- but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag);
- ui_but_add_search(but, ptr, prop, NULL, NULL);
-
- if (layout->redalert) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
-
- if (layout->activate_init) {
- UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
- }
- }
- /* single button */
- else {
- but = uiDefAutoButR(block, ptr, prop, index, name, icon, 0, 0, w, h);
-
- if (slider && but->type == UI_BTYPE_NUM) {
- but->type = UI_BTYPE_NUM_SLIDER;
- }
-
- if (toggle && but->type == UI_BTYPE_CHECKBOX) {
- but->type = UI_BTYPE_TOGGLE;
- }
-
- if (layout->redalert) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
-
- if (layout->activate_init) {
- UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
- }
-
- if (use_prop_sep && (use_prop_sep_split_label == false)) {
- /* When the button uses it's own text right align it. */
- but->drawflag |= UI_BUT_TEXT_RIGHT;
- but->drawflag &= ~UI_BUT_TEXT_LEFT;
- }
-
- }
-
- /* Mark non-embossed textfields inside a listbox. */
- if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) && (but->dt & UI_EMBOSS_NONE)) {
- UI_but_flag_enable(but, UI_BUT_LIST_ITEM);
- }
+ if (ui_decorate.use_prop_decorate) {
+ ui_decorate.layout = uiLayoutColumn(layout_row, true);
+ ui_decorate.layout->space = 0;
+ UI_block_layout_set_current(block, layout);
+ ui_decorate.but = block->buttons.last;
+
+ /* Clear after. */
+ layout->item.flag |= UI_ITEM_PROP_DECORATE_NO_PAD;
+ }
+#endif /* UI_PROP_DECORATE */
+ }
+ /* End split. */
+
+ /* array property */
+ if (index == RNA_NO_INDEX && is_array) {
+ ui_item_array(layout,
+ block,
+ name,
+ icon,
+ ptr,
+ prop,
+ len,
+ 0,
+ 0,
+ w,
+ h,
+ expand,
+ slider,
+ toggle,
+ icon_only,
+ compact,
+ !use_prop_sep_split_label);
+ }
+ /* enum item */
+ else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
+ if (icon && name[0] && !icon_only) {
+ uiDefIconTextButR_prop(
+ block, UI_BTYPE_ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ }
+ else if (icon) {
+ uiDefIconButR_prop(
+ block, UI_BTYPE_ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ }
+ else {
+ uiDefButR_prop(
+ block, UI_BTYPE_ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
+ }
+ }
+ /* expanded enum */
+ else if (type == PROP_ENUM && expand) {
+ ui_item_enum_expand(layout, block, ptr, prop, name, h, icon_only);
+ }
+ /* property with separate label */
+ else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
+ but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag);
+ ui_but_add_search(but, ptr, prop, NULL, NULL);
+
+ if (layout->redalert) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+
+ if (layout->activate_init) {
+ UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
+ }
+ }
+ /* single button */
+ else {
+ but = uiDefAutoButR(block, ptr, prop, index, name, icon, 0, 0, w, h);
+
+ if (slider && but->type == UI_BTYPE_NUM) {
+ but->type = UI_BTYPE_NUM_SLIDER;
+ }
+
+ if (toggle && but->type == UI_BTYPE_CHECKBOX) {
+ but->type = UI_BTYPE_TOGGLE;
+ }
+
+ if (layout->redalert) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+
+ if (layout->activate_init) {
+ UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
+ }
+
+ if (use_prop_sep && (use_prop_sep_split_label == false)) {
+ /* When the button uses it's own text right align it. */
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
+ }
+ }
+
+ /* Mark non-embossed textfields inside a listbox. */
+ if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) &&
+ (but->dt & UI_EMBOSS_NONE)) {
+ UI_but_flag_enable(but, UI_BUT_LIST_ITEM);
+ }
#ifdef UI_PROP_DECORATE
- if (ui_decorate.use_prop_decorate) {
- const bool is_anim = RNA_property_animateable(ptr, prop);
- uiBut *but_decorate = ui_decorate.but ? ui_decorate.but->next : block->buttons.first;
- uiLayout *layout_col = uiLayoutColumn(ui_decorate.layout, false);
- layout_col->space = 0;
- layout_col->emboss = UI_EMBOSS_NONE;
- int i;
- for (i = 0; i < ui_decorate.len && but_decorate; i++) {
- /* The icons are set in 'ui_but_anim_flag' */
- if (is_anim) {
- but = uiDefIconBut(
- block, UI_BTYPE_BUT, 0, ICON_DOT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Animate property"));
- UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL);
- but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
- }
- else {
- /* We may show other information here in future, for now use empty space. */
- but = uiDefIconBut(
- block, UI_BTYPE_BUT, 0, ICON_BLANK1, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, "");
- but->flag |= UI_BUT_DISABLED;
- }
- /* Order the decorator after the button we decorate, this is used so we can always
- * do a quick lookup. */
- BLI_remlink(&block->buttons, but);
- BLI_insertlinkafter(&block->buttons, but_decorate, but);
- but_decorate = but->next;
- }
- BLI_assert(ELEM(i, 1, ui_decorate.len));
-
- layout->item.flag &= ~UI_ITEM_PROP_DECORATE_NO_PAD;
- }
-#endif /* UI_PROP_DECORATE */
-
- if (no_bg) {
- layout->emboss = prev_emboss;
- }
-
- /* ensure text isn't added to icon_only buttons */
- if (but && icon_only) {
- BLI_assert(but->str[0] == '\0');
- }
-
-}
-
-void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
-{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
-
- if (!prop) {
- ui_item_disabled(layout, propname);
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- uiItemFullR(layout, ptr, prop, RNA_NO_INDEX, 0, flag, name, icon);
+ if (ui_decorate.use_prop_decorate) {
+ const bool is_anim = RNA_property_animateable(ptr, prop);
+ uiBut *but_decorate = ui_decorate.but ? ui_decorate.but->next : block->buttons.first;
+ uiLayout *layout_col = uiLayoutColumn(ui_decorate.layout, false);
+ layout_col->space = 0;
+ layout_col->emboss = UI_EMBOSS_NONE;
+ int i;
+ for (i = 0; i < ui_decorate.len && but_decorate; i++) {
+ /* The icons are set in 'ui_but_anim_flag' */
+ if (is_anim) {
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_DOT,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Animate property"));
+ UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL);
+ but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
+ }
+ else {
+ /* We may show other information here in future, for now use empty space. */
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_BLANK1,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ "");
+ but->flag |= UI_BUT_DISABLED;
+ }
+ /* Order the decorator after the button we decorate, this is used so we can always
+ * do a quick lookup. */
+ BLI_remlink(&block->buttons, but);
+ BLI_insertlinkafter(&block->buttons, but_decorate, but);
+ but_decorate = but->next;
+ }
+ BLI_assert(ELEM(i, 1, ui_decorate.len));
+
+ layout->item.flag &= ~UI_ITEM_PROP_DECORATE_NO_PAD;
+ }
+#endif /* UI_PROP_DECORATE */
+
+ if (no_bg) {
+ layout->emboss = prev_emboss;
+ }
+
+ /* ensure text isn't added to icon_only buttons */
+ if (but && icon_only) {
+ BLI_assert(but->str[0] == '\0');
+ }
+}
+
+void uiItemR(
+ uiLayout *layout, PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop) {
+ ui_item_disabled(layout, propname);
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ uiItemFullR(layout, ptr, prop, RNA_NO_INDEX, 0, flag, name, icon);
}
/**
* Use a wrapper function since re-implementing all the logic in this function would be messy.
*/
-void uiItemFullR_with_popover(
- uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int flag, const char *name, int icon,
- const char *panel_type)
-{
- uiBlock *block = layout->root->block;
- uiBut *but = block->buttons.last;
- uiItemFullR(layout, ptr, prop, index, value, flag, name, icon);
- but = but->next;
- while (but) {
- if (but->rnaprop == prop && but->type == UI_BTYPE_MENU) {
- ui_but_rna_menu_convert_to_panel_type(but, panel_type);
- break;
- }
- but = but->next;
- }
- if (but == NULL) {
- const char *propname = RNA_property_identifier(prop);
- ui_item_disabled(layout, panel_type);
- RNA_warning(
- "property could not use a popover: %s.%s (%s)",
- RNA_struct_identifier(ptr->type), propname, panel_type);
- }
-}
-
-void uiItemFullR_with_menu(
- uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int flag, const char *name, int icon,
- const char *menu_type)
-{
- uiBlock *block = layout->root->block;
- uiBut *but = block->buttons.last;
- uiItemFullR(layout, ptr, prop, index, value, flag, name, icon);
- but = but->next;
- while (but) {
- if (but->rnaprop == prop && but->type == UI_BTYPE_MENU) {
- ui_but_rna_menu_convert_to_menu_type(but, menu_type);
- break;
- }
- but = but->next;
- }
- if (but == NULL) {
- const char *propname = RNA_property_identifier(prop);
- ui_item_disabled(layout, menu_type);
- RNA_warning(
- "property could not use a menu: %s.%s (%s)",
- RNA_struct_identifier(ptr->type), propname, menu_type);
- }
-}
-
-void uiItemEnumR_prop(uiLayout *layout, const char *name, int icon, struct PointerRNA *ptr, PropertyRNA *prop, int value)
-{
- if (RNA_property_type(prop) != PROP_ENUM) {
- const char *propname = RNA_property_identifier(prop);
- ui_item_disabled(layout, propname);
- RNA_warning("property not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, value, 0, name, icon);
-}
-
-void uiItemEnumR(uiLayout *layout, const char *name, int icon, struct PointerRNA *ptr, const char *propname, int value)
-{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
-
- if (prop == NULL) {
- ui_item_disabled(layout, propname);
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, value, 0, name, icon);
-}
-
-
-void uiItemEnumR_string_prop(
- uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop,
- const char *value, const char *name, int icon)
-{
- const EnumPropertyItem *item;
- int ivalue, a;
- bool free;
-
- if (UNLIKELY(RNA_property_type(prop) != PROP_ENUM)) {
- const char *propname = RNA_property_identifier(prop);
- ui_item_disabled(layout, propname);
- RNA_warning("not an enum property: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
-
- if (!RNA_enum_value_from_id(item, value, &ivalue)) {
- const char *propname = RNA_property_identifier(prop);
- if (free) {
- MEM_freeN((void *)item);
- }
- ui_item_disabled(layout, propname);
- RNA_warning("enum property value not found: %s", value);
- return;
- }
-
- for (a = 0; item[a].identifier; a++) {
- if (item[a].value == ivalue) {
- const char *item_name = name ? name : CTX_IFACE_(RNA_property_translation_context(prop), item[a].name);
- const int flag = item_name[0] ? 0 : UI_ITEM_R_ICON_ONLY;
-
- uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, ivalue, flag, item_name, icon ? icon : item[a].icon);
- break;
- }
- }
-
- if (free) {
- MEM_freeN((void *)item);
- }
-}
-
-void uiItemEnumR_string(
- uiLayout *layout, struct PointerRNA *ptr, const char *propname,
- const char *value, const char *name, int icon)
-{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- if (UNLIKELY(prop == NULL)) {
- ui_item_disabled(layout, propname);
- RNA_warning("enum property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
- uiItemEnumR_string_prop(layout, ptr, prop, value, name, icon);
+void uiItemFullR_with_popover(uiLayout *layout,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int index,
+ int value,
+ int flag,
+ const char *name,
+ int icon,
+ const char *panel_type)
+{
+ uiBlock *block = layout->root->block;
+ uiBut *but = block->buttons.last;
+ uiItemFullR(layout, ptr, prop, index, value, flag, name, icon);
+ but = but->next;
+ while (but) {
+ if (but->rnaprop == prop && but->type == UI_BTYPE_MENU) {
+ ui_but_rna_menu_convert_to_panel_type(but, panel_type);
+ break;
+ }
+ but = but->next;
+ }
+ if (but == NULL) {
+ const char *propname = RNA_property_identifier(prop);
+ ui_item_disabled(layout, panel_type);
+ RNA_warning("property could not use a popover: %s.%s (%s)",
+ RNA_struct_identifier(ptr->type),
+ propname,
+ panel_type);
+ }
+}
+
+void uiItemFullR_with_menu(uiLayout *layout,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int index,
+ int value,
+ int flag,
+ const char *name,
+ int icon,
+ const char *menu_type)
+{
+ uiBlock *block = layout->root->block;
+ uiBut *but = block->buttons.last;
+ uiItemFullR(layout, ptr, prop, index, value, flag, name, icon);
+ but = but->next;
+ while (but) {
+ if (but->rnaprop == prop && but->type == UI_BTYPE_MENU) {
+ ui_but_rna_menu_convert_to_menu_type(but, menu_type);
+ break;
+ }
+ but = but->next;
+ }
+ if (but == NULL) {
+ const char *propname = RNA_property_identifier(prop);
+ ui_item_disabled(layout, menu_type);
+ RNA_warning("property could not use a menu: %s.%s (%s)",
+ RNA_struct_identifier(ptr->type),
+ propname,
+ menu_type);
+ }
+}
+
+void uiItemEnumR_prop(uiLayout *layout,
+ const char *name,
+ int icon,
+ struct PointerRNA *ptr,
+ PropertyRNA *prop,
+ int value)
+{
+ if (RNA_property_type(prop) != PROP_ENUM) {
+ const char *propname = RNA_property_identifier(prop);
+ ui_item_disabled(layout, propname);
+ RNA_warning("property not an enum: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, value, 0, name, icon);
+}
+
+void uiItemEnumR(uiLayout *layout,
+ const char *name,
+ int icon,
+ struct PointerRNA *ptr,
+ const char *propname,
+ int value)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+
+ if (prop == NULL) {
+ ui_item_disabled(layout, propname);
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ uiItemFullR(layout, ptr, prop, RNA_ENUM_VALUE, value, 0, name, icon);
+}
+
+void uiItemEnumR_string_prop(uiLayout *layout,
+ struct PointerRNA *ptr,
+ PropertyRNA *prop,
+ const char *value,
+ const char *name,
+ int icon)
+{
+ const EnumPropertyItem *item;
+ int ivalue, a;
+ bool free;
+
+ if (UNLIKELY(RNA_property_type(prop) != PROP_ENUM)) {
+ const char *propname = RNA_property_identifier(prop);
+ ui_item_disabled(layout, propname);
+ RNA_warning("not an enum property: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ RNA_property_enum_items(layout->root->block->evil_C, ptr, prop, &item, NULL, &free);
+
+ if (!RNA_enum_value_from_id(item, value, &ivalue)) {
+ const char *propname = RNA_property_identifier(prop);
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+ ui_item_disabled(layout, propname);
+ RNA_warning("enum property value not found: %s", value);
+ return;
+ }
+
+ for (a = 0; item[a].identifier; a++) {
+ if (item[a].value == ivalue) {
+ const char *item_name = name ?
+ name :
+ CTX_IFACE_(RNA_property_translation_context(prop), item[a].name);
+ const int flag = item_name[0] ? 0 : UI_ITEM_R_ICON_ONLY;
+
+ uiItemFullR(
+ layout, ptr, prop, RNA_ENUM_VALUE, ivalue, flag, item_name, icon ? icon : item[a].icon);
+ break;
+ }
+ }
+
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+}
+
+void uiItemEnumR_string(uiLayout *layout,
+ struct PointerRNA *ptr,
+ const char *propname,
+ const char *value,
+ const char *name,
+ int icon)
+{
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ if (UNLIKELY(prop == NULL)) {
+ ui_item_disabled(layout, propname);
+ RNA_warning("enum property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+ uiItemEnumR_string_prop(layout, ptr, prop, value, name, icon);
}
void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname)
{
- PropertyRNA *prop;
- uiBlock *block = layout->root->block;
- uiBut *bt;
-
- prop = RNA_struct_find_property(ptr, propname);
-
- if (!prop) {
- ui_item_disabled(layout, propname);
- RNA_warning("enum property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- if (RNA_property_type(prop) != PROP_ENUM) {
- RNA_warning("not an enum property: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
- else {
- const EnumPropertyItem *item;
- int totitem, i;
- bool free;
- uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
- uiLayout *column = uiLayoutColumn(split, false);
-
- RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free);
-
- for (i = 0; i < totitem; i++) {
- if (item[i].identifier[0]) {
- uiItemEnumR_prop(column, item[i].name, item[i].icon, ptr, prop, item[i].value);
- ui_but_tip_from_enum_item(block->buttons.last, &item[i]);
- }
- else {
- if (item[i].name) {
- if (i != 0) {
- column = uiLayoutColumn(split, false);
- /* inconsistent, but menus with labels do not look good flipped */
- block->flag |= UI_BLOCK_NO_FLIP;
- }
-
- uiItemL(column, item[i].name, ICON_NONE);
- bt = block->buttons.last;
- bt->drawflag = UI_BUT_TEXT_LEFT;
-
- ui_but_tip_from_enum_item(bt, &item[i]);
- }
- else {
- uiItemS(column);
- }
- }
- }
-
- if (free) {
- MEM_freeN((void *)item);
- }
- }
-
- /* intentionally don't touch UI_BLOCK_IS_FLIP here,
- * we don't know the context this is called in */
+ PropertyRNA *prop;
+ uiBlock *block = layout->root->block;
+ uiBut *bt;
+
+ prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop) {
+ ui_item_disabled(layout, propname);
+ RNA_warning("enum property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ if (RNA_property_type(prop) != PROP_ENUM) {
+ RNA_warning("not an enum property: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+ else {
+ const EnumPropertyItem *item;
+ int totitem, i;
+ bool free;
+ uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
+ uiLayout *column = uiLayoutColumn(split, false);
+
+ RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item, &totitem, &free);
+
+ for (i = 0; i < totitem; i++) {
+ if (item[i].identifier[0]) {
+ uiItemEnumR_prop(column, item[i].name, item[i].icon, ptr, prop, item[i].value);
+ ui_but_tip_from_enum_item(block->buttons.last, &item[i]);
+ }
+ else {
+ if (item[i].name) {
+ if (i != 0) {
+ column = uiLayoutColumn(split, false);
+ /* inconsistent, but menus with labels do not look good flipped */
+ block->flag |= UI_BLOCK_NO_FLIP;
+ }
+
+ uiItemL(column, item[i].name, ICON_NONE);
+ bt = block->buttons.last;
+ bt->drawflag = UI_BUT_TEXT_LEFT;
+
+ ui_but_tip_from_enum_item(bt, &item[i]);
+ }
+ else {
+ uiItemS(column);
+ }
+ }
+ }
+
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+ }
+
+ /* intentionally don't touch UI_BLOCK_IS_FLIP here,
+ * we don't know the context this is called in */
}
/* Pointer RNA button with search */
-
static void search_id_collection(StructRNA *ptype, PointerRNA *r_ptr, PropertyRNA **r_prop)
{
- StructRNA *srna;
-
- /* look for collection property in Main */
- /* Note: using global Main is OK-ish here, UI shall not access other Mains anyay... */
- RNA_main_pointer_create(G_MAIN, r_ptr);
-
- *r_prop = NULL;
-
- RNA_STRUCT_BEGIN (r_ptr, iprop)
- {
- /* if it's a collection and has same pointer type, we've got it */
- if (RNA_property_type(iprop) == PROP_COLLECTION) {
- srna = RNA_property_pointer_type(r_ptr, iprop);
-
- if (ptype == srna) {
- *r_prop = iprop;
- break;
- }
- }
- }
- RNA_STRUCT_END;
-}
-
-void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
-{
- StructRNA *ptype;
- PointerRNA sptr;
-
- /* for ID's we do automatic lookup */
- if (!searchprop) {
- if (RNA_property_type(prop) == PROP_POINTER) {
- ptype = RNA_property_pointer_type(ptr, prop);
- search_id_collection(ptype, &sptr, &searchprop);
- searchptr = &sptr;
- }
- }
-
- /* turn button into search button */
- if (searchprop) {
- uiRNACollectionSearch *coll_search = MEM_mallocN(sizeof(*coll_search), __func__);
-
- but->type = UI_BTYPE_SEARCH_MENU;
- but->hardmax = MAX2(but->hardmax, 256.0f);
- but->rnasearchpoin = *searchptr;
- but->rnasearchprop = searchprop;
- but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
- if (RNA_property_is_unlink(prop)) {
- but->flag |= UI_BUT_VALUE_CLEAR;
- }
-
- coll_search->target_ptr = *ptr;
- coll_search->target_prop = prop;
- coll_search->search_ptr = *searchptr;
- coll_search->search_prop = searchprop;
- coll_search->but_changed = &but->changed;
-
- if (RNA_property_type(prop) == PROP_ENUM) {
- /* XXX, this will have a menu string,
- * but in this case we just want the text */
- but->str[0] = 0;
- }
-
- UI_but_func_search_set(
- but, ui_searchbox_create_generic, ui_rna_collection_search_cb,
- coll_search, true, NULL, NULL);
- }
- else if (but->type == UI_BTYPE_SEARCH_MENU) {
- /* In case we fail to find proper searchprop,
- * so other code might have already set but->type to search menu... */
- but->flag |= UI_BUT_DISABLED;
- }
-}
-
-void uiItemPointerR_prop(
- uiLayout *layout,
- PointerRNA *ptr, PropertyRNA *prop,
- PointerRNA *searchptr, PropertyRNA *searchprop,
- const char *name, int icon)
-{
- PropertyType type;
- uiBut *but;
- uiBlock *block;
- StructRNA *icontype;
- int w, h;
- char namestr[UI_MAX_NAME_STR];
- const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
-
- type = RNA_property_type(prop);
- if (!ELEM(type, PROP_POINTER, PROP_STRING, PROP_ENUM)) {
- RNA_warning("Property %s.%s must be a pointer, string or enum",
- RNA_struct_identifier(ptr->type), RNA_property_identifier(prop));
- return;
- }
- if (RNA_property_type(searchprop) != PROP_COLLECTION) {
- RNA_warning("search collection property is not a collection type: %s.%s",
- RNA_struct_identifier(searchptr->type), RNA_property_identifier(searchprop));
- return;
- }
-
- /* get icon & name */
- if (icon == ICON_NONE) {
- if (type == PROP_POINTER) {
- icontype = RNA_property_pointer_type(ptr, prop);
- }
- else {
- icontype = RNA_property_pointer_type(searchptr, searchprop);
- }
-
- icon = RNA_struct_ui_icon(icontype);
- }
- if (!name) {
- name = RNA_property_ui_name(prop);
- }
-
- if (use_prop_sep == false) {
- name = ui_item_name_add_colon(name, namestr);
- }
-
- /* create button */
- block = uiLayoutGetBlock(layout);
-
- ui_item_rna_size(layout, name, icon, ptr, prop, 0, 0, false, &w, &h);
- w += UI_UNIT_X; /* X icon needs more space */
- but = ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h, 0);
-
- ui_but_add_search(but, ptr, prop, searchptr, searchprop);
-}
-
-void uiItemPointerR(
- uiLayout *layout,
- PointerRNA *ptr, const char *propname,
- PointerRNA *searchptr, const char *searchpropname,
- const char *name, int icon)
-{
- PropertyRNA *prop, *searchprop;
-
- /* validate arguments */
- prop = RNA_struct_find_property(ptr, propname);
- if (!prop) {
- RNA_warning("property not found: %s.%s",
- RNA_struct_identifier(ptr->type), propname);
- return;
- }
- searchprop = RNA_struct_find_property(searchptr, searchpropname);
- if (!searchprop) {
- RNA_warning("search collection property not found: %s.%s",
- RNA_struct_identifier(searchptr->type), searchpropname);
- return;
- }
-
- uiItemPointerR_prop(layout, ptr, prop, searchptr, searchprop, name, icon);
+ StructRNA *srna;
+
+ /* look for collection property in Main */
+ /* Note: using global Main is OK-ish here, UI shall not access other Mains anyay... */
+ RNA_main_pointer_create(G_MAIN, r_ptr);
+
+ *r_prop = NULL;
+
+ RNA_STRUCT_BEGIN (r_ptr, iprop) {
+ /* if it's a collection and has same pointer type, we've got it */
+ if (RNA_property_type(iprop) == PROP_COLLECTION) {
+ srna = RNA_property_pointer_type(r_ptr, iprop);
+
+ if (ptype == srna) {
+ *r_prop = iprop;
+ break;
+ }
+ }
+ }
+ RNA_STRUCT_END;
+}
+
+void ui_but_add_search(
+ uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
+{
+ StructRNA *ptype;
+ PointerRNA sptr;
+
+ /* for ID's we do automatic lookup */
+ if (!searchprop) {
+ if (RNA_property_type(prop) == PROP_POINTER) {
+ ptype = RNA_property_pointer_type(ptr, prop);
+ search_id_collection(ptype, &sptr, &searchprop);
+ searchptr = &sptr;
+ }
+ }
+
+ /* turn button into search button */
+ if (searchprop) {
+ uiRNACollectionSearch *coll_search = MEM_mallocN(sizeof(*coll_search), __func__);
+
+ but->type = UI_BTYPE_SEARCH_MENU;
+ but->hardmax = MAX2(but->hardmax, 256.0f);
+ but->rnasearchpoin = *searchptr;
+ but->rnasearchprop = searchprop;
+ but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
+ if (RNA_property_is_unlink(prop)) {
+ but->flag |= UI_BUT_VALUE_CLEAR;
+ }
+
+ coll_search->target_ptr = *ptr;
+ coll_search->target_prop = prop;
+ coll_search->search_ptr = *searchptr;
+ coll_search->search_prop = searchprop;
+ coll_search->but_changed = &but->changed;
+
+ if (RNA_property_type(prop) == PROP_ENUM) {
+ /* XXX, this will have a menu string,
+ * but in this case we just want the text */
+ but->str[0] = 0;
+ }
+
+ UI_but_func_search_set(but,
+ ui_searchbox_create_generic,
+ ui_rna_collection_search_cb,
+ coll_search,
+ true,
+ NULL,
+ NULL);
+ }
+ else if (but->type == UI_BTYPE_SEARCH_MENU) {
+ /* In case we fail to find proper searchprop,
+ * so other code might have already set but->type to search menu... */
+ but->flag |= UI_BUT_DISABLED;
+ }
+}
+
+void uiItemPointerR_prop(uiLayout *layout,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ PointerRNA *searchptr,
+ PropertyRNA *searchprop,
+ const char *name,
+ int icon)
+{
+ PropertyType type;
+ uiBut *but;
+ uiBlock *block;
+ StructRNA *icontype;
+ int w, h;
+ char namestr[UI_MAX_NAME_STR];
+ const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
+
+ type = RNA_property_type(prop);
+ if (!ELEM(type, PROP_POINTER, PROP_STRING, PROP_ENUM)) {
+ RNA_warning("Property %s.%s must be a pointer, string or enum",
+ RNA_struct_identifier(ptr->type),
+ RNA_property_identifier(prop));
+ return;
+ }
+ if (RNA_property_type(searchprop) != PROP_COLLECTION) {
+ RNA_warning("search collection property is not a collection type: %s.%s",
+ RNA_struct_identifier(searchptr->type),
+ RNA_property_identifier(searchprop));
+ return;
+ }
+
+ /* get icon & name */
+ if (icon == ICON_NONE) {
+ if (type == PROP_POINTER) {
+ icontype = RNA_property_pointer_type(ptr, prop);
+ }
+ else {
+ icontype = RNA_property_pointer_type(searchptr, searchprop);
+ }
+
+ icon = RNA_struct_ui_icon(icontype);
+ }
+ if (!name) {
+ name = RNA_property_ui_name(prop);
+ }
+
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
+
+ /* create button */
+ block = uiLayoutGetBlock(layout);
+
+ ui_item_rna_size(layout, name, icon, ptr, prop, 0, 0, false, &w, &h);
+ w += UI_UNIT_X; /* X icon needs more space */
+ but = ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h, 0);
+
+ ui_but_add_search(but, ptr, prop, searchptr, searchprop);
+}
+
+void uiItemPointerR(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ PointerRNA *searchptr,
+ const char *searchpropname,
+ const char *name,
+ int icon)
+{
+ PropertyRNA *prop, *searchprop;
+
+ /* validate arguments */
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+ searchprop = RNA_struct_find_property(searchptr, searchpropname);
+ if (!searchprop) {
+ RNA_warning("search collection property not found: %s.%s",
+ RNA_struct_identifier(searchptr->type),
+ searchpropname);
+ return;
+ }
+
+ uiItemPointerR_prop(layout, ptr, prop, searchptr, searchprop, name, icon);
}
/* menu item */
void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
{
- MenuType *mt = (MenuType *)arg_mt;
+ MenuType *mt = (MenuType *)arg_mt;
- UI_menutype_draw(C, mt, layout);
+ UI_menutype_draw(C, mt, layout);
- /* menus are created flipped (from event handling pov) */
- layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
+ /* menus are created flipped (from event handling pov) */
+ layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt)
{
- PanelType *pt = (PanelType *)arg_pt;
- UI_paneltype_draw(C, pt, layout);
-
- /* panels are created flipped (from event handling pov) */
- layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
-}
-
-static uiBut *ui_item_menu(
- uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg, void *argN,
- const char *tip, bool force_menu)
-{
- uiBlock *block = layout->root->block;
- uiBut *but;
- int w, h;
-
- UI_block_layout_set_current(block, layout);
-
- if (!name) {
- name = "";
- }
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
-
- w = ui_text_icon_width(layout, name, icon, 1);
- h = UI_UNIT_Y;
-
- if (layout->root->type == UI_LAYOUT_HEADER) { /* ugly .. */
- if (icon == ICON_NONE && force_menu) {
- /* pass */
- }
- else if (force_menu) {
- w += 0.6f * UI_UNIT_X;
- }
- else {
- if (name[0]) {
- w -= UI_UNIT_X / 2;
- }
- }
- }
-
- if (name[0] && icon) {
- but = uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip);
- }
- else if (icon) {
- but = uiDefIconMenuBut(block, func, arg, icon, 0, 0, w, h, tip);
- if (force_menu) {
- UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
- }
- }
- else {
- but = uiDefMenuBut(block, func, arg, name, 0, 0, w, h, tip);
- }
-
- if (argN) {
- /* ugly .. */
- if (arg != argN) {
- but->poin = (char *)but;
- }
- but->func_argN = argN;
- }
-
- if (ELEM(layout->root->type, UI_LAYOUT_PANEL, UI_LAYOUT_TOOLBAR) ||
- /* We never want a dropdown in menu! */
- (force_menu && layout->root->type != UI_LAYOUT_MENU))
- {
- UI_but_type_set_menu_from_pulldown(but);
- }
-
- return but;
+ PanelType *pt = (PanelType *)arg_pt;
+ UI_paneltype_draw(C, pt, layout);
+
+ /* panels are created flipped (from event handling pov) */
+ layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
+}
+
+static uiBut *ui_item_menu(uiLayout *layout,
+ const char *name,
+ int icon,
+ uiMenuCreateFunc func,
+ void *arg,
+ void *argN,
+ const char *tip,
+ bool force_menu)
+{
+ uiBlock *block = layout->root->block;
+ uiBut *but;
+ int w, h;
+
+ UI_block_layout_set_current(block, layout);
+
+ if (!name) {
+ name = "";
+ }
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
+
+ w = ui_text_icon_width(layout, name, icon, 1);
+ h = UI_UNIT_Y;
+
+ if (layout->root->type == UI_LAYOUT_HEADER) { /* ugly .. */
+ if (icon == ICON_NONE && force_menu) {
+ /* pass */
+ }
+ else if (force_menu) {
+ w += 0.6f * UI_UNIT_X;
+ }
+ else {
+ if (name[0]) {
+ w -= UI_UNIT_X / 2;
+ }
+ }
+ }
+
+ if (name[0] && icon) {
+ but = uiDefIconTextMenuBut(block, func, arg, icon, name, 0, 0, w, h, tip);
+ }
+ else if (icon) {
+ but = uiDefIconMenuBut(block, func, arg, icon, 0, 0, w, h, tip);
+ if (force_menu) {
+ UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
+ }
+ }
+ else {
+ but = uiDefMenuBut(block, func, arg, name, 0, 0, w, h, tip);
+ }
+
+ if (argN) {
+ /* ugly .. */
+ if (arg != argN) {
+ but->poin = (char *)but;
+ }
+ but->func_argN = argN;
+ }
+
+ if (ELEM(layout->root->type, UI_LAYOUT_PANEL, UI_LAYOUT_TOOLBAR) ||
+ /* We never want a dropdown in menu! */
+ (force_menu && layout->root->type != UI_LAYOUT_MENU)) {
+ UI_but_type_set_menu_from_pulldown(but);
+ }
+
+ return but;
}
void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon)
{
- MenuType *mt = WM_menutype_find(menuname, false);
- if (mt == NULL) {
- RNA_warning("not found %s", menuname);
- return;
- }
+ MenuType *mt = WM_menutype_find(menuname, false);
+ if (mt == NULL) {
+ RNA_warning("not found %s", menuname);
+ return;
+ }
- if (!name) {
- name = CTX_IFACE_(mt->translation_context, mt->label);
- }
+ if (!name) {
+ name = CTX_IFACE_(mt->translation_context, mt->label);
+ }
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
- ui_item_menu(
- layout, name, icon, ui_item_menutype_func, mt, NULL,
- mt->description ? TIP_(mt->description) : "", false);
+ ui_item_menu(layout,
+ name,
+ icon,
+ ui_item_menutype_func,
+ mt,
+ NULL,
+ mt->description ? TIP_(mt->description) : "",
+ false);
}
void uiItemMContents(uiLayout *layout, const char *menuname)
{
- MenuType *mt = WM_menutype_find(menuname, false);
- if (mt == NULL) {
- RNA_warning("not found %s", menuname);
- return;
- }
+ MenuType *mt = WM_menutype_find(menuname, false);
+ if (mt == NULL) {
+ RNA_warning("not found %s", menuname);
+ return;
+ }
- uiBlock *block = layout->root->block;
- bContext *C = block->evil_C;
- UI_menutype_draw(C, mt, layout);
+ uiBlock *block = layout->root->block;
+ bContext *C = block->evil_C;
+ UI_menutype_draw(C, mt, layout);
}
/* popover */
-void uiItemPopoverPanel_ptr(uiLayout *layout, bContext *C, PanelType *pt, const char *name, int icon)
-{
- if (!name) {
- name = CTX_IFACE_(pt->translation_context, pt->label);
- }
-
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
-
- const bool ok = (pt->poll == NULL) || pt->poll(C, pt);
- if (ok && (pt->draw_header != NULL)) {
- layout = uiLayoutRow(layout, true);
- Panel panel = {
- .type = pt,
- .layout = layout,
- .flag = PNL_POPOVER,
- };
- pt->draw_header(C, &panel);
- }
- uiBut *but = ui_item_menu(layout, name, icon, ui_item_paneltype_func, pt, NULL, NULL, true);
- but->type = UI_BTYPE_POPOVER;
- if (!ok) {
- but->flag |= UI_BUT_DISABLED;
- }
+void uiItemPopoverPanel_ptr(
+ uiLayout *layout, bContext *C, PanelType *pt, const char *name, int icon)
+{
+ if (!name) {
+ name = CTX_IFACE_(pt->translation_context, pt->label);
+ }
+
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
+
+ const bool ok = (pt->poll == NULL) || pt->poll(C, pt);
+ if (ok && (pt->draw_header != NULL)) {
+ layout = uiLayoutRow(layout, true);
+ Panel panel = {
+ .type = pt,
+ .layout = layout,
+ .flag = PNL_POPOVER,
+ };
+ pt->draw_header(C, &panel);
+ }
+ uiBut *but = ui_item_menu(layout, name, icon, ui_item_paneltype_func, pt, NULL, NULL, true);
+ but->type = UI_BTYPE_POPOVER;
+ if (!ok) {
+ but->flag |= UI_BUT_DISABLED;
+ }
}
void uiItemPopoverPanel(
- uiLayout *layout, bContext *C,
- const char *panel_type, const char *name, int icon)
-{
- PanelType *pt = WM_paneltype_find(panel_type, true);
- if (pt == NULL) {
- RNA_warning("Panel type not found '%s'", panel_type);
- return;
- }
- uiItemPopoverPanel_ptr(layout, C, pt, name, icon);
-}
-
-void uiItemPopoverPanelFromGroup(
- uiLayout *layout, bContext *C,
- int space_id, int region_id, const char *context, const char *category)
-{
- SpaceType *st = BKE_spacetype_from_id(space_id);
- if (st == NULL) {
- RNA_warning("space type not found %d", space_id);
- return;
- }
- ARegionType *art = BKE_regiontype_from_id(st, region_id);
- if (art == NULL) {
- RNA_warning("region type not found %d", region_id);
- return;
- }
-
- for (PanelType *pt = art->paneltypes.first; pt; pt = pt->next) {
- /* Causes too many panels, check context. */
- if (pt->parent_id[0] == '\0') {
- if (/* (*context == '\0') || */ STREQ(pt->context, context)) {
- if ((*category == '\0') || STREQ(pt->category, category)) {
- if (pt->poll == NULL || pt->poll(C, pt)) {
- uiItemPopoverPanel_ptr(layout, C, pt, NULL, ICON_NONE);
- }
- }
- }
- }
- }
+ uiLayout *layout, bContext *C, const char *panel_type, const char *name, int icon)
+{
+ PanelType *pt = WM_paneltype_find(panel_type, true);
+ if (pt == NULL) {
+ RNA_warning("Panel type not found '%s'", panel_type);
+ return;
+ }
+ uiItemPopoverPanel_ptr(layout, C, pt, name, icon);
+}
+
+void uiItemPopoverPanelFromGroup(uiLayout *layout,
+ bContext *C,
+ int space_id,
+ int region_id,
+ const char *context,
+ const char *category)
+{
+ SpaceType *st = BKE_spacetype_from_id(space_id);
+ if (st == NULL) {
+ RNA_warning("space type not found %d", space_id);
+ return;
+ }
+ ARegionType *art = BKE_regiontype_from_id(st, region_id);
+ if (art == NULL) {
+ RNA_warning("region type not found %d", region_id);
+ return;
+ }
+
+ for (PanelType *pt = art->paneltypes.first; pt; pt = pt->next) {
+ /* Causes too many panels, check context. */
+ if (pt->parent_id[0] == '\0') {
+ if (/* (*context == '\0') || */ STREQ(pt->context, context)) {
+ if ((*category == '\0') || STREQ(pt->category, category)) {
+ if (pt->poll == NULL || pt->poll(C, pt)) {
+ uiItemPopoverPanel_ptr(layout, C, pt, NULL, ICON_NONE);
+ }
+ }
+ }
+ }
+ }
}
-
/* label item */
static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
{
- uiBlock *block = layout->root->block;
- uiBut *but;
- int w;
-
- UI_block_layout_set_current(block, layout);
-
- if (!name) {
- name = "";
- }
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
-
- w = ui_text_icon_width(layout, name, icon, 0);
-
- if (icon && name[0]) {
- but = uiDefIconTextBut(block, UI_BTYPE_LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, NULL);
- }
- else if (icon) {
- but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, NULL);
- }
- else {
- but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, NULL);
- }
-
- /* to compensate for string size padding in ui_text_icon_width,
- * make text aligned right if the layout is aligned right.
- */
- if (uiLayoutGetAlignment(layout) == UI_LAYOUT_ALIGN_RIGHT) {
- but->drawflag &= ~UI_BUT_TEXT_LEFT; /* default, needs to be unset */
- but->drawflag |= UI_BUT_TEXT_RIGHT;
- }
-
- /* Mark as a label inside a listbox. */
- if (block->flag & UI_BLOCK_LIST_ITEM) {
- but->flag |= UI_BUT_LIST_ITEM;
- }
-
- if (layout->redalert) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
-
- return but;
+ uiBlock *block = layout->root->block;
+ uiBut *but;
+ int w;
+
+ UI_block_layout_set_current(block, layout);
+
+ if (!name) {
+ name = "";
+ }
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
+
+ w = ui_text_icon_width(layout, name, icon, 0);
+
+ if (icon && name[0]) {
+ but = uiDefIconTextBut(
+ block, UI_BTYPE_LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, NULL);
+ }
+ else if (icon) {
+ but = uiDefIconBut(
+ block, UI_BTYPE_LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, NULL);
+ }
+ else {
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, NULL);
+ }
+
+ /* to compensate for string size padding in ui_text_icon_width,
+ * make text aligned right if the layout is aligned right.
+ */
+ if (uiLayoutGetAlignment(layout) == UI_LAYOUT_ALIGN_RIGHT) {
+ but->drawflag &= ~UI_BUT_TEXT_LEFT; /* default, needs to be unset */
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ }
+
+ /* Mark as a label inside a listbox. */
+ if (block->flag & UI_BLOCK_LIST_ITEM) {
+ but->flag |= UI_BUT_LIST_ITEM;
+ }
+
+ if (layout->redalert) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+
+ return but;
}
void uiItemL(uiLayout *layout, const char *name, int icon)
{
- uiItemL_(layout, name, icon);
+ uiItemL_(layout, name, icon);
}
void uiItemLDrag(uiLayout *layout, PointerRNA *ptr, const char *name, int icon)
{
- uiBut *but = uiItemL_(layout, name, icon);
+ uiBut *but = uiItemL_(layout, name, icon);
- if (ptr && ptr->type) {
- if (RNA_struct_is_ID(ptr->type)) {
- UI_but_drag_set_id(but, ptr->id.data);
- }
- }
+ if (ptr && ptr->type) {
+ if (RNA_struct_is_ID(ptr->type)) {
+ UI_but_drag_set_id(but, ptr->id.data);
+ }
+ }
}
-
/* value item */
void uiItemV(uiLayout *layout, const char *name, int icon, int argval)
{
- /* label */
- uiBlock *block = layout->root->block;
- int *retvalue = (block->handle) ? &block->handle->retvalue : NULL;
- int w;
-
- UI_block_layout_set_current(block, layout);
-
- if (!name) {
- name = "";
- }
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
-
- w = ui_text_icon_width(layout, name, icon, 0);
-
- if (icon && name[0]) {
- uiDefIconTextButI(block, UI_BTYPE_BUT, argval, icon, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
- }
- else if (icon) {
- uiDefIconButI(block, UI_BTYPE_BUT, argval, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
- }
- else {
- uiDefButI(block, UI_BTYPE_BUT, argval, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
- }
+ /* label */
+ uiBlock *block = layout->root->block;
+ int *retvalue = (block->handle) ? &block->handle->retvalue : NULL;
+ int w;
+
+ UI_block_layout_set_current(block, layout);
+
+ if (!name) {
+ name = "";
+ }
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
+
+ w = ui_text_icon_width(layout, name, icon, 0);
+
+ if (icon && name[0]) {
+ uiDefIconTextButI(block,
+ UI_BTYPE_BUT,
+ argval,
+ icon,
+ name,
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ retvalue,
+ 0.0,
+ 0.0,
+ 0,
+ -1,
+ "");
+ }
+ else if (icon) {
+ uiDefIconButI(
+ block, UI_BTYPE_BUT, argval, icon, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
+ }
+ else {
+ uiDefButI(
+ block, UI_BTYPE_BUT, argval, name, 0, 0, w, UI_UNIT_Y, retvalue, 0.0, 0.0, 0, -1, "");
+ }
}
/* separator item */
void uiItemS_ex(uiLayout *layout, float factor)
{
- uiBlock *block = layout->root->block;
- bool is_menu = ui_block_is_menu(block);
- int space = (is_menu) ? 0.45f * UI_UNIT_X : 0.3f * UI_UNIT_X;
- space *= factor;
-
- UI_block_layout_set_current(block, layout);
- uiDefBut(block, (is_menu) ? UI_BTYPE_SEPR_LINE : UI_BTYPE_SEPR, 0, "", 0, 0, space, space, NULL, 0.0, 0.0, 0, 0, "");
+ uiBlock *block = layout->root->block;
+ bool is_menu = ui_block_is_menu(block);
+ int space = (is_menu) ? 0.45f * UI_UNIT_X : 0.3f * UI_UNIT_X;
+ space *= factor;
+
+ UI_block_layout_set_current(block, layout);
+ uiDefBut(block,
+ (is_menu) ? UI_BTYPE_SEPR_LINE : UI_BTYPE_SEPR,
+ 0,
+ "",
+ 0,
+ 0,
+ space,
+ space,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
}
/* separator item */
void uiItemS(uiLayout *layout)
{
- uiItemS_ex(layout, 1.0f);
+ uiItemS_ex(layout, 1.0f);
}
/* Flexible spacing. */
void uiItemSpacer(uiLayout *layout)
{
- uiBlock *block = layout->root->block;
- const bool is_popup = ui_block_is_popup_any(block);
-
- if (is_popup) {
- printf("Error: separator_spacer() not supported in popups.\n");
- return;
- }
-
- if (block->direction & UI_DIR_RIGHT) {
- printf("Error: separator_spacer() only supported in horizontal blocks.\n");
- return;
- }
-
- UI_block_layout_set_current(block, layout);
- uiDefBut(block, UI_BTYPE_SEPR_SPACER, 0, "", 0, 0, 0.3f * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ uiBlock *block = layout->root->block;
+ const bool is_popup = ui_block_is_popup_any(block);
+
+ if (is_popup) {
+ printf("Error: separator_spacer() not supported in popups.\n");
+ return;
+ }
+
+ if (block->direction & UI_DIR_RIGHT) {
+ printf("Error: separator_spacer() only supported in horizontal blocks.\n");
+ return;
+ }
+
+ UI_block_layout_set_current(block, layout);
+ uiDefBut(block,
+ UI_BTYPE_SEPR_SPACER,
+ 0,
+ "",
+ 0,
+ 0,
+ 0.3f * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
}
/* level items */
void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg)
{
- if (!func) {
- return;
- }
+ if (!func) {
+ return;
+ }
- ui_item_menu(layout, name, icon, func, arg, NULL, "", false);
+ ui_item_menu(layout, name, icon, func, arg, NULL, "", false);
}
/**
@@ -2683,142 +3029,159 @@ void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc
*/
void uiItemMenuFN(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *argN)
{
- if (!func) {
- return;
- }
+ if (!func) {
+ return;
+ }
- /* Second 'argN' only ensures it gets freed. */
- ui_item_menu(layout, name, icon, func, argN, argN, "", false);
+ /* Second 'argN' only ensures it gets freed. */
+ ui_item_menu(layout, name, icon, func, argN, argN, "", false);
}
typedef struct MenuItemLevel {
- int opcontext;
- /* don't use pointers to the strings because python can dynamically
- * allocate strings and free before the menu draws, see [#27304] */
- char opname[OP_MAX_TYPENAME];
- char propname[MAX_IDPROP_NAME];
- PointerRNA rnapoin;
+ int opcontext;
+ /* don't use pointers to the strings because python can dynamically
+ * allocate strings and free before the menu draws, see [#27304] */
+ char opname[OP_MAX_TYPENAME];
+ char propname[MAX_IDPROP_NAME];
+ PointerRNA rnapoin;
} MenuItemLevel;
static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, void *arg)
{
- MenuItemLevel *lvl = (MenuItemLevel *)(((uiBut *)arg)->func_argN);
+ MenuItemLevel *lvl = (MenuItemLevel *)(((uiBut *)arg)->func_argN);
- uiLayoutSetOperatorContext(layout, lvl->opcontext);
- uiItemsEnumO(layout, lvl->opname, lvl->propname);
+ uiLayoutSetOperatorContext(layout, lvl->opcontext);
+ uiItemsEnumO(layout, lvl->opname, lvl->propname);
- layout->root->block->flag |= UI_BLOCK_IS_FLIP;
+ layout->root->block->flag |= UI_BLOCK_IS_FLIP;
- /* override default, needed since this was assumed pre 2.70 */
- UI_block_direction_set(layout->root->block, UI_DIR_DOWN);
+ /* override default, needed since this was assumed pre 2.70 */
+ UI_block_direction_set(layout->root->block, UI_DIR_DOWN);
}
-void uiItemMenuEnumO_ptr(
- uiLayout *layout, bContext *C, wmOperatorType *ot, const char *propname,
- const char *name, int icon)
+void uiItemMenuEnumO_ptr(uiLayout *layout,
+ bContext *C,
+ wmOperatorType *ot,
+ const char *propname,
+ const char *name,
+ int icon)
{
- MenuItemLevel *lvl;
- uiBut *but;
+ MenuItemLevel *lvl;
+ uiBut *but;
- /* Caller must check */
- BLI_assert(ot->srna != NULL);
+ /* Caller must check */
+ BLI_assert(ot->srna != NULL);
- if (name == NULL) {
- name = RNA_struct_ui_name(ot->srna);
- }
+ if (name == NULL) {
+ name = RNA_struct_ui_name(ot->srna);
+ }
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
- lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel");
- BLI_strncpy(lvl->opname, ot->idname, sizeof(lvl->opname));
- BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname));
- lvl->opcontext = layout->root->opcontext;
+ lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel");
+ BLI_strncpy(lvl->opname, ot->idname, sizeof(lvl->opname));
+ BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname));
+ lvl->opcontext = layout->root->opcontext;
- but = ui_item_menu(
- layout, name, icon, menu_item_enum_opname_menu, NULL, lvl,
- RNA_struct_ui_description(ot->srna), true);
+ but = ui_item_menu(layout,
+ name,
+ icon,
+ menu_item_enum_opname_menu,
+ NULL,
+ lvl,
+ RNA_struct_ui_description(ot->srna),
+ true);
- /* add hotkey here, lower UI code can't detect it */
- if ((layout->root->block->flag & UI_BLOCK_LOOP) &&
- (ot->prop && ot->invoke))
- {
- char keybuf[128];
- if (WM_key_event_operator_string(
- C, ot->idname, layout->root->opcontext, NULL, false,
- keybuf, sizeof(keybuf)))
- {
- ui_but_add_shortcut(but, keybuf, false);
- }
- }
+ /* add hotkey here, lower UI code can't detect it */
+ if ((layout->root->block->flag & UI_BLOCK_LOOP) && (ot->prop && ot->invoke)) {
+ char keybuf[128];
+ if (WM_key_event_operator_string(
+ C, ot->idname, layout->root->opcontext, NULL, false, keybuf, sizeof(keybuf))) {
+ ui_but_add_shortcut(but, keybuf, false);
+ }
+ }
}
-void uiItemMenuEnumO(
- uiLayout *layout, bContext *C, const char *opname, const char *propname,
- const char *name, int icon)
+void uiItemMenuEnumO(uiLayout *layout,
+ bContext *C,
+ const char *opname,
+ const char *propname,
+ const char *name,
+ int icon)
{
- wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
+ wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */
- UI_OPERATOR_ERROR_RET(ot, opname, return);
+ UI_OPERATOR_ERROR_RET(ot, opname, return );
- if (!ot->srna) {
- ui_item_disabled(layout, opname);
- RNA_warning("operator missing srna '%s'", opname);
- return;
- }
+ if (!ot->srna) {
+ ui_item_disabled(layout, opname);
+ RNA_warning("operator missing srna '%s'", opname);
+ return;
+ }
- uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon);
+ uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon);
}
static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void *arg)
{
- MenuItemLevel *lvl = (MenuItemLevel *)(((uiBut *)arg)->func_argN);
+ MenuItemLevel *lvl = (MenuItemLevel *)(((uiBut *)arg)->func_argN);
- uiLayoutSetOperatorContext(layout, lvl->opcontext);
- uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname);
- layout->root->block->flag |= UI_BLOCK_IS_FLIP;
+ uiLayoutSetOperatorContext(layout, lvl->opcontext);
+ uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname);
+ layout->root->block->flag |= UI_BLOCK_IS_FLIP;
}
-void uiItemMenuEnumR_prop(uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon)
+void uiItemMenuEnumR_prop(
+ uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon)
{
- MenuItemLevel *lvl;
+ MenuItemLevel *lvl;
- if (!name) {
- name = RNA_property_ui_name(prop);
- }
- if (layout->root->type == UI_LAYOUT_MENU && !icon) {
- icon = ICON_BLANK1;
- }
+ if (!name) {
+ name = RNA_property_ui_name(prop);
+ }
+ if (layout->root->type == UI_LAYOUT_MENU && !icon) {
+ icon = ICON_BLANK1;
+ }
- lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel");
- lvl->rnapoin = *ptr;
- BLI_strncpy(lvl->propname, RNA_property_identifier(prop), sizeof(lvl->propname));
- lvl->opcontext = layout->root->opcontext;
+ lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel");
+ lvl->rnapoin = *ptr;
+ BLI_strncpy(lvl->propname, RNA_property_identifier(prop), sizeof(lvl->propname));
+ lvl->opcontext = layout->root->opcontext;
- ui_item_menu(layout, name, icon, menu_item_enum_rna_menu, NULL, lvl, RNA_property_description(prop), false);
+ ui_item_menu(layout,
+ name,
+ icon,
+ menu_item_enum_rna_menu,
+ NULL,
+ lvl,
+ RNA_property_description(prop),
+ false);
}
-void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon)
+void uiItemMenuEnumR(
+ uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- prop = RNA_struct_find_property(ptr, propname);
- if (!prop) {
- ui_item_disabled(layout, propname);
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop) {
+ ui_item_disabled(layout, propname);
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
- uiItemMenuEnumR_prop(layout, ptr, prop, name, icon);
+ uiItemMenuEnumR_prop(layout, ptr, prop, name, icon);
}
-void uiItemTabsEnumR_prop(uiLayout *layout, bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool icon_only)
+void uiItemTabsEnumR_prop(
+ uiLayout *layout, bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool icon_only)
{
- uiBlock *block = layout->root->block;
+ uiBlock *block = layout->root->block;
- UI_block_layout_set_current(block, layout);
- ui_item_enum_expand_tabs(layout, C, block, ptr, prop, NULL, UI_UNIT_Y, icon_only);
+ UI_block_layout_set_current(block, layout);
+ ui_item_enum_expand_tabs(layout, C, block, ptr, prop, NULL, UI_UNIT_Y, icon_only);
}
/**************************** Layout Items ***************************/
@@ -2826,1235 +3189,1248 @@ void uiItemTabsEnumR_prop(uiLayout *layout, bContext *C, PointerRNA *ptr, Proper
/* single-row layout */
static void ui_litem_estimate_row(uiLayout *litem)
{
- uiItem *item;
- int itemw, itemh;
- bool min_size_flag = true;
+ uiItem *item;
+ int itemw, itemh;
+ bool min_size_flag = true;
- litem->w = 0;
- litem->h = 0;
+ litem->w = 0;
+ litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
- min_size_flag = min_size_flag && (item->flag & UI_ITEM_MIN);
+ min_size_flag = min_size_flag && (item->flag & UI_ITEM_MIN);
- litem->w += itemw;
- litem->h = MAX2(itemh, litem->h);
+ litem->w += itemw;
+ litem->h = MAX2(itemh, litem->h);
- if (item->next) {
- litem->w += litem->space;
- }
- }
+ if (item->next) {
+ litem->w += litem->space;
+ }
+ }
- if (min_size_flag) {
- litem->item.flag |= UI_ITEM_MIN;
- }
+ if (min_size_flag) {
+ litem->item.flag |= UI_ITEM_MIN;
+ }
}
static int ui_litem_min_width(int itemw)
{
- return MIN2(2 * UI_UNIT_X, itemw);
+ return MIN2(2 * UI_UNIT_X, itemw);
}
static void ui_litem_layout_row(uiLayout *litem)
{
- uiItem *item, *last_free_item = NULL;
- int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset;
- int fixedw, freew, fixedx, freex, flag = 0, lastw = 0;
- float extra_pixel;
-
- /* x = litem->x; */ /* UNUSED */
- y = litem->y;
- w = litem->w;
- totw = 0;
- tot = 0;
-
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
- totw += itemw;
- tot++;
- }
-
- if (totw == 0) {
- return;
- }
-
- if (w != 0) {
- w -= (tot - 1) * litem->space;
- }
- fixedw = 0;
-
- /* keep clamping items to fixed minimum size until all are done */
- do {
- freew = 0;
- x = 0;
- flag = 0;
- newtotw = totw;
- extra_pixel = 0.0f;
-
- for (item = litem->items.first; item; item = item->next) {
- if (item->flag & UI_ITEM_FIXED) {
- continue;
- }
-
- ui_item_size(item, &itemw, &itemh);
- minw = ui_litem_min_width(itemw);
-
- if (w - lastw > 0) {
- neww = ui_item_fit(itemw, x, totw, w - lastw, !item->next, litem->alignment, &extra_pixel);
- }
- else {
- neww = 0; /* no space left, all will need clamping to minimum size */
- }
-
- x += neww;
-
- bool min_flag = item->flag & UI_ITEM_MIN;
- /* ignore min flag for rows with right or center alignment */
- if (item->type != ITEM_BUTTON &&
- ELEM(((uiLayout *)item)->alignment, UI_LAYOUT_ALIGN_RIGHT, UI_LAYOUT_ALIGN_CENTER) &&
- litem->alignment == UI_LAYOUT_ALIGN_EXPAND &&
- ((uiItem *)litem)->flag & UI_ITEM_MIN)
- {
- min_flag = false;
- }
-
- if ((neww < minw || min_flag) && w != 0) {
- /* fixed size */
- item->flag |= UI_ITEM_FIXED;
- if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_MIN) {
- minw = itemw;
- }
- fixedw += minw;
- flag = 1;
- newtotw -= itemw;
- }
- else {
- /* keep free size */
- item->flag &= ~UI_ITEM_FIXED;
- freew += itemw;
- }
- }
-
- totw = newtotw;
- lastw = fixedw;
- } while (flag);
-
- freex = 0;
- fixedx = 0;
- extra_pixel = 0.0f;
- x = litem->x;
-
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
- minw = ui_litem_min_width(itemw);
-
- if (item->flag & UI_ITEM_FIXED) {
- /* fixed minimum size items */
- if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_MIN) {
- minw = itemw;
- }
- itemw = ui_item_fit(minw, fixedx, fixedw, min_ii(w, fixedw), !item->next, litem->alignment, &extra_pixel);
- fixedx += itemw;
- }
- else {
- /* free size item */
- itemw = ui_item_fit(itemw, freex, freew, w - fixedw, !item->next, litem->alignment, &extra_pixel);
- freex += itemw;
- last_free_item = item;
- }
-
- /* align right/center */
- offset = 0;
- if (litem->alignment == UI_LAYOUT_ALIGN_RIGHT) {
- if (freew + fixedw > 0 && freew + fixedw < w) {
- offset = w - (fixedw + freew);
- }
- }
- else if (litem->alignment == UI_LAYOUT_ALIGN_CENTER) {
- if (freew + fixedw > 0 && freew + fixedw < w) {
- offset = (w - (fixedw + freew)) / 2;
- }
- }
-
- /* position item */
- ui_item_position(item, x + offset, y - itemh, itemw, itemh);
-
- x += itemw;
- if (item->next) {
- x += litem->space;
- }
- }
-
- /* add extra pixel */
- uiItem *last_item = litem->items.last;
- extra_pixel = litem->w - (x - litem->x);
- if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND &&
- last_free_item && last_item && last_item->flag & UI_ITEM_FIXED)
- {
- ui_item_move(last_free_item, 0, extra_pixel);
- for (item = last_free_item->next; item; item = item->next) {
- ui_item_move(item, extra_pixel, extra_pixel);
- }
- }
-
- litem->w = x - litem->x;
- litem->h = litem->y - y;
- litem->x = x;
- litem->y = y;
+ uiItem *item, *last_free_item = NULL;
+ int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset;
+ int fixedw, freew, fixedx, freex, flag = 0, lastw = 0;
+ float extra_pixel;
+
+ /* x = litem->x; */ /* UNUSED */
+ y = litem->y;
+ w = litem->w;
+ totw = 0;
+ tot = 0;
+
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ totw += itemw;
+ tot++;
+ }
+
+ if (totw == 0) {
+ return;
+ }
+
+ if (w != 0) {
+ w -= (tot - 1) * litem->space;
+ }
+ fixedw = 0;
+
+ /* keep clamping items to fixed minimum size until all are done */
+ do {
+ freew = 0;
+ x = 0;
+ flag = 0;
+ newtotw = totw;
+ extra_pixel = 0.0f;
+
+ for (item = litem->items.first; item; item = item->next) {
+ if (item->flag & UI_ITEM_FIXED) {
+ continue;
+ }
+
+ ui_item_size(item, &itemw, &itemh);
+ minw = ui_litem_min_width(itemw);
+
+ if (w - lastw > 0) {
+ neww = ui_item_fit(itemw, x, totw, w - lastw, !item->next, litem->alignment, &extra_pixel);
+ }
+ else {
+ neww = 0; /* no space left, all will need clamping to minimum size */
+ }
+
+ x += neww;
+
+ bool min_flag = item->flag & UI_ITEM_MIN;
+ /* ignore min flag for rows with right or center alignment */
+ if (item->type != ITEM_BUTTON &&
+ ELEM(((uiLayout *)item)->alignment, UI_LAYOUT_ALIGN_RIGHT, UI_LAYOUT_ALIGN_CENTER) &&
+ litem->alignment == UI_LAYOUT_ALIGN_EXPAND && ((uiItem *)litem)->flag & UI_ITEM_MIN) {
+ min_flag = false;
+ }
+
+ if ((neww < minw || min_flag) && w != 0) {
+ /* fixed size */
+ item->flag |= UI_ITEM_FIXED;
+ if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_MIN) {
+ minw = itemw;
+ }
+ fixedw += minw;
+ flag = 1;
+ newtotw -= itemw;
+ }
+ else {
+ /* keep free size */
+ item->flag &= ~UI_ITEM_FIXED;
+ freew += itemw;
+ }
+ }
+
+ totw = newtotw;
+ lastw = fixedw;
+ } while (flag);
+
+ freex = 0;
+ fixedx = 0;
+ extra_pixel = 0.0f;
+ x = litem->x;
+
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ minw = ui_litem_min_width(itemw);
+
+ if (item->flag & UI_ITEM_FIXED) {
+ /* fixed minimum size items */
+ if (item->type != ITEM_BUTTON && item->flag & UI_ITEM_MIN) {
+ minw = itemw;
+ }
+ itemw = ui_item_fit(
+ minw, fixedx, fixedw, min_ii(w, fixedw), !item->next, litem->alignment, &extra_pixel);
+ fixedx += itemw;
+ }
+ else {
+ /* free size item */
+ itemw = ui_item_fit(
+ itemw, freex, freew, w - fixedw, !item->next, litem->alignment, &extra_pixel);
+ freex += itemw;
+ last_free_item = item;
+ }
+
+ /* align right/center */
+ offset = 0;
+ if (litem->alignment == UI_LAYOUT_ALIGN_RIGHT) {
+ if (freew + fixedw > 0 && freew + fixedw < w) {
+ offset = w - (fixedw + freew);
+ }
+ }
+ else if (litem->alignment == UI_LAYOUT_ALIGN_CENTER) {
+ if (freew + fixedw > 0 && freew + fixedw < w) {
+ offset = (w - (fixedw + freew)) / 2;
+ }
+ }
+
+ /* position item */
+ ui_item_position(item, x + offset, y - itemh, itemw, itemh);
+
+ x += itemw;
+ if (item->next) {
+ x += litem->space;
+ }
+ }
+
+ /* add extra pixel */
+ uiItem *last_item = litem->items.last;
+ extra_pixel = litem->w - (x - litem->x);
+ if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND && last_free_item &&
+ last_item && last_item->flag & UI_ITEM_FIXED) {
+ ui_item_move(last_free_item, 0, extra_pixel);
+ for (item = last_free_item->next; item; item = item->next) {
+ ui_item_move(item, extra_pixel, extra_pixel);
+ }
+ }
+
+ litem->w = x - litem->x;
+ litem->h = litem->y - y;
+ litem->x = x;
+ litem->y = y;
}
/* single-column layout */
static void ui_litem_estimate_column(uiLayout *litem, bool is_box)
{
- uiItem *item;
- int itemw, itemh;
- bool min_size_flag = true;
+ uiItem *item;
+ int itemw, itemh;
+ bool min_size_flag = true;
- litem->w = 0;
- litem->h = 0;
+ litem->w = 0;
+ litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
- min_size_flag = min_size_flag && (item->flag & UI_ITEM_MIN);
+ min_size_flag = min_size_flag && (item->flag & UI_ITEM_MIN);
- litem->w = MAX2(litem->w, itemw);
- litem->h += itemh;
+ litem->w = MAX2(litem->w, itemw);
+ litem->h += itemh;
- if (item->next && (!is_box || item != litem->items.first)) {
- litem->h += litem->space;
- }
- }
+ if (item->next && (!is_box || item != litem->items.first)) {
+ litem->h += litem->space;
+ }
+ }
- if (min_size_flag) {
- litem->item.flag |= UI_ITEM_MIN;
- }
+ if (min_size_flag) {
+ litem->item.flag |= UI_ITEM_MIN;
+ }
}
static void ui_litem_layout_column(uiLayout *litem, bool is_box)
{
- uiItem *item;
- int itemh, x, y;
+ uiItem *item;
+ int itemh, x, y;
- x = litem->x;
- y = litem->y;
+ x = litem->x;
+ y = litem->y;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, NULL, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, NULL, &itemh);
- y -= itemh;
- ui_item_position(item, x, y, litem->w, itemh);
+ y -= itemh;
+ ui_item_position(item, x, y, litem->w, itemh);
- if (item->next && (!is_box || item != litem->items.first)) {
- y -= litem->space;
- }
+ if (item->next && (!is_box || item != litem->items.first)) {
+ y -= litem->space;
+ }
- if (is_box) {
- item->flag |= UI_ITEM_BOX_ITEM;
- }
- }
+ if (is_box) {
+ item->flag |= UI_ITEM_BOX_ITEM;
+ }
+ }
- litem->h = litem->y - y;
- litem->x = x;
- litem->y = y;
+ litem->h = litem->y - y;
+ litem->x = x;
+ litem->y = y;
}
/* calculates the angle of a specified button in a radial menu,
* stores a float vector in unit circle */
static RadialDirection ui_get_radialbut_vec(float vec[2], short itemnum)
{
- RadialDirection dir;
+ RadialDirection dir;
- if (itemnum >= PIE_MAX_ITEMS) {
- itemnum %= PIE_MAX_ITEMS;
- printf("Warning: Pie menus with more than %i items are currently unsupported\n", PIE_MAX_ITEMS);
- }
+ if (itemnum >= PIE_MAX_ITEMS) {
+ itemnum %= PIE_MAX_ITEMS;
+ printf("Warning: Pie menus with more than %i items are currently unsupported\n",
+ PIE_MAX_ITEMS);
+ }
- dir = ui_radial_dir_order[itemnum];
- ui_but_pie_dir(dir, vec);
+ dir = ui_radial_dir_order[itemnum];
+ ui_but_pie_dir(dir, vec);
- return dir;
+ return dir;
}
static bool ui_item_is_radial_displayable(uiItem *item)
{
- if ((item->type == ITEM_BUTTON) && (((uiButtonItem *)item)->but->type == UI_BTYPE_LABEL)) {
- return false;
- }
+ if ((item->type == ITEM_BUTTON) && (((uiButtonItem *)item)->but->type == UI_BTYPE_LABEL)) {
+ return false;
+ }
- return true;
+ return true;
}
static bool ui_item_is_radial_drawable(uiButtonItem *bitem)
{
- if (ELEM(bitem->but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) {
- return false;
- }
+ if (ELEM(bitem->but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) {
+ return false;
+ }
- return true;
+ return true;
}
static void ui_litem_layout_radial(uiLayout *litem)
{
- uiItem *item;
- int itemh, itemw, x, y;
- int itemnum = 0;
- int totitems = 0;
-
- /* For the radial layout we will use Matt Ebb's design
- * for radiation, see http://mattebb.com/weblog/radiation/
- * also the old code at http://developer.blender.org/T5103
- */
-
- int pie_radius = U.pie_menu_radius * UI_DPI_FAC;
-
- x = litem->x;
- y = litem->y;
-
- int minx = x, miny = y, maxx = x, maxy = y;
-
- /* first count total items */
- for (item = litem->items.first; item; item = item->next) {
- totitems++;
- }
-
- if (totitems < 5) {
- litem->root->block->pie_data.flags |= UI_PIE_DEGREES_RANGE_LARGE;
- }
-
- for (item = litem->items.first; item; item = item->next) {
- /* not all button types are drawn in a radial menu, do filtering here */
- if (ui_item_is_radial_displayable(item)) {
- RadialDirection dir;
- float vec[2];
- float factor[2];
-
- dir = ui_get_radialbut_vec(vec, itemnum);
- factor[0] = (vec[0] > 0.01f) ? 0.0f : ((vec[0] < -0.01f) ? -1.0f : -0.5f);
- factor[1] = (vec[1] > 0.99f) ? 0.0f : ((vec[1] < -0.99f) ? -1.0f : -0.5f);
-
- itemnum++;
-
- if (item->type == ITEM_BUTTON) {
- uiButtonItem *bitem = (uiButtonItem *) item;
-
- bitem->but->pie_dir = dir;
- /* scale the buttons */
- bitem->but->rect.ymax *= 1.5f;
- /* add a little bit more here to include number */
- bitem->but->rect.xmax += 1.5f * UI_UNIT_X;
- /* enable drawing as pie item if supported by widget */
- if (ui_item_is_radial_drawable(bitem)) {
- bitem->but->dt = UI_EMBOSS_RADIAL;
- bitem->but->drawflag |= UI_BUT_ICON_LEFT;
- }
- }
-
- ui_item_size(item, &itemw, &itemh);
-
- ui_item_position(item, x + vec[0] * pie_radius + factor[0] * itemw, y + vec[1] * pie_radius + factor[1] * itemh, itemw, itemh);
-
- minx = min_ii(minx, x + vec[0] * pie_radius - itemw / 2);
- maxx = max_ii(maxx, x + vec[0] * pie_radius + itemw / 2);
- miny = min_ii(miny, y + vec[1] * pie_radius - itemh / 2);
- maxy = max_ii(maxy, y + vec[1] * pie_radius + itemh / 2);
- }
- }
-
- litem->x = minx;
- litem->y = miny;
- litem->w = maxx - minx;
- litem->h = maxy - miny;
+ uiItem *item;
+ int itemh, itemw, x, y;
+ int itemnum = 0;
+ int totitems = 0;
+
+ /* For the radial layout we will use Matt Ebb's design
+ * for radiation, see http://mattebb.com/weblog/radiation/
+ * also the old code at http://developer.blender.org/T5103
+ */
+
+ int pie_radius = U.pie_menu_radius * UI_DPI_FAC;
+
+ x = litem->x;
+ y = litem->y;
+
+ int minx = x, miny = y, maxx = x, maxy = y;
+
+ /* first count total items */
+ for (item = litem->items.first; item; item = item->next) {
+ totitems++;
+ }
+
+ if (totitems < 5) {
+ litem->root->block->pie_data.flags |= UI_PIE_DEGREES_RANGE_LARGE;
+ }
+
+ for (item = litem->items.first; item; item = item->next) {
+ /* not all button types are drawn in a radial menu, do filtering here */
+ if (ui_item_is_radial_displayable(item)) {
+ RadialDirection dir;
+ float vec[2];
+ float factor[2];
+
+ dir = ui_get_radialbut_vec(vec, itemnum);
+ factor[0] = (vec[0] > 0.01f) ? 0.0f : ((vec[0] < -0.01f) ? -1.0f : -0.5f);
+ factor[1] = (vec[1] > 0.99f) ? 0.0f : ((vec[1] < -0.99f) ? -1.0f : -0.5f);
+
+ itemnum++;
+
+ if (item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
+
+ bitem->but->pie_dir = dir;
+ /* scale the buttons */
+ bitem->but->rect.ymax *= 1.5f;
+ /* add a little bit more here to include number */
+ bitem->but->rect.xmax += 1.5f * UI_UNIT_X;
+ /* enable drawing as pie item if supported by widget */
+ if (ui_item_is_radial_drawable(bitem)) {
+ bitem->but->dt = UI_EMBOSS_RADIAL;
+ bitem->but->drawflag |= UI_BUT_ICON_LEFT;
+ }
+ }
+
+ ui_item_size(item, &itemw, &itemh);
+
+ ui_item_position(item,
+ x + vec[0] * pie_radius + factor[0] * itemw,
+ y + vec[1] * pie_radius + factor[1] * itemh,
+ itemw,
+ itemh);
+
+ minx = min_ii(minx, x + vec[0] * pie_radius - itemw / 2);
+ maxx = max_ii(maxx, x + vec[0] * pie_radius + itemw / 2);
+ miny = min_ii(miny, y + vec[1] * pie_radius - itemh / 2);
+ maxy = max_ii(maxy, y + vec[1] * pie_radius + itemh / 2);
+ }
+ }
+
+ litem->x = minx;
+ litem->y = miny;
+ litem->w = maxx - minx;
+ litem->h = maxy - miny;
}
/* root layout */
static void ui_litem_estimate_root(uiLayout *UNUSED(litem))
{
- /* nothing to do */
+ /* nothing to do */
}
static void ui_litem_layout_root_radial(uiLayout *litem)
{
- /* first item is pie menu title, align on center of menu */
- uiItem *item = litem->items.first;
+ /* first item is pie menu title, align on center of menu */
+ uiItem *item = litem->items.first;
- if (item->type == ITEM_BUTTON) {
- int itemh, itemw, x, y;
- x = litem->x;
- y = litem->y;
+ if (item->type == ITEM_BUTTON) {
+ int itemh, itemw, x, y;
+ x = litem->x;
+ y = litem->y;
- ui_item_size(item, &itemw, &itemh);
+ ui_item_size(item, &itemw, &itemh);
- ui_item_position(item, x - itemw / 2, y + U.dpi_fac * (U.pie_menu_threshold + 9.0f), itemw, itemh);
- }
+ ui_item_position(
+ item, x - itemw / 2, y + U.dpi_fac * (U.pie_menu_threshold + 9.0f), itemw, itemh);
+ }
}
static void ui_litem_layout_root(uiLayout *litem)
{
- if (litem->root->type == UI_LAYOUT_HEADER) {
- ui_litem_layout_row(litem);
- }
- else if (litem->root->type == UI_LAYOUT_PIEMENU) {
- ui_litem_layout_root_radial(litem);
- }
- else {
- ui_litem_layout_column(litem, false);
- }
+ if (litem->root->type == UI_LAYOUT_HEADER) {
+ ui_litem_layout_row(litem);
+ }
+ else if (litem->root->type == UI_LAYOUT_PIEMENU) {
+ ui_litem_layout_root_radial(litem);
+ }
+ else {
+ ui_litem_layout_column(litem, false);
+ }
}
/* box layout */
static void ui_litem_estimate_box(uiLayout *litem)
{
- uiStyle *style = litem->root->style;
+ uiStyle *style = litem->root->style;
- ui_litem_estimate_column(litem, true);
- litem->w += 2 * style->boxspace;
- litem->h += 2 * style->boxspace;
+ ui_litem_estimate_column(litem, true);
+ litem->w += 2 * style->boxspace;
+ litem->h += 2 * style->boxspace;
}
static void ui_litem_layout_box(uiLayout *litem)
{
- uiLayoutItemBx *box = (uiLayoutItemBx *)litem;
- uiStyle *style = litem->root->style;
- uiBut *but;
- int w, h;
+ uiLayoutItemBx *box = (uiLayoutItemBx *)litem;
+ uiStyle *style = litem->root->style;
+ uiBut *but;
+ int w, h;
- w = litem->w;
- h = litem->h;
+ w = litem->w;
+ h = litem->h;
- litem->x += style->boxspace;
- litem->y -= style->boxspace;
+ litem->x += style->boxspace;
+ litem->y -= style->boxspace;
- if (w != 0) {
- litem->w -= 2 * style->boxspace;
- }
- if (h != 0) {
- litem->h -= 2 * style->boxspace;
- }
+ if (w != 0) {
+ litem->w -= 2 * style->boxspace;
+ }
+ if (h != 0) {
+ litem->h -= 2 * style->boxspace;
+ }
- ui_litem_layout_column(litem, true);
+ ui_litem_layout_column(litem, true);
- litem->x -= style->boxspace;
- litem->y -= style->boxspace;
+ litem->x -= style->boxspace;
+ litem->y -= style->boxspace;
- if (w != 0) {
- litem->w += 2 * style->boxspace;
- }
- if (h != 0) {
- litem->h += 2 * style->boxspace;
- }
+ if (w != 0) {
+ litem->w += 2 * style->boxspace;
+ }
+ if (h != 0) {
+ litem->h += 2 * style->boxspace;
+ }
- /* roundbox around the sublayout */
- but = box->roundbox;
- but->rect.xmin = litem->x;
- but->rect.ymin = litem->y;
- but->rect.xmax = litem->x + litem->w;
- but->rect.ymax = litem->y + litem->h;
+ /* roundbox around the sublayout */
+ but = box->roundbox;
+ but->rect.xmin = litem->x;
+ but->rect.ymin = litem->y;
+ but->rect.xmax = litem->x + litem->w;
+ but->rect.ymax = litem->y + litem->h;
}
/* multi-column layout, automatically flowing to the next */
static void ui_litem_estimate_column_flow(uiLayout *litem)
{
- uiStyle *style = litem->root->style;
- uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem;
- uiItem *item;
- int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0;
- int toth, totitem;
-
- /* compute max needed width and total height */
- toth = 0;
- totitem = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
- maxw = MAX2(maxw, itemw);
- toth += itemh;
- totitem++;
- }
-
- if (flow->number <= 0) {
- /* auto compute number of columns, not very good */
- if (maxw == 0) {
- flow->totcol = 1;
- return;
- }
-
- flow->totcol = max_ii(litem->root->emw / maxw, 1);
- flow->totcol = min_ii(flow->totcol, totitem);
- }
- else {
- flow->totcol = flow->number;
- }
-
- /* compute sizes */
- x = 0;
- y = 0;
- emy = 0;
- miny = 0;
-
- maxw = 0;
- emh = toth / flow->totcol;
-
- /* create column per column */
- col = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
-
- y -= itemh + style->buttonspacey;
- miny = min_ii(miny, y);
- emy -= itemh;
- maxw = max_ii(itemw, maxw);
-
- /* decide to go to next one */
- if (col < flow->totcol - 1 && emy <= -emh) {
- x += maxw + litem->space;
- maxw = 0;
- y = 0;
- emy = 0; /* need to reset height again for next column */
- col++;
- }
- }
-
- litem->w = x;
- litem->h = litem->y - miny;
+ uiStyle *style = litem->root->style;
+ uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem;
+ uiItem *item;
+ int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0;
+ int toth, totitem;
+
+ /* compute max needed width and total height */
+ toth = 0;
+ totitem = 0;
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ maxw = MAX2(maxw, itemw);
+ toth += itemh;
+ totitem++;
+ }
+
+ if (flow->number <= 0) {
+ /* auto compute number of columns, not very good */
+ if (maxw == 0) {
+ flow->totcol = 1;
+ return;
+ }
+
+ flow->totcol = max_ii(litem->root->emw / maxw, 1);
+ flow->totcol = min_ii(flow->totcol, totitem);
+ }
+ else {
+ flow->totcol = flow->number;
+ }
+
+ /* compute sizes */
+ x = 0;
+ y = 0;
+ emy = 0;
+ miny = 0;
+
+ maxw = 0;
+ emh = toth / flow->totcol;
+
+ /* create column per column */
+ col = 0;
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
+
+ y -= itemh + style->buttonspacey;
+ miny = min_ii(miny, y);
+ emy -= itemh;
+ maxw = max_ii(itemw, maxw);
+
+ /* decide to go to next one */
+ if (col < flow->totcol - 1 && emy <= -emh) {
+ x += maxw + litem->space;
+ maxw = 0;
+ y = 0;
+ emy = 0; /* need to reset height again for next column */
+ col++;
+ }
+ }
+
+ litem->w = x;
+ litem->h = litem->y - miny;
}
static void ui_litem_layout_column_flow(uiLayout *litem)
{
- uiStyle *style = litem->root->style;
- uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem;
- uiItem *item;
- int col, x, y, w, emh, emy, miny, itemw, itemh;
- int toth, totitem;
-
- /* compute max needed width and total height */
- toth = 0;
- totitem = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
- toth += itemh;
- totitem++;
- }
-
- /* compute sizes */
- x = litem->x;
- y = litem->y;
- emy = 0;
- miny = 0;
-
- w = litem->w - (flow->totcol - 1) * style->columnspace;
- emh = toth / flow->totcol;
-
- /* create column per column */
- col = 0;
- w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
-
- itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw);
-
- y -= itemh;
- emy -= itemh;
- ui_item_position(item, x, y, itemw, itemh);
- y -= style->buttonspacey;
- miny = min_ii(miny, y);
-
- /* decide to go to next one */
- if (col < flow->totcol - 1 && emy <= -emh) {
- x += w + style->columnspace;
- y = litem->y;
- emy = 0; /* need to reset height again for next column */
- col++;
-
- /* (< remaining width > - < space between remaining columns >) / <remamining columns > */
- w = ((litem->w - (x - litem->x)) - (flow->totcol - col - 1) * style->columnspace) / (flow->totcol - col);
- }
- }
-
- litem->h = litem->y - miny;
- litem->x = x;
- litem->y = miny;
+ uiStyle *style = litem->root->style;
+ uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem;
+ uiItem *item;
+ int col, x, y, w, emh, emy, miny, itemw, itemh;
+ int toth, totitem;
+
+ /* compute max needed width and total height */
+ toth = 0;
+ totitem = 0;
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ toth += itemh;
+ totitem++;
+ }
+
+ /* compute sizes */
+ x = litem->x;
+ y = litem->y;
+ emy = 0;
+ miny = 0;
+
+ w = litem->w - (flow->totcol - 1) * style->columnspace;
+ emh = toth / flow->totcol;
+
+ /* create column per column */
+ col = 0;
+ w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol;
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
+
+ itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw);
+
+ y -= itemh;
+ emy -= itemh;
+ ui_item_position(item, x, y, itemw, itemh);
+ y -= style->buttonspacey;
+ miny = min_ii(miny, y);
+
+ /* decide to go to next one */
+ if (col < flow->totcol - 1 && emy <= -emh) {
+ x += w + style->columnspace;
+ y = litem->y;
+ emy = 0; /* need to reset height again for next column */
+ col++;
+
+ /* (< remaining width > - < space between remaining columns >) / <remamining columns > */
+ w = ((litem->w - (x - litem->x)) - (flow->totcol - col - 1) * style->columnspace) /
+ (flow->totcol - col);
+ }
+ }
+
+ litem->h = litem->y - miny;
+ litem->x = x;
+ litem->y = miny;
}
/* multi-column and multi-row layout. */
typedef struct UILayoutGridFlowInput {
- /* General layout control settings. */
- const bool row_major : 1; /* Fill rows before columns */
- const bool even_columns : 1; /* All columns will have same width. */
- const bool even_rows : 1; /* All rows will have same height. */
- const int space_x; /* Space between columns. */
- const int space_y; /* Space between rows. */
- /* Real data about current position and size of this layout item
- * (either estimated, or final values). */
- const int litem_w; /* Layout item width. */
- const int litem_x; /* Layout item X position. */
- const int litem_y; /* Layout item Y position. */
- /* Actual number of columns and rows to generate (computed from first pass usually). */
- const int tot_columns; /* Number of columns. */
- const int tot_rows; /* Number of rows. */
+ /* General layout control settings. */
+ const bool row_major : 1; /* Fill rows before columns */
+ const bool even_columns : 1; /* All columns will have same width. */
+ const bool even_rows : 1; /* All rows will have same height. */
+ const int space_x; /* Space between columns. */
+ const int space_y; /* Space between rows. */
+ /* Real data about current position and size of this layout item
+ * (either estimated, or final values). */
+ const int litem_w; /* Layout item width. */
+ const int litem_x; /* Layout item X position. */
+ const int litem_y; /* Layout item Y position. */
+ /* Actual number of columns and rows to generate (computed from first pass usually). */
+ const int tot_columns; /* Number of columns. */
+ const int tot_rows; /* Number of rows. */
} UILayoutGridFlowInput;
typedef struct UILayoutGridFlowOutput {
- int *tot_items; /* Total number of items in this grid layout. */
- /* Width / X pos data. */
- float *global_avg_w; /* Computed average width of the columns. */
- int *cos_x_array; /* Computed X coordinate of each column. */
- int *widths_array; /* Computed width of each column. */
- int *tot_w; /* Computed total width. */
- /* Height / Y pos data. */
- int *global_max_h; /* Computed height of the tallest item in the grid. */
- int *cos_y_array; /* Computed Y coordinate of each column. */
- int *heights_array; /* Computed height of each column. */
- int *tot_h; /* Computed total height. */
+ int *tot_items; /* Total number of items in this grid layout. */
+ /* Width / X pos data. */
+ float *global_avg_w; /* Computed average width of the columns. */
+ int *cos_x_array; /* Computed X coordinate of each column. */
+ int *widths_array; /* Computed width of each column. */
+ int *tot_w; /* Computed total width. */
+ /* Height / Y pos data. */
+ int *global_max_h; /* Computed height of the tallest item in the grid. */
+ int *cos_y_array; /* Computed Y coordinate of each column. */
+ int *heights_array; /* Computed height of each column. */
+ int *tot_h; /* Computed total height. */
} UILayoutGridFlowOutput;
-static void ui_litem_grid_flow_compute(
- ListBase *items, UILayoutGridFlowInput *parameters, UILayoutGridFlowOutput *results)
-{
- uiItem *item;
- int i;
-
- float tot_w = 0.0f, tot_h = 0.0f;
- float global_avg_w = 0.0f, global_totweight_w = 0.0f;
- int global_max_h = 0;
-
- float *avg_w = NULL, *totweight_w = NULL;
- int *max_h = NULL;
-
- BLI_assert(parameters->tot_columns != 0 || (results->cos_x_array == NULL && results->widths_array == NULL && results->tot_w == NULL));
- BLI_assert(parameters->tot_rows != 0 || (results->cos_y_array == NULL && results->heights_array == NULL && results->tot_h == NULL));
-
- if (results->tot_items) {
- *results->tot_items = 0;
- }
-
- if (items->first == NULL) {
- if (results->global_avg_w) {
- *results->global_avg_w = 0.0f;
- }
- if (results->global_max_h) {
- *results->global_max_h = 0;
- }
- return;
- }
-
- if (parameters->tot_columns != 0) {
- avg_w = BLI_array_alloca(avg_w, parameters->tot_columns);
- totweight_w = BLI_array_alloca(totweight_w, parameters->tot_columns);
- memset(avg_w, 0, sizeof(*avg_w) * parameters->tot_columns);
- memset(totweight_w, 0, sizeof(*totweight_w) * parameters->tot_columns);
- }
- if (parameters->tot_rows != 0) {
- max_h = BLI_array_alloca(max_h, parameters->tot_rows);
- memset(max_h, 0, sizeof(*max_h) * parameters->tot_rows);
- }
-
- for (i = 0, item = items->first; item; item = item->next, i++) {
- int item_w, item_h;
- ui_item_size(item, &item_w, &item_h);
-
- global_avg_w += (float)(item_w * item_w);
- global_totweight_w += (float)item_w;
- global_max_h = max_ii(global_max_h, item_h);
-
- if (parameters->tot_rows != 0 && parameters->tot_columns != 0) {
- const int index_col = parameters->row_major ? i % parameters->tot_columns : i / parameters->tot_rows;
- const int index_row = parameters->row_major ? i / parameters->tot_columns : i % parameters->tot_rows;
-
- avg_w[index_col] += (float)(item_w * item_w);
- totweight_w[index_col] += (float)item_w;
-
- max_h[index_row] = max_ii(max_h[index_row], item_h);
- }
-
- if (results->tot_items) {
- (*results->tot_items)++;
- }
- }
-
- /* Finalize computing of column average sizes */
- global_avg_w /= global_totweight_w;
- if (parameters->tot_columns != 0) {
- for (i = 0; i < parameters->tot_columns; i++) {
- avg_w[i] /= totweight_w[i];
- tot_w += avg_w[i];
- }
- if (parameters->even_columns) {
- tot_w = ceilf(global_avg_w) * parameters->tot_columns;
- }
- }
- /* Finalize computing of rows max sizes */
- if (parameters->tot_rows != 0) {
- for (i = 0; i < parameters->tot_rows; i++) {
- tot_h += max_h[i];
- }
- if (parameters->even_rows) {
- tot_h = global_max_h * parameters->tot_columns;
- }
- }
-
- /* Compute positions and sizes of all cells. */
- if (results->cos_x_array != NULL && results->widths_array != NULL) {
- /* We enlarge/narrow columns evenly to match available width. */
- const float wfac = (float)(parameters->litem_w - (parameters->tot_columns - 1) * parameters->space_x) / tot_w;
-
- for (int col = 0; col < parameters->tot_columns; col++) {
- results->cos_x_array[col] = (
- col ?
- results->cos_x_array[col - 1] + results->widths_array[col - 1] + parameters->space_x :
- parameters->litem_x
- );
- if (parameters->even_columns) {
- /* (< remaining width > - < space between remaining columns >) / < remaining columns > */
- results->widths_array[col] = (
- ((parameters->litem_w - (results->cos_x_array[col] - parameters->litem_x)) -
- (parameters->tot_columns - col - 1) * parameters->space_x) / (parameters->tot_columns - col));
- }
- else if (col == parameters->tot_columns - 1) {
- /* Last column copes width rounding errors... */
- results->widths_array[col] = parameters->litem_w - (results->cos_x_array[col] - parameters->litem_x);
- }
- else {
- results->widths_array[col] = (int)(avg_w[col] * wfac);
- }
- }
- }
- if (results->cos_y_array != NULL && results->heights_array != NULL) {
- for (int row = 0; row < parameters->tot_rows; row++) {
- if (parameters->even_rows) {
- results->heights_array[row] = global_max_h;
- }
- else {
- results->heights_array[row] = max_h[row];
- }
- results->cos_y_array[row] = (
- row ?
- results->cos_y_array[row - 1] - parameters->space_y - results->heights_array[row] :
- parameters->litem_y - results->heights_array[row]);
- }
- }
-
- if (results->global_avg_w) {
- *results->global_avg_w = global_avg_w;
- }
- if (results->global_max_h) {
- *results->global_max_h = global_max_h;
- }
- if (results->tot_w) {
- *results->tot_w = (int)tot_w + parameters->space_x * (parameters->tot_columns - 1);
- }
- if (results->tot_h) {
- *results->tot_h = tot_h + parameters->space_y * (parameters->tot_rows - 1);
- }
+static void ui_litem_grid_flow_compute(ListBase *items,
+ UILayoutGridFlowInput *parameters,
+ UILayoutGridFlowOutput *results)
+{
+ uiItem *item;
+ int i;
+
+ float tot_w = 0.0f, tot_h = 0.0f;
+ float global_avg_w = 0.0f, global_totweight_w = 0.0f;
+ int global_max_h = 0;
+
+ float *avg_w = NULL, *totweight_w = NULL;
+ int *max_h = NULL;
+
+ BLI_assert(
+ parameters->tot_columns != 0 ||
+ (results->cos_x_array == NULL && results->widths_array == NULL && results->tot_w == NULL));
+ BLI_assert(
+ parameters->tot_rows != 0 ||
+ (results->cos_y_array == NULL && results->heights_array == NULL && results->tot_h == NULL));
+
+ if (results->tot_items) {
+ *results->tot_items = 0;
+ }
+
+ if (items->first == NULL) {
+ if (results->global_avg_w) {
+ *results->global_avg_w = 0.0f;
+ }
+ if (results->global_max_h) {
+ *results->global_max_h = 0;
+ }
+ return;
+ }
+
+ if (parameters->tot_columns != 0) {
+ avg_w = BLI_array_alloca(avg_w, parameters->tot_columns);
+ totweight_w = BLI_array_alloca(totweight_w, parameters->tot_columns);
+ memset(avg_w, 0, sizeof(*avg_w) * parameters->tot_columns);
+ memset(totweight_w, 0, sizeof(*totweight_w) * parameters->tot_columns);
+ }
+ if (parameters->tot_rows != 0) {
+ max_h = BLI_array_alloca(max_h, parameters->tot_rows);
+ memset(max_h, 0, sizeof(*max_h) * parameters->tot_rows);
+ }
+
+ for (i = 0, item = items->first; item; item = item->next, i++) {
+ int item_w, item_h;
+ ui_item_size(item, &item_w, &item_h);
+
+ global_avg_w += (float)(item_w * item_w);
+ global_totweight_w += (float)item_w;
+ global_max_h = max_ii(global_max_h, item_h);
+
+ if (parameters->tot_rows != 0 && parameters->tot_columns != 0) {
+ const int index_col = parameters->row_major ? i % parameters->tot_columns :
+ i / parameters->tot_rows;
+ const int index_row = parameters->row_major ? i / parameters->tot_columns :
+ i % parameters->tot_rows;
+
+ avg_w[index_col] += (float)(item_w * item_w);
+ totweight_w[index_col] += (float)item_w;
+
+ max_h[index_row] = max_ii(max_h[index_row], item_h);
+ }
+
+ if (results->tot_items) {
+ (*results->tot_items)++;
+ }
+ }
+
+ /* Finalize computing of column average sizes */
+ global_avg_w /= global_totweight_w;
+ if (parameters->tot_columns != 0) {
+ for (i = 0; i < parameters->tot_columns; i++) {
+ avg_w[i] /= totweight_w[i];
+ tot_w += avg_w[i];
+ }
+ if (parameters->even_columns) {
+ tot_w = ceilf(global_avg_w) * parameters->tot_columns;
+ }
+ }
+ /* Finalize computing of rows max sizes */
+ if (parameters->tot_rows != 0) {
+ for (i = 0; i < parameters->tot_rows; i++) {
+ tot_h += max_h[i];
+ }
+ if (parameters->even_rows) {
+ tot_h = global_max_h * parameters->tot_columns;
+ }
+ }
+
+ /* Compute positions and sizes of all cells. */
+ if (results->cos_x_array != NULL && results->widths_array != NULL) {
+ /* We enlarge/narrow columns evenly to match available width. */
+ const float wfac = (float)(parameters->litem_w -
+ (parameters->tot_columns - 1) * parameters->space_x) /
+ tot_w;
+
+ for (int col = 0; col < parameters->tot_columns; col++) {
+ results->cos_x_array[col] = (col ? results->cos_x_array[col - 1] +
+ results->widths_array[col - 1] + parameters->space_x :
+ parameters->litem_x);
+ if (parameters->even_columns) {
+ /* (< remaining width > - < space between remaining columns >) / < remaining columns > */
+ results->widths_array[col] = (((parameters->litem_w -
+ (results->cos_x_array[col] - parameters->litem_x)) -
+ (parameters->tot_columns - col - 1) * parameters->space_x) /
+ (parameters->tot_columns - col));
+ }
+ else if (col == parameters->tot_columns - 1) {
+ /* Last column copes width rounding errors... */
+ results->widths_array[col] = parameters->litem_w -
+ (results->cos_x_array[col] - parameters->litem_x);
+ }
+ else {
+ results->widths_array[col] = (int)(avg_w[col] * wfac);
+ }
+ }
+ }
+ if (results->cos_y_array != NULL && results->heights_array != NULL) {
+ for (int row = 0; row < parameters->tot_rows; row++) {
+ if (parameters->even_rows) {
+ results->heights_array[row] = global_max_h;
+ }
+ else {
+ results->heights_array[row] = max_h[row];
+ }
+ results->cos_y_array[row] = (row ? results->cos_y_array[row - 1] - parameters->space_y -
+ results->heights_array[row] :
+ parameters->litem_y - results->heights_array[row]);
+ }
+ }
+
+ if (results->global_avg_w) {
+ *results->global_avg_w = global_avg_w;
+ }
+ if (results->global_max_h) {
+ *results->global_max_h = global_max_h;
+ }
+ if (results->tot_w) {
+ *results->tot_w = (int)tot_w + parameters->space_x * (parameters->tot_columns - 1);
+ }
+ if (results->tot_h) {
+ *results->tot_h = tot_h + parameters->space_y * (parameters->tot_rows - 1);
+ }
}
static void ui_litem_estimate_grid_flow(uiLayout *litem)
{
- uiStyle *style = litem->root->style;
- uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem;
-
- const int space_x = style->columnspace;
- const int space_y = style->buttonspacey;
-
- /* Estimate average needed width and height per item. */
- {
- float avg_w;
- int max_h;
-
- ui_litem_grid_flow_compute(
- &litem->items,
- &((UILayoutGridFlowInput) {
- .row_major = gflow->row_major,
- .even_columns = gflow->even_columns,
- .even_rows = gflow->even_rows,
- .litem_w = litem->w,
- .litem_x = litem->x,
- .litem_y = litem->y,
- .space_x = space_x,
- .space_y = space_y,
- }),
- &((UILayoutGridFlowOutput) {
- .tot_items = &gflow->tot_items,
- .global_avg_w = &avg_w,
- .global_max_h = &max_h,
- }));
-
- if (gflow->tot_items == 0) {
- litem->w = litem->h = 0;
- gflow->tot_columns = gflow->tot_rows = 0;
- return;
- }
-
- /* Even in varying column width case, we fix our columns number from weighted average width of items,
- * a proper solving of required width would be too costly, and this should give reasonably good results
- * in all reasonable cases... */
- if (gflow->columns_len > 0) {
- gflow->tot_columns = gflow->columns_len;
- }
- else {
- if (avg_w == 0.0f) {
- gflow->tot_columns = 1;
- }
- else {
- gflow->tot_columns = min_ii(max_ii((int)(litem->w / avg_w), 1), gflow->tot_items);
- }
- }
- gflow->tot_rows = (int)ceilf((float)gflow->tot_items / gflow->tot_columns);
-
- /* Try to tweak number of columns and rows to get better filling of last column or row,
- * and apply 'modulo' value to number of columns or rows.
- * Note that modulo does not prevent ending with fewer columns/rows than modulo, if mandatory
- * to avoid empty column/row. */
- {
- const int modulo = (gflow->columns_len < -1) ? -gflow->columns_len : 0;
- const int step = modulo ? modulo : 1;
-
- if (gflow->row_major) {
- /* Adjust number of columns to be multiple of given modulo. */
- if (modulo && gflow->tot_columns % modulo != 0 && gflow->tot_columns > modulo) {
- gflow->tot_columns = gflow->tot_columns - (gflow->tot_columns % modulo);
- }
- /* Find smallest number of columns conserving computed optimal number of rows. */
- for (gflow->tot_rows = (int)ceilf((float)gflow->tot_items / gflow->tot_columns);
- (gflow->tot_columns - step) > 0 &&
- (int)ceilf((float)gflow->tot_items / (gflow->tot_columns - step)) <= gflow->tot_rows;
- gflow->tot_columns -= step)
- {
- /* pass */
- }
- }
- else {
- /* Adjust number of rows to be multiple of given modulo. */
- if (modulo && gflow->tot_rows % modulo != 0) {
- gflow->tot_rows = min_ii(gflow->tot_rows + modulo - (gflow->tot_rows % modulo), gflow->tot_items);
- }
- /* Find smallest number of rows conserving computed optimal number of columns. */
- for (gflow->tot_columns = (int)ceilf((float)gflow->tot_items / gflow->tot_rows);
- (gflow->tot_rows - step) > 0 &&
- (int)ceilf((float)gflow->tot_items / (gflow->tot_rows - step)) <= gflow->tot_columns;
- gflow->tot_rows -= step)
- {
- /* pass */
- }
- }
- }
-
- /* Set evenly-spaced axes size
- * (quick optimization in case we have even columns and rows). */
- if (gflow->even_columns && gflow->even_rows) {
- litem->w = (int)(gflow->tot_columns * avg_w) + space_x * (gflow->tot_columns - 1);
- litem->h = (int)(gflow->tot_rows * max_h) + space_y * (gflow->tot_rows - 1);
- return;
- }
- }
-
- /* Now that we have our final number of columns and rows,
- * we can compute actual needed space for non-evenly sized axes. */
- {
- int tot_w, tot_h;
-
- ui_litem_grid_flow_compute(
- &litem->items,
- &((UILayoutGridFlowInput) {
- .row_major = gflow->row_major,
- .even_columns = gflow->even_columns,
- .even_rows = gflow->even_rows,
- .litem_w = litem->w,
- .litem_x = litem->x,
- .litem_y = litem->y,
- .space_x = space_x,
- .space_y = space_y,
- .tot_columns = gflow->tot_columns,
- .tot_rows = gflow->tot_rows,
- }),
- &((UILayoutGridFlowOutput) {
- .tot_w = &tot_w,
- .tot_h = &tot_h,
- }));
-
- litem->w = tot_w;
- litem->h = tot_h;
- }
+ uiStyle *style = litem->root->style;
+ uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem;
+
+ const int space_x = style->columnspace;
+ const int space_y = style->buttonspacey;
+
+ /* Estimate average needed width and height per item. */
+ {
+ float avg_w;
+ int max_h;
+
+ ui_litem_grid_flow_compute(&litem->items,
+ &((UILayoutGridFlowInput){
+ .row_major = gflow->row_major,
+ .even_columns = gflow->even_columns,
+ .even_rows = gflow->even_rows,
+ .litem_w = litem->w,
+ .litem_x = litem->x,
+ .litem_y = litem->y,
+ .space_x = space_x,
+ .space_y = space_y,
+ }),
+ &((UILayoutGridFlowOutput){
+ .tot_items = &gflow->tot_items,
+ .global_avg_w = &avg_w,
+ .global_max_h = &max_h,
+ }));
+
+ if (gflow->tot_items == 0) {
+ litem->w = litem->h = 0;
+ gflow->tot_columns = gflow->tot_rows = 0;
+ return;
+ }
+
+ /* Even in varying column width case, we fix our columns number from weighted average width of items,
+ * a proper solving of required width would be too costly, and this should give reasonably good results
+ * in all reasonable cases... */
+ if (gflow->columns_len > 0) {
+ gflow->tot_columns = gflow->columns_len;
+ }
+ else {
+ if (avg_w == 0.0f) {
+ gflow->tot_columns = 1;
+ }
+ else {
+ gflow->tot_columns = min_ii(max_ii((int)(litem->w / avg_w), 1), gflow->tot_items);
+ }
+ }
+ gflow->tot_rows = (int)ceilf((float)gflow->tot_items / gflow->tot_columns);
+
+ /* Try to tweak number of columns and rows to get better filling of last column or row,
+ * and apply 'modulo' value to number of columns or rows.
+ * Note that modulo does not prevent ending with fewer columns/rows than modulo, if mandatory
+ * to avoid empty column/row. */
+ {
+ const int modulo = (gflow->columns_len < -1) ? -gflow->columns_len : 0;
+ const int step = modulo ? modulo : 1;
+
+ if (gflow->row_major) {
+ /* Adjust number of columns to be multiple of given modulo. */
+ if (modulo && gflow->tot_columns % modulo != 0 && gflow->tot_columns > modulo) {
+ gflow->tot_columns = gflow->tot_columns - (gflow->tot_columns % modulo);
+ }
+ /* Find smallest number of columns conserving computed optimal number of rows. */
+ for (gflow->tot_rows = (int)ceilf((float)gflow->tot_items / gflow->tot_columns);
+ (gflow->tot_columns - step) > 0 &&
+ (int)ceilf((float)gflow->tot_items / (gflow->tot_columns - step)) <= gflow->tot_rows;
+ gflow->tot_columns -= step) {
+ /* pass */
+ }
+ }
+ else {
+ /* Adjust number of rows to be multiple of given modulo. */
+ if (modulo && gflow->tot_rows % modulo != 0) {
+ gflow->tot_rows = min_ii(gflow->tot_rows + modulo - (gflow->tot_rows % modulo),
+ gflow->tot_items);
+ }
+ /* Find smallest number of rows conserving computed optimal number of columns. */
+ for (gflow->tot_columns = (int)ceilf((float)gflow->tot_items / gflow->tot_rows);
+ (gflow->tot_rows - step) > 0 &&
+ (int)ceilf((float)gflow->tot_items / (gflow->tot_rows - step)) <= gflow->tot_columns;
+ gflow->tot_rows -= step) {
+ /* pass */
+ }
+ }
+ }
+
+ /* Set evenly-spaced axes size
+ * (quick optimization in case we have even columns and rows). */
+ if (gflow->even_columns && gflow->even_rows) {
+ litem->w = (int)(gflow->tot_columns * avg_w) + space_x * (gflow->tot_columns - 1);
+ litem->h = (int)(gflow->tot_rows * max_h) + space_y * (gflow->tot_rows - 1);
+ return;
+ }
+ }
+
+ /* Now that we have our final number of columns and rows,
+ * we can compute actual needed space for non-evenly sized axes. */
+ {
+ int tot_w, tot_h;
+
+ ui_litem_grid_flow_compute(&litem->items,
+ &((UILayoutGridFlowInput){
+ .row_major = gflow->row_major,
+ .even_columns = gflow->even_columns,
+ .even_rows = gflow->even_rows,
+ .litem_w = litem->w,
+ .litem_x = litem->x,
+ .litem_y = litem->y,
+ .space_x = space_x,
+ .space_y = space_y,
+ .tot_columns = gflow->tot_columns,
+ .tot_rows = gflow->tot_rows,
+ }),
+ &((UILayoutGridFlowOutput){
+ .tot_w = &tot_w,
+ .tot_h = &tot_h,
+ }));
+
+ litem->w = tot_w;
+ litem->h = tot_h;
+ }
}
static void ui_litem_layout_grid_flow(uiLayout *litem)
{
- int i;
- uiStyle *style = litem->root->style;
- uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem;
- uiItem *item;
-
- if (gflow->tot_items == 0) {
- litem->w = litem->h = 0;
- return;
- }
-
- BLI_assert(gflow->tot_columns > 0);
- BLI_assert(gflow->tot_rows > 0);
-
- const int space_x = style->columnspace;
- const int space_y = style->buttonspacey;
-
- int *widths = BLI_array_alloca(widths, gflow->tot_columns);
- int *heights = BLI_array_alloca(heights, gflow->tot_rows);
- int *cos_x = BLI_array_alloca(cos_x, gflow->tot_columns);
- int *cos_y = BLI_array_alloca(cos_y, gflow->tot_rows);
-
- /* This time we directly compute coordinates and sizes of all cells. */
- ui_litem_grid_flow_compute(
- &litem->items,
- &((UILayoutGridFlowInput) {
- .row_major = gflow->row_major,
- .even_columns = gflow->even_columns,
- .even_rows = gflow->even_rows,
- .litem_w = litem->w,
- .litem_x = litem->x,
- .litem_y = litem->y,
- .space_x = space_x,
- .space_y = space_y,
- .tot_columns = gflow->tot_columns,
- .tot_rows = gflow->tot_rows,
- }),
- &((UILayoutGridFlowOutput) {
- .cos_x_array = cos_x,
- .cos_y_array = cos_y,
- .widths_array = widths,
- .heights_array = heights,
- }));
-
- for (item = litem->items.first, i = 0; item; item = item->next, i++) {
- const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows;
- const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows;
- int item_w, item_h;
- ui_item_size(item, &item_w, &item_h);
-
- const int w = widths[col];
- const int h = heights[row];
-
- item_w = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, item_w);
- item_h = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? h : min_ii(h, item_h);
-
- ui_item_position(item, cos_x[col], cos_y[row], item_w, item_h);
- }
-
- litem->h = litem->y - cos_y[gflow->tot_rows - 1];
- litem->x = (cos_x[gflow->tot_columns - 1] - litem->x) + widths[gflow->tot_columns - 1];
- litem->y = litem->y - litem->h;
+ int i;
+ uiStyle *style = litem->root->style;
+ uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem;
+ uiItem *item;
+
+ if (gflow->tot_items == 0) {
+ litem->w = litem->h = 0;
+ return;
+ }
+
+ BLI_assert(gflow->tot_columns > 0);
+ BLI_assert(gflow->tot_rows > 0);
+
+ const int space_x = style->columnspace;
+ const int space_y = style->buttonspacey;
+
+ int *widths = BLI_array_alloca(widths, gflow->tot_columns);
+ int *heights = BLI_array_alloca(heights, gflow->tot_rows);
+ int *cos_x = BLI_array_alloca(cos_x, gflow->tot_columns);
+ int *cos_y = BLI_array_alloca(cos_y, gflow->tot_rows);
+
+ /* This time we directly compute coordinates and sizes of all cells. */
+ ui_litem_grid_flow_compute(&litem->items,
+ &((UILayoutGridFlowInput){
+ .row_major = gflow->row_major,
+ .even_columns = gflow->even_columns,
+ .even_rows = gflow->even_rows,
+ .litem_w = litem->w,
+ .litem_x = litem->x,
+ .litem_y = litem->y,
+ .space_x = space_x,
+ .space_y = space_y,
+ .tot_columns = gflow->tot_columns,
+ .tot_rows = gflow->tot_rows,
+ }),
+ &((UILayoutGridFlowOutput){
+ .cos_x_array = cos_x,
+ .cos_y_array = cos_y,
+ .widths_array = widths,
+ .heights_array = heights,
+ }));
+
+ for (item = litem->items.first, i = 0; item; item = item->next, i++) {
+ const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows;
+ const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows;
+ int item_w, item_h;
+ ui_item_size(item, &item_w, &item_h);
+
+ const int w = widths[col];
+ const int h = heights[row];
+
+ item_w = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, item_w);
+ item_h = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? h : min_ii(h, item_h);
+
+ ui_item_position(item, cos_x[col], cos_y[row], item_w, item_h);
+ }
+
+ litem->h = litem->y - cos_y[gflow->tot_rows - 1];
+ litem->x = (cos_x[gflow->tot_columns - 1] - litem->x) + widths[gflow->tot_columns - 1];
+ litem->y = litem->y - litem->h;
}
/* free layout */
static void ui_litem_estimate_absolute(uiLayout *litem)
{
- uiItem *item;
- int itemx, itemy, itemw, itemh, minx, miny;
+ uiItem *item;
+ int itemx, itemy, itemw, itemh, minx, miny;
- minx = 1e6;
- miny = 1e6;
- litem->w = 0;
- litem->h = 0;
+ minx = 1e6;
+ miny = 1e6;
+ litem->w = 0;
+ litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_offset(item, &itemx, &itemy);
- ui_item_size(item, &itemw, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_offset(item, &itemx, &itemy);
+ ui_item_size(item, &itemw, &itemh);
- minx = min_ii(minx, itemx);
- miny = min_ii(miny, itemy);
+ minx = min_ii(minx, itemx);
+ miny = min_ii(miny, itemy);
- litem->w = MAX2(litem->w, itemx + itemw);
- litem->h = MAX2(litem->h, itemy + itemh);
- }
+ litem->w = MAX2(litem->w, itemx + itemw);
+ litem->h = MAX2(litem->h, itemy + itemh);
+ }
- litem->w -= minx;
- litem->h -= miny;
+ litem->w -= minx;
+ litem->h -= miny;
}
static void ui_litem_layout_absolute(uiLayout *litem)
{
- uiItem *item;
- float scalex = 1.0f, scaley = 1.0f;
- int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth;
+ uiItem *item;
+ float scalex = 1.0f, scaley = 1.0f;
+ int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth;
- minx = 1e6;
- miny = 1e6;
- totw = 0;
- toth = 0;
+ minx = 1e6;
+ miny = 1e6;
+ totw = 0;
+ toth = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_offset(item, &itemx, &itemy);
- ui_item_size(item, &itemw, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_offset(item, &itemx, &itemy);
+ ui_item_size(item, &itemw, &itemh);
- minx = min_ii(minx, itemx);
- miny = min_ii(miny, itemy);
+ minx = min_ii(minx, itemx);
+ miny = min_ii(miny, itemy);
- totw = max_ii(totw, itemx + itemw);
- toth = max_ii(toth, itemy + itemh);
- }
+ totw = max_ii(totw, itemx + itemw);
+ toth = max_ii(toth, itemy + itemh);
+ }
- totw -= minx;
- toth -= miny;
+ totw -= minx;
+ toth -= miny;
- if (litem->w && totw > 0) {
- scalex = (float)litem->w / (float)totw;
- }
- if (litem->h && toth > 0) {
- scaley = (float)litem->h / (float)toth;
- }
+ if (litem->w && totw > 0) {
+ scalex = (float)litem->w / (float)totw;
+ }
+ if (litem->h && toth > 0) {
+ scaley = (float)litem->h / (float)toth;
+ }
- x = litem->x;
- y = litem->y - scaley * toth;
+ x = litem->x;
+ y = litem->y - scaley * toth;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_offset(item, &itemx, &itemy);
- ui_item_size(item, &itemw, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_offset(item, &itemx, &itemy);
+ ui_item_size(item, &itemw, &itemh);
- if (scalex != 1.0f) {
- newx = (itemx - minx) * scalex;
- itemw = (itemx - minx + itemw) * scalex - newx;
- itemx = minx + newx;
- }
+ if (scalex != 1.0f) {
+ newx = (itemx - minx) * scalex;
+ itemw = (itemx - minx + itemw) * scalex - newx;
+ itemx = minx + newx;
+ }
- if (scaley != 1.0f) {
- newy = (itemy - miny) * scaley;
- itemh = (itemy - miny + itemh) * scaley - newy;
- itemy = miny + newy;
- }
+ if (scaley != 1.0f) {
+ newy = (itemy - miny) * scaley;
+ itemh = (itemy - miny + itemh) * scaley - newy;
+ itemy = miny + newy;
+ }
- ui_item_position(item, x + itemx - minx, y + itemy - miny, itemw, itemh);
- }
+ ui_item_position(item, x + itemx - minx, y + itemy - miny, itemw, itemh);
+ }
- litem->w = scalex * totw;
- litem->h = litem->y - y;
- litem->x = x + litem->w;
- litem->y = y;
+ litem->w = scalex * totw;
+ litem->h = litem->y - y;
+ litem->x = x + litem->w;
+ litem->y = y;
}
/* split layout */
static void ui_litem_estimate_split(uiLayout *litem)
{
- ui_litem_estimate_row(litem);
- litem->item.flag &= ~UI_ITEM_MIN;
+ ui_litem_estimate_row(litem);
+ litem->item.flag &= ~UI_ITEM_MIN;
}
static void ui_litem_layout_split(uiLayout *litem)
{
- uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem;
- uiItem *item;
- float percentage, extra_pixel = 0.0f;
- const int tot = BLI_listbase_count(&litem->items);
- int itemh, x, y, w, colw = 0;
+ uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem;
+ uiItem *item;
+ float percentage, extra_pixel = 0.0f;
+ const int tot = BLI_listbase_count(&litem->items);
+ int itemh, x, y, w, colw = 0;
- if (tot == 0) {
- return;
- }
+ if (tot == 0) {
+ return;
+ }
- x = litem->x;
- y = litem->y;
+ x = litem->x;
+ y = litem->y;
- percentage = (split->percentage == 0.0f) ? 1.0f / (float)tot : split->percentage;
+ percentage = (split->percentage == 0.0f) ? 1.0f / (float)tot : split->percentage;
- w = (litem->w - (tot - 1) * litem->space);
- colw = w * percentage;
- colw = MAX2(colw, 0);
+ w = (litem->w - (tot - 1) * litem->space);
+ colw = w * percentage;
+ colw = MAX2(colw, 0);
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, NULL, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, NULL, &itemh);
- ui_item_position(item, x, y - itemh, colw, itemh);
- x += colw;
+ ui_item_position(item, x, y - itemh, colw, itemh);
+ x += colw;
- if (item->next) {
- const float width = extra_pixel + (w - (int)(w * percentage)) / ((float)tot - 1);
- extra_pixel = width - (int)width;
- colw = (int)width;
- colw = MAX2(colw, 0);
+ if (item->next) {
+ const float width = extra_pixel + (w - (int)(w * percentage)) / ((float)tot - 1);
+ extra_pixel = width - (int)width;
+ colw = (int)width;
+ colw = MAX2(colw, 0);
- x += litem->space;
- }
- }
+ x += litem->space;
+ }
+ }
- litem->w = x - litem->x;
- litem->h = litem->y - y;
- litem->x = x;
- litem->y = y;
+ litem->w = x - litem->x;
+ litem->h = litem->y - y;
+ litem->x = x;
+ litem->y = y;
}
/* overlap layout */
static void ui_litem_estimate_overlap(uiLayout *litem)
{
- uiItem *item;
- int itemw, itemh;
+ uiItem *item;
+ int itemw, itemh;
- litem->w = 0;
- litem->h = 0;
+ litem->w = 0;
+ litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
- litem->w = MAX2(itemw, litem->w);
- litem->h = MAX2(itemh, litem->h);
- }
+ litem->w = MAX2(itemw, litem->w);
+ litem->h = MAX2(itemh, litem->h);
+ }
}
static void ui_litem_layout_overlap(uiLayout *litem)
{
- uiItem *item;
- int itemw, itemh, x, y;
+ uiItem *item;
+ int itemw, itemh, x, y;
- x = litem->x;
- y = litem->y;
+ x = litem->x;
+ y = litem->y;
- for (item = litem->items.first; item; item = item->next) {
- ui_item_size(item, &itemw, &itemh);
- ui_item_position(item, x, y - itemh, litem->w, itemh);
+ for (item = litem->items.first; item; item = item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ ui_item_position(item, x, y - itemh, litem->w, itemh);
- litem->h = MAX2(litem->h, itemh);
- }
+ litem->h = MAX2(litem->h, itemh);
+ }
- litem->x = x;
- litem->y = y - litem->h;
+ litem->x = x;
+ litem->y = y - litem->h;
}
static void ui_litem_init_from_parent(uiLayout *litem, uiLayout *layout, int align)
{
- litem->root = layout->root;
- litem->align = align;
- /* Children of gridflow layout shall never have "ideal big size" returned as estimated size. */
- litem->variable_size = layout->variable_size || layout->item.type == ITEM_LAYOUT_GRID_FLOW;
- litem->active = true;
- litem->enabled = true;
- litem->context = layout->context;
- litem->redalert = layout->redalert;
- litem->w = layout->w;
- litem->emboss = layout->emboss;
- litem->item.flag = (layout->item.flag & (UI_ITEM_PROP_SEP | UI_ITEM_PROP_DECORATE));
-
- if (layout->child_items_layout) {
- BLI_addtail(&layout->child_items_layout->items, litem);
- }
- else {
- BLI_addtail(&layout->items, litem);
- }
+ litem->root = layout->root;
+ litem->align = align;
+ /* Children of gridflow layout shall never have "ideal big size" returned as estimated size. */
+ litem->variable_size = layout->variable_size || layout->item.type == ITEM_LAYOUT_GRID_FLOW;
+ litem->active = true;
+ litem->enabled = true;
+ litem->context = layout->context;
+ litem->redalert = layout->redalert;
+ litem->w = layout->w;
+ litem->emboss = layout->emboss;
+ litem->item.flag = (layout->item.flag & (UI_ITEM_PROP_SEP | UI_ITEM_PROP_DECORATE));
+
+ if (layout->child_items_layout) {
+ BLI_addtail(&layout->child_items_layout->items, litem);
+ }
+ else {
+ BLI_addtail(&layout->items, litem);
+ }
}
/* layout create functions */
uiLayout *uiLayoutRow(uiLayout *layout, bool align)
{
- uiLayout *litem;
+ uiLayout *litem;
- litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRow");
- ui_litem_init_from_parent(litem, layout, align);
+ litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRow");
+ ui_litem_init_from_parent(litem, layout, align);
- litem->item.type = ITEM_LAYOUT_ROW;
- litem->space = (align) ? 0 : layout->root->style->buttonspacex;
+ litem->item.type = ITEM_LAYOUT_ROW;
+ litem->space = (align) ? 0 : layout->root->style->buttonspacex;
- UI_block_layout_set_current(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
- return litem;
+ return litem;
}
uiLayout *uiLayoutColumn(uiLayout *layout, bool align)
{
- uiLayout *litem;
+ uiLayout *litem;
- litem = MEM_callocN(sizeof(uiLayout), "uiLayoutColumn");
- ui_litem_init_from_parent(litem, layout, align);
+ litem = MEM_callocN(sizeof(uiLayout), "uiLayoutColumn");
+ ui_litem_init_from_parent(litem, layout, align);
- litem->item.type = ITEM_LAYOUT_COLUMN;
- litem->space = (align) ? 0 : layout->root->style->buttonspacey;
+ litem->item.type = ITEM_LAYOUT_COLUMN;
+ litem->space = (align) ? 0 : layout->root->style->buttonspacey;
- UI_block_layout_set_current(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
- return litem;
+ return litem;
}
uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, bool align)
{
- uiLayoutItemFlow *flow;
+ uiLayoutItemFlow *flow;
- flow = MEM_callocN(sizeof(uiLayoutItemFlow), "uiLayoutItemFlow");
- ui_litem_init_from_parent(&flow->litem, layout, align);
+ flow = MEM_callocN(sizeof(uiLayoutItemFlow), "uiLayoutItemFlow");
+ ui_litem_init_from_parent(&flow->litem, layout, align);
- flow->litem.item.type = ITEM_LAYOUT_COLUMN_FLOW;
- flow->litem.space = (flow->litem.align) ? 0 : layout->root->style->columnspace;
- flow->number = number;
+ flow->litem.item.type = ITEM_LAYOUT_COLUMN_FLOW;
+ flow->litem.space = (flow->litem.align) ? 0 : layout->root->style->columnspace;
+ flow->number = number;
- UI_block_layout_set_current(layout->root->block, &flow->litem);
+ UI_block_layout_set_current(layout->root->block, &flow->litem);
- return &flow->litem;
+ return &flow->litem;
}
-uiLayout *uiLayoutGridFlow(
- uiLayout *layout, bool row_major, int columns_len, bool even_columns, bool even_rows, bool align)
+uiLayout *uiLayoutGridFlow(uiLayout *layout,
+ bool row_major,
+ int columns_len,
+ bool even_columns,
+ bool even_rows,
+ bool align)
{
- uiLayoutItemGridFlow *flow;
+ uiLayoutItemGridFlow *flow;
- flow = MEM_callocN(sizeof(uiLayoutItemGridFlow), __func__);
- flow->litem.item.type = ITEM_LAYOUT_GRID_FLOW;
- ui_litem_init_from_parent(&flow->litem, layout, align);
+ flow = MEM_callocN(sizeof(uiLayoutItemGridFlow), __func__);
+ flow->litem.item.type = ITEM_LAYOUT_GRID_FLOW;
+ ui_litem_init_from_parent(&flow->litem, layout, align);
- flow->litem.space = (flow->litem.align) ? 0 : layout->root->style->columnspace;
- flow->row_major = row_major;
- flow->columns_len = columns_len;
- flow->even_columns = even_columns;
- flow->even_rows = even_rows;
+ flow->litem.space = (flow->litem.align) ? 0 : layout->root->style->columnspace;
+ flow->row_major = row_major;
+ flow->columns_len = columns_len;
+ flow->even_columns = even_columns;
+ flow->even_rows = even_rows;
- UI_block_layout_set_current(layout->root->block, &flow->litem);
+ UI_block_layout_set_current(layout->root->block, &flow->litem);
- return &flow->litem;
+ return &flow->litem;
}
static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type)
{
- uiLayoutItemBx *box;
+ uiLayoutItemBx *box;
- box = MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx");
- ui_litem_init_from_parent(&box->litem, layout, false);
+ box = MEM_callocN(sizeof(uiLayoutItemBx), "uiLayoutItemBx");
+ ui_litem_init_from_parent(&box->litem, layout, false);
- box->litem.item.type = ITEM_LAYOUT_BOX;
- box->litem.space = layout->root->style->columnspace;
+ box->litem.item.type = ITEM_LAYOUT_BOX;
+ box->litem.space = layout->root->style->columnspace;
- UI_block_layout_set_current(layout->root->block, &box->litem);
+ UI_block_layout_set_current(layout->root->block, &box->litem);
- box->roundbox = uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
+ box->roundbox = uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
- return box;
+ return box;
}
uiLayout *uiLayoutRadial(uiLayout *layout)
{
- uiLayout *litem;
- uiItem *item;
+ uiLayout *litem;
+ uiItem *item;
- /* radial layouts are only valid for radial menus */
- if (layout->root->type != UI_LAYOUT_PIEMENU) {
- return ui_item_local_sublayout(layout, layout, 0);
- }
+ /* radial layouts are only valid for radial menus */
+ if (layout->root->type != UI_LAYOUT_PIEMENU) {
+ return ui_item_local_sublayout(layout, layout, 0);
+ }
- /* only one radial wheel per root layout is allowed, so check and return that, if it exists */
- for (item = layout->root->layout->items.first; item; item = item->next) {
- litem = (uiLayout *)item;
- if (litem->item.type == ITEM_LAYOUT_RADIAL) {
- UI_block_layout_set_current(layout->root->block, litem);
- return litem;
- }
- }
+ /* only one radial wheel per root layout is allowed, so check and return that, if it exists */
+ for (item = layout->root->layout->items.first; item; item = item->next) {
+ litem = (uiLayout *)item;
+ if (litem->item.type == ITEM_LAYOUT_RADIAL) {
+ UI_block_layout_set_current(layout->root->block, litem);
+ return litem;
+ }
+ }
- litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRadial");
- ui_litem_init_from_parent(litem, layout, false);
+ litem = MEM_callocN(sizeof(uiLayout), "uiLayoutRadial");
+ ui_litem_init_from_parent(litem, layout, false);
- litem->item.type = ITEM_LAYOUT_RADIAL;
+ litem->item.type = ITEM_LAYOUT_RADIAL;
- UI_block_layout_set_current(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
- return litem;
+ return litem;
}
-
uiLayout *uiLayoutBox(uiLayout *layout)
{
- return (uiLayout *)ui_layout_box(layout, UI_BTYPE_ROUNDBOX);
+ return (uiLayout *)ui_layout_box(layout, UI_BTYPE_ROUNDBOX);
}
/**
@@ -4063,762 +4439,763 @@ uiLayout *uiLayoutBox(uiLayout *layout)
*/
void ui_layout_list_set_labels_active(uiLayout *layout)
{
- uiButtonItem *bitem;
- for (bitem = layout->items.first; bitem; bitem = bitem->item.next) {
- if (bitem->item.type != ITEM_BUTTON) {
- ui_layout_list_set_labels_active((uiLayout *)(&bitem->item));
- }
- else if (bitem->but->flag & UI_BUT_LIST_ITEM) {
- UI_but_flag_enable(bitem->but, UI_SELECT);
- }
- }
+ uiButtonItem *bitem;
+ for (bitem = layout->items.first; bitem; bitem = bitem->item.next) {
+ if (bitem->item.type != ITEM_BUTTON) {
+ ui_layout_list_set_labels_active((uiLayout *)(&bitem->item));
+ }
+ else if (bitem->but->flag & UI_BUT_LIST_ITEM) {
+ UI_but_flag_enable(bitem->but, UI_SELECT);
+ }
+ }
}
-uiLayout *uiLayoutListBox(
- uiLayout *layout, uiList *ui_list, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr,
- PropertyRNA *actprop)
+uiLayout *uiLayoutListBox(uiLayout *layout,
+ uiList *ui_list,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ PointerRNA *actptr,
+ PropertyRNA *actprop)
{
- uiLayoutItemBx *box = ui_layout_box(layout, UI_BTYPE_LISTBOX);
- uiBut *but = box->roundbox;
+ uiLayoutItemBx *box = ui_layout_box(layout, UI_BTYPE_LISTBOX);
+ uiBut *but = box->roundbox;
- but->custom_data = ui_list;
+ but->custom_data = ui_list;
- but->rnasearchpoin = *ptr;
- but->rnasearchprop = prop;
- but->rnapoin = *actptr;
- but->rnaprop = actprop;
+ but->rnasearchpoin = *ptr;
+ but->rnasearchprop = prop;
+ but->rnapoin = *actptr;
+ but->rnaprop = actprop;
- /* only for the undo string */
- if (but->flag & UI_BUT_UNDO) {
- but->tip = RNA_property_description(actprop);
- }
+ /* only for the undo string */
+ if (but->flag & UI_BUT_UNDO) {
+ but->tip = RNA_property_description(actprop);
+ }
- return (uiLayout *)box;
+ return (uiLayout *)box;
}
uiLayout *uiLayoutAbsolute(uiLayout *layout, bool align)
{
- uiLayout *litem;
+ uiLayout *litem;
- litem = MEM_callocN(sizeof(uiLayout), "uiLayoutAbsolute");
- ui_litem_init_from_parent(litem, layout, align);
+ litem = MEM_callocN(sizeof(uiLayout), "uiLayoutAbsolute");
+ ui_litem_init_from_parent(litem, layout, align);
- litem->item.type = ITEM_LAYOUT_ABSOLUTE;
+ litem->item.type = ITEM_LAYOUT_ABSOLUTE;
- UI_block_layout_set_current(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
- return litem;
+ return litem;
}
uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout)
{
- uiBlock *block;
+ uiBlock *block;
- block = uiLayoutGetBlock(layout);
- uiLayoutAbsolute(layout, false);
+ block = uiLayoutGetBlock(layout);
+ uiLayoutAbsolute(layout, false);
- return block;
+ return block;
}
uiLayout *uiLayoutOverlap(uiLayout *layout)
{
- uiLayout *litem;
+ uiLayout *litem;
- litem = MEM_callocN(sizeof(uiLayout), "uiLayoutOverlap");
- ui_litem_init_from_parent(litem, layout, false);
+ litem = MEM_callocN(sizeof(uiLayout), "uiLayoutOverlap");
+ ui_litem_init_from_parent(litem, layout, false);
- litem->item.type = ITEM_LAYOUT_OVERLAP;
+ litem->item.type = ITEM_LAYOUT_OVERLAP;
- UI_block_layout_set_current(layout->root->block, litem);
+ UI_block_layout_set_current(layout->root->block, litem);
- return litem;
+ return litem;
}
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, bool align)
{
- uiLayoutItemSplit *split;
+ uiLayoutItemSplit *split;
- split = MEM_callocN(sizeof(uiLayoutItemSplit), "uiLayoutItemSplit");
- ui_litem_init_from_parent(&split->litem, layout, align);
+ split = MEM_callocN(sizeof(uiLayoutItemSplit), "uiLayoutItemSplit");
+ ui_litem_init_from_parent(&split->litem, layout, align);
- split->litem.item.type = ITEM_LAYOUT_SPLIT;
- split->litem.space = layout->root->style->columnspace;
- split->percentage = percentage;
+ split->litem.item.type = ITEM_LAYOUT_SPLIT;
+ split->litem.space = layout->root->style->columnspace;
+ split->percentage = percentage;
- UI_block_layout_set_current(layout->root->block, &split->litem);
+ UI_block_layout_set_current(layout->root->block, &split->litem);
- return &split->litem;
+ return &split->litem;
}
void uiLayoutSetActive(uiLayout *layout, bool active)
{
- layout->active = active;
+ layout->active = active;
}
void uiLayoutSetActiveDefault(uiLayout *layout, bool active_default)
{
- layout->active_default = active_default;
+ layout->active_default = active_default;
}
void uiLayoutSetActivateInit(uiLayout *layout, bool activate_init)
{
- layout->activate_init = activate_init;
+ layout->activate_init = activate_init;
}
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
{
- layout->enabled = enabled;
+ layout->enabled = enabled;
}
void uiLayoutSetRedAlert(uiLayout *layout, bool redalert)
{
- layout->redalert = redalert;
+ layout->redalert = redalert;
}
void uiLayoutSetKeepAspect(uiLayout *layout, bool keepaspect)
{
- layout->keepaspect = keepaspect;
+ layout->keepaspect = keepaspect;
}
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
{
- layout->alignment = alignment;
+ layout->alignment = alignment;
}
void uiLayoutSetScaleX(uiLayout *layout, float scale)
{
- layout->scale[0] = scale;
+ layout->scale[0] = scale;
}
void uiLayoutSetScaleY(uiLayout *layout, float scale)
{
- layout->scale[1] = scale;
+ layout->scale[1] = scale;
}
void uiLayoutSetUnitsX(uiLayout *layout, float unit)
{
- layout->units[0] = unit;
+ layout->units[0] = unit;
}
void uiLayoutSetUnitsY(uiLayout *layout, float unit)
{
- layout->units[1] = unit;
+ layout->units[1] = unit;
}
void uiLayoutSetEmboss(uiLayout *layout, char emboss)
{
- layout->emboss = emboss;
+ layout->emboss = emboss;
}
bool uiLayoutGetPropSep(uiLayout *layout)
{
- return (layout->item.flag & UI_ITEM_PROP_SEP) != 0;
+ return (layout->item.flag & UI_ITEM_PROP_SEP) != 0;
}
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
{
- SET_FLAG_FROM_TEST(layout->item.flag, is_sep, UI_ITEM_PROP_SEP);
+ SET_FLAG_FROM_TEST(layout->item.flag, is_sep, UI_ITEM_PROP_SEP);
}
bool uiLayoutGetPropDecorate(uiLayout *layout)
{
- return (layout->item.flag & UI_ITEM_PROP_DECORATE) != 0;
+ return (layout->item.flag & UI_ITEM_PROP_DECORATE) != 0;
}
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
{
- SET_FLAG_FROM_TEST(layout->item.flag, is_sep, UI_ITEM_PROP_DECORATE);
+ SET_FLAG_FROM_TEST(layout->item.flag, is_sep, UI_ITEM_PROP_DECORATE);
}
bool uiLayoutGetActive(uiLayout *layout)
{
- return layout->active;
+ return layout->active;
}
bool uiLayoutGetActiveDefault(uiLayout *layout)
{
- return layout->active_default;
+ return layout->active_default;
}
bool uiLayoutGetActivateInit(uiLayout *layout)
{
- return layout->activate_init;
+ return layout->activate_init;
}
bool uiLayoutGetEnabled(uiLayout *layout)
{
- return layout->enabled;
+ return layout->enabled;
}
bool uiLayoutGetRedAlert(uiLayout *layout)
{
- return layout->redalert;
+ return layout->redalert;
}
bool uiLayoutGetKeepAspect(uiLayout *layout)
{
- return layout->keepaspect;
+ return layout->keepaspect;
}
int uiLayoutGetAlignment(uiLayout *layout)
{
- return layout->alignment;
+ return layout->alignment;
}
int uiLayoutGetWidth(uiLayout *layout)
{
- return layout->w;
+ return layout->w;
}
float uiLayoutGetScaleX(uiLayout *layout)
{
- return layout->scale[0];
+ return layout->scale[0];
}
float uiLayoutGetScaleY(uiLayout *layout)
{
- return layout->scale[1];
+ return layout->scale[1];
}
float uiLayoutGetUnitsX(uiLayout *layout)
{
- return layout->units[0];
+ return layout->units[0];
}
float uiLayoutGetUnitsY(uiLayout *layout)
{
- return layout->units[1];
+ return layout->units[1];
}
int uiLayoutGetEmboss(uiLayout *layout)
{
- if (layout->emboss == UI_EMBOSS_UNDEFINED) {
- return layout->root->block->dt;
- }
- else {
- return layout->emboss;
- }
+ if (layout->emboss == UI_EMBOSS_UNDEFINED) {
+ return layout->root->block->dt;
+ }
+ else {
+ return layout->emboss;
+ }
}
/********************** Layout *******************/
static void ui_item_scale(uiLayout *litem, const float scale[2])
{
- uiItem *item;
- int x, y, w, h;
+ uiItem *item;
+ int x, y, w, h;
- for (item = litem->items.last; item; item = item->prev) {
- if (item->type != ITEM_BUTTON) {
- uiLayout *subitem = (uiLayout *)item;
- ui_item_scale(subitem, scale);
- }
+ for (item = litem->items.last; item; item = item->prev) {
+ if (item->type != ITEM_BUTTON) {
+ uiLayout *subitem = (uiLayout *)item;
+ ui_item_scale(subitem, scale);
+ }
- ui_item_size(item, &w, &h);
- ui_item_offset(item, &x, &y);
+ ui_item_size(item, &w, &h);
+ ui_item_offset(item, &x, &y);
- if (scale[0] != 0.0f) {
- x *= scale[0];
- w *= scale[0];
- }
+ if (scale[0] != 0.0f) {
+ x *= scale[0];
+ w *= scale[0];
+ }
- if (scale[1] != 0.0f) {
- y *= scale[1];
- h *= scale[1];
- }
+ if (scale[1] != 0.0f) {
+ y *= scale[1];
+ h *= scale[1];
+ }
- ui_item_position(item, x, y, w, h);
- }
+ ui_item_position(item, x, y, w, h);
+ }
}
static void ui_item_estimate(uiItem *item)
{
- uiItem *subitem;
-
- if (item->type != ITEM_BUTTON) {
- uiLayout *litem = (uiLayout *)item;
-
- for (subitem = litem->items.first; subitem; subitem = subitem->next) {
- ui_item_estimate(subitem);
- }
-
- if (BLI_listbase_is_empty(&litem->items)) {
- litem->w = 0;
- litem->h = 0;
- return;
- }
-
- if (litem->scale[0] != 0.0f || litem->scale[1] != 0.0f) {
- ui_item_scale(litem, litem->scale);
- }
-
- switch (litem->item.type) {
- case ITEM_LAYOUT_COLUMN:
- ui_litem_estimate_column(litem, false);
- break;
- case ITEM_LAYOUT_COLUMN_FLOW:
- ui_litem_estimate_column_flow(litem);
- break;
- case ITEM_LAYOUT_GRID_FLOW:
- ui_litem_estimate_grid_flow(litem);
- break;
- case ITEM_LAYOUT_ROW:
- ui_litem_estimate_row(litem);
- break;
- case ITEM_LAYOUT_BOX:
- ui_litem_estimate_box(litem);
- break;
- case ITEM_LAYOUT_ROOT:
- ui_litem_estimate_root(litem);
- break;
- case ITEM_LAYOUT_ABSOLUTE:
- ui_litem_estimate_absolute(litem);
- break;
- case ITEM_LAYOUT_SPLIT:
- ui_litem_estimate_split(litem);
- break;
- case ITEM_LAYOUT_OVERLAP:
- ui_litem_estimate_overlap(litem);
- break;
- default:
- break;
- }
-
- /* Force fixed size. */
- if (litem->units[0] > 0) {
- litem->w = UI_UNIT_X * litem->units[0];
- }
- if (litem->units[1] > 0) {
- litem->h = UI_UNIT_Y * litem->units[1];
- }
- }
+ uiItem *subitem;
+
+ if (item->type != ITEM_BUTTON) {
+ uiLayout *litem = (uiLayout *)item;
+
+ for (subitem = litem->items.first; subitem; subitem = subitem->next) {
+ ui_item_estimate(subitem);
+ }
+
+ if (BLI_listbase_is_empty(&litem->items)) {
+ litem->w = 0;
+ litem->h = 0;
+ return;
+ }
+
+ if (litem->scale[0] != 0.0f || litem->scale[1] != 0.0f) {
+ ui_item_scale(litem, litem->scale);
+ }
+
+ switch (litem->item.type) {
+ case ITEM_LAYOUT_COLUMN:
+ ui_litem_estimate_column(litem, false);
+ break;
+ case ITEM_LAYOUT_COLUMN_FLOW:
+ ui_litem_estimate_column_flow(litem);
+ break;
+ case ITEM_LAYOUT_GRID_FLOW:
+ ui_litem_estimate_grid_flow(litem);
+ break;
+ case ITEM_LAYOUT_ROW:
+ ui_litem_estimate_row(litem);
+ break;
+ case ITEM_LAYOUT_BOX:
+ ui_litem_estimate_box(litem);
+ break;
+ case ITEM_LAYOUT_ROOT:
+ ui_litem_estimate_root(litem);
+ break;
+ case ITEM_LAYOUT_ABSOLUTE:
+ ui_litem_estimate_absolute(litem);
+ break;
+ case ITEM_LAYOUT_SPLIT:
+ ui_litem_estimate_split(litem);
+ break;
+ case ITEM_LAYOUT_OVERLAP:
+ ui_litem_estimate_overlap(litem);
+ break;
+ default:
+ break;
+ }
+
+ /* Force fixed size. */
+ if (litem->units[0] > 0) {
+ litem->w = UI_UNIT_X * litem->units[0];
+ }
+ if (litem->units[1] > 0) {
+ litem->h = UI_UNIT_Y * litem->units[1];
+ }
+ }
}
static void ui_item_align(uiLayout *litem, short nr)
{
- uiItem *item;
- uiButtonItem *bitem;
- uiLayoutItemBx *box;
+ uiItem *item;
+ uiButtonItem *bitem;
+ uiLayoutItemBx *box;
- for (item = litem->items.last; item; item = item->prev) {
- if (item->type == ITEM_BUTTON) {
- bitem = (uiButtonItem *)item;
+ for (item = litem->items.last; item; item = item->prev) {
+ if (item->type == ITEM_BUTTON) {
+ bitem = (uiButtonItem *)item;
#ifndef USE_UIBUT_SPATIAL_ALIGN
- if (ui_but_can_align(bitem->but))
+ if (ui_but_can_align(bitem->but))
#endif
- {
- if (!bitem->but->alignnr) {
- bitem->but->alignnr = nr;
- }
- }
- }
- else if (item->type == ITEM_LAYOUT_ABSOLUTE) {
- /* pass */
- }
- else if (item->type == ITEM_LAYOUT_OVERLAP) {
- /* pass */
- }
- else if (item->type == ITEM_LAYOUT_BOX) {
- box = (uiLayoutItemBx *)item;
- if (!box->roundbox->alignnr) {
- box->roundbox->alignnr = nr;
- }
- }
- else if (((uiLayout *)item)->align) {
- ui_item_align((uiLayout *)item, nr);
- }
- }
+ {
+ if (!bitem->but->alignnr) {
+ bitem->but->alignnr = nr;
+ }
+ }
+ }
+ else if (item->type == ITEM_LAYOUT_ABSOLUTE) {
+ /* pass */
+ }
+ else if (item->type == ITEM_LAYOUT_OVERLAP) {
+ /* pass */
+ }
+ else if (item->type == ITEM_LAYOUT_BOX) {
+ box = (uiLayoutItemBx *)item;
+ if (!box->roundbox->alignnr) {
+ box->roundbox->alignnr = nr;
+ }
+ }
+ else if (((uiLayout *)item)->align) {
+ ui_item_align((uiLayout *)item, nr);
+ }
+ }
}
static void ui_item_flag(uiLayout *litem, int flag)
{
- uiItem *item;
- uiButtonItem *bitem;
+ uiItem *item;
+ uiButtonItem *bitem;
- for (item = litem->items.last; item; item = item->prev) {
- if (item->type == ITEM_BUTTON) {
- bitem = (uiButtonItem *)item;
- bitem->but->flag |= flag;
- }
- else {
- ui_item_flag((uiLayout *)item, flag);
- }
- }
+ for (item = litem->items.last; item; item = item->prev) {
+ if (item->type == ITEM_BUTTON) {
+ bitem = (uiButtonItem *)item;
+ bitem->but->flag |= flag;
+ }
+ else {
+ ui_item_flag((uiLayout *)item, flag);
+ }
+ }
}
static void ui_item_layout(uiItem *item)
{
- uiItem *subitem;
-
- if (item->type != ITEM_BUTTON) {
- uiLayout *litem = (uiLayout *)item;
-
- if (BLI_listbase_is_empty(&litem->items)) {
- return;
- }
-
- if (litem->align) {
- ui_item_align(litem, ++litem->root->block->alignnr);
- }
- if (!litem->active) {
- ui_item_flag(litem, UI_BUT_INACTIVE);
- }
- if (!litem->enabled) {
- ui_item_flag(litem, UI_BUT_DISABLED);
- }
-
- switch (litem->item.type) {
- case ITEM_LAYOUT_COLUMN:
- ui_litem_layout_column(litem, false);
- break;
- case ITEM_LAYOUT_COLUMN_FLOW:
- ui_litem_layout_column_flow(litem);
- break;
- case ITEM_LAYOUT_GRID_FLOW:
- ui_litem_layout_grid_flow(litem);
- break;
- case ITEM_LAYOUT_ROW:
- ui_litem_layout_row(litem);
- break;
- case ITEM_LAYOUT_BOX:
- ui_litem_layout_box(litem);
- break;
- case ITEM_LAYOUT_ROOT:
- ui_litem_layout_root(litem);
- break;
- case ITEM_LAYOUT_ABSOLUTE:
- ui_litem_layout_absolute(litem);
- break;
- case ITEM_LAYOUT_SPLIT:
- ui_litem_layout_split(litem);
- break;
- case ITEM_LAYOUT_OVERLAP:
- ui_litem_layout_overlap(litem);
- break;
- case ITEM_LAYOUT_RADIAL:
- ui_litem_layout_radial(litem);
- break;
- default:
- break;
- }
-
- for (subitem = litem->items.first; subitem; subitem = subitem->next) {
- if (item->flag & UI_ITEM_BOX_ITEM) {
- subitem->flag |= UI_ITEM_BOX_ITEM;
- }
- ui_item_layout(subitem);
- }
- }
- else {
- if (item->flag & UI_ITEM_BOX_ITEM) {
- uiButtonItem *bitem = (uiButtonItem *)item;
- bitem->but->drawflag |= UI_BUT_BOX_ITEM;
- }
- }
+ uiItem *subitem;
+
+ if (item->type != ITEM_BUTTON) {
+ uiLayout *litem = (uiLayout *)item;
+
+ if (BLI_listbase_is_empty(&litem->items)) {
+ return;
+ }
+
+ if (litem->align) {
+ ui_item_align(litem, ++litem->root->block->alignnr);
+ }
+ if (!litem->active) {
+ ui_item_flag(litem, UI_BUT_INACTIVE);
+ }
+ if (!litem->enabled) {
+ ui_item_flag(litem, UI_BUT_DISABLED);
+ }
+
+ switch (litem->item.type) {
+ case ITEM_LAYOUT_COLUMN:
+ ui_litem_layout_column(litem, false);
+ break;
+ case ITEM_LAYOUT_COLUMN_FLOW:
+ ui_litem_layout_column_flow(litem);
+ break;
+ case ITEM_LAYOUT_GRID_FLOW:
+ ui_litem_layout_grid_flow(litem);
+ break;
+ case ITEM_LAYOUT_ROW:
+ ui_litem_layout_row(litem);
+ break;
+ case ITEM_LAYOUT_BOX:
+ ui_litem_layout_box(litem);
+ break;
+ case ITEM_LAYOUT_ROOT:
+ ui_litem_layout_root(litem);
+ break;
+ case ITEM_LAYOUT_ABSOLUTE:
+ ui_litem_layout_absolute(litem);
+ break;
+ case ITEM_LAYOUT_SPLIT:
+ ui_litem_layout_split(litem);
+ break;
+ case ITEM_LAYOUT_OVERLAP:
+ ui_litem_layout_overlap(litem);
+ break;
+ case ITEM_LAYOUT_RADIAL:
+ ui_litem_layout_radial(litem);
+ break;
+ default:
+ break;
+ }
+
+ for (subitem = litem->items.first; subitem; subitem = subitem->next) {
+ if (item->flag & UI_ITEM_BOX_ITEM) {
+ subitem->flag |= UI_ITEM_BOX_ITEM;
+ }
+ ui_item_layout(subitem);
+ }
+ }
+ else {
+ if (item->flag & UI_ITEM_BOX_ITEM) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
+ bitem->but->drawflag |= UI_BUT_BOX_ITEM;
+ }
+ }
}
static void ui_layout_end(uiBlock *block, uiLayout *layout, int *r_x, int *r_y)
{
- if (layout->root->handlefunc) {
- UI_block_func_handle_set(block, layout->root->handlefunc, layout->root->argv);
- }
+ if (layout->root->handlefunc) {
+ UI_block_func_handle_set(block, layout->root->handlefunc, layout->root->argv);
+ }
- ui_item_estimate(&layout->item);
- ui_item_layout(&layout->item);
+ ui_item_estimate(&layout->item);
+ ui_item_layout(&layout->item);
- if (r_x) {
- *r_x = layout->x;
- }
- if (r_y) {
- *r_y = layout->y;
- }
+ if (r_x) {
+ *r_x = layout->x;
+ }
+ if (r_y) {
+ *r_y = layout->y;
+ }
}
static void ui_layout_free(uiLayout *layout)
{
- uiItem *item, *next;
+ uiItem *item, *next;
- for (item = layout->items.first; item; item = next) {
- next = item->next;
+ for (item = layout->items.first; item; item = next) {
+ next = item->next;
- if (item->type == ITEM_BUTTON) {
- MEM_freeN(item);
- }
- else {
- ui_layout_free((uiLayout *)item);
- }
- }
+ if (item->type == ITEM_BUTTON) {
+ MEM_freeN(item);
+ }
+ else {
+ ui_layout_free((uiLayout *)item);
+ }
+ }
- MEM_freeN(layout);
+ MEM_freeN(layout);
}
static void ui_layout_add_padding_button(uiLayoutRoot *root)
{
- if (root->padding) {
- /* add an invisible button for padding */
- uiBlock *block = root->block;
- uiLayout *prev_layout = block->curlayout;
+ if (root->padding) {
+ /* add an invisible button for padding */
+ uiBlock *block = root->block;
+ uiLayout *prev_layout = block->curlayout;
- block->curlayout = root->layout;
- uiDefBut(block, UI_BTYPE_SEPR, 0, "", 0, 0, root->padding, root->padding, NULL, 0.0, 0.0, 0, 0, "");
- block->curlayout = prev_layout;
- }
+ block->curlayout = root->layout;
+ uiDefBut(
+ block, UI_BTYPE_SEPR, 0, "", 0, 0, root->padding, root->padding, NULL, 0.0, 0.0, 0, 0, "");
+ block->curlayout = prev_layout;
+ }
}
-uiLayout *UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, uiStyle *style)
+uiLayout *UI_block_layout(
+ uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, uiStyle *style)
{
- uiLayout *layout;
- uiLayoutRoot *root;
+ uiLayout *layout;
+ uiLayoutRoot *root;
- root = MEM_callocN(sizeof(uiLayoutRoot), "uiLayoutRoot");
- root->type = type;
- root->style = style;
- root->block = block;
- root->padding = padding;
- root->opcontext = WM_OP_INVOKE_REGION_WIN;
+ root = MEM_callocN(sizeof(uiLayoutRoot), "uiLayoutRoot");
+ root->type = type;
+ root->style = style;
+ root->block = block;
+ root->padding = padding;
+ root->opcontext = WM_OP_INVOKE_REGION_WIN;
- layout = MEM_callocN(sizeof(uiLayout), "uiLayout");
- layout->item.type = (type == UI_LAYOUT_VERT_BAR) ? ITEM_LAYOUT_COLUMN : ITEM_LAYOUT_ROOT;
+ layout = MEM_callocN(sizeof(uiLayout), "uiLayout");
+ layout->item.type = (type == UI_LAYOUT_VERT_BAR) ? ITEM_LAYOUT_COLUMN : ITEM_LAYOUT_ROOT;
- /* Only used when 'UI_ITEM_PROP_SEP' is set. */
- layout->item.flag = UI_ITEM_PROP_DECORATE;
+ /* Only used when 'UI_ITEM_PROP_SEP' is set. */
+ layout->item.flag = UI_ITEM_PROP_DECORATE;
- layout->x = x;
- layout->y = y;
- layout->root = root;
- layout->space = style->templatespace;
- layout->active = 1;
- layout->enabled = 1;
- layout->context = NULL;
- layout->emboss = UI_EMBOSS_UNDEFINED;
+ layout->x = x;
+ layout->y = y;
+ layout->root = root;
+ layout->space = style->templatespace;
+ layout->active = 1;
+ layout->enabled = 1;
+ layout->context = NULL;
+ layout->emboss = UI_EMBOSS_UNDEFINED;
- if (type == UI_LAYOUT_MENU || type == UI_LAYOUT_PIEMENU) {
- layout->space = 0;
- }
+ if (type == UI_LAYOUT_MENU || type == UI_LAYOUT_PIEMENU) {
+ layout->space = 0;
+ }
- if (dir == UI_LAYOUT_HORIZONTAL) {
- layout->h = size;
- layout->root->emh = em * UI_UNIT_Y;
- }
- else {
- layout->w = size;
- layout->root->emw = em * UI_UNIT_X;
- }
+ if (dir == UI_LAYOUT_HORIZONTAL) {
+ layout->h = size;
+ layout->root->emh = em * UI_UNIT_Y;
+ }
+ else {
+ layout->w = size;
+ layout->root->emw = em * UI_UNIT_X;
+ }
- block->curlayout = layout;
- root->layout = layout;
- BLI_addtail(&block->layouts, root);
+ block->curlayout = layout;
+ root->layout = layout;
+ BLI_addtail(&block->layouts, root);
- ui_layout_add_padding_button(root);
+ ui_layout_add_padding_button(root);
- return layout;
+ return layout;
}
uiBlock *uiLayoutGetBlock(uiLayout *layout)
{
- return layout->root->block;
+ return layout->root->block;
}
int uiLayoutGetOperatorContext(uiLayout *layout)
{
- return layout->root->opcontext;
+ return layout->root->opcontext;
}
-
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
{
- block->curlayout = layout;
+ block->curlayout = layout;
}
void ui_layout_add_but(uiLayout *layout, uiBut *but)
{
- uiButtonItem *bitem;
+ uiButtonItem *bitem;
- bitem = MEM_callocN(sizeof(uiButtonItem), "uiButtonItem");
- bitem->item.type = ITEM_BUTTON;
- bitem->but = but;
+ bitem = MEM_callocN(sizeof(uiButtonItem), "uiButtonItem");
+ bitem->item.type = ITEM_BUTTON;
+ bitem->but = but;
- int w, h;
- ui_item_size((uiItem *)bitem, &w, &h);
- /* XXX uiBut hasn't scaled yet
- * we can flag the button as not expandable, depending on its size */
- if (w <= 2 * UI_UNIT_X && (!but->str || but->str[0] == '\0')) {
- bitem->item.flag |= UI_ITEM_MIN;
- }
+ int w, h;
+ ui_item_size((uiItem *)bitem, &w, &h);
+ /* XXX uiBut hasn't scaled yet
+ * we can flag the button as not expandable, depending on its size */
+ if (w <= 2 * UI_UNIT_X && (!but->str || but->str[0] == '\0')) {
+ bitem->item.flag |= UI_ITEM_MIN;
+ }
- if (layout->child_items_layout) {
- BLI_addtail(&layout->child_items_layout->items, bitem);
- }
- else {
- BLI_addtail(&layout->items, bitem);
- }
+ if (layout->child_items_layout) {
+ BLI_addtail(&layout->child_items_layout->items, bitem);
+ }
+ else {
+ BLI_addtail(&layout->items, bitem);
+ }
- if (layout->context) {
- but->context = layout->context;
- but->context->used = true;
- }
+ if (layout->context) {
+ but->context = layout->context;
+ but->context->used = true;
+ }
- if (layout->emboss != UI_EMBOSS_UNDEFINED) {
- but->dt = layout->emboss;
- }
+ if (layout->emboss != UI_EMBOSS_UNDEFINED) {
+ but->dt = layout->emboss;
+ }
}
void uiLayoutSetOperatorContext(uiLayout *layout, int opcontext)
{
- layout->root->opcontext = opcontext;
+ layout->root->opcontext = opcontext;
}
void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
{
- layout->root->handlefunc = handlefunc;
- layout->root->argv = argv;
+ layout->root->handlefunc = handlefunc;
+ layout->root->argv = argv;
}
void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
{
- uiLayoutRoot *root;
+ uiLayoutRoot *root;
- BLI_assert(block->active);
+ BLI_assert(block->active);
- if (r_x) {
- *r_x = 0;
- }
- if (r_y) {
- *r_y = 0;
- }
+ if (r_x) {
+ *r_x = 0;
+ }
+ if (r_y) {
+ *r_y = 0;
+ }
- block->curlayout = NULL;
+ block->curlayout = NULL;
- for (root = block->layouts.first; root; root = root->next) {
- ui_layout_add_padding_button(root);
+ for (root = block->layouts.first; root; root = root->next) {
+ ui_layout_add_padding_button(root);
- /* NULL in advance so we don't interfere when adding button */
- ui_layout_end(block, root->layout, r_x, r_y);
- ui_layout_free(root->layout);
- }
+ /* NULL in advance so we don't interfere when adding button */
+ ui_layout_end(block, root->layout, r_x, r_y);
+ ui_layout_free(root->layout);
+ }
- BLI_freelistN(&block->layouts);
+ BLI_freelistN(&block->layouts);
- /* XXX silly trick, interface_templates.c doesn't get linked
- * because it's not used by other files in this module? */
- {
- UI_template_fix_linking();
- }
+ /* XXX silly trick, interface_templates.c doesn't get linked
+ * because it's not used by other files in this module? */
+ {
+ UI_template_fix_linking();
+ }
}
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, PointerRNA *ptr)
{
- uiBlock *block = layout->root->block;
- layout->context = CTX_store_add(&block->contexts, name, ptr);
+ uiBlock *block = layout->root->block;
+ layout->context = CTX_store_add(&block->contexts, name, ptr);
}
void uiLayoutContextCopy(uiLayout *layout, bContextStore *context)
{
- uiBlock *block = layout->root->block;
- layout->context = CTX_store_add_all(&block->contexts, context);
+ uiBlock *block = layout->root->block;
+ layout->context = CTX_store_add_all(&block->contexts, context);
}
void uiLayoutSetContextFromBut(uiLayout *layout, uiBut *but)
{
- if (but->opptr) {
- uiLayoutSetContextPointer(layout, "button_operator", but->opptr);
- }
+ if (but->opptr) {
+ uiLayoutSetContextPointer(layout, "button_operator", but->opptr);
+ }
- if (but->rnapoin.data && but->rnaprop) {
- /* TODO: index could be supported as well */
- PointerRNA ptr_prop;
- RNA_pointer_create(NULL, &RNA_Property, but->rnaprop, &ptr_prop);
- uiLayoutSetContextPointer(layout, "button_prop", &ptr_prop);
- uiLayoutSetContextPointer(layout, "button_pointer", &but->rnapoin);
- }
+ if (but->rnapoin.data && but->rnaprop) {
+ /* TODO: index could be supported as well */
+ PointerRNA ptr_prop;
+ RNA_pointer_create(NULL, &RNA_Property, but->rnaprop, &ptr_prop);
+ uiLayoutSetContextPointer(layout, "button_prop", &ptr_prop);
+ uiLayoutSetContextPointer(layout, "button_pointer", &but->rnapoin);
+ }
}
/* this is a bit of a hack but best keep it in one place at least */
MenuType *UI_but_menutype_get(uiBut *but)
{
- if (but->menu_create_func == ui_item_menutype_func) {
- return (MenuType *)but->poin;
- }
- else {
- return NULL;
- }
+ if (but->menu_create_func == ui_item_menutype_func) {
+ return (MenuType *)but->poin;
+ }
+ else {
+ return NULL;
+ }
}
/* this is a bit of a hack but best keep it in one place at least */
PanelType *UI_but_paneltype_get(uiBut *but)
{
- if (but->menu_create_func == ui_item_paneltype_func) {
- return (PanelType *)but->poin;
- }
- else {
- return NULL;
- }
+ if (but->menu_create_func == ui_item_paneltype_func) {
+ return (PanelType *)but->poin;
+ }
+ else {
+ return NULL;
+ }
}
-
void UI_menutype_draw(bContext *C, MenuType *mt, struct uiLayout *layout)
{
- Menu menu = {
- .layout = layout,
- .type = mt,
- };
+ Menu menu = {
+ .layout = layout,
+ .type = mt,
+ };
- if (G.debug & G_DEBUG_WM) {
- printf("%s: opening menu \"%s\"\n", __func__, mt->idname);
- }
+ if (G.debug & G_DEBUG_WM) {
+ printf("%s: opening menu \"%s\"\n", __func__, mt->idname);
+ }
- if (layout->context) {
- CTX_store_set(C, layout->context);
- }
+ if (layout->context) {
+ CTX_store_set(C, layout->context);
+ }
- mt->draw(C, &menu);
+ mt->draw(C, &menu);
- if (layout->context) {
- CTX_store_set(C, NULL);
- }
+ if (layout->context) {
+ CTX_store_set(C, NULL);
+ }
}
-
-static void ui_paneltype_draw_impl(
- bContext *C, PanelType *pt, uiLayout *layout, bool show_header)
+static void ui_paneltype_draw_impl(bContext *C, PanelType *pt, uiLayout *layout, bool show_header)
{
- Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
- panel->type = pt;
- panel->flag = PNL_POPOVER;
+ Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
+ panel->type = pt;
+ panel->flag = PNL_POPOVER;
- uiLayout *last_item = layout->items.last;
+ uiLayout *last_item = layout->items.last;
- /* Draw main panel. */
- if (show_header) {
- uiLayout *row = uiLayoutRow(layout, false);
- if (pt->draw_header) {
- panel->layout = row;
- pt->draw_header(C, panel);
- panel->layout = NULL;
- }
- uiItemL(row, pt->label, ICON_NONE);
- }
+ /* Draw main panel. */
+ if (show_header) {
+ uiLayout *row = uiLayoutRow(layout, false);
+ if (pt->draw_header) {
+ panel->layout = row;
+ pt->draw_header(C, panel);
+ panel->layout = NULL;
+ }
+ uiItemL(row, pt->label, ICON_NONE);
+ }
- panel->layout = layout;
- pt->draw(C, panel);
- panel->layout = NULL;
+ panel->layout = layout;
+ pt->draw(C, panel);
+ panel->layout = NULL;
- MEM_freeN(panel);
+ MEM_freeN(panel);
- /* Draw child panels. */
- for (LinkData *link = pt->children.first; link; link = link->next) {
- PanelType *child_pt = link->data;
+ /* Draw child panels. */
+ for (LinkData *link = pt->children.first; link; link = link->next) {
+ PanelType *child_pt = link->data;
- if (child_pt->poll == NULL || child_pt->poll(C, child_pt)) {
- /* Add space if something was added to the layout. */
- if (last_item != layout->items.last) {
- uiItemS(layout);
- last_item = layout->items.last;
- }
+ if (child_pt->poll == NULL || child_pt->poll(C, child_pt)) {
+ /* Add space if something was added to the layout. */
+ if (last_item != layout->items.last) {
+ uiItemS(layout);
+ last_item = layout->items.last;
+ }
- uiLayout *col = uiLayoutColumn(layout, false);
- ui_paneltype_draw_impl(C, child_pt, col, true);
- }
- }
+ uiLayout *col = uiLayoutColumn(layout, false);
+ ui_paneltype_draw_impl(C, child_pt, col, true);
+ }
+ }
}
/**
@@ -4826,14 +5203,13 @@ static void ui_paneltype_draw_impl(
*/
void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout)
{
- if (layout->context) {
- CTX_store_set(C, layout->context);
- }
-
- ui_paneltype_draw_impl(C, pt, layout, false);
+ if (layout->context) {
+ CTX_store_set(C, layout->context);
+ }
- if (layout->context) {
- CTX_store_set(C, NULL);
- }
+ ui_paneltype_draw_impl(C, pt, layout, false);
+ if (layout->context) {
+ CTX_store_set(C, NULL);
+ }
}
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index e00ea2d16bd..537a1d4c851 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -27,7 +27,7 @@
#include "DNA_armature_types.h"
#include "DNA_screen_types.h"
-#include "DNA_text_types.h" /* for UI_OT_reports_to_text */
+#include "DNA_text_types.h" /* for UI_OT_reports_to_text */
#include "DNA_object_types.h" /* for OB_DATA_SUPPORT_ID */
#include "BLI_blenlib.h"
@@ -76,92 +76,92 @@
static bool copy_data_path_button_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- char *path;
- int index;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ char *path;
+ int index;
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (ptr.id.data && ptr.data && prop) {
- path = RNA_path_from_ID_to_property(&ptr, prop);
+ if (ptr.id.data && ptr.data && prop) {
+ path = RNA_path_from_ID_to_property(&ptr, prop);
- if (path) {
- MEM_freeN(path);
- return 1;
- }
- }
+ if (path) {
+ MEM_freeN(path);
+ return 1;
+ }
+ }
- return 0;
+ return 0;
}
static int copy_data_path_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- char *path;
- int index;
-
- const bool full_path = RNA_boolean_get(op->ptr, "full_path");
-
- /* try to create driver using property retrieved from UI */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- if (ptr.id.data != NULL) {
-
- if (full_path) {
-
- if (prop) {
- path = RNA_path_full_property_py_ex(&ptr, prop, index, true);
- }
- else {
- path = RNA_path_full_struct_py(&ptr);
- }
- }
- else {
- path = RNA_path_from_ID_to_property(&ptr, prop);
- }
-
- if (path) {
- WM_clipboard_text_set(path, false);
- MEM_freeN(path);
- return OPERATOR_FINISHED;
- }
- }
-
- return OPERATOR_CANCELLED;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ char *path;
+ int index;
+
+ const bool full_path = RNA_boolean_get(op->ptr, "full_path");
+
+ /* try to create driver using property retrieved from UI */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ if (ptr.id.data != NULL) {
+
+ if (full_path) {
+
+ if (prop) {
+ path = RNA_path_full_property_py_ex(&ptr, prop, index, true);
+ }
+ else {
+ path = RNA_path_full_struct_py(&ptr);
+ }
+ }
+ else {
+ path = RNA_path_from_ID_to_property(&ptr, prop);
+ }
+
+ if (path) {
+ WM_clipboard_text_set(path, false);
+ MEM_freeN(path);
+ return OPERATOR_FINISHED;
+ }
+ }
+
+ return OPERATOR_CANCELLED;
}
static void UI_OT_copy_data_path_button(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Copy Data Path";
- ot->idname = "UI_OT_copy_data_path_button";
- ot->description = "Copy the RNA data path for this property to the clipboard";
+ /* identifiers */
+ ot->name = "Copy Data Path";
+ ot->idname = "UI_OT_copy_data_path_button";
+ ot->description = "Copy the RNA data path for this property to the clipboard";
- /* callbacks */
- ot->exec = copy_data_path_button_exec;
- ot->poll = copy_data_path_button_poll;
+ /* callbacks */
+ ot->exec = copy_data_path_button_exec;
+ ot->poll = copy_data_path_button_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
- /* properties */
- prop = RNA_def_boolean(ot->srna, "full_path", false, "full_path", "Copy full data path");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ prop = RNA_def_boolean(ot->srna, "full_path", false, "full_path", "Copy full data path");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static bool copy_python_command_button_poll(bContext *C)
{
- uiBut *but = UI_context_active_but_get(C);
+ uiBut *but = UI_context_active_but_get(C);
- if (but && (but->optype != NULL)) {
- return 1;
- }
+ if (but && (but->optype != NULL)) {
+ return 1;
+ }
- return 0;
+ return 0;
}
/** \} */
@@ -172,38 +172,38 @@ static bool copy_python_command_button_poll(bContext *C)
static int copy_python_command_button_exec(bContext *C, wmOperator *UNUSED(op))
{
- uiBut *but = UI_context_active_but_get(C);
+ uiBut *but = UI_context_active_but_get(C);
- if (but && (but->optype != NULL)) {
- PointerRNA *opptr;
- char *str;
- opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */
+ if (but && (but->optype != NULL)) {
+ PointerRNA *opptr;
+ char *str;
+ opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */
- str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr);
+ str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr);
- WM_clipboard_text_set(str, 0);
+ WM_clipboard_text_set(str, 0);
- MEM_freeN(str);
+ MEM_freeN(str);
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
+ }
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
static void UI_OT_copy_python_command_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Python Command";
- ot->idname = "UI_OT_copy_python_command_button";
- ot->description = "Copy the Python command matching this button";
+ /* identifiers */
+ ot->name = "Copy Python Command";
+ ot->idname = "UI_OT_copy_python_command_button";
+ ot->description = "Copy the Python command matching this button";
- /* callbacks */
- ot->exec = copy_python_command_button_exec;
- ot->poll = copy_python_command_button_poll;
+ /* callbacks */
+ ot->exec = copy_python_command_button_exec;
+ ot->poll = copy_python_command_button_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
}
/** \} */
@@ -214,73 +214,73 @@ static void UI_OT_copy_python_command_button(wmOperatorType *ot)
static int operator_button_property_finish(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
{
- ID *id = ptr->id.data;
-
- /* perform updates required for this property */
- RNA_property_update(C, ptr, prop);
-
- /* as if we pressed the button */
- UI_context_active_but_prop_handle(C);
-
- /* Since we don't want to undo _all_ edits to settings, eg window
- * edits on the screen or on operator settings.
- * it might be better to move undo's inline - campbell */
- if (id && ID_CHECK_UNDO(id)) {
- /* do nothing, go ahead with undo */
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ ID *id = ptr->id.data;
+
+ /* perform updates required for this property */
+ RNA_property_update(C, ptr, prop);
+
+ /* as if we pressed the button */
+ UI_context_active_but_prop_handle(C);
+
+ /* Since we don't want to undo _all_ edits to settings, eg window
+ * edits on the screen or on operator settings.
+ * it might be better to move undo's inline - campbell */
+ if (id && ID_CHECK_UNDO(id)) {
+ /* do nothing, go ahead with undo */
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static bool reset_default_button_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- return (ptr.data && prop && RNA_property_editable(&ptr, prop));
+ return (ptr.data && prop && RNA_property_editable(&ptr, prop));
}
static int reset_default_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
- const bool all = RNA_boolean_get(op->ptr, "all");
-
- /* try to reset the nominated setting to its default value */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- /* if there is a valid property that is editable... */
- if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
- if (RNA_property_reset(&ptr, prop, (all) ? -1 : index)) {
- return operator_button_property_finish(C, &ptr, prop);
- }
- }
-
- return OPERATOR_CANCELLED;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+ const bool all = RNA_boolean_get(op->ptr, "all");
+
+ /* try to reset the nominated setting to its default value */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
+ if (RNA_property_reset(&ptr, prop, (all) ? -1 : index)) {
+ return operator_button_property_finish(C, &ptr, prop);
+ }
+ }
+
+ return OPERATOR_CANCELLED;
}
static void UI_OT_reset_default_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Reset to Default Value";
- ot->idname = "UI_OT_reset_default_button";
- ot->description = "Reset this property's value to its default value";
+ /* identifiers */
+ ot->name = "Reset to Default Value";
+ ot->idname = "UI_OT_reset_default_button";
+ ot->description = "Reset this property's value to its default value";
- /* callbacks */
- ot->poll = reset_default_button_poll;
- ot->exec = reset_default_button_exec;
+ /* callbacks */
+ ot->poll = reset_default_button_poll;
+ ot->exec = reset_default_button_exec;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
}
/** \} */
@@ -291,53 +291,54 @@ static void UI_OT_reset_default_button(wmOperatorType *ot)
static bool assign_default_button_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
- PropertyType type = RNA_property_type(prop);
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
+ PropertyType type = RNA_property_type(prop);
- return RNA_property_is_idprop(prop) && !RNA_property_array_check(prop) && ELEM(type, PROP_INT, PROP_FLOAT);
- }
+ return RNA_property_is_idprop(prop) && !RNA_property_array_check(prop) &&
+ ELEM(type, PROP_INT, PROP_FLOAT);
+ }
- return false;
+ return false;
}
static int assign_default_button_exec(bContext *C, wmOperator *UNUSED(op))
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
- /* try to reset the nominated setting to its default value */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ /* try to reset the nominated setting to its default value */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- /* if there is a valid property that is editable... */
- if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
- if (RNA_property_assign_default(&ptr, prop)) {
- return operator_button_property_finish(C, &ptr, prop);
- }
- }
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
+ if (RNA_property_assign_default(&ptr, prop)) {
+ return operator_button_property_finish(C, &ptr, prop);
+ }
+ }
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
static void UI_OT_assign_default_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Assign Value as Default";
- ot->idname = "UI_OT_assign_default_button";
- ot->description = "Set this property's current value as the new default";
+ /* identifiers */
+ ot->name = "Assign Value as Default";
+ ot->idname = "UI_OT_assign_default_button";
+ ot->description = "Set this property's current value as the new default";
- /* callbacks */
- ot->poll = assign_default_button_poll;
- ot->exec = assign_default_button_exec;
+ /* callbacks */
+ ot->poll = assign_default_button_poll;
+ ot->exec = assign_default_button_exec;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/** \} */
@@ -348,38 +349,37 @@ static void UI_OT_assign_default_button(wmOperatorType *ot)
static int unset_property_button_exec(bContext *C, wmOperator *UNUSED(op))
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
-
- /* try to unset the nominated property */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- /* if there is a valid property that is editable... */
- if (ptr.data && prop && RNA_property_editable(&ptr, prop) &&
- /* RNA_property_is_idprop(prop) && */
- RNA_property_is_set(&ptr, prop))
- {
- RNA_property_unset(&ptr, prop);
- return operator_button_property_finish(C, &ptr, prop);
- }
-
- return OPERATOR_CANCELLED;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+
+ /* try to unset the nominated property */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop && RNA_property_editable(&ptr, prop) &&
+ /* RNA_property_is_idprop(prop) && */
+ RNA_property_is_set(&ptr, prop)) {
+ RNA_property_unset(&ptr, prop);
+ return operator_button_property_finish(C, &ptr, prop);
+ }
+
+ return OPERATOR_CANCELLED;
}
static void UI_OT_unset_property_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Unset property";
- ot->idname = "UI_OT_unset_property_button";
- ot->description = "Clear the property and use default or generated value in operators";
+ /* identifiers */
+ ot->name = "Unset property";
+ ot->idname = "UI_OT_unset_property_button";
+ ot->description = "Clear the property and use default or generated value in operators";
- /* callbacks */
- ot->poll = ED_operator_regionactive;
- ot->exec = unset_property_button_exec;
+ /* callbacks */
+ ot->poll = ED_operator_regionactive;
+ ot->exec = unset_property_button_exec;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
}
/** \} */
@@ -391,211 +391,230 @@ static void UI_OT_unset_property_button(wmOperatorType *ot)
/* Note that we use different values for UI/UX than 'real' override operations, user does not care
* whether it's added or removed for the differential operation e.g. */
enum {
- UIOverride_Type_NOOP = 0,
- UIOverride_Type_Replace = 1,
- UIOverride_Type_Difference = 2, /* Add/subtract */
- UIOverride_Type_Factor = 3, /* Multiply */
- /* TODO: should/can we expose insert/remove ones for collections? Doubt it... */
+ UIOverride_Type_NOOP = 0,
+ UIOverride_Type_Replace = 1,
+ UIOverride_Type_Difference = 2, /* Add/subtract */
+ UIOverride_Type_Factor = 3, /* Multiply */
+ /* TODO: should/can we expose insert/remove ones for collections? Doubt it... */
};
static EnumPropertyItem override_type_items[] = {
- {UIOverride_Type_NOOP, "NOOP", 0, "NoOp",
- "'No-Operation', place holder preventing automatic override to ever affect the property"},
- {UIOverride_Type_Replace, "REPLACE", 0, "Replace", "Completely replace value from linked data by local one"},
- {UIOverride_Type_Difference, "DIFFERENCE", 0, "Difference", "Store difference to linked data value"},
- {UIOverride_Type_Factor, "FACTOR", 0, "Factor", "Store factor to linked data value (useful e.g. for scale)"},
- {0, NULL, 0, NULL, NULL},
+ {UIOverride_Type_NOOP,
+ "NOOP",
+ 0,
+ "NoOp",
+ "'No-Operation', place holder preventing automatic override to ever affect the property"},
+ {UIOverride_Type_Replace,
+ "REPLACE",
+ 0,
+ "Replace",
+ "Completely replace value from linked data by local one"},
+ {UIOverride_Type_Difference,
+ "DIFFERENCE",
+ 0,
+ "Difference",
+ "Store difference to linked data value"},
+ {UIOverride_Type_Factor,
+ "FACTOR",
+ 0,
+ "Factor",
+ "Store factor to linked data value (useful e.g. for scale)"},
+ {0, NULL, 0, NULL, NULL},
};
-
static bool override_type_set_button_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- const int override_status = RNA_property_static_override_status(&ptr, prop, index);
+ const int override_status = RNA_property_static_override_status(&ptr, prop, index);
- return (ptr.data && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE));
+ return (ptr.data && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDABLE));
}
static int override_type_set_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
- bool created;
- const bool all = RNA_boolean_get(op->ptr, "all");
- const int op_type = RNA_enum_get(op->ptr, "type");
-
- short operation;
-
- switch (op_type) {
- case UIOverride_Type_NOOP:
- operation = IDOVERRIDESTATIC_OP_NOOP;
- break;
- case UIOverride_Type_Replace:
- operation = IDOVERRIDESTATIC_OP_REPLACE;
- break;
- case UIOverride_Type_Difference:
- /* override code will automatically switch to subtract if needed. */
- operation = IDOVERRIDESTATIC_OP_ADD;
- break;
- case UIOverride_Type_Factor:
- operation = IDOVERRIDESTATIC_OP_MULTIPLY;
- break;
- default:
- operation = IDOVERRIDESTATIC_OP_REPLACE;
- BLI_assert(0);
- break;
- }
-
- /* try to reset the nominated setting to its default value */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- BLI_assert(ptr.id.data != NULL);
-
- if (all) {
- index = -1;
- }
-
- IDOverrideStaticPropertyOperation *opop = RNA_property_override_property_operation_get(
- &ptr, prop, operation, index, true, NULL, &created);
- if (!created) {
- opop->operation = operation;
- }
-
- return operator_button_property_finish(C, &ptr, prop);
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+ bool created;
+ const bool all = RNA_boolean_get(op->ptr, "all");
+ const int op_type = RNA_enum_get(op->ptr, "type");
+
+ short operation;
+
+ switch (op_type) {
+ case UIOverride_Type_NOOP:
+ operation = IDOVERRIDESTATIC_OP_NOOP;
+ break;
+ case UIOverride_Type_Replace:
+ operation = IDOVERRIDESTATIC_OP_REPLACE;
+ break;
+ case UIOverride_Type_Difference:
+ /* override code will automatically switch to subtract if needed. */
+ operation = IDOVERRIDESTATIC_OP_ADD;
+ break;
+ case UIOverride_Type_Factor:
+ operation = IDOVERRIDESTATIC_OP_MULTIPLY;
+ break;
+ default:
+ operation = IDOVERRIDESTATIC_OP_REPLACE;
+ BLI_assert(0);
+ break;
+ }
+
+ /* try to reset the nominated setting to its default value */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ BLI_assert(ptr.id.data != NULL);
+
+ if (all) {
+ index = -1;
+ }
+
+ IDOverrideStaticPropertyOperation *opop = RNA_property_override_property_operation_get(
+ &ptr, prop, operation, index, true, NULL, &created);
+ if (!created) {
+ opop->operation = operation;
+ }
+
+ return operator_button_property_finish(C, &ptr, prop);
}
-static int override_type_set_button_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+static int override_type_set_button_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *UNUSED(event))
{
-#if 0 /* Disabled for now */
- return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
+#if 0 /* Disabled for now */
+ return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
#else
- RNA_enum_set(op->ptr, "type", IDOVERRIDESTATIC_OP_REPLACE);
- return override_type_set_button_exec(C, op);
+ RNA_enum_set(op->ptr, "type", IDOVERRIDESTATIC_OP_REPLACE);
+ return override_type_set_button_exec(C, op);
#endif
}
static void UI_OT_override_type_set_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Define Override Type";
- ot->idname = "UI_OT_override_type_set_button";
- ot->description = "Create an override operation, or set the type of an existing one";
-
- /* callbacks */
- ot->poll = override_type_set_button_poll;
- ot->exec = override_type_set_button_exec;
- ot->invoke = override_type_set_button_invoke;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
- ot->prop = RNA_def_enum(
- ot->srna, "type", override_type_items, UIOverride_Type_Replace,
- "Type", "Type of override operation");
- /* TODO: add itemf callback, not all options are available for all data types... */
+ /* identifiers */
+ ot->name = "Define Override Type";
+ ot->idname = "UI_OT_override_type_set_button";
+ ot->description = "Create an override operation, or set the type of an existing one";
+
+ /* callbacks */
+ ot->poll = override_type_set_button_poll;
+ ot->exec = override_type_set_button_exec;
+ ot->invoke = override_type_set_button_invoke;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
+ ot->prop = RNA_def_enum(ot->srna,
+ "type",
+ override_type_items,
+ UIOverride_Type_Replace,
+ "Type",
+ "Type of override operation");
+ /* TODO: add itemf callback, not all options are available for all data types... */
}
-
static bool override_remove_button_poll(bContext *C)
{
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- const int override_status = RNA_property_static_override_status(&ptr, prop, index);
+ const int override_status = RNA_property_static_override_status(&ptr, prop, index);
- return (ptr.data && ptr.id.data && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN));
+ return (ptr.data && ptr.id.data && prop && (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN));
}
static int override_remove_button_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- PointerRNA ptr, id_refptr, src;
- PropertyRNA *prop;
- int index;
- const bool all = RNA_boolean_get(op->ptr, "all");
-
- /* try to reset the nominated setting to its default value */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- ID *id = ptr.id.data;
- IDOverrideStaticProperty *oprop = RNA_property_override_property_find(&ptr, prop);
- BLI_assert(oprop != NULL);
- BLI_assert(id != NULL && id->override_static != NULL);
-
- const bool is_template = (id->override_static->reference == NULL);
-
- /* We need source (i.e. linked data) to restore values of deleted overrides...
- * If this is an override template, we obviously do not need to restore anything. */
- if (!is_template) {
- RNA_id_pointer_create(id->override_static->reference, &id_refptr);
- if (!RNA_path_resolve(&id_refptr, oprop->rna_path, &src, NULL)) {
- BLI_assert(0 && "Failed to create matching source (linked data) RNA pointer");
- }
- }
-
- if (!all && index != -1) {
- bool is_strict_find;
- /* Remove override operation for given item,
- * add singular operations for the other items as needed. */
- IDOverrideStaticPropertyOperation *opop = BKE_override_static_property_operation_find(
- oprop, NULL, NULL, index, index, false, &is_strict_find);
- BLI_assert(opop != NULL);
- if (!is_strict_find) {
- /* No specific override operation, we have to get generic one,
- * and create item-specific override operations for all but given index,
- * before removing generic one. */
- for (int idx = RNA_property_array_length(&ptr, prop); idx--; ) {
- if (idx != index) {
- BKE_override_static_property_operation_get(oprop, opop->operation, NULL, NULL, idx, idx, true, NULL, NULL);
- }
- }
- }
- BKE_override_static_property_operation_delete(oprop, opop);
- if (!is_template) {
- RNA_property_copy(bmain, &ptr, &src, prop, index);
- }
- if (BLI_listbase_is_empty(&oprop->operations)) {
- BKE_override_static_property_delete(id->override_static, oprop);
- }
- }
- else {
- /* Just remove whole generic override operation of this property. */
- BKE_override_static_property_delete(id->override_static, oprop);
- if (!is_template) {
- RNA_property_copy(bmain, &ptr, &src, prop, -1);
- }
- }
-
- return operator_button_property_finish(C, &ptr, prop);
+ Main *bmain = CTX_data_main(C);
+ PointerRNA ptr, id_refptr, src;
+ PropertyRNA *prop;
+ int index;
+ const bool all = RNA_boolean_get(op->ptr, "all");
+
+ /* try to reset the nominated setting to its default value */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ ID *id = ptr.id.data;
+ IDOverrideStaticProperty *oprop = RNA_property_override_property_find(&ptr, prop);
+ BLI_assert(oprop != NULL);
+ BLI_assert(id != NULL && id->override_static != NULL);
+
+ const bool is_template = (id->override_static->reference == NULL);
+
+ /* We need source (i.e. linked data) to restore values of deleted overrides...
+ * If this is an override template, we obviously do not need to restore anything. */
+ if (!is_template) {
+ RNA_id_pointer_create(id->override_static->reference, &id_refptr);
+ if (!RNA_path_resolve(&id_refptr, oprop->rna_path, &src, NULL)) {
+ BLI_assert(0 && "Failed to create matching source (linked data) RNA pointer");
+ }
+ }
+
+ if (!all && index != -1) {
+ bool is_strict_find;
+ /* Remove override operation for given item,
+ * add singular operations for the other items as needed. */
+ IDOverrideStaticPropertyOperation *opop = BKE_override_static_property_operation_find(
+ oprop, NULL, NULL, index, index, false, &is_strict_find);
+ BLI_assert(opop != NULL);
+ if (!is_strict_find) {
+ /* No specific override operation, we have to get generic one,
+ * and create item-specific override operations for all but given index,
+ * before removing generic one. */
+ for (int idx = RNA_property_array_length(&ptr, prop); idx--;) {
+ if (idx != index) {
+ BKE_override_static_property_operation_get(
+ oprop, opop->operation, NULL, NULL, idx, idx, true, NULL, NULL);
+ }
+ }
+ }
+ BKE_override_static_property_operation_delete(oprop, opop);
+ if (!is_template) {
+ RNA_property_copy(bmain, &ptr, &src, prop, index);
+ }
+ if (BLI_listbase_is_empty(&oprop->operations)) {
+ BKE_override_static_property_delete(id->override_static, oprop);
+ }
+ }
+ else {
+ /* Just remove whole generic override operation of this property. */
+ BKE_override_static_property_delete(id->override_static, oprop);
+ if (!is_template) {
+ RNA_property_copy(bmain, &ptr, &src, prop, -1);
+ }
+ }
+
+ return operator_button_property_finish(C, &ptr, prop);
}
static void UI_OT_override_remove_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Override";
- ot->idname = "UI_OT_override_remove_button";
- ot->description = "Remove an override operation";
+ /* identifiers */
+ ot->name = "Remove Override";
+ ot->idname = "UI_OT_override_remove_button";
+ ot->description = "Remove an override operation";
- /* callbacks */
- ot->poll = override_remove_button_poll;
- ot->exec = override_remove_button_exec;
+ /* callbacks */
+ ot->poll = override_remove_button_poll;
+ ot->exec = override_remove_button_exec;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array");
}
/** \} */
@@ -604,150 +623,148 @@ static void UI_OT_override_remove_button(wmOperatorType *ot)
/** \name Copy To Selected Operator
* \{ */
-bool UI_context_copy_to_selected_list(
- bContext *C, PointerRNA *ptr, PropertyRNA *prop,
- ListBase *r_lb, bool *r_use_path_from_id, char **r_path)
+bool UI_context_copy_to_selected_list(bContext *C,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ ListBase *r_lb,
+ bool *r_use_path_from_id,
+ char **r_path)
{
- *r_use_path_from_id = false;
- *r_path = NULL;
-
- if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) {
- *r_lb = CTX_data_collection_get(C, "selected_editable_bones");
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
- *r_lb = CTX_data_collection_get(C, "selected_pose_bones");
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_Bone)) {
- ListBase lb;
- lb = CTX_data_collection_get(C, "selected_pose_bones");
-
- if (!BLI_listbase_is_empty(&lb)) {
- CollectionPointerLink *link;
- for (link = lb.first; link; link = link->next) {
- bPoseChannel *pchan = link->ptr.data;
- RNA_pointer_create(link->ptr.id.data, &RNA_Bone, pchan->bone, &link->ptr);
- }
- }
-
- *r_lb = lb;
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
- *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_FCurve)) {
- *r_lb = CTX_data_collection_get(C, "selected_editable_fcurves");
- }
- else if (RNA_struct_is_a(ptr->type, &RNA_Node) ||
- RNA_struct_is_a(ptr->type, &RNA_NodeSocket))
- {
- ListBase lb = {NULL, NULL};
- char *path = NULL;
- bNode *node = NULL;
-
- /* Get the node we're editing */
- if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
- bNodeTree *ntree = ptr->id.data;
- bNodeSocket *sock = ptr->data;
- if (nodeFindNode(ntree, sock, &node, NULL)) {
- if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != NULL) {
- /* we're good! */
- }
- else {
- node = NULL;
- }
- }
- }
- else {
- node = ptr->data;
- }
-
- /* Now filter by type */
- if (node) {
- CollectionPointerLink *link, *link_next;
- lb = CTX_data_collection_get(C, "selected_nodes");
-
- for (link = lb.first; link; link = link_next) {
- bNode *node_data = link->ptr.data;
- link_next = link->next;
-
- if (node_data->type != node->type) {
- BLI_remlink(&lb, link);
- MEM_freeN(link);
- }
- }
- }
-
- *r_lb = lb;
- *r_path = path;
- }
- else if (ptr->id.data) {
- ID *id = ptr->id.data;
-
- if (GS(id->name) == ID_OB) {
- *r_lb = CTX_data_collection_get(C, "selected_editable_objects");
- *r_use_path_from_id = true;
- *r_path = RNA_path_from_ID_to_property(ptr, prop);
- }
- else if (OB_DATA_SUPPORT_ID(GS(id->name))) {
- /* check we're using the active object */
- const short id_code = GS(id->name);
- ListBase lb = CTX_data_collection_get(C, "selected_editable_objects");
- char *path = RNA_path_from_ID_to_property(ptr, prop);
-
- /* de-duplicate obdata */
- if (!BLI_listbase_is_empty(&lb)) {
- CollectionPointerLink *link, *link_next;
-
- for (link = lb.first; link; link = link->next) {
- Object *ob = link->ptr.id.data;
- if (ob->data) {
- ID *id_data = ob->data;
- id_data->tag |= LIB_TAG_DOIT;
- }
- }
-
- for (link = lb.first; link; link = link_next) {
- Object *ob = link->ptr.id.data;
- ID *id_data = ob->data;
- link_next = link->next;
-
- if ((id_data == NULL) ||
- (id_data->tag & LIB_TAG_DOIT) == 0 ||
- ID_IS_LINKED(id_data) ||
- (GS(id_data->name) != id_code))
- {
- BLI_remlink(&lb, link);
- MEM_freeN(link);
- }
- else {
- /* avoid prepending 'data' to the path */
- RNA_id_pointer_create(id_data, &link->ptr);
- }
-
- if (id_data) {
- id_data->tag &= ~LIB_TAG_DOIT;
- }
- }
- }
-
- *r_lb = lb;
- *r_path = path;
- }
- else if (GS(id->name) == ID_SCE) {
- /* Sequencer's ID is scene :/ */
- /* Try to recursively find an RNA_Sequence ancestor,
- * to handle situations like T41062... */
- if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != NULL) {
- *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
- }
- }
- return (*r_path != NULL);
- }
- else {
- return false;
- }
-
- return true;
+ *r_use_path_from_id = false;
+ *r_path = NULL;
+
+ if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_bones");
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
+ *r_lb = CTX_data_collection_get(C, "selected_pose_bones");
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Bone)) {
+ ListBase lb;
+ lb = CTX_data_collection_get(C, "selected_pose_bones");
+
+ if (!BLI_listbase_is_empty(&lb)) {
+ CollectionPointerLink *link;
+ for (link = lb.first; link; link = link->next) {
+ bPoseChannel *pchan = link->ptr.data;
+ RNA_pointer_create(link->ptr.id.data, &RNA_Bone, pchan->bone, &link->ptr);
+ }
+ }
+
+ *r_lb = lb;
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_FCurve)) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_fcurves");
+ }
+ else if (RNA_struct_is_a(ptr->type, &RNA_Node) || RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
+ ListBase lb = {NULL, NULL};
+ char *path = NULL;
+ bNode *node = NULL;
+
+ /* Get the node we're editing */
+ if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
+ bNodeTree *ntree = ptr->id.data;
+ bNodeSocket *sock = ptr->data;
+ if (nodeFindNode(ntree, sock, &node, NULL)) {
+ if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != NULL) {
+ /* we're good! */
+ }
+ else {
+ node = NULL;
+ }
+ }
+ }
+ else {
+ node = ptr->data;
+ }
+
+ /* Now filter by type */
+ if (node) {
+ CollectionPointerLink *link, *link_next;
+ lb = CTX_data_collection_get(C, "selected_nodes");
+
+ for (link = lb.first; link; link = link_next) {
+ bNode *node_data = link->ptr.data;
+ link_next = link->next;
+
+ if (node_data->type != node->type) {
+ BLI_remlink(&lb, link);
+ MEM_freeN(link);
+ }
+ }
+ }
+
+ *r_lb = lb;
+ *r_path = path;
+ }
+ else if (ptr->id.data) {
+ ID *id = ptr->id.data;
+
+ if (GS(id->name) == ID_OB) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_objects");
+ *r_use_path_from_id = true;
+ *r_path = RNA_path_from_ID_to_property(ptr, prop);
+ }
+ else if (OB_DATA_SUPPORT_ID(GS(id->name))) {
+ /* check we're using the active object */
+ const short id_code = GS(id->name);
+ ListBase lb = CTX_data_collection_get(C, "selected_editable_objects");
+ char *path = RNA_path_from_ID_to_property(ptr, prop);
+
+ /* de-duplicate obdata */
+ if (!BLI_listbase_is_empty(&lb)) {
+ CollectionPointerLink *link, *link_next;
+
+ for (link = lb.first; link; link = link->next) {
+ Object *ob = link->ptr.id.data;
+ if (ob->data) {
+ ID *id_data = ob->data;
+ id_data->tag |= LIB_TAG_DOIT;
+ }
+ }
+
+ for (link = lb.first; link; link = link_next) {
+ Object *ob = link->ptr.id.data;
+ ID *id_data = ob->data;
+ link_next = link->next;
+
+ if ((id_data == NULL) || (id_data->tag & LIB_TAG_DOIT) == 0 || ID_IS_LINKED(id_data) ||
+ (GS(id_data->name) != id_code)) {
+ BLI_remlink(&lb, link);
+ MEM_freeN(link);
+ }
+ else {
+ /* avoid prepending 'data' to the path */
+ RNA_id_pointer_create(id_data, &link->ptr);
+ }
+
+ if (id_data) {
+ id_data->tag &= ~LIB_TAG_DOIT;
+ }
+ }
+ }
+
+ *r_lb = lb;
+ *r_path = path;
+ }
+ else if (GS(id->name) == ID_SCE) {
+ /* Sequencer's ID is scene :/ */
+ /* Try to recursively find an RNA_Sequence ancestor,
+ * to handle situations like T41062... */
+ if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != NULL) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_sequences");
+ }
+ }
+ return (*r_path != NULL);
+ }
+ else {
+ return false;
+ }
+
+ return true;
}
/**
@@ -759,104 +776,103 @@ bool UI_context_copy_to_selected_list(
*/
static bool copy_to_selected_button(bContext *C, bool all, bool poll)
{
- Main *bmain = CTX_data_main(C);
- PointerRNA ptr, lptr, idptr;
- PropertyRNA *prop, *lprop;
- bool success = false;
- int index;
-
- /* try to reset the nominated setting to its default value */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- /* if there is a valid property that is editable... */
- if (ptr.data && prop) {
- char *path = NULL;
- bool use_path_from_id;
- CollectionPointerLink *link;
- ListBase lb = {NULL};
-
- if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
- !BLI_listbase_is_empty(&lb))
- {
- for (link = lb.first; link; link = link->next) {
- if (link->ptr.data != ptr.data) {
- if (use_path_from_id) {
- /* Path relative to ID. */
- lprop = NULL;
- RNA_id_pointer_create(link->ptr.id.data, &idptr);
- RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
- }
- else if (path) {
- /* Path relative to elements from list. */
- lprop = NULL;
- RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
- }
- else {
- lptr = link->ptr;
- lprop = prop;
- }
-
- if (lptr.data == ptr.data) {
- /* lptr might not be the same as link->ptr! */
- continue;
- }
-
- if (lprop == prop) {
- if (RNA_property_editable(&lptr, lprop)) {
- if (poll) {
- success = true;
- break;
- }
- else {
- if (RNA_property_copy(bmain, &lptr, &ptr, prop, (all) ? -1 : index)) {
- RNA_property_update(C, &lptr, prop);
- success = true;
- }
- }
- }
- }
- }
- }
- }
- MEM_SAFE_FREE(path);
- BLI_freelistN(&lb);
- }
-
- return success;
+ Main *bmain = CTX_data_main(C);
+ PointerRNA ptr, lptr, idptr;
+ PropertyRNA *prop, *lprop;
+ bool success = false;
+ int index;
+
+ /* try to reset the nominated setting to its default value */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop) {
+ char *path = NULL;
+ bool use_path_from_id;
+ CollectionPointerLink *link;
+ ListBase lb = {NULL};
+
+ if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
+ !BLI_listbase_is_empty(&lb)) {
+ for (link = lb.first; link; link = link->next) {
+ if (link->ptr.data != ptr.data) {
+ if (use_path_from_id) {
+ /* Path relative to ID. */
+ lprop = NULL;
+ RNA_id_pointer_create(link->ptr.id.data, &idptr);
+ RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
+ }
+ else if (path) {
+ /* Path relative to elements from list. */
+ lprop = NULL;
+ RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
+ }
+ else {
+ lptr = link->ptr;
+ lprop = prop;
+ }
+
+ if (lptr.data == ptr.data) {
+ /* lptr might not be the same as link->ptr! */
+ continue;
+ }
+
+ if (lprop == prop) {
+ if (RNA_property_editable(&lptr, lprop)) {
+ if (poll) {
+ success = true;
+ break;
+ }
+ else {
+ if (RNA_property_copy(bmain, &lptr, &ptr, prop, (all) ? -1 : index)) {
+ RNA_property_update(C, &lptr, prop);
+ success = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ MEM_SAFE_FREE(path);
+ BLI_freelistN(&lb);
+ }
+
+ return success;
}
static bool copy_to_selected_button_poll(bContext *C)
{
- return copy_to_selected_button(C, false, true);
+ return copy_to_selected_button(C, false, true);
}
static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
{
- bool success;
+ bool success;
- const bool all = RNA_boolean_get(op->ptr, "all");
+ const bool all = RNA_boolean_get(op->ptr, "all");
- success = copy_to_selected_button(C, all, false);
+ success = copy_to_selected_button(C, all, false);
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static void UI_OT_copy_to_selected_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy To Selected";
- ot->idname = "UI_OT_copy_to_selected_button";
- ot->description = "Copy property from this object to selected objects or bones";
+ /* identifiers */
+ ot->name = "Copy To Selected";
+ ot->idname = "UI_OT_copy_to_selected_button";
+ ot->description = "Copy property from this object to selected objects or bones";
- /* callbacks */
- ot->poll = copy_to_selected_button_poll;
- ot->exec = copy_to_selected_button_exec;
+ /* callbacks */
+ ot->poll = copy_to_selected_button_poll;
+ ot->exec = copy_to_selected_button_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_boolean(ot->srna, "all", true, "All", "Copy to selected all elements of the array");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", true, "All", "Copy to selected all elements of the array");
}
/** \} */
@@ -868,63 +884,61 @@ static void UI_OT_copy_to_selected_button(wmOperatorType *ot)
/** Jump to the object or bone referenced by the pointer, or check if it is possible. */
static bool jump_to_target_ptr(bContext *C, PointerRNA ptr, const bool poll)
{
- if (RNA_pointer_is_null(&ptr)) {
- return false;
- }
-
- /* Verify pointer type. */
- char bone_name[MAXBONENAME];
- const StructRNA *target_type = NULL;
-
- if (ELEM(ptr.type, &RNA_EditBone, &RNA_PoseBone, &RNA_Bone)) {
- RNA_string_get(&ptr, "name", bone_name);
- if (bone_name[0] != '\0') {
- target_type = &RNA_Bone;
- }
- }
- else if (RNA_struct_is_a(ptr.type, &RNA_Object)) {
- target_type = &RNA_Object;
- }
-
- if (target_type == NULL) {
- return false;
- }
-
- /* Find the containing Object. */
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base = NULL;
- const short id_type = GS(((ID *)ptr.id.data)->name);
- if (id_type == ID_OB) {
- base = BKE_view_layer_base_find(view_layer, ptr.id.data);
- }
- else if (OB_DATA_SUPPORT_ID(id_type)) {
- base = ED_object_find_first_by_data_id(view_layer, ptr.id.data);
- }
-
- bool ok = false;
- if ((base == NULL) ||
- ((target_type == &RNA_Bone) && (base->object->type != OB_ARMATURE)))
- {
- /* pass */
- }
- else if (poll) {
- ok = true;
- }
- else {
- /* Make optional. */
- const bool reveal_hidden = true;
- /* Select and activate the target. */
- if (target_type == &RNA_Bone) {
- ok = ED_object_jump_to_bone(C, base->object, bone_name, reveal_hidden);
- }
- else if (target_type == &RNA_Object) {
- ok = ED_object_jump_to_object(C, base->object, reveal_hidden);
- }
- else {
- BLI_assert(0);
- }
- }
- return ok;
+ if (RNA_pointer_is_null(&ptr)) {
+ return false;
+ }
+
+ /* Verify pointer type. */
+ char bone_name[MAXBONENAME];
+ const StructRNA *target_type = NULL;
+
+ if (ELEM(ptr.type, &RNA_EditBone, &RNA_PoseBone, &RNA_Bone)) {
+ RNA_string_get(&ptr, "name", bone_name);
+ if (bone_name[0] != '\0') {
+ target_type = &RNA_Bone;
+ }
+ }
+ else if (RNA_struct_is_a(ptr.type, &RNA_Object)) {
+ target_type = &RNA_Object;
+ }
+
+ if (target_type == NULL) {
+ return false;
+ }
+
+ /* Find the containing Object. */
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base = NULL;
+ const short id_type = GS(((ID *)ptr.id.data)->name);
+ if (id_type == ID_OB) {
+ base = BKE_view_layer_base_find(view_layer, ptr.id.data);
+ }
+ else if (OB_DATA_SUPPORT_ID(id_type)) {
+ base = ED_object_find_first_by_data_id(view_layer, ptr.id.data);
+ }
+
+ bool ok = false;
+ if ((base == NULL) || ((target_type == &RNA_Bone) && (base->object->type != OB_ARMATURE))) {
+ /* pass */
+ }
+ else if (poll) {
+ ok = true;
+ }
+ else {
+ /* Make optional. */
+ const bool reveal_hidden = true;
+ /* Select and activate the target. */
+ if (target_type == &RNA_Bone) {
+ ok = ED_object_jump_to_bone(C, base->object, bone_name, reveal_hidden);
+ }
+ else if (target_type == &RNA_Object) {
+ ok = ED_object_jump_to_object(C, base->object, reveal_hidden);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ return ok;
}
/**
@@ -936,73 +950,74 @@ static bool jump_to_target_ptr(bContext *C, PointerRNA ptr, const bool poll)
*/
static bool jump_to_target_button(bContext *C, bool poll)
{
- PointerRNA ptr, target_ptr;
- PropertyRNA *prop;
- int index;
+ PointerRNA ptr, target_ptr;
+ PropertyRNA *prop;
+ int index;
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- /* If there is a valid property... */
- if (ptr.data && prop) {
- const PropertyType type = RNA_property_type(prop);
+ /* If there is a valid property... */
+ if (ptr.data && prop) {
+ const PropertyType type = RNA_property_type(prop);
- /* For pointer properties, use their value directly. */
- if (type == PROP_POINTER) {
- target_ptr = RNA_property_pointer_get(&ptr, prop);
+ /* For pointer properties, use their value directly. */
+ if (type == PROP_POINTER) {
+ target_ptr = RNA_property_pointer_get(&ptr, prop);
- return jump_to_target_ptr(C, target_ptr, poll);
- }
- /* For string properties with prop_search, look up the search collection item. */
- else if (type == PROP_STRING) {
- const uiBut *but = UI_context_active_but_get(C);
+ return jump_to_target_ptr(C, target_ptr, poll);
+ }
+ /* For string properties with prop_search, look up the search collection item. */
+ else if (type == PROP_STRING) {
+ const uiBut *but = UI_context_active_but_get(C);
- if (but->type == UI_BTYPE_SEARCH_MENU && but->search_func == ui_rna_collection_search_cb) {
- uiRNACollectionSearch *coll_search = but->search_arg;
+ if (but->type == UI_BTYPE_SEARCH_MENU && but->search_func == ui_rna_collection_search_cb) {
+ uiRNACollectionSearch *coll_search = but->search_arg;
- char str_buf[MAXBONENAME];
- char *str_ptr = RNA_property_string_get_alloc(&ptr, prop, str_buf, sizeof(str_buf), NULL);
+ char str_buf[MAXBONENAME];
+ char *str_ptr = RNA_property_string_get_alloc(&ptr, prop, str_buf, sizeof(str_buf), NULL);
- int found = RNA_property_collection_lookup_string(&coll_search->search_ptr, coll_search->search_prop, str_ptr, &target_ptr);
+ int found = RNA_property_collection_lookup_string(
+ &coll_search->search_ptr, coll_search->search_prop, str_ptr, &target_ptr);
- if (str_ptr != str_buf) {
- MEM_freeN(str_ptr);
- }
+ if (str_ptr != str_buf) {
+ MEM_freeN(str_ptr);
+ }
- if (found) {
- return jump_to_target_ptr(C, target_ptr, poll);
- }
- }
- }
- }
+ if (found) {
+ return jump_to_target_ptr(C, target_ptr, poll);
+ }
+ }
+ }
+ }
- return false;
+ return false;
}
bool ui_jump_to_target_button_poll(bContext *C)
{
- return jump_to_target_button(C, true);
+ return jump_to_target_button(C, true);
}
static int jump_to_target_button_exec(bContext *C, wmOperator *UNUSED(op))
{
- bool success = jump_to_target_button(C, false);
+ bool success = jump_to_target_button(C, false);
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static void UI_OT_jump_to_target_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Jump To Target";
- ot->idname = "UI_OT_jump_to_target_button";
- ot->description = "Switch to the target object or bone";
+ /* identifiers */
+ ot->name = "Jump To Target";
+ ot->idname = "UI_OT_jump_to_target_button";
+ ot->description = "Switch to the target object or bone";
- /* callbacks */
- ot->poll = ui_jump_to_target_button_poll;
- ot->exec = jump_to_target_button_exec;
+ /* callbacks */
+ ot->poll = ui_jump_to_target_button_poll;
+ ot->exec = jump_to_target_button_exec;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
@@ -1017,47 +1032,47 @@ static void UI_OT_jump_to_target_button(wmOperatorType *ot)
static bool reports_to_text_poll(bContext *C)
{
- return CTX_wm_reports(C) != NULL;
+ return CTX_wm_reports(C) != NULL;
}
static int reports_to_text_exec(bContext *C, wmOperator *UNUSED(op))
{
- ReportList *reports = CTX_wm_reports(C);
- Main *bmain = CTX_data_main(C);
- Text *txt;
- char *str;
-
- /* create new text-block to write to */
- txt = BKE_text_add(bmain, "Recent Reports");
-
- /* convert entire list to a display string, and add this to the text-block
- * - if commandline debug option enabled, show debug reports too
- * - otherwise, up to info (which is what users normally see)
- */
- str = BKE_reports_string(reports, (G.debug & G_DEBUG) ? RPT_DEBUG : RPT_INFO);
-
- if (str) {
- TextUndoBuf *utxt = NULL; // FIXME
- BKE_text_write(txt, utxt, str);
- MEM_freeN(str);
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ ReportList *reports = CTX_wm_reports(C);
+ Main *bmain = CTX_data_main(C);
+ Text *txt;
+ char *str;
+
+ /* create new text-block to write to */
+ txt = BKE_text_add(bmain, "Recent Reports");
+
+ /* convert entire list to a display string, and add this to the text-block
+ * - if commandline debug option enabled, show debug reports too
+ * - otherwise, up to info (which is what users normally see)
+ */
+ str = BKE_reports_string(reports, (G.debug & G_DEBUG) ? RPT_DEBUG : RPT_INFO);
+
+ if (str) {
+ TextUndoBuf *utxt = NULL; // FIXME
+ BKE_text_write(txt, utxt, str);
+ MEM_freeN(str);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static void UI_OT_reports_to_textblock(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Reports to Text Block";
- ot->idname = "UI_OT_reports_to_textblock";
- ot->description = "Write the reports ";
-
- /* callbacks */
- ot->poll = reports_to_text_poll;
- ot->exec = reports_to_text_exec;
+ /* identifiers */
+ ot->name = "Reports to Text Block";
+ ot->idname = "UI_OT_reports_to_textblock";
+ ot->description = "Write the reports ";
+
+ /* callbacks */
+ ot->poll = reports_to_text_poll;
+ ot->exec = reports_to_text_exec;
}
/** \} */
@@ -1073,13 +1088,13 @@ static void UI_OT_reports_to_textblock(wmOperatorType *ot)
* note, this includes utility functions and button matching checks */
typedef struct uiEditSourceStore {
- uiBut but_orig;
- GHash *hash;
+ uiBut but_orig;
+ GHash *hash;
} uiEditSourceStore;
typedef struct uiEditSourceButStore {
- char py_dbg_fn[FILE_MAX];
- int py_dbg_ln;
+ char py_dbg_fn[FILE_MAX];
+ int py_dbg_ln;
} uiEditSourceButStore;
/* should only ever be set while the edit source operator is running */
@@ -1087,198 +1102,190 @@ static struct uiEditSourceStore *ui_editsource_info = NULL;
bool UI_editsource_enable_check(void)
{
- return (ui_editsource_info != NULL);
+ return (ui_editsource_info != NULL);
}
static void ui_editsource_active_but_set(uiBut *but)
{
- BLI_assert(ui_editsource_info == NULL);
+ BLI_assert(ui_editsource_info == NULL);
- ui_editsource_info = MEM_callocN(sizeof(uiEditSourceStore), __func__);
- memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut));
+ ui_editsource_info = MEM_callocN(sizeof(uiEditSourceStore), __func__);
+ memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut));
- ui_editsource_info->hash = BLI_ghash_ptr_new(__func__);
+ ui_editsource_info->hash = BLI_ghash_ptr_new(__func__);
}
static void ui_editsource_active_but_clear(void)
{
- BLI_ghash_free(ui_editsource_info->hash, NULL, MEM_freeN);
- MEM_freeN(ui_editsource_info);
- ui_editsource_info = NULL;
+ BLI_ghash_free(ui_editsource_info->hash, NULL, MEM_freeN);
+ MEM_freeN(ui_editsource_info);
+ ui_editsource_info = NULL;
}
static bool ui_editsource_uibut_match(uiBut *but_a, uiBut *but_b)
{
-#if 0
- printf("matching buttons: '%s' == '%s'\n",
- but_a->drawstr, but_b->drawstr);
-#endif
-
- /* this just needs to be a 'good-enough' comparison so we can know beyond
- * reasonable doubt that these buttons are the same between redraws.
- * if this fails it only means edit-source fails - campbell */
- if (BLI_rctf_compare(&but_a->rect, &but_b->rect, FLT_EPSILON) &&
- (but_a->type == but_b->type) &&
- (but_a->rnaprop == but_b->rnaprop) &&
- (but_a->optype == but_b->optype) &&
- (but_a->unit_type == but_b->unit_type) &&
- STREQLEN(but_a->drawstr, but_b->drawstr, UI_MAX_DRAW_STR))
- {
- return true;
- }
- else {
- return false;
- }
+# if 0
+ printf("matching buttons: '%s' == '%s'\n",
+ but_a->drawstr, but_b->drawstr);
+# endif
+
+ /* this just needs to be a 'good-enough' comparison so we can know beyond
+ * reasonable doubt that these buttons are the same between redraws.
+ * if this fails it only means edit-source fails - campbell */
+ if (BLI_rctf_compare(&but_a->rect, &but_b->rect, FLT_EPSILON) && (but_a->type == but_b->type) &&
+ (but_a->rnaprop == but_b->rnaprop) && (but_a->optype == but_b->optype) &&
+ (but_a->unit_type == but_b->unit_type) &&
+ STREQLEN(but_a->drawstr, but_b->drawstr, UI_MAX_DRAW_STR)) {
+ return true;
+ }
+ else {
+ return false;
+ }
}
void UI_editsource_active_but_test(uiBut *but)
{
- extern void PyC_FileAndNum_Safe(const char **filename, int *lineno);
+ extern void PyC_FileAndNum_Safe(const char **filename, int *lineno);
- struct uiEditSourceButStore *but_store = MEM_callocN(sizeof(uiEditSourceButStore), __func__);
+ struct uiEditSourceButStore *but_store = MEM_callocN(sizeof(uiEditSourceButStore), __func__);
- const char *fn;
- int lineno = -1;
+ const char *fn;
+ int lineno = -1;
-#if 0
- printf("comparing buttons: '%s' == '%s'\n",
- but->drawstr, ui_editsource_info->but_orig.drawstr);
-#endif
+# if 0
+ printf("comparing buttons: '%s' == '%s'\n",
+ but->drawstr, ui_editsource_info->but_orig.drawstr);
+# endif
- PyC_FileAndNum_Safe(&fn, &lineno);
+ PyC_FileAndNum_Safe(&fn, &lineno);
- if (lineno != -1) {
- BLI_strncpy(but_store->py_dbg_fn, fn,
- sizeof(but_store->py_dbg_fn));
- but_store->py_dbg_ln = lineno;
- }
- else {
- but_store->py_dbg_fn[0] = '\0';
- but_store->py_dbg_ln = -1;
- }
+ if (lineno != -1) {
+ BLI_strncpy(but_store->py_dbg_fn, fn, sizeof(but_store->py_dbg_fn));
+ but_store->py_dbg_ln = lineno;
+ }
+ else {
+ but_store->py_dbg_fn[0] = '\0';
+ but_store->py_dbg_ln = -1;
+ }
- BLI_ghash_insert(ui_editsource_info->hash, but, but_store);
+ BLI_ghash_insert(ui_editsource_info->hash, but, but_store);
}
-static int editsource_text_edit(
- bContext *C, wmOperator *op,
- const char filepath[FILE_MAX], const int line)
+static int editsource_text_edit(bContext *C,
+ wmOperator *op,
+ const char filepath[FILE_MAX],
+ const int line)
{
- struct Main *bmain = CTX_data_main(C);
- Text *text;
-
- /* Developers may wish to copy-paste to an external editor. */
- printf("%s:%d\n", filepath, line);
-
- for (text = bmain->texts.first; text; text = text->id.next) {
- if (text->name && BLI_path_cmp(text->name, filepath) == 0) {
- break;
- }
- }
-
- if (text == NULL) {
- text = BKE_text_load(bmain, filepath, BKE_main_blendfile_path(bmain));
- id_us_ensure_real(&text->id);
- }
-
- if (text == NULL) {
- BKE_reportf(op->reports, RPT_WARNING, "File '%s' cannot be opened", filepath);
- return OPERATOR_CANCELLED;
- }
- else {
- /* naughty!, find text area to set, not good behavior
- * but since this is a dev tool lets allow it - campbell */
- ScrArea *sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TEXT, 0);
- if (sa) {
- SpaceText *st = sa->spacedata.first;
- st->text = text;
- }
- else {
- BKE_reportf(op->reports, RPT_INFO, "See '%s' in the text editor", text->id.name + 2);
- }
-
- txt_move_toline(text, line - 1, false);
- WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
- }
-
- return OPERATOR_FINISHED;
+ struct Main *bmain = CTX_data_main(C);
+ Text *text;
+
+ /* Developers may wish to copy-paste to an external editor. */
+ printf("%s:%d\n", filepath, line);
+
+ for (text = bmain->texts.first; text; text = text->id.next) {
+ if (text->name && BLI_path_cmp(text->name, filepath) == 0) {
+ break;
+ }
+ }
+
+ if (text == NULL) {
+ text = BKE_text_load(bmain, filepath, BKE_main_blendfile_path(bmain));
+ id_us_ensure_real(&text->id);
+ }
+
+ if (text == NULL) {
+ BKE_reportf(op->reports, RPT_WARNING, "File '%s' cannot be opened", filepath);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ /* naughty!, find text area to set, not good behavior
+ * but since this is a dev tool lets allow it - campbell */
+ ScrArea *sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TEXT, 0);
+ if (sa) {
+ SpaceText *st = sa->spacedata.first;
+ st->text = text;
+ }
+ else {
+ BKE_reportf(op->reports, RPT_INFO, "See '%s' in the text editor", text->id.name + 2);
+ }
+
+ txt_move_toline(text, line - 1, false);
+ WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, text);
+ }
+
+ return OPERATOR_FINISHED;
}
static int editsource_exec(bContext *C, wmOperator *op)
{
- uiBut *but = UI_context_active_but_get(C);
-
- if (but) {
- GHashIterator ghi;
- struct uiEditSourceButStore *but_store = NULL;
-
- ARegion *ar = CTX_wm_region(C);
- int ret;
-
- /* needed else the active button does not get tested */
- UI_screen_free_active_but(C, CTX_wm_screen(C));
-
- // printf("%s: begin\n", __func__);
-
- /* take care not to return before calling ui_editsource_active_but_clear */
- ui_editsource_active_but_set(but);
-
- /* redraw and get active button python info */
- ED_region_do_layout(C, ar);
- ED_region_do_draw(C, ar);
- ar->do_draw = false;
-
- for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
- BLI_ghashIterator_done(&ghi) == false;
- BLI_ghashIterator_step(&ghi))
- {
- uiBut *but_key = BLI_ghashIterator_getKey(&ghi);
- if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) {
- but_store = BLI_ghashIterator_getValue(&ghi);
- break;
- }
-
- }
-
- if (but_store) {
- if (but_store->py_dbg_ln != -1) {
- ret = editsource_text_edit(
- C, op,
- but_store->py_dbg_fn,
- but_store->py_dbg_ln);
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Active button is not from a script, cannot edit source");
- ret = OPERATOR_CANCELLED;
- }
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Active button match cannot be found");
- ret = OPERATOR_CANCELLED;
- }
-
-
- ui_editsource_active_but_clear();
-
- // printf("%s: end\n", __func__);
-
- return ret;
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Active button not found");
- return OPERATOR_CANCELLED;
- }
+ uiBut *but = UI_context_active_but_get(C);
+
+ if (but) {
+ GHashIterator ghi;
+ struct uiEditSourceButStore *but_store = NULL;
+
+ ARegion *ar = CTX_wm_region(C);
+ int ret;
+
+ /* needed else the active button does not get tested */
+ UI_screen_free_active_but(C, CTX_wm_screen(C));
+
+ // printf("%s: begin\n", __func__);
+
+ /* take care not to return before calling ui_editsource_active_but_clear */
+ ui_editsource_active_but_set(but);
+
+ /* redraw and get active button python info */
+ ED_region_do_layout(C, ar);
+ ED_region_do_draw(C, ar);
+ ar->do_draw = false;
+
+ for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
+ BLI_ghashIterator_done(&ghi) == false;
+ BLI_ghashIterator_step(&ghi)) {
+ uiBut *but_key = BLI_ghashIterator_getKey(&ghi);
+ if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) {
+ but_store = BLI_ghashIterator_getValue(&ghi);
+ break;
+ }
+ }
+
+ if (but_store) {
+ if (but_store->py_dbg_ln != -1) {
+ ret = editsource_text_edit(C, op, but_store->py_dbg_fn, but_store->py_dbg_ln);
+ }
+ else {
+ BKE_report(
+ op->reports, RPT_ERROR, "Active button is not from a script, cannot edit source");
+ ret = OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Active button match cannot be found");
+ ret = OPERATOR_CANCELLED;
+ }
+
+ ui_editsource_active_but_clear();
+
+ // printf("%s: end\n", __func__);
+
+ return ret;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Active button not found");
+ return OPERATOR_CANCELLED;
+ }
}
static void UI_OT_editsource(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Edit Source";
- ot->idname = "UI_OT_editsource";
- ot->description = "Edit UI source code of the active button";
+ /* identifiers */
+ ot->name = "Edit Source";
+ ot->idname = "UI_OT_editsource";
+ ot->description = "Edit UI source code of the active button";
- /* callbacks */
- ot->exec = editsource_exec;
+ /* callbacks */
+ ot->exec = editsource_exec;
}
/** \} */
@@ -1292,165 +1299,180 @@ static void UI_OT_editsource(wmOperatorType *ot)
* \note: this includes utility functions and button matching checks.
* this only works in conjunction with a py operator!
*/
-static void edittranslation_find_po_file(const char *root, const char *uilng, char *path, const size_t maxlen)
+static void edittranslation_find_po_file(const char *root,
+ const char *uilng,
+ char *path,
+ const size_t maxlen)
{
- char tstr[32]; /* Should be more than enough! */
-
- /* First, full lang code. */
- BLI_snprintf(tstr, sizeof(tstr), "%s.po", uilng);
- BLI_join_dirfile(path, maxlen, root, uilng);
- BLI_path_append(path, maxlen, tstr);
- if (BLI_is_file(path)) {
- return;
- }
-
- /* Now try without the second iso code part (_ES in es_ES). */
- {
- const char *tc = NULL;
- size_t szt = 0;
- tstr[0] = '\0';
-
- tc = strchr(uilng, '_');
- if (tc) {
- szt = tc - uilng;
- if (szt < sizeof(tstr)) { /* Paranoid, should always be true! */
- BLI_strncpy(tstr, uilng, szt + 1); /* +1 for '\0' char! */
- }
- }
- if (tstr[0]) {
- /* Because of some codes like sr_SR@latin... */
- tc = strchr(uilng, '@');
- if (tc) {
- BLI_strncpy(tstr + szt, tc, sizeof(tstr) - szt);
- }
-
- BLI_join_dirfile(path, maxlen, root, tstr);
- strcat(tstr, ".po");
- BLI_path_append(path, maxlen, tstr);
- if (BLI_is_file(path)) {
- return;
- }
- }
- }
-
- /* Else no po file! */
- path[0] = '\0';
+ char tstr[32]; /* Should be more than enough! */
+
+ /* First, full lang code. */
+ BLI_snprintf(tstr, sizeof(tstr), "%s.po", uilng);
+ BLI_join_dirfile(path, maxlen, root, uilng);
+ BLI_path_append(path, maxlen, tstr);
+ if (BLI_is_file(path)) {
+ return;
+ }
+
+ /* Now try without the second iso code part (_ES in es_ES). */
+ {
+ const char *tc = NULL;
+ size_t szt = 0;
+ tstr[0] = '\0';
+
+ tc = strchr(uilng, '_');
+ if (tc) {
+ szt = tc - uilng;
+ if (szt < sizeof(tstr)) { /* Paranoid, should always be true! */
+ BLI_strncpy(tstr, uilng, szt + 1); /* +1 for '\0' char! */
+ }
+ }
+ if (tstr[0]) {
+ /* Because of some codes like sr_SR@latin... */
+ tc = strchr(uilng, '@');
+ if (tc) {
+ BLI_strncpy(tstr + szt, tc, sizeof(tstr) - szt);
+ }
+
+ BLI_join_dirfile(path, maxlen, root, tstr);
+ strcat(tstr, ".po");
+ BLI_path_append(path, maxlen, tstr);
+ if (BLI_is_file(path)) {
+ return;
+ }
+ }
+ }
+
+ /* Else no po file! */
+ path[0] = '\0';
}
static int edittranslation_exec(bContext *C, wmOperator *op)
{
- uiBut *but = UI_context_active_but_get(C);
- int ret = OPERATOR_CANCELLED;
-
- if (but) {
- wmOperatorType *ot;
- PointerRNA ptr;
- char popath[FILE_MAX];
- const char *root = U.i18ndir;
- const char *uilng = BLT_lang_get();
-
- uiStringInfo but_label = {BUT_GET_LABEL, NULL};
- uiStringInfo rna_label = {BUT_GET_RNA_LABEL, NULL};
- uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL};
- uiStringInfo but_tip = {BUT_GET_TIP, NULL};
- uiStringInfo rna_tip = {BUT_GET_RNA_TIP, NULL};
- uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL};
- uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL};
- uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL};
- uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, NULL};
- uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, NULL};
-
- if (!BLI_is_dir(root)) {
- BKE_report(
- op->reports, RPT_ERROR,
- "Please set your Preferences' 'Translation Branches "
- "Directory' path to a valid directory");
- return OPERATOR_CANCELLED;
- }
- ot = WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0);
- if (ot == NULL) {
- BKE_reportf(
- op->reports, RPT_ERROR,
- "Could not find operator '%s'! Please enable ui_translate add-on "
- "in the User Preferences", EDTSRC_I18N_OP_NAME);
- return OPERATOR_CANCELLED;
- }
- /* Try to find a valid po file for current language... */
- edittranslation_find_po_file(root, uilng, popath, FILE_MAX);
- /* printf("po path: %s\n", popath); */
- if (popath[0] == '\0') {
- BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root);
- return OPERATOR_CANCELLED;
- }
-
- UI_but_string_info_get(
- C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip,
- &rna_struct, &rna_prop, &rna_enum, &rna_ctxt, NULL);
-
- WM_operator_properties_create_ptr(&ptr, ot);
- RNA_string_set(&ptr, "lang", uilng);
- RNA_string_set(&ptr, "po_file", popath);
- RNA_string_set(&ptr, "but_label", but_label.strinfo);
- RNA_string_set(&ptr, "rna_label", rna_label.strinfo);
- RNA_string_set(&ptr, "enum_label", enum_label.strinfo);
- RNA_string_set(&ptr, "but_tip", but_tip.strinfo);
- RNA_string_set(&ptr, "rna_tip", rna_tip.strinfo);
- RNA_string_set(&ptr, "enum_tip", enum_tip.strinfo);
- RNA_string_set(&ptr, "rna_struct", rna_struct.strinfo);
- RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo);
- RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo);
- RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo);
- ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
-
- /* Clean up */
- if (but_label.strinfo) {
- MEM_freeN(but_label.strinfo);
- }
- if (rna_label.strinfo) {
- MEM_freeN(rna_label.strinfo);
- }
- if (enum_label.strinfo) {
- MEM_freeN(enum_label.strinfo);
- }
- if (but_tip.strinfo) {
- MEM_freeN(but_tip.strinfo);
- }
- if (rna_tip.strinfo) {
- MEM_freeN(rna_tip.strinfo);
- }
- if (enum_tip.strinfo) {
- MEM_freeN(enum_tip.strinfo);
- }
- if (rna_struct.strinfo) {
- MEM_freeN(rna_struct.strinfo);
- }
- if (rna_prop.strinfo) {
- MEM_freeN(rna_prop.strinfo);
- }
- if (rna_enum.strinfo) {
- MEM_freeN(rna_enum.strinfo);
- }
- if (rna_ctxt.strinfo) {
- MEM_freeN(rna_ctxt.strinfo);
- }
-
- return ret;
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Active button not found");
- return OPERATOR_CANCELLED;
- }
+ uiBut *but = UI_context_active_but_get(C);
+ int ret = OPERATOR_CANCELLED;
+
+ if (but) {
+ wmOperatorType *ot;
+ PointerRNA ptr;
+ char popath[FILE_MAX];
+ const char *root = U.i18ndir;
+ const char *uilng = BLT_lang_get();
+
+ uiStringInfo but_label = {BUT_GET_LABEL, NULL};
+ uiStringInfo rna_label = {BUT_GET_RNA_LABEL, NULL};
+ uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL};
+ uiStringInfo but_tip = {BUT_GET_TIP, NULL};
+ uiStringInfo rna_tip = {BUT_GET_RNA_TIP, NULL};
+ uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL};
+ uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL};
+ uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL};
+ uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, NULL};
+ uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, NULL};
+
+ if (!BLI_is_dir(root)) {
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "Please set your Preferences' 'Translation Branches "
+ "Directory' path to a valid directory");
+ return OPERATOR_CANCELLED;
+ }
+ ot = WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0);
+ if (ot == NULL) {
+ BKE_reportf(op->reports,
+ RPT_ERROR,
+ "Could not find operator '%s'! Please enable ui_translate add-on "
+ "in the User Preferences",
+ EDTSRC_I18N_OP_NAME);
+ return OPERATOR_CANCELLED;
+ }
+ /* Try to find a valid po file for current language... */
+ edittranslation_find_po_file(root, uilng, popath, FILE_MAX);
+ /* printf("po path: %s\n", popath); */
+ if (popath[0] == '\0') {
+ BKE_reportf(
+ op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root);
+ return OPERATOR_CANCELLED;
+ }
+
+ UI_but_string_info_get(C,
+ but,
+ &but_label,
+ &rna_label,
+ &enum_label,
+ &but_tip,
+ &rna_tip,
+ &enum_tip,
+ &rna_struct,
+ &rna_prop,
+ &rna_enum,
+ &rna_ctxt,
+ NULL);
+
+ WM_operator_properties_create_ptr(&ptr, ot);
+ RNA_string_set(&ptr, "lang", uilng);
+ RNA_string_set(&ptr, "po_file", popath);
+ RNA_string_set(&ptr, "but_label", but_label.strinfo);
+ RNA_string_set(&ptr, "rna_label", rna_label.strinfo);
+ RNA_string_set(&ptr, "enum_label", enum_label.strinfo);
+ RNA_string_set(&ptr, "but_tip", but_tip.strinfo);
+ RNA_string_set(&ptr, "rna_tip", rna_tip.strinfo);
+ RNA_string_set(&ptr, "enum_tip", enum_tip.strinfo);
+ RNA_string_set(&ptr, "rna_struct", rna_struct.strinfo);
+ RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo);
+ RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo);
+ RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo);
+ ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
+
+ /* Clean up */
+ if (but_label.strinfo) {
+ MEM_freeN(but_label.strinfo);
+ }
+ if (rna_label.strinfo) {
+ MEM_freeN(rna_label.strinfo);
+ }
+ if (enum_label.strinfo) {
+ MEM_freeN(enum_label.strinfo);
+ }
+ if (but_tip.strinfo) {
+ MEM_freeN(but_tip.strinfo);
+ }
+ if (rna_tip.strinfo) {
+ MEM_freeN(rna_tip.strinfo);
+ }
+ if (enum_tip.strinfo) {
+ MEM_freeN(enum_tip.strinfo);
+ }
+ if (rna_struct.strinfo) {
+ MEM_freeN(rna_struct.strinfo);
+ }
+ if (rna_prop.strinfo) {
+ MEM_freeN(rna_prop.strinfo);
+ }
+ if (rna_enum.strinfo) {
+ MEM_freeN(rna_enum.strinfo);
+ }
+ if (rna_ctxt.strinfo) {
+ MEM_freeN(rna_ctxt.strinfo);
+ }
+
+ return ret;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Active button not found");
+ return OPERATOR_CANCELLED;
+ }
}
static void UI_OT_edittranslation_init(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Edit Translation";
- ot->idname = "UI_OT_edittranslation_init";
- ot->description = "Edit i18n in current language for the active button";
+ /* identifiers */
+ ot->name = "Edit Translation";
+ ot->idname = "UI_OT_edittranslation_init";
+ ot->description = "Edit i18n in current language for the active button";
- /* callbacks */
- ot->exec = edittranslation_exec;
+ /* callbacks */
+ ot->exec = edittranslation_exec;
}
#endif /* WITH_PYTHON */
@@ -1463,22 +1485,22 @@ static void UI_OT_edittranslation_init(wmOperatorType *ot)
static int reloadtranslation_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
{
- BLT_lang_init();
- BLF_cache_clear();
- BLT_lang_set(NULL);
- UI_reinit_font();
- return OPERATOR_FINISHED;
+ BLT_lang_init();
+ BLF_cache_clear();
+ BLT_lang_set(NULL);
+ UI_reinit_font();
+ return OPERATOR_FINISHED;
}
static void UI_OT_reloadtranslation(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Reload Translation";
- ot->idname = "UI_OT_reloadtranslation";
- ot->description = "Force a full reload of UI translation";
+ /* identifiers */
+ ot->name = "Reload Translation";
+ ot->idname = "UI_OT_reloadtranslation";
+ ot->description = "Force a full reload of UI translation";
- /* callbacks */
- ot->exec = reloadtranslation_exec;
+ /* callbacks */
+ ot->exec = reloadtranslation_exec;
}
/** \} */
@@ -1489,61 +1511,61 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot)
static ARegion *region_event_inside_for_screen(bContext *C, const int xy[2])
{
- bScreen *sc = CTX_wm_screen(C);
- if (sc) {
- for (ARegion *ar = sc->regionbase.first; ar; ar = ar->next) {
- if (BLI_rcti_isect_pt_v(&ar->winrct, xy)) {
- return ar;
- }
- }
- }
- return NULL;
+ bScreen *sc = CTX_wm_screen(C);
+ if (sc) {
+ for (ARegion *ar = sc->regionbase.first; ar; ar = ar->next) {
+ if (BLI_rcti_isect_pt_v(&ar->winrct, xy)) {
+ return ar;
+ }
+ }
+ }
+ return NULL;
}
static int ui_button_press_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- const bool skip_depressed = RNA_boolean_get(op->ptr, "skip_depressed");
- ARegion *ar_prev = CTX_wm_region(C);
- ARegion *ar = region_event_inside_for_screen(C, &event->x);
+ const bool skip_depressed = RNA_boolean_get(op->ptr, "skip_depressed");
+ ARegion *ar_prev = CTX_wm_region(C);
+ ARegion *ar = region_event_inside_for_screen(C, &event->x);
- if (ar == NULL) {
- ar = ar_prev;
- }
+ if (ar == NULL) {
+ ar = ar_prev;
+ }
- CTX_wm_region_set(C, ar);
- uiBut *but = UI_context_active_but_get(C);
- CTX_wm_region_set(C, ar_prev);
+ CTX_wm_region_set(C, ar);
+ uiBut *but = UI_context_active_but_get(C);
+ CTX_wm_region_set(C, ar_prev);
- if (but == NULL) {
- return OPERATOR_PASS_THROUGH;
- }
- if (skip_depressed && (but->flag & (UI_SELECT | UI_SELECT_DRAW))) {
- return OPERATOR_PASS_THROUGH;
- }
+ if (but == NULL) {
+ return OPERATOR_PASS_THROUGH;
+ }
+ if (skip_depressed && (but->flag & (UI_SELECT | UI_SELECT_DRAW))) {
+ return OPERATOR_PASS_THROUGH;
+ }
- /* Weak, this is a workaround for 'UI_but_is_tool', which checks the operator type,
- * having this avoids a minor drawing glitch. */
- void *but_optype = but->optype;
+ /* Weak, this is a workaround for 'UI_but_is_tool', which checks the operator type,
+ * having this avoids a minor drawing glitch. */
+ void *but_optype = but->optype;
- UI_but_execute(C, but);
+ UI_but_execute(C, but);
- but->optype = but_optype;
+ but->optype = but_optype;
- WM_event_add_mousemove(C);
+ WM_event_add_mousemove(C);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void UI_OT_button_execute(wmOperatorType *ot)
{
- ot->name = "Press Button";
- ot->idname = "UI_OT_button_execute";
- ot->description = "Presses active button";
+ ot->name = "Press Button";
+ ot->idname = "UI_OT_button_execute";
+ ot->description = "Presses active button";
- ot->invoke = ui_button_press_invoke;
- ot->flag = OPTYPE_INTERNAL;
+ ot->invoke = ui_button_press_invoke;
+ ot->flag = OPTYPE_INTERNAL;
- RNA_def_boolean(ot->srna, "skip_depressed", 0, "Skip Depressed", "");
+ RNA_def_boolean(ot->srna, "skip_depressed", 0, "Skip Depressed", "");
}
/** \} */
@@ -1552,99 +1574,100 @@ static void UI_OT_button_execute(wmOperatorType *ot)
/** \name Drop Color Operator
* \{ */
-bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
+bool UI_drop_color_poll(struct bContext *C,
+ wmDrag *drag,
+ const wmEvent *UNUSED(event),
+ const char **UNUSED(tooltip))
{
- /* should only return true for regions that include buttons, for now
- * return true always */
- if (drag->type == WM_DRAG_COLOR) {
- SpaceImage *sima = CTX_wm_space_image(C);
- ARegion *ar = CTX_wm_region(C);
-
- if (UI_but_active_drop_color(C)) {
- return 1;
- }
-
- if (sima && (sima->mode == SI_MODE_PAINT) &&
- sima->image && (ar && ar->regiontype == RGN_TYPE_WINDOW))
- {
- return 1;
- }
- }
-
- return 0;
+ /* should only return true for regions that include buttons, for now
+ * return true always */
+ if (drag->type == WM_DRAG_COLOR) {
+ SpaceImage *sima = CTX_wm_space_image(C);
+ ARegion *ar = CTX_wm_region(C);
+
+ if (UI_but_active_drop_color(C)) {
+ return 1;
+ }
+
+ if (sima && (sima->mode == SI_MODE_PAINT) && sima->image &&
+ (ar && ar->regiontype == RGN_TYPE_WINDOW)) {
+ return 1;
+ }
+ }
+
+ return 0;
}
void UI_drop_color_copy(wmDrag *drag, wmDropBox *drop)
{
- uiDragColorHandle *drag_info = drag->poin;
+ uiDragColorHandle *drag_info = drag->poin;
- RNA_float_set_array(drop->ptr, "color", drag_info->color);
- RNA_boolean_set(drop->ptr, "gamma", drag_info->gamma_corrected);
+ RNA_float_set_array(drop->ptr, "color", drag_info->color);
+ RNA_boolean_set(drop->ptr, "gamma", drag_info->gamma_corrected);
}
static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- ARegion *ar = CTX_wm_region(C);
- uiBut *but = NULL;
- float color[4];
- bool gamma;
-
- RNA_float_get_array(op->ptr, "color", color);
- gamma = RNA_boolean_get(op->ptr, "gamma");
-
- /* find button under mouse, check if it has RNA color property and
- * if it does copy the data */
- but = ui_region_find_active_but(ar);
-
- if (but && but->type == UI_BTYPE_COLOR && but->rnaprop) {
- const int color_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
- BLI_assert(color_len <= 4);
-
- /* keep alpha channel as-is */
- if (color_len == 4) {
- color[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
- }
-
- if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- if (!gamma) {
- IMB_colormanagement_scene_linear_to_srgb_v3(color);
- }
- RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
- }
- else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
- if (gamma) {
- IMB_colormanagement_srgb_to_scene_linear_v3(color);
- }
- RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
- }
- }
- else {
- if (gamma) {
- srgb_to_linearrgb_v3_v3(color, color);
- }
-
- ED_imapaint_bucket_fill(C, color, op);
- }
-
- ED_region_tag_redraw(ar);
-
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ uiBut *but = NULL;
+ float color[4];
+ bool gamma;
+
+ RNA_float_get_array(op->ptr, "color", color);
+ gamma = RNA_boolean_get(op->ptr, "gamma");
+
+ /* find button under mouse, check if it has RNA color property and
+ * if it does copy the data */
+ but = ui_region_find_active_but(ar);
+
+ if (but && but->type == UI_BTYPE_COLOR && but->rnaprop) {
+ const int color_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
+ BLI_assert(color_len <= 4);
+
+ /* keep alpha channel as-is */
+ if (color_len == 4) {
+ color[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
+ }
+
+ if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ if (!gamma) {
+ IMB_colormanagement_scene_linear_to_srgb_v3(color);
+ }
+ RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ }
+ else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
+ if (gamma) {
+ IMB_colormanagement_srgb_to_scene_linear_v3(color);
+ }
+ RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
+ RNA_property_update(C, &but->rnapoin, but->rnaprop);
+ }
+ }
+ else {
+ if (gamma) {
+ srgb_to_linearrgb_v3_v3(color, color);
+ }
+
+ ED_imapaint_bucket_fill(C, color, op);
+ }
+
+ ED_region_tag_redraw(ar);
+
+ return OPERATOR_FINISHED;
}
-
static void UI_OT_drop_color(wmOperatorType *ot)
{
- ot->name = "Drop Color";
- ot->idname = "UI_OT_drop_color";
- ot->description = "Drop colors to buttons";
+ ot->name = "Drop Color";
+ ot->idname = "UI_OT_drop_color";
+ ot->description = "Drop colors to buttons";
- ot->invoke = drop_color_invoke;
- ot->flag = OPTYPE_INTERNAL;
+ ot->invoke = drop_color_invoke;
+ ot->flag = OPTYPE_INTERNAL;
- RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0);
- RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
+ RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0);
+ RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
}
/** \} */
@@ -1655,31 +1678,31 @@ static void UI_OT_drop_color(wmOperatorType *ot)
void ED_operatortypes_ui(void)
{
- WM_operatortype_append(UI_OT_copy_data_path_button);
- WM_operatortype_append(UI_OT_copy_python_command_button);
- WM_operatortype_append(UI_OT_reset_default_button);
- WM_operatortype_append(UI_OT_assign_default_button);
- WM_operatortype_append(UI_OT_unset_property_button);
- WM_operatortype_append(UI_OT_override_type_set_button);
- WM_operatortype_append(UI_OT_override_remove_button);
- WM_operatortype_append(UI_OT_copy_to_selected_button);
- WM_operatortype_append(UI_OT_jump_to_target_button);
- WM_operatortype_append(UI_OT_reports_to_textblock); /* XXX: temp? */
- WM_operatortype_append(UI_OT_drop_color);
+ WM_operatortype_append(UI_OT_copy_data_path_button);
+ WM_operatortype_append(UI_OT_copy_python_command_button);
+ WM_operatortype_append(UI_OT_reset_default_button);
+ WM_operatortype_append(UI_OT_assign_default_button);
+ WM_operatortype_append(UI_OT_unset_property_button);
+ WM_operatortype_append(UI_OT_override_type_set_button);
+ WM_operatortype_append(UI_OT_override_remove_button);
+ WM_operatortype_append(UI_OT_copy_to_selected_button);
+ WM_operatortype_append(UI_OT_jump_to_target_button);
+ WM_operatortype_append(UI_OT_reports_to_textblock); /* XXX: temp? */
+ WM_operatortype_append(UI_OT_drop_color);
#ifdef WITH_PYTHON
- WM_operatortype_append(UI_OT_editsource);
- WM_operatortype_append(UI_OT_edittranslation_init);
+ WM_operatortype_append(UI_OT_editsource);
+ WM_operatortype_append(UI_OT_edittranslation_init);
#endif
- WM_operatortype_append(UI_OT_reloadtranslation);
- WM_operatortype_append(UI_OT_button_execute);
-
- /* external */
- WM_operatortype_append(UI_OT_eyedropper_color);
- WM_operatortype_append(UI_OT_eyedropper_colorramp);
- WM_operatortype_append(UI_OT_eyedropper_colorramp_point);
- WM_operatortype_append(UI_OT_eyedropper_id);
- WM_operatortype_append(UI_OT_eyedropper_depth);
- WM_operatortype_append(UI_OT_eyedropper_driver);
+ WM_operatortype_append(UI_OT_reloadtranslation);
+ WM_operatortype_append(UI_OT_button_execute);
+
+ /* external */
+ WM_operatortype_append(UI_OT_eyedropper_color);
+ WM_operatortype_append(UI_OT_eyedropper_colorramp);
+ WM_operatortype_append(UI_OT_eyedropper_colorramp_point);
+ WM_operatortype_append(UI_OT_eyedropper_id);
+ WM_operatortype_append(UI_OT_eyedropper_depth);
+ WM_operatortype_append(UI_OT_eyedropper_driver);
}
/**
@@ -1687,10 +1710,10 @@ void ED_operatortypes_ui(void)
*/
void ED_keymap_ui(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "User Interface", 0, 0);
+ WM_keymap_ensure(keyconf, "User Interface", 0, 0);
- eyedropper_modal_keymap(keyconf);
- eyedropper_colorband_modal_keymap(keyconf);
+ eyedropper_modal_keymap(keyconf);
+ eyedropper_colorband_modal_keymap(keyconf);
}
/** \} */
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index b44b666a050..34e13f6620b 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
/* a full doc with API notes can be found in
* bf-blender/trunk/blender/doc/guides/interface_API.txt */
@@ -64,46 +63,46 @@
/*********************** defines and structs ************************/
-#define ANIMATION_TIME 0.30
-#define ANIMATION_INTERVAL 0.02
+#define ANIMATION_TIME 0.30
+#define ANIMATION_INTERVAL 0.02
-#define PNL_LAST_ADDED 1
-#define PNL_ACTIVE 2
-#define PNL_WAS_ACTIVE 4
-#define PNL_ANIM_ALIGN 8
-#define PNL_NEW_ADDED 16
-#define PNL_FIRST 32
+#define PNL_LAST_ADDED 1
+#define PNL_ACTIVE 2
+#define PNL_WAS_ACTIVE 4
+#define PNL_ANIM_ALIGN 8
+#define PNL_NEW_ADDED 16
+#define PNL_FIRST 32
/* only show pin header button for pinned panels */
#define USE_PIN_HIDDEN
/* the state of the mouse position relative to the panel */
typedef enum uiPanelMouseState {
- PANEL_MOUSE_OUTSIDE, /* mouse is not in the panel */
- PANEL_MOUSE_INSIDE_CONTENT, /* mouse is in the actual panel content */
- PANEL_MOUSE_INSIDE_HEADER, /* mouse is in the panel header */
- PANEL_MOUSE_INSIDE_SCALE, /* mouse is inside panel scale widget */
+ PANEL_MOUSE_OUTSIDE, /* mouse is not in the panel */
+ PANEL_MOUSE_INSIDE_CONTENT, /* mouse is in the actual panel content */
+ PANEL_MOUSE_INSIDE_HEADER, /* mouse is in the panel header */
+ PANEL_MOUSE_INSIDE_SCALE, /* mouse is inside panel scale widget */
} uiPanelMouseState;
typedef enum uiHandlePanelState {
- PANEL_STATE_DRAG,
- PANEL_STATE_DRAG_SCALE,
- PANEL_STATE_WAIT_UNTAB,
- PANEL_STATE_ANIMATION,
- PANEL_STATE_EXIT,
+ PANEL_STATE_DRAG,
+ PANEL_STATE_DRAG_SCALE,
+ PANEL_STATE_WAIT_UNTAB,
+ PANEL_STATE_ANIMATION,
+ PANEL_STATE_EXIT,
} uiHandlePanelState;
typedef struct uiHandlePanelData {
- uiHandlePanelState state;
+ uiHandlePanelState state;
- /* animation */
- wmTimer *animtimer;
- double starttime;
+ /* animation */
+ wmTimer *animtimer;
+ double starttime;
- /* dragging */
- int startx, starty;
- int startofsx, startofsy;
- int startsizex, startsizey;
+ /* dragging */
+ int startx, starty;
+ int startofsx, startofsy;
+ int startsizex, startsizey;
} uiHandlePanelData;
static int get_panel_real_size_y(const Panel *pa);
@@ -111,15 +110,15 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
static void panel_title_color_get(bool show_background, uchar color[4])
{
- if (show_background) {
- UI_GetThemeColor4ubv(TH_TITLE, color);
- }
- else {
- /* Use menu colors for floating panels. */
- bTheme *btheme = UI_GetTheme();
- const uiWidgetColors *wcol = &btheme->tui.wcol_menu_back;
- copy_v4_v4_uchar(color, (const uchar *)wcol->text);
- }
+ if (show_background) {
+ UI_GetThemeColor4ubv(TH_TITLE, color);
+ }
+ else {
+ /* Use menu colors for floating panels. */
+ bTheme *btheme = UI_GetTheme();
+ const uiWidgetColors *wcol = &btheme->tui.wcol_menu_back;
+ copy_v4_v4_uchar(color, (const uchar *)wcol->text);
+ }
}
/*********************** space specific code ************************/
@@ -127,141 +126,146 @@ static void panel_title_color_get(bool show_background, uchar color[4])
/* SpaceProperties.align */
typedef enum eSpaceButtons_Align {
- BUT_HORIZONTAL = 0,
- BUT_VERTICAL = 1,
- BUT_AUTO = 2,
+ BUT_HORIZONTAL = 0,
+ BUT_VERTICAL = 1,
+ BUT_AUTO = 2,
} eSpaceButtons_Align;
static int panel_aligned(ScrArea *sa, ARegion *ar)
{
- if (sa->spacetype == SPACE_PROPERTIES && ar->regiontype == RGN_TYPE_WINDOW) {
- return BUT_VERTICAL;
- }
- else if (sa->spacetype == SPACE_USERPREF && ar->regiontype == RGN_TYPE_WINDOW) {
- return BUT_VERTICAL;
- }
- else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS) {
- return BUT_VERTICAL;
- }
- else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW) {
- return BUT_VERTICAL;
- }
- else if (ELEM(ar->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS, RGN_TYPE_HUD, RGN_TYPE_NAV_BAR, RGN_TYPE_EXECUTE)) {
- return BUT_VERTICAL;
- }
-
- return 0;
+ if (sa->spacetype == SPACE_PROPERTIES && ar->regiontype == RGN_TYPE_WINDOW) {
+ return BUT_VERTICAL;
+ }
+ else if (sa->spacetype == SPACE_USERPREF && ar->regiontype == RGN_TYPE_WINDOW) {
+ return BUT_VERTICAL;
+ }
+ else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS) {
+ return BUT_VERTICAL;
+ }
+ else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW) {
+ return BUT_VERTICAL;
+ }
+ else if (ELEM(ar->regiontype,
+ RGN_TYPE_UI,
+ RGN_TYPE_TOOLS,
+ RGN_TYPE_TOOL_PROPS,
+ RGN_TYPE_HUD,
+ RGN_TYPE_NAV_BAR,
+ RGN_TYPE_EXECUTE)) {
+ return BUT_VERTICAL;
+ }
+
+ return 0;
}
static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, bool *no_animation)
{
- for (Panel *pa = lb->first; pa; pa = pa->next) {
- /* Detect panel active flag changes. */
- if (!(pa->type && pa->type->parent)) {
- if ((pa->runtime_flag & PNL_WAS_ACTIVE) && !(pa->runtime_flag & PNL_ACTIVE)) {
- return true;
- }
- if (!(pa->runtime_flag & PNL_WAS_ACTIVE) && (pa->runtime_flag & PNL_ACTIVE)) {
- return true;
- }
- }
-
- if ((pa->runtime_flag & PNL_ACTIVE) && !(pa->flag & PNL_CLOSED)) {
- if (panel_active_animation_changed(&pa->children, pa_animation, no_animation)) {
- return true;
- }
- }
-
- /* Detect animation. */
- if (pa->activedata) {
- uiHandlePanelData *data = pa->activedata;
- if (data->state == PANEL_STATE_ANIMATION) {
- *pa_animation = pa;
- }
- else {
- /* Don't animate while handling other interaction. */
- *no_animation = true;
- }
- }
- if ((pa->runtime_flag & PNL_ANIM_ALIGN) && !(*pa_animation)) {
- *pa_animation = pa;
- }
- }
-
- return false;
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
+ /* Detect panel active flag changes. */
+ if (!(pa->type && pa->type->parent)) {
+ if ((pa->runtime_flag & PNL_WAS_ACTIVE) && !(pa->runtime_flag & PNL_ACTIVE)) {
+ return true;
+ }
+ if (!(pa->runtime_flag & PNL_WAS_ACTIVE) && (pa->runtime_flag & PNL_ACTIVE)) {
+ return true;
+ }
+ }
+
+ if ((pa->runtime_flag & PNL_ACTIVE) && !(pa->flag & PNL_CLOSED)) {
+ if (panel_active_animation_changed(&pa->children, pa_animation, no_animation)) {
+ return true;
+ }
+ }
+
+ /* Detect animation. */
+ if (pa->activedata) {
+ uiHandlePanelData *data = pa->activedata;
+ if (data->state == PANEL_STATE_ANIMATION) {
+ *pa_animation = pa;
+ }
+ else {
+ /* Don't animate while handling other interaction. */
+ *no_animation = true;
+ }
+ }
+ if ((pa->runtime_flag & PNL_ANIM_ALIGN) && !(*pa_animation)) {
+ *pa_animation = pa;
+ }
+ }
+
+ return false;
}
static bool panels_need_realign(ScrArea *sa, ARegion *ar, Panel **r_pa_animate)
{
- *r_pa_animate = NULL;
-
- if (sa->spacetype == SPACE_PROPERTIES && ar->regiontype == RGN_TYPE_WINDOW) {
- SpaceProperties *sbuts = sa->spacedata.first;
-
- if (sbuts->mainbo != sbuts->mainb) {
- return true;
- }
- }
- else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW) {
- return true;
- }
- else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS) {
- return true;
- }
-
- /* Detect if a panel was added or removed. */
- Panel *pa_animation = NULL;
- bool no_animation = false;
- if (panel_active_animation_changed(&ar->panels, &pa_animation, &no_animation)) {
- return true;
- }
-
- /* Detect panel marked for animation, if we're not already animating. */
- if (pa_animation) {
- if (!no_animation) {
- *r_pa_animate = pa_animation;
- }
- return true;
- }
-
- return false;
+ *r_pa_animate = NULL;
+
+ if (sa->spacetype == SPACE_PROPERTIES && ar->regiontype == RGN_TYPE_WINDOW) {
+ SpaceProperties *sbuts = sa->spacedata.first;
+
+ if (sbuts->mainbo != sbuts->mainb) {
+ return true;
+ }
+ }
+ else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW) {
+ return true;
+ }
+ else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS) {
+ return true;
+ }
+
+ /* Detect if a panel was added or removed. */
+ Panel *pa_animation = NULL;
+ bool no_animation = false;
+ if (panel_active_animation_changed(&ar->panels, &pa_animation, &no_animation)) {
+ return true;
+ }
+
+ /* Detect panel marked for animation, if we're not already animating. */
+ if (pa_animation) {
+ if (!no_animation) {
+ *r_pa_animate = pa_animation;
+ }
+ return true;
+ }
+
+ return false;
}
/****************************** panels ******************************/
static void panels_collapse_all(ScrArea *sa, ARegion *ar, const Panel *from_pa)
{
- const bool has_category_tabs = UI_panel_category_is_visible(ar);
- const char *category = has_category_tabs ? UI_panel_category_active_get(ar, false) : NULL;
- const int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY);
- const PanelType *from_pt = from_pa->type;
- Panel *pa;
-
- for (pa = ar->panels.first; pa; pa = pa->next) {
- PanelType *pt = pa->type;
-
- /* close panels with headers in the same context */
- if (pt && from_pt && !(pt->flag & PNL_NO_HEADER)) {
- if (!pt->context[0] || !from_pt->context[0] || STREQ(pt->context, from_pt->context)) {
- if ((pa->flag & PNL_PIN) || !category || !pt->category[0] || STREQ(pt->category, category)) {
- pa->flag &= ~PNL_CLOSED;
- pa->flag |= flag;
- }
- }
- }
- }
+ const bool has_category_tabs = UI_panel_category_is_visible(ar);
+ const char *category = has_category_tabs ? UI_panel_category_active_get(ar, false) : NULL;
+ const int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY);
+ const PanelType *from_pt = from_pa->type;
+ Panel *pa;
+
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ PanelType *pt = pa->type;
+
+ /* close panels with headers in the same context */
+ if (pt && from_pt && !(pt->flag & PNL_NO_HEADER)) {
+ if (!pt->context[0] || !from_pt->context[0] || STREQ(pt->context, from_pt->context)) {
+ if ((pa->flag & PNL_PIN) || !category || !pt->category[0] ||
+ STREQ(pt->category, category)) {
+ pa->flag &= ~PNL_CLOSED;
+ pa->flag |= flag;
+ }
+ }
+ }
+ }
}
-
static void ui_panel_copy_offset(Panel *pa, Panel *papar)
{
- /* with respect to sizes... papar is parent */
+ /* with respect to sizes... papar is parent */
- pa->ofsx = papar->ofsx;
- pa->ofsy = papar->ofsy + papar->sizey - pa->sizey;
+ pa->ofsx = papar->ofsx;
+ pa->ofsy = papar->ofsy + papar->sizey - pa->sizey;
}
-
/**
* XXX Disabled paneltab handling for now. Old 2.4x feature, *DO NOT* confuse it with new tool tabs in 2.70. ;)
* See also T41704.
@@ -270,211 +274,212 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
Panel *UI_panel_find_by_type(ListBase *lb, PanelType *pt)
{
- Panel *pa;
- const char *idname = pt->idname;
+ Panel *pa;
+ const char *idname = pt->idname;
#ifdef UI_USE_PANELTAB
- const char *tabname = pt->idname;
- for (pa = lb->first; pa; pa = pa->next) {
- if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
- if (STREQLEN(pa->tabname, tabname, sizeof(pa->tabname))) {
- return pa;
- }
- }
- }
+ const char *tabname = pt->idname;
+ for (pa = lb->first; pa; pa = pa->next) {
+ if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
+ if (STREQLEN(pa->tabname, tabname, sizeof(pa->tabname))) {
+ return pa;
+ }
+ }
+ }
#else
- for (pa = lb->first; pa; pa = pa->next) {
- if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
- return pa;
- }
- }
+ for (pa = lb->first; pa; pa = pa->next) {
+ if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
+ return pa;
+ }
+ }
#endif
- return NULL;
+ return NULL;
}
/**
* \note \a pa should be return value from #UI_panel_find_by_type and can be NULL.
*/
-Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, ListBase *lb, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
+Panel *UI_panel_begin(
+ ScrArea *sa, ARegion *ar, ListBase *lb, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
{
- Panel *palast, *panext;
- const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
- const char *idname = pt->idname;
+ Panel *palast, *panext;
+ const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
+ const char *idname = pt->idname;
#ifdef UI_USE_PANELTAB
- const char *tabname = pt->idname;
- const char *hookname = NULL;
+ const char *tabname = pt->idname;
+ const char *hookname = NULL;
#endif
- const bool newpanel = (pa == NULL);
- int align = panel_aligned(sa, ar);
-
- if (!newpanel) {
- pa->type = pt;
- }
- else {
- /* new panel */
- pa = MEM_callocN(sizeof(Panel), "new panel");
- pa->type = pt;
- BLI_strncpy(pa->panelname, idname, sizeof(pa->panelname));
-
- if (pt->flag & PNL_DEFAULT_CLOSED) {
- if (align == BUT_VERTICAL) {
- pa->flag |= PNL_CLOSEDY;
- }
- else {
- pa->flag |= PNL_CLOSEDX;
- }
- }
-
- pa->ofsx = 0;
- pa->ofsy = 0;
- pa->sizex = 0;
- pa->sizey = 0;
- pa->blocksizex = 0;
- pa->blocksizey = 0;
- pa->runtime_flag |= PNL_NEW_ADDED;
-
- BLI_addtail(lb, pa);
+ const bool newpanel = (pa == NULL);
+ int align = panel_aligned(sa, ar);
+
+ if (!newpanel) {
+ pa->type = pt;
+ }
+ else {
+ /* new panel */
+ pa = MEM_callocN(sizeof(Panel), "new panel");
+ pa->type = pt;
+ BLI_strncpy(pa->panelname, idname, sizeof(pa->panelname));
+
+ if (pt->flag & PNL_DEFAULT_CLOSED) {
+ if (align == BUT_VERTICAL) {
+ pa->flag |= PNL_CLOSEDY;
+ }
+ else {
+ pa->flag |= PNL_CLOSEDX;
+ }
+ }
+
+ pa->ofsx = 0;
+ pa->ofsy = 0;
+ pa->sizex = 0;
+ pa->sizey = 0;
+ pa->blocksizex = 0;
+ pa->blocksizey = 0;
+ pa->runtime_flag |= PNL_NEW_ADDED;
+
+ BLI_addtail(lb, pa);
#ifdef UI_USE_PANELTAB
- BLI_strncpy(pa->tabname, tabname, sizeof(pa->tabname));
-
- /* make new Panel tabbed? */
- if (hookname) {
- Panel *patab;
- for (patab = lb->first; patab; patab = patab->next) {
- if ((patab->runtime_flag & PNL_ACTIVE) && patab->paneltab == NULL) {
- if (STREQLEN(hookname, patab->panelname, sizeof(patab->panelname))) {
- if (STREQLEN(tabname, patab->tabname, sizeof(patab->tabname))) {
- pa->paneltab = patab;
- ui_panel_copy_offset(pa, patab);
- break;
- }
- }
- }
- }
- }
+ BLI_strncpy(pa->tabname, tabname, sizeof(pa->tabname));
+
+ /* make new Panel tabbed? */
+ if (hookname) {
+ Panel *patab;
+ for (patab = lb->first; patab; patab = patab->next) {
+ if ((patab->runtime_flag & PNL_ACTIVE) && patab->paneltab == NULL) {
+ if (STREQLEN(hookname, patab->panelname, sizeof(patab->panelname))) {
+ if (STREQLEN(tabname, patab->tabname, sizeof(patab->tabname))) {
+ pa->paneltab = patab;
+ ui_panel_copy_offset(pa, patab);
+ break;
+ }
+ }
+ }
+ }
+ }
#else
- BLI_strncpy(pa->tabname, idname, sizeof(pa->tabname));
+ BLI_strncpy(pa->tabname, idname, sizeof(pa->tabname));
#endif
- }
-
- /* Do not allow closed panels without headers! Else user could get "disappeared" UI! */
- if ((pt->flag & PNL_NO_HEADER) && (pa->flag & PNL_CLOSED)) {
- pa->flag &= ~PNL_CLOSED;
- /* Force update of panels' positions! */
- pa->sizex = 0;
- pa->sizey = 0;
- pa->blocksizex = 0;
- pa->blocksizey = 0;
- }
-
- BLI_strncpy(pa->drawname, drawname, sizeof(pa->drawname));
-
- /* if a new panel is added, we insert it right after the panel
- * that was last added. this way new panels are inserted in the
- * right place between versions */
- for (palast = lb->first; palast; palast = palast->next) {
- if (palast->runtime_flag & PNL_LAST_ADDED) {
- BLI_remlink(lb, pa);
- BLI_insertlinkafter(lb, palast, pa);
- break;
- }
- }
-
- if (newpanel) {
- pa->sortorder = (palast) ? palast->sortorder + 1 : 0;
-
- for (panext = lb->first; panext; panext = panext->next) {
- if (panext != pa && panext->sortorder >= pa->sortorder) {
- panext->sortorder++;
- }
- }
- }
-
- if (palast) {
- palast->runtime_flag &= ~PNL_LAST_ADDED;
- }
-
- /* assign to block */
- block->panel = pa;
- pa->runtime_flag |= PNL_ACTIVE | PNL_LAST_ADDED;
- if (ar->alignment == RGN_ALIGN_FLOAT) {
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
- }
-
- *r_open = false;
-
- if (pa->paneltab) {
- return pa;
- }
- if (pa->flag & PNL_CLOSED) {
- return pa;
- }
-
- *r_open = true;
-
- return pa;
+ }
+
+ /* Do not allow closed panels without headers! Else user could get "disappeared" UI! */
+ if ((pt->flag & PNL_NO_HEADER) && (pa->flag & PNL_CLOSED)) {
+ pa->flag &= ~PNL_CLOSED;
+ /* Force update of panels' positions! */
+ pa->sizex = 0;
+ pa->sizey = 0;
+ pa->blocksizex = 0;
+ pa->blocksizey = 0;
+ }
+
+ BLI_strncpy(pa->drawname, drawname, sizeof(pa->drawname));
+
+ /* if a new panel is added, we insert it right after the panel
+ * that was last added. this way new panels are inserted in the
+ * right place between versions */
+ for (palast = lb->first; palast; palast = palast->next) {
+ if (palast->runtime_flag & PNL_LAST_ADDED) {
+ BLI_remlink(lb, pa);
+ BLI_insertlinkafter(lb, palast, pa);
+ break;
+ }
+ }
+
+ if (newpanel) {
+ pa->sortorder = (palast) ? palast->sortorder + 1 : 0;
+
+ for (panext = lb->first; panext; panext = panext->next) {
+ if (panext != pa && panext->sortorder >= pa->sortorder) {
+ panext->sortorder++;
+ }
+ }
+ }
+
+ if (palast) {
+ palast->runtime_flag &= ~PNL_LAST_ADDED;
+ }
+
+ /* assign to block */
+ block->panel = pa;
+ pa->runtime_flag |= PNL_ACTIVE | PNL_LAST_ADDED;
+ if (ar->alignment == RGN_ALIGN_FLOAT) {
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+ }
+
+ *r_open = false;
+
+ if (pa->paneltab) {
+ return pa;
+ }
+ if (pa->flag & PNL_CLOSED) {
+ return pa;
+ }
+
+ *r_open = true;
+
+ return pa;
}
void UI_panel_end(uiBlock *block, int width, int height)
{
- Panel *pa = block->panel;
-
- /* Set panel size excluding children. */
- pa->blocksizex = width;
- pa->blocksizey = height;
-
- /* Compute total panel size including children. */
- for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
- if (pachild->runtime_flag & PNL_ACTIVE) {
- width = max_ii(width, pachild->sizex);
- height += get_panel_real_size_y(pachild);
- }
- }
-
- /* Update total panel size. */
- if (pa->runtime_flag & PNL_NEW_ADDED) {
- pa->runtime_flag &= ~PNL_NEW_ADDED;
- pa->sizex = width;
- pa->sizey = height;
- }
- else {
- /* check if we need to do an animation */
- if (!ELEM(width, 0, pa->sizex) || !ELEM(height, 0, pa->sizey)) {
- pa->runtime_flag |= PNL_ANIM_ALIGN;
- if (height != 0) {
- pa->ofsy += pa->sizey - height;
- }
- }
-
- /* update width/height if non-zero */
- if (width != 0) {
- pa->sizex = width;
- }
- if (height != 0) {
- pa->sizey = height;
- }
- }
+ Panel *pa = block->panel;
+
+ /* Set panel size excluding children. */
+ pa->blocksizex = width;
+ pa->blocksizey = height;
+
+ /* Compute total panel size including children. */
+ for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
+ if (pachild->runtime_flag & PNL_ACTIVE) {
+ width = max_ii(width, pachild->sizex);
+ height += get_panel_real_size_y(pachild);
+ }
+ }
+
+ /* Update total panel size. */
+ if (pa->runtime_flag & PNL_NEW_ADDED) {
+ pa->runtime_flag &= ~PNL_NEW_ADDED;
+ pa->sizex = width;
+ pa->sizey = height;
+ }
+ else {
+ /* check if we need to do an animation */
+ if (!ELEM(width, 0, pa->sizex) || !ELEM(height, 0, pa->sizey)) {
+ pa->runtime_flag |= PNL_ANIM_ALIGN;
+ if (height != 0) {
+ pa->ofsy += pa->sizey - height;
+ }
+ }
+
+ /* update width/height if non-zero */
+ if (width != 0) {
+ pa->sizex = width;
+ }
+ if (height != 0) {
+ pa->sizey = height;
+ }
+ }
}
static void ui_offset_panel_block(uiBlock *block)
{
- uiStyle *style = UI_style_get_dpi();
+ uiStyle *style = UI_style_get_dpi();
- /* compute bounds and offset */
- ui_block_bounds_calc(block);
+ /* compute bounds and offset */
+ ui_block_bounds_calc(block);
- int ofsy = block->panel->sizey - style->panelspace;
+ int ofsy = block->panel->sizey - style->panelspace;
- for (uiBut *but = block->buttons.first; but; but = but->next) {
- but->rect.ymin += ofsy;
- but->rect.ymax += ofsy;
- }
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
+ but->rect.ymin += ofsy;
+ but->rect.ymax += ofsy;
+ }
- block->rect.xmax = block->panel->sizex;
- block->rect.ymax = block->panel->sizey;
- block->rect.xmin = block->rect.ymin = 0.0;
+ block->rect.xmax = block->panel->sizex;
+ block->rect.ymax = block->panel->sizey;
+ block->rect.xmin = block->rect.ymin = 0.0;
}
/**************************** drawing *******************************/
@@ -482,474 +487,479 @@ static void ui_offset_panel_block(uiBlock *block)
/* triangle 'icon' for panel header */
void UI_draw_icon_tri(float x, float y, char dir, const float color[4])
{
- float f3 = 0.05 * U.widget_unit;
- float f5 = 0.15 * U.widget_unit;
- float f7 = 0.25 * U.widget_unit;
-
- if (dir == 'h') {
- UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color);
- }
- else if (dir == 't') {
- UI_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3, color);
- }
- else { /* 'v' = vertical, down */
- UI_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7, color);
- }
+ float f3 = 0.05 * U.widget_unit;
+ float f5 = 0.15 * U.widget_unit;
+ float f7 = 0.25 * U.widget_unit;
+
+ if (dir == 'h') {
+ UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color);
+ }
+ else if (dir == 't') {
+ UI_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3, color);
+ }
+ else { /* 'v' = vertical, down */
+ UI_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7, color);
+ }
}
static void ui_draw_anti_x(uint pos, float x1, float y1, float x2, float y2)
{
- /* set antialias line */
- GPU_line_smooth(true);
- GPU_blend(true);
+ /* set antialias line */
+ GPU_line_smooth(true);
+ GPU_blend(true);
- GPU_line_width(2.0);
+ GPU_line_width(2.0);
- immBegin(GPU_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, x1, y1);
- immVertex2f(pos, x2, y2);
+ immVertex2f(pos, x1, y1);
+ immVertex2f(pos, x2, y2);
- immVertex2f(pos, x1, y2);
- immVertex2f(pos, x2, y1);
+ immVertex2f(pos, x1, y2);
+ immVertex2f(pos, x2, y1);
- immEnd();
-
- GPU_line_smooth(false);
- GPU_blend(false);
+ immEnd();
+ GPU_line_smooth(false);
+ GPU_blend(false);
}
/* x 'icon' for panel header */
static void ui_draw_x_icon(uint pos, float x, float y)
{
- ui_draw_anti_x(pos, x, y, x + 9.375f, y + 9.375f);
-
+ ui_draw_anti_x(pos, x, y, x + 9.375f, y + 9.375f);
}
-#define PNL_ICON UI_UNIT_X /* could be UI_UNIT_Y too */
+#define PNL_ICON UI_UNIT_X /* could be UI_UNIT_Y too */
static void ui_draw_panel_scalewidget(uint pos, const rcti *rect)
{
- float xmin, xmax, dx;
- float ymin, ymax, dy;
+ float xmin, xmax, dx;
+ float ymin, ymax, dy;
- xmin = rect->xmax - PNL_HEADER + 2;
- xmax = rect->xmax - 3;
- ymin = rect->ymin + 3;
- ymax = rect->ymin + PNL_HEADER - 2;
+ xmin = rect->xmax - PNL_HEADER + 2;
+ xmax = rect->xmax - 3;
+ ymin = rect->ymin + 3;
+ ymax = rect->ymin + PNL_HEADER - 2;
- dx = 0.5f * (xmax - xmin);
- dy = 0.5f * (ymax - ymin);
+ dx = 0.5f * (xmax - xmin);
+ dy = 0.5f * (ymax - ymin);
- GPU_blend(true);
- immUniformColor4ub(255, 255, 255, 50);
+ GPU_blend(true);
+ immUniformColor4ub(255, 255, 255, 50);
- immBegin(GPU_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, xmin, ymin);
- immVertex2f(pos, xmax, ymax);
+ immVertex2f(pos, xmin, ymin);
+ immVertex2f(pos, xmax, ymax);
- immVertex2f(pos, xmin + dx, ymin);
- immVertex2f(pos, xmax, ymax - dy);
+ immVertex2f(pos, xmin + dx, ymin);
+ immVertex2f(pos, xmax, ymax - dy);
- immEnd();
+ immEnd();
- immUniformColor4ub(0, 0, 0, 50);
+ immUniformColor4ub(0, 0, 0, 50);
- immBegin(GPU_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, xmin, ymin + 1);
- immVertex2f(pos, xmax, ymax + 1);
+ immVertex2f(pos, xmin, ymin + 1);
+ immVertex2f(pos, xmax, ymax + 1);
- immVertex2f(pos, xmin + dx, ymin + 1);
- immVertex2f(pos, xmax, ymax - dy + 1);
+ immVertex2f(pos, xmin + dx, ymin + 1);
+ immVertex2f(pos, xmax, ymax - dy + 1);
- immEnd();
+ immEnd();
- GPU_blend(false);
+ GPU_blend(false);
}
static void immRectf_tris_color_ex(
- uint pos, float x1, float y1, float x2, float y2,
- uint col, const float color[3])
+ uint pos, float x1, float y1, float x2, float y2, uint col, const float color[3])
{
- immAttr4fv(col, color);
- immVertex2f(pos, x1, y1);
- immAttr4fv(col, color);
- immVertex2f(pos, x2, y1);
- immAttr4fv(col, color);
- immVertex2f(pos, x2, y2);
-
- immAttr4fv(col, color);
- immVertex2f(pos, x1, y1);
- immAttr4fv(col, color);
- immVertex2f(pos, x2, y2);
- immAttr4fv(col, color);
- immVertex2f(pos, x1, y2);
+ immAttr4fv(col, color);
+ immVertex2f(pos, x1, y1);
+ immAttr4fv(col, color);
+ immVertex2f(pos, x2, y1);
+ immAttr4fv(col, color);
+ immVertex2f(pos, x2, y2);
+
+ immAttr4fv(col, color);
+ immVertex2f(pos, x1, y1);
+ immAttr4fv(col, color);
+ immVertex2f(pos, x2, y2);
+ immAttr4fv(col, color);
+ immVertex2f(pos, x1, y2);
}
static void ui_draw_panel_dragwidget(uint pos, uint col, const rctf *rect)
{
- float col_high[4], col_dark[4];
- const int col_tint = 84;
-
- const int px = (int)U.pixelsize;
- const int px_zoom = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 22.0f), 1);
-
- const int box_margin = max_ii(round_fl_to_int((float)(px_zoom * 2.0f)), px);
- const int box_size = max_ii(round_fl_to_int((BLI_rctf_size_y(rect) / 8.0f) - px), px);
-
- const int x_min = rect->xmin;
- const int y_min = rect->ymin;
- const int y_ofs = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 2.5f), px);
- const int x_ofs = y_ofs;
- int i_x, i_y;
-
- UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, col_high);
- UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark);
-
- /* draw multiple boxes */
- immBegin(GPU_PRIM_TRIS, 4 * 2 * (6 * 2));
- for (i_x = 0; i_x < 4; i_x++) {
- for (i_y = 0; i_y < 2; i_y++) {
- const int x_co = (x_min + x_ofs) + (i_x * (box_size + box_margin));
- const int y_co = (y_min + y_ofs) + (i_y * (box_size + box_margin));
-
- immRectf_tris_color_ex(
- pos, x_co - box_size, y_co - px_zoom, x_co, (y_co + box_size) - px_zoom,
- col, col_dark);
- immRectf_tris_color_ex(
- pos, x_co - box_size, y_co, x_co, y_co + box_size,
- col, col_high);
- }
- }
- immEnd();
+ float col_high[4], col_dark[4];
+ const int col_tint = 84;
+
+ const int px = (int)U.pixelsize;
+ const int px_zoom = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 22.0f), 1);
+
+ const int box_margin = max_ii(round_fl_to_int((float)(px_zoom * 2.0f)), px);
+ const int box_size = max_ii(round_fl_to_int((BLI_rctf_size_y(rect) / 8.0f) - px), px);
+
+ const int x_min = rect->xmin;
+ const int y_min = rect->ymin;
+ const int y_ofs = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 2.5f), px);
+ const int x_ofs = y_ofs;
+ int i_x, i_y;
+
+ UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, col_high);
+ UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark);
+
+ /* draw multiple boxes */
+ immBegin(GPU_PRIM_TRIS, 4 * 2 * (6 * 2));
+ for (i_x = 0; i_x < 4; i_x++) {
+ for (i_y = 0; i_y < 2; i_y++) {
+ const int x_co = (x_min + x_ofs) + (i_x * (box_size + box_margin));
+ const int y_co = (y_min + y_ofs) + (i_y * (box_size + box_margin));
+
+ immRectf_tris_color_ex(
+ pos, x_co - box_size, y_co - px_zoom, x_co, (y_co + box_size) - px_zoom, col, col_dark);
+ immRectf_tris_color_ex(pos, x_co - box_size, y_co, x_co, y_co + box_size, col, col_high);
+ }
+ }
+ immEnd();
}
/* For button layout next to label. */
void UI_panel_label_offset(uiBlock *block, int *r_x, int *r_y)
{
- Panel *panel = block->panel;
- const bool is_subpanel = (panel->type && panel->type->parent);
+ Panel *panel = block->panel;
+ const bool is_subpanel = (panel->type && panel->type->parent);
- *r_x = UI_UNIT_X * 1.0f;
- *r_y = UI_UNIT_Y * 1.5f;
+ *r_x = UI_UNIT_X * 1.0f;
+ *r_y = UI_UNIT_Y * 1.5f;
- if (is_subpanel) {
- *r_x += (0.7f * UI_UNIT_X);
- }
+ if (is_subpanel) {
+ *r_x += (0.7f * UI_UNIT_X);
+ }
}
static void ui_draw_aligned_panel_header(
- uiStyle *style, uiBlock *block, const rcti *rect, char dir,
- const bool show_background)
+ uiStyle *style, uiBlock *block, const rcti *rect, char dir, const bool show_background)
{
- Panel *panel = block->panel;
- rcti hrect;
- int pnl_icons;
- const char *activename = panel->drawname[0] ? panel->drawname : panel->panelname;
- const bool is_subpanel = (panel->type && panel->type->parent);
- uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle;
- uchar col_title[4];
-
- /* + 0.001f to avoid flirting with float inaccuracy */
- if (panel->control & UI_PNL_CLOSE) {
- pnl_icons = (panel->labelofs + (2.0f * PNL_ICON)) / block->aspect + 0.001f;
- }
- else {
- pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f;
- }
-
- /* draw text label */
- panel_title_color_get(show_background, col_title);
- col_title[3] = 255;
-
- hrect = *rect;
- if (dir == 'h') {
- hrect.xmin = rect->xmin + pnl_icons;
- hrect.ymin -= 2.0f / block->aspect;
- UI_fontstyle_draw(
- fontstyle, &hrect, activename, col_title,
- &(struct uiFontStyleDraw_Params) { .align = UI_STYLE_TEXT_LEFT, });
- }
- else {
- /* ignore 'pnl_icons', otherwise the text gets offset horizontally
- * + 0.001f to avoid flirting with float inaccuracy
- */
- hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f;
- UI_fontstyle_draw_rotated(fontstyle, &hrect, activename, col_title);
- }
+ Panel *panel = block->panel;
+ rcti hrect;
+ int pnl_icons;
+ const char *activename = panel->drawname[0] ? panel->drawname : panel->panelname;
+ const bool is_subpanel = (panel->type && panel->type->parent);
+ uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle;
+ uchar col_title[4];
+
+ /* + 0.001f to avoid flirting with float inaccuracy */
+ if (panel->control & UI_PNL_CLOSE) {
+ pnl_icons = (panel->labelofs + (2.0f * PNL_ICON)) / block->aspect + 0.001f;
+ }
+ else {
+ pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f;
+ }
+
+ /* draw text label */
+ panel_title_color_get(show_background, col_title);
+ col_title[3] = 255;
+
+ hrect = *rect;
+ if (dir == 'h') {
+ hrect.xmin = rect->xmin + pnl_icons;
+ hrect.ymin -= 2.0f / block->aspect;
+ UI_fontstyle_draw(fontstyle,
+ &hrect,
+ activename,
+ col_title,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_LEFT,
+ });
+ }
+ else {
+ /* ignore 'pnl_icons', otherwise the text gets offset horizontally
+ * + 0.001f to avoid flirting with float inaccuracy
+ */
+ hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f;
+ UI_fontstyle_draw_rotated(fontstyle, &hrect, activename, col_title);
+ }
}
/* panel integrated in buttonswindow, tool/property lists etc */
-void ui_draw_aligned_panel(
- uiStyle *style, uiBlock *block, const rcti *rect,
- const bool show_pin, const bool show_background)
+void ui_draw_aligned_panel(uiStyle *style,
+ uiBlock *block,
+ const rcti *rect,
+ const bool show_pin,
+ const bool show_background)
{
- Panel *panel = block->panel;
- rcti headrect;
- rctf itemrect;
- float color[4];
- const bool is_closed_x = (panel->flag & PNL_CLOSEDX) ? true : false;
- const bool is_closed_y = (panel->flag & PNL_CLOSEDY) ? true : false;
- const bool is_subpanel = (panel->type && panel->type->parent);
- const bool show_drag = (
- !is_subpanel &&
- /* FIXME(campbell): currently no background means floating panel which can't be dragged.
- * This may be changed in future. */
- show_background);
+ Panel *panel = block->panel;
+ rcti headrect;
+ rctf itemrect;
+ float color[4];
+ const bool is_closed_x = (panel->flag & PNL_CLOSEDX) ? true : false;
+ const bool is_closed_y = (panel->flag & PNL_CLOSEDY) ? true : false;
+ const bool is_subpanel = (panel->type && panel->type->parent);
+ const bool show_drag =
+ (!is_subpanel &&
+ /* FIXME(campbell): currently no background means floating panel which can't be dragged.
+ * This may be changed in future. */
+ show_background);
- if (panel->paneltab) {
- return;
- }
- if (panel->type && (panel->type->flag & PNL_NO_HEADER)) {
- return;
- }
+ if (panel->paneltab) {
+ return;
+ }
+ if (panel->type && (panel->type->flag & PNL_NO_HEADER)) {
+ return;
+ }
- /* calculate header rect */
- /* + 0.001f to prevent flicker due to float inaccuracy */
- headrect = *rect;
- headrect.ymin = headrect.ymax;
- headrect.ymax = headrect.ymin + floor(PNL_HEADER / block->aspect + 0.001f);
+ /* calculate header rect */
+ /* + 0.001f to prevent flicker due to float inaccuracy */
+ headrect = *rect;
+ headrect.ymin = headrect.ymax;
+ headrect.ymax = headrect.ymin + floor(PNL_HEADER / block->aspect + 0.001f);
- rcti titlerect = headrect;
- if (is_subpanel) {
- titlerect.xmin += (0.7f * UI_UNIT_X);
- }
+ rcti titlerect = headrect;
+ if (is_subpanel) {
+ titlerect.xmin += (0.7f * UI_UNIT_X);
+ }
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- if (show_background && !is_subpanel) {
- float minx = rect->xmin;
- float maxx = is_closed_x ? (minx + PNL_HEADER / block->aspect) : rect->xmax;
- float y = headrect.ymax;
+ if (show_background && !is_subpanel) {
+ float minx = rect->xmin;
+ float maxx = is_closed_x ? (minx + PNL_HEADER / block->aspect) : rect->xmax;
+ float y = headrect.ymax;
- GPU_blend(true);
+ GPU_blend(true);
- /* draw with background color */
- immUniformThemeColor(TH_PANEL_HEADER);
- immRectf(pos, minx, headrect.ymin, maxx, y);
+ /* draw with background color */
+ immUniformThemeColor(TH_PANEL_HEADER);
+ immRectf(pos, minx, headrect.ymin, maxx, y);
- immBegin(GPU_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, minx, y);
- immVertex2f(pos, maxx, y);
+ immVertex2f(pos, minx, y);
+ immVertex2f(pos, maxx, y);
- immVertex2f(pos, minx, y);
- immVertex2f(pos, maxx, y);
+ immVertex2f(pos, minx, y);
+ immVertex2f(pos, maxx, y);
- immEnd();
+ immEnd();
- GPU_blend(false);
- }
+ GPU_blend(false);
+ }
- immUnbindProgram();
+ immUnbindProgram();
- /* draw optional pin icon */
+ /* draw optional pin icon */
#ifdef USE_PIN_HIDDEN
- if (show_pin && (block->panel->flag & PNL_PIN))
+ if (show_pin && (block->panel->flag & PNL_PIN))
#else
- if (show_pin)
+ if (show_pin)
#endif
- {
- uchar col_title[4];
- panel_title_color_get(show_background, col_title);
-
- GPU_blend(true);
- UI_icon_draw_aspect(
- headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect), headrect.ymin + (5.0f / block->aspect),
- (panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED,
- (block->aspect / UI_DPI_FAC), 1.0f, (const char *)col_title);
- GPU_blend(false);
- }
-
-
- /* horizontal title */
- if (is_closed_x == false) {
- ui_draw_aligned_panel_header(style, block, &titlerect, 'h', show_background);
-
- if (show_drag) {
- uint col;
- GPUVertFormat *format = immVertexFormat();
- pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
- /* itemrect smaller */
- itemrect.xmax = headrect.xmax - (0.2f * UI_UNIT_X);
- itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
- itemrect.ymin = headrect.ymin;
- itemrect.ymax = headrect.ymax;
-
- BLI_rctf_scale(&itemrect, 0.7f);
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- ui_draw_panel_dragwidget(pos, col, &itemrect);
- immUnbindProgram();
-
- /* Restore format for the following draws. */
- pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- }
- }
-
- /* if the panel is minimized vertically:
- * (------)
- */
- if (is_closed_y) {
- /* skip */
- }
- else if (is_closed_x) {
- /* draw vertical title */
- ui_draw_aligned_panel_header(style, block, &headrect, 'v', show_background);
- pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- }
- /* an open panel */
- else {
- /* in some occasions, draw a border */
- if (panel->flag & PNL_SELECT) {
- if (panel->control & UI_PNL_SOLID) {
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- }
- else {
- UI_draw_roundbox_corner_set(UI_CNR_NONE);
- }
-
- UI_GetThemeColorShade4fv(TH_BACK, -120, color);
- UI_draw_roundbox_aa(false, 0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax + 1, 8, color);
- }
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- GPU_blend(true);
-
- if (show_background) {
- /* panel backdrop */
- int panel_col = is_subpanel ? TH_PANEL_SUB_BACK : TH_PANEL_BACK;
-
- immUniformThemeColor(panel_col);
- immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- }
-
- if (panel->control & UI_PNL_SCALE) {
- ui_draw_panel_scalewidget(pos, rect);
- }
-
- immUnbindProgram();
- }
-
-
- uchar col_title[4];
- panel_title_color_get(show_background, col_title);
-
- /* draw optional close icon */
-
- if (panel->control & UI_PNL_CLOSE) {
- const int ofsx = 6;
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3ubv(col_title);
- ui_draw_x_icon(pos, rect->xmin + 2 + ofsx, rect->ymax + 2);
- immUnbindProgram();
- }
-
- /* draw collapse icon */
-
- /* itemrect smaller */
- itemrect.xmin = titlerect.xmin;
- itemrect.xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect);
- itemrect.ymin = titlerect.ymin;
- itemrect.ymax = titlerect.ymax;
-
- BLI_rctf_scale(&itemrect, 0.25f);
-
- {
- float tria_color[4];
- rgb_uchar_to_float(tria_color, col_title);
- tria_color[3] = 1.0f;
-
- if (is_closed_y) {
- ui_draw_anti_tria_rect(&itemrect, 'h', tria_color);
- }
- else if (is_closed_x) {
- ui_draw_anti_tria_rect(&itemrect, 'h', tria_color);
- }
- else {
- ui_draw_anti_tria_rect(&itemrect, 'v', tria_color);
- }
- }
+ {
+ uchar col_title[4];
+ panel_title_color_get(show_background, col_title);
+
+ GPU_blend(true);
+ UI_icon_draw_aspect(headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect),
+ headrect.ymin + (5.0f / block->aspect),
+ (panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED,
+ (block->aspect / UI_DPI_FAC),
+ 1.0f,
+ (const char *)col_title);
+ GPU_blend(false);
+ }
+
+ /* horizontal title */
+ if (is_closed_x == false) {
+ ui_draw_aligned_panel_header(style, block, &titlerect, 'h', show_background);
+
+ if (show_drag) {
+ uint col;
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+ /* itemrect smaller */
+ itemrect.xmax = headrect.xmax - (0.2f * UI_UNIT_X);
+ itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
+ itemrect.ymin = headrect.ymin;
+ itemrect.ymax = headrect.ymax;
+
+ BLI_rctf_scale(&itemrect, 0.7f);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ ui_draw_panel_dragwidget(pos, col, &itemrect);
+ immUnbindProgram();
+
+ /* Restore format for the following draws. */
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ }
+ }
+
+ /* if the panel is minimized vertically:
+ * (------)
+ */
+ if (is_closed_y) {
+ /* skip */
+ }
+ else if (is_closed_x) {
+ /* draw vertical title */
+ ui_draw_aligned_panel_header(style, block, &headrect, 'v', show_background);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ }
+ /* an open panel */
+ else {
+ /* in some occasions, draw a border */
+ if (panel->flag & PNL_SELECT) {
+ if (panel->control & UI_PNL_SOLID) {
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ }
+ else {
+ UI_draw_roundbox_corner_set(UI_CNR_NONE);
+ }
+
+ UI_GetThemeColorShade4fv(TH_BACK, -120, color);
+ UI_draw_roundbox_aa(false,
+ 0.5f + rect->xmin,
+ 0.5f + rect->ymin,
+ 0.5f + rect->xmax,
+ 0.5f + headrect.ymax + 1,
+ 8,
+ color);
+ }
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ GPU_blend(true);
+
+ if (show_background) {
+ /* panel backdrop */
+ int panel_col = is_subpanel ? TH_PANEL_SUB_BACK : TH_PANEL_BACK;
+
+ immUniformThemeColor(panel_col);
+ immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ }
+
+ if (panel->control & UI_PNL_SCALE) {
+ ui_draw_panel_scalewidget(pos, rect);
+ }
+
+ immUnbindProgram();
+ }
+
+ uchar col_title[4];
+ panel_title_color_get(show_background, col_title);
+
+ /* draw optional close icon */
+
+ if (panel->control & UI_PNL_CLOSE) {
+ const int ofsx = 6;
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ubv(col_title);
+ ui_draw_x_icon(pos, rect->xmin + 2 + ofsx, rect->ymax + 2);
+ immUnbindProgram();
+ }
+
+ /* draw collapse icon */
+
+ /* itemrect smaller */
+ itemrect.xmin = titlerect.xmin;
+ itemrect.xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect);
+ itemrect.ymin = titlerect.ymin;
+ itemrect.ymax = titlerect.ymax;
+
+ BLI_rctf_scale(&itemrect, 0.25f);
+
+ {
+ float tria_color[4];
+ rgb_uchar_to_float(tria_color, col_title);
+ tria_color[3] = 1.0f;
+
+ if (is_closed_y) {
+ ui_draw_anti_tria_rect(&itemrect, 'h', tria_color);
+ }
+ else if (is_closed_x) {
+ ui_draw_anti_tria_rect(&itemrect, 'h', tria_color);
+ }
+ else {
+ ui_draw_anti_tria_rect(&itemrect, 'v', tria_color);
+ }
+ }
}
/************************** panel alignment *************************/
static int get_panel_header(const Panel *pa)
{
- if (pa->type && (pa->type->flag & PNL_NO_HEADER)) {
- return 0;
- }
+ if (pa->type && (pa->type->flag & PNL_NO_HEADER)) {
+ return 0;
+ }
- return PNL_HEADER;
+ return PNL_HEADER;
}
static int get_panel_size_y(const Panel *pa)
{
- if (pa->type && (pa->type->flag & PNL_NO_HEADER)) {
- return pa->sizey;
- }
+ if (pa->type && (pa->type->flag & PNL_NO_HEADER)) {
+ return pa->sizey;
+ }
- return PNL_HEADER + pa->sizey;
+ return PNL_HEADER + pa->sizey;
}
static int get_panel_real_size_y(const Panel *pa)
{
- int sizey = (pa->flag & PNL_CLOSED) ? 0 : pa->sizey;
+ int sizey = (pa->flag & PNL_CLOSED) ? 0 : pa->sizey;
- if (pa->type && (pa->type->flag & PNL_NO_HEADER)) {
- return sizey;
- }
+ if (pa->type && (pa->type->flag & PNL_NO_HEADER)) {
+ return sizey;
+ }
- return PNL_HEADER + sizey;
+ return PNL_HEADER + sizey;
}
int UI_panel_size_y(const Panel *pa)
{
- return get_panel_real_size_y(pa);
+ return get_panel_real_size_y(pa);
}
/* this function is needed because uiBlock and Panel itself don't
* change sizey or location when closed */
static int get_panel_real_ofsy(Panel *pa)
{
- if (pa->flag & PNL_CLOSEDY) {
- return pa->ofsy + pa->sizey;
- }
- else if (pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDY)) {
- return pa->ofsy + pa->sizey;
- }
- else if (pa->paneltab) {
- return pa->paneltab->ofsy;
- }
- else {
- return pa->ofsy;
- }
+ if (pa->flag & PNL_CLOSEDY) {
+ return pa->ofsy + pa->sizey;
+ }
+ else if (pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDY)) {
+ return pa->ofsy + pa->sizey;
+ }
+ else if (pa->paneltab) {
+ return pa->paneltab->ofsy;
+ }
+ else {
+ return pa->ofsy;
+ }
}
static int get_panel_real_ofsx(Panel *pa)
{
- if (pa->flag & PNL_CLOSEDX) {
- return pa->ofsx + get_panel_header(pa);
- }
- else if (pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDX)) {
- return pa->ofsx + get_panel_header(pa);
- }
- else {
- return pa->ofsx + pa->sizex;
- }
+ if (pa->flag & PNL_CLOSEDX) {
+ return pa->ofsx + get_panel_header(pa);
+ }
+ else if (pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDX)) {
+ return pa->ofsx + get_panel_header(pa);
+ }
+ else {
+ return pa->ofsx + pa->sizex;
+ }
}
typedef struct PanelSort {
- Panel *pa, *orig;
+ Panel *pa, *orig;
} PanelSort;
/**
@@ -962,590 +972,596 @@ typedef struct PanelSort {
static int find_leftmost_panel(const void *a1, const void *a2)
{
- const PanelSort *ps1 = a1, *ps2 = a2;
-
- if (ps1->pa->ofsx > ps2->pa->ofsx) {
- return 1;
- }
- else if (ps1->pa->ofsx < ps2->pa->ofsx) {
- return -1;
- }
- else if (ps1->pa->sortorder > ps2->pa->sortorder) {
- return 1;
- }
- else if (ps1->pa->sortorder < ps2->pa->sortorder) {
- return -1;
- }
-
- return 0;
+ const PanelSort *ps1 = a1, *ps2 = a2;
+
+ if (ps1->pa->ofsx > ps2->pa->ofsx) {
+ return 1;
+ }
+ else if (ps1->pa->ofsx < ps2->pa->ofsx) {
+ return -1;
+ }
+ else if (ps1->pa->sortorder > ps2->pa->sortorder) {
+ return 1;
+ }
+ else if (ps1->pa->sortorder < ps2->pa->sortorder) {
+ return -1;
+ }
+
+ return 0;
}
-
static int find_highest_panel(const void *a1, const void *a2)
{
- const PanelSort *ps1 = a1, *ps2 = a2;
-
- /* stick uppermost header-less panels to the top of the region -
- * prevent them from being sorted (multiple header-less panels have to be sorted though) */
- if (ps1->pa->type->flag & PNL_NO_HEADER && ps2->pa->type->flag & PNL_NO_HEADER) {
- /* skip and check for ofs and sortorder below */
- }
- else if (ps1->pa->type->flag & PNL_NO_HEADER) {
- return -1;
- }
- else if (ps2->pa->type->flag & PNL_NO_HEADER) {
- return 1;
- }
-
- if (ps1->pa->ofsy + ps1->pa->sizey < ps2->pa->ofsy + ps2->pa->sizey) {
- return 1;
- }
- else if (ps1->pa->ofsy + ps1->pa->sizey > ps2->pa->ofsy + ps2->pa->sizey) {
- return -1;
- }
- else if (ps1->pa->sortorder > ps2->pa->sortorder) {
- return 1;
- }
- else if (ps1->pa->sortorder < ps2->pa->sortorder) {
- return -1;
- }
-
- return 0;
+ const PanelSort *ps1 = a1, *ps2 = a2;
+
+ /* stick uppermost header-less panels to the top of the region -
+ * prevent them from being sorted (multiple header-less panels have to be sorted though) */
+ if (ps1->pa->type->flag & PNL_NO_HEADER && ps2->pa->type->flag & PNL_NO_HEADER) {
+ /* skip and check for ofs and sortorder below */
+ }
+ else if (ps1->pa->type->flag & PNL_NO_HEADER) {
+ return -1;
+ }
+ else if (ps2->pa->type->flag & PNL_NO_HEADER) {
+ return 1;
+ }
+
+ if (ps1->pa->ofsy + ps1->pa->sizey < ps2->pa->ofsy + ps2->pa->sizey) {
+ return 1;
+ }
+ else if (ps1->pa->ofsy + ps1->pa->sizey > ps2->pa->ofsy + ps2->pa->sizey) {
+ return -1;
+ }
+ else if (ps1->pa->sortorder > ps2->pa->sortorder) {
+ return 1;
+ }
+ else if (ps1->pa->sortorder < ps2->pa->sortorder) {
+ return -1;
+ }
+
+ return 0;
}
static int compare_panel(const void *a1, const void *a2)
{
- const PanelSort *ps1 = a1, *ps2 = a2;
+ const PanelSort *ps1 = a1, *ps2 = a2;
- if (ps1->pa->sortorder > ps2->pa->sortorder) {
- return 1;
- }
- else if (ps1->pa->sortorder < ps2->pa->sortorder) {
- return -1;
- }
+ if (ps1->pa->sortorder > ps2->pa->sortorder) {
+ return 1;
+ }
+ else if (ps1->pa->sortorder < ps2->pa->sortorder) {
+ return -1;
+ }
- return 0;
+ return 0;
}
static void align_sub_panels(Panel *pa)
{
- /* Position sub panels. */
- int ofsy = get_panel_real_ofsy(pa) + pa->sizey - pa->blocksizey;
-
- for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
- if (pachild->runtime_flag & PNL_ACTIVE) {
- pachild->ofsx = pa->ofsx;
- pachild->ofsy = ofsy - get_panel_size_y(pachild);
- ofsy -= get_panel_real_size_y(pachild);
-
- if (pachild->children.first) {
- align_sub_panels(pachild);
- }
- }
- }
+ /* Position sub panels. */
+ int ofsy = get_panel_real_ofsy(pa) + pa->sizey - pa->blocksizey;
+
+ for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
+ if (pachild->runtime_flag & PNL_ACTIVE) {
+ pachild->ofsx = pa->ofsx;
+ pachild->ofsy = ofsy - get_panel_size_y(pachild);
+ ofsy -= get_panel_real_size_y(pachild);
+
+ if (pachild->children.first) {
+ align_sub_panels(pachild);
+ }
+ }
+ }
}
/* this doesn't draw */
/* returns 1 when it did something */
static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bool drag)
{
- Panel *pa;
- PanelSort *ps, *panelsort, *psnext;
- int a, tot = 0;
- bool done;
- int align = panel_aligned(sa, ar);
- bool has_category_tabs = UI_panel_category_is_visible(ar);
-
- /* count active, not tabbed panels */
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
- tot++;
- }
- }
-
- if (tot == 0) {
- return 0;
- }
-
- /* extra; change close direction? */
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
- if ((pa->flag & PNL_CLOSEDX) && (align == BUT_VERTICAL)) {
- pa->flag ^= PNL_CLOSED;
- }
- else if ((pa->flag & PNL_CLOSEDY) && (align == BUT_HORIZONTAL)) {
- pa->flag ^= PNL_CLOSED;
- }
- }
- }
-
- /* sort panels */
- panelsort = MEM_callocN(tot * sizeof(PanelSort), "panelsort");
-
- ps = panelsort;
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
- ps->pa = MEM_dupallocN(pa);
- ps->orig = pa;
- ps++;
- }
- }
-
- if (drag) {
- /* while we are dragging, we sort on location and update sortorder */
- if (align == BUT_VERTICAL) {
- qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel);
- }
- else {
- qsort(panelsort, tot, sizeof(PanelSort), find_leftmost_panel);
- }
-
- for (ps = panelsort, a = 0; a < tot; a++, ps++) {
- ps->orig->sortorder = a;
- }
- }
- else {
- /* otherwise use sortorder */
- qsort(panelsort, tot, sizeof(PanelSort), compare_panel);
- }
-
- /* no smart other default start loc! this keeps switching f5/f6/etc compatible */
- ps = panelsort;
- ps->pa->ofsx = 0;
- ps->pa->ofsy = -get_panel_size_y(ps->pa);
-
- if (has_category_tabs) {
- if (align == BUT_VERTICAL && (ar->alignment != RGN_ALIGN_RIGHT)) {
- ps->pa->ofsx += UI_PANEL_CATEGORY_MARGIN_WIDTH;
- }
- }
-
- for (a = 0; a < tot - 1; a++, ps++) {
- psnext = ps + 1;
-
- if (align == BUT_VERTICAL) {
- psnext->pa->ofsx = ps->pa->ofsx;
- psnext->pa->ofsy = get_panel_real_ofsy(ps->pa) - get_panel_size_y(psnext->pa);
- }
- else {
- psnext->pa->ofsx = get_panel_real_ofsx(ps->pa);
- psnext->pa->ofsy = ps->pa->ofsy + get_panel_size_y(ps->pa) - get_panel_size_y(psnext->pa);
- }
- }
-
- /* we interpolate */
- done = false;
- ps = panelsort;
- for (a = 0; a < tot; a++, ps++) {
- if ((ps->pa->flag & PNL_SELECT) == 0) {
- if ((ps->orig->ofsx != ps->pa->ofsx) || (ps->orig->ofsy != ps->pa->ofsy)) {
- ps->orig->ofsx = round_fl_to_int(fac * (float)ps->pa->ofsx + (1.0f - fac) * (float)ps->orig->ofsx);
- ps->orig->ofsy = round_fl_to_int(fac * (float)ps->pa->ofsy + (1.0f - fac) * (float)ps->orig->ofsy);
- done = true;
- }
- }
- }
-
- /* set locations for tabbed and sub panels */
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if (pa->runtime_flag & PNL_ACTIVE) {
- if (pa->paneltab) {
- ui_panel_copy_offset(pa, pa->paneltab);
- }
- if (pa->children.first) {
- align_sub_panels(pa);
- }
- }
- }
-
- /* free panelsort array */
- for (ps = panelsort, a = 0; a < tot; a++, ps++) {
- MEM_freeN(ps->pa);
- }
- MEM_freeN(panelsort);
-
- return done;
+ Panel *pa;
+ PanelSort *ps, *panelsort, *psnext;
+ int a, tot = 0;
+ bool done;
+ int align = panel_aligned(sa, ar);
+ bool has_category_tabs = UI_panel_category_is_visible(ar);
+
+ /* count active, not tabbed panels */
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
+ tot++;
+ }
+ }
+
+ if (tot == 0) {
+ return 0;
+ }
+
+ /* extra; change close direction? */
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
+ if ((pa->flag & PNL_CLOSEDX) && (align == BUT_VERTICAL)) {
+ pa->flag ^= PNL_CLOSED;
+ }
+ else if ((pa->flag & PNL_CLOSEDY) && (align == BUT_HORIZONTAL)) {
+ pa->flag ^= PNL_CLOSED;
+ }
+ }
+ }
+
+ /* sort panels */
+ panelsort = MEM_callocN(tot * sizeof(PanelSort), "panelsort");
+
+ ps = panelsort;
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ if ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab == NULL) {
+ ps->pa = MEM_dupallocN(pa);
+ ps->orig = pa;
+ ps++;
+ }
+ }
+
+ if (drag) {
+ /* while we are dragging, we sort on location and update sortorder */
+ if (align == BUT_VERTICAL) {
+ qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel);
+ }
+ else {
+ qsort(panelsort, tot, sizeof(PanelSort), find_leftmost_panel);
+ }
+
+ for (ps = panelsort, a = 0; a < tot; a++, ps++) {
+ ps->orig->sortorder = a;
+ }
+ }
+ else {
+ /* otherwise use sortorder */
+ qsort(panelsort, tot, sizeof(PanelSort), compare_panel);
+ }
+
+ /* no smart other default start loc! this keeps switching f5/f6/etc compatible */
+ ps = panelsort;
+ ps->pa->ofsx = 0;
+ ps->pa->ofsy = -get_panel_size_y(ps->pa);
+
+ if (has_category_tabs) {
+ if (align == BUT_VERTICAL && (ar->alignment != RGN_ALIGN_RIGHT)) {
+ ps->pa->ofsx += UI_PANEL_CATEGORY_MARGIN_WIDTH;
+ }
+ }
+
+ for (a = 0; a < tot - 1; a++, ps++) {
+ psnext = ps + 1;
+
+ if (align == BUT_VERTICAL) {
+ psnext->pa->ofsx = ps->pa->ofsx;
+ psnext->pa->ofsy = get_panel_real_ofsy(ps->pa) - get_panel_size_y(psnext->pa);
+ }
+ else {
+ psnext->pa->ofsx = get_panel_real_ofsx(ps->pa);
+ psnext->pa->ofsy = ps->pa->ofsy + get_panel_size_y(ps->pa) - get_panel_size_y(psnext->pa);
+ }
+ }
+
+ /* we interpolate */
+ done = false;
+ ps = panelsort;
+ for (a = 0; a < tot; a++, ps++) {
+ if ((ps->pa->flag & PNL_SELECT) == 0) {
+ if ((ps->orig->ofsx != ps->pa->ofsx) || (ps->orig->ofsy != ps->pa->ofsy)) {
+ ps->orig->ofsx = round_fl_to_int(fac * (float)ps->pa->ofsx +
+ (1.0f - fac) * (float)ps->orig->ofsx);
+ ps->orig->ofsy = round_fl_to_int(fac * (float)ps->pa->ofsy +
+ (1.0f - fac) * (float)ps->orig->ofsy);
+ done = true;
+ }
+ }
+ }
+
+ /* set locations for tabbed and sub panels */
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
+ if (pa->paneltab) {
+ ui_panel_copy_offset(pa, pa->paneltab);
+ }
+ if (pa->children.first) {
+ align_sub_panels(pa);
+ }
+ }
+ }
+
+ /* free panelsort array */
+ for (ps = panelsort, a = 0; a < tot; a++, ps++) {
+ MEM_freeN(ps->pa);
+ }
+ MEM_freeN(panelsort);
+
+ return done;
}
static void ui_panels_size(ScrArea *sa, ARegion *ar, int *r_x, int *r_y)
{
- Panel *pa;
- int align = panel_aligned(sa, ar);
- int sizex = 0;
- int sizey = 0;
-
- /* compute size taken up by panels, for setting in view2d */
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if (pa->runtime_flag & PNL_ACTIVE) {
- int pa_sizex, pa_sizey;
-
- if (align == BUT_VERTICAL) {
- pa_sizex = pa->ofsx + pa->sizex;
- pa_sizey = get_panel_real_ofsy(pa);
- }
- else {
- pa_sizex = get_panel_real_ofsx(pa) + pa->sizex;
- pa_sizey = pa->ofsy + get_panel_size_y(pa);
- }
-
- sizex = max_ii(sizex, pa_sizex);
- sizey = min_ii(sizey, pa_sizey);
- }
- }
-
- if (sizex == 0) {
- sizex = UI_PANEL_WIDTH;
- }
- if (sizey == 0) {
- sizey = -UI_PANEL_WIDTH;
- }
-
- *r_x = sizex;
- *r_y = sizey;
+ Panel *pa;
+ int align = panel_aligned(sa, ar);
+ int sizex = 0;
+ int sizey = 0;
+
+ /* compute size taken up by panels, for setting in view2d */
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
+ int pa_sizex, pa_sizey;
+
+ if (align == BUT_VERTICAL) {
+ pa_sizex = pa->ofsx + pa->sizex;
+ pa_sizey = get_panel_real_ofsy(pa);
+ }
+ else {
+ pa_sizex = get_panel_real_ofsx(pa) + pa->sizex;
+ pa_sizey = pa->ofsy + get_panel_size_y(pa);
+ }
+
+ sizex = max_ii(sizex, pa_sizex);
+ sizey = min_ii(sizey, pa_sizey);
+ }
+ }
+
+ if (sizex == 0) {
+ sizex = UI_PANEL_WIDTH;
+ }
+ if (sizey == 0) {
+ sizey = -UI_PANEL_WIDTH;
+ }
+
+ *r_x = sizex;
+ *r_y = sizey;
}
static void ui_do_animate(const bContext *C, Panel *panel)
{
- uiHandlePanelData *data = panel->activedata;
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- float fac;
-
- fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME;
- fac = min_ff(sqrtf(fac), 1.0f);
-
- /* for max 1 second, interpolate positions */
- if (uiAlignPanelStep(sa, ar, fac, false)) {
- ED_region_tag_redraw(ar);
- }
- else {
- fac = 1.0f;
- }
-
- if (fac >= 1.0f) {
- panel_activate_state(C, panel, PANEL_STATE_EXIT);
- return;
- }
+ uiHandlePanelData *data = panel->activedata;
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ float fac;
+
+ fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME;
+ fac = min_ff(sqrtf(fac), 1.0f);
+
+ /* for max 1 second, interpolate positions */
+ if (uiAlignPanelStep(sa, ar, fac, false)) {
+ ED_region_tag_redraw(ar);
+ }
+ else {
+ fac = 1.0f;
+ }
+
+ if (fac >= 1.0f) {
+ panel_activate_state(C, panel, PANEL_STATE_EXIT);
+ return;
+ }
}
static void panel_list_clear_active(ListBase *lb)
{
- /* set all panels as inactive, so that at the end we know
- * which ones were used */
- for (Panel *pa = lb->first; pa; pa = pa->next) {
- if (pa->runtime_flag & PNL_ACTIVE) {
- pa->runtime_flag = PNL_WAS_ACTIVE;
- }
- else {
- pa->runtime_flag = 0;
- }
-
- panel_list_clear_active(&pa->children);
- }
+ /* set all panels as inactive, so that at the end we know
+ * which ones were used */
+ for (Panel *pa = lb->first; pa; pa = pa->next) {
+ if (pa->runtime_flag & PNL_ACTIVE) {
+ pa->runtime_flag = PNL_WAS_ACTIVE;
+ }
+ else {
+ pa->runtime_flag = 0;
+ }
+
+ panel_list_clear_active(&pa->children);
+ }
}
void UI_panels_begin(const bContext *UNUSED(C), ARegion *ar)
{
- panel_list_clear_active(&ar->panels);
+ panel_list_clear_active(&ar->panels);
}
/* only draws blocks with panels */
void UI_panels_end(const bContext *C, ARegion *ar, int *r_x, int *r_y)
{
- ScrArea *sa = CTX_wm_area(C);
- uiBlock *block;
- Panel *panot, *panew, *patest, *pa, *firstpa;
-
- /* offset contents */
- for (block = ar->uiblocks.first; block; block = block->next) {
- if (block->active && block->panel) {
- ui_offset_panel_block(block);
- }
- }
-
- /* consistency; are panels not made, whilst they have tabs */
- for (panot = ar->panels.first; panot; panot = panot->next) {
- if ((panot->runtime_flag & PNL_ACTIVE) == 0) { /* not made */
-
- for (panew = ar->panels.first; panew; panew = panew->next) {
- if ((panew->runtime_flag & PNL_ACTIVE)) {
- if (panew->paneltab == panot) { /* panew is tab in notmade pa */
- break;
- }
- }
- }
- /* now panew can become the new parent, check all other tabs */
- if (panew) {
- for (patest = ar->panels.first; patest; patest = patest->next) {
- if (patest->paneltab == panot) {
- patest->paneltab = panew;
- }
- }
- panot->paneltab = panew;
- panew->paneltab = NULL;
- ED_region_tag_redraw(ar); /* the buttons panew were not made */
- }
- }
- }
-
- /* re-align, possibly with animation */
- if (panels_need_realign(sa, ar, &pa)) {
- if (pa) {
- panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
- }
- else {
- uiAlignPanelStep(sa, ar, 1.0, false);
- }
- }
-
- /* tag first panel */
- firstpa = NULL;
- for (block = ar->uiblocks.first; block; block = block->next) {
- if (block->active && block->panel) {
- if (!firstpa || block->panel->sortorder < firstpa->sortorder) {
- firstpa = block->panel;
- }
- }
- }
-
- if (firstpa) {
- firstpa->runtime_flag |= PNL_FIRST;
- }
-
- /* compute size taken up by panel */
- ui_panels_size(sa, ar, r_x, r_y);
+ ScrArea *sa = CTX_wm_area(C);
+ uiBlock *block;
+ Panel *panot, *panew, *patest, *pa, *firstpa;
+
+ /* offset contents */
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ if (block->active && block->panel) {
+ ui_offset_panel_block(block);
+ }
+ }
+
+ /* consistency; are panels not made, whilst they have tabs */
+ for (panot = ar->panels.first; panot; panot = panot->next) {
+ if ((panot->runtime_flag & PNL_ACTIVE) == 0) { /* not made */
+
+ for (panew = ar->panels.first; panew; panew = panew->next) {
+ if ((panew->runtime_flag & PNL_ACTIVE)) {
+ if (panew->paneltab == panot) { /* panew is tab in notmade pa */
+ break;
+ }
+ }
+ }
+ /* now panew can become the new parent, check all other tabs */
+ if (panew) {
+ for (patest = ar->panels.first; patest; patest = patest->next) {
+ if (patest->paneltab == panot) {
+ patest->paneltab = panew;
+ }
+ }
+ panot->paneltab = panew;
+ panew->paneltab = NULL;
+ ED_region_tag_redraw(ar); /* the buttons panew were not made */
+ }
+ }
+ }
+
+ /* re-align, possibly with animation */
+ if (panels_need_realign(sa, ar, &pa)) {
+ if (pa) {
+ panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
+ }
+ else {
+ uiAlignPanelStep(sa, ar, 1.0, false);
+ }
+ }
+
+ /* tag first panel */
+ firstpa = NULL;
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ if (block->active && block->panel) {
+ if (!firstpa || block->panel->sortorder < firstpa->sortorder) {
+ firstpa = block->panel;
+ }
+ }
+ }
+
+ if (firstpa) {
+ firstpa->runtime_flag |= PNL_FIRST;
+ }
+
+ /* compute size taken up by panel */
+ ui_panels_size(sa, ar, r_x, r_y);
}
void UI_panels_draw(const bContext *C, ARegion *ar)
{
- uiBlock *block;
-
- if (ar->alignment != RGN_ALIGN_FLOAT) {
- UI_ThemeClearColor(TH_BACK);
- }
-
- /* Draw panels, selected on top. Also in reverse order, because
- * UI blocks are added in reverse order and we need child panels
- * to draw on top. */
- for (block = ar->uiblocks.last; block; block = block->prev) {
- if (block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
- UI_block_draw(C, block);
- }
- }
-
- for (block = ar->uiblocks.last; block; block = block->prev) {
- if (block->active && block->panel && (block->panel->flag & PNL_SELECT)) {
- UI_block_draw(C, block);
- }
- }
+ uiBlock *block;
+
+ if (ar->alignment != RGN_ALIGN_FLOAT) {
+ UI_ThemeClearColor(TH_BACK);
+ }
+
+ /* Draw panels, selected on top. Also in reverse order, because
+ * UI blocks are added in reverse order and we need child panels
+ * to draw on top. */
+ for (block = ar->uiblocks.last; block; block = block->prev) {
+ if (block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
+ UI_block_draw(C, block);
+ }
+ }
+
+ for (block = ar->uiblocks.last; block; block = block->prev) {
+ if (block->active && block->panel && (block->panel->flag & PNL_SELECT)) {
+ UI_block_draw(C, block);
+ }
+ }
}
void UI_panels_scale(ARegion *ar, float new_width)
{
- uiBlock *block;
- uiBut *but;
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- if (block->panel) {
- float fac = new_width / (float)block->panel->sizex;
- block->panel->sizex = new_width;
-
- for (but = block->buttons.first; but; but = but->next) {
- but->rect.xmin *= fac;
- but->rect.xmax *= fac;
- }
- }
- }
+ uiBlock *block;
+ uiBut *but;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ if (block->panel) {
+ float fac = new_width / (float)block->panel->sizex;
+ block->panel->sizex = new_width;
+
+ for (but = block->buttons.first; but; but = but->next) {
+ but->rect.xmin *= fac;
+ but->rect.xmax *= fac;
+ }
+ }
+ }
}
/* ------------ panel merging ---------------- */
static void check_panel_overlap(ARegion *ar, Panel *panel)
{
- Panel *pa;
-
- /* also called with (panel == NULL) for clear */
-
- for (pa = ar->panels.first; pa; pa = pa->next) {
- pa->flag &= ~PNL_OVERLAP;
- if (panel && (pa != panel)) {
- if (pa->paneltab == NULL && (pa->runtime_flag & PNL_ACTIVE)) {
- float safex = 0.2, safey = 0.2;
-
- if (pa->flag & PNL_CLOSEDX) {
- safex = 0.05;
- }
- else if (pa->flag & PNL_CLOSEDY) {
- safey = 0.05;
- }
- else if (panel->flag & PNL_CLOSEDX) {
- safex = 0.05;
- }
- else if (panel->flag & PNL_CLOSEDY) {
- safey = 0.05;
- }
-
- if (pa->ofsx > panel->ofsx - safex * panel->sizex) {
- if (pa->ofsx + pa->sizex < panel->ofsx + (1.0f + safex) * panel->sizex) {
- if (pa->ofsy > panel->ofsy - safey * panel->sizey) {
- if (pa->ofsy + pa->sizey < panel->ofsy + (1.0f + safey) * panel->sizey) {
- pa->flag |= PNL_OVERLAP;
- }
- }
- }
- }
- }
- }
- }
+ Panel *pa;
+
+ /* also called with (panel == NULL) for clear */
+
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ pa->flag &= ~PNL_OVERLAP;
+ if (panel && (pa != panel)) {
+ if (pa->paneltab == NULL && (pa->runtime_flag & PNL_ACTIVE)) {
+ float safex = 0.2, safey = 0.2;
+
+ if (pa->flag & PNL_CLOSEDX) {
+ safex = 0.05;
+ }
+ else if (pa->flag & PNL_CLOSEDY) {
+ safey = 0.05;
+ }
+ else if (panel->flag & PNL_CLOSEDX) {
+ safex = 0.05;
+ }
+ else if (panel->flag & PNL_CLOSEDY) {
+ safey = 0.05;
+ }
+
+ if (pa->ofsx > panel->ofsx - safex * panel->sizex) {
+ if (pa->ofsx + pa->sizex < panel->ofsx + (1.0f + safex) * panel->sizex) {
+ if (pa->ofsy > panel->ofsy - safey * panel->sizey) {
+ if (pa->ofsy + pa->sizey < panel->ofsy + (1.0f + safey) * panel->sizey) {
+ pa->flag |= PNL_OVERLAP;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
/************************ panel dragging ****************************/
static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
{
- uiHandlePanelData *data = panel->activedata;
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- short align = panel_aligned(sa, ar), dx = 0, dy = 0;
-
- /* first clip for window, no dragging outside */
- if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
- return;
- }
-
- dx = (event->x - data->startx) & ~(PNL_GRID - 1);
- dy = (event->y - data->starty) & ~(PNL_GRID - 1);
-
- dx *= (float)BLI_rctf_size_x(&ar->v2d.cur) / (float)BLI_rcti_size_x(&ar->winrct);
- dy *= (float)BLI_rctf_size_y(&ar->v2d.cur) / (float)BLI_rcti_size_y(&ar->winrct);
-
- if (data->state == PANEL_STATE_DRAG_SCALE) {
- panel->sizex = MAX2(data->startsizex + dx, UI_PANEL_MINX);
-
- if (data->startsizey - dy < UI_PANEL_MINY) {
- dy = -UI_PANEL_MINY + data->startsizey;
- }
-
- panel->sizey = data->startsizey - dy;
- panel->ofsy = data->startofsy + dy;
- }
- else {
- /* reset the panel snapping, to allow dragging away from snapped edges */
- panel->snap = PNL_SNAP_NONE;
-
- panel->ofsx = data->startofsx + dx;
- panel->ofsy = data->startofsy + dy;
- check_panel_overlap(ar, panel);
-
- if (align) {
- uiAlignPanelStep(sa, ar, 0.2, true);
- }
- }
-
- ED_region_tag_redraw(ar);
+ uiHandlePanelData *data = panel->activedata;
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ short align = panel_aligned(sa, ar), dx = 0, dy = 0;
+
+ /* first clip for window, no dragging outside */
+ if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
+ return;
+ }
+
+ dx = (event->x - data->startx) & ~(PNL_GRID - 1);
+ dy = (event->y - data->starty) & ~(PNL_GRID - 1);
+
+ dx *= (float)BLI_rctf_size_x(&ar->v2d.cur) / (float)BLI_rcti_size_x(&ar->winrct);
+ dy *= (float)BLI_rctf_size_y(&ar->v2d.cur) / (float)BLI_rcti_size_y(&ar->winrct);
+
+ if (data->state == PANEL_STATE_DRAG_SCALE) {
+ panel->sizex = MAX2(data->startsizex + dx, UI_PANEL_MINX);
+
+ if (data->startsizey - dy < UI_PANEL_MINY) {
+ dy = -UI_PANEL_MINY + data->startsizey;
+ }
+
+ panel->sizey = data->startsizey - dy;
+ panel->ofsy = data->startofsy + dy;
+ }
+ else {
+ /* reset the panel snapping, to allow dragging away from snapped edges */
+ panel->snap = PNL_SNAP_NONE;
+
+ panel->ofsx = data->startofsx + dx;
+ panel->ofsy = data->startofsy + dy;
+ check_panel_overlap(ar, panel);
+
+ if (align) {
+ uiAlignPanelStep(sa, ar, 0.2, true);
+ }
+ }
+
+ ED_region_tag_redraw(ar);
}
/******************* region level panel interaction *****************/
-static uiPanelMouseState ui_panel_mouse_state_get(const uiBlock *block, const Panel *pa, const int mx, const int my)
+static uiPanelMouseState ui_panel_mouse_state_get(const uiBlock *block,
+ const Panel *pa,
+ const int mx,
+ const int my)
{
- /* open panel */
- if (pa->flag & PNL_CLOSEDX) {
- if ((block->rect.xmin <= mx) && (block->rect.xmin + PNL_HEADER >= mx)) {
- return PANEL_MOUSE_INSIDE_HEADER;
- }
- }
- /* outside left/right side */
- else if ((block->rect.xmin > mx) || (block->rect.xmax < mx)) {
- /* pass */
- }
- else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
- return PANEL_MOUSE_INSIDE_HEADER;
- }
- /* open panel */
- else if (!(pa->flag & PNL_CLOSEDY)) {
- if (pa->control & UI_PNL_SCALE) {
- if (block->rect.xmax - PNL_HEADER <= mx) {
- if (block->rect.ymin + PNL_HEADER >= my) {
- return PANEL_MOUSE_INSIDE_SCALE;
- }
- }
- }
- if ((block->rect.xmin <= mx) && (block->rect.xmax >= mx)) {
- if ((block->rect.ymin <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
- return PANEL_MOUSE_INSIDE_CONTENT;
- }
- }
- }
- return PANEL_MOUSE_OUTSIDE;
+ /* open panel */
+ if (pa->flag & PNL_CLOSEDX) {
+ if ((block->rect.xmin <= mx) && (block->rect.xmin + PNL_HEADER >= mx)) {
+ return PANEL_MOUSE_INSIDE_HEADER;
+ }
+ }
+ /* outside left/right side */
+ else if ((block->rect.xmin > mx) || (block->rect.xmax < mx)) {
+ /* pass */
+ }
+ else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
+ return PANEL_MOUSE_INSIDE_HEADER;
+ }
+ /* open panel */
+ else if (!(pa->flag & PNL_CLOSEDY)) {
+ if (pa->control & UI_PNL_SCALE) {
+ if (block->rect.xmax - PNL_HEADER <= mx) {
+ if (block->rect.ymin + PNL_HEADER >= my) {
+ return PANEL_MOUSE_INSIDE_SCALE;
+ }
+ }
+ }
+ if ((block->rect.xmin <= mx) && (block->rect.xmax >= mx)) {
+ if ((block->rect.ymin <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
+ return PANEL_MOUSE_INSIDE_CONTENT;
+ }
+ }
+ }
+ return PANEL_MOUSE_OUTSIDE;
}
typedef struct uiPanelDragCollapseHandle {
- bool was_first_open;
- int xy_init[2];
+ bool was_first_open;
+ int xy_init[2];
} uiPanelDragCollapseHandle;
static void ui_panel_drag_collapse_handler_remove(bContext *UNUSED(C), void *userdata)
{
- uiPanelDragCollapseHandle *dragcol_data = userdata;
- MEM_freeN(dragcol_data);
+ uiPanelDragCollapseHandle *dragcol_data = userdata;
+ MEM_freeN(dragcol_data);
}
-static void ui_panel_drag_collapse(bContext *C, uiPanelDragCollapseHandle *dragcol_data, const int xy_dst[2])
+static void ui_panel_drag_collapse(bContext *C,
+ uiPanelDragCollapseHandle *dragcol_data,
+ const int xy_dst[2])
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- uiBlock *block;
- Panel *pa;
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- float xy_a_block[2] = {UNPACK2(dragcol_data->xy_init)};
- float xy_b_block[2] = {UNPACK2(xy_dst)};
- rctf rect = block->rect;
- int oldflag;
- const bool is_horizontal = (panel_aligned(sa, ar) == BUT_HORIZONTAL);
-
- if ((pa = block->panel) == 0 || (pa->type && (pa->type->flag & PNL_NO_HEADER))) {
- continue;
- }
- oldflag = pa->flag;
-
- /* lock one axis */
- if (is_horizontal) {
- xy_b_block[1] = dragcol_data->xy_init[1];
- }
- else {
- xy_b_block[0] = dragcol_data->xy_init[0];
- }
-
- /* use cursor coords in block space */
- ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
- ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]);
-
- /* set up rect to match header size */
- rect.ymin = rect.ymax;
- rect.ymax = rect.ymin + PNL_HEADER;
- if (pa->flag & PNL_CLOSEDX) {
- rect.xmax = rect.xmin + PNL_HEADER;
- }
-
- /* touch all panels between last mouse coord and the current one */
- if (BLI_rctf_isect_segment(&rect, xy_a_block, xy_b_block)) {
- /* force panel to close */
- if (dragcol_data->was_first_open == true) {
- pa->flag |= (is_horizontal ? PNL_CLOSEDX : PNL_CLOSEDY);
- }
- /* force panel to open */
- else {
- pa->flag &= ~PNL_CLOSED;
- }
-
- /* if pa->flag has changed this means a panel was opened/closed here */
- if (pa->flag != oldflag) {
- panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
- }
- }
- }
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ uiBlock *block;
+ Panel *pa;
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ float xy_a_block[2] = {UNPACK2(dragcol_data->xy_init)};
+ float xy_b_block[2] = {UNPACK2(xy_dst)};
+ rctf rect = block->rect;
+ int oldflag;
+ const bool is_horizontal = (panel_aligned(sa, ar) == BUT_HORIZONTAL);
+
+ if ((pa = block->panel) == 0 || (pa->type && (pa->type->flag & PNL_NO_HEADER))) {
+ continue;
+ }
+ oldflag = pa->flag;
+
+ /* lock one axis */
+ if (is_horizontal) {
+ xy_b_block[1] = dragcol_data->xy_init[1];
+ }
+ else {
+ xy_b_block[0] = dragcol_data->xy_init[0];
+ }
+
+ /* use cursor coords in block space */
+ ui_window_to_block_fl(ar, block, &xy_a_block[0], &xy_a_block[1]);
+ ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]);
+
+ /* set up rect to match header size */
+ rect.ymin = rect.ymax;
+ rect.ymax = rect.ymin + PNL_HEADER;
+ if (pa->flag & PNL_CLOSEDX) {
+ rect.xmax = rect.xmin + PNL_HEADER;
+ }
+
+ /* touch all panels between last mouse coord and the current one */
+ if (BLI_rctf_isect_segment(&rect, xy_a_block, xy_b_block)) {
+ /* force panel to close */
+ if (dragcol_data->was_first_open == true) {
+ pa->flag |= (is_horizontal ? PNL_CLOSEDX : PNL_CLOSEDY);
+ }
+ /* force panel to open */
+ else {
+ pa->flag &= ~PNL_CLOSED;
+ }
+
+ /* if pa->flag has changed this means a panel was opened/closed here */
+ if (pa->flag != oldflag) {
+ panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
+ }
+ }
+ }
}
/**
@@ -1555,915 +1571,931 @@ static void ui_panel_drag_collapse(bContext *C, uiPanelDragCollapseHandle *dragc
*/
static int ui_panel_drag_collapse_handler(bContext *C, const wmEvent *event, void *userdata)
{
- wmWindow *win = CTX_wm_window(C);
- uiPanelDragCollapseHandle *dragcol_data = userdata;
- short retval = WM_UI_HANDLER_CONTINUE;
-
- switch (event->type) {
- case MOUSEMOVE:
- ui_panel_drag_collapse(C, dragcol_data, &event->x);
-
- retval = WM_UI_HANDLER_BREAK;
- break;
- case LEFTMOUSE:
- if (event->val == KM_RELEASE) {
- /* done! */
- WM_event_remove_ui_handler(
- &win->modalhandlers,
- ui_panel_drag_collapse_handler,
- ui_panel_drag_collapse_handler_remove,
- dragcol_data, true);
- ui_panel_drag_collapse_handler_remove(C, dragcol_data);
- }
- /* don't let any left-mouse event fall through! */
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
-
- return retval;
+ wmWindow *win = CTX_wm_window(C);
+ uiPanelDragCollapseHandle *dragcol_data = userdata;
+ short retval = WM_UI_HANDLER_CONTINUE;
+
+ switch (event->type) {
+ case MOUSEMOVE:
+ ui_panel_drag_collapse(C, dragcol_data, &event->x);
+
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ /* done! */
+ WM_event_remove_ui_handler(&win->modalhandlers,
+ ui_panel_drag_collapse_handler,
+ ui_panel_drag_collapse_handler_remove,
+ dragcol_data,
+ true);
+ ui_panel_drag_collapse_handler_remove(C, dragcol_data);
+ }
+ /* don't let any left-mouse event fall through! */
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+
+ return retval;
}
static void ui_panel_drag_collapse_handler_add(const bContext *C, const bool was_open)
{
- wmWindow *win = CTX_wm_window(C);
- const wmEvent *event = win->eventstate;
- uiPanelDragCollapseHandle *dragcol_data = MEM_mallocN(sizeof(*dragcol_data), __func__);
-
- dragcol_data->was_first_open = was_open;
- copy_v2_v2_int(dragcol_data->xy_init, &event->x);
-
- WM_event_add_ui_handler(
- C, &win->modalhandlers,
- ui_panel_drag_collapse_handler,
- ui_panel_drag_collapse_handler_remove,
- dragcol_data, 0);
+ wmWindow *win = CTX_wm_window(C);
+ const wmEvent *event = win->eventstate;
+ uiPanelDragCollapseHandle *dragcol_data = MEM_mallocN(sizeof(*dragcol_data), __func__);
+
+ dragcol_data->was_first_open = was_open;
+ copy_v2_v2_int(dragcol_data->xy_init, &event->x);
+
+ WM_event_add_ui_handler(C,
+ &win->modalhandlers,
+ ui_panel_drag_collapse_handler,
+ ui_panel_drag_collapse_handler_remove,
+ dragcol_data,
+ 0);
}
/* this function is supposed to call general window drawing too */
/* also it supposes a block has panel, and isn't a menu */
-static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my, int event, short ctrl, short shift)
+static void ui_handle_panel_header(
+ const bContext *C, uiBlock *block, int mx, int my, int event, short ctrl, short shift)
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- Panel *pa;
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ Panel *pa;
#ifdef USE_PIN_HIDDEN
- const bool show_pin = UI_panel_category_is_visible(ar) && (block->panel->flag & PNL_PIN);
+ const bool show_pin = UI_panel_category_is_visible(ar) && (block->panel->flag & PNL_PIN);
#else
- const bool show_pin = UI_panel_category_is_visible(ar);
+ const bool show_pin = UI_panel_category_is_visible(ar);
#endif
- const bool is_subpanel = (block->panel->type && block->panel->type->parent);
- const bool show_drag = !is_subpanel;
-
- int align = panel_aligned(sa, ar), button = 0;
-
- rctf rect_drag, rect_pin;
- float rect_leftmost;
-
-
- /* drag and pin rect's */
- rect_drag = block->rect;
- rect_drag.xmin = block->rect.xmax - (PNL_ICON * 1.5f);
- rect_pin = rect_drag;
- if (show_pin) {
- BLI_rctf_translate(&rect_pin, -PNL_ICON, 0.0f);
- }
- rect_leftmost = rect_pin.xmin;
-
- /* mouse coordinates in panel space! */
-
- /* XXX weak code, currently it assumes layout style for location of widgets */
-
- /* check open/collapsed button */
- if (event == RETKEY) {
- button = 1;
- }
- else if (event == AKEY) {
- button = 1;
- }
- else if (ELEM(event, 0, RETKEY, LEFTMOUSE) && shift) {
- block->panel->flag ^= PNL_PIN;
- button = 2;
- }
- else if (block->panel->flag & PNL_CLOSEDX) {
- if (my >= block->rect.ymax) {
- button = 1;
- }
- }
- else if (block->panel->control & UI_PNL_CLOSE) {
- /* whole of header can be used to collapse panel (except top-right corner) */
- if (mx <= block->rect.xmax - 8 - PNL_ICON) {
- button = 2;
- }
- //else if (mx <= block->rect.xmin + 10 + 2 * PNL_ICON + 2) {
- // button = 1;
- //}
- }
- else if (mx < rect_leftmost) {
- button = 1;
- }
-
- if (button) {
- if (button == 2) { /* close */
- ED_region_tag_redraw(ar);
- }
- else { /* collapse */
- if (ctrl) {
- panels_collapse_all(sa, ar, block->panel);
-
- /* reset the view - we don't want to display a view without content */
- UI_view2d_offset(&ar->v2d, 0.0f, 1.0f);
- }
-
- if (block->panel->flag & PNL_CLOSED) {
- block->panel->flag &= ~PNL_CLOSED;
- /* snap back up so full panel aligns with screen edge */
- if (block->panel->snap & PNL_SNAP_BOTTOM) {
- block->panel->ofsy = 0;
- }
-
- if (event == LEFTMOUSE) {
- ui_panel_drag_collapse_handler_add(C, false);
- }
- }
- else if (align == BUT_HORIZONTAL) {
- block->panel->flag |= PNL_CLOSEDX;
-
- if (event == LEFTMOUSE) {
- ui_panel_drag_collapse_handler_add(C, true);
- }
- }
- else {
- /* snap down to bottom screen edge */
- block->panel->flag |= PNL_CLOSEDY;
- if (block->panel->snap & PNL_SNAP_BOTTOM) {
- block->panel->ofsy = -block->panel->sizey;
- }
-
- if (event == LEFTMOUSE) {
- ui_panel_drag_collapse_handler_add(C, true);
- }
- }
-
- for (pa = ar->panels.first; pa; pa = pa->next) {
- if (pa->paneltab == block->panel) {
- if (block->panel->flag & PNL_CLOSED) {
- pa->flag |= PNL_CLOSED;
- }
- else {
- pa->flag &= ~PNL_CLOSED;
- }
- }
- }
- }
-
- if (align) {
- panel_activate_state(C, block->panel, PANEL_STATE_ANIMATION);
- }
- else {
- /* FIXME: this doesn't update the panel drawing, assert to avoid debugging why this is.
- * We could fix this in the future if it's ever needed. */
- BLI_assert(0);
- ED_region_tag_redraw(ar);
- }
- }
- else if (show_drag && BLI_rctf_isect_x(&rect_drag, mx)) {
- /* XXX, for now don't allow dragging in floating windows yet. */
- if (ar->alignment == RGN_ALIGN_FLOAT) {
- return;
- }
- panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
- }
- else if (show_pin && BLI_rctf_isect_x(&rect_pin, mx)) {
- block->panel->flag ^= PNL_PIN;
- ED_region_tag_redraw(ar);
- }
+ const bool is_subpanel = (block->panel->type && block->panel->type->parent);
+ const bool show_drag = !is_subpanel;
+
+ int align = panel_aligned(sa, ar), button = 0;
+
+ rctf rect_drag, rect_pin;
+ float rect_leftmost;
+
+ /* drag and pin rect's */
+ rect_drag = block->rect;
+ rect_drag.xmin = block->rect.xmax - (PNL_ICON * 1.5f);
+ rect_pin = rect_drag;
+ if (show_pin) {
+ BLI_rctf_translate(&rect_pin, -PNL_ICON, 0.0f);
+ }
+ rect_leftmost = rect_pin.xmin;
+
+ /* mouse coordinates in panel space! */
+
+ /* XXX weak code, currently it assumes layout style for location of widgets */
+
+ /* check open/collapsed button */
+ if (event == RETKEY) {
+ button = 1;
+ }
+ else if (event == AKEY) {
+ button = 1;
+ }
+ else if (ELEM(event, 0, RETKEY, LEFTMOUSE) && shift) {
+ block->panel->flag ^= PNL_PIN;
+ button = 2;
+ }
+ else if (block->panel->flag & PNL_CLOSEDX) {
+ if (my >= block->rect.ymax) {
+ button = 1;
+ }
+ }
+ else if (block->panel->control & UI_PNL_CLOSE) {
+ /* whole of header can be used to collapse panel (except top-right corner) */
+ if (mx <= block->rect.xmax - 8 - PNL_ICON) {
+ button = 2;
+ }
+ //else if (mx <= block->rect.xmin + 10 + 2 * PNL_ICON + 2) {
+ // button = 1;
+ //}
+ }
+ else if (mx < rect_leftmost) {
+ button = 1;
+ }
+
+ if (button) {
+ if (button == 2) { /* close */
+ ED_region_tag_redraw(ar);
+ }
+ else { /* collapse */
+ if (ctrl) {
+ panels_collapse_all(sa, ar, block->panel);
+
+ /* reset the view - we don't want to display a view without content */
+ UI_view2d_offset(&ar->v2d, 0.0f, 1.0f);
+ }
+
+ if (block->panel->flag & PNL_CLOSED) {
+ block->panel->flag &= ~PNL_CLOSED;
+ /* snap back up so full panel aligns with screen edge */
+ if (block->panel->snap & PNL_SNAP_BOTTOM) {
+ block->panel->ofsy = 0;
+ }
+
+ if (event == LEFTMOUSE) {
+ ui_panel_drag_collapse_handler_add(C, false);
+ }
+ }
+ else if (align == BUT_HORIZONTAL) {
+ block->panel->flag |= PNL_CLOSEDX;
+
+ if (event == LEFTMOUSE) {
+ ui_panel_drag_collapse_handler_add(C, true);
+ }
+ }
+ else {
+ /* snap down to bottom screen edge */
+ block->panel->flag |= PNL_CLOSEDY;
+ if (block->panel->snap & PNL_SNAP_BOTTOM) {
+ block->panel->ofsy = -block->panel->sizey;
+ }
+
+ if (event == LEFTMOUSE) {
+ ui_panel_drag_collapse_handler_add(C, true);
+ }
+ }
+
+ for (pa = ar->panels.first; pa; pa = pa->next) {
+ if (pa->paneltab == block->panel) {
+ if (block->panel->flag & PNL_CLOSED) {
+ pa->flag |= PNL_CLOSED;
+ }
+ else {
+ pa->flag &= ~PNL_CLOSED;
+ }
+ }
+ }
+ }
+
+ if (align) {
+ panel_activate_state(C, block->panel, PANEL_STATE_ANIMATION);
+ }
+ else {
+ /* FIXME: this doesn't update the panel drawing, assert to avoid debugging why this is.
+ * We could fix this in the future if it's ever needed. */
+ BLI_assert(0);
+ ED_region_tag_redraw(ar);
+ }
+ }
+ else if (show_drag && BLI_rctf_isect_x(&rect_drag, mx)) {
+ /* XXX, for now don't allow dragging in floating windows yet. */
+ if (ar->alignment == RGN_ALIGN_FLOAT) {
+ return;
+ }
+ panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
+ }
+ else if (show_pin && BLI_rctf_isect_x(&rect_pin, mx)) {
+ block->panel->flag ^= PNL_PIN;
+ ED_region_tag_redraw(ar);
+ }
}
bool UI_panel_category_is_visible(ARegion *ar)
{
- /* more than one */
- return ar->panels_category.first && ar->panels_category.first != ar->panels_category.last;
+ /* more than one */
+ return ar->panels_category.first && ar->panels_category.first != ar->panels_category.last;
}
PanelCategoryDyn *UI_panel_category_find(ARegion *ar, const char *idname)
{
- return BLI_findstring(&ar->panels_category, idname, offsetof(PanelCategoryDyn, idname));
+ return BLI_findstring(&ar->panels_category, idname, offsetof(PanelCategoryDyn, idname));
}
PanelCategoryStack *UI_panel_category_active_find(ARegion *ar, const char *idname)
{
- return BLI_findstring(&ar->panels_category_active, idname, offsetof(PanelCategoryStack, idname));
+ return BLI_findstring(&ar->panels_category_active, idname, offsetof(PanelCategoryStack, idname));
}
const char *UI_panel_category_active_get(ARegion *ar, bool set_fallback)
{
- PanelCategoryStack *pc_act;
-
- for (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) {
- if (UI_panel_category_find(ar, pc_act->idname)) {
- return pc_act->idname;
- }
- }
-
- if (set_fallback) {
- PanelCategoryDyn *pc_dyn = ar->panels_category.first;
- if (pc_dyn) {
- UI_panel_category_active_set(ar, pc_dyn->idname);
- return pc_dyn->idname;
- }
- }
-
- return NULL;
+ PanelCategoryStack *pc_act;
+
+ for (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) {
+ if (UI_panel_category_find(ar, pc_act->idname)) {
+ return pc_act->idname;
+ }
+ }
+
+ if (set_fallback) {
+ PanelCategoryDyn *pc_dyn = ar->panels_category.first;
+ if (pc_dyn) {
+ UI_panel_category_active_set(ar, pc_dyn->idname);
+ return pc_dyn->idname;
+ }
+ }
+
+ return NULL;
}
void UI_panel_category_active_set(ARegion *ar, const char *idname)
{
- ListBase *lb = &ar->panels_category_active;
- PanelCategoryStack *pc_act = UI_panel_category_active_find(ar, idname);
-
- if (pc_act) {
- BLI_remlink(lb, pc_act);
- }
- else {
- pc_act = MEM_callocN(sizeof(PanelCategoryStack), __func__);
- BLI_strncpy(pc_act->idname, idname, sizeof(pc_act->idname));
- }
-
- BLI_addhead(lb, pc_act);
-
-
- /* validate all active panels, we could do this on load,
- * they are harmless - but we should remove somewhere.
- * (addons could define own and gather cruft over time) */
- {
- PanelCategoryStack *pc_act_next;
- /* intentionally skip first */
- pc_act_next = pc_act->next;
- while ((pc_act = pc_act_next)) {
- pc_act_next = pc_act->next;
- if (!BLI_findstring(&ar->type->paneltypes, pc_act->idname, offsetof(PanelType, category))) {
- BLI_remlink(lb, pc_act);
- MEM_freeN(pc_act);
- }
- }
- }
+ ListBase *lb = &ar->panels_category_active;
+ PanelCategoryStack *pc_act = UI_panel_category_active_find(ar, idname);
+
+ if (pc_act) {
+ BLI_remlink(lb, pc_act);
+ }
+ else {
+ pc_act = MEM_callocN(sizeof(PanelCategoryStack), __func__);
+ BLI_strncpy(pc_act->idname, idname, sizeof(pc_act->idname));
+ }
+
+ BLI_addhead(lb, pc_act);
+
+ /* validate all active panels, we could do this on load,
+ * they are harmless - but we should remove somewhere.
+ * (addons could define own and gather cruft over time) */
+ {
+ PanelCategoryStack *pc_act_next;
+ /* intentionally skip first */
+ pc_act_next = pc_act->next;
+ while ((pc_act = pc_act_next)) {
+ pc_act_next = pc_act->next;
+ if (!BLI_findstring(&ar->type->paneltypes, pc_act->idname, offsetof(PanelType, category))) {
+ BLI_remlink(lb, pc_act);
+ MEM_freeN(pc_act);
+ }
+ }
+ }
}
PanelCategoryDyn *UI_panel_category_find_mouse_over_ex(ARegion *ar, const int x, const int y)
{
- PanelCategoryDyn *ptd;
+ PanelCategoryDyn *ptd;
- for (ptd = ar->panels_category.first; ptd; ptd = ptd->next) {
- if (BLI_rcti_isect_pt(&ptd->rect, x, y)) {
- return ptd;
- }
- }
+ for (ptd = ar->panels_category.first; ptd; ptd = ptd->next) {
+ if (BLI_rcti_isect_pt(&ptd->rect, x, y)) {
+ return ptd;
+ }
+ }
- return NULL;
+ return NULL;
}
PanelCategoryDyn *UI_panel_category_find_mouse_over(ARegion *ar, const wmEvent *event)
{
- return UI_panel_category_find_mouse_over_ex(ar, event->mval[0], event->mval[1]);
+ return UI_panel_category_find_mouse_over_ex(ar, event->mval[0], event->mval[1]);
}
-
void UI_panel_category_add(ARegion *ar, const char *name)
{
- PanelCategoryDyn *pc_dyn = MEM_callocN(sizeof(*pc_dyn), __func__);
- BLI_addtail(&ar->panels_category, pc_dyn);
+ PanelCategoryDyn *pc_dyn = MEM_callocN(sizeof(*pc_dyn), __func__);
+ BLI_addtail(&ar->panels_category, pc_dyn);
- BLI_strncpy(pc_dyn->idname, name, sizeof(pc_dyn->idname));
+ BLI_strncpy(pc_dyn->idname, name, sizeof(pc_dyn->idname));
- /* 'pc_dyn->rect' must be set on draw */
+ /* 'pc_dyn->rect' must be set on draw */
}
void UI_panel_category_clear_all(ARegion *ar)
{
- BLI_freelistN(&ar->panels_category);
+ BLI_freelistN(&ar->panels_category);
}
static void imm_buf_append(
- float vbuf[][2],
- uchar cbuf[][3],
- float x, float y, const uchar col[3], int *index)
+ float vbuf[][2], uchar cbuf[][3], float x, float y, const uchar col[3], int *index)
{
- ARRAY_SET_ITEMS(vbuf[*index], x, y);
- ARRAY_SET_ITEMS(cbuf[*index], UNPACK3(col));
- (*index)++;
+ ARRAY_SET_ITEMS(vbuf[*index], x, y);
+ ARRAY_SET_ITEMS(cbuf[*index], UNPACK3(col));
+ (*index)++;
}
/* based on UI_draw_roundbox, check on making a version which allows us to skip some sides */
-static void ui_panel_category_draw_tab(
- bool filled, float minx, float miny, float maxx, float maxy, float rad,
- const int roundboxtype,
- const bool use_highlight, const bool use_shadow, const bool use_flip_x,
- const uchar highlight_fade[3],
- const uchar col[3])
+static void ui_panel_category_draw_tab(bool filled,
+ float minx,
+ float miny,
+ float maxx,
+ float maxy,
+ float rad,
+ const int roundboxtype,
+ const bool use_highlight,
+ const bool use_shadow,
+ const bool use_flip_x,
+ const uchar highlight_fade[3],
+ const uchar col[3])
{
- float vec[4][2] = {
- {0.195, 0.02},
- {0.55, 0.169},
- {0.831, 0.45},
- {0.98, 0.805}};
- int a;
-
- /* mult */
- for (a = 0; a < 4; a++) {
- mul_v2_fl(vec[a], rad);
- }
-
- uint vert_len = 0;
- if (use_highlight) {
- vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 6 : 1;
- vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 6 : 1;
- }
- if (use_highlight && !use_shadow) {
- vert_len++;
- }
- else {
- vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 6 : 1;
- vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 6 : 1;
- }
- /* Maximum size. */
- float vbuf[24][2];
- uchar cbuf[24][3];
- int buf_index = 0;
-
- /* start with corner right-top */
- if (use_highlight) {
- if (roundboxtype & UI_CNR_TOP_RIGHT) {
- imm_buf_append(vbuf, cbuf, maxx, maxy - rad, col, &buf_index);
- for (a = 0; a < 4; a++) {
- imm_buf_append(vbuf, cbuf, maxx - vec[a][1], maxy - rad + vec[a][0], col, &buf_index);
- }
- imm_buf_append(vbuf, cbuf, maxx - rad, maxy, col, &buf_index);
- }
- else {
- imm_buf_append(vbuf, cbuf, maxx, maxy, col, &buf_index);
- }
-
- /* corner left-top */
- if (roundboxtype & UI_CNR_TOP_LEFT) {
- imm_buf_append(vbuf, cbuf, minx + rad, maxy, col, &buf_index);
- for (a = 0; a < 4; a++) {
- imm_buf_append(vbuf, cbuf, minx + rad - vec[a][0], maxy - vec[a][1], col, &buf_index);
- }
- imm_buf_append(vbuf, cbuf, minx, maxy - rad, col, &buf_index);
- }
- else {
- imm_buf_append(vbuf, cbuf, minx, maxy, col, &buf_index);
- }
- }
-
- if (use_highlight && !use_shadow) {
- imm_buf_append(vbuf, cbuf, minx, miny + rad, highlight_fade ? col : highlight_fade, &buf_index);
- }
- else {
- /* corner left-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
- imm_buf_append(vbuf, cbuf, minx, miny + rad, col, &buf_index);
- for (a = 0; a < 4; a++) {
- imm_buf_append(vbuf, cbuf, minx + vec[a][1], miny + rad - vec[a][0], col, &buf_index);
- }
- imm_buf_append(vbuf, cbuf, minx + rad, miny, col, &buf_index);
- }
- else {
- imm_buf_append(vbuf, cbuf, minx, miny, col, &buf_index);
- }
-
- /* corner right-bottom */
- if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
- imm_buf_append(vbuf, cbuf, maxx - rad, miny, col, &buf_index);
- for (a = 0; a < 4; a++) {
- imm_buf_append(vbuf, cbuf, maxx - rad + vec[a][0], miny + vec[a][1], col, &buf_index);
- }
- imm_buf_append(vbuf, cbuf, maxx, miny + rad, col, &buf_index);
- }
- else {
- imm_buf_append(vbuf, cbuf, maxx, miny, col, &buf_index);
- }
- }
-
- if (use_flip_x) {
- float midx = (minx + maxx) / 2.0f;
- for (int i = 0; i < buf_index; i++) {
- vbuf[i][0] = midx - (vbuf[i][0] - midx);
- }
-
- }
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_STRIP, vert_len);
- for (int i = 0; i < buf_index; i++) {
- immAttr3ubv(color, cbuf[i]);
- immVertex2fv(pos, vbuf[i]);
- }
- immEnd();
- immUnbindProgram();
+ float vec[4][2] = {{0.195, 0.02}, {0.55, 0.169}, {0.831, 0.45}, {0.98, 0.805}};
+ int a;
+
+ /* mult */
+ for (a = 0; a < 4; a++) {
+ mul_v2_fl(vec[a], rad);
+ }
+
+ uint vert_len = 0;
+ if (use_highlight) {
+ vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 6 : 1;
+ vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 6 : 1;
+ }
+ if (use_highlight && !use_shadow) {
+ vert_len++;
+ }
+ else {
+ vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 6 : 1;
+ vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 6 : 1;
+ }
+ /* Maximum size. */
+ float vbuf[24][2];
+ uchar cbuf[24][3];
+ int buf_index = 0;
+
+ /* start with corner right-top */
+ if (use_highlight) {
+ if (roundboxtype & UI_CNR_TOP_RIGHT) {
+ imm_buf_append(vbuf, cbuf, maxx, maxy - rad, col, &buf_index);
+ for (a = 0; a < 4; a++) {
+ imm_buf_append(vbuf, cbuf, maxx - vec[a][1], maxy - rad + vec[a][0], col, &buf_index);
+ }
+ imm_buf_append(vbuf, cbuf, maxx - rad, maxy, col, &buf_index);
+ }
+ else {
+ imm_buf_append(vbuf, cbuf, maxx, maxy, col, &buf_index);
+ }
+
+ /* corner left-top */
+ if (roundboxtype & UI_CNR_TOP_LEFT) {
+ imm_buf_append(vbuf, cbuf, minx + rad, maxy, col, &buf_index);
+ for (a = 0; a < 4; a++) {
+ imm_buf_append(vbuf, cbuf, minx + rad - vec[a][0], maxy - vec[a][1], col, &buf_index);
+ }
+ imm_buf_append(vbuf, cbuf, minx, maxy - rad, col, &buf_index);
+ }
+ else {
+ imm_buf_append(vbuf, cbuf, minx, maxy, col, &buf_index);
+ }
+ }
+
+ if (use_highlight && !use_shadow) {
+ imm_buf_append(
+ vbuf, cbuf, minx, miny + rad, highlight_fade ? col : highlight_fade, &buf_index);
+ }
+ else {
+ /* corner left-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
+ imm_buf_append(vbuf, cbuf, minx, miny + rad, col, &buf_index);
+ for (a = 0; a < 4; a++) {
+ imm_buf_append(vbuf, cbuf, minx + vec[a][1], miny + rad - vec[a][0], col, &buf_index);
+ }
+ imm_buf_append(vbuf, cbuf, minx + rad, miny, col, &buf_index);
+ }
+ else {
+ imm_buf_append(vbuf, cbuf, minx, miny, col, &buf_index);
+ }
+
+ /* corner right-bottom */
+ if (roundboxtype & UI_CNR_BOTTOM_RIGHT) {
+ imm_buf_append(vbuf, cbuf, maxx - rad, miny, col, &buf_index);
+ for (a = 0; a < 4; a++) {
+ imm_buf_append(vbuf, cbuf, maxx - rad + vec[a][0], miny + vec[a][1], col, &buf_index);
+ }
+ imm_buf_append(vbuf, cbuf, maxx, miny + rad, col, &buf_index);
+ }
+ else {
+ imm_buf_append(vbuf, cbuf, maxx, miny, col, &buf_index);
+ }
+ }
+
+ if (use_flip_x) {
+ float midx = (minx + maxx) / 2.0f;
+ for (int i = 0; i < buf_index; i++) {
+ vbuf[i][0] = midx - (vbuf[i][0] - midx);
+ }
+ }
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(
+ format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+ immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_STRIP, vert_len);
+ for (int i = 0; i < buf_index; i++) {
+ immAttr3ubv(color, cbuf[i]);
+ immVertex2fv(pos, vbuf[i]);
+ }
+ immEnd();
+ immUnbindProgram();
}
-
/**
* Draw vertical tabs on the left side of the region,
* one tab per category.
*/
void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active)
{
- /* no tab outlines for */
-// #define USE_FLAT_INACTIVE
- const bool is_left = (ar->alignment != RGN_ALIGN_RIGHT);
- View2D *v2d = &ar->v2d;
- uiStyle *style = UI_style_get();
- const uiFontStyle *fstyle = &style->widget;
- const int fontid = fstyle->uifont_id;
- short fstyle_points = fstyle->points;
- PanelCategoryDyn *pc_dyn;
- const float aspect = ((uiBlock *)ar->uiblocks.first)->aspect;
- const float zoom = 1.0f / aspect;
- const int px = max_ii(1, round_fl_to_int(U.pixelsize));
- const int px_x_sign = is_left ? px : -px;
- const int category_tabs_width = round_fl_to_int(UI_PANEL_CATEGORY_MARGIN_WIDTH * zoom);
- const float dpi_fac = UI_DPI_FAC;
- /* padding of tabs around text */
- const int tab_v_pad_text = round_fl_to_int((2 + ((px * 3) * dpi_fac)) * zoom);
- /* padding between tabs */
- const int tab_v_pad = round_fl_to_int((4 + (2 * px * dpi_fac)) * zoom);
- const float tab_curve_radius = ((px * 3) * dpi_fac) * zoom;
- /* We flip the tab drawing, so always use these flags. */
- const int roundboxtype = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT;
- bool is_alpha;
- bool do_scaletabs = false;
+ /* no tab outlines for */
+ // #define USE_FLAT_INACTIVE
+ const bool is_left = (ar->alignment != RGN_ALIGN_RIGHT);
+ View2D *v2d = &ar->v2d;
+ uiStyle *style = UI_style_get();
+ const uiFontStyle *fstyle = &style->widget;
+ const int fontid = fstyle->uifont_id;
+ short fstyle_points = fstyle->points;
+ PanelCategoryDyn *pc_dyn;
+ const float aspect = ((uiBlock *)ar->uiblocks.first)->aspect;
+ const float zoom = 1.0f / aspect;
+ const int px = max_ii(1, round_fl_to_int(U.pixelsize));
+ const int px_x_sign = is_left ? px : -px;
+ const int category_tabs_width = round_fl_to_int(UI_PANEL_CATEGORY_MARGIN_WIDTH * zoom);
+ const float dpi_fac = UI_DPI_FAC;
+ /* padding of tabs around text */
+ const int tab_v_pad_text = round_fl_to_int((2 + ((px * 3) * dpi_fac)) * zoom);
+ /* padding between tabs */
+ const int tab_v_pad = round_fl_to_int((4 + (2 * px * dpi_fac)) * zoom);
+ const float tab_curve_radius = ((px * 3) * dpi_fac) * zoom;
+ /* We flip the tab drawing, so always use these flags. */
+ const int roundboxtype = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT;
+ bool is_alpha;
+ bool do_scaletabs = false;
#ifdef USE_FLAT_INACTIVE
- bool is_active_prev = false;
+ bool is_active_prev = false;
#endif
- float scaletabs = 1.0f;
- /* same for all tabs */
- /* intentionally dont scale by 'px' */
- const int rct_xmin = is_left ? v2d->mask.xmin + 3 : (v2d->mask.xmax - category_tabs_width);
- const int rct_xmax = is_left ? v2d->mask.xmin + category_tabs_width : (v2d->mask.xmax - 3);
- const int text_v_ofs = (rct_xmax - rct_xmin) * 0.3f;
-
- int y_ofs = tab_v_pad;
-
- /* Primary theme colors */
- uchar theme_col_back[4];
- uchar theme_col_text[3];
- uchar theme_col_text_hi[3];
-
- /* Tab colors */
- uchar theme_col_tab_bg[4];
- uchar theme_col_tab_active[3];
- uchar theme_col_tab_inactive[3];
-
- /* Secondary theme colors */
- uchar theme_col_tab_outline[3];
- uchar theme_col_tab_divider[3]; /* line that divides tabs from the main region */
- uchar theme_col_tab_highlight[3];
- uchar theme_col_tab_highlight_inactive[3];
-
-
-
- UI_GetThemeColor4ubv(TH_BACK, theme_col_back);
- UI_GetThemeColor3ubv(TH_TEXT, theme_col_text);
- UI_GetThemeColor3ubv(TH_TEXT_HI, theme_col_text_hi);
-
- UI_GetThemeColor4ubv(TH_TAB_BACK, theme_col_tab_bg);
- UI_GetThemeColor3ubv(TH_TAB_ACTIVE, theme_col_tab_active);
- UI_GetThemeColor3ubv(TH_TAB_INACTIVE, theme_col_tab_inactive);
- UI_GetThemeColor3ubv(TH_TAB_OUTLINE, theme_col_tab_outline);
-
- interp_v3_v3v3_uchar(theme_col_tab_divider, theme_col_back, theme_col_tab_outline, 0.3f);
- interp_v3_v3v3_uchar(theme_col_tab_highlight, theme_col_back, theme_col_text_hi, 0.2f);
- interp_v3_v3v3_uchar(theme_col_tab_highlight_inactive, theme_col_tab_inactive, theme_col_text_hi, 0.12f);
-
- is_alpha = (ar->overlap && (theme_col_back[3] != 255));
-
- if (fstyle->kerning == 1) {
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- BLF_enable(fontid, BLF_ROTATION);
- BLF_rotation(fontid, M_PI_2);
- //UI_fontstyle_set(&style->widget);
- ui_fontscale(&fstyle_points, aspect / (U.pixelsize * 1.1f));
- BLF_size(fontid, fstyle_points, U.dpi);
-
- BLI_assert(UI_panel_category_is_visible(ar));
-
-
- /* calculate tab rect's and check if we need to scale down */
- for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
- rcti *rct = &pc_dyn->rect;
- const char *category_id = pc_dyn->idname;
- const char *category_id_draw = IFACE_(category_id);
- const int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX);
-
- rct->xmin = rct_xmin;
- rct->xmax = rct_xmax;
-
- rct->ymin = v2d->mask.ymax - (y_ofs + category_width + (tab_v_pad_text * 2));
- rct->ymax = v2d->mask.ymax - (y_ofs);
-
- y_ofs += category_width + tab_v_pad + (tab_v_pad_text * 2);
- }
-
- if (y_ofs > BLI_rcti_size_y(&v2d->mask)) {
- scaletabs = (float)BLI_rcti_size_y(&v2d->mask) / (float)y_ofs;
-
- for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
- rcti *rct = &pc_dyn->rect;
- rct->ymin = ((rct->ymin - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax;
- rct->ymax = ((rct->ymax - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax;
- }
-
- do_scaletabs = true;
- }
-
-
- /* begin drawing */
- GPU_line_smooth(true);
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* draw the background */
- if (is_alpha) {
- GPU_blend(true);
- immUniformColor4ubv(theme_col_tab_bg);
- }
- else {
- immUniformColor3ubv(theme_col_tab_bg);
- }
-
- if (is_left) {
- immRecti(pos, v2d->mask.xmin, v2d->mask.ymin, v2d->mask.xmin + category_tabs_width, v2d->mask.ymax);
- }
- else {
- immRecti(pos, v2d->mask.xmax - category_tabs_width, v2d->mask.ymin, v2d->mask.xmax, v2d->mask.ymax);
- }
-
- if (is_alpha) {
- GPU_blend(false);
- }
-
- immUnbindProgram();
-
- const int divider_xmin =
- is_left ? (v2d->mask.xmin + (category_tabs_width - px)) : (v2d->mask.xmax - category_tabs_width) + px;
- const int divider_xmax =
- is_left ? (v2d->mask.xmin + category_tabs_width) : (v2d->mask.xmax - (category_tabs_width + px)) + px;
-
- for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
- const rcti *rct = &pc_dyn->rect;
- const char *category_id = pc_dyn->idname;
- const char *category_id_draw = IFACE_(category_id);
- int category_width = BLI_rcti_size_y(rct) - (tab_v_pad_text * 2);
- size_t category_draw_len = BLF_DRAW_STR_DUMMY_MAX;
- // int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX);
-
- const bool is_active = STREQ(category_id, category_id_active);
-
- GPU_blend(true);
+ float scaletabs = 1.0f;
+ /* same for all tabs */
+ /* intentionally dont scale by 'px' */
+ const int rct_xmin = is_left ? v2d->mask.xmin + 3 : (v2d->mask.xmax - category_tabs_width);
+ const int rct_xmax = is_left ? v2d->mask.xmin + category_tabs_width : (v2d->mask.xmax - 3);
+ const int text_v_ofs = (rct_xmax - rct_xmin) * 0.3f;
+
+ int y_ofs = tab_v_pad;
+
+ /* Primary theme colors */
+ uchar theme_col_back[4];
+ uchar theme_col_text[3];
+ uchar theme_col_text_hi[3];
+
+ /* Tab colors */
+ uchar theme_col_tab_bg[4];
+ uchar theme_col_tab_active[3];
+ uchar theme_col_tab_inactive[3];
+
+ /* Secondary theme colors */
+ uchar theme_col_tab_outline[3];
+ uchar theme_col_tab_divider[3]; /* line that divides tabs from the main region */
+ uchar theme_col_tab_highlight[3];
+ uchar theme_col_tab_highlight_inactive[3];
+
+ UI_GetThemeColor4ubv(TH_BACK, theme_col_back);
+ UI_GetThemeColor3ubv(TH_TEXT, theme_col_text);
+ UI_GetThemeColor3ubv(TH_TEXT_HI, theme_col_text_hi);
+
+ UI_GetThemeColor4ubv(TH_TAB_BACK, theme_col_tab_bg);
+ UI_GetThemeColor3ubv(TH_TAB_ACTIVE, theme_col_tab_active);
+ UI_GetThemeColor3ubv(TH_TAB_INACTIVE, theme_col_tab_inactive);
+ UI_GetThemeColor3ubv(TH_TAB_OUTLINE, theme_col_tab_outline);
+
+ interp_v3_v3v3_uchar(theme_col_tab_divider, theme_col_back, theme_col_tab_outline, 0.3f);
+ interp_v3_v3v3_uchar(theme_col_tab_highlight, theme_col_back, theme_col_text_hi, 0.2f);
+ interp_v3_v3v3_uchar(
+ theme_col_tab_highlight_inactive, theme_col_tab_inactive, theme_col_text_hi, 0.12f);
+
+ is_alpha = (ar->overlap && (theme_col_back[3] != 255));
+
+ if (fstyle->kerning == 1) {
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ BLF_enable(fontid, BLF_ROTATION);
+ BLF_rotation(fontid, M_PI_2);
+ //UI_fontstyle_set(&style->widget);
+ ui_fontscale(&fstyle_points, aspect / (U.pixelsize * 1.1f));
+ BLF_size(fontid, fstyle_points, U.dpi);
+
+ BLI_assert(UI_panel_category_is_visible(ar));
+
+ /* calculate tab rect's and check if we need to scale down */
+ for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
+ rcti *rct = &pc_dyn->rect;
+ const char *category_id = pc_dyn->idname;
+ const char *category_id_draw = IFACE_(category_id);
+ const int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX);
+
+ rct->xmin = rct_xmin;
+ rct->xmax = rct_xmax;
+
+ rct->ymin = v2d->mask.ymax - (y_ofs + category_width + (tab_v_pad_text * 2));
+ rct->ymax = v2d->mask.ymax - (y_ofs);
+
+ y_ofs += category_width + tab_v_pad + (tab_v_pad_text * 2);
+ }
+
+ if (y_ofs > BLI_rcti_size_y(&v2d->mask)) {
+ scaletabs = (float)BLI_rcti_size_y(&v2d->mask) / (float)y_ofs;
+
+ for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
+ rcti *rct = &pc_dyn->rect;
+ rct->ymin = ((rct->ymin - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax;
+ rct->ymax = ((rct->ymax - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax;
+ }
+
+ do_scaletabs = true;
+ }
+
+ /* begin drawing */
+ GPU_line_smooth(true);
+
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* draw the background */
+ if (is_alpha) {
+ GPU_blend(true);
+ immUniformColor4ubv(theme_col_tab_bg);
+ }
+ else {
+ immUniformColor3ubv(theme_col_tab_bg);
+ }
+
+ if (is_left) {
+ immRecti(
+ pos, v2d->mask.xmin, v2d->mask.ymin, v2d->mask.xmin + category_tabs_width, v2d->mask.ymax);
+ }
+ else {
+ immRecti(
+ pos, v2d->mask.xmax - category_tabs_width, v2d->mask.ymin, v2d->mask.xmax, v2d->mask.ymax);
+ }
+
+ if (is_alpha) {
+ GPU_blend(false);
+ }
+
+ immUnbindProgram();
+
+ const int divider_xmin = is_left ? (v2d->mask.xmin + (category_tabs_width - px)) :
+ (v2d->mask.xmax - category_tabs_width) + px;
+ const int divider_xmax = is_left ? (v2d->mask.xmin + category_tabs_width) :
+ (v2d->mask.xmax - (category_tabs_width + px)) + px;
+
+ for (pc_dyn = ar->panels_category.first; pc_dyn; pc_dyn = pc_dyn->next) {
+ const rcti *rct = &pc_dyn->rect;
+ const char *category_id = pc_dyn->idname;
+ const char *category_id_draw = IFACE_(category_id);
+ int category_width = BLI_rcti_size_y(rct) - (tab_v_pad_text * 2);
+ size_t category_draw_len = BLF_DRAW_STR_DUMMY_MAX;
+ // int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX);
+
+ const bool is_active = STREQ(category_id, category_id_active);
+
+ GPU_blend(true);
#ifdef USE_FLAT_INACTIVE
- if (is_active)
+ if (is_active)
#endif
- {
- const bool use_flip_x = !is_left;
- ui_panel_category_draw_tab(
- true, rct->xmin, rct->ymin, rct->xmax, rct->ymax,
- tab_curve_radius - px, roundboxtype, true, true, use_flip_x,
- NULL,
- is_active ? theme_col_tab_active : theme_col_tab_inactive);
-
- /* tab outline */
- ui_panel_category_draw_tab(
- false, rct->xmin - px_x_sign, rct->ymin - px, rct->xmax - px_x_sign, rct->ymax + px,
- tab_curve_radius, roundboxtype, true, true, use_flip_x,
- NULL,
- theme_col_tab_outline);
-
- /* tab highlight (3d look) */
- ui_panel_category_draw_tab(
- false, rct->xmin, rct->ymin, rct->xmax, rct->ymax,
- tab_curve_radius, roundboxtype, true, false, use_flip_x,
- is_active ? theme_col_back : theme_col_tab_inactive,
- is_active ? theme_col_tab_highlight : theme_col_tab_highlight_inactive);
- }
-
- /* tab blackline */
- if (!is_active) {
- pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor3ubv(theme_col_tab_divider);
- immRecti(pos,
- divider_xmin,
- rct->ymin - tab_v_pad,
- divider_xmax,
- rct->ymax + tab_v_pad);
- immUnbindProgram();
- }
-
- if (do_scaletabs) {
- category_draw_len = BLF_width_to_strlen(
- fontid, category_id_draw, category_draw_len,
- category_width, NULL);
- }
-
- BLF_position(fontid, rct->xmax - text_v_ofs, rct->ymin + tab_v_pad_text, 0.0f);
-
- /* tab titles */
-
- /* draw white shadow to give text more depth */
- BLF_color3ubv(fontid, theme_col_text);
-
- /* main tab title */
- BLF_draw(fontid, category_id_draw, category_draw_len);
-
- GPU_blend(false);
-
- /* tab blackline remaining (last tab) */
- pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- if (pc_dyn->prev == NULL) {
- immUniformColor3ubv(theme_col_tab_divider);
- immRecti(pos,
- divider_xmin,
- rct->ymax + px,
- divider_xmax,
- v2d->mask.ymax);
- }
- if (pc_dyn->next == NULL) {
- immUniformColor3ubv(theme_col_tab_divider);
- immRecti(pos,
- divider_xmin,
- 0,
- divider_xmax,
- rct->ymin);
- }
+ {
+ const bool use_flip_x = !is_left;
+ ui_panel_category_draw_tab(true,
+ rct->xmin,
+ rct->ymin,
+ rct->xmax,
+ rct->ymax,
+ tab_curve_radius - px,
+ roundboxtype,
+ true,
+ true,
+ use_flip_x,
+ NULL,
+ is_active ? theme_col_tab_active : theme_col_tab_inactive);
+
+ /* tab outline */
+ ui_panel_category_draw_tab(false,
+ rct->xmin - px_x_sign,
+ rct->ymin - px,
+ rct->xmax - px_x_sign,
+ rct->ymax + px,
+ tab_curve_radius,
+ roundboxtype,
+ true,
+ true,
+ use_flip_x,
+ NULL,
+ theme_col_tab_outline);
+
+ /* tab highlight (3d look) */
+ ui_panel_category_draw_tab(false,
+ rct->xmin,
+ rct->ymin,
+ rct->xmax,
+ rct->ymax,
+ tab_curve_radius,
+ roundboxtype,
+ true,
+ false,
+ use_flip_x,
+ is_active ? theme_col_back : theme_col_tab_inactive,
+ is_active ? theme_col_tab_highlight :
+ theme_col_tab_highlight_inactive);
+ }
+
+ /* tab blackline */
+ if (!is_active) {
+ pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos, divider_xmin, rct->ymin - tab_v_pad, divider_xmax, rct->ymax + tab_v_pad);
+ immUnbindProgram();
+ }
+
+ if (do_scaletabs) {
+ category_draw_len = BLF_width_to_strlen(
+ fontid, category_id_draw, category_draw_len, category_width, NULL);
+ }
+
+ BLF_position(fontid, rct->xmax - text_v_ofs, rct->ymin + tab_v_pad_text, 0.0f);
+
+ /* tab titles */
+
+ /* draw white shadow to give text more depth */
+ BLF_color3ubv(fontid, theme_col_text);
+
+ /* main tab title */
+ BLF_draw(fontid, category_id_draw, category_draw_len);
+
+ GPU_blend(false);
+
+ /* tab blackline remaining (last tab) */
+ pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ if (pc_dyn->prev == NULL) {
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos, divider_xmin, rct->ymax + px, divider_xmax, v2d->mask.ymax);
+ }
+ if (pc_dyn->next == NULL) {
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos, divider_xmin, 0, divider_xmax, rct->ymin);
+ }
#ifdef USE_FLAT_INACTIVE
- /* draw line between inactive tabs */
- if (is_active == false && is_active_prev == false && pc_dyn->prev) {
- immUniformColor3ubv(theme_col_tab_divider);
- immRecti(pos, v2d->mask.xmin + (category_tabs_width / 5),
- rct->ymax + px,
- (v2d->mask.xmin + category_tabs_width) - (category_tabs_width / 5),
- rct->ymax + (px * 3));
- }
-
- is_active_prev = is_active;
+ /* draw line between inactive tabs */
+ if (is_active == false && is_active_prev == false && pc_dyn->prev) {
+ immUniformColor3ubv(theme_col_tab_divider);
+ immRecti(pos,
+ v2d->mask.xmin + (category_tabs_width / 5),
+ rct->ymax + px,
+ (v2d->mask.xmin + category_tabs_width) - (category_tabs_width / 5),
+ rct->ymax + (px * 3));
+ }
+
+ is_active_prev = is_active;
#endif
- immUnbindProgram();
+ immUnbindProgram();
- /* not essential, but allows events to be handled right up until the region edge [#38171] */
- if (is_left) {
- pc_dyn->rect.xmin = v2d->mask.xmin;
- }
- else {
- pc_dyn->rect.xmax = v2d->mask.xmax;
- }
- }
+ /* not essential, but allows events to be handled right up until the region edge [#38171] */
+ if (is_left) {
+ pc_dyn->rect.xmin = v2d->mask.xmin;
+ }
+ else {
+ pc_dyn->rect.xmax = v2d->mask.xmax;
+ }
+ }
- GPU_line_smooth(false);
+ GPU_line_smooth(false);
- BLF_disable(fontid, BLF_ROTATION);
+ BLF_disable(fontid, BLF_ROTATION);
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
#undef USE_FLAT_INACTIVE
}
-static int ui_handle_panel_category_cycling(const wmEvent *event, ARegion *ar, const uiBut *active_but)
+static int ui_handle_panel_category_cycling(const wmEvent *event,
+ ARegion *ar,
+ const uiBut *active_but)
{
- const bool is_mousewheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
- const bool inside_tabregion = (
- (ar->alignment != RGN_ALIGN_RIGHT) ?
- (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax) :
- (event->mval[0] > ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmin));
-
- /* if mouse is inside non-tab region, ctrl key is required */
- if (is_mousewheel && !event->ctrl && !inside_tabregion) {
- return WM_UI_HANDLER_CONTINUE;
- }
-
-
- if (active_but && ui_but_supports_cycling(active_but)) {
- /* skip - exception to make cycling buttons
- * using ctrl+mousewheel work in tabbed regions */
- }
- else {
- const char *category = UI_panel_category_active_get(ar, false);
- if (LIKELY(category)) {
- PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category);
- if (LIKELY(pc_dyn)) {
- if (is_mousewheel) {
- /* we can probably get rid of this and only allow ctrl+tabbing */
- pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
- }
- else {
- const bool backwards = event->shift;
- pc_dyn = backwards ? pc_dyn->prev : pc_dyn->next;
- if (!pc_dyn) {
- /* proper cyclic behavior,
- * back to first/last category (only used for ctrl+tab) */
- pc_dyn = backwards ? ar->panels_category.last : ar->panels_category.first;
- }
- }
-
- if (pc_dyn) {
- /* intentionally don't reset scroll in this case,
- * this allows for quick browsing between tabs */
- UI_panel_category_active_set(ar, pc_dyn->idname);
- ED_region_tag_redraw(ar);
- }
- }
- }
- return WM_UI_HANDLER_BREAK;
- }
-
- return WM_UI_HANDLER_CONTINUE;
+ const bool is_mousewheel = ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
+ const bool inside_tabregion =
+ ((ar->alignment != RGN_ALIGN_RIGHT) ?
+ (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax) :
+ (event->mval[0] > ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmin));
+
+ /* if mouse is inside non-tab region, ctrl key is required */
+ if (is_mousewheel && !event->ctrl && !inside_tabregion) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+
+ if (active_but && ui_but_supports_cycling(active_but)) {
+ /* skip - exception to make cycling buttons
+ * using ctrl+mousewheel work in tabbed regions */
+ }
+ else {
+ const char *category = UI_panel_category_active_get(ar, false);
+ if (LIKELY(category)) {
+ PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category);
+ if (LIKELY(pc_dyn)) {
+ if (is_mousewheel) {
+ /* we can probably get rid of this and only allow ctrl+tabbing */
+ pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev;
+ }
+ else {
+ const bool backwards = event->shift;
+ pc_dyn = backwards ? pc_dyn->prev : pc_dyn->next;
+ if (!pc_dyn) {
+ /* proper cyclic behavior,
+ * back to first/last category (only used for ctrl+tab) */
+ pc_dyn = backwards ? ar->panels_category.last : ar->panels_category.first;
+ }
+ }
+
+ if (pc_dyn) {
+ /* intentionally don't reset scroll in this case,
+ * this allows for quick browsing between tabs */
+ UI_panel_category_active_set(ar, pc_dyn->idname);
+ ED_region_tag_redraw(ar);
+ }
+ }
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
}
/* XXX should become modal keymap */
/* AKey is opening/closing panels, independent of button state now */
-int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, const uiBut *active_but)
+int ui_handler_panel_region(bContext *C,
+ const wmEvent *event,
+ ARegion *ar,
+ const uiBut *active_but)
{
- uiBlock *block;
- Panel *pa;
- int retval, mx, my;
- bool has_category_tabs = UI_panel_category_is_visible(ar);
-
- retval = WM_UI_HANDLER_CONTINUE;
-
- /* Scrollbars can overlap panels now, they have handling priority. */
- if (UI_view2d_mouse_in_scrollers(ar, &ar->v2d, event->x, event->y)) {
- return retval;
- }
-
- /* handle category tabs */
- if (has_category_tabs) {
- if (event->val == KM_PRESS) {
- if (event->type == LEFTMOUSE) {
- PanelCategoryDyn *pc_dyn = UI_panel_category_find_mouse_over(ar, event);
- if (pc_dyn) {
- UI_panel_category_active_set(ar, pc_dyn->idname);
- ED_region_tag_redraw(ar);
-
- /* reset scroll to the top [#38348] */
- UI_view2d_offset(&ar->v2d, -1.0f, 1.0f);
-
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- else if ((event->type == TABKEY && event->ctrl) || ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
- /* cycle tabs */
- retval = ui_handle_panel_category_cycling(event, ar, active_but);
- }
- }
- }
-
- if (retval == WM_UI_HANDLER_BREAK) {
- return retval;
- }
-
- for (block = ar->uiblocks.last; block; block = block->prev) {
- uiPanelMouseState mouse_state;
-
- mx = event->x;
- my = event->y;
- ui_window_to_block(ar, block, &mx, &my);
-
- /* checks for mouse position inside */
- pa = block->panel;
-
- if (!pa || pa->paneltab != NULL) {
- continue;
- }
- /* XXX - accessed freed panels when scripts reload, need to fix. */
- if (pa->type && pa->type->flag & PNL_NO_HEADER) {
- continue;
- }
-
- mouse_state = ui_panel_mouse_state_get(block, pa, mx, my);
-
- /* XXX hardcoded key warning */
- if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER) && event->val == KM_PRESS) {
- if (event->type == AKEY && ((event->ctrl + event->oskey + event->shift + event->alt) == 0)) {
-
- if (pa->flag & PNL_CLOSEDY) {
- if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
- ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift);
- }
- }
- else {
- ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift);
- }
-
- retval = WM_UI_HANDLER_BREAK;
- continue;
- }
- }
-
- /* on active button, do not handle panels */
- if (ui_region_find_active_but(ar) != NULL) {
- continue;
- }
-
- if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) {
-
- if (event->val == KM_PRESS) {
-
- /* open close on header */
- if (ELEM(event->type, RETKEY, PADENTER)) {
- if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
- ui_handle_panel_header(C, block, mx, my, RETKEY, event->ctrl, event->shift);
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
- }
- else if (event->type == LEFTMOUSE) {
- /* all inside clicks should return in break - overlapping/float panels */
- retval = WM_UI_HANDLER_BREAK;
-
- if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
- ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift);
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
- else if ((mouse_state == PANEL_MOUSE_INSIDE_SCALE) && !(pa->flag & PNL_CLOSED)) {
- panel_activate_state(C, pa, PANEL_STATE_DRAG_SCALE);
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
-
- }
- else if (event->type == RIGHTMOUSE) {
- if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
- ui_popup_context_menu_for_panel(C, ar, block->panel);
- retval = WM_UI_HANDLER_BREAK;
- break;
- }
- }
- else if (event->type == ESCKEY) {
- /*XXX 2.50*/
+ uiBlock *block;
+ Panel *pa;
+ int retval, mx, my;
+ bool has_category_tabs = UI_panel_category_is_visible(ar);
+
+ retval = WM_UI_HANDLER_CONTINUE;
+
+ /* Scrollbars can overlap panels now, they have handling priority. */
+ if (UI_view2d_mouse_in_scrollers(ar, &ar->v2d, event->x, event->y)) {
+ return retval;
+ }
+
+ /* handle category tabs */
+ if (has_category_tabs) {
+ if (event->val == KM_PRESS) {
+ if (event->type == LEFTMOUSE) {
+ PanelCategoryDyn *pc_dyn = UI_panel_category_find_mouse_over(ar, event);
+ if (pc_dyn) {
+ UI_panel_category_active_set(ar, pc_dyn->idname);
+ ED_region_tag_redraw(ar);
+
+ /* reset scroll to the top [#38348] */
+ UI_view2d_offset(&ar->v2d, -1.0f, 1.0f);
+
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if ((event->type == TABKEY && event->ctrl) ||
+ ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
+ /* cycle tabs */
+ retval = ui_handle_panel_category_cycling(event, ar, active_but);
+ }
+ }
+ }
+
+ if (retval == WM_UI_HANDLER_BREAK) {
+ return retval;
+ }
+
+ for (block = ar->uiblocks.last; block; block = block->prev) {
+ uiPanelMouseState mouse_state;
+
+ mx = event->x;
+ my = event->y;
+ ui_window_to_block(ar, block, &mx, &my);
+
+ /* checks for mouse position inside */
+ pa = block->panel;
+
+ if (!pa || pa->paneltab != NULL) {
+ continue;
+ }
+ /* XXX - accessed freed panels when scripts reload, need to fix. */
+ if (pa->type && pa->type->flag & PNL_NO_HEADER) {
+ continue;
+ }
+
+ mouse_state = ui_panel_mouse_state_get(block, pa, mx, my);
+
+ /* XXX hardcoded key warning */
+ if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER) &&
+ event->val == KM_PRESS) {
+ if (event->type == AKEY && ((event->ctrl + event->oskey + event->shift + event->alt) == 0)) {
+
+ if (pa->flag & PNL_CLOSEDY) {
+ if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) {
+ ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift);
+ }
+ }
+ else {
+ ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift);
+ }
+
+ retval = WM_UI_HANDLER_BREAK;
+ continue;
+ }
+ }
+
+ /* on active button, do not handle panels */
+ if (ui_region_find_active_but(ar) != NULL) {
+ continue;
+ }
+
+ if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) {
+
+ if (event->val == KM_PRESS) {
+
+ /* open close on header */
+ if (ELEM(event->type, RETKEY, PADENTER)) {
+ if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
+ ui_handle_panel_header(C, block, mx, my, RETKEY, event->ctrl, event->shift);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+ }
+ else if (event->type == LEFTMOUSE) {
+ /* all inside clicks should return in break - overlapping/float panels */
+ retval = WM_UI_HANDLER_BREAK;
+
+ if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
+ ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+ else if ((mouse_state == PANEL_MOUSE_INSIDE_SCALE) && !(pa->flag & PNL_CLOSED)) {
+ panel_activate_state(C, pa, PANEL_STATE_DRAG_SCALE);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+ }
+ else if (event->type == RIGHTMOUSE) {
+ if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) {
+ ui_popup_context_menu_for_panel(C, ar, block->panel);
+ retval = WM_UI_HANDLER_BREAK;
+ break;
+ }
+ }
+ else if (event->type == ESCKEY) {
+ /*XXX 2.50*/
#if 0
- if (block->handler) {
- rem_blockhandler(sa, block->handler);
- ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
+ if (block->handler) {
+ rem_blockhandler(sa, block->handler);
+ ED_region_tag_redraw(ar);
+ retval = WM_UI_HANDLER_BREAK;
+ }
#endif
- }
- else if (event->type == PADPLUSKEY || event->type == PADMINUS) {
+ }
+ else if (event->type == PADPLUSKEY || event->type == PADMINUS) {
#if 0 /* XXX make float panel exception? */
- int zoom = 0;
-
- /* if panel is closed, only zoom if mouse is over the header */
- if (pa->flag & (PNL_CLOSEDX | PNL_CLOSEDY)) {
- if (inside_header) {
- zoom = 1;
- }
- }
- else {
- zoom = 1;
- }
-
- if (zoom) {
- ScrArea *sa = CTX_wm_area(C);
- SpaceLink *sl = sa->spacedata.first;
-
- if (sa->spacetype != SPACE_PROPERTIES) {
- if (!(pa->control & UI_PNL_SCALE)) {
- if (event->type == PADPLUSKEY) {
- sl->blockscale += 0.1;
- }
- else {
- sl->blockscale -= 0.1;
- }
- CLAMP(sl->blockscale, 0.6, 1.0);
-
- ED_region_tag_redraw(ar);
- retval = WM_UI_HANDLER_BREAK;
- }
- }
- }
+ int zoom = 0;
+
+ /* if panel is closed, only zoom if mouse is over the header */
+ if (pa->flag & (PNL_CLOSEDX | PNL_CLOSEDY)) {
+ if (inside_header) {
+ zoom = 1;
+ }
+ }
+ else {
+ zoom = 1;
+ }
+
+ if (zoom) {
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceLink *sl = sa->spacedata.first;
+
+ if (sa->spacetype != SPACE_PROPERTIES) {
+ if (!(pa->control & UI_PNL_SCALE)) {
+ if (event->type == PADPLUSKEY) {
+ sl->blockscale += 0.1;
+ }
+ else {
+ sl->blockscale -= 0.1;
+ }
+ CLAMP(sl->blockscale, 0.6, 1.0);
+
+ ED_region_tag_redraw(ar);
+ retval = WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
#endif
- }
- }
- }
- }
+ }
+ }
+ }
+ }
- return retval;
+ return retval;
}
/**************** window level modal panel interaction **************/
@@ -2471,125 +2503,127 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, cons
/* note, this is modal handler and should not swallow events for animation */
static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
{
- Panel *panel = userdata;
- uiHandlePanelData *data = panel->activedata;
-
- /* verify if we can stop */
- if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- int align = panel_aligned(sa, ar);
-
- if (align) {
- panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
- }
- else {
- panel_activate_state(C, panel, PANEL_STATE_EXIT);
- }
- }
- else if (event->type == MOUSEMOVE) {
- if (data->state == PANEL_STATE_DRAG) {
- ui_do_drag(C, event, panel);
- }
- }
- else if (event->type == TIMER && event->customdata == data->animtimer) {
- if (data->state == PANEL_STATE_ANIMATION) {
- ui_do_animate(C, panel);
- }
- else if (data->state == PANEL_STATE_DRAG) {
- ui_do_drag(C, event, panel);
- }
- }
-
- data = panel->activedata;
-
- if (data && data->state == PANEL_STATE_ANIMATION) {
- return WM_UI_HANDLER_CONTINUE;
- }
- else {
- return WM_UI_HANDLER_BREAK;
- }
+ Panel *panel = userdata;
+ uiHandlePanelData *data = panel->activedata;
+
+ /* verify if we can stop */
+ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ int align = panel_aligned(sa, ar);
+
+ if (align) {
+ panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
+ }
+ else {
+ panel_activate_state(C, panel, PANEL_STATE_EXIT);
+ }
+ }
+ else if (event->type == MOUSEMOVE) {
+ if (data->state == PANEL_STATE_DRAG) {
+ ui_do_drag(C, event, panel);
+ }
+ }
+ else if (event->type == TIMER && event->customdata == data->animtimer) {
+ if (data->state == PANEL_STATE_ANIMATION) {
+ ui_do_animate(C, panel);
+ }
+ else if (data->state == PANEL_STATE_DRAG) {
+ ui_do_drag(C, event, panel);
+ }
+ }
+
+ data = panel->activedata;
+
+ if (data && data->state == PANEL_STATE_ANIMATION) {
+ return WM_UI_HANDLER_CONTINUE;
+ }
+ else {
+ return WM_UI_HANDLER_BREAK;
+ }
}
static void ui_handler_remove_panel(bContext *C, void *userdata)
{
- Panel *pa = userdata;
+ Panel *pa = userdata;
- panel_activate_state(C, pa, PANEL_STATE_EXIT);
+ panel_activate_state(C, pa, PANEL_STATE_EXIT);
}
static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state)
{
- uiHandlePanelData *data = pa->activedata;
- wmWindow *win = CTX_wm_window(C);
- ARegion *ar = CTX_wm_region(C);
-
- if (data && data->state == state) {
- return;
- }
-
- if (state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) {
- if (data && data->state != PANEL_STATE_ANIMATION) {
- /* XXX:
- * - the panel tabbing function call below (test_add_new_tabs()) has been commented out
- * "It is too easy to do by accident when reordering panels,
- * is very hard to control and use, and has no real benefit." - BillRey
- * Aligorith, 2009Sep
- */
- //test_add_new_tabs(ar); // also copies locations of tabs in dragged panel
- check_panel_overlap(ar, NULL); /* clears */
- }
-
- pa->flag &= ~PNL_SELECT;
- }
- else {
- pa->flag |= PNL_SELECT;
- }
-
- if (data && data->animtimer) {
- WM_event_remove_timer(CTX_wm_manager(C), win, data->animtimer);
- data->animtimer = NULL;
- }
-
- if (state == PANEL_STATE_EXIT) {
- MEM_freeN(data);
- pa->activedata = NULL;
-
- WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, false);
- }
- else {
- if (!data) {
- data = MEM_callocN(sizeof(uiHandlePanelData), "uiHandlePanelData");
- pa->activedata = data;
-
- WM_event_add_ui_handler(C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, 0);
- }
-
- if (ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG)) {
- data->animtimer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, ANIMATION_INTERVAL);
- }
-
- data->state = state;
- data->startx = win->eventstate->x;
- data->starty = win->eventstate->y;
- data->startofsx = pa->ofsx;
- data->startofsy = pa->ofsy;
- data->startsizex = pa->sizex;
- data->startsizey = pa->sizey;
- data->starttime = PIL_check_seconds_timer();
- }
-
- ED_region_tag_redraw(ar);
+ uiHandlePanelData *data = pa->activedata;
+ wmWindow *win = CTX_wm_window(C);
+ ARegion *ar = CTX_wm_region(C);
+
+ if (data && data->state == state) {
+ return;
+ }
+
+ if (state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) {
+ if (data && data->state != PANEL_STATE_ANIMATION) {
+ /* XXX:
+ * - the panel tabbing function call below (test_add_new_tabs()) has been commented out
+ * "It is too easy to do by accident when reordering panels,
+ * is very hard to control and use, and has no real benefit." - BillRey
+ * Aligorith, 2009Sep
+ */
+ //test_add_new_tabs(ar); // also copies locations of tabs in dragged panel
+ check_panel_overlap(ar, NULL); /* clears */
+ }
+
+ pa->flag &= ~PNL_SELECT;
+ }
+ else {
+ pa->flag |= PNL_SELECT;
+ }
+
+ if (data && data->animtimer) {
+ WM_event_remove_timer(CTX_wm_manager(C), win, data->animtimer);
+ data->animtimer = NULL;
+ }
+
+ if (state == PANEL_STATE_EXIT) {
+ MEM_freeN(data);
+ pa->activedata = NULL;
+
+ WM_event_remove_ui_handler(
+ &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, false);
+ }
+ else {
+ if (!data) {
+ data = MEM_callocN(sizeof(uiHandlePanelData), "uiHandlePanelData");
+ pa->activedata = data;
+
+ WM_event_add_ui_handler(
+ C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, 0);
+ }
+
+ if (ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG)) {
+ data->animtimer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, ANIMATION_INTERVAL);
+ }
+
+ data->state = state;
+ data->startx = win->eventstate->x;
+ data->starty = win->eventstate->y;
+ data->startofsx = pa->ofsx;
+ data->startofsy = pa->ofsy;
+ data->startsizex = pa->sizex;
+ data->startsizey = pa->sizey;
+ data->starttime = PIL_check_seconds_timer();
+ }
+
+ ED_region_tag_redraw(ar);
}
PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname)
{
- SpaceType *st = BKE_spacetype_from_id(space_id);
- if (st) {
- ARegionType *art = BKE_regiontype_from_id(st, region_id);
- if (art) {
- return BLI_findstring(&art->paneltypes, idname, offsetof(PanelType, idname));
- }
- }
- return NULL;
+ SpaceType *st = BKE_spacetype_from_id(space_id);
+ if (st) {
+ ARegionType *art = BKE_regiontype_from_id(st, region_id);
+ if (art) {
+ return BLI_findstring(&art->paneltypes, idname, offsetof(PanelType, idname));
+ }
+ }
+ return NULL;
}
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 1954e20ab8b..be09e44fa9d 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -40,37 +40,33 @@
/** \name Button (#uiBut) State
* \{ */
-
bool ui_but_is_editable(const uiBut *but)
{
- return !ELEM(
- but->type,
- UI_BTYPE_LABEL, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE,
- UI_BTYPE_ROUNDBOX, UI_BTYPE_LISTBOX, UI_BTYPE_PROGRESS_BAR);
+ return !ELEM(but->type,
+ UI_BTYPE_LABEL,
+ UI_BTYPE_SEPR,
+ UI_BTYPE_SEPR_LINE,
+ UI_BTYPE_ROUNDBOX,
+ UI_BTYPE_LISTBOX,
+ UI_BTYPE_PROGRESS_BAR);
}
bool ui_but_is_editable_as_text(const uiBut *but)
{
- return ELEM(
- but->type,
- UI_BTYPE_TEXT, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER,
- UI_BTYPE_SEARCH_MENU);
-
+ return ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_SEARCH_MENU);
}
bool ui_but_is_toggle(const uiBut *but)
{
- return ELEM(
- but->type,
- UI_BTYPE_BUT_TOGGLE,
- UI_BTYPE_TOGGLE,
- UI_BTYPE_ICON_TOGGLE,
- UI_BTYPE_ICON_TOGGLE_N,
- UI_BTYPE_TOGGLE_N,
- UI_BTYPE_CHECKBOX,
- UI_BTYPE_CHECKBOX_N,
- UI_BTYPE_ROW
- );
+ return ELEM(but->type,
+ UI_BTYPE_BUT_TOGGLE,
+ UI_BTYPE_TOGGLE,
+ UI_BTYPE_ICON_TOGGLE,
+ UI_BTYPE_ICON_TOGGLE_N,
+ UI_BTYPE_TOGGLE_N,
+ UI_BTYPE_CHECKBOX,
+ UI_BTYPE_CHECKBOX_N,
+ UI_BTYPE_ROW);
}
/**
@@ -80,83 +76,88 @@ bool ui_but_is_toggle(const uiBut *but)
*/
bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
{
- /* note, UI_BTYPE_LABEL is included for highlights, this allows drags */
- if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == NULL) {
- return false;
- }
- if (ELEM(but->type, UI_BTYPE_ROUNDBOX, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_LISTBOX)) {
- return false;
- }
- if (but->flag & UI_HIDDEN) {
- return false;
- }
- if (but->flag & UI_SCROLLED) {
- return false;
- }
- if ((but->type == UI_BTYPE_TEXT) && (but->dt == UI_EMBOSS_NONE) && !labeledit) {
- return false;
- }
- if ((but->type == UI_BTYPE_LISTROW) && labeledit) {
- return false;
- }
-
- return true;
+ /* note, UI_BTYPE_LABEL is included for highlights, this allows drags */
+ if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == NULL) {
+ return false;
+ }
+ if (ELEM(but->type, UI_BTYPE_ROUNDBOX, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_LISTBOX)) {
+ return false;
+ }
+ if (but->flag & UI_HIDDEN) {
+ return false;
+ }
+ if (but->flag & UI_SCROLLED) {
+ return false;
+ }
+ if ((but->type == UI_BTYPE_TEXT) && (but->dt == UI_EMBOSS_NONE) && !labeledit) {
+ return false;
+ }
+ if ((but->type == UI_BTYPE_LISTROW) && labeledit) {
+ return false;
+ }
+
+ return true;
}
/* file selectors are exempt from utf-8 checks */
bool ui_but_is_utf8(const uiBut *but)
{
- if (but->rnaprop) {
- const int subtype = RNA_property_subtype(but->rnaprop);
- return !(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME, PROP_BYTESTRING));
- }
- else {
- return !(but->flag & UI_BUT_NO_UTF8);
- }
+ if (but->rnaprop) {
+ const int subtype = RNA_property_subtype(but->rnaprop);
+ return !(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME, PROP_BYTESTRING));
+ }
+ else {
+ return !(but->flag & UI_BUT_NO_UTF8);
+ }
}
-
#ifdef USE_UI_POPOVER_ONCE
bool ui_but_is_popover_once_compat(const uiBut *but)
{
- return (
- (but->type == UI_BTYPE_BUT) ||
- ui_but_is_toggle(but)
- );
+ return ((but->type == UI_BTYPE_BUT) || ui_but_is_toggle(but));
}
#endif
bool ui_but_has_array_value(const uiBut *but)
{
- return (but->rnapoin.data && but->rnaprop &&
- ELEM(RNA_property_subtype(but->rnaprop), PROP_COLOR, PROP_TRANSLATION, PROP_DIRECTION,
- PROP_VELOCITY, PROP_ACCELERATION, PROP_MATRIX, PROP_EULER, PROP_QUATERNION, PROP_AXISANGLE,
- PROP_XYZ, PROP_XYZ_LENGTH, PROP_COLOR_GAMMA, PROP_COORDS));
+ return (but->rnapoin.data && but->rnaprop &&
+ ELEM(RNA_property_subtype(but->rnaprop),
+ PROP_COLOR,
+ PROP_TRANSLATION,
+ PROP_DIRECTION,
+ PROP_VELOCITY,
+ PROP_ACCELERATION,
+ PROP_MATRIX,
+ PROP_EULER,
+ PROP_QUATERNION,
+ PROP_AXISANGLE,
+ PROP_XYZ,
+ PROP_XYZ_LENGTH,
+ PROP_COLOR_GAMMA,
+ PROP_COORDS));
}
-
-
bool UI_but_is_tool(const uiBut *but)
{
- /* very evil! */
- if (but->optype != NULL) {
- static wmOperatorType *ot = NULL;
- if (ot == NULL) {
- ot = WM_operatortype_find("WM_OT_tool_set_by_id", false);
- }
- if (but->optype == ot) {
- return true;
- }
- }
- return false;
+ /* very evil! */
+ if (but->optype != NULL) {
+ static wmOperatorType *ot = NULL;
+ if (ot == NULL) {
+ ot = WM_operatortype_find("WM_OT_tool_set_by_id", false);
+ }
+ if (but->optype == ot) {
+ return true;
+ }
+ }
+ return false;
}
bool UI_but_has_tooltip_label(const uiBut *but)
{
- if ((but->drawstr[0] == '\0') && !ui_block_is_popover(but->block)) {
- return UI_but_is_tool(but);
- }
- return false;
+ if ((but->drawstr[0] == '\0') && !ui_block_is_popover(but->block)) {
+ return UI_but_is_tool(but);
+ }
+ return false;
}
/** \} */
@@ -167,242 +168,245 @@ bool UI_but_has_tooltip_label(const uiBut *but)
void ui_but_pie_dir(RadialDirection dir, float vec[2])
{
- float angle;
+ float angle;
- BLI_assert(dir != UI_RADIAL_NONE);
+ BLI_assert(dir != UI_RADIAL_NONE);
- angle = DEG2RADF((float)ui_radial_dir_to_angle[dir]);
- vec[0] = cosf(angle);
- vec[1] = sinf(angle);
+ angle = DEG2RADF((float)ui_radial_dir_to_angle[dir]);
+ vec[0] = cosf(angle);
+ vec[1] = sinf(angle);
}
static bool ui_but_isect_pie_seg(const uiBlock *block, const uiBut *but)
{
- const float angle_range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_4 : M_PI_4 / 2.0;
- float vec[2];
+ const float angle_range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_4 :
+ M_PI_4 / 2.0;
+ float vec[2];
- if (block->pie_data.flags & UI_PIE_INVALID_DIR) {
- return false;
- }
+ if (block->pie_data.flags & UI_PIE_INVALID_DIR) {
+ return false;
+ }
- ui_but_pie_dir(but->pie_dir, vec);
+ ui_but_pie_dir(but->pie_dir, vec);
- if (saacos(dot_v2v2(vec, block->pie_data.pie_dir)) < angle_range) {
- return true;
- }
+ if (saacos(dot_v2v2(vec, block->pie_data.pie_dir)) < angle_range) {
+ return true;
+ }
- return false;
+ return false;
}
bool ui_but_contains_pt(const uiBut *but, float mx, float my)
{
- return BLI_rctf_isect_pt(&but->rect, mx, my);
+ return BLI_rctf_isect_pt(&but->rect, mx, my);
}
bool ui_but_contains_point_px(const uiBut *but, const ARegion *ar, int x, int y)
{
- uiBlock *block = but->block;
- float mx, my;
- if (!ui_region_contains_point_px(ar, x, y)) {
- return false;
- }
+ uiBlock *block = but->block;
+ float mx, my;
+ if (!ui_region_contains_point_px(ar, x, y)) {
+ return false;
+ }
- mx = x;
- my = y;
+ mx = x;
+ my = y;
- ui_window_to_block_fl(ar, block, &mx, &my);
+ ui_window_to_block_fl(ar, block, &mx, &my);
- if (but->pie_dir != UI_RADIAL_NONE) {
- if (!ui_but_isect_pie_seg(block, but)) {
- return false;
- }
- }
- else if (!ui_but_contains_pt(but, mx, my)) {
- return false;
- }
+ if (but->pie_dir != UI_RADIAL_NONE) {
+ if (!ui_but_isect_pie_seg(block, but)) {
+ return false;
+ }
+ }
+ else if (!ui_but_contains_pt(but, mx, my)) {
+ return false;
+ }
- return true;
+ return true;
}
bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *ar, const wmEvent *event)
{
- rcti rect;
- int x = event->x, y = event->y;
+ rcti rect;
+ int x = event->x, y = event->y;
- ui_window_to_block(ar, but->block, &x, &y);
+ ui_window_to_block(ar, but->block, &x, &y);
- BLI_rcti_rctf_copy(&rect, &but->rect);
+ BLI_rcti_rctf_copy(&rect, &but->rect);
- if (but->imb || but->type == UI_BTYPE_COLOR) {
- /* use button size itself */
- }
- else if (but->drawflag & UI_BUT_ICON_LEFT) {
- rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect));
- }
- else {
- int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect);
- rect.xmin += delta / 2;
- rect.xmax -= delta / 2;
- }
+ if (but->imb || but->type == UI_BTYPE_COLOR) {
+ /* use button size itself */
+ }
+ else if (but->drawflag & UI_BUT_ICON_LEFT) {
+ rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect));
+ }
+ else {
+ int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect);
+ rect.xmin += delta / 2;
+ rect.xmax -= delta / 2;
+ }
- return BLI_rcti_isect_pt(&rect, x, y);
+ return BLI_rcti_isect_pt(&rect, x, y);
}
/* x and y are only used in case event is NULL... */
uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit)
{
- uiBlock *block;
- uiBut *but, *butover = NULL;
- float mx, my;
-
-// if (!win->active) {
-// return NULL;
-// }
- if (!ui_region_contains_point_px(ar, x, y)) {
- return NULL;
- }
-
- for (block = ar->uiblocks.first; block; block = block->next) {
- mx = x;
- my = y;
- ui_window_to_block_fl(ar, block, &mx, &my);
-
- for (but = block->buttons.last; but; but = but->prev) {
- if (ui_but_is_interactive(but, labeledit)) {
- if (but->pie_dir != UI_RADIAL_NONE) {
- if (ui_but_isect_pie_seg(block, but)) {
- butover = but;
- break;
- }
- }
- else if (ui_but_contains_pt(but, mx, my)) {
- butover = but;
- break;
- }
- }
- }
-
- /* CLIP_EVENTS prevents the event from reaching other blocks */
- if (block->flag & UI_BLOCK_CLIP_EVENTS) {
- /* check if mouse is inside block */
- if (BLI_rctf_isect_pt(&block->rect, mx, my)) {
- break;
- }
- }
- }
-
- return butover;
+ uiBlock *block;
+ uiBut *but, *butover = NULL;
+ float mx, my;
+
+ // if (!win->active) {
+ // return NULL;
+ // }
+ if (!ui_region_contains_point_px(ar, x, y)) {
+ return NULL;
+ }
+
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ mx = x;
+ my = y;
+ ui_window_to_block_fl(ar, block, &mx, &my);
+
+ for (but = block->buttons.last; but; but = but->prev) {
+ if (ui_but_is_interactive(but, labeledit)) {
+ if (but->pie_dir != UI_RADIAL_NONE) {
+ if (ui_but_isect_pie_seg(block, but)) {
+ butover = but;
+ break;
+ }
+ }
+ else if (ui_but_contains_pt(but, mx, my)) {
+ butover = but;
+ break;
+ }
+ }
+ }
+
+ /* CLIP_EVENTS prevents the event from reaching other blocks */
+ if (block->flag & UI_BLOCK_CLIP_EVENTS) {
+ /* check if mouse is inside block */
+ if (BLI_rctf_isect_pt(&block->rect, mx, my)) {
+ break;
+ }
+ }
+ }
+
+ return butover;
}
uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event)
{
- return ui_but_find_mouse_over_ex(ar, event->x, event->y, event->ctrl != 0);
+ return ui_but_find_mouse_over_ex(ar, event->x, event->y, event->ctrl != 0);
}
uiBut *ui_list_find_mouse_over_ex(ARegion *ar, int x, int y)
{
- uiBlock *block;
- uiBut *but;
- float mx, my;
+ uiBlock *block;
+ uiBut *but;
+ float mx, my;
- if (!ui_region_contains_point_px(ar, x, y)) {
- return NULL;
- }
+ if (!ui_region_contains_point_px(ar, x, y)) {
+ return NULL;
+ }
- for (block = ar->uiblocks.first; block; block = block->next) {
- mx = x;
- my = y;
- ui_window_to_block_fl(ar, block, &mx, &my);
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ mx = x;
+ my = y;
+ ui_window_to_block_fl(ar, block, &mx, &my);
- for (but = block->buttons.last; but; but = but->prev) {
- if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) {
- return but;
- }
- }
- }
+ for (but = block->buttons.last; but; but = but->prev) {
+ if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) {
+ return but;
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
uiBut *ui_list_find_mouse_over(ARegion *ar, const wmEvent *event)
{
- return ui_list_find_mouse_over_ex(ar, event->x, event->y);
+ return ui_list_find_mouse_over_ex(ar, event->x, event->y);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Button (#uiBut) Relations
* \{ */
uiBut *ui_but_prev(uiBut *but)
{
- while (but->prev) {
- but = but->prev;
- if (ui_but_is_editable(but)) {
- return but;
- }
- }
- return NULL;
+ while (but->prev) {
+ but = but->prev;
+ if (ui_but_is_editable(but)) {
+ return but;
+ }
+ }
+ return NULL;
}
uiBut *ui_but_next(uiBut *but)
{
- while (but->next) {
- but = but->next;
- if (ui_but_is_editable(but)) {
- return but;
- }
- }
- return NULL;
+ while (but->next) {
+ but = but->next;
+ if (ui_but_is_editable(but)) {
+ return but;
+ }
+ }
+ return NULL;
}
uiBut *ui_but_first(uiBlock *block)
{
- uiBut *but;
+ uiBut *but;
- but = block->buttons.first;
- while (but) {
- if (ui_but_is_editable(but)) {
- return but;
- }
- but = but->next;
- }
- return NULL;
+ but = block->buttons.first;
+ while (but) {
+ if (ui_but_is_editable(but)) {
+ return but;
+ }
+ but = but->next;
+ }
+ return NULL;
}
uiBut *ui_but_last(uiBlock *block)
{
- uiBut *but;
+ uiBut *but;
- but = block->buttons.last;
- while (but) {
- if (ui_but_is_editable(but)) {
- return but;
- }
- but = but->prev;
- }
- return NULL;
+ but = block->buttons.last;
+ while (but) {
+ if (ui_but_is_editable(but)) {
+ return but;
+ }
+ but = but->prev;
+ }
+ return NULL;
}
bool ui_but_is_cursor_warp(const uiBut *but)
{
- if (U.uiflag & USER_CONTINUOUS_MOUSE) {
- if (ELEM(but->type,
- UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_HSVCIRCLE,
- UI_BTYPE_TRACK_PREVIEW, UI_BTYPE_HSVCUBE, UI_BTYPE_CURVE))
- {
- return true;
- }
- }
+ if (U.uiflag & USER_CONTINUOUS_MOUSE) {
+ if (ELEM(but->type,
+ UI_BTYPE_NUM,
+ UI_BTYPE_NUM_SLIDER,
+ UI_BTYPE_HSVCIRCLE,
+ UI_BTYPE_TRACK_PREVIEW,
+ UI_BTYPE_HSVCUBE,
+ UI_BTYPE_CURVE)) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
bool ui_but_contains_password(const uiBut *but)
{
- return but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD);
+ return but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD);
}
/** \} */
@@ -413,38 +417,34 @@ bool ui_but_contains_password(const uiBut *but)
bool ui_block_is_menu(const uiBlock *block)
{
- return (((block->flag & UI_BLOCK_LOOP) != 0) &&
- /* non-menu popups use keep-open, so check this is off */
- ((block->flag & UI_BLOCK_KEEP_OPEN) == 0));
+ return (((block->flag & UI_BLOCK_LOOP) != 0) &&
+ /* non-menu popups use keep-open, so check this is off */
+ ((block->flag & UI_BLOCK_KEEP_OPEN) == 0));
}
bool ui_block_is_popover(const uiBlock *block)
{
- return (block->flag & UI_BLOCK_POPOVER) != 0;
+ return (block->flag & UI_BLOCK_POPOVER) != 0;
}
bool ui_block_is_pie_menu(const uiBlock *block)
{
- return ((block->flag & UI_BLOCK_RADIAL) != 0);
+ return ((block->flag & UI_BLOCK_RADIAL) != 0);
}
bool ui_block_is_popup_any(const uiBlock *block)
{
- return (
- ui_block_is_menu(block) ||
- ui_block_is_popover(block) ||
- ui_block_is_pie_menu(block)
- );
+ return (ui_block_is_menu(block) || ui_block_is_popover(block) || ui_block_is_pie_menu(block));
}
bool UI_block_is_empty(const uiBlock *block)
{
- for (const uiBut *but = block->buttons.first; but; but = but->next) {
- if (!ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
- return false;
- }
- }
- return true;
+ for (const uiBut *but = block->buttons.first; but; but = but->next) {
+ if (!ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
+ return false;
+ }
+ }
+ return true;
}
/** \} */
@@ -455,33 +455,31 @@ bool UI_block_is_empty(const uiBlock *block)
uiBut *ui_region_find_active_but(ARegion *ar)
{
- uiBlock *block;
- uiBut *but;
+ uiBlock *block;
+ uiBut *but;
- for (block = ar->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
- if (but->active) {
- return but;
- }
- }
- }
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->active) {
+ return but;
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
uiBut *ui_region_find_first_but_test_flag(ARegion *ar, int flag_include, int flag_exclude)
{
- for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
- for (uiBut *but = block->buttons.first; but; but = but->next) {
- if (((but->flag & flag_include) == flag_include) &&
- ((but->flag & flag_exclude) == 0))
- {
- return but;
- }
- }
- }
+ for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
+ for (uiBut *but = block->buttons.first; but; but = but->next) {
+ if (((but->flag & flag_include) == flag_include) && ((but->flag & flag_exclude) == 0)) {
+ return but;
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
/** \} */
@@ -492,41 +490,42 @@ uiBut *ui_region_find_first_but_test_flag(ARegion *ar, int flag_include, int fla
bool ui_region_contains_point_px(const ARegion *ar, int x, int y)
{
- rcti winrct;
-
- /* scale down area rect to exclude shadow */
- ui_region_winrct_get_no_margin(ar, &winrct);
-
- /* check if the mouse is in the region */
- if (!BLI_rcti_isect_pt(&winrct, x, y)) {
- for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
- block->auto_open = false;
- }
-
- return false;
- }
-
- /* also, check that with view2d, that the mouse is not over the scrollbars
- * NOTE: care is needed here, since the mask rect may include the scrollbars
- * even when they are not visible, so we need to make a copy of the mask to
- * use to check
- */
- if (ar->v2d.mask.xmin != ar->v2d.mask.xmax) {
- const View2D *v2d = &ar->v2d;
- int mx, my;
-
- /* convert window coordinates to region coordinates */
- mx = x;
- my = y;
- ui_window_to_region(ar, &mx, &my);
-
- /* check if in the rect */
- if (!BLI_rcti_isect_pt(&v2d->mask, mx, my) || UI_view2d_mouse_in_scrollers(ar, &ar->v2d, x, y)) {
- return false;
- }
- }
-
- return true;
+ rcti winrct;
+
+ /* scale down area rect to exclude shadow */
+ ui_region_winrct_get_no_margin(ar, &winrct);
+
+ /* check if the mouse is in the region */
+ if (!BLI_rcti_isect_pt(&winrct, x, y)) {
+ for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
+ block->auto_open = false;
+ }
+
+ return false;
+ }
+
+ /* also, check that with view2d, that the mouse is not over the scrollbars
+ * NOTE: care is needed here, since the mask rect may include the scrollbars
+ * even when they are not visible, so we need to make a copy of the mask to
+ * use to check
+ */
+ if (ar->v2d.mask.xmin != ar->v2d.mask.xmax) {
+ const View2D *v2d = &ar->v2d;
+ int mx, my;
+
+ /* convert window coordinates to region coordinates */
+ mx = x;
+ my = y;
+ ui_window_to_region(ar, &mx, &my);
+
+ /* check if in the rect */
+ if (!BLI_rcti_isect_pt(&v2d->mask, mx, my) ||
+ UI_view2d_mouse_in_scrollers(ar, &ar->v2d, x, y)) {
+ return false;
+ }
+ }
+
+ return true;
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c
index 52136cee9ea..7ffe572a848 100644
--- a/source/blender/editors/interface/interface_region_color_picker.c
+++ b/source/blender/editors/interface/interface_region_color_picker.c
@@ -54,9 +54,9 @@
#include "interface_intern.h"
enum ePickerType {
- PICKER_TYPE_RGB = 0,
- PICKER_TYPE_HSV = 1,
- PICKER_TYPE_HEX = 2,
+ PICKER_TYPE_RGB = 0,
+ PICKER_TYPE_HSV = 1,
+ PICKER_TYPE_HEX = 2,
};
/* -------------------------------------------------------------------- */
@@ -65,80 +65,80 @@ enum ePickerType {
void ui_rgb_to_color_picker_compat_v(const float rgb[3], float r_cp[3])
{
- switch (U.color_picker_type) {
- case USER_CP_CIRCLE_HSL:
- rgb_to_hsl_compat_v(rgb, r_cp);
- break;
- default:
- rgb_to_hsv_compat_v(rgb, r_cp);
- break;
- }
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ rgb_to_hsl_compat_v(rgb, r_cp);
+ break;
+ default:
+ rgb_to_hsv_compat_v(rgb, r_cp);
+ break;
+ }
}
void ui_rgb_to_color_picker_v(const float rgb[3], float r_cp[3])
{
- switch (U.color_picker_type) {
- case USER_CP_CIRCLE_HSL:
- rgb_to_hsl_v(rgb, r_cp);
- break;
- default:
- rgb_to_hsv_v(rgb, r_cp);
- break;
- }
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ rgb_to_hsl_v(rgb, r_cp);
+ break;
+ default:
+ rgb_to_hsv_v(rgb, r_cp);
+ break;
+ }
}
void ui_color_picker_to_rgb_v(const float r_cp[3], float rgb[3])
{
- switch (U.color_picker_type) {
- case USER_CP_CIRCLE_HSL:
- hsl_to_rgb_v(r_cp, rgb);
- break;
- default:
- hsv_to_rgb_v(r_cp, rgb);
- break;
- }
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ hsl_to_rgb_v(r_cp, rgb);
+ break;
+ default:
+ hsv_to_rgb_v(r_cp, rgb);
+ break;
+ }
}
void ui_color_picker_to_rgb(float r_cp0, float r_cp1, float r_cp2, float *r, float *g, float *b)
{
- switch (U.color_picker_type) {
- case USER_CP_CIRCLE_HSL:
- hsl_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
- break;
- default:
- hsv_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
- break;
- }
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ hsl_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
+ break;
+ default:
+ hsv_to_rgb(r_cp0, r_cp1, r_cp2, r, g, b);
+ break;
+ }
}
/* Returns true if the button is for a color with gamma baked in,
* or if it's a color picker for such a button. */
bool ui_but_is_color_gamma(uiBut *but)
{
- if (but->rnaprop) {
- if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- return true;
- }
- }
+ if (but->rnaprop) {
+ if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
+ return true;
+ }
+ }
- return but->block->is_color_gamma_picker;
+ return but->block->is_color_gamma_picker;
}
void ui_scene_linear_to_color_picker_space(uiBut *but, float rgb[3])
{
- /* Map to color picking space for HSV values and HSV cube/circle,
- * assuming it is more perceptually linear then the scene linear
- * space for intuitive color picking. */
- if (!ui_but_is_color_gamma(but)) {
- IMB_colormanagement_scene_linear_to_color_picking_v3(rgb);
- }
+ /* Map to color picking space for HSV values and HSV cube/circle,
+ * assuming it is more perceptually linear then the scene linear
+ * space for intuitive color picking. */
+ if (!ui_but_is_color_gamma(but)) {
+ IMB_colormanagement_scene_linear_to_color_picking_v3(rgb);
+ }
}
void ui_color_picker_to_scene_linear_space(uiBut *but, float rgb[3])
{
- if (!ui_but_is_color_gamma(but)) {
- IMB_colormanagement_color_picking_to_scene_linear_v3(rgb);
- }
+ if (!ui_but_is_color_gamma(but)) {
+ IMB_colormanagement_color_picking_to_scene_linear_v3(rgb);
+ }
}
/** \} */
@@ -150,536 +150,759 @@ void ui_color_picker_to_scene_linear_space(uiBut *but, float rgb[3])
/* for picker, while editing hsv */
void ui_but_hsv_set(uiBut *but)
{
- float col[3];
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
+ float col[3];
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
- ui_color_picker_to_rgb_v(hsv, col);
+ ui_color_picker_to_rgb_v(hsv, col);
- ui_but_v3_set(but, col);
+ ui_but_v3_set(but, col);
}
/* Updates all buttons who share the same color picker as the one passed
* also used by small picker, be careful with name checks below... */
-static void ui_update_color_picker_buts_rgb(
- uiBut *from_but, uiBlock *block, ColorPicker *cpicker, const float rgb[3])
+static void ui_update_color_picker_buts_rgb(uiBut *from_but,
+ uiBlock *block,
+ ColorPicker *cpicker,
+ const float rgb[3])
{
- uiBut *bt;
- float *hsv = cpicker->color_data;
-
- /* Convert from RGB to HSV in perceptually linear space. */
- float tmp[3];
- copy_v3_v3(tmp, rgb);
- if (from_but) {
- ui_scene_linear_to_color_picker_space(from_but, tmp);
- }
- ui_rgb_to_color_picker_compat_v(tmp, hsv);
-
- /* this updates button strings,
- * is hackish... but button pointers are on stack of caller function */
- for (bt = block->buttons.first; bt; bt = bt->next) {
- if (bt->custom_data != cpicker) {
- continue;
- }
-
- if (bt->rnaprop) {
- ui_but_v3_set(bt, rgb);
-
- /* original button that created the color picker already does undo
- * push, so disable it on RNA buttons in the color picker block */
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- }
- else if (STREQ(bt->str, "Hex: ")) {
- float rgb_hex[3];
- uchar rgb_hex_uchar[3];
- double intpart;
- char col[16];
-
- /* Hex code is assumed to be in sRGB space
- * (coming from other applications, web, etc) */
- copy_v3_v3(rgb_hex, rgb);
- if (from_but && !ui_but_is_color_gamma(from_but)) {
- IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex);
- }
-
- if (rgb_hex[0] > 1.0f) {
- rgb_hex[0] = modf(rgb_hex[0], &intpart);
- }
- if (rgb_hex[1] > 1.0f) {
- rgb_hex[1] = modf(rgb_hex[1], &intpart);
- }
- if (rgb_hex[2] > 1.0f) {
- rgb_hex[2] = modf(rgb_hex[2], &intpart);
- }
-
- rgb_float_to_uchar(rgb_hex_uchar, rgb_hex);
- BLI_snprintf(col, sizeof(col), "%02X%02X%02X", UNPACK3_EX((uint), rgb_hex_uchar, ));
-
- strcpy(bt->poin, col);
- }
- else if (bt->str[1] == ' ') {
- if (bt->str[0] == 'R') {
- ui_but_value_set(bt, rgb[0]);
- }
- else if (bt->str[0] == 'G') {
- ui_but_value_set(bt, rgb[1]);
- }
- else if (bt->str[0] == 'B') {
- ui_but_value_set(bt, rgb[2]);
- }
- else if (bt->str[0] == 'H') {
- ui_but_value_set(bt, hsv[0]);
- }
- else if (bt->str[0] == 'S') {
- ui_but_value_set(bt, hsv[1]);
- }
- else if (bt->str[0] == 'V') {
- ui_but_value_set(bt, hsv[2]);
- }
- else if (bt->str[0] == 'L') {
- ui_but_value_set(bt, hsv[2]);
- }
- }
-
- ui_but_update(bt);
- }
+ uiBut *bt;
+ float *hsv = cpicker->color_data;
+
+ /* Convert from RGB to HSV in perceptually linear space. */
+ float tmp[3];
+ copy_v3_v3(tmp, rgb);
+ if (from_but) {
+ ui_scene_linear_to_color_picker_space(from_but, tmp);
+ }
+ ui_rgb_to_color_picker_compat_v(tmp, hsv);
+
+ /* this updates button strings,
+ * is hackish... but button pointers are on stack of caller function */
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (bt->custom_data != cpicker) {
+ continue;
+ }
+
+ if (bt->rnaprop) {
+ ui_but_v3_set(bt, rgb);
+
+ /* original button that created the color picker already does undo
+ * push, so disable it on RNA buttons in the color picker block */
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ }
+ else if (STREQ(bt->str, "Hex: ")) {
+ float rgb_hex[3];
+ uchar rgb_hex_uchar[3];
+ double intpart;
+ char col[16];
+
+ /* Hex code is assumed to be in sRGB space
+ * (coming from other applications, web, etc) */
+ copy_v3_v3(rgb_hex, rgb);
+ if (from_but && !ui_but_is_color_gamma(from_but)) {
+ IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex);
+ }
+
+ if (rgb_hex[0] > 1.0f) {
+ rgb_hex[0] = modf(rgb_hex[0], &intpart);
+ }
+ if (rgb_hex[1] > 1.0f) {
+ rgb_hex[1] = modf(rgb_hex[1], &intpart);
+ }
+ if (rgb_hex[2] > 1.0f) {
+ rgb_hex[2] = modf(rgb_hex[2], &intpart);
+ }
+
+ rgb_float_to_uchar(rgb_hex_uchar, rgb_hex);
+ BLI_snprintf(col, sizeof(col), "%02X%02X%02X", UNPACK3_EX((uint), rgb_hex_uchar, ));
+
+ strcpy(bt->poin, col);
+ }
+ else if (bt->str[1] == ' ') {
+ if (bt->str[0] == 'R') {
+ ui_but_value_set(bt, rgb[0]);
+ }
+ else if (bt->str[0] == 'G') {
+ ui_but_value_set(bt, rgb[1]);
+ }
+ else if (bt->str[0] == 'B') {
+ ui_but_value_set(bt, rgb[2]);
+ }
+ else if (bt->str[0] == 'H') {
+ ui_but_value_set(bt, hsv[0]);
+ }
+ else if (bt->str[0] == 'S') {
+ ui_but_value_set(bt, hsv[1]);
+ }
+ else if (bt->str[0] == 'V') {
+ ui_but_value_set(bt, hsv[2]);
+ }
+ else if (bt->str[0] == 'L') {
+ ui_but_value_set(bt, hsv[2]);
+ }
+ }
+
+ ui_but_update(bt);
+ }
}
static void ui_colorpicker_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
- uiBut *but = (uiBut *)bt1;
- uiPopupBlockHandle *popup = but->block->handle;
- PropertyRNA *prop = but->rnaprop;
- PointerRNA ptr = but->rnapoin;
- float rgb[4];
-
- if (prop) {
- RNA_property_float_get_array(&ptr, prop, rgb);
- ui_update_color_picker_buts_rgb(
- but, but->block, but->custom_data, rgb);
- }
-
- if (popup) {
- popup->menuretval = UI_RETURN_UPDATE;
- }
+ uiBut *but = (uiBut *)bt1;
+ uiPopupBlockHandle *popup = but->block->handle;
+ PropertyRNA *prop = but->rnaprop;
+ PointerRNA ptr = but->rnapoin;
+ float rgb[4];
+
+ if (prop) {
+ RNA_property_float_get_array(&ptr, prop, rgb);
+ ui_update_color_picker_buts_rgb(but, but->block, but->custom_data, rgb);
+ }
+
+ if (popup) {
+ popup->menuretval = UI_RETURN_UPDATE;
+ }
}
static void ui_color_wheel_rna_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
- uiBut *but = (uiBut *)bt1;
- uiPopupBlockHandle *popup = but->block->handle;
- float rgb[3];
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
+ uiBut *but = (uiBut *)bt1;
+ uiPopupBlockHandle *popup = but->block->handle;
+ float rgb[3];
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
- ui_color_picker_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_rgb_v(hsv, rgb);
- /* hsv is saved in perceptually linear space so convert back */
- ui_color_picker_to_scene_linear_space(but, rgb);
+ /* hsv is saved in perceptually linear space so convert back */
+ ui_color_picker_to_scene_linear_space(but, rgb);
- ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb);
+ ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb);
- if (popup) {
- popup->menuretval = UI_RETURN_UPDATE;
- }
+ if (popup) {
+ popup->menuretval = UI_RETURN_UPDATE;
+ }
}
static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexcl)
{
- uiBut *but = (uiBut *)bt1;
- uiPopupBlockHandle *popup = but->block->handle;
- ColorPicker *cpicker = but->custom_data;
- char *hexcol = (char *)hexcl;
- float rgb[3];
+ uiBut *but = (uiBut *)bt1;
+ uiPopupBlockHandle *popup = but->block->handle;
+ ColorPicker *cpicker = but->custom_data;
+ char *hexcol = (char *)hexcl;
+ float rgb[3];
- hex_to_rgb(hexcol, rgb, rgb + 1, rgb + 2);
+ hex_to_rgb(hexcol, rgb, rgb + 1, rgb + 2);
- /* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */
- if (!ui_but_is_color_gamma(but)) {
- IMB_colormanagement_srgb_to_scene_linear_v3(rgb);
- }
+ /* Hex code is assumed to be in sRGB space (coming from other applications, web, etc) */
+ if (!ui_but_is_color_gamma(but)) {
+ IMB_colormanagement_srgb_to_scene_linear_v3(rgb);
+ }
- ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb);
+ ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb);
- if (popup) {
- popup->menuretval = UI_RETURN_UPDATE;
- }
+ if (popup) {
+ popup->menuretval = UI_RETURN_UPDATE;
+ }
}
static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
- uiBut *but = (uiBut *)bt1;
- uiPopupBlockHandle *popup = but->block->handle;
-
- if (popup) {
- ColorPicker *cpicker = but->custom_data;
- BLI_assert(cpicker->is_init);
- popup->menuretval = (
- equals_v3v3(cpicker->color_data, cpicker->color_data_init) ?
- UI_RETURN_CANCEL : UI_RETURN_OK);
- }
+ uiBut *but = (uiBut *)bt1;
+ uiPopupBlockHandle *popup = but->block->handle;
+
+ if (popup) {
+ ColorPicker *cpicker = but->custom_data;
+ BLI_assert(cpicker->is_init);
+ popup->menuretval = (equals_v3v3(cpicker->color_data, cpicker->color_data_init) ?
+ UI_RETURN_CANCEL :
+ UI_RETURN_OK);
+ }
}
static void ui_colorpicker_hide_reveal(uiBlock *block, enum ePickerType colormode)
{
- /* tag buttons */
- for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
- if ((bt->func == ui_colorpicker_rna_cb) &&
- (bt->type == UI_BTYPE_NUM_SLIDER) &&
- (bt->rnaindex != 3))
- {
- /* RGB sliders (color circle and alpha are always shown) */
- SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_RGB), UI_HIDDEN);
- }
- else if (bt->func == ui_color_wheel_rna_cb) {
- /* HSV sliders */
- SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_HSV), UI_HIDDEN);
- }
- else if (bt->func == ui_colorpicker_hex_rna_cb || bt->type == UI_BTYPE_LABEL) {
- /* HEX input or gamma correction status label */
- SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_HEX), UI_HIDDEN);
- }
- }
+ /* tag buttons */
+ for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
+ if ((bt->func == ui_colorpicker_rna_cb) && (bt->type == UI_BTYPE_NUM_SLIDER) &&
+ (bt->rnaindex != 3)) {
+ /* RGB sliders (color circle and alpha are always shown) */
+ SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_RGB), UI_HIDDEN);
+ }
+ else if (bt->func == ui_color_wheel_rna_cb) {
+ /* HSV sliders */
+ SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_HSV), UI_HIDDEN);
+ }
+ else if (bt->func == ui_colorpicker_hex_rna_cb || bt->type == UI_BTYPE_LABEL) {
+ /* HEX input or gamma correction status label */
+ SET_FLAG_FROM_TEST(bt->flag, (colormode != PICKER_TYPE_HEX), UI_HIDDEN);
+ }
+ }
}
static void ui_colorpicker_create_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
- uiBut *bt = bt1;
- short colormode = ui_but_value_get(bt);
- ui_colorpicker_hide_reveal(bt->block, colormode);
+ uiBut *bt = bt1;
+ short colormode = ui_but_value_get(bt);
+ ui_colorpicker_hide_reveal(bt->block, colormode);
}
-#define PICKER_H (7.5f * U.widget_unit)
-#define PICKER_W (7.5f * U.widget_unit)
-#define PICKER_SPACE (0.3f * U.widget_unit)
-#define PICKER_BAR (0.7f * U.widget_unit)
+#define PICKER_H (7.5f * U.widget_unit)
+#define PICKER_W (7.5f * U.widget_unit)
+#define PICKER_SPACE (0.3f * U.widget_unit)
+#define PICKER_BAR (0.7f * U.widget_unit)
-#define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR)
+#define PICKER_TOTAL_W (PICKER_W + PICKER_SPACE + PICKER_BAR)
-static void ui_colorpicker_circle(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, ColorPicker *cpicker)
+static void ui_colorpicker_circle(uiBlock *block,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ ColorPicker *cpicker)
{
- uiBut *bt;
-
- /* HS circle */
- bt = uiDefButR_prop(
- block, UI_BTYPE_HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W,
- ptr, prop, -1, 0.0, 0.0, 0.0, 0, TIP_("Color"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- bt->custom_data = cpicker;
-
- /* value */
- if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
- bt = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H,
- ptr, prop, -1, 0.0, 0.0, UI_GRAD_L_ALT, 0, "Lightness");
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- }
- else {
- bt = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", PICKER_W + PICKER_SPACE, 0, PICKER_BAR, PICKER_H,
- ptr, prop, -1, 0.0, 0.0, UI_GRAD_V_ALT, 0, TIP_("Value"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- }
- bt->custom_data = cpicker;
+ uiBut *bt;
+
+ /* HS circle */
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_HSVCIRCLE,
+ 0,
+ "",
+ 0,
+ 0,
+ PICKER_H,
+ PICKER_W,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0,
+ TIP_("Color"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+
+ /* value */
+ if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ PICKER_W + PICKER_SPACE,
+ 0,
+ PICKER_BAR,
+ PICKER_H,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ UI_GRAD_L_ALT,
+ 0,
+ "Lightness");
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ }
+ else {
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ PICKER_W + PICKER_SPACE,
+ 0,
+ PICKER_BAR,
+ PICKER_H,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ UI_GRAD_V_ALT,
+ 0,
+ TIP_("Value"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ }
+ bt->custom_data = cpicker;
}
-
-static void ui_colorpicker_square(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type, ColorPicker *cpicker)
+static void ui_colorpicker_square(
+ uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type, ColorPicker *cpicker)
{
- uiBut *bt;
- int bartype = type + 3;
-
- /* HS square */
- bt = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, PICKER_BAR + PICKER_SPACE, PICKER_TOTAL_W, PICKER_H,
- ptr, prop, -1, 0.0, 0.0, type, 0, TIP_("Color"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- bt->custom_data = cpicker;
-
- /* value */
- bt = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR,
- ptr, prop, -1, 0.0, 0.0, bartype, 0, TIP_("Value"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- bt->custom_data = cpicker;
+ uiBut *bt;
+ int bartype = type + 3;
+
+ /* HS square */
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ PICKER_BAR + PICKER_SPACE,
+ PICKER_TOTAL_W,
+ PICKER_H,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ type,
+ 0,
+ TIP_("Color"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+
+ /* value */
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ 0,
+ PICKER_TOTAL_W,
+ PICKER_BAR,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ bartype,
+ 0,
+ TIP_("Value"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
}
/* a HS circle, V slider, rgb/hsv/hex sliders */
-static void ui_block_colorpicker(
- uiBlock *block, uiBut *from_but, float rgba[4], bool show_picker)
+static void ui_block_colorpicker(uiBlock *block, uiBut *from_but, float rgba[4], bool show_picker)
{
- /* ePickerType */
- static char colormode = 1;
- uiBut *bt;
- int width, butwidth;
- static char hexcol[128];
- float softmin, softmax, hardmin, hardmax, step, precision;
- int yco;
- ColorPicker *cpicker = ui_block_colorpicker_create(block);
- float *hsv = cpicker->color_data;
- PointerRNA *ptr = &from_but->rnapoin;
- PropertyRNA *prop = from_but->rnaprop;
-
- width = PICKER_TOTAL_W;
- butwidth = width - 1.5f * UI_UNIT_X;
-
- /* sneaky way to check for alpha */
- rgba[3] = FLT_MAX;
-
- RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
- RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
- RNA_property_float_get_array(ptr, prop, rgba);
-
- float rgb_perceptual[3];
- copy_v3_v3(rgb_perceptual, rgba);
- ui_scene_linear_to_color_picker_space(from_but, rgb_perceptual);
- ui_rgb_to_color_picker_v(rgb_perceptual, hsv);
- if (cpicker->is_init == false) {
- copy_v3_v3(cpicker->color_data_init, cpicker->color_data);
- cpicker->is_init = true;
- }
-
- /* when the softmax isn't defined in the RNA,
- * using very large numbers causes sRGB/linear round trip to fail. */
- if (softmax == FLT_MAX) {
- softmax = 1.0f;
- }
-
- switch (U.color_picker_type) {
- case USER_CP_SQUARE_SV:
- ui_colorpicker_square(block, ptr, prop, UI_GRAD_SV, cpicker);
- break;
- case USER_CP_SQUARE_HS:
- ui_colorpicker_square(block, ptr, prop, UI_GRAD_HS, cpicker);
- break;
- case USER_CP_SQUARE_HV:
- ui_colorpicker_square(block, ptr, prop, UI_GRAD_HV, cpicker);
- break;
-
- /* user default */
- case USER_CP_CIRCLE_HSV:
- case USER_CP_CIRCLE_HSL:
- default:
- ui_colorpicker_circle(block, ptr, prop, cpicker);
- break;
- }
-
- /* mode */
- yco = -1.5f * UI_UNIT_Y;
- UI_block_align_begin(block);
- bt = uiDefButC(
- block, UI_BTYPE_ROW, 0, IFACE_("RGB"), 0, yco, width / 3, UI_UNIT_Y,
- &colormode, 0.0, (float)PICKER_TYPE_RGB, 0, 0, "");
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
- bt->custom_data = cpicker;
- bt = uiDefButC(
- block, UI_BTYPE_ROW, 0,
- IFACE_((U.color_picker_type == USER_CP_CIRCLE_HSL) ? "HSL" : "HSV"),
- width / 3, yco, width / 3, UI_UNIT_Y,
- &colormode, 0.0, PICKER_TYPE_HSV, 0, 0, "");
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
- bt->custom_data = cpicker;
- bt = uiDefButC(
- block, UI_BTYPE_ROW, 0, IFACE_("Hex"), 2 * width / 3, yco, width / 3, UI_UNIT_Y,
- &colormode, 0.0, PICKER_TYPE_HEX, 0, 0, "");
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
- bt->custom_data = cpicker;
- UI_block_align_end(block);
-
- yco = -3.0f * UI_UNIT_Y;
- if (show_picker) {
- bt = uiDefIconButO(
- block, UI_BTYPE_BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER,
- butwidth + 10, yco, UI_UNIT_X, UI_UNIT_Y, NULL);
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_drawflag_disable(bt, UI_BUT_ICON_LEFT);
- UI_but_func_set(bt, ui_popup_close_cb, bt, NULL);
- bt->custom_data = cpicker;
- }
-
- /* Note: don't disable UI_BUT_UNDO for RGBA values, since these don't add undo steps. */
-
- /* RGB values */
- UI_block_align_begin(block);
- bt = uiDefButR_prop(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("R:"), 0, yco, butwidth, UI_UNIT_Y,
- ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- bt->custom_data = cpicker;
- bt = uiDefButR_prop(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("G:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y,
- ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- bt->custom_data = cpicker;
- bt = uiDefButR_prop(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("B:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y,
- ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- bt->custom_data = cpicker;
-
- /* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE);
- * but need to use UI_but_func_set for updating other fake buttons */
-
- /* HSV values */
- yco = -3.0f * UI_UNIT_Y;
- UI_block_align_begin(block);
- bt = uiDefButF(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("H:"), 0, yco, butwidth,
- UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue"));
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
- bt->custom_data = cpicker;
- bt = uiDefButF(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("S:"), 0, yco -= UI_UNIT_Y,
- butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation"));
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
- bt->custom_data = cpicker;
- if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
- bt = uiDefButF(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("L:"), 0, yco -= UI_UNIT_Y,
- butwidth, UI_UNIT_Y, hsv + 2, 0.0, 1.0, 10, 3, TIP_("Lightness"));
- }
- else {
- bt = uiDefButF(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("V:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y,
- hsv + 2, 0.0, softmax, 10, 3, TIP_("Value"));
- }
- UI_but_flag_disable(bt, UI_BUT_UNDO);
-
- bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
- UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
- bt->custom_data = cpicker;
-
- UI_block_align_end(block);
-
- if (rgba[3] != FLT_MAX) {
- bt = uiDefButR_prop(
- block, UI_BTYPE_NUM_SLIDER, 0, IFACE_("A: "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y,
- ptr, prop, 3, 0.0, 0.0, 0, 3, TIP_("Alpha"));
- UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
- bt->custom_data = cpicker;
- }
- else {
- rgba[3] = 1.0f;
- }
-
- /* Hex color is in sRGB space. */
- float rgb_hex[3];
- uchar rgb_hex_uchar[3];
-
- copy_v3_v3(rgb_hex, rgba);
-
- if (!ui_but_is_color_gamma(from_but)) {
- IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex);
- }
-
- rgb_float_to_uchar(rgb_hex_uchar, rgb_hex);
- BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3_EX((uint), rgb_hex_uchar, ));
-
- yco = -3.0f * UI_UNIT_Y;
- bt = uiDefBut(
- block, UI_BTYPE_TEXT, 0, IFACE_("Hex: "), 0, yco, butwidth, UI_UNIT_Y,
- hexcol, 0, 8, 0, 0, TIP_("Hex triplet for color (#RRGGBB)"));
- UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_colorpicker_hex_rna_cb, bt, hexcol);
- bt->custom_data = cpicker;
- uiDefBut(
- block, UI_BTYPE_LABEL, 0, IFACE_("(Gamma Corrected)"), 0, yco - UI_UNIT_Y,
- butwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- ui_colorpicker_hide_reveal(block, colormode);
+ /* ePickerType */
+ static char colormode = 1;
+ uiBut *bt;
+ int width, butwidth;
+ static char hexcol[128];
+ float softmin, softmax, hardmin, hardmax, step, precision;
+ int yco;
+ ColorPicker *cpicker = ui_block_colorpicker_create(block);
+ float *hsv = cpicker->color_data;
+ PointerRNA *ptr = &from_but->rnapoin;
+ PropertyRNA *prop = from_but->rnaprop;
+
+ width = PICKER_TOTAL_W;
+ butwidth = width - 1.5f * UI_UNIT_X;
+
+ /* sneaky way to check for alpha */
+ rgba[3] = FLT_MAX;
+
+ RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
+ RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
+ RNA_property_float_get_array(ptr, prop, rgba);
+
+ float rgb_perceptual[3];
+ copy_v3_v3(rgb_perceptual, rgba);
+ ui_scene_linear_to_color_picker_space(from_but, rgb_perceptual);
+ ui_rgb_to_color_picker_v(rgb_perceptual, hsv);
+ if (cpicker->is_init == false) {
+ copy_v3_v3(cpicker->color_data_init, cpicker->color_data);
+ cpicker->is_init = true;
+ }
+
+ /* when the softmax isn't defined in the RNA,
+ * using very large numbers causes sRGB/linear round trip to fail. */
+ if (softmax == FLT_MAX) {
+ softmax = 1.0f;
+ }
+
+ switch (U.color_picker_type) {
+ case USER_CP_SQUARE_SV:
+ ui_colorpicker_square(block, ptr, prop, UI_GRAD_SV, cpicker);
+ break;
+ case USER_CP_SQUARE_HS:
+ ui_colorpicker_square(block, ptr, prop, UI_GRAD_HS, cpicker);
+ break;
+ case USER_CP_SQUARE_HV:
+ ui_colorpicker_square(block, ptr, prop, UI_GRAD_HV, cpicker);
+ break;
+
+ /* user default */
+ case USER_CP_CIRCLE_HSV:
+ case USER_CP_CIRCLE_HSL:
+ default:
+ ui_colorpicker_circle(block, ptr, prop, cpicker);
+ break;
+ }
+
+ /* mode */
+ yco = -1.5f * UI_UNIT_Y;
+ UI_block_align_begin(block);
+ bt = uiDefButC(block,
+ UI_BTYPE_ROW,
+ 0,
+ IFACE_("RGB"),
+ 0,
+ yco,
+ width / 3,
+ UI_UNIT_Y,
+ &colormode,
+ 0.0,
+ (float)PICKER_TYPE_RGB,
+ 0,
+ 0,
+ "");
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ bt = uiDefButC(block,
+ UI_BTYPE_ROW,
+ 0,
+ IFACE_((U.color_picker_type == USER_CP_CIRCLE_HSL) ? "HSL" : "HSV"),
+ width / 3,
+ yco,
+ width / 3,
+ UI_UNIT_Y,
+ &colormode,
+ 0.0,
+ PICKER_TYPE_HSV,
+ 0,
+ 0,
+ "");
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ bt = uiDefButC(block,
+ UI_BTYPE_ROW,
+ 0,
+ IFACE_("Hex"),
+ 2 * width / 3,
+ yco,
+ width / 3,
+ UI_UNIT_Y,
+ &colormode,
+ 0.0,
+ PICKER_TYPE_HEX,
+ 0,
+ 0,
+ "");
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ UI_block_align_end(block);
+
+ yco = -3.0f * UI_UNIT_Y;
+ if (show_picker) {
+ bt = uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "UI_OT_eyedropper_color",
+ WM_OP_INVOKE_DEFAULT,
+ ICON_EYEDROPPER,
+ butwidth + 10,
+ yco,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL);
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ UI_but_drawflag_disable(bt, UI_BUT_ICON_LEFT);
+ UI_but_func_set(bt, ui_popup_close_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ }
+
+ /* Note: don't disable UI_BUT_UNDO for RGBA values, since these don't add undo steps. */
+
+ /* RGB values */
+ UI_block_align_begin(block);
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("R:"),
+ 0,
+ yco,
+ butwidth,
+ UI_UNIT_Y,
+ ptr,
+ prop,
+ 0,
+ 0.0,
+ 0.0,
+ 0,
+ 3,
+ TIP_("Red"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("G:"),
+ 0,
+ yco -= UI_UNIT_Y,
+ butwidth,
+ UI_UNIT_Y,
+ ptr,
+ prop,
+ 1,
+ 0.0,
+ 0.0,
+ 0,
+ 3,
+ TIP_("Green"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("B:"),
+ 0,
+ yco -= UI_UNIT_Y,
+ butwidth,
+ UI_UNIT_Y,
+ ptr,
+ prop,
+ 2,
+ 0.0,
+ 0.0,
+ 0,
+ 3,
+ TIP_("Blue"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+
+ /* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE);
+ * but need to use UI_but_func_set for updating other fake buttons */
+
+ /* HSV values */
+ yco = -3.0f * UI_UNIT_Y;
+ UI_block_align_begin(block);
+ bt = uiDefButF(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("H:"),
+ 0,
+ yco,
+ butwidth,
+ UI_UNIT_Y,
+ hsv,
+ 0.0,
+ 1.0,
+ 10,
+ 3,
+ TIP_("Hue"));
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
+ bt->custom_data = cpicker;
+ bt = uiDefButF(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("S:"),
+ 0,
+ yco -= UI_UNIT_Y,
+ butwidth,
+ UI_UNIT_Y,
+ hsv + 1,
+ 0.0,
+ 1.0,
+ 10,
+ 3,
+ TIP_("Saturation"));
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
+ bt->custom_data = cpicker;
+ if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
+ bt = uiDefButF(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("L:"),
+ 0,
+ yco -= UI_UNIT_Y,
+ butwidth,
+ UI_UNIT_Y,
+ hsv + 2,
+ 0.0,
+ 1.0,
+ 10,
+ 3,
+ TIP_("Lightness"));
+ }
+ else {
+ bt = uiDefButF(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("V:"),
+ 0,
+ yco -= UI_UNIT_Y,
+ butwidth,
+ UI_UNIT_Y,
+ hsv + 2,
+ 0.0,
+ softmax,
+ 10,
+ 3,
+ TIP_("Value"));
+ }
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+
+ bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
+ UI_but_func_set(bt, ui_color_wheel_rna_cb, bt, hsv);
+ bt->custom_data = cpicker;
+
+ UI_block_align_end(block);
+
+ if (rgba[3] != FLT_MAX) {
+ bt = uiDefButR_prop(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ IFACE_("A: "),
+ 0,
+ yco -= UI_UNIT_Y,
+ butwidth,
+ UI_UNIT_Y,
+ ptr,
+ prop,
+ 3,
+ 0.0,
+ 0.0,
+ 0,
+ 3,
+ TIP_("Alpha"));
+ UI_but_func_set(bt, ui_colorpicker_rna_cb, bt, NULL);
+ bt->custom_data = cpicker;
+ }
+ else {
+ rgba[3] = 1.0f;
+ }
+
+ /* Hex color is in sRGB space. */
+ float rgb_hex[3];
+ uchar rgb_hex_uchar[3];
+
+ copy_v3_v3(rgb_hex, rgba);
+
+ if (!ui_but_is_color_gamma(from_but)) {
+ IMB_colormanagement_scene_linear_to_srgb_v3(rgb_hex);
+ }
+
+ rgb_float_to_uchar(rgb_hex_uchar, rgb_hex);
+ BLI_snprintf(hexcol, sizeof(hexcol), "%02X%02X%02X", UNPACK3_EX((uint), rgb_hex_uchar, ));
+
+ yco = -3.0f * UI_UNIT_Y;
+ bt = uiDefBut(block,
+ UI_BTYPE_TEXT,
+ 0,
+ IFACE_("Hex: "),
+ 0,
+ yco,
+ butwidth,
+ UI_UNIT_Y,
+ hexcol,
+ 0,
+ 8,
+ 0,
+ 0,
+ TIP_("Hex triplet for color (#RRGGBB)"));
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
+ UI_but_func_set(bt, ui_colorpicker_hex_rna_cb, bt, hexcol);
+ bt->custom_data = cpicker;
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ IFACE_("(Gamma Corrected)"),
+ 0,
+ yco - UI_UNIT_Y,
+ butwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+
+ ui_colorpicker_hide_reveal(block, colormode);
}
-
-static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), uiBlock *block, const wmEvent *event)
+static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C),
+ uiBlock *block,
+ const wmEvent *event)
{
- float add = 0.0f;
-
- if (event->type == WHEELUPMOUSE) {
- add = 0.05f;
- }
- else if (event->type == WHEELDOWNMOUSE) {
- add = -0.05f;
- }
-
- if (add != 0.0f) {
- uiBut *but;
-
- for (but = block->buttons.first; but; but = but->next) {
- if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) {
- uiPopupBlockHandle *popup = block->handle;
- float rgb[3];
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
-
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
- ui_rgb_to_color_picker_compat_v(rgb, hsv);
-
- hsv[2] = clamp_f(hsv[2] + add, 0.0f, 1.0f);
-
- ui_color_picker_to_rgb_v(hsv, rgb);
- ui_color_picker_to_scene_linear_space(but, rgb);
- ui_but_v3_set(but, rgb);
-
- ui_update_color_picker_buts_rgb(but, block, cpicker, rgb);
- if (popup) {
- popup->menuretval = UI_RETURN_UPDATE;
- }
-
- return 1;
- }
- }
- }
- return 0;
+ float add = 0.0f;
+
+ if (event->type == WHEELUPMOUSE) {
+ add = 0.05f;
+ }
+ else if (event->type == WHEELDOWNMOUSE) {
+ add = -0.05f;
+ }
+
+ if (add != 0.0f) {
+ uiBut *but;
+
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) {
+ uiPopupBlockHandle *popup = block->handle;
+ float rgb[3];
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
+ hsv[2] = clamp_f(hsv[2] + add, 0.0f, 1.0f);
+
+ ui_color_picker_to_rgb_v(hsv, rgb);
+ ui_color_picker_to_scene_linear_space(but, rgb);
+ ui_but_v3_set(but, rgb);
+
+ ui_update_color_picker_buts_rgb(but, block, cpicker, rgb);
+ if (popup) {
+ popup->menuretval = UI_RETURN_UPDATE;
+ }
+
+ return 1;
+ }
+ }
+ }
+ return 0;
}
uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_but)
{
- uiBut *but = arg_but;
- uiBlock *block;
- bool show_picker = true;
+ uiBut *but = arg_but;
+ uiBlock *block;
+ bool show_picker = true;
- block = UI_block_begin(C, handle->region, __func__, UI_EMBOSS);
+ block = UI_block_begin(C, handle->region, __func__, UI_EMBOSS);
- if (ui_but_is_color_gamma(but)) {
- block->is_color_gamma_picker = true;
- }
+ if (ui_but_is_color_gamma(but)) {
+ block->is_color_gamma_picker = true;
+ }
- if (but->block) {
- /* if color block is invoked from a popup we wouldn't be able to set color properly
- * this is because color picker will close popups first and then will try to figure
- * out active button RNA, and of course it'll fail
- */
- show_picker = (but->block->flag & UI_BLOCK_POPUP) == 0;
- }
+ if (but->block) {
+ /* if color block is invoked from a popup we wouldn't be able to set color properly
+ * this is because color picker will close popups first and then will try to figure
+ * out active button RNA, and of course it'll fail
+ */
+ show_picker = (but->block->flag & UI_BLOCK_POPUP) == 0;
+ }
- copy_v3_v3(handle->retvec, but->editvec);
+ copy_v3_v3(handle->retvec, but->editvec);
- ui_block_colorpicker(block, but, handle->retvec, show_picker);
+ ui_block_colorpicker(block, but, handle->retvec, show_picker);
- block->flag = UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT;
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
- UI_block_bounds_set_normal(block, 0.5 * UI_UNIT_X);
+ block->flag = UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_OUT_1 | UI_BLOCK_MOVEMOUSE_QUIT;
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+ UI_block_bounds_set_normal(block, 0.5 * UI_UNIT_X);
- block->block_event_func = ui_colorpicker_small_wheel_cb;
+ block->block_event_func = ui_colorpicker_small_wheel_cb;
- /* and lets go */
- block->direction = UI_DIR_UP;
+ /* and lets go */
+ block->direction = UI_DIR_UP;
- return block;
+ return block;
}
ColorPicker *ui_block_colorpicker_create(struct uiBlock *block)
{
- ColorPicker *cpicker = MEM_callocN(sizeof(ColorPicker), "color_picker");
- BLI_addhead(&block->color_pickers.list, cpicker);
+ ColorPicker *cpicker = MEM_callocN(sizeof(ColorPicker), "color_picker");
+ BLI_addhead(&block->color_pickers.list, cpicker);
- return cpicker;
+ return cpicker;
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c
index f6a5c9611af..a1f4b71dc6d 100644
--- a/source/blender/editors/interface/interface_region_hud.c
+++ b/source/blender/editors/interface/interface_region_hud.c
@@ -42,7 +42,6 @@
#include "RNA_access.h"
-
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -54,32 +53,29 @@
#include "interface_intern.h"
#include "GPU_framebuffer.h"
-
/* -------------------------------------------------------------------- */
/** \name Utilities
* \{ */
static bool last_redo_poll(const bContext *C)
{
- wmOperator *op = WM_operator_last_redo(C);
- if (op == NULL) {
- return false;
- }
- bool success = false;
- if (WM_operator_repeat_check(C, op) &&
- WM_operator_check_ui_empty(op->type) == false)
- {
- success = WM_operator_poll((bContext *)C, op->type);
- }
- return success;
+ wmOperator *op = WM_operator_last_redo(C);
+ if (op == NULL) {
+ return false;
+ }
+ bool success = false;
+ if (WM_operator_repeat_check(C, op) && WM_operator_check_ui_empty(op->type) == false) {
+ success = WM_operator_poll((bContext *)C, op->type);
+ }
+ return success;
}
static void hud_region_hide(ARegion *ar)
{
- ar->flag |= RGN_FLAG_HIDDEN;
- /* Avoids setting 'AREA_FLAG_REGION_SIZE_UPDATE'
- * since other regions don't depend on this. */
- BLI_rcti_init(&ar->winrct, 0, 0, 0, 0);
+ ar->flag |= RGN_FLAG_HIDDEN;
+ /* Avoids setting 'AREA_FLAG_REGION_SIZE_UPDATE'
+ * since other regions don't depend on this. */
+ BLI_rcti_init(&ar->winrct, 0, 0, 0, 0);
}
/** \} */
@@ -90,43 +86,43 @@ static void hud_region_hide(ARegion *ar)
static bool hud_panel_operator_redo_poll(const bContext *C, PanelType *UNUSED(pt))
{
- return last_redo_poll(C);
+ return last_redo_poll(C);
}
static void hud_panel_operator_redo_draw_header(const bContext *C, Panel *pa)
{
- wmOperator *op = WM_operator_last_redo(C);
- BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
+ wmOperator *op = WM_operator_last_redo(C);
+ BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
}
static void hud_panel_operator_redo_draw(const bContext *C, Panel *pa)
{
- wmOperator *op = WM_operator_last_redo(C);
- if (op == NULL) {
- return;
- }
- if (!WM_operator_check_ui_enabled(C, op->type->name)) {
- uiLayoutSetEnabled(pa->layout, false);
- }
- uiLayout *col = uiLayoutColumn(pa->layout, false);
- uiTemplateOperatorRedoProperties(col, C);
+ wmOperator *op = WM_operator_last_redo(C);
+ if (op == NULL) {
+ return;
+ }
+ if (!WM_operator_check_ui_enabled(C, op->type->name)) {
+ uiLayoutSetEnabled(pa->layout, false);
+ }
+ uiLayout *col = uiLayoutColumn(pa->layout, false);
+ uiTemplateOperatorRedoProperties(col, C);
}
static void hud_panels_register(ARegionType *art, int space_type, int region_type)
{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), __func__);
- strcpy(pt->idname, "OPERATOR_PT_redo");
- strcpy(pt->label, N_("Redo"));
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw_header = hud_panel_operator_redo_draw_header;
- pt->draw = hud_panel_operator_redo_draw;
- pt->poll = hud_panel_operator_redo_poll;
- pt->space_type = space_type;
- pt->region_type = region_type;
- pt->flag |= PNL_DEFAULT_CLOSED;
- BLI_addtail(&art->paneltypes, pt);
+ PanelType *pt;
+
+ pt = MEM_callocN(sizeof(PanelType), __func__);
+ strcpy(pt->idname, "OPERATOR_PT_redo");
+ strcpy(pt->label, N_("Redo"));
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw_header = hud_panel_operator_redo_draw_header;
+ pt->draw = hud_panel_operator_redo_draw;
+ pt->poll = hud_panel_operator_redo_poll;
+ pt->space_type = space_type;
+ pt->region_type = region_type;
+ pt->flag |= PNL_DEFAULT_CLOSED;
+ BLI_addtail(&art->paneltypes, pt);
}
/** \} */
@@ -136,229 +132,240 @@ static void hud_panels_register(ARegionType *art, int space_type, int region_typ
* \{ */
struct HudRegionData {
- short regionid;
+ short regionid;
};
static void hud_region_init(wmWindowManager *wm, ARegion *ar)
{
- ED_region_panels_init(wm, ar);
- UI_region_handlers_add(&ar->handlers);
- ar->flag |= RGN_FLAG_TEMP_REGIONDATA;
+ ED_region_panels_init(wm, ar);
+ UI_region_handlers_add(&ar->handlers);
+ ar->flag |= RGN_FLAG_TEMP_REGIONDATA;
}
static void hud_region_free(ARegion *ar)
{
- MEM_SAFE_FREE(ar->regiondata);
+ MEM_SAFE_FREE(ar->regiondata);
}
static void hud_region_layout(const bContext *C, ARegion *ar)
{
- bool ok = false;
-
- {
- struct HudRegionData *hrd = ar->regiondata;
- if (hrd != NULL) {
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar_op = (hrd->regionid != -1) ? BKE_area_find_region_type(sa, hrd->regionid) : NULL;
- ARegion *ar_prev = CTX_wm_region(C);
- CTX_wm_region_set((bContext *)C, ar_op);
- ok = last_redo_poll(C);
- CTX_wm_region_set((bContext *)C, ar_prev);
- }
- }
-
- if (!ok) {
- ED_region_tag_redraw(ar);
- hud_region_hide(ar);
- return;
- }
-
- int size_y = ar->sizey;
-
- ED_region_panels_layout(C, ar);
-
- if (ar->panels.first && (ar->sizey != size_y)) {
- int winx_new = UI_DPI_FAC * (ar->sizex + 0.5f);
- int winy_new = UI_DPI_FAC * (ar->sizey + 0.5f);
- View2D *v2d = &ar->v2d;
-
- if (ar->flag & RGN_FLAG_SIZE_CLAMP_X) {
- CLAMP_MAX(winx_new, ar->winx);
- }
- if (ar->flag & RGN_FLAG_SIZE_CLAMP_Y) {
- CLAMP_MAX(winy_new, ar->winy);
- }
-
- ar->winx = winx_new;
- ar->winy = winy_new;
-
- ar->winrct.xmax = (ar->winrct.xmin + ar->winx) - 1;
- ar->winrct.ymax = (ar->winrct.ymin + ar->winy) - 1;
-
- UI_view2d_region_reinit(v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
-
- /* Weak, but needed to avoid glitches, especially with hi-dpi (where resizing the view glitches often).
- * Fortunately this only happens occasionally. */
- ED_region_panels_layout(C, ar);
- }
-
- /* restore view matrix */
- UI_view2d_view_restore(C);
+ bool ok = false;
+
+ {
+ struct HudRegionData *hrd = ar->regiondata;
+ if (hrd != NULL) {
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar_op = (hrd->regionid != -1) ? BKE_area_find_region_type(sa, hrd->regionid) : NULL;
+ ARegion *ar_prev = CTX_wm_region(C);
+ CTX_wm_region_set((bContext *)C, ar_op);
+ ok = last_redo_poll(C);
+ CTX_wm_region_set((bContext *)C, ar_prev);
+ }
+ }
+
+ if (!ok) {
+ ED_region_tag_redraw(ar);
+ hud_region_hide(ar);
+ return;
+ }
+
+ int size_y = ar->sizey;
+
+ ED_region_panels_layout(C, ar);
+
+ if (ar->panels.first && (ar->sizey != size_y)) {
+ int winx_new = UI_DPI_FAC * (ar->sizex + 0.5f);
+ int winy_new = UI_DPI_FAC * (ar->sizey + 0.5f);
+ View2D *v2d = &ar->v2d;
+
+ if (ar->flag & RGN_FLAG_SIZE_CLAMP_X) {
+ CLAMP_MAX(winx_new, ar->winx);
+ }
+ if (ar->flag & RGN_FLAG_SIZE_CLAMP_Y) {
+ CLAMP_MAX(winy_new, ar->winy);
+ }
+
+ ar->winx = winx_new;
+ ar->winy = winy_new;
+
+ ar->winrct.xmax = (ar->winrct.xmin + ar->winx) - 1;
+ ar->winrct.ymax = (ar->winrct.ymin + ar->winy) - 1;
+
+ UI_view2d_region_reinit(v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
+
+ /* Weak, but needed to avoid glitches, especially with hi-dpi (where resizing the view glitches often).
+ * Fortunately this only happens occasionally. */
+ ED_region_panels_layout(C, ar);
+ }
+
+ /* restore view matrix */
+ UI_view2d_view_restore(C);
}
static void hud_region_draw(const bContext *C, ARegion *ar)
{
- UI_view2d_view_ortho(&ar->v2d);
- wmOrtho2_region_pixelspace(ar);
- GPU_clear_color(0, 0, 0, 0.0f);
- GPU_clear(GPU_COLOR_BIT);
-
- if ((ar->flag & RGN_FLAG_HIDDEN) == 0) {
- ui_draw_menu_back(NULL, NULL, &(rcti){ .xmax = ar->winx, .ymax = ar->winy, });
- ED_region_panels_draw(C, ar);
- }
+ UI_view2d_view_ortho(&ar->v2d);
+ wmOrtho2_region_pixelspace(ar);
+ GPU_clear_color(0, 0, 0, 0.0f);
+ GPU_clear(GPU_COLOR_BIT);
+
+ if ((ar->flag & RGN_FLAG_HIDDEN) == 0) {
+ ui_draw_menu_back(NULL,
+ NULL,
+ &(rcti){
+ .xmax = ar->winx,
+ .ymax = ar->winy,
+ });
+ ED_region_panels_draw(C, ar);
+ }
}
ARegionType *ED_area_type_hud(int space_type)
{
- ARegionType *art = MEM_callocN(sizeof(ARegionType), __func__);
- art->regionid = RGN_TYPE_HUD;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
- art->layout = hud_region_layout;
- art->draw = hud_region_draw;
- art->init = hud_region_init;
- art->free = hud_region_free;
-
- hud_panels_register(art, space_type, art->regionid);
-
- art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */
- return art;
+ ARegionType *art = MEM_callocN(sizeof(ARegionType), __func__);
+ art->regionid = RGN_TYPE_HUD;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
+ art->layout = hud_region_layout;
+ art->draw = hud_region_draw;
+ art->init = hud_region_init;
+ art->free = hud_region_free;
+
+ hud_panels_register(art, space_type, art->regionid);
+
+ art->lock = 1; /* can become flag, see BKE_spacedata_draw_locks */
+ return art;
}
static ARegion *hud_region_add(ScrArea *sa)
{
- ARegion *ar = MEM_callocN(sizeof(ARegion), "area region");
- ARegion *ar_win = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar_win) {
- BLI_insertlinkbefore(&sa->regionbase, ar_win, ar);
- }
- else {
- BLI_addtail(&sa->regionbase, ar);
- }
- ar->regiontype = RGN_TYPE_HUD;
- ar->alignment = RGN_ALIGN_FLOAT;
- ar->overlap = true;
- ar->flag |= RGN_FLAG_DYNAMIC_SIZE;
-
- return ar;
+ ARegion *ar = MEM_callocN(sizeof(ARegion), "area region");
+ ARegion *ar_win = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar_win) {
+ BLI_insertlinkbefore(&sa->regionbase, ar_win, ar);
+ }
+ else {
+ BLI_addtail(&sa->regionbase, ar);
+ }
+ ar->regiontype = RGN_TYPE_HUD;
+ ar->alignment = RGN_ALIGN_FLOAT;
+ ar->overlap = true;
+ ar->flag |= RGN_FLAG_DYNAMIC_SIZE;
+
+ return ar;
}
void ED_area_type_hud_clear(wmWindowManager *wm, ScrArea *sa_keep)
{
- for (wmWindow *win = wm->windows.first; win; win = win->next) {
- bScreen *screen = WM_window_get_active_screen(win);
- for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
- if (sa != sa_keep) {
- for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
- if (ar->regiontype == RGN_TYPE_HUD) {
- if ((ar->flag & RGN_FLAG_HIDDEN) == 0) {
- hud_region_hide(ar);
- ED_region_tag_redraw(ar);
- ED_area_tag_redraw(sa);
- }
- }
- }
- }
- }
- }
+ for (wmWindow *win = wm->windows.first; win; win = win->next) {
+ bScreen *screen = WM_window_get_active_screen(win);
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ if (sa != sa_keep) {
+ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
+ if (ar->regiontype == RGN_TYPE_HUD) {
+ if ((ar->flag & RGN_FLAG_HIDDEN) == 0) {
+ hud_region_hide(ar);
+ ED_region_tag_redraw(ar);
+ ED_area_tag_redraw(sa);
+ }
+ }
+ }
+ }
+ }
+ }
}
void ED_area_type_hud_ensure(bContext *C, ScrArea *sa)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- ED_area_type_hud_clear(wm, sa);
-
- ARegionType *art = BKE_regiontype_from_id(sa->type, RGN_TYPE_HUD);
- if (art == NULL) {
- return;
- }
-
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HUD);
- bool init = false;
- bool was_hidden = ar == NULL || ar->visible == false;
- if (!last_redo_poll(C)) {
- if (ar) {
- ED_region_tag_redraw(ar);
- hud_region_hide(ar);
- }
- return;
- }
-
- if (ar == NULL) {
- init = true;
- ar = hud_region_add(sa);
- ar->type = art;
- }
-
- /* Let 'ED_area_update_region_sizes' do the work of placing the region.
- * Otherwise we could set the 'ar->winrct' & 'ar->winx/winy' here. */
- if (init) {
- sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
- }
- else {
- if (ar->flag & RGN_FLAG_HIDDEN) {
- sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
- }
- ar->flag &= ~RGN_FLAG_HIDDEN;
- }
-
- {
- ARegion *ar_op = CTX_wm_region(C);
- BLI_assert((ar_op == NULL) || (ar_op->regiontype != RGN_TYPE_HUD));
- struct HudRegionData *hrd = ar->regiondata;
- if (hrd == NULL) {
- hrd = MEM_callocN(sizeof(*hrd), __func__);
- ar->regiondata = hrd;
- }
- if (ar_op) {
- hrd->regionid = ar_op->regiontype;
- }
- else {
- hrd->regionid = -1;
- }
- }
-
- if (init) {
- /* This is needed or 'winrct' will be invalid. */
- wmWindow *win = CTX_wm_window(C);
- ED_area_update_region_sizes(wm, win, sa);
- }
-
- ED_region_init(ar);
- ED_region_tag_redraw(ar);
-
- /* Reset zoom level (not well supported). */
- ar->v2d.cur = ar->v2d.tot = (rctf){ .xmax = ar->winx, .ymax = ar->winy, };
- ar->v2d.minzoom = 1.0f;
- ar->v2d.maxzoom = 1.0f;
-
- ar->visible = !(ar->flag & RGN_FLAG_HIDDEN);
-
- /* We shouldn't need to do this every time :S */
- /* XXX, this is evil! - it also makes the menu show on first draw. :( */
- if (ar->visible) {
- ARegion *ar_prev = CTX_wm_region(C);
- CTX_wm_region_set((bContext *)C, ar);
- hud_region_layout(C, ar);
- if (was_hidden) {
- ar->winx = ar->v2d.winx;
- ar->winy = ar->v2d.winy;
- ar->v2d.cur = ar->v2d.tot = (rctf){ .xmax = ar->winx, .ymax = ar->winy, };
- }
- CTX_wm_region_set((bContext *)C, ar_prev);
- }
-
- ar->visible = !((ar->flag & RGN_FLAG_HIDDEN) || (ar->flag & RGN_FLAG_TOO_SMALL));
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ED_area_type_hud_clear(wm, sa);
+
+ ARegionType *art = BKE_regiontype_from_id(sa->type, RGN_TYPE_HUD);
+ if (art == NULL) {
+ return;
+ }
+
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HUD);
+ bool init = false;
+ bool was_hidden = ar == NULL || ar->visible == false;
+ if (!last_redo_poll(C)) {
+ if (ar) {
+ ED_region_tag_redraw(ar);
+ hud_region_hide(ar);
+ }
+ return;
+ }
+
+ if (ar == NULL) {
+ init = true;
+ ar = hud_region_add(sa);
+ ar->type = art;
+ }
+
+ /* Let 'ED_area_update_region_sizes' do the work of placing the region.
+ * Otherwise we could set the 'ar->winrct' & 'ar->winx/winy' here. */
+ if (init) {
+ sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
+ }
+ else {
+ if (ar->flag & RGN_FLAG_HIDDEN) {
+ sa->flag |= AREA_FLAG_REGION_SIZE_UPDATE;
+ }
+ ar->flag &= ~RGN_FLAG_HIDDEN;
+ }
+
+ {
+ ARegion *ar_op = CTX_wm_region(C);
+ BLI_assert((ar_op == NULL) || (ar_op->regiontype != RGN_TYPE_HUD));
+ struct HudRegionData *hrd = ar->regiondata;
+ if (hrd == NULL) {
+ hrd = MEM_callocN(sizeof(*hrd), __func__);
+ ar->regiondata = hrd;
+ }
+ if (ar_op) {
+ hrd->regionid = ar_op->regiontype;
+ }
+ else {
+ hrd->regionid = -1;
+ }
+ }
+
+ if (init) {
+ /* This is needed or 'winrct' will be invalid. */
+ wmWindow *win = CTX_wm_window(C);
+ ED_area_update_region_sizes(wm, win, sa);
+ }
+
+ ED_region_init(ar);
+ ED_region_tag_redraw(ar);
+
+ /* Reset zoom level (not well supported). */
+ ar->v2d.cur = ar->v2d.tot = (rctf){
+ .xmax = ar->winx,
+ .ymax = ar->winy,
+ };
+ ar->v2d.minzoom = 1.0f;
+ ar->v2d.maxzoom = 1.0f;
+
+ ar->visible = !(ar->flag & RGN_FLAG_HIDDEN);
+
+ /* We shouldn't need to do this every time :S */
+ /* XXX, this is evil! - it also makes the menu show on first draw. :( */
+ if (ar->visible) {
+ ARegion *ar_prev = CTX_wm_region(C);
+ CTX_wm_region_set((bContext *)C, ar);
+ hud_region_layout(C, ar);
+ if (was_hidden) {
+ ar->winx = ar->v2d.winx;
+ ar->winy = ar->v2d.winy;
+ ar->v2d.cur = ar->v2d.tot = (rctf){
+ .xmax = ar->winx,
+ .ymax = ar->winy,
+ };
+ }
+ CTX_wm_region_set((bContext *)C, ar_prev);
+ }
+
+ ar->visible = !((ar->flag & RGN_FLAG_HIDDEN) || (ar->flag & RGN_FLAG_TOO_SMALL));
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c
index b2fcfc0b23b..b115600a80b 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.c
+++ b/source/blender/editors/interface/interface_region_menu_pie.c
@@ -59,225 +59,249 @@
* \{ */
struct uiPieMenu {
- uiBlock *block_radial; /* radial block of the pie menu (more could be added later) */
- uiLayout *layout;
- int mx, my;
+ uiBlock *block_radial; /* radial block of the pie menu (more could be added later) */
+ uiLayout *layout;
+ int mx, my;
};
static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handle, void *arg_pie)
{
- uiBlock *block;
- uiPieMenu *pie = arg_pie;
- int minwidth, width, height;
+ uiBlock *block;
+ uiPieMenu *pie = arg_pie;
+ int minwidth, width, height;
- minwidth = UI_MENU_WIDTH_MIN;
- block = pie->block_radial;
+ minwidth = UI_MENU_WIDTH_MIN;
+ block = pie->block_radial;
- /* in some cases we create the block before the region,
- * so we set it delayed here if necessary */
- if (BLI_findindex(&handle->region->uiblocks, block) == -1) {
- UI_block_region_set(block, handle->region);
- }
+ /* in some cases we create the block before the region,
+ * so we set it delayed here if necessary */
+ if (BLI_findindex(&handle->region->uiblocks, block) == -1) {
+ UI_block_region_set(block, handle->region);
+ }
- UI_block_layout_resolve(block, &width, &height);
+ UI_block_layout_resolve(block, &width, &height);
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
- block->minbounds = minwidth;
- block->bounds = 1;
- block->bounds_offset[0] = 0;
- block->bounds_offset[1] = 0;
- block->bounds_type = UI_BLOCK_BOUNDS_PIE_CENTER;
+ block->minbounds = minwidth;
+ block->bounds = 1;
+ block->bounds_offset[0] = 0;
+ block->bounds_offset[1] = 0;
+ block->bounds_type = UI_BLOCK_BOUNDS_PIE_CENTER;
- block->pie_data.pie_center_spawned[0] = pie->mx;
- block->pie_data.pie_center_spawned[1] = pie->my;
+ block->pie_data.pie_center_spawned[0] = pie->mx;
+ block->pie_data.pie_center_spawned[1] = pie->my;
- return pie->block_radial;
+ return pie->block_radial;
}
static float ui_pie_menu_title_width(const char *name, int icon)
{
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- return (UI_fontstyle_string_width(fstyle, name) +
- (UI_UNIT_X * (1.50f + (icon ? 0.25f : 0.0f))));
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ return (UI_fontstyle_string_width(fstyle, name) + (UI_UNIT_X * (1.50f + (icon ? 0.25f : 0.0f))));
}
uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, const wmEvent *event)
{
- uiStyle *style;
- uiPieMenu *pie;
- short event_type;
-
- wmWindow *win = CTX_wm_window(C);
-
- style = UI_style_get_dpi();
- pie = MEM_callocN(sizeof(*pie), "pie menu");
-
- pie->block_radial = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
- /* may be useful later to allow spawning pies
- * from old positions */
- /* pie->block_radial->flag |= UI_BLOCK_POPUP_MEMORY; */
- pie->block_radial->puphash = ui_popup_menu_hash(title);
- pie->block_radial->flag |= UI_BLOCK_RADIAL;
-
- /* if pie is spawned by a left click, release or click event,
- * it is always assumed to be click style */
- if (event->type == LEFTMOUSE || ELEM(event->val, KM_RELEASE, KM_CLICK)) {
- pie->block_radial->pie_data.flags |= UI_PIE_CLICK_STYLE;
- pie->block_radial->pie_data.event = EVENT_NONE;
- win->lock_pie_event = EVENT_NONE;
- }
- else {
- if (win->last_pie_event != EVENT_NONE) {
- /* original pie key has been released, so don't propagate the event */
- if (win->lock_pie_event == EVENT_NONE) {
- event_type = EVENT_NONE;
- pie->block_radial->pie_data.flags |= UI_PIE_CLICK_STYLE;
- }
- else {
- event_type = win->last_pie_event;
- }
- }
- else {
- event_type = event->type;
- }
-
- pie->block_radial->pie_data.event = event_type;
- win->lock_pie_event = event_type;
- }
-
- pie->layout = UI_block_layout(pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style);
-
- /* Note event->x/y is where we started dragging in case of KM_CLICK_DRAG. */
- pie->mx = event->x;
- pie->my = event->y;
-
- /* create title button */
- if (title[0]) {
- uiBut *but;
- char titlestr[256];
- int w;
- if (icon) {
- BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
- w = ui_pie_menu_title_width(titlestr, icon);
- but = uiDefIconTextBut(
- pie->block_radial, UI_BTYPE_LABEL, 0, icon, titlestr, 0, 0, w, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0, "");
- }
- else {
- w = ui_pie_menu_title_width(title, 0);
- but = uiDefBut(
- pie->block_radial, UI_BTYPE_LABEL, 0, title, 0, 0, w, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0, "");
- }
- /* do not align left */
- but->drawflag &= ~UI_BUT_TEXT_LEFT;
- pie->block_radial->pie_data.title = but->str;
- pie->block_radial->pie_data.icon = icon;
- }
-
- return pie;
+ uiStyle *style;
+ uiPieMenu *pie;
+ short event_type;
+
+ wmWindow *win = CTX_wm_window(C);
+
+ style = UI_style_get_dpi();
+ pie = MEM_callocN(sizeof(*pie), "pie menu");
+
+ pie->block_radial = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
+ /* may be useful later to allow spawning pies
+ * from old positions */
+ /* pie->block_radial->flag |= UI_BLOCK_POPUP_MEMORY; */
+ pie->block_radial->puphash = ui_popup_menu_hash(title);
+ pie->block_radial->flag |= UI_BLOCK_RADIAL;
+
+ /* if pie is spawned by a left click, release or click event,
+ * it is always assumed to be click style */
+ if (event->type == LEFTMOUSE || ELEM(event->val, KM_RELEASE, KM_CLICK)) {
+ pie->block_radial->pie_data.flags |= UI_PIE_CLICK_STYLE;
+ pie->block_radial->pie_data.event = EVENT_NONE;
+ win->lock_pie_event = EVENT_NONE;
+ }
+ else {
+ if (win->last_pie_event != EVENT_NONE) {
+ /* original pie key has been released, so don't propagate the event */
+ if (win->lock_pie_event == EVENT_NONE) {
+ event_type = EVENT_NONE;
+ pie->block_radial->pie_data.flags |= UI_PIE_CLICK_STYLE;
+ }
+ else {
+ event_type = win->last_pie_event;
+ }
+ }
+ else {
+ event_type = event->type;
+ }
+
+ pie->block_radial->pie_data.event = event_type;
+ win->lock_pie_event = event_type;
+ }
+
+ pie->layout = UI_block_layout(
+ pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style);
+
+ /* Note event->x/y is where we started dragging in case of KM_CLICK_DRAG. */
+ pie->mx = event->x;
+ pie->my = event->y;
+
+ /* create title button */
+ if (title[0]) {
+ uiBut *but;
+ char titlestr[256];
+ int w;
+ if (icon) {
+ BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
+ w = ui_pie_menu_title_width(titlestr, icon);
+ but = uiDefIconTextBut(pie->block_radial,
+ UI_BTYPE_LABEL,
+ 0,
+ icon,
+ titlestr,
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ }
+ else {
+ w = ui_pie_menu_title_width(title, 0);
+ but = uiDefBut(pie->block_radial,
+ UI_BTYPE_LABEL,
+ 0,
+ title,
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ }
+ /* do not align left */
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
+ pie->block_radial->pie_data.title = but->str;
+ pie->block_radial->pie_data.icon = icon;
+ }
+
+ return pie;
}
void UI_pie_menu_end(bContext *C, uiPieMenu *pie)
{
- wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *menu;
+ wmWindow *window = CTX_wm_window(C);
+ uiPopupBlockHandle *menu;
- menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PIE, pie);
- menu->popup = true;
- menu->towardstime = PIL_check_seconds_timer();
+ menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PIE, pie);
+ menu->popup = true;
+ menu->towardstime = PIL_check_seconds_timer();
- UI_popup_handlers_add(
- C, &window->modalhandlers,
- menu, WM_HANDLER_ACCEPT_DBL_CLICK);
- WM_event_add_mousemove(C);
+ UI_popup_handlers_add(C, &window->modalhandlers, menu, WM_HANDLER_ACCEPT_DBL_CLICK);
+ WM_event_add_mousemove(C);
- MEM_freeN(pie);
+ MEM_freeN(pie);
}
uiLayout *UI_pie_menu_layout(uiPieMenu *pie)
{
- return pie->layout;
+ return pie->layout;
}
int UI_pie_menu_invoke(struct bContext *C, const char *idname, const wmEvent *event)
{
- uiPieMenu *pie;
- uiLayout *layout;
- MenuType *mt = WM_menutype_find(idname, true);
+ uiPieMenu *pie;
+ uiLayout *layout;
+ MenuType *mt = WM_menutype_find(idname, true);
- if (mt == NULL) {
- printf("%s: named menu \"%s\" not found\n", __func__, idname);
- return OPERATOR_CANCELLED;
- }
+ if (mt == NULL) {
+ printf("%s: named menu \"%s\" not found\n", __func__, idname);
+ return OPERATOR_CANCELLED;
+ }
- if (WM_menutype_poll(C, mt) == false) {
- /* cancel but allow event to pass through, just like operators do */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
+ if (WM_menutype_poll(C, mt) == false) {
+ /* cancel but allow event to pass through, just like operators do */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
- pie = UI_pie_menu_begin(C, IFACE_(mt->label), ICON_NONE, event);
- layout = UI_pie_menu_layout(pie);
+ pie = UI_pie_menu_begin(C, IFACE_(mt->label), ICON_NONE, event);
+ layout = UI_pie_menu_layout(pie);
- UI_menutype_draw(C, mt, layout);
+ UI_menutype_draw(C, mt, layout);
- UI_pie_menu_end(C, pie);
+ UI_pie_menu_end(C, pie);
- return OPERATOR_INTERFACE;
+ return OPERATOR_INTERFACE;
}
-int UI_pie_menu_invoke_from_operator_enum(
- struct bContext *C, const char *title, const char *opname,
- const char *propname, const wmEvent *event)
+int UI_pie_menu_invoke_from_operator_enum(struct bContext *C,
+ const char *title,
+ const char *opname,
+ const char *propname,
+ const wmEvent *event)
{
- uiPieMenu *pie;
- uiLayout *layout;
+ uiPieMenu *pie;
+ uiLayout *layout;
- pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event);
- layout = UI_pie_menu_layout(pie);
+ pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event);
+ layout = UI_pie_menu_layout(pie);
- layout = uiLayoutRadial(layout);
- uiItemsEnumO(layout, opname, propname);
+ layout = uiLayoutRadial(layout);
+ uiItemsEnumO(layout, opname, propname);
- UI_pie_menu_end(C, pie);
+ UI_pie_menu_end(C, pie);
- return OPERATOR_INTERFACE;
+ return OPERATOR_INTERFACE;
}
-int UI_pie_menu_invoke_from_rna_enum(
- struct bContext *C, const char *title, const char *path,
- const wmEvent *event)
+int UI_pie_menu_invoke_from_rna_enum(struct bContext *C,
+ const char *title,
+ const char *path,
+ const wmEvent *event)
{
- PointerRNA ctx_ptr;
- PointerRNA r_ptr;
- PropertyRNA *r_prop;
- uiPieMenu *pie;
- uiLayout *layout;
+ PointerRNA ctx_ptr;
+ PointerRNA r_ptr;
+ PropertyRNA *r_prop;
+ uiPieMenu *pie;
+ uiLayout *layout;
- RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
+ RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
- if (!RNA_path_resolve(&ctx_ptr, path, &r_ptr, &r_prop)) {
- return OPERATOR_CANCELLED;
- }
+ if (!RNA_path_resolve(&ctx_ptr, path, &r_ptr, &r_prop)) {
+ return OPERATOR_CANCELLED;
+ }
- /* invalid property, only accept enums */
- if (RNA_property_type(r_prop) != PROP_ENUM) {
- BLI_assert(0);
- return OPERATOR_CANCELLED;
- }
+ /* invalid property, only accept enums */
+ if (RNA_property_type(r_prop) != PROP_ENUM) {
+ BLI_assert(0);
+ return OPERATOR_CANCELLED;
+ }
- pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event);
+ pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event);
- layout = UI_pie_menu_layout(pie);
+ layout = UI_pie_menu_layout(pie);
- layout = uiLayoutRadial(layout);
- uiItemFullR(layout, &r_ptr, r_prop, RNA_NO_INDEX, 0, UI_ITEM_R_EXPAND, NULL, 0);
+ layout = uiLayoutRadial(layout);
+ uiItemFullR(layout, &r_ptr, r_prop, RNA_NO_INDEX, 0, UI_ITEM_R_EXPAND, NULL, 0);
- UI_pie_menu_end(C, pie);
+ UI_pie_menu_end(C, pie);
- return OPERATOR_INTERFACE;
+ return OPERATOR_INTERFACE;
}
/** \} */
@@ -298,15 +322,15 @@ int UI_pie_menu_invoke_from_rna_enum(
* \{ */
typedef struct PieMenuLevelData {
- char title[UI_MAX_NAME_STR]; /* parent pie title, copied for level */
- int icon; /* parent pie icon, copied for level */
- int totitem; /* total count of *remaining* items */
-
- /* needed for calling uiItemsFullEnumO_array again for new level */
- wmOperatorType *ot;
- const char *propname;
- IDProperty *properties;
- int context, flag;
+ char title[UI_MAX_NAME_STR]; /* parent pie title, copied for level */
+ int icon; /* parent pie icon, copied for level */
+ int totitem; /* total count of *remaining* items */
+
+ /* needed for calling uiItemsFullEnumO_array again for new level */
+ wmOperatorType *ot;
+ const char *propname;
+ IDProperty *properties;
+ int context, flag;
} PieMenuLevelData;
/**
@@ -314,66 +338,90 @@ typedef struct PieMenuLevelData {
*/
static void ui_pie_menu_level_invoke(bContext *C, void *argN, void *arg2)
{
- EnumPropertyItem *item_array = (EnumPropertyItem *)argN;
- PieMenuLevelData *lvl = (PieMenuLevelData *)arg2;
- wmWindow *win = CTX_wm_window(C);
-
- uiPieMenu *pie = UI_pie_menu_begin(C, IFACE_(lvl->title), lvl->icon, win->eventstate);
- uiLayout *layout = UI_pie_menu_layout(pie);
-
- layout = uiLayoutRadial(layout);
-
- PointerRNA ptr;
-
- WM_operator_properties_create_ptr(&ptr, lvl->ot);
- /* so the context is passed to itemf functions (some need it) */
- WM_operator_properties_sanitize(&ptr, false);
- PropertyRNA *prop = RNA_struct_find_property(&ptr, lvl->propname);
-
- if (prop) {
- uiItemsFullEnumO_items(
- layout, lvl->ot, ptr, prop, lvl->properties, lvl->context, lvl->flag,
- item_array, lvl->totitem);
- }
- else {
- RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), lvl->propname);
- }
-
- UI_pie_menu_end(C, pie);
+ EnumPropertyItem *item_array = (EnumPropertyItem *)argN;
+ PieMenuLevelData *lvl = (PieMenuLevelData *)arg2;
+ wmWindow *win = CTX_wm_window(C);
+
+ uiPieMenu *pie = UI_pie_menu_begin(C, IFACE_(lvl->title), lvl->icon, win->eventstate);
+ uiLayout *layout = UI_pie_menu_layout(pie);
+
+ layout = uiLayoutRadial(layout);
+
+ PointerRNA ptr;
+
+ WM_operator_properties_create_ptr(&ptr, lvl->ot);
+ /* so the context is passed to itemf functions (some need it) */
+ WM_operator_properties_sanitize(&ptr, false);
+ PropertyRNA *prop = RNA_struct_find_property(&ptr, lvl->propname);
+
+ if (prop) {
+ uiItemsFullEnumO_items(layout,
+ lvl->ot,
+ ptr,
+ prop,
+ lvl->properties,
+ lvl->context,
+ lvl->flag,
+ item_array,
+ lvl->totitem);
+ }
+ else {
+ RNA_warning("%s.%s not found", RNA_struct_identifier(ptr.type), lvl->propname);
+ }
+
+ UI_pie_menu_end(C, pie);
}
/**
* Set up data for defining a new pie menu level and add button that invokes it.
*/
-void ui_pie_menu_level_create(
- uiBlock *block, wmOperatorType *ot, const char *propname, IDProperty *properties,
- const EnumPropertyItem *items, int totitem, int context, int flag)
+void ui_pie_menu_level_create(uiBlock *block,
+ wmOperatorType *ot,
+ const char *propname,
+ IDProperty *properties,
+ const EnumPropertyItem *items,
+ int totitem,
+ int context,
+ int flag)
{
- const int totitem_parent = PIE_MAX_ITEMS - 1;
- const int totitem_remain = totitem - totitem_parent;
- size_t array_size = sizeof(EnumPropertyItem) * totitem_remain;
-
- /* used as but->func_argN so freeing is handled elsewhere */
- EnumPropertyItem *remaining = MEM_mallocN(array_size + sizeof(EnumPropertyItem), "pie_level_item_array");
- memcpy(remaining, items + totitem_parent, array_size);
- /* a NULL terminating sentinal element is required */
- memset(&remaining[totitem_remain], 0, sizeof(EnumPropertyItem));
-
-
- /* yuk, static... issue is we can't reliably free this without doing dangerous changes */
- static PieMenuLevelData lvl;
- BLI_strncpy(lvl.title, block->pie_data.title, UI_MAX_NAME_STR);
- lvl.totitem = totitem_remain;
- lvl.ot = ot;
- lvl.propname = propname;
- lvl.properties = properties;
- lvl.context = context;
- lvl.flag = flag;
-
- /* add a 'more' menu entry */
- uiBut *but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_PLUS, "More", 0, 0, UI_UNIT_X * 3, UI_UNIT_Y, NULL,
- 0.0f, 0.0f, 0.0f, 0.0f, "Show more items of this menu");
- UI_but_funcN_set(but, ui_pie_menu_level_invoke, remaining, &lvl);
+ const int totitem_parent = PIE_MAX_ITEMS - 1;
+ const int totitem_remain = totitem - totitem_parent;
+ size_t array_size = sizeof(EnumPropertyItem) * totitem_remain;
+
+ /* used as but->func_argN so freeing is handled elsewhere */
+ EnumPropertyItem *remaining = MEM_mallocN(array_size + sizeof(EnumPropertyItem),
+ "pie_level_item_array");
+ memcpy(remaining, items + totitem_parent, array_size);
+ /* a NULL terminating sentinal element is required */
+ memset(&remaining[totitem_remain], 0, sizeof(EnumPropertyItem));
+
+ /* yuk, static... issue is we can't reliably free this without doing dangerous changes */
+ static PieMenuLevelData lvl;
+ BLI_strncpy(lvl.title, block->pie_data.title, UI_MAX_NAME_STR);
+ lvl.totitem = totitem_remain;
+ lvl.ot = ot;
+ lvl.propname = propname;
+ lvl.properties = properties;
+ lvl.context = context;
+ lvl.flag = flag;
+
+ /* add a 'more' menu entry */
+ uiBut *but = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_PLUS,
+ "More",
+ 0,
+ 0,
+ UI_UNIT_X * 3,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ "Show more items of this menu");
+ UI_but_funcN_set(but, ui_pie_menu_level_invoke, remaining, &lvl);
}
/** \} */ /* Pie Menu Levels */
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index 0fe847caa20..d364bf7e102 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -64,90 +64,91 @@
bool ui_but_menu_step_poll(const uiBut *but)
{
- BLI_assert(but->type == UI_BTYPE_MENU);
+ BLI_assert(but->type == UI_BTYPE_MENU);
- /* currently only RNA buttons */
- return ((but->menu_step_func != NULL) ||
- (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM));
+ /* currently only RNA buttons */
+ return ((but->menu_step_func != NULL) ||
+ (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM));
}
int ui_but_menu_step(uiBut *but, int direction)
{
- if (ui_but_menu_step_poll(but)) {
- if (but->menu_step_func) {
- return but->menu_step_func(but->block->evil_C, direction, but->poin);
- }
- else {
- const int curval = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
- return RNA_property_enum_step(but->block->evil_C, &but->rnapoin, but->rnaprop, curval, direction);
- }
- }
-
- printf("%s: cannot cycle button '%s'\n", __func__, but->str);
- return 0;
+ if (ui_but_menu_step_poll(but)) {
+ if (but->menu_step_func) {
+ return but->menu_step_func(but->block->evil_C, direction, but->poin);
+ }
+ else {
+ const int curval = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
+ return RNA_property_enum_step(
+ but->block->evil_C, &but->rnapoin, but->rnaprop, curval, direction);
+ }
+ }
+
+ printf("%s: cannot cycle button '%s'\n", __func__, but->str);
+ return 0;
}
static uint ui_popup_string_hash(const char *str)
{
- /* sometimes button contains hotkey, sometimes not, strip for proper compare */
- int hash;
- const char *delimit = strrchr(str, UI_SEP_CHAR);
-
- if (delimit) {
- hash = BLI_ghashutil_strhash_n(str, delimit - str);
- }
- else {
- hash = BLI_ghashutil_strhash(str);
- }
-
- return hash;
+ /* sometimes button contains hotkey, sometimes not, strip for proper compare */
+ int hash;
+ const char *delimit = strrchr(str, UI_SEP_CHAR);
+
+ if (delimit) {
+ hash = BLI_ghashutil_strhash_n(str, delimit - str);
+ }
+ else {
+ hash = BLI_ghashutil_strhash(str);
+ }
+
+ return hash;
}
uint ui_popup_menu_hash(const char *str)
{
- return BLI_ghashutil_strhash(str);
+ return BLI_ghashutil_strhash(str);
}
/* but == NULL read, otherwise set */
static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
{
- static uint mem[256];
- static bool first = true;
-
- const uint hash = block->puphash;
- const uint hash_mod = hash & 255;
-
- if (first) {
- /* init */
- memset(mem, -1, sizeof(mem));
- first = 0;
- }
-
- if (but) {
- /* set */
- mem[hash_mod] = ui_popup_string_hash(but->str);
- return NULL;
- }
- else {
- /* get */
- for (but = block->buttons.first; but; but = but->next) {
- if (ui_popup_string_hash(but->str) == mem[hash_mod]) {
- return but;
- }
- }
-
- return NULL;
- }
+ static uint mem[256];
+ static bool first = true;
+
+ const uint hash = block->puphash;
+ const uint hash_mod = hash & 255;
+
+ if (first) {
+ /* init */
+ memset(mem, -1, sizeof(mem));
+ first = 0;
+ }
+
+ if (but) {
+ /* set */
+ mem[hash_mod] = ui_popup_string_hash(but->str);
+ return NULL;
+ }
+ else {
+ /* get */
+ for (but = block->buttons.first; but; but = but->next) {
+ if (ui_popup_string_hash(but->str) == mem[hash_mod]) {
+ return but;
+ }
+ }
+
+ return NULL;
+ }
}
uiBut *ui_popup_menu_memory_get(uiBlock *block)
{
- return ui_popup_menu_memory__internal(block, NULL);
+ return ui_popup_menu_memory__internal(block, NULL);
}
void ui_popup_menu_memory_set(uiBlock *block, uiBut *but)
{
- ui_popup_menu_memory__internal(block, but);
+ ui_popup_menu_memory__internal(block, but);
}
/** \} */
@@ -157,213 +158,211 @@ void ui_popup_menu_memory_set(uiBlock *block, uiBut *but)
* \{ */
struct uiPopupMenu {
- uiBlock *block;
- uiLayout *layout;
- uiBut *but;
- ARegion *butregion;
+ uiBlock *block;
+ uiLayout *layout;
+ uiBut *but;
+ ARegion *butregion;
- int mx, my;
- bool popup, slideout;
+ int mx, my;
+ bool popup, slideout;
- uiMenuCreateFunc menu_func;
- void *menu_arg;
+ uiMenuCreateFunc menu_func;
+ void *menu_arg;
};
static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
{
- uiBlock *block;
- uiPopupMenu *pup = arg_pup;
- int minwidth, width, height;
- char direction;
- bool flip;
-
- if (pup->menu_func) {
- pup->block->handle = handle;
- pup->menu_func(C, pup->layout, pup->menu_arg);
- pup->block->handle = NULL;
- }
-
- if (pup->but) {
- /* minimum width to enforece */
- if (pup->but->drawstr[0]) {
- minwidth = BLI_rctf_size_x(&pup->but->rect);
- }
- else {
- /* For buttons with no text, use the minimum (typically icon only). */
- minwidth = UI_MENU_WIDTH_MIN;
- }
-
- if (pup->block->direction != 0) {
- /* allow overriding the direction from menu_func */
- direction = pup->block->direction;
- }
- else {
- direction = UI_DIR_DOWN;
- }
- }
- else {
- minwidth = UI_MENU_WIDTH_MIN;
- direction = UI_DIR_DOWN;
- }
-
- flip = (direction == UI_DIR_DOWN);
-
- block = pup->block;
-
- /* in some cases we create the block before the region,
- * so we set it delayed here if necessary */
- if (BLI_findindex(&handle->region->uiblocks, block) == -1) {
- UI_block_region_set(block, handle->region);
- }
-
- block->direction = direction;
-
- UI_block_layout_resolve(block, &width, &height);
-
- UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
-
- if (pup->popup) {
- uiBut *bt;
- int offset[2];
-
- uiBut *but_activate = NULL;
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
- UI_block_direction_set(block, direction);
-
- /* offset the mouse position, possibly based on earlier selection */
- if ((block->flag & UI_BLOCK_POPUP_MEMORY) &&
- (bt = ui_popup_menu_memory_get(block)))
- {
- /* position mouse on last clicked item, at 0.8*width of the
- * button, so it doesn't overlap the text too much, also note
- * the offset is negative because we are inverse moving the
- * block to be under the mouse */
- offset[0] = -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect));
- offset[1] = -(bt->rect.ymin + 0.5f * UI_UNIT_Y);
-
- if (ui_but_is_editable(bt)) {
- but_activate = bt;
- }
- }
- else {
- /* position mouse at 0.8*width of the button and below the tile
- * on the first item */
- offset[0] = 0;
- for (bt = block->buttons.first; bt; bt = bt->next) {
- offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect)));
- }
-
- offset[1] = 2.1 * UI_UNIT_Y;
-
- for (bt = block->buttons.first; bt; bt = bt->next) {
- if (ui_but_is_editable(bt)) {
- but_activate = bt;
- break;
- }
- }
- }
-
- /* in rare cases this is needed since moving the popup
- * to be within the window bounds may move it away from the mouse,
- * This ensures we set an item to be active. */
- if (but_activate) {
- ui_but_activate_over(C, handle->region, but_activate);
- }
-
- block->minbounds = minwidth;
- UI_block_bounds_set_menu(block, 1, offset);
- }
- else {
- /* for a header menu we set the direction automatic */
- if (!pup->slideout && flip) {
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- if (sa && ar) {
- if (ar->regiontype == RGN_TYPE_HEADER) {
- if (ED_area_header_alignment(sa) == RGN_ALIGN_BOTTOM) {
- UI_block_direction_set(block, UI_DIR_UP);
- UI_block_order_flip(block);
- }
- }
- if (ar->regiontype == RGN_TYPE_FOOTER) {
- if (ED_area_footer_alignment(sa) == RGN_ALIGN_BOTTOM) {
- UI_block_direction_set(block, UI_DIR_UP);
- UI_block_order_flip(block);
- }
- }
- }
- }
-
- block->minbounds = minwidth;
- UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
- }
-
- /* if menu slides out of other menu, override direction */
- if (pup->slideout) {
- UI_block_direction_set(block, UI_DIR_RIGHT);
- }
-
- return pup->block;
+ uiBlock *block;
+ uiPopupMenu *pup = arg_pup;
+ int minwidth, width, height;
+ char direction;
+ bool flip;
+
+ if (pup->menu_func) {
+ pup->block->handle = handle;
+ pup->menu_func(C, pup->layout, pup->menu_arg);
+ pup->block->handle = NULL;
+ }
+
+ if (pup->but) {
+ /* minimum width to enforece */
+ if (pup->but->drawstr[0]) {
+ minwidth = BLI_rctf_size_x(&pup->but->rect);
+ }
+ else {
+ /* For buttons with no text, use the minimum (typically icon only). */
+ minwidth = UI_MENU_WIDTH_MIN;
+ }
+
+ if (pup->block->direction != 0) {
+ /* allow overriding the direction from menu_func */
+ direction = pup->block->direction;
+ }
+ else {
+ direction = UI_DIR_DOWN;
+ }
+ }
+ else {
+ minwidth = UI_MENU_WIDTH_MIN;
+ direction = UI_DIR_DOWN;
+ }
+
+ flip = (direction == UI_DIR_DOWN);
+
+ block = pup->block;
+
+ /* in some cases we create the block before the region,
+ * so we set it delayed here if necessary */
+ if (BLI_findindex(&handle->region->uiblocks, block) == -1) {
+ UI_block_region_set(block, handle->region);
+ }
+
+ block->direction = direction;
+
+ UI_block_layout_resolve(block, &width, &height);
+
+ UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
+
+ if (pup->popup) {
+ uiBut *bt;
+ int offset[2];
+
+ uiBut *but_activate = NULL;
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+ UI_block_direction_set(block, direction);
+
+ /* offset the mouse position, possibly based on earlier selection */
+ if ((block->flag & UI_BLOCK_POPUP_MEMORY) && (bt = ui_popup_menu_memory_get(block))) {
+ /* position mouse on last clicked item, at 0.8*width of the
+ * button, so it doesn't overlap the text too much, also note
+ * the offset is negative because we are inverse moving the
+ * block to be under the mouse */
+ offset[0] = -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect));
+ offset[1] = -(bt->rect.ymin + 0.5f * UI_UNIT_Y);
+
+ if (ui_but_is_editable(bt)) {
+ but_activate = bt;
+ }
+ }
+ else {
+ /* position mouse at 0.8*width of the button and below the tile
+ * on the first item */
+ offset[0] = 0;
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect)));
+ }
+
+ offset[1] = 2.1 * UI_UNIT_Y;
+
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (ui_but_is_editable(bt)) {
+ but_activate = bt;
+ break;
+ }
+ }
+ }
+
+ /* in rare cases this is needed since moving the popup
+ * to be within the window bounds may move it away from the mouse,
+ * This ensures we set an item to be active. */
+ if (but_activate) {
+ ui_but_activate_over(C, handle->region, but_activate);
+ }
+
+ block->minbounds = minwidth;
+ UI_block_bounds_set_menu(block, 1, offset);
+ }
+ else {
+ /* for a header menu we set the direction automatic */
+ if (!pup->slideout && flip) {
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ if (sa && ar) {
+ if (ar->regiontype == RGN_TYPE_HEADER) {
+ if (ED_area_header_alignment(sa) == RGN_ALIGN_BOTTOM) {
+ UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_order_flip(block);
+ }
+ }
+ if (ar->regiontype == RGN_TYPE_FOOTER) {
+ if (ED_area_footer_alignment(sa) == RGN_ALIGN_BOTTOM) {
+ UI_block_direction_set(block, UI_DIR_UP);
+ UI_block_order_flip(block);
+ }
+ }
+ }
+ }
+
+ block->minbounds = minwidth;
+ UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
+ }
+
+ /* if menu slides out of other menu, override direction */
+ if (pup->slideout) {
+ UI_block_direction_set(block, UI_DIR_RIGHT);
+ }
+
+ return pup->block;
}
uiPopupBlockHandle *ui_popup_menu_create(
- bContext *C, ARegion *butregion, uiBut *but,
- uiMenuCreateFunc menu_func, void *arg)
+ bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg)
{
- wmWindow *window = CTX_wm_window(C);
- uiStyle *style = UI_style_get_dpi();
- uiPopupBlockHandle *handle;
- uiPopupMenu *pup;
-
- pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
- pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN);
- pup->block->flag |= UI_BLOCK_NUMSELECT; /* default menus to numselect */
- pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
- pup->slideout = but ? ui_block_is_menu(but->block) : false;
- pup->but = but;
- uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN);
-
- if (!but) {
- /* no button to start from, means we are a popup */
- pup->mx = window->eventstate->x;
- pup->my = window->eventstate->y;
- pup->popup = true;
- pup->block->flag |= UI_BLOCK_NO_FLIP;
- }
- /* some enums reversing is strange, currently we have no good way to
- * reverse some enum's but not others, so reverse all so the first menu
- * items are always close to the mouse cursor */
- else {
+ wmWindow *window = CTX_wm_window(C);
+ uiStyle *style = UI_style_get_dpi();
+ uiPopupBlockHandle *handle;
+ uiPopupMenu *pup;
+
+ pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
+ pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN);
+ pup->block->flag |= UI_BLOCK_NUMSELECT; /* default menus to numselect */
+ pup->layout = UI_block_layout(
+ pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
+ pup->slideout = but ? ui_block_is_menu(but->block) : false;
+ pup->but = but;
+ uiLayoutSetOperatorContext(pup->layout, WM_OP_INVOKE_REGION_WIN);
+
+ if (!but) {
+ /* no button to start from, means we are a popup */
+ pup->mx = window->eventstate->x;
+ pup->my = window->eventstate->y;
+ pup->popup = true;
+ pup->block->flag |= UI_BLOCK_NO_FLIP;
+ }
+ /* some enums reversing is strange, currently we have no good way to
+ * reverse some enum's but not others, so reverse all so the first menu
+ * items are always close to the mouse cursor */
+ else {
#if 0
- /* if this is an rna button then we can assume its an enum
- * flipping enums is generally not good since the order can be
- * important [#28786] */
- if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
- pup->block->flag |= UI_BLOCK_NO_FLIP;
- }
+ /* if this is an rna button then we can assume its an enum
+ * flipping enums is generally not good since the order can be
+ * important [#28786] */
+ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
+ pup->block->flag |= UI_BLOCK_NO_FLIP;
+ }
#endif
- if (but->context) {
- uiLayoutContextCopy(pup->layout, but->context);
- }
- }
+ if (but->context) {
+ uiLayoutContextCopy(pup->layout, but->context);
+ }
+ }
- /* menu is created from a callback */
- pup->menu_func = menu_func;
- pup->menu_arg = arg;
+ /* menu is created from a callback */
+ pup->menu_func = menu_func;
+ pup->menu_arg = arg;
- handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
+ handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
- if (!but) {
- handle->popup = true;
+ if (!but) {
+ handle->popup = true;
- UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- WM_event_add_mousemove(C);
- }
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
+ WM_event_add_mousemove(C);
+ }
- MEM_freeN(pup);
+ MEM_freeN(pup);
- return handle;
+ return handle;
}
/** \} */
@@ -376,48 +375,66 @@ uiPopupBlockHandle *ui_popup_menu_create(
* Only return handler, and set optional title.
* \param block_name: Assigned to uiBlock.name (useful info for debugging).
*/
-uiPopupMenu *UI_popup_menu_begin_ex(bContext *C, const char *title, const char *block_name, int icon)
+uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
+ const char *title,
+ const char *block_name,
+ int icon)
{
- uiStyle *style = UI_style_get_dpi();
- uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
- uiBut *but;
-
- pup->block = UI_block_begin(C, NULL, block_name, UI_EMBOSS_PULLDOWN);
- pup->block->flag |= UI_BLOCK_POPUP_MEMORY | UI_BLOCK_IS_FLIP;
- pup->block->puphash = ui_popup_menu_hash(title);
- pup->layout = UI_block_layout(pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
-
- /* note, this intentionally differs from the menu & submenu default because many operators
- * use popups like this to select one of their options -
- * where having invoke doesn't make sense */
- uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
-
- /* create in advance so we can let buttons point to retval already */
- pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
-
- /* create title button */
- if (title[0]) {
- char titlestr[256];
-
- if (icon) {
- BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
- uiDefIconTextBut(
- pup->block, UI_BTYPE_LABEL, 0, icon, titlestr, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- }
- else {
- but = uiDefBut(pup->block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- but->drawflag = UI_BUT_TEXT_LEFT;
- }
-
- uiItemS(pup->layout);
- }
-
- return pup;
+ uiStyle *style = UI_style_get_dpi();
+ uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
+ uiBut *but;
+
+ pup->block = UI_block_begin(C, NULL, block_name, UI_EMBOSS_PULLDOWN);
+ pup->block->flag |= UI_BLOCK_POPUP_MEMORY | UI_BLOCK_IS_FLIP;
+ pup->block->puphash = ui_popup_menu_hash(title);
+ pup->layout = UI_block_layout(
+ pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
+
+ /* note, this intentionally differs from the menu & submenu default because many operators
+ * use popups like this to select one of their options -
+ * where having invoke doesn't make sense */
+ uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
+
+ /* create in advance so we can let buttons point to retval already */
+ pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
+
+ /* create title button */
+ if (title[0]) {
+ char titlestr[256];
+
+ if (icon) {
+ BLI_snprintf(titlestr, sizeof(titlestr), " %s", title);
+ uiDefIconTextBut(pup->block,
+ UI_BTYPE_LABEL,
+ 0,
+ icon,
+ titlestr,
+ 0,
+ 0,
+ 200,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ }
+ else {
+ but = uiDefBut(
+ pup->block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but->drawflag = UI_BUT_TEXT_LEFT;
+ }
+
+ uiItemS(pup->layout);
+ }
+
+ return pup;
}
uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon)
{
- return UI_popup_menu_begin_ex(C, title, __func__, icon);
+ return UI_popup_menu_begin_ex(C, title, __func__, icon);
}
/**
@@ -425,54 +442,54 @@ uiPopupMenu *UI_popup_menu_begin(bContext *C, const char *title, int icon)
*/
void UI_popup_menu_but_set(uiPopupMenu *pup, struct ARegion *butregion, uiBut *but)
{
- pup->but = but;
- pup->butregion = butregion;
+ pup->but = but;
+ pup->butregion = butregion;
}
/* set the whole structure to work */
void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
{
- wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *menu;
- uiBut *but = NULL;
- ARegion *butregion = NULL;
+ wmWindow *window = CTX_wm_window(C);
+ uiPopupBlockHandle *menu;
+ uiBut *but = NULL;
+ ARegion *butregion = NULL;
- pup->popup = true;
- pup->mx = window->eventstate->x;
- pup->my = window->eventstate->y;
+ pup->popup = true;
+ pup->mx = window->eventstate->x;
+ pup->my = window->eventstate->y;
- if (pup->but) {
- but = pup->but;
- butregion = pup->butregion;
- }
+ if (pup->but) {
+ but = pup->but;
+ butregion = pup->butregion;
+ }
- menu = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
- menu->popup = true;
+ menu = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup);
+ menu->popup = true;
- UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
- WM_event_add_mousemove(C);
+ UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
+ WM_event_add_mousemove(C);
- MEM_freeN(pup);
+ MEM_freeN(pup);
}
bool UI_popup_menu_end_or_cancel(bContext *C, uiPopupMenu *pup)
{
- if (!UI_block_is_empty(pup->block)) {
- UI_popup_menu_end(C, pup);
- return true;
- }
- else {
- UI_block_layout_resolve(pup->block, NULL, NULL);
- MEM_freeN(pup->block->handle);
- UI_block_free(C, pup->block);
- MEM_freeN(pup);
- return false;
- }
+ if (!UI_block_is_empty(pup->block)) {
+ UI_popup_menu_end(C, pup);
+ return true;
+ }
+ else {
+ UI_block_layout_resolve(pup->block, NULL, NULL);
+ MEM_freeN(pup->block->handle);
+ UI_block_free(C, pup->block);
+ MEM_freeN(pup);
+ return false;
+ }
}
uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
{
- return pup->layout;
+ return pup->layout;
}
/** \} */
@@ -483,79 +500,79 @@ uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
void UI_popup_menu_reports(bContext *C, ReportList *reports)
{
- Report *report;
-
- uiPopupMenu *pup = NULL;
- uiLayout *layout;
-
- if (!CTX_wm_window(C)) {
- return;
- }
-
- for (report = reports->list.first; report; report = report->next) {
- int icon;
- const char *msg, *msg_next;
-
- if (report->type < reports->printlevel) {
- continue;
- }
-
- if (pup == NULL) {
- char title[UI_MAX_DRAW_STR];
- BLI_snprintf(title, sizeof(title), "%s: %s", IFACE_("Report"), report->typestr);
- /* popup_menu stuff does just what we need (but pass meaningful block name) */
- pup = UI_popup_menu_begin_ex(C, title, __func__, ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- }
- else {
- uiItemS(layout);
- }
-
- /* split each newline into a label */
- msg = report->message;
- icon = UI_icon_from_report_type(report->type);
- do {
- char buf[UI_MAX_DRAW_STR];
- msg_next = strchr(msg, '\n');
- if (msg_next) {
- msg_next++;
- BLI_strncpy(buf, msg, MIN2(sizeof(buf), msg_next - msg));
- msg = buf;
- }
- uiItemL(layout, msg, icon);
- icon = ICON_NONE;
- } while ((msg = msg_next) && *msg);
- }
-
- if (pup) {
- UI_popup_menu_end(C, pup);
- }
+ Report *report;
+
+ uiPopupMenu *pup = NULL;
+ uiLayout *layout;
+
+ if (!CTX_wm_window(C)) {
+ return;
+ }
+
+ for (report = reports->list.first; report; report = report->next) {
+ int icon;
+ const char *msg, *msg_next;
+
+ if (report->type < reports->printlevel) {
+ continue;
+ }
+
+ if (pup == NULL) {
+ char title[UI_MAX_DRAW_STR];
+ BLI_snprintf(title, sizeof(title), "%s: %s", IFACE_("Report"), report->typestr);
+ /* popup_menu stuff does just what we need (but pass meaningful block name) */
+ pup = UI_popup_menu_begin_ex(C, title, __func__, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ }
+ else {
+ uiItemS(layout);
+ }
+
+ /* split each newline into a label */
+ msg = report->message;
+ icon = UI_icon_from_report_type(report->type);
+ do {
+ char buf[UI_MAX_DRAW_STR];
+ msg_next = strchr(msg, '\n');
+ if (msg_next) {
+ msg_next++;
+ BLI_strncpy(buf, msg, MIN2(sizeof(buf), msg_next - msg));
+ msg = buf;
+ }
+ uiItemL(layout, msg, icon);
+ icon = ICON_NONE;
+ } while ((msg = msg_next) && *msg);
+ }
+
+ if (pup) {
+ UI_popup_menu_end(C, pup);
+ }
}
int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
{
- uiPopupMenu *pup;
- uiLayout *layout;
- MenuType *mt = WM_menutype_find(idname, true);
+ uiPopupMenu *pup;
+ uiLayout *layout;
+ MenuType *mt = WM_menutype_find(idname, true);
- if (mt == NULL) {
- BKE_reportf(reports, RPT_ERROR, "Menu \"%s\" not found", idname);
- return OPERATOR_CANCELLED;
- }
+ if (mt == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Menu \"%s\" not found", idname);
+ return OPERATOR_CANCELLED;
+ }
- if (WM_menutype_poll(C, mt) == false) {
- /* cancel but allow event to pass through, just like operators do */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
+ if (WM_menutype_poll(C, mt) == false) {
+ /* cancel but allow event to pass through, just like operators do */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
- pup = UI_popup_menu_begin(C, IFACE_(mt->label), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
+ pup = UI_popup_menu_begin(C, IFACE_(mt->label), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
- UI_menutype_draw(C, mt, layout);
+ UI_menutype_draw(C, mt, layout);
- UI_popup_menu_end(C, pup);
+ UI_popup_menu_end(C, pup);
- return OPERATOR_INTERFACE;
+ return OPERATOR_INTERFACE;
}
/** \} */
@@ -564,104 +581,108 @@ int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
/** \name Popup Block API
* \{ */
-void UI_popup_block_invoke_ex(bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext)
+void UI_popup_block_invoke_ex(
+ bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext)
{
- wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *handle;
-
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
- handle->popup = true;
- handle->can_refresh = true;
- handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL;
- handle->opcontext = opcontext;
-
- UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- UI_block_active_only_flagged_buttons(C, handle->region, handle->region->uiblocks.first);
- WM_event_add_mousemove(C);
+ wmWindow *window = CTX_wm_window(C);
+ uiPopupBlockHandle *handle;
+
+ handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
+ handle->popup = true;
+ handle->can_refresh = true;
+ handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL;
+ handle->opcontext = opcontext;
+
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
+ UI_block_active_only_flagged_buttons(C, handle->region, handle->region->uiblocks.first);
+ WM_event_add_mousemove(C);
}
void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg)
{
- UI_popup_block_invoke_ex(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT);
+ UI_popup_block_invoke_ex(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT);
}
-void UI_popup_block_ex(
- bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func,
- void *arg, wmOperator *op)
+void UI_popup_block_ex(bContext *C,
+ uiBlockCreateFunc func,
+ uiBlockHandleFunc popup_func,
+ uiBlockCancelFunc cancel_func,
+ void *arg,
+ wmOperator *op)
{
- wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *handle;
-
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
- handle->popup = true;
- handle->retvalue = 1;
- handle->can_refresh = true;
-
- handle->popup_op = op;
- handle->popup_arg = arg;
- handle->popup_func = popup_func;
- handle->cancel_func = cancel_func;
- // handle->opcontext = opcontext;
-
- UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- UI_block_active_only_flagged_buttons(C, handle->region, handle->region->uiblocks.first);
- WM_event_add_mousemove(C);
+ wmWindow *window = CTX_wm_window(C);
+ uiPopupBlockHandle *handle;
+
+ handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg);
+ handle->popup = true;
+ handle->retvalue = 1;
+ handle->can_refresh = true;
+
+ handle->popup_op = op;
+ handle->popup_arg = arg;
+ handle->popup_func = popup_func;
+ handle->cancel_func = cancel_func;
+ // handle->opcontext = opcontext;
+
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
+ UI_block_active_only_flagged_buttons(C, handle->region, handle->region->uiblocks.first);
+ WM_event_add_mousemove(C);
}
#if 0 /* UNUSED */
void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, int opcontext)
{
- wmWindow *window = CTX_wm_window(C);
- uiPopupBlockHandle *handle;
+ wmWindow *window = CTX_wm_window(C);
+ uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, op);
- handle->popup = 1;
- handle->retvalue = 1;
- handle->can_refresh = true;
+ handle = ui_popup_block_create(C, NULL, NULL, func, NULL, op);
+ handle->popup = 1;
+ handle->retvalue = 1;
+ handle->can_refresh = true;
- handle->popup_arg = op;
- handle->popup_func = operator_cb;
- handle->cancel_func = confirm_cancel_operator;
- handle->opcontext = opcontext;
+ handle->popup_arg = op;
+ handle->popup_func = operator_cb;
+ handle->cancel_func = confirm_cancel_operator;
+ handle->opcontext = opcontext;
- UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- WM_event_add_mousemove(C);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
+ WM_event_add_mousemove(C);
}
#endif
void UI_popup_block_close(bContext *C, wmWindow *win, uiBlock *block)
{
- /* if loading new .blend while popup is open, window will be NULL */
- if (block->handle) {
- if (win) {
- const bScreen *screen = WM_window_get_active_screen(win);
-
- UI_popup_handlers_remove(&win->modalhandlers, block->handle);
- ui_popup_block_free(C, block->handle);
-
- /* In the case we have nested popups,
- * closing one may need to redraw another, see: T48874 */
- for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) {
- ED_region_tag_refresh_ui(ar);
- }
- }
- }
+ /* if loading new .blend while popup is open, window will be NULL */
+ if (block->handle) {
+ if (win) {
+ const bScreen *screen = WM_window_get_active_screen(win);
+
+ UI_popup_handlers_remove(&win->modalhandlers, block->handle);
+ ui_popup_block_free(C, block->handle);
+
+ /* In the case we have nested popups,
+ * closing one may need to redraw another, see: T48874 */
+ for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) {
+ ED_region_tag_refresh_ui(ar);
+ }
+ }
+ }
}
bool UI_popup_block_name_exists(bContext *C, const char *name)
{
- bScreen *sc = CTX_wm_screen(C);
- uiBlock *block;
- ARegion *ar;
-
- for (ar = sc->regionbase.first; ar; ar = ar->next) {
- for (block = ar->uiblocks.first; block; block = block->next) {
- if (STREQ(block->name, name)) {
- return true;
- }
- }
- }
- return false;
+ bScreen *sc = CTX_wm_screen(C);
+ uiBlock *block;
+ ARegion *ar;
+
+ for (ar = sc->regionbase.first; ar; ar = ar->next) {
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ if (STREQ(block->name, name)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index 7396b5406ed..bbf3df6a264 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -59,7 +59,6 @@
#include "WM_api.h"
#include "WM_types.h"
-
#include "UI_interface.h"
#include "interface_intern.h"
@@ -70,222 +69,227 @@
* \{ */
struct uiPopover {
- uiBlock *block;
- uiLayout *layout;
- uiBut *but;
+ uiBlock *block;
+ uiLayout *layout;
+ uiBut *but;
- /* Needed for keymap removal. */
- wmWindow *window;
- wmKeyMap *keymap;
- struct wmEventHandler_Keymap *keymap_handler;
+ /* Needed for keymap removal. */
+ wmWindow *window;
+ wmKeyMap *keymap;
+ struct wmEventHandler_Keymap *keymap_handler;
- uiMenuCreateFunc menu_func;
- void *menu_arg;
+ uiMenuCreateFunc menu_func;
+ void *menu_arg;
- /* Size in pixels (ui scale applied). */
- int ui_size_x;
+ /* Size in pixels (ui scale applied). */
+ int ui_size_x;
#ifdef USE_UI_POPOVER_ONCE
- bool is_once;
+ bool is_once;
#endif
};
static void ui_popover_create_block(bContext *C, uiPopover *pup, int opcontext)
{
- BLI_assert(pup->ui_size_x != 0);
+ BLI_assert(pup->ui_size_x != 0);
- uiStyle *style = UI_style_get_dpi();
+ uiStyle *style = UI_style_get_dpi();
- pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
- UI_block_flag_enable(pup->block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_POPOVER);
+ pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
+ UI_block_flag_enable(pup->block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_POPOVER);
#ifdef USE_UI_POPOVER_ONCE
- if (pup->is_once) {
- UI_block_flag_enable(pup->block, UI_BLOCK_POPOVER_ONCE);
- }
+ if (pup->is_once) {
+ UI_block_flag_enable(pup->block, UI_BLOCK_POPOVER_ONCE);
+ }
#endif
- pup->layout = UI_block_layout(
- pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0,
- pup->ui_size_x, 0, UI_MENU_PADDING, style);
-
- uiLayoutSetOperatorContext(pup->layout, opcontext);
-
- if (pup->but) {
- if (pup->but->context) {
- uiLayoutContextCopy(pup->layout, pup->but->context);
- }
- }
-
- pup->block->flag |= UI_BLOCK_NO_FLIP;
+ pup->layout = UI_block_layout(pup->block,
+ UI_LAYOUT_VERTICAL,
+ UI_LAYOUT_PANEL,
+ 0,
+ 0,
+ pup->ui_size_x,
+ 0,
+ UI_MENU_PADDING,
+ style);
+
+ uiLayoutSetOperatorContext(pup->layout, opcontext);
+
+ if (pup->but) {
+ if (pup->but->context) {
+ uiLayoutContextCopy(pup->layout, pup->but->context);
+ }
+ }
+
+ pup->block->flag |= UI_BLOCK_NO_FLIP;
}
static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
{
- uiPopover *pup = arg_pup;
-
- /* Create UI block and layout now if it wasn't done between begin/end. */
- if (!pup->layout) {
- ui_popover_create_block(C, pup, WM_OP_INVOKE_REGION_WIN);
-
- if (pup->menu_func) {
- pup->block->handle = handle;
- pup->menu_func(C, pup->layout, pup->menu_arg);
- pup->block->handle = NULL;
- }
-
- pup->layout = NULL;
- }
-
- /* Setup and resolve UI layout for block. */
- uiBlock *block = pup->block;
- int width, height;
-
- UI_block_region_set(block, handle->region);
- UI_block_layout_resolve(block, &width, &height);
- UI_block_direction_set(block, UI_DIR_DOWN | UI_DIR_CENTER_X);
-
- const int block_margin = U.widget_unit / 2;
-
- if (pup->but) {
- /* For a header menu we set the direction automatic. */
- block->minbounds = BLI_rctf_size_x(&pup->but->rect);
- UI_block_bounds_set_normal(block, block_margin);
-
- /* If menu slides out of other menu, override direction. */
- bool slideout = ui_block_is_menu(pup->but->block);
- if (slideout) {
- UI_block_direction_set(block, UI_DIR_RIGHT);
- }
-
- /* Store the button location for positioning the popover arrow hint. */
- if (!handle->refresh) {
- float center[2] = {BLI_rctf_cent_x(&pup->but->rect), BLI_rctf_cent_y(&pup->but->rect)};
- ui_block_to_window_fl(handle->ctx_region, pup->but->block, &center[0], &center[1]);
- /* These variables aren't used for popovers,
- * we could add new variables if there is a conflict. */
- block->bounds_offset[0] = (int)center[0];
- block->bounds_offset[1] = (int)center[1];
- copy_v2_v2_int(handle->prev_bounds_offset, block->bounds_offset);
- }
- else {
- copy_v2_v2_int(block->bounds_offset, handle->prev_bounds_offset);
- }
-
- if (!slideout) {
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
-
- if (ar && ar->panels.first) {
- /* For regions with panels, prefer to open to top so we can
- * see the values of the buttons below changing. */
- UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
- }
- /* Prefer popover from header to be positioned into the editor. */
- else if (sa && ar) {
- if (ar->regiontype == RGN_TYPE_HEADER) {
- if (ED_area_header_alignment(sa) == RGN_ALIGN_BOTTOM) {
- UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
- }
- }
- if (ar->regiontype == RGN_TYPE_FOOTER) {
- if (ED_area_footer_alignment(sa) == RGN_ALIGN_BOTTOM) {
- UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
- }
- }
- }
- }
-
- /* Estimated a maximum size so we don't go offscreen for low height
- * areas near the bottom of the window on refreshes. */
- handle->max_size_y = UI_UNIT_Y * 16.0f;
- }
- else {
- /* Not attached to a button. */
- int bounds_offset[2] = {0, 0};
- UI_block_flag_enable(block, UI_BLOCK_LOOP);
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
- UI_block_direction_set(block, block->direction);
- block->minbounds = UI_MENU_WIDTH_MIN;
-
- if (!handle->refresh) {
- uiBut *but = NULL;
- uiBut *but_first = NULL;
- for (but = block->buttons.first; but; but = but->next) {
- if ((but_first == NULL) && ui_but_is_editable(but)) {
- but_first = but;
- }
- if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) {
- break;
- }
- }
-
- if (but) {
- bounds_offset[0] = -(but->rect.xmin + 0.8f * BLI_rctf_size_x(&but->rect));
- bounds_offset[1] = -BLI_rctf_cent_y(&but->rect);
- }
- else {
- bounds_offset[0] = -(pup->ui_size_x / 2);
- bounds_offset[1] = but_first ? -BLI_rctf_cent_y(&but_first->rect) : (UI_UNIT_Y / 2);
- }
- copy_v2_v2_int(handle->prev_bounds_offset, bounds_offset);
- }
- else {
- copy_v2_v2_int(bounds_offset, handle->prev_bounds_offset);
- }
-
- UI_block_bounds_set_popup(block, block_margin, bounds_offset);
- }
-
- return block;
+ uiPopover *pup = arg_pup;
+
+ /* Create UI block and layout now if it wasn't done between begin/end. */
+ if (!pup->layout) {
+ ui_popover_create_block(C, pup, WM_OP_INVOKE_REGION_WIN);
+
+ if (pup->menu_func) {
+ pup->block->handle = handle;
+ pup->menu_func(C, pup->layout, pup->menu_arg);
+ pup->block->handle = NULL;
+ }
+
+ pup->layout = NULL;
+ }
+
+ /* Setup and resolve UI layout for block. */
+ uiBlock *block = pup->block;
+ int width, height;
+
+ UI_block_region_set(block, handle->region);
+ UI_block_layout_resolve(block, &width, &height);
+ UI_block_direction_set(block, UI_DIR_DOWN | UI_DIR_CENTER_X);
+
+ const int block_margin = U.widget_unit / 2;
+
+ if (pup->but) {
+ /* For a header menu we set the direction automatic. */
+ block->minbounds = BLI_rctf_size_x(&pup->but->rect);
+ UI_block_bounds_set_normal(block, block_margin);
+
+ /* If menu slides out of other menu, override direction. */
+ bool slideout = ui_block_is_menu(pup->but->block);
+ if (slideout) {
+ UI_block_direction_set(block, UI_DIR_RIGHT);
+ }
+
+ /* Store the button location for positioning the popover arrow hint. */
+ if (!handle->refresh) {
+ float center[2] = {BLI_rctf_cent_x(&pup->but->rect), BLI_rctf_cent_y(&pup->but->rect)};
+ ui_block_to_window_fl(handle->ctx_region, pup->but->block, &center[0], &center[1]);
+ /* These variables aren't used for popovers,
+ * we could add new variables if there is a conflict. */
+ block->bounds_offset[0] = (int)center[0];
+ block->bounds_offset[1] = (int)center[1];
+ copy_v2_v2_int(handle->prev_bounds_offset, block->bounds_offset);
+ }
+ else {
+ copy_v2_v2_int(block->bounds_offset, handle->prev_bounds_offset);
+ }
+
+ if (!slideout) {
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+
+ if (ar && ar->panels.first) {
+ /* For regions with panels, prefer to open to top so we can
+ * see the values of the buttons below changing. */
+ UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
+ }
+ /* Prefer popover from header to be positioned into the editor. */
+ else if (sa && ar) {
+ if (ar->regiontype == RGN_TYPE_HEADER) {
+ if (ED_area_header_alignment(sa) == RGN_ALIGN_BOTTOM) {
+ UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
+ }
+ }
+ if (ar->regiontype == RGN_TYPE_FOOTER) {
+ if (ED_area_footer_alignment(sa) == RGN_ALIGN_BOTTOM) {
+ UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
+ }
+ }
+ }
+ }
+
+ /* Estimated a maximum size so we don't go offscreen for low height
+ * areas near the bottom of the window on refreshes. */
+ handle->max_size_y = UI_UNIT_Y * 16.0f;
+ }
+ else {
+ /* Not attached to a button. */
+ int bounds_offset[2] = {0, 0};
+ UI_block_flag_enable(block, UI_BLOCK_LOOP);
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+ UI_block_direction_set(block, block->direction);
+ block->minbounds = UI_MENU_WIDTH_MIN;
+
+ if (!handle->refresh) {
+ uiBut *but = NULL;
+ uiBut *but_first = NULL;
+ for (but = block->buttons.first; but; but = but->next) {
+ if ((but_first == NULL) && ui_but_is_editable(but)) {
+ but_first = but;
+ }
+ if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) {
+ break;
+ }
+ }
+
+ if (but) {
+ bounds_offset[0] = -(but->rect.xmin + 0.8f * BLI_rctf_size_x(&but->rect));
+ bounds_offset[1] = -BLI_rctf_cent_y(&but->rect);
+ }
+ else {
+ bounds_offset[0] = -(pup->ui_size_x / 2);
+ bounds_offset[1] = but_first ? -BLI_rctf_cent_y(&but_first->rect) : (UI_UNIT_Y / 2);
+ }
+ copy_v2_v2_int(handle->prev_bounds_offset, bounds_offset);
+ }
+ else {
+ copy_v2_v2_int(bounds_offset, handle->prev_bounds_offset);
+ }
+
+ UI_block_bounds_set_popup(block, block_margin, bounds_offset);
+ }
+
+ return block;
}
static void ui_block_free_func_POPOVER(uiPopupBlockHandle *UNUSED(handle), void *arg_pup)
{
- uiPopover *pup = arg_pup;
- if (pup->keymap != NULL) {
- wmWindow *window = pup->window;
- WM_event_remove_keymap_handler(&window->modalhandlers, pup->keymap);
- }
- MEM_freeN(pup);
+ uiPopover *pup = arg_pup;
+ if (pup->keymap != NULL) {
+ wmWindow *window = pup->window;
+ WM_event_remove_keymap_handler(&window->modalhandlers, pup->keymap);
+ }
+ MEM_freeN(pup);
}
uiPopupBlockHandle *ui_popover_panel_create(
- bContext *C, ARegion *butregion, uiBut *but,
- uiMenuCreateFunc menu_func, void *arg)
+ bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg)
{
- /* Create popover, buttons are created from callback. */
- uiPopover *pup = MEM_callocN(sizeof(uiPopover), __func__);
- pup->but = but;
+ /* Create popover, buttons are created from callback. */
+ uiPopover *pup = MEM_callocN(sizeof(uiPopover), __func__);
+ pup->but = but;
- /* FIXME: maybe one day we want non panel popovers? */
- {
- int ui_units_x = ((PanelType *)arg)->ui_units_x;
- pup->ui_size_x = U.widget_unit * (ui_units_x ? ui_units_x : UI_POPOVER_WIDTH_UNITS);
- }
+ /* FIXME: maybe one day we want non panel popovers? */
+ {
+ int ui_units_x = ((PanelType *)arg)->ui_units_x;
+ pup->ui_size_x = U.widget_unit * (ui_units_x ? ui_units_x : UI_POPOVER_WIDTH_UNITS);
+ }
- pup->menu_func = menu_func;
- pup->menu_arg = arg;
+ pup->menu_func = menu_func;
+ pup->menu_arg = arg;
#ifdef USE_UI_POPOVER_ONCE
- pup->is_once = true;
+ pup->is_once = true;
#endif
- /* Create popup block. */
- uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPOVER, pup);
- handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
- handle->can_refresh = true;
-
- /* Add handlers. If attached to a button, the button will already
- * add a modal handler and pass on events. */
- if (!but) {
- wmWindow *window = CTX_wm_window(C);
- UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- WM_event_add_mousemove(C);
- handle->popup = true;
- }
-
- return handle;
+ /* Create popup block. */
+ uiPopupBlockHandle *handle;
+ handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPOVER, pup);
+ handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
+ handle->can_refresh = true;
+
+ /* Add handlers. If attached to a button, the button will already
+ * add a modal handler and pass on events. */
+ if (!but) {
+ wmWindow *window = CTX_wm_window(C);
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
+ WM_event_add_mousemove(C);
+ handle->popup = true;
+ }
+
+ return handle;
}
/** \} */
@@ -294,41 +298,39 @@ uiPopupBlockHandle *ui_popover_panel_create(
/** \name Standard Popover Panels
* \{ */
-int UI_popover_panel_invoke(
- bContext *C, const char *idname,
- bool keep_open, ReportList *reports)
+int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, ReportList *reports)
{
- uiLayout *layout;
- PanelType *pt = WM_paneltype_find(idname, true);
- if (pt == NULL) {
- BKE_reportf(reports, RPT_ERROR, "Panel \"%s\" not found", idname);
- return OPERATOR_CANCELLED;
- }
-
- if (pt->poll && (pt->poll(C, pt) == false)) {
- /* cancel but allow event to pass through, just like operators do */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- uiBlock *block = NULL;
- if (keep_open) {
- uiPopupBlockHandle *handle = ui_popover_panel_create(C, NULL, NULL, ui_item_paneltype_func, pt);
- uiPopover *pup = handle->popup_create_vars.arg;
- block = pup->block;
-
- }
- else {
- uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x);
- layout = UI_popover_layout(pup);
- UI_paneltype_draw(C, pt, layout);
- UI_popover_end(C, pup, NULL);
- block = pup->block;
- }
-
- if (block) {
- UI_block_active_only_flagged_buttons(C, CTX_wm_region(C), block);
- }
- return OPERATOR_INTERFACE;
+ uiLayout *layout;
+ PanelType *pt = WM_paneltype_find(idname, true);
+ if (pt == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Panel \"%s\" not found", idname);
+ return OPERATOR_CANCELLED;
+ }
+
+ if (pt->poll && (pt->poll(C, pt) == false)) {
+ /* cancel but allow event to pass through, just like operators do */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ uiBlock *block = NULL;
+ if (keep_open) {
+ uiPopupBlockHandle *handle = ui_popover_panel_create(
+ C, NULL, NULL, ui_item_paneltype_func, pt);
+ uiPopover *pup = handle->popup_create_vars.arg;
+ block = pup->block;
+ }
+ else {
+ uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x);
+ layout = UI_popover_layout(pup);
+ UI_paneltype_draw(C, pt, layout);
+ UI_popover_end(C, pup, NULL);
+ block = pup->block;
+ }
+
+ if (block) {
+ UI_block_active_only_flagged_buttons(C, CTX_wm_region(C), block);
+ }
+ return OPERATOR_INTERFACE;
}
/** \} */
@@ -342,77 +344,77 @@ int UI_popover_panel_invoke(
*/
uiPopover *UI_popover_begin(bContext *C, int ui_size_x)
{
- uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
- if (ui_size_x == 0) {
- ui_size_x = U.widget_unit * UI_POPOVER_WIDTH_UNITS;
- }
- pup->ui_size_x = ui_size_x;
+ uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
+ if (ui_size_x == 0) {
+ ui_size_x = U.widget_unit * UI_POPOVER_WIDTH_UNITS;
+ }
+ pup->ui_size_x = ui_size_x;
- /* Opertor context default same as menus, change if needed. */
- ui_popover_create_block(C, pup, WM_OP_EXEC_REGION_WIN);
+ /* Opertor context default same as menus, change if needed. */
+ ui_popover_create_block(C, pup, WM_OP_EXEC_REGION_WIN);
- /* create in advance so we can let buttons point to retval already */
- pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
+ /* create in advance so we can let buttons point to retval already */
+ pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
- return pup;
+ return pup;
}
static void popover_keymap_fn(wmKeyMap *UNUSED(keymap), wmKeyMapItem *UNUSED(kmi), void *user_data)
{
- uiPopover *pup = user_data;
- pup->block->handle->menuretval = UI_RETURN_OK;
+ uiPopover *pup = user_data;
+ pup->block->handle->menuretval = UI_RETURN_OK;
}
/* set the whole structure to work */
void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
{
- wmWindow *window = CTX_wm_window(C);
- /* Create popup block. No refresh support since the buttons were created
- * between begin/end and we have no callback to recreate them. */
- uiPopupBlockHandle *handle;
-
- if (keymap) {
- /* Add so we get keymaps shown in the buttons. */
- UI_block_flag_enable(pup->block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS);
- pup->keymap = keymap;
- pup->keymap_handler = WM_event_add_keymap_handler_priority(&window->modalhandlers, keymap, 0);
- WM_event_set_keymap_handler_post_callback(pup->keymap_handler, popover_keymap_fn, pup);
- }
-
- handle = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPOVER, pup);
- handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
-
- /* Add handlers. */
- UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- WM_event_add_mousemove(C);
- handle->popup = true;
-
- /* Re-add so it gets priority. */
- if (keymap) {
- BLI_remlink(&window->modalhandlers, pup->keymap_handler);
- BLI_addhead(&window->modalhandlers, pup->keymap_handler);
- }
-
- pup->window = window;
-
- /* TODO(campbell): we may want to make this configurable.
- * The begin/end stype of calling popups doesn't allow to 'can_refresh' to be set.
- * For now close this style of popvers when accessed. */
- UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN);
-
- /* panels are created flipped (from event handling pov) */
- pup->block->flag ^= UI_BLOCK_IS_FLIP;
+ wmWindow *window = CTX_wm_window(C);
+ /* Create popup block. No refresh support since the buttons were created
+ * between begin/end and we have no callback to recreate them. */
+ uiPopupBlockHandle *handle;
+
+ if (keymap) {
+ /* Add so we get keymaps shown in the buttons. */
+ UI_block_flag_enable(pup->block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS);
+ pup->keymap = keymap;
+ pup->keymap_handler = WM_event_add_keymap_handler_priority(&window->modalhandlers, keymap, 0);
+ WM_event_set_keymap_handler_post_callback(pup->keymap_handler, popover_keymap_fn, pup);
+ }
+
+ handle = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPOVER, pup);
+ handle->popup_create_vars.free_func = ui_block_free_func_POPOVER;
+
+ /* Add handlers. */
+ UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
+ WM_event_add_mousemove(C);
+ handle->popup = true;
+
+ /* Re-add so it gets priority. */
+ if (keymap) {
+ BLI_remlink(&window->modalhandlers, pup->keymap_handler);
+ BLI_addhead(&window->modalhandlers, pup->keymap_handler);
+ }
+
+ pup->window = window;
+
+ /* TODO(campbell): we may want to make this configurable.
+ * The begin/end stype of calling popups doesn't allow to 'can_refresh' to be set.
+ * For now close this style of popvers when accessed. */
+ UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN);
+
+ /* panels are created flipped (from event handling pov) */
+ pup->block->flag ^= UI_BLOCK_IS_FLIP;
}
uiLayout *UI_popover_layout(uiPopover *pup)
{
- return pup->layout;
+ return pup->layout;
}
#ifdef USE_UI_POPOVER_ONCE
void UI_popover_once_clear(uiPopover *pup)
{
- pup->is_once = false;
+ pup->is_once = false;
}
#endif
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 59223970af8..11b2e069d6c 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -59,256 +59,305 @@
*/
void ui_popup_translate(ARegion *ar, const int mdiff[2])
{
- uiBlock *block;
+ uiBlock *block;
- BLI_rcti_translate(&ar->winrct, UNPACK2(mdiff));
+ BLI_rcti_translate(&ar->winrct, UNPACK2(mdiff));
- ED_region_update_rect(ar);
+ ED_region_update_rect(ar);
- ED_region_tag_redraw(ar);
+ ED_region_tag_redraw(ar);
- /* update blocks */
- for (block = ar->uiblocks.first; block; block = block->next) {
- uiPopupBlockHandle *handle = block->handle;
- /* Make empty, will be initialized on next use, see T60608. */
- BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0);
+ /* update blocks */
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ uiPopupBlockHandle *handle = block->handle;
+ /* Make empty, will be initialized on next use, see T60608. */
+ BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0);
- uiSafetyRct *saferct;
- for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
- BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff));
- BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff));
- }
- }
+ uiSafetyRct *saferct;
+ for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
+ BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff));
+ BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff));
+ }
+ }
}
/* position block relative to but, result is in window space */
-static void ui_popup_block_position(wmWindow *window, ARegion *butregion, uiBut *but, uiBlock *block)
+static void ui_popup_block_position(wmWindow *window,
+ ARegion *butregion,
+ uiBut *but,
+ uiBlock *block)
{
- uiPopupBlockHandle *handle = block->handle;
-
- /* Compute button position in window coordinates using the source
- * button region/block, to position the popup attached to it. */
- rctf butrct;
-
- if (!handle->refresh) {
- ui_block_to_window_rctf(butregion, but->block, &butrct, &but->rect);
-
- /* widget_roundbox_set has this correction too, keep in sync */
- if (but->type != UI_BTYPE_PULLDOWN) {
- if (but->drawflag & UI_BUT_ALIGN_TOP) {
- butrct.ymax += U.pixelsize;
- }
- if (but->drawflag & UI_BUT_ALIGN_LEFT) {
- butrct.xmin -= U.pixelsize;
- }
- }
-
- handle->prev_butrct = butrct;
- }
- else {
- /* For refreshes, keep same button position so popup doesn't move. */
- butrct = handle->prev_butrct;
- }
-
- /* Compute block size in window space, based on buttons contained in it. */
- if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
- if (block->buttons.first) {
- BLI_rctf_init_minmax(&block->rect);
-
- for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
- if (block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT) {
- bt->rect.xmax += UI_MENU_SUBMENU_PADDING;
- }
- BLI_rctf_union(&block->rect, &bt->rect);
- }
- }
- else {
- /* we're nice and allow empty blocks too */
- block->rect.xmin = block->rect.ymin = 0;
- block->rect.xmax = block->rect.ymax = 20;
- }
- }
-
- ui_block_to_window_rctf(butregion, but->block, &block->rect, &block->rect);
-
- /* Compute direction relative to button, based on available space. */
- const int size_x = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */
- const int size_y = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y;
- const int center_x = (block->direction & UI_DIR_CENTER_X) ? size_x / 2 : 0;
- const int center_y = (block->direction & UI_DIR_CENTER_Y) ? size_y / 2 : 0;
-
- short dir1 = 0, dir2 = 0;
-
- if (!handle->refresh) {
- bool left = 0, right = 0, top = 0, down = 0;
-
- const int win_x = WM_window_pixels_x(window);
- const int win_y = WM_window_pixels_y(window);
-
- /* Take into account maximum size so we don't have to flip on refresh. */
- const float max_size_x = max_ff(size_x, handle->max_size_x);
- const float max_size_y = max_ff(size_y, handle->max_size_y);
-
- /* check if there's space at all */
- if (butrct.xmin - max_size_x + center_x > 0.0f) { left = 1; }
- if (butrct.xmax + max_size_x - center_x < win_x) { right = 1; }
- if (butrct.ymin - max_size_y + center_y > 0.0f) { down = 1; }
- if (butrct.ymax + max_size_y - center_y < win_y) { top = 1; }
-
- if (top == 0 && down == 0) {
- if (butrct.ymin - max_size_y < win_y - butrct.ymax - max_size_y) {
- top = 1;
- }
- else {
- down = 1;
- }
- }
-
- dir1 = (block->direction & UI_DIR_ALL);
-
- /* Secondary directions. */
- if (dir1 & (UI_DIR_UP | UI_DIR_DOWN)) {
- if (dir1 & UI_DIR_LEFT) { dir2 = UI_DIR_LEFT; }
- else if (dir1 & UI_DIR_RIGHT) { dir2 = UI_DIR_RIGHT; }
- dir1 &= (UI_DIR_UP | UI_DIR_DOWN);
- }
-
- if ((dir2 == 0) && (dir1 == UI_DIR_LEFT || dir1 == UI_DIR_RIGHT)) { dir2 = UI_DIR_DOWN; }
- if ((dir2 == 0) && (dir1 == UI_DIR_UP || dir1 == UI_DIR_DOWN)) { dir2 = UI_DIR_LEFT; }
-
- /* no space at all? don't change */
- if (left || right) {
- if (dir1 == UI_DIR_LEFT && left == 0) { dir1 = UI_DIR_RIGHT; }
- if (dir1 == UI_DIR_RIGHT && right == 0) { dir1 = UI_DIR_LEFT; }
- /* this is aligning, not append! */
- if (dir2 == UI_DIR_LEFT && right == 0) { dir2 = UI_DIR_RIGHT; }
- if (dir2 == UI_DIR_RIGHT && left == 0) { dir2 = UI_DIR_LEFT; }
- }
- if (down || top) {
- if (dir1 == UI_DIR_UP && top == 0) { dir1 = UI_DIR_DOWN; }
- if (dir1 == UI_DIR_DOWN && down == 0) { dir1 = UI_DIR_UP; }
- BLI_assert(dir2 != UI_DIR_UP);
-// if (dir2 == UI_DIR_UP && top == 0) { dir2 = UI_DIR_DOWN; }
- if (dir2 == UI_DIR_DOWN && down == 0) { dir2 = UI_DIR_UP; }
- }
-
- handle->prev_dir1 = dir1;
- handle->prev_dir2 = dir2;
- }
- else {
- /* For refreshes, keep same popup direct so popup doesn't move
- * to a totally different position while editing in it. */
- dir1 = handle->prev_dir1;
- dir2 = handle->prev_dir2;
- }
-
- /* Compute offset based on direction. */
- int offset_x = 0, offset_y = 0;
-
- if (dir1 == UI_DIR_LEFT) {
- offset_x = butrct.xmin - block->rect.xmax;
- if (dir2 == UI_DIR_UP) { offset_y = butrct.ymin - block->rect.ymin - center_y - UI_MENU_PADDING; }
- else { offset_y = butrct.ymax - block->rect.ymax + center_y + UI_MENU_PADDING; }
- }
- else if (dir1 == UI_DIR_RIGHT) {
- offset_x = butrct.xmax - block->rect.xmin;
- if (dir2 == UI_DIR_UP) { offset_y = butrct.ymin - block->rect.ymin - center_y - UI_MENU_PADDING; }
- else { offset_y = butrct.ymax - block->rect.ymax + center_y + UI_MENU_PADDING; }
- }
- else if (dir1 == UI_DIR_UP) {
- offset_y = butrct.ymax - block->rect.ymin;
- if (dir2 == UI_DIR_RIGHT) { offset_x = butrct.xmax - block->rect.xmax + center_x; }
- else { offset_x = butrct.xmin - block->rect.xmin - center_x; }
- /* changed direction? */
- if ((dir1 & block->direction) == 0) {
- /* TODO: still do */
- UI_block_order_flip(block);
- }
- }
- else if (dir1 == UI_DIR_DOWN) {
- offset_y = butrct.ymin - block->rect.ymax;
- if (dir2 == UI_DIR_RIGHT) { offset_x = butrct.xmax - block->rect.xmax + center_x; }
- else { offset_x = butrct.xmin - block->rect.xmin - center_x; }
- /* changed direction? */
- if ((dir1 & block->direction) == 0) {
- /* TODO: still do */
- UI_block_order_flip(block);
- }
- }
-
- /* Center over popovers for eg. */
- if (block->direction & UI_DIR_CENTER_X) {
- offset_x += BLI_rctf_size_x(&butrct) / ((dir2 == UI_DIR_LEFT) ? 2 : - 2);
- }
-
- /* Apply offset, buttons in window coords. */
- for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
- ui_block_to_window_rctf(butregion, but->block, &bt->rect, &bt->rect);
-
- BLI_rctf_translate(&bt->rect, offset_x, offset_y);
-
- /* ui_but_update recalculates drawstring size in pixels */
- ui_but_update(bt);
- }
-
- BLI_rctf_translate(&block->rect, offset_x, offset_y);
-
- /* Safety calculus. */
- {
- const float midx = BLI_rctf_cent_x(&butrct);
- const float midy = BLI_rctf_cent_y(&butrct);
-
- /* when you are outside parent button, safety there should be smaller */
-
- /* parent button to left */
- if (midx < block->rect.xmin) {
- block->safety.xmin = block->rect.xmin - 3;
- }
- else {
- block->safety.xmin = block->rect.xmin - 40;
- }
- /* parent button to right */
- if (midx > block->rect.xmax) {
- block->safety.xmax = block->rect.xmax + 3;
- }
- else {
- block->safety.xmax = block->rect.xmax + 40;
- }
-
- /* parent button on bottom */
- if (midy < block->rect.ymin) {
- block->safety.ymin = block->rect.ymin - 3;
- }
- else {
- block->safety.ymin = block->rect.ymin - 40;
- }
- /* parent button on top */
- if (midy > block->rect.ymax) {
- block->safety.ymax = block->rect.ymax + 3;
- }
- else {
- block->safety.ymax = block->rect.ymax + 40;
- }
-
- /* exception for switched pulldowns... */
- if (dir1 && (dir1 & block->direction) == 0) {
- if (dir2 == UI_DIR_RIGHT) {
- block->safety.xmax = block->rect.xmax + 3;
- }
- if (dir2 == UI_DIR_LEFT) {
- block->safety.xmin = block->rect.xmin - 3;
- }
- }
- block->direction = dir1;
- }
-
- /* keep a list of these, needed for pulldown menus */
- uiSafetyRct *saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
- saferct->parent = butrct;
- saferct->safety = block->safety;
- BLI_freelistN(&block->saferct);
- BLI_duplicatelist(&block->saferct, &but->block->saferct);
- BLI_addhead(&block->saferct, saferct);
+ uiPopupBlockHandle *handle = block->handle;
+
+ /* Compute button position in window coordinates using the source
+ * button region/block, to position the popup attached to it. */
+ rctf butrct;
+
+ if (!handle->refresh) {
+ ui_block_to_window_rctf(butregion, but->block, &butrct, &but->rect);
+
+ /* widget_roundbox_set has this correction too, keep in sync */
+ if (but->type != UI_BTYPE_PULLDOWN) {
+ if (but->drawflag & UI_BUT_ALIGN_TOP) {
+ butrct.ymax += U.pixelsize;
+ }
+ if (but->drawflag & UI_BUT_ALIGN_LEFT) {
+ butrct.xmin -= U.pixelsize;
+ }
+ }
+
+ handle->prev_butrct = butrct;
+ }
+ else {
+ /* For refreshes, keep same button position so popup doesn't move. */
+ butrct = handle->prev_butrct;
+ }
+
+ /* Compute block size in window space, based on buttons contained in it. */
+ if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
+ if (block->buttons.first) {
+ BLI_rctf_init_minmax(&block->rect);
+
+ for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
+ if (block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT) {
+ bt->rect.xmax += UI_MENU_SUBMENU_PADDING;
+ }
+ BLI_rctf_union(&block->rect, &bt->rect);
+ }
+ }
+ else {
+ /* we're nice and allow empty blocks too */
+ block->rect.xmin = block->rect.ymin = 0;
+ block->rect.xmax = block->rect.ymax = 20;
+ }
+ }
+
+ ui_block_to_window_rctf(butregion, but->block, &block->rect, &block->rect);
+
+ /* Compute direction relative to button, based on available space. */
+ const int size_x = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */
+ const int size_y = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y;
+ const int center_x = (block->direction & UI_DIR_CENTER_X) ? size_x / 2 : 0;
+ const int center_y = (block->direction & UI_DIR_CENTER_Y) ? size_y / 2 : 0;
+
+ short dir1 = 0, dir2 = 0;
+
+ if (!handle->refresh) {
+ bool left = 0, right = 0, top = 0, down = 0;
+
+ const int win_x = WM_window_pixels_x(window);
+ const int win_y = WM_window_pixels_y(window);
+
+ /* Take into account maximum size so we don't have to flip on refresh. */
+ const float max_size_x = max_ff(size_x, handle->max_size_x);
+ const float max_size_y = max_ff(size_y, handle->max_size_y);
+
+ /* check if there's space at all */
+ if (butrct.xmin - max_size_x + center_x > 0.0f) {
+ left = 1;
+ }
+ if (butrct.xmax + max_size_x - center_x < win_x) {
+ right = 1;
+ }
+ if (butrct.ymin - max_size_y + center_y > 0.0f) {
+ down = 1;
+ }
+ if (butrct.ymax + max_size_y - center_y < win_y) {
+ top = 1;
+ }
+
+ if (top == 0 && down == 0) {
+ if (butrct.ymin - max_size_y < win_y - butrct.ymax - max_size_y) {
+ top = 1;
+ }
+ else {
+ down = 1;
+ }
+ }
+
+ dir1 = (block->direction & UI_DIR_ALL);
+
+ /* Secondary directions. */
+ if (dir1 & (UI_DIR_UP | UI_DIR_DOWN)) {
+ if (dir1 & UI_DIR_LEFT) {
+ dir2 = UI_DIR_LEFT;
+ }
+ else if (dir1 & UI_DIR_RIGHT) {
+ dir2 = UI_DIR_RIGHT;
+ }
+ dir1 &= (UI_DIR_UP | UI_DIR_DOWN);
+ }
+
+ if ((dir2 == 0) && (dir1 == UI_DIR_LEFT || dir1 == UI_DIR_RIGHT)) {
+ dir2 = UI_DIR_DOWN;
+ }
+ if ((dir2 == 0) && (dir1 == UI_DIR_UP || dir1 == UI_DIR_DOWN)) {
+ dir2 = UI_DIR_LEFT;
+ }
+
+ /* no space at all? don't change */
+ if (left || right) {
+ if (dir1 == UI_DIR_LEFT && left == 0) {
+ dir1 = UI_DIR_RIGHT;
+ }
+ if (dir1 == UI_DIR_RIGHT && right == 0) {
+ dir1 = UI_DIR_LEFT;
+ }
+ /* this is aligning, not append! */
+ if (dir2 == UI_DIR_LEFT && right == 0) {
+ dir2 = UI_DIR_RIGHT;
+ }
+ if (dir2 == UI_DIR_RIGHT && left == 0) {
+ dir2 = UI_DIR_LEFT;
+ }
+ }
+ if (down || top) {
+ if (dir1 == UI_DIR_UP && top == 0) {
+ dir1 = UI_DIR_DOWN;
+ }
+ if (dir1 == UI_DIR_DOWN && down == 0) {
+ dir1 = UI_DIR_UP;
+ }
+ BLI_assert(dir2 != UI_DIR_UP);
+ // if (dir2 == UI_DIR_UP && top == 0) { dir2 = UI_DIR_DOWN; }
+ if (dir2 == UI_DIR_DOWN && down == 0) {
+ dir2 = UI_DIR_UP;
+ }
+ }
+
+ handle->prev_dir1 = dir1;
+ handle->prev_dir2 = dir2;
+ }
+ else {
+ /* For refreshes, keep same popup direct so popup doesn't move
+ * to a totally different position while editing in it. */
+ dir1 = handle->prev_dir1;
+ dir2 = handle->prev_dir2;
+ }
+
+ /* Compute offset based on direction. */
+ int offset_x = 0, offset_y = 0;
+
+ if (dir1 == UI_DIR_LEFT) {
+ offset_x = butrct.xmin - block->rect.xmax;
+ if (dir2 == UI_DIR_UP) {
+ offset_y = butrct.ymin - block->rect.ymin - center_y - UI_MENU_PADDING;
+ }
+ else {
+ offset_y = butrct.ymax - block->rect.ymax + center_y + UI_MENU_PADDING;
+ }
+ }
+ else if (dir1 == UI_DIR_RIGHT) {
+ offset_x = butrct.xmax - block->rect.xmin;
+ if (dir2 == UI_DIR_UP) {
+ offset_y = butrct.ymin - block->rect.ymin - center_y - UI_MENU_PADDING;
+ }
+ else {
+ offset_y = butrct.ymax - block->rect.ymax + center_y + UI_MENU_PADDING;
+ }
+ }
+ else if (dir1 == UI_DIR_UP) {
+ offset_y = butrct.ymax - block->rect.ymin;
+ if (dir2 == UI_DIR_RIGHT) {
+ offset_x = butrct.xmax - block->rect.xmax + center_x;
+ }
+ else {
+ offset_x = butrct.xmin - block->rect.xmin - center_x;
+ }
+ /* changed direction? */
+ if ((dir1 & block->direction) == 0) {
+ /* TODO: still do */
+ UI_block_order_flip(block);
+ }
+ }
+ else if (dir1 == UI_DIR_DOWN) {
+ offset_y = butrct.ymin - block->rect.ymax;
+ if (dir2 == UI_DIR_RIGHT) {
+ offset_x = butrct.xmax - block->rect.xmax + center_x;
+ }
+ else {
+ offset_x = butrct.xmin - block->rect.xmin - center_x;
+ }
+ /* changed direction? */
+ if ((dir1 & block->direction) == 0) {
+ /* TODO: still do */
+ UI_block_order_flip(block);
+ }
+ }
+
+ /* Center over popovers for eg. */
+ if (block->direction & UI_DIR_CENTER_X) {
+ offset_x += BLI_rctf_size_x(&butrct) / ((dir2 == UI_DIR_LEFT) ? 2 : -2);
+ }
+
+ /* Apply offset, buttons in window coords. */
+ for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
+ ui_block_to_window_rctf(butregion, but->block, &bt->rect, &bt->rect);
+
+ BLI_rctf_translate(&bt->rect, offset_x, offset_y);
+
+ /* ui_but_update recalculates drawstring size in pixels */
+ ui_but_update(bt);
+ }
+
+ BLI_rctf_translate(&block->rect, offset_x, offset_y);
+
+ /* Safety calculus. */
+ {
+ const float midx = BLI_rctf_cent_x(&butrct);
+ const float midy = BLI_rctf_cent_y(&butrct);
+
+ /* when you are outside parent button, safety there should be smaller */
+
+ /* parent button to left */
+ if (midx < block->rect.xmin) {
+ block->safety.xmin = block->rect.xmin - 3;
+ }
+ else {
+ block->safety.xmin = block->rect.xmin - 40;
+ }
+ /* parent button to right */
+ if (midx > block->rect.xmax) {
+ block->safety.xmax = block->rect.xmax + 3;
+ }
+ else {
+ block->safety.xmax = block->rect.xmax + 40;
+ }
+
+ /* parent button on bottom */
+ if (midy < block->rect.ymin) {
+ block->safety.ymin = block->rect.ymin - 3;
+ }
+ else {
+ block->safety.ymin = block->rect.ymin - 40;
+ }
+ /* parent button on top */
+ if (midy > block->rect.ymax) {
+ block->safety.ymax = block->rect.ymax + 3;
+ }
+ else {
+ block->safety.ymax = block->rect.ymax + 40;
+ }
+
+ /* exception for switched pulldowns... */
+ if (dir1 && (dir1 & block->direction) == 0) {
+ if (dir2 == UI_DIR_RIGHT) {
+ block->safety.xmax = block->rect.xmax + 3;
+ }
+ if (dir2 == UI_DIR_LEFT) {
+ block->safety.xmin = block->rect.xmin - 3;
+ }
+ }
+ block->direction = dir1;
+ }
+
+ /* keep a list of these, needed for pulldown menus */
+ uiSafetyRct *saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
+ saferct->parent = butrct;
+ saferct->safety = block->safety;
+ BLI_freelistN(&block->saferct);
+ BLI_duplicatelist(&block->saferct, &but->block->saferct);
+ BLI_addhead(&block->saferct, saferct);
}
/** \} */
@@ -319,459 +368,462 @@ static void ui_popup_block_position(wmWindow *window, ARegion *butregion, uiBut
static void ui_block_region_refresh(const bContext *C, ARegion *ar)
{
- ScrArea *ctx_area = CTX_wm_area(C);
- ARegion *ctx_region = CTX_wm_region(C);
- uiBlock *block;
-
- if (ar->do_draw & RGN_DRAW_REFRESH_UI) {
- ScrArea *handle_ctx_area;
- ARegion *handle_ctx_region;
- uiBlock *block_next;
-
- ar->do_draw &= ~RGN_DRAW_REFRESH_UI;
- for (block = ar->uiblocks.first; block; block = block_next) {
- block_next = block->next;
- uiPopupBlockHandle *handle = block->handle;
-
- if (handle->can_refresh) {
- handle_ctx_area = handle->ctx_area;
- handle_ctx_region = handle->ctx_region;
-
- if (handle_ctx_area) {
- CTX_wm_area_set((bContext *)C, handle_ctx_area);
- }
- if (handle_ctx_region) {
- CTX_wm_region_set((bContext *)C, handle_ctx_region);
- }
-
- uiBut *but = handle->popup_create_vars.but;
- ARegion *butregion = handle->popup_create_vars.butregion;
- ui_popup_block_refresh((bContext *)C, handle, butregion, but);
- }
- }
- }
-
- CTX_wm_area_set((bContext *)C, ctx_area);
- CTX_wm_region_set((bContext *)C, ctx_region);
+ ScrArea *ctx_area = CTX_wm_area(C);
+ ARegion *ctx_region = CTX_wm_region(C);
+ uiBlock *block;
+
+ if (ar->do_draw & RGN_DRAW_REFRESH_UI) {
+ ScrArea *handle_ctx_area;
+ ARegion *handle_ctx_region;
+ uiBlock *block_next;
+
+ ar->do_draw &= ~RGN_DRAW_REFRESH_UI;
+ for (block = ar->uiblocks.first; block; block = block_next) {
+ block_next = block->next;
+ uiPopupBlockHandle *handle = block->handle;
+
+ if (handle->can_refresh) {
+ handle_ctx_area = handle->ctx_area;
+ handle_ctx_region = handle->ctx_region;
+
+ if (handle_ctx_area) {
+ CTX_wm_area_set((bContext *)C, handle_ctx_area);
+ }
+ if (handle_ctx_region) {
+ CTX_wm_region_set((bContext *)C, handle_ctx_region);
+ }
+
+ uiBut *but = handle->popup_create_vars.but;
+ ARegion *butregion = handle->popup_create_vars.butregion;
+ ui_popup_block_refresh((bContext *)C, handle, butregion, but);
+ }
+ }
+ }
+
+ CTX_wm_area_set((bContext *)C, ctx_area);
+ CTX_wm_region_set((bContext *)C, ctx_region);
}
static void ui_block_region_draw(const bContext *C, ARegion *ar)
{
- uiBlock *block;
+ uiBlock *block;
- for (block = ar->uiblocks.first; block; block = block->next) {
- UI_block_draw(C, block);
- }
+ for (block = ar->uiblocks.first; block; block = block->next) {
+ UI_block_draw(C, block);
+ }
}
/**
* Use to refresh centered popups on screen resizing (for splash).
*/
-static void ui_block_region_popup_window_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn, const Scene *UNUSED(scene))
+static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- switch (wmn->category) {
- case NC_WINDOW:
- {
- switch (wmn->action) {
- case NA_EDITED:
- {
- /* window resize */
- ED_region_tag_refresh_ui(ar);
- break;
- }
- }
- break;
- }
- }
+ switch (wmn->category) {
+ case NC_WINDOW: {
+ switch (wmn->action) {
+ case NA_EDITED: {
+ /* window resize */
+ ED_region_tag_refresh_ui(ar);
+ break;
+ }
+ }
+ break;
+ }
+ }
}
static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
{
- uiBut *bt;
- const float xmin_orig = block->rect.xmin;
- const int margin = UI_SCREEN_MARGIN;
- int winx, winy;
-
- if (block->flag & UI_BLOCK_NO_WIN_CLIP) {
- return;
- }
-
- winx = WM_window_pixels_x(window);
- winy = WM_window_pixels_y(window);
-
- /* shift to left if outside of view */
- if (block->rect.xmax > winx - margin) {
- const float xofs = winx - margin - block->rect.xmax;
- block->rect.xmin += xofs;
- block->rect.xmax += xofs;
- }
- /* shift menus to right if outside of view */
- if (block->rect.xmin < margin) {
- const float xofs = (margin - block->rect.xmin);
- block->rect.xmin += xofs;
- block->rect.xmax += xofs;
- }
-
- if (block->rect.ymin < margin) {
- block->rect.ymin = margin;
- }
- if (block->rect.ymax > winy - UI_POPUP_MENU_TOP) {
- block->rect.ymax = winy - UI_POPUP_MENU_TOP;
- }
-
- /* ensure menu items draw inside left/right boundary */
- const float xofs = block->rect.xmin - xmin_orig;
- for (bt = block->buttons.first; bt; bt = bt->next) {
- bt->rect.xmin += xofs;
- bt->rect.xmax += xofs;
- }
+ uiBut *bt;
+ const float xmin_orig = block->rect.xmin;
+ const int margin = UI_SCREEN_MARGIN;
+ int winx, winy;
+
+ if (block->flag & UI_BLOCK_NO_WIN_CLIP) {
+ return;
+ }
+
+ winx = WM_window_pixels_x(window);
+ winy = WM_window_pixels_y(window);
+
+ /* shift to left if outside of view */
+ if (block->rect.xmax > winx - margin) {
+ const float xofs = winx - margin - block->rect.xmax;
+ block->rect.xmin += xofs;
+ block->rect.xmax += xofs;
+ }
+ /* shift menus to right if outside of view */
+ if (block->rect.xmin < margin) {
+ const float xofs = (margin - block->rect.xmin);
+ block->rect.xmin += xofs;
+ block->rect.xmax += xofs;
+ }
+
+ if (block->rect.ymin < margin) {
+ block->rect.ymin = margin;
+ }
+ if (block->rect.ymax > winy - UI_POPUP_MENU_TOP) {
+ block->rect.ymax = winy - UI_POPUP_MENU_TOP;
+ }
+
+ /* ensure menu items draw inside left/right boundary */
+ const float xofs = block->rect.xmin - xmin_orig;
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ bt->rect.xmin += xofs;
+ bt->rect.xmax += xofs;
+ }
}
void ui_popup_block_scrolltest(uiBlock *block)
{
- uiBut *bt;
-
- block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP);
-
- for (bt = block->buttons.first; bt; bt = bt->next) {
- bt->flag &= ~UI_SCROLLED;
- }
-
- if (block->buttons.first == block->buttons.last) {
- return;
- }
-
- /* mark buttons that are outside boundary */
- for (bt = block->buttons.first; bt; bt = bt->next) {
- if (bt->rect.ymin < block->rect.ymin) {
- bt->flag |= UI_SCROLLED;
- block->flag |= UI_BLOCK_CLIPBOTTOM;
- }
- if (bt->rect.ymax > block->rect.ymax) {
- bt->flag |= UI_SCROLLED;
- block->flag |= UI_BLOCK_CLIPTOP;
- }
- }
-
- /* mark buttons overlapping arrows, if we have them */
- for (bt = block->buttons.first; bt; bt = bt->next) {
- if (block->flag & UI_BLOCK_CLIPBOTTOM) {
- if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) {
- bt->flag |= UI_SCROLLED;
- }
- }
- if (block->flag & UI_BLOCK_CLIPTOP) {
- if (bt->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) {
- bt->flag |= UI_SCROLLED;
- }
- }
- }
+ uiBut *bt;
+
+ block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP);
+
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ bt->flag &= ~UI_SCROLLED;
+ }
+
+ if (block->buttons.first == block->buttons.last) {
+ return;
+ }
+
+ /* mark buttons that are outside boundary */
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (bt->rect.ymin < block->rect.ymin) {
+ bt->flag |= UI_SCROLLED;
+ block->flag |= UI_BLOCK_CLIPBOTTOM;
+ }
+ if (bt->rect.ymax > block->rect.ymax) {
+ bt->flag |= UI_SCROLLED;
+ block->flag |= UI_BLOCK_CLIPTOP;
+ }
+ }
+
+ /* mark buttons overlapping arrows, if we have them */
+ for (bt = block->buttons.first; bt; bt = bt->next) {
+ if (block->flag & UI_BLOCK_CLIPBOTTOM) {
+ if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) {
+ bt->flag |= UI_SCROLLED;
+ }
+ }
+ if (block->flag & UI_BLOCK_CLIPTOP) {
+ if (bt->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) {
+ bt->flag |= UI_SCROLLED;
+ }
+ }
+ }
}
static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
{
- wmWindow *win = CTX_wm_window(C);
- bScreen *sc = CTX_wm_screen(C);
+ wmWindow *win = CTX_wm_window(C);
+ bScreen *sc = CTX_wm_screen(C);
- ui_region_temp_remove(C, sc, handle->region);
+ ui_region_temp_remove(C, sc, handle->region);
- /* reset to region cursor (only if there's not another menu open) */
- if (BLI_listbase_is_empty(&sc->regionbase)) {
- ED_region_cursor_set(win, CTX_wm_area(C), CTX_wm_region(C));
- /* in case cursor needs to be changed again */
- WM_event_add_mousemove(C);
- }
+ /* reset to region cursor (only if there's not another menu open) */
+ if (BLI_listbase_is_empty(&sc->regionbase)) {
+ ED_region_cursor_set(win, CTX_wm_area(C), CTX_wm_region(C));
+ /* in case cursor needs to be changed again */
+ WM_event_add_mousemove(C);
+ }
- if (handle->scrolltimer) {
- WM_event_remove_timer(CTX_wm_manager(C), win, handle->scrolltimer);
- }
+ if (handle->scrolltimer) {
+ WM_event_remove_timer(CTX_wm_manager(C), win, handle->scrolltimer);
+ }
}
/**
* Called for creating new popups and refreshing existing ones.
*/
-uiBlock *ui_popup_block_refresh(
- bContext *C, uiPopupBlockHandle *handle,
- ARegion *butregion, uiBut *but)
+uiBlock *ui_popup_block_refresh(bContext *C,
+ uiPopupBlockHandle *handle,
+ ARegion *butregion,
+ uiBut *but)
{
- const int margin = UI_POPUP_MARGIN;
- wmWindow *window = CTX_wm_window(C);
- ARegion *ar = handle->region;
+ const int margin = UI_POPUP_MARGIN;
+ wmWindow *window = CTX_wm_window(C);
+ ARegion *ar = handle->region;
- uiBlockCreateFunc create_func = handle->popup_create_vars.create_func;
- uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func;
- void *arg = handle->popup_create_vars.arg;
+ uiBlockCreateFunc create_func = handle->popup_create_vars.create_func;
+ uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func;
+ void *arg = handle->popup_create_vars.arg;
- uiBlock *block_old = ar->uiblocks.first;
- uiBlock *block;
+ uiBlock *block_old = ar->uiblocks.first;
+ uiBlock *block;
- handle->refresh = (block_old != NULL);
+ handle->refresh = (block_old != NULL);
- BLI_assert(!handle->refresh || handle->can_refresh);
+ BLI_assert(!handle->refresh || handle->can_refresh);
#ifdef DEBUG
- wmEvent *event_back = window->eventstate;
+ wmEvent *event_back = window->eventstate;
#endif
- /* create ui block */
- if (create_func) {
- block = create_func(C, ar, arg);
- }
- else {
- block = handle_create_func(C, handle, arg);
- }
+ /* create ui block */
+ if (create_func) {
+ block = create_func(C, ar, arg);
+ }
+ else {
+ block = handle_create_func(C, handle, arg);
+ }
- /* callbacks _must_ leave this for us, otherwise we can't call UI_block_update_from_old */
- BLI_assert(!block->endblock);
+ /* callbacks _must_ leave this for us, otherwise we can't call UI_block_update_from_old */
+ BLI_assert(!block->endblock);
- /* ensure we don't use mouse coords here! */
+ /* ensure we don't use mouse coords here! */
#ifdef DEBUG
- window->eventstate = NULL;
+ window->eventstate = NULL;
#endif
- if (block->handle) {
- memcpy(block->handle, handle, sizeof(uiPopupBlockHandle));
- MEM_freeN(handle);
- handle = block->handle;
- }
- else {
- block->handle = handle;
- }
-
- ar->regiondata = handle;
-
- /* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */
- if (but == NULL) {
- block->flag |= UI_BLOCK_POPUP;
- }
-
- block->flag |= UI_BLOCK_LOOP;
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
-
- /* defer this until blocks are translated (below) */
- block->oldblock = NULL;
-
- if (!block->endblock) {
- UI_block_end_ex(C, block, handle->popup_create_vars.event_xy, handle->popup_create_vars.event_xy);
- }
-
- /* if this is being created from a button */
- if (but) {
- block->aspect = but->block->aspect;
- ui_popup_block_position(window, butregion, but, block);
- handle->direction = block->direction;
- }
- else {
- uiSafetyRct *saferct;
- /* keep a list of these, needed for pulldown menus */
- saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
- saferct->safety = block->safety;
- BLI_addhead(&block->saferct, saferct);
- }
-
- if (block->flag & UI_BLOCK_RADIAL) {
- int win_width = UI_SCREEN_MARGIN;
- int winx, winy;
-
- int x_offset = 0, y_offset = 0;
-
- winx = WM_window_pixels_x(window);
- winy = WM_window_pixels_y(window);
-
- copy_v2_v2(block->pie_data.pie_center_init, block->pie_data.pie_center_spawned);
-
- /* only try translation if area is large enough */
- if (BLI_rctf_size_x(&block->rect) < winx - (2.0f * win_width)) {
- if (block->rect.xmin < win_width ) {
- x_offset += win_width - block->rect.xmin;
- }
- if (block->rect.xmax > winx - win_width) {
- x_offset += winx - win_width - block->rect.xmax;
- }
- }
-
- if (BLI_rctf_size_y(&block->rect) < winy - (2.0f * win_width)) {
- if (block->rect.ymin < win_width ) {
- y_offset += win_width - block->rect.ymin;
- }
- if (block->rect.ymax > winy - win_width) {
- y_offset += winy - win_width - block->rect.ymax;
- }
- }
- /* if we are offsetting set up initial data for timeout functionality */
-
- if ((x_offset != 0) || (y_offset != 0)) {
- block->pie_data.pie_center_spawned[0] += x_offset;
- block->pie_data.pie_center_spawned[1] += y_offset;
-
- UI_block_translate(block, x_offset, y_offset);
-
- if (U.pie_initial_timeout > 0) {
- block->pie_data.flags |= UI_PIE_INITIAL_DIRECTION;
- }
- }
-
- ar->winrct.xmin = 0;
- ar->winrct.xmax = winx;
- ar->winrct.ymin = 0;
- ar->winrct.ymax = winy;
-
- ui_block_calc_pie_segment(block, block->pie_data.pie_center_init);
-
- /* lastly set the buttons at the center of the pie menu, ready for animation */
- if (U.pie_animation_timeout > 0) {
- for (uiBut *but_iter = block->buttons.first; but_iter; but_iter = but_iter->next) {
- if (but_iter->pie_dir != UI_RADIAL_NONE) {
- BLI_rctf_recenter(&but_iter->rect, UNPACK2(block->pie_data.pie_center_spawned));
- }
- }
- }
- }
- else {
- /* clip block with window boundary */
- ui_popup_block_clip(window, block);
-
- /* Avoid menu moving down and losing cursor focus by keeping it at
- * the same height. */
- if (handle->refresh && handle->prev_block_rect.ymax > block->rect.ymax) {
- float offset = handle->prev_block_rect.ymax - block->rect.ymax;
- UI_block_translate(block, 0, offset);
- block->rect.ymin = handle->prev_block_rect.ymin;
- }
-
- handle->prev_block_rect = block->rect;
-
- /* the block and buttons were positioned in window space as in 2.4x, now
- * these menu blocks are regions so we bring it back to region space.
- * additionally we add some padding for the menu shadow or rounded menus */
- ar->winrct.xmin = block->rect.xmin - margin;
- ar->winrct.xmax = block->rect.xmax + margin;
- ar->winrct.ymin = block->rect.ymin - margin;
- ar->winrct.ymax = block->rect.ymax + UI_POPUP_MENU_TOP;
-
- UI_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);
-
- /* apply scroll offset */
- if (handle->scrolloffset != 0.0f) {
- for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
- bt->rect.ymin += handle->scrolloffset;
- bt->rect.ymax += handle->scrolloffset;
- }
- }
- }
-
- if (block_old) {
- block->oldblock = block_old;
- UI_block_update_from_old(C, block);
- UI_blocklist_free_inactive(C, &ar->uiblocks);
- }
-
- /* checks which buttons are visible, sets flags to prevent draw (do after region init) */
- ui_popup_block_scrolltest(block);
-
- /* adds subwindow */
- ED_region_init(ar);
-
- /* get winmat now that we actually have the subwindow */
- wmGetProjectionMatrix(block->winmat, &ar->winrct);
-
- /* notify change and redraw */
- ED_region_tag_redraw(ar);
-
- ED_region_update_rect(ar);
+ if (block->handle) {
+ memcpy(block->handle, handle, sizeof(uiPopupBlockHandle));
+ MEM_freeN(handle);
+ handle = block->handle;
+ }
+ else {
+ block->handle = handle;
+ }
+
+ ar->regiondata = handle;
+
+ /* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */
+ if (but == NULL) {
+ block->flag |= UI_BLOCK_POPUP;
+ }
+
+ block->flag |= UI_BLOCK_LOOP;
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+
+ /* defer this until blocks are translated (below) */
+ block->oldblock = NULL;
+
+ if (!block->endblock) {
+ UI_block_end_ex(
+ C, block, handle->popup_create_vars.event_xy, handle->popup_create_vars.event_xy);
+ }
+
+ /* if this is being created from a button */
+ if (but) {
+ block->aspect = but->block->aspect;
+ ui_popup_block_position(window, butregion, but, block);
+ handle->direction = block->direction;
+ }
+ else {
+ uiSafetyRct *saferct;
+ /* keep a list of these, needed for pulldown menus */
+ saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
+ saferct->safety = block->safety;
+ BLI_addhead(&block->saferct, saferct);
+ }
+
+ if (block->flag & UI_BLOCK_RADIAL) {
+ int win_width = UI_SCREEN_MARGIN;
+ int winx, winy;
+
+ int x_offset = 0, y_offset = 0;
+
+ winx = WM_window_pixels_x(window);
+ winy = WM_window_pixels_y(window);
+
+ copy_v2_v2(block->pie_data.pie_center_init, block->pie_data.pie_center_spawned);
+
+ /* only try translation if area is large enough */
+ if (BLI_rctf_size_x(&block->rect) < winx - (2.0f * win_width)) {
+ if (block->rect.xmin < win_width) {
+ x_offset += win_width - block->rect.xmin;
+ }
+ if (block->rect.xmax > winx - win_width) {
+ x_offset += winx - win_width - block->rect.xmax;
+ }
+ }
+
+ if (BLI_rctf_size_y(&block->rect) < winy - (2.0f * win_width)) {
+ if (block->rect.ymin < win_width) {
+ y_offset += win_width - block->rect.ymin;
+ }
+ if (block->rect.ymax > winy - win_width) {
+ y_offset += winy - win_width - block->rect.ymax;
+ }
+ }
+ /* if we are offsetting set up initial data for timeout functionality */
+
+ if ((x_offset != 0) || (y_offset != 0)) {
+ block->pie_data.pie_center_spawned[0] += x_offset;
+ block->pie_data.pie_center_spawned[1] += y_offset;
+
+ UI_block_translate(block, x_offset, y_offset);
+
+ if (U.pie_initial_timeout > 0) {
+ block->pie_data.flags |= UI_PIE_INITIAL_DIRECTION;
+ }
+ }
+
+ ar->winrct.xmin = 0;
+ ar->winrct.xmax = winx;
+ ar->winrct.ymin = 0;
+ ar->winrct.ymax = winy;
+
+ ui_block_calc_pie_segment(block, block->pie_data.pie_center_init);
+
+ /* lastly set the buttons at the center of the pie menu, ready for animation */
+ if (U.pie_animation_timeout > 0) {
+ for (uiBut *but_iter = block->buttons.first; but_iter; but_iter = but_iter->next) {
+ if (but_iter->pie_dir != UI_RADIAL_NONE) {
+ BLI_rctf_recenter(&but_iter->rect, UNPACK2(block->pie_data.pie_center_spawned));
+ }
+ }
+ }
+ }
+ else {
+ /* clip block with window boundary */
+ ui_popup_block_clip(window, block);
+
+ /* Avoid menu moving down and losing cursor focus by keeping it at
+ * the same height. */
+ if (handle->refresh && handle->prev_block_rect.ymax > block->rect.ymax) {
+ float offset = handle->prev_block_rect.ymax - block->rect.ymax;
+ UI_block_translate(block, 0, offset);
+ block->rect.ymin = handle->prev_block_rect.ymin;
+ }
+
+ handle->prev_block_rect = block->rect;
+
+ /* the block and buttons were positioned in window space as in 2.4x, now
+ * these menu blocks are regions so we bring it back to region space.
+ * additionally we add some padding for the menu shadow or rounded menus */
+ ar->winrct.xmin = block->rect.xmin - margin;
+ ar->winrct.xmax = block->rect.xmax + margin;
+ ar->winrct.ymin = block->rect.ymin - margin;
+ ar->winrct.ymax = block->rect.ymax + UI_POPUP_MENU_TOP;
+
+ UI_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);
+
+ /* apply scroll offset */
+ if (handle->scrolloffset != 0.0f) {
+ for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
+ bt->rect.ymin += handle->scrolloffset;
+ bt->rect.ymax += handle->scrolloffset;
+ }
+ }
+ }
+
+ if (block_old) {
+ block->oldblock = block_old;
+ UI_block_update_from_old(C, block);
+ UI_blocklist_free_inactive(C, &ar->uiblocks);
+ }
+
+ /* checks which buttons are visible, sets flags to prevent draw (do after region init) */
+ ui_popup_block_scrolltest(block);
+
+ /* adds subwindow */
+ ED_region_init(ar);
+
+ /* get winmat now that we actually have the subwindow */
+ wmGetProjectionMatrix(block->winmat, &ar->winrct);
+
+ /* notify change and redraw */
+ ED_region_tag_redraw(ar);
+
+ ED_region_update_rect(ar);
#ifdef DEBUG
- window->eventstate = event_back;
+ window->eventstate = event_back;
#endif
- return block;
+ return block;
}
-uiPopupBlockHandle *ui_popup_block_create(
- bContext *C, ARegion *butregion, uiBut *but,
- uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func,
- void *arg)
+uiPopupBlockHandle *ui_popup_block_create(bContext *C,
+ ARegion *butregion,
+ uiBut *but,
+ uiBlockCreateFunc create_func,
+ uiBlockHandleCreateFunc handle_create_func,
+ void *arg)
{
- wmWindow *window = CTX_wm_window(C);
- uiBut *activebut = UI_context_active_but_get(C);
- static ARegionType type;
- ARegion *ar;
- uiBlock *block;
- uiPopupBlockHandle *handle;
-
- /* disable tooltips from buttons below */
- if (activebut) {
- UI_but_tooltip_timer_remove(C, activebut);
- }
- /* standard cursor by default */
- WM_cursor_set(window, CURSOR_STD);
-
- /* create handle */
- handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
-
- /* store context for operator */
- handle->ctx_area = CTX_wm_area(C);
- handle->ctx_region = CTX_wm_region(C);
-
- /* store vars to refresh popup (RGN_DRAW_REFRESH_UI) */
- handle->popup_create_vars.create_func = create_func;
- handle->popup_create_vars.handle_create_func = handle_create_func;
- handle->popup_create_vars.arg = arg;
- handle->popup_create_vars.but = but;
- handle->popup_create_vars.butregion = but ? butregion : NULL;
- copy_v2_v2_int(handle->popup_create_vars.event_xy, &window->eventstate->x);
-
- /* don't allow by default, only if popup type explicitly supports it */
- handle->can_refresh = false;
-
- /* create area region */
- ar = ui_region_temp_add(CTX_wm_screen(C));
- handle->region = ar;
-
- memset(&type, 0, sizeof(ARegionType));
- type.draw = ui_block_region_draw;
- type.layout = ui_block_region_refresh;
- type.regionid = RGN_TYPE_TEMPORARY;
- ar->type = &type;
-
- UI_region_handlers_add(&ar->handlers);
-
- block = ui_popup_block_refresh(C, handle, butregion, but);
- handle = block->handle;
-
- /* keep centered on window resizing */
- if (block->bounds_type == UI_BLOCK_BOUNDS_POPUP_CENTER) {
- type.listener = ui_block_region_popup_window_listener;
- }
-
- return handle;
+ wmWindow *window = CTX_wm_window(C);
+ uiBut *activebut = UI_context_active_but_get(C);
+ static ARegionType type;
+ ARegion *ar;
+ uiBlock *block;
+ uiPopupBlockHandle *handle;
+
+ /* disable tooltips from buttons below */
+ if (activebut) {
+ UI_but_tooltip_timer_remove(C, activebut);
+ }
+ /* standard cursor by default */
+ WM_cursor_set(window, CURSOR_STD);
+
+ /* create handle */
+ handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
+
+ /* store context for operator */
+ handle->ctx_area = CTX_wm_area(C);
+ handle->ctx_region = CTX_wm_region(C);
+
+ /* store vars to refresh popup (RGN_DRAW_REFRESH_UI) */
+ handle->popup_create_vars.create_func = create_func;
+ handle->popup_create_vars.handle_create_func = handle_create_func;
+ handle->popup_create_vars.arg = arg;
+ handle->popup_create_vars.but = but;
+ handle->popup_create_vars.butregion = but ? butregion : NULL;
+ copy_v2_v2_int(handle->popup_create_vars.event_xy, &window->eventstate->x);
+
+ /* don't allow by default, only if popup type explicitly supports it */
+ handle->can_refresh = false;
+
+ /* create area region */
+ ar = ui_region_temp_add(CTX_wm_screen(C));
+ handle->region = ar;
+
+ memset(&type, 0, sizeof(ARegionType));
+ type.draw = ui_block_region_draw;
+ type.layout = ui_block_region_refresh;
+ type.regionid = RGN_TYPE_TEMPORARY;
+ ar->type = &type;
+
+ UI_region_handlers_add(&ar->handlers);
+
+ block = ui_popup_block_refresh(C, handle, butregion, but);
+ handle = block->handle;
+
+ /* keep centered on window resizing */
+ if (block->bounds_type == UI_BLOCK_BOUNDS_POPUP_CENTER) {
+ type.listener = ui_block_region_popup_window_listener;
+ }
+
+ return handle;
}
void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
{
- /* If this popup is created from a popover which does NOT have keep-open flag set,
- * then close the popover too. We could extend this to other popup types too. */
- ARegion *ar = handle->popup_create_vars.butregion;
- if (ar != NULL) {
- for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
- if (block->handle &&
- (block->flag & UI_BLOCK_POPOVER) &&
- (block->flag & UI_BLOCK_KEEP_OPEN) == 0)
- {
- uiPopupBlockHandle *menu = block->handle;
- menu->menuretval = UI_RETURN_OK;
- }
- }
- }
-
- if (handle->popup_create_vars.free_func) {
- handle->popup_create_vars.free_func(handle, handle->popup_create_vars.arg);
- }
-
- ui_popup_block_remove(C, handle);
-
- MEM_freeN(handle);
+ /* If this popup is created from a popover which does NOT have keep-open flag set,
+ * then close the popover too. We could extend this to other popup types too. */
+ ARegion *ar = handle->popup_create_vars.butregion;
+ if (ar != NULL) {
+ for (uiBlock *block = ar->uiblocks.first; block; block = block->next) {
+ if (block->handle && (block->flag & UI_BLOCK_POPOVER) &&
+ (block->flag & UI_BLOCK_KEEP_OPEN) == 0) {
+ uiPopupBlockHandle *menu = block->handle;
+ menu->menuretval = UI_RETURN_OK;
+ }
+ }
+ }
+
+ if (handle->popup_create_vars.free_func) {
+ handle->popup_create_vars.free_func(handle, handle->popup_create_vars.arg);
+ }
+
+ ui_popup_block_remove(C, handle);
+
+ MEM_freeN(handle);
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 9aebf1183e0..c37775febda 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -46,7 +46,6 @@
#include "RNA_access.h"
-
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_view2d.h"
@@ -59,606 +58,608 @@
#include "interface_regions_intern.h"
#include "GPU_state.h"
-#define MENU_BORDER (int)(0.3f * U.widget_unit)
+#define MENU_BORDER (int)(0.3f * U.widget_unit)
/* -------------------------------------------------------------------- */
/** \name Search Box Creation
* \{ */
struct uiSearchItems {
- int maxitem, totitem, maxstrlen;
+ int maxitem, totitem, maxstrlen;
- int offset, offset_i; /* offset for inserting in array */
- int more; /* flag indicating there are more items */
+ int offset, offset_i; /* offset for inserting in array */
+ int more; /* flag indicating there are more items */
- char **names;
- void **pointers;
- int *icons;
+ char **names;
+ void **pointers;
+ int *icons;
- AutoComplete *autocpl;
- void *active;
+ AutoComplete *autocpl;
+ void *active;
};
typedef struct uiSearchboxData {
- rcti bbox;
- uiFontStyle fstyle;
- uiSearchItems items;
- /** index in items array */
- int active;
- /** when menu opened with enough space for this */
- bool noback;
- /** draw thumbnail previews, rather than list */
- bool preview;
- /** use the UI_SEP_CHAR char for splitting shortcuts (good for operators, bad for data) */
- bool use_sep;
- int prv_rows, prv_cols;
+ rcti bbox;
+ uiFontStyle fstyle;
+ uiSearchItems items;
+ /** index in items array */
+ int active;
+ /** when menu opened with enough space for this */
+ bool noback;
+ /** draw thumbnail previews, rather than list */
+ bool preview;
+ /** use the UI_SEP_CHAR char for splitting shortcuts (good for operators, bad for data) */
+ bool use_sep;
+ int prv_rows, prv_cols;
} uiSearchboxData;
-#define SEARCH_ITEMS 10
+#define SEARCH_ITEMS 10
/* exported for use by search callbacks */
/* returns zero if nothing to add */
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid)
{
- /* hijack for autocomplete */
- if (items->autocpl) {
- UI_autocomplete_update_name(items->autocpl, name);
- return true;
- }
-
- /* hijack for finding active item */
- if (items->active) {
- if (poin == items->active) {
- items->offset_i = items->totitem;
- }
- items->totitem++;
- return true;
- }
-
- if (items->totitem >= items->maxitem) {
- items->more = 1;
- return false;
- }
-
- /* skip first items in list */
- if (items->offset_i > 0) {
- items->offset_i--;
- return true;
- }
-
- if (items->names) {
- BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
- }
- if (items->pointers) {
- items->pointers[items->totitem] = poin;
- }
- if (items->icons) {
- items->icons[items->totitem] = iconid;
- }
-
- items->totitem++;
-
- return true;
+ /* hijack for autocomplete */
+ if (items->autocpl) {
+ UI_autocomplete_update_name(items->autocpl, name);
+ return true;
+ }
+
+ /* hijack for finding active item */
+ if (items->active) {
+ if (poin == items->active) {
+ items->offset_i = items->totitem;
+ }
+ items->totitem++;
+ return true;
+ }
+
+ if (items->totitem >= items->maxitem) {
+ items->more = 1;
+ return false;
+ }
+
+ /* skip first items in list */
+ if (items->offset_i > 0) {
+ items->offset_i--;
+ return true;
+ }
+
+ if (items->names) {
+ BLI_strncpy(items->names[items->totitem], name, items->maxstrlen);
+ }
+ if (items->pointers) {
+ items->pointers[items->totitem] = poin;
+ }
+ if (items->icons) {
+ items->icons[items->totitem] = iconid;
+ }
+
+ items->totitem++;
+
+ return true;
}
int UI_searchbox_size_y(void)
{
- return SEARCH_ITEMS * UI_UNIT_Y + 2 * UI_POPUP_MENU_TOP;
+ return SEARCH_ITEMS * UI_UNIT_Y + 2 * UI_POPUP_MENU_TOP;
}
int UI_searchbox_size_x(void)
{
- return 12 * UI_UNIT_X;
+ return 12 * UI_UNIT_X;
}
int UI_search_items_find_index(uiSearchItems *items, const char *name)
{
- int i;
- for (i = 0; i < items->totitem; i++) {
- if (STREQ(name, items->names[i])) {
- return i;
- }
- }
- return -1;
+ int i;
+ for (i = 0; i < items->totitem; i++) {
+ if (STREQ(name, items->names[i])) {
+ return i;
+ }
+ }
+ return -1;
}
/* ar is the search box itself */
static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* apply step */
- data->active += step;
-
- if (data->items.totitem == 0) {
- data->active = -1;
- }
- else if (data->active >= data->items.totitem) {
- if (data->items.more) {
- data->items.offset++;
- data->active = data->items.totitem - 1;
- ui_searchbox_update(C, ar, but, false);
- }
- else {
- data->active = data->items.totitem - 1;
- }
- }
- else if (data->active < 0) {
- if (data->items.offset) {
- data->items.offset--;
- data->active = 0;
- ui_searchbox_update(C, ar, but, false);
- }
- else {
- /* only let users step into an 'unset' state for unlink buttons */
- data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0;
- }
- }
-
- ED_region_tag_redraw(ar);
+ uiSearchboxData *data = ar->regiondata;
+
+ /* apply step */
+ data->active += step;
+
+ if (data->items.totitem == 0) {
+ data->active = -1;
+ }
+ else if (data->active >= data->items.totitem) {
+ if (data->items.more) {
+ data->items.offset++;
+ data->active = data->items.totitem - 1;
+ ui_searchbox_update(C, ar, but, false);
+ }
+ else {
+ data->active = data->items.totitem - 1;
+ }
+ }
+ else if (data->active < 0) {
+ if (data->items.offset) {
+ data->items.offset--;
+ data->active = 0;
+ ui_searchbox_update(C, ar, but, false);
+ }
+ else {
+ /* only let users step into an 'unset' state for unlink buttons */
+ data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0;
+ }
+ }
+
+ ED_region_tag_redraw(ar);
}
static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr)
{
- /* thumbnail preview */
- if (data->preview) {
- int butw = (BLI_rcti_size_x(&data->bbox) - 2 * MENU_BORDER) / data->prv_cols;
- int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_BORDER) / data->prv_rows;
- int row, col;
-
- *r_rect = data->bbox;
-
- col = itemnr % data->prv_cols;
- row = itemnr / data->prv_cols;
-
- r_rect->xmin += MENU_BORDER + (col * butw);
- r_rect->xmax = r_rect->xmin + butw;
-
- r_rect->ymax -= MENU_BORDER + (row * buth);
- r_rect->ymin = r_rect->ymax - buth;
- }
- /* list view */
- else {
- int buth = (BLI_rcti_size_y(&data->bbox) - 2 * UI_POPUP_MENU_TOP) / SEARCH_ITEMS;
-
- *r_rect = data->bbox;
- r_rect->xmin = data->bbox.xmin + 3.0f;
- r_rect->xmax = data->bbox.xmax - 3.0f;
-
- r_rect->ymax = data->bbox.ymax - UI_POPUP_MENU_TOP - itemnr * buth;
- r_rect->ymin = r_rect->ymax - buth;
- }
-
+ /* thumbnail preview */
+ if (data->preview) {
+ int butw = (BLI_rcti_size_x(&data->bbox) - 2 * MENU_BORDER) / data->prv_cols;
+ int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_BORDER) / data->prv_rows;
+ int row, col;
+
+ *r_rect = data->bbox;
+
+ col = itemnr % data->prv_cols;
+ row = itemnr / data->prv_cols;
+
+ r_rect->xmin += MENU_BORDER + (col * butw);
+ r_rect->xmax = r_rect->xmin + butw;
+
+ r_rect->ymax -= MENU_BORDER + (row * buth);
+ r_rect->ymin = r_rect->ymax - buth;
+ }
+ /* list view */
+ else {
+ int buth = (BLI_rcti_size_y(&data->bbox) - 2 * UI_POPUP_MENU_TOP) / SEARCH_ITEMS;
+
+ *r_rect = data->bbox;
+ r_rect->xmin = data->bbox.xmin + 3.0f;
+ r_rect->xmax = data->bbox.xmax - 3.0f;
+
+ r_rect->ymax = data->bbox.ymax - UI_POPUP_MENU_TOP - itemnr * buth;
+ r_rect->ymin = r_rect->ymax - buth;
+ }
}
int ui_searchbox_find_index(ARegion *ar, const char *name)
{
- uiSearchboxData *data = ar->regiondata;
- return UI_search_items_find_index(&data->items, name);
+ uiSearchboxData *data = ar->regiondata;
+ return UI_search_items_find_index(&data->items, name);
}
/* x and y in screencoords */
bool ui_searchbox_inside(ARegion *ar, int x, int y)
{
- uiSearchboxData *data = ar->regiondata;
+ uiSearchboxData *data = ar->regiondata;
- return BLI_rcti_isect_pt(&data->bbox, x - ar->winrct.xmin, y - ar->winrct.ymin);
+ return BLI_rcti_isect_pt(&data->bbox, x - ar->winrct.xmin, y - ar->winrct.ymin);
}
/* string validated to be of correct length (but->hardmax) */
bool ui_searchbox_apply(uiBut *but, ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
+ uiSearchboxData *data = ar->regiondata;
- but->func_arg2 = NULL;
+ but->func_arg2 = NULL;
- if (data->active != -1) {
- const char *name = data->items.names[data->active];
- const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
+ if (data->active != -1) {
+ const char *name = data->items.names[data->active];
+ const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
- BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen);
+ BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen);
- but->func_arg2 = data->items.pointers[data->active];
+ but->func_arg2 = data->items.pointers[data->active];
- return true;
- }
- else if (but->flag & UI_BUT_VALUE_CLEAR) {
- /* It is valid for _VALUE_CLEAR flavor to have no active element
- * (it's a valid way to unlink). */
- but->editstr[0] = '\0';
+ return true;
+ }
+ else if (but->flag & UI_BUT_VALUE_CLEAR) {
+ /* It is valid for _VALUE_CLEAR flavor to have no active element
+ * (it's a valid way to unlink). */
+ but->editstr[0] = '\0';
- return true;
- }
- else {
- return false;
- }
+ return true;
+ }
+ else {
+ return false;
+ }
}
void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, const wmEvent *event)
{
- uiSearchboxData *data = ar->regiondata;
- int type = event->type, val = event->val;
-
- if (type == MOUSEPAN) {
- ui_pan_to_scroll(event, &type, &val);
- }
-
- switch (type) {
- case WHEELUPMOUSE:
- case UPARROWKEY:
- ui_searchbox_select(C, ar, but, -1);
- break;
- case WHEELDOWNMOUSE:
- case DOWNARROWKEY:
- ui_searchbox_select(C, ar, but, 1);
- break;
- case MOUSEMOVE:
- if (BLI_rcti_isect_pt(&ar->winrct, event->x, event->y)) {
- rcti rect;
- int a;
-
- for (a = 0; a < data->items.totitem; a++) {
- ui_searchbox_butrect(&rect, data, a);
- if (BLI_rcti_isect_pt(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) {
- if (data->active != a) {
- data->active = a;
- ui_searchbox_select(C, ar, but, 0);
- break;
- }
- }
- }
- }
- break;
- }
+ uiSearchboxData *data = ar->regiondata;
+ int type = event->type, val = event->val;
+
+ if (type == MOUSEPAN) {
+ ui_pan_to_scroll(event, &type, &val);
+ }
+
+ switch (type) {
+ case WHEELUPMOUSE:
+ case UPARROWKEY:
+ ui_searchbox_select(C, ar, but, -1);
+ break;
+ case WHEELDOWNMOUSE:
+ case DOWNARROWKEY:
+ ui_searchbox_select(C, ar, but, 1);
+ break;
+ case MOUSEMOVE:
+ if (BLI_rcti_isect_pt(&ar->winrct, event->x, event->y)) {
+ rcti rect;
+ int a;
+
+ for (a = 0; a < data->items.totitem; a++) {
+ ui_searchbox_butrect(&rect, data, a);
+ if (BLI_rcti_isect_pt(&rect, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin)) {
+ if (data->active != a) {
+ data->active = a;
+ ui_searchbox_select(C, ar, but, 0);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
}
/* ar is the search box itself */
void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* reset vars */
- data->items.totitem = 0;
- data->items.more = 0;
- if (reset == false) {
- data->items.offset_i = data->items.offset;
- }
- else {
- data->items.offset_i = data->items.offset = 0;
- data->active = -1;
-
- /* handle active */
- if (but->search_func && but->func_arg2) {
- data->items.active = but->func_arg2;
- but->search_func(C, but->search_arg, but->editstr, &data->items);
- data->items.active = NULL;
-
- /* found active item, calculate real offset by centering it */
- if (data->items.totitem) {
- /* first case, begin of list */
- if (data->items.offset_i < data->items.maxitem) {
- data->active = data->items.offset_i;
- data->items.offset_i = 0;
- }
- else {
- /* second case, end of list */
- if (data->items.totitem - data->items.offset_i <= data->items.maxitem) {
- data->active = data->items.offset_i - data->items.totitem + data->items.maxitem;
- data->items.offset_i = data->items.totitem - data->items.maxitem;
- }
- else {
- /* center active item */
- data->items.offset_i -= data->items.maxitem / 2;
- data->active = data->items.maxitem / 2;
- }
- }
- }
- data->items.offset = data->items.offset_i;
- data->items.totitem = 0;
- }
- }
-
- /* callback */
- if (but->search_func) {
- but->search_func(C, but->search_arg, but->editstr, &data->items);
- }
-
- /* handle case where editstr is equal to one of items */
- if (reset && data->active == -1) {
- int a;
-
- for (a = 0; a < data->items.totitem; a++) {
- const char *name = data->items.names[a];
- const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
- if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
- data->active = a;
- break;
- }
- }
- if (data->items.totitem == 1 && but->editstr[0]) {
- data->active = 0;
- }
- }
-
- /* validate selected item */
- ui_searchbox_select(C, ar, but, 0);
-
- ED_region_tag_redraw(ar);
+ uiSearchboxData *data = ar->regiondata;
+
+ /* reset vars */
+ data->items.totitem = 0;
+ data->items.more = 0;
+ if (reset == false) {
+ data->items.offset_i = data->items.offset;
+ }
+ else {
+ data->items.offset_i = data->items.offset = 0;
+ data->active = -1;
+
+ /* handle active */
+ if (but->search_func && but->func_arg2) {
+ data->items.active = but->func_arg2;
+ but->search_func(C, but->search_arg, but->editstr, &data->items);
+ data->items.active = NULL;
+
+ /* found active item, calculate real offset by centering it */
+ if (data->items.totitem) {
+ /* first case, begin of list */
+ if (data->items.offset_i < data->items.maxitem) {
+ data->active = data->items.offset_i;
+ data->items.offset_i = 0;
+ }
+ else {
+ /* second case, end of list */
+ if (data->items.totitem - data->items.offset_i <= data->items.maxitem) {
+ data->active = data->items.offset_i - data->items.totitem + data->items.maxitem;
+ data->items.offset_i = data->items.totitem - data->items.maxitem;
+ }
+ else {
+ /* center active item */
+ data->items.offset_i -= data->items.maxitem / 2;
+ data->active = data->items.maxitem / 2;
+ }
+ }
+ }
+ data->items.offset = data->items.offset_i;
+ data->items.totitem = 0;
+ }
+ }
+
+ /* callback */
+ if (but->search_func) {
+ but->search_func(C, but->search_arg, but->editstr, &data->items);
+ }
+
+ /* handle case where editstr is equal to one of items */
+ if (reset && data->active == -1) {
+ int a;
+
+ for (a = 0; a < data->items.totitem; a++) {
+ const char *name = data->items.names[a];
+ const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
+ if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
+ data->active = a;
+ break;
+ }
+ }
+ if (data->items.totitem == 1 && but->editstr[0]) {
+ data->active = 0;
+ }
+ }
+
+ /* validate selected item */
+ ui_searchbox_select(C, ar, but, 0);
+
+ ED_region_tag_redraw(ar);
}
int ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str)
{
- uiSearchboxData *data = ar->regiondata;
- int match = AUTOCOMPLETE_NO_MATCH;
+ uiSearchboxData *data = ar->regiondata;
+ int match = AUTOCOMPLETE_NO_MATCH;
- if (str[0]) {
- data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but));
+ if (str[0]) {
+ data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but));
- but->search_func(C, but->search_arg, but->editstr, &data->items);
+ but->search_func(C, but->search_arg, but->editstr, &data->items);
- match = UI_autocomplete_end(data->items.autocpl, str);
- data->items.autocpl = NULL;
- }
+ match = UI_autocomplete_end(data->items.autocpl, str);
+ data->items.autocpl = NULL;
+ }
- return match;
+ return match;
}
static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* pixel space */
- wmOrtho2_region_pixelspace(ar);
-
- if (data->noback == false) {
- ui_draw_widget_menu_back(&data->bbox, true);
- }
-
- /* draw text */
- if (data->items.totitem) {
- rcti rect;
- int a;
-
- if (data->preview) {
- /* draw items */
- for (a = 0; a < data->items.totitem; a++) {
- /* ensure icon is up-to-date */
- ui_icon_ensure_deferred(C, data->items.icons[a], data->preview);
-
- ui_searchbox_butrect(&rect, data, a);
-
- /* widget itself */
- ui_draw_preview_item(
- &data->fstyle, &rect, data->items.names[a], data->items.icons[a],
- (a == data->active) ? UI_ACTIVE : 0);
- }
-
- /* indicate more */
- if (data->items.more) {
- ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
- UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN);
- GPU_blend(false);
- }
- if (data->items.offset) {
- ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
- UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP);
- GPU_blend(false);
- }
-
- }
- else {
- /* draw items */
- for (a = 0; a < data->items.totitem; a++) {
- ui_searchbox_butrect(&rect, data, a);
-
- /* widget itself */
- ui_draw_menu_item(
- &data->fstyle, &rect, data->items.names[a], data->items.icons[a],
- (a == data->active) ? UI_ACTIVE : 0, data->use_sep);
-
- }
- /* indicate more */
- if (data->items.more) {
- ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
- GPU_blend(false);
- }
- if (data->items.offset) {
- ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
- GPU_blend(false);
- }
- }
- }
+ uiSearchboxData *data = ar->regiondata;
+
+ /* pixel space */
+ wmOrtho2_region_pixelspace(ar);
+
+ if (data->noback == false) {
+ ui_draw_widget_menu_back(&data->bbox, true);
+ }
+
+ /* draw text */
+ if (data->items.totitem) {
+ rcti rect;
+ int a;
+
+ if (data->preview) {
+ /* draw items */
+ for (a = 0; a < data->items.totitem; a++) {
+ /* ensure icon is up-to-date */
+ ui_icon_ensure_deferred(C, data->items.icons[a], data->preview);
+
+ ui_searchbox_butrect(&rect, data, a);
+
+ /* widget itself */
+ ui_draw_preview_item(&data->fstyle,
+ &rect,
+ data->items.names[a],
+ data->items.icons[a],
+ (a == data->active) ? UI_ACTIVE : 0);
+ }
+
+ /* indicate more */
+ if (data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
+ GPU_blend(true);
+ UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN);
+ GPU_blend(false);
+ }
+ if (data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ GPU_blend(true);
+ UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP);
+ GPU_blend(false);
+ }
+ }
+ else {
+ /* draw items */
+ for (a = 0; a < data->items.totitem; a++) {
+ ui_searchbox_butrect(&rect, data, a);
+
+ /* widget itself */
+ ui_draw_menu_item(&data->fstyle,
+ &rect,
+ data->items.names[a],
+ data->items.icons[a],
+ (a == data->active) ? UI_ACTIVE : 0,
+ data->use_sep);
+ }
+ /* indicate more */
+ if (data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
+ GPU_blend(false);
+ }
+ if (data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
+ GPU_blend(false);
+ }
+ }
+ }
}
static void ui_searchbox_region_free_cb(ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
- int a;
-
- /* free search data */
- for (a = 0; a < data->items.maxitem; a++) {
- MEM_freeN(data->items.names[a]);
- }
- MEM_freeN(data->items.names);
- MEM_freeN(data->items.pointers);
- MEM_freeN(data->items.icons);
-
- MEM_freeN(data);
- ar->regiondata = NULL;
+ uiSearchboxData *data = ar->regiondata;
+ int a;
+
+ /* free search data */
+ for (a = 0; a < data->items.maxitem; a++) {
+ MEM_freeN(data->items.names[a]);
+ }
+ MEM_freeN(data->items.names);
+ MEM_freeN(data->items.pointers);
+ MEM_freeN(data->items.icons);
+
+ MEM_freeN(data);
+ ar->regiondata = NULL;
}
ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but)
{
- wmWindow *win = CTX_wm_window(C);
- uiStyle *style = UI_style_get();
- static ARegionType type;
- ARegion *ar;
- uiSearchboxData *data;
- float aspect = but->block->aspect;
- rctf rect_fl;
- rcti rect_i;
- const int margin = UI_POPUP_MARGIN;
- int winx /*, winy */, ofsx, ofsy;
- int i;
-
- /* create area region */
- ar = ui_region_temp_add(CTX_wm_screen(C));
-
- memset(&type, 0, sizeof(ARegionType));
- type.draw = ui_searchbox_region_draw_cb;
- type.free = ui_searchbox_region_free_cb;
- type.regionid = RGN_TYPE_TEMPORARY;
- ar->type = &type;
-
- /* create searchbox data */
- data = MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData");
-
- /* set font, get bb */
- data->fstyle = style->widget; /* copy struct */
- ui_fontscale(&data->fstyle.points, aspect);
- UI_fontstyle_set(&data->fstyle);
-
- ar->regiondata = data;
-
- /* special case, hardcoded feature, not draw backdrop when called from menus,
- * assume for design that popup already added it */
- if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
- data->noback = true;
- }
-
- if (but->a1 > 0 && but->a2 > 0) {
- data->preview = true;
- data->prv_rows = but->a1;
- data->prv_cols = but->a2;
- }
-
- /* Only show key shortcuts when needed (checking RNA prop pointer is useless here, a lot of buttons are about data
- * without having that pointer defined, let's rather try with optype!). One can also enforce that behavior by
- * setting UI_BUT_HAS_SHORTCUT drawflag of search button. */
- if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
- data->use_sep = true;
- }
-
- /* compute position */
- if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
- const int search_but_h = BLI_rctf_size_y(&but->rect) + 10;
- /* this case is search menu inside other menu */
- /* we copy region size */
-
- ar->winrct = butregion->winrct;
-
- /* widget rect, in region coords */
- data->bbox.xmin = margin;
- data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin;
- data->bbox.ymin = margin;
- data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - margin;
-
- /* check if button is lower half */
- if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) {
- data->bbox.ymin += search_but_h;
- }
- else {
- data->bbox.ymax -= search_but_h;
- }
- }
- else {
- const int searchbox_width = UI_searchbox_size_x();
-
- rect_fl.xmin = but->rect.xmin - 5; /* align text with button */
- rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */
- rect_fl.ymax = but->rect.ymin;
- rect_fl.ymin = rect_fl.ymax - UI_searchbox_size_y();
-
- ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
- ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
-
- BLI_rctf_translate(&rect_fl, ofsx, ofsy);
-
- /* minimal width */
- if (BLI_rctf_size_x(&rect_fl) < searchbox_width) {
- rect_fl.xmax = rect_fl.xmin + searchbox_width;
- }
-
- /* copy to int, gets projected if possible too */
- BLI_rcti_rctf_copy(&rect_i, &rect_fl);
-
- if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
- UI_view2d_view_to_region_rcti(&butregion->v2d, &rect_fl, &rect_i);
- }
-
- BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
-
- winx = WM_window_pixels_x(win);
- // winy = WM_window_pixels_y(win); /* UNUSED */
- //wm_window_get_size(win, &winx, &winy);
-
- if (rect_i.xmax > winx) {
- /* super size */
- if (rect_i.xmax > winx + rect_i.xmin) {
- rect_i.xmax = winx;
- rect_i.xmin = 0;
- }
- else {
- rect_i.xmin -= rect_i.xmax - winx;
- rect_i.xmax = winx;
- }
- }
-
- if (rect_i.ymin < 0) {
- int newy1 = but->rect.ymax + ofsy;
-
- if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
- newy1 = UI_view2d_view_to_region_y(&butregion->v2d, newy1);
- }
-
- newy1 += butregion->winrct.ymin;
-
- rect_i.ymax = BLI_rcti_size_y(&rect_i) + newy1;
- rect_i.ymin = newy1;
- }
-
- /* widget rect, in region coords */
- data->bbox.xmin = margin;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) + margin;
- data->bbox.ymin = margin;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i) + margin;
-
- /* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - margin;
- ar->winrct.xmax = rect_i.xmax + margin;
- ar->winrct.ymin = rect_i.ymin - margin;
- ar->winrct.ymax = rect_i.ymax;
- }
-
- /* adds subwindow */
- ED_region_init(ar);
-
- /* notify change and redraw */
- ED_region_tag_redraw(ar);
-
- /* prepare search data */
- if (data->preview) {
- data->items.maxitem = data->prv_rows * data->prv_cols;
- }
- else {
- data->items.maxitem = SEARCH_ITEMS;
- }
- data->items.maxstrlen = but->hardmax;
- data->items.totitem = 0;
- data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names");
- data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
- data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
- for (i = 0; i < data->items.maxitem; i++) {
- data->items.names[i] = MEM_callocN(but->hardmax + 1, "search pointers");
- }
-
- return ar;
+ wmWindow *win = CTX_wm_window(C);
+ uiStyle *style = UI_style_get();
+ static ARegionType type;
+ ARegion *ar;
+ uiSearchboxData *data;
+ float aspect = but->block->aspect;
+ rctf rect_fl;
+ rcti rect_i;
+ const int margin = UI_POPUP_MARGIN;
+ int winx /*, winy */, ofsx, ofsy;
+ int i;
+
+ /* create area region */
+ ar = ui_region_temp_add(CTX_wm_screen(C));
+
+ memset(&type, 0, sizeof(ARegionType));
+ type.draw = ui_searchbox_region_draw_cb;
+ type.free = ui_searchbox_region_free_cb;
+ type.regionid = RGN_TYPE_TEMPORARY;
+ ar->type = &type;
+
+ /* create searchbox data */
+ data = MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData");
+
+ /* set font, get bb */
+ data->fstyle = style->widget; /* copy struct */
+ ui_fontscale(&data->fstyle.points, aspect);
+ UI_fontstyle_set(&data->fstyle);
+
+ ar->regiondata = data;
+
+ /* special case, hardcoded feature, not draw backdrop when called from menus,
+ * assume for design that popup already added it */
+ if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
+ data->noback = true;
+ }
+
+ if (but->a1 > 0 && but->a2 > 0) {
+ data->preview = true;
+ data->prv_rows = but->a1;
+ data->prv_cols = but->a2;
+ }
+
+ /* Only show key shortcuts when needed (checking RNA prop pointer is useless here, a lot of buttons are about data
+ * without having that pointer defined, let's rather try with optype!). One can also enforce that behavior by
+ * setting UI_BUT_HAS_SHORTCUT drawflag of search button. */
+ if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
+ data->use_sep = true;
+ }
+
+ /* compute position */
+ if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
+ const int search_but_h = BLI_rctf_size_y(&but->rect) + 10;
+ /* this case is search menu inside other menu */
+ /* we copy region size */
+
+ ar->winrct = butregion->winrct;
+
+ /* widget rect, in region coords */
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&ar->winrct) - margin;
+ data->bbox.ymin = margin;
+ data->bbox.ymax = BLI_rcti_size_y(&ar->winrct) - margin;
+
+ /* check if button is lower half */
+ if (but->rect.ymax < BLI_rctf_cent_y(&but->block->rect)) {
+ data->bbox.ymin += search_but_h;
+ }
+ else {
+ data->bbox.ymax -= search_but_h;
+ }
+ }
+ else {
+ const int searchbox_width = UI_searchbox_size_x();
+
+ rect_fl.xmin = but->rect.xmin - 5; /* align text with button */
+ rect_fl.xmax = but->rect.xmax + 5; /* symmetrical */
+ rect_fl.ymax = but->rect.ymin;
+ rect_fl.ymin = rect_fl.ymax - UI_searchbox_size_y();
+
+ ofsx = (but->block->panel) ? but->block->panel->ofsx : 0;
+ ofsy = (but->block->panel) ? but->block->panel->ofsy : 0;
+
+ BLI_rctf_translate(&rect_fl, ofsx, ofsy);
+
+ /* minimal width */
+ if (BLI_rctf_size_x(&rect_fl) < searchbox_width) {
+ rect_fl.xmax = rect_fl.xmin + searchbox_width;
+ }
+
+ /* copy to int, gets projected if possible too */
+ BLI_rcti_rctf_copy(&rect_i, &rect_fl);
+
+ if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
+ UI_view2d_view_to_region_rcti(&butregion->v2d, &rect_fl, &rect_i);
+ }
+
+ BLI_rcti_translate(&rect_i, butregion->winrct.xmin, butregion->winrct.ymin);
+
+ winx = WM_window_pixels_x(win);
+ // winy = WM_window_pixels_y(win); /* UNUSED */
+ //wm_window_get_size(win, &winx, &winy);
+
+ if (rect_i.xmax > winx) {
+ /* super size */
+ if (rect_i.xmax > winx + rect_i.xmin) {
+ rect_i.xmax = winx;
+ rect_i.xmin = 0;
+ }
+ else {
+ rect_i.xmin -= rect_i.xmax - winx;
+ rect_i.xmax = winx;
+ }
+ }
+
+ if (rect_i.ymin < 0) {
+ int newy1 = but->rect.ymax + ofsy;
+
+ if (butregion->v2d.cur.xmin != butregion->v2d.cur.xmax) {
+ newy1 = UI_view2d_view_to_region_y(&butregion->v2d, newy1);
+ }
+
+ newy1 += butregion->winrct.ymin;
+
+ rect_i.ymax = BLI_rcti_size_y(&rect_i) + newy1;
+ rect_i.ymin = newy1;
+ }
+
+ /* widget rect, in region coords */
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) + margin;
+ data->bbox.ymin = margin;
+ data->bbox.ymax = BLI_rcti_size_y(&rect_i) + margin;
+
+ /* region bigger for shadow */
+ ar->winrct.xmin = rect_i.xmin - margin;
+ ar->winrct.xmax = rect_i.xmax + margin;
+ ar->winrct.ymin = rect_i.ymin - margin;
+ ar->winrct.ymax = rect_i.ymax;
+ }
+
+ /* adds subwindow */
+ ED_region_init(ar);
+
+ /* notify change and redraw */
+ ED_region_tag_redraw(ar);
+
+ /* prepare search data */
+ if (data->preview) {
+ data->items.maxitem = data->prv_rows * data->prv_cols;
+ }
+ else {
+ data->items.maxitem = SEARCH_ITEMS;
+ }
+ data->items.maxstrlen = but->hardmax;
+ data->items.totitem = 0;
+ data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names");
+ data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
+ data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
+ for (i = 0; i < data->items.maxitem; i++) {
+ data->items.names[i] = MEM_callocN(but->hardmax + 1, "search pointers");
+ }
+
+ return ar;
}
/**
@@ -669,152 +670,154 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but
*/
static void str_tolower_titlecaps_ascii(char *str, const size_t len)
{
- size_t i;
- bool prev_delim = true;
-
- for (i = 0; (i < len) && str[i]; i++) {
- if (str[i] >= 'A' && str[i] <= 'Z') {
- if (prev_delim == false) {
- str[i] += 'a' - 'A';
- }
- }
- else if (str[i] == '_') {
- str[i] = ' ';
- }
-
- prev_delim = ELEM(str[i], ' ') || (str[i] >= '0' && str[i] <= '9');
- }
-
+ size_t i;
+ bool prev_delim = true;
+
+ for (i = 0; (i < len) && str[i]; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ if (prev_delim == false) {
+ str[i] += 'a' - 'A';
+ }
+ }
+ else if (str[i] == '_') {
+ str[i] = ' ';
+ }
+
+ prev_delim = ELEM(str[i], ' ') || (str[i] >= '0' && str[i] <= '9');
+ }
}
static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARegion *ar)
{
- uiSearchboxData *data = ar->regiondata;
-
- /* pixel space */
- wmOrtho2_region_pixelspace(ar);
-
- if (data->noback == false) {
- ui_draw_widget_menu_back(&data->bbox, true);
- }
-
- /* draw text */
- if (data->items.totitem) {
- rcti rect;
- int a;
-
- /* draw items */
- for (a = 0; a < data->items.totitem; a++) {
- rcti rect_pre, rect_post;
- ui_searchbox_butrect(&rect, data, a);
-
- rect_pre = rect;
- rect_post = rect;
-
- rect_pre.xmax = rect_post.xmin = rect.xmin + ((rect.xmax - rect.xmin) / 4);
-
- /* widget itself */
- /* NOTE: i18n messages extracting tool does the same, please keep it in sync. */
- {
- wmOperatorType *ot = data->items.pointers[a];
-
- int state = (a == data->active) ? UI_ACTIVE : 0;
- char text_pre[128];
- char *text_pre_p = strstr(ot->idname, "_OT_");
- if (text_pre_p == NULL) {
- text_pre[0] = '\0';
- }
- else {
- int text_pre_len;
- text_pre_p += 1;
- text_pre_len = BLI_strncpy_rlen(
- text_pre, ot->idname, min_ii(sizeof(text_pre), text_pre_p - ot->idname));
- text_pre[text_pre_len] = ':';
- text_pre[text_pre_len + 1] = '\0';
- str_tolower_titlecaps_ascii(text_pre, sizeof(text_pre));
- }
-
- rect_pre.xmax += 4; /* sneaky, avoid showing ugly margin */
- ui_draw_menu_item(
- &data->fstyle, &rect_pre, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, text_pre),
- data->items.icons[a], state, false);
- ui_draw_menu_item(&data->fstyle, &rect_post, data->items.names[a], 0, state, data->use_sep);
- }
-
- }
- /* indicate more */
- if (data->items.more) {
- ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
- GPU_blend(false);
- }
- if (data->items.offset) {
- ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
- UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
- GPU_blend(false);
- }
- }
+ uiSearchboxData *data = ar->regiondata;
+
+ /* pixel space */
+ wmOrtho2_region_pixelspace(ar);
+
+ if (data->noback == false) {
+ ui_draw_widget_menu_back(&data->bbox, true);
+ }
+
+ /* draw text */
+ if (data->items.totitem) {
+ rcti rect;
+ int a;
+
+ /* draw items */
+ for (a = 0; a < data->items.totitem; a++) {
+ rcti rect_pre, rect_post;
+ ui_searchbox_butrect(&rect, data, a);
+
+ rect_pre = rect;
+ rect_post = rect;
+
+ rect_pre.xmax = rect_post.xmin = rect.xmin + ((rect.xmax - rect.xmin) / 4);
+
+ /* widget itself */
+ /* NOTE: i18n messages extracting tool does the same, please keep it in sync. */
+ {
+ wmOperatorType *ot = data->items.pointers[a];
+
+ int state = (a == data->active) ? UI_ACTIVE : 0;
+ char text_pre[128];
+ char *text_pre_p = strstr(ot->idname, "_OT_");
+ if (text_pre_p == NULL) {
+ text_pre[0] = '\0';
+ }
+ else {
+ int text_pre_len;
+ text_pre_p += 1;
+ text_pre_len = BLI_strncpy_rlen(
+ text_pre, ot->idname, min_ii(sizeof(text_pre), text_pre_p - ot->idname));
+ text_pre[text_pre_len] = ':';
+ text_pre[text_pre_len + 1] = '\0';
+ str_tolower_titlecaps_ascii(text_pre, sizeof(text_pre));
+ }
+
+ rect_pre.xmax += 4; /* sneaky, avoid showing ugly margin */
+ ui_draw_menu_item(&data->fstyle,
+ &rect_pre,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, text_pre),
+ data->items.icons[a],
+ state,
+ false);
+ ui_draw_menu_item(
+ &data->fstyle, &rect_post, data->items.names[a], 0, state, data->use_sep);
+ }
+ }
+ /* indicate more */
+ if (data->items.more) {
+ ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
+ GPU_blend(false);
+ }
+ if (data->items.offset) {
+ ui_searchbox_butrect(&rect, data, 0);
+ GPU_blend(true);
+ UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
+ GPU_blend(false);
+ }
+ }
}
ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiBut *but)
{
- ARegion *ar;
+ ARegion *ar;
- UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
- ar = ui_searchbox_create_generic(C, butregion, but);
+ UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
+ ar = ui_searchbox_create_generic(C, butregion, but);
- ar->type->draw = ui_searchbox_region_draw_cb__operator;
+ ar->type->draw = ui_searchbox_region_draw_cb__operator;
- return ar;
+ return ar;
}
void ui_searchbox_free(bContext *C, ARegion *ar)
{
- ui_region_temp_remove(C, CTX_wm_screen(C), ar);
+ ui_region_temp_remove(C, CTX_wm_screen(C), ar);
}
/* sets red alert if button holds a string it can't find */
/* XXX weak: search_func adds all partial matches... */
void ui_but_search_refresh(uiBut *but)
{
- uiSearchItems *items;
- int x1;
-
- /* possibly very large lists (such as ID datablocks) only
- * only validate string RNA buts (not pointers) */
- if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) {
- return;
- }
-
- items = MEM_callocN(sizeof(uiSearchItems), "search items");
-
- /* setup search struct */
- items->maxitem = 10;
- items->maxstrlen = 256;
- items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names");
- for (x1 = 0; x1 < items->maxitem; x1++) {
- items->names[x1] = MEM_callocN(but->hardmax + 1, "search names");
- }
-
- but->search_func(but->block->evil_C, but->search_arg, but->drawstr, items);
-
- /* only redalert when we are sure of it, this can miss cases when >10 matches */
- if (items->totitem == 0) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
- else if (items->more == 0) {
- if (UI_search_items_find_index(items, but->drawstr) == -1) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
- }
-
- for (x1 = 0; x1 < items->maxitem; x1++) {
- MEM_freeN(items->names[x1]);
- }
- MEM_freeN(items->names);
- MEM_freeN(items);
+ uiSearchItems *items;
+ int x1;
+
+ /* possibly very large lists (such as ID datablocks) only
+ * only validate string RNA buts (not pointers) */
+ if (but->rnaprop && RNA_property_type(but->rnaprop) != PROP_STRING) {
+ return;
+ }
+
+ items = MEM_callocN(sizeof(uiSearchItems), "search items");
+
+ /* setup search struct */
+ items->maxitem = 10;
+ items->maxstrlen = 256;
+ items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names");
+ for (x1 = 0; x1 < items->maxitem; x1++) {
+ items->names[x1] = MEM_callocN(but->hardmax + 1, "search names");
+ }
+
+ but->search_func(but->block->evil_C, but->search_arg, but->drawstr, items);
+
+ /* only redalert when we are sure of it, this can miss cases when >10 matches */
+ if (items->totitem == 0) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+ else if (items->more == 0) {
+ if (UI_search_items_find_index(items, but->drawstr) == -1) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+ }
+
+ for (x1 = 0; x1 < items->maxitem; x1++) {
+ MEM_freeN(items->names[x1]);
+ }
+ MEM_freeN(items->names);
+ MEM_freeN(items);
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 4bde694b5da..c8029a2b21a 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -55,7 +55,6 @@
#include "RNA_access.h"
-
#include "UI_interface.h"
#include "BLF_api.h"
@@ -70,46 +69,45 @@
#include "interface_intern.h"
#include "interface_regions_intern.h"
-#define UI_TIP_PAD_FAC 1.3f
-#define UI_TIP_PADDING (int)(UI_TIP_PAD_FAC * UI_UNIT_Y)
-#define UI_TIP_MAXWIDTH 600
-
+#define UI_TIP_PAD_FAC 1.3f
+#define UI_TIP_PADDING (int)(UI_TIP_PAD_FAC * UI_UNIT_Y)
+#define UI_TIP_MAXWIDTH 600
typedef struct uiTooltipFormat {
- enum {
- UI_TIP_STYLE_NORMAL = 0,
- UI_TIP_STYLE_HEADER,
- UI_TIP_STYLE_MONO,
- } style : 3;
- enum {
- UI_TIP_LC_MAIN = 0, /* primary text */
- UI_TIP_LC_VALUE, /* the value of buttons (also shortcuts) */
- UI_TIP_LC_ACTIVE, /* titles of active enum values */
- UI_TIP_LC_NORMAL, /* regular text */
- UI_TIP_LC_PYTHON, /* Python snippet */
- UI_TIP_LC_ALERT, /* description of why operator can't run */
- } color_id : 4;
- int is_pad : 1;
+ enum {
+ UI_TIP_STYLE_NORMAL = 0,
+ UI_TIP_STYLE_HEADER,
+ UI_TIP_STYLE_MONO,
+ } style : 3;
+ enum {
+ UI_TIP_LC_MAIN = 0, /* primary text */
+ UI_TIP_LC_VALUE, /* the value of buttons (also shortcuts) */
+ UI_TIP_LC_ACTIVE, /* titles of active enum values */
+ UI_TIP_LC_NORMAL, /* regular text */
+ UI_TIP_LC_PYTHON, /* Python snippet */
+ UI_TIP_LC_ALERT, /* description of why operator can't run */
+ } color_id : 4;
+ int is_pad : 1;
} uiTooltipFormat;
typedef struct uiTooltipField {
- char *text;
- char *text_suffix;
- struct {
- uint x_pos; /* x cursor position at the end of the last line */
- uint lines; /* number of lines, 1 or more with word-wrap */
- } geom;
- uiTooltipFormat format;
+ char *text;
+ char *text_suffix;
+ struct {
+ uint x_pos; /* x cursor position at the end of the last line */
+ uint lines; /* number of lines, 1 or more with word-wrap */
+ } geom;
+ uiTooltipFormat format;
} uiTooltipField;
typedef struct uiTooltipData {
- rcti bbox;
- uiTooltipField *fields;
- uint fields_len;
- uiFontStyle fstyle;
- int wrap_width;
- int toth, lineh;
+ rcti bbox;
+ uiTooltipField *fields;
+ uint fields_len;
+ uiFontStyle fstyle;
+ int wrap_width;
+ int toth, lineh;
} uiTooltipData;
#define UI_TIP_LC_MAX 6
@@ -117,183 +115,177 @@ typedef struct uiTooltipData {
BLI_STATIC_ASSERT(UI_TIP_LC_MAX == UI_TIP_LC_ALERT + 1, "invalid lc-max");
BLI_STATIC_ASSERT(sizeof(uiTooltipFormat) <= sizeof(int), "oversize");
-static uiTooltipField *text_field_add_only(
- uiTooltipData *data)
+static uiTooltipField *text_field_add_only(uiTooltipData *data)
{
- data->fields_len += 1;
- data->fields = MEM_recallocN(data->fields, sizeof(*data->fields) * data->fields_len);
- return &data->fields[data->fields_len - 1];
+ data->fields_len += 1;
+ data->fields = MEM_recallocN(data->fields, sizeof(*data->fields) * data->fields_len);
+ return &data->fields[data->fields_len - 1];
}
-static uiTooltipField *text_field_add(
- uiTooltipData *data,
- const uiTooltipFormat *format)
+static uiTooltipField *text_field_add(uiTooltipData *data, const uiTooltipFormat *format)
{
- uiTooltipField *field = text_field_add_only(data);
- field->format = *format;
- return field;
+ uiTooltipField *field = text_field_add_only(data);
+ field->format = *format;
+ return field;
}
/* -------------------------------------------------------------------- */
/** \name ToolTip Callbacks (Draw & Free)
* \{ */
-static void rgb_tint(
- float col[3],
- float h, float h_strength,
- float v, float v_strength)
+static void rgb_tint(float col[3], float h, float h_strength, float v, float v_strength)
{
- float col_hsv_from[3];
- float col_hsv_to[3];
+ float col_hsv_from[3];
+ float col_hsv_to[3];
- rgb_to_hsv_v(col, col_hsv_from);
+ rgb_to_hsv_v(col, col_hsv_from);
- col_hsv_to[0] = h;
- col_hsv_to[1] = h_strength;
- col_hsv_to[2] = (col_hsv_from[2] * (1.0f - v_strength)) + (v * v_strength);
+ col_hsv_to[0] = h;
+ col_hsv_to[1] = h_strength;
+ col_hsv_to[2] = (col_hsv_from[2] * (1.0f - v_strength)) + (v * v_strength);
- hsv_to_rgb_v(col_hsv_to, col);
+ hsv_to_rgb_v(col_hsv_to, col);
}
static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *ar)
{
- const float pad_px = UI_TIP_PADDING;
- uiTooltipData *data = ar->regiondata;
- const uiWidgetColors *theme = ui_tooltip_get_theme();
- rcti bbox = data->bbox;
- float tip_colors[UI_TIP_LC_MAX][3];
- uchar drawcol[4] = {0, 0, 0, 255}; /* to store color in while drawing (alpha is always 255) */
-
- float *main_color = tip_colors[UI_TIP_LC_MAIN]; /* the color from the theme */
- float *value_color = tip_colors[UI_TIP_LC_VALUE];
- float *active_color = tip_colors[UI_TIP_LC_ACTIVE];
- float *normal_color = tip_colors[UI_TIP_LC_NORMAL];
- float *python_color = tip_colors[UI_TIP_LC_PYTHON];
- float *alert_color = tip_colors[UI_TIP_LC_ALERT];
-
- float background_color[3];
- float tone_bg;
- int i;
-
- wmOrtho2_region_pixelspace(ar);
-
- /* draw background */
- ui_draw_tooltip_background(UI_style_get(), NULL, &bbox);
-
- /* set background_color */
- rgb_uchar_to_float(background_color, (const uchar *)theme->inner);
-
- /* calculate normal_color */
- rgb_uchar_to_float(main_color, (const uchar *)theme->text);
- copy_v3_v3(active_color, main_color);
- copy_v3_v3(normal_color, main_color);
- copy_v3_v3(python_color, main_color);
- copy_v3_v3(alert_color, main_color);
- copy_v3_v3(value_color, main_color);
-
- /* find the brightness difference between background and text colors */
-
- tone_bg = rgb_to_grayscale(background_color);
- /* tone_fg = rgb_to_grayscale(main_color); */
-
- /* mix the colors */
- rgb_tint(value_color, 0.0f, 0.0f, tone_bg, 0.2f); /* light gray */
- rgb_tint(active_color, 0.6f, 0.2f, tone_bg, 0.2f); /* light blue */
- rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.4f); /* gray */
- rgb_tint(python_color, 0.0f, 0.0f, tone_bg, 0.5f); /* dark gray */
- rgb_tint(alert_color, 0.0f, 0.8f, tone_bg, 0.1f); /* red */
-
- /* draw text */
- BLF_wordwrap(data->fstyle.uifont_id, data->wrap_width);
- BLF_wordwrap(blf_mono_font, data->wrap_width);
-
- bbox.xmin += 0.5f * pad_px; /* add padding to the text */
- bbox.ymax -= 0.25f * pad_px;
-
- for (i = 0; i < data->fields_len; i++) {
- const uiTooltipField *field = &data->fields[i];
- const uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL;
-
- bbox.ymin = bbox.ymax - (data->lineh * field->geom.lines);
- if (field->format.style == UI_TIP_STYLE_HEADER) {
- const struct uiFontStyleDraw_Params fs_params = {
- .align = UI_STYLE_TEXT_LEFT,
- .word_wrap = true,
- };
- /* draw header and active data (is done here to be able to change color) */
- rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_MAIN]);
- UI_fontstyle_set(&data->fstyle);
- UI_fontstyle_draw(&data->fstyle, &bbox, field->text, drawcol, &fs_params);
-
- /* offset to the end of the last line */
- if (field->text_suffix) {
- float xofs = field->geom.x_pos;
- float yofs = data->lineh * (field->geom.lines - 1);
- bbox.xmin += xofs;
- bbox.ymax -= yofs;
-
- rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_ACTIVE]);
- UI_fontstyle_draw(&data->fstyle, &bbox, field->text_suffix, drawcol, &fs_params);
-
- /* undo offset */
- bbox.xmin -= xofs;
- bbox.ymax += yofs;
- }
- }
- else if (field->format.style == UI_TIP_STYLE_MONO) {
- const struct uiFontStyleDraw_Params fs_params = {
- .align = UI_STYLE_TEXT_LEFT,
- .word_wrap = true,
- };
- uiFontStyle fstyle_mono = data->fstyle;
- fstyle_mono.uifont_id = blf_mono_font;
-
- UI_fontstyle_set(&fstyle_mono);
- /* XXX, needed because we dont have mono in 'U.uifonts' */
- BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi);
- rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]);
- UI_fontstyle_draw(&fstyle_mono, &bbox, field->text, drawcol, &fs_params);
- }
- else {
- BLI_assert(field->format.style == UI_TIP_STYLE_NORMAL);
- const struct uiFontStyleDraw_Params fs_params = {
- .align = UI_STYLE_TEXT_LEFT,
- .word_wrap = true,
- };
-
- /* draw remaining data */
- rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]);
- UI_fontstyle_set(&data->fstyle);
- UI_fontstyle_draw(&data->fstyle, &bbox, field->text, drawcol, &fs_params);
- }
-
- bbox.ymax -= data->lineh * field->geom.lines;
-
- if (field_next && field_next->format.is_pad) {
- bbox.ymax -= data->lineh * (UI_TIP_PAD_FAC - 1);
- }
- }
-
- BLF_disable(data->fstyle.uifont_id, BLF_WORD_WRAP);
- BLF_disable(blf_mono_font, BLF_WORD_WRAP);
+ const float pad_px = UI_TIP_PADDING;
+ uiTooltipData *data = ar->regiondata;
+ const uiWidgetColors *theme = ui_tooltip_get_theme();
+ rcti bbox = data->bbox;
+ float tip_colors[UI_TIP_LC_MAX][3];
+ uchar drawcol[4] = {0, 0, 0, 255}; /* to store color in while drawing (alpha is always 255) */
+
+ float *main_color = tip_colors[UI_TIP_LC_MAIN]; /* the color from the theme */
+ float *value_color = tip_colors[UI_TIP_LC_VALUE];
+ float *active_color = tip_colors[UI_TIP_LC_ACTIVE];
+ float *normal_color = tip_colors[UI_TIP_LC_NORMAL];
+ float *python_color = tip_colors[UI_TIP_LC_PYTHON];
+ float *alert_color = tip_colors[UI_TIP_LC_ALERT];
+
+ float background_color[3];
+ float tone_bg;
+ int i;
+
+ wmOrtho2_region_pixelspace(ar);
+
+ /* draw background */
+ ui_draw_tooltip_background(UI_style_get(), NULL, &bbox);
+
+ /* set background_color */
+ rgb_uchar_to_float(background_color, (const uchar *)theme->inner);
+
+ /* calculate normal_color */
+ rgb_uchar_to_float(main_color, (const uchar *)theme->text);
+ copy_v3_v3(active_color, main_color);
+ copy_v3_v3(normal_color, main_color);
+ copy_v3_v3(python_color, main_color);
+ copy_v3_v3(alert_color, main_color);
+ copy_v3_v3(value_color, main_color);
+
+ /* find the brightness difference between background and text colors */
+
+ tone_bg = rgb_to_grayscale(background_color);
+ /* tone_fg = rgb_to_grayscale(main_color); */
+
+ /* mix the colors */
+ rgb_tint(value_color, 0.0f, 0.0f, tone_bg, 0.2f); /* light gray */
+ rgb_tint(active_color, 0.6f, 0.2f, tone_bg, 0.2f); /* light blue */
+ rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.4f); /* gray */
+ rgb_tint(python_color, 0.0f, 0.0f, tone_bg, 0.5f); /* dark gray */
+ rgb_tint(alert_color, 0.0f, 0.8f, tone_bg, 0.1f); /* red */
+
+ /* draw text */
+ BLF_wordwrap(data->fstyle.uifont_id, data->wrap_width);
+ BLF_wordwrap(blf_mono_font, data->wrap_width);
+
+ bbox.xmin += 0.5f * pad_px; /* add padding to the text */
+ bbox.ymax -= 0.25f * pad_px;
+
+ for (i = 0; i < data->fields_len; i++) {
+ const uiTooltipField *field = &data->fields[i];
+ const uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL;
+
+ bbox.ymin = bbox.ymax - (data->lineh * field->geom.lines);
+ if (field->format.style == UI_TIP_STYLE_HEADER) {
+ const struct uiFontStyleDraw_Params fs_params = {
+ .align = UI_STYLE_TEXT_LEFT,
+ .word_wrap = true,
+ };
+ /* draw header and active data (is done here to be able to change color) */
+ rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_MAIN]);
+ UI_fontstyle_set(&data->fstyle);
+ UI_fontstyle_draw(&data->fstyle, &bbox, field->text, drawcol, &fs_params);
+
+ /* offset to the end of the last line */
+ if (field->text_suffix) {
+ float xofs = field->geom.x_pos;
+ float yofs = data->lineh * (field->geom.lines - 1);
+ bbox.xmin += xofs;
+ bbox.ymax -= yofs;
+
+ rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_ACTIVE]);
+ UI_fontstyle_draw(&data->fstyle, &bbox, field->text_suffix, drawcol, &fs_params);
+
+ /* undo offset */
+ bbox.xmin -= xofs;
+ bbox.ymax += yofs;
+ }
+ }
+ else if (field->format.style == UI_TIP_STYLE_MONO) {
+ const struct uiFontStyleDraw_Params fs_params = {
+ .align = UI_STYLE_TEXT_LEFT,
+ .word_wrap = true,
+ };
+ uiFontStyle fstyle_mono = data->fstyle;
+ fstyle_mono.uifont_id = blf_mono_font;
+
+ UI_fontstyle_set(&fstyle_mono);
+ /* XXX, needed because we dont have mono in 'U.uifonts' */
+ BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi);
+ rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]);
+ UI_fontstyle_draw(&fstyle_mono, &bbox, field->text, drawcol, &fs_params);
+ }
+ else {
+ BLI_assert(field->format.style == UI_TIP_STYLE_NORMAL);
+ const struct uiFontStyleDraw_Params fs_params = {
+ .align = UI_STYLE_TEXT_LEFT,
+ .word_wrap = true,
+ };
+
+ /* draw remaining data */
+ rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]);
+ UI_fontstyle_set(&data->fstyle);
+ UI_fontstyle_draw(&data->fstyle, &bbox, field->text, drawcol, &fs_params);
+ }
+
+ bbox.ymax -= data->lineh * field->geom.lines;
+
+ if (field_next && field_next->format.is_pad) {
+ bbox.ymax -= data->lineh * (UI_TIP_PAD_FAC - 1);
+ }
+ }
+
+ BLF_disable(data->fstyle.uifont_id, BLF_WORD_WRAP);
+ BLF_disable(blf_mono_font, BLF_WORD_WRAP);
}
static void ui_tooltip_region_free_cb(ARegion *ar)
{
- uiTooltipData *data;
-
- data = ar->regiondata;
-
- for (int i = 0; i < data->fields_len; i++) {
- const uiTooltipField *field = &data->fields[i];
- MEM_freeN(field->text);
- if (field->text_suffix) {
- MEM_freeN(field->text_suffix);
- }
- }
- MEM_freeN(data->fields);
- MEM_freeN(data);
- ar->regiondata = NULL;
+ uiTooltipData *data;
+
+ data = ar->regiondata;
+
+ for (int i = 0; i < data->fields_len; i++) {
+ const uiTooltipField *field = &data->fields[i];
+ MEM_freeN(field->text);
+ if (field->text_suffix) {
+ MEM_freeN(field->text_suffix);
+ }
+ }
+ MEM_freeN(data->fields);
+ MEM_freeN(data);
+ ar->regiondata = NULL;
}
/** \} */
@@ -302,929 +294,938 @@ static void ui_tooltip_region_free_cb(ARegion *ar)
/** \name ToolTip Creation
* \{ */
-static bool ui_tooltip_data_append_from_keymap(
- bContext *C, uiTooltipData *data,
- wmKeyMap *keymap)
+static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data, wmKeyMap *keymap)
{
- const int fields_len_init = data->fields_len;
- char buf[512];
-
- for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
- wmOperatorType *ot = WM_operatortype_find(kmi->idname, true);
- if (ot != NULL) {
- /* Tip */
- {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_MAIN,
- .is_pad = true,
- });
- field->text = BLI_strdup(ot->description ? ot->description : ot->name);
- }
- /* Shortcut */
- {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_NORMAL,
- });
- bool found = false;
- if (WM_keymap_item_to_string(kmi, false, buf, sizeof(buf))) {
- found = true;
- }
- field->text = BLI_sprintfN(TIP_("Shortcut: %s"), found ? buf : "None");
- }
-
- /* Python */
- if (U.flag & USER_TOOLTIPS_PYTHON) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_PYTHON,
- });
- char *str = WM_operator_pystring_ex(C, NULL, false, false, ot, kmi->ptr);
- WM_operator_pystring_abbreviate(str, 32);
- field->text = BLI_sprintfN(TIP_("Python: %s"), str);
- MEM_freeN(str);
- }
- }
- }
-
- return (fields_len_init != data->fields_len);
+ const int fields_len_init = data->fields_len;
+ char buf[512];
+
+ for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ wmOperatorType *ot = WM_operatortype_find(kmi->idname, true);
+ if (ot != NULL) {
+ /* Tip */
+ {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_MAIN,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(ot->description ? ot->description : ot->name);
+ }
+ /* Shortcut */
+ {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ bool found = false;
+ if (WM_keymap_item_to_string(kmi, false, buf, sizeof(buf))) {
+ found = true;
+ }
+ field->text = BLI_sprintfN(TIP_("Shortcut: %s"), found ? buf : "None");
+ }
+
+ /* Python */
+ if (U.flag & USER_TOOLTIPS_PYTHON) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_PYTHON,
+ });
+ char *str = WM_operator_pystring_ex(C, NULL, false, false, ot, kmi->ptr);
+ WM_operator_pystring_abbreviate(str, 32);
+ field->text = BLI_sprintfN(TIP_("Python: %s"), str);
+ MEM_freeN(str);
+ }
+ }
+ }
+
+ return (fields_len_init != data->fields_len);
}
-
/**
* Special tool-system exception.
*/
static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is_label)
{
- if (but->optype == NULL) {
- return NULL;
- }
+ if (but->optype == NULL) {
+ return NULL;
+ }
- if (!STREQ(but->optype->idname, "WM_OT_tool_set_by_id")) {
- return NULL;
- }
+ if (!STREQ(but->optype->idname, "WM_OT_tool_set_by_id")) {
+ return NULL;
+ }
- /* Needed to get the space-data's type (below). */
- if (CTX_wm_space_data(C) == NULL) {
- return NULL;
- }
+ /* Needed to get the space-data's type (below). */
+ if (CTX_wm_space_data(C) == NULL) {
+ return NULL;
+ }
- char tool_id[MAX_NAME];
- RNA_string_get(but->opptr, "name", tool_id);
- BLI_assert(tool_id[0] != '\0');
+ char tool_id[MAX_NAME];
+ RNA_string_get(but->opptr, "name", tool_id);
+ BLI_assert(tool_id[0] != '\0');
- /* We have a tool, now extract the info. */
- uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
+ /* We have a tool, now extract the info. */
+ uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
#ifdef WITH_PYTHON
- /* it turns out to be most simple to do this via Python since C
- * doesn't have access to information about non-active tools.
- */
-
- /* Title (when icon-only). */
- if (but->drawstr[0] == '\0') {
- const char *expr_imports[] = {"bpy", "bl_ui", NULL};
- char expr[256];
- SNPRINTF(
- expr,
- "bl_ui.space_toolsystem_common.item_from_id("
- "bpy.context, "
- "bpy.context.space_data.type, "
- "'%s').label",
- tool_id);
- char *expr_result = NULL;
- bool is_error = false;
- if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
- if (STREQ(expr_result, "")) {
- MEM_freeN(expr_result);
- expr_result = NULL;
- }
- }
- else {
- /* Note, this is an exceptional case, we could even remove it
- * however there have been reports of tooltips failing, so keep it for now. */
- expr_result = BLI_strdup("Internal error!");
- is_error = true;
- }
-
- if (expr_result != NULL) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_MAIN,
- .is_pad = true,
- });
- field->text = expr_result;
-
- if (UNLIKELY(is_error)) {
- field->format.color_id = UI_TIP_LC_ALERT;
- }
- }
- }
-
- /* Tip. */
- if (is_label == false) {
- const char *expr_imports[] = {"bpy", "bl_ui", NULL};
- char expr[256];
- SNPRINTF(
- expr,
- "bl_ui.space_toolsystem_common.description_from_id("
- "bpy.context, "
- "bpy.context.space_data.type, "
- "'%s') + '.'",
- tool_id);
-
- char *expr_result = NULL;
- bool is_error = false;
- if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
- if (STREQ(expr_result, ".")) {
- MEM_freeN(expr_result);
- expr_result = NULL;
- }
- }
- else {
- /* Note, this is an exceptional case, we could even remove it
- * however there have been reports of tooltips failing, so keep it for now. */
- expr_result = BLI_strdup("Internal error!");
- is_error = true;
- }
-
- if (expr_result != NULL) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_MAIN,
- .is_pad = true,
- });
- field->text = expr_result;
-
- if (UNLIKELY(is_error)) {
- field->format.color_id = UI_TIP_LC_ALERT;
- }
- }
- }
-
- /* Shortcut. */
- if (is_label == false && ((but->block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) == 0)) {
- /* There are different kinds of shortcuts:
- *
- * - Direct access to the tool (as if the toolbar button is pressed).
- * - The key is bound to a brush type (not the exact brush name).
- * - The key is assigned to the operator it's self (bypassing the tool, executing the operator).
- *
- * Either way case it's useful to show the shortcut.
- */
- char *shortcut = NULL;
-
- {
- uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL};
- UI_but_string_info_get(C, but, &op_keymap, NULL);
- shortcut = op_keymap.strinfo;
- }
-
- if (shortcut == NULL) {
- ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C);
- const char *tool_attr = BKE_paint_get_tool_prop_id_from_paintmode(paint_mode);
- if (tool_attr != NULL) {
- const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
- const int i = RNA_enum_from_name(items, tool_id);
- if (i != -1) {
- wmOperatorType *ot = WM_operatortype_find("paint.brush_select", true);
- PointerRNA op_props;
- WM_operator_properties_create_ptr(&op_props, ot);
- RNA_enum_set(&op_props, tool_attr, items[i].value);
-
- /* Check for direct access to the tool. */
- char shortcut_brush[128] = "";
- if (WM_key_event_operator_string(
- C, ot->idname, WM_OP_INVOKE_REGION_WIN, op_props.data, true,
- shortcut_brush, ARRAY_SIZE(shortcut_brush)))
- {
- shortcut = BLI_strdup(shortcut_brush);
- }
- WM_operator_properties_free(&op_props);
- }
- }
- }
-
- if (shortcut == NULL) {
- /* Check for direct access to the tool. */
- char shortcut_toolbar[128] = "";
- if (WM_key_event_operator_string(
- C, "WM_OT_toolbar", WM_OP_INVOKE_REGION_WIN, NULL, true,
- shortcut_toolbar, ARRAY_SIZE(shortcut_toolbar)))
- {
- /* Generate keymap in order to inspect it.
- * Note, we could make a utility to avoid the keymap generation part of this. */
- const char *expr_imports[] = {"bpy", "bl_keymap_utils", "bl_keymap_utils.keymap_from_toolbar", NULL};
- const char *expr = (
- "getattr("
- "bl_keymap_utils.keymap_from_toolbar.generate("
- "bpy.context, "
- "bpy.context.space_data.type), "
- "'as_pointer', lambda: 0)()");
-
- intptr_t expr_result = 0;
- if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
- if (expr_result != 0) {
- wmKeyMap *keymap = (wmKeyMap *)expr_result;
- for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
- if (STREQ(kmi->idname, but->optype->idname)) {
- char tool_id_test[MAX_NAME];
- RNA_string_get(kmi->ptr, "name", tool_id_test);
- if (STREQ(tool_id, tool_id_test)) {
- char buf[128];
- WM_keymap_item_to_string(kmi, false, buf, sizeof(buf));
- shortcut = BLI_sprintfN("%s, %s", shortcut_toolbar, buf);
- break;
- }
- }
- }
- }
- }
- else {
- BLI_assert(0);
- }
- }
- }
-
- if (shortcut != NULL) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = BLI_sprintfN(TIP_("Shortcut: %s"), shortcut);
- MEM_freeN(shortcut);
- }
- }
-
- /* Keymap */
-
- /* This is too handy not to expose somehow, let's be sneaky for now. */
- if ((is_label == false) && CTX_wm_window(C)->eventstate->shift) {
- const char *expr_imports[] = {"bpy", "bl_ui", NULL};
- char expr[256];
- SNPRINTF(
- expr,
- "getattr("
- "bl_ui.space_toolsystem_common.keymap_from_id("
- "bpy.context, "
- "bpy.context.space_data.type, "
- "'%s'), "
- "'as_pointer', lambda: 0)()",
- tool_id);
-
- intptr_t expr_result = 0;
- if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
- if (expr_result != 0) {
- {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_NORMAL,
- .is_pad = true,
- });
- field->text = BLI_strdup("Tool Keymap:");
- }
- wmKeyMap *keymap = (wmKeyMap *)expr_result;
- ui_tooltip_data_append_from_keymap(C, data, keymap);
- }
- }
- else {
- BLI_assert(0);
- }
- }
-#endif /* WITH_PYTHON */
-
- if (data->fields_len == 0) {
- MEM_freeN(data);
- return NULL;
- }
- else {
- return data;
- }
+ /* it turns out to be most simple to do this via Python since C
+ * doesn't have access to information about non-active tools.
+ */
+
+ /* Title (when icon-only). */
+ if (but->drawstr[0] == '\0') {
+ const char *expr_imports[] = {"bpy", "bl_ui", NULL};
+ char expr[256];
+ SNPRINTF(expr,
+ "bl_ui.space_toolsystem_common.item_from_id("
+ "bpy.context, "
+ "bpy.context.space_data.type, "
+ "'%s').label",
+ tool_id);
+ char *expr_result = NULL;
+ bool is_error = false;
+ if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ if (STREQ(expr_result, "")) {
+ MEM_freeN(expr_result);
+ expr_result = NULL;
+ }
+ }
+ else {
+ /* Note, this is an exceptional case, we could even remove it
+ * however there have been reports of tooltips failing, so keep it for now. */
+ expr_result = BLI_strdup("Internal error!");
+ is_error = true;
+ }
+
+ if (expr_result != NULL) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_MAIN,
+ .is_pad = true,
+ });
+ field->text = expr_result;
+
+ if (UNLIKELY(is_error)) {
+ field->format.color_id = UI_TIP_LC_ALERT;
+ }
+ }
+ }
+
+ /* Tip. */
+ if (is_label == false) {
+ const char *expr_imports[] = {"bpy", "bl_ui", NULL};
+ char expr[256];
+ SNPRINTF(expr,
+ "bl_ui.space_toolsystem_common.description_from_id("
+ "bpy.context, "
+ "bpy.context.space_data.type, "
+ "'%s') + '.'",
+ tool_id);
+
+ char *expr_result = NULL;
+ bool is_error = false;
+ if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ if (STREQ(expr_result, ".")) {
+ MEM_freeN(expr_result);
+ expr_result = NULL;
+ }
+ }
+ else {
+ /* Note, this is an exceptional case, we could even remove it
+ * however there have been reports of tooltips failing, so keep it for now. */
+ expr_result = BLI_strdup("Internal error!");
+ is_error = true;
+ }
+
+ if (expr_result != NULL) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_MAIN,
+ .is_pad = true,
+ });
+ field->text = expr_result;
+
+ if (UNLIKELY(is_error)) {
+ field->format.color_id = UI_TIP_LC_ALERT;
+ }
+ }
+ }
+
+ /* Shortcut. */
+ if (is_label == false && ((but->block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) == 0)) {
+ /* There are different kinds of shortcuts:
+ *
+ * - Direct access to the tool (as if the toolbar button is pressed).
+ * - The key is bound to a brush type (not the exact brush name).
+ * - The key is assigned to the operator it's self (bypassing the tool, executing the operator).
+ *
+ * Either way case it's useful to show the shortcut.
+ */
+ char *shortcut = NULL;
+
+ {
+ uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL};
+ UI_but_string_info_get(C, but, &op_keymap, NULL);
+ shortcut = op_keymap.strinfo;
+ }
+
+ if (shortcut == NULL) {
+ ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C);
+ const char *tool_attr = BKE_paint_get_tool_prop_id_from_paintmode(paint_mode);
+ if (tool_attr != NULL) {
+ const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode);
+ const int i = RNA_enum_from_name(items, tool_id);
+ if (i != -1) {
+ wmOperatorType *ot = WM_operatortype_find("paint.brush_select", true);
+ PointerRNA op_props;
+ WM_operator_properties_create_ptr(&op_props, ot);
+ RNA_enum_set(&op_props, tool_attr, items[i].value);
+
+ /* Check for direct access to the tool. */
+ char shortcut_brush[128] = "";
+ if (WM_key_event_operator_string(C,
+ ot->idname,
+ WM_OP_INVOKE_REGION_WIN,
+ op_props.data,
+ true,
+ shortcut_brush,
+ ARRAY_SIZE(shortcut_brush))) {
+ shortcut = BLI_strdup(shortcut_brush);
+ }
+ WM_operator_properties_free(&op_props);
+ }
+ }
+ }
+
+ if (shortcut == NULL) {
+ /* Check for direct access to the tool. */
+ char shortcut_toolbar[128] = "";
+ if (WM_key_event_operator_string(C,
+ "WM_OT_toolbar",
+ WM_OP_INVOKE_REGION_WIN,
+ NULL,
+ true,
+ shortcut_toolbar,
+ ARRAY_SIZE(shortcut_toolbar))) {
+ /* Generate keymap in order to inspect it.
+ * Note, we could make a utility to avoid the keymap generation part of this. */
+ const char *expr_imports[] = {
+ "bpy", "bl_keymap_utils", "bl_keymap_utils.keymap_from_toolbar", NULL};
+ const char *expr =
+ ("getattr("
+ "bl_keymap_utils.keymap_from_toolbar.generate("
+ "bpy.context, "
+ "bpy.context.space_data.type), "
+ "'as_pointer', lambda: 0)()");
+
+ intptr_t expr_result = 0;
+ if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
+ if (expr_result != 0) {
+ wmKeyMap *keymap = (wmKeyMap *)expr_result;
+ for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ if (STREQ(kmi->idname, but->optype->idname)) {
+ char tool_id_test[MAX_NAME];
+ RNA_string_get(kmi->ptr, "name", tool_id_test);
+ if (STREQ(tool_id, tool_id_test)) {
+ char buf[128];
+ WM_keymap_item_to_string(kmi, false, buf, sizeof(buf));
+ shortcut = BLI_sprintfN("%s, %s", shortcut_toolbar, buf);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+ }
+
+ if (shortcut != NULL) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Shortcut: %s"), shortcut);
+ MEM_freeN(shortcut);
+ }
+ }
+
+ /* Keymap */
+
+ /* This is too handy not to expose somehow, let's be sneaky for now. */
+ if ((is_label == false) && CTX_wm_window(C)->eventstate->shift) {
+ const char *expr_imports[] = {"bpy", "bl_ui", NULL};
+ char expr[256];
+ SNPRINTF(expr,
+ "getattr("
+ "bl_ui.space_toolsystem_common.keymap_from_id("
+ "bpy.context, "
+ "bpy.context.space_data.type, "
+ "'%s'), "
+ "'as_pointer', lambda: 0)()",
+ tool_id);
+
+ intptr_t expr_result = 0;
+ if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
+ if (expr_result != 0) {
+ {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup("Tool Keymap:");
+ }
+ wmKeyMap *keymap = (wmKeyMap *)expr_result;
+ ui_tooltip_data_append_from_keymap(C, data, keymap);
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
+#endif /* WITH_PYTHON */
+
+ if (data->fields_len == 0) {
+ MEM_freeN(data);
+ return NULL;
+ }
+ else {
+ return data;
+ }
}
static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
{
- uiStringInfo but_tip = {BUT_GET_TIP, NULL};
- uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL};
- uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL};
- uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL};
- uiStringInfo prop_keymap = {BUT_GET_PROP_KEYMAP, NULL};
- uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL};
- uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL};
-
- char buf[512];
-
- /* create tooltip data */
- uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
-
- UI_but_string_info_get(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &prop_keymap, &rna_struct, &rna_prop, NULL);
-
- /* Tip */
- if (but_tip.strinfo) {
- {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_HEADER,
- .color_id = UI_TIP_LC_NORMAL,
- });
- if (enum_label.strinfo) {
- field->text = BLI_sprintfN("%s: ", but_tip.strinfo);
- field->text_suffix = BLI_strdup(enum_label.strinfo);
- }
- else {
- field->text = BLI_sprintfN("%s.", but_tip.strinfo);
- }
- }
-
- /* special case enum rna buttons */
- if ((but->type & UI_BTYPE_ROW) && but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_NORMAL,
- });
- field->text = BLI_strdup(IFACE_("(Shift-Click/Drag to select multiple)"));
- }
-
- }
- /* Enum field label & tip */
- if (enum_tip.strinfo) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = BLI_strdup(enum_tip.strinfo);
- }
-
- /* Op shortcut */
- if (op_keymap.strinfo) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.strinfo);
- }
-
- /* Property context-toggle shortcut */
- if (prop_keymap.strinfo) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.strinfo);
- }
-
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- /* better not show the value of a password */
- if ((but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) == 0) {
- /* full string */
- ui_but_string_get(but, buf, sizeof(buf));
- if (buf[0]) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = BLI_sprintfN(TIP_("Value: %s"), buf);
- }
- }
- }
-
- if (but->rnaprop) {
- int unit_type = UI_but_unit_type_get(but);
-
- if (unit_type == PROP_UNIT_ROTATION) {
- if (RNA_property_type(but->rnaprop) == PROP_FLOAT) {
- float value = RNA_property_array_check(but->rnaprop) ?
- RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) :
- RNA_property_float_get(&but->rnapoin, but->rnaprop);
-
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- });
- field->text = BLI_sprintfN(TIP_("Radians: %f"), value);
- }
- }
-
- if (but->flag & UI_BUT_DRIVEN) {
- if (ui_but_anim_expression_get(but, buf, sizeof(buf))) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_NORMAL,
- });
- field->text = BLI_sprintfN(TIP_("Expression: %s"), buf);
- }
- }
-
- if (but->rnapoin.id.data) {
- const ID *id = but->rnapoin.id.data;
- if (ID_IS_LINKED(id)) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_NORMAL,
- });
- field->text = BLI_sprintfN(TIP_("Library: %s"), id->lib->name);
- }
- }
- }
- else if (but->optype) {
- PointerRNA *opptr;
- char *str;
- opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */
-
- /* so the context is passed to fieldf functions (some py fieldf functions use it) */
- WM_operator_properties_sanitize(opptr, false);
-
- str = WM_operator_pystring_ex(C, NULL, false, false, but->optype, opptr);
-
- /* avoid overly verbose tips (eg, arrays of 20 layers), exact limit is arbitrary */
- WM_operator_pystring_abbreviate(str, 32);
-
- /* operator info */
- if (U.flag & USER_TOOLTIPS_PYTHON) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_MONO,
- .color_id = UI_TIP_LC_PYTHON,
- .is_pad = true,
- });
- field->text = BLI_sprintfN(TIP_("Python: %s"), str);
- }
-
- MEM_freeN(str);
- }
-
- /* button is disabled, we may be able to tell user why */
- if (but->flag & UI_BUT_DISABLED) {
- const char *disabled_msg = NULL;
-
- /* if operator poll check failed, it can give pretty precise info why */
- if (but->optype) {
- CTX_wm_operator_poll_msg_set(C, NULL);
- WM_operator_poll_context(C, but->optype, but->opcontext);
- disabled_msg = CTX_wm_operator_poll_msg_get(C);
- }
- /* alternatively, buttons can store some reasoning too */
- else if (but->disabled_info) {
- disabled_msg = TIP_(but->disabled_info);
- }
-
- if (disabled_msg && disabled_msg[0]) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_ALERT,
- });
- field->text = BLI_sprintfN(TIP_("Disabled: %s"), disabled_msg);
- }
- }
-
- if ((U.flag & USER_TOOLTIPS_PYTHON) && !but->optype && rna_struct.strinfo) {
- {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_MONO,
- .color_id = UI_TIP_LC_PYTHON,
- .is_pad = true,
- });
- if (rna_prop.strinfo) {
- /* Struct and prop */
- field->text = BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo);
- }
- else {
- /* Only struct (e.g. menus) */
- field->text = BLI_sprintfN(TIP_("Python: %s"), rna_struct.strinfo);
- }
- }
-
- if (but->rnapoin.id.data) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_MONO,
- .color_id = UI_TIP_LC_PYTHON,
- });
-
- /* this could get its own 'BUT_GET_...' type */
-
- /* never fails */
- /* move ownership (no need for re-alloc) */
- if (but->rnaprop) {
- field->text = RNA_path_full_property_py_ex(&but->rnapoin, but->rnaprop, but->rnaindex, true);
- }
- else {
- field->text = RNA_path_full_struct_py(&but->rnapoin);
- }
-
- }
- }
-
- /* Free strinfo's... */
- if (but_tip.strinfo) {
- MEM_freeN(but_tip.strinfo);
- }
- if (enum_label.strinfo) {
- MEM_freeN(enum_label.strinfo);
- }
- if (enum_tip.strinfo) {
- MEM_freeN(enum_tip.strinfo);
- }
- if (op_keymap.strinfo) {
- MEM_freeN(op_keymap.strinfo);
- }
- if (prop_keymap.strinfo) {
- MEM_freeN(prop_keymap.strinfo);
- }
- if (rna_struct.strinfo) {
- MEM_freeN(rna_struct.strinfo);
- }
- if (rna_prop.strinfo) {
- MEM_freeN(rna_prop.strinfo);
- }
-
- if (data->fields_len == 0) {
- MEM_freeN(data);
- return NULL;
- }
- else {
- return data;
- }
+ uiStringInfo but_tip = {BUT_GET_TIP, NULL};
+ uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL};
+ uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL};
+ uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL};
+ uiStringInfo prop_keymap = {BUT_GET_PROP_KEYMAP, NULL};
+ uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL};
+ uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL};
+
+ char buf[512];
+
+ /* create tooltip data */
+ uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
+
+ UI_but_string_info_get(C,
+ but,
+ &but_tip,
+ &enum_label,
+ &enum_tip,
+ &op_keymap,
+ &prop_keymap,
+ &rna_struct,
+ &rna_prop,
+ NULL);
+
+ /* Tip */
+ if (but_tip.strinfo) {
+ {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_HEADER,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ if (enum_label.strinfo) {
+ field->text = BLI_sprintfN("%s: ", but_tip.strinfo);
+ field->text_suffix = BLI_strdup(enum_label.strinfo);
+ }
+ else {
+ field->text = BLI_sprintfN("%s.", but_tip.strinfo);
+ }
+ }
+
+ /* special case enum rna buttons */
+ if ((but->type & UI_BTYPE_ROW) && but->rnaprop &&
+ RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ field->text = BLI_strdup(IFACE_("(Shift-Click/Drag to select multiple)"));
+ }
+ }
+ /* Enum field label & tip */
+ if (enum_tip.strinfo) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(enum_tip.strinfo);
+ }
+
+ /* Op shortcut */
+ if (op_keymap.strinfo) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.strinfo);
+ }
+
+ /* Property context-toggle shortcut */
+ if (prop_keymap.strinfo) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.strinfo);
+ }
+
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
+ /* better not show the value of a password */
+ if ((but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) == 0) {
+ /* full string */
+ ui_but_string_get(but, buf, sizeof(buf));
+ if (buf[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Value: %s"), buf);
+ }
+ }
+ }
+
+ if (but->rnaprop) {
+ int unit_type = UI_but_unit_type_get(but);
+
+ if (unit_type == PROP_UNIT_ROTATION) {
+ if (RNA_property_type(but->rnaprop) == PROP_FLOAT) {
+ float value = RNA_property_array_check(but->rnaprop) ?
+ RNA_property_float_get_index(
+ &but->rnapoin, but->rnaprop, but->rnaindex) :
+ RNA_property_float_get(&but->rnapoin, but->rnaprop);
+
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ });
+ field->text = BLI_sprintfN(TIP_("Radians: %f"), value);
+ }
+ }
+
+ if (but->flag & UI_BUT_DRIVEN) {
+ if (ui_but_anim_expression_get(but, buf, sizeof(buf))) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ field->text = BLI_sprintfN(TIP_("Expression: %s"), buf);
+ }
+ }
+
+ if (but->rnapoin.id.data) {
+ const ID *id = but->rnapoin.id.data;
+ if (ID_IS_LINKED(id)) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_NORMAL,
+ });
+ field->text = BLI_sprintfN(TIP_("Library: %s"), id->lib->name);
+ }
+ }
+ }
+ else if (but->optype) {
+ PointerRNA *opptr;
+ char *str;
+ opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */
+
+ /* so the context is passed to fieldf functions (some py fieldf functions use it) */
+ WM_operator_properties_sanitize(opptr, false);
+
+ str = WM_operator_pystring_ex(C, NULL, false, false, but->optype, opptr);
+
+ /* avoid overly verbose tips (eg, arrays of 20 layers), exact limit is arbitrary */
+ WM_operator_pystring_abbreviate(str, 32);
+
+ /* operator info */
+ if (U.flag & USER_TOOLTIPS_PYTHON) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_MONO,
+ .color_id = UI_TIP_LC_PYTHON,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Python: %s"), str);
+ }
+
+ MEM_freeN(str);
+ }
+
+ /* button is disabled, we may be able to tell user why */
+ if (but->flag & UI_BUT_DISABLED) {
+ const char *disabled_msg = NULL;
+
+ /* if operator poll check failed, it can give pretty precise info why */
+ if (but->optype) {
+ CTX_wm_operator_poll_msg_set(C, NULL);
+ WM_operator_poll_context(C, but->optype, but->opcontext);
+ disabled_msg = CTX_wm_operator_poll_msg_get(C);
+ }
+ /* alternatively, buttons can store some reasoning too */
+ else if (but->disabled_info) {
+ disabled_msg = TIP_(but->disabled_info);
+ }
+
+ if (disabled_msg && disabled_msg[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_ALERT,
+ });
+ field->text = BLI_sprintfN(TIP_("Disabled: %s"), disabled_msg);
+ }
+ }
+
+ if ((U.flag & USER_TOOLTIPS_PYTHON) && !but->optype && rna_struct.strinfo) {
+ {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_MONO,
+ .color_id = UI_TIP_LC_PYTHON,
+ .is_pad = true,
+ });
+ if (rna_prop.strinfo) {
+ /* Struct and prop */
+ field->text = BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo);
+ }
+ else {
+ /* Only struct (e.g. menus) */
+ field->text = BLI_sprintfN(TIP_("Python: %s"), rna_struct.strinfo);
+ }
+ }
+
+ if (but->rnapoin.id.data) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_MONO,
+ .color_id = UI_TIP_LC_PYTHON,
+ });
+
+ /* this could get its own 'BUT_GET_...' type */
+
+ /* never fails */
+ /* move ownership (no need for re-alloc) */
+ if (but->rnaprop) {
+ field->text = RNA_path_full_property_py_ex(
+ &but->rnapoin, but->rnaprop, but->rnaindex, true);
+ }
+ else {
+ field->text = RNA_path_full_struct_py(&but->rnapoin);
+ }
+ }
+ }
+
+ /* Free strinfo's... */
+ if (but_tip.strinfo) {
+ MEM_freeN(but_tip.strinfo);
+ }
+ if (enum_label.strinfo) {
+ MEM_freeN(enum_label.strinfo);
+ }
+ if (enum_tip.strinfo) {
+ MEM_freeN(enum_tip.strinfo);
+ }
+ if (op_keymap.strinfo) {
+ MEM_freeN(op_keymap.strinfo);
+ }
+ if (prop_keymap.strinfo) {
+ MEM_freeN(prop_keymap.strinfo);
+ }
+ if (rna_struct.strinfo) {
+ MEM_freeN(rna_struct.strinfo);
+ }
+ if (rna_prop.strinfo) {
+ MEM_freeN(rna_prop.strinfo);
+ }
+
+ if (data->fields_len == 0) {
+ MEM_freeN(data);
+ return NULL;
+ }
+ else {
+ return data;
+ }
}
static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
{
- uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
-
- /* TODO(campbell): a way for gizmos to have their own descriptions (low priority). */
-
- /* Operator Actions */
- {
- bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part;
-
- const struct {
- int part;
- const char *prefix;
- } gzop_actions[] = {
- {
- .part = gz->highlight_part,
- .prefix = use_drag ? TIP_("Click") : NULL,
- }, {
- .part = use_drag ? gz->drag_part : -1,
- .prefix = use_drag ? TIP_("Drag") : NULL,
- },
- };
-
- for (int i = 0; i < ARRAY_SIZE(gzop_actions); i++) {
- wmGizmoOpElem *gzop = (gzop_actions[i].part != -1) ? WM_gizmo_operator_get(gz, gzop_actions[i].part) : NULL;
- if (gzop != NULL) {
- /* Description */
- const char *info = RNA_struct_ui_description(gzop->type->srna);
- if (!(info && info[0])) {
- info = RNA_struct_ui_name(gzop->type->srna);
- }
-
- if (info && info[0]) {
- char *text = NULL;
- if (gzop_actions[i].prefix != NULL) {
- text = BLI_sprintfN("%s: %s", gzop_actions[i].prefix, info);
- }
- else {
- text = BLI_strdup(info);
- }
-
- if (text != NULL) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_HEADER,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = text;
- }
- }
-
- /* Shortcut */
- {
- IDProperty *prop = gzop->ptr.data;
- char buf[128];
- if (WM_key_event_operator_string(
- C, gzop->type->idname, WM_OP_INVOKE_DEFAULT, prop, true,
- buf, ARRAY_SIZE(buf)))
- {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = BLI_sprintfN(TIP_("Shortcut: %s"), buf);
- }
- }
- }
- }
- }
-
- /* Property Actions */
- if (gz->type->target_property_defs_len) {
- wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz);
- for (int i = 0; i < gz->type->target_property_defs_len; i++) {
- /* TODO(campbell): function callback descriptions. */
- wmGizmoProperty *gz_prop = &gz_prop_array[i];
- if (gz_prop->prop != NULL) {
- const char *info = RNA_property_ui_description(gz_prop->prop);
- if (info && info[0]) {
- uiTooltipField *field = text_field_add(
- data, &(uiTooltipFormat){
- .style = UI_TIP_STYLE_NORMAL,
- .color_id = UI_TIP_LC_VALUE,
- .is_pad = true,
- });
- field->text = BLI_strdup(info);
- }
- }
- }
- }
-
- if (data->fields_len == 0) {
- MEM_freeN(data);
- return NULL;
- }
- else {
- return data;
- }
+ uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
+
+ /* TODO(campbell): a way for gizmos to have their own descriptions (low priority). */
+
+ /* Operator Actions */
+ {
+ bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part;
+
+ const struct {
+ int part;
+ const char *prefix;
+ } gzop_actions[] = {
+ {
+ .part = gz->highlight_part,
+ .prefix = use_drag ? TIP_("Click") : NULL,
+ },
+ {
+ .part = use_drag ? gz->drag_part : -1,
+ .prefix = use_drag ? TIP_("Drag") : NULL,
+ },
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(gzop_actions); i++) {
+ wmGizmoOpElem *gzop = (gzop_actions[i].part != -1) ?
+ WM_gizmo_operator_get(gz, gzop_actions[i].part) :
+ NULL;
+ if (gzop != NULL) {
+ /* Description */
+ const char *info = RNA_struct_ui_description(gzop->type->srna);
+ if (!(info && info[0])) {
+ info = RNA_struct_ui_name(gzop->type->srna);
+ }
+
+ if (info && info[0]) {
+ char *text = NULL;
+ if (gzop_actions[i].prefix != NULL) {
+ text = BLI_sprintfN("%s: %s", gzop_actions[i].prefix, info);
+ }
+ else {
+ text = BLI_strdup(info);
+ }
+
+ if (text != NULL) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_HEADER,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = text;
+ }
+ }
+
+ /* Shortcut */
+ {
+ IDProperty *prop = gzop->ptr.data;
+ char buf[128];
+ if (WM_key_event_operator_string(
+ C, gzop->type->idname, WM_OP_INVOKE_DEFAULT, prop, true, buf, ARRAY_SIZE(buf))) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_sprintfN(TIP_("Shortcut: %s"), buf);
+ }
+ }
+ }
+ }
+ }
+
+ /* Property Actions */
+ if (gz->type->target_property_defs_len) {
+ wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz);
+ for (int i = 0; i < gz->type->target_property_defs_len; i++) {
+ /* TODO(campbell): function callback descriptions. */
+ wmGizmoProperty *gz_prop = &gz_prop_array[i];
+ if (gz_prop->prop != NULL) {
+ const char *info = RNA_property_ui_description(gz_prop->prop);
+ if (info && info[0]) {
+ uiTooltipField *field = text_field_add(data,
+ &(uiTooltipFormat){
+ .style = UI_TIP_STYLE_NORMAL,
+ .color_id = UI_TIP_LC_VALUE,
+ .is_pad = true,
+ });
+ field->text = BLI_strdup(info);
+ }
+ }
+ }
+ }
+
+ if (data->fields_len == 0) {
+ MEM_freeN(data);
+ return NULL;
+ }
+ else {
+ return data;
+ }
}
-
-static ARegion *ui_tooltip_create_with_data(
- bContext *C, uiTooltipData *data,
- const float init_position[2], const rcti *init_rect_overlap,
- const float aspect)
+static ARegion *ui_tooltip_create_with_data(bContext *C,
+ uiTooltipData *data,
+ const float init_position[2],
+ const rcti *init_rect_overlap,
+ const float aspect)
{
- const float pad_px = UI_TIP_PADDING;
- wmWindow *win = CTX_wm_window(C);
- const int winx = WM_window_pixels_x(win);
- const int winy = WM_window_pixels_y(win);
- uiStyle *style = UI_style_get();
- static ARegionType type;
- ARegion *ar;
- int fonth, fontw;
- int h, i;
- rcti rect_i;
- int font_flag = 0;
-
- /* create area region */
- ar = ui_region_temp_add(CTX_wm_screen(C));
-
- memset(&type, 0, sizeof(ARegionType));
- type.draw = ui_tooltip_region_draw_cb;
- type.free = ui_tooltip_region_free_cb;
- type.regionid = RGN_TYPE_TEMPORARY;
- ar->type = &type;
-
- /* set font, get bb */
- data->fstyle = style->widget; /* copy struct */
- ui_fontscale(&data->fstyle.points, aspect);
-
- UI_fontstyle_set(&data->fstyle);
-
- data->wrap_width = min_ii(UI_TIP_MAXWIDTH * U.pixelsize / aspect, winx - (UI_TIP_PADDING * 2));
-
- font_flag |= BLF_WORD_WRAP;
- if (data->fstyle.kerning == 1) {
- font_flag |= BLF_KERNING_DEFAULT;
- }
- BLF_enable(data->fstyle.uifont_id, font_flag);
- BLF_enable(blf_mono_font, font_flag);
- BLF_wordwrap(data->fstyle.uifont_id, data->wrap_width);
- BLF_wordwrap(blf_mono_font, data->wrap_width);
-
- /* these defines tweaked depending on font */
+ const float pad_px = UI_TIP_PADDING;
+ wmWindow *win = CTX_wm_window(C);
+ const int winx = WM_window_pixels_x(win);
+ const int winy = WM_window_pixels_y(win);
+ uiStyle *style = UI_style_get();
+ static ARegionType type;
+ ARegion *ar;
+ int fonth, fontw;
+ int h, i;
+ rcti rect_i;
+ int font_flag = 0;
+
+ /* create area region */
+ ar = ui_region_temp_add(CTX_wm_screen(C));
+
+ memset(&type, 0, sizeof(ARegionType));
+ type.draw = ui_tooltip_region_draw_cb;
+ type.free = ui_tooltip_region_free_cb;
+ type.regionid = RGN_TYPE_TEMPORARY;
+ ar->type = &type;
+
+ /* set font, get bb */
+ data->fstyle = style->widget; /* copy struct */
+ ui_fontscale(&data->fstyle.points, aspect);
+
+ UI_fontstyle_set(&data->fstyle);
+
+ data->wrap_width = min_ii(UI_TIP_MAXWIDTH * U.pixelsize / aspect, winx - (UI_TIP_PADDING * 2));
+
+ font_flag |= BLF_WORD_WRAP;
+ if (data->fstyle.kerning == 1) {
+ font_flag |= BLF_KERNING_DEFAULT;
+ }
+ BLF_enable(data->fstyle.uifont_id, font_flag);
+ BLF_enable(blf_mono_font, font_flag);
+ BLF_wordwrap(data->fstyle.uifont_id, data->wrap_width);
+ BLF_wordwrap(blf_mono_font, data->wrap_width);
+
+ /* these defines tweaked depending on font */
#define TIP_BORDER_X (16.0f / aspect)
#define TIP_BORDER_Y (6.0f / aspect)
- h = BLF_height_max(data->fstyle.uifont_id);
-
- for (i = 0, fontw = 0, fonth = 0; i < data->fields_len; i++) {
- uiTooltipField *field = &data->fields[i];
- uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL;
-
- struct ResultBLF info;
- int w, x_pos = 0;
- int font_id;
-
- if (field->format.style == UI_TIP_STYLE_MONO) {
- BLF_size(blf_mono_font, data->fstyle.points * U.pixelsize, U.dpi);
- font_id = blf_mono_font;
- }
- else {
- BLI_assert(ELEM(field->format.style, UI_TIP_STYLE_NORMAL, UI_TIP_STYLE_HEADER));
- font_id = data->fstyle.uifont_id;
- }
- w = BLF_width_ex(font_id, field->text, BLF_DRAW_STR_DUMMY_MAX, &info);
-
- /* check for suffix (enum label) */
- if (field->text_suffix && field->text_suffix[0]) {
- x_pos = info.width;
- w = max_ii(w, x_pos + BLF_width(font_id, field->text_suffix, BLF_DRAW_STR_DUMMY_MAX));
- }
- fontw = max_ii(fontw, w);
-
- fonth += h * info.lines;
- if (field_next && field_next->format.is_pad) {
- fonth += h * (UI_TIP_PAD_FAC - 1);
- }
-
- field->geom.lines = info.lines;
- field->geom.x_pos = x_pos;
- }
-
- //fontw *= aspect;
-
- BLF_disable(data->fstyle.uifont_id, font_flag);
- BLF_disable(blf_mono_font, font_flag);
-
- ar->regiondata = data;
-
- data->toth = fonth;
- data->lineh = h;
-
- /* Compute position. */
- {
- rctf rect_fl;
- rect_fl.xmin = init_position[0] - TIP_BORDER_X;
- rect_fl.xmax = rect_fl.xmin + fontw + pad_px;
- rect_fl.ymax = init_position[1] - TIP_BORDER_Y;
- rect_fl.ymin = rect_fl.ymax - fonth - TIP_BORDER_Y;
- BLI_rcti_rctf_copy(&rect_i, &rect_fl);
- }
+ h = BLF_height_max(data->fstyle.uifont_id);
+
+ for (i = 0, fontw = 0, fonth = 0; i < data->fields_len; i++) {
+ uiTooltipField *field = &data->fields[i];
+ uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL;
+
+ struct ResultBLF info;
+ int w, x_pos = 0;
+ int font_id;
+
+ if (field->format.style == UI_TIP_STYLE_MONO) {
+ BLF_size(blf_mono_font, data->fstyle.points * U.pixelsize, U.dpi);
+ font_id = blf_mono_font;
+ }
+ else {
+ BLI_assert(ELEM(field->format.style, UI_TIP_STYLE_NORMAL, UI_TIP_STYLE_HEADER));
+ font_id = data->fstyle.uifont_id;
+ }
+ w = BLF_width_ex(font_id, field->text, BLF_DRAW_STR_DUMMY_MAX, &info);
+
+ /* check for suffix (enum label) */
+ if (field->text_suffix && field->text_suffix[0]) {
+ x_pos = info.width;
+ w = max_ii(w, x_pos + BLF_width(font_id, field->text_suffix, BLF_DRAW_STR_DUMMY_MAX));
+ }
+ fontw = max_ii(fontw, w);
+
+ fonth += h * info.lines;
+ if (field_next && field_next->format.is_pad) {
+ fonth += h * (UI_TIP_PAD_FAC - 1);
+ }
+
+ field->geom.lines = info.lines;
+ field->geom.x_pos = x_pos;
+ }
+
+ //fontw *= aspect;
+
+ BLF_disable(data->fstyle.uifont_id, font_flag);
+ BLF_disable(blf_mono_font, font_flag);
+
+ ar->regiondata = data;
+
+ data->toth = fonth;
+ data->lineh = h;
+
+ /* Compute position. */
+ {
+ rctf rect_fl;
+ rect_fl.xmin = init_position[0] - TIP_BORDER_X;
+ rect_fl.xmax = rect_fl.xmin + fontw + pad_px;
+ rect_fl.ymax = init_position[1] - TIP_BORDER_Y;
+ rect_fl.ymin = rect_fl.ymax - fonth - TIP_BORDER_Y;
+ BLI_rcti_rctf_copy(&rect_i, &rect_fl);
+ }
#undef TIP_BORDER_X
#undef TIP_BORDER_Y
-// #define USE_ALIGN_Y_CENTER
-
- /* Clamp to window bounds. */
- {
- /* Ensure at least 5 px above screen bounds
- * UI_UNIT_Y is just a guess to be above the menu item */
- if (init_rect_overlap != NULL) {
- const int pad = max_ff(1.0f, U.pixelsize) * 5;
- const rcti init_rect = {
- .xmin = init_rect_overlap->xmin - pad,
- .xmax = init_rect_overlap->xmax + pad,
- .ymin = init_rect_overlap->ymin - pad,
- .ymax = init_rect_overlap->ymax + pad,
- };
- const rcti rect_clamp = {
- .xmin = 0,
- .xmax = winx,
- .ymin = 0,
- .ymax = winy,
- };
- /* try right. */
- const int size_x = BLI_rcti_size_x(&rect_i);
- const int size_y = BLI_rcti_size_y(&rect_i);
- const int cent_overlap_x = BLI_rcti_cent_x(&init_rect);
+ // #define USE_ALIGN_Y_CENTER
+
+ /* Clamp to window bounds. */
+ {
+ /* Ensure at least 5 px above screen bounds
+ * UI_UNIT_Y is just a guess to be above the menu item */
+ if (init_rect_overlap != NULL) {
+ const int pad = max_ff(1.0f, U.pixelsize) * 5;
+ const rcti init_rect = {
+ .xmin = init_rect_overlap->xmin - pad,
+ .xmax = init_rect_overlap->xmax + pad,
+ .ymin = init_rect_overlap->ymin - pad,
+ .ymax = init_rect_overlap->ymax + pad,
+ };
+ const rcti rect_clamp = {
+ .xmin = 0,
+ .xmax = winx,
+ .ymin = 0,
+ .ymax = winy,
+ };
+ /* try right. */
+ const int size_x = BLI_rcti_size_x(&rect_i);
+ const int size_y = BLI_rcti_size_y(&rect_i);
+ const int cent_overlap_x = BLI_rcti_cent_x(&init_rect);
#ifdef USE_ALIGN_Y_CENTER
- const int cent_overlap_y = BLI_rcti_cent_y(&init_rect);
+ const int cent_overlap_y = BLI_rcti_cent_y(&init_rect);
#endif
- struct {
- rcti xpos;
- rcti xneg;
- rcti ypos;
- rcti yneg;
- } rect;
-
- { /* xpos */
- rcti r = rect_i;
- r.xmin = init_rect.xmax;
- r.xmax = r.xmin + size_x;
+ struct {
+ rcti xpos;
+ rcti xneg;
+ rcti ypos;
+ rcti yneg;
+ } rect;
+
+ { /* xpos */
+ rcti r = rect_i;
+ r.xmin = init_rect.xmax;
+ r.xmax = r.xmin + size_x;
#ifdef USE_ALIGN_Y_CENTER
- r.ymin = cent_overlap_y - (size_y / 2);
- r.ymax = r.ymin + size_y;
+ r.ymin = cent_overlap_y - (size_y / 2);
+ r.ymax = r.ymin + size_y;
#else
- r.ymin = init_rect.ymax - BLI_rcti_size_y(&rect_i);
- r.ymax = init_rect.ymax;
- r.ymin -= UI_POPUP_MARGIN;
- r.ymax -= UI_POPUP_MARGIN;
+ r.ymin = init_rect.ymax - BLI_rcti_size_y(&rect_i);
+ r.ymax = init_rect.ymax;
+ r.ymin -= UI_POPUP_MARGIN;
+ r.ymax -= UI_POPUP_MARGIN;
#endif
- rect.xpos = r;
- }
- { /* xneg */
- rcti r = rect_i;
- r.xmin = init_rect.xmin - size_x;
- r.xmax = r.xmin + size_x;
+ rect.xpos = r;
+ }
+ { /* xneg */
+ rcti r = rect_i;
+ r.xmin = init_rect.xmin - size_x;
+ r.xmax = r.xmin + size_x;
#ifdef USE_ALIGN_Y_CENTER
- r.ymin = cent_overlap_y - (size_y / 2);
- r.ymax = r.ymin + size_y;
+ r.ymin = cent_overlap_y - (size_y / 2);
+ r.ymax = r.ymin + size_y;
#else
- r.ymin = init_rect.ymax - BLI_rcti_size_y(&rect_i);
- r.ymax = init_rect.ymax;
- r.ymin -= UI_POPUP_MARGIN;
- r.ymax -= UI_POPUP_MARGIN;
+ r.ymin = init_rect.ymax - BLI_rcti_size_y(&rect_i);
+ r.ymax = init_rect.ymax;
+ r.ymin -= UI_POPUP_MARGIN;
+ r.ymax -= UI_POPUP_MARGIN;
#endif
- rect.xneg = r;
- }
- { /* ypos */
- rcti r = rect_i;
- r.xmin = cent_overlap_x - (size_x / 2);
- r.xmax = r.xmin + size_x;
- r.ymin = init_rect.ymax;
- r.ymax = r.ymin + size_y;
- rect.ypos = r;
- }
- { /* yneg */
- rcti r = rect_i;
- r.xmin = cent_overlap_x - (size_x / 2);
- r.xmax = r.xmin + size_x;
- r.ymin = init_rect.ymin - size_y;
- r.ymax = r.ymin + size_y;
- rect.yneg = r;
- }
-
- bool found = false;
- for (int j = 0; j < 4; j++) {
- const rcti *r = (&rect.xpos) + j;
- if (BLI_rcti_inside_rcti(&rect_clamp, r)) {
- rect_i = *r;
- found = true;
- break;
- }
- }
- if (!found) {
- /* Fallback, we could pick the best fallback, for now just use xpos. */
- int offset_dummy[2];
- rect_i = rect.xpos;
- BLI_rcti_clamp(&rect_i, &rect_clamp, offset_dummy);
- }
-
- }
- else {
- const int pad = max_ff(1.0f, U.pixelsize) * 5;
- const rcti rect_clamp = {
- .xmin = pad,
- .xmax = winx - pad,
- .ymin = pad + (UI_UNIT_Y * 2),
- .ymax = winy - pad,
- };
- int offset_dummy[2];
- BLI_rcti_clamp(&rect_i, &rect_clamp, offset_dummy);
- }
- }
+ rect.xneg = r;
+ }
+ { /* ypos */
+ rcti r = rect_i;
+ r.xmin = cent_overlap_x - (size_x / 2);
+ r.xmax = r.xmin + size_x;
+ r.ymin = init_rect.ymax;
+ r.ymax = r.ymin + size_y;
+ rect.ypos = r;
+ }
+ { /* yneg */
+ rcti r = rect_i;
+ r.xmin = cent_overlap_x - (size_x / 2);
+ r.xmax = r.xmin + size_x;
+ r.ymin = init_rect.ymin - size_y;
+ r.ymax = r.ymin + size_y;
+ rect.yneg = r;
+ }
+
+ bool found = false;
+ for (int j = 0; j < 4; j++) {
+ const rcti *r = (&rect.xpos) + j;
+ if (BLI_rcti_inside_rcti(&rect_clamp, r)) {
+ rect_i = *r;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ /* Fallback, we could pick the best fallback, for now just use xpos. */
+ int offset_dummy[2];
+ rect_i = rect.xpos;
+ BLI_rcti_clamp(&rect_i, &rect_clamp, offset_dummy);
+ }
+ }
+ else {
+ const int pad = max_ff(1.0f, U.pixelsize) * 5;
+ const rcti rect_clamp = {
+ .xmin = pad,
+ .xmax = winx - pad,
+ .ymin = pad + (UI_UNIT_Y * 2),
+ .ymax = winy - pad,
+ };
+ int offset_dummy[2];
+ BLI_rcti_clamp(&rect_i, &rect_clamp, offset_dummy);
+ }
+ }
#undef USE_ALIGN_Y_CENTER
- /* add padding */
- BLI_rcti_resize(&rect_i,
- BLI_rcti_size_x(&rect_i) + pad_px,
- BLI_rcti_size_y(&rect_i) + pad_px);
-
- /* widget rect, in region coords */
- {
- /* Compensate for margin offset, visually this corrects the position. */
- const int margin = UI_POPUP_MARGIN;
- if (init_rect_overlap != NULL) {
- BLI_rcti_translate(&rect_i, margin, margin / 2);
- }
-
- data->bbox.xmin = margin;
- data->bbox.xmax = BLI_rcti_size_x(&rect_i) - margin;
- data->bbox.ymin = margin;
- data->bbox.ymax = BLI_rcti_size_y(&rect_i);
-
- /* region bigger for shadow */
- ar->winrct.xmin = rect_i.xmin - margin;
- ar->winrct.xmax = rect_i.xmax + margin;
- ar->winrct.ymin = rect_i.ymin - margin;
- ar->winrct.ymax = rect_i.ymax + margin;
- }
-
- /* adds subwindow */
- ED_region_init(ar);
-
- /* notify change and redraw */
- ED_region_tag_redraw(ar);
-
- return ar;
+ /* add padding */
+ BLI_rcti_resize(&rect_i, BLI_rcti_size_x(&rect_i) + pad_px, BLI_rcti_size_y(&rect_i) + pad_px);
+
+ /* widget rect, in region coords */
+ {
+ /* Compensate for margin offset, visually this corrects the position. */
+ const int margin = UI_POPUP_MARGIN;
+ if (init_rect_overlap != NULL) {
+ BLI_rcti_translate(&rect_i, margin, margin / 2);
+ }
+
+ data->bbox.xmin = margin;
+ data->bbox.xmax = BLI_rcti_size_x(&rect_i) - margin;
+ data->bbox.ymin = margin;
+ data->bbox.ymax = BLI_rcti_size_y(&rect_i);
+
+ /* region bigger for shadow */
+ ar->winrct.xmin = rect_i.xmin - margin;
+ ar->winrct.xmax = rect_i.xmax + margin;
+ ar->winrct.ymin = rect_i.ymin - margin;
+ ar->winrct.ymax = rect_i.ymax + margin;
+ }
+
+ /* adds subwindow */
+ ED_region_init(ar);
+
+ /* notify change and redraw */
+ ED_region_tag_redraw(ar);
+
+ return ar;
}
/** \} */
@@ -1233,80 +1234,80 @@ static ARegion *ui_tooltip_create_with_data(
/** \name ToolTip Public API
* \{ */
-
ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *but, bool is_label)
{
- wmWindow *win = CTX_wm_window(C);
- /* aspect values that shrink text are likely unreadable */
- const float aspect = min_ff(1.0f, but->block->aspect);
- float init_position[2];
-
- if (but->drawflag & UI_BUT_NO_TOOLTIP) {
- return NULL;
- }
- uiTooltipData *data = NULL;
-
- if (data == NULL) {
- data = ui_tooltip_data_from_tool(C, but, is_label);
- }
-
- if (data == NULL) {
- data = ui_tooltip_data_from_button(C, but);
- }
-
- if (data == NULL) {
- return NULL;
- }
-
- const bool is_no_overlap = UI_but_has_tooltip_label(but) || UI_but_is_tool(but);
- rcti init_rect;
- if (is_no_overlap) {
- rctf overlap_rect_fl;
- init_position[0] = BLI_rctf_cent_x(&but->rect);
- init_position[1] = BLI_rctf_cent_y(&but->rect);
- if (butregion) {
- ui_block_to_window_fl(butregion, but->block, &init_position[0], &init_position[1]);
- ui_block_to_window_rctf(butregion, but->block, &overlap_rect_fl, &but->rect);
- }
- else {
- overlap_rect_fl = but->rect;
- }
- BLI_rcti_rctf_copy_round(&init_rect, &overlap_rect_fl);
- }
- else {
- init_position[0] = BLI_rctf_cent_x(&but->rect);
- init_position[1] = but->rect.ymin - (UI_POPUP_MARGIN / 2);
- if (butregion) {
- ui_block_to_window_fl(butregion, but->block, &init_position[0], &init_position[1]);
- init_position[0] = win->eventstate->x;
- }
- }
-
- ARegion *ar = ui_tooltip_create_with_data(C, data, init_position, is_no_overlap ? &init_rect : NULL, aspect);
-
- return ar;
+ wmWindow *win = CTX_wm_window(C);
+ /* aspect values that shrink text are likely unreadable */
+ const float aspect = min_ff(1.0f, but->block->aspect);
+ float init_position[2];
+
+ if (but->drawflag & UI_BUT_NO_TOOLTIP) {
+ return NULL;
+ }
+ uiTooltipData *data = NULL;
+
+ if (data == NULL) {
+ data = ui_tooltip_data_from_tool(C, but, is_label);
+ }
+
+ if (data == NULL) {
+ data = ui_tooltip_data_from_button(C, but);
+ }
+
+ if (data == NULL) {
+ return NULL;
+ }
+
+ const bool is_no_overlap = UI_but_has_tooltip_label(but) || UI_but_is_tool(but);
+ rcti init_rect;
+ if (is_no_overlap) {
+ rctf overlap_rect_fl;
+ init_position[0] = BLI_rctf_cent_x(&but->rect);
+ init_position[1] = BLI_rctf_cent_y(&but->rect);
+ if (butregion) {
+ ui_block_to_window_fl(butregion, but->block, &init_position[0], &init_position[1]);
+ ui_block_to_window_rctf(butregion, but->block, &overlap_rect_fl, &but->rect);
+ }
+ else {
+ overlap_rect_fl = but->rect;
+ }
+ BLI_rcti_rctf_copy_round(&init_rect, &overlap_rect_fl);
+ }
+ else {
+ init_position[0] = BLI_rctf_cent_x(&but->rect);
+ init_position[1] = but->rect.ymin - (UI_POPUP_MARGIN / 2);
+ if (butregion) {
+ ui_block_to_window_fl(butregion, but->block, &init_position[0], &init_position[1]);
+ init_position[0] = win->eventstate->x;
+ }
+ }
+
+ ARegion *ar = ui_tooltip_create_with_data(
+ C, data, init_position, is_no_overlap ? &init_rect : NULL, aspect);
+
+ return ar;
}
ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz)
{
- wmWindow *win = CTX_wm_window(C);
- const float aspect = 1.0f;
- float init_position[2];
+ wmWindow *win = CTX_wm_window(C);
+ const float aspect = 1.0f;
+ float init_position[2];
- uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz);
- if (data == NULL) {
- return NULL;
- }
+ uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz);
+ if (data == NULL) {
+ return NULL;
+ }
- init_position[0] = win->eventstate->x;
- init_position[1] = win->eventstate->y;
+ init_position[0] = win->eventstate->x;
+ init_position[1] = win->eventstate->y;
- return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect);
+ return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect);
}
void UI_tooltip_free(bContext *C, bScreen *sc, ARegion *ar)
{
- ui_region_temp_remove(C, sc, ar);
+ ui_region_temp_remove(C, sc, ar);
}
/** \} */
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 933864c1cb4..5ba4dcd7439 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -41,28 +41,28 @@
ARegion *ui_region_temp_add(bScreen *sc)
{
- ARegion *ar;
+ ARegion *ar;
- ar = MEM_callocN(sizeof(ARegion), "area region");
- BLI_addtail(&sc->regionbase, ar);
+ ar = MEM_callocN(sizeof(ARegion), "area region");
+ BLI_addtail(&sc->regionbase, ar);
- ar->regiontype = RGN_TYPE_TEMPORARY;
- ar->alignment = RGN_ALIGN_FLOAT;
+ ar->regiontype = RGN_TYPE_TEMPORARY;
+ ar->alignment = RGN_ALIGN_FLOAT;
- return ar;
+ return ar;
}
void ui_region_temp_remove(bContext *C, bScreen *sc, ARegion *ar)
{
- wmWindow *win = CTX_wm_window(C);
+ wmWindow *win = CTX_wm_window(C);
- BLI_assert(ar->regiontype == RGN_TYPE_TEMPORARY);
- BLI_assert(BLI_findindex(&sc->regionbase, ar) != -1);
- if (win) {
- wm_draw_region_clear(win, ar);
- }
+ BLI_assert(ar->regiontype == RGN_TYPE_TEMPORARY);
+ BLI_assert(BLI_findindex(&sc->regionbase, ar) != -1);
+ if (win) {
+ wm_draw_region_clear(win, ar);
+ }
- ED_region_exit(C, ar);
- BKE_area_region_free(NULL, ar); /* NULL: no spacetype */
- BLI_freelinkN(&sc->regionbase, ar);
+ ED_region_exit(C, ar);
+ BKE_area_region_free(NULL, ar); /* NULL: no spacetype */
+ BLI_freelinkN(&sc->regionbase, ar);
}
diff --git a/source/blender/editors/interface/interface_regions_intern.h b/source/blender/editors/interface/interface_regions_intern.h
index fb71cbd788b..31a0a0876a2 100644
--- a/source/blender/editors/interface/interface_regions_intern.h
+++ b/source/blender/editors/interface/interface_regions_intern.h
@@ -28,6 +28,6 @@ uint ui_popup_menu_hash(const char *str);
/* interface_regions_intern.h */
ARegion *ui_region_temp_add(bScreen *sc);
-void ui_region_temp_remove(struct bContext *C, bScreen *sc, ARegion *ar);
+void ui_region_temp_remove(struct bContext *C, bScreen *sc, ARegion *ar);
-#endif /* __INTERFACE_REGIONS_INTERN_H__ */
+#endif /* __INTERFACE_REGIONS_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index eecd5885c74..192571044b9 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
#include <limits.h>
#include <math.h>
#include <stdlib.h>
@@ -71,205 +70,216 @@
* - font types, styles and relative sizes for Panel titles, labels, etc.
*/
-
/* ********************************************** */
static uiStyle *ui_style_new(ListBase *styles, const char *name, short uifont_id)
{
- uiStyle *style = MEM_callocN(sizeof(uiStyle), "new style");
-
- BLI_addtail(styles, style);
- BLI_strncpy(style->name, name, MAX_STYLE_NAME);
-
- style->panelzoom = 1.0; /* unused */
-
- style->paneltitle.uifont_id = uifont_id;
- style->paneltitle.points = 12;
- style->paneltitle.kerning = 1;
- style->paneltitle.shadow = 3;
- style->paneltitle.shadx = 0;
- style->paneltitle.shady = -1;
- style->paneltitle.shadowalpha = 0.5f;
- style->paneltitle.shadowcolor = 0.0f;
-
- style->grouplabel.uifont_id = uifont_id;
- style->grouplabel.points = 12;
- style->grouplabel.kerning = 1;
- style->grouplabel.shadow = 3;
- style->grouplabel.shadx = 0;
- style->grouplabel.shady = -1;
- style->grouplabel.shadowalpha = 0.5f;
- style->grouplabel.shadowcolor = 0.0f;
-
- style->widgetlabel.uifont_id = uifont_id;
- style->widgetlabel.points = 11;
- style->widgetlabel.kerning = 1;
- style->widgetlabel.shadow = 3;
- style->widgetlabel.shadx = 0;
- style->widgetlabel.shady = -1;
- style->widgetlabel.shadowalpha = 0.5f;
- style->widgetlabel.shadowcolor = 0.0f;
-
- style->widget.uifont_id = uifont_id;
- style->widget.points = 11;
- style->widget.kerning = 1;
- style->widget.shadow = 1;
- style->widget.shady = -1;
- style->widget.shadowalpha = 0.5f;
- style->widget.shadowcolor = 0.0f;
-
- style->columnspace = 8;
- style->templatespace = 5;
- style->boxspace = 5;
- style->buttonspacex = 8;
- style->buttonspacey = 2;
- style->panelspace = 8;
- style->panelouter = 4;
-
- return style;
+ uiStyle *style = MEM_callocN(sizeof(uiStyle), "new style");
+
+ BLI_addtail(styles, style);
+ BLI_strncpy(style->name, name, MAX_STYLE_NAME);
+
+ style->panelzoom = 1.0; /* unused */
+
+ style->paneltitle.uifont_id = uifont_id;
+ style->paneltitle.points = 12;
+ style->paneltitle.kerning = 1;
+ style->paneltitle.shadow = 3;
+ style->paneltitle.shadx = 0;
+ style->paneltitle.shady = -1;
+ style->paneltitle.shadowalpha = 0.5f;
+ style->paneltitle.shadowcolor = 0.0f;
+
+ style->grouplabel.uifont_id = uifont_id;
+ style->grouplabel.points = 12;
+ style->grouplabel.kerning = 1;
+ style->grouplabel.shadow = 3;
+ style->grouplabel.shadx = 0;
+ style->grouplabel.shady = -1;
+ style->grouplabel.shadowalpha = 0.5f;
+ style->grouplabel.shadowcolor = 0.0f;
+
+ style->widgetlabel.uifont_id = uifont_id;
+ style->widgetlabel.points = 11;
+ style->widgetlabel.kerning = 1;
+ style->widgetlabel.shadow = 3;
+ style->widgetlabel.shadx = 0;
+ style->widgetlabel.shady = -1;
+ style->widgetlabel.shadowalpha = 0.5f;
+ style->widgetlabel.shadowcolor = 0.0f;
+
+ style->widget.uifont_id = uifont_id;
+ style->widget.points = 11;
+ style->widget.kerning = 1;
+ style->widget.shadow = 1;
+ style->widget.shady = -1;
+ style->widget.shadowalpha = 0.5f;
+ style->widget.shadowcolor = 0.0f;
+
+ style->columnspace = 8;
+ style->templatespace = 5;
+ style->boxspace = 5;
+ style->buttonspacex = 8;
+ style->buttonspacey = 2;
+ style->panelspace = 8;
+ style->panelouter = 4;
+
+ return style;
}
static uiFont *uifont_to_blfont(int id)
{
- uiFont *font = U.uifonts.first;
-
- for (; font; font = font->next) {
- if (font->uifont_id == id) {
- return font;
- }
- }
- return U.uifonts.first;
+ uiFont *font = U.uifonts.first;
+
+ for (; font; font = font->next) {
+ if (font->uifont_id == id) {
+ return font;
+ }
+ }
+ return U.uifonts.first;
}
/* *************** draw ************************ */
-
-void UI_fontstyle_draw_ex(
- const uiFontStyle *fs, const rcti *rect, const char *str, const uchar col[4],
- const struct uiFontStyleDraw_Params *fs_params,
- size_t len, float *r_xofs, float *r_yofs)
+void UI_fontstyle_draw_ex(const uiFontStyle *fs,
+ const rcti *rect,
+ const char *str,
+ const uchar col[4],
+ const struct uiFontStyleDraw_Params *fs_params,
+ size_t len,
+ float *r_xofs,
+ float *r_yofs)
{
- int xofs = 0, yofs;
- int font_flag = BLF_CLIPPING;
-
- UI_fontstyle_set(fs);
-
- /* set the flag */
- if (fs->shadow) {
- font_flag |= BLF_SHADOW;
- const float shadow_color[4] = {fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha};
- BLF_shadow(fs->uifont_id, fs->shadow, shadow_color);
- BLF_shadow_offset(fs->uifont_id, fs->shadx, fs->shady);
- }
- if (fs->kerning == 1) {
- font_flag |= BLF_KERNING_DEFAULT;
- }
- if (fs_params->word_wrap == 1) {
- font_flag |= BLF_WORD_WRAP;
- }
-
- BLF_enable(fs->uifont_id, font_flag);
-
- if (fs_params->word_wrap == 1) {
- /* draw from boundbox top */
- yofs = BLI_rcti_size_y(rect) - BLF_height_max(fs->uifont_id);
- }
- else {
- /* draw from boundbox center */
- float height = BLF_ascender(fs->uifont_id) + BLF_descender(fs->uifont_id);
- yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height));
- }
-
- if (fs_params->align == UI_STYLE_TEXT_CENTER) {
- xofs = floor(0.5f * (BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len)));
- }
- else if (fs_params->align == UI_STYLE_TEXT_RIGHT) {
- xofs = BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len);
- }
-
- yofs = MAX2(0, yofs);
- xofs = MAX2(0, xofs);
-
- BLF_clipping(fs->uifont_id, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f);
- BLF_color4ubv(fs->uifont_id, col);
-
- BLF_draw(fs->uifont_id, str, len);
-
- BLF_disable(fs->uifont_id, font_flag);
-
- *r_xofs = xofs;
- *r_yofs = yofs;
+ int xofs = 0, yofs;
+ int font_flag = BLF_CLIPPING;
+
+ UI_fontstyle_set(fs);
+
+ /* set the flag */
+ if (fs->shadow) {
+ font_flag |= BLF_SHADOW;
+ const float shadow_color[4] = {
+ fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha};
+ BLF_shadow(fs->uifont_id, fs->shadow, shadow_color);
+ BLF_shadow_offset(fs->uifont_id, fs->shadx, fs->shady);
+ }
+ if (fs->kerning == 1) {
+ font_flag |= BLF_KERNING_DEFAULT;
+ }
+ if (fs_params->word_wrap == 1) {
+ font_flag |= BLF_WORD_WRAP;
+ }
+
+ BLF_enable(fs->uifont_id, font_flag);
+
+ if (fs_params->word_wrap == 1) {
+ /* draw from boundbox top */
+ yofs = BLI_rcti_size_y(rect) - BLF_height_max(fs->uifont_id);
+ }
+ else {
+ /* draw from boundbox center */
+ float height = BLF_ascender(fs->uifont_id) + BLF_descender(fs->uifont_id);
+ yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height));
+ }
+
+ if (fs_params->align == UI_STYLE_TEXT_CENTER) {
+ xofs = floor(0.5f * (BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len)));
+ }
+ else if (fs_params->align == UI_STYLE_TEXT_RIGHT) {
+ xofs = BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len);
+ }
+
+ yofs = MAX2(0, yofs);
+ xofs = MAX2(0, xofs);
+
+ BLF_clipping(fs->uifont_id, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f);
+ BLF_color4ubv(fs->uifont_id, col);
+
+ BLF_draw(fs->uifont_id, str, len);
+
+ BLF_disable(fs->uifont_id, font_flag);
+
+ *r_xofs = xofs;
+ *r_yofs = yofs;
}
-void UI_fontstyle_draw(
- const uiFontStyle *fs, const rcti *rect, const char *str, const uchar col[4],
- const struct uiFontStyleDraw_Params *fs_params)
+void UI_fontstyle_draw(const uiFontStyle *fs,
+ const rcti *rect,
+ const char *str,
+ const uchar col[4],
+ const struct uiFontStyleDraw_Params *fs_params)
{
- float xofs, yofs;
+ float xofs, yofs;
- UI_fontstyle_draw_ex(
- fs, rect, str, col, fs_params,
- BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs);
+ UI_fontstyle_draw_ex(fs, rect, str, col, fs_params, BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs);
}
/* drawn same as above, but at 90 degree angle */
-void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const char *str, const uchar col[4])
+void UI_fontstyle_draw_rotated(const uiFontStyle *fs,
+ const rcti *rect,
+ const char *str,
+ const uchar col[4])
{
- float height;
- int xofs, yofs;
- float angle;
- rcti txtrect;
-
- UI_fontstyle_set(fs);
-
- height = BLF_ascender(fs->uifont_id) + BLF_descender(fs->uifont_id);
- /* becomes x-offset when rotated */
- xofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height));
-
- /* ignore UI_STYLE, always aligned to top */
-
- /* rotate counter-clockwise for now (assumes left-to-right language)*/
- xofs += height;
- yofs = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX) + 5;
- angle = M_PI_2;
-
- /* translate rect to vertical */
- txtrect.xmin = rect->xmin - BLI_rcti_size_y(rect);
- txtrect.ymin = rect->ymin - BLI_rcti_size_x(rect);
- txtrect.xmax = rect->xmin;
- txtrect.ymax = rect->ymin;
-
- /* clip is very strict, so we give it some space */
- /* clipping is done without rotation, so make rect big enough to contain both positions */
- BLF_clipping(fs->uifont_id, txtrect.xmin - 1, txtrect.ymin - yofs - xofs - 4, rect->xmax + 1, rect->ymax + 4);
- BLF_enable(fs->uifont_id, BLF_CLIPPING);
- BLF_position(fs->uifont_id, txtrect.xmin + xofs, txtrect.ymax - yofs, 0.0f);
-
- BLF_enable(fs->uifont_id, BLF_ROTATION);
- BLF_rotation(fs->uifont_id, angle);
- BLF_color4ubv(fs->uifont_id, col);
-
- if (fs->shadow) {
- BLF_enable(fs->uifont_id, BLF_SHADOW);
- const float shadow_color[4] = {fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha};
- BLF_shadow(fs->uifont_id, fs->shadow, shadow_color);
- BLF_shadow_offset(fs->uifont_id, fs->shadx, fs->shady);
- }
-
- if (fs->kerning == 1) {
- BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
- BLF_disable(fs->uifont_id, BLF_ROTATION);
- BLF_disable(fs->uifont_id, BLF_CLIPPING);
- if (fs->shadow) {
- BLF_disable(fs->uifont_id, BLF_SHADOW);
- }
- if (fs->kerning == 1) {
- BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
+ float height;
+ int xofs, yofs;
+ float angle;
+ rcti txtrect;
+
+ UI_fontstyle_set(fs);
+
+ height = BLF_ascender(fs->uifont_id) + BLF_descender(fs->uifont_id);
+ /* becomes x-offset when rotated */
+ xofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height));
+
+ /* ignore UI_STYLE, always aligned to top */
+
+ /* rotate counter-clockwise for now (assumes left-to-right language)*/
+ xofs += height;
+ yofs = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX) + 5;
+ angle = M_PI_2;
+
+ /* translate rect to vertical */
+ txtrect.xmin = rect->xmin - BLI_rcti_size_y(rect);
+ txtrect.ymin = rect->ymin - BLI_rcti_size_x(rect);
+ txtrect.xmax = rect->xmin;
+ txtrect.ymax = rect->ymin;
+
+ /* clip is very strict, so we give it some space */
+ /* clipping is done without rotation, so make rect big enough to contain both positions */
+ BLF_clipping(fs->uifont_id,
+ txtrect.xmin - 1,
+ txtrect.ymin - yofs - xofs - 4,
+ rect->xmax + 1,
+ rect->ymax + 4);
+ BLF_enable(fs->uifont_id, BLF_CLIPPING);
+ BLF_position(fs->uifont_id, txtrect.xmin + xofs, txtrect.ymax - yofs, 0.0f);
+
+ BLF_enable(fs->uifont_id, BLF_ROTATION);
+ BLF_rotation(fs->uifont_id, angle);
+ BLF_color4ubv(fs->uifont_id, col);
+
+ if (fs->shadow) {
+ BLF_enable(fs->uifont_id, BLF_SHADOW);
+ const float shadow_color[4] = {
+ fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha};
+ BLF_shadow(fs->uifont_id, fs->shadow, shadow_color);
+ BLF_shadow_offset(fs->uifont_id, fs->shadx, fs->shady);
+ }
+
+ if (fs->kerning == 1) {
+ BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_disable(fs->uifont_id, BLF_ROTATION);
+ BLF_disable(fs->uifont_id, BLF_CLIPPING);
+ if (fs->shadow) {
+ BLF_disable(fs->uifont_id, BLF_SHADOW);
+ }
+ if (fs->kerning == 1) {
+ BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
}
/**
@@ -278,313 +288,311 @@ void UI_fontstyle_draw_rotated(const uiFontStyle *fs, const rcti *rect, const ch
*
* For drawing on-screen labels.
*/
-void UI_fontstyle_draw_simple(const uiFontStyle *fs, float x, float y, const char *str, const uchar col[4])
+void UI_fontstyle_draw_simple(
+ const uiFontStyle *fs, float x, float y, const char *str, const uchar col[4])
{
- if (fs->kerning == 1) {
- BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- UI_fontstyle_set(fs);
- BLF_position(fs->uifont_id, x, y, 0.0f);
- BLF_color4ubv(fs->uifont_id, col);
- BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
-
- if (fs->kerning == 1) {
- BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
+ if (fs->kerning == 1) {
+ BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ UI_fontstyle_set(fs);
+ BLF_position(fs->uifont_id, x, y, 0.0f);
+ BLF_color4ubv(fs->uifont_id, col);
+ BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+
+ if (fs->kerning == 1) {
+ BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
}
/**
* Same as #UI_fontstyle_draw but draw a colored backdrop.
*/
-void UI_fontstyle_draw_simple_backdrop(
- const uiFontStyle *fs, float x, float y, const char *str,
- const float col_fg[4], const float col_bg[4])
+void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs,
+ float x,
+ float y,
+ const char *str,
+ const float col_fg[4],
+ const float col_bg[4])
{
- if (fs->kerning == 1) {
- BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- UI_fontstyle_set(fs);
-
- {
- const float width = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
- const float height = BLF_height_max(fs->uifont_id);
- const float decent = BLF_descender(fs->uifont_id);
- const float margin = height / 4.0f;
-
- /* backdrop */
- float color[4] = { col_bg[0], col_bg[1], col_bg[2], 0.5f };
-
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(
- true,
- x - margin,
- (y + decent) - margin,
- x + width + margin,
- (y + decent) + height + margin,
- margin, color);
- }
-
- BLF_position(fs->uifont_id, x, y, 0.0f);
- BLF_color4fv(fs->uifont_id, col_fg);
- BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
-
- if (fs->kerning == 1) {
- BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
+ if (fs->kerning == 1) {
+ BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ UI_fontstyle_set(fs);
+
+ {
+ const float width = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ const float height = BLF_height_max(fs->uifont_id);
+ const float decent = BLF_descender(fs->uifont_id);
+ const float margin = height / 4.0f;
+
+ /* backdrop */
+ float color[4] = {col_bg[0], col_bg[1], col_bg[2], 0.5f};
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
+ x - margin,
+ (y + decent) - margin,
+ x + width + margin,
+ (y + decent) + height + margin,
+ margin,
+ color);
+ }
+
+ BLF_position(fs->uifont_id, x, y, 0.0f);
+ BLF_color4fv(fs->uifont_id, col_fg);
+ BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+
+ if (fs->kerning == 1) {
+ BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
}
-
/* ************** helpers ************************ */
/* XXX: read a style configure */
uiStyle *UI_style_get(void)
{
#if 0
- uiStyle *style = NULL;
- /* offset is two struct uiStyle pointers */
- style = BLI_findstring(&U.uistyles, "Unifont Style", sizeof(style) * 2);
- return (style != NULL) ? style : U.uistyles.first;
+ uiStyle *style = NULL;
+ /* offset is two struct uiStyle pointers */
+ style = BLI_findstring(&U.uistyles, "Unifont Style", sizeof(style) * 2);
+ return (style != NULL) ? style : U.uistyles.first;
#else
- return U.uistyles.first;
+ return U.uistyles.first;
#endif
}
/* for drawing, scaled with DPI setting */
uiStyle *UI_style_get_dpi(void)
{
- uiStyle *style = UI_style_get();
- static uiStyle _style;
-
- _style = *style;
-
- _style.paneltitle.shadx = (short)(UI_DPI_FAC * _style.paneltitle.shadx);
- _style.paneltitle.shady = (short)(UI_DPI_FAC * _style.paneltitle.shady);
- _style.grouplabel.shadx = (short)(UI_DPI_FAC * _style.grouplabel.shadx);
- _style.grouplabel.shady = (short)(UI_DPI_FAC * _style.grouplabel.shady);
- _style.widgetlabel.shadx = (short)(UI_DPI_FAC * _style.widgetlabel.shadx);
- _style.widgetlabel.shady = (short)(UI_DPI_FAC * _style.widgetlabel.shady);
-
- _style.columnspace = (short)(UI_DPI_FAC * _style.columnspace);
- _style.templatespace = (short)(UI_DPI_FAC * _style.templatespace);
- _style.boxspace = (short)(UI_DPI_FAC * _style.boxspace);
- _style.buttonspacex = (short)(UI_DPI_FAC * _style.buttonspacex);
- _style.buttonspacey = (short)(UI_DPI_FAC * _style.buttonspacey);
- _style.panelspace = (short)(UI_DPI_FAC * _style.panelspace);
- _style.panelouter = (short)(UI_DPI_FAC * _style.panelouter);
-
- return &_style;
+ uiStyle *style = UI_style_get();
+ static uiStyle _style;
+
+ _style = *style;
+
+ _style.paneltitle.shadx = (short)(UI_DPI_FAC * _style.paneltitle.shadx);
+ _style.paneltitle.shady = (short)(UI_DPI_FAC * _style.paneltitle.shady);
+ _style.grouplabel.shadx = (short)(UI_DPI_FAC * _style.grouplabel.shadx);
+ _style.grouplabel.shady = (short)(UI_DPI_FAC * _style.grouplabel.shady);
+ _style.widgetlabel.shadx = (short)(UI_DPI_FAC * _style.widgetlabel.shadx);
+ _style.widgetlabel.shady = (short)(UI_DPI_FAC * _style.widgetlabel.shady);
+
+ _style.columnspace = (short)(UI_DPI_FAC * _style.columnspace);
+ _style.templatespace = (short)(UI_DPI_FAC * _style.templatespace);
+ _style.boxspace = (short)(UI_DPI_FAC * _style.boxspace);
+ _style.buttonspacex = (short)(UI_DPI_FAC * _style.buttonspacex);
+ _style.buttonspacey = (short)(UI_DPI_FAC * _style.buttonspacey);
+ _style.panelspace = (short)(UI_DPI_FAC * _style.panelspace);
+ _style.panelouter = (short)(UI_DPI_FAC * _style.panelouter);
+
+ return &_style;
}
int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str)
{
- int width;
+ int width;
- if (fs->kerning == 1) {
- /* for BLF_width */
- BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
+ if (fs->kerning == 1) {
+ /* for BLF_width */
+ BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
- UI_fontstyle_set(fs);
- width = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ UI_fontstyle_set(fs);
+ width = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX);
- if (fs->kerning == 1) {
- BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
- }
+ if (fs->kerning == 1) {
+ BLF_disable(fs->uifont_id, BLF_KERNING_DEFAULT);
+ }
- return width;
+ return width;
}
int UI_fontstyle_height_max(const uiFontStyle *fs)
{
- UI_fontstyle_set(fs);
- return BLF_height_max(fs->uifont_id);
+ UI_fontstyle_set(fs);
+ return BLF_height_max(fs->uifont_id);
}
-
/* ************** init exit ************************ */
/* called on each startup.blend read */
/* reading without uifont will create one */
void uiStyleInit(void)
{
- uiFont *font;
- uiStyle *style = U.uistyles.first;
- int monofont_size = datatoc_bmonofont_ttf_size;
- uchar *monofont_ttf = (uchar *)datatoc_bmonofont_ttf;
-
- /* recover from uninitialized dpi */
- if (U.dpi == 0) {
- U.dpi = 72;
- }
- CLAMP(U.dpi, 48, 144);
-
- for (font = U.uifonts.first; font; font = font->next) {
- BLF_unload_id(font->blf_id);
- }
-
- if (blf_mono_font != -1) {
- BLF_unload_id(blf_mono_font);
- blf_mono_font = -1;
- }
-
- if (blf_mono_font_render != -1) {
- BLF_unload_id(blf_mono_font_render);
- blf_mono_font_render = -1;
- }
-
- font = U.uifonts.first;
-
- /* default builtin */
- if (font == NULL) {
- font = MEM_callocN(sizeof(uiFont), "ui font");
- BLI_addtail(&U.uifonts, font);
- }
-
- if (U.font_path_ui[0]) {
- BLI_strncpy(font->filename, U.font_path_ui, sizeof(font->filename));
- font->uifont_id = UIFONT_CUSTOM1;
- }
- else {
- BLI_strncpy(font->filename, "default", sizeof(font->filename));
- font->uifont_id = UIFONT_DEFAULT;
- }
-
- for (font = U.uifonts.first; font; font = font->next) {
-
- if (font->uifont_id == UIFONT_DEFAULT) {
+ uiFont *font;
+ uiStyle *style = U.uistyles.first;
+ int monofont_size = datatoc_bmonofont_ttf_size;
+ uchar *monofont_ttf = (uchar *)datatoc_bmonofont_ttf;
+
+ /* recover from uninitialized dpi */
+ if (U.dpi == 0) {
+ U.dpi = 72;
+ }
+ CLAMP(U.dpi, 48, 144);
+
+ for (font = U.uifonts.first; font; font = font->next) {
+ BLF_unload_id(font->blf_id);
+ }
+
+ if (blf_mono_font != -1) {
+ BLF_unload_id(blf_mono_font);
+ blf_mono_font = -1;
+ }
+
+ if (blf_mono_font_render != -1) {
+ BLF_unload_id(blf_mono_font_render);
+ blf_mono_font_render = -1;
+ }
+
+ font = U.uifonts.first;
+
+ /* default builtin */
+ if (font == NULL) {
+ font = MEM_callocN(sizeof(uiFont), "ui font");
+ BLI_addtail(&U.uifonts, font);
+ }
+
+ if (U.font_path_ui[0]) {
+ BLI_strncpy(font->filename, U.font_path_ui, sizeof(font->filename));
+ font->uifont_id = UIFONT_CUSTOM1;
+ }
+ else {
+ BLI_strncpy(font->filename, "default", sizeof(font->filename));
+ font->uifont_id = UIFONT_DEFAULT;
+ }
+
+ for (font = U.uifonts.first; font; font = font->next) {
+
+ if (font->uifont_id == UIFONT_DEFAULT) {
#ifdef WITH_INTERNATIONAL
- int font_size = datatoc_bfont_ttf_size;
- uchar *font_ttf = (uchar *)datatoc_bfont_ttf;
- static int last_font_size = 0;
-
- /* use unicode font for translation */
- if (U.transopts & USER_DOTRANSLATE) {
- font_ttf = BLF_get_unifont(&font_size);
-
- if (!font_ttf) {
- /* fall back if not found */
- font_size = datatoc_bfont_ttf_size;
- font_ttf = (uchar *)datatoc_bfont_ttf;
- }
- }
-
- /* relload only if needed */
- if (last_font_size != font_size) {
- BLF_unload("default");
- last_font_size = font_size;
- }
-
- font->blf_id = BLF_load_mem("default", font_ttf, font_size);
+ int font_size = datatoc_bfont_ttf_size;
+ uchar *font_ttf = (uchar *)datatoc_bfont_ttf;
+ static int last_font_size = 0;
+
+ /* use unicode font for translation */
+ if (U.transopts & USER_DOTRANSLATE) {
+ font_ttf = BLF_get_unifont(&font_size);
+
+ if (!font_ttf) {
+ /* fall back if not found */
+ font_size = datatoc_bfont_ttf_size;
+ font_ttf = (uchar *)datatoc_bfont_ttf;
+ }
+ }
+
+ /* relload only if needed */
+ if (last_font_size != font_size) {
+ BLF_unload("default");
+ last_font_size = font_size;
+ }
+
+ font->blf_id = BLF_load_mem("default", font_ttf, font_size);
#else
- font->blf_id = BLF_load_mem("default", (uchar *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
+ font->blf_id = BLF_load_mem("default", (uchar *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
#endif
- }
- else {
- font->blf_id = BLF_load(font->filename);
- if (font->blf_id == -1) {
- font->blf_id = BLF_load_mem("default", (uchar *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
- }
- }
-
- BLF_default_set(font->blf_id);
-
- if (font->blf_id == -1) {
- if (G.debug & G_DEBUG) {
- printf("%s: error, no fonts available\n", __func__);
- }
- }
- else {
- /* ? just for speed to initialize?
- * Yes, this build the glyph cache and create
- * the texture.
- */
- BLF_size(font->blf_id, 11 * U.pixelsize, U.dpi);
- BLF_size(font->blf_id, 12 * U.pixelsize, U.dpi);
- BLF_size(font->blf_id, 14 * U.pixelsize, U.dpi);
- }
- }
-
- if (style == NULL) {
- ui_style_new(&U.uistyles, "Default Style", UIFONT_DEFAULT);
- }
+ }
+ else {
+ font->blf_id = BLF_load(font->filename);
+ if (font->blf_id == -1) {
+ font->blf_id = BLF_load_mem("default", (uchar *)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
+ }
+ }
+
+ BLF_default_set(font->blf_id);
+
+ if (font->blf_id == -1) {
+ if (G.debug & G_DEBUG) {
+ printf("%s: error, no fonts available\n", __func__);
+ }
+ }
+ else {
+ /* ? just for speed to initialize?
+ * Yes, this build the glyph cache and create
+ * the texture.
+ */
+ BLF_size(font->blf_id, 11 * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, 12 * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, 14 * U.pixelsize, U.dpi);
+ }
+ }
+
+ if (style == NULL) {
+ ui_style_new(&U.uistyles, "Default Style", UIFONT_DEFAULT);
+ }
#ifdef WITH_INTERNATIONAL
- /* use unicode font for text editor and interactive console */
- if (U.transopts & USER_DOTRANSLATE) {
- monofont_ttf = BLF_get_unifont_mono(&monofont_size);
-
- if (!monofont_ttf) {
- /* fall back if not found */
- monofont_size = datatoc_bmonofont_ttf_size;
- monofont_ttf = (uchar *)datatoc_bmonofont_ttf;
- }
- }
+ /* use unicode font for text editor and interactive console */
+ if (U.transopts & USER_DOTRANSLATE) {
+ monofont_ttf = BLF_get_unifont_mono(&monofont_size);
+
+ if (!monofont_ttf) {
+ /* fall back if not found */
+ monofont_size = datatoc_bmonofont_ttf_size;
+ monofont_ttf = (uchar *)datatoc_bmonofont_ttf;
+ }
+ }
#endif
- /* XXX, this should be moved into a style,
- * but for now best only load the monospaced font once. */
- BLI_assert(blf_mono_font == -1);
- if (U.font_path_ui_mono[0]) {
- blf_mono_font = BLF_load_unique(U.font_path_ui_mono);
- }
- if (blf_mono_font == -1) {
- blf_mono_font = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
- }
-
- BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
-
- /* Set default flags based on UI preferences (not render fonts) */
- {
- int flag_disable = (
- BLF_MONOCHROME |
- BLF_HINTING_NONE |
- BLF_HINTING_SLIGHT |
- BLF_HINTING_FULL);
- int flag_enable = 0;
-
- if (U.text_render & USER_TEXT_HINTING_NONE) {
- flag_enable |= BLF_HINTING_NONE;
- }
- else if (U.text_render & USER_TEXT_HINTING_SLIGHT) {
- flag_enable |= BLF_HINTING_SLIGHT;
- }
- else if (U.text_render & USER_TEXT_HINTING_FULL) {
- flag_enable |= BLF_HINTING_FULL;
- }
-
- if (U.text_render & USER_TEXT_DISABLE_AA) {
- flag_enable |= BLF_MONOCHROME;
- }
-
- for (font = U.uifonts.first; font; font = font->next) {
- if (font->blf_id != -1) {
- BLF_disable(font->blf_id, flag_disable);
- BLF_enable(font->blf_id, flag_enable);
- }
- }
- if (blf_mono_font != -1) {
- BLF_disable(blf_mono_font, flag_disable);
- BLF_enable(blf_mono_font, flag_enable);
- }
- }
-
- /**
- * Second for rendering else we get threading problems,
- *
- * \note This isn't good that the render font depends on the preferences,
- * keep for now though, since without this there is no way to display many unicode chars.
- */
- if (blf_mono_font_render == -1) {
- blf_mono_font_render = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
- }
-
- BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72);
+ /* XXX, this should be moved into a style,
+ * but for now best only load the monospaced font once. */
+ BLI_assert(blf_mono_font == -1);
+ if (U.font_path_ui_mono[0]) {
+ blf_mono_font = BLF_load_unique(U.font_path_ui_mono);
+ }
+ if (blf_mono_font == -1) {
+ blf_mono_font = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
+ }
+
+ BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
+
+ /* Set default flags based on UI preferences (not render fonts) */
+ {
+ int flag_disable = (BLF_MONOCHROME | BLF_HINTING_NONE | BLF_HINTING_SLIGHT | BLF_HINTING_FULL);
+ int flag_enable = 0;
+
+ if (U.text_render & USER_TEXT_HINTING_NONE) {
+ flag_enable |= BLF_HINTING_NONE;
+ }
+ else if (U.text_render & USER_TEXT_HINTING_SLIGHT) {
+ flag_enable |= BLF_HINTING_SLIGHT;
+ }
+ else if (U.text_render & USER_TEXT_HINTING_FULL) {
+ flag_enable |= BLF_HINTING_FULL;
+ }
+
+ if (U.text_render & USER_TEXT_DISABLE_AA) {
+ flag_enable |= BLF_MONOCHROME;
+ }
+
+ for (font = U.uifonts.first; font; font = font->next) {
+ if (font->blf_id != -1) {
+ BLF_disable(font->blf_id, flag_disable);
+ BLF_enable(font->blf_id, flag_enable);
+ }
+ }
+ if (blf_mono_font != -1) {
+ BLF_disable(blf_mono_font, flag_disable);
+ BLF_enable(blf_mono_font, flag_enable);
+ }
+ }
+
+ /**
+ * Second for rendering else we get threading problems,
+ *
+ * \note This isn't good that the render font depends on the preferences,
+ * keep for now though, since without this there is no way to display many unicode chars.
+ */
+ if (blf_mono_font_render == -1) {
+ blf_mono_font_render = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
+ }
+
+ BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72);
}
void UI_fontstyle_set(const uiFontStyle *fs)
{
- uiFont *font = uifont_to_blfont(fs->uifont_id);
+ uiFont *font = uifont_to_blfont(fs->uifont_id);
- BLF_size(font->blf_id, fs->points * U.pixelsize, U.dpi);
+ BLF_size(font->blf_id, fs->points * U.pixelsize, U.dpi);
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 897a07708d0..6666991ad26 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -18,7 +18,6 @@
* \ingroup edinterface
*/
-
#include <ctype.h>
#include <stdlib.h>
#include <stddef.h>
@@ -95,13 +94,11 @@
#include "PIL_time.h"
-
// #define USE_OP_RESET_BUT // we may want to make this optional, disable for now.
/* defines for templateID/TemplateSearch */
-#define TEMPLATE_SEARCH_TEXTBUT_WIDTH (UI_UNIT_X * 6)
-#define TEMPLATE_SEARCH_TEXTBUT_HEIGHT UI_UNIT_Y
-
+#define TEMPLATE_SEARCH_TEXTBUT_WIDTH (UI_UNIT_X * 6)
+#define TEMPLATE_SEARCH_TEXTBUT_HEIGHT UI_UNIT_Y
void UI_template_fix_linking(void)
{
@@ -110,463 +107,543 @@ void UI_template_fix_linking(void)
/**
* Add a block button for the search menu for templateID and templateSearch.
*/
-static void template_add_button_search_menu(
- const bContext *C, uiLayout *layout, uiBlock *block,
- PointerRNA *ptr, PropertyRNA *prop,
- uiBlockCreateFunc block_func, void *block_argN, const char * const tip,
- const bool use_previews, const bool editable, const bool live_icon)
+static void template_add_button_search_menu(const bContext *C,
+ uiLayout *layout,
+ uiBlock *block,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ uiBlockCreateFunc block_func,
+ void *block_argN,
+ const char *const tip,
+ const bool use_previews,
+ const bool editable,
+ const bool live_icon)
{
- PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
- ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
- const ID *idfrom = ptr->id.data;
- const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
- uiBut *but;
-
- if (use_previews) {
- ARegion *region = CTX_wm_region(C);
- ScrArea *area = CTX_wm_area(C);
- /* XXX ugly top-bar exception */
- const bool use_big_size = (
- /* silly check, could be more generic */
- (region->regiontype != RGN_TYPE_HEADER) &&
- (area->spacetype != SPACE_TOPBAR));
- /* Ugly exception for screens here,
- * drawing their preview in icon size looks ugly/useless */
- const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
- const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
- const short height = UI_UNIT_Y * (use_big_size ? 6 : 1);
-
- but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
- if (use_preview_icon) {
- int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
- ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
- }
- else {
- ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
- UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
- }
-
- if ((idfrom && idfrom->lib) || !editable) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- if (use_big_size) {
- uiLayoutRow(layout, true);
- }
- }
- else {
- but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
-
- if (live_icon) {
- int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type);
- ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
- }
- else {
- ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
- }
- if (id) {
- /* default dragging of icon for id browse buttons */
- UI_but_drag_set_id(but, id);
- }
- UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
-
- if ((idfrom && idfrom->lib) || !editable) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- }
+ PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop);
+ ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL;
+ const ID *idfrom = ptr->id.data;
+ const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop);
+ uiBut *but;
+
+ if (use_previews) {
+ ARegion *region = CTX_wm_region(C);
+ ScrArea *area = CTX_wm_area(C);
+ /* XXX ugly top-bar exception */
+ const bool use_big_size = (
+ /* silly check, could be more generic */
+ (region->regiontype != RGN_TYPE_HEADER) && (area->spacetype != SPACE_TOPBAR));
+ /* Ugly exception for screens here,
+ * drawing their preview in icon size looks ugly/useless */
+ const bool use_preview_icon = use_big_size || (id && (GS(id->name) != ID_SCR));
+ const short width = UI_UNIT_X * (use_big_size ? 6 : 1.6f);
+ const short height = UI_UNIT_Y * (use_big_size ? 6 : 1);
+
+ but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip);
+ if (use_preview_icon) {
+ int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type);
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ }
+ else {
+ ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
+ UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
+ }
+
+ if ((idfrom && idfrom->lib) || !editable) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ if (use_big_size) {
+ uiLayoutRow(layout, true);
+ }
+ }
+ else {
+ but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip);
+
+ if (live_icon) {
+ int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type);
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ }
+ else {
+ ui_def_but_icon(but, RNA_struct_ui_icon(type), UI_HAS_ICON);
+ }
+ if (id) {
+ /* default dragging of icon for id browse buttons */
+ UI_but_drag_set_id(but, id);
+ }
+ UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT);
+
+ if ((idfrom && idfrom->lib) || !editable) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ }
}
-static uiBlock *template_common_search_menu(
- const bContext *C, ARegion *region,
- uiButSearchFunc search_func, void *search_arg,
- uiButHandleFunc handle_func, void *active_item,
- const int preview_rows, const int preview_cols,
- float scale)
+static uiBlock *template_common_search_menu(const bContext *C,
+ ARegion *region,
+ uiButSearchFunc search_func,
+ void *search_arg,
+ uiButHandleFunc handle_func,
+ void *active_item,
+ const int preview_rows,
+ const int preview_cols,
+ float scale)
{
- static char search[256];
- wmWindow *win = CTX_wm_window(C);
- uiBlock *block;
- uiBut *but;
-
- /* clear initial search string, then all items show */
- search[0] = 0;
-
- block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
-
- /* preview thumbnails */
- if (preview_rows > 0 && preview_cols > 0) {
- const int w = 4 * U.widget_unit * preview_cols * scale;
- const int h = 5 * U.widget_unit * preview_rows * scale;
-
- /* fake button, it holds space for search items */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
-
- but = uiDefSearchBut(
- block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0, w, UI_UNIT_Y,
- preview_rows, preview_cols, "");
- }
- /* list view */
- else {
- const int searchbox_width = UI_searchbox_size_x();
- const int searchbox_height = UI_searchbox_size_y();
-
- /* fake button, it holds space for search items */
- uiDefBut(
- block, UI_BTYPE_LABEL, 0, "", 10, 15, searchbox_width, searchbox_height,
- NULL, 0, 0, 0, 0, NULL);
- but = uiDefSearchBut(
- block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 0,
- searchbox_width, UI_UNIT_Y - 1, 0, 0, "");
- }
- UI_but_func_search_set(
- but, ui_searchbox_create_generic, search_func,
- search_arg, false, handle_func, active_item);
-
-
- UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
- UI_block_direction_set(block, UI_DIR_DOWN);
-
- /* give search-field focus */
- UI_but_focus_on_enter_event(win, but);
- /* this type of search menu requires undo */
- but->flag |= UI_BUT_UNDO;
-
- return block;
+ static char search[256];
+ wmWindow *win = CTX_wm_window(C);
+ uiBlock *block;
+ uiBut *but;
+
+ /* clear initial search string, then all items show */
+ search[0] = 0;
+
+ block = UI_block_begin(C, region, "_popup", UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_SEARCH_MENU);
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+
+ /* preview thumbnails */
+ if (preview_rows > 0 && preview_cols > 0) {
+ const int w = 4 * U.widget_unit * preview_cols * scale;
+ const int h = 5 * U.widget_unit * preview_rows * scale;
+
+ /* fake button, it holds space for search items */
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", 10, 26, w, h, NULL, 0, 0, 0, 0, NULL);
+
+ but = uiDefSearchBut(block,
+ search,
+ 0,
+ ICON_VIEWZOOM,
+ sizeof(search),
+ 10,
+ 0,
+ w,
+ UI_UNIT_Y,
+ preview_rows,
+ preview_cols,
+ "");
+ }
+ /* list view */
+ else {
+ const int searchbox_width = UI_searchbox_size_x();
+ const int searchbox_height = UI_searchbox_size_y();
+
+ /* fake button, it holds space for search items */
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ "",
+ 10,
+ 15,
+ searchbox_width,
+ searchbox_height,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ but = uiDefSearchBut(block,
+ search,
+ 0,
+ ICON_VIEWZOOM,
+ sizeof(search),
+ 10,
+ 0,
+ searchbox_width,
+ UI_UNIT_Y - 1,
+ 0,
+ 0,
+ "");
+ }
+ UI_but_func_search_set(
+ but, ui_searchbox_create_generic, search_func, search_arg, false, handle_func, active_item);
+
+ UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
+ UI_block_direction_set(block, UI_DIR_DOWN);
+
+ /* give search-field focus */
+ UI_but_focus_on_enter_event(win, but);
+ /* this type of search menu requires undo */
+ but->flag |= UI_BUT_UNDO;
+
+ return block;
}
/********************** Header Template *************************/
void uiTemplateHeader(uiLayout *layout, bContext *C)
{
- uiBlock *block;
+ uiBlock *block;
- block = uiLayoutAbsoluteBlock(layout);
- ED_area_header_switchbutton(C, block, 0);
+ block = uiLayoutAbsoluteBlock(layout);
+ ED_area_header_switchbutton(C, block, 0);
}
/********************** Search Callbacks *************************/
typedef struct TemplateID {
- PointerRNA ptr;
- PropertyRNA *prop;
-
- ListBase *idlb;
- short idcode;
- short filter;
- int prv_rows, prv_cols;
- bool preview;
- float scale;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ ListBase *idlb;
+ short idcode;
+ short filter;
+ int prv_rows, prv_cols;
+ bool preview;
+ float scale;
} TemplateID;
/* Search browse menu, assign */
static void template_ID_set_property_cb(bContext *C, void *arg_template, void *item)
{
- TemplateID *template_ui = (TemplateID *)arg_template;
+ TemplateID *template_ui = (TemplateID *)arg_template;
- /* ID */
- if (item) {
- PointerRNA idptr;
+ /* ID */
+ if (item) {
+ PointerRNA idptr;
- RNA_id_pointer_create(item, &idptr);
- RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
- RNA_property_update(C, &template_ui->ptr, template_ui->prop);
- }
+ RNA_id_pointer_create(item, &idptr);
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_update(C, &template_ui->ptr, template_ui->prop);
+ }
}
-static bool id_search_add(
- const bContext *C, TemplateID *template_ui,
- const int flag, const char *str, uiSearchItems *items,
- ID *id)
+static bool id_search_add(const bContext *C,
+ TemplateID *template_ui,
+ const int flag,
+ const char *str,
+ uiSearchItems *items,
+ ID *id)
{
- ID *id_from = template_ui->ptr.id.data;
-
- if (!((flag & PROP_ID_SELF_CHECK) && id == id_from)) {
-
- /* use filter */
- if (RNA_property_type(template_ui->prop) == PROP_POINTER) {
- PointerRNA ptr;
- RNA_id_pointer_create(id, &ptr);
- if (RNA_property_pointer_poll(&template_ui->ptr, template_ui->prop, &ptr) == 0) {
- return true;
- }
- }
-
- /* hide dot-datablocks, but only if filter does not force it visible */
- if (U.uiflag & USER_HIDE_DOT) {
- if ((id->name[2] == '.') && (str[0] != '.')) {
- return true;
- }
- }
-
- if (*str == '\0' || BLI_strcasestr(id->name + 2, str)) {
- /* +1 is needed because BKE_id_ui_prefix used 3 letter prefix
- * followed by ID_NAME-2 characters from id->name
- */
- char name_ui[MAX_ID_FULL_NAME_UI];
- BKE_id_full_name_ui_prefix_get(name_ui, id);
-
- int iconid = ui_id_icon_get(C, id, template_ui->preview);
-
- if (false == UI_search_item_add(items, name_ui, id, iconid)) {
- return false;
- }
- }
- }
- return true;
+ ID *id_from = template_ui->ptr.id.data;
+
+ if (!((flag & PROP_ID_SELF_CHECK) && id == id_from)) {
+
+ /* use filter */
+ if (RNA_property_type(template_ui->prop) == PROP_POINTER) {
+ PointerRNA ptr;
+ RNA_id_pointer_create(id, &ptr);
+ if (RNA_property_pointer_poll(&template_ui->ptr, template_ui->prop, &ptr) == 0) {
+ return true;
+ }
+ }
+
+ /* hide dot-datablocks, but only if filter does not force it visible */
+ if (U.uiflag & USER_HIDE_DOT) {
+ if ((id->name[2] == '.') && (str[0] != '.')) {
+ return true;
+ }
+ }
+
+ if (*str == '\0' || BLI_strcasestr(id->name + 2, str)) {
+ /* +1 is needed because BKE_id_ui_prefix used 3 letter prefix
+ * followed by ID_NAME-2 characters from id->name
+ */
+ char name_ui[MAX_ID_FULL_NAME_UI];
+ BKE_id_full_name_ui_prefix_get(name_ui, id);
+
+ int iconid = ui_id_icon_get(C, id, template_ui->preview);
+
+ if (false == UI_search_item_add(items, name_ui, id, iconid)) {
+ return false;
+ }
+ }
+ }
+ return true;
}
/* ID Search browse menu, do the search */
-static void id_search_cb(const bContext *C, void *arg_template, const char *str, uiSearchItems *items)
+static void id_search_cb(const bContext *C,
+ void *arg_template,
+ const char *str,
+ uiSearchItems *items)
{
- TemplateID *template_ui = (TemplateID *)arg_template;
- ListBase *lb = template_ui->idlb;
- ID *id;
- int flag = RNA_property_flag(template_ui->prop);
-
- /* ID listbase */
- for (id = lb->first; id; id = id->next) {
- if (!id_search_add(C, template_ui, flag, str, items, id)) {
- break;
- }
- }
+ TemplateID *template_ui = (TemplateID *)arg_template;
+ ListBase *lb = template_ui->idlb;
+ ID *id;
+ int flag = RNA_property_flag(template_ui->prop);
+
+ /* ID listbase */
+ for (id = lb->first; id; id = id->next) {
+ if (!id_search_add(C, template_ui, flag, str, items, id)) {
+ break;
+ }
+ }
}
/**
* Use id tags for filtering.
*/
-static void id_search_cb_tagged(const bContext *C, void *arg_template, const char *str, uiSearchItems *items)
+static void id_search_cb_tagged(const bContext *C,
+ void *arg_template,
+ const char *str,
+ uiSearchItems *items)
{
- TemplateID *template_ui = (TemplateID *)arg_template;
- ListBase *lb = template_ui->idlb;
- ID *id;
- int flag = RNA_property_flag(template_ui->prop);
-
- /* ID listbase */
- for (id = lb->first; id; id = id->next) {
- if (id->tag & LIB_TAG_DOIT) {
- if (!id_search_add(C, template_ui, flag, str, items, id)) {
- break;
- }
- id->tag &= ~LIB_TAG_DOIT;
- }
- }
+ TemplateID *template_ui = (TemplateID *)arg_template;
+ ListBase *lb = template_ui->idlb;
+ ID *id;
+ int flag = RNA_property_flag(template_ui->prop);
+
+ /* ID listbase */
+ for (id = lb->first; id; id = id->next) {
+ if (id->tag & LIB_TAG_DOIT) {
+ if (!id_search_add(C, template_ui, flag, str, items, id)) {
+ break;
+ }
+ id->tag &= ~LIB_TAG_DOIT;
+ }
+ }
}
/**
* A version of 'id_search_cb' that lists scene objects.
*/
-static void id_search_cb_objects_from_scene(const bContext *C, void *arg_template, const char *str, uiSearchItems *items)
+static void id_search_cb_objects_from_scene(const bContext *C,
+ void *arg_template,
+ const char *str,
+ uiSearchItems *items)
{
- TemplateID *template_ui = (TemplateID *)arg_template;
- ListBase *lb = template_ui->idlb;
- Scene *scene = NULL;
- ID *id_from = template_ui->ptr.id.data;
-
- if (id_from && GS(id_from->name) == ID_SCE) {
- scene = (Scene *)id_from;
- }
- else {
- scene = CTX_data_scene(C);
- }
-
- BKE_main_id_flag_listbase(lb, LIB_TAG_DOIT, false);
-
- FOREACH_SCENE_OBJECT_BEGIN(scene, ob_iter)
- {
- ob_iter->id.tag |= LIB_TAG_DOIT;
- }
- FOREACH_SCENE_OBJECT_END;
- id_search_cb_tagged(C, arg_template, str, items);
+ TemplateID *template_ui = (TemplateID *)arg_template;
+ ListBase *lb = template_ui->idlb;
+ Scene *scene = NULL;
+ ID *id_from = template_ui->ptr.id.data;
+
+ if (id_from && GS(id_from->name) == ID_SCE) {
+ scene = (Scene *)id_from;
+ }
+ else {
+ scene = CTX_data_scene(C);
+ }
+
+ BKE_main_id_flag_listbase(lb, LIB_TAG_DOIT, false);
+
+ FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
+ ob_iter->id.tag |= LIB_TAG_DOIT;
+ }
+ FOREACH_SCENE_OBJECT_END;
+ id_search_cb_tagged(C, arg_template, str, items);
}
/* ID Search browse menu, open */
static uiBlock *id_search_menu(bContext *C, ARegion *ar, void *arg_litem)
{
- static TemplateID template_ui;
- PointerRNA active_item_ptr;
- void (*id_search_cb_p)(const bContext *, void *, const char *, uiSearchItems *) = id_search_cb;
-
- /* arg_litem is malloced, can be freed by parent button */
- template_ui = *((TemplateID *)arg_litem);
- active_item_ptr = RNA_property_pointer_get(&template_ui.ptr, template_ui.prop);
-
- if (template_ui.filter) {
- /* Currently only used for objects. */
- if (template_ui.idcode == ID_OB) {
- if (template_ui.filter == UI_TEMPLATE_ID_FILTER_AVAILABLE) {
- id_search_cb_p = id_search_cb_objects_from_scene;
- }
- }
- }
-
- return template_common_search_menu(
- C, ar, id_search_cb_p, &template_ui, template_ID_set_property_cb, active_item_ptr.data,
- template_ui.prv_rows, template_ui.prv_cols, template_ui.scale);
+ static TemplateID template_ui;
+ PointerRNA active_item_ptr;
+ void (*id_search_cb_p)(const bContext *, void *, const char *, uiSearchItems *) = id_search_cb;
+
+ /* arg_litem is malloced, can be freed by parent button */
+ template_ui = *((TemplateID *)arg_litem);
+ active_item_ptr = RNA_property_pointer_get(&template_ui.ptr, template_ui.prop);
+
+ if (template_ui.filter) {
+ /* Currently only used for objects. */
+ if (template_ui.idcode == ID_OB) {
+ if (template_ui.filter == UI_TEMPLATE_ID_FILTER_AVAILABLE) {
+ id_search_cb_p = id_search_cb_objects_from_scene;
+ }
+ }
+ }
+
+ return template_common_search_menu(C,
+ ar,
+ id_search_cb_p,
+ &template_ui,
+ template_ID_set_property_cb,
+ active_item_ptr.data,
+ template_ui.prv_rows,
+ template_ui.prv_cols,
+ template_ui.scale);
}
/************************ ID Template ***************************/
/* This is for browsing and editing the ID-blocks used */
/* for new/open operators */
-void UI_context_active_but_prop_get_templateID(
- bContext *C,
- PointerRNA *r_ptr, PropertyRNA **r_prop)
+void UI_context_active_but_prop_get_templateID(bContext *C,
+ PointerRNA *r_ptr,
+ PropertyRNA **r_prop)
{
- TemplateID *template_ui;
- uiBut *but = UI_context_active_but_get(C);
+ TemplateID *template_ui;
+ uiBut *but = UI_context_active_but_get(C);
- memset(r_ptr, 0, sizeof(*r_ptr));
- *r_prop = NULL;
+ memset(r_ptr, 0, sizeof(*r_ptr));
+ *r_prop = NULL;
- if (but && but->func_argN) {
- template_ui = but->func_argN;
- *r_ptr = template_ui->ptr;
- *r_prop = template_ui->prop;
- }
+ if (but && but->func_argN) {
+ template_ui = but->func_argN;
+ *r_ptr = template_ui->ptr;
+ *r_prop = template_ui->prop;
+ }
}
static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
{
- TemplateID *template_ui = (TemplateID *)arg_litem;
- PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
- ID *id = idptr.data;
- int event = POINTER_AS_INT(arg_event);
-
- switch (event) {
- case UI_ID_BROWSE:
- case UI_ID_PIN:
- RNA_warning("warning, id event %d shouldnt come here", event);
- break;
- case UI_ID_OPEN:
- case UI_ID_ADD_NEW:
- /* these call UI_context_active_but_prop_get_templateID */
- break;
- case UI_ID_DELETE:
- memset(&idptr, 0, sizeof(idptr));
- RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
- RNA_property_update(C, &template_ui->ptr, template_ui->prop);
-
- if (id && CTX_wm_window(C)->eventstate->shift) {
- /* only way to force-remove data (on save) */
- id_fake_user_clear(id);
- id->us = 0;
- }
-
- break;
- case UI_ID_FAKE_USER:
- if (id) {
- if (id->flag & LIB_FAKEUSER) {
- id_us_plus(id);
- }
- else {
- id_us_min(id);
- }
- }
- else {
- return;
- }
- break;
- case UI_ID_LOCAL:
- if (id) {
- Main *bmain = CTX_data_main(C);
- if (BKE_override_static_is_enabled() && CTX_wm_window(C)->eventstate->shift) {
- ID *override_id = BKE_override_static_create_from_id(bmain, id);
- if (override_id != NULL) {
- BKE_main_id_clear_newpoins(bmain);
-
- /* Assign new pointer, takes care of updates/notifiers */
- RNA_id_pointer_create(override_id, &idptr);
- }
- }
- else {
- if (id_make_local(bmain, id, false, false)) {
- BKE_main_id_clear_newpoins(bmain);
-
- /* reassign to get get proper updates/notifiers */
- idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
- }
- }
- RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
- RNA_property_update(C, &template_ui->ptr, template_ui->prop);
- }
- break;
- case UI_ID_OVERRIDE:
- if (id && id->override_static) {
- BKE_override_static_free(&id->override_static);
- /* reassign to get get proper updates/notifiers */
- idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
- RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
- RNA_property_update(C, &template_ui->ptr, template_ui->prop);
- }
- break;
- case UI_ID_ALONE:
- if (id) {
- const bool do_scene_obj = (
- (GS(id->name) == ID_OB) &&
- (template_ui->ptr.type == &RNA_LayerObjects));
-
- /* make copy */
- if (do_scene_obj) {
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ED_object_single_user(bmain, scene, (struct Object *)id);
- WM_event_add_notifier(C, NC_WINDOW, NULL);
- DEG_relations_tag_update(bmain);
- }
- else {
- if (id) {
- Main *bmain = CTX_data_main(C);
- id_single_user(C, id, &template_ui->ptr, template_ui->prop);
- DEG_relations_tag_update(bmain);
- }
- }
- }
- break;
+ TemplateID *template_ui = (TemplateID *)arg_litem;
+ PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
+ ID *id = idptr.data;
+ int event = POINTER_AS_INT(arg_event);
+
+ switch (event) {
+ case UI_ID_BROWSE:
+ case UI_ID_PIN:
+ RNA_warning("warning, id event %d shouldnt come here", event);
+ break;
+ case UI_ID_OPEN:
+ case UI_ID_ADD_NEW:
+ /* these call UI_context_active_but_prop_get_templateID */
+ break;
+ case UI_ID_DELETE:
+ memset(&idptr, 0, sizeof(idptr));
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_update(C, &template_ui->ptr, template_ui->prop);
+
+ if (id && CTX_wm_window(C)->eventstate->shift) {
+ /* only way to force-remove data (on save) */
+ id_fake_user_clear(id);
+ id->us = 0;
+ }
+
+ break;
+ case UI_ID_FAKE_USER:
+ if (id) {
+ if (id->flag & LIB_FAKEUSER) {
+ id_us_plus(id);
+ }
+ else {
+ id_us_min(id);
+ }
+ }
+ else {
+ return;
+ }
+ break;
+ case UI_ID_LOCAL:
+ if (id) {
+ Main *bmain = CTX_data_main(C);
+ if (BKE_override_static_is_enabled() && CTX_wm_window(C)->eventstate->shift) {
+ ID *override_id = BKE_override_static_create_from_id(bmain, id);
+ if (override_id != NULL) {
+ BKE_main_id_clear_newpoins(bmain);
+
+ /* Assign new pointer, takes care of updates/notifiers */
+ RNA_id_pointer_create(override_id, &idptr);
+ }
+ }
+ else {
+ if (id_make_local(bmain, id, false, false)) {
+ BKE_main_id_clear_newpoins(bmain);
+
+ /* reassign to get get proper updates/notifiers */
+ idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
+ }
+ }
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_update(C, &template_ui->ptr, template_ui->prop);
+ }
+ break;
+ case UI_ID_OVERRIDE:
+ if (id && id->override_static) {
+ BKE_override_static_free(&id->override_static);
+ /* reassign to get get proper updates/notifiers */
+ idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_update(C, &template_ui->ptr, template_ui->prop);
+ }
+ break;
+ case UI_ID_ALONE:
+ if (id) {
+ const bool do_scene_obj = ((GS(id->name) == ID_OB) &&
+ (template_ui->ptr.type == &RNA_LayerObjects));
+
+ /* make copy */
+ if (do_scene_obj) {
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ED_object_single_user(bmain, scene, (struct Object *)id);
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+ DEG_relations_tag_update(bmain);
+ }
+ else {
+ if (id) {
+ Main *bmain = CTX_data_main(C);
+ id_single_user(C, id, &template_ui->ptr, template_ui->prop);
+ DEG_relations_tag_update(bmain);
+ }
+ }
+ }
+ break;
#if 0
- case UI_ID_AUTO_NAME:
- break;
+ case UI_ID_AUTO_NAME:
+ break;
#endif
- }
+ }
}
static const char *template_id_browse_tip(const StructRNA *type)
{
- if (type) {
- switch (RNA_type_to_ID_code(type)) {
- case ID_SCE: return N_("Browse Scene to be linked");
- case ID_OB: return N_("Browse Object to be linked");
- case ID_ME: return N_("Browse Mesh Data to be linked");
- case ID_CU: return N_("Browse Curve Data to be linked");
- case ID_MB: return N_("Browse Metaball Data to be linked");
- case ID_MA: return N_("Browse Material to be linked");
- case ID_TE: return N_("Browse Texture to be linked");
- case ID_IM: return N_("Browse Image to be linked");
- case ID_LS: return N_("Browse Line Style Data to be linked");
- case ID_LT: return N_("Browse Lattice Data to be linked");
- case ID_LA: return N_("Browse Light Data to be linked");
- case ID_CA: return N_("Browse Camera Data to be linked");
- case ID_WO: return N_("Browse World Settings to be linked");
- case ID_SCR: return N_("Choose Screen layout");
- case ID_TXT: return N_("Browse Text to be linked");
- case ID_SPK: return N_("Browse Speaker Data to be linked");
- case ID_SO: return N_("Browse Sound to be linked");
- case ID_AR: return N_("Browse Armature data to be linked");
- case ID_AC: return N_("Browse Action to be linked");
- case ID_NT: return N_("Browse Node Tree to be linked");
- case ID_BR: return N_("Browse Brush to be linked");
- case ID_PA: return N_("Browse Particle Settings to be linked");
- case ID_GD: return N_("Browse Grease Pencil Data to be linked");
- case ID_MC: return N_("Browse Movie Clip to be linked");
- case ID_MSK: return N_("Browse Mask to be linked");
- case ID_PAL: return N_("Browse Palette Data to be linked");
- case ID_PC: return N_("Browse Paint Curve Data to be linked");
- case ID_CF: return N_("Browse Cache Files to be linked");
- case ID_WS: return N_("Browse Workspace to be linked");
- case ID_LP: return N_("Browse LightProbe to be linked");
- }
- }
- return N_("Browse ID data to be linked");
+ if (type) {
+ switch (RNA_type_to_ID_code(type)) {
+ case ID_SCE:
+ return N_("Browse Scene to be linked");
+ case ID_OB:
+ return N_("Browse Object to be linked");
+ case ID_ME:
+ return N_("Browse Mesh Data to be linked");
+ case ID_CU:
+ return N_("Browse Curve Data to be linked");
+ case ID_MB:
+ return N_("Browse Metaball Data to be linked");
+ case ID_MA:
+ return N_("Browse Material to be linked");
+ case ID_TE:
+ return N_("Browse Texture to be linked");
+ case ID_IM:
+ return N_("Browse Image to be linked");
+ case ID_LS:
+ return N_("Browse Line Style Data to be linked");
+ case ID_LT:
+ return N_("Browse Lattice Data to be linked");
+ case ID_LA:
+ return N_("Browse Light Data to be linked");
+ case ID_CA:
+ return N_("Browse Camera Data to be linked");
+ case ID_WO:
+ return N_("Browse World Settings to be linked");
+ case ID_SCR:
+ return N_("Choose Screen layout");
+ case ID_TXT:
+ return N_("Browse Text to be linked");
+ case ID_SPK:
+ return N_("Browse Speaker Data to be linked");
+ case ID_SO:
+ return N_("Browse Sound to be linked");
+ case ID_AR:
+ return N_("Browse Armature data to be linked");
+ case ID_AC:
+ return N_("Browse Action to be linked");
+ case ID_NT:
+ return N_("Browse Node Tree to be linked");
+ case ID_BR:
+ return N_("Browse Brush to be linked");
+ case ID_PA:
+ return N_("Browse Particle Settings to be linked");
+ case ID_GD:
+ return N_("Browse Grease Pencil Data to be linked");
+ case ID_MC:
+ return N_("Browse Movie Clip to be linked");
+ case ID_MSK:
+ return N_("Browse Mask to be linked");
+ case ID_PAL:
+ return N_("Browse Palette Data to be linked");
+ case ID_PC:
+ return N_("Browse Paint Curve Data to be linked");
+ case ID_CF:
+ return N_("Browse Cache Files to be linked");
+ case ID_WS:
+ return N_("Browse Workspace to be linked");
+ case ID_LP:
+ return N_("Browse LightProbe to be linked");
+ }
+ }
+ return N_("Browse ID data to be linked");
}
/**
@@ -576,460 +653,719 @@ static const char *template_id_browse_tip(const StructRNA *type)
#ifdef WITH_INTERNATIONAL
static const char *template_id_context(StructRNA *type)
{
- if (type) {
- return BKE_idcode_to_translation_context(RNA_type_to_ID_code(type));
- }
- return BLT_I18NCONTEXT_DEFAULT;
+ if (type) {
+ return BKE_idcode_to_translation_context(RNA_type_to_ID_code(type));
+ }
+ return BLT_I18NCONTEXT_DEFAULT;
}
#endif
-static uiBut *template_id_def_new_but(
- uiBlock *block, const ID *id, const TemplateID *template_ui, StructRNA *type,
- const char * const newop, const bool editable, const bool id_open, const bool use_tab_but,
- int but_height)
+static uiBut *template_id_def_new_but(uiBlock *block,
+ const ID *id,
+ const TemplateID *template_ui,
+ StructRNA *type,
+ const char *const newop,
+ const bool editable,
+ const bool id_open,
+ const bool use_tab_but,
+ int but_height)
{
- ID *idfrom = template_ui->ptr.id.data;
- uiBut *but;
- const int w = id ? UI_UNIT_X : id_open ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
- const int but_type = use_tab_but ? UI_BTYPE_TAB : UI_BTYPE_BUT;
-
- /* i18n markup, does nothing! */
- BLT_I18N_MSGID_MULTI_CTXT(
- "New",
- BLT_I18NCONTEXT_DEFAULT,
- BLT_I18NCONTEXT_ID_SCENE,
- BLT_I18NCONTEXT_ID_OBJECT,
- BLT_I18NCONTEXT_ID_MESH,
- BLT_I18NCONTEXT_ID_CURVE,
- BLT_I18NCONTEXT_ID_METABALL,
- BLT_I18NCONTEXT_ID_MATERIAL,
- BLT_I18NCONTEXT_ID_TEXTURE,
- BLT_I18NCONTEXT_ID_IMAGE,
- BLT_I18NCONTEXT_ID_LATTICE,
- BLT_I18NCONTEXT_ID_LIGHT,
- BLT_I18NCONTEXT_ID_CAMERA,
- BLT_I18NCONTEXT_ID_WORLD,
- BLT_I18NCONTEXT_ID_SCREEN,
- BLT_I18NCONTEXT_ID_TEXT,
- );
- BLT_I18N_MSGID_MULTI_CTXT(
- "New",
- BLT_I18NCONTEXT_ID_SPEAKER,
- BLT_I18NCONTEXT_ID_SOUND,
- BLT_I18NCONTEXT_ID_ARMATURE,
- BLT_I18NCONTEXT_ID_ACTION,
- BLT_I18NCONTEXT_ID_NODETREE,
- BLT_I18NCONTEXT_ID_BRUSH,
- BLT_I18NCONTEXT_ID_PARTICLESETTINGS,
- BLT_I18NCONTEXT_ID_GPENCIL,
- BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE,
- BLT_I18NCONTEXT_ID_WORKSPACE,
- BLT_I18NCONTEXT_ID_LIGHTPROBE,
- );
-
- if (newop) {
- but = uiDefIconTextButO(
- block, but_type, newop, WM_OP_INVOKE_DEFAULT, (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
- (id) ? "" : CTX_IFACE_(template_id_context(type), "New"), 0, 0, w, but_height, NULL);
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW));
- }
- else {
- but = uiDefIconTextBut(
- block, but_type, 0, (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
- (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
- 0, 0, w, but_height, NULL, 0, 0, 0, 0, NULL);
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW));
- }
-
- if ((idfrom && idfrom->lib) || !editable) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
+ ID *idfrom = template_ui->ptr.id.data;
+ uiBut *but;
+ const int w = id ? UI_UNIT_X : id_open ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
+ const int but_type = use_tab_but ? UI_BTYPE_TAB : UI_BTYPE_BUT;
+
+ /* i18n markup, does nothing! */
+ BLT_I18N_MSGID_MULTI_CTXT("New",
+ BLT_I18NCONTEXT_DEFAULT,
+ BLT_I18NCONTEXT_ID_SCENE,
+ BLT_I18NCONTEXT_ID_OBJECT,
+ BLT_I18NCONTEXT_ID_MESH,
+ BLT_I18NCONTEXT_ID_CURVE,
+ BLT_I18NCONTEXT_ID_METABALL,
+ BLT_I18NCONTEXT_ID_MATERIAL,
+ BLT_I18NCONTEXT_ID_TEXTURE,
+ BLT_I18NCONTEXT_ID_IMAGE,
+ BLT_I18NCONTEXT_ID_LATTICE,
+ BLT_I18NCONTEXT_ID_LIGHT,
+ BLT_I18NCONTEXT_ID_CAMERA,
+ BLT_I18NCONTEXT_ID_WORLD,
+ BLT_I18NCONTEXT_ID_SCREEN,
+ BLT_I18NCONTEXT_ID_TEXT, );
+ BLT_I18N_MSGID_MULTI_CTXT("New",
+ BLT_I18NCONTEXT_ID_SPEAKER,
+ BLT_I18NCONTEXT_ID_SOUND,
+ BLT_I18NCONTEXT_ID_ARMATURE,
+ BLT_I18NCONTEXT_ID_ACTION,
+ BLT_I18NCONTEXT_ID_NODETREE,
+ BLT_I18NCONTEXT_ID_BRUSH,
+ BLT_I18NCONTEXT_ID_PARTICLESETTINGS,
+ BLT_I18NCONTEXT_ID_GPENCIL,
+ BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE,
+ BLT_I18NCONTEXT_ID_WORKSPACE,
+ BLT_I18NCONTEXT_ID_LIGHTPROBE, );
+
+ if (newop) {
+ but = uiDefIconTextButO(block,
+ but_type,
+ newop,
+ WM_OP_INVOKE_DEFAULT,
+ (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
+ (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
+ 0,
+ 0,
+ w,
+ but_height,
+ NULL);
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW));
+ }
+ else {
+ but = uiDefIconTextBut(block,
+ but_type,
+ 0,
+ (id && !use_tab_but) ? ICON_DUPLICATE : ICON_ADD,
+ (id) ? "" : CTX_IFACE_(template_id_context(type), "New"),
+ 0,
+ 0,
+ w,
+ but_height,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ADD_NEW));
+ }
+
+ if ((idfrom && idfrom->lib) || !editable) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
#ifndef WITH_INTERNATIONAL
- UNUSED_VARS(type);
+ UNUSED_VARS(type);
#endif
- return but;
+ return but;
}
-static void template_ID(
- bContext *C, uiLayout *layout, TemplateID *template_ui, StructRNA *type, int flag,
- const char *newop, const char *openop, const char *unlinkop,
- const bool live_icon, const bool hide_buttons)
+static void template_ID(bContext *C,
+ uiLayout *layout,
+ TemplateID *template_ui,
+ StructRNA *type,
+ int flag,
+ const char *newop,
+ const char *openop,
+ const char *unlinkop,
+ const bool live_icon,
+ const bool hide_buttons)
{
- uiBut *but;
- uiBlock *block;
- PointerRNA idptr;
- // ListBase *lb; // UNUSED
- ID *id, *idfrom;
- const bool editable = RNA_property_editable(&template_ui->ptr, template_ui->prop);
- const bool use_previews = template_ui->preview = (flag & UI_ID_PREVIEWS) != 0;
-
- idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
- id = idptr.data;
- idfrom = template_ui->ptr.id.data;
- // lb = template_ui->idlb;
-
- block = uiLayoutGetBlock(layout);
- UI_block_align_begin(block);
-
- if (idptr.type) {
- type = idptr.type;
- }
-
- if (flag & UI_ID_BROWSE) {
- template_add_button_search_menu(
- C, layout, block, &template_ui->ptr, template_ui->prop,
- id_search_menu, MEM_dupallocN(template_ui), TIP_(template_id_browse_tip(type)),
- use_previews, editable, live_icon);
- }
-
- /* text button with name */
- if (id) {
- char name[UI_MAX_NAME_STR];
- const bool user_alert = (id->us <= 0);
-
- //text_idbutton(id, name);
- name[0] = '\0';
- but = uiDefButR(
- block, UI_BTYPE_TEXT, 0, name, 0, 0, TEMPLATE_SEARCH_TEXTBUT_WIDTH, TEMPLATE_SEARCH_TEXTBUT_HEIGHT,
- &idptr, "name", -1, 0, 0, -1, -1, RNA_struct_ui_description(type));
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_RENAME));
- if (user_alert) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
-
- if (id->lib) {
- if (id->tag & LIB_TAG_INDIRECT) {
- but = uiDefIconBut(
- block, UI_BTYPE_BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Indirect library data-block, cannot change"));
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- else {
- const bool disabled = (
- !id_make_local(CTX_data_main(C), id, true /* test */, false) ||
- (idfrom && idfrom->lib));
- but = uiDefIconBut(
- block, UI_BTYPE_BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0,
- BKE_override_static_is_enabled() ?
- TIP_("Direct linked library data-block, click to make local, "
- "Shift + Click to create a static override") :
- TIP_("Direct linked library data-block, click to make local"));
- if (disabled) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- else {
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_LOCAL));
- }
- }
- }
- else if (ID_IS_STATIC_OVERRIDE(id)) {
- but = uiDefIconBut(
- block, UI_BTYPE_BUT, 0, ICON_LIBRARY_DATA_OVERRIDE, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0,
- TIP_("Static override of linked library data-block, click to make fully local"));
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OVERRIDE));
- }
-
- if ((ID_REAL_USERS(id) > 1) && (hide_buttons == false)) {
- char numstr[32];
- short numstr_len;
-
- numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id));
-
- but = uiDefBut(
- block, UI_BTYPE_BUT, 0, numstr, 0, 0,
- numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Display number of users of this data (click to make a single-user copy)"));
- but->flag |= UI_BUT_UNDO;
-
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ALONE));
- if ((!BKE_id_copy_is_allowed(id)) ||
- (idfrom && idfrom->lib) ||
- (!editable) ||
- /* object in editmode - don't change data */
- (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT)))
- {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- }
-
- if (user_alert) {
- UI_but_flag_enable(but, UI_BUT_REDALERT);
- }
-
- if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS)) &&
- (hide_buttons == false))
- {
- uiDefIconButR(
- block, UI_BTYPE_ICON_TOGGLE, 0, ICON_FAKE_USER_OFF, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &idptr, "use_fake_user", -1, 0, 0, -1, -1, NULL);
- }
- }
-
- if ((flag & UI_ID_ADD_NEW) && (hide_buttons == false)) {
- template_id_def_new_but(block, id, template_ui, type, newop, editable, flag & UI_ID_OPEN, false, UI_UNIT_X);
- }
-
- /* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
- * Only for images, sound and fonts */
- if (id && BKE_pack_check(id)) {
- but = uiDefIconButO(
- block, UI_BTYPE_BUT, "FILE_OT_unpack_item", WM_OP_INVOKE_REGION_WIN, ICON_PACKAGE, 0, 0,
- UI_UNIT_X, UI_UNIT_Y, TIP_("Packed File, click to unpack"));
- UI_but_operator_ptr_get(but);
-
- RNA_string_set(but->opptr, "id_name", id->name + 2);
- RNA_int_set(but->opptr, "id_type", GS(id->name));
-
- }
- else if (flag & UI_ID_OPEN) {
- int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
-
- if (openop) {
- but = uiDefIconTextButO(
- block, UI_BTYPE_BUT, openop, WM_OP_INVOKE_DEFAULT, ICON_FILEBROWSER, (id) ? "" : IFACE_("Open"),
- 0, 0, w, UI_UNIT_Y, NULL);
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN));
- }
- else {
- but = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_FILEBROWSER, (id) ? "" : IFACE_("Open"), 0, 0, w, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, NULL);
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN));
- }
-
- if ((idfrom && idfrom->lib) || !editable) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- }
-
- /* delete button */
- /* don't use RNA_property_is_unlink here */
- if (id && (flag & UI_ID_DELETE) && (hide_buttons == false)) {
- /* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */
- but = NULL;
-
- if (unlinkop) {
- but = uiDefIconButO(block, UI_BTYPE_BUT, unlinkop, WM_OP_INVOKE_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
- /* so we can access the template from operators, font unlinking needs this */
- UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL);
- }
- else {
- if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) {
- but = uiDefIconBut(
- block, UI_BTYPE_BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0,
- TIP_("Unlink data-block "
- "(Shift + Click to set users to zero, data will then not be saved)"));
- UI_but_funcN_set(but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_DELETE));
-
- if (RNA_property_flag(template_ui->prop) & PROP_NEVER_NULL) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- }
- }
-
- if (but) {
- if ((idfrom && idfrom->lib) || !editable) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- }
- }
-
- if (template_ui->idcode == ID_TE) {
- uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop);
- }
- UI_block_align_end(block);
+ uiBut *but;
+ uiBlock *block;
+ PointerRNA idptr;
+ // ListBase *lb; // UNUSED
+ ID *id, *idfrom;
+ const bool editable = RNA_property_editable(&template_ui->ptr, template_ui->prop);
+ const bool use_previews = template_ui->preview = (flag & UI_ID_PREVIEWS) != 0;
+
+ idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
+ id = idptr.data;
+ idfrom = template_ui->ptr.id.data;
+ // lb = template_ui->idlb;
+
+ block = uiLayoutGetBlock(layout);
+ UI_block_align_begin(block);
+
+ if (idptr.type) {
+ type = idptr.type;
+ }
+
+ if (flag & UI_ID_BROWSE) {
+ template_add_button_search_menu(C,
+ layout,
+ block,
+ &template_ui->ptr,
+ template_ui->prop,
+ id_search_menu,
+ MEM_dupallocN(template_ui),
+ TIP_(template_id_browse_tip(type)),
+ use_previews,
+ editable,
+ live_icon);
+ }
+
+ /* text button with name */
+ if (id) {
+ char name[UI_MAX_NAME_STR];
+ const bool user_alert = (id->us <= 0);
+
+ //text_idbutton(id, name);
+ name[0] = '\0';
+ but = uiDefButR(block,
+ UI_BTYPE_TEXT,
+ 0,
+ name,
+ 0,
+ 0,
+ TEMPLATE_SEARCH_TEXTBUT_WIDTH,
+ TEMPLATE_SEARCH_TEXTBUT_HEIGHT,
+ &idptr,
+ "name",
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ RNA_struct_ui_description(type));
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_RENAME));
+ if (user_alert) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+
+ if (id->lib) {
+ if (id->tag & LIB_TAG_INDIRECT) {
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_LIBRARY_DATA_INDIRECT,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Indirect library data-block, cannot change"));
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ else {
+ const bool disabled = (!id_make_local(CTX_data_main(C), id, true /* test */, false) ||
+ (idfrom && idfrom->lib));
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_LIBRARY_DATA_DIRECT,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ BKE_override_static_is_enabled() ?
+ TIP_("Direct linked library data-block, click to make local, "
+ "Shift + Click to create a static override") :
+ TIP_("Direct linked library data-block, click to make local"));
+ if (disabled) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ else {
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_LOCAL));
+ }
+ }
+ }
+ else if (ID_IS_STATIC_OVERRIDE(id)) {
+ but = uiDefIconBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_LIBRARY_DATA_OVERRIDE,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Static override of linked library data-block, click to make fully local"));
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OVERRIDE));
+ }
+
+ if ((ID_REAL_USERS(id) > 1) && (hide_buttons == false)) {
+ char numstr[32];
+ short numstr_len;
+
+ numstr_len = BLI_snprintf(numstr, sizeof(numstr), "%d", ID_REAL_USERS(id));
+
+ but = uiDefBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ numstr,
+ 0,
+ 0,
+ numstr_len * 0.2f * UI_UNIT_X + UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Display number of users of this data (click to make a single-user copy)"));
+ but->flag |= UI_BUT_UNDO;
+
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_ALONE));
+ if ((!BKE_id_copy_is_allowed(id)) || (idfrom && idfrom->lib) || (!editable) ||
+ /* object in editmode - don't change data */
+ (idfrom && GS(idfrom->name) == ID_OB && (((Object *)idfrom)->mode & OB_MODE_EDIT))) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ }
+
+ if (user_alert) {
+ UI_but_flag_enable(but, UI_BUT_REDALERT);
+ }
+
+ if (id->lib == NULL && !(ELEM(GS(id->name), ID_GR, ID_SCE, ID_SCR, ID_TXT, ID_OB, ID_WS)) &&
+ (hide_buttons == false)) {
+ uiDefIconButR(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ ICON_FAKE_USER_OFF,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &idptr,
+ "use_fake_user",
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ }
+
+ if ((flag & UI_ID_ADD_NEW) && (hide_buttons == false)) {
+ template_id_def_new_but(
+ block, id, template_ui, type, newop, editable, flag & UI_ID_OPEN, false, UI_UNIT_X);
+ }
+
+ /* Due to space limit in UI - skip the "open" icon for packed data, and allow to unpack.
+ * Only for images, sound and fonts */
+ if (id && BKE_pack_check(id)) {
+ but = uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "FILE_OT_unpack_item",
+ WM_OP_INVOKE_REGION_WIN,
+ ICON_PACKAGE,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ TIP_("Packed File, click to unpack"));
+ UI_but_operator_ptr_get(but);
+
+ RNA_string_set(but->opptr, "id_name", id->name + 2);
+ RNA_int_set(but->opptr, "id_type", GS(id->name));
+ }
+ else if (flag & UI_ID_OPEN) {
+ int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6;
+
+ if (openop) {
+ but = uiDefIconTextButO(block,
+ UI_BTYPE_BUT,
+ openop,
+ WM_OP_INVOKE_DEFAULT,
+ ICON_FILEBROWSER,
+ (id) ? "" : IFACE_("Open"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL);
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN));
+ }
+ else {
+ but = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_FILEBROWSER,
+ (id) ? "" : IFACE_("Open"),
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL);
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_OPEN));
+ }
+
+ if ((idfrom && idfrom->lib) || !editable) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ }
+
+ /* delete button */
+ /* don't use RNA_property_is_unlink here */
+ if (id && (flag & UI_ID_DELETE) && (hide_buttons == false)) {
+ /* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */
+ but = NULL;
+
+ if (unlinkop) {
+ but = uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ unlinkop,
+ WM_OP_INVOKE_DEFAULT,
+ ICON_X,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL);
+ /* so we can access the template from operators, font unlinking needs this */
+ UI_but_funcN_set(but, NULL, MEM_dupallocN(template_ui), NULL);
+ }
+ else {
+ if ((RNA_property_flag(template_ui->prop) & PROP_NEVER_UNLINK) == 0) {
+ but = uiDefIconBut(
+ block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_X,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Unlink data-block "
+ "(Shift + Click to set users to zero, data will then not be saved)"));
+ UI_but_funcN_set(
+ but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_DELETE));
+
+ if (RNA_property_flag(template_ui->prop) & PROP_NEVER_NULL) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ }
+ }
+
+ if (but) {
+ if ((idfrom && idfrom->lib) || !editable) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ }
+ }
+
+ if (template_ui->idcode == ID_TE) {
+ uiTemplateTextureShow(layout, C, &template_ui->ptr, template_ui->prop);
+ }
+ UI_block_align_end(block);
}
-
ID *UI_context_active_but_get_tab_ID(bContext *C)
{
- uiBut *but = UI_context_active_but_get(C);
-
- if (but && but->type == UI_BTYPE_TAB) {
- return but->custom_data;
- }
- else {
- return NULL;
- }
+ uiBut *but = UI_context_active_but_get(C);
+
+ if (but && but->type == UI_BTYPE_TAB) {
+ return but->custom_data;
+ }
+ else {
+ return NULL;
+ }
}
-static void template_ID_tabs(
- bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag,
- const char *newop, const char *menu)
+static void template_ID_tabs(bContext *C,
+ uiLayout *layout,
+ TemplateID *template,
+ StructRNA *type,
+ int flag,
+ const char *newop,
+ const char *menu)
{
- const ARegion *region = CTX_wm_region(C);
- const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, template->prop);
- MenuType *mt = WM_menutype_find(menu, false);
-
- const int but_align = ui_but_align_opposite_to_area_align_get(region);
- const int but_height = UI_UNIT_Y * 1.1;
-
- uiBlock *block = uiLayoutGetBlock(layout);
- uiStyle *style = UI_style_get_dpi();
-
- ListBase ordered;
- BKE_id_ordered_list(&ordered, template->idlb);
-
- for (LinkData *link = ordered.first; link; link = link->next) {
- ID *id = link->data;
- const int name_width = UI_fontstyle_string_width(&style->widgetlabel, id->name + 2);
- const int but_width = name_width + UI_UNIT_X;
-
- uiButTab *tab = (uiButTab *)uiDefButR_prop(
- block, UI_BTYPE_TAB, 0, id->name + 2, 0, 0, but_width, but_height,
- &template->ptr, template->prop, 0, 0.0f,
- sizeof(id->name) - 2, 0.0f, 0.0f, "");
- UI_but_funcN_set(&tab->but, template_ID_set_property_cb, MEM_dupallocN(template), id);
- tab->but.custom_data = (void *)id;
- tab->but.dragpoin = id;
- tab->menu = mt;
-
- UI_but_drawflag_enable(&tab->but, but_align);
- }
-
- BLI_freelistN(&ordered);
-
- if (flag & UI_ID_ADD_NEW) {
- const bool editable = RNA_property_editable(&template->ptr, template->prop);
- uiBut *but;
-
- if (active_ptr.type) {
- type = active_ptr.type;
- }
-
- but = template_id_def_new_but(block, active_ptr.data, template, type, newop, editable, flag & UI_ID_OPEN, true, but_height);
- UI_but_drawflag_enable(but, but_align);
- }
+ const ARegion *region = CTX_wm_region(C);
+ const PointerRNA active_ptr = RNA_property_pointer_get(&template->ptr, template->prop);
+ MenuType *mt = WM_menutype_find(menu, false);
+
+ const int but_align = ui_but_align_opposite_to_area_align_get(region);
+ const int but_height = UI_UNIT_Y * 1.1;
+
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiStyle *style = UI_style_get_dpi();
+
+ ListBase ordered;
+ BKE_id_ordered_list(&ordered, template->idlb);
+
+ for (LinkData *link = ordered.first; link; link = link->next) {
+ ID *id = link->data;
+ const int name_width = UI_fontstyle_string_width(&style->widgetlabel, id->name + 2);
+ const int but_width = name_width + UI_UNIT_X;
+
+ uiButTab *tab = (uiButTab *)uiDefButR_prop(block,
+ UI_BTYPE_TAB,
+ 0,
+ id->name + 2,
+ 0,
+ 0,
+ but_width,
+ but_height,
+ &template->ptr,
+ template->prop,
+ 0,
+ 0.0f,
+ sizeof(id->name) - 2,
+ 0.0f,
+ 0.0f,
+ "");
+ UI_but_funcN_set(&tab->but, template_ID_set_property_cb, MEM_dupallocN(template), id);
+ tab->but.custom_data = (void *)id;
+ tab->but.dragpoin = id;
+ tab->menu = mt;
+
+ UI_but_drawflag_enable(&tab->but, but_align);
+ }
+
+ BLI_freelistN(&ordered);
+
+ if (flag & UI_ID_ADD_NEW) {
+ const bool editable = RNA_property_editable(&template->ptr, template->prop);
+ uiBut *but;
+
+ if (active_ptr.type) {
+ type = active_ptr.type;
+ }
+
+ but = template_id_def_new_but(block,
+ active_ptr.data,
+ template,
+ type,
+ newop,
+ editable,
+ flag & UI_ID_OPEN,
+ true,
+ but_height);
+ UI_but_drawflag_enable(but, but_align);
+ }
}
-static void ui_template_id(
- uiLayout *layout, bContext *C,
- PointerRNA *ptr, const char *propname,
- const char *newop, const char *openop, const char *unlinkop,
- int flag, int prv_rows, int prv_cols, int filter, bool use_tabs,
- float scale, const bool live_icon, const bool hide_buttons)
+static void ui_template_id(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ const char *newop,
+ const char *openop,
+ const char *unlinkop,
+ int flag,
+ int prv_rows,
+ int prv_cols,
+ int filter,
+ bool use_tabs,
+ float scale,
+ const bool live_icon,
+ const bool hide_buttons)
{
- TemplateID *template_ui;
- PropertyRNA *prop;
- StructRNA *type;
- short idcode;
-
- prop = RNA_struct_find_property(ptr, propname);
-
- if (!prop || RNA_property_type(prop) != PROP_POINTER) {
- RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- template_ui = MEM_callocN(sizeof(TemplateID), "TemplateID");
- template_ui->ptr = *ptr;
- template_ui->prop = prop;
- template_ui->prv_rows = prv_rows;
- template_ui->prv_cols = prv_cols;
- template_ui->scale = scale;
-
- if ((flag & UI_ID_PIN) == 0) {
- template_ui->filter = filter;
- }
- else {
- template_ui->filter = 0;
- }
-
- if (newop) {
- flag |= UI_ID_ADD_NEW;
- }
- if (openop) {
- flag |= UI_ID_OPEN;
- }
-
- type = RNA_property_pointer_type(ptr, prop);
- idcode = RNA_type_to_ID_code(type);
- template_ui->idcode = idcode;
- template_ui->idlb = which_libbase(CTX_data_main(C), idcode);
-
- /* create UI elements for this template
- * - template_ID makes a copy of the template data and assigns it to the relevant buttons
- */
- if (template_ui->idlb) {
- if (use_tabs) {
- uiLayoutRow(layout, true);
- template_ID_tabs(C, layout, template_ui, type, flag, newop, unlinkop);
- }
- else {
- uiLayoutRow(layout, true);
- template_ID(
- C, layout, template_ui, type, flag, newop, openop,
- unlinkop, live_icon, hide_buttons);
- }
- }
-
- MEM_freeN(template_ui);
+ TemplateID *template_ui;
+ PropertyRNA *prop;
+ StructRNA *type;
+ short idcode;
+
+ prop = RNA_struct_find_property(ptr, propname);
+
+ if (!prop || RNA_property_type(prop) != PROP_POINTER) {
+ RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ template_ui = MEM_callocN(sizeof(TemplateID), "TemplateID");
+ template_ui->ptr = *ptr;
+ template_ui->prop = prop;
+ template_ui->prv_rows = prv_rows;
+ template_ui->prv_cols = prv_cols;
+ template_ui->scale = scale;
+
+ if ((flag & UI_ID_PIN) == 0) {
+ template_ui->filter = filter;
+ }
+ else {
+ template_ui->filter = 0;
+ }
+
+ if (newop) {
+ flag |= UI_ID_ADD_NEW;
+ }
+ if (openop) {
+ flag |= UI_ID_OPEN;
+ }
+
+ type = RNA_property_pointer_type(ptr, prop);
+ idcode = RNA_type_to_ID_code(type);
+ template_ui->idcode = idcode;
+ template_ui->idlb = which_libbase(CTX_data_main(C), idcode);
+
+ /* create UI elements for this template
+ * - template_ID makes a copy of the template data and assigns it to the relevant buttons
+ */
+ if (template_ui->idlb) {
+ if (use_tabs) {
+ uiLayoutRow(layout, true);
+ template_ID_tabs(C, layout, template_ui, type, flag, newop, unlinkop);
+ }
+ else {
+ uiLayoutRow(layout, true);
+ template_ID(
+ C, layout, template_ui, type, flag, newop, openop, unlinkop, live_icon, hide_buttons);
+ }
+ }
+
+ MEM_freeN(template_ui);
}
-void uiTemplateID(
- uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop,
- int filter, const bool live_icon)
+void uiTemplateID(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ const char *newop,
+ const char *openop,
+ const char *unlinkop,
+ int filter,
+ const bool live_icon)
{
- ui_template_id(
- layout, C, ptr, propname,
- newop, openop, unlinkop,
- UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE,
- 0, 0, filter, false, 1.0f, live_icon, false);
+ ui_template_id(layout,
+ C,
+ ptr,
+ propname,
+ newop,
+ openop,
+ unlinkop,
+ UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE,
+ 0,
+ 0,
+ filter,
+ false,
+ 1.0f,
+ live_icon,
+ false);
}
-void uiTemplateIDBrowse(
- uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop, int filter)
+void uiTemplateIDBrowse(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ const char *newop,
+ const char *openop,
+ const char *unlinkop,
+ int filter)
{
- ui_template_id(
- layout, C, ptr, propname,
- newop, openop, unlinkop,
- UI_ID_BROWSE | UI_ID_RENAME,
- 0, 0, filter, false, 1.0f, false, false);
+ ui_template_id(layout,
+ C,
+ ptr,
+ propname,
+ newop,
+ openop,
+ unlinkop,
+ UI_ID_BROWSE | UI_ID_RENAME,
+ 0,
+ 0,
+ filter,
+ false,
+ 1.0f,
+ false,
+ false);
}
-void uiTemplateIDPreview(
- uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, const char *newop,
- const char *openop, const char *unlinkop, int rows, int cols, int filter,
- const bool hide_buttons)
+void uiTemplateIDPreview(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ const char *newop,
+ const char *openop,
+ const char *unlinkop,
+ int rows,
+ int cols,
+ int filter,
+ const bool hide_buttons)
{
- ui_template_id(
- layout, C, ptr, propname,
- newop, openop, unlinkop,
- UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS,
- rows, cols, filter, false, 1.0f, false, hide_buttons);
+ ui_template_id(layout,
+ C,
+ ptr,
+ propname,
+ newop,
+ openop,
+ unlinkop,
+ UI_ID_BROWSE | UI_ID_RENAME | UI_ID_DELETE | UI_ID_PREVIEWS,
+ rows,
+ cols,
+ filter,
+ false,
+ 1.0f,
+ false,
+ hide_buttons);
}
-void uiTemplateGpencilColorPreview(
- uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname,
- int rows, int cols, float scale, int filter)
+void uiTemplateGpencilColorPreview(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ int rows,
+ int cols,
+ float scale,
+ int filter)
{
- ui_template_id(
- layout, C, ptr, propname,
- NULL, NULL, NULL,
- UI_ID_BROWSE | UI_ID_PREVIEWS | UI_ID_DELETE,
- rows, cols, filter, false, scale < 0.5f ? 0.5f : scale, false, false);
+ ui_template_id(layout,
+ C,
+ ptr,
+ propname,
+ NULL,
+ NULL,
+ NULL,
+ UI_ID_BROWSE | UI_ID_PREVIEWS | UI_ID_DELETE,
+ rows,
+ cols,
+ filter,
+ false,
+ scale < 0.5f ? 0.5f : scale,
+ false,
+ false);
}
/**
* Version of #uiTemplateID using tabs.
*/
-void uiTemplateIDTabs(
- uiLayout *layout, bContext *C,
- PointerRNA *ptr, const char *propname,
- const char *newop, const char *unlinkop,
- int filter)
+void uiTemplateIDTabs(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ const char *newop,
+ const char *unlinkop,
+ int filter)
{
- ui_template_id(
- layout, C, ptr, propname,
- newop, NULL, unlinkop,
- UI_ID_BROWSE | UI_ID_RENAME,
- 0, 0, filter, true, 1.0f, false, false);
+ ui_template_id(layout,
+ C,
+ ptr,
+ propname,
+ newop,
+ NULL,
+ unlinkop,
+ UI_ID_BROWSE | UI_ID_RENAME,
+ 0,
+ 0,
+ filter,
+ true,
+ 1.0f,
+ false,
+ false);
}
/************************ ID Chooser Template ***************************/
@@ -1040,267 +1376,313 @@ void uiTemplateIDTabs(
* - propname: property identifier for property that ID-pointer gets stored to
* - proptypename: property identifier for property used to determine the type of ID-pointer that can be used
*/
-void uiTemplateAnyID(
- uiLayout *layout, PointerRNA *ptr, const char *propname, const char *proptypename,
- const char *text)
+void uiTemplateAnyID(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ const char *proptypename,
+ const char *text)
{
- PropertyRNA *propID, *propType;
- uiLayout *split, *row, *sub;
+ PropertyRNA *propID, *propType;
+ uiLayout *split, *row, *sub;
- /* get properties... */
- propID = RNA_struct_find_property(ptr, propname);
- propType = RNA_struct_find_property(ptr, proptypename);
+ /* get properties... */
+ propID = RNA_struct_find_property(ptr, propname);
+ propType = RNA_struct_find_property(ptr, proptypename);
- if (!propID || RNA_property_type(propID) != PROP_POINTER) {
- RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
- if (!propType || RNA_property_type(propType) != PROP_ENUM) {
- RNA_warning("pointer-type property not found: %s.%s", RNA_struct_identifier(ptr->type), proptypename);
- return;
- }
+ if (!propID || RNA_property_type(propID) != PROP_POINTER) {
+ RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+ if (!propType || RNA_property_type(propType) != PROP_ENUM) {
+ RNA_warning(
+ "pointer-type property not found: %s.%s", RNA_struct_identifier(ptr->type), proptypename);
+ return;
+ }
- /* Start drawing UI Elements using standard defines */
+ /* Start drawing UI Elements using standard defines */
- /* NOTE: split amount here needs to be synced with normal labels */
- split = uiLayoutSplit(layout, 0.33f, false);
+ /* NOTE: split amount here needs to be synced with normal labels */
+ split = uiLayoutSplit(layout, 0.33f, false);
- /* FIRST PART ................................................ */
- row = uiLayoutRow(split, false);
+ /* FIRST PART ................................................ */
+ row = uiLayoutRow(split, false);
- /* Label - either use the provided text, or will become "ID-Block:" */
- if (text) {
- if (text[0]) {
- uiItemL(row, text, ICON_NONE);
- }
- }
- else {
- uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
- }
+ /* Label - either use the provided text, or will become "ID-Block:" */
+ if (text) {
+ if (text[0]) {
+ uiItemL(row, text, ICON_NONE);
+ }
+ }
+ else {
+ uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
+ }
- /* SECOND PART ................................................ */
- row = uiLayoutRow(split, true);
+ /* SECOND PART ................................................ */
+ row = uiLayoutRow(split, true);
- /* ID-Type Selector - just have a menu of icons */
+ /* ID-Type Selector - just have a menu of icons */
- /* HACK: special group just for the enum,
- * otherwise we get ugly layout with text included too... */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+ /* HACK: special group just for the enum,
+ * otherwise we get ugly layout with text included too... */
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
- uiItemFullR(sub, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ uiItemFullR(sub, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- /* ID-Block Selector - just use pointer widget... */
+ /* ID-Block Selector - just use pointer widget... */
- /* HACK: special group to counteract the effects of the previous enum,
- * which now pushes everything too far right. */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND);
+ /* HACK: special group to counteract the effects of the previous enum,
+ * which now pushes everything too far right. */
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND);
- uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
+ uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
}
/********************* Search Template ********************/
typedef struct TemplateSearch {
- uiRNACollectionSearch search_data;
+ uiRNACollectionSearch search_data;
- bool use_previews;
- int preview_rows, preview_cols;
+ bool use_previews;
+ int preview_rows, preview_cols;
} TemplateSearch;
static void template_search_handle_cb(bContext *C, void *arg_template, void *item)
{
- TemplateSearch *template_search = arg_template;
- uiRNACollectionSearch *coll_search = &template_search->search_data;
- StructRNA *type = RNA_property_pointer_type(&coll_search->target_ptr, coll_search->target_prop);
- PointerRNA item_ptr;
-
- RNA_pointer_create(NULL, type, item, &item_ptr);
- RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr);
- RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
+ TemplateSearch *template_search = arg_template;
+ uiRNACollectionSearch *coll_search = &template_search->search_data;
+ StructRNA *type = RNA_property_pointer_type(&coll_search->target_ptr, coll_search->target_prop);
+ PointerRNA item_ptr;
+
+ RNA_pointer_create(NULL, type, item, &item_ptr);
+ RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr);
+ RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
}
static uiBlock *template_search_menu(bContext *C, ARegion *region, void *arg_template)
{
- static TemplateSearch template_search;
- PointerRNA active_ptr;
-
- /* arg_template is malloced, can be freed by parent button */
- template_search = *((TemplateSearch *)arg_template);
- active_ptr = RNA_property_pointer_get(
- &template_search.search_data.target_ptr,
- template_search.search_data.target_prop);
-
- return template_common_search_menu(
- C, region, ui_rna_collection_search_cb, &template_search,
- template_search_handle_cb, active_ptr.data,
- template_search.preview_rows, template_search.preview_cols, 1.0f);
+ static TemplateSearch template_search;
+ PointerRNA active_ptr;
+
+ /* arg_template is malloced, can be freed by parent button */
+ template_search = *((TemplateSearch *)arg_template);
+ active_ptr = RNA_property_pointer_get(&template_search.search_data.target_ptr,
+ template_search.search_data.target_prop);
+
+ return template_common_search_menu(C,
+ region,
+ ui_rna_collection_search_cb,
+ &template_search,
+ template_search_handle_cb,
+ active_ptr.data,
+ template_search.preview_rows,
+ template_search.preview_cols,
+ 1.0f);
}
-static void template_search_add_button_searchmenu(
- const bContext *C, uiLayout *layout, uiBlock *block,
- TemplateSearch *template_search, const bool editable, const bool live_icon)
+static void template_search_add_button_searchmenu(const bContext *C,
+ uiLayout *layout,
+ uiBlock *block,
+ TemplateSearch *template_search,
+ const bool editable,
+ const bool live_icon)
{
- const char *ui_description = RNA_property_ui_description(template_search->search_data.target_prop);
-
- template_add_button_search_menu(
- C, layout, block,
- &template_search->search_data.target_ptr, template_search->search_data.target_prop,
- template_search_menu, MEM_dupallocN(template_search), ui_description,
- template_search->use_previews, editable, live_icon);
+ const char *ui_description = RNA_property_ui_description(
+ template_search->search_data.target_prop);
+
+ template_add_button_search_menu(C,
+ layout,
+ block,
+ &template_search->search_data.target_ptr,
+ template_search->search_data.target_prop,
+ template_search_menu,
+ MEM_dupallocN(template_search),
+ ui_description,
+ template_search->use_previews,
+ editable,
+ live_icon);
}
-static void template_search_add_button_name(
- uiBlock *block, PointerRNA *active_ptr, const StructRNA *type)
+static void template_search_add_button_name(uiBlock *block,
+ PointerRNA *active_ptr,
+ const StructRNA *type)
{
- uiDefAutoButR(
- block, active_ptr, RNA_struct_name_property(type), 0, "", ICON_NONE,
- 0, 0, TEMPLATE_SEARCH_TEXTBUT_WIDTH, TEMPLATE_SEARCH_TEXTBUT_HEIGHT);
+ uiDefAutoButR(block,
+ active_ptr,
+ RNA_struct_name_property(type),
+ 0,
+ "",
+ ICON_NONE,
+ 0,
+ 0,
+ TEMPLATE_SEARCH_TEXTBUT_WIDTH,
+ TEMPLATE_SEARCH_TEXTBUT_HEIGHT);
}
-static void template_search_add_button_operator(
- uiBlock *block, const char * const operator_name,
- const int opcontext, const int icon, const bool editable)
+static void template_search_add_button_operator(uiBlock *block,
+ const char *const operator_name,
+ const int opcontext,
+ const int icon,
+ const bool editable)
{
- if (!operator_name) {
- return;
- }
+ if (!operator_name) {
+ return;
+ }
- uiBut *but = uiDefIconButO(
- block, UI_BTYPE_BUT, operator_name, opcontext, icon,
- 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
+ uiBut *but = uiDefIconButO(
+ block, UI_BTYPE_BUT, operator_name, opcontext, icon, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
- if (!editable) {
- UI_but_drawflag_enable(but, UI_BUT_DISABLED);
- }
+ if (!editable) {
+ UI_but_drawflag_enable(but, UI_BUT_DISABLED);
+ }
}
-static void template_search_buttons(
- const bContext *C, uiLayout *layout, TemplateSearch *template_search,
- const char *newop, const char *unlinkop)
+static void template_search_buttons(const bContext *C,
+ uiLayout *layout,
+ TemplateSearch *template_search,
+ const char *newop,
+ const char *unlinkop)
{
- uiBlock *block = uiLayoutGetBlock(layout);
- uiRNACollectionSearch *search_data = &template_search->search_data;
- StructRNA *type = RNA_property_pointer_type(&search_data->target_ptr, search_data->target_prop);
- const bool editable = RNA_property_editable(&search_data->target_ptr, search_data->target_prop);
- PointerRNA active_ptr = RNA_property_pointer_get(&search_data->target_ptr, search_data->target_prop);
-
- if (active_ptr.type) {
- /* can only get correct type when there is an active item */
- type = active_ptr.type;
- }
-
- uiLayoutRow(layout, true);
- UI_block_align_begin(block);
-
- template_search_add_button_searchmenu(C, layout, block, template_search, editable, false);
- template_search_add_button_name(block, &active_ptr, type);
- template_search_add_button_operator(block, newop, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE, editable);
- template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
-
- UI_block_align_end(block);
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiRNACollectionSearch *search_data = &template_search->search_data;
+ StructRNA *type = RNA_property_pointer_type(&search_data->target_ptr, search_data->target_prop);
+ const bool editable = RNA_property_editable(&search_data->target_ptr, search_data->target_prop);
+ PointerRNA active_ptr = RNA_property_pointer_get(&search_data->target_ptr,
+ search_data->target_prop);
+
+ if (active_ptr.type) {
+ /* can only get correct type when there is an active item */
+ type = active_ptr.type;
+ }
+
+ uiLayoutRow(layout, true);
+ UI_block_align_begin(block);
+
+ template_search_add_button_searchmenu(C, layout, block, template_search, editable, false);
+ template_search_add_button_name(block, &active_ptr, type);
+ template_search_add_button_operator(
+ block, newop, WM_OP_INVOKE_DEFAULT, ICON_DUPLICATE, editable);
+ template_search_add_button_operator(block, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, editable);
+
+ UI_block_align_end(block);
}
-static PropertyRNA *template_search_get_searchprop(
- PointerRNA *targetptr, PropertyRNA *targetprop,
- PointerRNA *searchptr, const char * const searchpropname)
+static PropertyRNA *template_search_get_searchprop(PointerRNA *targetptr,
+ PropertyRNA *targetprop,
+ PointerRNA *searchptr,
+ const char *const searchpropname)
{
- PropertyRNA *searchprop;
-
- if (searchptr && !searchptr->data) {
- searchptr = NULL;
- }
-
- if (!searchptr && !searchpropname) {
- /* both NULL means we don't use a custom rna collection to search in */
- }
- else if (!searchptr && searchpropname) {
- RNA_warning("searchpropname defined (%s) but searchptr is missing", searchpropname);
- }
- else if (searchptr && !searchpropname) {
- RNA_warning("searchptr defined (%s) but searchpropname is missing", RNA_struct_identifier(searchptr->type));
- }
- else if (!(searchprop = RNA_struct_find_property(searchptr, searchpropname))) {
- RNA_warning("search collection property not found: %s.%s",
- RNA_struct_identifier(searchptr->type), searchpropname);
- }
- else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
- RNA_warning("search collection property is not a collection type: %s.%s",
- RNA_struct_identifier(searchptr->type), searchpropname);
- }
- /* check if searchprop has same type as targetprop */
- else if (RNA_property_pointer_type(searchptr, searchprop) != RNA_property_pointer_type(targetptr, targetprop)) {
- RNA_warning("search collection items from %s.%s are not of type %s",
- RNA_struct_identifier(searchptr->type), searchpropname,
- RNA_struct_identifier(RNA_property_pointer_type(targetptr, targetprop)));
- }
- else {
- return searchprop;
- }
-
- return NULL;
+ PropertyRNA *searchprop;
+
+ if (searchptr && !searchptr->data) {
+ searchptr = NULL;
+ }
+
+ if (!searchptr && !searchpropname) {
+ /* both NULL means we don't use a custom rna collection to search in */
+ }
+ else if (!searchptr && searchpropname) {
+ RNA_warning("searchpropname defined (%s) but searchptr is missing", searchpropname);
+ }
+ else if (searchptr && !searchpropname) {
+ RNA_warning("searchptr defined (%s) but searchpropname is missing",
+ RNA_struct_identifier(searchptr->type));
+ }
+ else if (!(searchprop = RNA_struct_find_property(searchptr, searchpropname))) {
+ RNA_warning("search collection property not found: %s.%s",
+ RNA_struct_identifier(searchptr->type),
+ searchpropname);
+ }
+ else if (RNA_property_type(searchprop) != PROP_COLLECTION) {
+ RNA_warning("search collection property is not a collection type: %s.%s",
+ RNA_struct_identifier(searchptr->type),
+ searchpropname);
+ }
+ /* check if searchprop has same type as targetprop */
+ else if (RNA_property_pointer_type(searchptr, searchprop) !=
+ RNA_property_pointer_type(targetptr, targetprop)) {
+ RNA_warning("search collection items from %s.%s are not of type %s",
+ RNA_struct_identifier(searchptr->type),
+ searchpropname,
+ RNA_struct_identifier(RNA_property_pointer_type(targetptr, targetprop)));
+ }
+ else {
+ return searchprop;
+ }
+
+ return NULL;
}
-static TemplateSearch *template_search_setup(
- PointerRNA *ptr, const char * const propname,
- PointerRNA *searchptr, const char * const searchpropname)
+static TemplateSearch *template_search_setup(PointerRNA *ptr,
+ const char *const propname,
+ PointerRNA *searchptr,
+ const char *const searchpropname)
{
- TemplateSearch *template_search;
- PropertyRNA *prop, *searchprop;
+ TemplateSearch *template_search;
+ PropertyRNA *prop, *searchprop;
- prop = RNA_struct_find_property(ptr, propname);
+ prop = RNA_struct_find_property(ptr, propname);
- if (!prop || RNA_property_type(prop) != PROP_POINTER) {
- RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return NULL;
- }
- searchprop = template_search_get_searchprop(ptr, prop, searchptr, searchpropname);
+ if (!prop || RNA_property_type(prop) != PROP_POINTER) {
+ RNA_warning("pointer property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return NULL;
+ }
+ searchprop = template_search_get_searchprop(ptr, prop, searchptr, searchpropname);
- template_search = MEM_callocN(sizeof(*template_search), __func__);
- template_search->search_data.target_ptr = *ptr;
- template_search->search_data.target_prop = prop;
- template_search->search_data.search_ptr = *searchptr;
- template_search->search_data.search_prop = searchprop;
+ template_search = MEM_callocN(sizeof(*template_search), __func__);
+ template_search->search_data.target_ptr = *ptr;
+ template_search->search_data.target_prop = prop;
+ template_search->search_data.search_ptr = *searchptr;
+ template_search->search_data.search_prop = searchprop;
- return template_search;
+ return template_search;
}
/**
* Search menu to pick an item from a collection.
* A version of uiTemplateID that works for non-ID types.
*/
-void uiTemplateSearch(
- uiLayout *layout, bContext *C,
- PointerRNA *ptr, const char *propname,
- PointerRNA *searchptr, const char *searchpropname,
- const char *newop, const char *unlinkop)
+void uiTemplateSearch(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ PointerRNA *searchptr,
+ const char *searchpropname,
+ const char *newop,
+ const char *unlinkop)
{
- TemplateSearch *template_search = template_search_setup(ptr, propname, searchptr, searchpropname);
- if (template_search != NULL) {
- template_search_buttons(C, layout, template_search, newop, unlinkop);
- MEM_freeN(template_search);
- }
+ TemplateSearch *template_search = template_search_setup(
+ ptr, propname, searchptr, searchpropname);
+ if (template_search != NULL) {
+ template_search_buttons(C, layout, template_search, newop, unlinkop);
+ MEM_freeN(template_search);
+ }
}
-void uiTemplateSearchPreview(
- uiLayout *layout, bContext *C,
- PointerRNA *ptr, const char *propname,
- PointerRNA *searchptr, const char *searchpropname,
- const char *newop, const char *unlinkop,
- const int rows, const int cols)
+void uiTemplateSearchPreview(uiLayout *layout,
+ bContext *C,
+ PointerRNA *ptr,
+ const char *propname,
+ PointerRNA *searchptr,
+ const char *searchpropname,
+ const char *newop,
+ const char *unlinkop,
+ const int rows,
+ const int cols)
{
- TemplateSearch *template_search = template_search_setup(ptr, propname, searchptr, searchpropname);
+ TemplateSearch *template_search = template_search_setup(
+ ptr, propname, searchptr, searchpropname);
- if (template_search != NULL) {
- template_search->use_previews = true;
- template_search->preview_rows = rows;
- template_search->preview_cols = cols;
+ if (template_search != NULL) {
+ template_search->use_previews = true;
+ template_search->preview_rows = rows;
+ template_search->preview_cols = cols;
- template_search_buttons(C, layout, template_search, newop, unlinkop);
+ template_search_buttons(C, layout, template_search, newop, unlinkop);
- MEM_freeN(template_search);
- }
+ MEM_freeN(template_search);
+ }
}
/********************* RNA Path Builder Template ********************/
@@ -1314,28 +1696,30 @@ void uiTemplateSearchPreview(
* - propname: property identifier for property that path gets stored to
* - root_ptr: struct that path gets built from
*/
-void uiTemplatePathBuilder(
- uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *UNUSED(root_ptr),
- const char *text)
+void uiTemplatePathBuilder(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ PointerRNA *UNUSED(root_ptr),
+ const char *text)
{
- PropertyRNA *propPath;
- uiLayout *row;
+ PropertyRNA *propPath;
+ uiLayout *row;
- /* check that properties are valid */
- propPath = RNA_struct_find_property(ptr, propname);
- if (!propPath || RNA_property_type(propPath) != PROP_STRING) {
- RNA_warning("path property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ /* check that properties are valid */
+ propPath = RNA_struct_find_property(ptr, propname);
+ if (!propPath || RNA_property_type(propPath) != PROP_STRING) {
+ RNA_warning("path property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
- /* Start drawing UI Elements using standard defines */
- row = uiLayoutRow(layout, true);
+ /* Start drawing UI Elements using standard defines */
+ row = uiLayoutRow(layout, true);
- /* Path (existing string) Widget */
- uiItemR(row, ptr, propname, 0, text, ICON_RNA);
+ /* Path (existing string) Widget */
+ uiItemR(row, ptr, propname, 0, text, ICON_RNA);
- /* TODO: attach something to this to make allow
- * searching of nested properties to 'build' the path */
+ /* TODO: attach something to this to make allow
+ * searching of nested properties to 'build' the path */
}
/************************ Modifier Template *************************/
@@ -1344,796 +1728,887 @@ void uiTemplatePathBuilder(
static void modifiers_convertToReal(bContext *C, void *ob_v, void *md_v)
{
- Object *ob = ob_v;
- ModifierData *md = md_v;
- ModifierData *nmd = modifier_new(md->type);
+ Object *ob = ob_v;
+ ModifierData *md = md_v;
+ ModifierData *nmd = modifier_new(md->type);
- modifier_copyData(md, nmd);
- nmd->mode &= ~eModifierMode_Virtual;
+ modifier_copyData(md, nmd);
+ nmd->mode &= ~eModifierMode_Virtual;
- BLI_addhead(&ob->modifiers, nmd);
+ BLI_addhead(&ob->modifiers, nmd);
- modifier_unique_name(&ob->modifiers, nmd);
+ modifier_unique_name(&ob->modifiers, nmd);
- ob->partype = PAROBJECT;
+ ob->partype = PAROBJECT;
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
- ED_undo_push(C, "Modifier convert to real");
+ ED_undo_push(C, "Modifier convert to real");
}
static int modifier_can_delete(ModifierData *md)
{
- /* fluid particle modifier can't be deleted here */
- if (md->type == eModifierType_ParticleSystem) {
- if (((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID) {
- return 0;
- }
- }
-
- return 1;
+ /* fluid particle modifier can't be deleted here */
+ if (md->type == eModifierType_ParticleSystem) {
+ if (((ParticleSystemModifierData *)md)->psys->part->type == PART_FLUID) {
+ return 0;
+ }
+ }
+
+ return 1;
}
/* Check whether Modifier is a simulation or not,
* this is used for switching to the physics/particles context tab */
static int modifier_is_simulation(ModifierData *md)
{
- /* Physic Tab */
- if (ELEM(md->type, eModifierType_Cloth, eModifierType_Collision, eModifierType_Fluidsim, eModifierType_Smoke,
- eModifierType_Softbody, eModifierType_Surface, eModifierType_DynamicPaint))
- {
- return 1;
- }
- /* Particle Tab */
- else if (md->type == eModifierType_ParticleSystem) {
- return 2;
- }
- else {
- return 0;
- }
+ /* Physic Tab */
+ if (ELEM(md->type,
+ eModifierType_Cloth,
+ eModifierType_Collision,
+ eModifierType_Fluidsim,
+ eModifierType_Smoke,
+ eModifierType_Softbody,
+ eModifierType_Surface,
+ eModifierType_DynamicPaint)) {
+ return 1;
+ }
+ /* Particle Tab */
+ else if (md->type == eModifierType_ParticleSystem) {
+ return 2;
+ }
+ else {
+ return 0;
+ }
}
-static uiLayout *draw_modifier(
- uiLayout *layout, Scene *scene, Object *ob,
- ModifierData *md, int index, int cageIndex, int lastCageIndex)
+static uiLayout *draw_modifier(uiLayout *layout,
+ Scene *scene,
+ Object *ob,
+ ModifierData *md,
+ int index,
+ int cageIndex,
+ int lastCageIndex)
{
- const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- PointerRNA ptr;
- uiBut *but;
- uiBlock *block;
- uiLayout *box, *column, *row, *sub;
- uiLayout *result = NULL;
- int isVirtual = (md->mode & eModifierMode_Virtual);
- char str[128];
-
- /* create RNA pointer */
- RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
-
- column = uiLayoutColumn(layout, true);
- uiLayoutSetContextPointer(column, "modifier", &ptr);
-
- /* rounded header ------------------------------------------------------------------- */
- box = uiLayoutBox(column);
-
- if (isVirtual) {
- row = uiLayoutRow(box, false);
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
- block = uiLayoutGetBlock(row);
- /* VIRTUAL MODIFIER */
- /* XXX this is not used now, since these cannot be accessed via RNA */
- BLI_snprintf(str, sizeof(str), IFACE_("%s parent deform"), md->name);
- uiDefBut(block, UI_BTYPE_LABEL, 0, str, 0, 0, 185, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Modifier name"));
-
- but = uiDefBut(
- block, UI_BTYPE_BUT, 0, IFACE_("Make Real"), 0, 0, 80, 16, NULL, 0.0, 0.0, 0.0, 0.0,
- TIP_("Convert virtual modifier to a real modifier"));
- UI_but_func_set(but, modifiers_convertToReal, ob, md);
- }
- else {
- /* REAL MODIFIER */
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- /* Open/Close ................................. */
- uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
-
- /* modifier-type icon */
- uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
- UI_block_emboss_set(block, UI_EMBOSS);
-
- /* modifier name */
- if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
- uiLayoutSetRedAlert(row, true);
- }
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
- uiLayoutSetRedAlert(row, false);
-
- /* mode enabling buttons */
- UI_block_align_begin(block);
- /* Collision and Surface are always enabled, hide buttons! */
- if (((md->type != eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) &&
- (md->type != eModifierType_Surface) )
- {
- uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
- uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
-
- if (mti->flags & eModifierTypeFlag_SupportsEditmode) {
- sub = uiLayoutRow(row, true);
- if (!(md->mode & eModifierMode_Realtime)) {
- uiLayoutSetActive(sub, false);
- }
- uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
- }
- }
-
- if (ob->type == OB_MESH) {
- if (modifier_supportsCage(scene, md) && (index <= lastCageIndex)) {
- sub = uiLayoutRow(row, true);
- if (index < cageIndex || !modifier_couldBeCage(scene, md)) {
- uiLayoutSetActive(sub, false);
- }
- uiItemR(sub, &ptr, "show_on_cage", 0, "", ICON_NONE);
- }
- } /* tessellation point for curve-typed objects */
- else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
- /* some modifiers could work with pre-tessellated curves only */
- if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
- /* add disabled pre-tessellated button, so users could have
- * message for this modifiers */
- but = uiDefIconButBitI(
- block, UI_BTYPE_TOGGLE, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0,
- UI_UNIT_X - 2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0,
- TIP_("This modifier can only be applied on splines' points"));
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- else if (mti->type != eModifierTypeType_Constructive) {
- /* constructive modifiers tessellates curve before applying */
- uiItemR(row, &ptr, "use_apply_on_spline", 0, "", ICON_NONE);
- }
- }
-
- UI_block_align_end(block);
-
- /* Up/Down + Delete ........................... */
- UI_block_align_begin(block);
- uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_modifier_move_up");
- uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_modifier_move_down");
- UI_block_align_end(block);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- /* When Modifier is a simulation,
- * show button to switch to context rather than the delete button. */
- if (modifier_can_delete(md) &&
- !modifier_is_simulation(md))
- {
- uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove");
- }
- else if (modifier_is_simulation(md) == 1) {
- uiItemStringO(row, "", ICON_PROPERTIES, "WM_OT_properties_context_change", "context", "PHYSICS");
- }
- else if (modifier_is_simulation(md) == 2) {
- uiItemStringO(row, "", ICON_PROPERTIES, "WM_OT_properties_context_change", "context", "PARTICLES");
- }
- UI_block_emboss_set(block, UI_EMBOSS);
- }
-
-
- /* modifier settings (under the header) --------------------------------------------------- */
- if (!isVirtual && (md->mode & eModifierMode_Expanded)) {
- /* apply/convert/copy */
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
-
- if (!ELEM(md->type, eModifierType_Collision, eModifierType_Surface)) {
- /* only here obdata, the rest of modifiers is ob level */
- UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
- if (md->type == eModifierType_ParticleSystem) {
- ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
-
- if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
- if (ELEM(psys->part->ren_as, PART_DRAW_GR, PART_DRAW_OB)) {
- uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE,
- "OBJECT_OT_duplicates_make_real");
- }
- else if (psys->part->ren_as == PART_DRAW_PATH) {
- uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"), ICON_NONE,
- "OBJECT_OT_modifier_convert");
- }
- }
- }
- else {
- uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
- uiItemEnumO(
- row, "OBJECT_OT_modifier_apply", CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
- 0, "apply_as", MODIFIER_APPLY_DATA);
-
- if (modifier_isSameTopology(md) && !modifier_isNonGeometrical(md)) {
- uiItemEnumO(
- row, "OBJECT_OT_modifier_apply",
- CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply as Shape Key"),
- 0, "apply_as", MODIFIER_APPLY_SHAPE);
- }
- }
-
- UI_block_lock_clear(block);
- UI_block_lock_set(block, ob && ID_IS_LINKED(ob), ERROR_LIBDATA_MESSAGE);
-
- if (!ELEM(md->type, eModifierType_Fluidsim, eModifierType_Softbody, eModifierType_ParticleSystem,
- eModifierType_Cloth, eModifierType_Smoke))
- {
- uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"), ICON_NONE,
- "OBJECT_OT_modifier_copy");
- }
- }
-
- /* result is the layout block inside the box,
- * that we return so that modifier settings can be drawn */
- result = uiLayoutColumn(box, false);
- block = uiLayoutAbsoluteBlock(box);
- }
-
- /* error messages */
- if (md->error) {
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
- uiItemL(row, md->error, ICON_ERROR);
- }
-
- return result;
+ const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+ PointerRNA ptr;
+ uiBut *but;
+ uiBlock *block;
+ uiLayout *box, *column, *row, *sub;
+ uiLayout *result = NULL;
+ int isVirtual = (md->mode & eModifierMode_Virtual);
+ char str[128];
+
+ /* create RNA pointer */
+ RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
+
+ column = uiLayoutColumn(layout, true);
+ uiLayoutSetContextPointer(column, "modifier", &ptr);
+
+ /* rounded header ------------------------------------------------------------------- */
+ box = uiLayoutBox(column);
+
+ if (isVirtual) {
+ row = uiLayoutRow(box, false);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_EXPAND);
+ block = uiLayoutGetBlock(row);
+ /* VIRTUAL MODIFIER */
+ /* XXX this is not used now, since these cannot be accessed via RNA */
+ BLI_snprintf(str, sizeof(str), IFACE_("%s parent deform"), md->name);
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ str,
+ 0,
+ 0,
+ 185,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Modifier name"));
+
+ but = uiDefBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ IFACE_("Make Real"),
+ 0,
+ 0,
+ 80,
+ 16,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Convert virtual modifier to a real modifier"));
+ UI_but_func_set(but, modifiers_convertToReal, ob, md);
+ }
+ else {
+ /* REAL MODIFIER */
+ row = uiLayoutRow(box, false);
+ block = uiLayoutGetBlock(row);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ /* Open/Close ................................. */
+ uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
+
+ /* modifier-type icon */
+ uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* modifier name */
+ if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
+ uiLayoutSetRedAlert(row, true);
+ }
+ uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
+ uiLayoutSetRedAlert(row, false);
+
+ /* mode enabling buttons */
+ UI_block_align_begin(block);
+ /* Collision and Surface are always enabled, hide buttons! */
+ if (((md->type != eModifierType_Collision) || !(ob->pd && ob->pd->deflect)) &&
+ (md->type != eModifierType_Surface)) {
+ uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
+ uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
+
+ if (mti->flags & eModifierTypeFlag_SupportsEditmode) {
+ sub = uiLayoutRow(row, true);
+ if (!(md->mode & eModifierMode_Realtime)) {
+ uiLayoutSetActive(sub, false);
+ }
+ uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
+ }
+ }
+
+ if (ob->type == OB_MESH) {
+ if (modifier_supportsCage(scene, md) && (index <= lastCageIndex)) {
+ sub = uiLayoutRow(row, true);
+ if (index < cageIndex || !modifier_couldBeCage(scene, md)) {
+ uiLayoutSetActive(sub, false);
+ }
+ uiItemR(sub, &ptr, "show_on_cage", 0, "", ICON_NONE);
+ }
+ } /* tessellation point for curve-typed objects */
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ /* some modifiers could work with pre-tessellated curves only */
+ if (ELEM(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
+ /* add disabled pre-tessellated button, so users could have
+ * message for this modifiers */
+ but = uiDefIconButBitI(block,
+ UI_BTYPE_TOGGLE,
+ eModifierMode_ApplyOnSpline,
+ 0,
+ ICON_SURFACE_DATA,
+ 0,
+ 0,
+ UI_UNIT_X - 2,
+ UI_UNIT_Y,
+ &md->mode,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("This modifier can only be applied on splines' points"));
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ else if (mti->type != eModifierTypeType_Constructive) {
+ /* constructive modifiers tessellates curve before applying */
+ uiItemR(row, &ptr, "use_apply_on_spline", 0, "", ICON_NONE);
+ }
+ }
+
+ UI_block_align_end(block);
+
+ /* Up/Down + Delete ........................... */
+ UI_block_align_begin(block);
+ uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_modifier_move_up");
+ uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_modifier_move_down");
+ UI_block_align_end(block);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ /* When Modifier is a simulation,
+ * show button to switch to context rather than the delete button. */
+ if (modifier_can_delete(md) && !modifier_is_simulation(md)) {
+ uiItemO(row, "", ICON_X, "OBJECT_OT_modifier_remove");
+ }
+ else if (modifier_is_simulation(md) == 1) {
+ uiItemStringO(
+ row, "", ICON_PROPERTIES, "WM_OT_properties_context_change", "context", "PHYSICS");
+ }
+ else if (modifier_is_simulation(md) == 2) {
+ uiItemStringO(
+ row, "", ICON_PROPERTIES, "WM_OT_properties_context_change", "context", "PARTICLES");
+ }
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
+
+ /* modifier settings (under the header) --------------------------------------------------- */
+ if (!isVirtual && (md->mode & eModifierMode_Expanded)) {
+ /* apply/convert/copy */
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+
+ if (!ELEM(md->type, eModifierType_Collision, eModifierType_Surface)) {
+ /* only here obdata, the rest of modifiers is ob level */
+ UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
+
+ if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) {
+ if (ELEM(psys->part->ren_as, PART_DRAW_GR, PART_DRAW_OB)) {
+ uiItemO(row,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"),
+ ICON_NONE,
+ "OBJECT_OT_duplicates_make_real");
+ }
+ else if (psys->part->ren_as == PART_DRAW_PATH) {
+ uiItemO(row,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Convert"),
+ ICON_NONE,
+ "OBJECT_OT_modifier_convert");
+ }
+ }
+ }
+ else {
+ uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
+ uiItemEnumO(row,
+ "OBJECT_OT_modifier_apply",
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
+ 0,
+ "apply_as",
+ MODIFIER_APPLY_DATA);
+
+ if (modifier_isSameTopology(md) && !modifier_isNonGeometrical(md)) {
+ uiItemEnumO(row,
+ "OBJECT_OT_modifier_apply",
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply as Shape Key"),
+ 0,
+ "apply_as",
+ MODIFIER_APPLY_SHAPE);
+ }
+ }
+
+ UI_block_lock_clear(block);
+ UI_block_lock_set(block, ob && ID_IS_LINKED(ob), ERROR_LIBDATA_MESSAGE);
+
+ if (!ELEM(md->type,
+ eModifierType_Fluidsim,
+ eModifierType_Softbody,
+ eModifierType_ParticleSystem,
+ eModifierType_Cloth,
+ eModifierType_Smoke)) {
+ uiItemO(row,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"),
+ ICON_NONE,
+ "OBJECT_OT_modifier_copy");
+ }
+ }
+
+ /* result is the layout block inside the box,
+ * that we return so that modifier settings can be drawn */
+ result = uiLayoutColumn(box, false);
+ block = uiLayoutAbsoluteBlock(box);
+ }
+
+ /* error messages */
+ if (md->error) {
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, md->error, ICON_ERROR);
+ }
+
+ return result;
}
uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
- Scene *scene = CTX_data_scene(C);
- Object *ob;
- ModifierData *md, *vmd;
- VirtualModifierData virtualModifierData;
- int i, lastCageIndex, cageIndex;
-
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
-
- ob = ptr->id.data;
- md = ptr->data;
-
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
-
- UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
-
- /* find modifier and draw it */
- cageIndex = modifiers_getCageIndex(scene, ob, &lastCageIndex, 0);
-
- /* XXX virtual modifiers are not accessible for python */
- vmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
-
- for (i = 0; vmd; i++, vmd = vmd->next) {
- if (md == vmd) {
- return draw_modifier(layout, scene, ob, md, i, cageIndex, lastCageIndex);
- }
- else if (vmd->mode & eModifierMode_Virtual) {
- i--;
- }
- }
-
- return NULL;
+ Scene *scene = CTX_data_scene(C);
+ Object *ob;
+ ModifierData *md, *vmd;
+ VirtualModifierData virtualModifierData;
+ int i, lastCageIndex, cageIndex;
+
+ /* verify we have valid data */
+ if (!RNA_struct_is_a(ptr->type, &RNA_Modifier)) {
+ RNA_warning("Expected modifier on object");
+ return NULL;
+ }
+
+ ob = ptr->id.data;
+ md = ptr->data;
+
+ if (!ob || !(GS(ob->id.name) == ID_OB)) {
+ RNA_warning("Expected modifier on object");
+ return NULL;
+ }
+
+ UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
+
+ /* find modifier and draw it */
+ cageIndex = modifiers_getCageIndex(scene, ob, &lastCageIndex, 0);
+
+ /* XXX virtual modifiers are not accessible for python */
+ vmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+
+ for (i = 0; vmd; i++, vmd = vmd->next) {
+ if (md == vmd) {
+ return draw_modifier(layout, scene, ob, md, i, cageIndex, lastCageIndex);
+ }
+ else if (vmd->mode & eModifierMode_Virtual) {
+ i--;
+ }
+ }
+
+ return NULL;
}
/************************ Grease Pencil Modifier Template *************************/
-static uiLayout *gpencil_draw_modifier(
- uiLayout *layout, Object *ob,
- GpencilModifierData *md)
+static uiLayout *gpencil_draw_modifier(uiLayout *layout, Object *ob, GpencilModifierData *md)
{
- const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
- PointerRNA ptr;
- uiBlock *block;
- uiLayout *box, *column, *row, *sub;
- uiLayout *result = NULL;
-
- /* create RNA pointer */
- RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr);
-
- column = uiLayoutColumn(layout, true);
- uiLayoutSetContextPointer(column, "modifier", &ptr);
-
- /* rounded header ------------------------------------------------------------------- */
- box = uiLayoutBox(column);
-
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- /* Open/Close ................................. */
- uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
-
- /* modifier-type icon */
- uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
- UI_block_emboss_set(block, UI_EMBOSS);
-
- /* modifier name */
- if (mti->isDisabled && mti->isDisabled(md, 0)) {
- uiLayoutSetRedAlert(row, true);
- }
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
- uiLayoutSetRedAlert(row, false);
-
- /* mode enabling buttons */
- UI_block_align_begin(block);
- uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
- uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
-
- if (mti->flags & eGpencilModifierTypeFlag_SupportsEditmode) {
- sub = uiLayoutRow(row, true);
- uiLayoutSetActive(sub, false);
- uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
- }
-
- UI_block_align_end(block);
-
- /* Up/Down + Delete ........................... */
- UI_block_align_begin(block);
- uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_gpencil_modifier_move_up");
- uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_gpencil_modifier_move_down");
- UI_block_align_end(block);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemO(row, "", ICON_X, "OBJECT_OT_gpencil_modifier_remove");
- UI_block_emboss_set(block, UI_EMBOSS);
-
- /* modifier settings (under the header) --------------------------------------------------- */
- if (md->mode & eGpencilModifierMode_Expanded) {
- /* apply/convert/copy */
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
-
- /* only here obdata, the rest of modifiers is ob level */
- UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
- uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
-
- sub = uiLayoutRow(row, false);
- if (mti->flags & eGpencilModifierTypeFlag_NoApply) {
- uiLayoutSetEnabled(sub, false);
- }
- uiItemEnumO(sub, "OBJECT_OT_gpencil_modifier_apply", CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
- 0, "apply_as", MODIFIER_APPLY_DATA);
- uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"), ICON_NONE,
- "OBJECT_OT_gpencil_modifier_copy");
-
- /* result is the layout block inside the box,
- * that we return so that modifier settings can be drawn */
- result = uiLayoutColumn(box, false);
- block = uiLayoutAbsoluteBlock(box);
- }
-
- /* error messages */
- if (md->error) {
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
- uiItemL(row, md->error, ICON_ERROR);
- }
-
- return result;
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
+ PointerRNA ptr;
+ uiBlock *block;
+ uiLayout *box, *column, *row, *sub;
+ uiLayout *result = NULL;
+
+ /* create RNA pointer */
+ RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, &ptr);
+
+ column = uiLayoutColumn(layout, true);
+ uiLayoutSetContextPointer(column, "modifier", &ptr);
+
+ /* rounded header ------------------------------------------------------------------- */
+ box = uiLayoutBox(column);
+
+ row = uiLayoutRow(box, false);
+ block = uiLayoutGetBlock(row);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ /* Open/Close ................................. */
+ uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
+
+ /* modifier-type icon */
+ uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* modifier name */
+ if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ uiLayoutSetRedAlert(row, true);
+ }
+ uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
+ uiLayoutSetRedAlert(row, false);
+
+ /* mode enabling buttons */
+ UI_block_align_begin(block);
+ uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
+ uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
+
+ if (mti->flags & eGpencilModifierTypeFlag_SupportsEditmode) {
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, false);
+ uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
+ }
+
+ UI_block_align_end(block);
+
+ /* Up/Down + Delete ........................... */
+ UI_block_align_begin(block);
+ uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_gpencil_modifier_move_up");
+ uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_gpencil_modifier_move_down");
+ UI_block_align_end(block);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiItemO(row, "", ICON_X, "OBJECT_OT_gpencil_modifier_remove");
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* modifier settings (under the header) --------------------------------------------------- */
+ if (md->mode & eGpencilModifierMode_Expanded) {
+ /* apply/convert/copy */
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+
+ /* only here obdata, the rest of modifiers is ob level */
+ UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
+
+ sub = uiLayoutRow(row, false);
+ if (mti->flags & eGpencilModifierTypeFlag_NoApply) {
+ uiLayoutSetEnabled(sub, false);
+ }
+ uiItemEnumO(sub,
+ "OBJECT_OT_gpencil_modifier_apply",
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
+ 0,
+ "apply_as",
+ MODIFIER_APPLY_DATA);
+ uiItemO(row,
+ CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"),
+ ICON_NONE,
+ "OBJECT_OT_gpencil_modifier_copy");
+
+ /* result is the layout block inside the box,
+ * that we return so that modifier settings can be drawn */
+ result = uiLayoutColumn(box, false);
+ block = uiLayoutAbsoluteBlock(box);
+ }
+
+ /* error messages */
+ if (md->error) {
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, md->error, ICON_ERROR);
+ }
+
+ return result;
}
uiLayout *uiTemplateGpencilModifier(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- Object *ob;
- GpencilModifierData *md, *vmd;
- int i;
-
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_GpencilModifier)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
-
- ob = ptr->id.data;
- md = ptr->data;
-
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected modifier on object");
- return NULL;
- }
-
- UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
-
- /* find modifier and draw it */
- vmd = ob->greasepencil_modifiers.first;
- for (i = 0; vmd; i++, vmd = vmd->next) {
- if (md == vmd) {
- return gpencil_draw_modifier(layout, ob, md);
- }
- }
-
- return NULL;
+ Object *ob;
+ GpencilModifierData *md, *vmd;
+ int i;
+
+ /* verify we have valid data */
+ if (!RNA_struct_is_a(ptr->type, &RNA_GpencilModifier)) {
+ RNA_warning("Expected modifier on object");
+ return NULL;
+ }
+
+ ob = ptr->id.data;
+ md = ptr->data;
+
+ if (!ob || !(GS(ob->id.name) == ID_OB)) {
+ RNA_warning("Expected modifier on object");
+ return NULL;
+ }
+
+ UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
+
+ /* find modifier and draw it */
+ vmd = ob->greasepencil_modifiers.first;
+ for (i = 0; vmd; i++, vmd = vmd->next) {
+ if (md == vmd) {
+ return gpencil_draw_modifier(layout, ob, md);
+ }
+ }
+
+ return NULL;
}
/************************ Shader FX Template *************************/
-static uiLayout *gpencil_draw_shaderfx(
- uiLayout *layout, Object *ob,
- ShaderFxData *md)
+static uiLayout *gpencil_draw_shaderfx(uiLayout *layout, Object *ob, ShaderFxData *md)
{
- const ShaderFxTypeInfo *mti = BKE_shaderfxType_getInfo(md->type);
- PointerRNA ptr;
- uiBlock *block;
- uiLayout *box, *column, *row, *sub;
- uiLayout *result = NULL;
-
- /* create RNA pointer */
- RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, &ptr);
-
- column = uiLayoutColumn(layout, true);
- uiLayoutSetContextPointer(column, "shaderfx", &ptr);
-
- /* rounded header ------------------------------------------------------------------- */
- box = uiLayoutBox(column);
-
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- /* Open/Close ................................. */
- uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
-
- /* shader-type icon */
- uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
- UI_block_emboss_set(block, UI_EMBOSS);
-
- /* effect name */
- if (mti->isDisabled && mti->isDisabled(md, 0)) {
- uiLayoutSetRedAlert(row, true);
- }
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
- uiLayoutSetRedAlert(row, false);
-
- /* mode enabling buttons */
- UI_block_align_begin(block);
- uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
- uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
-
- if (mti->flags & eShaderFxTypeFlag_SupportsEditmode) {
- sub = uiLayoutRow(row, true);
- uiLayoutSetActive(sub, false);
- uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
- }
-
- UI_block_align_end(block);
-
- /* Up/Down + Delete ........................... */
- UI_block_align_begin(block);
- uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_shaderfx_move_up");
- uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_shaderfx_move_down");
- UI_block_align_end(block);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemO(row, "", ICON_X, "OBJECT_OT_shaderfx_remove");
- UI_block_emboss_set(block, UI_EMBOSS);
-
- /* effect settings (under the header) --------------------------------------------------- */
- if (md->mode & eShaderFxMode_Expanded) {
- /* apply/convert/copy */
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
-
- /* only here obdata, the rest of effect is ob level */
- UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
- /* result is the layout block inside the box,
- * that we return so that effect settings can be drawn */
- result = uiLayoutColumn(box, false);
- block = uiLayoutAbsoluteBlock(box);
- }
-
- /* error messages */
- if (md->error) {
- box = uiLayoutBox(column);
- row = uiLayoutRow(box, false);
- uiItemL(row, md->error, ICON_ERROR);
- }
-
- return result;
+ const ShaderFxTypeInfo *mti = BKE_shaderfxType_getInfo(md->type);
+ PointerRNA ptr;
+ uiBlock *block;
+ uiLayout *box, *column, *row, *sub;
+ uiLayout *result = NULL;
+
+ /* create RNA pointer */
+ RNA_pointer_create(&ob->id, &RNA_ShaderFx, md, &ptr);
+
+ column = uiLayoutColumn(layout, true);
+ uiLayoutSetContextPointer(column, "shaderfx", &ptr);
+
+ /* rounded header ------------------------------------------------------------------- */
+ box = uiLayoutBox(column);
+
+ row = uiLayoutRow(box, false);
+ block = uiLayoutGetBlock(row);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ /* Open/Close ................................. */
+ uiItemR(row, &ptr, "show_expanded", 0, "", ICON_NONE);
+
+ /* shader-type icon */
+ uiItemL(row, "", RNA_struct_ui_icon(ptr.type));
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* effect name */
+ if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ uiLayoutSetRedAlert(row, true);
+ }
+ uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
+ uiLayoutSetRedAlert(row, false);
+
+ /* mode enabling buttons */
+ UI_block_align_begin(block);
+ uiItemR(row, &ptr, "show_render", 0, "", ICON_NONE);
+ uiItemR(row, &ptr, "show_viewport", 0, "", ICON_NONE);
+
+ if (mti->flags & eShaderFxTypeFlag_SupportsEditmode) {
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetActive(sub, false);
+ uiItemR(sub, &ptr, "show_in_editmode", 0, "", ICON_NONE);
+ }
+
+ UI_block_align_end(block);
+
+ /* Up/Down + Delete ........................... */
+ UI_block_align_begin(block);
+ uiItemO(row, "", ICON_TRIA_UP, "OBJECT_OT_shaderfx_move_up");
+ uiItemO(row, "", ICON_TRIA_DOWN, "OBJECT_OT_shaderfx_move_down");
+ UI_block_align_end(block);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiItemO(row, "", ICON_X, "OBJECT_OT_shaderfx_remove");
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* effect settings (under the header) --------------------------------------------------- */
+ if (md->mode & eShaderFxMode_Expanded) {
+ /* apply/convert/copy */
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+
+ /* only here obdata, the rest of effect is ob level */
+ UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
+
+ /* result is the layout block inside the box,
+ * that we return so that effect settings can be drawn */
+ result = uiLayoutColumn(box, false);
+ block = uiLayoutAbsoluteBlock(box);
+ }
+
+ /* error messages */
+ if (md->error) {
+ box = uiLayoutBox(column);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, md->error, ICON_ERROR);
+ }
+
+ return result;
}
uiLayout *uiTemplateShaderFx(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- Object *ob;
- ShaderFxData *fx, *vfx;
- int i;
-
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_ShaderFx)) {
- RNA_warning("Expected shader fx on object");
- return NULL;
- }
-
- ob = ptr->id.data;
- fx = ptr->data;
-
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected shader fx on object");
- return NULL;
- }
-
- UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
-
- /* find modifier and draw it */
- vfx = ob->shader_fx.first;
- for (i = 0; vfx; i++, vfx = vfx->next) {
- if (fx == vfx) {
- return gpencil_draw_shaderfx(layout, ob, fx);
- }
- }
-
- return NULL;
+ Object *ob;
+ ShaderFxData *fx, *vfx;
+ int i;
+
+ /* verify we have valid data */
+ if (!RNA_struct_is_a(ptr->type, &RNA_ShaderFx)) {
+ RNA_warning("Expected shader fx on object");
+ return NULL;
+ }
+
+ ob = ptr->id.data;
+ fx = ptr->data;
+
+ if (!ob || !(GS(ob->id.name) == ID_OB)) {
+ RNA_warning("Expected shader fx on object");
+ return NULL;
+ }
+
+ UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
+
+ /* find modifier and draw it */
+ vfx = ob->shader_fx.first;
+ for (i = 0; vfx; i++, vfx = vfx->next) {
+ if (fx == vfx) {
+ return gpencil_draw_shaderfx(layout, ob, fx);
+ }
+ }
+
+ return NULL;
}
/************************ Redo Buttons Template *************************/
static void template_operator_redo_property_buts_draw(
- const bContext *C, wmOperator *op,
- uiLayout *layout, int layout_flags,
- bool *r_has_advanced)
+ const bContext *C, wmOperator *op, uiLayout *layout, int layout_flags, bool *r_has_advanced)
{
- if (op->type->flag & OPTYPE_MACRO) {
- for (wmOperator *macro_op = op->macro.first; macro_op; macro_op = macro_op->next) {
- template_operator_redo_property_buts_draw(C, macro_op, layout, layout_flags, r_has_advanced);
- }
- }
- else {
- /* Might want to make label_align adjustable somehow. */
- eAutoPropButsReturn return_info = uiTemplateOperatorPropertyButs(
- C, layout, op,
- UI_BUT_LABEL_ALIGN_NONE,
- layout_flags);
- if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) {
- if (r_has_advanced) {
- *r_has_advanced = true;
- }
- }
- }
+ if (op->type->flag & OPTYPE_MACRO) {
+ for (wmOperator *macro_op = op->macro.first; macro_op; macro_op = macro_op->next) {
+ template_operator_redo_property_buts_draw(C, macro_op, layout, layout_flags, r_has_advanced);
+ }
+ }
+ else {
+ /* Might want to make label_align adjustable somehow. */
+ eAutoPropButsReturn return_info = uiTemplateOperatorPropertyButs(
+ C, layout, op, UI_BUT_LABEL_ALIGN_NONE, layout_flags);
+ if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) {
+ if (r_has_advanced) {
+ *r_has_advanced = true;
+ }
+ }
+ }
}
void uiTemplateOperatorRedoProperties(uiLayout *layout, const bContext *C)
{
- wmOperator *op = WM_operator_last_redo(C);
- uiBlock *block = uiLayoutGetBlock(layout);
+ wmOperator *op = WM_operator_last_redo(C);
+ uiBlock *block = uiLayoutGetBlock(layout);
- if (op == NULL) {
- return;
- }
+ if (op == NULL) {
+ return;
+ }
- /* Disable for now, doesn't fit well in popover. */
+ /* Disable for now, doesn't fit well in popover. */
#if 0
- /* Repeat button with operator name as text. */
- uiItemFullO(layout, "SCREEN_OT_repeat_last", RNA_struct_ui_name(op->type->srna),
- ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
+ /* Repeat button with operator name as text. */
+ uiItemFullO(layout, "SCREEN_OT_repeat_last", RNA_struct_ui_name(op->type->srna),
+ ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL);
#endif
- if (WM_operator_repeat_check(C, op)) {
- int layout_flags = 0;
- if (block->panel == NULL) {
- layout_flags = UI_TEMPLATE_OP_PROPS_SHOW_TITLE;
- }
+ if (WM_operator_repeat_check(C, op)) {
+ int layout_flags = 0;
+ if (block->panel == NULL) {
+ layout_flags = UI_TEMPLATE_OP_PROPS_SHOW_TITLE;
+ }
#if 0
- bool has_advanced = false;
+ bool has_advanced = false;
#endif
- UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op);
- template_operator_redo_property_buts_draw(C, op, layout, layout_flags, NULL /* &has_advanced */ );
- /* Warning! this leaves the handle function for any other users of this block. */
+ UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op);
+ template_operator_redo_property_buts_draw(
+ C, op, layout, layout_flags, NULL /* &has_advanced */);
+ /* Warning! this leaves the handle function for any other users of this block. */
#if 0
- if (has_advanced) {
- uiItemO(layout, IFACE_("More..."), ICON_NONE, "SCREEN_OT_redo_last");
- }
+ if (has_advanced) {
+ uiItemO(layout, IFACE_("More..."), ICON_NONE, "SCREEN_OT_redo_last");
+ }
#endif
- }
+ }
}
/************************ Constraint Template *************************/
static void constraint_active_func(bContext *UNUSED(C), void *ob_v, void *con_v)
{
- ED_object_constraint_set_active(ob_v, con_v);
+ ED_object_constraint_set_active(ob_v, con_v);
}
/* draw panel showing settings for a constraint */
static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con)
{
- bPoseChannel *pchan = BKE_pose_channel_active(ob);
- const bConstraintTypeInfo *cti;
- uiBlock *block;
- uiLayout *result = NULL, *col, *box, *row;
- PointerRNA ptr;
- char typestr[32];
- short proxy_protected, xco = 0, yco = 0;
- // int rb_col; // UNUSED
-
- /* get constraint typeinfo */
- cti = BKE_constraint_typeinfo_get(con);
- if (cti == NULL) {
- /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
- BLI_strncpy(typestr, (con->type == CONSTRAINT_TYPE_NULL) ? IFACE_("Null") : IFACE_("Unknown"), sizeof(typestr));
- }
- else {
- BLI_strncpy(typestr, IFACE_(cti->name), sizeof(typestr));
- }
-
- /* determine whether constraint is proxy protected or not */
- if (BKE_constraints_proxylocked_owner(ob, pchan)) {
- proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
- }
- else {
- proxy_protected = 0;
- }
-
- /* unless button has own callback, it adds this callback to button */
- block = uiLayoutGetBlock(layout);
- UI_block_func_set(block, constraint_active_func, ob, con);
-
- RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
-
- col = uiLayoutColumn(layout, true);
- uiLayoutSetContextPointer(col, "constraint", &ptr);
-
- box = uiLayoutBox(col);
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(box);
-
- /* Draw constraint header */
-
- /* open/close */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemR(row, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- UI_block_emboss_set(block, UI_EMBOSS);
-
- /* name */
- uiDefBut(block, UI_BTYPE_LABEL, 0, typestr,
- xco + 0.5f * UI_UNIT_X, yco, 5 * UI_UNIT_X, 0.9f * UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "");
-
- if (con->flag & CONSTRAINT_DISABLE) {
- uiLayoutSetRedAlert(row, true);
- }
-
- if (proxy_protected == 0) {
- uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
- }
- else {
- uiItemL(row, con->name, ICON_NONE);
- }
-
- uiLayoutSetRedAlert(row, false);
-
- /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
- if (proxy_protected) {
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- /* draw a ghost icon (for proxy) and also a lock beside it,
- * to show that constraint is "proxy locked" */
- uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_GHOST_ENABLED, xco + 12.2f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
- uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_LOCKED, xco + 13.1f * UI_UNIT_X, yco, 0.95f * UI_UNIT_X, 0.95f * UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Proxy Protected"));
-
- UI_block_emboss_set(block, UI_EMBOSS);
- }
- else {
- short prev_proxylock, show_upbut, show_downbut;
-
- /* Up/Down buttons:
- * Proxy-constraints are not allowed to occur after local (non-proxy) constraints
- * as that poses problems when restoring them, so disable the "up" button where
- * it may cause this situation.
- *
- * Up/Down buttons should only be shown (or not grayed - todo) if they serve some purpose.
- */
- if (BKE_constraints_proxylocked_owner(ob, pchan)) {
- if (con->prev) {
- prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
- }
- else {
- prev_proxylock = 0;
- }
- }
- else {
- prev_proxylock = 0;
- }
-
- show_upbut = ((prev_proxylock == 0) && (con->prev));
- show_downbut = (con->next) ? 1 : 0;
-
- /* enabled */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemR(row, &ptr, "mute", 0, "",
- (con->flag & CONSTRAINT_OFF) ? ICON_HIDE_ON : ICON_HIDE_OFF);
- UI_block_emboss_set(block, UI_EMBOSS);
-
- uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
-
- /* up/down */
- if (show_upbut || show_downbut) {
- UI_block_align_begin(block);
- if (show_upbut) {
- uiItemO(row, "", ICON_TRIA_UP, "CONSTRAINT_OT_move_up");
- }
-
- if (show_downbut) {
- uiItemO(row, "", ICON_TRIA_DOWN, "CONSTRAINT_OT_move_down");
- }
- UI_block_align_end(block);
- }
-
- /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- uiItemO(row, "", ICON_X, "CONSTRAINT_OT_delete");
- UI_block_emboss_set(block, UI_EMBOSS);
- }
-
- /* Set but-locks for protected settings (magic numbers are used here!) */
- if (proxy_protected) {
- UI_block_lock_set(block, true, IFACE_("Cannot edit Proxy-Protected Constraint"));
- }
-
- /* Draw constraint data */
- if ((con->flag & CONSTRAINT_EXPAND) == 0) {
- (yco) -= 10.5f * UI_UNIT_Y;
- }
- else {
- box = uiLayoutBox(col);
- block = uiLayoutAbsoluteBlock(box);
- result = box;
- }
-
- /* clear any locks set up for proxies/lib-linking */
- UI_block_lock_clear(block);
-
- return result;
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+ const bConstraintTypeInfo *cti;
+ uiBlock *block;
+ uiLayout *result = NULL, *col, *box, *row;
+ PointerRNA ptr;
+ char typestr[32];
+ short proxy_protected, xco = 0, yco = 0;
+ // int rb_col; // UNUSED
+
+ /* get constraint typeinfo */
+ cti = BKE_constraint_typeinfo_get(con);
+ if (cti == NULL) {
+ /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
+ BLI_strncpy(typestr,
+ (con->type == CONSTRAINT_TYPE_NULL) ? IFACE_("Null") : IFACE_("Unknown"),
+ sizeof(typestr));
+ }
+ else {
+ BLI_strncpy(typestr, IFACE_(cti->name), sizeof(typestr));
+ }
+
+ /* determine whether constraint is proxy protected or not */
+ if (BKE_constraints_proxylocked_owner(ob, pchan)) {
+ proxy_protected = (con->flag & CONSTRAINT_PROXY_LOCAL) == 0;
+ }
+ else {
+ proxy_protected = 0;
+ }
+
+ /* unless button has own callback, it adds this callback to button */
+ block = uiLayoutGetBlock(layout);
+ UI_block_func_set(block, constraint_active_func, ob, con);
+
+ RNA_pointer_create(&ob->id, &RNA_Constraint, con, &ptr);
+
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetContextPointer(col, "constraint", &ptr);
+
+ box = uiLayoutBox(col);
+ row = uiLayoutRow(box, false);
+ block = uiLayoutGetBlock(box);
+
+ /* Draw constraint header */
+
+ /* open/close */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiItemR(row, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* name */
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ typestr,
+ xco + 0.5f * UI_UNIT_X,
+ yco,
+ 5 * UI_UNIT_X,
+ 0.9f * UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ "");
+
+ if (con->flag & CONSTRAINT_DISABLE) {
+ uiLayoutSetRedAlert(row, true);
+ }
+
+ if (proxy_protected == 0) {
+ uiItemR(row, &ptr, "name", 0, "", ICON_NONE);
+ }
+ else {
+ uiItemL(row, con->name, ICON_NONE);
+ }
+
+ uiLayoutSetRedAlert(row, false);
+
+ /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
+ if (proxy_protected) {
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ /* draw a ghost icon (for proxy) and also a lock beside it,
+ * to show that constraint is "proxy locked" */
+ uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_GHOST_ENABLED,
+ xco + 12.2f * UI_UNIT_X,
+ yco,
+ 0.95f * UI_UNIT_X,
+ 0.95f * UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Proxy Protected"));
+ uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_LOCKED,
+ xco + 13.1f * UI_UNIT_X,
+ yco,
+ 0.95f * UI_UNIT_X,
+ 0.95f * UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Proxy Protected"));
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
+ else {
+ short prev_proxylock, show_upbut, show_downbut;
+
+ /* Up/Down buttons:
+ * Proxy-constraints are not allowed to occur after local (non-proxy) constraints
+ * as that poses problems when restoring them, so disable the "up" button where
+ * it may cause this situation.
+ *
+ * Up/Down buttons should only be shown (or not grayed - todo) if they serve some purpose.
+ */
+ if (BKE_constraints_proxylocked_owner(ob, pchan)) {
+ if (con->prev) {
+ prev_proxylock = (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
+ }
+ else {
+ prev_proxylock = 0;
+ }
+ }
+ else {
+ prev_proxylock = 0;
+ }
+
+ show_upbut = ((prev_proxylock == 0) && (con->prev));
+ show_downbut = (con->next) ? 1 : 0;
+
+ /* enabled */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiItemR(row, &ptr, "mute", 0, "", (con->flag & CONSTRAINT_OFF) ? ICON_HIDE_ON : ICON_HIDE_OFF);
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
+
+ /* up/down */
+ if (show_upbut || show_downbut) {
+ UI_block_align_begin(block);
+ if (show_upbut) {
+ uiItemO(row, "", ICON_TRIA_UP, "CONSTRAINT_OT_move_up");
+ }
+
+ if (show_downbut) {
+ uiItemO(row, "", ICON_TRIA_DOWN, "CONSTRAINT_OT_move_down");
+ }
+ UI_block_align_end(block);
+ }
+
+ /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ uiItemO(row, "", ICON_X, "CONSTRAINT_OT_delete");
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
+
+ /* Set but-locks for protected settings (magic numbers are used here!) */
+ if (proxy_protected) {
+ UI_block_lock_set(block, true, IFACE_("Cannot edit Proxy-Protected Constraint"));
+ }
+
+ /* Draw constraint data */
+ if ((con->flag & CONSTRAINT_EXPAND) == 0) {
+ (yco) -= 10.5f * UI_UNIT_Y;
+ }
+ else {
+ box = uiLayoutBox(col);
+ block = uiLayoutAbsoluteBlock(box);
+ result = box;
+ }
+
+ /* clear any locks set up for proxies/lib-linking */
+ UI_block_lock_clear(block);
+
+ return result;
}
uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
{
- Object *ob;
- bConstraint *con;
-
- /* verify we have valid data */
- if (!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
- RNA_warning("Expected constraint on object");
- return NULL;
- }
-
- ob = ptr->id.data;
- con = ptr->data;
-
- if (!ob || !(GS(ob->id.name) == ID_OB)) {
- RNA_warning("Expected constraint on object");
- return NULL;
- }
-
- UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
-
- /* hrms, the temporal constraint should not draw! */
- if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
- bKinematicConstraint *data = con->data;
- if (data->flag & CONSTRAINT_IK_TEMP) {
- return NULL;
- }
- }
-
- return draw_constraint(layout, ob, con);
+ Object *ob;
+ bConstraint *con;
+
+ /* verify we have valid data */
+ if (!RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
+ RNA_warning("Expected constraint on object");
+ return NULL;
+ }
+
+ ob = ptr->id.data;
+ con = ptr->data;
+
+ if (!ob || !(GS(ob->id.name) == ID_OB)) {
+ RNA_warning("Expected constraint on object");
+ return NULL;
+ }
+
+ UI_block_lock_set(uiLayoutGetBlock(layout), (ob && ID_IS_LINKED(ob)), ERROR_LIBDATA_MESSAGE);
+
+ /* hrms, the temporal constraint should not draw! */
+ if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
+ bKinematicConstraint *data = con->data;
+ if (data->flag & CONSTRAINT_IK_TEMP) {
+ return NULL;
+ }
+ }
+
+ return draw_constraint(layout, ob, con);
}
-
/************************* Preview Template ***************************/
#include "DNA_light_types.h"
@@ -2144,465 +2619,687 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, PointerRNA *ptr)
static void do_preview_buttons(bContext *C, void *arg, int event)
{
- switch (event) {
- case B_MATPRV:
- WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, arg);
- break;
- }
+ switch (event) {
+ case B_MATPRV:
+ WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, arg);
+ break;
+ }
}
-void uiTemplatePreview(
- uiLayout *layout, bContext *C, ID *id, bool show_buttons, ID *parent, MTex *slot,
- const char *preview_id)
+void uiTemplatePreview(uiLayout *layout,
+ bContext *C,
+ ID *id,
+ bool show_buttons,
+ ID *parent,
+ MTex *slot,
+ const char *preview_id)
{
- uiLayout *row, *col;
- uiBlock *block;
- uiPreview *ui_preview = NULL;
- ARegion *ar;
-
- Material *ma = NULL;
- Tex *tex = (Tex *)id;
- ID *pid, *pparent;
- short *pr_texture = NULL;
- PointerRNA material_ptr;
- PointerRNA texture_ptr;
-
- char _preview_id[UI_MAX_NAME_STR];
-
- if (id && !ELEM(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA, ID_LS)) {
- RNA_warning("Expected ID of type material, texture, light, world or line style");
- return;
- }
-
- /* decide what to render */
- pid = id;
- pparent = NULL;
-
- if (id && (GS(id->name) == ID_TE)) {
- if (parent && (GS(parent->name) == ID_MA)) {
- pr_texture = &((Material *)parent)->pr_texture;
- }
- else if (parent && (GS(parent->name) == ID_WO)) {
- pr_texture = &((World *)parent)->pr_texture;
- }
- else if (parent && (GS(parent->name) == ID_LA)) {
- pr_texture = &((Light *)parent)->pr_texture;
- }
- else if (parent && (GS(parent->name) == ID_LS)) {
- pr_texture = &((FreestyleLineStyle *)parent)->pr_texture;
- }
-
- if (pr_texture) {
- if (*pr_texture == TEX_PR_OTHER) {
- pid = parent;
- }
- else if (*pr_texture == TEX_PR_BOTH) {
- pparent = parent;
- }
- }
- }
-
- if (!preview_id || (preview_id[0] == '\0')) {
- /* If no identifier given, generate one from ID type. */
- BLI_snprintf(_preview_id, UI_MAX_NAME_STR, "uiPreview_%s", BKE_idcode_to_name(GS(id->name)));
- preview_id = _preview_id;
- }
-
- /* Find or add the uiPreview to the current Region. */
- ar = CTX_wm_region(C);
- ui_preview = BLI_findstring(&ar->ui_previews, preview_id, offsetof(uiPreview, preview_id));
-
- if (!ui_preview) {
- ui_preview = MEM_callocN(sizeof(uiPreview), "uiPreview");
- BLI_strncpy(ui_preview->preview_id, preview_id, sizeof(ui_preview->preview_id));
- ui_preview->height = (short)(UI_UNIT_Y * 7.6f);
- BLI_addtail(&ar->ui_previews, ui_preview);
- }
-
- if (ui_preview->height < UI_UNIT_Y) {
- ui_preview->height = UI_UNIT_Y;
- }
- else if (ui_preview->height > UI_UNIT_Y * 50) { /* Rather high upper limit, yet not insane! */
- ui_preview->height = UI_UNIT_Y * 50;
- }
-
- /* layout */
- block = uiLayoutGetBlock(layout);
- row = uiLayoutRow(layout, false);
- col = uiLayoutColumn(row, false);
- uiLayoutSetKeepAspect(col, true);
-
- /* add preview */
- uiDefBut(block, UI_BTYPE_EXTRA, 0, "", 0, 0, UI_UNIT_X * 10, ui_preview->height, pid, 0.0, 0.0, 0, 0, "");
- UI_but_func_drawextra_set(block, ED_preview_draw, pparent, slot);
- UI_block_func_handle_set(block, do_preview_buttons, NULL);
-
- uiDefIconButS(
- block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &ui_preview->height,
- UI_UNIT_Y, UI_UNIT_Y * 50.0f, 0.0f, 0.0f, "");
-
- /* add buttons */
- if (pid && show_buttons) {
- if (GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
- if (GS(pid->name) == ID_MA) {
- ma = (Material *)pid;
- }
- else {
- ma = (Material *)pparent;
- }
-
- /* Create RNA Pointer */
- RNA_pointer_create(&ma->id, &RNA_Material, ma, &material_ptr);
-
- col = uiLayoutColumn(row, true);
- uiLayoutSetScaleX(col, 1.5);
- uiItemR(col, &material_ptr, "preview_render_type", UI_ITEM_R_EXPAND, "", ICON_NONE);
- uiItemS(col);
- uiItemR(col, &material_ptr, "use_preview_world", 0, "", ICON_WORLD);
- }
-
- if (pr_texture) {
- /* Create RNA Pointer */
- RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
-
- uiLayoutRow(layout, true);
- uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Texture"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- pr_texture, 10, TEX_PR_TEXTURE, 0, 0, "");
- if (GS(parent->name) == ID_MA) {
- uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Material"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- }
- else if (GS(parent->name) == ID_LA) {
- uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, CTX_IFACE_(BLT_I18NCONTEXT_ID_LIGHT, "Light"),
- 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- }
- else if (GS(parent->name) == ID_WO) {
- uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("World"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- }
- else if (GS(parent->name) == ID_LS) {
- uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Line Style"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- pr_texture, 10, TEX_PR_OTHER, 0, 0, "");
- }
- uiDefButS(block, UI_BTYPE_ROW, B_MATPRV, IFACE_("Both"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- pr_texture, 10, TEX_PR_BOTH, 0, 0, "");
-
- /* Alpha button for texture preview */
- if (*pr_texture != TEX_PR_OTHER) {
- row = uiLayoutRow(layout, false);
- uiItemR(row, &texture_ptr, "use_preview_alpha", 0, NULL, ICON_NONE);
- }
- }
- }
+ uiLayout *row, *col;
+ uiBlock *block;
+ uiPreview *ui_preview = NULL;
+ ARegion *ar;
+
+ Material *ma = NULL;
+ Tex *tex = (Tex *)id;
+ ID *pid, *pparent;
+ short *pr_texture = NULL;
+ PointerRNA material_ptr;
+ PointerRNA texture_ptr;
+
+ char _preview_id[UI_MAX_NAME_STR];
+
+ if (id && !ELEM(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA, ID_LS)) {
+ RNA_warning("Expected ID of type material, texture, light, world or line style");
+ return;
+ }
+
+ /* decide what to render */
+ pid = id;
+ pparent = NULL;
+
+ if (id && (GS(id->name) == ID_TE)) {
+ if (parent && (GS(parent->name) == ID_MA)) {
+ pr_texture = &((Material *)parent)->pr_texture;
+ }
+ else if (parent && (GS(parent->name) == ID_WO)) {
+ pr_texture = &((World *)parent)->pr_texture;
+ }
+ else if (parent && (GS(parent->name) == ID_LA)) {
+ pr_texture = &((Light *)parent)->pr_texture;
+ }
+ else if (parent && (GS(parent->name) == ID_LS)) {
+ pr_texture = &((FreestyleLineStyle *)parent)->pr_texture;
+ }
+
+ if (pr_texture) {
+ if (*pr_texture == TEX_PR_OTHER) {
+ pid = parent;
+ }
+ else if (*pr_texture == TEX_PR_BOTH) {
+ pparent = parent;
+ }
+ }
+ }
+
+ if (!preview_id || (preview_id[0] == '\0')) {
+ /* If no identifier given, generate one from ID type. */
+ BLI_snprintf(_preview_id, UI_MAX_NAME_STR, "uiPreview_%s", BKE_idcode_to_name(GS(id->name)));
+ preview_id = _preview_id;
+ }
+
+ /* Find or add the uiPreview to the current Region. */
+ ar = CTX_wm_region(C);
+ ui_preview = BLI_findstring(&ar->ui_previews, preview_id, offsetof(uiPreview, preview_id));
+
+ if (!ui_preview) {
+ ui_preview = MEM_callocN(sizeof(uiPreview), "uiPreview");
+ BLI_strncpy(ui_preview->preview_id, preview_id, sizeof(ui_preview->preview_id));
+ ui_preview->height = (short)(UI_UNIT_Y * 7.6f);
+ BLI_addtail(&ar->ui_previews, ui_preview);
+ }
+
+ if (ui_preview->height < UI_UNIT_Y) {
+ ui_preview->height = UI_UNIT_Y;
+ }
+ else if (ui_preview->height > UI_UNIT_Y * 50) { /* Rather high upper limit, yet not insane! */
+ ui_preview->height = UI_UNIT_Y * 50;
+ }
+
+ /* layout */
+ block = uiLayoutGetBlock(layout);
+ row = uiLayoutRow(layout, false);
+ col = uiLayoutColumn(row, false);
+ uiLayoutSetKeepAspect(col, true);
+
+ /* add preview */
+ uiDefBut(block,
+ UI_BTYPE_EXTRA,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ ui_preview->height,
+ pid,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ UI_but_func_drawextra_set(block, ED_preview_draw, pparent, slot);
+ UI_block_func_handle_set(block, do_preview_buttons, NULL);
+
+ uiDefIconButS(block,
+ UI_BTYPE_GRIP,
+ 0,
+ ICON_GRIP,
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ (short)(UI_UNIT_Y * 0.3f),
+ &ui_preview->height,
+ UI_UNIT_Y,
+ UI_UNIT_Y * 50.0f,
+ 0.0f,
+ 0.0f,
+ "");
+
+ /* add buttons */
+ if (pid && show_buttons) {
+ if (GS(pid->name) == ID_MA || (pparent && GS(pparent->name) == ID_MA)) {
+ if (GS(pid->name) == ID_MA) {
+ ma = (Material *)pid;
+ }
+ else {
+ ma = (Material *)pparent;
+ }
+
+ /* Create RNA Pointer */
+ RNA_pointer_create(&ma->id, &RNA_Material, ma, &material_ptr);
+
+ col = uiLayoutColumn(row, true);
+ uiLayoutSetScaleX(col, 1.5);
+ uiItemR(col, &material_ptr, "preview_render_type", UI_ITEM_R_EXPAND, "", ICON_NONE);
+ uiItemS(col);
+ uiItemR(col, &material_ptr, "use_preview_world", 0, "", ICON_WORLD);
+ }
+
+ if (pr_texture) {
+ /* Create RNA Pointer */
+ RNA_pointer_create(id, &RNA_Texture, tex, &texture_ptr);
+
+ uiLayoutRow(layout, true);
+ uiDefButS(block,
+ UI_BTYPE_ROW,
+ B_MATPRV,
+ IFACE_("Texture"),
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ pr_texture,
+ 10,
+ TEX_PR_TEXTURE,
+ 0,
+ 0,
+ "");
+ if (GS(parent->name) == ID_MA) {
+ uiDefButS(block,
+ UI_BTYPE_ROW,
+ B_MATPRV,
+ IFACE_("Material"),
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ pr_texture,
+ 10,
+ TEX_PR_OTHER,
+ 0,
+ 0,
+ "");
+ }
+ else if (GS(parent->name) == ID_LA) {
+ uiDefButS(block,
+ UI_BTYPE_ROW,
+ B_MATPRV,
+ CTX_IFACE_(BLT_I18NCONTEXT_ID_LIGHT, "Light"),
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ pr_texture,
+ 10,
+ TEX_PR_OTHER,
+ 0,
+ 0,
+ "");
+ }
+ else if (GS(parent->name) == ID_WO) {
+ uiDefButS(block,
+ UI_BTYPE_ROW,
+ B_MATPRV,
+ IFACE_("World"),
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ pr_texture,
+ 10,
+ TEX_PR_OTHER,
+ 0,
+ 0,
+ "");
+ }
+ else if (GS(parent->name) == ID_LS) {
+ uiDefButS(block,
+ UI_BTYPE_ROW,
+ B_MATPRV,
+ IFACE_("Line Style"),
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ pr_texture,
+ 10,
+ TEX_PR_OTHER,
+ 0,
+ 0,
+ "");
+ }
+ uiDefButS(block,
+ UI_BTYPE_ROW,
+ B_MATPRV,
+ IFACE_("Both"),
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ pr_texture,
+ 10,
+ TEX_PR_BOTH,
+ 0,
+ 0,
+ "");
+
+ /* Alpha button for texture preview */
+ if (*pr_texture != TEX_PR_OTHER) {
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &texture_ptr, "use_preview_alpha", 0, NULL, ICON_NONE);
+ }
+ }
+ }
}
/********************** ColorRamp Template **************************/
-
typedef struct RNAUpdateCb {
- PointerRNA ptr;
- PropertyRNA *prop;
+ PointerRNA ptr;
+ PropertyRNA *prop;
} RNAUpdateCb;
static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
{
- RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
+ RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
- /* we call update here on the pointer property, this way the
- * owner of the curve mapping can still define it's own update
- * and notifier, even if the CurveMapping struct is shared. */
- RNA_property_update(C, &cb->ptr, cb->prop);
+ /* we call update here on the pointer property, this way the
+ * owner of the curve mapping can still define it's own update
+ * and notifier, even if the CurveMapping struct is shared. */
+ RNA_property_update(C, &cb->ptr, cb->prop);
}
enum {
- CB_FUNC_FLIP,
- CB_FUNC_DISTRIBUTE_LR,
- CB_FUNC_DISTRIBUTE_EVENLY,
- CB_FUNC_RESET,
+ CB_FUNC_FLIP,
+ CB_FUNC_DISTRIBUTE_LR,
+ CB_FUNC_DISTRIBUTE_EVENLY,
+ CB_FUNC_RESET,
};
static void colorband_flip_cb(bContext *C, ColorBand *coba)
{
- CBData data_tmp[MAXCOLORBAND];
+ CBData data_tmp[MAXCOLORBAND];
- int a;
+ int a;
- for (a = 0; a < coba->tot; a++) {
- data_tmp[a] = coba->data[coba->tot - (a + 1)];
- }
- for (a = 0; a < coba->tot; a++) {
- data_tmp[a].pos = 1.0f - data_tmp[a].pos;
- coba->data[a] = data_tmp[a];
- }
+ for (a = 0; a < coba->tot; a++) {
+ data_tmp[a] = coba->data[coba->tot - (a + 1)];
+ }
+ for (a = 0; a < coba->tot; a++) {
+ data_tmp[a].pos = 1.0f - data_tmp[a].pos;
+ coba->data[a] = data_tmp[a];
+ }
- /* may as well flip the cur*/
- coba->cur = coba->tot - (coba->cur + 1);
+ /* may as well flip the cur*/
+ coba->cur = coba->tot - (coba->cur + 1);
- ED_undo_push(C, "Flip Color Ramp");
+ ED_undo_push(C, "Flip Color Ramp");
}
static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly)
{
- if (coba->tot > 1) {
- int a;
- int tot = evenly ? coba->tot - 1 : coba->tot;
- float gap = 1.0f / tot;
- float pos = 0.0f;
- for (a = 0; a < coba->tot; a++) {
- coba->data[a].pos = pos;
- pos += gap;
- }
- ED_undo_push(C, evenly ? "Distribute Stops Evenly" : "Distribute Stops from Left");
- }
+ if (coba->tot > 1) {
+ int a;
+ int tot = evenly ? coba->tot - 1 : coba->tot;
+ float gap = 1.0f / tot;
+ float pos = 0.0f;
+ for (a = 0; a < coba->tot; a++) {
+ coba->data[a].pos = pos;
+ pos += gap;
+ }
+ ED_undo_push(C, evenly ? "Distribute Stops Evenly" : "Distribute Stops from Left");
+ }
}
static void colorband_tools_dofunc(bContext *C, void *coba_v, int event)
{
- ColorBand *coba = coba_v;
-
- switch (event) {
- case CB_FUNC_FLIP:
- colorband_flip_cb(C, coba);
- break;
- case CB_FUNC_DISTRIBUTE_LR:
- colorband_distribute_cb(C, coba, false);
- break;
- case CB_FUNC_DISTRIBUTE_EVENLY:
- colorband_distribute_cb(C, coba, true);
- break;
- case CB_FUNC_RESET:
- BKE_colorband_init(coba, true);
- ED_undo_push(C, "Reset Color Ramp");
- break;
- }
- ED_region_tag_redraw(CTX_wm_region(C));
+ ColorBand *coba = coba_v;
+
+ switch (event) {
+ case CB_FUNC_FLIP:
+ colorband_flip_cb(C, coba);
+ break;
+ case CB_FUNC_DISTRIBUTE_LR:
+ colorband_distribute_cb(C, coba, false);
+ break;
+ case CB_FUNC_DISTRIBUTE_EVENLY:
+ colorband_distribute_cb(C, coba, true);
+ break;
+ case CB_FUNC_RESET:
+ BKE_colorband_init(coba, true);
+ ED_undo_push(C, "Reset Color Ramp");
+ break;
+ }
+ ED_region_tag_redraw(CTX_wm_region(C));
}
-static uiBlock *colorband_tools_func(
- bContext *C, ARegion *ar, void *coba_v)
+static uiBlock *colorband_tools_func(bContext *C, ARegion *ar, void *coba_v)
{
- uiStyle *style = UI_style_get_dpi();
- ColorBand *coba = coba_v;
- uiBlock *block;
- short yco = 0, menuwidth = 10 * UI_UNIT_X;
-
- block = UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN);
- UI_block_func_butmenu_set(block, colorband_tools_dofunc, coba);
-
- uiLayout *layout = UI_block_layout(
- block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, UI_MENU_WIDTH_MIN, 0, UI_MENU_PADDING, style);
- UI_block_layout_set_current(block, layout);
- {
- PointerRNA coba_ptr;
- RNA_pointer_create(NULL, &RNA_ColorRamp, coba, &coba_ptr);
- uiLayoutSetContextPointer(layout, "color_ramp", &coba_ptr);
- }
-
- /* We could move these to operators,
- * although this isn't important unless we want to assign key shortcuts to them. */
- {
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1,
- IFACE_("Flip Color Ramp"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, CB_FUNC_FLIP, "");
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1,
- IFACE_("Distribute Stops from Left"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, CB_FUNC_DISTRIBUTE_LR, "");
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1,
- IFACE_("Distribute Stops Evenly"), 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, CB_FUNC_DISTRIBUTE_EVENLY, "");
-
- uiItemO(layout, IFACE_("Eyedropper"), ICON_EYEDROPPER, "UI_OT_eyedropper_colorramp");
-
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Color Ramp"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, CB_FUNC_RESET, "");
- }
-
- UI_block_direction_set(block, UI_DIR_DOWN);
- UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
-
- return block;
+ uiStyle *style = UI_style_get_dpi();
+ ColorBand *coba = coba_v;
+ uiBlock *block;
+ short yco = 0, menuwidth = 10 * UI_UNIT_X;
+
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS_PULLDOWN);
+ UI_block_func_butmenu_set(block, colorband_tools_dofunc, coba);
+
+ uiLayout *layout = UI_block_layout(block,
+ UI_LAYOUT_VERTICAL,
+ UI_LAYOUT_MENU,
+ 0,
+ 0,
+ UI_MENU_WIDTH_MIN,
+ 0,
+ UI_MENU_PADDING,
+ style);
+ UI_block_layout_set_current(block, layout);
+ {
+ PointerRNA coba_ptr;
+ RNA_pointer_create(NULL, &RNA_ColorRamp, coba, &coba_ptr);
+ uiLayoutSetContextPointer(layout, "color_ramp", &coba_ptr);
+ }
+
+ /* We could move these to operators,
+ * although this isn't important unless we want to assign key shortcuts to them. */
+ {
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Flip Color Ramp"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ CB_FUNC_FLIP,
+ "");
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Distribute Stops from Left"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ CB_FUNC_DISTRIBUTE_LR,
+ "");
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Distribute Stops Evenly"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ CB_FUNC_DISTRIBUTE_EVENLY,
+ "");
+
+ uiItemO(layout, IFACE_("Eyedropper"), ICON_EYEDROPPER, "UI_OT_eyedropper_colorramp");
+
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Reset Color Ramp"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ CB_FUNC_RESET,
+ "");
+ }
+
+ UI_block_direction_set(block, UI_DIR_DOWN);
+ UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
+
+ return block;
}
static void colorband_add_cb(bContext *C, void *cb_v, void *coba_v)
{
- ColorBand *coba = coba_v;
- float pos = 0.5f;
-
- if (coba->tot > 1) {
- if (coba->cur > 0) {
- pos = (coba->data[coba->cur - 1].pos + coba->data[coba->cur].pos) * 0.5f;
- }
- else {
- pos = (coba->data[coba->cur + 1].pos + coba->data[coba->cur].pos) * 0.5f;
- }
- }
-
- if (BKE_colorband_element_add(coba, pos)) {
- rna_update_cb(C, cb_v, NULL);
- ED_undo_push(C, "Add Color Ramp Stop");
- }
+ ColorBand *coba = coba_v;
+ float pos = 0.5f;
+
+ if (coba->tot > 1) {
+ if (coba->cur > 0) {
+ pos = (coba->data[coba->cur - 1].pos + coba->data[coba->cur].pos) * 0.5f;
+ }
+ else {
+ pos = (coba->data[coba->cur + 1].pos + coba->data[coba->cur].pos) * 0.5f;
+ }
+ }
+
+ if (BKE_colorband_element_add(coba, pos)) {
+ rna_update_cb(C, cb_v, NULL);
+ ED_undo_push(C, "Add Color Ramp Stop");
+ }
}
static void colorband_del_cb(bContext *C, void *cb_v, void *coba_v)
{
- ColorBand *coba = coba_v;
+ ColorBand *coba = coba_v;
- if (BKE_colorband_element_remove(coba, coba->cur)) {
- ED_undo_push(C, "Delete Color Ramp Stop");
- rna_update_cb(C, cb_v, NULL);
- }
+ if (BKE_colorband_element_remove(coba, coba->cur)) {
+ ED_undo_push(C, "Delete Color Ramp Stop");
+ rna_update_cb(C, cb_v, NULL);
+ }
}
static void colorband_update_cb(bContext *UNUSED(C), void *bt_v, void *coba_v)
{
- uiBut *bt = bt_v;
- ColorBand *coba = coba_v;
+ uiBut *bt = bt_v;
+ ColorBand *coba = coba_v;
- /* sneaky update here, we need to sort the colorband points to be in order,
- * however the RNA pointer then is wrong, so we update it */
- BKE_colorband_update_sort(coba);
- bt->rnapoin.data = coba->data + coba->cur;
+ /* sneaky update here, we need to sort the colorband points to be in order,
+ * however the RNA pointer then is wrong, so we update it */
+ BKE_colorband_update_sort(coba);
+ bt->rnapoin.data = coba->data + coba->cur;
}
-static void colorband_buttons_layout(
- uiLayout *layout, uiBlock *block, ColorBand *coba, const rctf *butr,
- RNAUpdateCb *cb, int expand)
+static void colorband_buttons_layout(uiLayout *layout,
+ uiBlock *block,
+ ColorBand *coba,
+ const rctf *butr,
+ RNAUpdateCb *cb,
+ int expand)
{
- uiLayout *row, *split, *subsplit;
- uiBut *bt;
- float unit = BLI_rctf_size_x(butr) / 14.0f;
- float xs = butr->xmin;
- float ys = butr->ymin;
- PointerRNA ptr;
-
- RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRamp, coba, &ptr);
-
- split = uiLayoutSplit(layout, 0.4f, false);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- UI_block_align_begin(block);
- row = uiLayoutRow(split, false);
-
- bt = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_ADD, "", 0, 0, 2.0f * unit, UI_UNIT_Y, NULL,
- 0, 0, 0, 0, TIP_("Add a new color stop to the color ramp"));
- UI_but_funcN_set(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
-
- bt = uiDefIconTextBut(
- block, UI_BTYPE_BUT, 0, ICON_REMOVE, "", xs + 2.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Delete the active position"));
- UI_but_funcN_set(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
-
- bt = uiDefIconBlockBut(
- block, colorband_tools_func, coba, 0, ICON_DOWNARROW_HLT,
- xs + 4.0f * unit, ys + UI_UNIT_Y, 2.0f * unit, UI_UNIT_Y, TIP_("Tools"));
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), coba);
-
- UI_block_align_end(block);
- UI_block_emboss_set(block, UI_EMBOSS);
-
- row = uiLayoutRow(split, false);
-
- UI_block_align_begin(block);
- uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE);
- if (ELEM(coba->color_mode, COLBAND_BLEND_HSV, COLBAND_BLEND_HSL)) {
- uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE);
- }
- else { /* COLBAND_BLEND_RGB */
- uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
- }
- UI_block_align_end(block);
-
- row = uiLayoutRow(layout, false);
-
- bt = uiDefBut(block, UI_BTYPE_COLORBAND, 0, "", xs, ys, BLI_rctf_size_x(butr), UI_UNIT_Y, coba, 0, 0, 0, 0, "");
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-
- row = uiLayoutRow(layout, false);
-
- if (coba->tot) {
- CBData *cbd = coba->data + coba->cur;
-
- RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
-
- if (!expand) {
- split = uiLayoutSplit(layout, 0.3f, false);
-
- row = uiLayoutRow(split, false);
- uiDefButS(block, UI_BTYPE_NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
- 0, 0, TIP_("Choose active color stop"));
- row = uiLayoutRow(split, false);
- uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
- bt = block->buttons.last;
- bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
- UI_but_func_set(bt, colorband_update_cb, bt, coba);
-
- row = uiLayoutRow(layout, false);
- uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
- bt = block->buttons.last;
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- }
- else {
- split = uiLayoutSplit(layout, 0.5f, false);
- subsplit = uiLayoutSplit(split, 0.35f, false);
-
- row = uiLayoutRow(subsplit, false);
- uiDefButS(block, UI_BTYPE_NUM, 0, "", 0, 0, 5.0f * UI_UNIT_X, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot - 1)),
- 0, 0, TIP_("Choose active color stop"));
- row = uiLayoutRow(subsplit, false);
- uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
- bt = block->buttons.last;
- bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
- UI_but_func_set(bt, colorband_update_cb, bt, coba);
-
- row = uiLayoutRow(split, false);
- uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
- bt = block->buttons.last;
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- }
- }
+ uiLayout *row, *split, *subsplit;
+ uiBut *bt;
+ float unit = BLI_rctf_size_x(butr) / 14.0f;
+ float xs = butr->xmin;
+ float ys = butr->ymin;
+ PointerRNA ptr;
+
+ RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRamp, coba, &ptr);
+
+ split = uiLayoutSplit(layout, 0.4f, false);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ UI_block_align_begin(block);
+ row = uiLayoutRow(split, false);
+
+ bt = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_ADD,
+ "",
+ 0,
+ 0,
+ 2.0f * unit,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Add a new color stop to the color ramp"));
+ UI_but_funcN_set(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
+
+ bt = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_REMOVE,
+ "",
+ xs + 2.0f * unit,
+ ys + UI_UNIT_Y,
+ 2.0f * unit,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Delete the active position"));
+ UI_but_funcN_set(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
+
+ bt = uiDefIconBlockBut(block,
+ colorband_tools_func,
+ coba,
+ 0,
+ ICON_DOWNARROW_HLT,
+ xs + 4.0f * unit,
+ ys + UI_UNIT_Y,
+ 2.0f * unit,
+ UI_UNIT_Y,
+ TIP_("Tools"));
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), coba);
+
+ UI_block_align_end(block);
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ row = uiLayoutRow(split, false);
+
+ UI_block_align_begin(block);
+ uiItemR(row, &ptr, "color_mode", 0, "", ICON_NONE);
+ if (ELEM(coba->color_mode, COLBAND_BLEND_HSV, COLBAND_BLEND_HSL)) {
+ uiItemR(row, &ptr, "hue_interpolation", 0, "", ICON_NONE);
+ }
+ else { /* COLBAND_BLEND_RGB */
+ uiItemR(row, &ptr, "interpolation", 0, "", ICON_NONE);
+ }
+ UI_block_align_end(block);
+
+ row = uiLayoutRow(layout, false);
+
+ bt = uiDefBut(block,
+ UI_BTYPE_COLORBAND,
+ 0,
+ "",
+ xs,
+ ys,
+ BLI_rctf_size_x(butr),
+ UI_UNIT_Y,
+ coba,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ row = uiLayoutRow(layout, false);
+
+ if (coba->tot) {
+ CBData *cbd = coba->data + coba->cur;
+
+ RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
+
+ if (!expand) {
+ split = uiLayoutSplit(layout, 0.3f, false);
+
+ row = uiLayoutRow(split, false);
+ uiDefButS(block,
+ UI_BTYPE_NUM,
+ 0,
+ "",
+ 0,
+ 0,
+ 5.0f * UI_UNIT_X,
+ UI_UNIT_Y,
+ &coba->cur,
+ 0.0,
+ (float)(MAX2(0, coba->tot - 1)),
+ 0,
+ 0,
+ TIP_("Choose active color stop"));
+ row = uiLayoutRow(split, false);
+ uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE);
+ bt = block->buttons.last;
+ bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
+ UI_but_func_set(bt, colorband_update_cb, bt, coba);
+
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
+ bt = block->buttons.last;
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ }
+ else {
+ split = uiLayoutSplit(layout, 0.5f, false);
+ subsplit = uiLayoutSplit(split, 0.35f, false);
+
+ row = uiLayoutRow(subsplit, false);
+ uiDefButS(block,
+ UI_BTYPE_NUM,
+ 0,
+ "",
+ 0,
+ 0,
+ 5.0f * UI_UNIT_X,
+ UI_UNIT_Y,
+ &coba->cur,
+ 0.0,
+ (float)(MAX2(0, coba->tot - 1)),
+ 0,
+ 0,
+ TIP_("Choose active color stop"));
+ row = uiLayoutRow(subsplit, false);
+ uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE);
+ bt = block->buttons.last;
+ bt->a1 = 1.0f; /* gives a bit more precision for modifying position */
+ UI_but_func_set(bt, colorband_update_cb, bt, coba);
+
+ row = uiLayoutRow(split, false);
+ uiItemR(row, &ptr, "color", 0, "", ICON_NONE);
+ bt = block->buttons.last;
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+ }
+ }
}
void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, bool expand)
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- RNAUpdateCb *cb;
- uiBlock *block;
- ID *id;
- rctf rect;
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ RNAUpdateCb *cb;
+ uiBlock *block;
+ ID *id;
+ rctf rect;
- if (!prop || RNA_property_type(prop) != PROP_POINTER) {
- return;
- }
+ if (!prop || RNA_property_type(prop) != PROP_POINTER) {
+ return;
+ }
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp)) {
- return;
- }
+ cptr = RNA_property_pointer_get(ptr, prop);
+ if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_ColorRamp)) {
+ return;
+ }
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
+ cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr = *ptr;
+ cb->prop = prop;
- rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
- rect.ymin = 0; rect.ymax = 19.5f * UI_UNIT_X;
+ rect.xmin = 0;
+ rect.xmax = 10.0f * UI_UNIT_X;
+ rect.ymin = 0;
+ rect.ymax = 19.5f * UI_UNIT_X;
- block = uiLayoutAbsoluteBlock(layout);
+ block = uiLayoutAbsoluteBlock(layout);
- id = cptr.id.data;
- UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
+ id = cptr.id.data;
+ UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
- colorband_buttons_layout(layout, block, cptr.data, &rect, cb, expand);
+ colorband_buttons_layout(layout, block, cptr.data, &rect, cb, expand);
- UI_block_lock_clear(block);
+ UI_block_lock_clear(block);
- MEM_freeN(cb);
+ MEM_freeN(cb);
}
/********************* Icon Template ************************/
@@ -2611,2549 +3308,3420 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
*/
void uiTemplateIcon(uiLayout *layout, int icon_value, float icon_scale)
{
- uiBlock *block;
- uiBut *but;
-
- block = uiLayoutAbsoluteBlock(layout);
- but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, ICON_X, 0, 0, UI_UNIT_X * icon_scale, UI_UNIT_Y * icon_scale, NULL, 0.0, 0.0, 0.0, 0.0, "");
- ui_def_but_icon(but, icon_value, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ uiBlock *block;
+ uiBut *but;
+
+ block = uiLayoutAbsoluteBlock(layout);
+ but = uiDefIconBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ ICON_X,
+ 0,
+ 0,
+ UI_UNIT_X * icon_scale,
+ UI_UNIT_Y * icon_scale,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ "");
+ ui_def_but_icon(but, icon_value, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
}
/********************* Icon viewer Template ************************/
typedef struct IconViewMenuArgs {
- PointerRNA ptr;
- PropertyRNA *prop;
- bool show_labels;
- float icon_scale;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ bool show_labels;
+ float icon_scale;
} IconViewMenuArgs;
/* ID Search browse menu, open */
static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *ar, void *arg_litem)
{
- static IconViewMenuArgs args;
- uiBlock *block;
- uiBut *but;
- int icon, value;
- const EnumPropertyItem *item;
- int a;
- bool free;
- int w, h;
-
- /* arg_litem is malloced, can be freed by parent button */
- args = *((IconViewMenuArgs *) arg_litem);
- w = UI_UNIT_X * (args.icon_scale);
- h = UI_UNIT_X * (args.icon_scale + args.show_labels);
-
- block = UI_block_begin(C, ar, "_popup", UI_EMBOSS_PULLDOWN);
- UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NO_FLIP);
- UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
-
- RNA_property_enum_items(C, &args.ptr, args.prop, &item, NULL, &free);
-
- for (a = 0; item[a].identifier; a++) {
- int x, y;
-
- x = (a % 8) * w;
- y = -(a / 8) * h;
-
- icon = item[a].icon;
- value = item[a].value;
- if (args.show_labels) {
- but = uiDefIconTextButR_prop(
- block, UI_BTYPE_ROW, 0, icon, item[a].name, x, y, w, h,
- &args.ptr, args.prop, -1, 0, value, -1, -1, NULL);
- }
- else {
- but = uiDefIconButR_prop(
- block, UI_BTYPE_ROW, 0, icon, x, y, w, h,
- &args.ptr, args.prop, -1, 0, value, -1, -1, NULL);
- }
- ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
- }
-
- UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
- UI_block_direction_set(block, UI_DIR_DOWN);
-
- if (free) {
- MEM_freeN((void *)item);
- }
-
- return block;
+ static IconViewMenuArgs args;
+ uiBlock *block;
+ uiBut *but;
+ int icon, value;
+ const EnumPropertyItem *item;
+ int a;
+ bool free;
+ int w, h;
+
+ /* arg_litem is malloced, can be freed by parent button */
+ args = *((IconViewMenuArgs *)arg_litem);
+ w = UI_UNIT_X * (args.icon_scale);
+ h = UI_UNIT_X * (args.icon_scale + args.show_labels);
+
+ block = UI_block_begin(C, ar, "_popup", UI_EMBOSS_PULLDOWN);
+ UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NO_FLIP);
+ UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
+
+ RNA_property_enum_items(C, &args.ptr, args.prop, &item, NULL, &free);
+
+ for (a = 0; item[a].identifier; a++) {
+ int x, y;
+
+ x = (a % 8) * w;
+ y = -(a / 8) * h;
+
+ icon = item[a].icon;
+ value = item[a].value;
+ if (args.show_labels) {
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_ROW,
+ 0,
+ icon,
+ item[a].name,
+ x,
+ y,
+ w,
+ h,
+ &args.ptr,
+ args.prop,
+ -1,
+ 0,
+ value,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefIconButR_prop(block,
+ UI_BTYPE_ROW,
+ 0,
+ icon,
+ x,
+ y,
+ w,
+ h,
+ &args.ptr,
+ args.prop,
+ -1,
+ 0,
+ value,
+ -1,
+ -1,
+ NULL);
+ }
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ }
+
+ UI_block_bounds_set_normal(block, 0.3f * U.widget_unit);
+ UI_block_direction_set(block, UI_DIR_DOWN);
+
+ if (free) {
+ MEM_freeN((void *)item);
+ }
+
+ return block;
}
/**
* \param icon_scale: Scale of the icon, 1x == button height.
*/
-void uiTemplateIconView(
- uiLayout *layout, PointerRNA *ptr, const char *propname, bool show_labels,
- float icon_scale, float icon_scale_popup)
+void uiTemplateIconView(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ bool show_labels,
+ float icon_scale,
+ float icon_scale_popup)
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- IconViewMenuArgs *cb_args;
- const EnumPropertyItem *items;
- uiBlock *block;
- uiBut *but;
- int value, icon = ICON_NONE, tot_items;
- bool free_items;
-
- if (!prop || RNA_property_type(prop) != PROP_ENUM) {
- RNA_warning("property of type Enum not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- block = uiLayoutAbsoluteBlock(layout);
-
- RNA_property_enum_items(block->evil_C, ptr, prop, &items, &tot_items, &free_items);
- value = RNA_property_enum_get(ptr, prop);
- RNA_enum_icon_from_value(items, value, &icon);
-
-
- if (RNA_property_editable(ptr, prop)) {
- cb_args = MEM_callocN(sizeof(IconViewMenuArgs), __func__);
- cb_args->ptr = *ptr;
- cb_args->prop = prop;
- cb_args->show_labels = show_labels;
- cb_args->icon_scale = icon_scale_popup;
-
- but = uiDefBlockButN(
- block, ui_icon_view_menu_cb, cb_args, "",
- 0, 0, UI_UNIT_X * icon_scale, UI_UNIT_Y * icon_scale, "");
- }
- else {
- but = uiDefIconBut(
- block, UI_BTYPE_LABEL, 0, ICON_X,
- 0, 0, UI_UNIT_X * icon_scale, UI_UNIT_Y * icon_scale, NULL, 0.0, 0.0, 0.0, 0.0, "");
- }
-
-
- ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
-
- if (free_items) {
- MEM_freeN((void *)items);
- }
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ IconViewMenuArgs *cb_args;
+ const EnumPropertyItem *items;
+ uiBlock *block;
+ uiBut *but;
+ int value, icon = ICON_NONE, tot_items;
+ bool free_items;
+
+ if (!prop || RNA_property_type(prop) != PROP_ENUM) {
+ RNA_warning(
+ "property of type Enum not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ block = uiLayoutAbsoluteBlock(layout);
+
+ RNA_property_enum_items(block->evil_C, ptr, prop, &items, &tot_items, &free_items);
+ value = RNA_property_enum_get(ptr, prop);
+ RNA_enum_icon_from_value(items, value, &icon);
+
+ if (RNA_property_editable(ptr, prop)) {
+ cb_args = MEM_callocN(sizeof(IconViewMenuArgs), __func__);
+ cb_args->ptr = *ptr;
+ cb_args->prop = prop;
+ cb_args->show_labels = show_labels;
+ cb_args->icon_scale = icon_scale_popup;
+
+ but = uiDefBlockButN(block,
+ ui_icon_view_menu_cb,
+ cb_args,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * icon_scale,
+ UI_UNIT_Y * icon_scale,
+ "");
+ }
+ else {
+ but = uiDefIconBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ ICON_X,
+ 0,
+ 0,
+ UI_UNIT_X * icon_scale,
+ UI_UNIT_Y * icon_scale,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ "");
+ }
+
+ ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+
+ if (free_items) {
+ MEM_freeN((void *)items);
+ }
}
/********************* Histogram Template ************************/
void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- uiBlock *block;
- uiLayout *col;
- Histogram *hist;
-
- if (!prop || RNA_property_type(prop) != PROP_POINTER) {
- return;
- }
-
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Histogram)) {
- return;
- }
- hist = (Histogram *)cptr.data;
-
- if (hist->height < UI_UNIT_Y) {
- hist->height = UI_UNIT_Y;
- }
- else if (hist->height > UI_UNIT_Y * 20) {
- hist->height = UI_UNIT_Y * 20;
- }
-
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- uiDefBut(block, UI_BTYPE_HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
-
- /* Resize grip. */
- uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &hist->height,
- UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ uiBlock *block;
+ uiLayout *col;
+ Histogram *hist;
+
+ if (!prop || RNA_property_type(prop) != PROP_POINTER) {
+ return;
+ }
+
+ cptr = RNA_property_pointer_get(ptr, prop);
+ if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Histogram)) {
+ return;
+ }
+ hist = (Histogram *)cptr.data;
+
+ if (hist->height < UI_UNIT_Y) {
+ hist->height = UI_UNIT_Y;
+ }
+ else if (hist->height > UI_UNIT_Y * 20) {
+ hist->height = UI_UNIT_Y * 20;
+ }
+
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ uiDefBut(
+ block, UI_BTYPE_HISTOGRAM, 0, "", 0, 0, UI_UNIT_X * 10, hist->height, hist, 0, 0, 0, 0, "");
+
+ /* Resize grip. */
+ uiDefIconButI(block,
+ UI_BTYPE_GRIP,
+ 0,
+ ICON_GRIP,
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ (short)(UI_UNIT_Y * 0.3f),
+ &hist->height,
+ UI_UNIT_Y,
+ UI_UNIT_Y * 20.0f,
+ 0.0f,
+ 0.0f,
+ "");
}
/********************* Waveform Template ************************/
void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- uiBlock *block;
- uiLayout *col;
- Scopes *scopes;
-
- if (!prop || RNA_property_type(prop) != PROP_POINTER) {
- return;
- }
-
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
- return;
- }
- scopes = (Scopes *)cptr.data;
-
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- if (scopes->wavefrm_height < UI_UNIT_Y) {
- scopes->wavefrm_height = UI_UNIT_Y;
- }
- else if (scopes->wavefrm_height > UI_UNIT_Y * 20) {
- scopes->wavefrm_height = UI_UNIT_Y * 20;
- }
-
- uiDefBut(block, UI_BTYPE_WAVEFORM, 0, "", 0, 0, UI_UNIT_X * 10, scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
-
- /* Resize grip. */
- uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->wavefrm_height,
- UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ uiBlock *block;
+ uiLayout *col;
+ Scopes *scopes;
+
+ if (!prop || RNA_property_type(prop) != PROP_POINTER) {
+ return;
+ }
+
+ cptr = RNA_property_pointer_get(ptr, prop);
+ if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
+ return;
+ }
+ scopes = (Scopes *)cptr.data;
+
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ if (scopes->wavefrm_height < UI_UNIT_Y) {
+ scopes->wavefrm_height = UI_UNIT_Y;
+ }
+ else if (scopes->wavefrm_height > UI_UNIT_Y * 20) {
+ scopes->wavefrm_height = UI_UNIT_Y * 20;
+ }
+
+ uiDefBut(block,
+ UI_BTYPE_WAVEFORM,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ scopes->wavefrm_height,
+ scopes,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+
+ /* Resize grip. */
+ uiDefIconButI(block,
+ UI_BTYPE_GRIP,
+ 0,
+ ICON_GRIP,
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ (short)(UI_UNIT_Y * 0.3f),
+ &scopes->wavefrm_height,
+ UI_UNIT_Y,
+ UI_UNIT_Y * 20.0f,
+ 0.0f,
+ 0.0f,
+ "");
}
/********************* Vectorscope Template ************************/
void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propname)
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- uiBlock *block;
- uiLayout *col;
- Scopes *scopes;
-
- if (!prop || RNA_property_type(prop) != PROP_POINTER) {
- return;
- }
-
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
- return;
- }
- scopes = (Scopes *)cptr.data;
-
- if (scopes->vecscope_height < UI_UNIT_Y) {
- scopes->vecscope_height = UI_UNIT_Y;
- }
- else if (scopes->vecscope_height > UI_UNIT_Y * 20) {
- scopes->vecscope_height = UI_UNIT_Y * 20;
- }
-
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- uiDefBut(block, UI_BTYPE_VECTORSCOPE, 0, "", 0, 0, UI_UNIT_X * 10, scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
-
- /* Resize grip. */
- uiDefIconButI(block, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10, (short)(UI_UNIT_Y * 0.3f), &scopes->vecscope_height,
- UI_UNIT_Y, UI_UNIT_Y * 20.0f, 0.0f, 0.0f, "");
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ uiBlock *block;
+ uiLayout *col;
+ Scopes *scopes;
+
+ if (!prop || RNA_property_type(prop) != PROP_POINTER) {
+ return;
+ }
+
+ cptr = RNA_property_pointer_get(ptr, prop);
+ if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes)) {
+ return;
+ }
+ scopes = (Scopes *)cptr.data;
+
+ if (scopes->vecscope_height < UI_UNIT_Y) {
+ scopes->vecscope_height = UI_UNIT_Y;
+ }
+ else if (scopes->vecscope_height > UI_UNIT_Y * 20) {
+ scopes->vecscope_height = UI_UNIT_Y * 20;
+ }
+
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ uiDefBut(block,
+ UI_BTYPE_VECTORSCOPE,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ scopes->vecscope_height,
+ scopes,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+
+ /* Resize grip. */
+ uiDefIconButI(block,
+ UI_BTYPE_GRIP,
+ 0,
+ ICON_GRIP,
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ (short)(UI_UNIT_Y * 0.3f),
+ &scopes->vecscope_height,
+ UI_UNIT_Y,
+ UI_UNIT_Y * 20.0f,
+ 0.0f,
+ 0.0f,
+ "");
}
/********************* CurveMapping Template ************************/
-
static void curvemap_buttons_zoom_in(bContext *C, void *cumap_v, void *UNUSED(arg))
{
- CurveMapping *cumap = cumap_v;
- float d;
-
- /* we allow 20 times zoom */
- if (BLI_rctf_size_x(&cumap->curr) > 0.04f * BLI_rctf_size_x(&cumap->clipr)) {
- d = 0.1154f * BLI_rctf_size_x(&cumap->curr);
- cumap->curr.xmin += d;
- cumap->curr.xmax -= d;
- d = 0.1154f * BLI_rctf_size_y(&cumap->curr);
- cumap->curr.ymin += d;
- cumap->curr.ymax -= d;
- }
-
- ED_region_tag_redraw(CTX_wm_region(C));
+ CurveMapping *cumap = cumap_v;
+ float d;
+
+ /* we allow 20 times zoom */
+ if (BLI_rctf_size_x(&cumap->curr) > 0.04f * BLI_rctf_size_x(&cumap->clipr)) {
+ d = 0.1154f * BLI_rctf_size_x(&cumap->curr);
+ cumap->curr.xmin += d;
+ cumap->curr.xmax -= d;
+ d = 0.1154f * BLI_rctf_size_y(&cumap->curr);
+ cumap->curr.ymin += d;
+ cumap->curr.ymax -= d;
+ }
+
+ ED_region_tag_redraw(CTX_wm_region(C));
}
static void curvemap_buttons_zoom_out(bContext *C, void *cumap_v, void *UNUSED(unused))
{
- CurveMapping *cumap = cumap_v;
- float d, d1;
-
- /* we allow 20 times zoom, but don't view outside clip */
- if (BLI_rctf_size_x(&cumap->curr) < 20.0f * BLI_rctf_size_x(&cumap->clipr)) {
- d = d1 = 0.15f * BLI_rctf_size_x(&cumap->curr);
-
- if (cumap->flag & CUMA_DO_CLIP) {
- if (cumap->curr.xmin - d < cumap->clipr.xmin) {
- d1 = cumap->curr.xmin - cumap->clipr.xmin;
- }
- }
- cumap->curr.xmin -= d1;
-
- d1 = d;
- if (cumap->flag & CUMA_DO_CLIP) {
- if (cumap->curr.xmax + d > cumap->clipr.xmax) {
- d1 = -cumap->curr.xmax + cumap->clipr.xmax;
- }
- }
- cumap->curr.xmax += d1;
-
- d = d1 = 0.15f * BLI_rctf_size_y(&cumap->curr);
-
- if (cumap->flag & CUMA_DO_CLIP) {
- if (cumap->curr.ymin - d < cumap->clipr.ymin) {
- d1 = cumap->curr.ymin - cumap->clipr.ymin;
- }
- }
- cumap->curr.ymin -= d1;
-
- d1 = d;
- if (cumap->flag & CUMA_DO_CLIP) {
- if (cumap->curr.ymax + d > cumap->clipr.ymax) {
- d1 = -cumap->curr.ymax + cumap->clipr.ymax;
- }
- }
- cumap->curr.ymax += d1;
- }
-
- ED_region_tag_redraw(CTX_wm_region(C));
+ CurveMapping *cumap = cumap_v;
+ float d, d1;
+
+ /* we allow 20 times zoom, but don't view outside clip */
+ if (BLI_rctf_size_x(&cumap->curr) < 20.0f * BLI_rctf_size_x(&cumap->clipr)) {
+ d = d1 = 0.15f * BLI_rctf_size_x(&cumap->curr);
+
+ if (cumap->flag & CUMA_DO_CLIP) {
+ if (cumap->curr.xmin - d < cumap->clipr.xmin) {
+ d1 = cumap->curr.xmin - cumap->clipr.xmin;
+ }
+ }
+ cumap->curr.xmin -= d1;
+
+ d1 = d;
+ if (cumap->flag & CUMA_DO_CLIP) {
+ if (cumap->curr.xmax + d > cumap->clipr.xmax) {
+ d1 = -cumap->curr.xmax + cumap->clipr.xmax;
+ }
+ }
+ cumap->curr.xmax += d1;
+
+ d = d1 = 0.15f * BLI_rctf_size_y(&cumap->curr);
+
+ if (cumap->flag & CUMA_DO_CLIP) {
+ if (cumap->curr.ymin - d < cumap->clipr.ymin) {
+ d1 = cumap->curr.ymin - cumap->clipr.ymin;
+ }
+ }
+ cumap->curr.ymin -= d1;
+
+ d1 = d;
+ if (cumap->flag & CUMA_DO_CLIP) {
+ if (cumap->curr.ymax + d > cumap->clipr.ymax) {
+ d1 = -cumap->curr.ymax + cumap->clipr.ymax;
+ }
+ }
+ cumap->curr.ymax += d1;
+ }
+
+ ED_region_tag_redraw(CTX_wm_region(C));
}
static void curvemap_buttons_setclip(bContext *UNUSED(C), void *cumap_v, void *UNUSED(arg))
{
- CurveMapping *cumap = cumap_v;
+ CurveMapping *cumap = cumap_v;
- curvemapping_changed(cumap, false);
+ curvemapping_changed(cumap, false);
}
static void curvemap_buttons_delete(bContext *C, void *cb_v, void *cumap_v)
{
- CurveMapping *cumap = cumap_v;
+ CurveMapping *cumap = cumap_v;
- curvemap_remove(cumap->cm + cumap->cur, SELECT);
- curvemapping_changed(cumap, false);
+ curvemap_remove(cumap->cm + cumap->cur, SELECT);
+ curvemapping_changed(cumap, false);
- rna_update_cb(C, cb_v, NULL);
+ rna_update_cb(C, cb_v, NULL);
}
/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
static uiBlock *curvemap_clipping_func(bContext *C, ARegion *ar, void *cumap_v)
{
- CurveMapping *cumap = cumap_v;
- uiBlock *block;
- uiBut *bt;
- float width = 8 * UI_UNIT_X;
-
- block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
-
- /* use this for a fake extra empty space around the buttons */
- uiDefBut(block, UI_BTYPE_LABEL, 0, "", -4, 16, width + 8, 6 * UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
-
- bt = uiDefButBitI(
- block, UI_BTYPE_TOGGLE, CUMA_DO_CLIP, 1, IFACE_("Use Clipping"),
- 0, 5 * UI_UNIT_Y, width, UI_UNIT_Y, &cumap->flag, 0.0, 0.0, 10, 0, "");
- UI_but_func_set(bt, curvemap_buttons_setclip, cumap, NULL);
-
- UI_block_align_begin(block);
- uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Min X "), 0, 4 * UI_UNIT_Y, width, UI_UNIT_Y,
- &cumap->clipr.xmin, -100.0, cumap->clipr.xmax, 10, 2, "");
- uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Min Y "), 0, 3 * UI_UNIT_Y, width, UI_UNIT_Y,
- &cumap->clipr.ymin, -100.0, cumap->clipr.ymax, 10, 2, "");
- uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Max X "), 0, 2 * UI_UNIT_Y, width, UI_UNIT_Y,
- &cumap->clipr.xmax, cumap->clipr.xmin, 100.0, 10, 2, "");
- uiDefButF(block, UI_BTYPE_NUM, 0, IFACE_("Max Y "), 0, UI_UNIT_Y, width, UI_UNIT_Y,
- &cumap->clipr.ymax, cumap->clipr.ymin, 100.0, 10, 2, "");
-
- UI_block_direction_set(block, UI_DIR_RIGHT);
-
- return block;
+ CurveMapping *cumap = cumap_v;
+ uiBlock *block;
+ uiBut *bt;
+ float width = 8 * UI_UNIT_X;
+
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+
+ /* use this for a fake extra empty space around the buttons */
+ uiDefBut(block, UI_BTYPE_LABEL, 0, "", -4, 16, width + 8, 6 * UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+
+ bt = uiDefButBitI(block,
+ UI_BTYPE_TOGGLE,
+ CUMA_DO_CLIP,
+ 1,
+ IFACE_("Use Clipping"),
+ 0,
+ 5 * UI_UNIT_Y,
+ width,
+ UI_UNIT_Y,
+ &cumap->flag,
+ 0.0,
+ 0.0,
+ 10,
+ 0,
+ "");
+ UI_but_func_set(bt, curvemap_buttons_setclip, cumap, NULL);
+
+ UI_block_align_begin(block);
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Min X "),
+ 0,
+ 4 * UI_UNIT_Y,
+ width,
+ UI_UNIT_Y,
+ &cumap->clipr.xmin,
+ -100.0,
+ cumap->clipr.xmax,
+ 10,
+ 2,
+ "");
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Min Y "),
+ 0,
+ 3 * UI_UNIT_Y,
+ width,
+ UI_UNIT_Y,
+ &cumap->clipr.ymin,
+ -100.0,
+ cumap->clipr.ymax,
+ 10,
+ 2,
+ "");
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Max X "),
+ 0,
+ 2 * UI_UNIT_Y,
+ width,
+ UI_UNIT_Y,
+ &cumap->clipr.xmax,
+ cumap->clipr.xmin,
+ 100.0,
+ 10,
+ 2,
+ "");
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ 0,
+ IFACE_("Max Y "),
+ 0,
+ UI_UNIT_Y,
+ width,
+ UI_UNIT_Y,
+ &cumap->clipr.ymax,
+ cumap->clipr.ymin,
+ 100.0,
+ 10,
+ 2,
+ "");
+
+ UI_block_direction_set(block, UI_DIR_RIGHT);
+
+ return block;
}
/* only for curvemap_tools_dofunc */
enum {
- UICURVE_FUNC_RESET_NEG,
- UICURVE_FUNC_RESET_POS,
- UICURVE_FUNC_RESET_VIEW,
- UICURVE_FUNC_HANDLE_VECTOR,
- UICURVE_FUNC_HANDLE_AUTO,
- UICURVE_FUNC_HANDLE_AUTO_ANIM,
- UICURVE_FUNC_EXTEND_HOZ,
- UICURVE_FUNC_EXTEND_EXP,
+ UICURVE_FUNC_RESET_NEG,
+ UICURVE_FUNC_RESET_POS,
+ UICURVE_FUNC_RESET_VIEW,
+ UICURVE_FUNC_HANDLE_VECTOR,
+ UICURVE_FUNC_HANDLE_AUTO,
+ UICURVE_FUNC_HANDLE_AUTO_ANIM,
+ UICURVE_FUNC_EXTEND_HOZ,
+ UICURVE_FUNC_EXTEND_EXP,
};
static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
{
- CurveMapping *cumap = cumap_v;
- CurveMap *cuma = cumap->cm + cumap->cur;
-
- switch (event) {
- case UICURVE_FUNC_RESET_NEG:
- case UICURVE_FUNC_RESET_POS: /* reset */
- curvemap_reset(cuma, &cumap->clipr, cumap->preset,
- (event == UICURVE_FUNC_RESET_NEG) ? CURVEMAP_SLOPE_NEGATIVE : CURVEMAP_SLOPE_POSITIVE);
- curvemapping_changed(cumap, false);
- break;
- case UICURVE_FUNC_RESET_VIEW:
- cumap->curr = cumap->clipr;
- break;
- case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */
- curvemap_handle_set(cuma, HD_VECT);
- curvemapping_changed(cumap, false);
- break;
- case UICURVE_FUNC_HANDLE_AUTO: /* set auto */
- curvemap_handle_set(cuma, HD_AUTO);
- curvemapping_changed(cumap, false);
- break;
- case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
- curvemap_handle_set(cuma, HD_AUTO_ANIM);
- curvemapping_changed(cumap, false);
- break;
- case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
- cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
- curvemapping_changed(cumap, false);
- break;
- case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */
- cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
- curvemapping_changed(cumap, false);
- break;
- }
- ED_undo_push(C, "CurveMap tools");
- ED_region_tag_redraw(CTX_wm_region(C));
+ CurveMapping *cumap = cumap_v;
+ CurveMap *cuma = cumap->cm + cumap->cur;
+
+ switch (event) {
+ case UICURVE_FUNC_RESET_NEG:
+ case UICURVE_FUNC_RESET_POS: /* reset */
+ curvemap_reset(cuma,
+ &cumap->clipr,
+ cumap->preset,
+ (event == UICURVE_FUNC_RESET_NEG) ? CURVEMAP_SLOPE_NEGATIVE :
+ CURVEMAP_SLOPE_POSITIVE);
+ curvemapping_changed(cumap, false);
+ break;
+ case UICURVE_FUNC_RESET_VIEW:
+ cumap->curr = cumap->clipr;
+ break;
+ case UICURVE_FUNC_HANDLE_VECTOR: /* set vector */
+ curvemap_handle_set(cuma, HD_VECT);
+ curvemapping_changed(cumap, false);
+ break;
+ case UICURVE_FUNC_HANDLE_AUTO: /* set auto */
+ curvemap_handle_set(cuma, HD_AUTO);
+ curvemapping_changed(cumap, false);
+ break;
+ case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
+ curvemap_handle_set(cuma, HD_AUTO_ANIM);
+ curvemapping_changed(cumap, false);
+ break;
+ case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
+ cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
+ curvemapping_changed(cumap, false);
+ break;
+ case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */
+ cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
+ curvemapping_changed(cumap, false);
+ break;
+ }
+ ED_undo_push(C, "CurveMap tools");
+ ED_region_tag_redraw(CTX_wm_region(C));
}
static uiBlock *curvemap_tools_func(
- bContext *C, ARegion *ar, CurveMapping *cumap,
- bool show_extend, int reset_mode)
+ bContext *C, ARegion *ar, CurveMapping *cumap, bool show_extend, int reset_mode)
{
- uiBlock *block;
- short yco = 0, menuwidth = 10 * UI_UNIT_X;
-
- block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
- UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap);
-
- {
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset View"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_RESET_VIEW, "");
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Vector Handle"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_VECTOR, "");
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Handle"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO, "");
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Auto Clamped Handle"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_HANDLE_AUTO_ANIM, "");
- }
-
- if (show_extend) {
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Horizontal"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_HOZ, "");
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Extend Extrapolated"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, UICURVE_FUNC_EXTEND_EXP, "");
- }
-
- {
- uiDefIconTextBut(
- block, UI_BTYPE_BUT_MENU, 1, ICON_BLANK1, IFACE_("Reset Curve"),
- 0, yco -= UI_UNIT_Y, menuwidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, reset_mode, "");
- }
-
- UI_block_direction_set(block, UI_DIR_DOWN);
- UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
-
- return block;
+ uiBlock *block;
+ short yco = 0, menuwidth = 10 * UI_UNIT_X;
+
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_func_butmenu_set(block, curvemap_tools_dofunc, cumap);
+
+ {
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Reset View"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ UICURVE_FUNC_RESET_VIEW,
+ "");
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Vector Handle"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ UICURVE_FUNC_HANDLE_VECTOR,
+ "");
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Auto Handle"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ UICURVE_FUNC_HANDLE_AUTO,
+ "");
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Auto Clamped Handle"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ UICURVE_FUNC_HANDLE_AUTO_ANIM,
+ "");
+ }
+
+ if (show_extend) {
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Extend Horizontal"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ UICURVE_FUNC_EXTEND_HOZ,
+ "");
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Extend Extrapolated"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ UICURVE_FUNC_EXTEND_EXP,
+ "");
+ }
+
+ {
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT_MENU,
+ 1,
+ ICON_BLANK1,
+ IFACE_("Reset Curve"),
+ 0,
+ yco -= UI_UNIT_Y,
+ menuwidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ reset_mode,
+ "");
+ }
+
+ UI_block_direction_set(block, UI_DIR_DOWN);
+ UI_block_bounds_set_text(block, 3.0f * UI_UNIT_X);
+
+ return block;
}
static uiBlock *curvemap_tools_posslope_func(bContext *C, ARegion *ar, void *cumap_v)
{
- return curvemap_tools_func(C, ar, cumap_v, true, UICURVE_FUNC_RESET_POS);
+ return curvemap_tools_func(C, ar, cumap_v, true, UICURVE_FUNC_RESET_POS);
}
static uiBlock *curvemap_tools_negslope_func(bContext *C, ARegion *ar, void *cumap_v)
{
- return curvemap_tools_func(C, ar, cumap_v, true, UICURVE_FUNC_RESET_NEG);
+ return curvemap_tools_func(C, ar, cumap_v, true, UICURVE_FUNC_RESET_NEG);
}
static uiBlock *curvemap_brush_tools_func(bContext *C, ARegion *ar, void *cumap_v)
{
- return curvemap_tools_func(C, ar, cumap_v, false, UICURVE_FUNC_RESET_NEG);
+ return curvemap_tools_func(C, ar, cumap_v, false, UICURVE_FUNC_RESET_NEG);
}
static void curvemap_buttons_redraw(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
{
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
}
static void curvemap_buttons_update(bContext *C, void *arg1_v, void *cumap_v)
{
- CurveMapping *cumap = cumap_v;
- curvemapping_changed(cumap, true);
- rna_update_cb(C, arg1_v, NULL);
+ CurveMapping *cumap = cumap_v;
+ curvemapping_changed(cumap, true);
+ rna_update_cb(C, arg1_v, NULL);
}
static void curvemap_buttons_reset(bContext *C, void *cb_v, void *cumap_v)
{
- CurveMapping *cumap = cumap_v;
- int a;
+ CurveMapping *cumap = cumap_v;
+ int a;
- cumap->preset = CURVE_PRESET_LINE;
- for (a = 0; a < CM_TOT; a++) {
- curvemap_reset(cumap->cm + a, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
- }
+ cumap->preset = CURVE_PRESET_LINE;
+ for (a = 0; a < CM_TOT; a++) {
+ curvemap_reset(cumap->cm + a, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
+ }
- cumap->black[0] = cumap->black[1] = cumap->black[2] = 0.0f;
- cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
- curvemapping_set_black_white(cumap, NULL, NULL);
+ cumap->black[0] = cumap->black[1] = cumap->black[2] = 0.0f;
+ cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f;
+ curvemapping_set_black_white(cumap, NULL, NULL);
- curvemapping_changed(cumap, false);
+ curvemapping_changed(cumap, false);
- rna_update_cb(C, cb_v, NULL);
+ rna_update_cb(C, cb_v, NULL);
}
/* still unsure how this call evolves...
* we use labeltype for defining what curve-channels to show */
-static void curvemap_buttons_layout(
- uiLayout *layout, PointerRNA *ptr, char labeltype, bool levels,
- bool brush, bool neg_slope, bool tone, RNAUpdateCb *cb)
+static void curvemap_buttons_layout(uiLayout *layout,
+ PointerRNA *ptr,
+ char labeltype,
+ bool levels,
+ bool brush,
+ bool neg_slope,
+ bool tone,
+ RNAUpdateCb *cb)
{
- CurveMapping *cumap = ptr->data;
- CurveMap *cm = &cumap->cm[cumap->cur];
- CurveMapPoint *cmp = NULL;
- uiLayout *row, *sub, *split;
- uiBlock *block;
- uiBut *bt;
- float dx = UI_UNIT_X;
- int icon, size;
- int bg = -1, i;
-
- block = uiLayoutGetBlock(layout);
-
- if (tone) {
- split = uiLayoutSplit(layout, 0.0f, false);
- uiItemR(uiLayoutRow(split, false), ptr, "tone", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- }
-
- /* curve chooser */
- row = uiLayoutRow(layout, false);
-
- if (labeltype == 'v') {
- /* vector */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
-
- if (cumap->cm[0].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- if (cumap->cm[1].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- if (cumap->cm[2].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- }
- else if (labeltype == 'c') {
- /* color */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
-
- if (cumap->cm[3].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- if (cumap->cm[0].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- if (cumap->cm[1].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- if (cumap->cm[2].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- }
- else if (labeltype == 'h') {
- /* HSV */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
-
- if (cumap->cm[0].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- if (cumap->cm[1].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- if (cumap->cm[2].curve) {
- bt = uiDefButI(block, UI_BTYPE_ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
- UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
- }
- }
- else {
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
- }
-
- if (labeltype == 'h') {
- bg = UI_GRAD_H;
- }
-
- /* operation buttons */
- sub = uiLayoutRow(row, true);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_ZOOM_IN, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom in"));
- UI_but_func_set(bt, curvemap_buttons_zoom_in, cumap, NULL);
-
- bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_ZOOM_OUT, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Zoom out"));
- UI_but_func_set(bt, curvemap_buttons_zoom_out, cumap, NULL);
-
- if (brush) {
- bt = uiDefIconBlockBut(block, curvemap_brush_tools_func, cumap, 0, ICON_DOWNARROW_HLT, 0, 0, dx, dx, TIP_("Tools"));
- }
- else if (neg_slope) {
- bt = uiDefIconBlockBut(
- block, curvemap_tools_negslope_func, cumap, 0, ICON_DOWNARROW_HLT,
- 0, 0, dx, dx, TIP_("Tools"));
- }
- else {
- bt = uiDefIconBlockBut(
- block, curvemap_tools_posslope_func, cumap, 0, ICON_DOWNARROW_HLT,
- 0, 0, dx, dx, TIP_("Tools"));
- }
-
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-
- icon = (cumap->flag & CUMA_DO_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
- bt = uiDefIconBlockBut(block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options"));
- UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-
- bt = uiDefIconBut(block, UI_BTYPE_BUT, 0, ICON_X, 0, 0, dx, dx, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete points"));
- UI_but_funcN_set(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap);
-
- UI_block_emboss_set(block, UI_EMBOSS);
-
- UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
-
- /* curve itself */
- size = uiLayoutGetWidth(layout);
- row = uiLayoutRow(layout, false);
- uiDefBut(block, UI_BTYPE_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, bg, 0, "");
-
- /* sliders for selected point */
- for (i = 0; i < cm->totpoint; i++) {
- if (cm->curve[i].flag & CUMA_SELECT) {
- cmp = &cm->curve[i];
- break;
- }
- }
-
- if (cmp) {
- rctf bounds;
-
- if (cumap->flag & CUMA_DO_CLIP) {
- bounds = cumap->clipr;
- }
- else {
- bounds.xmin = bounds.ymin = -1000.0;
- bounds.xmax = bounds.ymax = 1000.0;
- }
-
- uiLayoutRow(layout, true);
- UI_block_funcN_set(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
- uiDefButF(block, UI_BTYPE_NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->x, bounds.xmin, bounds.xmax, 1, 5, "");
- uiDefButF(block, UI_BTYPE_NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->y, bounds.ymin, bounds.ymax, 1, 5, "");
- }
-
- /* black/white levels */
- if (levels) {
- split = uiLayoutSplit(layout, 0.0f, false);
- uiItemR(uiLayoutColumn(split, false), ptr, "black_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
- uiItemR(uiLayoutColumn(split, false), ptr, "white_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
-
- uiLayoutRow(layout, false);
- bt = uiDefBut(block, UI_BTYPE_BUT, 0, IFACE_("Reset"), 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0,
- TIP_("Reset Black/White point and curves"));
- UI_but_funcN_set(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap);
- }
-
- UI_block_funcN_set(block, NULL, NULL, NULL);
+ CurveMapping *cumap = ptr->data;
+ CurveMap *cm = &cumap->cm[cumap->cur];
+ CurveMapPoint *cmp = NULL;
+ uiLayout *row, *sub, *split;
+ uiBlock *block;
+ uiBut *bt;
+ float dx = UI_UNIT_X;
+ int icon, size;
+ int bg = -1, i;
+
+ block = uiLayoutGetBlock(layout);
+
+ if (tone) {
+ split = uiLayoutSplit(layout, 0.0f, false);
+ uiItemR(uiLayoutRow(split, false), ptr, "tone", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ }
+
+ /* curve chooser */
+ row = uiLayoutRow(layout, false);
+
+ if (labeltype == 'v') {
+ /* vector */
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ if (cumap->cm[0].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "X", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if (cumap->cm[1].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "Y", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if (cumap->cm[2].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "Z", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ }
+ else if (labeltype == 'c') {
+ /* color */
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ if (cumap->cm[3].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "C", 0, 0, dx, dx, &cumap->cur, 0.0, 3.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if (cumap->cm[0].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "R", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if (cumap->cm[1].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "G", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if (cumap->cm[2].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "B", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ }
+ else if (labeltype == 'h') {
+ /* HSV */
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ if (cumap->cm[0].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "H", 0, 0, dx, dx, &cumap->cur, 0.0, 0.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if (cumap->cm[1].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "S", 0, 0, dx, dx, &cumap->cur, 0.0, 1.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ if (cumap->cm[2].curve) {
+ bt = uiDefButI(
+ block, UI_BTYPE_ROW, 0, "V", 0, 0, dx, dx, &cumap->cur, 0.0, 2.0, 0.0, 0.0, "");
+ UI_but_func_set(bt, curvemap_buttons_redraw, NULL, NULL);
+ }
+ }
+ else {
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT);
+ }
+
+ if (labeltype == 'h') {
+ bg = UI_GRAD_H;
+ }
+
+ /* operation buttons */
+ sub = uiLayoutRow(row, true);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ bt = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_ZOOM_IN,
+ 0,
+ 0,
+ dx,
+ dx,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Zoom in"));
+ UI_but_func_set(bt, curvemap_buttons_zoom_in, cumap, NULL);
+
+ bt = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_ZOOM_OUT,
+ 0,
+ 0,
+ dx,
+ dx,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Zoom out"));
+ UI_but_func_set(bt, curvemap_buttons_zoom_out, cumap, NULL);
+
+ if (brush) {
+ bt = uiDefIconBlockBut(block,
+ curvemap_brush_tools_func,
+ cumap,
+ 0,
+ ICON_DOWNARROW_HLT,
+ 0,
+ 0,
+ dx,
+ dx,
+ TIP_("Tools"));
+ }
+ else if (neg_slope) {
+ bt = uiDefIconBlockBut(block,
+ curvemap_tools_negslope_func,
+ cumap,
+ 0,
+ ICON_DOWNARROW_HLT,
+ 0,
+ 0,
+ dx,
+ dx,
+ TIP_("Tools"));
+ }
+ else {
+ bt = uiDefIconBlockBut(block,
+ curvemap_tools_posslope_func,
+ cumap,
+ 0,
+ ICON_DOWNARROW_HLT,
+ 0,
+ 0,
+ dx,
+ dx,
+ TIP_("Tools"));
+ }
+
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ icon = (cumap->flag & CUMA_DO_CLIP) ? ICON_CLIPUV_HLT : ICON_CLIPUV_DEHLT;
+ bt = uiDefIconBlockBut(
+ block, curvemap_clipping_func, cumap, 0, icon, 0, 0, dx, dx, TIP_("Clipping Options"));
+ UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ bt = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_X,
+ 0,
+ 0,
+ dx,
+ dx,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Delete points"));
+ UI_but_funcN_set(bt, curvemap_buttons_delete, MEM_dupallocN(cb), cumap);
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ /* curve itself */
+ size = uiLayoutGetWidth(layout);
+ row = uiLayoutRow(layout, false);
+ uiDefBut(
+ block, UI_BTYPE_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, bg, 0, "");
+
+ /* sliders for selected point */
+ for (i = 0; i < cm->totpoint; i++) {
+ if (cm->curve[i].flag & CUMA_SELECT) {
+ cmp = &cm->curve[i];
+ break;
+ }
+ }
+
+ if (cmp) {
+ rctf bounds;
+
+ if (cumap->flag & CUMA_DO_CLIP) {
+ bounds = cumap->clipr;
+ }
+ else {
+ bounds.xmin = bounds.ymin = -1000.0;
+ bounds.xmax = bounds.ymax = 1000.0;
+ }
+
+ uiLayoutRow(layout, true);
+ UI_block_funcN_set(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ 0,
+ "X",
+ 0,
+ 2 * UI_UNIT_Y,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ &cmp->x,
+ bounds.xmin,
+ bounds.xmax,
+ 1,
+ 5,
+ "");
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ 0,
+ "Y",
+ 0,
+ 1 * UI_UNIT_Y,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ &cmp->y,
+ bounds.ymin,
+ bounds.ymax,
+ 1,
+ 5,
+ "");
+ }
+
+ /* black/white levels */
+ if (levels) {
+ split = uiLayoutSplit(layout, 0.0f, false);
+ uiItemR(uiLayoutColumn(split, false), ptr, "black_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(uiLayoutColumn(split, false), ptr, "white_level", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ uiLayoutRow(layout, false);
+ bt = uiDefBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ IFACE_("Reset"),
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0,
+ 0,
+ TIP_("Reset Black/White point and curves"));
+ UI_but_funcN_set(bt, curvemap_buttons_reset, MEM_dupallocN(cb), cumap);
+ }
+
+ UI_block_funcN_set(block, NULL, NULL, NULL);
}
-void uiTemplateCurveMapping(
- uiLayout *layout, PointerRNA *ptr, const char *propname, int type,
- bool levels, bool brush, bool neg_slope, bool tone)
+void uiTemplateCurveMapping(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ int type,
+ bool levels,
+ bool brush,
+ bool neg_slope,
+ bool tone)
{
- RNAUpdateCb *cb;
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- ID *id;
- uiBlock *block = uiLayoutGetBlock(layout);
+ RNAUpdateCb *cb;
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ ID *id;
+ uiBlock *block = uiLayoutGetBlock(layout);
- if (!prop) {
- RNA_warning("curve property not found: %s.%s",
- RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ if (!prop) {
+ RNA_warning("curve property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
- if (RNA_property_type(prop) != PROP_POINTER) {
- RNA_warning("curve is not a pointer: %s.%s",
- RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ if (RNA_property_type(prop) != PROP_POINTER) {
+ RNA_warning("curve is not a pointer: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveMapping)) {
- return;
- }
+ cptr = RNA_property_pointer_get(ptr, prop);
+ if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_CurveMapping)) {
+ return;
+ }
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
+ cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr = *ptr;
+ cb->prop = prop;
- id = cptr.id.data;
- UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
+ id = cptr.id.data;
+ UI_block_lock_set(block, (id && ID_IS_LINKED(id)), ERROR_LIBDATA_MESSAGE);
- curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb);
+ curvemap_buttons_layout(layout, &cptr, type, levels, brush, neg_slope, tone, cb);
- UI_block_lock_clear(block);
+ UI_block_lock_clear(block);
- MEM_freeN(cb);
+ MEM_freeN(cb);
}
/********************* ColorPicker Template ************************/
-#define WHEEL_SIZE (5 * U.widget_unit)
+#define WHEEL_SIZE (5 * U.widget_unit)
/* This template now follows User Preference for type - name is not correct anymore... */
-void uiTemplateColorPicker(
- uiLayout *layout, PointerRNA *ptr, const char *propname, bool value_slider,
- bool lock, bool lock_luminosity, bool cubic)
+void uiTemplateColorPicker(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ bool value_slider,
+ bool lock,
+ bool lock_luminosity,
+ bool cubic)
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- uiBlock *block = uiLayoutGetBlock(layout);
- uiLayout *col, *row;
- uiBut *but = NULL;
- ColorPicker *cpicker = ui_block_colorpicker_create(block);
- float softmin, softmax, step, precision;
-
- if (!prop) {
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
-
- col = uiLayoutColumn(layout, true);
- row = uiLayoutRow(col, true);
-
- switch (U.color_picker_type) {
- case USER_CP_SQUARE_SV:
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
- -1, 0.0, 0.0, UI_GRAD_SV, 0, "");
- break;
- case USER_CP_SQUARE_HS:
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
- -1, 0.0, 0.0, UI_GRAD_HS, 0, "");
- break;
- case USER_CP_SQUARE_HV:
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
- -1, 0.0, 0.0, UI_GRAD_HV, 0, "");
- break;
-
- /* user default */
- case USER_CP_CIRCLE_HSV:
- case USER_CP_CIRCLE_HSL:
- default:
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop,
- -1, 0.0, 0.0, 0, 0, "");
- break;
-
- }
-
- but->custom_data = cpicker;
-
- cpicker->use_color_lock = lock;
- cpicker->use_color_cubic = cubic;
- cpicker->use_luminosity_lock = lock_luminosity;
-
- if (lock_luminosity) {
- float color[4]; /* in case of alpha */
- RNA_property_float_get_array(ptr, prop, color);
- but->a2 = len_v3(color);
- cpicker->luminosity_lock_value = len_v3(color);
- }
-
-
- if (value_slider) {
- switch (U.color_picker_type) {
- case USER_CP_CIRCLE_HSL:
- uiItemS(row);
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14 * UI_DPI_FAC, WHEEL_SIZE, ptr, prop,
- -1, softmin, softmax, UI_GRAD_L_ALT, 0, "");
- break;
- case USER_CP_SQUARE_SV:
- uiItemS(col);
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18 * UI_DPI_FAC, ptr, prop,
- -1, softmin, softmax, UI_GRAD_SV + 3, 0, "");
- break;
- case USER_CP_SQUARE_HS:
- uiItemS(col);
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18 * UI_DPI_FAC, ptr, prop,
- -1, softmin, softmax, UI_GRAD_HS + 3, 0, "");
- break;
- case USER_CP_SQUARE_HV:
- uiItemS(col);
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", 0, 4, WHEEL_SIZE, 18 * UI_DPI_FAC, ptr, prop,
- -1, softmin, softmax, UI_GRAD_HV + 3, 0, "");
- break;
-
- /* user default */
- case USER_CP_CIRCLE_HSV:
- default:
- uiItemS(row);
- but = uiDefButR_prop(
- block, UI_BTYPE_HSVCUBE, 0, "", WHEEL_SIZE + 6, 0, 14 * UI_DPI_FAC, WHEEL_SIZE, ptr, prop,
- -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
- break;
- }
-
- but->custom_data = cpicker;
- }
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ uiBlock *block = uiLayoutGetBlock(layout);
+ uiLayout *col, *row;
+ uiBut *but = NULL;
+ ColorPicker *cpicker = ui_block_colorpicker_create(block);
+ float softmin, softmax, step, precision;
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
+
+ col = uiLayoutColumn(layout, true);
+ row = uiLayoutRow(col, true);
+
+ switch (U.color_picker_type) {
+ case USER_CP_SQUARE_SV:
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ 0,
+ WHEEL_SIZE,
+ WHEEL_SIZE,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ UI_GRAD_SV,
+ 0,
+ "");
+ break;
+ case USER_CP_SQUARE_HS:
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ 0,
+ WHEEL_SIZE,
+ WHEEL_SIZE,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ UI_GRAD_HS,
+ 0,
+ "");
+ break;
+ case USER_CP_SQUARE_HV:
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ 0,
+ WHEEL_SIZE,
+ WHEEL_SIZE,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ UI_GRAD_HV,
+ 0,
+ "");
+ break;
+
+ /* user default */
+ case USER_CP_CIRCLE_HSV:
+ case USER_CP_CIRCLE_HSL:
+ default:
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCIRCLE,
+ 0,
+ "",
+ 0,
+ 0,
+ WHEEL_SIZE,
+ WHEEL_SIZE,
+ ptr,
+ prop,
+ -1,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ break;
+ }
+
+ but->custom_data = cpicker;
+
+ cpicker->use_color_lock = lock;
+ cpicker->use_color_cubic = cubic;
+ cpicker->use_luminosity_lock = lock_luminosity;
+
+ if (lock_luminosity) {
+ float color[4]; /* in case of alpha */
+ RNA_property_float_get_array(ptr, prop, color);
+ but->a2 = len_v3(color);
+ cpicker->luminosity_lock_value = len_v3(color);
+ }
+
+ if (value_slider) {
+ switch (U.color_picker_type) {
+ case USER_CP_CIRCLE_HSL:
+ uiItemS(row);
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ WHEEL_SIZE + 6,
+ 0,
+ 14 * UI_DPI_FAC,
+ WHEEL_SIZE,
+ ptr,
+ prop,
+ -1,
+ softmin,
+ softmax,
+ UI_GRAD_L_ALT,
+ 0,
+ "");
+ break;
+ case USER_CP_SQUARE_SV:
+ uiItemS(col);
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ 4,
+ WHEEL_SIZE,
+ 18 * UI_DPI_FAC,
+ ptr,
+ prop,
+ -1,
+ softmin,
+ softmax,
+ UI_GRAD_SV + 3,
+ 0,
+ "");
+ break;
+ case USER_CP_SQUARE_HS:
+ uiItemS(col);
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ 4,
+ WHEEL_SIZE,
+ 18 * UI_DPI_FAC,
+ ptr,
+ prop,
+ -1,
+ softmin,
+ softmax,
+ UI_GRAD_HS + 3,
+ 0,
+ "");
+ break;
+ case USER_CP_SQUARE_HV:
+ uiItemS(col);
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ 0,
+ 4,
+ WHEEL_SIZE,
+ 18 * UI_DPI_FAC,
+ ptr,
+ prop,
+ -1,
+ softmin,
+ softmax,
+ UI_GRAD_HV + 3,
+ 0,
+ "");
+ break;
+
+ /* user default */
+ case USER_CP_CIRCLE_HSV:
+ default:
+ uiItemS(row);
+ but = uiDefButR_prop(block,
+ UI_BTYPE_HSVCUBE,
+ 0,
+ "",
+ WHEEL_SIZE + 6,
+ 0,
+ 14 * UI_DPI_FAC,
+ WHEEL_SIZE,
+ ptr,
+ prop,
+ -1,
+ softmin,
+ softmax,
+ UI_GRAD_V_ALT,
+ 0,
+ "");
+ break;
+ }
+
+ but->custom_data = cpicker;
+ }
}
-void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname, bool UNUSED(colors))
+void uiTemplatePalette(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ bool UNUSED(colors))
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- PointerRNA cptr;
- Palette *palette;
- PaletteColor *color;
- uiBlock *block;
- uiLayout *col;
- int row_cols = 0, col_id = 0;
- int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1);
-
- if (!prop) {
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- cptr = RNA_property_pointer_get(ptr, prop);
- if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Palette)) {
- return;
- }
-
- block = uiLayoutGetBlock(layout);
-
- palette = cptr.data;
-
- color = palette->colors.first;
-
- col = uiLayoutColumn(layout, true);
- uiLayoutRow(col, true);
- uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_add", WM_OP_INVOKE_DEFAULT, ICON_ADD, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
- uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_delete", WM_OP_INVOKE_DEFAULT, ICON_REMOVE, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
-
- col = uiLayoutColumn(layout, true);
- uiLayoutRow(col, true);
-
- for (; color; color = color->next) {
- PointerRNA color_ptr;
-
- if (row_cols >= cols_per_row) {
- uiLayoutRow(col, true);
- row_cols = 0;
- }
-
- RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr);
- uiDefButR(
- block, UI_BTYPE_COLOR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, &color_ptr, "color", -1, 0.0, 1.0,
- UI_PALETTE_COLOR, col_id, "");
- row_cols++;
- col_id++;
- }
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ Palette *palette;
+ PaletteColor *color;
+ uiBlock *block;
+ uiLayout *col;
+ int row_cols = 0, col_id = 0;
+ int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1);
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ cptr = RNA_property_pointer_get(ptr, prop);
+ if (!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Palette)) {
+ return;
+ }
+
+ block = uiLayoutGetBlock(layout);
+
+ palette = cptr.data;
+
+ color = palette->colors.first;
+
+ col = uiLayoutColumn(layout, true);
+ uiLayoutRow(col, true);
+ uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "PALETTE_OT_color_add",
+ WM_OP_INVOKE_DEFAULT,
+ ICON_ADD,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL);
+ uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "PALETTE_OT_color_delete",
+ WM_OP_INVOKE_DEFAULT,
+ ICON_REMOVE,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL);
+
+ col = uiLayoutColumn(layout, true);
+ uiLayoutRow(col, true);
+
+ for (; color; color = color->next) {
+ PointerRNA color_ptr;
+
+ if (row_cols >= cols_per_row) {
+ uiLayoutRow(col, true);
+ row_cols = 0;
+ }
+
+ RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr);
+ uiDefButR(block,
+ UI_BTYPE_COLOR,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &color_ptr,
+ "color",
+ -1,
+ 0.0,
+ 1.0,
+ UI_PALETTE_COLOR,
+ col_id,
+ "");
+ row_cols++;
+ col_id++;
+ }
}
void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propname)
{
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- uiBlock *block;
- uiBut *but;
-
- if (!prop) {
- RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- block = uiLayoutGetBlock(layout);
-
- but = uiDefIconTextButO(block, UI_BTYPE_BUT, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, RNA_property_ui_name(prop), 0, 0, UI_UNIT_X, UI_UNIT_Y, RNA_property_ui_description(prop));
- but->rnapoin = *ptr;
- but->rnaprop = prop;
- but->rnaindex = -1;
-
- PointerRNA *opptr = UI_but_operator_ptr_get(but);
- /* Important for crypto-matte operation. */
- RNA_boolean_set(opptr, "use_accumulate", false);
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ uiBlock *block;
+ uiBut *but;
+
+ if (!prop) {
+ RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ block = uiLayoutGetBlock(layout);
+
+ but = uiDefIconTextButO(block,
+ UI_BTYPE_BUT,
+ "UI_OT_eyedropper_color",
+ WM_OP_INVOKE_DEFAULT,
+ ICON_EYEDROPPER,
+ RNA_property_ui_name(prop),
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ RNA_property_ui_description(prop));
+ but->rnapoin = *ptr;
+ but->rnaprop = prop;
+ but->rnaindex = -1;
+
+ PointerRNA *opptr = UI_but_operator_ptr_get(but);
+ /* Important for crypto-matte operation. */
+ RNA_boolean_set(opptr, "use_accumulate", false);
}
/********************* Layer Buttons Template ************************/
static void handle_layer_buttons(bContext *C, void *arg1, void *arg2)
{
- uiBut *but = arg1;
- int cur = POINTER_AS_INT(arg2);
- wmWindow *win = CTX_wm_window(C);
- int i, tot, shift = win->eventstate->shift;
-
- if (!shift) {
- tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
-
- /* Normally clicking only selects one layer */
- RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, true);
- for (i = 0; i < tot; ++i) {
- if (i != cur) {
- RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, false);
- }
- }
- }
-
- /* view3d layer change should update depsgraph (invisible object changed maybe) */
- /* see view3d_header.c */
+ uiBut *but = arg1;
+ int cur = POINTER_AS_INT(arg2);
+ wmWindow *win = CTX_wm_window(C);
+ int i, tot, shift = win->eventstate->shift;
+
+ if (!shift) {
+ tot = RNA_property_array_length(&but->rnapoin, but->rnaprop);
+
+ /* Normally clicking only selects one layer */
+ RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, cur, true);
+ for (i = 0; i < tot; ++i) {
+ if (i != cur) {
+ RNA_property_boolean_set_index(&but->rnapoin, but->rnaprop, i, false);
+ }
+ }
+ }
+
+ /* view3d layer change should update depsgraph (invisible object changed maybe) */
+ /* see view3d_header.c */
}
/**
* \todo for now, grouping of layers is determined by dividing up the length of
* the array of layer bitflags
*/
-void uiTemplateLayers(
- uiLayout *layout, PointerRNA *ptr, const char *propname,
- PointerRNA *used_ptr, const char *used_propname, int active_layer)
+void uiTemplateLayers(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ PointerRNA *used_ptr,
+ const char *used_propname,
+ int active_layer)
{
- uiLayout *uRow, *uCol;
- PropertyRNA *prop, *used_prop = NULL;
- int groups, cols, layers;
- int group, col, layer, row;
- int cols_per_group = 5;
-
- prop = RNA_struct_find_property(ptr, propname);
- if (!prop) {
- RNA_warning("layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
- return;
- }
-
- /* the number of layers determines the way we group them
- * - we want 2 rows only (for now)
- * - the number of columns (cols) is the total number of buttons per row
- * the 'remainder' is added to this, as it will be ok to have first row slightly wider if need be
- * - for now, only split into groups if group will have at least 5 items
- */
- layers = RNA_property_array_length(ptr, prop);
- cols = (layers / 2) + (layers % 2);
- groups = ((cols / 2) < cols_per_group) ? (1) : (cols / cols_per_group);
-
- if (used_ptr && used_propname) {
- used_prop = RNA_struct_find_property(used_ptr, used_propname);
- if (!used_prop) {
- RNA_warning("used layers property not found: %s.%s", RNA_struct_identifier(ptr->type), used_propname);
- return;
- }
-
- if (RNA_property_array_length(used_ptr, used_prop) < layers) {
- used_prop = NULL;
- }
- }
-
- /* layers are laid out going across rows, with the columns being divided into groups */
-
- for (group = 0; group < groups; group++) {
- uCol = uiLayoutColumn(layout, true);
-
- for (row = 0; row < 2; row++) {
- uiBlock *block;
- uiBut *but;
-
- uRow = uiLayoutRow(uCol, true);
- block = uiLayoutGetBlock(uRow);
- layer = groups * cols_per_group * row + cols_per_group * group;
-
- /* add layers as toggle buts */
- for (col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) {
- int icon = 0;
- int butlay = 1 << layer;
-
- if (active_layer & butlay) {
- icon = ICON_LAYER_ACTIVE;
- }
- else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer)) {
- icon = ICON_LAYER_USED;
- }
-
- but = uiDefAutoButR(block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
- UI_but_func_set(but, handle_layer_buttons, but, POINTER_FROM_INT(layer));
- but->type = UI_BTYPE_TOGGLE;
- }
- }
- }
+ uiLayout *uRow, *uCol;
+ PropertyRNA *prop, *used_prop = NULL;
+ int groups, cols, layers;
+ int group, col, layer, row;
+ int cols_per_group = 5;
+
+ prop = RNA_struct_find_property(ptr, propname);
+ if (!prop) {
+ RNA_warning("layers property not found: %s.%s", RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
+
+ /* the number of layers determines the way we group them
+ * - we want 2 rows only (for now)
+ * - the number of columns (cols) is the total number of buttons per row
+ * the 'remainder' is added to this, as it will be ok to have first row slightly wider if need be
+ * - for now, only split into groups if group will have at least 5 items
+ */
+ layers = RNA_property_array_length(ptr, prop);
+ cols = (layers / 2) + (layers % 2);
+ groups = ((cols / 2) < cols_per_group) ? (1) : (cols / cols_per_group);
+
+ if (used_ptr && used_propname) {
+ used_prop = RNA_struct_find_property(used_ptr, used_propname);
+ if (!used_prop) {
+ RNA_warning("used layers property not found: %s.%s",
+ RNA_struct_identifier(ptr->type),
+ used_propname);
+ return;
+ }
+
+ if (RNA_property_array_length(used_ptr, used_prop) < layers) {
+ used_prop = NULL;
+ }
+ }
+
+ /* layers are laid out going across rows, with the columns being divided into groups */
+
+ for (group = 0; group < groups; group++) {
+ uCol = uiLayoutColumn(layout, true);
+
+ for (row = 0; row < 2; row++) {
+ uiBlock *block;
+ uiBut *but;
+
+ uRow = uiLayoutRow(uCol, true);
+ block = uiLayoutGetBlock(uRow);
+ layer = groups * cols_per_group * row + cols_per_group * group;
+
+ /* add layers as toggle buts */
+ for (col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) {
+ int icon = 0;
+ int butlay = 1 << layer;
+
+ if (active_layer & butlay) {
+ icon = ICON_LAYER_ACTIVE;
+ }
+ else if (used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer)) {
+ icon = ICON_LAYER_USED;
+ }
+
+ but = uiDefAutoButR(block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X / 2, UI_UNIT_Y / 2);
+ UI_but_func_set(but, handle_layer_buttons, but, POINTER_FROM_INT(layer));
+ but->type = UI_BTYPE_TOGGLE;
+ }
+ }
+ }
}
/************************* List Template **************************/
-static void uilist_draw_item_default(
- struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout,
- struct PointerRNA *UNUSED(dataptr), struct PointerRNA *itemptr, int icon,
- struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname),
- int UNUSED(index), int UNUSED(flt_flag))
+static void uilist_draw_item_default(struct uiList *ui_list,
+ struct bContext *UNUSED(C),
+ struct uiLayout *layout,
+ struct PointerRNA *UNUSED(dataptr),
+ struct PointerRNA *itemptr,
+ int icon,
+ struct PointerRNA *UNUSED(active_dataptr),
+ const char *UNUSED(active_propname),
+ int UNUSED(index),
+ int UNUSED(flt_flag))
{
- PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type);
-
- /* Simplest one! */
- switch (ui_list->layout_type) {
- case UILST_LAYOUT_GRID:
- uiItemL(layout, "", icon);
- break;
- case UILST_LAYOUT_DEFAULT:
- case UILST_LAYOUT_COMPACT:
- default:
- if (nameprop) {
- uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon);
- }
- else {
- uiItemL(layout, "", icon);
- }
- break;
- }
+ PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type);
+
+ /* Simplest one! */
+ switch (ui_list->layout_type) {
+ case UILST_LAYOUT_GRID:
+ uiItemL(layout, "", icon);
+ break;
+ case UILST_LAYOUT_DEFAULT:
+ case UILST_LAYOUT_COMPACT:
+ default:
+ if (nameprop) {
+ uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon);
+ }
+ else {
+ uiItemL(layout, "", icon);
+ }
+ break;
+ }
}
-static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout)
+static void uilist_draw_filter_default(struct uiList *ui_list,
+ struct bContext *UNUSED(C),
+ struct uiLayout *layout)
{
- PointerRNA listptr;
- uiLayout *row, *subrow;
-
- RNA_pointer_create(NULL, &RNA_UIList, ui_list, &listptr);
-
- row = uiLayoutRow(layout, false);
-
- subrow = uiLayoutRow(row, true);
- uiItemR(subrow, &listptr, "filter_name", 0, "", ICON_NONE);
- uiItemR(subrow, &listptr, "use_filter_invert", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "",
- (ui_list->filter_flag & UILST_FLT_EXCLUDE) ? ICON_ZOOM_OUT : ICON_ZOOM_IN);
-
- if ((ui_list->filter_sort_flag & UILST_FLT_SORT_LOCK) == 0) {
- subrow = uiLayoutRow(row, true);
- uiItemR(subrow, &listptr, "use_filter_sort_alpha", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
- uiItemR(subrow, &listptr, "use_filter_sort_reverse", UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY, "",
- (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC);
- }
+ PointerRNA listptr;
+ uiLayout *row, *subrow;
+
+ RNA_pointer_create(NULL, &RNA_UIList, ui_list, &listptr);
+
+ row = uiLayoutRow(layout, false);
+
+ subrow = uiLayoutRow(row, true);
+ uiItemR(subrow, &listptr, "filter_name", 0, "", ICON_NONE);
+ uiItemR(subrow,
+ &listptr,
+ "use_filter_invert",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ (ui_list->filter_flag & UILST_FLT_EXCLUDE) ? ICON_ZOOM_OUT : ICON_ZOOM_IN);
+
+ if ((ui_list->filter_sort_flag & UILST_FLT_SORT_LOCK) == 0) {
+ subrow = uiLayoutRow(row, true);
+ uiItemR(subrow,
+ &listptr,
+ "use_filter_sort_alpha",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ ICON_NONE);
+ uiItemR(subrow,
+ &listptr,
+ "use_filter_sort_reverse",
+ UI_ITEM_R_TOGGLE | UI_ITEM_R_ICON_ONLY,
+ "",
+ (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) ? ICON_SORT_DESC : ICON_SORT_ASC);
+ }
}
typedef struct {
- char name[MAX_IDPROP_NAME];
- int org_idx;
+ char name[MAX_IDPROP_NAME];
+ int org_idx;
} StringCmp;
static int cmpstringp(const void *p1, const void *p2)
{
- /* Case-insensitive comparison. */
- return BLI_strcasecmp(((StringCmp *) p1)->name, ((StringCmp *) p2)->name);
+ /* Case-insensitive comparison. */
+ return BLI_strcasecmp(((StringCmp *)p1)->name, ((StringCmp *)p2)->name);
}
-static void uilist_filter_items_default(
- struct uiList *ui_list, struct bContext *UNUSED(C), struct PointerRNA *dataptr,
- const char *propname)
+static void uilist_filter_items_default(struct uiList *ui_list,
+ struct bContext *UNUSED(C),
+ struct PointerRNA *dataptr,
+ const char *propname)
{
- uiListDyn *dyn_data = ui_list->dyn_data;
- PropertyRNA *prop = RNA_struct_find_property(dataptr, propname);
-
- const char *filter_raw = ui_list->filter_byname;
- char *filter = (char *)filter_raw, filter_buff[32], *filter_dyn = NULL;
- const bool filter_exclude = (ui_list->filter_flag & UILST_FLT_EXCLUDE) != 0;
- const bool order_by_name = (ui_list->filter_sort_flag & UILST_FLT_SORT_MASK) == UILST_FLT_SORT_ALPHA;
- int len = RNA_property_collection_length(dataptr, prop);
-
- dyn_data->items_shown = dyn_data->items_len = len;
-
- if (len && (order_by_name || filter_raw[0])) {
- StringCmp *names = NULL;
- int order_idx = 0, i = 0;
-
- if (order_by_name) {
- names = MEM_callocN(sizeof(StringCmp) * len, "StringCmp");
- }
- if (filter_raw[0]) {
- size_t slen = strlen(filter_raw);
-
- dyn_data->items_filter_flags = MEM_callocN(sizeof(int) * len, "items_filter_flags");
- dyn_data->items_shown = 0;
-
- /* Implicitly add heading/trailing wildcards if needed. */
- if (slen + 3 <= sizeof(filter_buff)) {
- filter = filter_buff;
- }
- else {
- filter = filter_dyn = MEM_mallocN((slen + 3) * sizeof(char), "filter_dyn");
- }
- BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 3);
- }
-
- RNA_PROP_BEGIN (dataptr, itemptr, prop)
- {
- char *namebuf;
- const char *name;
- bool do_order = false;
-
- namebuf = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL);
- name = namebuf ? namebuf : "";
-
- if (filter[0]) {
- /* Case-insensitive! */
- if (fnmatch(filter, name, FNM_CASEFOLD) == 0) {
- dyn_data->items_filter_flags[i] = UILST_FLT_ITEM;
- if (!filter_exclude) {
- dyn_data->items_shown++;
- do_order = order_by_name;
- }
- //printf("%s: '%s' matches '%s'\n", __func__, name, filter);
- }
- else if (filter_exclude) {
- dyn_data->items_shown++;
- do_order = order_by_name;
- }
- }
- else {
- do_order = order_by_name;
- }
-
- if (do_order) {
- names[order_idx].org_idx = order_idx;
- BLI_strncpy(names[order_idx++].name, name, MAX_IDPROP_NAME);
- }
-
- /* free name */
- if (namebuf) {
- MEM_freeN(namebuf);
- }
- i++;
- }
- RNA_PROP_END;
-
- if (order_by_name) {
- int new_idx;
- /* note: order_idx equals either to ui_list->items_len if no filtering done,
- * or to ui_list->items_shown if filter is enabled,
- * or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded.
- * This way, we only sort items we actually intend to draw!
- */
- qsort(names, order_idx, sizeof(StringCmp), cmpstringp);
-
- dyn_data->items_filter_neworder = MEM_mallocN(sizeof(int) * order_idx, "items_filter_neworder");
- for (new_idx = 0; new_idx < order_idx; new_idx++) {
- dyn_data->items_filter_neworder[names[new_idx].org_idx] = new_idx;
- }
- }
-
- if (filter_dyn) {
- MEM_freeN(filter_dyn);
- }
- if (names) {
- MEM_freeN(names);
- }
- }
+ uiListDyn *dyn_data = ui_list->dyn_data;
+ PropertyRNA *prop = RNA_struct_find_property(dataptr, propname);
+
+ const char *filter_raw = ui_list->filter_byname;
+ char *filter = (char *)filter_raw, filter_buff[32], *filter_dyn = NULL;
+ const bool filter_exclude = (ui_list->filter_flag & UILST_FLT_EXCLUDE) != 0;
+ const bool order_by_name = (ui_list->filter_sort_flag & UILST_FLT_SORT_MASK) ==
+ UILST_FLT_SORT_ALPHA;
+ int len = RNA_property_collection_length(dataptr, prop);
+
+ dyn_data->items_shown = dyn_data->items_len = len;
+
+ if (len && (order_by_name || filter_raw[0])) {
+ StringCmp *names = NULL;
+ int order_idx = 0, i = 0;
+
+ if (order_by_name) {
+ names = MEM_callocN(sizeof(StringCmp) * len, "StringCmp");
+ }
+ if (filter_raw[0]) {
+ size_t slen = strlen(filter_raw);
+
+ dyn_data->items_filter_flags = MEM_callocN(sizeof(int) * len, "items_filter_flags");
+ dyn_data->items_shown = 0;
+
+ /* Implicitly add heading/trailing wildcards if needed. */
+ if (slen + 3 <= sizeof(filter_buff)) {
+ filter = filter_buff;
+ }
+ else {
+ filter = filter_dyn = MEM_mallocN((slen + 3) * sizeof(char), "filter_dyn");
+ }
+ BLI_strncpy_ensure_pad(filter, filter_raw, '*', slen + 3);
+ }
+
+ RNA_PROP_BEGIN (dataptr, itemptr, prop) {
+ char *namebuf;
+ const char *name;
+ bool do_order = false;
+
+ namebuf = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL);
+ name = namebuf ? namebuf : "";
+
+ if (filter[0]) {
+ /* Case-insensitive! */
+ if (fnmatch(filter, name, FNM_CASEFOLD) == 0) {
+ dyn_data->items_filter_flags[i] = UILST_FLT_ITEM;
+ if (!filter_exclude) {
+ dyn_data->items_shown++;
+ do_order = order_by_name;
+ }
+ //printf("%s: '%s' matches '%s'\n", __func__, name, filter);
+ }
+ else if (filter_exclude) {
+ dyn_data->items_shown++;
+ do_order = order_by_name;
+ }
+ }
+ else {
+ do_order = order_by_name;
+ }
+
+ if (do_order) {
+ names[order_idx].org_idx = order_idx;
+ BLI_strncpy(names[order_idx++].name, name, MAX_IDPROP_NAME);
+ }
+
+ /* free name */
+ if (namebuf) {
+ MEM_freeN(namebuf);
+ }
+ i++;
+ }
+ RNA_PROP_END;
+
+ if (order_by_name) {
+ int new_idx;
+ /* note: order_idx equals either to ui_list->items_len if no filtering done,
+ * or to ui_list->items_shown if filter is enabled,
+ * or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded.
+ * This way, we only sort items we actually intend to draw!
+ */
+ qsort(names, order_idx, sizeof(StringCmp), cmpstringp);
+
+ dyn_data->items_filter_neworder = MEM_mallocN(sizeof(int) * order_idx,
+ "items_filter_neworder");
+ for (new_idx = 0; new_idx < order_idx; new_idx++) {
+ dyn_data->items_filter_neworder[names[new_idx].org_idx] = new_idx;
+ }
+ }
+
+ if (filter_dyn) {
+ MEM_freeN(filter_dyn);
+ }
+ if (names) {
+ MEM_freeN(names);
+ }
+ }
}
typedef struct {
- PointerRNA item;
- int org_idx;
- int flt_flag;
+ PointerRNA item;
+ int org_idx;
+ int flt_flag;
} _uilist_item;
typedef struct {
- int visual_items; /* Visual number of items (i.e. number of items we have room to display). */
- int start_idx; /* Index of first item to display. */
- int end_idx; /* Index of last item to display + 1. */
+ int visual_items; /* Visual number of items (i.e. number of items we have room to display). */
+ int start_idx; /* Index of first item to display. */
+ int end_idx; /* Index of last item to display + 1. */
} uiListLayoutdata;
-static void uilist_prepare(
- uiList *ui_list, int len, int activei, int rows, int maxrows, int columns,
- uiListLayoutdata *layoutdata)
+static void uilist_prepare(uiList *ui_list,
+ int len,
+ int activei,
+ int rows,
+ int maxrows,
+ int columns,
+ uiListLayoutdata *layoutdata)
{
- uiListDyn *dyn_data = ui_list->dyn_data;
- int activei_row, max_scroll;
- const bool use_auto_size = (ui_list->list_grip < (rows - UI_LIST_AUTO_SIZE_THRESHOLD));
-
- /* default rows */
- if (rows <= 0) {
- rows = 5;
- }
- dyn_data->visual_height_min = rows;
- if (maxrows < rows) {
- maxrows = max_ii(rows, 5);
- }
- if (columns <= 0) {
- columns = 9;
- }
-
- if (columns > 1) {
- dyn_data->height = (int)ceil((double)len / (double)columns);
- activei_row = (int)floor((double)activei / (double)columns);
- }
- else {
- dyn_data->height = len;
- activei_row = activei;
- }
-
- if (!use_auto_size) {
- /* No auto-size, yet we clamp at min size! */
- maxrows = rows = max_ii(ui_list->list_grip, rows);
- }
- else if ((rows != maxrows) && (dyn_data->height > rows)) {
- /* Expand size if needed and possible. */
- rows = min_ii(dyn_data->height, maxrows);
- }
-
- /* If list length changes or list is tagged to check this,
- * and active is out of view, scroll to it .*/
- if (ui_list->list_last_len != len || ui_list->flag & UILST_SCROLL_TO_ACTIVE_ITEM) {
- if (activei_row < ui_list->list_scroll) {
- ui_list->list_scroll = activei_row;
- }
- else if (activei_row >= ui_list->list_scroll + rows) {
- ui_list->list_scroll = activei_row - rows + 1;
- }
- ui_list->flag &= ~UILST_SCROLL_TO_ACTIVE_ITEM;
- }
-
- max_scroll = max_ii(0, dyn_data->height - rows);
- CLAMP(ui_list->list_scroll, 0, max_scroll);
- ui_list->list_last_len = len;
- dyn_data->visual_height = rows;
- layoutdata->visual_items = rows * columns;
- layoutdata->start_idx = ui_list->list_scroll * columns;
- layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len);
+ uiListDyn *dyn_data = ui_list->dyn_data;
+ int activei_row, max_scroll;
+ const bool use_auto_size = (ui_list->list_grip < (rows - UI_LIST_AUTO_SIZE_THRESHOLD));
+
+ /* default rows */
+ if (rows <= 0) {
+ rows = 5;
+ }
+ dyn_data->visual_height_min = rows;
+ if (maxrows < rows) {
+ maxrows = max_ii(rows, 5);
+ }
+ if (columns <= 0) {
+ columns = 9;
+ }
+
+ if (columns > 1) {
+ dyn_data->height = (int)ceil((double)len / (double)columns);
+ activei_row = (int)floor((double)activei / (double)columns);
+ }
+ else {
+ dyn_data->height = len;
+ activei_row = activei;
+ }
+
+ if (!use_auto_size) {
+ /* No auto-size, yet we clamp at min size! */
+ maxrows = rows = max_ii(ui_list->list_grip, rows);
+ }
+ else if ((rows != maxrows) && (dyn_data->height > rows)) {
+ /* Expand size if needed and possible. */
+ rows = min_ii(dyn_data->height, maxrows);
+ }
+
+ /* If list length changes or list is tagged to check this,
+ * and active is out of view, scroll to it .*/
+ if (ui_list->list_last_len != len || ui_list->flag & UILST_SCROLL_TO_ACTIVE_ITEM) {
+ if (activei_row < ui_list->list_scroll) {
+ ui_list->list_scroll = activei_row;
+ }
+ else if (activei_row >= ui_list->list_scroll + rows) {
+ ui_list->list_scroll = activei_row - rows + 1;
+ }
+ ui_list->flag &= ~UILST_SCROLL_TO_ACTIVE_ITEM;
+ }
+
+ max_scroll = max_ii(0, dyn_data->height - rows);
+ CLAMP(ui_list->list_scroll, 0, max_scroll);
+ ui_list->list_last_len = len;
+ dyn_data->visual_height = rows;
+ layoutdata->visual_items = rows * columns;
+ layoutdata->start_idx = ui_list->list_scroll * columns;
+ layoutdata->end_idx = min_ii(layoutdata->start_idx + rows * columns, len);
}
static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
{
- uiList *ui_list = arg1;
- uiListDyn *dyn_data = ui_list->dyn_data;
+ uiList *ui_list = arg1;
+ uiListDyn *dyn_data = ui_list->dyn_data;
- /* This way we get diff in number of additional items to show (positive) or hide (negative). */
- const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) / (float)UI_UNIT_Y);
+ /* This way we get diff in number of additional items to show (positive) or hide (negative). */
+ const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) /
+ (float)UI_UNIT_Y);
- if (diff != 0) {
- ui_list->list_grip += diff;
- dyn_data->resize_prev += diff * UI_UNIT_Y;
- ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
- }
+ if (diff != 0) {
+ ui_list->list_grip += diff;
+ dyn_data->resize_prev += diff * UI_UNIT_Y;
+ ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+ }
- /* In case uilist is in popup, we need special refreshing */
- ED_region_tag_refresh_ui(CTX_wm_menu(C));
+ /* In case uilist is in popup, we need special refreshing */
+ ED_region_tag_refresh_ui(CTX_wm_menu(C));
}
static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname)
{
- if (propname && propname[0] && itemptr && itemptr->data) {
- PropertyRNA *prop = RNA_struct_find_property(itemptr, propname);
-
- if (prop && (RNA_property_type(prop) == PROP_STRING)) {
- return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL);
- }
- }
- return NULL;
+ if (propname && propname[0] && itemptr && itemptr->data) {
+ PropertyRNA *prop = RNA_struct_find_property(itemptr, propname);
+
+ if (prop && (RNA_property_type(prop) == PROP_STRING)) {
+ return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL);
+ }
+ }
+ return NULL;
}
static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip)
{
- char *dyn_tooltip = argN;
- return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
+ char *dyn_tooltip = argN;
+ return BLI_sprintfN("%s - %s", tip, dyn_tooltip);
}
-void uiTemplateList(
- uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id,
- PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname,
- const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns,
- bool sort_reverse, bool sort_lock)
+void uiTemplateList(uiLayout *layout,
+ bContext *C,
+ const char *listtype_name,
+ const char *list_id,
+ PointerRNA *dataptr,
+ const char *propname,
+ PointerRNA *active_dataptr,
+ const char *active_propname,
+ const char *item_dyntip_propname,
+ int rows,
+ int maxrows,
+ int layout_type,
+ int columns,
+ bool sort_reverse,
+ bool sort_lock)
{
- uiListType *ui_list_type;
- uiList *ui_list = NULL;
- uiListDyn *dyn_data;
- ARegion *ar;
- uiListDrawItemFunc draw_item;
- uiListDrawFilterFunc draw_filter;
- uiListFilterItemsFunc filter_items;
-
- PropertyRNA *prop = NULL, *activeprop;
- PropertyType type, activetype;
- _uilist_item *items_ptr = NULL;
- StructRNA *ptype;
- uiLayout *glob = NULL, *box, *row, *col, *subrow, *sub, *overlap;
- uiBlock *block, *subblock;
- uiBut *but;
-
- uiListLayoutdata layoutdata;
- char ui_list_id[UI_MAX_NAME_STR];
- char numstr[32];
- int rnaicon = ICON_NONE, icon = ICON_NONE;
- int i = 0, activei = 0;
- int len = 0;
-
- /* validate arguments */
- /* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */
- if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
- RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
- UI_UL_DEFAULT_CLASS_NAME);
- return;
- }
-
- block = uiLayoutGetBlock(layout);
-
- if (!active_dataptr->data) {
- RNA_warning("No active data");
- return;
- }
-
- if (dataptr->data) {
- prop = RNA_struct_find_property(dataptr, propname);
- if (!prop) {
- RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
- return;
- }
- }
-
- activeprop = RNA_struct_find_property(active_dataptr, active_propname);
- if (!activeprop) {
- RNA_warning("Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
- return;
- }
-
- if (prop) {
- type = RNA_property_type(prop);
- if (type != PROP_COLLECTION) {
- RNA_warning("Expected a collection data property");
- return;
- }
- }
-
- activetype = RNA_property_type(activeprop);
- if (activetype != PROP_INT) {
- RNA_warning("Expected an integer active data property");
- return;
- }
-
- /* get icon */
- if (dataptr->data && prop) {
- ptype = RNA_property_pointer_type(dataptr, prop);
- rnaicon = RNA_struct_ui_icon(ptype);
- }
-
- /* get active data */
- activei = RNA_property_int_get(active_dataptr, activeprop);
-
- /* Find the uiList type. */
- ui_list_type = WM_uilisttype_find(listtype_name, false);
-
- if (ui_list_type == NULL) {
- RNA_warning("List type %s not found", listtype_name);
- return;
- }
-
- draw_item = ui_list_type->draw_item ? ui_list_type->draw_item : uilist_draw_item_default;
- draw_filter = ui_list_type->draw_filter ? ui_list_type->draw_filter : uilist_draw_filter_default;
- filter_items = ui_list_type->filter_items ? ui_list_type->filter_items : uilist_filter_items_default;
-
- /* Find or add the uiList to the current Region. */
- /* We tag the list id with the list type... */
- BLI_snprintf(ui_list_id, sizeof(ui_list_id), "%s_%s", ui_list_type->idname, list_id ? list_id : "");
-
- /* Allows to work in popups. */
- ar = CTX_wm_menu(C);
- if (ar == NULL) {
- ar = CTX_wm_region(C);
- }
- ui_list = BLI_findstring(&ar->ui_lists, ui_list_id, offsetof(uiList, list_id));
-
- if (!ui_list) {
- ui_list = MEM_callocN(sizeof(uiList), "uiList");
- BLI_strncpy(ui_list->list_id, ui_list_id, sizeof(ui_list->list_id));
- BLI_addtail(&ar->ui_lists, ui_list);
- ui_list->list_grip = -UI_LIST_AUTO_SIZE_THRESHOLD; /* Force auto size by default. */
- if (sort_reverse) {
- ui_list->filter_sort_flag |= UILST_FLT_SORT_REVERSE;
- }
- if (sort_lock) {
- ui_list->filter_sort_flag |= UILST_FLT_SORT_LOCK;
- }
- }
-
- if (!ui_list->dyn_data) {
- ui_list->dyn_data = MEM_callocN(sizeof(uiListDyn), "uiList.dyn_data");
- }
- dyn_data = ui_list->dyn_data;
-
- /* Because we can't actually pass type across save&load... */
- ui_list->type = ui_list_type;
- ui_list->layout_type = layout_type;
-
- /* Reset filtering data. */
- MEM_SAFE_FREE(dyn_data->items_filter_flags);
- MEM_SAFE_FREE(dyn_data->items_filter_neworder);
- dyn_data->items_len = dyn_data->items_shown = -1;
-
- /* When active item changed since last draw, scroll to it. */
- if (activei != ui_list->list_last_activei) {
- ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
- ui_list->list_last_activei = activei;
- }
-
- /* Filter list items! (not for compact layout, though) */
- if (dataptr->data && prop) {
- const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
- const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0;
- int items_shown, idx = 0;
+ uiListType *ui_list_type;
+ uiList *ui_list = NULL;
+ uiListDyn *dyn_data;
+ ARegion *ar;
+ uiListDrawItemFunc draw_item;
+ uiListDrawFilterFunc draw_filter;
+ uiListFilterItemsFunc filter_items;
+
+ PropertyRNA *prop = NULL, *activeprop;
+ PropertyType type, activetype;
+ _uilist_item *items_ptr = NULL;
+ StructRNA *ptype;
+ uiLayout *glob = NULL, *box, *row, *col, *subrow, *sub, *overlap;
+ uiBlock *block, *subblock;
+ uiBut *but;
+
+ uiListLayoutdata layoutdata;
+ char ui_list_id[UI_MAX_NAME_STR];
+ char numstr[32];
+ int rnaicon = ICON_NONE, icon = ICON_NONE;
+ int i = 0, activei = 0;
+ int len = 0;
+
+ /* validate arguments */
+ /* Forbid default UI_UL_DEFAULT_CLASS_NAME list class without a custom list_id! */
+ if (STREQ(UI_UL_DEFAULT_CLASS_NAME, listtype_name) && !(list_id && list_id[0])) {
+ RNA_warning("template_list using default '%s' UIList class must provide a custom list_id",
+ UI_UL_DEFAULT_CLASS_NAME);
+ return;
+ }
+
+ block = uiLayoutGetBlock(layout);
+
+ if (!active_dataptr->data) {
+ RNA_warning("No active data");
+ return;
+ }
+
+ if (dataptr->data) {
+ prop = RNA_struct_find_property(dataptr, propname);
+ if (!prop) {
+ RNA_warning("Property not found: %s.%s", RNA_struct_identifier(dataptr->type), propname);
+ return;
+ }
+ }
+
+ activeprop = RNA_struct_find_property(active_dataptr, active_propname);
+ if (!activeprop) {
+ RNA_warning(
+ "Property not found: %s.%s", RNA_struct_identifier(active_dataptr->type), active_propname);
+ return;
+ }
+
+ if (prop) {
+ type = RNA_property_type(prop);
+ if (type != PROP_COLLECTION) {
+ RNA_warning("Expected a collection data property");
+ return;
+ }
+ }
+
+ activetype = RNA_property_type(activeprop);
+ if (activetype != PROP_INT) {
+ RNA_warning("Expected an integer active data property");
+ return;
+ }
+
+ /* get icon */
+ if (dataptr->data && prop) {
+ ptype = RNA_property_pointer_type(dataptr, prop);
+ rnaicon = RNA_struct_ui_icon(ptype);
+ }
+
+ /* get active data */
+ activei = RNA_property_int_get(active_dataptr, activeprop);
+
+ /* Find the uiList type. */
+ ui_list_type = WM_uilisttype_find(listtype_name, false);
+
+ if (ui_list_type == NULL) {
+ RNA_warning("List type %s not found", listtype_name);
+ return;
+ }
+
+ draw_item = ui_list_type->draw_item ? ui_list_type->draw_item : uilist_draw_item_default;
+ draw_filter = ui_list_type->draw_filter ? ui_list_type->draw_filter : uilist_draw_filter_default;
+ filter_items = ui_list_type->filter_items ? ui_list_type->filter_items :
+ uilist_filter_items_default;
+
+ /* Find or add the uiList to the current Region. */
+ /* We tag the list id with the list type... */
+ BLI_snprintf(
+ ui_list_id, sizeof(ui_list_id), "%s_%s", ui_list_type->idname, list_id ? list_id : "");
+
+ /* Allows to work in popups. */
+ ar = CTX_wm_menu(C);
+ if (ar == NULL) {
+ ar = CTX_wm_region(C);
+ }
+ ui_list = BLI_findstring(&ar->ui_lists, ui_list_id, offsetof(uiList, list_id));
+
+ if (!ui_list) {
+ ui_list = MEM_callocN(sizeof(uiList), "uiList");
+ BLI_strncpy(ui_list->list_id, ui_list_id, sizeof(ui_list->list_id));
+ BLI_addtail(&ar->ui_lists, ui_list);
+ ui_list->list_grip = -UI_LIST_AUTO_SIZE_THRESHOLD; /* Force auto size by default. */
+ if (sort_reverse) {
+ ui_list->filter_sort_flag |= UILST_FLT_SORT_REVERSE;
+ }
+ if (sort_lock) {
+ ui_list->filter_sort_flag |= UILST_FLT_SORT_LOCK;
+ }
+ }
+
+ if (!ui_list->dyn_data) {
+ ui_list->dyn_data = MEM_callocN(sizeof(uiListDyn), "uiList.dyn_data");
+ }
+ dyn_data = ui_list->dyn_data;
+
+ /* Because we can't actually pass type across save&load... */
+ ui_list->type = ui_list_type;
+ ui_list->layout_type = layout_type;
+
+ /* Reset filtering data. */
+ MEM_SAFE_FREE(dyn_data->items_filter_flags);
+ MEM_SAFE_FREE(dyn_data->items_filter_neworder);
+ dyn_data->items_len = dyn_data->items_shown = -1;
+
+ /* When active item changed since last draw, scroll to it. */
+ if (activei != ui_list->list_last_activei) {
+ ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM;
+ ui_list->list_last_activei = activei;
+ }
+
+ /* Filter list items! (not for compact layout, though) */
+ if (dataptr->data && prop) {
+ const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE;
+ const bool order_reverse = (ui_list->filter_sort_flag & UILST_FLT_SORT_REVERSE) != 0;
+ int items_shown, idx = 0;
#if 0
- int prev_ii = -1, prev_i;
+ int prev_ii = -1, prev_i;
#endif
- if (layout_type == UILST_LAYOUT_COMPACT) {
- dyn_data->items_len = dyn_data->items_shown = RNA_property_collection_length(dataptr, prop);
- }
- else {
- //printf("%s: filtering...\n", __func__);
- filter_items(ui_list, C, dataptr, propname);
- //printf("%s: filtering done.\n", __func__);
- }
-
- items_shown = dyn_data->items_shown;
- if (items_shown >= 0) {
- bool activei_mapping_pending = true;
- items_ptr = MEM_mallocN(sizeof(_uilist_item) * items_shown, __func__);
- //printf("%s: items shown: %d.\n", __func__, items_shown);
- RNA_PROP_BEGIN (dataptr, itemptr, prop)
- {
- if (!dyn_data->items_filter_flags ||
- ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude))
- {
- int ii;
- if (dyn_data->items_filter_neworder) {
- ii = dyn_data->items_filter_neworder[idx++];
- ii = order_reverse ? items_shown - ii - 1 : ii;
- }
- else {
- ii = order_reverse ? items_shown - ++idx : idx++;
- }
- //printf("%s: ii: %d\n", __func__, ii);
- items_ptr[ii].item = itemptr;
- items_ptr[ii].org_idx = i;
- items_ptr[ii].flt_flag = dyn_data->items_filter_flags ? dyn_data->items_filter_flags[i] : 0;
-
- if (activei_mapping_pending && activei == i) {
- activei = ii;
- /* So that we do not map again activei! */
- activei_mapping_pending = false;
- }
+ if (layout_type == UILST_LAYOUT_COMPACT) {
+ dyn_data->items_len = dyn_data->items_shown = RNA_property_collection_length(dataptr, prop);
+ }
+ else {
+ //printf("%s: filtering...\n", __func__);
+ filter_items(ui_list, C, dataptr, propname);
+ //printf("%s: filtering done.\n", __func__);
+ }
+
+ items_shown = dyn_data->items_shown;
+ if (items_shown >= 0) {
+ bool activei_mapping_pending = true;
+ items_ptr = MEM_mallocN(sizeof(_uilist_item) * items_shown, __func__);
+ //printf("%s: items shown: %d.\n", __func__, items_shown);
+ RNA_PROP_BEGIN (dataptr, itemptr, prop) {
+ if (!dyn_data->items_filter_flags ||
+ ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)) {
+ int ii;
+ if (dyn_data->items_filter_neworder) {
+ ii = dyn_data->items_filter_neworder[idx++];
+ ii = order_reverse ? items_shown - ii - 1 : ii;
+ }
+ else {
+ ii = order_reverse ? items_shown - ++idx : idx++;
+ }
+ //printf("%s: ii: %d\n", __func__, ii);
+ items_ptr[ii].item = itemptr;
+ items_ptr[ii].org_idx = i;
+ items_ptr[ii].flt_flag = dyn_data->items_filter_flags ? dyn_data->items_filter_flags[i] :
+ 0;
+
+ if (activei_mapping_pending && activei == i) {
+ activei = ii;
+ /* So that we do not map again activei! */
+ activei_mapping_pending = false;
+ }
#if 0 /* For now, do not alter active element, even if it will be hidden... */
- else if (activei < i) {
- /* We do not want an active but invisible item!
- * Only exception is when all items are filtered out...
- */
- if (prev_ii >= 0) {
- activei = prev_ii;
- RNA_property_int_set(active_dataptr, activeprop, prev_i);
- }
- else {
- activei = ii;
- RNA_property_int_set(active_dataptr, activeprop, i);
- }
- }
- prev_i = i;
- prev_ii = ii;
+ else if (activei < i) {
+ /* We do not want an active but invisible item!
+ * Only exception is when all items are filtered out...
+ */
+ if (prev_ii >= 0) {
+ activei = prev_ii;
+ RNA_property_int_set(active_dataptr, activeprop, prev_i);
+ }
+ else {
+ activei = ii;
+ RNA_property_int_set(active_dataptr, activeprop, i);
+ }
+ }
+ prev_i = i;
+ prev_ii = ii;
#endif
- }
- i++;
- }
- RNA_PROP_END;
-
- if (activei_mapping_pending) {
- /* No active item found, set to 'invalid' -1 value... */
- activei = -1;
- }
- }
- if (dyn_data->items_shown >= 0) {
- len = dyn_data->items_shown;
- }
- else {
- len = dyn_data->items_len;
- }
- }
-
- switch (layout_type) {
- case UILST_LAYOUT_DEFAULT:
- /* layout */
- box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
- glob = uiLayoutColumn(box, true);
- row = uiLayoutRow(glob, false);
- col = uiLayoutColumn(row, true);
-
- /* init numbers */
- uilist_prepare(ui_list, len, activei, rows, maxrows, 1, &layoutdata);
-
- if (dataptr->data && prop) {
- /* create list items */
- for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
- PointerRNA *itemptr = &items_ptr[i].item;
- void *dyntip_data;
- int org_i = items_ptr[i].org_idx;
- int flt_flag = items_ptr[i].flt_flag;
- subblock = uiLayoutGetBlock(col);
-
- overlap = uiLayoutOverlap(col);
-
- UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
-
- /* list item behind label & other buttons */
- sub = uiLayoutRow(overlap, false);
-
- but = uiDefButR_prop(
- subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- active_dataptr, activeprop, 0, 0, org_i, 0, 0,
- TIP_("Double click to rename"));
- if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) {
- UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data);
- }
-
- sub = uiLayoutRow(overlap, false);
-
- icon = UI_rnaptr_icon_get(C, itemptr, rnaicon, false);
- if (icon == ICON_DOT) {
- icon = ICON_NONE;
- }
- draw_item(ui_list, C, sub, dataptr, itemptr, icon, active_dataptr, active_propname,
- org_i, flt_flag);
-
- /* If we are "drawing" active item, set all labels as active. */
- if (i == activei) {
- ui_layout_list_set_labels_active(sub);
- }
-
- UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
- }
- }
-
- /* add dummy buttons to fill space */
- for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
- uiItemL(col, "", ICON_NONE);
- }
-
- /* add scrollbar */
- if (len > layoutdata.visual_items) {
- col = uiLayoutColumn(row, false);
- uiDefButI(block, UI_BTYPE_SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height,
- &ui_list->list_scroll, 0, dyn_data->height - dyn_data->visual_height,
- dyn_data->visual_height, 0, "");
- }
- break;
- case UILST_LAYOUT_COMPACT:
- row = uiLayoutRow(layout, true);
-
- if ((dataptr->data && prop) && (dyn_data->items_shown > 0) &&
- (activei >= 0) && (activei < dyn_data->items_shown))
- {
- PointerRNA *itemptr = &items_ptr[activei].item;
- int org_i = items_ptr[activei].org_idx;
-
- icon = UI_rnaptr_icon_get(C, itemptr, rnaicon, false);
- if (icon == ICON_DOT) {
- icon = ICON_NONE;
- }
- draw_item(ui_list, C, row, dataptr, itemptr, icon, active_dataptr, active_propname, org_i, 0);
- }
- /* if list is empty, add in dummy button */
- else {
- uiItemL(row, "", ICON_NONE);
- }
-
- /* next/prev button */
- BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown);
- but = uiDefIconTextButR_prop(
- block, UI_BTYPE_NUM, 0, 0, numstr, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y,
- active_dataptr, activeprop, 0, 0, 0, 0, 0, "");
- if (dyn_data->items_shown == 0) {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
- break;
- case UILST_LAYOUT_GRID:
- box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
- glob = uiLayoutColumn(box, true);
- row = uiLayoutRow(glob, false);
- col = uiLayoutColumn(row, true);
- subrow = NULL; /* Quite gcc warning! */
-
- uilist_prepare(ui_list, len, activei, rows, maxrows, columns, &layoutdata);
-
- if (dataptr->data && prop) {
- /* create list items */
- for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
- PointerRNA *itemptr = &items_ptr[i].item;
- int org_i = items_ptr[i].org_idx;
- int flt_flag = items_ptr[i].flt_flag;
-
- /* create button */
- if (!(i % columns)) {
- subrow = uiLayoutRow(col, false);
- }
-
- subblock = uiLayoutGetBlock(subrow);
- overlap = uiLayoutOverlap(subrow);
-
- UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
-
- /* list item behind label & other buttons */
- sub = uiLayoutRow(overlap, false);
-
- but = uiDefButR_prop(subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y,
- active_dataptr, activeprop, 0, 0, org_i, 0, 0, NULL);
- UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP);
-
- sub = uiLayoutRow(overlap, false);
-
- icon = UI_rnaptr_icon_get(C, itemptr, rnaicon, false);
- draw_item(ui_list, C, sub, dataptr, itemptr, icon, active_dataptr, active_propname,
- org_i, flt_flag);
-
- /* If we are "drawing" active item, set all labels as active. */
- if (i == activei) {
- ui_layout_list_set_labels_active(sub);
- }
-
- UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
- }
- }
-
- /* add dummy buttons to fill space */
- for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
- if (!(i % columns)) {
- subrow = uiLayoutRow(col, false);
- }
- uiItemL(subrow, "", ICON_NONE);
- }
-
- /* add scrollbar */
- if (len > layoutdata.visual_items) {
- /* col = */ uiLayoutColumn(row, false);
- uiDefButI(block, UI_BTYPE_SCROLL, 0, "", 0, 0, UI_UNIT_X * 0.75, UI_UNIT_Y * dyn_data->visual_height,
- &ui_list->list_scroll, 0, dyn_data->height - dyn_data->visual_height,
- dyn_data->visual_height, 0, "");
- }
- break;
- }
-
- if (glob) {
- /* About UI_BTYPE_GRIP drag-resize:
- * We can't directly use results from a grip button, since we have a rather complex behavior here
- * (sizing by discrete steps and, overall, autosize feature).
- * Since we *never* know whether we are grip-resizing or not (because there is no callback for when a
- * button enters/leaves its "edit mode"), we use the fact that grip-controlled value (dyn_data->resize)
- * is completely handled by the grip during the grab resize, so settings its value here has no effect
- * at all.
- * It is only meaningful when we are not resizing, in which case this gives us the correct "init drag" value.
- * Note we cannot affect dyn_data->resize_prev here, since this value is not controlled by the grip!
- */
- dyn_data->resize = dyn_data->resize_prev + (dyn_data->visual_height - ui_list->list_grip) * UI_UNIT_Y;
-
- row = uiLayoutRow(glob, true);
- subblock = uiLayoutGetBlock(row);
- UI_block_emboss_set(subblock, UI_EMBOSS_NONE);
-
- if (ui_list->filter_flag & UILST_FLT_SHOW) {
- but = uiDefIconButBitI(subblock, UI_BTYPE_TOGGLE, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_DOWN, 0, 0,
- UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0,
- TIP_("Hide filtering options"));
- UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
-
- but = uiDefIconButI(subblock, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
- &dyn_data->resize, 0.0, 0.0, 0, 0, "");
- UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
-
- UI_block_emboss_set(subblock, UI_EMBOSS);
-
- col = uiLayoutColumn(glob, false);
- subblock = uiLayoutGetBlock(col);
- uiDefBut(subblock, UI_BTYPE_SEPR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y * 0.05f, NULL, 0.0, 0.0, 0, 0, "");
-
- draw_filter(ui_list, C, col);
- }
- else {
- but = uiDefIconButBitI(subblock, UI_BTYPE_TOGGLE, UILST_FLT_SHOW, 0, ICON_DISCLOSURE_TRI_RIGHT, 0, 0,
- UI_UNIT_X, UI_UNIT_Y * 0.5f, &(ui_list->filter_flag), 0, 0, 0, 0,
- TIP_("Show filtering options"));
- UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
-
- but = uiDefIconButI(subblock, UI_BTYPE_GRIP, 0, ICON_GRIP, 0, 0, UI_UNIT_X * 10.0f, UI_UNIT_Y * 0.5f,
- &dyn_data->resize, 0.0, 0.0, 0, 0, "");
- UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
-
- UI_block_emboss_set(subblock, UI_EMBOSS);
- }
- }
-
- if (items_ptr) {
- MEM_freeN(items_ptr);
- }
+ }
+ i++;
+ }
+ RNA_PROP_END;
+
+ if (activei_mapping_pending) {
+ /* No active item found, set to 'invalid' -1 value... */
+ activei = -1;
+ }
+ }
+ if (dyn_data->items_shown >= 0) {
+ len = dyn_data->items_shown;
+ }
+ else {
+ len = dyn_data->items_len;
+ }
+ }
+
+ switch (layout_type) {
+ case UILST_LAYOUT_DEFAULT:
+ /* layout */
+ box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ glob = uiLayoutColumn(box, true);
+ row = uiLayoutRow(glob, false);
+ col = uiLayoutColumn(row, true);
+
+ /* init numbers */
+ uilist_prepare(ui_list, len, activei, rows, maxrows, 1, &layoutdata);
+
+ if (dataptr->data && prop) {
+ /* create list items */
+ for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
+ PointerRNA *itemptr = &items_ptr[i].item;
+ void *dyntip_data;
+ int org_i = items_ptr[i].org_idx;
+ int flt_flag = items_ptr[i].flt_flag;
+ subblock = uiLayoutGetBlock(col);
+
+ overlap = uiLayoutOverlap(col);
+
+ UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
+
+ /* list item behind label & other buttons */
+ sub = uiLayoutRow(overlap, false);
+
+ but = uiDefButR_prop(subblock,
+ UI_BTYPE_LISTROW,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ active_dataptr,
+ activeprop,
+ 0,
+ 0,
+ org_i,
+ 0,
+ 0,
+ TIP_("Double click to rename"));
+ if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) {
+ UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data);
+ }
+
+ sub = uiLayoutRow(overlap, false);
+
+ icon = UI_rnaptr_icon_get(C, itemptr, rnaicon, false);
+ if (icon == ICON_DOT) {
+ icon = ICON_NONE;
+ }
+ draw_item(ui_list,
+ C,
+ sub,
+ dataptr,
+ itemptr,
+ icon,
+ active_dataptr,
+ active_propname,
+ org_i,
+ flt_flag);
+
+ /* If we are "drawing" active item, set all labels as active. */
+ if (i == activei) {
+ ui_layout_list_set_labels_active(sub);
+ }
+
+ UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
+ }
+ }
+
+ /* add dummy buttons to fill space */
+ for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
+ uiItemL(col, "", ICON_NONE);
+ }
+
+ /* add scrollbar */
+ if (len > layoutdata.visual_items) {
+ col = uiLayoutColumn(row, false);
+ uiDefButI(block,
+ UI_BTYPE_SCROLL,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * 0.75,
+ UI_UNIT_Y * dyn_data->visual_height,
+ &ui_list->list_scroll,
+ 0,
+ dyn_data->height - dyn_data->visual_height,
+ dyn_data->visual_height,
+ 0,
+ "");
+ }
+ break;
+ case UILST_LAYOUT_COMPACT:
+ row = uiLayoutRow(layout, true);
+
+ if ((dataptr->data && prop) && (dyn_data->items_shown > 0) && (activei >= 0) &&
+ (activei < dyn_data->items_shown)) {
+ PointerRNA *itemptr = &items_ptr[activei].item;
+ int org_i = items_ptr[activei].org_idx;
+
+ icon = UI_rnaptr_icon_get(C, itemptr, rnaicon, false);
+ if (icon == ICON_DOT) {
+ icon = ICON_NONE;
+ }
+ draw_item(
+ ui_list, C, row, dataptr, itemptr, icon, active_dataptr, active_propname, org_i, 0);
+ }
+ /* if list is empty, add in dummy button */
+ else {
+ uiItemL(row, "", ICON_NONE);
+ }
+
+ /* next/prev button */
+ BLI_snprintf(numstr, sizeof(numstr), "%d :", dyn_data->items_shown);
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_NUM,
+ 0,
+ 0,
+ numstr,
+ 0,
+ 0,
+ UI_UNIT_X * 5,
+ UI_UNIT_Y,
+ active_dataptr,
+ activeprop,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+ if (dyn_data->items_shown == 0) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
+ break;
+ case UILST_LAYOUT_GRID:
+ box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ glob = uiLayoutColumn(box, true);
+ row = uiLayoutRow(glob, false);
+ col = uiLayoutColumn(row, true);
+ subrow = NULL; /* Quite gcc warning! */
+
+ uilist_prepare(ui_list, len, activei, rows, maxrows, columns, &layoutdata);
+
+ if (dataptr->data && prop) {
+ /* create list items */
+ for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) {
+ PointerRNA *itemptr = &items_ptr[i].item;
+ int org_i = items_ptr[i].org_idx;
+ int flt_flag = items_ptr[i].flt_flag;
+
+ /* create button */
+ if (!(i % columns)) {
+ subrow = uiLayoutRow(col, false);
+ }
+
+ subblock = uiLayoutGetBlock(subrow);
+ overlap = uiLayoutOverlap(subrow);
+
+ UI_block_flag_enable(subblock, UI_BLOCK_LIST_ITEM);
+
+ /* list item behind label & other buttons */
+ sub = uiLayoutRow(overlap, false);
+
+ but = uiDefButR_prop(subblock,
+ UI_BTYPE_LISTROW,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * 10,
+ UI_UNIT_Y,
+ active_dataptr,
+ activeprop,
+ 0,
+ 0,
+ org_i,
+ 0,
+ 0,
+ NULL);
+ UI_but_drawflag_enable(but, UI_BUT_NO_TOOLTIP);
+
+ sub = uiLayoutRow(overlap, false);
+
+ icon = UI_rnaptr_icon_get(C, itemptr, rnaicon, false);
+ draw_item(ui_list,
+ C,
+ sub,
+ dataptr,
+ itemptr,
+ icon,
+ active_dataptr,
+ active_propname,
+ org_i,
+ flt_flag);
+
+ /* If we are "drawing" active item, set all labels as active. */
+ if (i == activei) {
+ ui_layout_list_set_labels_active(sub);
+ }
+
+ UI_block_flag_disable(subblock, UI_BLOCK_LIST_ITEM);
+ }
+ }
+
+ /* add dummy buttons to fill space */
+ for (; i < layoutdata.start_idx + layoutdata.visual_items; i++) {
+ if (!(i % columns)) {
+ subrow = uiLayoutRow(col, false);
+ }
+ uiItemL(subrow, "", ICON_NONE);
+ }
+
+ /* add scrollbar */
+ if (len > layoutdata.visual_items) {
+ /* col = */ uiLayoutColumn(row, false);
+ uiDefButI(block,
+ UI_BTYPE_SCROLL,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X * 0.75,
+ UI_UNIT_Y * dyn_data->visual_height,
+ &ui_list->list_scroll,
+ 0,
+ dyn_data->height - dyn_data->visual_height,
+ dyn_data->visual_height,
+ 0,
+ "");
+ }
+ break;
+ }
+
+ if (glob) {
+ /* About UI_BTYPE_GRIP drag-resize:
+ * We can't directly use results from a grip button, since we have a rather complex behavior here
+ * (sizing by discrete steps and, overall, autosize feature).
+ * Since we *never* know whether we are grip-resizing or not (because there is no callback for when a
+ * button enters/leaves its "edit mode"), we use the fact that grip-controlled value (dyn_data->resize)
+ * is completely handled by the grip during the grab resize, so settings its value here has no effect
+ * at all.
+ * It is only meaningful when we are not resizing, in which case this gives us the correct "init drag" value.
+ * Note we cannot affect dyn_data->resize_prev here, since this value is not controlled by the grip!
+ */
+ dyn_data->resize = dyn_data->resize_prev +
+ (dyn_data->visual_height - ui_list->list_grip) * UI_UNIT_Y;
+
+ row = uiLayoutRow(glob, true);
+ subblock = uiLayoutGetBlock(row);
+ UI_block_emboss_set(subblock, UI_EMBOSS_NONE);
+
+ if (ui_list->filter_flag & UILST_FLT_SHOW) {
+ but = uiDefIconButBitI(subblock,
+ UI_BTYPE_TOGGLE,
+ UILST_FLT_SHOW,
+ 0,
+ ICON_DISCLOSURE_TRI_DOWN,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y * 0.5f,
+ &(ui_list->filter_flag),
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Hide filtering options"));
+ UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
+
+ but = uiDefIconButI(subblock,
+ UI_BTYPE_GRIP,
+ 0,
+ ICON_GRIP,
+ 0,
+ 0,
+ UI_UNIT_X * 10.0f,
+ UI_UNIT_Y * 0.5f,
+ &dyn_data->resize,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
+
+ UI_block_emboss_set(subblock, UI_EMBOSS);
+
+ col = uiLayoutColumn(glob, false);
+ subblock = uiLayoutGetBlock(col);
+ uiDefBut(subblock,
+ UI_BTYPE_SEPR,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y * 0.05f,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+
+ draw_filter(ui_list, C, col);
+ }
+ else {
+ but = uiDefIconButBitI(subblock,
+ UI_BTYPE_TOGGLE,
+ UILST_FLT_SHOW,
+ 0,
+ ICON_DISCLOSURE_TRI_RIGHT,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y * 0.5f,
+ &(ui_list->filter_flag),
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Show filtering options"));
+ UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
+
+ but = uiDefIconButI(subblock,
+ UI_BTYPE_GRIP,
+ 0,
+ ICON_GRIP,
+ 0,
+ 0,
+ UI_UNIT_X * 10.0f,
+ UI_UNIT_Y * 0.5f,
+ &dyn_data->resize,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ UI_but_func_set(but, uilist_resize_update_cb, ui_list, NULL);
+
+ UI_block_emboss_set(subblock, UI_EMBOSS);
+ }
+ }
+
+ if (items_ptr) {
+ MEM_freeN(items_ptr);
+ }
}
/************************* Operator Search Template **************************/
static void operator_call_cb(bContext *C, void *UNUSED(arg1), void *arg2)
{
- wmOperatorType *ot = arg2;
+ wmOperatorType *ot = arg2;
- if (ot) {
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, NULL);
- }
+ if (ot) {
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, NULL);
+ }
}
static bool has_word_prefix(const char *haystack, const char *needle, size_t needle_len)
{
- const char *match = BLI_strncasestr(haystack, needle, needle_len);
- if (match) {
- if ((match == haystack) || (*(match - 1) == ' ') || ispunct(*(match - 1))) {
- return true;
- }
- else {
- return has_word_prefix(match + 1, needle, needle_len);
- }
- }
- else {
- return false;
- }
+ const char *match = BLI_strncasestr(haystack, needle, needle_len);
+ if (match) {
+ if ((match == haystack) || (*(match - 1) == ' ') || ispunct(*(match - 1))) {
+ return true;
+ }
+ else {
+ return has_word_prefix(match + 1, needle, needle_len);
+ }
+ }
+ else {
+ return false;
+ }
}
-static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
+static void operator_search_cb(const bContext *C,
+ void *UNUSED(arg),
+ const char *str,
+ uiSearchItems *items)
{
- GHashIterator iter;
- const size_t str_len = strlen(str);
- const int words_max = (str_len / 2) + 1;
- int (*words)[2] = BLI_array_alloca(words, words_max);
-
- const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max);
-
- for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
- wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
- const char *ot_ui_name = CTX_IFACE_(ot->translation_context, ot->name);
- int index;
-
- if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) {
- continue;
- }
-
- /* match name against all search words */
- for (index = 0; index < words_len; index++) {
- if (!has_word_prefix(ot_ui_name, str + words[index][0], words[index][1])) {
- break;
- }
- }
-
- if (index == words_len) {
- if (WM_operator_poll((bContext *)C, ot)) {
- char name[256];
- int len = strlen(ot_ui_name);
-
- /* display name for menu, can hold hotkey */
- BLI_strncpy(name, ot_ui_name, sizeof(name));
-
- /* check for hotkey */
- if (len < sizeof(name) - 6) {
- if (WM_key_event_operator_string(
- C, ot->idname, WM_OP_EXEC_DEFAULT, NULL, true,
- &name[len + 1], sizeof(name) - len - 1))
- {
- name[len] = UI_SEP_CHAR;
- }
- }
-
- if (false == UI_search_item_add(items, name, ot, 0)) {
- break;
- }
- }
- }
- }
+ GHashIterator iter;
+ const size_t str_len = strlen(str);
+ const int words_max = (str_len / 2) + 1;
+ int(*words)[2] = BLI_array_alloca(words, words_max);
+
+ const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max);
+
+ for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter);
+ BLI_ghashIterator_step(&iter)) {
+ wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
+ const char *ot_ui_name = CTX_IFACE_(ot->translation_context, ot->name);
+ int index;
+
+ if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) {
+ continue;
+ }
+
+ /* match name against all search words */
+ for (index = 0; index < words_len; index++) {
+ if (!has_word_prefix(ot_ui_name, str + words[index][0], words[index][1])) {
+ break;
+ }
+ }
+
+ if (index == words_len) {
+ if (WM_operator_poll((bContext *)C, ot)) {
+ char name[256];
+ int len = strlen(ot_ui_name);
+
+ /* display name for menu, can hold hotkey */
+ BLI_strncpy(name, ot_ui_name, sizeof(name));
+
+ /* check for hotkey */
+ if (len < sizeof(name) - 6) {
+ if (WM_key_event_operator_string(C,
+ ot->idname,
+ WM_OP_EXEC_DEFAULT,
+ NULL,
+ true,
+ &name[len + 1],
+ sizeof(name) - len - 1)) {
+ name[len] = UI_SEP_CHAR;
+ }
+ }
+
+ if (false == UI_search_item_add(items, name, ot, 0)) {
+ break;
+ }
+ }
+ }
+ }
}
void UI_but_func_operator_search(uiBut *but)
{
- UI_but_func_search_set(
- but, ui_searchbox_create_operator, operator_search_cb,
- NULL, false, operator_call_cb, NULL);
+ UI_but_func_search_set(
+ but, ui_searchbox_create_operator, operator_search_cb, NULL, false, operator_call_cb, NULL);
}
void uiTemplateOperatorSearch(uiLayout *layout)
{
- uiBlock *block;
- uiBut *but;
- static char search[256] = "";
+ uiBlock *block;
+ uiBut *but;
+ static char search[256] = "";
- block = uiLayoutGetBlock(layout);
- UI_block_layout_set_current(block, layout);
+ block = uiLayoutGetBlock(layout);
+ UI_block_layout_set_current(block, layout);
- but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, 0, "");
- UI_but_func_operator_search(but);
+ but = uiDefSearchBut(
+ block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, 0, "");
+ UI_but_func_operator_search(but);
}
/************************* Operator Redo Properties Template **************************/
#ifdef USE_OP_RESET_BUT
-static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt, void *UNUSED(arg_dummy2))
+static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C),
+ void *op_pt,
+ void *UNUSED(arg_dummy2))
{
- WM_operator_properties_reset((wmOperator *)op_pt);
+ WM_operator_properties_reset((wmOperator *)op_pt);
}
#endif
struct uiTemplateOperatorPropertyPollParam {
- const bContext *C;
- wmOperator *op;
- short flag;
+ const bContext *C;
+ wmOperator *op;
+ short flag;
};
-static bool ui_layout_operator_buts_poll_property(
- struct PointerRNA *UNUSED(ptr), struct PropertyRNA *prop, void *user_data)
+static bool ui_layout_operator_buts_poll_property(struct PointerRNA *UNUSED(ptr),
+ struct PropertyRNA *prop,
+ void *user_data)
{
- struct uiTemplateOperatorPropertyPollParam *params = user_data;
- if ((params->flag & UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED) &&
- (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED))
- {
- return false;
- }
- return params->op->type->poll_property(params->C, params->op, prop);
+ struct uiTemplateOperatorPropertyPollParam *params = user_data;
+ if ((params->flag & UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED) &&
+ (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED)) {
+ return false;
+ }
+ return params->op->type->poll_property(params->C, params->op, prop);
}
/**
* Draw Operator property buttons for redoing execution with different settings.
* This function does not initialize the layout, functions can be called on the layout before and after.
*/
-eAutoPropButsReturn uiTemplateOperatorPropertyButs(
- const bContext *C, uiLayout *layout, wmOperator *op,
- const eButLabelAlign label_align, const short flag)
+eAutoPropButsReturn uiTemplateOperatorPropertyButs(const bContext *C,
+ uiLayout *layout,
+ wmOperator *op,
+ const eButLabelAlign label_align,
+ const short flag)
{
- uiBlock *block = uiLayoutGetBlock(layout);
- eAutoPropButsReturn return_info = 0;
-
- if (!op->properties) {
- IDPropertyTemplate val = {0};
- op->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
- }
-
- /* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
- * just fails silently */
- if (!WM_operator_repeat_check(C, op)) {
- UI_block_lock_set(block, true, "Operator can't' redo");
- return return_info;
- }
- else {
- /* useful for macros where only one of the steps can't be re-done */
- UI_block_lock_clear(block);
- }
-
- if (flag & UI_TEMPLATE_OP_PROPS_SHOW_TITLE) {
- uiItemL(layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
- }
-
-
- /* menu */
- if (op->type->flag & OPTYPE_PRESET) {
- /* XXX, no simple way to get WM_MT_operator_presets.bl_label
- * from python! Label remains the same always! */
- PointerRNA op_ptr;
- uiLayout *row;
-
- block->ui_operator = op;
-
- row = uiLayoutRow(layout, true);
- uiItemM(row, "WM_MT_operator_presets", NULL, ICON_NONE);
-
- wmOperatorType *ot = WM_operatortype_find("WM_OT_operator_preset_add", false);
- uiItemFullO_ptr(row, ot, "", ICON_ADD, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_string_set(&op_ptr, "operator", op->type->idname);
-
- uiItemFullO_ptr(row, ot, "", ICON_REMOVE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
- RNA_string_set(&op_ptr, "operator", op->type->idname);
- RNA_boolean_set(&op_ptr, "remove_active", true);
- }
-
- if (op->type->ui) {
- op->layout = layout;
- op->type->ui((bContext *)C, op);
- op->layout = NULL;
-
- /* UI_LAYOUT_OP_SHOW_EMPTY ignored. return_info is ignored too. We could
- * allow ot.ui callback to return this, but not needed right now. */
- }
- else {
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
- struct uiTemplateOperatorPropertyPollParam user_data = { .C = C, .op = op, .flag = flag, };
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- uiLayoutSetPropSep(layout, true);
-
- /* main draw call */
- return_info = uiDefAutoButsRNA(
- layout, &ptr,
- op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL,
- op->type->poll_property ? &user_data : NULL,
- op->type->prop,
- label_align, (flag & UI_TEMPLATE_OP_PROPS_COMPACT));
-
- if ((return_info & UI_PROP_BUTS_NONE_ADDED) && (flag & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
- uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
- }
- }
+ uiBlock *block = uiLayoutGetBlock(layout);
+ eAutoPropButsReturn return_info = 0;
+
+ if (!op->properties) {
+ IDPropertyTemplate val = {0};
+ op->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties");
+ }
+
+ /* poll() on this operator may still fail, at the moment there is no nice feedback when this happens
+ * just fails silently */
+ if (!WM_operator_repeat_check(C, op)) {
+ UI_block_lock_set(block, true, "Operator can't' redo");
+ return return_info;
+ }
+ else {
+ /* useful for macros where only one of the steps can't be re-done */
+ UI_block_lock_clear(block);
+ }
+
+ if (flag & UI_TEMPLATE_OP_PROPS_SHOW_TITLE) {
+ uiItemL(layout, RNA_struct_ui_name(op->type->srna), ICON_NONE);
+ }
+
+ /* menu */
+ if (op->type->flag & OPTYPE_PRESET) {
+ /* XXX, no simple way to get WM_MT_operator_presets.bl_label
+ * from python! Label remains the same always! */
+ PointerRNA op_ptr;
+ uiLayout *row;
+
+ block->ui_operator = op;
+
+ row = uiLayoutRow(layout, true);
+ uiItemM(row, "WM_MT_operator_presets", NULL, ICON_NONE);
+
+ wmOperatorType *ot = WM_operatortype_find("WM_OT_operator_preset_add", false);
+ uiItemFullO_ptr(row, ot, "", ICON_ADD, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_string_set(&op_ptr, "operator", op->type->idname);
+
+ uiItemFullO_ptr(row, ot, "", ICON_REMOVE, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr);
+ RNA_string_set(&op_ptr, "operator", op->type->idname);
+ RNA_boolean_set(&op_ptr, "remove_active", true);
+ }
+
+ if (op->type->ui) {
+ op->layout = layout;
+ op->type->ui((bContext *)C, op);
+ op->layout = NULL;
+
+ /* UI_LAYOUT_OP_SHOW_EMPTY ignored. return_info is ignored too. We could
+ * allow ot.ui callback to return this, but not needed right now. */
+ }
+ else {
+ wmWindowManager *wm = CTX_wm_manager(C);
+ PointerRNA ptr;
+ struct uiTemplateOperatorPropertyPollParam user_data = {
+ .C = C,
+ .op = op,
+ .flag = flag,
+ };
+
+ RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
+
+ uiLayoutSetPropSep(layout, true);
+
+ /* main draw call */
+ return_info = uiDefAutoButsRNA(
+ layout,
+ &ptr,
+ op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL,
+ op->type->poll_property ? &user_data : NULL,
+ op->type->prop,
+ label_align,
+ (flag & UI_TEMPLATE_OP_PROPS_COMPACT));
+
+ if ((return_info & UI_PROP_BUTS_NONE_ADDED) && (flag & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
+ uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
+ }
+ }
#ifdef USE_OP_RESET_BUT
- /* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
- * but this is not so important if this button is drawn in those cases
- * (which isn't all that likely anyway) - campbell */
- if (op->properties->len) {
- uiBut *but;
- uiLayout *col; /* needed to avoid alignment errors with previous buttons */
-
- col = uiLayoutColumn(layout, false);
- block = uiLayoutGetBlock(col);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, ICON_FILE_REFRESH, IFACE_("Reset"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Reset operator defaults"));
- UI_but_func_set(but, ui_layout_operator_buts__reset_cb, op, NULL);
- }
+ /* its possible that reset can do nothing if all have PROP_SKIP_SAVE enabled
+ * but this is not so important if this button is drawn in those cases
+ * (which isn't all that likely anyway) - campbell */
+ if (op->properties->len) {
+ uiBut *but;
+ uiLayout *col; /* needed to avoid alignment errors with previous buttons */
+
+ col = uiLayoutColumn(layout, false);
+ block = uiLayoutGetBlock(col);
+ but = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ 0,
+ ICON_FILE_REFRESH,
+ IFACE_("Reset"),
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Reset operator defaults"));
+ UI_but_func_set(but, ui_layout_operator_buts__reset_cb, op, NULL);
+ }
#endif
- /* set various special settings for buttons */
+ /* set various special settings for buttons */
- /* Only do this if we're not refreshing an existing UI. */
- if (block->oldblock == NULL) {
- const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
- uiBut *but;
+ /* Only do this if we're not refreshing an existing UI. */
+ if (block->oldblock == NULL) {
+ const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
+ uiBut *but;
- for (but = block->buttons.first; but; but = but->next) {
- /* no undo for buttons for operator redo panels */
- UI_but_flag_disable(but, UI_BUT_UNDO);
+ for (but = block->buttons.first; but; but = but->next) {
+ /* no undo for buttons for operator redo panels */
+ UI_but_flag_disable(but, UI_BUT_UNDO);
- /* only for popups, see [#36109] */
+ /* only for popups, see [#36109] */
- /* if button is operator's default property, and a text-field, enable focus for it
- * - this is used for allowing operators with popups to rename stuff with fewer clicks
- */
- if (is_popup) {
- if ((but->rnaprop == op->type->prop) && (but->type == UI_BTYPE_TEXT)) {
- UI_but_focus_on_enter_event(CTX_wm_window(C), but);
- }
- }
- }
- }
+ /* if button is operator's default property, and a text-field, enable focus for it
+ * - this is used for allowing operators with popups to rename stuff with fewer clicks
+ */
+ if (is_popup) {
+ if ((but->rnaprop == op->type->prop) && (but->type == UI_BTYPE_TEXT)) {
+ UI_but_focus_on_enter_event(CTX_wm_window(C), but);
+ }
+ }
+ }
+ }
- return return_info;
+ return return_info;
}
/************************* Running Jobs Template **************************/
-#define B_STOPRENDER 1
-#define B_STOPCAST 2
-#define B_STOPANIM 3
-#define B_STOPCOMPO 4
-#define B_STOPSEQ 5
-#define B_STOPCLIP 6
-#define B_STOPFILE 7
-#define B_STOPOTHER 8
+#define B_STOPRENDER 1
+#define B_STOPCAST 2
+#define B_STOPANIM 3
+#define B_STOPCOMPO 4
+#define B_STOPSEQ 5
+#define B_STOPCLIP 6
+#define B_STOPFILE 7
+#define B_STOPOTHER 8
static void do_running_jobs(bContext *C, void *UNUSED(arg), int event)
{
- switch (event) {
- case B_STOPRENDER:
- G.is_break = true;
- break;
- case B_STOPCAST:
- WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C), NULL);
- break;
- case B_STOPANIM:
- WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL);
- break;
- case B_STOPCOMPO:
- WM_jobs_stop(CTX_wm_manager(C), CTX_data_scene(C), NULL);
- break;
- case B_STOPSEQ:
- WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
- break;
- case B_STOPCLIP:
- WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
- break;
- case B_STOPFILE:
- WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
- break;
- case B_STOPOTHER:
- G.is_break = true;
- break;
- }
+ switch (event) {
+ case B_STOPRENDER:
+ G.is_break = true;
+ break;
+ case B_STOPCAST:
+ WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C), NULL);
+ break;
+ case B_STOPANIM:
+ WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL);
+ break;
+ case B_STOPCOMPO:
+ WM_jobs_stop(CTX_wm_manager(C), CTX_data_scene(C), NULL);
+ break;
+ case B_STOPSEQ:
+ WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
+ break;
+ case B_STOPCLIP:
+ WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
+ break;
+ case B_STOPFILE:
+ WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
+ break;
+ case B_STOPOTHER:
+ G.is_break = true;
+ break;
+ }
}
struct ProgressTooltip_Store {
- wmWindowManager *wm;
- void *owner;
+ wmWindowManager *wm;
+ void *owner;
};
static char *progress_tooltip_func(bContext *UNUSED(C), void *argN, const char *UNUSED(tip))
{
- struct ProgressTooltip_Store *arg = argN;
- wmWindowManager *wm = arg->wm;
- void *owner = arg->owner;
-
- const float progress = WM_jobs_progress(wm, owner);
-
- /* create tooltip text and associate it with the job */
- char elapsed_str[32];
- char remaining_str[32] = "Unknown";
- const double elapsed = PIL_check_seconds_timer() - WM_jobs_starttime(wm, owner);
- BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
-
- if (progress) {
- const double remaining = (elapsed / (double)progress) - elapsed;
- BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining);
- }
-
- return BLI_sprintfN(
- "Time Remaining: %s\n"
- "Time Elapsed: %s",
- remaining_str, elapsed_str);
+ struct ProgressTooltip_Store *arg = argN;
+ wmWindowManager *wm = arg->wm;
+ void *owner = arg->owner;
+
+ const float progress = WM_jobs_progress(wm, owner);
+
+ /* create tooltip text and associate it with the job */
+ char elapsed_str[32];
+ char remaining_str[32] = "Unknown";
+ const double elapsed = PIL_check_seconds_timer() - WM_jobs_starttime(wm, owner);
+ BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
+
+ if (progress) {
+ const double remaining = (elapsed / (double)progress) - elapsed;
+ BLI_timecode_string_from_time_simple(remaining_str, sizeof(remaining_str), remaining);
+ }
+
+ return BLI_sprintfN(
+ "Time Remaining: %s\n"
+ "Time Elapsed: %s",
+ remaining_str,
+ elapsed_str);
}
void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
{
- bScreen *screen = CTX_wm_screen(C);
- wmWindowManager *wm = CTX_wm_manager(C);
- ScrArea *sa = CTX_wm_area(C);
- uiBlock *block;
- void *owner = NULL;
- int handle_event, icon = 0;
-
- block = uiLayoutGetBlock(layout);
- UI_block_layout_set_current(block, layout);
-
- UI_block_func_handle_set(block, do_running_jobs, NULL);
-
- if (sa->spacetype == SPACE_SEQ) {
- if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY)) {
- owner = sa;
- }
- handle_event = B_STOPSEQ;
- icon = ICON_SEQUENCE;
- }
- else if (sa->spacetype == SPACE_CLIP) {
- if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY)) {
- owner = sa;
- }
- handle_event = B_STOPCLIP;
- icon = ICON_TRACKER;
- }
- else if (sa->spacetype == SPACE_FILE) {
- if (WM_jobs_test(wm, sa, WM_JOB_TYPE_FILESEL_READDIR)) {
- owner = sa;
- }
- handle_event = B_STOPFILE;
- icon = ICON_FILEBROWSER;
- }
- else {
- Scene *scene;
- /* another scene can be rendering too, for example via compositor */
- for (scene = CTX_data_main(C)->scenes.first; scene; scene = scene->id.next) {
- if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) {
- handle_event = B_STOPRENDER;
- icon = ICON_SCENE;
- break;
- }
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_COMPOSITE)) {
- handle_event = B_STOPCOMPO;
- icon = ICON_RENDERLAYERS;
- break;
- }
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE) ||
- WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE))
- {
- /* Skip bake jobs in compositor to avoid compo header displaying
- * progress bar which is not being updated (bake jobs only need
- * to update NC_IMAGE context.
- */
- if (sa->spacetype != SPACE_NODE) {
- handle_event = B_STOPOTHER;
- icon = ICON_IMAGE;
- break;
- }
- }
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_DPAINT_BAKE)) {
- handle_event = B_STOPOTHER;
- icon = ICON_MOD_DYNAMICPAINT;
- break;
- }
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_POINTCACHE)) {
- handle_event = B_STOPOTHER;
- icon = ICON_PHYSICS;
- break;
- }
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_FLUID)) {
- handle_event = B_STOPOTHER;
- icon = ICON_MOD_FLUIDSIM;
- break;
- }
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_OCEAN)) {
- handle_event = B_STOPOTHER;
- icon = ICON_MOD_OCEAN;
- break;
- }
- else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) {
- handle_event = B_STOPOTHER;
- icon = ICON_NONE;
- break;
- }
- }
- owner = scene;
- }
-
- if (owner) {
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner));
-
- uiLayout *row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
-
- /* get percentage done and set it as the UI text */
- const float progress = WM_jobs_progress(wm, owner);
- char text[8];
- BLI_snprintf(text, 8, "%d%%", (int)(progress * 100));
-
- const char *name = active ? WM_jobs_name(wm, owner) : "Canceling...";
-
- /* job name and icon */
- const int textwidth = UI_fontstyle_string_width(fstyle, name);
- uiDefIconTextBut(block, UI_BTYPE_LABEL, 0, icon, name, 0, 0,
- textwidth + UI_UNIT_X * 1.5f, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0.0f, 0.0f, "");
-
- /* stick progress bar and cancel button together */
- row = uiLayoutRow(layout, true);
- uiLayoutSetActive(row, active);
- block = uiLayoutGetBlock(row);
-
- {
- struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__);
- tip_arg->wm = wm;
- tip_arg->owner = owner;
- uiBut *but_progress = uiDefIconTextBut(
- block, UI_BTYPE_PROGRESS_BAR, 0, 0, text,
- UI_UNIT_X, 0, UI_UNIT_X * 6.0f, UI_UNIT_Y, NULL, 0.0f, 0.0f,
- progress, 0, NULL);
- UI_but_func_tooltip_set(but_progress, progress_tooltip_func, tip_arg);
- }
-
- if (!wm->is_interface_locked) {
- uiDefIconTextBut(block, UI_BTYPE_BUT, handle_event, ICON_PANEL_CLOSE,
- "", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop this job"));
- }
- }
-
- if (screen->animtimer) {
- uiDefIconTextBut(block, UI_BTYPE_BUT, B_STOPANIM, ICON_CANCEL, IFACE_("Anim Player"), 0, 0, UI_UNIT_X * 5.0f, UI_UNIT_Y,
- NULL, 0.0f, 0.0f, 0, 0, TIP_("Stop animation playback"));
- }
+ bScreen *screen = CTX_wm_screen(C);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ ScrArea *sa = CTX_wm_area(C);
+ uiBlock *block;
+ void *owner = NULL;
+ int handle_event, icon = 0;
+
+ block = uiLayoutGetBlock(layout);
+ UI_block_layout_set_current(block, layout);
+
+ UI_block_func_handle_set(block, do_running_jobs, NULL);
+
+ if (sa->spacetype == SPACE_SEQ) {
+ if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY)) {
+ owner = sa;
+ }
+ handle_event = B_STOPSEQ;
+ icon = ICON_SEQUENCE;
+ }
+ else if (sa->spacetype == SPACE_CLIP) {
+ if (WM_jobs_test(wm, sa, WM_JOB_TYPE_ANY)) {
+ owner = sa;
+ }
+ handle_event = B_STOPCLIP;
+ icon = ICON_TRACKER;
+ }
+ else if (sa->spacetype == SPACE_FILE) {
+ if (WM_jobs_test(wm, sa, WM_JOB_TYPE_FILESEL_READDIR)) {
+ owner = sa;
+ }
+ handle_event = B_STOPFILE;
+ icon = ICON_FILEBROWSER;
+ }
+ else {
+ Scene *scene;
+ /* another scene can be rendering too, for example via compositor */
+ for (scene = CTX_data_main(C)->scenes.first; scene; scene = scene->id.next) {
+ if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) {
+ handle_event = B_STOPRENDER;
+ icon = ICON_SCENE;
+ break;
+ }
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_COMPOSITE)) {
+ handle_event = B_STOPCOMPO;
+ icon = ICON_RENDERLAYERS;
+ break;
+ }
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE) ||
+ WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_BAKE)) {
+ /* Skip bake jobs in compositor to avoid compo header displaying
+ * progress bar which is not being updated (bake jobs only need
+ * to update NC_IMAGE context.
+ */
+ if (sa->spacetype != SPACE_NODE) {
+ handle_event = B_STOPOTHER;
+ icon = ICON_IMAGE;
+ break;
+ }
+ }
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_DPAINT_BAKE)) {
+ handle_event = B_STOPOTHER;
+ icon = ICON_MOD_DYNAMICPAINT;
+ break;
+ }
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_POINTCACHE)) {
+ handle_event = B_STOPOTHER;
+ icon = ICON_PHYSICS;
+ break;
+ }
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_FLUID)) {
+ handle_event = B_STOPOTHER;
+ icon = ICON_MOD_FLUIDSIM;
+ break;
+ }
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_OBJECT_SIM_OCEAN)) {
+ handle_event = B_STOPOTHER;
+ icon = ICON_MOD_OCEAN;
+ break;
+ }
+ else if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) {
+ handle_event = B_STOPOTHER;
+ icon = ICON_NONE;
+ break;
+ }
+ }
+ owner = scene;
+ }
+
+ if (owner) {
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner));
+
+ uiLayout *row = uiLayoutRow(layout, false);
+ block = uiLayoutGetBlock(row);
+
+ /* get percentage done and set it as the UI text */
+ const float progress = WM_jobs_progress(wm, owner);
+ char text[8];
+ BLI_snprintf(text, 8, "%d%%", (int)(progress * 100));
+
+ const char *name = active ? WM_jobs_name(wm, owner) : "Canceling...";
+
+ /* job name and icon */
+ const int textwidth = UI_fontstyle_string_width(fstyle, name);
+ uiDefIconTextBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ icon,
+ name,
+ 0,
+ 0,
+ textwidth + UI_UNIT_X * 1.5f,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ "");
+
+ /* stick progress bar and cancel button together */
+ row = uiLayoutRow(layout, true);
+ uiLayoutSetActive(row, active);
+ block = uiLayoutGetBlock(row);
+
+ {
+ struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__);
+ tip_arg->wm = wm;
+ tip_arg->owner = owner;
+ uiBut *but_progress = uiDefIconTextBut(block,
+ UI_BTYPE_PROGRESS_BAR,
+ 0,
+ 0,
+ text,
+ UI_UNIT_X,
+ 0,
+ UI_UNIT_X * 6.0f,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ progress,
+ 0,
+ NULL);
+ UI_but_func_tooltip_set(but_progress, progress_tooltip_func, tip_arg);
+ }
+
+ if (!wm->is_interface_locked) {
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ handle_event,
+ ICON_PANEL_CLOSE,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0,
+ 0,
+ TIP_("Stop this job"));
+ }
+ }
+
+ if (screen->animtimer) {
+ uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ B_STOPANIM,
+ ICON_CANCEL,
+ IFACE_("Anim Player"),
+ 0,
+ 0,
+ UI_UNIT_X * 5.0f,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0,
+ 0,
+ TIP_("Stop animation playback"));
+ }
}
/************************* Reports for Last Operator Template **************************/
void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
{
- ReportList *reports = CTX_wm_reports(C);
- Report *report = BKE_reports_last_displayable(reports);
- ReportTimerInfo *rti;
-
- uiLayout *ui_abs;
- uiBlock *block;
- uiBut *but;
- uiStyle *style = UI_style_get();
- int width;
- int icon;
-
- /* if the report display has timed out, don't show */
- if (!reports->reporttimer) {
- return;
- }
-
- rti = (ReportTimerInfo *)reports->reporttimer->customdata;
-
- if (!rti || rti->widthfac == 0.0f || !report) {
- return;
- }
-
- ui_abs = uiLayoutAbsolute(layout, false);
- block = uiLayoutGetBlock(ui_abs);
-
- UI_fontstyle_set(&style->widgetlabel);
- width = BLF_width(style->widgetlabel.uifont_id, report->message, report->len);
- width = min_ii((int)(rti->widthfac * width), width);
- width = max_ii(width, 10 * UI_DPI_FAC);
-
- /* make a box around the report to make it stand out */
- UI_block_align_begin(block);
- but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 5, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- /* set the report's bg color in but->col - UI_BTYPE_ROUNDBOX feature */
- rgba_float_to_uchar(but->col, rti->col);
-
- but = uiDefBut(block, UI_BTYPE_ROUNDBOX, 0, "", UI_UNIT_X + 5, 0, UI_UNIT_X + width, UI_UNIT_Y,
- NULL, 0.0f, 0.0f, 0, 0, "");
- rgba_float_to_uchar(but->col, rti->col);
-
- UI_block_align_end(block);
-
- /* icon and report message on top */
- icon = UI_icon_from_report_type(report->type);
-
- /* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report
- * to be shown instead of icon when appropriate...
- */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- if (reports->list.first != reports->list.last) {
- uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_reports_to_textblock", WM_OP_INVOKE_REGION_WIN, icon, 2, 0, UI_UNIT_X,
- UI_UNIT_Y, TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
- }
- else {
- uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
- }
-
- UI_block_emboss_set(block, UI_EMBOSS);
-
- uiDefBut(block, UI_BTYPE_LABEL, 0, report->message, UI_UNIT_X + 5, 0, UI_UNIT_X + width, UI_UNIT_Y,
- NULL, 0.0f, 0.0f, 0, 0, "");
+ ReportList *reports = CTX_wm_reports(C);
+ Report *report = BKE_reports_last_displayable(reports);
+ ReportTimerInfo *rti;
+
+ uiLayout *ui_abs;
+ uiBlock *block;
+ uiBut *but;
+ uiStyle *style = UI_style_get();
+ int width;
+ int icon;
+
+ /* if the report display has timed out, don't show */
+ if (!reports->reporttimer) {
+ return;
+ }
+
+ rti = (ReportTimerInfo *)reports->reporttimer->customdata;
+
+ if (!rti || rti->widthfac == 0.0f || !report) {
+ return;
+ }
+
+ ui_abs = uiLayoutAbsolute(layout, false);
+ block = uiLayoutGetBlock(ui_abs);
+
+ UI_fontstyle_set(&style->widgetlabel);
+ width = BLF_width(style->widgetlabel.uifont_id, report->message, report->len);
+ width = min_ii((int)(rti->widthfac * width), width);
+ width = max_ii(width, 10 * UI_DPI_FAC);
+
+ /* make a box around the report to make it stand out */
+ UI_block_align_begin(block);
+ but = uiDefBut(
+ block, UI_BTYPE_ROUNDBOX, 0, "", 0, 0, UI_UNIT_X + 5, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ /* set the report's bg color in but->col - UI_BTYPE_ROUNDBOX feature */
+ rgba_float_to_uchar(but->col, rti->col);
+
+ but = uiDefBut(block,
+ UI_BTYPE_ROUNDBOX,
+ 0,
+ "",
+ UI_UNIT_X + 5,
+ 0,
+ UI_UNIT_X + width,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0,
+ 0,
+ "");
+ rgba_float_to_uchar(but->col, rti->col);
+
+ UI_block_align_end(block);
+
+ /* icon and report message on top */
+ icon = UI_icon_from_report_type(report->type);
+
+ /* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report
+ * to be shown instead of icon when appropriate...
+ */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ if (reports->list.first != reports->list.last) {
+ uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "UI_OT_reports_to_textblock",
+ WM_OP_INVOKE_REGION_WIN,
+ icon,
+ 2,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ TIP_("Click to see the remaining reports in text block: 'Recent Reports'"));
+ }
+ else {
+ uiDefIconBut(
+ block, UI_BTYPE_LABEL, 0, icon, 2, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "");
+ }
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ report->message,
+ UI_UNIT_X + 5,
+ 0,
+ UI_UNIT_X + width,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0,
+ 0,
+ "");
}
-
void uiTemplateInputStatus(uiLayout *layout, struct bContext *C)
{
- wmWindow *win = CTX_wm_window(C);
- WorkSpace *workspace = CTX_wm_workspace(C);
-
- /* Workspace status text has priority. */
- if (workspace->status_text) {
- uiItemL(layout, workspace->status_text, ICON_NONE);
- return;
- }
-
- if (WM_window_modal_keymap_status_draw(C, win, layout)) {
- return;
- }
-
- /* Otherwise should cursor keymap status. */
- for (int i = 0; i < 3; i++) {
- uiLayout *box = uiLayoutRow(layout, false);
- uiLayout *col = uiLayoutColumn(box, false);
- uiLayout *row = uiLayoutRow(col, true);
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
-
- const char *msg = WM_window_cursor_keymap_status_get(win, i, 0);
- const char *msg_drag = WM_window_cursor_keymap_status_get(win, i, 1);
-
- if (msg || (msg_drag == NULL)) {
- uiItemL(row, msg ? msg : "", (ICON_MOUSE_LMB + i));
- }
-
- if (msg_drag) {
- uiItemL(row, msg_drag, (ICON_MOUSE_LMB_DRAG + i));
- }
-
- /* Use trick with empty string to keep icons in same position. */
- row = uiLayoutRow(col, false);
- uiItemL(row, " ", ICON_NONE);
- }
+ wmWindow *win = CTX_wm_window(C);
+ WorkSpace *workspace = CTX_wm_workspace(C);
+
+ /* Workspace status text has priority. */
+ if (workspace->status_text) {
+ uiItemL(layout, workspace->status_text, ICON_NONE);
+ return;
+ }
+
+ if (WM_window_modal_keymap_status_draw(C, win, layout)) {
+ return;
+ }
+
+ /* Otherwise should cursor keymap status. */
+ for (int i = 0; i < 3; i++) {
+ uiLayout *box = uiLayoutRow(layout, false);
+ uiLayout *col = uiLayoutColumn(box, false);
+ uiLayout *row = uiLayoutRow(col, true);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
+
+ const char *msg = WM_window_cursor_keymap_status_get(win, i, 0);
+ const char *msg_drag = WM_window_cursor_keymap_status_get(win, i, 1);
+
+ if (msg || (msg_drag == NULL)) {
+ uiItemL(row, msg ? msg : "", (ICON_MOUSE_LMB + i));
+ }
+
+ if (msg_drag) {
+ uiItemL(row, msg_drag, (ICON_MOUSE_LMB_DRAG + i));
+ }
+
+ /* Use trick with empty string to keep icons in same position. */
+ row = uiLayoutRow(col, false);
+ uiItemL(row, " ", ICON_NONE);
+ }
}
/********************************* Keymap *************************************/
static void keymap_item_modified(bContext *UNUSED(C), void *kmi_p, void *UNUSED(unused))
{
- wmKeyMapItem *kmi = (wmKeyMapItem *)kmi_p;
- WM_keyconfig_update_tag(NULL, kmi);
+ wmKeyMapItem *kmi = (wmKeyMapItem *)kmi_p;
+ WM_keyconfig_update_tag(NULL, kmi);
}
static void template_keymap_item_properties(uiLayout *layout, const char *title, PointerRNA *ptr)
{
- uiLayout *flow, *box, *row;
-
- uiItemS(layout);
-
- if (title) {
- uiItemL(layout, title, ICON_NONE);
- }
-
- flow = uiLayoutColumnFlow(layout, 2, false);
-
- RNA_STRUCT_BEGIN (ptr, prop)
- {
- const bool is_set = RNA_property_is_set(ptr, prop);
- uiBut *but;
-
- /* recurse for nested properties */
- if (RNA_property_type(prop) == PROP_POINTER) {
- PointerRNA propptr = RNA_property_pointer_get(ptr, prop);
-
- if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) {
- const char *name = RNA_property_ui_name(prop);
- template_keymap_item_properties(layout, name, &propptr);
- continue;
- }
- }
-
- box = uiLayoutBox(flow);
- uiLayoutSetActive(box, is_set);
- row = uiLayoutRow(box, false);
-
- /* property value */
- uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
-
- if (is_set) {
- /* unset operator */
- uiBlock *block = uiLayoutGetBlock(row);
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- but = uiDefIconButO(block, UI_BTYPE_BUT, "UI_OT_unset_property_button", WM_OP_EXEC_DEFAULT, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
- but->rnapoin = *ptr;
- but->rnaprop = prop;
- UI_block_emboss_set(block, UI_EMBOSS);
- }
- }
- RNA_STRUCT_END;
+ uiLayout *flow, *box, *row;
+
+ uiItemS(layout);
+
+ if (title) {
+ uiItemL(layout, title, ICON_NONE);
+ }
+
+ flow = uiLayoutColumnFlow(layout, 2, false);
+
+ RNA_STRUCT_BEGIN (ptr, prop) {
+ const bool is_set = RNA_property_is_set(ptr, prop);
+ uiBut *but;
+
+ /* recurse for nested properties */
+ if (RNA_property_type(prop) == PROP_POINTER) {
+ PointerRNA propptr = RNA_property_pointer_get(ptr, prop);
+
+ if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) {
+ const char *name = RNA_property_ui_name(prop);
+ template_keymap_item_properties(layout, name, &propptr);
+ continue;
+ }
+ }
+
+ box = uiLayoutBox(flow);
+ uiLayoutSetActive(box, is_set);
+ row = uiLayoutRow(box, false);
+
+ /* property value */
+ uiItemFullR(row, ptr, prop, -1, 0, 0, NULL, ICON_NONE);
+
+ if (is_set) {
+ /* unset operator */
+ uiBlock *block = uiLayoutGetBlock(row);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ but = uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "UI_OT_unset_property_button",
+ WM_OP_EXEC_DEFAULT,
+ ICON_X,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL);
+ but->rnapoin = *ptr;
+ but->rnaprop = prop;
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
+ }
+ RNA_STRUCT_END;
}
void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
{
- PointerRNA propptr = RNA_pointer_get(ptr, "properties");
-
- if (propptr.data) {
- uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
-
- WM_operator_properties_sanitize(&propptr, false);
- template_keymap_item_properties(layout, NULL, &propptr);
-
- /* attach callbacks to compensate for missing properties update,
- * we don't know which keymap (item) is being modified there */
- for (; but; but = but->next) {
- /* operator buttons may store props for use (file selector, [#36492]) */
- if (but->rnaprop) {
- UI_but_func_set(but, keymap_item_modified, ptr->data, NULL);
-
- /* Otherwise the keymap will be re-generated which we're trying to edit,
- * see: T47685 */
- UI_but_flag_enable(but, UI_BUT_UPDATE_DELAY);
- }
- }
- }
+ PointerRNA propptr = RNA_pointer_get(ptr, "properties");
+
+ if (propptr.data) {
+ uiBut *but = uiLayoutGetBlock(layout)->buttons.last;
+
+ WM_operator_properties_sanitize(&propptr, false);
+ template_keymap_item_properties(layout, NULL, &propptr);
+
+ /* attach callbacks to compensate for missing properties update,
+ * we don't know which keymap (item) is being modified there */
+ for (; but; but = but->next) {
+ /* operator buttons may store props for use (file selector, [#36492]) */
+ if (but->rnaprop) {
+ UI_but_func_set(but, keymap_item_modified, ptr->data, NULL);
+
+ /* Otherwise the keymap will be re-generated which we're trying to edit,
+ * see: T47685 */
+ UI_but_flag_enable(but, UI_BUT_UPDATE_DELAY);
+ }
+ }
+ }
}
/********************************* Color management *************************************/
void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, const char *propname)
{
- PropertyRNA *prop;
- PointerRNA colorspace_settings_ptr;
+ PropertyRNA *prop;
+ PointerRNA colorspace_settings_ptr;
- prop = RNA_struct_find_property(ptr, propname);
+ prop = RNA_struct_find_property(ptr, propname);
- if (!prop) {
- printf("%s: property not found: %s.%s\n",
- __func__, RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ if (!prop) {
+ printf(
+ "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
- colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
+ colorspace_settings_ptr = RNA_property_pointer_get(ptr, prop);
- uiItemR(layout, &colorspace_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE);
+ uiItemR(layout, &colorspace_settings_ptr, "name", 0, IFACE_("Color Space"), ICON_NONE);
}
-void uiTemplateColormanagedViewSettings(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr, const char *propname)
+void uiTemplateColormanagedViewSettings(uiLayout *layout,
+ bContext *UNUSED(C),
+ PointerRNA *ptr,
+ const char *propname)
{
- PropertyRNA *prop;
- PointerRNA view_transform_ptr;
- uiLayout *col, *row;
- ColorManagedViewSettings *view_settings;
+ PropertyRNA *prop;
+ PointerRNA view_transform_ptr;
+ uiLayout *col, *row;
+ ColorManagedViewSettings *view_settings;
- prop = RNA_struct_find_property(ptr, propname);
+ prop = RNA_struct_find_property(ptr, propname);
- if (!prop) {
- printf("%s: property not found: %s.%s\n",
- __func__, RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ if (!prop) {
+ printf(
+ "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
- view_transform_ptr = RNA_property_pointer_get(ptr, prop);
- view_settings = view_transform_ptr.data;
+ view_transform_ptr = RNA_property_pointer_get(ptr, prop);
+ view_settings = view_transform_ptr.data;
- col = uiLayoutColumn(layout, false);
+ col = uiLayoutColumn(layout, false);
- row = uiLayoutRow(col, false);
- uiItemR(row, &view_transform_ptr, "view_transform", 0, IFACE_("View"), ICON_NONE);
+ row = uiLayoutRow(col, false);
+ uiItemR(row, &view_transform_ptr, "view_transform", 0, IFACE_("View"), ICON_NONE);
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &view_transform_ptr, "exposure", 0, NULL, ICON_NONE);
- uiItemR(col, &view_transform_ptr, "gamma", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, &view_transform_ptr, "exposure", 0, NULL, ICON_NONE);
+ uiItemR(col, &view_transform_ptr, "gamma", 0, NULL, ICON_NONE);
- uiItemR(col, &view_transform_ptr, "look", 0, IFACE_("Look"), ICON_NONE);
+ uiItemR(col, &view_transform_ptr, "look", 0, IFACE_("Look"), ICON_NONE);
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &view_transform_ptr, "use_curve_mapping", 0, NULL, ICON_NONE);
- if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
- uiTemplateCurveMapping(col, &view_transform_ptr, "curve_mapping", 'c', true, false, false, false);
- }
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, &view_transform_ptr, "use_curve_mapping", 0, NULL, ICON_NONE);
+ if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
+ uiTemplateCurveMapping(
+ col, &view_transform_ptr, "curve_mapping", 'c', true, false, false, false);
+ }
}
/********************************* Component Menu *************************************/
typedef struct ComponentMenuArgs {
- PointerRNA ptr;
- char propname[64]; /* XXX arbitrary */
+ PointerRNA ptr;
+ char propname[64]; /* XXX arbitrary */
} ComponentMenuArgs;
/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */
static uiBlock *component_menu(bContext *C, ARegion *ar, void *args_v)
{
- ComponentMenuArgs *args = (ComponentMenuArgs *)args_v;
- uiBlock *block;
- uiLayout *layout;
-
- block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
- UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN);
-
- layout = uiLayoutColumn(UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, UI_style_get()), 0);
-
- uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE);
-
- UI_block_bounds_set_normal(block, 6);
- UI_block_direction_set(block, UI_DIR_DOWN);
-
- return block;
+ ComponentMenuArgs *args = (ComponentMenuArgs *)args_v;
+ uiBlock *block;
+ uiLayout *layout;
+
+ block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN);
+
+ layout = uiLayoutColumn(UI_block_layout(block,
+ UI_LAYOUT_VERTICAL,
+ UI_LAYOUT_PANEL,
+ 0,
+ 0,
+ UI_UNIT_X * 6,
+ UI_UNIT_Y,
+ 0,
+ UI_style_get()),
+ 0);
+
+ uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE);
+
+ UI_block_bounds_set_normal(block, 6);
+ UI_block_direction_set(block, UI_DIR_DOWN);
+
+ return block;
}
-void uiTemplateComponentMenu(uiLayout *layout, PointerRNA *ptr, const char *propname, const char *name)
+void uiTemplateComponentMenu(uiLayout *layout,
+ PointerRNA *ptr,
+ const char *propname,
+ const char *name)
{
- ComponentMenuArgs *args = MEM_callocN(sizeof(ComponentMenuArgs), "component menu template args");
- uiBlock *block;
- uiBut *but;
+ ComponentMenuArgs *args = MEM_callocN(sizeof(ComponentMenuArgs), "component menu template args");
+ uiBlock *block;
+ uiBut *but;
- args->ptr = *ptr;
- BLI_strncpy(args->propname, propname, sizeof(args->propname));
+ args->ptr = *ptr;
+ BLI_strncpy(args->propname, propname, sizeof(args->propname));
- block = uiLayoutGetBlock(layout);
- UI_block_align_begin(block);
+ block = uiLayoutGetBlock(layout);
+ UI_block_align_begin(block);
- but = uiDefBlockButN(block, component_menu, args, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, "");
- /* set rna directly, uiDefBlockButN doesn't do this */
- but->rnapoin = *ptr;
- but->rnaprop = RNA_struct_find_property(ptr, propname);
- but->rnaindex = 0;
+ but = uiDefBlockButN(block, component_menu, args, name, 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, "");
+ /* set rna directly, uiDefBlockButN doesn't do this */
+ but->rnapoin = *ptr;
+ but->rnaprop = RNA_struct_find_property(ptr, propname);
+ but->rnaindex = 0;
- UI_block_align_end(block);
+ UI_block_align_end(block);
}
/************************* Node Socket Icon **************************/
void uiTemplateNodeSocket(uiLayout *layout, bContext *UNUSED(C), float *color)
{
- uiBlock *block;
- uiBut *but;
+ uiBlock *block;
+ uiBut *but;
- block = uiLayoutGetBlock(layout);
- UI_block_align_begin(block);
+ block = uiLayoutGetBlock(layout);
+ UI_block_align_begin(block);
- /* XXX using explicit socket colors is not quite ideal.
- * Eventually it should be possible to use theme colors for this purpose,
- * but this requires a better design for extendable color palettes in user prefs.
- */
- but = uiDefBut(block, UI_BTYPE_NODE_SOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
- rgba_float_to_uchar(but->col, color);
+ /* XXX using explicit socket colors is not quite ideal.
+ * Eventually it should be possible to use theme colors for this purpose,
+ * but this requires a better design for extendable color palettes in user prefs.
+ */
+ but = uiDefBut(
+ block, UI_BTYPE_NODE_SOCKET, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
+ rgba_float_to_uchar(but->col, color);
- UI_block_align_end(block);
+ UI_block_align_end(block);
}
/********************************* Cache File *********************************/
void uiTemplateCacheFile(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname)
{
- if (!ptr->data) {
- return;
- }
+ if (!ptr->data) {
+ return;
+ }
- PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
- if (!prop) {
- printf("%s: property not found: %s.%s\n",
- __func__, RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ if (!prop) {
+ printf(
+ "%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
+ return;
+ }
- if (RNA_property_type(prop) != PROP_POINTER) {
- printf("%s: expected pointer property for %s.%s\n",
- __func__, RNA_struct_identifier(ptr->type), propname);
- return;
- }
+ if (RNA_property_type(prop) != PROP_POINTER) {
+ printf("%s: expected pointer property for %s.%s\n",
+ __func__,
+ RNA_struct_identifier(ptr->type),
+ propname);
+ return;
+ }
- PointerRNA fileptr = RNA_property_pointer_get(ptr, prop);
- CacheFile *file = fileptr.data;
+ PointerRNA fileptr = RNA_property_pointer_get(ptr, prop);
+ CacheFile *file = fileptr.data;
- uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr);
+ uiLayoutSetContextPointer(layout, "edit_cachefile", &fileptr);
- uiTemplateID(layout, C, ptr, propname, NULL, "CACHEFILE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
+ uiTemplateID(
+ layout, C, ptr, propname, NULL, "CACHEFILE_OT_open", NULL, UI_TEMPLATE_ID_FILTER_ALL, false);
- if (!file) {
- return;
- }
+ if (!file) {
+ return;
+ }
- SpaceProperties *sbuts = CTX_wm_space_properties(C);
+ SpaceProperties *sbuts = CTX_wm_space_properties(C);
- uiLayout *row = uiLayoutRow(layout, false);
- uiBlock *block = uiLayoutGetBlock(row);
- uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
+ uiLayout *row = uiLayoutRow(layout, false);
+ uiBlock *block = uiLayoutGetBlock(row);
+ uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("File Path:"), 0, 19, 145, 19, NULL, 0, 0, 0, 0, "");
- row = uiLayoutRow(layout, false);
- uiLayout *split = uiLayoutSplit(row, 0.0f, false);
- row = uiLayoutRow(split, true);
+ row = uiLayoutRow(layout, false);
+ uiLayout *split = uiLayoutSplit(row, 0.0f, false);
+ row = uiLayoutRow(split, true);
- uiItemR(row, &fileptr, "filepath", 0, "", ICON_NONE);
- uiItemO(row, "", ICON_FILE_REFRESH, "cachefile.reload");
+ uiItemR(row, &fileptr, "filepath", 0, "", ICON_NONE);
+ uiItemO(row, "", ICON_FILE_REFRESH, "cachefile.reload");
- row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "is_sequence", 0, "Is Sequence", ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &fileptr, "is_sequence", 0, "Is Sequence", ICON_NONE);
- row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "override_frame", 0, "Override Frame", ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &fileptr, "override_frame", 0, "Override Frame", ICON_NONE);
- row = uiLayoutRow(layout, false);
- uiLayoutSetEnabled(row, RNA_boolean_get(&fileptr, "override_frame"));
- uiItemR(row, &fileptr, "frame", 0, "Frame", ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiLayoutSetEnabled(row, RNA_boolean_get(&fileptr, "override_frame"));
+ uiItemR(row, &fileptr, "frame", 0, "Frame", ICON_NONE);
- row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "frame_offset", 0, "Frame Offset", ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &fileptr, "frame_offset", 0, "Frame Offset", ICON_NONE);
- row = uiLayoutRow(layout, false);
- uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
- row = uiLayoutRow(layout, false);
- uiLayoutSetEnabled(row, (sbuts->mainb == BCONTEXT_CONSTRAINT));
- uiItemR(row, &fileptr, "scale", 0, "Scale", ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiLayoutSetEnabled(row, (sbuts->mainb == BCONTEXT_CONSTRAINT));
+ uiItemR(row, &fileptr, "scale", 0, "Scale", ICON_NONE);
- /* TODO: unused for now, so no need to expose. */
+ /* TODO: unused for now, so no need to expose. */
#if 0
- row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "forward_axis", 0, "Forward Axis", ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &fileptr, "forward_axis", 0, "Forward Axis", ICON_NONE);
- row = uiLayoutRow(layout, false);
- uiItemR(row, &fileptr, "up_axis", 0, "Up Axis", ICON_NONE);
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, &fileptr, "up_axis", 0, "Up Axis", ICON_NONE);
#endif
}
@@ -5161,15 +6729,18 @@ void uiTemplateCacheFile(uiLayout *layout, bContext *C, PointerRNA *ptr, const c
int uiTemplateRecentFiles(uiLayout *layout, int rows)
{
- const RecentFile *recent;
- int i;
-
- for (recent = G.recent_files.first, i = 0; (i < rows) && (recent); recent = recent->next, i++) {
- const char *filename = BLI_path_basename(recent->filepath);
- uiItemStringO(layout, filename,
- BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
- "WM_OT_open_mainfile", "filepath", recent->filepath);
- }
-
- return i;
+ const RecentFile *recent;
+ int i;
+
+ for (recent = G.recent_files.first, i = 0; (i < rows) && (recent); recent = recent->next, i++) {
+ const char *filename = BLI_path_basename(recent->filepath);
+ uiItemStringO(layout,
+ filename,
+ BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP,
+ "WM_OT_open_mainfile",
+ "filepath",
+ recent->filepath);
+ }
+
+ return i;
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 915793445db..9920d4f1fa5 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -51,109 +50,230 @@
#include "interface_intern.h"
-
/*************************** RNA Utilities ******************************/
-uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2)
+uiBut *uiDefAutoButR(uiBlock *block,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ int index,
+ const char *name,
+ int icon,
+ int x1,
+ int y1,
+ int x2,
+ int y2)
{
- uiBut *but = NULL;
-
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- {
- if (RNA_property_array_check(prop) && index == -1) {
- return NULL;
- }
-
- if (icon && name && name[0] == '\0') {
- but = uiDefIconButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else if (icon) {
- but = uiDefIconTextButR_prop(block, UI_BTYPE_ICON_TOGGLE, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_CHECKBOX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- break;
- }
- case PROP_INT:
- case PROP_FLOAT:
- {
- if (RNA_property_array_check(prop) && index == -1) {
- if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
- but = uiDefButR_prop(block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
- }
- else {
- return NULL;
- }
- }
- else if (RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR) {
- but = uiDefButR_prop(block, UI_BTYPE_NUM_SLIDER, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
-
- if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
- UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
- }
- break;
- }
- case PROP_ENUM:
- if (icon && name && name[0] == '\0') {
- but = uiDefIconButR_prop(block, UI_BTYPE_MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else if (icon) {
- but = uiDefIconTextButR_prop(block, UI_BTYPE_MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- break;
- case PROP_STRING:
- if (icon && name && name[0] == '\0') {
- but = uiDefIconButR_prop(block, UI_BTYPE_TEXT, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else if (icon) {
- but = uiDefIconTextButR_prop(block, UI_BTYPE_TEXT, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
- else {
- but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- }
-
- if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
- /* TEXTEDIT_UPDATE is usually used for search buttons. For these we also want
- * the 'x' icon to clear search string, so setting VALUE_CLEAR flag, too. */
- UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE | UI_BUT_VALUE_CLEAR);
- }
- break;
- case PROP_POINTER:
- {
- if (icon == 0) {
- PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
- icon = RNA_struct_ui_icon(pptr.type ? pptr.type : RNA_property_pointer_type(ptr, prop));
- }
- if (icon == ICON_DOT) {
- icon = 0;
- }
-
- but = uiDefIconTextButR_prop(block, UI_BTYPE_SEARCH_MENU, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
- break;
- }
- case PROP_COLLECTION:
- {
- char text[256];
- BLI_snprintf(text, sizeof(text), IFACE_("%d items"), RNA_property_collection_length(ptr, prop));
- but = uiDefBut(block, UI_BTYPE_LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- break;
- }
- default:
- but = NULL;
- break;
- }
-
- return but;
+ uiBut *but = NULL;
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN: {
+ if (RNA_property_array_check(prop) && index == -1) {
+ return NULL;
+ }
+
+ if (icon && name && name[0] == '\0') {
+ but = uiDefIconButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ icon,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else if (icon) {
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_ICON_TOGGLE,
+ 0,
+ icon,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(block,
+ UI_BTYPE_CHECKBOX,
+ 0,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ break;
+ }
+ case PROP_INT:
+ case PROP_FLOAT: {
+ if (RNA_property_array_check(prop) && index == -1) {
+ if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
+ }
+ else {
+ return NULL;
+ }
+ }
+ else if (RNA_property_subtype(prop) == PROP_PERCENTAGE ||
+ RNA_property_subtype(prop) == PROP_FACTOR) {
+ but = uiDefButR_prop(block,
+ UI_BTYPE_NUM_SLIDER,
+ 0,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+
+ if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+ UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
+ }
+ break;
+ }
+ case PROP_ENUM:
+ if (icon && name && name[0] == '\0') {
+ but = uiDefIconButR_prop(
+ block, UI_BTYPE_MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+ else if (icon) {
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_MENU,
+ 0,
+ icon,
+ NULL,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_MENU, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+ break;
+ case PROP_STRING:
+ if (icon && name && name[0] == '\0') {
+ but = uiDefIconButR_prop(
+ block, UI_BTYPE_TEXT, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+ else if (icon) {
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_TEXT,
+ 0,
+ icon,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ }
+ else {
+ but = uiDefButR_prop(
+ block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ }
+
+ if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
+ /* TEXTEDIT_UPDATE is usually used for search buttons. For these we also want
+ * the 'x' icon to clear search string, so setting VALUE_CLEAR flag, too. */
+ UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE | UI_BUT_VALUE_CLEAR);
+ }
+ break;
+ case PROP_POINTER: {
+ if (icon == 0) {
+ PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
+ icon = RNA_struct_ui_icon(pptr.type ? pptr.type : RNA_property_pointer_type(ptr, prop));
+ }
+ if (icon == ICON_DOT) {
+ icon = 0;
+ }
+
+ but = uiDefIconTextButR_prop(block,
+ UI_BTYPE_SEARCH_MENU,
+ 0,
+ icon,
+ name,
+ x1,
+ y1,
+ x2,
+ y2,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ break;
+ }
+ case PROP_COLLECTION: {
+ char text[256];
+ BLI_snprintf(
+ text, sizeof(text), IFACE_("%d items"), RNA_property_collection_length(ptr, prop));
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, NULL);
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ break;
+ }
+ default:
+ but = NULL;
+ break;
+ }
+
+ return but;
}
/**
@@ -162,225 +282,227 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
*
* \param prop_activate_init: Property to activate on initial popup (#UI_BUT_ACTIVATE_ON_INIT).
*/
-eAutoPropButsReturn uiDefAutoButsRNA(
- uiLayout *layout, PointerRNA *ptr,
- bool (*check_prop)(PointerRNA *ptr, PropertyRNA *prop, void *user_data), void *user_data,
- PropertyRNA *prop_activate_init,
- const eButLabelAlign label_align, const bool compact)
+eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
+ PointerRNA *ptr,
+ bool (*check_prop)(PointerRNA *ptr,
+ PropertyRNA *prop,
+ void *user_data),
+ void *user_data,
+ PropertyRNA *prop_activate_init,
+ const eButLabelAlign label_align,
+ const bool compact)
{
- eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED;
- uiLayout *split, *col;
- const char *name;
-
- RNA_STRUCT_BEGIN (ptr, prop)
- {
- const int flag = RNA_property_flag(prop);
-
- if (flag & PROP_HIDDEN) {
- continue;
- }
- if (check_prop && check_prop(ptr, prop, user_data) == 0) {
- return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
- continue;
- }
-
- const PropertyType type = RNA_property_type(prop);
- switch (label_align) {
- case UI_BUT_LABEL_ALIGN_COLUMN:
- case UI_BUT_LABEL_ALIGN_SPLIT_COLUMN:
- {
- const bool is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));
-
- name = RNA_property_ui_name(prop);
-
- if (label_align == UI_BUT_LABEL_ALIGN_COLUMN) {
- col = uiLayoutColumn(layout, true);
-
- if (!is_boolean) {
- uiItemL(col, name, ICON_NONE);
- }
- }
- else {
- BLI_assert(label_align == UI_BUT_LABEL_ALIGN_SPLIT_COLUMN);
- split = uiLayoutSplit(layout, 0.5f, false);
-
- col = uiLayoutColumn(split, false);
- uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
- col = uiLayoutColumn(split, false);
- }
-
- /* May need to add more cases here.
- * don't override enum flag names */
-
- /* name is shown above, empty name for button below */
- name = (flag & PROP_ENUM_FLAG || is_boolean) ? NULL : "";
-
- break;
- }
- case UI_BUT_LABEL_ALIGN_NONE:
- default:
- col = layout;
- name = NULL; /* no smart label alignment, show default name with button */
- break;
- }
-
- /* Only buttons that can be edited as text. */
- const bool use_activate_init = (
- (prop == prop_activate_init) &&
- (ELEM(type, PROP_STRING, PROP_INT, PROP_FLOAT)));
-
- if (use_activate_init) {
- uiLayoutSetActivateInit(col, true);
- }
-
- uiItemFullR(col, ptr, prop, -1, 0, compact ? UI_ITEM_R_COMPACT : 0, name, ICON_NONE);
- return_info &= ~UI_PROP_BUTS_NONE_ADDED;
-
- if (use_activate_init) {
- uiLayoutSetActivateInit(col, false);
- }
-
- }
- RNA_STRUCT_END;
-
- return return_info;
+ eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED;
+ uiLayout *split, *col;
+ const char *name;
+
+ RNA_STRUCT_BEGIN (ptr, prop) {
+ const int flag = RNA_property_flag(prop);
+
+ if (flag & PROP_HIDDEN) {
+ continue;
+ }
+ if (check_prop && check_prop(ptr, prop, user_data) == 0) {
+ return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
+ continue;
+ }
+
+ const PropertyType type = RNA_property_type(prop);
+ switch (label_align) {
+ case UI_BUT_LABEL_ALIGN_COLUMN:
+ case UI_BUT_LABEL_ALIGN_SPLIT_COLUMN: {
+ const bool is_boolean = (type == PROP_BOOLEAN && !RNA_property_array_check(prop));
+
+ name = RNA_property_ui_name(prop);
+
+ if (label_align == UI_BUT_LABEL_ALIGN_COLUMN) {
+ col = uiLayoutColumn(layout, true);
+
+ if (!is_boolean) {
+ uiItemL(col, name, ICON_NONE);
+ }
+ }
+ else {
+ BLI_assert(label_align == UI_BUT_LABEL_ALIGN_SPLIT_COLUMN);
+ split = uiLayoutSplit(layout, 0.5f, false);
+
+ col = uiLayoutColumn(split, false);
+ uiItemL(col, (is_boolean) ? "" : name, ICON_NONE);
+ col = uiLayoutColumn(split, false);
+ }
+
+ /* May need to add more cases here.
+ * don't override enum flag names */
+
+ /* name is shown above, empty name for button below */
+ name = (flag & PROP_ENUM_FLAG || is_boolean) ? NULL : "";
+
+ break;
+ }
+ case UI_BUT_LABEL_ALIGN_NONE:
+ default:
+ col = layout;
+ name = NULL; /* no smart label alignment, show default name with button */
+ break;
+ }
+
+ /* Only buttons that can be edited as text. */
+ const bool use_activate_init = ((prop == prop_activate_init) &&
+ (ELEM(type, PROP_STRING, PROP_INT, PROP_FLOAT)));
+
+ if (use_activate_init) {
+ uiLayoutSetActivateInit(col, true);
+ }
+
+ uiItemFullR(col, ptr, prop, -1, 0, compact ? UI_ITEM_R_COMPACT : 0, name, ICON_NONE);
+ return_info &= ~UI_PROP_BUTS_NONE_ADDED;
+
+ if (use_activate_init) {
+ uiLayoutSetActivateInit(col, false);
+ }
+ }
+ RNA_STRUCT_END;
+
+ return return_info;
}
/* *** RNA collection search menu *** */
typedef struct CollItemSearch {
- struct CollItemSearch *next, *prev;
- void *data;
- char *name;
- int index;
- int iconid;
+ struct CollItemSearch *next, *prev;
+ void *data;
+ char *name;
+ int index;
+ int iconid;
} CollItemSearch;
static int sort_search_items_list(const void *a, const void *b)
{
- const CollItemSearch *cis1 = a;
- const CollItemSearch *cis2 = b;
-
- if (BLI_strcasecmp(cis1->name, cis2->name) > 0) {
- return 1;
- }
- else {
- return 0;
- }
+ const CollItemSearch *cis1 = a;
+ const CollItemSearch *cis2 = b;
+
+ if (BLI_strcasecmp(cis1->name, cis2->name) > 0) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
-void ui_rna_collection_search_cb(const struct bContext *C, void *arg, const char *str, uiSearchItems *items)
+void ui_rna_collection_search_cb(const struct bContext *C,
+ void *arg,
+ const char *str,
+ uiSearchItems *items)
{
- uiRNACollectionSearch *data = arg;
- char *name;
- int i = 0, iconid = 0, flag = RNA_property_flag(data->target_prop);
- ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
- CollItemSearch *cis;
- const bool skip_filter = (data->but_changed && !(*data->but_changed));
-
- /* build a temporary list of relevant items first */
- RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop)
- {
-
- if (flag & PROP_ID_SELF_CHECK) {
- if (itemptr.data == data->target_ptr.id.data) {
- continue;
- }
- }
-
- /* use filter */
- if (RNA_property_type(data->target_prop) == PROP_POINTER) {
- if (RNA_property_pointer_poll(&data->target_ptr, data->target_prop, &itemptr) == 0) {
- continue;
- }
- }
-
- name = RNA_struct_name_get_alloc(&itemptr, NULL, 0, NULL); /* could use the string length here */
- iconid = 0;
- if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
- iconid = ui_id_icon_get(C, itemptr.data, false);
- }
-
- if (name) {
- if (skip_filter || BLI_strcasestr(name, str)) {
- cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
- cis->data = itemptr.data;
- cis->name = MEM_dupallocN(name);
- cis->index = i;
- cis->iconid = iconid;
- BLI_addtail(items_list, cis);
- }
- MEM_freeN(name);
- }
-
- i++;
- }
- RNA_PROP_END;
-
- BLI_listbase_sort(items_list, sort_search_items_list);
-
- /* add search items from temporary list */
- for (cis = items_list->first; cis; cis = cis->next) {
- if (UI_search_item_add(items, cis->name, cis->data, cis->iconid) == false) {
- break;
- }
- }
-
- for (cis = items_list->first; cis; cis = cis->next) {
- MEM_freeN(cis->name);
- }
- BLI_freelistN(items_list);
- MEM_freeN(items_list);
+ uiRNACollectionSearch *data = arg;
+ char *name;
+ int i = 0, iconid = 0, flag = RNA_property_flag(data->target_prop);
+ ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
+ CollItemSearch *cis;
+ const bool skip_filter = (data->but_changed && !(*data->but_changed));
+
+ /* build a temporary list of relevant items first */
+ RNA_PROP_BEGIN (&data->search_ptr, itemptr, data->search_prop) {
+
+ if (flag & PROP_ID_SELF_CHECK) {
+ if (itemptr.data == data->target_ptr.id.data) {
+ continue;
+ }
+ }
+
+ /* use filter */
+ if (RNA_property_type(data->target_prop) == PROP_POINTER) {
+ if (RNA_property_pointer_poll(&data->target_ptr, data->target_prop, &itemptr) == 0) {
+ continue;
+ }
+ }
+
+ name = RNA_struct_name_get_alloc(
+ &itemptr, NULL, 0, NULL); /* could use the string length here */
+ iconid = 0;
+ if (itemptr.type && RNA_struct_is_ID(itemptr.type)) {
+ iconid = ui_id_icon_get(C, itemptr.data, false);
+ }
+
+ if (name) {
+ if (skip_filter || BLI_strcasestr(name, str)) {
+ cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
+ cis->data = itemptr.data;
+ cis->name = MEM_dupallocN(name);
+ cis->index = i;
+ cis->iconid = iconid;
+ BLI_addtail(items_list, cis);
+ }
+ MEM_freeN(name);
+ }
+
+ i++;
+ }
+ RNA_PROP_END;
+
+ BLI_listbase_sort(items_list, sort_search_items_list);
+
+ /* add search items from temporary list */
+ for (cis = items_list->first; cis; cis = cis->next) {
+ if (UI_search_item_add(items, cis->name, cis->data, cis->iconid) == false) {
+ break;
+ }
+ }
+
+ for (cis = items_list->first; cis; cis = cis->next) {
+ MEM_freeN(cis->name);
+ }
+ BLI_freelistN(items_list);
+ MEM_freeN(items_list);
}
-
/***************************** ID Utilities *******************************/
int UI_icon_from_id(ID *id)
{
- Object *ob;
- PointerRNA ptr;
- short idcode;
+ Object *ob;
+ PointerRNA ptr;
+ short idcode;
- if (id == NULL) {
- return ICON_NONE;
- }
+ if (id == NULL) {
+ return ICON_NONE;
+ }
- idcode = GS(id->name);
+ idcode = GS(id->name);
- /* exception for objects */
- if (idcode == ID_OB) {
- ob = (Object *)id;
+ /* exception for objects */
+ if (idcode == ID_OB) {
+ ob = (Object *)id;
- if (ob->type == OB_EMPTY) {
- return ICON_EMPTY_DATA;
- }
- else {
- return UI_icon_from_id(ob->data);
- }
- }
+ if (ob->type == OB_EMPTY) {
+ return ICON_EMPTY_DATA;
+ }
+ else {
+ return UI_icon_from_id(ob->data);
+ }
+ }
- /* otherwise get it through RNA, creating the pointer
- * will set the right type, also with subclassing */
- RNA_id_pointer_create(id, &ptr);
+ /* otherwise get it through RNA, creating the pointer
+ * will set the right type, also with subclassing */
+ RNA_id_pointer_create(id, &ptr);
- return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE;
+ return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE;
}
/* see: report_type_str */
int UI_icon_from_report_type(int type)
{
- if (type & RPT_ERROR_ALL) {
- return ICON_ERROR;
- }
- else if (type & RPT_WARNING_ALL) {
- return ICON_ERROR;
- }
- else if (type & RPT_INFO_ALL) {
- return ICON_INFO;
- }
- else {
- return ICON_NONE;
- }
+ if (type & RPT_ERROR_ALL) {
+ return ICON_ERROR;
+ }
+ else if (type & RPT_WARNING_ALL) {
+ return ICON_ERROR;
+ }
+ else if (type & RPT_INFO_ALL) {
+ return ICON_INFO;
+ }
+ else {
+ return ICON_NONE;
+ }
}
/********************************** Misc **************************************/
@@ -390,84 +512,86 @@ int UI_icon_from_report_type(int type)
*/
int UI_calc_float_precision(int prec, double value)
{
- static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6};
- static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */
-
- BLI_assert(prec <= UI_PRECISION_FLOAT_MAX);
- BLI_assert(fabs(pow10_neg[prec] - pow(10, -prec)) < 1e-16);
-
- /* check on the number of decimal places need to display the number, this is so 0.00001 is not displayed as 0.00,
- * _but_, this is only for small values si 10.0001 will not get the same treatment.
- */
- value = ABS(value);
- if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
- int value_i = (int)((value * max_pow) + 0.5);
- if (value_i != 0) {
- const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
- int test_prec;
- int prec_min = -1;
- int dec_flag = 0;
- int i = UI_PRECISION_FLOAT_MAX;
- while (i && value_i) {
- if (value_i % 10) {
- dec_flag |= 1 << i;
- prec_min = i;
- }
- value_i /= 10;
- i--;
- }
-
- /* even though its a small value, if the second last digit is not 0, use it */
- test_prec = prec_min;
-
- dec_flag = (dec_flag >> (prec_min + 1)) & ((1 << prec_span) - 1);
-
- while (dec_flag) {
- test_prec++;
- dec_flag = dec_flag >> 1;
- }
-
- if (test_prec > prec) {
- prec = test_prec;
- }
- }
- }
-
- CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
-
- return prec;
+ static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {
+ 1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6};
+ static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */
+
+ BLI_assert(prec <= UI_PRECISION_FLOAT_MAX);
+ BLI_assert(fabs(pow10_neg[prec] - pow(10, -prec)) < 1e-16);
+
+ /* check on the number of decimal places need to display the number, this is so 0.00001 is not displayed as 0.00,
+ * _but_, this is only for small values si 10.0001 will not get the same treatment.
+ */
+ value = ABS(value);
+ if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
+ int value_i = (int)((value * max_pow) + 0.5);
+ if (value_i != 0) {
+ const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
+ int test_prec;
+ int prec_min = -1;
+ int dec_flag = 0;
+ int i = UI_PRECISION_FLOAT_MAX;
+ while (i && value_i) {
+ if (value_i % 10) {
+ dec_flag |= 1 << i;
+ prec_min = i;
+ }
+ value_i /= 10;
+ i--;
+ }
+
+ /* even though its a small value, if the second last digit is not 0, use it */
+ test_prec = prec_min;
+
+ dec_flag = (dec_flag >> (prec_min + 1)) & ((1 << prec_span) - 1);
+
+ while (dec_flag) {
+ test_prec++;
+ dec_flag = dec_flag >> 1;
+ }
+
+ if (test_prec > prec) {
+ prec = test_prec;
+ }
+ }
+ }
+
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+
+ return prec;
}
bool UI_but_online_manual_id(const uiBut *but, char *r_str, size_t maxlength)
{
- if (but->rnapoin.id.data && but->rnapoin.data && but->rnaprop) {
- BLI_snprintf(
- r_str, maxlength, "%s.%s", RNA_struct_identifier(but->rnapoin.type),
- RNA_property_identifier(but->rnaprop));
- return true;
- }
- else if (but->optype) {
- WM_operator_py_idname(r_str, but->optype->idname);
- return true;
- }
-
- *r_str = '\0';
- return false;
+ if (but->rnapoin.id.data && but->rnapoin.data && but->rnaprop) {
+ BLI_snprintf(r_str,
+ maxlength,
+ "%s.%s",
+ RNA_struct_identifier(but->rnapoin.type),
+ RNA_property_identifier(but->rnaprop));
+ return true;
+ }
+ else if (but->optype) {
+ WM_operator_py_idname(r_str, but->optype->idname);
+ return true;
+ }
+
+ *r_str = '\0';
+ return false;
}
bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str, size_t maxlength)
{
- uiBut *but = UI_context_active_but_get(C);
+ uiBut *but = UI_context_active_but_get(C);
- if (but) {
- return UI_but_online_manual_id(but, r_str, maxlength);
- }
+ if (but) {
+ return UI_but_online_manual_id(but, r_str, maxlength);
+ }
- *r_str = '\0';
- return false;
+ *r_str = '\0';
+ return false;
}
-
/* -------------------------------------------------------------------- */
/* Modal Button Store API */
@@ -481,14 +605,14 @@ bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str,
* \{ */
struct uiButStore {
- struct uiButStore *next, *prev;
- uiBlock *block;
- ListBase items;
+ struct uiButStore *next, *prev;
+ uiBlock *block;
+ ListBase items;
};
struct uiButStoreElem {
- struct uiButStoreElem *next, *prev;
- uiBut **but_p;
+ struct uiButStoreElem *next, *prev;
+ uiBut **but_p;
};
/**
@@ -496,78 +620,77 @@ struct uiButStoreElem {
*/
uiButStore *UI_butstore_create(uiBlock *block)
{
- uiButStore *bs_handle = MEM_callocN(sizeof(uiButStore), __func__);
+ uiButStore *bs_handle = MEM_callocN(sizeof(uiButStore), __func__);
- bs_handle->block = block;
- BLI_addtail(&block->butstore, bs_handle);
+ bs_handle->block = block;
+ BLI_addtail(&block->butstore, bs_handle);
- return bs_handle;
+ return bs_handle;
}
void UI_butstore_free(uiBlock *block, uiButStore *bs_handle)
{
- /* Workaround for button store being moved into new block,
- * which then can't use the previous buttons state ('ui_but_update_from_old_block' fails to find a match),
- * keeping the active button in the old block holding a reference to the button-state in the new block: see T49034.
- *
- * Ideally we would manage moving the 'uiButStore', keeping a correct state.
- * All things considered this is the most straightforward fix - Campbell.
- */
- if (block != bs_handle->block && bs_handle->block != NULL) {
- block = bs_handle->block;
- }
-
- BLI_freelistN(&bs_handle->items);
- BLI_remlink(&block->butstore, bs_handle);
-
- MEM_freeN(bs_handle);
+ /* Workaround for button store being moved into new block,
+ * which then can't use the previous buttons state ('ui_but_update_from_old_block' fails to find a match),
+ * keeping the active button in the old block holding a reference to the button-state in the new block: see T49034.
+ *
+ * Ideally we would manage moving the 'uiButStore', keeping a correct state.
+ * All things considered this is the most straightforward fix - Campbell.
+ */
+ if (block != bs_handle->block && bs_handle->block != NULL) {
+ block = bs_handle->block;
+ }
+
+ BLI_freelistN(&bs_handle->items);
+ BLI_remlink(&block->butstore, bs_handle);
+
+ MEM_freeN(bs_handle);
}
bool UI_butstore_is_valid(uiButStore *bs)
{
- return (bs->block != NULL);
+ return (bs->block != NULL);
}
bool UI_butstore_is_registered(uiBlock *block, uiBut *but)
{
- uiButStore *bs_handle;
+ uiButStore *bs_handle;
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+ uiButStoreElem *bs_elem;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- if (*bs_elem->but_p == but) {
- return true;
- }
- }
- }
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ if (*bs_elem->but_p == but) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p)
{
- uiButStoreElem *bs_elem = MEM_callocN(sizeof(uiButStoreElem), __func__);
- BLI_assert(*but_p);
- bs_elem->but_p = but_p;
-
- BLI_addtail(&bs_handle->items, bs_elem);
+ uiButStoreElem *bs_elem = MEM_callocN(sizeof(uiButStoreElem), __func__);
+ BLI_assert(*but_p);
+ bs_elem->but_p = but_p;
+ BLI_addtail(&bs_handle->items, bs_elem);
}
void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
{
- uiButStoreElem *bs_elem, *bs_elem_next;
+ uiButStoreElem *bs_elem, *bs_elem_next;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) {
- bs_elem_next = bs_elem->next;
- if (bs_elem->but_p == but_p) {
- BLI_remlink(&bs_handle->items, bs_elem);
- MEM_freeN(bs_elem);
- }
- }
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) {
+ bs_elem_next = bs_elem->next;
+ if (bs_elem->but_p == but_p) {
+ BLI_remlink(&bs_handle->items, bs_elem);
+ MEM_freeN(bs_elem);
+ }
+ }
- BLI_assert(0);
+ BLI_assert(0);
}
/**
@@ -575,20 +698,20 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
*/
bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src)
{
- uiButStore *bs_handle;
- bool found = false;
-
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- if (*bs_elem->but_p == but_src) {
- *bs_elem->but_p = but_dst;
- found = true;
- }
- }
- }
-
- return found;
+ uiButStore *bs_handle;
+ bool found = false;
+
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+ uiButStoreElem *bs_elem;
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ if (*bs_elem->but_p == but_src) {
+ *bs_elem->but_p = but_dst;
+ found = true;
+ }
+ }
+ }
+
+ return found;
}
/**
@@ -596,17 +719,17 @@ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *bu
*/
void UI_butstore_clear(uiBlock *block)
{
- uiButStore *bs_handle;
+ uiButStore *bs_handle;
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+ uiButStoreElem *bs_elem;
- bs_handle->block = NULL;
+ bs_handle->block = NULL;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- *bs_elem->but_p = NULL;
- }
- }
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ *bs_elem->but_p = NULL;
+ }
+ }
}
/**
@@ -614,45 +737,44 @@ void UI_butstore_clear(uiBlock *block)
*/
void UI_butstore_update(uiBlock *block)
{
- uiButStore *bs_handle;
-
- /* move this list to the new block */
- if (block->oldblock) {
- if (block->oldblock->butstore.first) {
- block->butstore = block->oldblock->butstore;
- BLI_listbase_clear(&block->oldblock->butstore);
- }
- }
-
- if (LIKELY(block->butstore.first == NULL)) {
- return;
- }
-
- /* warning, loop-in-loop, in practice we only store <10 buttons at a time,
- * so this isn't going to be a problem, if that changes old-new mapping can be cached first */
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
-
- BLI_assert((bs_handle->block == NULL) ||
- (bs_handle->block == block) ||
- (block->oldblock && block->oldblock == bs_handle->block));
-
- if (bs_handle->block == block->oldblock) {
- uiButStoreElem *bs_elem;
-
- bs_handle->block = block;
-
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
- if (*bs_elem->but_p) {
- uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
-
- /* can be NULL if the buttons removed,
- * note: we could allow passing in a callback when buttons are removed
- * so the caller can cleanup */
- *bs_elem->but_p = but_new;
- }
- }
- }
- }
+ uiButStore *bs_handle;
+
+ /* move this list to the new block */
+ if (block->oldblock) {
+ if (block->oldblock->butstore.first) {
+ block->butstore = block->oldblock->butstore;
+ BLI_listbase_clear(&block->oldblock->butstore);
+ }
+ }
+
+ if (LIKELY(block->butstore.first == NULL)) {
+ return;
+ }
+
+ /* warning, loop-in-loop, in practice we only store <10 buttons at a time,
+ * so this isn't going to be a problem, if that changes old-new mapping can be cached first */
+ for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
+
+ BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) ||
+ (block->oldblock && block->oldblock == bs_handle->block));
+
+ if (bs_handle->block == block->oldblock) {
+ uiButStoreElem *bs_elem;
+
+ bs_handle->block = block;
+
+ for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ if (*bs_elem->but_p) {
+ uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
+
+ /* can be NULL if the buttons removed,
+ * note: we could allow passing in a callback when buttons are removed
+ * so the caller can cleanup */
+ *bs_elem->but_p = but_new;
+ }
+ }
+ }
+ }
}
/** \} */
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 6528faca265..e18a2e6068a 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -64,73 +64,67 @@
/* visual types for drawing */
/* for time being separated from functional types */
typedef enum {
- /* default */
- UI_WTYPE_REGULAR,
-
- /* standard set */
- UI_WTYPE_LABEL,
- UI_WTYPE_TOGGLE,
- UI_WTYPE_CHECKBOX,
- UI_WTYPE_RADIO,
- UI_WTYPE_NUMBER,
- UI_WTYPE_SLIDER,
- UI_WTYPE_EXEC,
- UI_WTYPE_TOOLBAR_ITEM,
- UI_WTYPE_TAB,
- UI_WTYPE_TOOLTIP,
-
- /* strings */
- UI_WTYPE_NAME,
- UI_WTYPE_NAME_LINK,
- UI_WTYPE_POINTER_LINK,
- UI_WTYPE_FILENAME,
-
- /* menus */
- UI_WTYPE_MENU_RADIO,
- UI_WTYPE_MENU_ICON_RADIO,
- UI_WTYPE_MENU_POINTER_LINK,
- UI_WTYPE_MENU_NODE_LINK,
-
- UI_WTYPE_PULLDOWN,
- UI_WTYPE_MENU_ITEM,
- UI_WTYPE_MENU_ITEM_RADIAL,
- UI_WTYPE_MENU_BACK,
-
- /* specials */
- UI_WTYPE_ICON,
- UI_WTYPE_ICON_LABEL,
- UI_WTYPE_SWATCH,
- UI_WTYPE_RGB_PICKER,
- UI_WTYPE_UNITVEC,
- UI_WTYPE_BOX,
- UI_WTYPE_SCROLL,
- UI_WTYPE_LISTITEM,
- UI_WTYPE_PROGRESSBAR,
+ /* default */
+ UI_WTYPE_REGULAR,
+
+ /* standard set */
+ UI_WTYPE_LABEL,
+ UI_WTYPE_TOGGLE,
+ UI_WTYPE_CHECKBOX,
+ UI_WTYPE_RADIO,
+ UI_WTYPE_NUMBER,
+ UI_WTYPE_SLIDER,
+ UI_WTYPE_EXEC,
+ UI_WTYPE_TOOLBAR_ITEM,
+ UI_WTYPE_TAB,
+ UI_WTYPE_TOOLTIP,
+
+ /* strings */
+ UI_WTYPE_NAME,
+ UI_WTYPE_NAME_LINK,
+ UI_WTYPE_POINTER_LINK,
+ UI_WTYPE_FILENAME,
+
+ /* menus */
+ UI_WTYPE_MENU_RADIO,
+ UI_WTYPE_MENU_ICON_RADIO,
+ UI_WTYPE_MENU_POINTER_LINK,
+ UI_WTYPE_MENU_NODE_LINK,
+
+ UI_WTYPE_PULLDOWN,
+ UI_WTYPE_MENU_ITEM,
+ UI_WTYPE_MENU_ITEM_RADIAL,
+ UI_WTYPE_MENU_BACK,
+
+ /* specials */
+ UI_WTYPE_ICON,
+ UI_WTYPE_ICON_LABEL,
+ UI_WTYPE_SWATCH,
+ UI_WTYPE_RGB_PICKER,
+ UI_WTYPE_UNITVEC,
+ UI_WTYPE_BOX,
+ UI_WTYPE_SCROLL,
+ UI_WTYPE_LISTITEM,
+ UI_WTYPE_PROGRESSBAR,
} uiWidgetTypeEnum;
-
/* Button state argument shares bits with 'uiBut.flag'.
* reuse flags that aren't needed for drawing to avoid collision. */
enum {
- /* Show that holding the button opens a menu. */
- UI_STATE_HOLD_ACTION = UI_BUT_UPDATE_DELAY,
- UI_STATE_TEXT_INPUT = UI_BUT_UNDO,
- UI_STATE_ACTIVE_LEFT = UI_BUT_VALUE_CLEAR,
- UI_STATE_ACTIVE_RIGHT = UI_BUT_TEXTEDIT_UPDATE,
- UI_STATE_TEXT_BEFORE_WIDGET = UI_BUT_IMMEDIATE,
-
- UI_STATE_FLAGS_ALL = (
- UI_STATE_HOLD_ACTION |
- UI_STATE_TEXT_INPUT |
- UI_STATE_ACTIVE_LEFT |
- UI_STATE_ACTIVE_RIGHT |
- UI_STATE_TEXT_BEFORE_WIDGET),
+ /* Show that holding the button opens a menu. */
+ UI_STATE_HOLD_ACTION = UI_BUT_UPDATE_DELAY,
+ UI_STATE_TEXT_INPUT = UI_BUT_UNDO,
+ UI_STATE_ACTIVE_LEFT = UI_BUT_VALUE_CLEAR,
+ UI_STATE_ACTIVE_RIGHT = UI_BUT_TEXTEDIT_UPDATE,
+ UI_STATE_TEXT_BEFORE_WIDGET = UI_BUT_IMMEDIATE,
+
+ UI_STATE_FLAGS_ALL = (UI_STATE_HOLD_ACTION | UI_STATE_TEXT_INPUT | UI_STATE_ACTIVE_LEFT |
+ UI_STATE_ACTIVE_RIGHT | UI_STATE_TEXT_BEFORE_WIDGET),
};
/* Prevent accidental use. */
#define UI_BUT_UPDATE_DELAY ((void)0)
#define UI_BUT_UNDO ((void)0)
-
/* ************** widget base functions ************** */
/**
* - in: roundbox codes for corner types and radius
@@ -149,12 +143,12 @@ enum {
/* it has outline, back, and two optional tria meshes */
typedef struct uiWidgetTrias {
- uint tot;
- int type;
- float size, center[2];
+ uint tot;
+ int type;
+ float size, center[2];
- float vec[16][2];
- const uint (*index)[3];
+ float vec[16][2];
+ const uint (*index)[3];
} uiWidgetTrias;
@@ -164,19 +158,19 @@ typedef struct uiWidgetTrias {
#define WIDGET_SIZE_MAX (WIDGET_CURVE_RESOLU * 4)
typedef struct uiWidgetBase {
- /* TODO remove these completely */
- int totvert, halfwayvert;
- float outer_v[WIDGET_SIZE_MAX][2];
- float inner_v[WIDGET_SIZE_MAX][2];
- float inner_uv[WIDGET_SIZE_MAX][2];
+ /* TODO remove these completely */
+ int totvert, halfwayvert;
+ float outer_v[WIDGET_SIZE_MAX][2];
+ float inner_v[WIDGET_SIZE_MAX][2];
+ float inner_uv[WIDGET_SIZE_MAX][2];
- bool draw_inner, draw_outline, draw_emboss;
+ bool draw_inner, draw_outline, draw_emboss;
- uiWidgetTrias tria1;
- uiWidgetTrias tria2;
+ uiWidgetTrias tria1;
+ uiWidgetTrias tria2;
- /* Widget shader parameters, must match the shader layout. */
- uiWidgetBaseParameters uniform_params;
+ /* Widget shader parameters, must match the shader layout. */
+ uiWidgetBaseParameters uniform_params;
} uiWidgetBase;
/** uiWidgetType: for time being only for visual appearance,
@@ -184,35 +178,43 @@ typedef struct uiWidgetBase {
*/
typedef struct uiWidgetType {
- /* pointer to theme color definition */
- const uiWidgetColors *wcol_theme;
- uiWidgetStateColors *wcol_state;
+ /* pointer to theme color definition */
+ const uiWidgetColors *wcol_theme;
+ uiWidgetStateColors *wcol_state;
- /* converted colors for state */
- uiWidgetColors wcol;
+ /* converted colors for state */
+ uiWidgetColors wcol;
- void (*state)(struct uiWidgetType *, int state, int drawflag);
- void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign);
- void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign);
- void (*text)(const uiFontStyle *, const uiWidgetColors *, uiBut *, rcti *);
+ void (*state)(struct uiWidgetType *, int state, int drawflag);
+ void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign);
+ void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign);
+ void (*text)(const uiFontStyle *, const uiWidgetColors *, uiBut *, rcti *);
} uiWidgetType;
-
/* *********************** draw data ************************** */
static const float cornervec[WIDGET_CURVE_RESOLU][2] = {
- {0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067},
- {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45},
- {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0},
+ {0.0, 0.0},
+ {0.195, 0.02},
+ {0.383, 0.067},
+ {0.55, 0.169},
+ {0.707, 0.293},
+ {0.831, 0.45},
+ {0.924, 0.617},
+ {0.98, 0.805},
+ {1.0, 1.0},
};
-
const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2] = {
- { 0.468813, -0.481430}, {-0.155755, -0.352820},
- { 0.219306, -0.238501}, {-0.393286, -0.110949},
- {-0.024699, 0.013908}, { 0.343805, 0.147431},
- {-0.272855, 0.269918}, { 0.095909, 0.388710},
+ {0.468813, -0.481430},
+ {-0.155755, -0.352820},
+ {0.219306, -0.238501},
+ {-0.393286, -0.110949},
+ {-0.024699, 0.013908},
+ {0.343805, 0.147431},
+ {-0.272855, 0.269918},
+ {0.095909, 0.388710},
};
#define WIDGET_AA_JITTER UI_PIXEL_AA_JITTER
#define jit ui_pixel_jitter
@@ -222,42 +224,81 @@ const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2] = {
* \{ */
static const float g_shape_preset_number_arrow_vert[3][2] = {
- {-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.330000, -0.008353},
+ {-0.352077, 0.532607},
+ {-0.352077, -0.549313},
+ {0.330000, -0.008353},
};
static const uint g_shape_preset_number_arrow_face[1][3] = {
- {0, 1, 2},
+ {0, 1, 2},
};
static const float g_shape_preset_scroll_circle_vert[16][2] = {
- {0.382684, 0.923879}, {0.000001, 1.000000}, {-0.382683, 0.923880}, {-0.707107, 0.707107},
- {-0.923879, 0.382684}, {-1.000000, 0.000000}, {-0.923880, -0.382684}, {-0.707107, -0.707107},
- {-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107},
- {0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107},
+ {0.382684, 0.923879},
+ {0.000001, 1.000000},
+ {-0.382683, 0.923880},
+ {-0.707107, 0.707107},
+ {-0.923879, 0.382684},
+ {-1.000000, 0.000000},
+ {-0.923880, -0.382684},
+ {-0.707107, -0.707107},
+ {-0.382683, -0.923880},
+ {0.000000, -1.000000},
+ {0.382684, -0.923880},
+ {0.707107, -0.707107},
+ {0.923880, -0.382684},
+ {1.000000, -0.000000},
+ {0.923880, 0.382683},
+ {0.707107, 0.707107},
};
static const uint g_shape_preset_scroll_circle_face[14][3] = {
- {0, 1, 2}, {2, 0, 3}, {3, 0, 15}, {3, 15, 4}, {4, 15, 14}, {4, 14, 5}, {5, 14, 13}, {5, 13, 6},
- {6, 13, 12}, {6, 12, 7}, {7, 12, 11}, {7, 11, 8}, {8, 11, 10}, {8, 10, 9},
+ {0, 1, 2},
+ {2, 0, 3},
+ {3, 0, 15},
+ {3, 15, 4},
+ {4, 15, 14},
+ {4, 14, 5},
+ {5, 14, 13},
+ {5, 13, 6},
+ {6, 13, 12},
+ {6, 12, 7},
+ {7, 12, 11},
+ {7, 11, 8},
+ {8, 11, 10},
+ {8, 10, 9},
};
static const float g_shape_preset_menu_arrow_vert[6][2] = {
- {-0.33, 0.16}, {0.33, 0.16}, {0, 0.82},
- {0, -0.82}, {-0.33, -0.16}, {0.33, -0.16},
+ {-0.33, 0.16},
+ {0.33, 0.16},
+ {0, 0.82},
+ {0, -0.82},
+ {-0.33, -0.16},
+ {0.33, -0.16},
};
static const uint g_shape_preset_menu_arrow_face[2][3] = {{2, 0, 1}, {3, 5, 4}};
static const float g_shape_preset_checkmark_vert[6][2] = {
- {-0.578579, 0.253369}, {-0.392773, 0.412794}, {-0.004241, -0.328551},
- {-0.003001, 0.034320}, {1.055313, 0.864744}, {0.866408, 1.026895},
+ {-0.578579, 0.253369},
+ {-0.392773, 0.412794},
+ {-0.004241, -0.328551},
+ {-0.003001, 0.034320},
+ {1.055313, 0.864744},
+ {0.866408, 1.026895},
};
static const uint g_shape_preset_checkmark_face[4][3] = {
- {3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3},
+ {3, 2, 4},
+ {3, 4, 5},
+ {1, 0, 3},
+ {0, 2, 3},
};
#define OY (-0.2 / 2)
#define SC (0.35 * 2)
static const float g_shape_preset_hold_action_vert[6][2] = {
- {-0.5 + SC, 1.0 + OY}, {0.5, 1.0 + OY}, {0.5, 0.0 + OY + SC},
+ {-0.5 + SC, 1.0 + OY},
+ {0.5, 1.0 + OY},
+ {0.5, 0.0 + OY + SC},
};
static const uint g_shape_preset_hold_action_face[2][3] = {{2, 0, 1}, {3, 5, 4}};
#undef OY
@@ -274,41 +315,42 @@ static const uint g_shape_preset_hold_action_face[2][3] = {{2, 0, 1}, {3, 5, 4}}
/* offset in triavec[] in shader per type */
static const int tria_ofs[ROUNDBOX_TRIA_MAX] = {
- [ROUNDBOX_TRIA_NONE] = 0,
- [ROUNDBOX_TRIA_ARROWS] = 0,
- [ROUNDBOX_TRIA_SCROLL] = 12,
- [ROUNDBOX_TRIA_MENU] = 28,
- [ROUNDBOX_TRIA_CHECK] = 34,
- [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 40,
+ [ROUNDBOX_TRIA_NONE] = 0,
+ [ROUNDBOX_TRIA_ARROWS] = 0,
+ [ROUNDBOX_TRIA_SCROLL] = 12,
+ [ROUNDBOX_TRIA_MENU] = 28,
+ [ROUNDBOX_TRIA_CHECK] = 34,
+ [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 40,
};
static const int tria_vcount[ROUNDBOX_TRIA_MAX] = {
- [ROUNDBOX_TRIA_NONE] = 0,
- [ROUNDBOX_TRIA_ARROWS] = 6,
- [ROUNDBOX_TRIA_SCROLL] = 16,
- [ROUNDBOX_TRIA_MENU] = 6,
- [ROUNDBOX_TRIA_CHECK] = 6,
- [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 3,
+ [ROUNDBOX_TRIA_NONE] = 0,
+ [ROUNDBOX_TRIA_ARROWS] = 6,
+ [ROUNDBOX_TRIA_SCROLL] = 16,
+ [ROUNDBOX_TRIA_MENU] = 6,
+ [ROUNDBOX_TRIA_CHECK] = 6,
+ [ROUNDBOX_TRIA_HOLD_ACTION_ARROW] = 3,
};
static struct {
- GPUBatch *roundbox_widget[ROUNDBOX_TRIA_MAX];
+ GPUBatch *roundbox_widget[ROUNDBOX_TRIA_MAX];
- GPUBatch *roundbox_simple;
- GPUBatch *roundbox_simple_aa;
- GPUBatch *roundbox_simple_outline;
- GPUBatch *roundbox_shadow;
+ GPUBatch *roundbox_simple;
+ GPUBatch *roundbox_simple_aa;
+ GPUBatch *roundbox_simple_outline;
+ GPUBatch *roundbox_shadow;
- GPUVertFormat format;
- uint vflag_id;
+ GPUVertFormat format;
+ uint vflag_id;
} g_ui_batch_cache = {{0}};
static GPUVertFormat *vflag_format(void)
{
- if (g_ui_batch_cache.format.attr_len == 0) {
- GPUVertFormat *format = &g_ui_batch_cache.format;
- g_ui_batch_cache.vflag_id = GPU_vertformat_attr_add(format, "vflag", GPU_COMP_U32, 1, GPU_FETCH_INT);
- }
- return &g_ui_batch_cache.format;
+ if (g_ui_batch_cache.format.attr_len == 0) {
+ GPUVertFormat *format = &g_ui_batch_cache.format;
+ g_ui_batch_cache.vflag_id = GPU_vertformat_attr_add(
+ format, "vflag", GPU_COMP_U32, 1, GPU_FETCH_INT);
+ }
+ return &g_ui_batch_cache.format;
}
#define INNER 0
@@ -316,231 +358,236 @@ static GPUVertFormat *vflag_format(void)
#define EMBOSS 2
#define NO_AA WIDGET_AA_JITTER
-static void set_roundbox_vertex_data(
- GPUVertBufRaw *vflag_step, uint32_t d)
+static void set_roundbox_vertex_data(GPUVertBufRaw *vflag_step, uint32_t d)
{
- uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
- *data = d;
+ uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
+ *data = d;
}
-static uint32_t set_roundbox_vertex(
- GPUVertBufRaw *vflag_step,
- int corner_id, int corner_v, int jit_v, bool inner, bool emboss, int color)
+static uint32_t set_roundbox_vertex(GPUVertBufRaw *vflag_step,
+ int corner_id,
+ int corner_v,
+ int jit_v,
+ bool inner,
+ bool emboss,
+ int color)
{
- uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
- *data = corner_id;
- *data |= corner_v << 2;
- *data |= jit_v << 6;
- *data |= color << 12;
- *data |= (inner) ? (1 << 10) : 0; /* is inner vert */
- *data |= (emboss) ? (1 << 11) : 0; /* is emboss vert */
- return *data;
+ uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
+ *data = corner_id;
+ *data |= corner_v << 2;
+ *data |= jit_v << 6;
+ *data |= color << 12;
+ *data |= (inner) ? (1 << 10) : 0; /* is inner vert */
+ *data |= (emboss) ? (1 << 11) : 0; /* is emboss vert */
+ return *data;
}
static uint32_t set_tria_vertex(
- GPUVertBufRaw *vflag_step,
- int tria_type, int tria_v, int tria_id, int jit_v)
+ GPUVertBufRaw *vflag_step, int tria_type, int tria_v, int tria_id, int jit_v)
{
- uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
- if (ELEM(tria_type, ROUNDBOX_TRIA_ARROWS)) {
- tria_v += tria_id * tria_vcount[ROUNDBOX_TRIA_ARROWS];
- }
- *data = tria_ofs[tria_type] + tria_v;
- *data |= jit_v << 6;
- *data |= (tria_id == 0) ? (1 << 10) : 0; /* is first tria */
- *data |= 1 << 14; /* is tria vert */
- return *data;
+ uint32_t *data = GPU_vertbuf_raw_step(vflag_step);
+ if (ELEM(tria_type, ROUNDBOX_TRIA_ARROWS)) {
+ tria_v += tria_id * tria_vcount[ROUNDBOX_TRIA_ARROWS];
+ }
+ *data = tria_ofs[tria_type] + tria_v;
+ *data |= jit_v << 6;
+ *data |= (tria_id == 0) ? (1 << 10) : 0; /* is first tria */
+ *data |= 1 << 14; /* is tria vert */
+ return *data;
}
static void roundbox_batch_add_tria(GPUVertBufRaw *vflag_step, int tria, uint32_t last_data)
{
- const int tria_num = ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU) ? 1 : 2;
- /* for each tria */
- for (int t = 0; t < tria_num; ++t) {
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- /* restart */
- set_roundbox_vertex_data(vflag_step, last_data);
- set_tria_vertex(vflag_step, tria, 0, t, j);
- for (int v = 0; v < tria_vcount[tria]; v++) {
- last_data = set_tria_vertex(vflag_step, tria, v, t, j);
- }
- }
- }
+ const int tria_num =
+ ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU) ? 1 : 2;
+ /* for each tria */
+ for (int t = 0; t < tria_num; ++t) {
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ /* restart */
+ set_roundbox_vertex_data(vflag_step, last_data);
+ set_tria_vertex(vflag_step, tria, 0, t, j);
+ for (int v = 0; v < tria_vcount[tria]; v++) {
+ last_data = set_tria_vertex(vflag_step, tria, v, t, j);
+ }
+ }
+ }
}
GPUBatch *ui_batch_roundbox_widget_get(int tria)
{
- if (g_ui_batch_cache.roundbox_widget[tria] == NULL) {
- uint32_t last_data;
- GPUVertBufRaw vflag_step;
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
- int vcount = WIDGET_SIZE_MAX; /* inner */
- vcount += 2; /* restart */
- vcount += ((WIDGET_SIZE_MAX + 1) * 2) * WIDGET_AA_JITTER; /* outline (edges) */
- vcount += 2; /* restart */
- vcount += ((WIDGET_CURVE_RESOLU * 2) * 2) * WIDGET_AA_JITTER; /* emboss */
- if (tria) {
- vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria1 */
- if (!ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU)) {
- vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria2 */
- }
- }
- GPU_vertbuf_data_alloc(vbo, vcount);
- GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
- /* Inner */
- for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
- for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU -1; a2 >= 0; a1++, a2--) {
- last_data = set_roundbox_vertex(&vflag_step, c1, a1, NO_AA, true, false, INNER);
- last_data = set_roundbox_vertex(&vflag_step, c2, a2, NO_AA, true, false, INNER);
- }
- }
- /* restart */
- set_roundbox_vertex_data(&vflag_step, last_data);
- set_roundbox_vertex(&vflag_step, 0, 0, 0, true, false, OUTLINE);
- /* Outlines */
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- for (int c = 0; c < 4; c++) {
- for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
- set_roundbox_vertex(&vflag_step, c, a, j, true, false, OUTLINE);
- set_roundbox_vertex(&vflag_step, c, a, j, false, false, OUTLINE);
- }
- }
- /* Close the loop. */
- set_roundbox_vertex(&vflag_step, 0, 0, j, true, false, OUTLINE);
- last_data = set_roundbox_vertex(&vflag_step, 0, 0, j, false, false, OUTLINE);
- }
- /* restart */
- set_roundbox_vertex_data(&vflag_step, last_data);
- set_roundbox_vertex(&vflag_step, 0, 0, 0, false, false, EMBOSS);
- /* Emboss */
- /* go back and forth : avoid degenerate triangle (but beware of backface cull) */
- bool rev = false;
- for (int j = 0; j < WIDGET_AA_JITTER; j++, rev = !rev) {
- for (int c = (rev) ? 1 : 0; (rev) ? c >= 0 : c < 2; (rev) ? c-- : c++) {
- int sta = (rev) ? WIDGET_CURVE_RESOLU - 1 : 0;
- int end = WIDGET_CURVE_RESOLU;
- for (int a = sta; (rev) ? a >= 0 : a < end; (rev) ? a-- : a++) {
- set_roundbox_vertex(&vflag_step, c, a, j, false, false, EMBOSS);
- last_data = set_roundbox_vertex(&vflag_step, c, a, j, false, true, EMBOSS);
- }
- }
- }
- if (tria) {
- roundbox_batch_add_tria(&vflag_step, tria, last_data);
- }
- g_ui_batch_cache.roundbox_widget[tria] = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
- gpu_batch_presets_register(g_ui_batch_cache.roundbox_widget[tria]);
- }
- return g_ui_batch_cache.roundbox_widget[tria];
+ if (g_ui_batch_cache.roundbox_widget[tria] == NULL) {
+ uint32_t last_data;
+ GPUVertBufRaw vflag_step;
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
+ int vcount = WIDGET_SIZE_MAX; /* inner */
+ vcount += 2; /* restart */
+ vcount += ((WIDGET_SIZE_MAX + 1) * 2) * WIDGET_AA_JITTER; /* outline (edges) */
+ vcount += 2; /* restart */
+ vcount += ((WIDGET_CURVE_RESOLU * 2) * 2) * WIDGET_AA_JITTER; /* emboss */
+ if (tria) {
+ vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria1 */
+ if (!ELEM(tria, ROUNDBOX_TRIA_CHECK, ROUNDBOX_TRIA_HOLD_ACTION_ARROW, ROUNDBOX_TRIA_MENU)) {
+ vcount += (tria_vcount[tria] + 2) * WIDGET_AA_JITTER; /* tria2 */
+ }
+ }
+ GPU_vertbuf_data_alloc(vbo, vcount);
+ GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
+ /* Inner */
+ for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
+ for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU - 1; a2 >= 0; a1++, a2--) {
+ last_data = set_roundbox_vertex(&vflag_step, c1, a1, NO_AA, true, false, INNER);
+ last_data = set_roundbox_vertex(&vflag_step, c2, a2, NO_AA, true, false, INNER);
+ }
+ }
+ /* restart */
+ set_roundbox_vertex_data(&vflag_step, last_data);
+ set_roundbox_vertex(&vflag_step, 0, 0, 0, true, false, OUTLINE);
+ /* Outlines */
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ for (int c = 0; c < 4; c++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
+ set_roundbox_vertex(&vflag_step, c, a, j, true, false, OUTLINE);
+ set_roundbox_vertex(&vflag_step, c, a, j, false, false, OUTLINE);
+ }
+ }
+ /* Close the loop. */
+ set_roundbox_vertex(&vflag_step, 0, 0, j, true, false, OUTLINE);
+ last_data = set_roundbox_vertex(&vflag_step, 0, 0, j, false, false, OUTLINE);
+ }
+ /* restart */
+ set_roundbox_vertex_data(&vflag_step, last_data);
+ set_roundbox_vertex(&vflag_step, 0, 0, 0, false, false, EMBOSS);
+ /* Emboss */
+ /* go back and forth : avoid degenerate triangle (but beware of backface cull) */
+ bool rev = false;
+ for (int j = 0; j < WIDGET_AA_JITTER; j++, rev = !rev) {
+ for (int c = (rev) ? 1 : 0; (rev) ? c >= 0 : c < 2; (rev) ? c-- : c++) {
+ int sta = (rev) ? WIDGET_CURVE_RESOLU - 1 : 0;
+ int end = WIDGET_CURVE_RESOLU;
+ for (int a = sta; (rev) ? a >= 0 : a < end; (rev) ? a-- : a++) {
+ set_roundbox_vertex(&vflag_step, c, a, j, false, false, EMBOSS);
+ last_data = set_roundbox_vertex(&vflag_step, c, a, j, false, true, EMBOSS);
+ }
+ }
+ }
+ if (tria) {
+ roundbox_batch_add_tria(&vflag_step, tria, last_data);
+ }
+ g_ui_batch_cache.roundbox_widget[tria] = GPU_batch_create_ex(
+ GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ gpu_batch_presets_register(g_ui_batch_cache.roundbox_widget[tria]);
+ }
+ return g_ui_batch_cache.roundbox_widget[tria];
}
GPUBatch *ui_batch_roundbox_get(bool filled, bool antialiased)
{
- GPUBatch **batch = NULL;
-
- if (filled) {
- if (antialiased) {
- batch = &g_ui_batch_cache.roundbox_simple_aa;
- }
- else {
- batch = &g_ui_batch_cache.roundbox_simple;
- }
- }
- else {
- if (antialiased) {
- BLI_assert(0); /* Use GL_LINE_SMOOTH instead!!: */
- }
- else {
- batch = &g_ui_batch_cache.roundbox_simple_outline;
- }
- }
-
- if (*batch == NULL) {
- uint32_t last_data;
- GPUVertBufRaw vflag_step;
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
- int vcount = WIDGET_SIZE_MAX;
- vcount += (filled) ? 2 : 0;
- vcount *= (antialiased) ? WIDGET_AA_JITTER : 1;
- GPU_vertbuf_data_alloc(vbo, vcount);
- GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
-
- if (filled) {
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- if (!antialiased) {
- j = NO_AA;
- }
- /* restart */
- set_roundbox_vertex(&vflag_step, 0, 0, j, true, false, INNER);
- for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
- for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU -1; a2 >= 0; a1++, a2--) {
- last_data = set_roundbox_vertex(&vflag_step, c1, a1, j, true, false, INNER);
- last_data = set_roundbox_vertex(&vflag_step, c2, a2, j, true, false, INNER);
- }
- }
- /* restart */
- set_roundbox_vertex_data(&vflag_step, last_data);
- if (!antialiased) {
- break;
- }
- }
- *batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
- else {
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- if (!antialiased) {
- j = NO_AA;
- }
- for (int c = 0; c < 4; c++) {
- for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
- set_roundbox_vertex(&vflag_step, c, a, j, true, false, INNER);
- }
- }
- if (!antialiased) {
- break;
- }
- }
- *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO);
- }
-
- gpu_batch_presets_register(*batch);
- }
- return *batch;
+ GPUBatch **batch = NULL;
+
+ if (filled) {
+ if (antialiased) {
+ batch = &g_ui_batch_cache.roundbox_simple_aa;
+ }
+ else {
+ batch = &g_ui_batch_cache.roundbox_simple;
+ }
+ }
+ else {
+ if (antialiased) {
+ BLI_assert(0); /* Use GL_LINE_SMOOTH instead!!: */
+ }
+ else {
+ batch = &g_ui_batch_cache.roundbox_simple_outline;
+ }
+ }
+
+ if (*batch == NULL) {
+ uint32_t last_data;
+ GPUVertBufRaw vflag_step;
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
+ int vcount = WIDGET_SIZE_MAX;
+ vcount += (filled) ? 2 : 0;
+ vcount *= (antialiased) ? WIDGET_AA_JITTER : 1;
+ GPU_vertbuf_data_alloc(vbo, vcount);
+ GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
+
+ if (filled) {
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ if (!antialiased) {
+ j = NO_AA;
+ }
+ /* restart */
+ set_roundbox_vertex(&vflag_step, 0, 0, j, true, false, INNER);
+ for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
+ for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU - 1; a2 >= 0; a1++, a2--) {
+ last_data = set_roundbox_vertex(&vflag_step, c1, a1, j, true, false, INNER);
+ last_data = set_roundbox_vertex(&vflag_step, c2, a2, j, true, false, INNER);
+ }
+ }
+ /* restart */
+ set_roundbox_vertex_data(&vflag_step, last_data);
+ if (!antialiased) {
+ break;
+ }
+ }
+ *batch = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+ else {
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ if (!antialiased) {
+ j = NO_AA;
+ }
+ for (int c = 0; c < 4; c++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
+ set_roundbox_vertex(&vflag_step, c, a, j, true, false, INNER);
+ }
+ }
+ if (!antialiased) {
+ break;
+ }
+ }
+ *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ }
+
+ gpu_batch_presets_register(*batch);
+ }
+ return *batch;
}
GPUBatch *ui_batch_roundbox_shadow_get(void)
{
- if (g_ui_batch_cache.roundbox_shadow == NULL) {
- uint32_t last_data;
- GPUVertBufRaw vflag_step;
- GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
- int vcount = (WIDGET_SIZE_MAX + 1) * 2 + 2 + WIDGET_SIZE_MAX;
- GPU_vertbuf_data_alloc(vbo, vcount);
- GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
-
- for (int c = 0; c < 4; c++) {
- for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
- set_roundbox_vertex(&vflag_step, c, a, NO_AA, true, false, INNER);
- set_roundbox_vertex(&vflag_step, c, a, NO_AA, false, false, INNER);
- }
- }
- /* close loop */
- last_data = set_roundbox_vertex(&vflag_step, 0, 0, NO_AA, true, false, INNER);
- last_data = set_roundbox_vertex(&vflag_step, 0, 0, NO_AA, false, false, INNER);
- /* restart */
- set_roundbox_vertex_data(&vflag_step, last_data);
- set_roundbox_vertex(&vflag_step, 0, 0, NO_AA, true, false, INNER);
- /* filled */
- for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
- for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU -1; a2 >= 0; a1++, a2--) {
- set_roundbox_vertex(&vflag_step, c1, a1, NO_AA, true, false, INNER);
- set_roundbox_vertex(&vflag_step, c2, a2, NO_AA, true, false, INNER);
- }
- }
- g_ui_batch_cache.roundbox_shadow = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
- gpu_batch_presets_register(g_ui_batch_cache.roundbox_shadow);
- }
- return g_ui_batch_cache.roundbox_shadow;
+ if (g_ui_batch_cache.roundbox_shadow == NULL) {
+ uint32_t last_data;
+ GPUVertBufRaw vflag_step;
+ GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format());
+ int vcount = (WIDGET_SIZE_MAX + 1) * 2 + 2 + WIDGET_SIZE_MAX;
+ GPU_vertbuf_data_alloc(vbo, vcount);
+ GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step);
+
+ for (int c = 0; c < 4; c++) {
+ for (int a = 0; a < WIDGET_CURVE_RESOLU; a++) {
+ set_roundbox_vertex(&vflag_step, c, a, NO_AA, true, false, INNER);
+ set_roundbox_vertex(&vflag_step, c, a, NO_AA, false, false, INNER);
+ }
+ }
+ /* close loop */
+ last_data = set_roundbox_vertex(&vflag_step, 0, 0, NO_AA, true, false, INNER);
+ last_data = set_roundbox_vertex(&vflag_step, 0, 0, NO_AA, false, false, INNER);
+ /* restart */
+ set_roundbox_vertex_data(&vflag_step, last_data);
+ set_roundbox_vertex(&vflag_step, 0, 0, NO_AA, true, false, INNER);
+ /* filled */
+ for (int c1 = 0, c2 = 3; c1 < 2; c1++, c2--) {
+ for (int a1 = 0, a2 = WIDGET_CURVE_RESOLU - 1; a2 >= 0; a1++, a2--) {
+ set_roundbox_vertex(&vflag_step, c1, a1, NO_AA, true, false, INNER);
+ set_roundbox_vertex(&vflag_step, c2, a2, NO_AA, true, false, INNER);
+ }
+ }
+ g_ui_batch_cache.roundbox_shadow = GPU_batch_create_ex(
+ GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ gpu_batch_presets_register(g_ui_batch_cache.roundbox_shadow);
+ }
+ return g_ui_batch_cache.roundbox_shadow;
}
#undef INNER
@@ -550,354 +597,360 @@ GPUBatch *ui_batch_roundbox_shadow_get(void)
/* ************************************************* */
-void UI_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3,
- const float color[4])
+void UI_draw_anti_tria(
+ float x1, float y1, float x2, float y2, float x3, float y3, const float color[4])
{
- float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}};
- float draw_color[4];
+ float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}};
+ float draw_color[4];
- copy_v4_v4(draw_color, color);
- /* Note: This won't give back the original color. */
- draw_color[3] *= 1.0f / WIDGET_AA_JITTER;
+ copy_v4_v4(draw_color, color);
+ /* Note: This won't give back the original color. */
+ draw_color[3] *= 1.0f / WIDGET_AA_JITTER;
- GPU_blend(true);
+ GPU_blend(true);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(draw_color);
- immBegin(GPU_PRIM_TRIS, 3 * WIDGET_AA_JITTER);
+ immUniformColor4fv(draw_color);
+ immBegin(GPU_PRIM_TRIS, 3 * WIDGET_AA_JITTER);
- /* for each AA step */
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- immVertex2f(pos, tri_arr[0][0] + jit[j][0], tri_arr[0][1] + jit[j][1]);
- immVertex2f(pos, tri_arr[1][0] + jit[j][0], tri_arr[1][1] + jit[j][1]);
- immVertex2f(pos, tri_arr[2][0] + jit[j][0], tri_arr[2][1] + jit[j][1]);
- }
+ /* for each AA step */
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ immVertex2f(pos, tri_arr[0][0] + jit[j][0], tri_arr[0][1] + jit[j][1]);
+ immVertex2f(pos, tri_arr[1][0] + jit[j][0], tri_arr[1][1] + jit[j][1]);
+ immVertex2f(pos, tri_arr[2][0] + jit[j][0], tri_arr[2][1] + jit[j][1]);
+ }
- immEnd();
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(false);
}
/* triangle 'icon' inside rect */
void ui_draw_anti_tria_rect(const rctf *rect, char dir, const float color[4])
{
- if (dir == 'h') {
- float half = 0.5f * BLI_rctf_size_y(rect);
- UI_draw_anti_tria(rect->xmin, rect->ymin, rect->xmin, rect->ymax, rect->xmax, rect->ymin + half, color);
- }
- else {
- float half = 0.5f * BLI_rctf_size_x(rect);
- UI_draw_anti_tria(rect->xmin, rect->ymax, rect->xmax, rect->ymax, rect->xmin + half, rect->ymin, color);
- }
+ if (dir == 'h') {
+ float half = 0.5f * BLI_rctf_size_y(rect);
+ UI_draw_anti_tria(
+ rect->xmin, rect->ymin, rect->xmin, rect->ymax, rect->xmax, rect->ymin + half, color);
+ }
+ else {
+ float half = 0.5f * BLI_rctf_size_x(rect);
+ UI_draw_anti_tria(
+ rect->xmin, rect->ymax, rect->xmax, rect->ymax, rect->xmin + half, rect->ymin, color);
+ }
}
-
void UI_draw_anti_fan(float tri_array[][2], uint length, const float color[4])
{
- float draw_color[4];
+ float draw_color[4];
- copy_v4_v4(draw_color, color);
- draw_color[3] *= 2.0f / WIDGET_AA_JITTER;
+ copy_v4_v4(draw_color, color);
+ draw_color[3] *= 2.0f / WIDGET_AA_JITTER;
- GPU_blend(true);
+ GPU_blend(true);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4fv(draw_color);
+ immUniformColor4fv(draw_color);
- /* for each AA step */
- for (int j = 0; j < WIDGET_AA_JITTER; j++) {
- immBegin(GPU_PRIM_TRI_FAN, length);
- immVertex2f(pos, tri_array[0][0], tri_array[0][1]);
- immVertex2f(pos, tri_array[1][0], tri_array[1][1]);
+ /* for each AA step */
+ for (int j = 0; j < WIDGET_AA_JITTER; j++) {
+ immBegin(GPU_PRIM_TRI_FAN, length);
+ immVertex2f(pos, tri_array[0][0], tri_array[0][1]);
+ immVertex2f(pos, tri_array[1][0], tri_array[1][1]);
- /* We jitter only the middle of the fan, the extremes are pinned. */
- for (int i = 2; i < length - 1; i++) {
- immVertex2f(pos, tri_array[i][0] + jit[j][0], tri_array[i][1] + jit[j][1]);
- }
+ /* We jitter only the middle of the fan, the extremes are pinned. */
+ for (int i = 2; i < length - 1; i++) {
+ immVertex2f(pos, tri_array[i][0] + jit[j][0], tri_array[i][1] + jit[j][1]);
+ }
- immVertex2f(pos, tri_array[length - 1][0], tri_array[length - 1][1]);
- immEnd();
- }
+ immVertex2f(pos, tri_array[length - 1][0], tri_array[length - 1][1]);
+ immEnd();
+ }
- immUnbindProgram();
+ immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(false);
}
static void widget_init(uiWidgetBase *wtb)
{
- wtb->totvert = wtb->halfwayvert = 0;
- wtb->tria1.tot = 0;
- wtb->tria2.tot = 0;
- wtb->tria1.type = ROUNDBOX_TRIA_NONE;
- wtb->tria1.size = 0;
- wtb->tria2.size = 0;
-
- wtb->draw_inner = true;
- wtb->draw_outline = true;
- wtb->draw_emboss = true;
-
- wtb->uniform_params.shade_dir = 1.0f;
- wtb->uniform_params.alpha_discard = 1.0f;
+ wtb->totvert = wtb->halfwayvert = 0;
+ wtb->tria1.tot = 0;
+ wtb->tria2.tot = 0;
+ wtb->tria1.type = ROUNDBOX_TRIA_NONE;
+ wtb->tria1.size = 0;
+ wtb->tria2.size = 0;
+
+ wtb->draw_inner = true;
+ wtb->draw_outline = true;
+ wtb->draw_emboss = true;
+
+ wtb->uniform_params.shade_dir = 1.0f;
+ wtb->uniform_params.alpha_discard = 1.0f;
}
/* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */
/* return tot */
-static int round_box_shadow_edges(float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step)
+static int round_box_shadow_edges(
+ float (*vert)[2], const rcti *rect, float rad, int roundboxalign, float step)
{
- float vec[WIDGET_CURVE_RESOLU][2];
- float minx, miny, maxx, maxy;
- int a, tot = 0;
-
- rad += step;
-
- if (2.0f * rad > BLI_rcti_size_y(rect)) {
- rad = 0.5f * BLI_rcti_size_y(rect);
- }
-
- minx = rect->xmin - step;
- miny = rect->ymin - step;
- maxx = rect->xmax + step;
- maxy = rect->ymax + step;
-
- /* mult */
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
- vec[a][0] = rad * cornervec[a][0];
- vec[a][1] = rad * cornervec[a][1];
- }
-
- /* start with left-top, anti clockwise */
- if (roundboxalign & UI_CNR_TOP_LEFT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = minx + rad - vec[a][0];
- vert[tot][1] = maxy - vec[a][1];
- }
- }
- else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = minx;
- vert[tot][1] = maxy;
- }
- }
-
- if (roundboxalign & UI_CNR_BOTTOM_LEFT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = minx + vec[a][1];
- vert[tot][1] = miny + rad - vec[a][0];
- }
- }
- else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = minx;
- vert[tot][1] = miny;
- }
- }
-
- if (roundboxalign & UI_CNR_BOTTOM_RIGHT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = maxx - rad + vec[a][0];
- vert[tot][1] = miny + vec[a][1];
- }
- }
- else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = maxx;
- vert[tot][1] = miny;
- }
- }
-
- if (roundboxalign & UI_CNR_TOP_RIGHT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = maxx - vec[a][1];
- vert[tot][1] = maxy - rad + vec[a][0];
- }
- }
- else {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- vert[tot][0] = maxx;
- vert[tot][1] = maxy;
- }
- }
- return tot;
+ float vec[WIDGET_CURVE_RESOLU][2];
+ float minx, miny, maxx, maxy;
+ int a, tot = 0;
+
+ rad += step;
+
+ if (2.0f * rad > BLI_rcti_size_y(rect)) {
+ rad = 0.5f * BLI_rcti_size_y(rect);
+ }
+
+ minx = rect->xmin - step;
+ miny = rect->ymin - step;
+ maxx = rect->xmax + step;
+ maxy = rect->ymax + step;
+
+ /* mult */
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
+ vec[a][0] = rad * cornervec[a][0];
+ vec[a][1] = rad * cornervec[a][1];
+ }
+
+ /* start with left-top, anti clockwise */
+ if (roundboxalign & UI_CNR_TOP_LEFT) {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = minx + rad - vec[a][0];
+ vert[tot][1] = maxy - vec[a][1];
+ }
+ }
+ else {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = minx;
+ vert[tot][1] = maxy;
+ }
+ }
+
+ if (roundboxalign & UI_CNR_BOTTOM_LEFT) {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = minx + vec[a][1];
+ vert[tot][1] = miny + rad - vec[a][0];
+ }
+ }
+ else {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = minx;
+ vert[tot][1] = miny;
+ }
+ }
+
+ if (roundboxalign & UI_CNR_BOTTOM_RIGHT) {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = maxx - rad + vec[a][0];
+ vert[tot][1] = miny + vec[a][1];
+ }
+ }
+ else {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = maxx;
+ vert[tot][1] = miny;
+ }
+ }
+
+ if (roundboxalign & UI_CNR_TOP_RIGHT) {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = maxx - vec[a][1];
+ vert[tot][1] = maxy - rad + vec[a][0];
+ }
+ }
+ else {
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ vert[tot][0] = maxx;
+ vert[tot][1] = maxy;
+ }
+ }
+ return tot;
}
/* this call has 1 extra arg to allow mask outline */
-static void round_box__edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi)
+static void round_box__edges(
+ uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi)
{
- float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2];
- float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax;
- float minxi = minx + U.pixelsize; /* boundbox inner */
- float maxxi = maxx - U.pixelsize;
- float minyi = miny + U.pixelsize;
- float maxyi = maxy - U.pixelsize;
- /* for uv, can divide by zero */
- float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f;
- float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f;
- int a, tot = 0, minsize;
- const int hnum = (
- (roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT)) == (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT) ||
- (roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT)) == (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT)) ? 1 : 2;
- const int vnum = (
- (roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)) == (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT) ||
- (roundboxalign & (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) == (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) ? 1 : 2;
-
- minsize = min_ii(
- BLI_rcti_size_x(rect) * hnum,
- BLI_rcti_size_y(rect) * vnum);
-
- if (2.0f * rad > minsize) {
- rad = 0.5f * minsize;
- }
-
- if (2.0f * (radi + 1.0f) > minsize) {
- radi = 0.5f * minsize - U.pixelsize;
- }
-
- wt->uniform_params.rad = rad;
- wt->uniform_params.radi = radi;
- wt->uniform_params.facxi = facxi;
- wt->uniform_params.facyi = facyi;
- wt->uniform_params.round_corners[0] = (roundboxalign & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
- wt->uniform_params.round_corners[1] = (roundboxalign & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
- wt->uniform_params.round_corners[2] = (roundboxalign & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
- wt->uniform_params.round_corners[3] = (roundboxalign & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
- BLI_rctf_rcti_copy(&wt->uniform_params.rect, rect);
- BLI_rctf_init(&wt->uniform_params.recti, minxi, maxxi, minyi, maxyi);
-
- /* mult */
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
- veci[a][0] = radi * cornervec[a][0];
- veci[a][1] = radi * cornervec[a][1];
- vec[a][0] = rad * cornervec[a][0];
- vec[a][1] = rad * cornervec[a][1];
- }
-
- /* corner left-bottom */
- if (roundboxalign & UI_CNR_BOTTOM_LEFT) {
-
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- wt->inner_v[tot][0] = minxi + veci[a][1];
- wt->inner_v[tot][1] = minyi + radi - veci[a][0];
-
- wt->outer_v[tot][0] = minx + vec[a][1];
- wt->outer_v[tot][1] = miny + rad - vec[a][0];
-
- wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
- wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
- }
- }
- else {
- wt->inner_v[tot][0] = minxi;
- wt->inner_v[tot][1] = minyi;
-
- wt->outer_v[tot][0] = minx;
- wt->outer_v[tot][1] = miny;
-
- wt->inner_uv[tot][0] = 0.0f;
- wt->inner_uv[tot][1] = 0.0f;
-
- tot++;
- }
-
- /* corner right-bottom */
- if (roundboxalign & UI_CNR_BOTTOM_RIGHT) {
-
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- wt->inner_v[tot][0] = maxxi - radi + veci[a][0];
- wt->inner_v[tot][1] = minyi + veci[a][1];
-
- wt->outer_v[tot][0] = maxx - rad + vec[a][0];
- wt->outer_v[tot][1] = miny + vec[a][1];
-
- wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
- wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
- }
- }
- else {
- wt->inner_v[tot][0] = maxxi;
- wt->inner_v[tot][1] = minyi;
-
- wt->outer_v[tot][0] = maxx;
- wt->outer_v[tot][1] = miny;
-
- wt->inner_uv[tot][0] = 1.0f;
- wt->inner_uv[tot][1] = 0.0f;
-
- tot++;
- }
-
- wt->halfwayvert = tot;
-
- /* corner right-top */
- if (roundboxalign & UI_CNR_TOP_RIGHT) {
-
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- wt->inner_v[tot][0] = maxxi - veci[a][1];
- wt->inner_v[tot][1] = maxyi - radi + veci[a][0];
-
- wt->outer_v[tot][0] = maxx - vec[a][1];
- wt->outer_v[tot][1] = maxy - rad + vec[a][0];
+ float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2];
+ float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax;
+ float minxi = minx + U.pixelsize; /* boundbox inner */
+ float maxxi = maxx - U.pixelsize;
+ float minyi = miny + U.pixelsize;
+ float maxyi = maxy - U.pixelsize;
+ /* for uv, can divide by zero */
+ float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f;
+ float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f;
+ int a, tot = 0, minsize;
+ const int hnum = ((roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT)) ==
+ (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT) ||
+ (roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT)) ==
+ (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT)) ?
+ 1 :
+ 2;
+ const int vnum = ((roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT)) ==
+ (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT) ||
+ (roundboxalign & (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) ==
+ (UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT)) ?
+ 1 :
+ 2;
+
+ minsize = min_ii(BLI_rcti_size_x(rect) * hnum, BLI_rcti_size_y(rect) * vnum);
+
+ if (2.0f * rad > minsize) {
+ rad = 0.5f * minsize;
+ }
+
+ if (2.0f * (radi + 1.0f) > minsize) {
+ radi = 0.5f * minsize - U.pixelsize;
+ }
+
+ wt->uniform_params.rad = rad;
+ wt->uniform_params.radi = radi;
+ wt->uniform_params.facxi = facxi;
+ wt->uniform_params.facyi = facyi;
+ wt->uniform_params.round_corners[0] = (roundboxalign & UI_CNR_BOTTOM_LEFT) ? 1.0f : 0.0f;
+ wt->uniform_params.round_corners[1] = (roundboxalign & UI_CNR_BOTTOM_RIGHT) ? 1.0f : 0.0f;
+ wt->uniform_params.round_corners[2] = (roundboxalign & UI_CNR_TOP_RIGHT) ? 1.0f : 0.0f;
+ wt->uniform_params.round_corners[3] = (roundboxalign & UI_CNR_TOP_LEFT) ? 1.0f : 0.0f;
+ BLI_rctf_rcti_copy(&wt->uniform_params.rect, rect);
+ BLI_rctf_init(&wt->uniform_params.recti, minxi, maxxi, minyi, maxyi);
+
+ /* mult */
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++) {
+ veci[a][0] = radi * cornervec[a][0];
+ veci[a][1] = radi * cornervec[a][1];
+ vec[a][0] = rad * cornervec[a][0];
+ vec[a][1] = rad * cornervec[a][1];
+ }
+
+ /* corner left-bottom */
+ if (roundboxalign & UI_CNR_BOTTOM_LEFT) {
+
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ wt->inner_v[tot][0] = minxi + veci[a][1];
+ wt->inner_v[tot][1] = minyi + radi - veci[a][0];
+
+ wt->outer_v[tot][0] = minx + vec[a][1];
+ wt->outer_v[tot][1] = miny + rad - vec[a][0];
+
+ wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
+ }
+ }
+ else {
+ wt->inner_v[tot][0] = minxi;
+ wt->inner_v[tot][1] = minyi;
+
+ wt->outer_v[tot][0] = minx;
+ wt->outer_v[tot][1] = miny;
+
+ wt->inner_uv[tot][0] = 0.0f;
+ wt->inner_uv[tot][1] = 0.0f;
+
+ tot++;
+ }
+
+ /* corner right-bottom */
+ if (roundboxalign & UI_CNR_BOTTOM_RIGHT) {
+
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ wt->inner_v[tot][0] = maxxi - radi + veci[a][0];
+ wt->inner_v[tot][1] = minyi + veci[a][1];
+
+ wt->outer_v[tot][0] = maxx - rad + vec[a][0];
+ wt->outer_v[tot][1] = miny + vec[a][1];
+
+ wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
+ }
+ }
+ else {
+ wt->inner_v[tot][0] = maxxi;
+ wt->inner_v[tot][1] = minyi;
+
+ wt->outer_v[tot][0] = maxx;
+ wt->outer_v[tot][1] = miny;
+
+ wt->inner_uv[tot][0] = 1.0f;
+ wt->inner_uv[tot][1] = 0.0f;
+
+ tot++;
+ }
+
+ wt->halfwayvert = tot;
+
+ /* corner right-top */
+ if (roundboxalign & UI_CNR_TOP_RIGHT) {
+
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ wt->inner_v[tot][0] = maxxi - veci[a][1];
+ wt->inner_v[tot][1] = maxyi - radi + veci[a][0];
+
+ wt->outer_v[tot][0] = maxx - vec[a][1];
+ wt->outer_v[tot][1] = maxy - rad + vec[a][0];
- wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
- wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
- }
- }
- else {
- wt->inner_v[tot][0] = maxxi;
- wt->inner_v[tot][1] = maxyi;
+ wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
+ }
+ }
+ else {
+ wt->inner_v[tot][0] = maxxi;
+ wt->inner_v[tot][1] = maxyi;
- wt->outer_v[tot][0] = maxx;
- wt->outer_v[tot][1] = maxy;
+ wt->outer_v[tot][0] = maxx;
+ wt->outer_v[tot][1] = maxy;
- wt->inner_uv[tot][0] = 1.0f;
- wt->inner_uv[tot][1] = 1.0f;
+ wt->inner_uv[tot][0] = 1.0f;
+ wt->inner_uv[tot][1] = 1.0f;
- tot++;
- }
+ tot++;
+ }
- /* corner left-top */
- if (roundboxalign & UI_CNR_TOP_LEFT) {
+ /* corner left-top */
+ if (roundboxalign & UI_CNR_TOP_LEFT) {
- for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
- wt->inner_v[tot][0] = minxi + radi - veci[a][0];
- wt->inner_v[tot][1] = maxyi - veci[a][1];
+ for (a = 0; a < WIDGET_CURVE_RESOLU; a++, tot++) {
+ wt->inner_v[tot][0] = minxi + radi - veci[a][0];
+ wt->inner_v[tot][1] = maxyi - veci[a][1];
- wt->outer_v[tot][0] = minx + rad - vec[a][0];
- wt->outer_v[tot][1] = maxy - vec[a][1];
+ wt->outer_v[tot][0] = minx + rad - vec[a][0];
+ wt->outer_v[tot][1] = maxy - vec[a][1];
- wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
- wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
- }
+ wt->inner_uv[tot][0] = facxi * (wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1] = facyi * (wt->inner_v[tot][1] - minyi);
+ }
+ }
+ else {
- }
- else {
+ wt->inner_v[tot][0] = minxi;
+ wt->inner_v[tot][1] = maxyi;
- wt->inner_v[tot][0] = minxi;
- wt->inner_v[tot][1] = maxyi;
+ wt->outer_v[tot][0] = minx;
+ wt->outer_v[tot][1] = maxy;
- wt->outer_v[tot][0] = minx;
- wt->outer_v[tot][1] = maxy;
+ wt->inner_uv[tot][0] = 0.0f;
+ wt->inner_uv[tot][1] = 1.0f;
- wt->inner_uv[tot][0] = 0.0f;
- wt->inner_uv[tot][1] = 1.0f;
+ tot++;
+ }
- tot++;
- }
+ BLI_assert(tot <= WIDGET_SIZE_MAX);
- BLI_assert(tot <= WIDGET_SIZE_MAX);
-
- wt->totvert = tot;
+ wt->totvert = tot;
}
static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad)
{
- round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize);
+ round_box__edges(wt, roundboxalign, rect, rad, rad - U.pixelsize);
}
/* -------------------------------------------------------------------- */
@@ -905,239 +958,270 @@ static void round_box_edges(uiWidgetBase *wt, int roundboxalign, const rcti *rec
* \{ */
/* based on button rect, return scaled array of triangles */
-static void shape_preset_init_trias_ex(
- uiWidgetTrias *tria, const rcti *rect, float triasize, char where,
- /* input data */
- const float verts[][2], const int verts_tot,
- const uint tris[][3], const int tris_tot)
+static void shape_preset_init_trias_ex(uiWidgetTrias *tria,
+ const rcti *rect,
+ float triasize,
+ char where,
+ /* input data */
+ const float verts[][2],
+ const int verts_tot,
+ const uint tris[][3],
+ const int tris_tot)
{
- float centx, centy, sizex, sizey, minsize;
- int a, i1 = 0, i2 = 1;
-
- if (where == 'r' || where == 'l') {
- minsize = BLI_rcti_size_y(rect);
- }
- else {
- minsize = BLI_rcti_size_x(rect);
- }
-
- /* center position and size */
- centx = (float)rect->xmin + 0.4f * minsize;
- centy = (float)rect->ymin + 0.5f * minsize;
- tria->size = sizex = sizey = -0.5f * triasize * minsize;
-
- if (where == 'r') {
- centx = (float)rect->xmax - 0.4f * minsize;
- sizex = -sizex;
- }
- else if (where == 't') {
- centx = (float)rect->xmin + 0.5f * minsize;
- centy = (float)rect->ymax - 0.5f * minsize;
- sizey = -sizey;
- i2 = 0; i1 = 1;
- }
- else if (where == 'b') {
- centx = (float)rect->xmin + 0.5f * minsize;
- sizex = -sizex;
- i2 = 0; i1 = 1;
- }
-
- for (a = 0; a < verts_tot; a++) {
- tria->vec[a][0] = sizex * verts[a][i1] + centx;
- tria->vec[a][1] = sizey * verts[a][i2] + centy;
- }
-
- tria->center[0] = centx;
- tria->center[1] = centy;
-
- tria->tot = tris_tot;
- tria->index = tris;
+ float centx, centy, sizex, sizey, minsize;
+ int a, i1 = 0, i2 = 1;
+
+ if (where == 'r' || where == 'l') {
+ minsize = BLI_rcti_size_y(rect);
+ }
+ else {
+ minsize = BLI_rcti_size_x(rect);
+ }
+
+ /* center position and size */
+ centx = (float)rect->xmin + 0.4f * minsize;
+ centy = (float)rect->ymin + 0.5f * minsize;
+ tria->size = sizex = sizey = -0.5f * triasize * minsize;
+
+ if (where == 'r') {
+ centx = (float)rect->xmax - 0.4f * minsize;
+ sizex = -sizex;
+ }
+ else if (where == 't') {
+ centx = (float)rect->xmin + 0.5f * minsize;
+ centy = (float)rect->ymax - 0.5f * minsize;
+ sizey = -sizey;
+ i2 = 0;
+ i1 = 1;
+ }
+ else if (where == 'b') {
+ centx = (float)rect->xmin + 0.5f * minsize;
+ sizex = -sizex;
+ i2 = 0;
+ i1 = 1;
+ }
+
+ for (a = 0; a < verts_tot; a++) {
+ tria->vec[a][0] = sizex * verts[a][i1] + centx;
+ tria->vec[a][1] = sizey * verts[a][i2] + centy;
+ }
+
+ tria->center[0] = centx;
+ tria->center[1] = centy;
+
+ tria->tot = tris_tot;
+ tria->index = tris;
}
-static void shape_preset_init_number_arrows(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
+static void shape_preset_init_number_arrows(uiWidgetTrias *tria,
+ const rcti *rect,
+ float triasize,
+ char where)
{
- tria->type = ROUNDBOX_TRIA_ARROWS;
- shape_preset_init_trias_ex(
- tria, rect, triasize, where,
- g_shape_preset_number_arrow_vert, ARRAY_SIZE(g_shape_preset_number_arrow_vert),
- g_shape_preset_number_arrow_face, ARRAY_SIZE(g_shape_preset_number_arrow_face));
+ tria->type = ROUNDBOX_TRIA_ARROWS;
+ shape_preset_init_trias_ex(tria,
+ rect,
+ triasize,
+ where,
+ g_shape_preset_number_arrow_vert,
+ ARRAY_SIZE(g_shape_preset_number_arrow_vert),
+ g_shape_preset_number_arrow_face,
+ ARRAY_SIZE(g_shape_preset_number_arrow_face));
}
-static void shape_preset_init_hold_action(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
+static void shape_preset_init_hold_action(uiWidgetTrias *tria,
+ const rcti *rect,
+ float triasize,
+ char where)
{
- tria->type = ROUNDBOX_TRIA_HOLD_ACTION_ARROW;
- /* With the current changes to use batches for widget drawing, the code
- * below is doing almost nothing effectively. 'where' doesn't work either,
- * shader is currently hardcoded to work for the button triangle pointing
- * at the lower right. The same limitation applies to other trias as well.
- * XXX Should be addressed. */
- shape_preset_init_trias_ex(
- tria, rect, triasize, where,
- g_shape_preset_hold_action_vert, ARRAY_SIZE(g_shape_preset_hold_action_vert),
- g_shape_preset_hold_action_face, ARRAY_SIZE(g_shape_preset_hold_action_face));
+ tria->type = ROUNDBOX_TRIA_HOLD_ACTION_ARROW;
+ /* With the current changes to use batches for widget drawing, the code
+ * below is doing almost nothing effectively. 'where' doesn't work either,
+ * shader is currently hardcoded to work for the button triangle pointing
+ * at the lower right. The same limitation applies to other trias as well.
+ * XXX Should be addressed. */
+ shape_preset_init_trias_ex(tria,
+ rect,
+ triasize,
+ where,
+ g_shape_preset_hold_action_vert,
+ ARRAY_SIZE(g_shape_preset_hold_action_vert),
+ g_shape_preset_hold_action_face,
+ ARRAY_SIZE(g_shape_preset_hold_action_face));
}
-static void shape_preset_init_scroll_circle(uiWidgetTrias *tria, const rcti *rect, float triasize, char where)
+static void shape_preset_init_scroll_circle(uiWidgetTrias *tria,
+ const rcti *rect,
+ float triasize,
+ char where)
{
- tria->type = ROUNDBOX_TRIA_SCROLL;
- shape_preset_init_trias_ex(
- tria, rect, triasize, where,
- g_shape_preset_scroll_circle_vert, ARRAY_SIZE(g_shape_preset_scroll_circle_vert),
- g_shape_preset_scroll_circle_face, ARRAY_SIZE(g_shape_preset_scroll_circle_face));
+ tria->type = ROUNDBOX_TRIA_SCROLL;
+ shape_preset_init_trias_ex(tria,
+ rect,
+ triasize,
+ where,
+ g_shape_preset_scroll_circle_vert,
+ ARRAY_SIZE(g_shape_preset_scroll_circle_vert),
+ g_shape_preset_scroll_circle_face,
+ ARRAY_SIZE(g_shape_preset_scroll_circle_face));
}
-static void widget_draw_vertex_buffer(uint pos, uint col, int mode,
+static void widget_draw_vertex_buffer(uint pos,
+ uint col,
+ int mode,
const float quads_pos[WIDGET_SIZE_MAX][2],
const uchar quads_col[WIDGET_SIZE_MAX][4],
uint totvert)
{
- immBegin(mode, totvert);
- for (int i = 0; i < totvert; ++i) {
- if (quads_col) {
- immAttr4ubv(col, quads_col[i]);
- }
- immVertex2fv(pos, quads_pos[i]);
- }
- immEnd();
+ immBegin(mode, totvert);
+ for (int i = 0; i < totvert; ++i) {
+ if (quads_col) {
+ immAttr4ubv(col, quads_col[i]);
+ }
+ immVertex2fv(pos, quads_pos[i]);
+ }
+ immEnd();
}
static void shape_preset_trias_from_rect_menu(uiWidgetTrias *tria, const rcti *rect)
{
- float width = BLI_rcti_size_x(rect);
- float height = BLI_rcti_size_y(rect);
- float centx, centy, size;
+ float width = BLI_rcti_size_x(rect);
+ float height = BLI_rcti_size_y(rect);
+ float centx, centy, size;
- tria->type = ROUNDBOX_TRIA_MENU;
+ tria->type = ROUNDBOX_TRIA_MENU;
- /* Center position and size. */
- tria->center[0] = centx = rect->xmin + 0.52f * BLI_rcti_size_y(rect);
- tria->center[1] = centy = rect->ymin + 0.52f * BLI_rcti_size_y(rect);
- tria->size = size = 0.4f * height;
+ /* Center position and size. */
+ tria->center[0] = centx = rect->xmin + 0.52f * BLI_rcti_size_y(rect);
+ tria->center[1] = centy = rect->ymin + 0.52f * BLI_rcti_size_y(rect);
+ tria->size = size = 0.4f * height;
- if (width > height * 1.1f) {
- /* For wider buttons align tighter to the right. */
- tria->center[0] = centx = rect->xmax - 0.32f * height;
- }
+ if (width > height * 1.1f) {
+ /* For wider buttons align tighter to the right. */
+ tria->center[0] = centx = rect->xmax - 0.32f * height;
+ }
- for (int a = 0; a < 6; a++) {
- tria->vec[a][0] = size * g_shape_preset_menu_arrow_vert[a][0] + centx;
- tria->vec[a][1] = size * g_shape_preset_menu_arrow_vert[a][1] + centy;
- }
+ for (int a = 0; a < 6; a++) {
+ tria->vec[a][0] = size * g_shape_preset_menu_arrow_vert[a][0] + centx;
+ tria->vec[a][1] = size * g_shape_preset_menu_arrow_vert[a][1] + centy;
+ }
- tria->tot = 2;
- tria->index = g_shape_preset_menu_arrow_face;
+ tria->tot = 2;
+ tria->index = g_shape_preset_menu_arrow_face;
}
static void shape_preset_trias_from_rect_checkmark(uiWidgetTrias *tria, const rcti *rect)
{
- float centx, centy, size;
+ float centx, centy, size;
- tria->type = ROUNDBOX_TRIA_CHECK;
+ tria->type = ROUNDBOX_TRIA_CHECK;
- /* Center position and size. */
- tria->center[0] = centx = rect->xmin + 0.5f * BLI_rcti_size_y(rect);
- tria->center[1] = centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect);
- tria->size = size = 0.5f * BLI_rcti_size_y(rect);
+ /* Center position and size. */
+ tria->center[0] = centx = rect->xmin + 0.5f * BLI_rcti_size_y(rect);
+ tria->center[1] = centy = rect->ymin + 0.5f * BLI_rcti_size_y(rect);
+ tria->size = size = 0.5f * BLI_rcti_size_y(rect);
- for (int a = 0; a < 6; a++) {
- tria->vec[a][0] = size * g_shape_preset_checkmark_vert[a][0] + centx;
- tria->vec[a][1] = size * g_shape_preset_checkmark_vert[a][1] + centy;
- }
+ for (int a = 0; a < 6; a++) {
+ tria->vec[a][0] = size * g_shape_preset_checkmark_vert[a][0] + centx;
+ tria->vec[a][1] = size * g_shape_preset_checkmark_vert[a][1] + centy;
+ }
- tria->tot = 4;
- tria->index = g_shape_preset_checkmark_face;
+ tria->tot = 4;
+ tria->index = g_shape_preset_checkmark_face;
}
/** \} */
-
/* prepares shade colors */
-static void shadecolors4(char coltop[4], char coldown[4], const char *color, short shadetop, short shadedown)
+static void shadecolors4(
+ char coltop[4], char coldown[4], const char *color, short shadetop, short shadedown)
{
- coltop[0] = CLAMPIS(color[0] + shadetop, 0, 255);
- coltop[1] = CLAMPIS(color[1] + shadetop, 0, 255);
- coltop[2] = CLAMPIS(color[2] + shadetop, 0, 255);
- coltop[3] = color[3];
-
- coldown[0] = CLAMPIS(color[0] + shadedown, 0, 255);
- coldown[1] = CLAMPIS(color[1] + shadedown, 0, 255);
- coldown[2] = CLAMPIS(color[2] + shadedown, 0, 255);
- coldown[3] = color[3];
+ coltop[0] = CLAMPIS(color[0] + shadetop, 0, 255);
+ coltop[1] = CLAMPIS(color[1] + shadetop, 0, 255);
+ coltop[2] = CLAMPIS(color[2] + shadetop, 0, 255);
+ coltop[3] = color[3];
+
+ coldown[0] = CLAMPIS(color[0] + shadedown, 0, 255);
+ coldown[1] = CLAMPIS(color[1] + shadedown, 0, 255);
+ coldown[2] = CLAMPIS(color[2] + shadedown, 0, 255);
+ coldown[3] = color[3];
}
-static void round_box_shade_col4_r(uchar r_col[4], const char col1[4], const char col2[4], const float fac)
+static void round_box_shade_col4_r(uchar r_col[4],
+ const char col1[4],
+ const char col2[4],
+ const float fac)
{
- const int faci = unit_float_to_uchar_clamp(fac);
- const int facm = 255 - faci;
+ const int faci = unit_float_to_uchar_clamp(fac);
+ const int facm = 255 - faci;
- r_col[0] = (faci * col1[0] + facm * col2[0]) / 256;
- r_col[1] = (faci * col1[1] + facm * col2[1]) / 256;
- r_col[2] = (faci * col1[2] + facm * col2[2]) / 256;
- r_col[3] = (faci * col1[3] + facm * col2[3]) / 256;
+ r_col[0] = (faci * col1[0] + facm * col2[0]) / 256;
+ r_col[1] = (faci * col1[1] + facm * col2[1]) / 256;
+ r_col[2] = (faci * col1[2] + facm * col2[2]) / 256;
+ r_col[3] = (faci * col1[3] + facm * col2[3]) / 256;
}
-static void widget_verts_to_triangle_strip(uiWidgetBase *wtb, const int totvert, float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2])
+static void widget_verts_to_triangle_strip(uiWidgetBase *wtb,
+ const int totvert,
+ float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2])
{
- int a;
- for (a = 0; a < totvert; a++) {
- copy_v2_v2(triangle_strip[a * 2], wtb->outer_v[a]);
- copy_v2_v2(triangle_strip[a * 2 + 1], wtb->inner_v[a]);
- }
- copy_v2_v2(triangle_strip[a * 2], wtb->outer_v[0]);
- copy_v2_v2(triangle_strip[a * 2 + 1], wtb->inner_v[0]);
+ int a;
+ for (a = 0; a < totvert; a++) {
+ copy_v2_v2(triangle_strip[a * 2], wtb->outer_v[a]);
+ copy_v2_v2(triangle_strip[a * 2 + 1], wtb->inner_v[a]);
+ }
+ copy_v2_v2(triangle_strip[a * 2], wtb->outer_v[0]);
+ copy_v2_v2(triangle_strip[a * 2 + 1], wtb->inner_v[0]);
}
static void widgetbase_outline(uiWidgetBase *wtb, uint pos)
{
- float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
- widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip);
+ float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */
+ widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip);
- widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2);
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2);
}
-static void widgetbase_set_uniform_alpha_discard(
- uiWidgetBase *wtb,
- const bool alpha_check,
- const float discard_factor)
+static void widgetbase_set_uniform_alpha_discard(uiWidgetBase *wtb,
+ const bool alpha_check,
+ const float discard_factor)
{
- if (alpha_check) {
- wtb->uniform_params.alpha_discard = -discard_factor;
- }
- else {
- wtb->uniform_params.alpha_discard = discard_factor;
- }
+ if (alpha_check) {
+ wtb->uniform_params.alpha_discard = -discard_factor;
+ }
+ else {
+ wtb->uniform_params.alpha_discard = discard_factor;
+ }
}
-static void widgetbase_set_uniform_alpha_check(
- uiWidgetBase *wtb,
- const bool alpha_check)
+static void widgetbase_set_uniform_alpha_check(uiWidgetBase *wtb, const bool alpha_check)
{
- const float discard_factor = fabs(wtb->uniform_params.alpha_discard);
- widgetbase_set_uniform_alpha_discard(wtb, alpha_check, discard_factor);
+ const float discard_factor = fabs(wtb->uniform_params.alpha_discard);
+ widgetbase_set_uniform_alpha_discard(wtb, alpha_check, discard_factor);
}
-static void widgetbase_set_uniform_discard_factor(
- uiWidgetBase *wtb,
- const float discard_factor)
+static void widgetbase_set_uniform_discard_factor(uiWidgetBase *wtb, const float discard_factor)
{
- bool alpha_check = wtb->uniform_params.alpha_discard < 0.0f;
- widgetbase_set_uniform_alpha_discard(wtb, alpha_check, discard_factor);
+ bool alpha_check = wtb->uniform_params.alpha_discard < 0.0f;
+ widgetbase_set_uniform_alpha_discard(wtb, alpha_check, discard_factor);
}
-static void widgetbase_set_uniform_colors_ubv(
- uiWidgetBase *wtb,
- const uchar *col1, const uchar *col2,
- const uchar *outline,
- const uchar *emboss,
- const uchar *tria,
- const bool alpha_check)
+static void widgetbase_set_uniform_colors_ubv(uiWidgetBase *wtb,
+ const uchar *col1,
+ const uchar *col2,
+ const uchar *outline,
+ const uchar *emboss,
+ const uchar *tria,
+ const bool alpha_check)
{
- widgetbase_set_uniform_alpha_check(wtb, alpha_check);
- rgba_float_args_set_ch(wtb->uniform_params.color_inner1, col1[0], col1[1], col1[2], col1[3]);
- rgba_float_args_set_ch(wtb->uniform_params.color_inner2, col2[0], col2[1], col2[2], col2[3]);
- rgba_float_args_set_ch(wtb->uniform_params.color_outline, outline[0], outline[1], outline[2], outline[3]);
- rgba_float_args_set_ch(wtb->uniform_params.color_emboss, emboss[0], emboss[1], emboss[2], emboss[3]);
- rgba_float_args_set_ch(wtb->uniform_params.color_tria, tria[0], tria[1], tria[2], tria[3]);
+ widgetbase_set_uniform_alpha_check(wtb, alpha_check);
+ rgba_float_args_set_ch(wtb->uniform_params.color_inner1, col1[0], col1[1], col1[2], col1[3]);
+ rgba_float_args_set_ch(wtb->uniform_params.color_inner2, col2[0], col2[1], col2[2], col2[3]);
+ rgba_float_args_set_ch(
+ wtb->uniform_params.color_outline, outline[0], outline[1], outline[2], outline[3]);
+ rgba_float_args_set_ch(
+ wtb->uniform_params.color_emboss, emboss[0], emboss[1], emboss[2], emboss[3]);
+ rgba_float_args_set_ch(wtb->uniform_params.color_tria, tria[0], tria[1], tria[2], tria[3]);
}
/* keep in sync with shader */
@@ -1145,165 +1229,173 @@ static void widgetbase_set_uniform_colors_ubv(
#define MAX_WIDGET_PARAMETERS 11
static struct {
- GPUBatch *batch; /* Batch type */
- uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH];
- int count;
- bool enabled;
+ GPUBatch *batch; /* Batch type */
+ uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH];
+ int count;
+ bool enabled;
} g_widget_base_batch = {0};
void UI_widgetbase_draw_cache_flush(void)
{
- float checker_params[3] = {UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f};
-
- if (g_widget_base_batch.count == 0) {
- return;
- }
-
- GPUBatch *batch = g_widget_base_batch.batch;
- if (g_widget_base_batch.count == 1) {
- /* draw single */
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params);
- GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
- GPU_batch_draw(batch);
- }
- else {
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_INST);
- GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH,
- (float *)g_widget_base_batch.params);
- GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
- GPU_matrix_bind(batch->interface);
- GPU_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true);
- GPU_batch_program_use_end(batch);
- }
- g_widget_base_batch.count = 0;
+ float checker_params[3] = {
+ UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f};
+
+ if (g_widget_base_batch.count == 0) {
+ return;
+ }
+
+ GPUBatch *batch = g_widget_base_batch.batch;
+ if (g_widget_base_batch.count == 1) {
+ /* draw single */
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(
+ batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params);
+ GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
+ GPU_batch_draw(batch);
+ }
+ else {
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_INST);
+ GPU_batch_uniform_4fv_array(batch,
+ "parameters",
+ MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH,
+ (float *)g_widget_base_batch.params);
+ GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
+ GPU_matrix_bind(batch->interface);
+ GPU_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true);
+ GPU_batch_program_use_end(batch);
+ }
+ g_widget_base_batch.count = 0;
}
void UI_widgetbase_draw_cache_begin(void)
{
- BLI_assert(g_widget_base_batch.enabled == false);
- g_widget_base_batch.enabled = true;
+ BLI_assert(g_widget_base_batch.enabled == false);
+ g_widget_base_batch.enabled = true;
}
void UI_widgetbase_draw_cache_end(void)
{
- BLI_assert(g_widget_base_batch.enabled == true);
- g_widget_base_batch.enabled = false;
+ BLI_assert(g_widget_base_batch.enabled == true);
+ g_widget_base_batch.enabled = false;
- GPU_blend(true);
+ GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
+ UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(false);
}
static void draw_widgetbase_batch(GPUBatch *batch, uiWidgetBase *wtb)
{
- wtb->uniform_params.tria1_size = wtb->tria1.size;
- wtb->uniform_params.tria2_size = wtb->tria2.size;
- copy_v2_v2(wtb->uniform_params.tria1_center, wtb->tria1.center);
- copy_v2_v2(wtb->uniform_params.tria2_center, wtb->tria2.center);
-
- if (g_widget_base_batch.enabled) {
- if (g_widget_base_batch.batch == NULL) {
- g_widget_base_batch.batch = ui_batch_roundbox_widget_get(ROUNDBOX_TRIA_ARROWS);
- }
-
- /* draw multi */
- if (batch != g_ui_batch_cache.roundbox_widget[ROUNDBOX_TRIA_NONE] &&
- batch != g_widget_base_batch.batch)
- {
- /* issue previous calls before changing batch type. */
- UI_widgetbase_draw_cache_flush();
- g_widget_base_batch.batch = batch;
- }
-
- /* No need to change batch if tria is not visible. Just scale it to 0. */
- if (batch == g_ui_batch_cache.roundbox_widget[ROUNDBOX_TRIA_NONE]) {
- wtb->uniform_params.tria1_size = wtb->uniform_params.tria2_size = 0;
- }
-
- g_widget_base_batch.params[g_widget_base_batch.count] = wtb->uniform_params;
- g_widget_base_batch.count++;
-
- if (g_widget_base_batch.count == MAX_WIDGET_BASE_BATCH) {
- UI_widgetbase_draw_cache_flush();
- }
- }
- else {
- float checker_params[3] = {UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f};
- /* draw single */
- GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)&wtb->uniform_params);
- GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
- GPU_batch_draw(batch);
- }
+ wtb->uniform_params.tria1_size = wtb->tria1.size;
+ wtb->uniform_params.tria2_size = wtb->tria2.size;
+ copy_v2_v2(wtb->uniform_params.tria1_center, wtb->tria1.center);
+ copy_v2_v2(wtb->uniform_params.tria2_center, wtb->tria2.center);
+
+ if (g_widget_base_batch.enabled) {
+ if (g_widget_base_batch.batch == NULL) {
+ g_widget_base_batch.batch = ui_batch_roundbox_widget_get(ROUNDBOX_TRIA_ARROWS);
+ }
+
+ /* draw multi */
+ if (batch != g_ui_batch_cache.roundbox_widget[ROUNDBOX_TRIA_NONE] &&
+ batch != g_widget_base_batch.batch) {
+ /* issue previous calls before changing batch type. */
+ UI_widgetbase_draw_cache_flush();
+ g_widget_base_batch.batch = batch;
+ }
+
+ /* No need to change batch if tria is not visible. Just scale it to 0. */
+ if (batch == g_ui_batch_cache.roundbox_widget[ROUNDBOX_TRIA_NONE]) {
+ wtb->uniform_params.tria1_size = wtb->uniform_params.tria2_size = 0;
+ }
+
+ g_widget_base_batch.params[g_widget_base_batch.count] = wtb->uniform_params;
+ g_widget_base_batch.count++;
+
+ if (g_widget_base_batch.count == MAX_WIDGET_BASE_BATCH) {
+ UI_widgetbase_draw_cache_flush();
+ }
+ }
+ else {
+ float checker_params[3] = {
+ UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f};
+ /* draw single */
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
+ GPU_batch_uniform_4fv_array(
+ batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)&wtb->uniform_params);
+ GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
+ GPU_batch_draw(batch);
+ }
}
-static void widgetbase_draw_ex(
- uiWidgetBase *wtb, const uiWidgetColors *wcol,
- bool show_alpha_checkers)
+static void widgetbase_draw_ex(uiWidgetBase *wtb,
+ const uiWidgetColors *wcol,
+ bool show_alpha_checkers)
{
- uchar inner_col1[4] = {0};
- uchar inner_col2[4] = {0};
- uchar emboss_col[4] = {0};
- uchar outline_col[4] = {0};
- uchar tria_col[4] = {0};
- /* For color widget. */
- if (wcol->shaded != 0) {
- show_alpha_checkers = false;
- }
-
- GPU_blend(true);
-
- /* backdrop non AA */
- if (wtb->draw_inner) {
- if (wcol->shaded == 0) {
- /* simple fill */
- inner_col1[0] = inner_col2[0] = (uchar)wcol->inner[0];
- inner_col1[1] = inner_col2[1] = (uchar)wcol->inner[1];
- inner_col1[2] = inner_col2[2] = (uchar)wcol->inner[2];
- inner_col1[3] = inner_col2[3] = (uchar)wcol->inner[3];
- }
- else {
- /* gradient fill */
- shadecolors4((char *)inner_col1, (char *)inner_col2, wcol->inner, wcol->shadetop, wcol->shadedown);
- }
- }
-
- if (wtb->draw_outline) {
- outline_col[0] = wcol->outline[0];
- outline_col[1] = wcol->outline[1];
- outline_col[2] = wcol->outline[2];
- outline_col[3] = wcol->outline[3] / WIDGET_AA_JITTER;
-
- /* emboss bottom shadow */
- if (wtb->draw_emboss) {
- UI_GetThemeColor4ubv(TH_WIDGET_EMBOSS, emboss_col);
- }
- }
-
- if (wtb->tria1.type != ROUNDBOX_TRIA_NONE) {
- tria_col[0] = wcol->item[0];
- tria_col[1] = wcol->item[1];
- tria_col[2] = wcol->item[2];
- tria_col[3] = (uchar)((float)wcol->item[3] / WIDGET_AA_JITTER);
- }
-
- /* Draw everything in one drawcall */
- if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3] || show_alpha_checkers) {
- widgetbase_set_uniform_colors_ubv(wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, show_alpha_checkers);
-
- GPUBatch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type);
- draw_widgetbase_batch(roundbox_batch, wtb);
- }
-
- GPU_blend(false);
+ uchar inner_col1[4] = {0};
+ uchar inner_col2[4] = {0};
+ uchar emboss_col[4] = {0};
+ uchar outline_col[4] = {0};
+ uchar tria_col[4] = {0};
+ /* For color widget. */
+ if (wcol->shaded != 0) {
+ show_alpha_checkers = false;
+ }
+
+ GPU_blend(true);
+
+ /* backdrop non AA */
+ if (wtb->draw_inner) {
+ if (wcol->shaded == 0) {
+ /* simple fill */
+ inner_col1[0] = inner_col2[0] = (uchar)wcol->inner[0];
+ inner_col1[1] = inner_col2[1] = (uchar)wcol->inner[1];
+ inner_col1[2] = inner_col2[2] = (uchar)wcol->inner[2];
+ inner_col1[3] = inner_col2[3] = (uchar)wcol->inner[3];
+ }
+ else {
+ /* gradient fill */
+ shadecolors4(
+ (char *)inner_col1, (char *)inner_col2, wcol->inner, wcol->shadetop, wcol->shadedown);
+ }
+ }
+
+ if (wtb->draw_outline) {
+ outline_col[0] = wcol->outline[0];
+ outline_col[1] = wcol->outline[1];
+ outline_col[2] = wcol->outline[2];
+ outline_col[3] = wcol->outline[3] / WIDGET_AA_JITTER;
+
+ /* emboss bottom shadow */
+ if (wtb->draw_emboss) {
+ UI_GetThemeColor4ubv(TH_WIDGET_EMBOSS, emboss_col);
+ }
+ }
+
+ if (wtb->tria1.type != ROUNDBOX_TRIA_NONE) {
+ tria_col[0] = wcol->item[0];
+ tria_col[1] = wcol->item[1];
+ tria_col[2] = wcol->item[2];
+ tria_col[3] = (uchar)((float)wcol->item[3] / WIDGET_AA_JITTER);
+ }
+
+ /* Draw everything in one drawcall */
+ if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3] ||
+ show_alpha_checkers) {
+ widgetbase_set_uniform_colors_ubv(
+ wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, show_alpha_checkers);
+
+ GPUBatch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type);
+ draw_widgetbase_batch(roundbox_batch, wtb);
+ }
+
+ GPU_blend(false);
}
static void widgetbase_draw(uiWidgetBase *wtb, const uiWidgetColors *wcol)
{
- widgetbase_draw_ex(wtb, wcol, false);
+ widgetbase_draw_ex(wtb, wcol, false);
}
/* *********************** text/icon ************************************** */
@@ -1314,160 +1406,162 @@ static void widgetbase_draw(uiWidgetBase *wtb, const uiWidgetColors *wcol)
static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect)
{
- int w, h, size;
+ int w, h, size;
- if (icon == ICON_NONE) {
- return;
- }
+ if (icon == ICON_NONE) {
+ return;
+ }
- w = BLI_rcti_size_x(rect);
- h = BLI_rcti_size_y(rect);
- size = MIN2(w, h);
- size -= PREVIEW_PAD * 2; /* padding */
+ w = BLI_rcti_size_x(rect);
+ h = BLI_rcti_size_y(rect);
+ size = MIN2(w, h);
+ size -= PREVIEW_PAD * 2; /* padding */
- if (size > 0) {
- int x = rect->xmin + w / 2 - size / 2;
- int y = rect->ymin + h / 2 - size / 2;
+ if (size > 0) {
+ int x = rect->xmin + w / 2 - size / 2;
+ int y = rect->ymin + h / 2 - size / 2;
- UI_icon_draw_preview_aspect_size(x, y, icon, 1.0f, alpha, size);
- }
+ UI_icon_draw_preview_aspect_size(x, y, icon, 1.0f, alpha, size);
+ }
}
-
static int ui_but_draw_menu_icon(const uiBut *but)
{
- return (but->flag & UI_BUT_ICON_SUBMENU) && (but->dt == UI_EMBOSS_PULLDOWN);
+ return (but->flag & UI_BUT_ICON_SUBMENU) && (but->dt == UI_EMBOSS_PULLDOWN);
}
/* icons have been standardized... and this call draws in untransformed coordinates */
static void widget_draw_icon(
- const uiBut *but, BIFIconID icon, float alpha,
- const rcti *rect, const char mono_color[4])
+ const uiBut *but, BIFIconID icon, float alpha, const rcti *rect, const char mono_color[4])
{
- float xs = 0.0f, ys = 0.0f;
- float aspect, height;
-
- if (but->flag & UI_BUT_ICON_PREVIEW) {
- GPU_blend(true);
- widget_draw_preview(icon, alpha, rect);
- GPU_blend(false);
- return;
- }
-
- /* this icon doesn't need draw... */
- if (icon == ICON_BLANK1 && (but->flag & UI_BUT_ICON_SUBMENU) == 0) {
- return;
- }
-
- aspect = but->block->aspect / UI_DPI_FAC;
- height = ICON_DEFAULT_HEIGHT / aspect;
-
- /* calculate blend color */
- if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_ROW, UI_BTYPE_TOGGLE_N, UI_BTYPE_LISTROW)) {
- if (but->flag & UI_SELECT) {
- /* pass */
- }
- else if (but->flag & UI_ACTIVE) {
- /* pass */
- }
- else {
- alpha = 0.75f;
- }
- }
- else if ((but->type == UI_BTYPE_LABEL)) {
- /* extra feature allows more alpha blending */
- if (but->a1 == 1.0f) {
- alpha *= but->a2;
- }
- }
- else if (ELEM(but->type, UI_BTYPE_BUT)) {
- if (but->flag & UI_BUT_DISABLED) {
- alpha *= 0.5f;
- }
- }
-
- GPU_blend(true);
-
- if (icon && icon != ICON_BLANK1) {
- float ofs = 1.0f / aspect;
-
- if (but->drawflag & UI_BUT_ICON_LEFT) {
- /* special case - icon_only pie buttons */
- if (ui_block_is_pie_menu(but->block) && !ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_POPOVER) && but->str && but->str[0] == '\0') {
- xs = rect->xmin + 2.0f * ofs;
- }
- else if (but->dt == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) {
- xs = rect->xmin + 2.0f * ofs;
- }
- else {
- xs = rect->xmin + 4.0f * ofs;
- }
- }
- else {
- xs = (rect->xmin + rect->xmax - height) / 2.0f;
- }
- ys = (rect->ymin + rect->ymax - height) / 2.0f;
-
- /* force positions to integers, for zoom levels near 1. draws icons crisp. */
- if (aspect > 0.95f && aspect < 1.05f) {
- xs = (int)(xs + 0.1f);
- ys = (int)(ys + 0.1f);
- }
-
- /* to indicate draggable */
- if (but->dragpoin && (but->flag & UI_ACTIVE)) {
- float rgb[3] = {1.25f, 1.25f, 1.25f};
- UI_icon_draw_aspect_color(xs, ys, icon, aspect, rgb, mono_color);
- }
- else if ((but->flag & (UI_ACTIVE | UI_SELECT | UI_SELECT_DRAW)) || !UI_but_is_tool(but)) {
- UI_icon_draw_aspect(xs, ys, icon, aspect, alpha, mono_color);
- }
- else {
- const bTheme *btheme = UI_GetTheme();
- UI_icon_draw_desaturate(xs, ys, icon, aspect, alpha, 1.0 - btheme->tui.icon_saturation, mono_color);
- }
- }
-
- GPU_blend(false);
+ float xs = 0.0f, ys = 0.0f;
+ float aspect, height;
+
+ if (but->flag & UI_BUT_ICON_PREVIEW) {
+ GPU_blend(true);
+ widget_draw_preview(icon, alpha, rect);
+ GPU_blend(false);
+ return;
+ }
+
+ /* this icon doesn't need draw... */
+ if (icon == ICON_BLANK1 && (but->flag & UI_BUT_ICON_SUBMENU) == 0) {
+ return;
+ }
+
+ aspect = but->block->aspect / UI_DPI_FAC;
+ height = ICON_DEFAULT_HEIGHT / aspect;
+
+ /* calculate blend color */
+ if (ELEM(but->type, UI_BTYPE_TOGGLE, UI_BTYPE_ROW, UI_BTYPE_TOGGLE_N, UI_BTYPE_LISTROW)) {
+ if (but->flag & UI_SELECT) {
+ /* pass */
+ }
+ else if (but->flag & UI_ACTIVE) {
+ /* pass */
+ }
+ else {
+ alpha = 0.75f;
+ }
+ }
+ else if ((but->type == UI_BTYPE_LABEL)) {
+ /* extra feature allows more alpha blending */
+ if (but->a1 == 1.0f) {
+ alpha *= but->a2;
+ }
+ }
+ else if (ELEM(but->type, UI_BTYPE_BUT)) {
+ if (but->flag & UI_BUT_DISABLED) {
+ alpha *= 0.5f;
+ }
+ }
+
+ GPU_blend(true);
+
+ if (icon && icon != ICON_BLANK1) {
+ float ofs = 1.0f / aspect;
+
+ if (but->drawflag & UI_BUT_ICON_LEFT) {
+ /* special case - icon_only pie buttons */
+ if (ui_block_is_pie_menu(but->block) && !ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_POPOVER) &&
+ but->str && but->str[0] == '\0') {
+ xs = rect->xmin + 2.0f * ofs;
+ }
+ else if (but->dt == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) {
+ xs = rect->xmin + 2.0f * ofs;
+ }
+ else {
+ xs = rect->xmin + 4.0f * ofs;
+ }
+ }
+ else {
+ xs = (rect->xmin + rect->xmax - height) / 2.0f;
+ }
+ ys = (rect->ymin + rect->ymax - height) / 2.0f;
+
+ /* force positions to integers, for zoom levels near 1. draws icons crisp. */
+ if (aspect > 0.95f && aspect < 1.05f) {
+ xs = (int)(xs + 0.1f);
+ ys = (int)(ys + 0.1f);
+ }
+
+ /* to indicate draggable */
+ if (but->dragpoin && (but->flag & UI_ACTIVE)) {
+ float rgb[3] = {1.25f, 1.25f, 1.25f};
+ UI_icon_draw_aspect_color(xs, ys, icon, aspect, rgb, mono_color);
+ }
+ else if ((but->flag & (UI_ACTIVE | UI_SELECT | UI_SELECT_DRAW)) || !UI_but_is_tool(but)) {
+ UI_icon_draw_aspect(xs, ys, icon, aspect, alpha, mono_color);
+ }
+ else {
+ const bTheme *btheme = UI_GetTheme();
+ UI_icon_draw_desaturate(
+ xs, ys, icon, aspect, alpha, 1.0 - btheme->tui.icon_saturation, mono_color);
+ }
+ }
+
+ GPU_blend(false);
}
-static void widget_draw_submenu_tria(const uiBut *but, const rcti *rect, const uiWidgetColors *wcol)
+static void widget_draw_submenu_tria(const uiBut *but,
+ const rcti *rect,
+ const uiWidgetColors *wcol)
{
- const float aspect = but->block->aspect / UI_DPI_FAC;
- const int tria_height = (int)(ICON_DEFAULT_HEIGHT / aspect);
- const int tria_width = (int)(ICON_DEFAULT_WIDTH / aspect) - 2 * U.pixelsize;
- const int xs = rect->xmax - tria_width;
- const int ys = (rect->ymin + rect->ymax - tria_height) / 2.0f;
- float col[4];
- rctf tria_rect;
-
- rgba_uchar_to_float(col, (const uchar *)wcol->text);
- col[3] *= 0.8f;
-
- BLI_rctf_init(&tria_rect, xs, xs + tria_width, ys, ys + tria_height);
- BLI_rctf_scale(&tria_rect, 0.4f);
-
- GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
- ui_draw_anti_tria_rect(&tria_rect, 'h', col);
+ const float aspect = but->block->aspect / UI_DPI_FAC;
+ const int tria_height = (int)(ICON_DEFAULT_HEIGHT / aspect);
+ const int tria_width = (int)(ICON_DEFAULT_WIDTH / aspect) - 2 * U.pixelsize;
+ const int xs = rect->xmax - tria_width;
+ const int ys = (rect->ymin + rect->ymax - tria_height) / 2.0f;
+ float col[4];
+ rctf tria_rect;
+
+ rgba_uchar_to_float(col, (const uchar *)wcol->text);
+ col[3] *= 0.8f;
+
+ BLI_rctf_init(&tria_rect, xs, xs + tria_width, ys, ys + tria_height);
+ BLI_rctf_scale(&tria_rect, 0.4f);
+
+ GPU_blend(true);
+ UI_widgetbase_draw_cache_flush();
+ GPU_blend(false);
+ ui_draw_anti_tria_rect(&tria_rect, 'h', col);
}
static void ui_text_clip_give_prev_off(uiBut *but, const char *str)
{
- const char *prev_utf8 = BLI_str_find_prev_char_utf8(str, str + but->ofs);
- int bytes = str + but->ofs - prev_utf8;
+ const char *prev_utf8 = BLI_str_find_prev_char_utf8(str, str + but->ofs);
+ int bytes = str + but->ofs - prev_utf8;
- but->ofs -= bytes;
+ but->ofs -= bytes;
}
static void ui_text_clip_give_next_off(uiBut *but, const char *str)
{
- const char *next_utf8 = BLI_str_find_next_char_utf8(str + but->ofs, NULL);
- int bytes = next_utf8 - (str + but->ofs);
+ const char *next_utf8 = BLI_str_find_next_char_utf8(str + but->ofs, NULL);
+ int bytes = next_utf8 - (str + but->ofs);
- but->ofs += bytes;
+ but->ofs += bytes;
}
/**
@@ -1475,32 +1569,37 @@ static void ui_text_clip_give_next_off(uiBut *but, const char *str)
* This func assumes things like kerning handling have already been handled!
* Return the length of modified (right-clipped + ellipsis) string.
*/
-static void ui_text_clip_right_ex(
- const uiFontStyle *fstyle, char *str, const size_t max_len, const float okwidth,
- const char *sep, const int sep_len, const float sep_strwidth, size_t *r_final_len)
+static void ui_text_clip_right_ex(const uiFontStyle *fstyle,
+ char *str,
+ const size_t max_len,
+ const float okwidth,
+ const char *sep,
+ const int sep_len,
+ const float sep_strwidth,
+ size_t *r_final_len)
{
- float tmp;
- int l_end;
-
- BLI_assert(str[0]);
-
- /* If the trailing ellipsis takes more than 20% of all available width, just cut the string
- * (as using the ellipsis would remove even more useful chars, and we cannot show much already!).
- */
- if (sep_strwidth / okwidth > 0.2f) {
- l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
- str[l_end] = '\0';
- if (r_final_len) {
- *r_final_len = (size_t)l_end;
- }
- }
- else {
- l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
- memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
- if (r_final_len) {
- *r_final_len = (size_t)(l_end + sep_len);
- }
- }
+ float tmp;
+ int l_end;
+
+ BLI_assert(str[0]);
+
+ /* If the trailing ellipsis takes more than 20% of all available width, just cut the string
+ * (as using the ellipsis would remove even more useful chars, and we cannot show much already!).
+ */
+ if (sep_strwidth / okwidth > 0.2f) {
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
+ str[l_end] = '\0';
+ if (r_final_len) {
+ *r_final_len = (size_t)l_end;
+ }
+ }
+ else {
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
+ memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */
+ if (r_final_len) {
+ *r_final_len = (size_t)(l_end + sep_len);
+ }
+ }
}
/**
@@ -1509,126 +1608,131 @@ static void ui_text_clip_right_ex(
* If rpart_sep is not Null, the part of str starting to first occurrence of rpart_sep is preserved at all cost (useful
* for strings with shortcuts, like 'AVeryLongFooBarLabelForMenuEntry|Ctrl O' -> 'AVeryLong...MenuEntry|Ctrl O').
*/
-float UI_text_clip_middle_ex(
- const uiFontStyle *fstyle, char *str, float okwidth, const float minwidth,
- const size_t max_len, const char rpart_sep)
+float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
+ char *str,
+ float okwidth,
+ const float minwidth,
+ const size_t max_len,
+ const char rpart_sep)
{
- float strwidth;
-
- /* Add some epsilon to OK width, avoids 'ellipsing' text that nearly fits!
- * Better to have a small piece of the last char cut out,
- * than two remaining chars replaced by an ellipsis... */
- okwidth += 1.0f + UI_DPI_FAC;
-
- BLI_assert(str[0]);
-
- /* need to set this first */
- UI_fontstyle_set(fstyle);
-
- if (fstyle->kerning == 1) {
- /* for BLF_width */
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- strwidth = BLF_width(fstyle->uifont_id, str, max_len);
-
- if ((okwidth > 0.0f) && (strwidth > okwidth)) {
- /* utf8 two-dots leader '..' (shorter than ellipsis '...'),
- * some compilers complain with real litteral string. */
- const char sep[] = {0xe2, 0x80, 0xA5, 0x0};
- const int sep_len = sizeof(sep) - 1;
- const float sep_strwidth = BLF_width(fstyle->uifont_id, sep, sep_len + 1);
- float parts_strwidth;
- size_t l_end;
-
- char *rpart = NULL, rpart_buf[UI_MAX_DRAW_STR];
- float rpart_width = 0.0f;
- size_t rpart_len = 0;
- size_t final_lpart_len;
-
- if (rpart_sep) {
- rpart = strrchr(str, rpart_sep);
-
- if (rpart) {
- rpart_len = strlen(rpart);
- rpart_width = BLF_width(fstyle->uifont_id, rpart, rpart_len);
- okwidth -= rpart_width;
- strwidth -= rpart_width;
-
- if (okwidth < 0.0f) {
- /* Not enough place for actual label, just display protected right part.
- * Here just for safety, should never happen in real life! */
- memmove(str, rpart, rpart_len + 1);
- rpart = NULL;
- okwidth += rpart_width;
- strwidth = rpart_width;
- }
- }
- }
-
- parts_strwidth = (okwidth - sep_strwidth) / 2.0f;
-
- if (rpart) {
- strcpy(rpart_buf, rpart);
- *rpart = '\0';
- rpart = rpart_buf;
- }
-
- l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
- if (l_end < 10 || min_ff(parts_strwidth, strwidth - okwidth) < minwidth) {
- /* If we really have no place, or we would clip a very small piece of string in the middle,
- * only show start of string.
- */
- ui_text_clip_right_ex(fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth, &final_lpart_len);
- }
- else {
- size_t r_offset, r_len;
-
- r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
- r_len = strlen(str + r_offset) + 1; /* +1 for the trailing '\0'. */
-
- if (l_end + sep_len + r_len + rpart_len > max_len) {
- /* Corner case, the str already takes all available mem, and the ellipsis chars would actually
- * add more chars...
- * Better to just trim one or two letters to the right in this case...
- * Note: with a single-char ellipsis, this should never happen! But better be safe here...
- */
- ui_text_clip_right_ex(fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth, &final_lpart_len);
- }
- else {
- memmove(str + l_end + sep_len, str + r_offset, r_len);
- memcpy(str + l_end, sep, sep_len);
- /* -1 to remove trailing '\0'! */
- final_lpart_len = (size_t)(l_end + sep_len + r_len - 1);
-
- while (BLF_width(fstyle->uifont_id, str, max_len) > okwidth) {
- /* This will happen because a lot of string width processing is done in integer pixels,
- * which can introduce a rather high error in the end (about 2 pixels or so).
- * Only one char removal shall ever be needed in real-life situation... */
- r_len--;
- final_lpart_len--;
- char *c = str + l_end + sep_len;
- memmove(c, c + 1, r_len);
- }
- }
- }
-
- if (rpart) {
- /* Add back preserved right part to our shorten str. */
- memcpy(str + final_lpart_len, rpart, rpart_len + 1); /* +1 for trailing '\0'. */
- okwidth += rpart_width;
- }
-
- strwidth = BLF_width(fstyle->uifont_id, str, max_len);
- }
-
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- BLI_assert(strwidth <= okwidth);
-
- return strwidth;
+ float strwidth;
+
+ /* Add some epsilon to OK width, avoids 'ellipsing' text that nearly fits!
+ * Better to have a small piece of the last char cut out,
+ * than two remaining chars replaced by an ellipsis... */
+ okwidth += 1.0f + UI_DPI_FAC;
+
+ BLI_assert(str[0]);
+
+ /* need to set this first */
+ UI_fontstyle_set(fstyle);
+
+ if (fstyle->kerning == 1) {
+ /* for BLF_width */
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ strwidth = BLF_width(fstyle->uifont_id, str, max_len);
+
+ if ((okwidth > 0.0f) && (strwidth > okwidth)) {
+ /* utf8 two-dots leader '..' (shorter than ellipsis '...'),
+ * some compilers complain with real litteral string. */
+ const char sep[] = {0xe2, 0x80, 0xA5, 0x0};
+ const int sep_len = sizeof(sep) - 1;
+ const float sep_strwidth = BLF_width(fstyle->uifont_id, sep, sep_len + 1);
+ float parts_strwidth;
+ size_t l_end;
+
+ char *rpart = NULL, rpart_buf[UI_MAX_DRAW_STR];
+ float rpart_width = 0.0f;
+ size_t rpart_len = 0;
+ size_t final_lpart_len;
+
+ if (rpart_sep) {
+ rpart = strrchr(str, rpart_sep);
+
+ if (rpart) {
+ rpart_len = strlen(rpart);
+ rpart_width = BLF_width(fstyle->uifont_id, rpart, rpart_len);
+ okwidth -= rpart_width;
+ strwidth -= rpart_width;
+
+ if (okwidth < 0.0f) {
+ /* Not enough place for actual label, just display protected right part.
+ * Here just for safety, should never happen in real life! */
+ memmove(str, rpart, rpart_len + 1);
+ rpart = NULL;
+ okwidth += rpart_width;
+ strwidth = rpart_width;
+ }
+ }
+ }
+
+ parts_strwidth = (okwidth - sep_strwidth) / 2.0f;
+
+ if (rpart) {
+ strcpy(rpart_buf, rpart);
+ *rpart = '\0';
+ rpart = rpart_buf;
+ }
+
+ l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
+ if (l_end < 10 || min_ff(parts_strwidth, strwidth - okwidth) < minwidth) {
+ /* If we really have no place, or we would clip a very small piece of string in the middle,
+ * only show start of string.
+ */
+ ui_text_clip_right_ex(
+ fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth, &final_lpart_len);
+ }
+ else {
+ size_t r_offset, r_len;
+
+ r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, NULL);
+ r_len = strlen(str + r_offset) + 1; /* +1 for the trailing '\0'. */
+
+ if (l_end + sep_len + r_len + rpart_len > max_len) {
+ /* Corner case, the str already takes all available mem, and the ellipsis chars would actually
+ * add more chars...
+ * Better to just trim one or two letters to the right in this case...
+ * Note: with a single-char ellipsis, this should never happen! But better be safe here...
+ */
+ ui_text_clip_right_ex(
+ fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth, &final_lpart_len);
+ }
+ else {
+ memmove(str + l_end + sep_len, str + r_offset, r_len);
+ memcpy(str + l_end, sep, sep_len);
+ /* -1 to remove trailing '\0'! */
+ final_lpart_len = (size_t)(l_end + sep_len + r_len - 1);
+
+ while (BLF_width(fstyle->uifont_id, str, max_len) > okwidth) {
+ /* This will happen because a lot of string width processing is done in integer pixels,
+ * which can introduce a rather high error in the end (about 2 pixels or so).
+ * Only one char removal shall ever be needed in real-life situation... */
+ r_len--;
+ final_lpart_len--;
+ char *c = str + l_end + sep_len;
+ memmove(c, c + 1, r_len);
+ }
+ }
+ }
+
+ if (rpart) {
+ /* Add back preserved right part to our shorten str. */
+ memcpy(str + final_lpart_len, rpart, rpart_len + 1); /* +1 for trailing '\0'. */
+ okwidth += rpart_width;
+ }
+
+ strwidth = BLF_width(fstyle->uifont_id, str, max_len);
+ }
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ BLI_assert(strwidth <= okwidth);
+
+ return strwidth;
}
/**
@@ -1636,30 +1740,37 @@ float UI_text_clip_middle_ex(
*/
static void ui_text_clip_middle(const uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
- /* No margin for labels! */
- const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU, UI_BTYPE_POPOVER) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
- const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
- const size_t max_len = sizeof(but->drawstr);
- const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
-
- but->ofs = 0;
- but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, '\0');
+ /* No margin for labels! */
+ const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU, UI_BTYPE_POPOVER) ?
+ 0 :
+ (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
+ const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
+ const size_t max_len = sizeof(but->drawstr);
+ const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
+
+ but->ofs = 0;
+ but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, '\0');
}
/**
* Like ui_text_clip_middle(), but protect/preserve at all cost the right part of the string after sep.
* Useful for strings with shortcuts (like 'AVeryLongFooBarLabelForMenuEntry|Ctrl O' -> 'AVeryLong...MenuEntry|Ctrl O').
*/
-static void ui_text_clip_middle_protect_right(const uiFontStyle *fstyle, uiBut *but, const rcti *rect, const char rsep)
+static void ui_text_clip_middle_protect_right(const uiFontStyle *fstyle,
+ uiBut *but,
+ const rcti *rect,
+ const char rsep)
{
- /* No margin for labels! */
- const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU, UI_BTYPE_POPOVER) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
- const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
- const size_t max_len = sizeof(but->drawstr);
- const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
-
- but->ofs = 0;
- but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, rsep);
+ /* No margin for labels! */
+ const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU, UI_BTYPE_POPOVER) ?
+ 0 :
+ (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
+ const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
+ const size_t max_len = sizeof(but->drawstr);
+ const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
+
+ but->ofs = 0;
+ but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, rsep);
}
/**
@@ -1667,67 +1778,67 @@ static void ui_text_clip_middle_protect_right(const uiFontStyle *fstyle, uiBut *
*/
static void ui_text_clip_cursor(const uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
- const int border = (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
- const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
-
- BLI_assert(but->editstr && but->pos >= 0);
-
- /* need to set this first */
- UI_fontstyle_set(fstyle);
-
- if (fstyle->kerning == 1) {
- /* for BLF_width */
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- /* define ofs dynamically */
- if (but->ofs > but->pos) {
- but->ofs = but->pos;
- }
-
- if (BLF_width(fstyle->uifont_id, but->editstr, INT_MAX) <= okwidth) {
- but->ofs = 0;
- }
-
- but->strwidth = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, INT_MAX);
-
- if (but->strwidth > okwidth) {
- int len = strlen(but->editstr);
-
- while (but->strwidth > okwidth) {
- float width;
-
- /* string position of cursor */
- width = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, (but->pos - but->ofs));
-
- /* if cursor is at 20 pixels of right side button we clip left */
- if (width > okwidth - 20) {
- ui_text_clip_give_next_off(but, but->editstr);
- }
- else {
- int bytes;
- /* shift string to the left */
- if (width < 20 && but->ofs > 0) {
- ui_text_clip_give_prev_off(but, but->editstr);
- }
- bytes = BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->editstr, but->editstr + len));
- if (bytes == -1) {
- bytes = 1;
- }
- len -= bytes;
- }
-
- but->strwidth = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, len - but->ofs);
-
- if (but->strwidth < 10) {
- break;
- }
- }
- }
-
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
+ const int border = (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
+ const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
+
+ BLI_assert(but->editstr && but->pos >= 0);
+
+ /* need to set this first */
+ UI_fontstyle_set(fstyle);
+
+ if (fstyle->kerning == 1) {
+ /* for BLF_width */
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ /* define ofs dynamically */
+ if (but->ofs > but->pos) {
+ but->ofs = but->pos;
+ }
+
+ if (BLF_width(fstyle->uifont_id, but->editstr, INT_MAX) <= okwidth) {
+ but->ofs = 0;
+ }
+
+ but->strwidth = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, INT_MAX);
+
+ if (but->strwidth > okwidth) {
+ int len = strlen(but->editstr);
+
+ while (but->strwidth > okwidth) {
+ float width;
+
+ /* string position of cursor */
+ width = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, (but->pos - but->ofs));
+
+ /* if cursor is at 20 pixels of right side button we clip left */
+ if (width > okwidth - 20) {
+ ui_text_clip_give_next_off(but, but->editstr);
+ }
+ else {
+ int bytes;
+ /* shift string to the left */
+ if (width < 20 && but->ofs > 0) {
+ ui_text_clip_give_prev_off(but, but->editstr);
+ }
+ bytes = BLI_str_utf8_size(BLI_str_find_prev_char_utf8(but->editstr, but->editstr + len));
+ if (bytes == -1) {
+ bytes = 1;
+ }
+ len -= bytes;
+ }
+
+ but->strwidth = BLF_width(fstyle->uifont_id, but->editstr + but->ofs, len - but->ofs);
+
+ if (but->strwidth < 10) {
+ break;
+ }
+ }
+ }
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
}
/**
@@ -1737,1093 +1848,1123 @@ static void ui_text_clip_cursor(const uiFontStyle *fstyle, uiBut *but, const rct
*/
static void ui_text_clip_right_label(const uiFontStyle *fstyle, uiBut *but, const rcti *rect)
{
- const int border = UI_TEXT_CLIP_MARGIN + 1;
- const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
- char *cpoin = NULL;
- int drawstr_len = strlen(but->drawstr);
- const char *cpend = but->drawstr + drawstr_len;
-
- /* need to set this first */
- UI_fontstyle_set(fstyle);
-
- if (fstyle->kerning == 1) {
- /* for BLF_width */
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr));
- but->ofs = 0;
-
-
- /* First shorten num-buttons eg,
- * Translucency: 0.000
- * becomes
- * Trans: 0.000
- */
-
- /* find the space after ':' separator */
- cpoin = strrchr(but->drawstr, ':');
-
- if (cpoin && (cpoin < cpend - 2)) {
- char *cp2 = cpoin;
-
- /* chop off the leading text, starting from the right */
- while (but->strwidth > okwidth && cp2 > but->drawstr) {
- const char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, cp2);
- int bytes = cp2 - prev_utf8;
-
- /* shift the text after and including cp2 back by 1 char,
- * +1 to include null terminator */
- memmove(cp2 - bytes, cp2, drawstr_len + 1);
- cp2 -= bytes;
-
- drawstr_len -= bytes;
- // BLI_assert(strlen(but->drawstr) == drawstr_len);
-
- but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
- if (but->strwidth < 10) {
- break;
- }
- }
-
-
- /* after the leading text is gone, chop off the : and following space, with ofs */
- while ((but->strwidth > okwidth) && (but->ofs < 2)) {
- ui_text_clip_give_next_off(but, but->drawstr);
- but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
- if (but->strwidth < 10) {
- break;
- }
- }
- }
-
-
- /* Now just remove trailing chars */
- /* once the label's gone, chop off the least significant digits */
- if (but->strwidth > okwidth) {
- float strwidth;
- drawstr_len = BLF_width_to_strlen(
- fstyle->uifont_id, but->drawstr + but->ofs,
- drawstr_len - but->ofs, okwidth, &strwidth) + but->ofs;
- but->strwidth = strwidth;
- but->drawstr[drawstr_len] = 0;
- }
-
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
+ const int border = UI_TEXT_CLIP_MARGIN + 1;
+ const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
+ char *cpoin = NULL;
+ int drawstr_len = strlen(but->drawstr);
+ const char *cpend = but->drawstr + drawstr_len;
+
+ /* need to set this first */
+ UI_fontstyle_set(fstyle);
+
+ if (fstyle->kerning == 1) {
+ /* for BLF_width */
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr));
+ but->ofs = 0;
+
+ /* First shorten num-buttons eg,
+ * Translucency: 0.000
+ * becomes
+ * Trans: 0.000
+ */
+
+ /* find the space after ':' separator */
+ cpoin = strrchr(but->drawstr, ':');
+
+ if (cpoin && (cpoin < cpend - 2)) {
+ char *cp2 = cpoin;
+
+ /* chop off the leading text, starting from the right */
+ while (but->strwidth > okwidth && cp2 > but->drawstr) {
+ const char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, cp2);
+ int bytes = cp2 - prev_utf8;
+
+ /* shift the text after and including cp2 back by 1 char,
+ * +1 to include null terminator */
+ memmove(cp2 - bytes, cp2, drawstr_len + 1);
+ cp2 -= bytes;
+
+ drawstr_len -= bytes;
+ // BLI_assert(strlen(but->drawstr) == drawstr_len);
+
+ but->strwidth = BLF_width(
+ fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
+ if (but->strwidth < 10) {
+ break;
+ }
+ }
+
+ /* after the leading text is gone, chop off the : and following space, with ofs */
+ while ((but->strwidth > okwidth) && (but->ofs < 2)) {
+ ui_text_clip_give_next_off(but, but->drawstr);
+ but->strwidth = BLF_width(
+ fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs);
+ if (but->strwidth < 10) {
+ break;
+ }
+ }
+ }
+
+ /* Now just remove trailing chars */
+ /* once the label's gone, chop off the least significant digits */
+ if (but->strwidth > okwidth) {
+ float strwidth;
+ drawstr_len = BLF_width_to_strlen(fstyle->uifont_id,
+ but->drawstr + but->ofs,
+ drawstr_len - but->ofs,
+ okwidth,
+ &strwidth) +
+ but->ofs;
+ but->strwidth = strwidth;
+ but->drawstr[drawstr_len] = 0;
+ }
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
}
#ifdef WITH_INPUT_IME
-static void widget_draw_text_ime_underline(
- uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, const rcti *rect,
- const wmIMEData *ime_data, const char *drawstr)
+static void widget_draw_text_ime_underline(uiFontStyle *fstyle,
+ uiWidgetColors *wcol,
+ uiBut *but,
+ const rcti *rect,
+ const wmIMEData *ime_data,
+ const char *drawstr)
{
- int ofs_x, width;
- int rect_x = BLI_rcti_size_x(rect);
- int sel_start = ime_data->sel_start, sel_end = ime_data->sel_end;
- float fcol[4];
-
- if (drawstr[0] != 0) {
- if (but->pos >= but->ofs) {
- ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->pos - but->ofs);
- }
- else {
- ofs_x = 0;
- }
-
- width = BLF_width(
- fstyle->uifont_id, drawstr + but->ofs,
- ime_data->composite_len + but->pos - but->ofs);
-
- rgba_uchar_to_float(fcol, wcol->text);
- UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 1, fcol);
-
- /* draw the thick line */
- if (sel_start != -1 && sel_end != -1) {
- sel_end -= sel_start;
- sel_start += but->pos;
-
- if (sel_start >= but->ofs) {
- ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, sel_start - but->ofs);
- }
- else {
- ofs_x = 0;
- }
-
- width = BLF_width(
- fstyle->uifont_id, drawstr + but->ofs,
- sel_end + sel_start - but->ofs);
-
- UI_draw_text_underline(rect->xmin + ofs_x, rect->ymin + 6 * U.pixelsize, min_ii(width, rect_x - 2) - ofs_x, 2, fcol);
- }
- }
+ int ofs_x, width;
+ int rect_x = BLI_rcti_size_x(rect);
+ int sel_start = ime_data->sel_start, sel_end = ime_data->sel_end;
+ float fcol[4];
+
+ if (drawstr[0] != 0) {
+ if (but->pos >= but->ofs) {
+ ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->pos - but->ofs);
+ }
+ else {
+ ofs_x = 0;
+ }
+
+ width = BLF_width(
+ fstyle->uifont_id, drawstr + but->ofs, ime_data->composite_len + but->pos - but->ofs);
+
+ rgba_uchar_to_float(fcol, wcol->text);
+ UI_draw_text_underline(rect->xmin + ofs_x,
+ rect->ymin + 6 * U.pixelsize,
+ min_ii(width, rect_x - 2) - ofs_x,
+ 1,
+ fcol);
+
+ /* draw the thick line */
+ if (sel_start != -1 && sel_end != -1) {
+ sel_end -= sel_start;
+ sel_start += but->pos;
+
+ if (sel_start >= but->ofs) {
+ ofs_x = BLF_width(fstyle->uifont_id, drawstr + but->ofs, sel_start - but->ofs);
+ }
+ else {
+ ofs_x = 0;
+ }
+
+ width = BLF_width(fstyle->uifont_id, drawstr + but->ofs, sel_end + sel_start - but->ofs);
+
+ UI_draw_text_underline(rect->xmin + ofs_x,
+ rect->ymin + 6 * U.pixelsize,
+ min_ii(width, rect_x - 2) - ofs_x,
+ 2,
+ fcol);
+ }
+ }
}
-#endif /* WITH_INPUT_IME */
+#endif /* WITH_INPUT_IME */
-static void widget_draw_text(const uiFontStyle *fstyle, const uiWidgetColors *wcol, uiBut *but, rcti *rect)
+static void widget_draw_text(const uiFontStyle *fstyle,
+ const uiWidgetColors *wcol,
+ uiBut *but,
+ rcti *rect)
{
- int drawstr_left_len = UI_MAX_DRAW_STR;
- const char *drawstr = but->drawstr;
- const char *drawstr_right = NULL;
- bool use_right_only = false;
+ int drawstr_left_len = UI_MAX_DRAW_STR;
+ const char *drawstr = but->drawstr;
+ const char *drawstr_right = NULL;
+ bool use_right_only = false;
#ifdef WITH_INPUT_IME
- const wmIMEData *ime_data;
+ const wmIMEData *ime_data;
#endif
- UI_fontstyle_set(fstyle);
-
- eFontStyle_Align align;
- if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) {
- align = UI_STYLE_TEXT_LEFT;
- }
- else if (but->drawflag & UI_BUT_TEXT_RIGHT) {
- align = UI_STYLE_TEXT_RIGHT;
- }
- else {
- align = UI_STYLE_TEXT_CENTER;
- }
-
- if (fstyle->kerning == 1) {
- /* for BLF_width */
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- /* Special case: when we're entering text for multiple buttons,
- * don't draw the text for any of the multi-editing buttons */
- if (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI)) {
- uiBut *but_edit = ui_but_drag_multi_edit_get(but);
- if (but_edit) {
- drawstr = but_edit->editstr;
- align = UI_STYLE_TEXT_LEFT;
- }
- }
- else {
- if (but->editstr) {
- /* max length isn't used in this case,
- * we rely on string being NULL terminated. */
- drawstr_left_len = INT_MAX;
+ UI_fontstyle_set(fstyle);
+
+ eFontStyle_Align align;
+ if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) {
+ align = UI_STYLE_TEXT_LEFT;
+ }
+ else if (but->drawflag & UI_BUT_TEXT_RIGHT) {
+ align = UI_STYLE_TEXT_RIGHT;
+ }
+ else {
+ align = UI_STYLE_TEXT_CENTER;
+ }
+
+ if (fstyle->kerning == 1) {
+ /* for BLF_width */
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ /* Special case: when we're entering text for multiple buttons,
+ * don't draw the text for any of the multi-editing buttons */
+ if (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI)) {
+ uiBut *but_edit = ui_but_drag_multi_edit_get(but);
+ if (but_edit) {
+ drawstr = but_edit->editstr;
+ align = UI_STYLE_TEXT_LEFT;
+ }
+ }
+ else {
+ if (but->editstr) {
+ /* max length isn't used in this case,
+ * we rely on string being NULL terminated. */
+ drawstr_left_len = INT_MAX;
#ifdef WITH_INPUT_IME
- /* FIXME, IME is modifying 'const char *drawstr! */
- ime_data = ui_but_ime_data_get(but);
-
- if (ime_data && ime_data->composite_len) {
- /* insert composite string into cursor pos */
- BLI_snprintf(
- (char *)drawstr, UI_MAX_DRAW_STR, "%s%s%s",
- but->editstr, ime_data->str_composite,
- but->editstr + but->pos);
- }
- else
+ /* FIXME, IME is modifying 'const char *drawstr! */
+ ime_data = ui_but_ime_data_get(but);
+
+ if (ime_data && ime_data->composite_len) {
+ /* insert composite string into cursor pos */
+ BLI_snprintf((char *)drawstr,
+ UI_MAX_DRAW_STR,
+ "%s%s%s",
+ but->editstr,
+ ime_data->str_composite,
+ but->editstr + but->pos);
+ }
+ else
#endif
- {
- drawstr = but->editstr;
- }
- }
- }
-
-
- /* text button selection, cursor, composite underline */
- if (but->editstr && but->pos != -1) {
- int but_pos_ofs;
- int tx, ty;
-
- /* text button selection */
- if ((but->selend - but->selsta) > 0) {
- int selsta_draw, selwidth_draw;
-
- if (drawstr[0] != 0) {
- /* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
-
- if (but->selsta >= but->ofs) {
- selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs);
- }
- else {
- selsta_draw = 0;
- }
-
- selwidth_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selend - but->ofs);
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor4ubv((uchar *)wcol->item);
- immRecti(pos, rect->xmin + selsta_draw,
- rect->ymin + 2,
- min_ii(rect->xmin + selwidth_draw, rect->xmax - 2),
- rect->ymax - 2);
-
- immUnbindProgram();
- }
- }
-
- /* text cursor */
- but_pos_ofs = but->pos;
+ {
+ drawstr = but->editstr;
+ }
+ }
+ }
+
+ /* text button selection, cursor, composite underline */
+ if (but->editstr && but->pos != -1) {
+ int but_pos_ofs;
+ int tx, ty;
+
+ /* text button selection */
+ if ((but->selend - but->selsta) > 0) {
+ int selsta_draw, selwidth_draw;
+
+ if (drawstr[0] != 0) {
+ /* We are drawing on top of widget bases. Flush cache. */
+ GPU_blend(true);
+ UI_widgetbase_draw_cache_flush();
+ GPU_blend(false);
+
+ if (but->selsta >= but->ofs) {
+ selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs);
+ }
+ else {
+ selsta_draw = 0;
+ }
+
+ selwidth_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selend - but->ofs);
+
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor4ubv((uchar *)wcol->item);
+ immRecti(pos,
+ rect->xmin + selsta_draw,
+ rect->ymin + 2,
+ min_ii(rect->xmin + selwidth_draw, rect->xmax - 2),
+ rect->ymax - 2);
+
+ immUnbindProgram();
+ }
+ }
+
+ /* text cursor */
+ but_pos_ofs = but->pos;
#ifdef WITH_INPUT_IME
- /* if is ime compositing, move the cursor */
- if (ime_data && ime_data->composite_len && ime_data->cursor_pos != -1) {
- but_pos_ofs += ime_data->cursor_pos;
- }
+ /* if is ime compositing, move the cursor */
+ if (ime_data && ime_data->composite_len && ime_data->cursor_pos != -1) {
+ but_pos_ofs += ime_data->cursor_pos;
+ }
#endif
- if (but->pos >= but->ofs) {
- int t;
- if (drawstr[0] != 0) {
- t = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but_pos_ofs - but->ofs);
- }
- else {
- t = 0;
- }
- /* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ if (but->pos >= but->ofs) {
+ int t;
+ if (drawstr[0] != 0) {
+ t = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but_pos_ofs - but->ofs);
+ }
+ else {
+ t = 0;
+ }
+ /* We are drawing on top of widget bases. Flush cache. */
+ GPU_blend(true);
+ UI_widgetbase_draw_cache_flush();
+ GPU_blend(false);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3f(0.2f, 0.6f, 0.9f);
+ immUniformColor3f(0.2f, 0.6f, 0.9f);
- tx = rect->xmin + t + 2;
- ty = rect->ymin + 2;
+ tx = rect->xmin + t + 2;
+ ty = rect->ymin + 2;
- /* draw cursor */
- immRecti(pos, rect->xmin + t, ty, tx, rect->ymax - 2);
+ /* draw cursor */
+ immRecti(pos, rect->xmin + t, ty, tx, rect->ymax - 2);
- immUnbindProgram();
- }
+ immUnbindProgram();
+ }
#ifdef WITH_INPUT_IME
- if (ime_data && ime_data->composite_len) {
- /* ime cursor following */
- if (but->pos >= but->ofs) {
- ui_but_ime_reposition(but, tx + 5, ty + 3, false);
- }
-
- /* composite underline */
- widget_draw_text_ime_underline(fstyle, wcol, but, rect, ime_data, drawstr);
- }
+ if (ime_data && ime_data->composite_len) {
+ /* ime cursor following */
+ if (but->pos >= but->ofs) {
+ ui_but_ime_reposition(but, tx + 5, ty + 3, false);
+ }
+
+ /* composite underline */
+ widget_draw_text_ime_underline(fstyle, wcol, but, rect, ime_data, drawstr);
+ }
#endif
- }
+ }
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
#if 0
- ui_rasterpos_safe(x, y, but->aspect);
- transopts = ui_translate_buttons();
+ ui_rasterpos_safe(x, y, but->aspect);
+ transopts = ui_translate_buttons();
#endif
- /* cut string in 2 parts - only for menu entries */
- if ((but->drawflag & UI_BUT_HAS_SHORTCUT) &&
- (but->editstr == NULL))
- {
- if (but->flag & UI_BUT_HAS_SEP_CHAR) {
- drawstr_right = strrchr(drawstr, UI_SEP_CHAR);
- if (drawstr_right) {
- drawstr_left_len = (drawstr_right - drawstr);
- drawstr_right++;
- }
- }
- }
+ /* cut string in 2 parts - only for menu entries */
+ if ((but->drawflag & UI_BUT_HAS_SHORTCUT) && (but->editstr == NULL)) {
+ if (but->flag & UI_BUT_HAS_SEP_CHAR) {
+ drawstr_right = strrchr(drawstr, UI_SEP_CHAR);
+ if (drawstr_right) {
+ drawstr_left_len = (drawstr_right - drawstr);
+ drawstr_right++;
+ }
+ }
+ }
#ifdef USE_NUMBUTS_LR_ALIGN
- if (!drawstr_right &&
- (but->drawflag & UI_BUT_TEXT_LEFT) &&
- ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
- /* if we're editing or multi-drag (fake editing), then use left alignment */
- (but->editstr == NULL) && (drawstr == but->drawstr))
- {
- drawstr_right = strchr(drawstr + but->ofs, ':');
- if (drawstr_right) {
- drawstr_right++;
- drawstr_left_len = (drawstr_right - drawstr);
-
- while (*drawstr_right == ' ') {
- drawstr_right++;
- }
- }
- else {
- /* no prefix, even so use only cpoin */
- drawstr_right = drawstr + but->ofs;
- use_right_only = true;
- }
- }
+ if (!drawstr_right && (but->drawflag & UI_BUT_TEXT_LEFT) &&
+ ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
+ /* if we're editing or multi-drag (fake editing), then use left alignment */
+ (but->editstr == NULL) && (drawstr == but->drawstr)) {
+ drawstr_right = strchr(drawstr + but->ofs, ':');
+ if (drawstr_right) {
+ drawstr_right++;
+ drawstr_left_len = (drawstr_right - drawstr);
+
+ while (*drawstr_right == ' ') {
+ drawstr_right++;
+ }
+ }
+ else {
+ /* no prefix, even so use only cpoin */
+ drawstr_right = drawstr + but->ofs;
+ use_right_only = true;
+ }
+ }
#endif
- if (!use_right_only) {
- /* for underline drawing */
- float font_xofs, font_yofs;
-
- int drawlen = (drawstr_left_len == INT_MAX) ? strlen(drawstr + but->ofs) : (drawstr_left_len - but->ofs);
-
- if (drawlen > 0) {
- UI_fontstyle_draw_ex(
- fstyle, rect, drawstr + but->ofs, (uchar *)wcol->text,
- &(struct uiFontStyleDraw_Params) { .align = align, },
- drawlen, &font_xofs, &font_yofs);
-
- if (but->menu_key != '\0') {
- char fixedbuf[128];
- const char *str;
-
- BLI_strncpy(fixedbuf, drawstr + but->ofs, min_ii(sizeof(fixedbuf), drawlen));
-
- str = strchr(fixedbuf, but->menu_key - 32); /* upper case */
- if (str == NULL) {
- str = strchr(fixedbuf, but->menu_key);
- }
-
- if (str) {
- int ul_index = -1;
- float ul_advance;
-
- ul_index = (int)(str - fixedbuf);
-
- if (fstyle->kerning == 1) {
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- fixedbuf[ul_index] = '\0';
- ul_advance = BLF_width(fstyle->uifont_id, fixedbuf, ul_index) + (1.0f * UI_DPI_FAC);
-
- BLF_position(fstyle->uifont_id, rect->xmin + font_xofs + ul_advance, rect->ymin + font_yofs, 0.0f);
- BLF_color4ubv(fstyle->uifont_id, (uchar *)wcol->text);
- BLF_draw(fstyle->uifont_id, "_", 2);
-
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
- }
- }
- }
- }
-
- /* part text right aligned */
- if (drawstr_right) {
- char col[4];
- copy_v4_v4_char(col, wcol->text);
- if (but->drawflag & UI_BUT_HAS_SHORTCUT) {
- col[3] *= 0.5f;
- }
-
- rect->xmax -= UI_TEXT_CLIP_MARGIN;
- UI_fontstyle_draw(
- fstyle, rect, drawstr_right, (const uchar *)col,
- &(struct uiFontStyleDraw_Params) { .align = UI_STYLE_TEXT_RIGHT, });
- }
+ if (!use_right_only) {
+ /* for underline drawing */
+ float font_xofs, font_yofs;
+
+ int drawlen = (drawstr_left_len == INT_MAX) ? strlen(drawstr + but->ofs) :
+ (drawstr_left_len - but->ofs);
+
+ if (drawlen > 0) {
+ UI_fontstyle_draw_ex(fstyle,
+ rect,
+ drawstr + but->ofs,
+ (uchar *)wcol->text,
+ &(struct uiFontStyleDraw_Params){
+ .align = align,
+ },
+ drawlen,
+ &font_xofs,
+ &font_yofs);
+
+ if (but->menu_key != '\0') {
+ char fixedbuf[128];
+ const char *str;
+
+ BLI_strncpy(fixedbuf, drawstr + but->ofs, min_ii(sizeof(fixedbuf), drawlen));
+
+ str = strchr(fixedbuf, but->menu_key - 32); /* upper case */
+ if (str == NULL) {
+ str = strchr(fixedbuf, but->menu_key);
+ }
+
+ if (str) {
+ int ul_index = -1;
+ float ul_advance;
+
+ ul_index = (int)(str - fixedbuf);
+
+ if (fstyle->kerning == 1) {
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ fixedbuf[ul_index] = '\0';
+ ul_advance = BLF_width(fstyle->uifont_id, fixedbuf, ul_index) + (1.0f * UI_DPI_FAC);
+
+ BLF_position(fstyle->uifont_id,
+ rect->xmin + font_xofs + ul_advance,
+ rect->ymin + font_yofs,
+ 0.0f);
+ BLF_color4ubv(fstyle->uifont_id, (uchar *)wcol->text);
+ BLF_draw(fstyle->uifont_id, "_", 2);
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+ }
+ }
+ }
+ }
+
+ /* part text right aligned */
+ if (drawstr_right) {
+ char col[4];
+ copy_v4_v4_char(col, wcol->text);
+ if (but->drawflag & UI_BUT_HAS_SHORTCUT) {
+ col[3] *= 0.5f;
+ }
+
+ rect->xmax -= UI_TEXT_CLIP_MARGIN;
+ UI_fontstyle_draw(fstyle,
+ rect,
+ drawstr_right,
+ (const uchar *)col,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_RIGHT,
+ });
+ }
}
static BIFIconID widget_icon_id(uiBut *but)
{
- if (!(but->flag & UI_HAS_ICON)) {
- return ICON_NONE;
- }
-
- /* Consecutive icons can be toggle between. */
- if (but->drawflag & UI_BUT_ICON_REVERSE) {
- return but->icon - but->iconadd;
- }
- else {
- return but->icon + but->iconadd;
- }
+ if (!(but->flag & UI_HAS_ICON)) {
+ return ICON_NONE;
+ }
+
+ /* Consecutive icons can be toggle between. */
+ if (but->drawflag & UI_BUT_ICON_REVERSE) {
+ return but->icon - but->iconadd;
+ }
+ else {
+ return but->icon + but->iconadd;
+ }
}
/* draws text and icons for buttons */
-static void widget_draw_text_icon(const uiFontStyle *fstyle, const uiWidgetColors *wcol, uiBut *but, rcti *rect)
+static void widget_draw_text_icon(const uiFontStyle *fstyle,
+ const uiWidgetColors *wcol,
+ uiBut *but,
+ rcti *rect)
{
- const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
- const bool show_menu_icon = ui_but_draw_menu_icon(but);
- float alpha = (float)wcol->text[3] / 255.0f;
- char password_str[UI_MAX_DRAW_STR];
-
- ui_but_text_password_hide(password_str, but, false);
-
- /* check for button text label */
- if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_POPOVER) && (but->flag & UI_BUT_NODE_LINK)) {
- rcti temp = *rect;
- temp.xmin = rect->xmax - BLI_rcti_size_y(rect) - 1;
- widget_draw_icon(but, ICON_LAYER_USED, alpha, &temp, wcol->text);
- rect->xmax = temp.xmin;
- }
-
- /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
- * and offset the text label to accommodate it */
-
- /* Big previews with optional text label below */
- if (but->flag & UI_BUT_ICON_PREVIEW && ui_block_is_menu(but->block)) {
- const BIFIconID icon = widget_icon_id(but);
- int icon_size = BLI_rcti_size_y(rect);
- int text_size = 0;
-
- /* This is a bit britle, but avoids adding an 'UI_BUT_HAS_LABEL' flag to but... */
- if (icon_size > BLI_rcti_size_x(rect)) {
- /* button is not square, it has extra height for label */
- text_size = UI_UNIT_Y;
- icon_size -= text_size;
- }
-
- /* draw icon in rect above the space reserved for the label */
- rect->ymin += text_size;
- GPU_blend(true);
- widget_draw_preview(icon, alpha, rect);
- GPU_blend(false);
-
- /* offset rect to draw label in */
- rect->ymin -= text_size;
- rect->ymax -= icon_size;
-
- /* vertically centering text */
- rect->ymin += UI_UNIT_Y / 2;
- }
- /* Icons on the left with optional text label on the right */
- else if (but->flag & UI_HAS_ICON || show_menu_icon) {
- const bool is_tool = UI_but_is_tool(but);
-
- /* XXX add way to draw icons at a different size!
- * Use small icons for popup. */
+ const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
+ const bool show_menu_icon = ui_but_draw_menu_icon(but);
+ float alpha = (float)wcol->text[3] / 255.0f;
+ char password_str[UI_MAX_DRAW_STR];
+
+ ui_but_text_password_hide(password_str, but, false);
+
+ /* check for button text label */
+ if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_POPOVER) && (but->flag & UI_BUT_NODE_LINK)) {
+ rcti temp = *rect;
+ temp.xmin = rect->xmax - BLI_rcti_size_y(rect) - 1;
+ widget_draw_icon(but, ICON_LAYER_USED, alpha, &temp, wcol->text);
+ rect->xmax = temp.xmin;
+ }
+
+ /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
+ * and offset the text label to accommodate it */
+
+ /* Big previews with optional text label below */
+ if (but->flag & UI_BUT_ICON_PREVIEW && ui_block_is_menu(but->block)) {
+ const BIFIconID icon = widget_icon_id(but);
+ int icon_size = BLI_rcti_size_y(rect);
+ int text_size = 0;
+
+ /* This is a bit britle, but avoids adding an 'UI_BUT_HAS_LABEL' flag to but... */
+ if (icon_size > BLI_rcti_size_x(rect)) {
+ /* button is not square, it has extra height for label */
+ text_size = UI_UNIT_Y;
+ icon_size -= text_size;
+ }
+
+ /* draw icon in rect above the space reserved for the label */
+ rect->ymin += text_size;
+ GPU_blend(true);
+ widget_draw_preview(icon, alpha, rect);
+ GPU_blend(false);
+
+ /* offset rect to draw label in */
+ rect->ymin -= text_size;
+ rect->ymax -= icon_size;
+
+ /* vertically centering text */
+ rect->ymin += UI_UNIT_Y / 2;
+ }
+ /* Icons on the left with optional text label on the right */
+ else if (but->flag & UI_HAS_ICON || show_menu_icon) {
+ const bool is_tool = UI_but_is_tool(but);
+
+ /* XXX add way to draw icons at a different size!
+ * Use small icons for popup. */
#ifdef USE_UI_TOOLBAR_HACK
- const float aspect_orig = but->block->aspect;
- if (is_tool && (but->block->flag & UI_BLOCK_POPOVER)) {
- but->block->aspect *= 2.0f;
- }
+ const float aspect_orig = but->block->aspect;
+ if (is_tool && (but->block->flag & UI_BLOCK_POPOVER)) {
+ but->block->aspect *= 2.0f;
+ }
#endif
- const BIFIconID icon = widget_icon_id(but);
- int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT;
- const float icon_size = icon_size_init / (but->block->aspect / UI_DPI_FAC);
- const float icon_padding = 2 * UI_DPI_FAC;
+ const BIFIconID icon = widget_icon_id(but);
+ int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT;
+ const float icon_size = icon_size_init / (but->block->aspect / UI_DPI_FAC);
+ const float icon_padding = 2 * UI_DPI_FAC;
#ifdef USE_UI_TOOLBAR_HACK
- if (is_tool) {
- /* pass (even if its a menu toolbar) */
- but->drawflag |= UI_BUT_TEXT_LEFT;
- but->drawflag |= UI_BUT_ICON_LEFT;
- }
+ if (is_tool) {
+ /* pass (even if its a menu toolbar) */
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ but->drawflag |= UI_BUT_ICON_LEFT;
+ }
#endif
- /* menu item - add some more padding so menus don't feel cramped. it must
- * be part of the button so that this area is still clickable */
- if (is_tool) {
- /* pass (even if its a menu toolbar) */
- }
- else if (ui_block_is_pie_menu(but->block)) {
- if (but->dt == UI_EMBOSS_RADIAL) {
- rect->xmin += 0.3f * U.widget_unit;
- }
- }
- else if (ui_block_is_menu(but->block)) {
- rect->xmin += 0.2f * U.widget_unit;
- }
-
- widget_draw_icon(but, icon, alpha, rect, wcol->text);
- if (show_menu_icon) {
- BLI_assert(but->block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT);
- widget_draw_submenu_tria(but, rect, wcol);
- }
+ /* menu item - add some more padding so menus don't feel cramped. it must
+ * be part of the button so that this area is still clickable */
+ if (is_tool) {
+ /* pass (even if its a menu toolbar) */
+ }
+ else if (ui_block_is_pie_menu(but->block)) {
+ if (but->dt == UI_EMBOSS_RADIAL) {
+ rect->xmin += 0.3f * U.widget_unit;
+ }
+ }
+ else if (ui_block_is_menu(but->block)) {
+ rect->xmin += 0.2f * U.widget_unit;
+ }
+
+ widget_draw_icon(but, icon, alpha, rect, wcol->text);
+ if (show_menu_icon) {
+ BLI_assert(but->block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT);
+ widget_draw_submenu_tria(but, rect, wcol);
+ }
#ifdef USE_UI_TOOLBAR_HACK
- but->block->aspect = aspect_orig;
+ but->block->aspect = aspect_orig;
#endif
- rect->xmin += icon_size + icon_padding;
- }
-
- int text_padding = (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
- if (but->editstr) {
- rect->xmin += text_padding;
- }
- else if (but->flag & UI_BUT_DRAG_MULTI) {
- bool text_is_edited = ui_but_drag_multi_edit_get(but) != NULL;
- if (text_is_edited) {
- rect->xmin += text_padding;
- }
- }
- else if (but->drawflag & UI_BUT_TEXT_LEFT) {
- rect->xmin += text_padding;
- }
- else if (but->drawflag & UI_BUT_TEXT_RIGHT) {
- rect->xmax -= text_padding;
- }
-
- /* Menu contains sub-menu items with triangle icon on their right. Shortcut
- * strings should be drawn with some padding to the right then. */
- if (ui_block_is_menu(but->block) && (but->block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT)) {
- rect->xmax -= UI_MENU_SUBMENU_PADDING;
- }
-
- /* extra icons, e.g. 'x' icon to clear text or icon for eyedropper */
- if (extra_icon_type != UI_BUT_ICONEXTRA_NONE) {
- rcti temp = *rect;
-
- temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
-
- if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
- widget_draw_icon(but, ICON_PANEL_CLOSE, alpha, &temp, wcol->text);
- }
- else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
- widget_draw_icon(but, ICON_EYEDROPPER, alpha, &temp, wcol->text);
- }
- else {
- BLI_assert(0);
- }
-
- rect->xmax -= ICON_SIZE_FROM_BUTRECT(rect);
- }
-
- /* clip but->drawstr to fit in available space */
- if (but->editstr && but->pos >= 0) {
- ui_text_clip_cursor(fstyle, but, rect);
- }
- else if (but->drawstr[0] == '\0') {
- /* bypass text clipping on icon buttons */
- but->ofs = 0;
- but->strwidth = 0;
- }
- else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
- ui_text_clip_right_label(fstyle, but, rect);
- }
- else if (but->flag & UI_BUT_HAS_SEP_CHAR) {
- /* Clip middle, but protect in all case right part containing the shortcut, if any. */
- ui_text_clip_middle_protect_right(fstyle, but, rect, UI_SEP_CHAR);
- }
- else {
- ui_text_clip_middle(fstyle, but, rect);
- }
-
- /* always draw text for textbutton cursor */
- widget_draw_text(fstyle, wcol, but, rect);
-
- ui_but_text_password_hide(password_str, but, true);
-
- /* if a widget uses font shadow it has to be deactivated now */
- BLF_disable(fstyle->uifont_id, BLF_SHADOW);
+ rect->xmin += icon_size + icon_padding;
+ }
+
+ int text_padding = (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
+ if (but->editstr) {
+ rect->xmin += text_padding;
+ }
+ else if (but->flag & UI_BUT_DRAG_MULTI) {
+ bool text_is_edited = ui_but_drag_multi_edit_get(but) != NULL;
+ if (text_is_edited) {
+ rect->xmin += text_padding;
+ }
+ }
+ else if (but->drawflag & UI_BUT_TEXT_LEFT) {
+ rect->xmin += text_padding;
+ }
+ else if (but->drawflag & UI_BUT_TEXT_RIGHT) {
+ rect->xmax -= text_padding;
+ }
+
+ /* Menu contains sub-menu items with triangle icon on their right. Shortcut
+ * strings should be drawn with some padding to the right then. */
+ if (ui_block_is_menu(but->block) &&
+ (but->block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT)) {
+ rect->xmax -= UI_MENU_SUBMENU_PADDING;
+ }
+
+ /* extra icons, e.g. 'x' icon to clear text or icon for eyedropper */
+ if (extra_icon_type != UI_BUT_ICONEXTRA_NONE) {
+ rcti temp = *rect;
+
+ temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
+
+ if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
+ widget_draw_icon(but, ICON_PANEL_CLOSE, alpha, &temp, wcol->text);
+ }
+ else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
+ widget_draw_icon(but, ICON_EYEDROPPER, alpha, &temp, wcol->text);
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ rect->xmax -= ICON_SIZE_FROM_BUTRECT(rect);
+ }
+
+ /* clip but->drawstr to fit in available space */
+ if (but->editstr && but->pos >= 0) {
+ ui_text_clip_cursor(fstyle, but, rect);
+ }
+ else if (but->drawstr[0] == '\0') {
+ /* bypass text clipping on icon buttons */
+ but->ofs = 0;
+ but->strwidth = 0;
+ }
+ else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
+ ui_text_clip_right_label(fstyle, but, rect);
+ }
+ else if (but->flag & UI_BUT_HAS_SEP_CHAR) {
+ /* Clip middle, but protect in all case right part containing the shortcut, if any. */
+ ui_text_clip_middle_protect_right(fstyle, but, rect, UI_SEP_CHAR);
+ }
+ else {
+ ui_text_clip_middle(fstyle, but, rect);
+ }
+
+ /* always draw text for textbutton cursor */
+ widget_draw_text(fstyle, wcol, but, rect);
+
+ ui_but_text_password_hide(password_str, but, true);
+
+ /* if a widget uses font shadow it has to be deactivated now */
+ BLF_disable(fstyle->uifont_id, BLF_SHADOW);
}
#undef UI_TEXT_CLIP_MARGIN
-
/* *********************** widget types ************************************* */
/* ************ button callbacks, state ***************** */
static void widget_state_blend(char cp[3], const char cpstate[3], const float fac)
{
- if (fac != 0.0f) {
- cp[0] = (int)((1.0f - fac) * cp[0] + fac * cpstate[0]);
- cp[1] = (int)((1.0f - fac) * cp[1] + fac * cpstate[1]);
- cp[2] = (int)((1.0f - fac) * cp[2] + fac * cpstate[2]);
- }
+ if (fac != 0.0f) {
+ cp[0] = (int)((1.0f - fac) * cp[0] + fac * cpstate[0]);
+ cp[1] = (int)((1.0f - fac) * cp[1] + fac * cpstate[1]);
+ cp[2] = (int)((1.0f - fac) * cp[2] + fac * cpstate[2]);
+ }
}
/* put all widget colors on half alpha, use local storage */
static void ui_widget_color_disabled(uiWidgetType *wt)
{
- static uiWidgetColors wcol_theme_s;
+ static uiWidgetColors wcol_theme_s;
- wcol_theme_s = *wt->wcol_theme;
+ wcol_theme_s = *wt->wcol_theme;
- wcol_theme_s.outline[3] *= 0.5;
- wcol_theme_s.inner[3] *= 0.5;
- wcol_theme_s.inner_sel[3] *= 0.5;
- wcol_theme_s.item[3] *= 0.5;
- wcol_theme_s.text[3] *= 0.5;
- wcol_theme_s.text_sel[3] *= 0.5;
+ wcol_theme_s.outline[3] *= 0.5;
+ wcol_theme_s.inner[3] *= 0.5;
+ wcol_theme_s.inner_sel[3] *= 0.5;
+ wcol_theme_s.item[3] *= 0.5;
+ wcol_theme_s.text[3] *= 0.5;
+ wcol_theme_s.text_sel[3] *= 0.5;
- wt->wcol_theme = &wcol_theme_s;
+ wt->wcol_theme = &wcol_theme_s;
}
static void widget_active_color(char cp[3])
{
- cp[0] = cp[0] >= 240 ? 255 : cp[0] + 15;
- cp[1] = cp[1] >= 240 ? 255 : cp[1] + 15;
- cp[2] = cp[2] >= 240 ? 255 : cp[2] + 15;
+ cp[0] = cp[0] >= 240 ? 255 : cp[0] + 15;
+ cp[1] = cp[1] >= 240 ? 255 : cp[1] + 15;
+ cp[2] = cp[2] >= 240 ? 255 : cp[2] + 15;
}
/* copy colors from theme, and set changes in it based on state */
static void widget_state(uiWidgetType *wt, int state, int drawflag)
{
- uiWidgetStateColors *wcol_state = wt->wcol_state;
-
- if ((state & UI_BUT_LIST_ITEM) && !(state & UI_STATE_TEXT_INPUT)) {
- /* Override default widget's colors. */
- bTheme *btheme = UI_GetTheme();
- wt->wcol_theme = &btheme->tui.wcol_list_item;
-
- if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- ui_widget_color_disabled(wt);
- }
- }
-
- wt->wcol = *(wt->wcol_theme);
-
- if (state & UI_SELECT) {
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- if (drawflag & UI_BUT_ANIMATED_CHANGED) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_changed_sel, wcol_state->blend);
- }
- else if (state & UI_BUT_ANIMATED_KEY) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_key_sel, wcol_state->blend);
- }
- else if (state & UI_BUT_ANIMATED) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_anim_sel, wcol_state->blend);
- }
- else if (state & UI_BUT_DRIVEN) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_driven_sel, wcol_state->blend);
- }
- else if (state & UI_BUT_OVERRIDEN) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_overridden_sel, wcol_state->blend);
- }
-
- copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
-
- if (state & UI_SELECT) {
- SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown);
- }
- }
- else {
- if (drawflag & UI_BUT_ANIMATED_CHANGED) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_changed, wcol_state->blend);
- }
- else if (state & UI_BUT_ANIMATED_KEY) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_key, wcol_state->blend);
- }
- else if (state & UI_BUT_ANIMATED) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_anim, wcol_state->blend);
- }
- else if (state & UI_BUT_DRIVEN) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_driven, wcol_state->blend);
- }
- else if (state & UI_BUT_OVERRIDEN) {
- widget_state_blend(wt->wcol.inner, wcol_state->inner_overridden, wcol_state->blend);
- }
-
- if (state & UI_ACTIVE) { /* mouse over? */
- widget_active_color(wt->wcol.inner);
- }
- }
-
- if (state & UI_BUT_REDALERT) {
- char red[4] = {255, 0, 0};
- if (wt->draw) {
- widget_state_blend(wt->wcol.inner, red, 0.4f);
- }
- else {
- widget_state_blend(wt->wcol.text, red, 0.4f);
- }
- }
-
- if (state & UI_BUT_DRAG_MULTI) {
- /* the button isn't SELECT but we're editing this so draw with sel color */
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown);
- widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.85f);
- }
-
- if (state & UI_BUT_NODE_ACTIVE) {
- char blue[4] = {86, 128, 194};
- widget_state_blend(wt->wcol.inner, blue, 0.3f);
- }
+ uiWidgetStateColors *wcol_state = wt->wcol_state;
+
+ if ((state & UI_BUT_LIST_ITEM) && !(state & UI_STATE_TEXT_INPUT)) {
+ /* Override default widget's colors. */
+ bTheme *btheme = UI_GetTheme();
+ wt->wcol_theme = &btheme->tui.wcol_list_item;
+
+ if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ ui_widget_color_disabled(wt);
+ }
+ }
+
+ wt->wcol = *(wt->wcol_theme);
+
+ if (state & UI_SELECT) {
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ if (drawflag & UI_BUT_ANIMATED_CHANGED) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_changed_sel, wcol_state->blend);
+ }
+ else if (state & UI_BUT_ANIMATED_KEY) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_key_sel, wcol_state->blend);
+ }
+ else if (state & UI_BUT_ANIMATED) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_anim_sel, wcol_state->blend);
+ }
+ else if (state & UI_BUT_DRIVEN) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_driven_sel, wcol_state->blend);
+ }
+ else if (state & UI_BUT_OVERRIDEN) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_overridden_sel, wcol_state->blend);
+ }
+
+ copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+
+ if (state & UI_SELECT) {
+ SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown);
+ }
+ }
+ else {
+ if (drawflag & UI_BUT_ANIMATED_CHANGED) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_changed, wcol_state->blend);
+ }
+ else if (state & UI_BUT_ANIMATED_KEY) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_key, wcol_state->blend);
+ }
+ else if (state & UI_BUT_ANIMATED) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_anim, wcol_state->blend);
+ }
+ else if (state & UI_BUT_DRIVEN) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_driven, wcol_state->blend);
+ }
+ else if (state & UI_BUT_OVERRIDEN) {
+ widget_state_blend(wt->wcol.inner, wcol_state->inner_overridden, wcol_state->blend);
+ }
+
+ if (state & UI_ACTIVE) { /* mouse over? */
+ widget_active_color(wt->wcol.inner);
+ }
+ }
+
+ if (state & UI_BUT_REDALERT) {
+ char red[4] = {255, 0, 0};
+ if (wt->draw) {
+ widget_state_blend(wt->wcol.inner, red, 0.4f);
+ }
+ else {
+ widget_state_blend(wt->wcol.text, red, 0.4f);
+ }
+ }
+
+ if (state & UI_BUT_DRAG_MULTI) {
+ /* the button isn't SELECT but we're editing this so draw with sel color */
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown);
+ widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.85f);
+ }
+
+ if (state & UI_BUT_NODE_ACTIVE) {
+ char blue[4] = {86, 128, 194};
+ widget_state_blend(wt->wcol.inner, blue, 0.3f);
+ }
}
/* sliders use special hack which sets 'item' as inner when drawing filling */
static void widget_state_numslider(uiWidgetType *wt, int state, int drawflag)
{
- uiWidgetStateColors *wcol_state = wt->wcol_state;
- /* XXX special tweak to make sure that bar will still be visible */
- float blend = wcol_state->blend - 0.2f;
-
- /* call this for option button */
- widget_state(wt, state, drawflag);
-
- /* now, set the inner-part so that it reflects state settings too */
- /* TODO: maybe we should have separate settings for the blending colors used for this case? */
- if (state & UI_SELECT) {
-
- if (drawflag & UI_BUT_ANIMATED_CHANGED) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_changed_sel, blend);
- }
- else if (state & UI_BUT_ANIMATED_KEY) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_key_sel, blend);
- }
- else if (state & UI_BUT_ANIMATED) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_anim_sel, blend);
- }
- else if (state & UI_BUT_DRIVEN) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_driven_sel, blend);
- }
- else if (state & UI_BUT_OVERRIDEN) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_overridden_sel, blend);
- }
-
- if (state & UI_SELECT) {
- SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown);
- }
- }
- else {
- if (drawflag & UI_BUT_ANIMATED_CHANGED) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_changed, blend);
- }
- else if (state & UI_BUT_ANIMATED_KEY) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_key, blend);
- }
- else if (state & UI_BUT_ANIMATED) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_anim, blend);
- }
- else if (state & UI_BUT_DRIVEN) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_driven, blend);
- }
- else if (state & UI_BUT_OVERRIDEN) {
- widget_state_blend(wt->wcol.item, wcol_state->inner_overridden, blend);
- }
- }
+ uiWidgetStateColors *wcol_state = wt->wcol_state;
+ /* XXX special tweak to make sure that bar will still be visible */
+ float blend = wcol_state->blend - 0.2f;
+
+ /* call this for option button */
+ widget_state(wt, state, drawflag);
+
+ /* now, set the inner-part so that it reflects state settings too */
+ /* TODO: maybe we should have separate settings for the blending colors used for this case? */
+ if (state & UI_SELECT) {
+
+ if (drawflag & UI_BUT_ANIMATED_CHANGED) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_changed_sel, blend);
+ }
+ else if (state & UI_BUT_ANIMATED_KEY) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_key_sel, blend);
+ }
+ else if (state & UI_BUT_ANIMATED) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_anim_sel, blend);
+ }
+ else if (state & UI_BUT_DRIVEN) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_driven_sel, blend);
+ }
+ else if (state & UI_BUT_OVERRIDEN) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_overridden_sel, blend);
+ }
+
+ if (state & UI_SELECT) {
+ SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown);
+ }
+ }
+ else {
+ if (drawflag & UI_BUT_ANIMATED_CHANGED) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_changed, blend);
+ }
+ else if (state & UI_BUT_ANIMATED_KEY) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_key, blend);
+ }
+ else if (state & UI_BUT_ANIMATED) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_anim, blend);
+ }
+ else if (state & UI_BUT_DRIVEN) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_driven, blend);
+ }
+ else if (state & UI_BUT_OVERRIDEN) {
+ widget_state_blend(wt->wcol.item, wcol_state->inner_overridden, blend);
+ }
+ }
}
/* labels use theme colors for text */
static void widget_state_option_menu(uiWidgetType *wt, int state, int drawflag)
{
- bTheme *btheme = UI_GetTheme(); /* XXX */
-
- /* call this for option button */
- widget_state(wt, state, drawflag);
-
- /* if not selected we get theme from menu back */
- if (state & UI_SELECT) {
- copy_v3_v3_char(wt->wcol.text, btheme->tui.wcol_menu_back.text_sel);
- }
- else {
- copy_v3_v3_char(wt->wcol.text, btheme->tui.wcol_menu_back.text);
- }
+ bTheme *btheme = UI_GetTheme(); /* XXX */
+
+ /* call this for option button */
+ widget_state(wt, state, drawflag);
+
+ /* if not selected we get theme from menu back */
+ if (state & UI_SELECT) {
+ copy_v3_v3_char(wt->wcol.text, btheme->tui.wcol_menu_back.text_sel);
+ }
+ else {
+ copy_v3_v3_char(wt->wcol.text, btheme->tui.wcol_menu_back.text);
+ }
}
-
static void widget_state_nothing(uiWidgetType *wt, int UNUSED(state), int UNUSED(drawflag))
{
- wt->wcol = *(wt->wcol_theme);
+ wt->wcol = *(wt->wcol_theme);
}
/* special case, button that calls pulldown */
static void widget_state_pulldown(uiWidgetType *wt, int UNUSED(state), int UNUSED(drawflag))
{
- wt->wcol = *(wt->wcol_theme);
+ wt->wcol = *(wt->wcol_theme);
}
/* special case, pie menu items */
static void widget_state_pie_menu_item(uiWidgetType *wt, int state, int UNUSED(drawflag))
{
- wt->wcol = *(wt->wcol_theme);
-
- /* active and disabled (not so common) */
- if ((state & UI_BUT_DISABLED) && (state & UI_ACTIVE)) {
- widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.5f);
- /* draw the backdrop at low alpha, helps navigating with keys
- * when disabled items are active */
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
- wt->wcol.inner[3] = 64;
- }
- else {
- /* regular active */
- if (state & (UI_SELECT | UI_ACTIVE)) {
- copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
- }
- else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- /* regular disabled */
- widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
- }
-
- if (state & UI_SELECT) {
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- }
- else if (state & UI_ACTIVE) {
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
- }
- }
+ wt->wcol = *(wt->wcol_theme);
+
+ /* active and disabled (not so common) */
+ if ((state & UI_BUT_DISABLED) && (state & UI_ACTIVE)) {
+ widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.5f);
+ /* draw the backdrop at low alpha, helps navigating with keys
+ * when disabled items are active */
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
+ wt->wcol.inner[3] = 64;
+ }
+ else {
+ /* regular active */
+ if (state & (UI_SELECT | UI_ACTIVE)) {
+ copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+ }
+ else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ /* regular disabled */
+ widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
+ }
+
+ if (state & UI_SELECT) {
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ }
+ else if (state & UI_ACTIVE) {
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.item);
+ }
+ }
}
/* special case, menu items */
static void widget_state_menu_item(uiWidgetType *wt, int state, int UNUSED(drawflag))
{
- wt->wcol = *(wt->wcol_theme);
-
- /* active and disabled (not so common) */
- if ((state & UI_BUT_DISABLED) && (state & UI_ACTIVE)) {
- widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.5f);
- /* draw the backdrop at low alpha, helps navigating with keys
- * when disabled items are active */
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- wt->wcol.inner[3] = 64;
- }
- else {
- /* regular active */
- if (state & UI_ACTIVE) {
- copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
- }
- else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- /* regular disabled */
- widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
- }
-
- if (state & UI_ACTIVE) {
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- }
- }
+ wt->wcol = *(wt->wcol_theme);
+
+ /* active and disabled (not so common) */
+ if ((state & UI_BUT_DISABLED) && (state & UI_ACTIVE)) {
+ widget_state_blend(wt->wcol.text, wt->wcol.text_sel, 0.5f);
+ /* draw the backdrop at low alpha, helps navigating with keys
+ * when disabled items are active */
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ wt->wcol.inner[3] = 64;
+ }
+ else {
+ /* regular active */
+ if (state & UI_ACTIVE) {
+ copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel);
+ }
+ else if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ /* regular disabled */
+ widget_state_blend(wt->wcol.text, wt->wcol.inner, 0.5f);
+ }
+
+ if (state & UI_ACTIVE) {
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ }
+ }
}
-
/* ************ menu backdrop ************************* */
/* outside of rect, rad to left/bottom/right */
static void widget_softshadow(const rcti *rect, int roundboxalign, const float radin)
{
- bTheme *btheme = UI_GetTheme();
- uiWidgetBase wtb;
- rcti rect1 = *rect;
- float alphastep;
- int step, totvert;
- float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2];
- const float radout = UI_ThemeMenuShadowWidth();
+ bTheme *btheme = UI_GetTheme();
+ uiWidgetBase wtb;
+ rcti rect1 = *rect;
+ float alphastep;
+ int step, totvert;
+ float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2];
+ const float radout = UI_ThemeMenuShadowWidth();
- /* disabled shadow */
- if (radout == 0.0f) {
- return;
- }
+ /* disabled shadow */
+ if (radout == 0.0f) {
+ return;
+ }
- /* prevent tooltips to not show round shadow */
- if (radout > 0.2f * BLI_rcti_size_y(&rect1)) {
- rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1);
- }
- else {
- rect1.ymax -= radout;
- }
+ /* prevent tooltips to not show round shadow */
+ if (radout > 0.2f * BLI_rcti_size_y(&rect1)) {
+ rect1.ymax -= 0.2f * BLI_rcti_size_y(&rect1);
+ }
+ else {
+ rect1.ymax -= radout;
+ }
- /* inner part */
- totvert = round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT), 0.0f);
+ /* inner part */
+ totvert = round_box_shadow_edges(wtb.inner_v,
+ &rect1,
+ radin,
+ roundboxalign & (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT),
+ 0.0f);
- /* we draw a number of increasing size alpha quad strips */
- alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
+ /* we draw a number of increasing size alpha quad strips */
+ alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout;
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- for (step = 1; step <= (int)radout; step++) {
- float expfac = sqrtf(step / radout);
+ for (step = 1; step <= (int)radout; step++) {
+ float expfac = sqrtf(step / radout);
- round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step);
+ round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step);
- immUniformColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
+ immUniformColor4f(0.0f, 0.0f, 0.0f, alphastep * (1.0f - expfac));
- widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip);
+ widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip);
- widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, totvert * 2);
- }
+ widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, totvert * 2);
+ }
- immUnbindProgram();
+ immUnbindProgram();
}
static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int direction)
{
- uiWidgetBase wtb;
- int roundboxalign = UI_CNR_ALL;
-
- widget_init(&wtb);
-
- /* menu is 2nd level or deeper */
- if (flag & UI_BLOCK_POPUP) {
- //rect->ymin -= 4.0;
- //rect->ymax += 4.0;
- }
- else if (direction == UI_DIR_DOWN) {
- roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
- rect->ymin -= 0.1f * U.widget_unit;
- }
- else if (direction == UI_DIR_UP) {
- roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
- rect->ymax += 0.1f * U.widget_unit;
- }
-
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
- widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit);
-
- round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit);
- wtb.draw_emboss = false;
- widgetbase_draw(&wtb, wcol);
-
- GPU_blend(false);
+ uiWidgetBase wtb;
+ int roundboxalign = UI_CNR_ALL;
+
+ widget_init(&wtb);
+
+ /* menu is 2nd level or deeper */
+ if (flag & UI_BLOCK_POPUP) {
+ //rect->ymin -= 4.0;
+ //rect->ymax += 4.0;
+ }
+ else if (direction == UI_DIR_DOWN) {
+ roundboxalign = (UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+ rect->ymin -= 0.1f * U.widget_unit;
+ }
+ else if (direction == UI_DIR_UP) {
+ roundboxalign = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
+ rect->ymax += 0.1f * U.widget_unit;
+ }
+
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+ widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit);
+
+ round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit);
+ wtb.draw_emboss = false;
+ widgetbase_draw(&wtb, wcol);
+
+ GPU_blend(false);
}
static void ui_hsv_cursor(float x, float y)
{
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3f(1.0f, 1.0f, 1.0f);
- imm_draw_circle_fill_2d(pos, x, y, 3.0f * U.pixelsize, 8);
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
+ imm_draw_circle_fill_2d(pos, x, y, 3.0f * U.pixelsize, 8);
- GPU_blend(true);
- GPU_line_smooth(true);
- immUniformColor3f(0.0f, 0.0f, 0.0f);
- imm_draw_circle_wire_2d(pos, x, y, 3.0f * U.pixelsize, 12);
- GPU_blend(false);
- GPU_line_smooth(false);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ imm_draw_circle_wire_2d(pos, x, y, 3.0f * U.pixelsize, 12);
+ GPU_blend(false);
+ GPU_line_smooth(false);
- immUnbindProgram();
+ immUnbindProgram();
}
void ui_hsvcircle_vals_from_pos(
- const rcti *rect, const float mx, const float my,
- float *r_val_rad, float *r_val_dist)
+ const rcti *rect, const float mx, const float my, float *r_val_rad, float *r_val_dist)
{
- /* duplication of code... well, simple is better now */
- const float centx = BLI_rcti_cent_x_fl(rect);
- const float centy = BLI_rcti_cent_y_fl(rect);
- const float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
- const float m_delta[2] = {mx - centx, my - centy};
- const float dist_sq = len_squared_v2(m_delta);
-
- *r_val_dist = (dist_sq < (radius * radius)) ? sqrtf(dist_sq) / radius : 1.0f;
- *r_val_rad = atan2f(m_delta[0], m_delta[1]) / (2.0f * (float)M_PI) + 0.5f;
+ /* duplication of code... well, simple is better now */
+ const float centx = BLI_rcti_cent_x_fl(rect);
+ const float centy = BLI_rcti_cent_y_fl(rect);
+ const float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
+ const float m_delta[2] = {mx - centx, my - centy};
+ const float dist_sq = len_squared_v2(m_delta);
+
+ *r_val_dist = (dist_sq < (radius * radius)) ? sqrtf(dist_sq) / radius : 1.0f;
+ *r_val_rad = atan2f(m_delta[0], m_delta[1]) / (2.0f * (float)M_PI) + 0.5f;
}
/* cursor in hsv circle, in float units -1 to 1, to map on radius */
void ui_hsvcircle_pos_from_vals(
- const ColorPicker *cpicker, const rcti *rect, const float *hsv,
- float *r_xpos, float *r_ypos)
+ const ColorPicker *cpicker, const rcti *rect, const float *hsv, float *r_xpos, float *r_ypos)
{
- /* duplication of code... well, simple is better now */
- const float centx = BLI_rcti_cent_x_fl(rect);
- const float centy = BLI_rcti_cent_y_fl(rect);
- float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
- float ang, radius_t;
-
- ang = 2.0f * (float)M_PI * hsv[0] + (float)M_PI_2;
-
- if (cpicker->use_color_cubic && (U.color_picker_type == USER_CP_CIRCLE_HSV)) {
- radius_t = (1.0f - pow3f(1.0f - hsv[1]));
- }
- else {
- radius_t = hsv[1];
- }
-
- radius = clamp_f(radius_t, 0.0f, 1.0f) * radius;
- *r_xpos = centx + cosf(-ang) * radius;
- *r_ypos = centy + sinf(-ang) * radius;
+ /* duplication of code... well, simple is better now */
+ const float centx = BLI_rcti_cent_x_fl(rect);
+ const float centy = BLI_rcti_cent_y_fl(rect);
+ float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
+ float ang, radius_t;
+
+ ang = 2.0f * (float)M_PI * hsv[0] + (float)M_PI_2;
+
+ if (cpicker->use_color_cubic && (U.color_picker_type == USER_CP_CIRCLE_HSV)) {
+ radius_t = (1.0f - pow3f(1.0f - hsv[1]));
+ }
+ else {
+ radius_t = hsv[1];
+ }
+
+ radius = clamp_f(radius_t, 0.0f, 1.0f) * radius;
+ *r_xpos = centx + cosf(-ang) * radius;
+ *r_ypos = centy + sinf(-ang) * radius;
}
static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
{
- /* TODO(merwin): reimplement as shader for pixel-perfect colors */
-
- const int tot = 64;
- const float radstep = 2.0f * (float)M_PI / (float)tot;
- const float centx = BLI_rcti_cent_x_fl(rect);
- const float centy = BLI_rcti_cent_y_fl(rect);
- float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
-
- ColorPicker *cpicker = but->custom_data;
- float rgb[3], hsv[3], rgb_center[3];
- bool is_color_gamma = ui_but_is_color_gamma(but);
-
- /* Initialize for compatibility. */
- copy_v3_v3(hsv, cpicker->color_data);
-
- /* Compute current hue. */
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
- ui_rgb_to_color_picker_compat_v(rgb, hsv);
-
- CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */
-
- /* exception: if 'lock' is set
- * lock the value of the color wheel to 1.
- * Useful for color correction tools where you're only interested in hue. */
- if (cpicker->use_color_lock) {
- if (U.color_picker_type == USER_CP_CIRCLE_HSV) {
- hsv[2] = 1.0f;
- }
- else {
- hsv[2] = 0.5f;
- }
- }
-
- const float hsv_center[3] = {0.0f, 0.0f, hsv[2]};
- ui_color_picker_to_rgb_v(hsv_center, rgb_center);
- ui_color_picker_to_scene_linear_space(but, rgb_center);
-
- if (!is_color_gamma) {
- ui_block_cm_to_display_space_v3(but->block, rgb_center);
- }
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- immBegin(GPU_PRIM_TRI_FAN, tot + 2);
- immAttr3fv(color, rgb_center);
- immVertex2f(pos, centx, centy);
-
- float ang = 0.0f;
- for (int a = 0; a <= tot; a++, ang += radstep) {
- float si = sinf(ang);
- float co = cosf(ang);
- float hsv_ang[3];
- float rgb_ang[3];
-
- ui_hsvcircle_vals_from_pos(
- rect, centx + co * radius, centy + si * radius,
- hsv_ang, hsv_ang + 1);
- hsv_ang[2] = hsv[2];
-
- ui_color_picker_to_rgb_v(hsv_ang, rgb_ang);
- ui_color_picker_to_scene_linear_space(but, rgb_ang);
-
- if (!is_color_gamma) {
- ui_block_cm_to_display_space_v3(but->block, rgb_ang);
- }
-
- immAttr3fv(color, rgb_ang);
- immVertex2f(pos, centx + co * radius, centy + si * radius);
- }
- immEnd();
- immUnbindProgram();
-
- /* fully rounded outline */
- format = immVertexFormat();
- pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- GPU_blend(true);
- GPU_line_smooth(true);
-
- immUniformColor3ubv((uchar *)wcol->outline);
- imm_draw_circle_wire_2d(pos, centx, centy, radius, tot);
-
- immUnbindProgram();
-
- GPU_blend(false);
- GPU_line_smooth(false);
-
- /* cursor */
- copy_v3_v3(hsv, cpicker->color_data);
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
- ui_rgb_to_color_picker_compat_v(rgb, hsv);
-
- float xpos, ypos;
- ui_hsvcircle_pos_from_vals(cpicker, rect, hsv, &xpos, &ypos);
- ui_hsv_cursor(xpos, ypos);
+ /* TODO(merwin): reimplement as shader for pixel-perfect colors */
+
+ const int tot = 64;
+ const float radstep = 2.0f * (float)M_PI / (float)tot;
+ const float centx = BLI_rcti_cent_x_fl(rect);
+ const float centy = BLI_rcti_cent_y_fl(rect);
+ float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f;
+
+ ColorPicker *cpicker = but->custom_data;
+ float rgb[3], hsv[3], rgb_center[3];
+ bool is_color_gamma = ui_but_is_color_gamma(but);
+
+ /* Initialize for compatibility. */
+ copy_v3_v3(hsv, cpicker->color_data);
+
+ /* Compute current hue. */
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
+ CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */
+
+ /* exception: if 'lock' is set
+ * lock the value of the color wheel to 1.
+ * Useful for color correction tools where you're only interested in hue. */
+ if (cpicker->use_color_lock) {
+ if (U.color_picker_type == USER_CP_CIRCLE_HSV) {
+ hsv[2] = 1.0f;
+ }
+ else {
+ hsv[2] = 0.5f;
+ }
+ }
+
+ const float hsv_center[3] = {0.0f, 0.0f, hsv[2]};
+ ui_color_picker_to_rgb_v(hsv_center, rgb_center);
+ ui_color_picker_to_scene_linear_space(but, rgb_center);
+
+ if (!is_color_gamma) {
+ ui_block_cm_to_display_space_v3(but->block, rgb_center);
+ }
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ immBegin(GPU_PRIM_TRI_FAN, tot + 2);
+ immAttr3fv(color, rgb_center);
+ immVertex2f(pos, centx, centy);
+
+ float ang = 0.0f;
+ for (int a = 0; a <= tot; a++, ang += radstep) {
+ float si = sinf(ang);
+ float co = cosf(ang);
+ float hsv_ang[3];
+ float rgb_ang[3];
+
+ ui_hsvcircle_vals_from_pos(
+ rect, centx + co * radius, centy + si * radius, hsv_ang, hsv_ang + 1);
+ hsv_ang[2] = hsv[2];
+
+ ui_color_picker_to_rgb_v(hsv_ang, rgb_ang);
+ ui_color_picker_to_scene_linear_space(but, rgb_ang);
+
+ if (!is_color_gamma) {
+ ui_block_cm_to_display_space_v3(but->block, rgb_ang);
+ }
+
+ immAttr3fv(color, rgb_ang);
+ immVertex2f(pos, centx + co * radius, centy + si * radius);
+ }
+ immEnd();
+ immUnbindProgram();
+
+ /* fully rounded outline */
+ format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ GPU_blend(true);
+ GPU_line_smooth(true);
+
+ immUniformColor3ubv((uchar *)wcol->outline);
+ imm_draw_circle_wire_2d(pos, centx, centy, radius, tot);
+
+ immUnbindProgram();
+
+ GPU_blend(false);
+ GPU_line_smooth(false);
+
+ /* cursor */
+ copy_v3_v3(hsv, cpicker->color_data);
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+ ui_rgb_to_color_picker_compat_v(rgb, hsv);
+
+ float xpos, ypos;
+ ui_hsvcircle_pos_from_vals(cpicker, rect, hsv, &xpos, &ypos);
+ ui_hsv_cursor(xpos, ypos);
}
/* ************ custom buttons, old stuff ************** */
@@ -2831,1427 +2972,1462 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const
/* draws in resolution of 48x4 colors */
void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha)
{
- /* allows for 4 steps (red->yellow) */
- const int steps = 48;
- const float color_step = 1.0f / steps;
- int a;
- float h = hsv[0], s = hsv[1], v = hsv[2];
- float dx, dy, sx1, sx2, sy;
- float col0[4][3]; /* left half, rect bottom to top */
- float col1[4][3]; /* right half, rect bottom to top */
-
- /* draw series of gouraud rects */
-
- switch (type) {
- case UI_GRAD_SV:
- hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(h, 0.0, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(h, 0.0, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(h, 0.0, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
- break;
- case UI_GRAD_HV:
- hsv_to_rgb(0.0, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(0.0, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
- break;
- case UI_GRAD_HS:
- hsv_to_rgb(0.0, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(0.0, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
- break;
- case UI_GRAD_H:
- hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- copy_v3_v3(col1[1], col1[0]);
- copy_v3_v3(col1[2], col1[0]);
- copy_v3_v3(col1[3], col1[0]);
- break;
- case UI_GRAD_S:
- hsv_to_rgb(1.0, 0.0, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
- copy_v3_v3(col1[0], col1[1]);
- copy_v3_v3(col1[2], col1[1]);
- copy_v3_v3(col1[3], col1[1]);
- break;
- case UI_GRAD_V:
- hsv_to_rgb(1.0, 1.0, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
- copy_v3_v3(col1[0], col1[2]);
- copy_v3_v3(col1[1], col1[2]);
- copy_v3_v3(col1[3], col1[2]);
- break;
- default:
- assert(!"invalid 'type' argument");
- hsv_to_rgb(1.0, 1.0, 1.0, &col1[2][0], &col1[2][1], &col1[2][2]);
- copy_v3_v3(col1[0], col1[2]);
- copy_v3_v3(col1[1], col1[2]);
- copy_v3_v3(col1[3], col1[2]);
- break;
- }
-
- /* old below */
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
-
- immBegin(GPU_PRIM_TRIS, steps * 3 * 6);
-
- /* 0.999 = prevent float inaccuracy for steps */
- for (dx = 0.0f; dx < 0.999f; dx += color_step) {
- const float dx_next = dx + color_step;
-
- /* previous color */
- copy_v3_v3(col0[0], col1[0]);
- copy_v3_v3(col0[1], col1[1]);
- copy_v3_v3(col0[2], col1[2]);
- copy_v3_v3(col0[3], col1[3]);
-
- /* new color */
- switch (type) {
- case UI_GRAD_SV:
- hsv_to_rgb(h, dx, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(h, dx, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(h, dx, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(h, dx, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
- break;
- case UI_GRAD_HV:
- hsv_to_rgb(dx_next, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(dx_next, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(dx_next, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(dx_next, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
- break;
- case UI_GRAD_HS:
- hsv_to_rgb(dx_next, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
- hsv_to_rgb(dx_next, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
- hsv_to_rgb(dx_next, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
- hsv_to_rgb(dx_next, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
- break;
- case UI_GRAD_H:
- /* annoying but without this the color shifts - could be solved some other way
- * - campbell */
- hsv_to_rgb(dx_next, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
- copy_v3_v3(col1[1], col1[0]);
- copy_v3_v3(col1[2], col1[0]);
- copy_v3_v3(col1[3], col1[0]);
- break;
- case UI_GRAD_S:
- hsv_to_rgb(h, dx, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
- copy_v3_v3(col1[0], col1[1]);
- copy_v3_v3(col1[2], col1[1]);
- copy_v3_v3(col1[3], col1[1]);
- break;
- case UI_GRAD_V:
- hsv_to_rgb(h, 1.0, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
- copy_v3_v3(col1[0], col1[2]);
- copy_v3_v3(col1[1], col1[2]);
- copy_v3_v3(col1[3], col1[2]);
- break;
- }
-
- /* rect */
- sx1 = rect->xmin + dx * BLI_rcti_size_x(rect);
- sx2 = rect->xmin + dx_next * BLI_rcti_size_x(rect);
- sy = rect->ymin;
- dy = (float)BLI_rcti_size_y(rect) / 3.0f;
-
- for (a = 0; a < 3; a++, sy += dy) {
- immAttr4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
- immVertex2f(pos, sx1, sy);
-
- immAttr4f(col, col1[a][0], col1[a][1], col1[a][2], alpha);
- immVertex2f(pos, sx2, sy);
-
- immAttr4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
- immVertex2f(pos, sx2, sy + dy);
-
- immAttr4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
- immVertex2f(pos, sx1, sy);
-
- immAttr4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
- immVertex2f(pos, sx2, sy + dy);
-
- immAttr4f(col, col0[a + 1][0], col0[a + 1][1], col0[a + 1][2], alpha);
- immVertex2f(pos, sx1, sy + dy);
- }
- }
- immEnd();
-
- immUnbindProgram();
+ /* allows for 4 steps (red->yellow) */
+ const int steps = 48;
+ const float color_step = 1.0f / steps;
+ int a;
+ float h = hsv[0], s = hsv[1], v = hsv[2];
+ float dx, dy, sx1, sx2, sy;
+ float col0[4][3]; /* left half, rect bottom to top */
+ float col1[4][3]; /* right half, rect bottom to top */
+
+ /* draw series of gouraud rects */
+
+ switch (type) {
+ case UI_GRAD_SV:
+ hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(h, 0.0, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(h, 0.0, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(h, 0.0, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
+ break;
+ case UI_GRAD_HV:
+ hsv_to_rgb(0.0, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(0.0, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
+ break;
+ case UI_GRAD_HS:
+ hsv_to_rgb(0.0, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(0.0, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
+ break;
+ case UI_GRAD_H:
+ hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ copy_v3_v3(col1[1], col1[0]);
+ copy_v3_v3(col1[2], col1[0]);
+ copy_v3_v3(col1[3], col1[0]);
+ break;
+ case UI_GRAD_S:
+ hsv_to_rgb(1.0, 0.0, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
+ copy_v3_v3(col1[0], col1[1]);
+ copy_v3_v3(col1[2], col1[1]);
+ copy_v3_v3(col1[3], col1[1]);
+ break;
+ case UI_GRAD_V:
+ hsv_to_rgb(1.0, 1.0, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
+ copy_v3_v3(col1[0], col1[2]);
+ copy_v3_v3(col1[1], col1[2]);
+ copy_v3_v3(col1[3], col1[2]);
+ break;
+ default:
+ assert(!"invalid 'type' argument");
+ hsv_to_rgb(1.0, 1.0, 1.0, &col1[2][0], &col1[2][1], &col1[2][2]);
+ copy_v3_v3(col1[0], col1[2]);
+ copy_v3_v3(col1[1], col1[2]);
+ copy_v3_v3(col1[3], col1[2]);
+ break;
+ }
+
+ /* old below */
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+
+ immBegin(GPU_PRIM_TRIS, steps * 3 * 6);
+
+ /* 0.999 = prevent float inaccuracy for steps */
+ for (dx = 0.0f; dx < 0.999f; dx += color_step) {
+ const float dx_next = dx + color_step;
+
+ /* previous color */
+ copy_v3_v3(col0[0], col1[0]);
+ copy_v3_v3(col0[1], col1[1]);
+ copy_v3_v3(col0[2], col1[2]);
+ copy_v3_v3(col0[3], col1[3]);
+
+ /* new color */
+ switch (type) {
+ case UI_GRAD_SV:
+ hsv_to_rgb(h, dx, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(h, dx, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(h, dx, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(h, dx, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
+ break;
+ case UI_GRAD_HV:
+ hsv_to_rgb(dx_next, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(dx_next, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(dx_next, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(dx_next, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
+ break;
+ case UI_GRAD_HS:
+ hsv_to_rgb(dx_next, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
+ hsv_to_rgb(dx_next, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
+ hsv_to_rgb(dx_next, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
+ hsv_to_rgb(dx_next, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
+ break;
+ case UI_GRAD_H:
+ /* annoying but without this the color shifts - could be solved some other way
+ * - campbell */
+ hsv_to_rgb(dx_next, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
+ copy_v3_v3(col1[1], col1[0]);
+ copy_v3_v3(col1[2], col1[0]);
+ copy_v3_v3(col1[3], col1[0]);
+ break;
+ case UI_GRAD_S:
+ hsv_to_rgb(h, dx, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]);
+ copy_v3_v3(col1[0], col1[1]);
+ copy_v3_v3(col1[2], col1[1]);
+ copy_v3_v3(col1[3], col1[1]);
+ break;
+ case UI_GRAD_V:
+ hsv_to_rgb(h, 1.0, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
+ copy_v3_v3(col1[0], col1[2]);
+ copy_v3_v3(col1[1], col1[2]);
+ copy_v3_v3(col1[3], col1[2]);
+ break;
+ }
+
+ /* rect */
+ sx1 = rect->xmin + dx * BLI_rcti_size_x(rect);
+ sx2 = rect->xmin + dx_next * BLI_rcti_size_x(rect);
+ sy = rect->ymin;
+ dy = (float)BLI_rcti_size_y(rect) / 3.0f;
+
+ for (a = 0; a < 3; a++, sy += dy) {
+ immAttr4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
+ immVertex2f(pos, sx1, sy);
+
+ immAttr4f(col, col1[a][0], col1[a][1], col1[a][2], alpha);
+ immVertex2f(pos, sx2, sy);
+
+ immAttr4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
+ immVertex2f(pos, sx2, sy + dy);
+
+ immAttr4f(col, col0[a][0], col0[a][1], col0[a][2], alpha);
+ immVertex2f(pos, sx1, sy);
+
+ immAttr4f(col, col1[a + 1][0], col1[a + 1][1], col1[a + 1][2], alpha);
+ immVertex2f(pos, sx2, sy + dy);
+
+ immAttr4f(col, col0[a + 1][0], col0[a + 1][1], col0[a + 1][2], alpha);
+ immVertex2f(pos, sx1, sy + dy);
+ }
+ }
+ immEnd();
+
+ immUnbindProgram();
}
void ui_hsvcube_pos_from_vals(
- const uiBut *but, const rcti *rect, const float *hsv,
- float *r_xp, float *r_yp)
+ const uiBut *but, const rcti *rect, const float *hsv, float *r_xp, float *r_yp)
{
- float x = 0.0f, y = 0.0f;
-
- switch ((int)but->a1) {
- case UI_GRAD_SV:
- x = hsv[1]; y = hsv[2]; break;
- case UI_GRAD_HV:
- x = hsv[0]; y = hsv[2]; break;
- case UI_GRAD_HS:
- x = hsv[0]; y = hsv[1]; break;
- case UI_GRAD_H:
- x = hsv[0]; y = 0.5; break;
- case UI_GRAD_S:
- x = hsv[1]; y = 0.5; break;
- case UI_GRAD_V:
- x = hsv[2]; y = 0.5; break;
- case UI_GRAD_L_ALT:
- x = 0.5f;
- /* exception only for value strip - use the range set in but->min/max */
- y = hsv[2];
- break;
- case UI_GRAD_V_ALT:
- x = 0.5f;
- /* exception only for value strip - use the range set in but->min/max */
- y = (hsv[2] - but->softmin) / (but->softmax - but->softmin);
- break;
- }
-
- /* cursor */
- *r_xp = rect->xmin + x * BLI_rcti_size_x(rect);
- *r_yp = rect->ymin + y * BLI_rcti_size_y(rect);
+ float x = 0.0f, y = 0.0f;
+
+ switch ((int)but->a1) {
+ case UI_GRAD_SV:
+ x = hsv[1];
+ y = hsv[2];
+ break;
+ case UI_GRAD_HV:
+ x = hsv[0];
+ y = hsv[2];
+ break;
+ case UI_GRAD_HS:
+ x = hsv[0];
+ y = hsv[1];
+ break;
+ case UI_GRAD_H:
+ x = hsv[0];
+ y = 0.5;
+ break;
+ case UI_GRAD_S:
+ x = hsv[1];
+ y = 0.5;
+ break;
+ case UI_GRAD_V:
+ x = hsv[2];
+ y = 0.5;
+ break;
+ case UI_GRAD_L_ALT:
+ x = 0.5f;
+ /* exception only for value strip - use the range set in but->min/max */
+ y = hsv[2];
+ break;
+ case UI_GRAD_V_ALT:
+ x = 0.5f;
+ /* exception only for value strip - use the range set in but->min/max */
+ y = (hsv[2] - but->softmin) / (but->softmax - but->softmin);
+ break;
+ }
+
+ /* cursor */
+ *r_xp = rect->xmin + x * BLI_rcti_size_x(rect);
+ *r_yp = rect->ymin + y * BLI_rcti_size_y(rect);
}
static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
{
- float rgb[3];
- float x = 0.0f, y = 0.0f;
- ColorPicker *cpicker = but->custom_data;
- float *hsv = cpicker->color_data;
- float hsv_n[3];
+ float rgb[3];
+ float x = 0.0f, y = 0.0f;
+ ColorPicker *cpicker = but->custom_data;
+ float *hsv = cpicker->color_data;
+ float hsv_n[3];
- /* Initialize for compatibility. */
- copy_v3_v3(hsv_n, hsv);
+ /* Initialize for compatibility. */
+ copy_v3_v3(hsv_n, hsv);
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
- rgb_to_hsv_compat_v(rgb, hsv_n);
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+ rgb_to_hsv_compat_v(rgb, hsv_n);
- ui_draw_gradient(rect, hsv_n, but->a1, 1.0f);
+ ui_draw_gradient(rect, hsv_n, but->a1, 1.0f);
- ui_hsvcube_pos_from_vals(but, rect, hsv_n, &x, &y);
- CLAMP(x, rect->xmin + 3.0f, rect->xmax - 3.0f);
- CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
+ ui_hsvcube_pos_from_vals(but, rect, hsv_n, &x, &y);
+ CLAMP(x, rect->xmin + 3.0f, rect->xmax - 3.0f);
+ CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
- ui_hsv_cursor(x, y);
+ ui_hsv_cursor(x, y);
- /* outline */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3ub(0, 0, 0);
- imm_draw_box_wire_2d(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
- immUnbindProgram();
+ /* outline */
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3ub(0, 0, 0);
+ imm_draw_box_wire_2d(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
+ immUnbindProgram();
}
/* vertical 'value' slider, using new widget code */
static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
{
- bTheme *btheme = UI_GetTheme();
- uiWidgetColors *wcol = &btheme->tui.wcol_numslider;
- uiWidgetBase wtb;
- const float rad = wcol->roundness * BLI_rcti_size_x(rect);
- float x, y;
- float rgb[3], hsv[3], v;
-
- ui_but_v3_get(but, rgb);
- ui_scene_linear_to_color_picker_space(but, rgb);
-
- if (but->a1 == UI_GRAD_L_ALT) {
- rgb_to_hsl_v(rgb, hsv);
- }
- else {
- rgb_to_hsv_v(rgb, hsv);
- }
- v = hsv[2];
-
- /* map v from property range to [0,1] */
- if (but->a1 == UI_GRAD_V_ALT) {
- float min = but->softmin, max = but->softmax;
- v = (v - min) / (max - min);
- }
-
- widget_init(&wtb);
-
- /* fully rounded */
- round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
-
- /* setup temp colors */
- widgetbase_draw(
- &wtb,
- &((uiWidgetColors){
- .outline = {0, 0, 0, 255},
- .inner = {128, 128, 128, 255},
- .shadetop = 127,
- .shadedown = -128,
- .shaded = 1,
- })
- );
-
- /* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
-
- /* cursor */
- x = rect->xmin + 0.5f * BLI_rcti_size_x(rect);
- y = rect->ymin + v * BLI_rcti_size_y(rect);
- CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
-
- ui_hsv_cursor(x, y);
+ bTheme *btheme = UI_GetTheme();
+ uiWidgetColors *wcol = &btheme->tui.wcol_numslider;
+ uiWidgetBase wtb;
+ const float rad = wcol->roundness * BLI_rcti_size_x(rect);
+ float x, y;
+ float rgb[3], hsv[3], v;
+
+ ui_but_v3_get(but, rgb);
+ ui_scene_linear_to_color_picker_space(but, rgb);
+
+ if (but->a1 == UI_GRAD_L_ALT) {
+ rgb_to_hsl_v(rgb, hsv);
+ }
+ else {
+ rgb_to_hsv_v(rgb, hsv);
+ }
+ v = hsv[2];
+
+ /* map v from property range to [0,1] */
+ if (but->a1 == UI_GRAD_V_ALT) {
+ float min = but->softmin, max = but->softmax;
+ v = (v - min) / (max - min);
+ }
+
+ widget_init(&wtb);
+
+ /* fully rounded */
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+
+ /* setup temp colors */
+ widgetbase_draw(&wtb,
+ &((uiWidgetColors){
+ .outline = {0, 0, 0, 255},
+ .inner = {128, 128, 128, 255},
+ .shadetop = 127,
+ .shadedown = -128,
+ .shaded = 1,
+ }));
+
+ /* We are drawing on top of widget bases. Flush cache. */
+ GPU_blend(true);
+ UI_widgetbase_draw_cache_flush();
+ GPU_blend(false);
+
+ /* cursor */
+ x = rect->xmin + 0.5f * BLI_rcti_size_x(rect);
+ y = rect->ymin + v * BLI_rcti_size_y(rect);
+ CLAMP(y, rect->ymin + 3.0f, rect->ymax - 3.0f);
+
+ ui_hsv_cursor(x, y);
}
/* Generic round-box drawing. */
static void ui_draw_roundbox(const rcti *rect, const float rad, const uiWidgetColors *wcol)
{
- uiWidgetBase wtb;
- widget_init(&wtb);
- round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
- widgetbase_draw(&wtb, wcol);
-
- /* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ uiWidgetBase wtb;
+ widget_init(&wtb);
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+ widgetbase_draw(&wtb, wcol);
+
+ /* We are drawing on top of widget bases. Flush cache. */
+ GPU_blend(true);
+ UI_widgetbase_draw_cache_flush();
+ GPU_blend(false);
}
-
/* ************ separator, for menus etc ***************** */
static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol)
{
- int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1;
- uchar col[4] = {
- wcol->text[0],
- wcol->text[1],
- wcol->text[2],
- 30,
- };
+ int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1;
+ uchar col[4] = {
+ wcol->text[0],
+ wcol->text[1],
+ wcol->text[2],
+ 30,
+ };
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
- immUniformColor4ubv(col);
- GPU_line_width(1.0f);
+ GPU_blend(true);
+ immUniformColor4ubv(col);
+ GPU_line_width(1.0f);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, rect->xmin, y);
- immVertex2f(pos, rect->xmax, y);
- immEnd();
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, rect->xmin, y);
+ immVertex2f(pos, rect->xmax, y);
+ immEnd();
- GPU_blend(false);
+ GPU_blend(false);
- immUnbindProgram();
+ immUnbindProgram();
}
/* ************ button callbacks, draw ***************** */
-static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, bool emboss)
+static void widget_numbut_draw(
+ uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign, bool emboss)
{
- uiWidgetBase wtb;
- const float rad = wcol->roundness * BLI_rcti_size_y(rect);
- const int handle_width = min_ii(BLI_rcti_size_x(rect) / 3, BLI_rcti_size_y(rect) * 0.7f);
-
- if (state & UI_SELECT) {
- SWAP(short, wcol->shadetop, wcol->shadedown);
- }
-
- widget_init(&wtb);
-
- if (!emboss) {
- round_box_edges(&wtb, roundboxalign, rect, rad);
- }
- else {
- wtb.draw_inner = false;
- wtb.draw_outline = false;
- }
-
- /* decoration */
- if ((state & UI_ACTIVE) && !(state & UI_STATE_TEXT_INPUT)) {
- uiWidgetColors wcol_zone;
- uiWidgetBase wtb_zone;
- rcti rect_zone;
- int roundboxalign_zone;
-
- /* left arrow zone */
- widget_init(&wtb_zone);
- wtb_zone.draw_outline = false;
- wtb_zone.draw_emboss = false;
-
- wcol_zone = *wcol;
- copy_v3_v3_char(wcol_zone.item, wcol->text);
- if (state & UI_STATE_ACTIVE_LEFT) {
- widget_active_color(wcol_zone.inner);
- }
-
- rect_zone = *rect;
- rect_zone.xmax = rect->xmin + handle_width + U.pixelsize;
- roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
- round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
-
- shape_preset_init_number_arrows(&wtb_zone.tria1, &rect_zone, 0.6f, 'l');
- widgetbase_draw(&wtb_zone, &wcol_zone);
-
- /* right arrow zone */
- widget_init(&wtb_zone);
- wtb_zone.draw_outline = false;
- wtb_zone.draw_emboss = false;
- wtb_zone.tria1.type = ROUNDBOX_TRIA_ARROWS;
-
- wcol_zone = *wcol;
- copy_v3_v3_char(wcol_zone.item, wcol->text);
- if (state & UI_STATE_ACTIVE_RIGHT) {
- widget_active_color(wcol_zone.inner);
- }
-
- rect_zone = *rect;
- rect_zone.xmin = rect->xmax - handle_width - U.pixelsize;
- roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
- round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
-
- shape_preset_init_number_arrows(&wtb_zone.tria2, &rect_zone, 0.6f, 'r');
- widgetbase_draw(&wtb_zone, &wcol_zone);
-
- /* middle highlight zone */
- widget_init(&wtb_zone);
- wtb_zone.draw_outline = false;
- wtb_zone.draw_emboss = false;
-
- wcol_zone = *wcol;
- copy_v3_v3_char(wcol_zone.item, wcol->text);
- if (!(state & (UI_STATE_ACTIVE_LEFT | UI_STATE_ACTIVE_RIGHT))) {
- widget_active_color(wcol_zone.inner);
- }
-
- rect_zone = *rect;
- rect_zone.xmin = rect->xmin + handle_width - U.pixelsize;
- rect_zone.xmax = rect->xmax - handle_width + U.pixelsize;
- round_box_edges(&wtb_zone, 0, &rect_zone, 0);
- widgetbase_draw(&wtb_zone, &wcol_zone);
-
- /* outline */
- wtb.draw_inner = false;
- widgetbase_draw(&wtb, wcol);
- }
- else {
- /* inner and outline */
- widgetbase_draw(&wtb, wcol);
- }
-
- if (!(state & UI_STATE_TEXT_INPUT)) {
- const float textofs = 0.425f * BLI_rcti_size_y(rect);
-
- /* text space */
- rect->xmin += textofs;
- rect->xmax -= textofs;
- }
+ uiWidgetBase wtb;
+ const float rad = wcol->roundness * BLI_rcti_size_y(rect);
+ const int handle_width = min_ii(BLI_rcti_size_x(rect) / 3, BLI_rcti_size_y(rect) * 0.7f);
+
+ if (state & UI_SELECT) {
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+ }
+
+ widget_init(&wtb);
+
+ if (!emboss) {
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+ }
+ else {
+ wtb.draw_inner = false;
+ wtb.draw_outline = false;
+ }
+
+ /* decoration */
+ if ((state & UI_ACTIVE) && !(state & UI_STATE_TEXT_INPUT)) {
+ uiWidgetColors wcol_zone;
+ uiWidgetBase wtb_zone;
+ rcti rect_zone;
+ int roundboxalign_zone;
+
+ /* left arrow zone */
+ widget_init(&wtb_zone);
+ wtb_zone.draw_outline = false;
+ wtb_zone.draw_emboss = false;
+
+ wcol_zone = *wcol;
+ copy_v3_v3_char(wcol_zone.item, wcol->text);
+ if (state & UI_STATE_ACTIVE_LEFT) {
+ widget_active_color(wcol_zone.inner);
+ }
+
+ rect_zone = *rect;
+ rect_zone.xmax = rect->xmin + handle_width + U.pixelsize;
+ roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+ round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
+
+ shape_preset_init_number_arrows(&wtb_zone.tria1, &rect_zone, 0.6f, 'l');
+ widgetbase_draw(&wtb_zone, &wcol_zone);
+
+ /* right arrow zone */
+ widget_init(&wtb_zone);
+ wtb_zone.draw_outline = false;
+ wtb_zone.draw_emboss = false;
+ wtb_zone.tria1.type = ROUNDBOX_TRIA_ARROWS;
+
+ wcol_zone = *wcol;
+ copy_v3_v3_char(wcol_zone.item, wcol->text);
+ if (state & UI_STATE_ACTIVE_RIGHT) {
+ widget_active_color(wcol_zone.inner);
+ }
+
+ rect_zone = *rect;
+ rect_zone.xmin = rect->xmax - handle_width - U.pixelsize;
+ roundboxalign_zone = roundboxalign & ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ round_box_edges(&wtb_zone, roundboxalign_zone, &rect_zone, rad);
+
+ shape_preset_init_number_arrows(&wtb_zone.tria2, &rect_zone, 0.6f, 'r');
+ widgetbase_draw(&wtb_zone, &wcol_zone);
+
+ /* middle highlight zone */
+ widget_init(&wtb_zone);
+ wtb_zone.draw_outline = false;
+ wtb_zone.draw_emboss = false;
+
+ wcol_zone = *wcol;
+ copy_v3_v3_char(wcol_zone.item, wcol->text);
+ if (!(state & (UI_STATE_ACTIVE_LEFT | UI_STATE_ACTIVE_RIGHT))) {
+ widget_active_color(wcol_zone.inner);
+ }
+
+ rect_zone = *rect;
+ rect_zone.xmin = rect->xmin + handle_width - U.pixelsize;
+ rect_zone.xmax = rect->xmax - handle_width + U.pixelsize;
+ round_box_edges(&wtb_zone, 0, &rect_zone, 0);
+ widgetbase_draw(&wtb_zone, &wcol_zone);
+
+ /* outline */
+ wtb.draw_inner = false;
+ widgetbase_draw(&wtb, wcol);
+ }
+ else {
+ /* inner and outline */
+ widgetbase_draw(&wtb, wcol);
+ }
+
+ if (!(state & UI_STATE_TEXT_INPUT)) {
+ const float textofs = 0.425f * BLI_rcti_size_y(rect);
+
+ /* text space */
+ rect->xmin += textofs;
+ rect->xmax -= textofs;
+ }
}
static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- widget_numbut_draw(wcol, rect, state, roundboxalign, false);
+ widget_numbut_draw(wcol, rect, state, roundboxalign, false);
}
/**
* Draw number buttons still with triangles when field is not embossed
*/
-static void widget_numbut_embossn(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+static void widget_numbut_embossn(
+ uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- widget_numbut_draw(wcol, rect, state, roundboxalign, true);
+ widget_numbut_draw(wcol, rect, state, roundboxalign, true);
}
/* function in use for buttons and for view2d sliders */
void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *slider, int state)
{
- uiWidgetBase wtb;
- int horizontal;
- float rad;
- bool outline = false;
-
- widget_init(&wtb);
-
- /* determine horizontal/vertical */
- horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
-
- if (horizontal) {
- rad = wcol->roundness * BLI_rcti_size_y(rect);
- }
- else {
- rad = wcol->roundness * BLI_rcti_size_x(rect);
- }
-
- wtb.uniform_params.shade_dir = (horizontal) ? 1.0f : 0.0;
-
- /* draw back part, colors swapped and shading inverted */
- if (horizontal) {
- SWAP(short, wcol->shadetop, wcol->shadedown);
- }
-
- round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
- widgetbase_draw(&wtb, wcol);
-
- /* slider */
- if ((BLI_rcti_size_x(slider) < 2) || (BLI_rcti_size_y(slider) < 2)) {
- /* pass */
- }
- else {
- SWAP(short, wcol->shadetop, wcol->shadedown);
-
- copy_v4_v4_char(wcol->inner, wcol->item);
-
- if (wcol->shadetop > wcol->shadedown) {
- wcol->shadetop += 20; /* XXX violates themes... */
- }
- else {
- wcol->shadedown += 20;
- }
-
- if (state & UI_SCROLL_PRESSED) {
- wcol->inner[0] = wcol->inner[0] >= 250 ? 255 : wcol->inner[0] + 5;
- wcol->inner[1] = wcol->inner[1] >= 250 ? 255 : wcol->inner[1] + 5;
- wcol->inner[2] = wcol->inner[2] >= 250 ? 255 : wcol->inner[2] + 5;
- }
-
- /* draw */
- wtb.draw_emboss = false; /* only emboss once */
-
- /* exception for progress bar */
- if (state & UI_SCROLL_NO_OUTLINE) {
- SWAP(bool, outline, wtb.draw_outline);
- }
-
- round_box_edges(&wtb, UI_CNR_ALL, slider, rad);
-
- if (state & UI_SCROLL_ARROWS) {
- if (wcol->item[0] > 48) {
- wcol->item[0] -= 48;
- }
- if (wcol->item[1] > 48) {
- wcol->item[1] -= 48;
- }
- if (wcol->item[2] > 48) {
- wcol->item[2] -= 48;
- }
- wcol->item[3] = 255;
-
- if (horizontal) {
- shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'l');
- shape_preset_init_scroll_circle(&wtb.tria2, slider, 0.6f, 'r');
- }
- else {
- shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'b');
- shape_preset_init_scroll_circle(&wtb.tria2, slider, 0.6f, 't');
- }
- }
- widgetbase_draw(&wtb, wcol);
-
- if (state & UI_SCROLL_NO_OUTLINE) {
- SWAP(bool, outline, wtb.draw_outline);
- }
- }
+ uiWidgetBase wtb;
+ int horizontal;
+ float rad;
+ bool outline = false;
+
+ widget_init(&wtb);
+
+ /* determine horizontal/vertical */
+ horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
+
+ if (horizontal) {
+ rad = wcol->roundness * BLI_rcti_size_y(rect);
+ }
+ else {
+ rad = wcol->roundness * BLI_rcti_size_x(rect);
+ }
+
+ wtb.uniform_params.shade_dir = (horizontal) ? 1.0f : 0.0;
+
+ /* draw back part, colors swapped and shading inverted */
+ if (horizontal) {
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+ }
+
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+ widgetbase_draw(&wtb, wcol);
+
+ /* slider */
+ if ((BLI_rcti_size_x(slider) < 2) || (BLI_rcti_size_y(slider) < 2)) {
+ /* pass */
+ }
+ else {
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+
+ copy_v4_v4_char(wcol->inner, wcol->item);
+
+ if (wcol->shadetop > wcol->shadedown) {
+ wcol->shadetop += 20; /* XXX violates themes... */
+ }
+ else {
+ wcol->shadedown += 20;
+ }
+
+ if (state & UI_SCROLL_PRESSED) {
+ wcol->inner[0] = wcol->inner[0] >= 250 ? 255 : wcol->inner[0] + 5;
+ wcol->inner[1] = wcol->inner[1] >= 250 ? 255 : wcol->inner[1] + 5;
+ wcol->inner[2] = wcol->inner[2] >= 250 ? 255 : wcol->inner[2] + 5;
+ }
+
+ /* draw */
+ wtb.draw_emboss = false; /* only emboss once */
+
+ /* exception for progress bar */
+ if (state & UI_SCROLL_NO_OUTLINE) {
+ SWAP(bool, outline, wtb.draw_outline);
+ }
+
+ round_box_edges(&wtb, UI_CNR_ALL, slider, rad);
+
+ if (state & UI_SCROLL_ARROWS) {
+ if (wcol->item[0] > 48) {
+ wcol->item[0] -= 48;
+ }
+ if (wcol->item[1] > 48) {
+ wcol->item[1] -= 48;
+ }
+ if (wcol->item[2] > 48) {
+ wcol->item[2] -= 48;
+ }
+ wcol->item[3] = 255;
+
+ if (horizontal) {
+ shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'l');
+ shape_preset_init_scroll_circle(&wtb.tria2, slider, 0.6f, 'r');
+ }
+ else {
+ shape_preset_init_scroll_circle(&wtb.tria1, slider, 0.6f, 'b');
+ shape_preset_init_scroll_circle(&wtb.tria2, slider, 0.6f, 't');
+ }
+ }
+ widgetbase_draw(&wtb, wcol);
+
+ if (state & UI_SCROLL_NO_OUTLINE) {
+ SWAP(bool, outline, wtb.draw_outline);
+ }
+ }
}
-static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
+static void widget_scroll(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
{
- rcti rect1;
- double value;
- float fac, size, min;
- int horizontal;
-
- /* calculate slider part */
- value = ui_but_value_get(but);
-
- size = (but->softmax + but->a1 - but->softmin);
- size = max_ff(size, 2.0f);
-
- /* position */
- rect1 = *rect;
-
- /* determine horizontal/vertical */
- horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
-
- if (horizontal) {
- fac = BLI_rcti_size_x(rect) / size;
- rect1.xmin = rect1.xmin + ceilf(fac * ((float)value - but->softmin));
- rect1.xmax = rect1.xmin + ceilf(fac * (but->a1 - but->softmin));
-
- /* ensure minimium size */
- min = BLI_rcti_size_y(rect);
-
- if (BLI_rcti_size_x(&rect1) < min) {
- rect1.xmax = rect1.xmin + min;
-
- if (rect1.xmax > rect->xmax) {
- rect1.xmax = rect->xmax;
- rect1.xmin = max_ii(rect1.xmax - min, rect->xmin);
- }
- }
- }
- else {
- fac = BLI_rcti_size_y(rect) / size;
- rect1.ymax = rect1.ymax - ceilf(fac * ((float)value - but->softmin));
- rect1.ymin = rect1.ymax - ceilf(fac * (but->a1 - but->softmin));
-
- /* ensure minimium size */
- min = BLI_rcti_size_x(rect);
-
- if (BLI_rcti_size_y(&rect1) < min) {
- rect1.ymax = rect1.ymin + min;
-
- if (rect1.ymax > rect->ymax) {
- rect1.ymax = rect->ymax;
- rect1.ymin = max_ii(rect1.ymax - min, rect->ymin);
- }
- }
- }
-
- if (state & UI_SELECT) {
- state = UI_SCROLL_PRESSED;
- }
- else {
- state = 0;
- }
- UI_draw_widget_scroll(wcol, rect, &rect1, state);
+ rcti rect1;
+ double value;
+ float fac, size, min;
+ int horizontal;
+
+ /* calculate slider part */
+ value = ui_but_value_get(but);
+
+ size = (but->softmax + but->a1 - but->softmin);
+ size = max_ff(size, 2.0f);
+
+ /* position */
+ rect1 = *rect;
+
+ /* determine horizontal/vertical */
+ horizontal = (BLI_rcti_size_x(rect) > BLI_rcti_size_y(rect));
+
+ if (horizontal) {
+ fac = BLI_rcti_size_x(rect) / size;
+ rect1.xmin = rect1.xmin + ceilf(fac * ((float)value - but->softmin));
+ rect1.xmax = rect1.xmin + ceilf(fac * (but->a1 - but->softmin));
+
+ /* ensure minimium size */
+ min = BLI_rcti_size_y(rect);
+
+ if (BLI_rcti_size_x(&rect1) < min) {
+ rect1.xmax = rect1.xmin + min;
+
+ if (rect1.xmax > rect->xmax) {
+ rect1.xmax = rect->xmax;
+ rect1.xmin = max_ii(rect1.xmax - min, rect->xmin);
+ }
+ }
+ }
+ else {
+ fac = BLI_rcti_size_y(rect) / size;
+ rect1.ymax = rect1.ymax - ceilf(fac * ((float)value - but->softmin));
+ rect1.ymin = rect1.ymax - ceilf(fac * (but->a1 - but->softmin));
+
+ /* ensure minimium size */
+ min = BLI_rcti_size_x(rect);
+
+ if (BLI_rcti_size_y(&rect1) < min) {
+ rect1.ymax = rect1.ymin + min;
+
+ if (rect1.ymax > rect->ymax) {
+ rect1.ymax = rect->ymax;
+ rect1.ymin = max_ii(rect1.ymax - min, rect->ymin);
+ }
+ }
+ }
+
+ if (state & UI_SELECT) {
+ state = UI_SCROLL_PRESSED;
+ }
+ else {
+ state = 0;
+ }
+ UI_draw_widget_scroll(wcol, rect, &rect1, state);
}
-static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
+static void widget_progressbar(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
- uiWidgetBase wtb, wtb_bar;
- rcti rect_prog = *rect, rect_bar = *rect;
+ uiWidgetBase wtb, wtb_bar;
+ rcti rect_prog = *rect, rect_bar = *rect;
- widget_init(&wtb);
- widget_init(&wtb_bar);
+ widget_init(&wtb);
+ widget_init(&wtb_bar);
- /* round corners */
- float value = but->a1;
- float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
- float w = value * BLI_rcti_size_x(&rect_prog);
+ /* round corners */
+ float value = but->a1;
+ float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
+ float w = value * BLI_rcti_size_x(&rect_prog);
- /* ensure minimium size */
- w = MAX2(w, offs);
+ /* ensure minimium size */
+ w = MAX2(w, offs);
- rect_bar.xmax = rect_bar.xmin + w;
+ rect_bar.xmax = rect_bar.xmin + w;
- round_box_edges(&wtb, roundboxalign, &rect_prog, offs);
- round_box_edges(&wtb_bar, roundboxalign, &rect_bar, offs);
+ round_box_edges(&wtb, roundboxalign, &rect_prog, offs);
+ round_box_edges(&wtb_bar, roundboxalign, &rect_bar, offs);
- wtb.draw_outline = true;
- widgetbase_draw(&wtb, wcol);
+ wtb.draw_outline = true;
+ widgetbase_draw(&wtb, wcol);
- /* "slider" bar color */
- copy_v3_v3_char(wcol->inner, wcol->item);
- widgetbase_draw(&wtb_bar, wcol);
+ /* "slider" bar color */
+ copy_v3_v3_char(wcol->inner, wcol->item);
+ widgetbase_draw(&wtb_bar, wcol);
- /* raise text a bit */
- rect->xmin += (BLI_rcti_size_x(&rect_prog) / 2);
- rect->xmax += (BLI_rcti_size_x(&rect_prog) / 2);
+ /* raise text a bit */
+ rect->xmin += (BLI_rcti_size_x(&rect_prog) / 2);
+ rect->xmax += (BLI_rcti_size_x(&rect_prog) / 2);
}
-static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+static void widget_numslider(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- uiWidgetBase wtb, wtb1;
- rcti rect1;
- float offs, toffs;
- char outline[3];
-
- widget_init(&wtb);
- widget_init(&wtb1);
-
- /* Backdrop first. */
- offs = wcol->roundness * BLI_rcti_size_y(rect);
- toffs = offs * 0.75f;
- round_box_edges(&wtb, roundboxalign, rect, offs);
-
- wtb.draw_outline = false;
- widgetbase_draw(&wtb, wcol);
-
- /* Draw slider part only when not in text editing. */
- if (!(state & UI_STATE_TEXT_INPUT)) {
- int roundboxalign_slider = roundboxalign;
-
- copy_v3_v3_char(outline, wcol->outline);
- copy_v3_v3_char(wcol->outline, wcol->item);
- copy_v3_v3_char(wcol->inner, wcol->item);
-
- if (!(state & UI_SELECT)) {
- SWAP(short, wcol->shadetop, wcol->shadedown);
- }
-
- rect1 = *rect;
- float factor, factor_ui;
- float factor_discard = 1.0f; /* No discard. */
- float value = (float)ui_but_value_get(but);
-
- if (but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PERCENTAGE)) {
- factor = value / but->softmax;
- }
- else {
- factor = (value - but->softmin) / (but->softmax - but->softmin);
- }
-
- float width = (float)BLI_rcti_size_x(rect);
- factor_ui = factor * width;
-
- if (factor_ui <= offs) {
- /* Left part only. */
- roundboxalign_slider &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
- rect1.xmax = rect1.xmin + offs;
- factor_discard = factor_ui / offs;
- }
- else if (factor_ui <= width - offs) {
- /* Left part + middle part. */
- roundboxalign_slider &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
- rect1.xmax = rect1.xmin + factor_ui;
- }
- else {
- /* Left part + middle part + right part. */
- factor_discard = factor;
- }
-
- round_box_edges(&wtb1, roundboxalign_slider, &rect1, offs);
- wtb1.draw_outline = false;
- widgetbase_set_uniform_discard_factor(&wtb1, factor_discard);
- widgetbase_draw(&wtb1, wcol);
-
- copy_v3_v3_char(wcol->outline, outline);
-
- if (!(state & UI_SELECT)) {
- SWAP(short, wcol->shadetop, wcol->shadedown);
- }
- }
-
- /* Outline. */
- wtb.draw_outline = true;
- wtb.draw_inner = false;
- widgetbase_draw(&wtb, wcol);
-
- /* Add space at either side of the button so text aligns with numbuttons
- * (which have arrow icons). */
- if (!(state & UI_STATE_TEXT_INPUT)) {
- rect->xmax -= toffs;
- rect->xmin += toffs;
- }
+ uiWidgetBase wtb, wtb1;
+ rcti rect1;
+ float offs, toffs;
+ char outline[3];
+
+ widget_init(&wtb);
+ widget_init(&wtb1);
+
+ /* Backdrop first. */
+ offs = wcol->roundness * BLI_rcti_size_y(rect);
+ toffs = offs * 0.75f;
+ round_box_edges(&wtb, roundboxalign, rect, offs);
+
+ wtb.draw_outline = false;
+ widgetbase_draw(&wtb, wcol);
+
+ /* Draw slider part only when not in text editing. */
+ if (!(state & UI_STATE_TEXT_INPUT)) {
+ int roundboxalign_slider = roundboxalign;
+
+ copy_v3_v3_char(outline, wcol->outline);
+ copy_v3_v3_char(wcol->outline, wcol->item);
+ copy_v3_v3_char(wcol->inner, wcol->item);
+
+ if (!(state & UI_SELECT)) {
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+ }
+
+ rect1 = *rect;
+ float factor, factor_ui;
+ float factor_discard = 1.0f; /* No discard. */
+ float value = (float)ui_but_value_get(but);
+
+ if (but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PERCENTAGE)) {
+ factor = value / but->softmax;
+ }
+ else {
+ factor = (value - but->softmin) / (but->softmax - but->softmin);
+ }
+
+ float width = (float)BLI_rcti_size_x(rect);
+ factor_ui = factor * width;
+
+ if (factor_ui <= offs) {
+ /* Left part only. */
+ roundboxalign_slider &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+ rect1.xmax = rect1.xmin + offs;
+ factor_discard = factor_ui / offs;
+ }
+ else if (factor_ui <= width - offs) {
+ /* Left part + middle part. */
+ roundboxalign_slider &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+ rect1.xmax = rect1.xmin + factor_ui;
+ }
+ else {
+ /* Left part + middle part + right part. */
+ factor_discard = factor;
+ }
+
+ round_box_edges(&wtb1, roundboxalign_slider, &rect1, offs);
+ wtb1.draw_outline = false;
+ widgetbase_set_uniform_discard_factor(&wtb1, factor_discard);
+ widgetbase_draw(&wtb1, wcol);
+
+ copy_v3_v3_char(wcol->outline, outline);
+
+ if (!(state & UI_SELECT)) {
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+ }
+ }
+
+ /* Outline. */
+ wtb.draw_outline = true;
+ wtb.draw_inner = false;
+ widgetbase_draw(&wtb, wcol);
+
+ /* Add space at either side of the button so text aligns with numbuttons
+ * (which have arrow icons). */
+ if (!(state & UI_STATE_TEXT_INPUT)) {
+ rect->xmax -= toffs;
+ rect->xmin += toffs;
+ }
}
/* I think 3 is sufficient border to indicate keyed status */
#define SWATCH_KEYED_BORDER 3
-static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+static void widget_swatch(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- uiWidgetBase wtb;
- float rad, col[4];
-
- col[3] = 1.0f;
-
- if (but->rnaprop) {
- BLI_assert(but->rnaindex == -1);
-
- if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4) {
- col[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
- }
- }
-
- widget_init(&wtb);
-
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, roundboxalign, rect, rad);
-
- ui_but_v3_get(but, col);
-
- if ((state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_OVERRIDEN | UI_BUT_REDALERT)) ||
- (but->drawflag & UI_BUT_ANIMATED_CHANGED))
- {
- /* draw based on state - color for keyed etc */
- widgetbase_draw(&wtb, wcol);
-
- /* inset to draw swatch color */
- rect->xmin += SWATCH_KEYED_BORDER;
- rect->xmax -= SWATCH_KEYED_BORDER;
- rect->ymin += SWATCH_KEYED_BORDER;
- rect->ymax -= SWATCH_KEYED_BORDER;
-
- round_box_edges(&wtb, roundboxalign, rect, rad);
- }
-
- if (!ui_but_is_color_gamma(but)) {
- ui_block_cm_to_display_space_v3(but->block, col);
- }
-
- rgba_float_to_uchar((uchar *)wcol->inner, col);
- const bool show_alpha_checkers = (wcol->inner[3] < 255);
-
- wcol->shaded = 0;
-
- if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- /* Now we reduce alpha of the inner color (i.e. the color shown)
- * so that this setting can look grayed out, while retaining
- * the checkboard (for transparent values). This is needed
- * here as the effects of ui_widget_color_disabled() are overwritten.
- */
- wcol->inner[3] /= 2;
- }
-
- widgetbase_draw_ex(&wtb, wcol, show_alpha_checkers);
- if (but->a1 == UI_PALETTE_COLOR && ((Palette *)but->rnapoin.id.data)->active_color == (int)but->a2) {
- float width = rect->xmax - rect->xmin;
- float height = rect->ymax - rect->ymin;
- /* find color luminance and change it slightly */
- float bw = rgb_to_grayscale(col);
-
- bw += (bw < 0.5f) ? 0.5f : -0.5f;
-
- /* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformColor3f(bw, bw, bw);
- immBegin(GPU_PRIM_TRIS, 3);
- immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.9f * height);
- immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.5f * height);
- immVertex2f(pos, rect->xmin + 0.5f * width, rect->ymin + 0.9f * height);
- immEnd();
-
- immUnbindProgram();
- }
+ uiWidgetBase wtb;
+ float rad, col[4];
+
+ col[3] = 1.0f;
+
+ if (but->rnaprop) {
+ BLI_assert(but->rnaindex == -1);
+
+ if (RNA_property_array_length(&but->rnapoin, but->rnaprop) == 4) {
+ col[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
+ }
+ }
+
+ widget_init(&wtb);
+
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+
+ ui_but_v3_get(but, col);
+
+ if ((state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_OVERRIDEN |
+ UI_BUT_REDALERT)) ||
+ (but->drawflag & UI_BUT_ANIMATED_CHANGED)) {
+ /* draw based on state - color for keyed etc */
+ widgetbase_draw(&wtb, wcol);
+
+ /* inset to draw swatch color */
+ rect->xmin += SWATCH_KEYED_BORDER;
+ rect->xmax -= SWATCH_KEYED_BORDER;
+ rect->ymin += SWATCH_KEYED_BORDER;
+ rect->ymax -= SWATCH_KEYED_BORDER;
+
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+ }
+
+ if (!ui_but_is_color_gamma(but)) {
+ ui_block_cm_to_display_space_v3(but->block, col);
+ }
+
+ rgba_float_to_uchar((uchar *)wcol->inner, col);
+ const bool show_alpha_checkers = (wcol->inner[3] < 255);
+
+ wcol->shaded = 0;
+
+ if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ /* Now we reduce alpha of the inner color (i.e. the color shown)
+ * so that this setting can look grayed out, while retaining
+ * the checkboard (for transparent values). This is needed
+ * here as the effects of ui_widget_color_disabled() are overwritten.
+ */
+ wcol->inner[3] /= 2;
+ }
+
+ widgetbase_draw_ex(&wtb, wcol, show_alpha_checkers);
+ if (but->a1 == UI_PALETTE_COLOR &&
+ ((Palette *)but->rnapoin.id.data)->active_color == (int)but->a2) {
+ float width = rect->xmax - rect->xmin;
+ float height = rect->ymax - rect->ymin;
+ /* find color luminance and change it slightly */
+ float bw = rgb_to_grayscale(col);
+
+ bw += (bw < 0.5f) ? 0.5f : -0.5f;
+
+ /* We are drawing on top of widget bases. Flush cache. */
+ GPU_blend(true);
+ UI_widgetbase_draw_cache_flush();
+ GPU_blend(false);
+
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ immUniformColor3f(bw, bw, bw);
+ immBegin(GPU_PRIM_TRIS, 3);
+ immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.9f * height);
+ immVertex2f(pos, rect->xmin + 0.1f * width, rect->ymin + 0.5f * height);
+ immVertex2f(pos, rect->xmin + 0.5f * width, rect->ymin + 0.9f * height);
+ immEnd();
+
+ immUnbindProgram();
+ }
}
-static void widget_unitvec(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+static void widget_unitvec(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
- ui_draw_but_UNITVEC(but, wcol, rect);
+ ui_draw_but_UNITVEC(but, wcol, rect);
}
-static void widget_icon_has_anim(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
+static void widget_icon_has_anim(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
- uiWidgetBase wtb;
- float rad;
-
- widget_init(&wtb);
- wtb.draw_outline = false;
-
- rad = wcol->roundness * BLI_rcti_size_y(rect);
- round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
- widgetbase_draw(&wtb, wcol);
- }
- else if (but->type == UI_BTYPE_NUM) {
- /* Draw number buttons still with left/right
- * triangles when field is not embossed */
- widget_numbut_embossn(but, wcol, rect, state, roundboxalign);
- }
+ if (state & (UI_BUT_ANIMATED | UI_BUT_ANIMATED_KEY | UI_BUT_DRIVEN | UI_BUT_REDALERT)) {
+ uiWidgetBase wtb;
+ float rad;
+
+ widget_init(&wtb);
+ wtb.draw_outline = false;
+
+ rad = wcol->roundness * BLI_rcti_size_y(rect);
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+ widgetbase_draw(&wtb, wcol);
+ }
+ else if (but->type == UI_BTYPE_NUM) {
+ /* Draw number buttons still with left/right
+ * triangles when field is not embossed */
+ widget_numbut_embossn(but, wcol, rect, state, roundboxalign);
+ }
}
-
static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- uiWidgetBase wtb;
- float rad;
+ uiWidgetBase wtb;
+ float rad;
- if (state & UI_SELECT) {
- SWAP(short, wcol->shadetop, wcol->shadedown);
- }
+ if (state & UI_SELECT) {
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+ }
- widget_init(&wtb);
+ widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
-
static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
- uiWidgetBase wtb;
- float rad;
+ uiWidgetBase wtb;
+ float rad;
- widget_init(&wtb);
+ widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- /* decoration */
- shape_preset_trias_from_rect_menu(&wtb.tria1, rect);
- /* copy size and center to 2nd tria */
- wtb.tria2 = wtb.tria1;
+ /* decoration */
+ shape_preset_trias_from_rect_menu(&wtb.tria1, rect);
+ /* copy size and center to 2nd tria */
+ wtb.tria2 = wtb.tria1;
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
- /* text space, arrows are about 0.6 height of button */
- rect->xmax -= (6 * BLI_rcti_size_y(rect)) / 10;
+ /* text space, arrows are about 0.6 height of button */
+ rect->xmax -= (6 * BLI_rcti_size_y(rect)) / 10;
}
-static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
+static void widget_menuiconbut(uiWidgetColors *wcol,
+ rcti *rect,
+ int UNUSED(state),
+ int roundboxalign)
{
- uiWidgetBase wtb;
- float rad;
+ uiWidgetBase wtb;
+ float rad;
- widget_init(&wtb);
+ widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- /* decoration */
- widgetbase_draw(&wtb, wcol);
+ /* decoration */
+ widgetbase_draw(&wtb, wcol);
}
static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- float back[4];
- UI_GetThemeColor4fv(TH_BACK, back);
-
- if ((state & UI_ACTIVE) || (back[3] < 1.0f)) {
- uiWidgetBase wtb;
- const float rad = wcol->roundness * U.widget_unit;
-
- if (state & UI_ACTIVE) {
- copy_v4_v4_char(wcol->inner, wcol->inner_sel);
- copy_v3_v3_char(wcol->text, wcol->text_sel);
- copy_v3_v3_char(wcol->outline, wcol->inner);
- }
- else {
- wcol->inner[3] *= 1.0f - back[3];
- wcol->outline[3] = 0.0f;
- }
-
- widget_init(&wtb);
-
- /* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, rad);
-
- widgetbase_draw(&wtb, wcol);
- }
+ float back[4];
+ UI_GetThemeColor4fv(TH_BACK, back);
+
+ if ((state & UI_ACTIVE) || (back[3] < 1.0f)) {
+ uiWidgetBase wtb;
+ const float rad = wcol->roundness * U.widget_unit;
+
+ if (state & UI_ACTIVE) {
+ copy_v4_v4_char(wcol->inner, wcol->inner_sel);
+ copy_v3_v3_char(wcol->text, wcol->text_sel);
+ copy_v3_v3_char(wcol->outline, wcol->inner);
+ }
+ else {
+ wcol->inner[3] *= 1.0f - back[3];
+ wcol->outline[3] = 0.0f;
+ }
+
+ widget_init(&wtb);
+
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, rad);
+
+ widgetbase_draw(&wtb, wcol);
+ }
}
-static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+static void widget_menu_itembut(uiWidgetColors *wcol,
+ rcti *rect,
+ int UNUSED(state),
+ int UNUSED(roundboxalign))
{
- uiWidgetBase wtb;
+ uiWidgetBase wtb;
- widget_init(&wtb);
+ widget_init(&wtb);
- /* not rounded, no outline */
- wtb.draw_outline = false;
- round_box_edges(&wtb, 0, rect, 0.0f);
+ /* not rounded, no outline */
+ wtb.draw_outline = false;
+ round_box_edges(&wtb, 0, rect, 0.0f);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
-static void widget_menu_radial_itembut(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+static void widget_menu_radial_itembut(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
{
- uiWidgetBase wtb;
- float rad;
- float fac = but->block->pie_data.alphafac;
+ uiWidgetBase wtb;
+ float rad;
+ float fac = but->block->pie_data.alphafac;
- widget_init(&wtb);
+ widget_init(&wtb);
- wtb.draw_emboss = false;
+ wtb.draw_emboss = false;
- rad = wcol->roundness * BLI_rcti_size_y(rect);
- round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+ rad = wcol->roundness * BLI_rcti_size_y(rect);
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
- wcol->inner[3] *= fac;
- wcol->inner_sel[3] *= fac;
- wcol->item[3] *= fac;
- wcol->text[3] *= fac;
- wcol->text_sel[3] *= fac;
- wcol->outline[3] *= fac;
+ wcol->inner[3] *= fac;
+ wcol->inner_sel[3] *= fac;
+ wcol->item[3] *= fac;
+ wcol->text[3] *= fac;
+ wcol->text_sel[3] *= fac;
+ wcol->outline[3] *= fac;
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
-static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign))
+static void widget_list_itembut(uiWidgetColors *wcol,
+ rcti *rect,
+ int UNUSED(state),
+ int UNUSED(roundboxalign))
{
- uiWidgetBase wtb;
- float rad;
+ uiWidgetBase wtb;
+ float rad;
- widget_init(&wtb);
+ widget_init(&wtb);
- /* no outline */
- wtb.draw_outline = false;
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+ /* no outline */
+ wtb.draw_outline = false;
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
-static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign))
+static void widget_optionbut(uiWidgetColors *wcol,
+ rcti *rect,
+ int state,
+ int UNUSED(roundboxalign))
{
- bool text_before_widget = (state & UI_STATE_TEXT_BEFORE_WIDGET);
- uiWidgetBase wtb;
- rcti recttemp = *rect;
- float rad;
- int delta;
-
- widget_init(&wtb);
-
- /* square */
- if (text_before_widget) {
- recttemp.xmin = recttemp.xmax - BLI_rcti_size_y(&recttemp);
- }
- else {
- recttemp.xmax = recttemp.xmin + BLI_rcti_size_y(&recttemp);
- }
-
- /* smaller */
- delta = 1 + BLI_rcti_size_y(&recttemp) / 8;
- recttemp.xmin += delta;
- recttemp.ymin += delta;
- recttemp.xmax -= delta;
- recttemp.ymax -= delta;
-
- rad = wcol->roundness * BLI_rcti_size_y(&recttemp);
- round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
-
- /* decoration */
- if (state & UI_SELECT) {
- shape_preset_trias_from_rect_checkmark(&wtb.tria1, &recttemp);
- }
-
- widgetbase_draw(&wtb, wcol);
-
- /* text space */
- const float offset = BLI_rcti_size_y(rect) * 0.7 + delta;
- if (text_before_widget) {
- rect->xmax -= offset;
- }
- else {
- rect->xmin += offset;
- }
+ bool text_before_widget = (state & UI_STATE_TEXT_BEFORE_WIDGET);
+ uiWidgetBase wtb;
+ rcti recttemp = *rect;
+ float rad;
+ int delta;
+
+ widget_init(&wtb);
+
+ /* square */
+ if (text_before_widget) {
+ recttemp.xmin = recttemp.xmax - BLI_rcti_size_y(&recttemp);
+ }
+ else {
+ recttemp.xmax = recttemp.xmin + BLI_rcti_size_y(&recttemp);
+ }
+
+ /* smaller */
+ delta = 1 + BLI_rcti_size_y(&recttemp) / 8;
+ recttemp.xmin += delta;
+ recttemp.ymin += delta;
+ recttemp.xmax -= delta;
+ recttemp.ymax -= delta;
+
+ rad = wcol->roundness * BLI_rcti_size_y(&recttemp);
+ round_box_edges(&wtb, UI_CNR_ALL, &recttemp, rad);
+
+ /* decoration */
+ if (state & UI_SELECT) {
+ shape_preset_trias_from_rect_checkmark(&wtb.tria1, &recttemp);
+ }
+
+ widgetbase_draw(&wtb, wcol);
+
+ /* text space */
+ const float offset = BLI_rcti_size_y(rect) * 0.7 + delta;
+ if (text_before_widget) {
+ rect->xmax -= offset;
+ }
+ else {
+ rect->xmin += offset;
+ }
}
/* labels use Editor theme colors for text */
static void widget_state_label(uiWidgetType *wt, int state, int drawflag)
{
- if (state & UI_BUT_LIST_ITEM) {
- /* Override default label theme's colors. */
- bTheme *btheme = UI_GetTheme();
- wt->wcol_theme = &btheme->tui.wcol_list_item;
- /* call this for option button */
- widget_state(wt, state, drawflag);
- }
- else {
- /* call this for option button */
- widget_state(wt, state, drawflag);
- if (state & UI_SELECT) {
- UI_GetThemeColor3ubv(TH_TEXT_HI, (uchar *)wt->wcol.text);
- }
- else {
- UI_GetThemeColor3ubv(TH_TEXT, (uchar *)wt->wcol.text);
- }
- }
-
- if (state & UI_BUT_REDALERT) {
- char red[4] = {255, 0, 0};
- widget_state_blend(wt->wcol.text, red, 0.4f);
- }
+ if (state & UI_BUT_LIST_ITEM) {
+ /* Override default label theme's colors. */
+ bTheme *btheme = UI_GetTheme();
+ wt->wcol_theme = &btheme->tui.wcol_list_item;
+ /* call this for option button */
+ widget_state(wt, state, drawflag);
+ }
+ else {
+ /* call this for option button */
+ widget_state(wt, state, drawflag);
+ if (state & UI_SELECT) {
+ UI_GetThemeColor3ubv(TH_TEXT_HI, (uchar *)wt->wcol.text);
+ }
+ else {
+ UI_GetThemeColor3ubv(TH_TEXT, (uchar *)wt->wcol.text);
+ }
+ }
+
+ if (state & UI_BUT_REDALERT) {
+ char red[4] = {255, 0, 0};
+ widget_state_blend(wt->wcol.text, red, 0.4f);
+ }
}
static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
- uiWidgetBase wtb;
- float rad;
+ uiWidgetBase wtb;
+ float rad;
- widget_init(&wtb);
+ widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
-static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
+static void widget_box(
+ uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
- uiWidgetBase wtb;
- float rad;
- char old_col[3];
+ uiWidgetBase wtb;
+ float rad;
+ char old_col[3];
- widget_init(&wtb);
+ widget_init(&wtb);
- copy_v3_v3_char(old_col, wcol->inner);
+ copy_v3_v3_char(old_col, wcol->inner);
- /* abuse but->hsv - if it's non-zero, use this color as the box's background */
- if (but->col[3]) {
- wcol->inner[0] = but->col[0];
- wcol->inner[1] = but->col[1];
- wcol->inner[2] = but->col[2];
- wcol->inner[3] = but->col[3];
- }
+ /* abuse but->hsv - if it's non-zero, use this color as the box's background */
+ if (but->col[3]) {
+ wcol->inner[0] = but->col[0];
+ wcol->inner[1] = but->col[1];
+ wcol->inner[2] = but->col[2];
+ wcol->inner[3] = but->col[3];
+ }
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
- copy_v3_v3_char(wcol->inner, old_col);
+ copy_v3_v3_char(wcol->inner, old_col);
}
static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
- uiWidgetBase wtb;
- float rad;
+ uiWidgetBase wtb;
+ float rad;
- widget_init(&wtb);
+ widget_init(&wtb);
- rad = wcol->roundness * U.widget_unit;
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ rad = wcol->roundness * U.widget_unit;
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
#if 0
static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
- uiWidgetBase wtb;
- const float rad = wcol->roundness * U.widget_unit;
+ uiWidgetBase wtb;
+ const float rad = wcol->roundness * U.widget_unit;
- widget_init(&wtb);
+ widget_init(&wtb);
- /* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
#endif
static void widget_roundbut_exec(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- uiWidgetBase wtb;
- const float rad = wcol->roundness * U.widget_unit;
+ uiWidgetBase wtb;
+ const float rad = wcol->roundness * U.widget_unit;
- widget_init(&wtb);
+ widget_init(&wtb);
- if (state & UI_STATE_HOLD_ACTION) {
- /* Show that keeping pressed performs another action (typically a menu). */
- shape_preset_init_hold_action(&wtb.tria1, rect, 0.75f, 'r');
- }
+ if (state & UI_STATE_HOLD_ACTION) {
+ /* Show that keeping pressed performs another action (typically a menu). */
+ shape_preset_init_hold_action(&wtb.tria1, rect, 0.75f, 'r');
+ }
- /* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
}
static void widget_tab(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
- const float rad = wcol->roundness * U.widget_unit;
- const bool is_active = (state & UI_SELECT);
+ const float rad = wcol->roundness * U.widget_unit;
+ const bool is_active = (state & UI_SELECT);
-/* Draw shaded outline - Disabled for now,
+ /* Draw shaded outline - Disabled for now,
* seems incorrect and also looks nicer without it imho ;) */
-//#define USE_TAB_SHADED_HIGHLIGHT
+ //#define USE_TAB_SHADED_HIGHLIGHT
- uiWidgetBase wtb;
- uchar theme_col_tab_highlight[3];
+ uiWidgetBase wtb;
+ uchar theme_col_tab_highlight[3];
#ifdef USE_TAB_SHADED_HIGHLIGHT
- /* create outline highlight colors */
- if (is_active) {
- interp_v3_v3v3_uchar(theme_col_tab_highlight, (uchar *)wcol->inner_sel,
- (uchar *)wcol->outline, 0.2f);
- }
- else {
- interp_v3_v3v3_uchar(theme_col_tab_highlight, (uchar *)wcol->inner,
- (uchar *)wcol->outline, 0.12f);
- }
+ /* create outline highlight colors */
+ if (is_active) {
+ interp_v3_v3v3_uchar(
+ theme_col_tab_highlight, (uchar *)wcol->inner_sel, (uchar *)wcol->outline, 0.2f);
+ }
+ else {
+ interp_v3_v3v3_uchar(
+ theme_col_tab_highlight, (uchar *)wcol->inner, (uchar *)wcol->outline, 0.12f);
+ }
#endif
- widget_init(&wtb);
+ widget_init(&wtb);
- /* half rounded */
- round_box_edges(&wtb, roundboxalign, rect, rad);
+ /* half rounded */
+ round_box_edges(&wtb, roundboxalign, rect, rad);
- /* draw inner */
+ /* draw inner */
#ifdef USE_TAB_SHADED_HIGHLIGHT
- wtb.draw_outline = 0;
+ wtb.draw_outline = 0;
#endif
- widgetbase_draw(&wtb, wcol);
+ widgetbase_draw(&wtb, wcol);
- /* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
- UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ /* We are drawing on top of widget bases. Flush cache. */
+ GPU_blend(true);
+ UI_widgetbase_draw_cache_flush();
+ GPU_blend(false);
#ifdef USE_TAB_SHADED_HIGHLIGHT
- /* draw outline (3d look) */
- ui_draw_but_TAB_outline(rect, rad, theme_col_tab_highlight, (uchar *)wcol->inner);
+ /* draw outline (3d look) */
+ ui_draw_but_TAB_outline(rect, rad, theme_col_tab_highlight, (uchar *)wcol->inner);
#endif
#ifndef USE_TAB_SHADED_HIGHLIGHT
- UNUSED_VARS(is_active, theme_col_tab_highlight);
+ UNUSED_VARS(is_active, theme_col_tab_highlight);
#endif
}
static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect)
{
- bTheme *btheme = UI_GetTheme();
- uiWidgetColors *wcol = &btheme->tui.wcol_radio;
- uiWidgetBase wtb;
- const float rad = wcol->roundness * U.widget_unit;
- uchar col[4];
+ bTheme *btheme = UI_GetTheme();
+ uiWidgetColors *wcol = &btheme->tui.wcol_radio;
+ uiWidgetBase wtb;
+ const float rad = wcol->roundness * U.widget_unit;
+ uchar col[4];
- /* state copy! */
- wt->wcol = *(wt->wcol_theme);
+ /* state copy! */
+ wt->wcol = *(wt->wcol_theme);
- widget_init(&wtb);
+ widget_init(&wtb);
- if (but->block->drawextra) {
- /* note: drawextra can change rect +1 or -1, to match round errors of existing previews */
- but->block->drawextra(C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect);
+ if (but->block->drawextra) {
+ /* note: drawextra can change rect +1 or -1, to match round errors of existing previews */
+ but->block->drawextra(
+ C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* make mask to draw over image */
- UI_GetThemeColor3ubv(TH_BACK, col);
- immUniformColor3ubv(col);
+ /* make mask to draw over image */
+ UI_GetThemeColor3ubv(TH_BACK, col);
+ immUniformColor3ubv(col);
- round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad);
- widgetbase_outline(&wtb, pos);
+ round_box__edges(&wtb, UI_CNR_ALL, rect, 0.0f, rad);
+ widgetbase_outline(&wtb, pos);
- immUnbindProgram();
- }
+ immUnbindProgram();
+ }
- /* outline */
- round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
- wtb.draw_outline = true;
- wtb.draw_inner = false;
- widgetbase_draw(&wtb, &wt->wcol);
+ /* outline */
+ round_box_edges(&wtb, UI_CNR_ALL, rect, rad);
+ wtb.draw_outline = true;
+ wtb.draw_inner = false;
+ widgetbase_draw(&wtb, &wt->wcol);
}
static uiWidgetType *widget_type(uiWidgetTypeEnum type)
{
- bTheme *btheme = UI_GetTheme();
- static uiWidgetType wt;
-
- /* defaults */
- wt.wcol_theme = &btheme->tui.wcol_regular;
- wt.wcol_state = &btheme->tui.wcol_state;
- wt.state = widget_state;
- wt.draw = widget_but;
- wt.custom = NULL;
- wt.text = widget_draw_text_icon;
-
- switch (type) {
- case UI_WTYPE_REGULAR:
- break;
-
- case UI_WTYPE_LABEL:
- wt.draw = NULL;
- wt.state = widget_state_label;
- break;
-
- case UI_WTYPE_TOGGLE:
- wt.wcol_theme = &btheme->tui.wcol_toggle;
- break;
-
- case UI_WTYPE_CHECKBOX:
- wt.wcol_theme = &btheme->tui.wcol_option;
- wt.draw = widget_optionbut;
- break;
-
- case UI_WTYPE_RADIO:
- wt.wcol_theme = &btheme->tui.wcol_radio;
- wt.draw = widget_radiobut;
- break;
-
- case UI_WTYPE_NUMBER:
- wt.wcol_theme = &btheme->tui.wcol_num;
- wt.draw = widget_numbut;
- break;
-
- case UI_WTYPE_SLIDER:
- wt.wcol_theme = &btheme->tui.wcol_numslider;
- wt.custom = widget_numslider;
- wt.state = widget_state_numslider;
- break;
-
- case UI_WTYPE_EXEC:
- wt.wcol_theme = &btheme->tui.wcol_tool;
- wt.draw = widget_roundbut_exec;
- break;
-
- case UI_WTYPE_TOOLBAR_ITEM:
- wt.wcol_theme = &btheme->tui.wcol_toolbar_item;
- wt.draw = widget_roundbut_exec;
- break;
-
- case UI_WTYPE_TAB:
- wt.wcol_theme = &btheme->tui.wcol_tab;
- wt.draw = widget_tab;
- break;
-
- case UI_WTYPE_TOOLTIP:
- wt.wcol_theme = &btheme->tui.wcol_tooltip;
- wt.draw = widget_menu_back;
- break;
-
-
- /* strings */
- case UI_WTYPE_NAME:
- wt.wcol_theme = &btheme->tui.wcol_text;
- wt.draw = widget_textbut;
- break;
-
- case UI_WTYPE_NAME_LINK:
- break;
-
- case UI_WTYPE_POINTER_LINK:
- break;
-
- case UI_WTYPE_FILENAME:
- break;
-
-
- /* start menus */
- case UI_WTYPE_MENU_RADIO:
- wt.wcol_theme = &btheme->tui.wcol_menu;
- wt.draw = widget_menubut;
- break;
-
- case UI_WTYPE_MENU_ICON_RADIO:
- case UI_WTYPE_MENU_NODE_LINK:
- wt.wcol_theme = &btheme->tui.wcol_menu;
- wt.draw = widget_menuiconbut;
- break;
-
- case UI_WTYPE_MENU_POINTER_LINK:
- wt.wcol_theme = &btheme->tui.wcol_menu;
- wt.draw = widget_menubut;
- break;
-
- case UI_WTYPE_PULLDOWN:
- wt.wcol_theme = &btheme->tui.wcol_pulldown;
- wt.draw = widget_pulldownbut;
- wt.state = widget_state_pulldown;
- break;
-
- /* in menus */
- case UI_WTYPE_MENU_ITEM:
- wt.wcol_theme = &btheme->tui.wcol_menu_item;
- wt.draw = widget_menu_itembut;
- wt.state = widget_state_menu_item;
- break;
-
- case UI_WTYPE_MENU_BACK:
- wt.wcol_theme = &btheme->tui.wcol_menu_back;
- wt.draw = widget_menu_back;
- break;
-
- /* specials */
- case UI_WTYPE_ICON:
- wt.custom = widget_icon_has_anim;
- break;
-
- case UI_WTYPE_ICON_LABEL:
- /* behave like regular labels (this is simply a label with an icon) */
- wt.state = widget_state_label;
- wt.custom = widget_icon_has_anim;
- break;
-
- case UI_WTYPE_SWATCH:
- wt.custom = widget_swatch;
- break;
-
- case UI_WTYPE_BOX:
- wt.custom = widget_box;
- wt.wcol_theme = &btheme->tui.wcol_box;
- break;
-
- case UI_WTYPE_RGB_PICKER:
- break;
-
- case UI_WTYPE_UNITVEC:
- wt.custom = widget_unitvec;
- break;
-
- case UI_WTYPE_SCROLL:
- wt.wcol_theme = &btheme->tui.wcol_scroll;
- wt.state = widget_state_nothing;
- wt.custom = widget_scroll;
- break;
-
- case UI_WTYPE_LISTITEM:
- wt.wcol_theme = &btheme->tui.wcol_list_item;
- wt.draw = widget_list_itembut;
- break;
-
- case UI_WTYPE_PROGRESSBAR:
- wt.wcol_theme = &btheme->tui.wcol_progress;
- wt.custom = widget_progressbar;
- break;
-
- case UI_WTYPE_MENU_ITEM_RADIAL:
- wt.wcol_theme = &btheme->tui.wcol_pie_menu;
- wt.custom = widget_menu_radial_itembut;
- wt.state = widget_state_pie_menu_item;
- break;
- }
-
- return &wt;
+ bTheme *btheme = UI_GetTheme();
+ static uiWidgetType wt;
+
+ /* defaults */
+ wt.wcol_theme = &btheme->tui.wcol_regular;
+ wt.wcol_state = &btheme->tui.wcol_state;
+ wt.state = widget_state;
+ wt.draw = widget_but;
+ wt.custom = NULL;
+ wt.text = widget_draw_text_icon;
+
+ switch (type) {
+ case UI_WTYPE_REGULAR:
+ break;
+
+ case UI_WTYPE_LABEL:
+ wt.draw = NULL;
+ wt.state = widget_state_label;
+ break;
+
+ case UI_WTYPE_TOGGLE:
+ wt.wcol_theme = &btheme->tui.wcol_toggle;
+ break;
+
+ case UI_WTYPE_CHECKBOX:
+ wt.wcol_theme = &btheme->tui.wcol_option;
+ wt.draw = widget_optionbut;
+ break;
+
+ case UI_WTYPE_RADIO:
+ wt.wcol_theme = &btheme->tui.wcol_radio;
+ wt.draw = widget_radiobut;
+ break;
+
+ case UI_WTYPE_NUMBER:
+ wt.wcol_theme = &btheme->tui.wcol_num;
+ wt.draw = widget_numbut;
+ break;
+
+ case UI_WTYPE_SLIDER:
+ wt.wcol_theme = &btheme->tui.wcol_numslider;
+ wt.custom = widget_numslider;
+ wt.state = widget_state_numslider;
+ break;
+
+ case UI_WTYPE_EXEC:
+ wt.wcol_theme = &btheme->tui.wcol_tool;
+ wt.draw = widget_roundbut_exec;
+ break;
+
+ case UI_WTYPE_TOOLBAR_ITEM:
+ wt.wcol_theme = &btheme->tui.wcol_toolbar_item;
+ wt.draw = widget_roundbut_exec;
+ break;
+
+ case UI_WTYPE_TAB:
+ wt.wcol_theme = &btheme->tui.wcol_tab;
+ wt.draw = widget_tab;
+ break;
+
+ case UI_WTYPE_TOOLTIP:
+ wt.wcol_theme = &btheme->tui.wcol_tooltip;
+ wt.draw = widget_menu_back;
+ break;
+
+ /* strings */
+ case UI_WTYPE_NAME:
+ wt.wcol_theme = &btheme->tui.wcol_text;
+ wt.draw = widget_textbut;
+ break;
+
+ case UI_WTYPE_NAME_LINK:
+ break;
+
+ case UI_WTYPE_POINTER_LINK:
+ break;
+
+ case UI_WTYPE_FILENAME:
+ break;
+
+ /* start menus */
+ case UI_WTYPE_MENU_RADIO:
+ wt.wcol_theme = &btheme->tui.wcol_menu;
+ wt.draw = widget_menubut;
+ break;
+
+ case UI_WTYPE_MENU_ICON_RADIO:
+ case UI_WTYPE_MENU_NODE_LINK:
+ wt.wcol_theme = &btheme->tui.wcol_menu;
+ wt.draw = widget_menuiconbut;
+ break;
+
+ case UI_WTYPE_MENU_POINTER_LINK:
+ wt.wcol_theme = &btheme->tui.wcol_menu;
+ wt.draw = widget_menubut;
+ break;
+
+ case UI_WTYPE_PULLDOWN:
+ wt.wcol_theme = &btheme->tui.wcol_pulldown;
+ wt.draw = widget_pulldownbut;
+ wt.state = widget_state_pulldown;
+ break;
+
+ /* in menus */
+ case UI_WTYPE_MENU_ITEM:
+ wt.wcol_theme = &btheme->tui.wcol_menu_item;
+ wt.draw = widget_menu_itembut;
+ wt.state = widget_state_menu_item;
+ break;
+
+ case UI_WTYPE_MENU_BACK:
+ wt.wcol_theme = &btheme->tui.wcol_menu_back;
+ wt.draw = widget_menu_back;
+ break;
+
+ /* specials */
+ case UI_WTYPE_ICON:
+ wt.custom = widget_icon_has_anim;
+ break;
+
+ case UI_WTYPE_ICON_LABEL:
+ /* behave like regular labels (this is simply a label with an icon) */
+ wt.state = widget_state_label;
+ wt.custom = widget_icon_has_anim;
+ break;
+
+ case UI_WTYPE_SWATCH:
+ wt.custom = widget_swatch;
+ break;
+
+ case UI_WTYPE_BOX:
+ wt.custom = widget_box;
+ wt.wcol_theme = &btheme->tui.wcol_box;
+ break;
+
+ case UI_WTYPE_RGB_PICKER:
+ break;
+
+ case UI_WTYPE_UNITVEC:
+ wt.custom = widget_unitvec;
+ break;
+
+ case UI_WTYPE_SCROLL:
+ wt.wcol_theme = &btheme->tui.wcol_scroll;
+ wt.state = widget_state_nothing;
+ wt.custom = widget_scroll;
+ break;
+
+ case UI_WTYPE_LISTITEM:
+ wt.wcol_theme = &btheme->tui.wcol_list_item;
+ wt.draw = widget_list_itembut;
+ break;
+
+ case UI_WTYPE_PROGRESSBAR:
+ wt.wcol_theme = &btheme->tui.wcol_progress;
+ wt.custom = widget_progressbar;
+ break;
+
+ case UI_WTYPE_MENU_ITEM_RADIAL:
+ wt.wcol_theme = &btheme->tui.wcol_pie_menu;
+ wt.custom = widget_menu_radial_itembut;
+ wt.state = widget_state_pie_menu_item;
+ break;
+ }
+
+ return &wt;
}
-
static int widget_roundbox_set(uiBut *but, rcti *rect)
{
- int roundbox = UI_CNR_ALL;
-
- /* alignment */
- if ((but->drawflag & UI_BUT_ALIGN) && but->type != UI_BTYPE_PULLDOWN) {
-
- /* ui_popup_block_position has this correction too, keep in sync */
- if (but->drawflag & (UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_STITCH_TOP)) {
- rect->ymax += U.pixelsize;
- }
- if (but->drawflag & (UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_STITCH_LEFT)) {
- rect->xmin -= U.pixelsize;
- }
-
- switch (but->drawflag & UI_BUT_ALIGN) {
- case UI_BUT_ALIGN_TOP:
- roundbox = UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT;
- break;
- case UI_BUT_ALIGN_DOWN:
- roundbox = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
- break;
- case UI_BUT_ALIGN_LEFT:
- roundbox = UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT;
- break;
- case UI_BUT_ALIGN_RIGHT:
- roundbox = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT;
- break;
- case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT:
- roundbox = UI_CNR_TOP_LEFT;
- break;
- case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT:
- roundbox = UI_CNR_TOP_RIGHT;
- break;
- case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT:
- roundbox = UI_CNR_BOTTOM_LEFT;
- break;
- case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT:
- roundbox = UI_CNR_BOTTOM_RIGHT;
- break;
- default:
- roundbox = 0;
- break;
- }
- }
-
- /* align with open menu */
- if (but->active && (but->type != UI_BTYPE_POPOVER)) {
- int direction = ui_but_menu_direction(but);
-
- if (direction == UI_DIR_UP) { roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT); }
- else if (direction == UI_DIR_DOWN) { roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); }
- else if (direction == UI_DIR_LEFT) { roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); }
- else if (direction == UI_DIR_RIGHT) { roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); }
- }
-
- return roundbox;
+ int roundbox = UI_CNR_ALL;
+
+ /* alignment */
+ if ((but->drawflag & UI_BUT_ALIGN) && but->type != UI_BTYPE_PULLDOWN) {
+
+ /* ui_popup_block_position has this correction too, keep in sync */
+ if (but->drawflag & (UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_STITCH_TOP)) {
+ rect->ymax += U.pixelsize;
+ }
+ if (but->drawflag & (UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_STITCH_LEFT)) {
+ rect->xmin -= U.pixelsize;
+ }
+
+ switch (but->drawflag & UI_BUT_ALIGN) {
+ case UI_BUT_ALIGN_TOP:
+ roundbox = UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT;
+ break;
+ case UI_BUT_ALIGN_DOWN:
+ roundbox = UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT;
+ break;
+ case UI_BUT_ALIGN_LEFT:
+ roundbox = UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT;
+ break;
+ case UI_BUT_ALIGN_RIGHT:
+ roundbox = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT;
+ break;
+ case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_RIGHT:
+ roundbox = UI_CNR_TOP_LEFT;
+ break;
+ case UI_BUT_ALIGN_DOWN | UI_BUT_ALIGN_LEFT:
+ roundbox = UI_CNR_TOP_RIGHT;
+ break;
+ case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT:
+ roundbox = UI_CNR_BOTTOM_LEFT;
+ break;
+ case UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT:
+ roundbox = UI_CNR_BOTTOM_RIGHT;
+ break;
+ default:
+ roundbox = 0;
+ break;
+ }
+ }
+
+ /* align with open menu */
+ if (but->active && (but->type != UI_BTYPE_POPOVER)) {
+ int direction = ui_but_menu_direction(but);
+
+ if (direction == UI_DIR_UP) {
+ roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT);
+ }
+ else if (direction == UI_DIR_DOWN) {
+ roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT);
+ }
+ else if (direction == UI_DIR_LEFT) {
+ roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ }
+ else if (direction == UI_DIR_RIGHT) {
+ roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT);
+ }
+ }
+
+ return roundbox;
}
/* -------------------------------------------------------------------- */
@@ -4261,749 +4437,812 @@ static int widget_roundbox_set(uiBut *but, rcti *rect)
/* conversion from old to new buttons, so still messy */
void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rcti *rect)
{
- bTheme *btheme = UI_GetTheme();
- const ThemeUI *tui = &btheme->tui;
- const uiFontStyle *fstyle = &style->widget;
- uiWidgetType *wt = NULL;
+ bTheme *btheme = UI_GetTheme();
+ const ThemeUI *tui = &btheme->tui;
+ const uiFontStyle *fstyle = &style->widget;
+ uiWidgetType *wt = NULL;
#ifdef USE_UI_POPOVER_ONCE
- const rcti rect_orig = *rect;
+ const rcti rect_orig = *rect;
#endif
- /* handle menus separately */
- if (but->dt == UI_EMBOSS_PULLDOWN) {
- switch (but->type) {
- case UI_BTYPE_LABEL:
- widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect);
- break;
- case UI_BTYPE_SEPR_LINE:
- ui_draw_separator(rect, &tui->wcol_menu_item);
- break;
- default:
- wt = widget_type(UI_WTYPE_MENU_ITEM);
- break;
- }
- }
- else if (but->dt == UI_EMBOSS_NONE) {
- /* "nothing" */
- switch (but->type) {
- case UI_BTYPE_LABEL:
- wt = widget_type(UI_WTYPE_ICON_LABEL);
- break;
- default:
- wt = widget_type(UI_WTYPE_ICON);
- break;
- }
- }
- else if (but->dt == UI_EMBOSS_RADIAL) {
- wt = widget_type(UI_WTYPE_MENU_ITEM_RADIAL);
- }
- else {
- BLI_assert(but->dt == UI_EMBOSS);
-
- switch (but->type) {
- case UI_BTYPE_LABEL:
- wt = widget_type(UI_WTYPE_LABEL);
- fstyle = &style->widgetlabel;
- if (but->drawflag & UI_BUT_BOX_ITEM) {
- wt->wcol_theme = &tui->wcol_box;
- wt->state = widget_state;
- }
- else if (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) {
- wt->wcol_theme = &tui->wcol_menu_back;
- wt->state = widget_state;
- }
- break;
-
- case UI_BTYPE_SEPR:
- case UI_BTYPE_SEPR_LINE:
- case UI_BTYPE_SEPR_SPACER:
- break;
-
- case UI_BTYPE_BUT:
+ /* handle menus separately */
+ if (but->dt == UI_EMBOSS_PULLDOWN) {
+ switch (but->type) {
+ case UI_BTYPE_LABEL:
+ widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect);
+ break;
+ case UI_BTYPE_SEPR_LINE:
+ ui_draw_separator(rect, &tui->wcol_menu_item);
+ break;
+ default:
+ wt = widget_type(UI_WTYPE_MENU_ITEM);
+ break;
+ }
+ }
+ else if (but->dt == UI_EMBOSS_NONE) {
+ /* "nothing" */
+ switch (but->type) {
+ case UI_BTYPE_LABEL:
+ wt = widget_type(UI_WTYPE_ICON_LABEL);
+ break;
+ default:
+ wt = widget_type(UI_WTYPE_ICON);
+ break;
+ }
+ }
+ else if (but->dt == UI_EMBOSS_RADIAL) {
+ wt = widget_type(UI_WTYPE_MENU_ITEM_RADIAL);
+ }
+ else {
+ BLI_assert(but->dt == UI_EMBOSS);
+
+ switch (but->type) {
+ case UI_BTYPE_LABEL:
+ wt = widget_type(UI_WTYPE_LABEL);
+ fstyle = &style->widgetlabel;
+ if (but->drawflag & UI_BUT_BOX_ITEM) {
+ wt->wcol_theme = &tui->wcol_box;
+ wt->state = widget_state;
+ }
+ else if (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) {
+ wt->wcol_theme = &tui->wcol_menu_back;
+ wt->state = widget_state;
+ }
+ break;
+
+ case UI_BTYPE_SEPR:
+ case UI_BTYPE_SEPR_LINE:
+ case UI_BTYPE_SEPR_SPACER:
+ break;
+
+ case UI_BTYPE_BUT:
#ifdef USE_UI_TOOLBAR_HACK
- if (UI_but_is_tool(but)) {
- wt = widget_type(UI_WTYPE_TOOLBAR_ITEM);
- }
- else {
- wt = widget_type(UI_WTYPE_EXEC);
- }
+ if (UI_but_is_tool(but)) {
+ wt = widget_type(UI_WTYPE_TOOLBAR_ITEM);
+ }
+ else {
+ wt = widget_type(UI_WTYPE_EXEC);
+ }
#else
- wt = widget_type(UI_WTYPE_EXEC);
+ wt = widget_type(UI_WTYPE_EXEC);
#endif
- break;
-
- case UI_BTYPE_NUM:
- wt = widget_type(UI_WTYPE_NUMBER);
- break;
-
- case UI_BTYPE_NUM_SLIDER:
- wt = widget_type(UI_WTYPE_SLIDER);
- break;
-
- case UI_BTYPE_ROW:
- wt = widget_type(UI_WTYPE_RADIO);
- break;
-
- case UI_BTYPE_LISTROW:
- wt = widget_type(UI_WTYPE_LISTITEM);
- break;
-
- case UI_BTYPE_TEXT:
- wt = widget_type(UI_WTYPE_NAME);
- break;
-
- case UI_BTYPE_SEARCH_MENU:
- wt = widget_type(UI_WTYPE_NAME);
- if (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) {
- wt->wcol_theme = &btheme->tui.wcol_menu_back;
- }
- break;
-
- case UI_BTYPE_TAB:
- wt = widget_type(UI_WTYPE_TAB);
- break;
-
- case UI_BTYPE_BUT_TOGGLE:
- case UI_BTYPE_TOGGLE:
- case UI_BTYPE_TOGGLE_N:
- wt = widget_type(UI_WTYPE_TOGGLE);
- break;
-
- case UI_BTYPE_CHECKBOX:
- case UI_BTYPE_CHECKBOX_N:
- if (!(but->flag & UI_HAS_ICON)) {
- wt = widget_type(UI_WTYPE_CHECKBOX);
- if ((but->drawflag & (UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT)) == 0) {
- but->drawflag |= UI_BUT_TEXT_LEFT;
- }
- }
- else {
- wt = widget_type(UI_WTYPE_TOGGLE);
- }
-
- /* option buttons have strings outside, on menus use different colors */
- if (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) {
- wt->state = widget_state_option_menu;
- }
- break;
-
- case UI_BTYPE_MENU:
- case UI_BTYPE_BLOCK:
- case UI_BTYPE_POPOVER:
- if (but->flag & UI_BUT_NODE_LINK) {
- /* new node-link button, not active yet XXX */
- wt = widget_type(UI_WTYPE_MENU_NODE_LINK);
- }
- else {
- /* with menu arrows */
-
- /* we could use a flag for this, but for now just check size,
- * add updown arrows if there is room. */
- if ((!but->str[0] && but->icon && (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect) + 2)) ||
- /* disable for brushes also */
- (but->flag & UI_BUT_ICON_PREVIEW))
- {
- /* no arrows */
- wt = widget_type(UI_WTYPE_MENU_ICON_RADIO);
- }
- else {
- wt = widget_type(UI_WTYPE_MENU_RADIO);
- }
- }
- break;
-
- case UI_BTYPE_PULLDOWN:
- wt = widget_type(UI_WTYPE_PULLDOWN);
- break;
-
- case UI_BTYPE_BUT_MENU:
- wt = widget_type(UI_WTYPE_MENU_ITEM);
- break;
-
- case UI_BTYPE_COLOR:
- wt = widget_type(UI_WTYPE_SWATCH);
- break;
-
- case UI_BTYPE_ROUNDBOX:
- case UI_BTYPE_LISTBOX:
- wt = widget_type(UI_WTYPE_BOX);
- break;
-
- case UI_BTYPE_EXTRA:
- widget_draw_extra_mask(C, but, widget_type(UI_WTYPE_BOX), rect);
- break;
-
- case UI_BTYPE_HSVCUBE:
- if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) {
- /* vertical V slider, uses new widget draw now */
- ui_draw_but_HSV_v(but, rect);
- }
- else { /* other HSV pickers... */
- ui_draw_but_HSVCUBE(but, rect);
- }
- break;
-
- case UI_BTYPE_HSVCIRCLE:
- ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_COLORBAND:
- ui_draw_but_COLORBAND(but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_UNITVEC:
- wt = widget_type(UI_WTYPE_UNITVEC);
- break;
-
- case UI_BTYPE_IMAGE:
- ui_draw_but_IMAGE(ar, but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_HISTOGRAM:
- ui_draw_but_HISTOGRAM(ar, but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_WAVEFORM:
- ui_draw_but_WAVEFORM(ar, but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_VECTORSCOPE:
- ui_draw_but_VECTORSCOPE(ar, but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_CURVE:
- ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_PROGRESS_BAR:
- wt = widget_type(UI_WTYPE_PROGRESSBAR);
- fstyle = &style->widgetlabel;
- break;
-
- case UI_BTYPE_SCROLL:
- wt = widget_type(UI_WTYPE_SCROLL);
- break;
-
- case UI_BTYPE_GRIP:
- wt = widget_type(UI_WTYPE_ICON);
- break;
-
- case UI_BTYPE_TRACK_PREVIEW:
- ui_draw_but_TRACKPREVIEW(ar, but, &tui->wcol_regular, rect);
- break;
-
- case UI_BTYPE_NODE_SOCKET:
- ui_draw_but_NODESOCKET(ar, but, &tui->wcol_regular, rect);
- break;
-
- default:
- wt = widget_type(UI_WTYPE_REGULAR);
- break;
- }
- }
-
- if (wt) {
- //rcti disablerect = *rect; /* rect gets clipped smaller for text */
- int roundboxalign, state, drawflag;
- bool disabled = false;
-
- roundboxalign = widget_roundbox_set(but, rect);
-
- /* Mask out flags re-used for local state. */
- state = but->flag & ~UI_STATE_FLAGS_ALL;
- drawflag = but->drawflag;
-
- if (state & UI_SELECT_DRAW) {
- state |= UI_SELECT;
- }
-
- if ((but->editstr) ||
- (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_but_drag_multi_edit_get(but)))
- {
- state |= UI_STATE_TEXT_INPUT;
- }
-
- if (but->hold_func) {
- state |= UI_STATE_HOLD_ACTION;
- }
-
- if (state & UI_ACTIVE) {
- if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
- state |= UI_STATE_ACTIVE_LEFT;
- }
- else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
- state |= UI_STATE_ACTIVE_RIGHT;
- }
- }
-
- if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- if (but->dt != UI_EMBOSS_PULLDOWN) {
- disabled = true;
- }
- }
-
- if (drawflag & UI_BUT_TEXT_RIGHT) {
- state |= UI_STATE_TEXT_BEFORE_WIDGET;
- }
-
- if (disabled) {
- ui_widget_color_disabled(wt);
- }
-
- wt->state(wt, state, drawflag);
- if (wt->custom) {
- wt->custom(but, &wt->wcol, rect, state, roundboxalign);
- }
- else if (wt->draw) {
- wt->draw(&wt->wcol, rect, state, roundboxalign);
- }
-
- if (disabled) {
- GPU_blend(true);
- }
-
- bool show_semi_highlight = false;
+ break;
+
+ case UI_BTYPE_NUM:
+ wt = widget_type(UI_WTYPE_NUMBER);
+ break;
+
+ case UI_BTYPE_NUM_SLIDER:
+ wt = widget_type(UI_WTYPE_SLIDER);
+ break;
+
+ case UI_BTYPE_ROW:
+ wt = widget_type(UI_WTYPE_RADIO);
+ break;
+
+ case UI_BTYPE_LISTROW:
+ wt = widget_type(UI_WTYPE_LISTITEM);
+ break;
+
+ case UI_BTYPE_TEXT:
+ wt = widget_type(UI_WTYPE_NAME);
+ break;
+
+ case UI_BTYPE_SEARCH_MENU:
+ wt = widget_type(UI_WTYPE_NAME);
+ if (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) {
+ wt->wcol_theme = &btheme->tui.wcol_menu_back;
+ }
+ break;
+
+ case UI_BTYPE_TAB:
+ wt = widget_type(UI_WTYPE_TAB);
+ break;
+
+ case UI_BTYPE_BUT_TOGGLE:
+ case UI_BTYPE_TOGGLE:
+ case UI_BTYPE_TOGGLE_N:
+ wt = widget_type(UI_WTYPE_TOGGLE);
+ break;
+
+ case UI_BTYPE_CHECKBOX:
+ case UI_BTYPE_CHECKBOX_N:
+ if (!(but->flag & UI_HAS_ICON)) {
+ wt = widget_type(UI_WTYPE_CHECKBOX);
+ if ((but->drawflag & (UI_BUT_TEXT_LEFT | UI_BUT_TEXT_RIGHT)) == 0) {
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ }
+ }
+ else {
+ wt = widget_type(UI_WTYPE_TOGGLE);
+ }
+
+ /* option buttons have strings outside, on menus use different colors */
+ if (but->block->theme_style == UI_BLOCK_THEME_STYLE_POPUP) {
+ wt->state = widget_state_option_menu;
+ }
+ break;
+
+ case UI_BTYPE_MENU:
+ case UI_BTYPE_BLOCK:
+ case UI_BTYPE_POPOVER:
+ if (but->flag & UI_BUT_NODE_LINK) {
+ /* new node-link button, not active yet XXX */
+ wt = widget_type(UI_WTYPE_MENU_NODE_LINK);
+ }
+ else {
+ /* with menu arrows */
+
+ /* we could use a flag for this, but for now just check size,
+ * add updown arrows if there is room. */
+ if ((!but->str[0] && but->icon && (BLI_rcti_size_x(rect) < BLI_rcti_size_y(rect) + 2)) ||
+ /* disable for brushes also */
+ (but->flag & UI_BUT_ICON_PREVIEW)) {
+ /* no arrows */
+ wt = widget_type(UI_WTYPE_MENU_ICON_RADIO);
+ }
+ else {
+ wt = widget_type(UI_WTYPE_MENU_RADIO);
+ }
+ }
+ break;
+
+ case UI_BTYPE_PULLDOWN:
+ wt = widget_type(UI_WTYPE_PULLDOWN);
+ break;
+
+ case UI_BTYPE_BUT_MENU:
+ wt = widget_type(UI_WTYPE_MENU_ITEM);
+ break;
+
+ case UI_BTYPE_COLOR:
+ wt = widget_type(UI_WTYPE_SWATCH);
+ break;
+
+ case UI_BTYPE_ROUNDBOX:
+ case UI_BTYPE_LISTBOX:
+ wt = widget_type(UI_WTYPE_BOX);
+ break;
+
+ case UI_BTYPE_EXTRA:
+ widget_draw_extra_mask(C, but, widget_type(UI_WTYPE_BOX), rect);
+ break;
+
+ case UI_BTYPE_HSVCUBE:
+ if (ELEM(but->a1, UI_GRAD_V_ALT, UI_GRAD_L_ALT)) {
+ /* vertical V slider, uses new widget draw now */
+ ui_draw_but_HSV_v(but, rect);
+ }
+ else { /* other HSV pickers... */
+ ui_draw_but_HSVCUBE(but, rect);
+ }
+ break;
+
+ case UI_BTYPE_HSVCIRCLE:
+ ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_COLORBAND:
+ ui_draw_but_COLORBAND(but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_UNITVEC:
+ wt = widget_type(UI_WTYPE_UNITVEC);
+ break;
+
+ case UI_BTYPE_IMAGE:
+ ui_draw_but_IMAGE(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_HISTOGRAM:
+ ui_draw_but_HISTOGRAM(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_WAVEFORM:
+ ui_draw_but_WAVEFORM(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_VECTORSCOPE:
+ ui_draw_but_VECTORSCOPE(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_CURVE:
+ ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_PROGRESS_BAR:
+ wt = widget_type(UI_WTYPE_PROGRESSBAR);
+ fstyle = &style->widgetlabel;
+ break;
+
+ case UI_BTYPE_SCROLL:
+ wt = widget_type(UI_WTYPE_SCROLL);
+ break;
+
+ case UI_BTYPE_GRIP:
+ wt = widget_type(UI_WTYPE_ICON);
+ break;
+
+ case UI_BTYPE_TRACK_PREVIEW:
+ ui_draw_but_TRACKPREVIEW(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ case UI_BTYPE_NODE_SOCKET:
+ ui_draw_but_NODESOCKET(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ default:
+ wt = widget_type(UI_WTYPE_REGULAR);
+ break;
+ }
+ }
+
+ if (wt) {
+ //rcti disablerect = *rect; /* rect gets clipped smaller for text */
+ int roundboxalign, state, drawflag;
+ bool disabled = false;
+
+ roundboxalign = widget_roundbox_set(but, rect);
+
+ /* Mask out flags re-used for local state. */
+ state = but->flag & ~UI_STATE_FLAGS_ALL;
+ drawflag = but->drawflag;
+
+ if (state & UI_SELECT_DRAW) {
+ state |= UI_SELECT;
+ }
+
+ if ((but->editstr) ||
+ (UNLIKELY(but->flag & UI_BUT_DRAG_MULTI) && ui_but_drag_multi_edit_get(but))) {
+ state |= UI_STATE_TEXT_INPUT;
+ }
+
+ if (but->hold_func) {
+ state |= UI_STATE_HOLD_ACTION;
+ }
+
+ if (state & UI_ACTIVE) {
+ if (but->drawflag & UI_BUT_ACTIVE_LEFT) {
+ state |= UI_STATE_ACTIVE_LEFT;
+ }
+ else if (but->drawflag & UI_BUT_ACTIVE_RIGHT) {
+ state |= UI_STATE_ACTIVE_RIGHT;
+ }
+ }
+
+ if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ if (but->dt != UI_EMBOSS_PULLDOWN) {
+ disabled = true;
+ }
+ }
+
+ if (drawflag & UI_BUT_TEXT_RIGHT) {
+ state |= UI_STATE_TEXT_BEFORE_WIDGET;
+ }
+
+ if (disabled) {
+ ui_widget_color_disabled(wt);
+ }
+
+ wt->state(wt, state, drawflag);
+ if (wt->custom) {
+ wt->custom(but, &wt->wcol, rect, state, roundboxalign);
+ }
+ else if (wt->draw) {
+ wt->draw(&wt->wcol, rect, state, roundboxalign);
+ }
+
+ if (disabled) {
+ GPU_blend(true);
+ }
+
+ bool show_semi_highlight = false;
#ifdef USE_UI_POPOVER_ONCE
- if (but->block->flag & UI_BLOCK_POPOVER_ONCE) {
- if ((state & UI_ACTIVE) && ui_but_is_popover_once_compat(but)) {
- show_semi_highlight = true;
- }
- }
+ if (but->block->flag & UI_BLOCK_POPOVER_ONCE) {
+ if ((state & UI_ACTIVE) && ui_but_is_popover_once_compat(but)) {
+ show_semi_highlight = true;
+ }
+ }
#endif
- if (but->flag & UI_BUT_ACTIVE_DEFAULT) {
- show_semi_highlight = true;
- }
-
- if (show_semi_highlight) {
- uiWidgetType wt_back = *wt;
- uiWidgetType *wt_temp = widget_type(UI_WTYPE_MENU_ITEM);
- wt_temp->state(wt_temp, state, drawflag);
- copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
- wt->wcol.inner[3] = 128;
- wt->wcol.roundness = 0.5f;
- ui_draw_roundbox(
- &rect_orig,
- 0.25f * min_ff(BLI_rcti_size_x(&rect_orig), BLI_rcti_size_y(&rect_orig)),
- &wt_temp->wcol);
- *wt = wt_back;
- }
-
- wt->text(fstyle, &wt->wcol, but, rect);
- if (disabled) {
- GPU_blend(false);
- }
-
-// if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
-// if (but->dt != UI_EMBOSS_PULLDOWN) {
-// widget_disabled(&disablerect);
-// }
-// }
- }
+ if (but->flag & UI_BUT_ACTIVE_DEFAULT) {
+ show_semi_highlight = true;
+ }
+
+ if (show_semi_highlight) {
+ uiWidgetType wt_back = *wt;
+ uiWidgetType *wt_temp = widget_type(UI_WTYPE_MENU_ITEM);
+ wt_temp->state(wt_temp, state, drawflag);
+ copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel);
+ wt->wcol.inner[3] = 128;
+ wt->wcol.roundness = 0.5f;
+ ui_draw_roundbox(&rect_orig,
+ 0.25f * min_ff(BLI_rcti_size_x(&rect_orig), BLI_rcti_size_y(&rect_orig)),
+ &wt_temp->wcol);
+ *wt = wt_back;
+ }
+
+ wt->text(fstyle, &wt->wcol, but, rect);
+ if (disabled) {
+ GPU_blend(false);
+ }
+
+ // if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
+ // if (but->dt != UI_EMBOSS_PULLDOWN) {
+ // widget_disabled(&disablerect);
+ // }
+ // }
+ }
}
static void ui_draw_clip_tri(uiBlock *block, rcti *rect, uiWidgetType *wt)
{
- if (block) {
- float draw_color[4];
- uchar *color = (uchar *)wt->wcol.text;
-
- draw_color[0] = ((float)color[0]) / 255.0f;
- draw_color[1] = ((float)color[1]) / 255.0f;
- draw_color[2] = ((float)color[2]) / 255.0f;
- draw_color[3] = 1.0f;
-
- if (block->flag & UI_BLOCK_CLIPTOP) {
- /* XXX no scaling for UI here yet */
- UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymax - 8, 't', draw_color);
- }
- if (block->flag & UI_BLOCK_CLIPBOTTOM) {
- /* XXX no scaling for UI here yet */
- UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v', draw_color);
- }
- }
+ if (block) {
+ float draw_color[4];
+ uchar *color = (uchar *)wt->wcol.text;
+
+ draw_color[0] = ((float)color[0]) / 255.0f;
+ draw_color[1] = ((float)color[1]) / 255.0f;
+ draw_color[2] = ((float)color[2]) / 255.0f;
+ draw_color[3] = 1.0f;
+
+ if (block->flag & UI_BLOCK_CLIPTOP) {
+ /* XXX no scaling for UI here yet */
+ UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymax - 8, 't', draw_color);
+ }
+ if (block->flag & UI_BLOCK_CLIPBOTTOM) {
+ /* XXX no scaling for UI here yet */
+ UI_draw_icon_tri(BLI_rcti_cent_x(rect), rect->ymin + 10, 'v', draw_color);
+ }
+ }
}
void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
{
- uiWidgetType *wt = widget_type(UI_WTYPE_MENU_BACK);
+ uiWidgetType *wt = widget_type(UI_WTYPE_MENU_BACK);
- wt->state(wt, 0, 0);
- if (block) {
- wt->draw(&wt->wcol, rect, block->flag, block->direction);
- }
- else {
- wt->draw(&wt->wcol, rect, 0, 0);
- }
+ wt->state(wt, 0, 0);
+ if (block) {
+ wt->draw(&wt->wcol, rect, block->flag, block->direction);
+ }
+ else {
+ wt->draw(&wt->wcol, rect, 0, 0);
+ }
- ui_draw_clip_tri(block, rect, wt);
+ ui_draw_clip_tri(block, rect, wt);
}
/**
* Similar to 'widget_menu_back', however we can't use the widget preset system
* because we need to pass in the original location so we know where to show the arrow.
*/
-static void ui_draw_popover_back_impl(
- const uiWidgetColors *wcol, rcti *rect, int direction, const float unit_size,
- const float mval_origin[2])
+static void ui_draw_popover_back_impl(const uiWidgetColors *wcol,
+ rcti *rect,
+ int direction,
+ const float unit_size,
+ const float mval_origin[2])
{
- /* tsk, this isn't nice. */
- const float unit_half = unit_size / 2;
- const float cent_x = mval_origin ? mval_origin[0] : BLI_rcti_cent_x(rect);
- rect->ymax -= unit_half;
- rect->ymin += unit_half;
-
- GPU_blend(true);
-
- /* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */
- {
- uiWidgetBase wtb;
- widget_init(&wtb);
-
- const int roundboxalign = UI_CNR_ALL;
- widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit);
-
- round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit);
- wtb.draw_emboss = false;
- widgetbase_draw(&wtb, wcol);
- }
-
- /* Draw popover arrow (top/bottom) */
- if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) {
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4ubv((uchar *)wcol->inner);
- GPU_blend(true);
- immBegin(GPU_PRIM_TRIS, 3);
- if (direction == UI_DIR_DOWN) {
- const float y = rect->ymax;
- immVertex2f(pos, cent_x - unit_half, y);
- immVertex2f(pos, cent_x + unit_half, y);
- immVertex2f(pos, cent_x, y + unit_half);
- }
- else {
- const float y = rect->ymin;
- immVertex2f(pos, cent_x - unit_half, y);
- immVertex2f(pos, cent_x + unit_half, y);
- immVertex2f(pos, cent_x, y - unit_half);
- }
- immEnd();
- immUnbindProgram();
- }
-
- GPU_blend(false);
+ /* tsk, this isn't nice. */
+ const float unit_half = unit_size / 2;
+ const float cent_x = mval_origin ? mval_origin[0] : BLI_rcti_cent_x(rect);
+ rect->ymax -= unit_half;
+ rect->ymin += unit_half;
+
+ GPU_blend(true);
+
+ /* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */
+ {
+ uiWidgetBase wtb;
+ widget_init(&wtb);
+
+ const int roundboxalign = UI_CNR_ALL;
+ widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit);
+
+ round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit);
+ wtb.draw_emboss = false;
+ widgetbase_draw(&wtb, wcol);
+ }
+
+ /* Draw popover arrow (top/bottom) */
+ if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) {
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv((uchar *)wcol->inner);
+ GPU_blend(true);
+ immBegin(GPU_PRIM_TRIS, 3);
+ if (direction == UI_DIR_DOWN) {
+ const float y = rect->ymax;
+ immVertex2f(pos, cent_x - unit_half, y);
+ immVertex2f(pos, cent_x + unit_half, y);
+ immVertex2f(pos, cent_x, y + unit_half);
+ }
+ else {
+ const float y = rect->ymin;
+ immVertex2f(pos, cent_x - unit_half, y);
+ immVertex2f(pos, cent_x + unit_half, y);
+ immVertex2f(pos, cent_x, y - unit_half);
+ }
+ immEnd();
+ immUnbindProgram();
+ }
+
+ GPU_blend(false);
}
void ui_draw_popover_back(ARegion *ar, uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
{
- uiWidgetType *wt = widget_type(UI_WTYPE_MENU_BACK);
-
- if (block) {
- float mval_origin[2] = {UNPACK2(block->bounds_offset)};
- ui_window_to_block_fl(ar, block, &mval_origin[0], &mval_origin[1]);
- ui_draw_popover_back_impl(wt->wcol_theme, rect, block->direction, U.widget_unit / block->aspect, mval_origin);
- }
- else {
- wt->state(wt, 0, 0);
- wt->draw(&wt->wcol, rect, 0, 0);
- }
-
- ui_draw_clip_tri(block, rect, wt);
+ uiWidgetType *wt = widget_type(UI_WTYPE_MENU_BACK);
+
+ if (block) {
+ float mval_origin[2] = {UNPACK2(block->bounds_offset)};
+ ui_window_to_block_fl(ar, block, &mval_origin[0], &mval_origin[1]);
+ ui_draw_popover_back_impl(
+ wt->wcol_theme, rect, block->direction, U.widget_unit / block->aspect, mval_origin);
+ }
+ else {
+ wt->state(wt, 0, 0);
+ wt->draw(&wt->wcol, rect, 0, 0);
+ }
+
+ ui_draw_clip_tri(block, rect, wt);
}
-static void draw_disk_shaded(
- float start, float angle,
- float radius_int, float radius_ext, int subd,
- const char col1[4], const char col2[4],
- bool shaded)
+static void draw_disk_shaded(float start,
+ float angle,
+ float radius_int,
+ float radius_ext,
+ int subd,
+ const char col1[4],
+ const char col2[4],
+ bool shaded)
{
- const float radius_ext_scale = (0.5f / radius_ext); /* 1 / (2 * radius_ext) */
- int i;
-
- float s, c;
- float y1, y2;
- float fac;
- uchar r_col[4];
- uint pos, col;
-
- GPUVertFormat *format = immVertexFormat();
- pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- if (shaded) {
- col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
- }
- else {
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4ubv((uchar *)col1);
- }
-
- immBegin(GPU_PRIM_TRI_STRIP, subd * 2);
- for (i = 0; i < subd; i++) {
- float a;
-
- a = start + ((i) / (float)(subd - 1)) * angle;
- s = sinf(a);
- c = cosf(a);
- y1 = s * radius_int;
- y2 = s * radius_ext;
-
- if (shaded) {
- fac = (y1 + radius_ext) * radius_ext_scale;
- round_box_shade_col4_r(r_col, col1, col2, fac);
- immAttr4ubv(col, r_col);
- }
- immVertex2f(pos, c * radius_int, s * radius_int);
-
- if (shaded) {
- fac = (y2 + radius_ext) * radius_ext_scale;
- round_box_shade_col4_r(r_col, col1, col2, fac);
- immAttr4ubv(col, r_col);
- }
- immVertex2f(pos, c * radius_ext, s * radius_ext);
- }
- immEnd();
-
- immUnbindProgram();
+ const float radius_ext_scale = (0.5f / radius_ext); /* 1 / (2 * radius_ext) */
+ int i;
+
+ float s, c;
+ float y1, y2;
+ float fac;
+ uchar r_col[4];
+ uint pos, col;
+
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ if (shaded) {
+ col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
+ }
+ else {
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv((uchar *)col1);
+ }
+
+ immBegin(GPU_PRIM_TRI_STRIP, subd * 2);
+ for (i = 0; i < subd; i++) {
+ float a;
+
+ a = start + ((i) / (float)(subd - 1)) * angle;
+ s = sinf(a);
+ c = cosf(a);
+ y1 = s * radius_int;
+ y2 = s * radius_ext;
+
+ if (shaded) {
+ fac = (y1 + radius_ext) * radius_ext_scale;
+ round_box_shade_col4_r(r_col, col1, col2, fac);
+ immAttr4ubv(col, r_col);
+ }
+ immVertex2f(pos, c * radius_int, s * radius_int);
+
+ if (shaded) {
+ fac = (y2 + radius_ext) * radius_ext_scale;
+ round_box_shade_col4_r(r_col, col1, col2, fac);
+ immAttr4ubv(col, r_col);
+ }
+ immVertex2f(pos, c * radius_ext, s * radius_ext);
+ }
+ immEnd();
+
+ immUnbindProgram();
}
void ui_draw_pie_center(uiBlock *block)
{
- bTheme *btheme = UI_GetTheme();
- float cx = block->pie_data.pie_center_spawned[0];
- float cy = block->pie_data.pie_center_spawned[1];
-
- float *pie_dir = block->pie_data.pie_dir;
-
- float pie_radius_internal = U.dpi_fac * U.pie_menu_threshold;
- float pie_radius_external = U.dpi_fac * (U.pie_menu_threshold + 7.0f);
-
- int subd = 40;
-
- float angle = atan2f(pie_dir[1], pie_dir[0]);
- float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4;
-
- GPU_matrix_push();
- GPU_matrix_translate_2f(cx, cy);
-
- GPU_blend(true);
- if (btheme->tui.wcol_pie_menu.shaded) {
- char col1[4], col2[4];
- shadecolors4(col1, col2, btheme->tui.wcol_pie_menu.inner, btheme->tui.wcol_pie_menu.shadetop, btheme->tui.wcol_pie_menu.shadedown);
- draw_disk_shaded(0.0f, (float)(M_PI * 2.0), pie_radius_internal, pie_radius_external, subd, col1, col2, true);
- }
- else {
- draw_disk_shaded(0.0f, (float)(M_PI * 2.0), pie_radius_internal, pie_radius_external, subd, btheme->tui.wcol_pie_menu.inner, NULL, false);
- }
-
- if (!(block->pie_data.flags & UI_PIE_INVALID_DIR)) {
- if (btheme->tui.wcol_pie_menu.shaded) {
- char col1[4], col2[4];
- shadecolors4(col1, col2, btheme->tui.wcol_pie_menu.inner_sel, btheme->tui.wcol_pie_menu.shadetop, btheme->tui.wcol_pie_menu.shadedown);
- draw_disk_shaded(angle - range / 2.0f, range, pie_radius_internal, pie_radius_external, subd, col1, col2, true);
- }
- else {
- draw_disk_shaded(angle - range / 2.0f, range, pie_radius_internal, pie_radius_external, subd, btheme->tui.wcol_pie_menu.inner_sel, NULL, false);
- }
- }
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor4ubv((uchar *)btheme->tui.wcol_pie_menu.outline);
-
- imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, pie_radius_internal, subd);
- imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, pie_radius_external, subd);
-
- immUnbindProgram();
-
- if (U.pie_menu_confirm > 0 && !(block->pie_data.flags & (UI_PIE_INVALID_DIR | UI_PIE_CLICK_STYLE))) {
- float pie_confirm_radius = U.dpi_fac * (pie_radius_internal + U.pie_menu_confirm);
- float pie_confirm_external = U.dpi_fac * (pie_radius_internal + U.pie_menu_confirm + 7.0f);
-
- const char col[4] = {UNPACK3(btheme->tui.wcol_pie_menu.text_sel), 64};
- draw_disk_shaded(angle - range / 2.0f, range, pie_confirm_radius, pie_confirm_external, subd, col, NULL, false);
- }
-
- GPU_blend(false);
- GPU_matrix_pop();
+ bTheme *btheme = UI_GetTheme();
+ float cx = block->pie_data.pie_center_spawned[0];
+ float cy = block->pie_data.pie_center_spawned[1];
+
+ float *pie_dir = block->pie_data.pie_dir;
+
+ float pie_radius_internal = U.dpi_fac * U.pie_menu_threshold;
+ float pie_radius_external = U.dpi_fac * (U.pie_menu_threshold + 7.0f);
+
+ int subd = 40;
+
+ float angle = atan2f(pie_dir[1], pie_dir[0]);
+ float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4;
+
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(cx, cy);
+
+ GPU_blend(true);
+ if (btheme->tui.wcol_pie_menu.shaded) {
+ char col1[4], col2[4];
+ shadecolors4(col1,
+ col2,
+ btheme->tui.wcol_pie_menu.inner,
+ btheme->tui.wcol_pie_menu.shadetop,
+ btheme->tui.wcol_pie_menu.shadedown);
+ draw_disk_shaded(0.0f,
+ (float)(M_PI * 2.0),
+ pie_radius_internal,
+ pie_radius_external,
+ subd,
+ col1,
+ col2,
+ true);
+ }
+ else {
+ draw_disk_shaded(0.0f,
+ (float)(M_PI * 2.0),
+ pie_radius_internal,
+ pie_radius_external,
+ subd,
+ btheme->tui.wcol_pie_menu.inner,
+ NULL,
+ false);
+ }
+
+ if (!(block->pie_data.flags & UI_PIE_INVALID_DIR)) {
+ if (btheme->tui.wcol_pie_menu.shaded) {
+ char col1[4], col2[4];
+ shadecolors4(col1,
+ col2,
+ btheme->tui.wcol_pie_menu.inner_sel,
+ btheme->tui.wcol_pie_menu.shadetop,
+ btheme->tui.wcol_pie_menu.shadedown);
+ draw_disk_shaded(angle - range / 2.0f,
+ range,
+ pie_radius_internal,
+ pie_radius_external,
+ subd,
+ col1,
+ col2,
+ true);
+ }
+ else {
+ draw_disk_shaded(angle - range / 2.0f,
+ range,
+ pie_radius_internal,
+ pie_radius_external,
+ subd,
+ btheme->tui.wcol_pie_menu.inner_sel,
+ NULL,
+ false);
+ }
+ }
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4ubv((uchar *)btheme->tui.wcol_pie_menu.outline);
+
+ imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, pie_radius_internal, subd);
+ imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, pie_radius_external, subd);
+
+ immUnbindProgram();
+
+ if (U.pie_menu_confirm > 0 &&
+ !(block->pie_data.flags & (UI_PIE_INVALID_DIR | UI_PIE_CLICK_STYLE))) {
+ float pie_confirm_radius = U.dpi_fac * (pie_radius_internal + U.pie_menu_confirm);
+ float pie_confirm_external = U.dpi_fac * (pie_radius_internal + U.pie_menu_confirm + 7.0f);
+
+ const char col[4] = {UNPACK3(btheme->tui.wcol_pie_menu.text_sel), 64};
+ draw_disk_shaded(angle - range / 2.0f,
+ range,
+ pie_confirm_radius,
+ pie_confirm_external,
+ subd,
+ col,
+ NULL,
+ false);
+ }
+
+ GPU_blend(false);
+ GPU_matrix_pop();
}
-
const uiWidgetColors *ui_tooltip_get_theme(void)
{
- uiWidgetType *wt = widget_type(UI_WTYPE_TOOLTIP);
- return wt->wcol_theme;
+ uiWidgetType *wt = widget_type(UI_WTYPE_TOOLTIP);
+ return wt->wcol_theme;
}
/**
* Generic drawing for background.
*/
-static void ui_draw_widget_back_color(
- uiWidgetTypeEnum type, bool use_shadow, const rcti *rect,
- const float color[4])
+static void ui_draw_widget_back_color(uiWidgetTypeEnum type,
+ bool use_shadow,
+ const rcti *rect,
+ const float color[4])
{
- uiWidgetType *wt = widget_type(type);
-
- if (use_shadow) {
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit);
- GPU_blend(false);
- }
-
- rcti rect_copy = *rect;
- wt->state(wt, 0, 0);
- if (color) {
- rgba_float_to_uchar((uchar *)wt->wcol.inner, color);
- }
- wt->draw(&wt->wcol, &rect_copy, 0, UI_CNR_ALL);
+ uiWidgetType *wt = widget_type(type);
+
+ if (use_shadow) {
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit);
+ GPU_blend(false);
+ }
+
+ rcti rect_copy = *rect;
+ wt->state(wt, 0, 0);
+ if (color) {
+ rgba_float_to_uchar((uchar *)wt->wcol.inner, color);
+ }
+ wt->draw(&wt->wcol, &rect_copy, 0, UI_CNR_ALL);
}
void ui_draw_widget_menu_back_color(const rcti *rect, bool use_shadow, const float color[4])
{
- ui_draw_widget_back_color(UI_WTYPE_MENU_BACK, use_shadow, rect, color);
+ ui_draw_widget_back_color(UI_WTYPE_MENU_BACK, use_shadow, rect, color);
}
void ui_draw_widget_menu_back(const rcti *rect, bool use_shadow)
{
- ui_draw_widget_back_color(UI_WTYPE_MENU_BACK, use_shadow, rect, NULL);
+ ui_draw_widget_back_color(UI_WTYPE_MENU_BACK, use_shadow, rect, NULL);
}
void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock *UNUSED(block), rcti *rect)
{
- uiWidgetType *wt = widget_type(UI_WTYPE_TOOLTIP);
- wt->state(wt, 0, 0);
- /* wt->draw ends up using same function to draw the tooltip as menu_back */
- wt->draw(&wt->wcol, rect, 0, 0);
+ uiWidgetType *wt = widget_type(UI_WTYPE_TOOLTIP);
+ wt->state(wt, 0, 0);
+ /* wt->draw ends up using same function to draw the tooltip as menu_back */
+ wt->draw(&wt->wcol, rect, 0, 0);
}
/* helper call to draw a menu item without button */
/* state: UI_ACTIVE or 0 */
-void ui_draw_menu_item(const uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state, bool use_sep)
+void ui_draw_menu_item(
+ const uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state, bool use_sep)
{
- uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
- rcti _rect = *rect;
- char *cpoin = NULL;
-
- wt->state(wt, state, 0);
- wt->draw(&wt->wcol, rect, 0, 0);
-
- UI_fontstyle_set(fstyle);
-
- /* text location offset */
- rect->xmin += 0.25f * UI_UNIT_X;
- if (iconid) {
- rect->xmin += UI_DPI_ICON_SIZE;
- }
-
- /* cut string in 2 parts? */
- if (use_sep) {
- cpoin = strchr(name, UI_SEP_CHAR);
- if (cpoin) {
- *cpoin = 0;
-
- /* need to set this first */
- UI_fontstyle_set(fstyle);
-
- if (fstyle->kerning == 1) {
- /* for BLF_width */
- BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
-
- rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
-
- if (fstyle->kerning == 1) {
- BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
- }
- }
- }
-
- {
- char drawstr[UI_MAX_DRAW_STR];
- const float okwidth = (float)BLI_rcti_size_x(rect);
- const size_t max_len = sizeof(drawstr);
- const float minwidth = (float)(UI_DPI_ICON_SIZE);
-
- BLI_strncpy(drawstr, name, sizeof(drawstr));
- if (drawstr[0]) {
- UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
- }
-
- UI_fontstyle_draw(
- fstyle, rect, drawstr, (uchar *)wt->wcol.text,
- &(struct uiFontStyleDraw_Params) { .align = UI_STYLE_TEXT_LEFT, });
- }
-
- /* part text right aligned */
- if (use_sep) {
- if (cpoin) {
- rect->xmax = _rect.xmax - 5;
- UI_fontstyle_draw(
- fstyle, rect, cpoin + 1, (uchar *)wt->wcol.text,
- &(struct uiFontStyleDraw_Params) { .align = UI_STYLE_TEXT_RIGHT, });
- *cpoin = UI_SEP_CHAR;
- }
- }
-
- /* restore rect, was messed with */
- *rect = _rect;
-
- if (iconid) {
- float height, aspect;
- int xs = rect->xmin + 0.2f * UI_UNIT_X;
- int ys = rect->ymin + 0.1f * BLI_rcti_size_y(rect);
-
- height = ICON_SIZE_FROM_BUTRECT(rect);
- aspect = ICON_DEFAULT_HEIGHT / height;
-
- GPU_blend(true);
- /* XXX scale weak get from fstyle? */
- UI_icon_draw_aspect(xs, ys, iconid, aspect, 1.0f, wt->wcol.text);
- GPU_blend(false);
- }
+ uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
+ rcti _rect = *rect;
+ char *cpoin = NULL;
+
+ wt->state(wt, state, 0);
+ wt->draw(&wt->wcol, rect, 0, 0);
+
+ UI_fontstyle_set(fstyle);
+
+ /* text location offset */
+ rect->xmin += 0.25f * UI_UNIT_X;
+ if (iconid) {
+ rect->xmin += UI_DPI_ICON_SIZE;
+ }
+
+ /* cut string in 2 parts? */
+ if (use_sep) {
+ cpoin = strchr(name, UI_SEP_CHAR);
+ if (cpoin) {
+ *cpoin = 0;
+
+ /* need to set this first */
+ UI_fontstyle_set(fstyle);
+
+ if (fstyle->kerning == 1) {
+ /* for BLF_width */
+ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+
+ rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
+
+ if (fstyle->kerning == 1) {
+ BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+ }
+ }
+ }
+
+ {
+ char drawstr[UI_MAX_DRAW_STR];
+ const float okwidth = (float)BLI_rcti_size_x(rect);
+ const size_t max_len = sizeof(drawstr);
+ const float minwidth = (float)(UI_DPI_ICON_SIZE);
+
+ BLI_strncpy(drawstr, name, sizeof(drawstr));
+ if (drawstr[0]) {
+ UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
+ }
+
+ UI_fontstyle_draw(fstyle,
+ rect,
+ drawstr,
+ (uchar *)wt->wcol.text,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_LEFT,
+ });
+ }
+
+ /* part text right aligned */
+ if (use_sep) {
+ if (cpoin) {
+ rect->xmax = _rect.xmax - 5;
+ UI_fontstyle_draw(fstyle,
+ rect,
+ cpoin + 1,
+ (uchar *)wt->wcol.text,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_RIGHT,
+ });
+ *cpoin = UI_SEP_CHAR;
+ }
+ }
+
+ /* restore rect, was messed with */
+ *rect = _rect;
+
+ if (iconid) {
+ float height, aspect;
+ int xs = rect->xmin + 0.2f * UI_UNIT_X;
+ int ys = rect->ymin + 0.1f * BLI_rcti_size_y(rect);
+
+ height = ICON_SIZE_FROM_BUTRECT(rect);
+ aspect = ICON_DEFAULT_HEIGHT / height;
+
+ GPU_blend(true);
+ /* XXX scale weak get from fstyle? */
+ UI_icon_draw_aspect(xs, ys, iconid, aspect, 1.0f, wt->wcol.text);
+ GPU_blend(false);
+ }
}
-void ui_draw_preview_item(const uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state)
+void ui_draw_preview_item(
+ const uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state)
{
- rcti trect = *rect;
- const float text_size = UI_UNIT_Y;
- float font_dims[2] = {0.0f, 0.0f};
- uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
-
- /* drawing button background */
- wt->state(wt, state, 0);
- wt->draw(&wt->wcol, rect, 0, 0);
-
- /* draw icon in rect above the space reserved for the label */
- rect->ymin += text_size;
- GPU_blend(true);
- widget_draw_preview(iconid, 1.0f, rect);
- GPU_blend(false);
-
- BLF_width_and_height(fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
-
- /* text rect */
- trect.xmin += 0;
- trect.xmax = trect.xmin + font_dims[0] + U.widget_unit / 2;
- trect.ymin += U.widget_unit / 2;
- trect.ymax = trect.ymin + font_dims[1];
- if (trect.xmax > rect->xmax - PREVIEW_PAD) {
- trect.xmax = rect->xmax - PREVIEW_PAD;
- }
-
- {
- char drawstr[UI_MAX_DRAW_STR];
- const float okwidth = (float)BLI_rcti_size_x(&trect);
- const size_t max_len = sizeof(drawstr);
- const float minwidth = (float)(UI_DPI_ICON_SIZE);
-
- BLI_strncpy(drawstr, name, sizeof(drawstr));
- UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
-
- UI_fontstyle_draw(
- fstyle, &trect, drawstr, (uchar *)wt->wcol.text,
- &(struct uiFontStyleDraw_Params) { .align = UI_STYLE_TEXT_CENTER, });
- }
+ rcti trect = *rect;
+ const float text_size = UI_UNIT_Y;
+ float font_dims[2] = {0.0f, 0.0f};
+ uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
+
+ /* drawing button background */
+ wt->state(wt, state, 0);
+ wt->draw(&wt->wcol, rect, 0, 0);
+
+ /* draw icon in rect above the space reserved for the label */
+ rect->ymin += text_size;
+ GPU_blend(true);
+ widget_draw_preview(iconid, 1.0f, rect);
+ GPU_blend(false);
+
+ BLF_width_and_height(
+ fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
+
+ /* text rect */
+ trect.xmin += 0;
+ trect.xmax = trect.xmin + font_dims[0] + U.widget_unit / 2;
+ trect.ymin += U.widget_unit / 2;
+ trect.ymax = trect.ymin + font_dims[1];
+ if (trect.xmax > rect->xmax - PREVIEW_PAD) {
+ trect.xmax = rect->xmax - PREVIEW_PAD;
+ }
+
+ {
+ char drawstr[UI_MAX_DRAW_STR];
+ const float okwidth = (float)BLI_rcti_size_x(&trect);
+ const size_t max_len = sizeof(drawstr);
+ const float minwidth = (float)(UI_DPI_ICON_SIZE);
+
+ BLI_strncpy(drawstr, name, sizeof(drawstr));
+ UI_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len, '\0');
+
+ UI_fontstyle_draw(fstyle,
+ &trect,
+ drawstr,
+ (uchar *)wt->wcol.text,
+ &(struct uiFontStyleDraw_Params){
+ .align = UI_STYLE_TEXT_CENTER,
+ });
+ }
}
/** \} */
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 8d908375c1b..fa56dc04143 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -40,7 +40,7 @@
#include "BKE_main.h"
#include "BKE_mesh_runtime.h"
-#include "BLO_readfile.h" /* for UserDef version patching. */
+#include "BLO_readfile.h" /* for UserDef version patching. */
#include "BLF_api.h"
@@ -68,693 +68,853 @@ static struct bThemeState g_theme_state = {
void ui_resources_init(void)
{
- UI_icons_init();
+ UI_icons_init();
}
void ui_resources_free(void)
{
- UI_icons_free();
+ UI_icons_free();
}
-
/* ******************************************************** */
/* THEMES */
/* ******************************************************** */
const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
{
- ThemeSpace *ts = NULL;
- static char error[4] = {240, 0, 240, 255};
- static char alert[4] = {240, 60, 60, 255};
- static char headerdesel[4] = {0, 0, 0, 255};
- static char back[4] = {0, 0, 0, 255};
- static char setting = 0;
- const char *cp = error;
-
- /* ensure we're not getting a color after running BKE_blender_userdef_free */
- BLI_assert(BLI_findindex(&U.themes, theme_active) != -1);
- BLI_assert(colorid != TH_UNDEFINED);
-
- if (btheme) {
-
- /* first check for ui buttons theme */
- if (colorid < TH_THEMEUI) {
-
- switch (colorid) {
-
- case TH_REDALERT:
- cp = alert; break;
- }
- }
- else {
-
- switch (spacetype) {
- case SPACE_PROPERTIES:
- ts = &btheme->space_properties;
- break;
- case SPACE_VIEW3D:
- ts = &btheme->space_view3d;
- break;
- case SPACE_GRAPH:
- ts = &btheme->space_graph;
- break;
- case SPACE_FILE:
- ts = &btheme->space_file;
- break;
- case SPACE_NLA:
- ts = &btheme->space_nla;
- break;
- case SPACE_ACTION:
- ts = &btheme->space_action;
- break;
- case SPACE_SEQ:
- ts = &btheme->space_sequencer;
- break;
- case SPACE_IMAGE:
- ts = &btheme->space_image;
- break;
- case SPACE_TEXT:
- ts = &btheme->space_text;
- break;
- case SPACE_OUTLINER:
- ts = &btheme->space_outliner;
- break;
- case SPACE_INFO:
- ts = &btheme->space_info;
- break;
- case SPACE_USERPREF:
- ts = &btheme->space_preferences;
- break;
- case SPACE_CONSOLE:
- ts = &btheme->space_console;
- break;
- case SPACE_NODE:
- ts = &btheme->space_node;
- break;
- case SPACE_CLIP:
- ts = &btheme->space_clip;
- break;
- case SPACE_TOPBAR:
- ts = &btheme->space_topbar;
- break;
- case SPACE_STATUSBAR:
- ts = &btheme->space_statusbar;
- break;
- default:
- ts = &btheme->space_view3d;
- break;
- }
-
- switch (colorid) {
- case TH_BACK:
- if (ELEM(theme_regionid, RGN_TYPE_WINDOW, RGN_TYPE_PREVIEW)) {
- cp = ts->back;
- }
- else if (theme_regionid == RGN_TYPE_CHANNELS) {
- cp = ts->list;
- }
- else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
- cp = ts->header;
- }
- else if (theme_regionid == RGN_TYPE_NAV_BAR) {
- cp = ts->navigation_bar;
- }
- else if (theme_regionid == RGN_TYPE_EXECUTE) {
- cp = ts->execution_buts;
- }
- else {
- cp = ts->button;
- }
-
- copy_v4_v4_char(back, cp);
- if (!ED_region_is_overlap(spacetype, theme_regionid)) {
- back[3] = 255;
- }
- cp = back;
- break;
- case TH_BACK_GRAD:
- cp = ts->back_grad;
- break;
-
- case TH_SHOW_BACK_GRAD:
- cp = &setting;
- setting = ts->show_back_grad;
- break;
- case TH_TEXT:
- if (theme_regionid == RGN_TYPE_WINDOW) {
- cp = ts->text;
- }
- else if (theme_regionid == RGN_TYPE_CHANNELS) {
- cp = ts->list_text;
- }
- else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
- cp = ts->header_text;
- }
- else {
- cp = ts->button_text;
- }
- break;
- case TH_TEXT_HI:
- if (theme_regionid == RGN_TYPE_WINDOW) {
- cp = ts->text_hi;
- }
- else if (theme_regionid == RGN_TYPE_CHANNELS) {
- cp = ts->list_text_hi;
- }
- else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
- cp = ts->header_text_hi;
- }
- else {
- cp = ts->button_text_hi;
- }
- break;
- case TH_TITLE:
- if (theme_regionid == RGN_TYPE_WINDOW) {
- cp = ts->title;
- }
- else if (theme_regionid == RGN_TYPE_CHANNELS) {
- cp = ts->list_title;
- }
- else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
- cp = ts->header_title;
- }
- else {
- cp = ts->button_title;
- }
- break;
-
- case TH_HEADER:
- cp = ts->header; break;
- case TH_HEADERDESEL:
- /* we calculate a dynamic builtin header deselect color,
- * also for pulldowns... */
- cp = ts->header;
- headerdesel[0] = cp[0] > 10 ? cp[0] - 10 : 0;
- headerdesel[1] = cp[1] > 10 ? cp[1] - 10 : 0;
- headerdesel[2] = cp[2] > 10 ? cp[2] - 10 : 0;
- headerdesel[3] = cp[3];
- cp = headerdesel;
- break;
- case TH_HEADER_TEXT:
- cp = ts->header_text; break;
- case TH_HEADER_TEXT_HI:
- cp = ts->header_text_hi; break;
-
- case TH_PANEL_HEADER:
- cp = ts->panelcolors.header; break;
- case TH_PANEL_BACK:
- cp = ts->panelcolors.back; break;
- case TH_PANEL_SUB_BACK:
- cp = ts->panelcolors.sub_back; break;
-
- case TH_BUTBACK:
- cp = ts->button; break;
- case TH_BUTBACK_TEXT:
- cp = ts->button_text; break;
- case TH_BUTBACK_TEXT_HI:
- cp = ts->button_text_hi; break;
-
- case TH_TAB_ACTIVE:
- cp = ts->tab_active; break;
- case TH_TAB_INACTIVE:
- cp = ts->tab_inactive; break;
- case TH_TAB_BACK:
- cp = ts->tab_back; break;
- case TH_TAB_OUTLINE:
- cp = ts->tab_outline; break;
-
- case TH_SHADE1:
- cp = ts->shade1; break;
- case TH_SHADE2:
- cp = ts->shade2; break;
- case TH_HILITE:
- cp = ts->hilite; break;
-
- case TH_GRID:
- cp = ts->grid; break;
- case TH_VIEW_OVERLAY:
- cp = ts->view_overlay; break;
- case TH_WIRE:
- cp = ts->wire; break;
- case TH_WIRE_INNER:
- cp = ts->syntaxr; break;
- case TH_WIRE_EDIT:
- cp = ts->wire_edit; break;
- case TH_LIGHT:
- cp = ts->lamp; break;
- case TH_SPEAKER:
- cp = ts->speaker; break;
- case TH_CAMERA:
- cp = ts->camera; break;
- case TH_EMPTY:
- cp = ts->empty; break;
- case TH_SELECT:
- cp = ts->select; break;
- case TH_ACTIVE:
- cp = ts->active; break;
- case TH_GROUP:
- cp = ts->group; break;
- case TH_GROUP_ACTIVE:
- cp = ts->group_active; break;
- case TH_TRANSFORM:
- cp = ts->transform; break;
- case TH_VERTEX:
- cp = ts->vertex; break;
- case TH_VERTEX_SELECT:
- cp = ts->vertex_select; break;
- case TH_VERTEX_BEVEL:
- cp = ts->vertex_bevel; break;
- case TH_VERTEX_UNREFERENCED:
- cp = ts->vertex_unreferenced; break;
- case TH_VERTEX_SIZE:
- cp = &ts->vertex_size; break;
- case TH_OUTLINE_WIDTH:
- cp = &ts->outline_width; break;
- case TH_EDGE:
- cp = ts->edge; break;
- case TH_EDGE_SELECT:
- cp = ts->edge_select; break;
- case TH_EDGE_SEAM:
- cp = ts->edge_seam; break;
- case TH_EDGE_SHARP:
- cp = ts->edge_sharp; break;
- case TH_EDGE_CREASE:
- cp = ts->edge_crease; break;
- case TH_EDGE_BEVEL:
- cp = ts->edge_bevel; break;
- case TH_EDITMESH_ACTIVE:
- cp = ts->editmesh_active; break;
- case TH_EDGE_FACESEL:
- cp = ts->edge_facesel; break;
- case TH_FACE:
- cp = ts->face; break;
- case TH_FACE_SELECT:
- cp = ts->face_select; break;
- case TH_FACE_DOT:
- cp = ts->face_dot; break;
- case TH_FACEDOT_SIZE:
- cp = &ts->facedot_size; break;
- case TH_DRAWEXTRA_EDGELEN:
- cp = ts->extra_edge_len; break;
- case TH_DRAWEXTRA_EDGEANG:
- cp = ts->extra_edge_angle; break;
- case TH_DRAWEXTRA_FACEAREA:
- cp = ts->extra_face_area; break;
- case TH_DRAWEXTRA_FACEANG:
- cp = ts->extra_face_angle; break;
- case TH_NORMAL:
- cp = ts->normal; break;
- case TH_VNORMAL:
- cp = ts->vertex_normal; break;
- case TH_LNORMAL:
- cp = ts->loop_normal; break;
- case TH_BONE_SOLID:
- cp = ts->bone_solid; break;
- case TH_BONE_POSE:
- cp = ts->bone_pose; break;
- case TH_BONE_POSE_ACTIVE:
- cp = ts->bone_pose_active; break;
- case TH_STRIP:
- cp = ts->strip; break;
- case TH_STRIP_SELECT:
- cp = ts->strip_select; break;
- case TH_KEYTYPE_KEYFRAME:
- cp = ts->keytype_keyframe; break;
- case TH_KEYTYPE_KEYFRAME_SELECT:
- cp = ts->keytype_keyframe_select; break;
- case TH_KEYTYPE_EXTREME:
- cp = ts->keytype_extreme; break;
- case TH_KEYTYPE_EXTREME_SELECT:
- cp = ts->keytype_extreme_select; break;
- case TH_KEYTYPE_BREAKDOWN:
- cp = ts->keytype_breakdown; break;
- case TH_KEYTYPE_BREAKDOWN_SELECT:
- cp = ts->keytype_breakdown_select; break;
- case TH_KEYTYPE_JITTER:
- cp = ts->keytype_jitter; break;
- case TH_KEYTYPE_JITTER_SELECT:
- cp = ts->keytype_jitter_select; break;
- case TH_KEYTYPE_MOVEHOLD:
- cp = ts->keytype_movehold; break;
- case TH_KEYTYPE_MOVEHOLD_SELECT:
- cp = ts->keytype_movehold_select; break;
- case TH_KEYBORDER:
- cp = ts->keyborder; break;
- case TH_KEYBORDER_SELECT:
- cp = ts->keyborder_select; break;
- case TH_CFRAME:
- cp = ts->cframe; break;
- case TH_TIME_KEYFRAME:
- cp = ts->time_keyframe; break;
- case TH_TIME_GP_KEYFRAME:
- cp = ts->time_gp_keyframe; break;
- case TH_NURB_ULINE:
- cp = ts->nurb_uline; break;
- case TH_NURB_VLINE:
- cp = ts->nurb_vline; break;
- case TH_NURB_SEL_ULINE:
- cp = ts->nurb_sel_uline; break;
- case TH_NURB_SEL_VLINE:
- cp = ts->nurb_sel_vline; break;
- case TH_ACTIVE_SPLINE:
- cp = ts->act_spline; break;
- case TH_ACTIVE_VERT:
- cp = ts->lastsel_point; break;
- case TH_HANDLE_FREE:
- cp = ts->handle_free; break;
- case TH_HANDLE_AUTO:
- cp = ts->handle_auto; break;
- case TH_HANDLE_AUTOCLAMP:
- cp = ts->handle_auto_clamped; break;
- case TH_HANDLE_VECT:
- cp = ts->handle_vect; break;
- case TH_HANDLE_ALIGN:
- cp = ts->handle_align; break;
- case TH_HANDLE_SEL_FREE:
- cp = ts->handle_sel_free; break;
- case TH_HANDLE_SEL_AUTO:
- cp = ts->handle_sel_auto; break;
- case TH_HANDLE_SEL_AUTOCLAMP:
- cp = ts->handle_sel_auto_clamped; break;
- case TH_HANDLE_SEL_VECT:
- cp = ts->handle_sel_vect; break;
- case TH_HANDLE_SEL_ALIGN:
- cp = ts->handle_sel_align; break;
- case TH_FREESTYLE_EDGE_MARK:
- cp = ts->freestyle_edge_mark; break;
- case TH_FREESTYLE_FACE_MARK:
- cp = ts->freestyle_face_mark; break;
-
- case TH_SYNTAX_B:
- cp = ts->syntaxb; break;
- case TH_SYNTAX_V:
- cp = ts->syntaxv; break;
- case TH_SYNTAX_C:
- cp = ts->syntaxc; break;
- case TH_SYNTAX_L:
- cp = ts->syntaxl; break;
- case TH_SYNTAX_D:
- cp = ts->syntaxd; break;
- case TH_SYNTAX_R:
- cp = ts->syntaxr; break;
- case TH_SYNTAX_N:
- cp = ts->syntaxn; break;
- case TH_SYNTAX_S:
- cp = ts->syntaxs; break;
-
- case TH_NODE:
- cp = ts->syntaxl; break;
- case TH_NODE_INPUT:
- cp = ts->syntaxn; break;
- case TH_NODE_OUTPUT:
- cp = ts->nodeclass_output; break;
- case TH_NODE_COLOR:
- cp = ts->syntaxb; break;
- case TH_NODE_FILTER:
- cp = ts->nodeclass_filter; break;
- case TH_NODE_VECTOR:
- cp = ts->nodeclass_vector; break;
- case TH_NODE_TEXTURE:
- cp = ts->nodeclass_texture; break;
- case TH_NODE_PATTERN:
- cp = ts->nodeclass_pattern; break;
- case TH_NODE_SCRIPT:
- cp = ts->nodeclass_script; break;
- case TH_NODE_LAYOUT:
- cp = ts->nodeclass_layout; break;
- case TH_NODE_SHADER:
- cp = ts->nodeclass_shader; break;
- case TH_NODE_CONVERTOR:
- cp = ts->syntaxv; break;
- case TH_NODE_GROUP:
- cp = ts->syntaxc; break;
- case TH_NODE_INTERFACE:
- cp = ts->console_output; break;
- case TH_NODE_FRAME:
- cp = ts->movie; break;
- case TH_NODE_MATTE:
- cp = ts->syntaxs; break;
- case TH_NODE_DISTORT:
- cp = ts->syntaxd; break;
- case TH_NODE_CURVING:
- cp = &ts->noodle_curving; break;
-
- case TH_SEQ_MOVIE:
- cp = ts->movie; break;
- case TH_SEQ_MOVIECLIP:
- cp = ts->movieclip; break;
- case TH_SEQ_MASK:
- cp = ts->mask; break;
- case TH_SEQ_IMAGE:
- cp = ts->image; break;
- case TH_SEQ_SCENE:
- cp = ts->scene; break;
- case TH_SEQ_AUDIO:
- cp = ts->audio; break;
- case TH_SEQ_EFFECT:
- cp = ts->effect; break;
- case TH_SEQ_TRANSITION:
- cp = ts->transition; break;
- case TH_SEQ_META:
- cp = ts->meta; break;
- case TH_SEQ_TEXT:
- cp = ts->text_strip; break;
- case TH_SEQ_PREVIEW:
- cp = ts->preview_back; break;
-
- case TH_CONSOLE_OUTPUT:
- cp = ts->console_output; break;
- case TH_CONSOLE_INPUT:
- cp = ts->console_input; break;
- case TH_CONSOLE_INFO:
- cp = ts->console_info; break;
- case TH_CONSOLE_ERROR:
- cp = ts->console_error; break;
- case TH_CONSOLE_CURSOR:
- cp = ts->console_cursor; break;
- case TH_CONSOLE_SELECT:
- cp = ts->console_select; break;
-
- case TH_HANDLE_VERTEX:
- cp = ts->handle_vertex;
- break;
- case TH_HANDLE_VERTEX_SELECT:
- cp = ts->handle_vertex_select;
- break;
- case TH_HANDLE_VERTEX_SIZE:
- cp = &ts->handle_vertex_size;
- break;
-
- case TH_GP_VERTEX:
- cp = ts->gp_vertex;
- break;
- case TH_GP_VERTEX_SELECT:
- cp = ts->gp_vertex_select;
- break;
- case TH_GP_VERTEX_SIZE:
- cp = &ts->gp_vertex_size;
- break;
-
- case TH_DOPESHEET_CHANNELOB:
- cp = ts->ds_channel;
- break;
- case TH_DOPESHEET_CHANNELSUBOB:
- cp = ts->ds_subchannel;
- break;
- case TH_DOPESHEET_IPOLINE:
- cp = ts->ds_ipoline;
- break;
-
- case TH_PREVIEW_BACK:
- cp = ts->preview_back;
- break;
-
- case TH_STITCH_PREVIEW_FACE:
- cp = ts->preview_stitch_face;
- break;
-
- case TH_STITCH_PREVIEW_EDGE:
- cp = ts->preview_stitch_edge;
- break;
-
- case TH_STITCH_PREVIEW_VERT:
- cp = ts->preview_stitch_vert;
- break;
-
- case TH_STITCH_PREVIEW_STITCHABLE:
- cp = ts->preview_stitch_stitchable;
- break;
-
- case TH_STITCH_PREVIEW_UNSTITCHABLE:
- cp = ts->preview_stitch_unstitchable;
- break;
- case TH_STITCH_PREVIEW_ACTIVE:
- cp = ts->preview_stitch_active;
- break;
-
- case TH_PAINT_CURVE_HANDLE:
- cp = ts->paint_curve_handle;
- break;
- case TH_PAINT_CURVE_PIVOT:
- cp = ts->paint_curve_pivot;
- break;
-
- case TH_METADATA_BG:
- cp = ts->metadatabg;
- break;
- case TH_METADATA_TEXT:
- cp = ts->metadatatext;
- break;
-
- case TH_UV_OTHERS:
- cp = ts->uv_others;
- break;
- case TH_UV_SHADOW:
- cp = ts->uv_shadow;
- break;
-
- case TH_MARKER_OUTLINE:
- cp = ts->marker_outline; break;
- case TH_MARKER:
- cp = ts->marker; break;
- case TH_ACT_MARKER:
- cp = ts->act_marker; break;
- case TH_SEL_MARKER:
- cp = ts->sel_marker; break;
- case TH_BUNDLE_SOLID:
- cp = ts->bundle_solid; break;
- case TH_DIS_MARKER:
- cp = ts->dis_marker; break;
- case TH_PATH_BEFORE:
- cp = ts->path_before; break;
- case TH_PATH_AFTER:
- cp = ts->path_after; break;
- case TH_CAMERA_PATH:
- cp = ts->camera_path; break;
- case TH_LOCK_MARKER:
- cp = ts->lock_marker; break;
-
- case TH_MATCH:
- cp = ts->match;
- break;
-
- case TH_SELECT_HIGHLIGHT:
- cp = ts->selected_highlight;
- break;
-
- case TH_SKIN_ROOT:
- cp = ts->skin_root;
- break;
-
- case TH_ANIM_ACTIVE:
- cp = ts->anim_active;
- break;
- case TH_ANIM_INACTIVE:
- cp = ts->anim_non_active;
- break;
- case TH_ANIM_PREVIEW_RANGE:
- cp = ts->anim_preview_range;
- break;
-
- case TH_NLA_TWEAK:
- cp = ts->nla_tweaking;
- break;
- case TH_NLA_TWEAK_DUPLI:
- cp = ts->nla_tweakdupli;
- break;
-
- case TH_NLA_TRANSITION:
- cp = ts->nla_transition;
- break;
- case TH_NLA_TRANSITION_SEL:
- cp = ts->nla_transition_sel;
- break;
- case TH_NLA_META:
- cp = ts->nla_meta;
- break;
- case TH_NLA_META_SEL:
- cp = ts->nla_meta_sel;
- break;
- case TH_NLA_SOUND:
- cp = ts->nla_sound;
- break;
- case TH_NLA_SOUND_SEL:
- cp = ts->nla_sound_sel;
- break;
-
- case TH_WIDGET_EMBOSS:
- cp = btheme->tui.widget_emboss; break;
-
- case TH_EDITOR_OUTLINE:
- cp = btheme->tui.editor_outline;
- break;
- case TH_AXIS_X:
- cp = btheme->tui.xaxis; break;
- case TH_AXIS_Y:
- cp = btheme->tui.yaxis; break;
- case TH_AXIS_Z:
- cp = btheme->tui.zaxis; break;
-
- case TH_GIZMO_HI:
- cp = btheme->tui.gizmo_hi; break;
- case TH_GIZMO_PRIMARY:
- cp = btheme->tui.gizmo_primary; break;
- case TH_GIZMO_SECONDARY:
- cp = btheme->tui.gizmo_secondary; break;
- case TH_GIZMO_A:
- cp = btheme->tui.gizmo_a; break;
- case TH_GIZMO_B:
- cp = btheme->tui.gizmo_b; break;
-
- case TH_ICON_COLLECTION:
- cp = btheme->tui.icon_collection; break;
- case TH_ICON_OBJECT:
- cp = btheme->tui.icon_object; break;
- case TH_ICON_OBJECT_DATA:
- cp = btheme->tui.icon_object_data; break;
- case TH_ICON_MODIFIER:
- cp = btheme->tui.icon_modifier; break;
- case TH_ICON_SHADING:
- cp = btheme->tui.icon_shading; break;
-
- case TH_INFO_SELECTED:
- cp = ts->info_selected;
- break;
- case TH_INFO_SELECTED_TEXT:
- cp = ts->info_selected_text;
- break;
- case TH_INFO_ERROR:
- cp = ts->info_error;
- break;
- case TH_INFO_ERROR_TEXT:
- cp = ts->info_error_text;
- break;
- case TH_INFO_WARNING:
- cp = ts->info_warning;
- break;
- case TH_INFO_WARNING_TEXT:
- cp = ts->info_warning_text;
- break;
- case TH_INFO_INFO:
- cp = ts->info_info;
- break;
- case TH_INFO_INFO_TEXT:
- cp = ts->info_info_text;
- break;
- case TH_INFO_DEBUG:
- cp = ts->info_debug;
- break;
- case TH_INFO_DEBUG_TEXT:
- cp = ts->info_debug_text;
- break;
- case TH_V3D_CLIPPING_BORDER:
- cp = ts->clipping_border_3d;
- break;
- }
- }
- }
-
- return (const uchar *)cp;
+ ThemeSpace *ts = NULL;
+ static char error[4] = {240, 0, 240, 255};
+ static char alert[4] = {240, 60, 60, 255};
+ static char headerdesel[4] = {0, 0, 0, 255};
+ static char back[4] = {0, 0, 0, 255};
+ static char setting = 0;
+ const char *cp = error;
+
+ /* ensure we're not getting a color after running BKE_blender_userdef_free */
+ BLI_assert(BLI_findindex(&U.themes, theme_active) != -1);
+ BLI_assert(colorid != TH_UNDEFINED);
+
+ if (btheme) {
+
+ /* first check for ui buttons theme */
+ if (colorid < TH_THEMEUI) {
+
+ switch (colorid) {
+
+ case TH_REDALERT:
+ cp = alert;
+ break;
+ }
+ }
+ else {
+
+ switch (spacetype) {
+ case SPACE_PROPERTIES:
+ ts = &btheme->space_properties;
+ break;
+ case SPACE_VIEW3D:
+ ts = &btheme->space_view3d;
+ break;
+ case SPACE_GRAPH:
+ ts = &btheme->space_graph;
+ break;
+ case SPACE_FILE:
+ ts = &btheme->space_file;
+ break;
+ case SPACE_NLA:
+ ts = &btheme->space_nla;
+ break;
+ case SPACE_ACTION:
+ ts = &btheme->space_action;
+ break;
+ case SPACE_SEQ:
+ ts = &btheme->space_sequencer;
+ break;
+ case SPACE_IMAGE:
+ ts = &btheme->space_image;
+ break;
+ case SPACE_TEXT:
+ ts = &btheme->space_text;
+ break;
+ case SPACE_OUTLINER:
+ ts = &btheme->space_outliner;
+ break;
+ case SPACE_INFO:
+ ts = &btheme->space_info;
+ break;
+ case SPACE_USERPREF:
+ ts = &btheme->space_preferences;
+ break;
+ case SPACE_CONSOLE:
+ ts = &btheme->space_console;
+ break;
+ case SPACE_NODE:
+ ts = &btheme->space_node;
+ break;
+ case SPACE_CLIP:
+ ts = &btheme->space_clip;
+ break;
+ case SPACE_TOPBAR:
+ ts = &btheme->space_topbar;
+ break;
+ case SPACE_STATUSBAR:
+ ts = &btheme->space_statusbar;
+ break;
+ default:
+ ts = &btheme->space_view3d;
+ break;
+ }
+
+ switch (colorid) {
+ case TH_BACK:
+ if (ELEM(theme_regionid, RGN_TYPE_WINDOW, RGN_TYPE_PREVIEW)) {
+ cp = ts->back;
+ }
+ else if (theme_regionid == RGN_TYPE_CHANNELS) {
+ cp = ts->list;
+ }
+ else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
+ cp = ts->header;
+ }
+ else if (theme_regionid == RGN_TYPE_NAV_BAR) {
+ cp = ts->navigation_bar;
+ }
+ else if (theme_regionid == RGN_TYPE_EXECUTE) {
+ cp = ts->execution_buts;
+ }
+ else {
+ cp = ts->button;
+ }
+
+ copy_v4_v4_char(back, cp);
+ if (!ED_region_is_overlap(spacetype, theme_regionid)) {
+ back[3] = 255;
+ }
+ cp = back;
+ break;
+ case TH_BACK_GRAD:
+ cp = ts->back_grad;
+ break;
+
+ case TH_SHOW_BACK_GRAD:
+ cp = &setting;
+ setting = ts->show_back_grad;
+ break;
+ case TH_TEXT:
+ if (theme_regionid == RGN_TYPE_WINDOW) {
+ cp = ts->text;
+ }
+ else if (theme_regionid == RGN_TYPE_CHANNELS) {
+ cp = ts->list_text;
+ }
+ else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
+ cp = ts->header_text;
+ }
+ else {
+ cp = ts->button_text;
+ }
+ break;
+ case TH_TEXT_HI:
+ if (theme_regionid == RGN_TYPE_WINDOW) {
+ cp = ts->text_hi;
+ }
+ else if (theme_regionid == RGN_TYPE_CHANNELS) {
+ cp = ts->list_text_hi;
+ }
+ else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
+ cp = ts->header_text_hi;
+ }
+ else {
+ cp = ts->button_text_hi;
+ }
+ break;
+ case TH_TITLE:
+ if (theme_regionid == RGN_TYPE_WINDOW) {
+ cp = ts->title;
+ }
+ else if (theme_regionid == RGN_TYPE_CHANNELS) {
+ cp = ts->list_title;
+ }
+ else if (ELEM(theme_regionid, RGN_TYPE_HEADER, RGN_TYPE_FOOTER)) {
+ cp = ts->header_title;
+ }
+ else {
+ cp = ts->button_title;
+ }
+ break;
+
+ case TH_HEADER:
+ cp = ts->header;
+ break;
+ case TH_HEADERDESEL:
+ /* we calculate a dynamic builtin header deselect color,
+ * also for pulldowns... */
+ cp = ts->header;
+ headerdesel[0] = cp[0] > 10 ? cp[0] - 10 : 0;
+ headerdesel[1] = cp[1] > 10 ? cp[1] - 10 : 0;
+ headerdesel[2] = cp[2] > 10 ? cp[2] - 10 : 0;
+ headerdesel[3] = cp[3];
+ cp = headerdesel;
+ break;
+ case TH_HEADER_TEXT:
+ cp = ts->header_text;
+ break;
+ case TH_HEADER_TEXT_HI:
+ cp = ts->header_text_hi;
+ break;
+
+ case TH_PANEL_HEADER:
+ cp = ts->panelcolors.header;
+ break;
+ case TH_PANEL_BACK:
+ cp = ts->panelcolors.back;
+ break;
+ case TH_PANEL_SUB_BACK:
+ cp = ts->panelcolors.sub_back;
+ break;
+
+ case TH_BUTBACK:
+ cp = ts->button;
+ break;
+ case TH_BUTBACK_TEXT:
+ cp = ts->button_text;
+ break;
+ case TH_BUTBACK_TEXT_HI:
+ cp = ts->button_text_hi;
+ break;
+
+ case TH_TAB_ACTIVE:
+ cp = ts->tab_active;
+ break;
+ case TH_TAB_INACTIVE:
+ cp = ts->tab_inactive;
+ break;
+ case TH_TAB_BACK:
+ cp = ts->tab_back;
+ break;
+ case TH_TAB_OUTLINE:
+ cp = ts->tab_outline;
+ break;
+
+ case TH_SHADE1:
+ cp = ts->shade1;
+ break;
+ case TH_SHADE2:
+ cp = ts->shade2;
+ break;
+ case TH_HILITE:
+ cp = ts->hilite;
+ break;
+
+ case TH_GRID:
+ cp = ts->grid;
+ break;
+ case TH_VIEW_OVERLAY:
+ cp = ts->view_overlay;
+ break;
+ case TH_WIRE:
+ cp = ts->wire;
+ break;
+ case TH_WIRE_INNER:
+ cp = ts->syntaxr;
+ break;
+ case TH_WIRE_EDIT:
+ cp = ts->wire_edit;
+ break;
+ case TH_LIGHT:
+ cp = ts->lamp;
+ break;
+ case TH_SPEAKER:
+ cp = ts->speaker;
+ break;
+ case TH_CAMERA:
+ cp = ts->camera;
+ break;
+ case TH_EMPTY:
+ cp = ts->empty;
+ break;
+ case TH_SELECT:
+ cp = ts->select;
+ break;
+ case TH_ACTIVE:
+ cp = ts->active;
+ break;
+ case TH_GROUP:
+ cp = ts->group;
+ break;
+ case TH_GROUP_ACTIVE:
+ cp = ts->group_active;
+ break;
+ case TH_TRANSFORM:
+ cp = ts->transform;
+ break;
+ case TH_VERTEX:
+ cp = ts->vertex;
+ break;
+ case TH_VERTEX_SELECT:
+ cp = ts->vertex_select;
+ break;
+ case TH_VERTEX_BEVEL:
+ cp = ts->vertex_bevel;
+ break;
+ case TH_VERTEX_UNREFERENCED:
+ cp = ts->vertex_unreferenced;
+ break;
+ case TH_VERTEX_SIZE:
+ cp = &ts->vertex_size;
+ break;
+ case TH_OUTLINE_WIDTH:
+ cp = &ts->outline_width;
+ break;
+ case TH_EDGE:
+ cp = ts->edge;
+ break;
+ case TH_EDGE_SELECT:
+ cp = ts->edge_select;
+ break;
+ case TH_EDGE_SEAM:
+ cp = ts->edge_seam;
+ break;
+ case TH_EDGE_SHARP:
+ cp = ts->edge_sharp;
+ break;
+ case TH_EDGE_CREASE:
+ cp = ts->edge_crease;
+ break;
+ case TH_EDGE_BEVEL:
+ cp = ts->edge_bevel;
+ break;
+ case TH_EDITMESH_ACTIVE:
+ cp = ts->editmesh_active;
+ break;
+ case TH_EDGE_FACESEL:
+ cp = ts->edge_facesel;
+ break;
+ case TH_FACE:
+ cp = ts->face;
+ break;
+ case TH_FACE_SELECT:
+ cp = ts->face_select;
+ break;
+ case TH_FACE_DOT:
+ cp = ts->face_dot;
+ break;
+ case TH_FACEDOT_SIZE:
+ cp = &ts->facedot_size;
+ break;
+ case TH_DRAWEXTRA_EDGELEN:
+ cp = ts->extra_edge_len;
+ break;
+ case TH_DRAWEXTRA_EDGEANG:
+ cp = ts->extra_edge_angle;
+ break;
+ case TH_DRAWEXTRA_FACEAREA:
+ cp = ts->extra_face_area;
+ break;
+ case TH_DRAWEXTRA_FACEANG:
+ cp = ts->extra_face_angle;
+ break;
+ case TH_NORMAL:
+ cp = ts->normal;
+ break;
+ case TH_VNORMAL:
+ cp = ts->vertex_normal;
+ break;
+ case TH_LNORMAL:
+ cp = ts->loop_normal;
+ break;
+ case TH_BONE_SOLID:
+ cp = ts->bone_solid;
+ break;
+ case TH_BONE_POSE:
+ cp = ts->bone_pose;
+ break;
+ case TH_BONE_POSE_ACTIVE:
+ cp = ts->bone_pose_active;
+ break;
+ case TH_STRIP:
+ cp = ts->strip;
+ break;
+ case TH_STRIP_SELECT:
+ cp = ts->strip_select;
+ break;
+ case TH_KEYTYPE_KEYFRAME:
+ cp = ts->keytype_keyframe;
+ break;
+ case TH_KEYTYPE_KEYFRAME_SELECT:
+ cp = ts->keytype_keyframe_select;
+ break;
+ case TH_KEYTYPE_EXTREME:
+ cp = ts->keytype_extreme;
+ break;
+ case TH_KEYTYPE_EXTREME_SELECT:
+ cp = ts->keytype_extreme_select;
+ break;
+ case TH_KEYTYPE_BREAKDOWN:
+ cp = ts->keytype_breakdown;
+ break;
+ case TH_KEYTYPE_BREAKDOWN_SELECT:
+ cp = ts->keytype_breakdown_select;
+ break;
+ case TH_KEYTYPE_JITTER:
+ cp = ts->keytype_jitter;
+ break;
+ case TH_KEYTYPE_JITTER_SELECT:
+ cp = ts->keytype_jitter_select;
+ break;
+ case TH_KEYTYPE_MOVEHOLD:
+ cp = ts->keytype_movehold;
+ break;
+ case TH_KEYTYPE_MOVEHOLD_SELECT:
+ cp = ts->keytype_movehold_select;
+ break;
+ case TH_KEYBORDER:
+ cp = ts->keyborder;
+ break;
+ case TH_KEYBORDER_SELECT:
+ cp = ts->keyborder_select;
+ break;
+ case TH_CFRAME:
+ cp = ts->cframe;
+ break;
+ case TH_TIME_KEYFRAME:
+ cp = ts->time_keyframe;
+ break;
+ case TH_TIME_GP_KEYFRAME:
+ cp = ts->time_gp_keyframe;
+ break;
+ case TH_NURB_ULINE:
+ cp = ts->nurb_uline;
+ break;
+ case TH_NURB_VLINE:
+ cp = ts->nurb_vline;
+ break;
+ case TH_NURB_SEL_ULINE:
+ cp = ts->nurb_sel_uline;
+ break;
+ case TH_NURB_SEL_VLINE:
+ cp = ts->nurb_sel_vline;
+ break;
+ case TH_ACTIVE_SPLINE:
+ cp = ts->act_spline;
+ break;
+ case TH_ACTIVE_VERT:
+ cp = ts->lastsel_point;
+ break;
+ case TH_HANDLE_FREE:
+ cp = ts->handle_free;
+ break;
+ case TH_HANDLE_AUTO:
+ cp = ts->handle_auto;
+ break;
+ case TH_HANDLE_AUTOCLAMP:
+ cp = ts->handle_auto_clamped;
+ break;
+ case TH_HANDLE_VECT:
+ cp = ts->handle_vect;
+ break;
+ case TH_HANDLE_ALIGN:
+ cp = ts->handle_align;
+ break;
+ case TH_HANDLE_SEL_FREE:
+ cp = ts->handle_sel_free;
+ break;
+ case TH_HANDLE_SEL_AUTO:
+ cp = ts->handle_sel_auto;
+ break;
+ case TH_HANDLE_SEL_AUTOCLAMP:
+ cp = ts->handle_sel_auto_clamped;
+ break;
+ case TH_HANDLE_SEL_VECT:
+ cp = ts->handle_sel_vect;
+ break;
+ case TH_HANDLE_SEL_ALIGN:
+ cp = ts->handle_sel_align;
+ break;
+ case TH_FREESTYLE_EDGE_MARK:
+ cp = ts->freestyle_edge_mark;
+ break;
+ case TH_FREESTYLE_FACE_MARK:
+ cp = ts->freestyle_face_mark;
+ break;
+
+ case TH_SYNTAX_B:
+ cp = ts->syntaxb;
+ break;
+ case TH_SYNTAX_V:
+ cp = ts->syntaxv;
+ break;
+ case TH_SYNTAX_C:
+ cp = ts->syntaxc;
+ break;
+ case TH_SYNTAX_L:
+ cp = ts->syntaxl;
+ break;
+ case TH_SYNTAX_D:
+ cp = ts->syntaxd;
+ break;
+ case TH_SYNTAX_R:
+ cp = ts->syntaxr;
+ break;
+ case TH_SYNTAX_N:
+ cp = ts->syntaxn;
+ break;
+ case TH_SYNTAX_S:
+ cp = ts->syntaxs;
+ break;
+
+ case TH_NODE:
+ cp = ts->syntaxl;
+ break;
+ case TH_NODE_INPUT:
+ cp = ts->syntaxn;
+ break;
+ case TH_NODE_OUTPUT:
+ cp = ts->nodeclass_output;
+ break;
+ case TH_NODE_COLOR:
+ cp = ts->syntaxb;
+ break;
+ case TH_NODE_FILTER:
+ cp = ts->nodeclass_filter;
+ break;
+ case TH_NODE_VECTOR:
+ cp = ts->nodeclass_vector;
+ break;
+ case TH_NODE_TEXTURE:
+ cp = ts->nodeclass_texture;
+ break;
+ case TH_NODE_PATTERN:
+ cp = ts->nodeclass_pattern;
+ break;
+ case TH_NODE_SCRIPT:
+ cp = ts->nodeclass_script;
+ break;
+ case TH_NODE_LAYOUT:
+ cp = ts->nodeclass_layout;
+ break;
+ case TH_NODE_SHADER:
+ cp = ts->nodeclass_shader;
+ break;
+ case TH_NODE_CONVERTOR:
+ cp = ts->syntaxv;
+ break;
+ case TH_NODE_GROUP:
+ cp = ts->syntaxc;
+ break;
+ case TH_NODE_INTERFACE:
+ cp = ts->console_output;
+ break;
+ case TH_NODE_FRAME:
+ cp = ts->movie;
+ break;
+ case TH_NODE_MATTE:
+ cp = ts->syntaxs;
+ break;
+ case TH_NODE_DISTORT:
+ cp = ts->syntaxd;
+ break;
+ case TH_NODE_CURVING:
+ cp = &ts->noodle_curving;
+ break;
+
+ case TH_SEQ_MOVIE:
+ cp = ts->movie;
+ break;
+ case TH_SEQ_MOVIECLIP:
+ cp = ts->movieclip;
+ break;
+ case TH_SEQ_MASK:
+ cp = ts->mask;
+ break;
+ case TH_SEQ_IMAGE:
+ cp = ts->image;
+ break;
+ case TH_SEQ_SCENE:
+ cp = ts->scene;
+ break;
+ case TH_SEQ_AUDIO:
+ cp = ts->audio;
+ break;
+ case TH_SEQ_EFFECT:
+ cp = ts->effect;
+ break;
+ case TH_SEQ_TRANSITION:
+ cp = ts->transition;
+ break;
+ case TH_SEQ_META:
+ cp = ts->meta;
+ break;
+ case TH_SEQ_TEXT:
+ cp = ts->text_strip;
+ break;
+ case TH_SEQ_PREVIEW:
+ cp = ts->preview_back;
+ break;
+
+ case TH_CONSOLE_OUTPUT:
+ cp = ts->console_output;
+ break;
+ case TH_CONSOLE_INPUT:
+ cp = ts->console_input;
+ break;
+ case TH_CONSOLE_INFO:
+ cp = ts->console_info;
+ break;
+ case TH_CONSOLE_ERROR:
+ cp = ts->console_error;
+ break;
+ case TH_CONSOLE_CURSOR:
+ cp = ts->console_cursor;
+ break;
+ case TH_CONSOLE_SELECT:
+ cp = ts->console_select;
+ break;
+
+ case TH_HANDLE_VERTEX:
+ cp = ts->handle_vertex;
+ break;
+ case TH_HANDLE_VERTEX_SELECT:
+ cp = ts->handle_vertex_select;
+ break;
+ case TH_HANDLE_VERTEX_SIZE:
+ cp = &ts->handle_vertex_size;
+ break;
+
+ case TH_GP_VERTEX:
+ cp = ts->gp_vertex;
+ break;
+ case TH_GP_VERTEX_SELECT:
+ cp = ts->gp_vertex_select;
+ break;
+ case TH_GP_VERTEX_SIZE:
+ cp = &ts->gp_vertex_size;
+ break;
+
+ case TH_DOPESHEET_CHANNELOB:
+ cp = ts->ds_channel;
+ break;
+ case TH_DOPESHEET_CHANNELSUBOB:
+ cp = ts->ds_subchannel;
+ break;
+ case TH_DOPESHEET_IPOLINE:
+ cp = ts->ds_ipoline;
+ break;
+
+ case TH_PREVIEW_BACK:
+ cp = ts->preview_back;
+ break;
+
+ case TH_STITCH_PREVIEW_FACE:
+ cp = ts->preview_stitch_face;
+ break;
+
+ case TH_STITCH_PREVIEW_EDGE:
+ cp = ts->preview_stitch_edge;
+ break;
+
+ case TH_STITCH_PREVIEW_VERT:
+ cp = ts->preview_stitch_vert;
+ break;
+
+ case TH_STITCH_PREVIEW_STITCHABLE:
+ cp = ts->preview_stitch_stitchable;
+ break;
+
+ case TH_STITCH_PREVIEW_UNSTITCHABLE:
+ cp = ts->preview_stitch_unstitchable;
+ break;
+ case TH_STITCH_PREVIEW_ACTIVE:
+ cp = ts->preview_stitch_active;
+ break;
+
+ case TH_PAINT_CURVE_HANDLE:
+ cp = ts->paint_curve_handle;
+ break;
+ case TH_PAINT_CURVE_PIVOT:
+ cp = ts->paint_curve_pivot;
+ break;
+
+ case TH_METADATA_BG:
+ cp = ts->metadatabg;
+ break;
+ case TH_METADATA_TEXT:
+ cp = ts->metadatatext;
+ break;
+
+ case TH_UV_OTHERS:
+ cp = ts->uv_others;
+ break;
+ case TH_UV_SHADOW:
+ cp = ts->uv_shadow;
+ break;
+
+ case TH_MARKER_OUTLINE:
+ cp = ts->marker_outline;
+ break;
+ case TH_MARKER:
+ cp = ts->marker;
+ break;
+ case TH_ACT_MARKER:
+ cp = ts->act_marker;
+ break;
+ case TH_SEL_MARKER:
+ cp = ts->sel_marker;
+ break;
+ case TH_BUNDLE_SOLID:
+ cp = ts->bundle_solid;
+ break;
+ case TH_DIS_MARKER:
+ cp = ts->dis_marker;
+ break;
+ case TH_PATH_BEFORE:
+ cp = ts->path_before;
+ break;
+ case TH_PATH_AFTER:
+ cp = ts->path_after;
+ break;
+ case TH_CAMERA_PATH:
+ cp = ts->camera_path;
+ break;
+ case TH_LOCK_MARKER:
+ cp = ts->lock_marker;
+ break;
+
+ case TH_MATCH:
+ cp = ts->match;
+ break;
+
+ case TH_SELECT_HIGHLIGHT:
+ cp = ts->selected_highlight;
+ break;
+
+ case TH_SKIN_ROOT:
+ cp = ts->skin_root;
+ break;
+
+ case TH_ANIM_ACTIVE:
+ cp = ts->anim_active;
+ break;
+ case TH_ANIM_INACTIVE:
+ cp = ts->anim_non_active;
+ break;
+ case TH_ANIM_PREVIEW_RANGE:
+ cp = ts->anim_preview_range;
+ break;
+
+ case TH_NLA_TWEAK:
+ cp = ts->nla_tweaking;
+ break;
+ case TH_NLA_TWEAK_DUPLI:
+ cp = ts->nla_tweakdupli;
+ break;
+
+ case TH_NLA_TRANSITION:
+ cp = ts->nla_transition;
+ break;
+ case TH_NLA_TRANSITION_SEL:
+ cp = ts->nla_transition_sel;
+ break;
+ case TH_NLA_META:
+ cp = ts->nla_meta;
+ break;
+ case TH_NLA_META_SEL:
+ cp = ts->nla_meta_sel;
+ break;
+ case TH_NLA_SOUND:
+ cp = ts->nla_sound;
+ break;
+ case TH_NLA_SOUND_SEL:
+ cp = ts->nla_sound_sel;
+ break;
+
+ case TH_WIDGET_EMBOSS:
+ cp = btheme->tui.widget_emboss;
+ break;
+
+ case TH_EDITOR_OUTLINE:
+ cp = btheme->tui.editor_outline;
+ break;
+ case TH_AXIS_X:
+ cp = btheme->tui.xaxis;
+ break;
+ case TH_AXIS_Y:
+ cp = btheme->tui.yaxis;
+ break;
+ case TH_AXIS_Z:
+ cp = btheme->tui.zaxis;
+ break;
+
+ case TH_GIZMO_HI:
+ cp = btheme->tui.gizmo_hi;
+ break;
+ case TH_GIZMO_PRIMARY:
+ cp = btheme->tui.gizmo_primary;
+ break;
+ case TH_GIZMO_SECONDARY:
+ cp = btheme->tui.gizmo_secondary;
+ break;
+ case TH_GIZMO_A:
+ cp = btheme->tui.gizmo_a;
+ break;
+ case TH_GIZMO_B:
+ cp = btheme->tui.gizmo_b;
+ break;
+
+ case TH_ICON_COLLECTION:
+ cp = btheme->tui.icon_collection;
+ break;
+ case TH_ICON_OBJECT:
+ cp = btheme->tui.icon_object;
+ break;
+ case TH_ICON_OBJECT_DATA:
+ cp = btheme->tui.icon_object_data;
+ break;
+ case TH_ICON_MODIFIER:
+ cp = btheme->tui.icon_modifier;
+ break;
+ case TH_ICON_SHADING:
+ cp = btheme->tui.icon_shading;
+ break;
+
+ case TH_INFO_SELECTED:
+ cp = ts->info_selected;
+ break;
+ case TH_INFO_SELECTED_TEXT:
+ cp = ts->info_selected_text;
+ break;
+ case TH_INFO_ERROR:
+ cp = ts->info_error;
+ break;
+ case TH_INFO_ERROR_TEXT:
+ cp = ts->info_error_text;
+ break;
+ case TH_INFO_WARNING:
+ cp = ts->info_warning;
+ break;
+ case TH_INFO_WARNING_TEXT:
+ cp = ts->info_warning_text;
+ break;
+ case TH_INFO_INFO:
+ cp = ts->info_info;
+ break;
+ case TH_INFO_INFO_TEXT:
+ cp = ts->info_info_text;
+ break;
+ case TH_INFO_DEBUG:
+ cp = ts->info_debug;
+ break;
+ case TH_INFO_DEBUG_TEXT:
+ cp = ts->info_debug_text;
+ break;
+ case TH_V3D_CLIPPING_BORDER:
+ cp = ts->clipping_border_3d;
+ break;
+ }
+ }
+ }
+
+ return (const uchar *)cp;
}
/**
@@ -764,53 +924,52 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
*/
void UI_theme_init_default(void)
{
- /* we search for the theme with name Default */
- bTheme *btheme = BLI_findstring(&U.themes, "Default", offsetof(bTheme, name));
- if (btheme == NULL) {
- btheme = MEM_callocN(sizeof(bTheme), __func__);
- BLI_addtail(&U.themes, btheme);
- }
-
- UI_SetTheme(0, 0); /* make sure the global used in this file is set */
-
- const int active_theme_area = btheme->active_theme_area;
- memcpy(btheme, &U_theme_default, sizeof(*btheme));
- btheme->active_theme_area = active_theme_area;
+ /* we search for the theme with name Default */
+ bTheme *btheme = BLI_findstring(&U.themes, "Default", offsetof(bTheme, name));
+ if (btheme == NULL) {
+ btheme = MEM_callocN(sizeof(bTheme), __func__);
+ BLI_addtail(&U.themes, btheme);
+ }
+
+ UI_SetTheme(0, 0); /* make sure the global used in this file is set */
+
+ const int active_theme_area = btheme->active_theme_area;
+ memcpy(btheme, &U_theme_default, sizeof(*btheme));
+ btheme->active_theme_area = active_theme_area;
}
void UI_style_init_default(void)
{
- BLI_freelistN(&U.uistyles);
- /* gets automatically re-allocated */
- uiStyleInit();
+ BLI_freelistN(&U.uistyles);
+ /* gets automatically re-allocated */
+ uiStyleInit();
}
-
void UI_SetTheme(int spacetype, int regionid)
{
- if (spacetype) {
- /* later on, a local theme can be found too */
- theme_active = U.themes.first;
- theme_spacetype = spacetype;
- theme_regionid = regionid;
- }
- else if (regionid) {
- /* popups */
- theme_active = U.themes.first;
- theme_spacetype = SPACE_PROPERTIES;
- theme_regionid = regionid;
- }
- else {
- /* for safety, when theme was deleted */
- theme_active = U.themes.first;
- theme_spacetype = SPACE_VIEW3D;
- theme_regionid = RGN_TYPE_WINDOW;
- }
+ if (spacetype) {
+ /* later on, a local theme can be found too */
+ theme_active = U.themes.first;
+ theme_spacetype = spacetype;
+ theme_regionid = regionid;
+ }
+ else if (regionid) {
+ /* popups */
+ theme_active = U.themes.first;
+ theme_spacetype = SPACE_PROPERTIES;
+ theme_regionid = regionid;
+ }
+ else {
+ /* for safety, when theme was deleted */
+ theme_active = U.themes.first;
+ theme_spacetype = SPACE_VIEW3D;
+ theme_regionid = RGN_TYPE_WINDOW;
+ }
}
bTheme *UI_GetTheme(void)
{
- return U.themes.first;
+ return U.themes.first;
}
/**
@@ -818,492 +977,487 @@ bTheme *UI_GetTheme(void)
*/
void UI_Theme_Store(struct bThemeState *theme_state)
{
- *theme_state = g_theme_state;
+ *theme_state = g_theme_state;
}
void UI_Theme_Restore(struct bThemeState *theme_state)
{
- g_theme_state = *theme_state;
+ g_theme_state = *theme_state;
}
void UI_GetThemeColorShadeAlpha4ubv(int colorid, int coloffset, int alphaoffset, uchar col[4])
{
- int r, g, b, a;
- const uchar *cp;
-
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- r = coloffset + (int) cp[0];
- CLAMP(r, 0, 255);
- g = coloffset + (int) cp[1];
- CLAMP(g, 0, 255);
- b = coloffset + (int) cp[2];
- CLAMP(b, 0, 255);
- a = alphaoffset + (int) cp[3];
- CLAMP(a, 0, 255);
-
- col[0] = r;
- col[1] = g;
- col[2] = b;
- col[3] = a;
+ int r, g, b, a;
+ const uchar *cp;
+
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ r = coloffset + (int)cp[0];
+ CLAMP(r, 0, 255);
+ g = coloffset + (int)cp[1];
+ CLAMP(g, 0, 255);
+ b = coloffset + (int)cp[2];
+ CLAMP(b, 0, 255);
+ a = alphaoffset + (int)cp[3];
+ CLAMP(a, 0, 255);
+
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = a;
}
void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, uchar col[3])
{
- const uchar *cp1, *cp2;
+ const uchar *cp1, *cp2;
- cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
- cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
- CLAMP(fac, 0.0f, 1.0f);
- col[0] = floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
- col[1] = floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
- col[2] = floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
+ CLAMP(fac, 0.0f, 1.0f);
+ col[0] = floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ col[1] = floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ col[2] = floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
}
void UI_GetThemeColorBlend3f(int colorid1, int colorid2, float fac, float r_col[3])
{
- const uchar *cp1, *cp2;
+ const uchar *cp1, *cp2;
- cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
- cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
- CLAMP(fac, 0.0f, 1.0f);
- r_col[0] = ((1.0f - fac) * cp1[0] + fac * cp2[0]) / 255.0f;
- r_col[1] = ((1.0f - fac) * cp1[1] + fac * cp2[1]) / 255.0f;
- r_col[2] = ((1.0f - fac) * cp1[2] + fac * cp2[2]) / 255.0f;
+ CLAMP(fac, 0.0f, 1.0f);
+ r_col[0] = ((1.0f - fac) * cp1[0] + fac * cp2[0]) / 255.0f;
+ r_col[1] = ((1.0f - fac) * cp1[1] + fac * cp2[1]) / 255.0f;
+ r_col[2] = ((1.0f - fac) * cp1[2] + fac * cp2[2]) / 255.0f;
}
void UI_GetThemeColorBlend4f(int colorid1, int colorid2, float fac, float r_col[4])
{
- const uchar *cp1, *cp2;
+ const uchar *cp1, *cp2;
- cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
- cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
- CLAMP(fac, 0.0f, 1.0f);
- r_col[0] = ((1.0f - fac) * cp1[0] + fac * cp2[0]) / 255.0f;
- r_col[1] = ((1.0f - fac) * cp1[1] + fac * cp2[1]) / 255.0f;
- r_col[2] = ((1.0f - fac) * cp1[2] + fac * cp2[2]) / 255.0f;
- r_col[3] = ((1.0f - fac) * cp1[3] + fac * cp2[3]) / 255.0f;
+ CLAMP(fac, 0.0f, 1.0f);
+ r_col[0] = ((1.0f - fac) * cp1[0] + fac * cp2[0]) / 255.0f;
+ r_col[1] = ((1.0f - fac) * cp1[1] + fac * cp2[1]) / 255.0f;
+ r_col[2] = ((1.0f - fac) * cp1[2] + fac * cp2[2]) / 255.0f;
+ r_col[3] = ((1.0f - fac) * cp1[3] + fac * cp2[3]) / 255.0f;
}
void UI_FontThemeColor(int fontid, int colorid)
{
- uchar color[4];
- UI_GetThemeColor4ubv(colorid, color);
- BLF_color4ubv(fontid, color);
+ uchar color[4];
+ UI_GetThemeColor4ubv(colorid, color);
+ BLF_color4ubv(fontid, color);
}
/* get individual values, not scaled */
float UI_GetThemeValuef(int colorid)
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- return ((float)cp[0]);
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ return ((float)cp[0]);
}
/* get individual values, not scaled */
int UI_GetThemeValue(int colorid)
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- return ((int) cp[0]);
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ return ((int)cp[0]);
}
/* versions of the function above, which take a space-type */
float UI_GetThemeValueTypef(int colorid, int spacetype)
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
- return ((float)cp[0]);
+ cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
+ return ((float)cp[0]);
}
int UI_GetThemeValueType(int colorid, int spacetype)
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
- return ((int)cp[0]);
+ cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
+ return ((int)cp[0]);
}
-
/* get the color, range 0.0-1.0 */
void UI_GetThemeColor3fv(int colorid, float col[3])
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- col[0] = ((float)cp[0]) / 255.0f;
- col[1] = ((float)cp[1]) / 255.0f;
- col[2] = ((float)cp[2]) / 255.0f;
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ col[0] = ((float)cp[0]) / 255.0f;
+ col[1] = ((float)cp[1]) / 255.0f;
+ col[2] = ((float)cp[2]) / 255.0f;
}
void UI_GetThemeColor4fv(int colorid, float col[4])
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- col[0] = ((float)cp[0]) / 255.0f;
- col[1] = ((float)cp[1]) / 255.0f;
- col[2] = ((float)cp[2]) / 255.0f;
- col[3] = ((float)cp[3]) / 255.0f;
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ col[0] = ((float)cp[0]) / 255.0f;
+ col[1] = ((float)cp[1]) / 255.0f;
+ col[2] = ((float)cp[2]) / 255.0f;
+ col[3] = ((float)cp[3]) / 255.0f;
}
void UI_GetThemeColorType4fv(int colorid, int spacetype, float col[4])
{
- const unsigned char *cp;
+ const unsigned char *cp;
- cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
- col[0] = ((float)cp[0]) / 255.0f;
- col[1] = ((float)cp[1]) / 255.0f;
- col[2] = ((float)cp[2]) / 255.0f;
- col[3] = ((float)cp[3]) / 255.0f;
+ cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
+ col[0] = ((float)cp[0]) / 255.0f;
+ col[1] = ((float)cp[1]) / 255.0f;
+ col[2] = ((float)cp[2]) / 255.0f;
+ col[3] = ((float)cp[3]) / 255.0f;
}
/* get the color, range 0.0-1.0, complete with shading offset */
void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3])
{
- int r, g, b;
- const uchar *cp;
+ int r, g, b;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- r = offset + (int) cp[0];
- CLAMP(r, 0, 255);
- g = offset + (int) cp[1];
- CLAMP(g, 0, 255);
- b = offset + (int) cp[2];
- CLAMP(b, 0, 255);
+ r = offset + (int)cp[0];
+ CLAMP(r, 0, 255);
+ g = offset + (int)cp[1];
+ CLAMP(g, 0, 255);
+ b = offset + (int)cp[2];
+ CLAMP(b, 0, 255);
- col[0] = ((float)r) / 255.0f;
- col[1] = ((float)g) / 255.0f;
- col[2] = ((float)b) / 255.0f;
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
}
void UI_GetThemeColorShade3ubv(int colorid, int offset, uchar col[3])
{
- int r, g, b;
- const uchar *cp;
+ int r, g, b;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- r = offset + (int) cp[0];
- CLAMP(r, 0, 255);
- g = offset + (int) cp[1];
- CLAMP(g, 0, 255);
- b = offset + (int) cp[2];
- CLAMP(b, 0, 255);
+ r = offset + (int)cp[0];
+ CLAMP(r, 0, 255);
+ g = offset + (int)cp[1];
+ CLAMP(g, 0, 255);
+ b = offset + (int)cp[2];
+ CLAMP(b, 0, 255);
- col[0] = r;
- col[1] = g;
- col[2] = b;
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
}
-void UI_GetThemeColorBlendShade3ubv(int colorid1, int colorid2, float fac, int offset, uchar col[3])
+void UI_GetThemeColorBlendShade3ubv(
+ int colorid1, int colorid2, float fac, int offset, uchar col[3])
{
- const uchar *cp1, *cp2;
+ const uchar *cp1, *cp2;
- cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
- cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
- CLAMP(fac, 0.0f, 1.0f);
+ CLAMP(fac, 0.0f, 1.0f);
- float blend[3];
- blend[0] = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
- blend[1] = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
- blend[2] = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
+ float blend[3];
+ blend[0] = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ blend[1] = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ blend[2] = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
- unit_float_to_uchar_clamp_v3(col, blend);
+ unit_float_to_uchar_clamp_v3(col, blend);
}
void UI_GetThemeColorShade4ubv(int colorid, int offset, uchar col[4])
{
- int r, g, b;
- const uchar *cp;
-
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- r = offset + (int) cp[0];
- CLAMP(r, 0, 255);
- g = offset + (int) cp[1];
- CLAMP(g, 0, 255);
- b = offset + (int) cp[2];
- CLAMP(b, 0, 255);
-
- col[0] = r;
- col[1] = g;
- col[2] = b;
- col[3] = cp[3];
+ int r, g, b;
+ const uchar *cp;
+
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ r = offset + (int)cp[0];
+ CLAMP(r, 0, 255);
+ g = offset + (int)cp[1];
+ CLAMP(g, 0, 255);
+ b = offset + (int)cp[2];
+ CLAMP(b, 0, 255);
+
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = cp[3];
}
void UI_GetThemeColorShadeAlpha4fv(int colorid, int coloffset, int alphaoffset, float col[4])
{
- int r, g, b, a;
- const uchar *cp;
-
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
-
- r = coloffset + (int) cp[0];
- CLAMP(r, 0, 255);
- g = coloffset + (int) cp[1];
- CLAMP(g, 0, 255);
- b = coloffset + (int) cp[2];
- CLAMP(b, 0, 255);
- a = alphaoffset + (int) cp[3];
- CLAMP(b, 0, 255);
-
- col[0] = ((float)r) / 255.0f;
- col[1] = ((float)g) / 255.0f;
- col[2] = ((float)b) / 255.0f;
- col[3] = ((float)a) / 255.0f;
+ int r, g, b, a;
+ const uchar *cp;
+
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+
+ r = coloffset + (int)cp[0];
+ CLAMP(r, 0, 255);
+ g = coloffset + (int)cp[1];
+ CLAMP(g, 0, 255);
+ b = coloffset + (int)cp[2];
+ CLAMP(b, 0, 255);
+ a = alphaoffset + (int)cp[3];
+ CLAMP(b, 0, 255);
+
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
+ col[3] = ((float)a) / 255.0f;
}
void UI_GetThemeColorBlendShade3fv(int colorid1, int colorid2, float fac, int offset, float col[3])
{
- int r, g, b;
- const uchar *cp1, *cp2;
+ int r, g, b;
+ const uchar *cp1, *cp2;
- cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
- cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
- CLAMP(fac, 0.0f, 1.0f);
+ CLAMP(fac, 0.0f, 1.0f);
- r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
- CLAMP(r, 0, 255);
- g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
- CLAMP(g, 0, 255);
- b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
- CLAMP(b, 0, 255);
+ r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ CLAMP(r, 0, 255);
+ g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ CLAMP(g, 0, 255);
+ b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
+ CLAMP(b, 0, 255);
- col[0] = ((float)r) / 255.0f;
- col[1] = ((float)g) / 255.0f;
- col[2] = ((float)b) / 255.0f;
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
}
void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4])
{
- int r, g, b, a;
- const uchar *cp1, *cp2;
-
- cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
- cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
-
- CLAMP(fac, 0.0f, 1.0f);
-
- r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
- CLAMP(r, 0, 255);
- g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
- CLAMP(g, 0, 255);
- b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
- CLAMP(b, 0, 255);
- a = offset + floorf((1.0f - fac) * cp1[3] + fac * cp2[3]);
- CLAMP(a, 0, 255);
-
- col[0] = ((float)r) / 255.0f;
- col[1] = ((float)g) / 255.0f;
- col[2] = ((float)b) / 255.0f;
- col[3] = ((float)a) / 255.0f;
+ int r, g, b, a;
+ const uchar *cp1, *cp2;
+
+ cp1 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
+ cp2 = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
+
+ CLAMP(fac, 0.0f, 1.0f);
+
+ r = offset + floorf((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ CLAMP(r, 0, 255);
+ g = offset + floorf((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ CLAMP(g, 0, 255);
+ b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]);
+ CLAMP(b, 0, 255);
+ a = offset + floorf((1.0f - fac) * cp1[3] + fac * cp2[3]);
+ CLAMP(a, 0, 255);
+
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
+ col[3] = ((float)a) / 255.0f;
}
/* get the color, in char pointer */
void UI_GetThemeColor3ubv(int colorid, uchar col[3])
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- col[0] = cp[0];
- col[1] = cp[1];
- col[2] = cp[2];
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ col[0] = cp[0];
+ col[1] = cp[1];
+ col[2] = cp[2];
}
/* get the color, range 0.0-1.0, complete with shading offset */
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
{
- int r, g, b, a;
- const uchar *cp;
+ int r, g, b, a;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- r = offset + (int) cp[0];
- CLAMP(r, 0, 255);
- g = offset + (int) cp[1];
- CLAMP(g, 0, 255);
- b = offset + (int) cp[2];
- CLAMP(b, 0, 255);
+ r = offset + (int)cp[0];
+ CLAMP(r, 0, 255);
+ g = offset + (int)cp[1];
+ CLAMP(g, 0, 255);
+ b = offset + (int)cp[2];
+ CLAMP(b, 0, 255);
- a = (int) cp[3]; /* no shading offset... */
- CLAMP(a, 0, 255);
+ a = (int)cp[3]; /* no shading offset... */
+ CLAMP(a, 0, 255);
- col[0] = ((float)r) / 255.0f;
- col[1] = ((float)g) / 255.0f;
- col[2] = ((float)b) / 255.0f;
- col[3] = ((float)a) / 255.0f;
+ col[0] = ((float)r) / 255.0f;
+ col[1] = ((float)g) / 255.0f;
+ col[2] = ((float)b) / 255.0f;
+ col[3] = ((float)a) / 255.0f;
}
/* get the color, in char pointer */
void UI_GetThemeColor4ubv(int colorid, uchar col[4])
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- col[0] = cp[0];
- col[1] = cp[1];
- col[2] = cp[2];
- col[3] = cp[3];
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ col[0] = cp[0];
+ col[1] = cp[1];
+ col[2] = cp[2];
+ col[3] = cp[3];
}
void UI_GetThemeColorType3fv(int colorid, int spacetype, float col[3])
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
- col[0] = ((float)cp[0]) / 255.0f;
- col[1] = ((float)cp[1]) / 255.0f;
- col[2] = ((float)cp[2]) / 255.0f;
+ cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
+ col[0] = ((float)cp[0]) / 255.0f;
+ col[1] = ((float)cp[1]) / 255.0f;
+ col[2] = ((float)cp[2]) / 255.0f;
}
void UI_GetThemeColorType3ubv(int colorid, int spacetype, uchar col[3])
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
- col[0] = cp[0];
- col[1] = cp[1];
- col[2] = cp[2];
+ cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
+ col[0] = cp[0];
+ col[1] = cp[1];
+ col[2] = cp[2];
}
void UI_GetThemeColorType4ubv(int colorid, int spacetype, uchar col[4])
{
- const uchar *cp;
+ const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
- col[0] = cp[0];
- col[1] = cp[1];
- col[2] = cp[2];
- col[3] = cp[3];
+ cp = UI_ThemeGetColorPtr(theme_active, spacetype, colorid);
+ col[0] = cp[0];
+ col[1] = cp[1];
+ col[2] = cp[2];
+ col[3] = cp[3];
}
bool UI_GetIconThemeColor4fv(int colorid, float col[4])
{
- if (colorid == 0) {
- return false;
- }
-
- /* Only colored icons in outliner and popups, overall UI is intended
- * to stay monochrome and out of the way except a few places where it
- * is important to communicate different data types. */
- if (!((theme_spacetype == SPACE_OUTLINER) ||
- (theme_regionid == RGN_TYPE_TEMPORARY)))
- {
- return false;
- }
-
- const uchar *cp;
- cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
- col[0] = ((float)cp[0]) / 255.0f;
- col[1] = ((float)cp[1]) / 255.0f;
- col[2] = ((float)cp[2]) / 255.0f;
- col[3] = ((float)cp[3]) / 255.0f;
-
- return true;
+ if (colorid == 0) {
+ return false;
+ }
+
+ /* Only colored icons in outliner and popups, overall UI is intended
+ * to stay monochrome and out of the way except a few places where it
+ * is important to communicate different data types. */
+ if (!((theme_spacetype == SPACE_OUTLINER) || (theme_regionid == RGN_TYPE_TEMPORARY))) {
+ return false;
+ }
+
+ const uchar *cp;
+ cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
+ col[0] = ((float)cp[0]) / 255.0f;
+ col[1] = ((float)cp[1]) / 255.0f;
+ col[2] = ((float)cp[2]) / 255.0f;
+ col[3] = ((float)cp[3]) / 255.0f;
+
+ return true;
}
void UI_GetColorPtrShade3ubv(const uchar cp[3], uchar col[3], int offset)
{
- int r, g, b;
+ int r, g, b;
- r = offset + (int)cp[0];
- g = offset + (int)cp[1];
- b = offset + (int)cp[2];
+ r = offset + (int)cp[0];
+ g = offset + (int)cp[1];
+ b = offset + (int)cp[2];
- CLAMP(r, 0, 255);
- CLAMP(g, 0, 255);
- CLAMP(b, 0, 255);
+ CLAMP(r, 0, 255);
+ CLAMP(g, 0, 255);
+ CLAMP(b, 0, 255);
- col[0] = r;
- col[1] = g;
- col[2] = b;
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
}
/* get a 3 byte color, blended and shaded between two other char color pointers */
void UI_GetColorPtrBlendShade3ubv(
- const uchar cp1[3], const uchar cp2[3], uchar col[3],
- float fac, int offset)
+ const uchar cp1[3], const uchar cp2[3], uchar col[3], float fac, int offset)
{
- int r, g, b;
+ int r, g, b;
- CLAMP(fac, 0.0f, 1.0f);
- r = offset + floor((1.0f - fac) * cp1[0] + fac * cp2[0]);
- g = offset + floor((1.0f - fac) * cp1[1] + fac * cp2[1]);
- b = offset + floor((1.0f - fac) * cp1[2] + fac * cp2[2]);
+ CLAMP(fac, 0.0f, 1.0f);
+ r = offset + floor((1.0f - fac) * cp1[0] + fac * cp2[0]);
+ g = offset + floor((1.0f - fac) * cp1[1] + fac * cp2[1]);
+ b = offset + floor((1.0f - fac) * cp1[2] + fac * cp2[2]);
- CLAMP(r, 0, 255);
- CLAMP(g, 0, 255);
- CLAMP(b, 0, 255);
+ CLAMP(r, 0, 255);
+ CLAMP(g, 0, 255);
+ CLAMP(b, 0, 255);
- col[0] = r;
- col[1] = g;
- col[2] = b;
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
}
void UI_ThemeClearColor(int colorid)
{
- float col[3];
+ float col[3];
- UI_GetThemeColor3fv(colorid, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0f);
+ UI_GetThemeColor3fv(colorid, col);
+ GPU_clear_color(col[0], col[1], col[2], 0.0f);
}
void UI_ThemeClearColorAlpha(int colorid, float alpha)
{
- float col[3];
- UI_GetThemeColor3fv(colorid, col);
- GPU_clear_color(col[0], col[1], col[2], alpha);
+ float col[3];
+ UI_GetThemeColor3fv(colorid, col);
+ GPU_clear_color(col[0], col[1], col[2], alpha);
}
-
int UI_ThemeMenuShadowWidth(void)
{
- bTheme *btheme = UI_GetTheme();
- return (int)(btheme->tui.menu_shadow_width * UI_DPI_FAC);
+ bTheme *btheme = UI_GetTheme();
+ return (int)(btheme->tui.menu_shadow_width * UI_DPI_FAC);
}
void UI_make_axis_color(const uchar src_col[3], uchar dst_col[3], const char axis)
{
- uchar col[3];
-
- switch (axis) {
- case 'X':
- UI_GetThemeColor3ubv(TH_AXIS_X, col);
- UI_GetColorPtrBlendShade3ubv(src_col, col, dst_col, 0.5f, -10);
- break;
- case 'Y':
- UI_GetThemeColor3ubv(TH_AXIS_Y, col);
- UI_GetColorPtrBlendShade3ubv(src_col, col, dst_col, 0.5f, -10);
- break;
- case 'Z':
- UI_GetThemeColor3ubv(TH_AXIS_Z, col);
- UI_GetColorPtrBlendShade3ubv(src_col, col, dst_col, 0.5f, -10);
- break;
- default:
- BLI_assert(0);
- break;
- }
+ uchar col[3];
+
+ switch (axis) {
+ case 'X':
+ UI_GetThemeColor3ubv(TH_AXIS_X, col);
+ UI_GetColorPtrBlendShade3ubv(src_col, col, dst_col, 0.5f, -10);
+ break;
+ case 'Y':
+ UI_GetThemeColor3ubv(TH_AXIS_Y, col);
+ UI_GetColorPtrBlendShade3ubv(src_col, col, dst_col, 0.5f, -10);
+ break;
+ case 'Z':
+ UI_GetThemeColor3ubv(TH_AXIS_Z, col);
+ UI_GetColorPtrBlendShade3ubv(src_col, col, dst_col, 0.5f, -10);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
}
/* patching UserDef struct and Themes */
void init_userdef_do_versions(Main *bmain)
{
- BLO_version_defaults_userpref_blend(bmain, &U);
+ BLO_version_defaults_userpref_blend(bmain, &U);
- if (STREQ(U.tempdir, "/")) {
- BKE_tempdir_system_init(U.tempdir);
- }
+ if (STREQ(U.tempdir, "/")) {
+ BKE_tempdir_system_init(U.tempdir);
+ }
- /* Not versioning, just avoid errors. */
+ /* Not versioning, just avoid errors. */
#ifndef WITH_CYCLES
- BKE_addon_remove_safe(&U.addons, "cycles");
+ BKE_addon_remove_safe(&U.addons, "cycles");
#endif
-
}
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index a01088277f2..fa56721c11f 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
#include <float.h>
#include <limits.h>
#include <math.h>
@@ -64,18 +63,18 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize, bool mas
BLI_INLINE int clamp_float_to_int(const float f)
{
- const float min = INT_MIN;
- const float max = INT_MAX;
-
- if (UNLIKELY(f < min)) {
- return min;
- }
- else if (UNLIKELY(f > max)) {
- return (int)max;
- }
- else {
- return (int)f;
- }
+ const float min = INT_MIN;
+ const float max = INT_MAX;
+
+ if (UNLIKELY(f < min)) {
+ return min;
+ }
+ else if (UNLIKELY(f > max)) {
+ return (int)max;
+ }
+ else {
+ return (int)f;
+ }
}
/**
@@ -84,13 +83,12 @@ BLI_INLINE int clamp_float_to_int(const float f)
*/
BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src)
{
- dst->xmin = clamp_float_to_int(src->xmin);
- dst->xmax = clamp_float_to_int(src->xmax);
- dst->ymin = clamp_float_to_int(src->ymin);
- dst->ymax = clamp_float_to_int(src->ymax);
+ dst->xmin = clamp_float_to_int(src->xmin);
+ dst->xmax = clamp_float_to_int(src->xmax);
+ dst->ymin = clamp_float_to_int(src->ymin);
+ dst->ymax = clamp_float_to_int(src->ymax);
}
-
/* XXX still unresolved: scrolls hide/unhide vs region mask handling */
/* XXX there's V2D_SCROLL_HORIZONTAL_HIDE and V2D_SCROLL_HORIZONTAL_FULLR ... */
@@ -103,21 +101,21 @@ BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src)
*/
static int view2d_scroll_mapped(int scroll)
{
- if (scroll & V2D_SCROLL_HORIZONTAL_FULLR) {
- scroll &= ~(V2D_SCROLL_HORIZONTAL);
- }
- if (scroll & V2D_SCROLL_VERTICAL_FULLR) {
- scroll &= ~(V2D_SCROLL_VERTICAL);
- }
- return scroll;
+ if (scroll & V2D_SCROLL_HORIZONTAL_FULLR) {
+ scroll &= ~(V2D_SCROLL_HORIZONTAL);
+ }
+ if (scroll & V2D_SCROLL_VERTICAL_FULLR) {
+ scroll &= ~(V2D_SCROLL_VERTICAL);
+ }
+ return scroll;
}
void UI_view2d_mask_from_win(const View2D *v2d, rcti *r_mask)
{
- r_mask->xmin = 0;
- r_mask->ymin = 0;
- r_mask->xmax = v2d->winx - 1; /* -1 yes! masks are pixels */
- r_mask->ymax = v2d->winy - 1;
+ r_mask->xmin = 0;
+ r_mask->ymin = 0;
+ r_mask->xmax = v2d->winx - 1; /* -1 yes! masks are pixels */
+ r_mask->ymax = v2d->winy - 1;
}
/**
@@ -127,87 +125,88 @@ void UI_view2d_mask_from_win(const View2D *v2d, rcti *r_mask)
*/
static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scroll)
{
- int scroll;
-
- /* mask - view frame */
- UI_view2d_mask_from_win(v2d, &v2d->mask);
- if (mask_scroll == NULL) {
- mask_scroll = &v2d->mask;
- }
-
- if (check_scrollers) {
- /* check size if hiding flag is set: */
- if (v2d->scroll & V2D_SCROLL_HORIZONTAL_HIDE) {
- if (!(v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL)) {
- if (BLI_rctf_size_x(&v2d->tot) > BLI_rctf_size_x(&v2d->cur)) {
- v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR;
- }
- else {
- v2d->scroll |= V2D_SCROLL_HORIZONTAL_FULLR;
- }
- }
- }
- if (v2d->scroll & V2D_SCROLL_VERTICAL_HIDE) {
- if (!(v2d->scroll & V2D_SCROLL_SCALE_VERTICAL)) {
- if (BLI_rctf_size_y(&v2d->tot) + 0.01f > BLI_rctf_size_y(&v2d->cur)) {
- v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR;
- }
- else {
- v2d->scroll |= V2D_SCROLL_VERTICAL_FULLR;
- }
- }
- }
- }
-
- scroll = view2d_scroll_mapped(v2d->scroll);
-
- /* scrollers are based off regionsize
- * - they can only be on one to two edges of the region they define
- * - if they overlap, they must not occupy the corners (which are reserved for other widgets)
- */
- if (scroll) {
- const int scroll_width = (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) ?
- V2D_SCROLL_WIDTH_TEXT : V2D_SCROLL_WIDTH;
- const int scroll_height = (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) ?
- V2D_SCROLL_HEIGHT_TEXT : V2D_SCROLL_HEIGHT;
-
- /* vertical scroller */
- if (scroll & V2D_SCROLL_LEFT) {
- /* on left-hand edge of region */
- v2d->vert = *mask_scroll;
- v2d->vert.xmax = scroll_width;
- }
- else if (scroll & V2D_SCROLL_RIGHT) {
- /* on right-hand edge of region */
- v2d->vert = *mask_scroll;
- v2d->vert.xmax++; /* one pixel extra... was leaving a minor gap... */
- v2d->vert.xmin = v2d->vert.xmax - scroll_width;
- }
-
- /* horizontal scroller */
- if (scroll & (V2D_SCROLL_BOTTOM)) {
- /* on bottom edge of region */
- v2d->hor = *mask_scroll;
- v2d->hor.ymax = scroll_height;
- }
- else if (scroll & V2D_SCROLL_TOP) {
- /* on upper edge of region */
- v2d->hor = *mask_scroll;
- v2d->hor.ymin = v2d->hor.ymax - scroll_height;
- }
-
- /* adjust vertical scroller if there's a horizontal scroller, to leave corner free */
- if (scroll & V2D_SCROLL_VERTICAL) {
- if (scroll & (V2D_SCROLL_BOTTOM)) {
- /* on bottom edge of region */
- v2d->vert.ymin = v2d->hor.ymax;
- }
- else if (scroll & V2D_SCROLL_TOP) {
- /* on upper edge of region */
- v2d->vert.ymax = v2d->hor.ymin;
- }
- }
- }
+ int scroll;
+
+ /* mask - view frame */
+ UI_view2d_mask_from_win(v2d, &v2d->mask);
+ if (mask_scroll == NULL) {
+ mask_scroll = &v2d->mask;
+ }
+
+ if (check_scrollers) {
+ /* check size if hiding flag is set: */
+ if (v2d->scroll & V2D_SCROLL_HORIZONTAL_HIDE) {
+ if (!(v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL)) {
+ if (BLI_rctf_size_x(&v2d->tot) > BLI_rctf_size_x(&v2d->cur)) {
+ v2d->scroll &= ~V2D_SCROLL_HORIZONTAL_FULLR;
+ }
+ else {
+ v2d->scroll |= V2D_SCROLL_HORIZONTAL_FULLR;
+ }
+ }
+ }
+ if (v2d->scroll & V2D_SCROLL_VERTICAL_HIDE) {
+ if (!(v2d->scroll & V2D_SCROLL_SCALE_VERTICAL)) {
+ if (BLI_rctf_size_y(&v2d->tot) + 0.01f > BLI_rctf_size_y(&v2d->cur)) {
+ v2d->scroll &= ~V2D_SCROLL_VERTICAL_FULLR;
+ }
+ else {
+ v2d->scroll |= V2D_SCROLL_VERTICAL_FULLR;
+ }
+ }
+ }
+ }
+
+ scroll = view2d_scroll_mapped(v2d->scroll);
+
+ /* scrollers are based off regionsize
+ * - they can only be on one to two edges of the region they define
+ * - if they overlap, they must not occupy the corners (which are reserved for other widgets)
+ */
+ if (scroll) {
+ const int scroll_width = (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) ? V2D_SCROLL_WIDTH_TEXT :
+ V2D_SCROLL_WIDTH;
+ const int scroll_height = (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) ?
+ V2D_SCROLL_HEIGHT_TEXT :
+ V2D_SCROLL_HEIGHT;
+
+ /* vertical scroller */
+ if (scroll & V2D_SCROLL_LEFT) {
+ /* on left-hand edge of region */
+ v2d->vert = *mask_scroll;
+ v2d->vert.xmax = scroll_width;
+ }
+ else if (scroll & V2D_SCROLL_RIGHT) {
+ /* on right-hand edge of region */
+ v2d->vert = *mask_scroll;
+ v2d->vert.xmax++; /* one pixel extra... was leaving a minor gap... */
+ v2d->vert.xmin = v2d->vert.xmax - scroll_width;
+ }
+
+ /* horizontal scroller */
+ if (scroll & (V2D_SCROLL_BOTTOM)) {
+ /* on bottom edge of region */
+ v2d->hor = *mask_scroll;
+ v2d->hor.ymax = scroll_height;
+ }
+ else if (scroll & V2D_SCROLL_TOP) {
+ /* on upper edge of region */
+ v2d->hor = *mask_scroll;
+ v2d->hor.ymin = v2d->hor.ymax - scroll_height;
+ }
+
+ /* adjust vertical scroller if there's a horizontal scroller, to leave corner free */
+ if (scroll & V2D_SCROLL_VERTICAL) {
+ if (scroll & (V2D_SCROLL_BOTTOM)) {
+ /* on bottom edge of region */
+ v2d->vert.ymin = v2d->hor.ymax;
+ }
+ else if (scroll & V2D_SCROLL_TOP) {
+ /* on upper edge of region */
+ v2d->vert.ymax = v2d->hor.ymin;
+ }
+ }
+ }
}
/* Refresh and Validation */
@@ -221,175 +220,169 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr
*/
void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
{
- bool tot_changed = false, do_init;
- uiStyle *style = UI_style_get();
-
- do_init = (v2d->flag & V2D_IS_INITIALISED) == 0;
-
- /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
- switch (type) {
- /* 'standard view' - optimum setup for 'standard' view behavior,
- * that should be used new views as basis for their
- * own unique View2D settings, which should be used instead of this in most cases...
- */
- case V2D_COMMONVIEW_STANDARD:
- {
- /* for now, aspect ratio should be maintained,
- * and zoom is clamped within sane default limits */
- v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM);
- v2d->minzoom = 0.01f;
- v2d->maxzoom = 1000.0f;
-
- /* tot rect and cur should be same size, and aligned using 'standard' OpenGL coordinates for now
- * - region can resize 'tot' later to fit other data
- * - keeptot is only within bounds, as strict locking is not that critical
- * - view is aligned for (0,0) -> (winx-1, winy-1) setup
- */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_BOUNDS;
-
- if (do_init) {
- v2d->tot.xmin = v2d->tot.ymin = 0.0f;
- v2d->tot.xmax = (float)(winx - 1);
- v2d->tot.ymax = (float)(winy - 1);
-
- v2d->cur = v2d->tot;
- }
- /* scrollers - should we have these by default? */
- /* XXX for now, we don't override this, or set it either! */
- break;
- }
- /* 'list/channel view' - zoom, aspect ratio, and alignment restrictions are set here */
- case V2D_COMMONVIEW_LIST:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
-
- /* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = do_init;
-
- /* scroller settings are currently not set here... that is left for regions... */
- break;
- }
- /* 'stack view' - practically the same as list/channel view, except is located in the pos y half instead.
- * zoom, aspect ratio, and alignment restrictions are set here */
- case V2D_COMMONVIEW_STACK:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
-
- /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = do_init;
-
- /* scroller settings are currently not set here... that is left for regions... */
- break;
- }
- /* 'header' regions - zoom, aspect ratio,
- * alignment, and panning restrictions are set here */
- case V2D_COMMONVIEW_HEADER:
- {
- /* zoom + aspect ratio are locked */
- v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
- v2d->minzoom = v2d->maxzoom = 1.0f;
-
- if (do_init) {
- v2d->tot.xmin = 0.0f;
- v2d->tot.xmax = winx;
- v2d->tot.ymin = 0.0f;
- v2d->tot.ymax = winy;
- v2d->cur = v2d->tot;
-
- v2d->min[0] = v2d->max[0] = (float)(winx - 1);
- v2d->min[1] = v2d->max[1] = (float)(winy - 1);
- }
- /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
- v2d->keeptot = V2D_KEEPTOT_STRICT;
- tot_changed = do_init;
-
- /* panning in y-axis is prohibited */
- v2d->keepofs = V2D_LOCKOFS_Y;
-
- /* absolutely no scrollers allowed */
- v2d->scroll = 0;
- break;
- }
- /* panels view, with horizontal/vertical align */
- case V2D_COMMONVIEW_PANELS_UI:
- {
-
- /* for now, aspect ratio should be maintained,
- * and zoom is clamped within sane default limits */
- v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM | V2D_KEEPZOOM);
- v2d->minzoom = 0.5f;
- v2d->maxzoom = 2.0f;
-
- v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
- v2d->keeptot = V2D_KEEPTOT_BOUNDS;
-
- /* note, scroll is being flipped in ED_region_panels() drawing */
- v2d->scroll |= (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_VERTICAL_HIDE);
-
- /* initialize without scroll bars (interferes with zoom level see: T47047) */
- if (do_init) {
- v2d->scroll |= (V2D_SCROLL_VERTICAL_FULLR | V2D_SCROLL_HORIZONTAL_FULLR);
- }
-
- if (do_init) {
- float panelzoom = (style) ? style->panelzoom : 1.0f;
-
- v2d->tot.xmin = 0.0f;
- v2d->tot.xmax = winx;
-
- v2d->tot.ymax = 0.0f;
- v2d->tot.ymin = -winy;
-
- v2d->cur.xmin = 0.0f;
- v2d->cur.xmax = (winx) * panelzoom;
-
- v2d->cur.ymax = 0.0f;
- v2d->cur.ymin = (-winy) * panelzoom;
- }
- break;
- }
- /* other view types are completely defined using their own settings already */
- default:
- /* we don't do anything here,
- * as settings should be fine, but just make sure that rect */
- break;
- }
-
- /* set initialized flag so that View2D doesn't get reinitialised next time again */
- v2d->flag |= V2D_IS_INITIALISED;
-
- /* store view size */
- v2d->winx = winx;
- v2d->winy = winy;
-
- /* set masks (always do), but leave scroller scheck to totrect_set */
- view2d_masks(v2d, 0, NULL);
-
- if (do_init) {
- /* Visible by default. */
- v2d->alpha_hor = v2d->alpha_vert = 255;
- }
-
- /* set 'tot' rect before setting cur? */
- /* XXX confusing stuff here still -
- * I made this function not check scroller hide - that happens in totrect_set */
- if (tot_changed) {
- UI_view2d_totRect_set_resize(v2d, winx, winy, !do_init);
- }
- else {
- ui_view2d_curRect_validate_resize(v2d, !do_init, 0);
- }
-
+ bool tot_changed = false, do_init;
+ uiStyle *style = UI_style_get();
+
+ do_init = (v2d->flag & V2D_IS_INITIALISED) == 0;
+
+ /* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
+ switch (type) {
+ /* 'standard view' - optimum setup for 'standard' view behavior,
+ * that should be used new views as basis for their
+ * own unique View2D settings, which should be used instead of this in most cases...
+ */
+ case V2D_COMMONVIEW_STANDARD: {
+ /* for now, aspect ratio should be maintained,
+ * and zoom is clamped within sane default limits */
+ v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM);
+ v2d->minzoom = 0.01f;
+ v2d->maxzoom = 1000.0f;
+
+ /* tot rect and cur should be same size, and aligned using 'standard' OpenGL coordinates for now
+ * - region can resize 'tot' later to fit other data
+ * - keeptot is only within bounds, as strict locking is not that critical
+ * - view is aligned for (0,0) -> (winx-1, winy-1) setup
+ */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_BOUNDS;
+
+ if (do_init) {
+ v2d->tot.xmin = v2d->tot.ymin = 0.0f;
+ v2d->tot.xmax = (float)(winx - 1);
+ v2d->tot.ymax = (float)(winy - 1);
+
+ v2d->cur = v2d->tot;
+ }
+ /* scrollers - should we have these by default? */
+ /* XXX for now, we don't override this, or set it either! */
+ break;
+ }
+ /* 'list/channel view' - zoom, aspect ratio, and alignment restrictions are set here */
+ case V2D_COMMONVIEW_LIST: {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
+
+ /* tot rect has strictly regulated placement, and must only occur in +/- quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* scroller settings are currently not set here... that is left for regions... */
+ break;
+ }
+ /* 'stack view' - practically the same as list/channel view, except is located in the pos y half instead.
+ * zoom, aspect ratio, and alignment restrictions are set here */
+ case V2D_COMMONVIEW_STACK: {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
+
+ /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* scroller settings are currently not set here... that is left for regions... */
+ break;
+ }
+ /* 'header' regions - zoom, aspect ratio,
+ * alignment, and panning restrictions are set here */
+ case V2D_COMMONVIEW_HEADER: {
+ /* zoom + aspect ratio are locked */
+ v2d->keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT);
+ v2d->minzoom = v2d->maxzoom = 1.0f;
+
+ if (do_init) {
+ v2d->tot.xmin = 0.0f;
+ v2d->tot.xmax = winx;
+ v2d->tot.ymin = 0.0f;
+ v2d->tot.ymax = winy;
+ v2d->cur = v2d->tot;
+
+ v2d->min[0] = v2d->max[0] = (float)(winx - 1);
+ v2d->min[1] = v2d->max[1] = (float)(winy - 1);
+ }
+ /* tot rect has strictly regulated placement, and must only occur in +/+ quadrant */
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y);
+ v2d->keeptot = V2D_KEEPTOT_STRICT;
+ tot_changed = do_init;
+
+ /* panning in y-axis is prohibited */
+ v2d->keepofs = V2D_LOCKOFS_Y;
+
+ /* absolutely no scrollers allowed */
+ v2d->scroll = 0;
+ break;
+ }
+ /* panels view, with horizontal/vertical align */
+ case V2D_COMMONVIEW_PANELS_UI: {
+
+ /* for now, aspect ratio should be maintained,
+ * and zoom is clamped within sane default limits */
+ v2d->keepzoom = (V2D_KEEPASPECT | V2D_LIMITZOOM | V2D_KEEPZOOM);
+ v2d->minzoom = 0.5f;
+ v2d->maxzoom = 2.0f;
+
+ v2d->align = (V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y);
+ v2d->keeptot = V2D_KEEPTOT_BOUNDS;
+
+ /* note, scroll is being flipped in ED_region_panels() drawing */
+ v2d->scroll |= (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_VERTICAL_HIDE);
+
+ /* initialize without scroll bars (interferes with zoom level see: T47047) */
+ if (do_init) {
+ v2d->scroll |= (V2D_SCROLL_VERTICAL_FULLR | V2D_SCROLL_HORIZONTAL_FULLR);
+ }
+
+ if (do_init) {
+ float panelzoom = (style) ? style->panelzoom : 1.0f;
+
+ v2d->tot.xmin = 0.0f;
+ v2d->tot.xmax = winx;
+
+ v2d->tot.ymax = 0.0f;
+ v2d->tot.ymin = -winy;
+
+ v2d->cur.xmin = 0.0f;
+ v2d->cur.xmax = (winx)*panelzoom;
+
+ v2d->cur.ymax = 0.0f;
+ v2d->cur.ymin = (-winy) * panelzoom;
+ }
+ break;
+ }
+ /* other view types are completely defined using their own settings already */
+ default:
+ /* we don't do anything here,
+ * as settings should be fine, but just make sure that rect */
+ break;
+ }
+
+ /* set initialized flag so that View2D doesn't get reinitialised next time again */
+ v2d->flag |= V2D_IS_INITIALISED;
+
+ /* store view size */
+ v2d->winx = winx;
+ v2d->winy = winy;
+
+ /* set masks (always do), but leave scroller scheck to totrect_set */
+ view2d_masks(v2d, 0, NULL);
+
+ if (do_init) {
+ /* Visible by default. */
+ v2d->alpha_hor = v2d->alpha_vert = 255;
+ }
+
+ /* set 'tot' rect before setting cur? */
+ /* XXX confusing stuff here still -
+ * I made this function not check scroller hide - that happens in totrect_set */
+ if (tot_changed) {
+ UI_view2d_totRect_set_resize(v2d, winx, winy, !do_init);
+ }
+ else {
+ ui_view2d_curRect_validate_resize(v2d, !do_init, 0);
+ }
}
/**
@@ -399,449 +392,450 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
// XXX pre2.5 -> this used to be called test_view2d()
static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize, bool mask_scrollers)
{
- float totwidth, totheight, curwidth, curheight, width, height;
- float winx, winy;
- rctf *cur, *tot;
-
- /* use mask as size of region that View2D resides in, as it takes into account
- * scrollbars already - keep in sync with zoomx/zoomy in view_zoomstep_apply_ex! */
- winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
- winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
-
- /* get pointers to rcts for less typing */
- cur = &v2d->cur;
- tot = &v2d->tot;
-
- /* we must satisfy the following constraints (in decreasing order of importance):
- * - alignment restrictions are respected
- * - cur must not fall outside of tot
- * - axis locks (zoom and offset) must be maintained
- * - zoom must not be excessive (check either sizes or zoom values)
- * - aspect ratio should be respected (NOTE: this is quite closely related to zoom too)
- */
-
- /* Step 1: if keepzoom, adjust the sizes of the rects only
- * - firstly, we calculate the sizes of the rects
- * - curwidth and curheight are saved as reference... modify width and height values here
- */
- totwidth = BLI_rctf_size_x(tot);
- totheight = BLI_rctf_size_y(tot);
- /* keep in sync with zoomx/zoomy in view_zoomstep_apply_ex! */
- curwidth = width = BLI_rctf_size_x(cur);
- curheight = height = BLI_rctf_size_y(cur);
-
- /* if zoom is locked, size on the appropriate axis is reset to mask size */
- if (v2d->keepzoom & V2D_LOCKZOOM_X) {
- width = winx;
- }
- if (v2d->keepzoom & V2D_LOCKZOOM_Y) {
- height = winy;
- }
-
- /* values used to divide, so make it safe
- * NOTE: width and height must use FLT_MIN instead of 1, otherwise it is impossible to
- * get enough resolution in Graph Editor for editing some curves
- */
- if (width < FLT_MIN) {
- width = 1;
- }
- if (height < FLT_MIN) {
- height = 1;
- }
- if (winx < 1) {
- winx = 1;
- }
- if (winy < 1) {
- winy = 1;
- }
-
- /* V2D_LIMITZOOM indicates that zoom level should be preserved when the window size changes */
- if (resize && (v2d->keepzoom & V2D_KEEPZOOM)) {
- float zoom, oldzoom;
-
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
- zoom = winx / width;
- oldzoom = v2d->oldwinx / curwidth;
-
- if (oldzoom != zoom) {
- width *= zoom / oldzoom;
- }
- }
-
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
- zoom = winy / height;
- oldzoom = v2d->oldwiny / curheight;
-
- if (oldzoom != zoom) {
- height *= zoom / oldzoom;
- }
- }
- }
- /* keepzoom (V2D_LIMITZOOM set), indicates that zoom level on each axis must not exceed limits
- * NOTE: in general, it is not expected that the lock-zoom will be used in conjunction with this
- */
- else if (v2d->keepzoom & V2D_LIMITZOOM) {
-
- /* check if excessive zoom on x-axis */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
- const float zoom = winx / width;
- if (zoom < v2d->minzoom) {
- width = winx / v2d->minzoom;
- }
- else if (zoom > v2d->maxzoom) {
- width = winx / v2d->maxzoom;
- }
- }
-
- /* check if excessive zoom on y-axis */
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
- const float zoom = winy / height;
- if (zoom < v2d->minzoom) {
- height = winy / v2d->minzoom;
- }
- else if (zoom > v2d->maxzoom) {
- height = winy / v2d->maxzoom;
- }
- }
- }
- else {
- /* make sure sizes don't exceed that of the min/max sizes
- * (even though we're not doing zoom clamping) */
- CLAMP(width, v2d->min[0], v2d->max[0]);
- CLAMP(height, v2d->min[1], v2d->max[1]);
- }
-
- /* check if we should restore aspect ratio (if view size changed) */
- if (v2d->keepzoom & V2D_KEEPASPECT) {
- bool do_x = false, do_y = false, do_cur /* , do_win */ /* UNUSED */;
- float curRatio, winRatio;
-
- /* when a window edge changes, the aspect ratio can't be used to
- * find which is the best new 'cur' rect. that's why it stores 'old'
- */
- if (winx != v2d->oldwinx) {
- do_x = true;
- }
- if (winy != v2d->oldwiny) {
- do_y = true;
- }
-
- curRatio = height / width;
- winRatio = winy / winx;
-
- /* both sizes change (area/region maximized) */
- if (do_x == do_y) {
- if (do_x && do_y) {
- /* here is 1,1 case, so all others must be 0,0 */
- if (fabsf(winx - v2d->oldwinx) > fabsf(winy - v2d->oldwiny)) {
- do_y = false;
- }
- else {
- do_x = false;
- }
- }
- else if (winRatio > curRatio) {
- do_x = false;
- }
- else {
- do_x = true;
- }
- }
- do_cur = do_x;
- /* do_win = do_y; */ /* UNUSED */
-
- if (do_cur) {
- if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winx != v2d->oldwinx)) {
- /* special exception for Outliner (and later channel-lists):
- * - The view may be moved left to avoid contents being pushed out of view when view shrinks.
- * - The keeptot code will make sure cur->xmin will not be less than tot->xmin (which cannot be allowed)
- * - width is not adjusted for changed ratios here...
- */
- if (winx < v2d->oldwinx) {
- float temp = v2d->oldwinx - winx;
-
- cur->xmin -= temp;
- cur->xmax -= temp;
-
- /* width does not get modified, as keepaspect here is just set to make
- * sure visible area adjusts to changing view shape!
- */
- }
- }
- else {
- /* portrait window: correct for x */
- width = height / winRatio;
- }
- }
- else {
- if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winy != v2d->oldwiny)) {
- /* special exception for Outliner (and later channel-lists):
- * - Currently, no actions need to be taken here...
- */
-
- if (winy < v2d->oldwiny) {
- float temp = v2d->oldwiny - winy;
-
- if (v2d->align & V2D_ALIGN_NO_NEG_Y) {
- cur->ymin -= temp;
- cur->ymax -= temp;
- }
- else { /* Assume V2D_ALIGN_NO_POS_Y or combination */
- cur->ymin += temp;
- cur->ymax += temp;
- }
- }
-
- }
- else {
- /* landscape window: correct for y */
- height = width * winRatio;
- }
- }
-
- /* store region size for next time */
- v2d->oldwinx = (short)winx;
- v2d->oldwiny = (short)winy;
- }
-
- /* Step 2: apply new sizes to cur rect,
- * but need to take into account alignment settings here... */
- if ((width != curwidth) || (height != curheight)) {
- float temp, dh;
-
- /* resize from centerpoint, unless otherwise specified */
- if (width != curwidth) {
- if (v2d->keepofs & V2D_LOCKOFS_X) {
- cur->xmax += width - BLI_rctf_size_x(cur);
- }
- else if (v2d->keepofs & V2D_KEEPOFS_X) {
- if (v2d->align & V2D_ALIGN_NO_POS_X) {
- cur->xmin -= width - BLI_rctf_size_x(cur);
- }
- else {
- cur->xmax += width - BLI_rctf_size_x(cur);
- }
- }
- else {
- temp = BLI_rctf_cent_x(cur);
- dh = width * 0.5f;
-
- cur->xmin = temp - dh;
- cur->xmax = temp + dh;
- }
- }
- if (height != curheight) {
- if (v2d->keepofs & V2D_LOCKOFS_Y) {
- cur->ymax += height - BLI_rctf_size_y(cur);
- }
- else if (v2d->keepofs & V2D_KEEPOFS_Y) {
- if (v2d->align & V2D_ALIGN_NO_POS_Y) {
- cur->ymin -= height - BLI_rctf_size_y(cur);
- }
- else {
- cur->ymax += height - BLI_rctf_size_y(cur);
- }
- }
- else {
- temp = BLI_rctf_cent_y(cur);
- dh = height * 0.5f;
-
- cur->ymin = temp - dh;
- cur->ymax = temp + dh;
- }
- }
- }
-
- /* Step 3: adjust so that it doesn't fall outside of bounds of 'tot' */
- if (v2d->keeptot) {
- float temp, diff;
-
- /* recalculate extents of cur */
- curwidth = BLI_rctf_size_x(cur);
- curheight = BLI_rctf_size_y(cur);
-
- /* width */
- if ((curwidth > totwidth) && !(v2d->keepzoom & (V2D_KEEPZOOM | V2D_LOCKZOOM_X | V2D_LIMITZOOM))) {
- /* if zoom doesn't have to be maintained, just clamp edges */
- if (cur->xmin < tot->xmin) {
- cur->xmin = tot->xmin;
- }
- if (cur->xmax > tot->xmax) {
- cur->xmax = tot->xmax;
- }
- }
- else if (v2d->keeptot == V2D_KEEPTOT_STRICT) {
- /* This is an exception for the outliner (and later channel-lists, headers)
- * - must clamp within tot rect (absolutely no excuses)
- * --> therefore, cur->xmin must not be less than tot->xmin
- */
- if (cur->xmin < tot->xmin) {
- /* move cur across so that it sits at minimum of tot */
- temp = tot->xmin - cur->xmin;
-
- cur->xmin += temp;
- cur->xmax += temp;
- }
- else if (cur->xmax > tot->xmax) {
- /* - only offset by difference of cur-xmax and tot-xmax if that would not move
- * cur-xmin to lie past tot-xmin
- * - otherwise, simply shift to tot-xmin???
- */
- temp = cur->xmax - tot->xmax;
-
- if ((cur->xmin - temp) < tot->xmin) {
- /* only offset by difference from cur-min and tot-min */
- temp = cur->xmin - tot->xmin;
-
- cur->xmin -= temp;
- cur->xmax -= temp;
- }
- else {
- cur->xmin -= temp;
- cur->xmax -= temp;
- }
- }
- }
- else {
- /* This here occurs when:
- * - width too big, but maintaining zoom (i.e. widths cannot be changed)
- * - width is OK, but need to check if outside of boundaries
- *
- * So, resolution is to just shift view by the gap between the extremities.
- * We favour moving the 'minimum' across, as that's origin for most things
- * (XXX - in the past, max was favored... if there are bugs, swap!)
- */
- if ((cur->xmin < tot->xmin) && (cur->xmax > tot->xmax)) {
- /* outside boundaries on both sides,
- * so take middle-point of tot, and place in balanced way */
- temp = BLI_rctf_cent_x(tot);
- diff = curwidth * 0.5f;
-
- cur->xmin = temp - diff;
- cur->xmax = temp + diff;
- }
- else if (cur->xmin < tot->xmin) {
- /* move cur across so that it sits at minimum of tot */
- temp = tot->xmin - cur->xmin;
-
- cur->xmin += temp;
- cur->xmax += temp;
- }
- else if (cur->xmax > tot->xmax) {
- /* - only offset by difference of cur-xmax and tot-xmax if that would not move
- * cur-xmin to lie past tot-xmin
- * - otherwise, simply shift to tot-xmin???
- */
- temp = cur->xmax - tot->xmax;
-
- if ((cur->xmin - temp) < tot->xmin) {
- /* only offset by difference from cur-min and tot-min */
- temp = cur->xmin - tot->xmin;
-
- cur->xmin -= temp;
- cur->xmax -= temp;
- }
- else {
- cur->xmin -= temp;
- cur->xmax -= temp;
- }
- }
- }
-
- /* height */
- if ((curheight > totheight) && !(v2d->keepzoom & (V2D_KEEPZOOM | V2D_LOCKZOOM_Y | V2D_LIMITZOOM))) {
- /* if zoom doesn't have to be maintained, just clamp edges */
- if (cur->ymin < tot->ymin) {
- cur->ymin = tot->ymin;
- }
- if (cur->ymax > tot->ymax) {
- cur->ymax = tot->ymax;
- }
- }
- else {
- /* This here occurs when:
- * - height too big, but maintaining zoom (i.e. heights cannot be changed)
- * - height is OK, but need to check if outside of boundaries
- *
- * So, resolution is to just shift view by the gap between the extremities.
- * We favour moving the 'minimum' across, as that's origin for most things
- */
- if ((cur->ymin < tot->ymin) && (cur->ymax > tot->ymax)) {
- /* outside boundaries on both sides,
- * so take middle-point of tot, and place in balanced way */
- temp = BLI_rctf_cent_y(tot);
- diff = curheight * 0.5f;
-
- cur->ymin = temp - diff;
- cur->ymax = temp + diff;
- }
- else if (cur->ymin < tot->ymin) {
- /* there's still space remaining, so shift up */
- temp = tot->ymin - cur->ymin;
-
- cur->ymin += temp;
- cur->ymax += temp;
- }
- else if (cur->ymax > tot->ymax) {
- /* there's still space remaining, so shift down */
- temp = cur->ymax - tot->ymax;
-
- cur->ymin -= temp;
- cur->ymax -= temp;
- }
- }
- }
-
- /* Step 4: Make sure alignment restrictions are respected */
- if (v2d->align) {
- /* If alignment flags are set (but keeptot is not), they must still be respected, as although
- * they don't specify any particular bounds to stay within, they do define ranges which are
- * invalid.
- *
- * Here, we only check to make sure that on each axis, the 'cur' rect doesn't stray into these
- * invalid zones, otherwise we offset.
- */
-
- /* handle width - posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
- /* width is in negative-x half */
- if (v2d->cur.xmax > 0) {
- v2d->cur.xmin -= v2d->cur.xmax;
- v2d->cur.xmax = 0.0f;
- }
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
- /* width is in positive-x half */
- if (v2d->cur.xmin < 0) {
- v2d->cur.xmax -= v2d->cur.xmin;
- v2d->cur.xmin = 0.0f;
- }
- }
-
- /* handle height - posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
- /* height is in negative-y half */
- if (v2d->cur.ymax > 0) {
- v2d->cur.ymin -= v2d->cur.ymax;
- v2d->cur.ymax = 0.0f;
- }
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
- /* height is in positive-y half */
- if (v2d->cur.ymin < 0) {
- v2d->cur.ymax -= v2d->cur.ymin;
- v2d->cur.ymin = 0.0f;
- }
- }
- }
-
- /* set masks */
- view2d_masks(v2d, mask_scrollers, NULL);
+ float totwidth, totheight, curwidth, curheight, width, height;
+ float winx, winy;
+ rctf *cur, *tot;
+
+ /* use mask as size of region that View2D resides in, as it takes into account
+ * scrollbars already - keep in sync with zoomx/zoomy in view_zoomstep_apply_ex! */
+ winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
+ winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
+
+ /* get pointers to rcts for less typing */
+ cur = &v2d->cur;
+ tot = &v2d->tot;
+
+ /* we must satisfy the following constraints (in decreasing order of importance):
+ * - alignment restrictions are respected
+ * - cur must not fall outside of tot
+ * - axis locks (zoom and offset) must be maintained
+ * - zoom must not be excessive (check either sizes or zoom values)
+ * - aspect ratio should be respected (NOTE: this is quite closely related to zoom too)
+ */
+
+ /* Step 1: if keepzoom, adjust the sizes of the rects only
+ * - firstly, we calculate the sizes of the rects
+ * - curwidth and curheight are saved as reference... modify width and height values here
+ */
+ totwidth = BLI_rctf_size_x(tot);
+ totheight = BLI_rctf_size_y(tot);
+ /* keep in sync with zoomx/zoomy in view_zoomstep_apply_ex! */
+ curwidth = width = BLI_rctf_size_x(cur);
+ curheight = height = BLI_rctf_size_y(cur);
+
+ /* if zoom is locked, size on the appropriate axis is reset to mask size */
+ if (v2d->keepzoom & V2D_LOCKZOOM_X) {
+ width = winx;
+ }
+ if (v2d->keepzoom & V2D_LOCKZOOM_Y) {
+ height = winy;
+ }
+
+ /* values used to divide, so make it safe
+ * NOTE: width and height must use FLT_MIN instead of 1, otherwise it is impossible to
+ * get enough resolution in Graph Editor for editing some curves
+ */
+ if (width < FLT_MIN) {
+ width = 1;
+ }
+ if (height < FLT_MIN) {
+ height = 1;
+ }
+ if (winx < 1) {
+ winx = 1;
+ }
+ if (winy < 1) {
+ winy = 1;
+ }
+
+ /* V2D_LIMITZOOM indicates that zoom level should be preserved when the window size changes */
+ if (resize && (v2d->keepzoom & V2D_KEEPZOOM)) {
+ float zoom, oldzoom;
+
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
+ zoom = winx / width;
+ oldzoom = v2d->oldwinx / curwidth;
+
+ if (oldzoom != zoom) {
+ width *= zoom / oldzoom;
+ }
+ }
+
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
+ zoom = winy / height;
+ oldzoom = v2d->oldwiny / curheight;
+
+ if (oldzoom != zoom) {
+ height *= zoom / oldzoom;
+ }
+ }
+ }
+ /* keepzoom (V2D_LIMITZOOM set), indicates that zoom level on each axis must not exceed limits
+ * NOTE: in general, it is not expected that the lock-zoom will be used in conjunction with this
+ */
+ else if (v2d->keepzoom & V2D_LIMITZOOM) {
+
+ /* check if excessive zoom on x-axis */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
+ const float zoom = winx / width;
+ if (zoom < v2d->minzoom) {
+ width = winx / v2d->minzoom;
+ }
+ else if (zoom > v2d->maxzoom) {
+ width = winx / v2d->maxzoom;
+ }
+ }
+
+ /* check if excessive zoom on y-axis */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
+ const float zoom = winy / height;
+ if (zoom < v2d->minzoom) {
+ height = winy / v2d->minzoom;
+ }
+ else if (zoom > v2d->maxzoom) {
+ height = winy / v2d->maxzoom;
+ }
+ }
+ }
+ else {
+ /* make sure sizes don't exceed that of the min/max sizes
+ * (even though we're not doing zoom clamping) */
+ CLAMP(width, v2d->min[0], v2d->max[0]);
+ CLAMP(height, v2d->min[1], v2d->max[1]);
+ }
+
+ /* check if we should restore aspect ratio (if view size changed) */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ bool do_x = false, do_y = false, do_cur /* , do_win */ /* UNUSED */;
+ float curRatio, winRatio;
+
+ /* when a window edge changes, the aspect ratio can't be used to
+ * find which is the best new 'cur' rect. that's why it stores 'old'
+ */
+ if (winx != v2d->oldwinx) {
+ do_x = true;
+ }
+ if (winy != v2d->oldwiny) {
+ do_y = true;
+ }
+
+ curRatio = height / width;
+ winRatio = winy / winx;
+
+ /* both sizes change (area/region maximized) */
+ if (do_x == do_y) {
+ if (do_x && do_y) {
+ /* here is 1,1 case, so all others must be 0,0 */
+ if (fabsf(winx - v2d->oldwinx) > fabsf(winy - v2d->oldwiny)) {
+ do_y = false;
+ }
+ else {
+ do_x = false;
+ }
+ }
+ else if (winRatio > curRatio) {
+ do_x = false;
+ }
+ else {
+ do_x = true;
+ }
+ }
+ do_cur = do_x;
+ /* do_win = do_y; */ /* UNUSED */
+
+ if (do_cur) {
+ if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winx != v2d->oldwinx)) {
+ /* special exception for Outliner (and later channel-lists):
+ * - The view may be moved left to avoid contents being pushed out of view when view shrinks.
+ * - The keeptot code will make sure cur->xmin will not be less than tot->xmin (which cannot be allowed)
+ * - width is not adjusted for changed ratios here...
+ */
+ if (winx < v2d->oldwinx) {
+ float temp = v2d->oldwinx - winx;
+
+ cur->xmin -= temp;
+ cur->xmax -= temp;
+
+ /* width does not get modified, as keepaspect here is just set to make
+ * sure visible area adjusts to changing view shape!
+ */
+ }
+ }
+ else {
+ /* portrait window: correct for x */
+ width = height / winRatio;
+ }
+ }
+ else {
+ if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winy != v2d->oldwiny)) {
+ /* special exception for Outliner (and later channel-lists):
+ * - Currently, no actions need to be taken here...
+ */
+
+ if (winy < v2d->oldwiny) {
+ float temp = v2d->oldwiny - winy;
+
+ if (v2d->align & V2D_ALIGN_NO_NEG_Y) {
+ cur->ymin -= temp;
+ cur->ymax -= temp;
+ }
+ else { /* Assume V2D_ALIGN_NO_POS_Y or combination */
+ cur->ymin += temp;
+ cur->ymax += temp;
+ }
+ }
+ }
+ else {
+ /* landscape window: correct for y */
+ height = width * winRatio;
+ }
+ }
+
+ /* store region size for next time */
+ v2d->oldwinx = (short)winx;
+ v2d->oldwiny = (short)winy;
+ }
+
+ /* Step 2: apply new sizes to cur rect,
+ * but need to take into account alignment settings here... */
+ if ((width != curwidth) || (height != curheight)) {
+ float temp, dh;
+
+ /* resize from centerpoint, unless otherwise specified */
+ if (width != curwidth) {
+ if (v2d->keepofs & V2D_LOCKOFS_X) {
+ cur->xmax += width - BLI_rctf_size_x(cur);
+ }
+ else if (v2d->keepofs & V2D_KEEPOFS_X) {
+ if (v2d->align & V2D_ALIGN_NO_POS_X) {
+ cur->xmin -= width - BLI_rctf_size_x(cur);
+ }
+ else {
+ cur->xmax += width - BLI_rctf_size_x(cur);
+ }
+ }
+ else {
+ temp = BLI_rctf_cent_x(cur);
+ dh = width * 0.5f;
+
+ cur->xmin = temp - dh;
+ cur->xmax = temp + dh;
+ }
+ }
+ if (height != curheight) {
+ if (v2d->keepofs & V2D_LOCKOFS_Y) {
+ cur->ymax += height - BLI_rctf_size_y(cur);
+ }
+ else if (v2d->keepofs & V2D_KEEPOFS_Y) {
+ if (v2d->align & V2D_ALIGN_NO_POS_Y) {
+ cur->ymin -= height - BLI_rctf_size_y(cur);
+ }
+ else {
+ cur->ymax += height - BLI_rctf_size_y(cur);
+ }
+ }
+ else {
+ temp = BLI_rctf_cent_y(cur);
+ dh = height * 0.5f;
+
+ cur->ymin = temp - dh;
+ cur->ymax = temp + dh;
+ }
+ }
+ }
+
+ /* Step 3: adjust so that it doesn't fall outside of bounds of 'tot' */
+ if (v2d->keeptot) {
+ float temp, diff;
+
+ /* recalculate extents of cur */
+ curwidth = BLI_rctf_size_x(cur);
+ curheight = BLI_rctf_size_y(cur);
+
+ /* width */
+ if ((curwidth > totwidth) &&
+ !(v2d->keepzoom & (V2D_KEEPZOOM | V2D_LOCKZOOM_X | V2D_LIMITZOOM))) {
+ /* if zoom doesn't have to be maintained, just clamp edges */
+ if (cur->xmin < tot->xmin) {
+ cur->xmin = tot->xmin;
+ }
+ if (cur->xmax > tot->xmax) {
+ cur->xmax = tot->xmax;
+ }
+ }
+ else if (v2d->keeptot == V2D_KEEPTOT_STRICT) {
+ /* This is an exception for the outliner (and later channel-lists, headers)
+ * - must clamp within tot rect (absolutely no excuses)
+ * --> therefore, cur->xmin must not be less than tot->xmin
+ */
+ if (cur->xmin < tot->xmin) {
+ /* move cur across so that it sits at minimum of tot */
+ temp = tot->xmin - cur->xmin;
+
+ cur->xmin += temp;
+ cur->xmax += temp;
+ }
+ else if (cur->xmax > tot->xmax) {
+ /* - only offset by difference of cur-xmax and tot-xmax if that would not move
+ * cur-xmin to lie past tot-xmin
+ * - otherwise, simply shift to tot-xmin???
+ */
+ temp = cur->xmax - tot->xmax;
+
+ if ((cur->xmin - temp) < tot->xmin) {
+ /* only offset by difference from cur-min and tot-min */
+ temp = cur->xmin - tot->xmin;
+
+ cur->xmin -= temp;
+ cur->xmax -= temp;
+ }
+ else {
+ cur->xmin -= temp;
+ cur->xmax -= temp;
+ }
+ }
+ }
+ else {
+ /* This here occurs when:
+ * - width too big, but maintaining zoom (i.e. widths cannot be changed)
+ * - width is OK, but need to check if outside of boundaries
+ *
+ * So, resolution is to just shift view by the gap between the extremities.
+ * We favour moving the 'minimum' across, as that's origin for most things
+ * (XXX - in the past, max was favored... if there are bugs, swap!)
+ */
+ if ((cur->xmin < tot->xmin) && (cur->xmax > tot->xmax)) {
+ /* outside boundaries on both sides,
+ * so take middle-point of tot, and place in balanced way */
+ temp = BLI_rctf_cent_x(tot);
+ diff = curwidth * 0.5f;
+
+ cur->xmin = temp - diff;
+ cur->xmax = temp + diff;
+ }
+ else if (cur->xmin < tot->xmin) {
+ /* move cur across so that it sits at minimum of tot */
+ temp = tot->xmin - cur->xmin;
+
+ cur->xmin += temp;
+ cur->xmax += temp;
+ }
+ else if (cur->xmax > tot->xmax) {
+ /* - only offset by difference of cur-xmax and tot-xmax if that would not move
+ * cur-xmin to lie past tot-xmin
+ * - otherwise, simply shift to tot-xmin???
+ */
+ temp = cur->xmax - tot->xmax;
+
+ if ((cur->xmin - temp) < tot->xmin) {
+ /* only offset by difference from cur-min and tot-min */
+ temp = cur->xmin - tot->xmin;
+
+ cur->xmin -= temp;
+ cur->xmax -= temp;
+ }
+ else {
+ cur->xmin -= temp;
+ cur->xmax -= temp;
+ }
+ }
+ }
+
+ /* height */
+ if ((curheight > totheight) &&
+ !(v2d->keepzoom & (V2D_KEEPZOOM | V2D_LOCKZOOM_Y | V2D_LIMITZOOM))) {
+ /* if zoom doesn't have to be maintained, just clamp edges */
+ if (cur->ymin < tot->ymin) {
+ cur->ymin = tot->ymin;
+ }
+ if (cur->ymax > tot->ymax) {
+ cur->ymax = tot->ymax;
+ }
+ }
+ else {
+ /* This here occurs when:
+ * - height too big, but maintaining zoom (i.e. heights cannot be changed)
+ * - height is OK, but need to check if outside of boundaries
+ *
+ * So, resolution is to just shift view by the gap between the extremities.
+ * We favour moving the 'minimum' across, as that's origin for most things
+ */
+ if ((cur->ymin < tot->ymin) && (cur->ymax > tot->ymax)) {
+ /* outside boundaries on both sides,
+ * so take middle-point of tot, and place in balanced way */
+ temp = BLI_rctf_cent_y(tot);
+ diff = curheight * 0.5f;
+
+ cur->ymin = temp - diff;
+ cur->ymax = temp + diff;
+ }
+ else if (cur->ymin < tot->ymin) {
+ /* there's still space remaining, so shift up */
+ temp = tot->ymin - cur->ymin;
+
+ cur->ymin += temp;
+ cur->ymax += temp;
+ }
+ else if (cur->ymax > tot->ymax) {
+ /* there's still space remaining, so shift down */
+ temp = cur->ymax - tot->ymax;
+
+ cur->ymin -= temp;
+ cur->ymax -= temp;
+ }
+ }
+ }
+
+ /* Step 4: Make sure alignment restrictions are respected */
+ if (v2d->align) {
+ /* If alignment flags are set (but keeptot is not), they must still be respected, as although
+ * they don't specify any particular bounds to stay within, they do define ranges which are
+ * invalid.
+ *
+ * Here, we only check to make sure that on each axis, the 'cur' rect doesn't stray into these
+ * invalid zones, otherwise we offset.
+ */
+
+ /* handle width - posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
+ /* width is in negative-x half */
+ if (v2d->cur.xmax > 0) {
+ v2d->cur.xmin -= v2d->cur.xmax;
+ v2d->cur.xmax = 0.0f;
+ }
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
+ /* width is in positive-x half */
+ if (v2d->cur.xmin < 0) {
+ v2d->cur.xmax -= v2d->cur.xmin;
+ v2d->cur.xmin = 0.0f;
+ }
+ }
+
+ /* handle height - posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
+ /* height is in negative-y half */
+ if (v2d->cur.ymax > 0) {
+ v2d->cur.ymin -= v2d->cur.ymax;
+ v2d->cur.ymax = 0.0f;
+ }
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
+ /* height is in positive-y half */
+ if (v2d->cur.ymin < 0) {
+ v2d->cur.ymax -= v2d->cur.ymin;
+ v2d->cur.ymin = 0.0f;
+ }
+ }
+ }
+
+ /* set masks */
+ view2d_masks(v2d, mask_scrollers, NULL);
}
void UI_view2d_curRect_validate(View2D *v2d)
{
- ui_view2d_curRect_validate_resize(v2d, 0, 1);
+ ui_view2d_curRect_validate_resize(v2d, 0, 1);
}
/* ------------------ */
@@ -850,117 +844,116 @@ void UI_view2d_curRect_validate(View2D *v2d)
* to make sure 'related' views stay in synchrony */
void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag)
{
- ScrArea *sa;
- ARegion *ar;
-
- /* don't continue if no view syncing to be done */
- if ((v2dcur->flag & (V2D_VIEWSYNC_SCREEN_TIME | V2D_VIEWSYNC_AREA_VERTICAL)) == 0) {
- return;
- }
-
- /* check if doing within area syncing (i.e. channels/vertical) */
- if ((v2dcur->flag & V2D_VIEWSYNC_AREA_VERTICAL) && (area)) {
- for (ar = area->regionbase.first; ar; ar = ar->next) {
- /* don't operate on self */
- if (v2dcur != &ar->v2d) {
- /* only if view has vertical locks enabled */
- if (ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) {
- if (flag == V2D_LOCK_COPY) {
- /* other views with locks on must copy active */
- ar->v2d.cur.ymin = v2dcur->cur.ymin;
- ar->v2d.cur.ymax = v2dcur->cur.ymax;
- }
- else { /* V2D_LOCK_SET */
- /* active must copy others */
- v2dcur->cur.ymin = ar->v2d.cur.ymin;
- v2dcur->cur.ymax = ar->v2d.cur.ymax;
- }
-
- /* region possibly changed, so refresh */
- ED_region_tag_redraw_no_rebuild(ar);
- }
- }
- }
- }
-
- /* check if doing whole screen syncing (i.e. time/horizontal) */
- if ((v2dcur->flag & V2D_VIEWSYNC_SCREEN_TIME) && (screen)) {
- for (sa = screen->areabase.first; sa; sa = sa->next) {
- for (ar = sa->regionbase.first; ar; ar = ar->next) {
- /* don't operate on self */
- if (v2dcur != &ar->v2d) {
- /* only if view has horizontal locks enabled */
- if (ar->v2d.flag & V2D_VIEWSYNC_SCREEN_TIME) {
- if (flag == V2D_LOCK_COPY) {
- /* other views with locks on must copy active */
- ar->v2d.cur.xmin = v2dcur->cur.xmin;
- ar->v2d.cur.xmax = v2dcur->cur.xmax;
- }
- else { /* V2D_LOCK_SET */
- /* active must copy others */
- v2dcur->cur.xmin = ar->v2d.cur.xmin;
- v2dcur->cur.xmax = ar->v2d.cur.xmax;
- }
-
- /* region possibly changed, so refresh */
- ED_region_tag_redraw_no_rebuild(ar);
- }
- }
- }
- }
- }
+ ScrArea *sa;
+ ARegion *ar;
+
+ /* don't continue if no view syncing to be done */
+ if ((v2dcur->flag & (V2D_VIEWSYNC_SCREEN_TIME | V2D_VIEWSYNC_AREA_VERTICAL)) == 0) {
+ return;
+ }
+
+ /* check if doing within area syncing (i.e. channels/vertical) */
+ if ((v2dcur->flag & V2D_VIEWSYNC_AREA_VERTICAL) && (area)) {
+ for (ar = area->regionbase.first; ar; ar = ar->next) {
+ /* don't operate on self */
+ if (v2dcur != &ar->v2d) {
+ /* only if view has vertical locks enabled */
+ if (ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) {
+ if (flag == V2D_LOCK_COPY) {
+ /* other views with locks on must copy active */
+ ar->v2d.cur.ymin = v2dcur->cur.ymin;
+ ar->v2d.cur.ymax = v2dcur->cur.ymax;
+ }
+ else { /* V2D_LOCK_SET */
+ /* active must copy others */
+ v2dcur->cur.ymin = ar->v2d.cur.ymin;
+ v2dcur->cur.ymax = ar->v2d.cur.ymax;
+ }
+
+ /* region possibly changed, so refresh */
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+ }
+ }
+ }
+
+ /* check if doing whole screen syncing (i.e. time/horizontal) */
+ if ((v2dcur->flag & V2D_VIEWSYNC_SCREEN_TIME) && (screen)) {
+ for (sa = screen->areabase.first; sa; sa = sa->next) {
+ for (ar = sa->regionbase.first; ar; ar = ar->next) {
+ /* don't operate on self */
+ if (v2dcur != &ar->v2d) {
+ /* only if view has horizontal locks enabled */
+ if (ar->v2d.flag & V2D_VIEWSYNC_SCREEN_TIME) {
+ if (flag == V2D_LOCK_COPY) {
+ /* other views with locks on must copy active */
+ ar->v2d.cur.xmin = v2dcur->cur.xmin;
+ ar->v2d.cur.xmax = v2dcur->cur.xmax;
+ }
+ else { /* V2D_LOCK_SET */
+ /* active must copy others */
+ v2dcur->cur.xmin = ar->v2d.cur.xmin;
+ v2dcur->cur.xmax = ar->v2d.cur.xmax;
+ }
+
+ /* region possibly changed, so refresh */
+ ED_region_tag_redraw_no_rebuild(ar);
+ }
+ }
+ }
+ }
+ }
}
-
/**
* Restore 'cur' rect to standard orientation (i.e. optimal maximum view of tot)
* This does not take into account if zooming the view on an axis will improve the view (if allowed)
*/
void UI_view2d_curRect_reset(View2D *v2d)
{
- float width, height;
-
- /* assume width and height of 'cur' rect by default, should be same size as mask */
- width = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
- height = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
-
- /* handle width - posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
- /* width is in negative-x half */
- v2d->cur.xmin = -width;
- v2d->cur.xmax = 0.0f;
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
- /* width is in positive-x half */
- v2d->cur.xmin = 0.0f;
- v2d->cur.xmax = width;
- }
- else {
- /* width is centered around (x == 0) */
- const float dx = width / 2.0f;
-
- v2d->cur.xmin = -dx;
- v2d->cur.xmax = dx;
- }
-
- /* handle height - posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
- /* height is in negative-y half */
- v2d->cur.ymin = -height;
- v2d->cur.ymax = 0.0f;
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
- /* height is in positive-y half */
- v2d->cur.ymin = 0.0f;
- v2d->cur.ymax = height;
- }
- else {
- /* height is centered around (y == 0) */
- const float dy = height / 2.0f;
-
- v2d->cur.ymin = -dy;
- v2d->cur.ymax = dy;
- }
+ float width, height;
+
+ /* assume width and height of 'cur' rect by default, should be same size as mask */
+ width = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
+ height = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
+
+ /* handle width - posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
+ /* width is in negative-x half */
+ v2d->cur.xmin = -width;
+ v2d->cur.xmax = 0.0f;
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
+ /* width is in positive-x half */
+ v2d->cur.xmin = 0.0f;
+ v2d->cur.xmax = width;
+ }
+ else {
+ /* width is centered around (x == 0) */
+ const float dx = width / 2.0f;
+
+ v2d->cur.xmin = -dx;
+ v2d->cur.xmax = dx;
+ }
+
+ /* handle height - posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
+ /* height is in negative-y half */
+ v2d->cur.ymin = -height;
+ v2d->cur.ymax = 0.0f;
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
+ /* height is in positive-y half */
+ v2d->cur.ymin = 0.0f;
+ v2d->cur.ymax = height;
+ }
+ else {
+ /* height is centered around (y == 0) */
+ const float dy = height / 2.0f;
+
+ v2d->cur.ymin = -dy;
+ v2d->cur.ymax = dy;
+ }
}
/* ------------------ */
@@ -968,147 +961,148 @@ void UI_view2d_curRect_reset(View2D *v2d)
/* Change the size of the maximum viewable area (i.e. 'tot' rect) */
void UI_view2d_totRect_set_resize(View2D *v2d, int width, int height, bool resize)
{
-// int scroll = view2d_scroll_mapped(v2d->scroll);
-
- /* don't do anything if either value is 0 */
- width = abs(width);
- height = abs(height);
-
- /* hrumf! */
- /* XXX: there are work arounds for this in the panel and file browse code. */
- /* round to int, because this is called with width + V2D_SCROLL_WIDTH */
-// if (scroll & V2D_SCROLL_HORIZONTAL) {
-// width -= (int)V2D_SCROLL_WIDTH;
-// }
-// if (scroll & V2D_SCROLL_VERTICAL) {
-// height -= (int)V2D_SCROLL_HEIGHT;
-// }
-
- if (ELEM(0, width, height)) {
- if (G.debug & G_DEBUG) {
- printf("Error: View2D totRect set exiting: v2d=%p width=%d height=%d\n", (void *)v2d, width, height); // XXX temp debug info
- }
- return;
- }
-
- /* handle width - posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
- /* width is in negative-x half */
- v2d->tot.xmin = (float)-width;
- v2d->tot.xmax = 0.0f;
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
- /* width is in positive-x half */
- v2d->tot.xmin = 0.0f;
- v2d->tot.xmax = (float)width;
- }
- else {
- /* width is centered around (x == 0) */
- const float dx = (float)width / 2.0f;
-
- v2d->tot.xmin = -dx;
- v2d->tot.xmax = dx;
- }
-
- /* handle height - posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
- /* height is in negative-y half */
- v2d->tot.ymin = (float)-height;
- v2d->tot.ymax = 0.0f;
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
- /* height is in positive-y half */
- v2d->tot.ymin = 0.0f;
- v2d->tot.ymax = (float)height;
- }
- else {
- /* height is centered around (y == 0) */
- const float dy = (float)height / 2.0f;
-
- v2d->tot.ymin = -dy;
- v2d->tot.ymax = dy;
- }
-
- /* make sure that 'cur' rect is in a valid state as a result of these changes */
- ui_view2d_curRect_validate_resize(v2d, resize, 1);
-
+ // int scroll = view2d_scroll_mapped(v2d->scroll);
+
+ /* don't do anything if either value is 0 */
+ width = abs(width);
+ height = abs(height);
+
+ /* hrumf! */
+ /* XXX: there are work arounds for this in the panel and file browse code. */
+ /* round to int, because this is called with width + V2D_SCROLL_WIDTH */
+ // if (scroll & V2D_SCROLL_HORIZONTAL) {
+ // width -= (int)V2D_SCROLL_WIDTH;
+ // }
+ // if (scroll & V2D_SCROLL_VERTICAL) {
+ // height -= (int)V2D_SCROLL_HEIGHT;
+ // }
+
+ if (ELEM(0, width, height)) {
+ if (G.debug & G_DEBUG) {
+ printf("Error: View2D totRect set exiting: v2d=%p width=%d height=%d\n",
+ (void *)v2d,
+ width,
+ height); // XXX temp debug info
+ }
+ return;
+ }
+
+ /* handle width - posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
+ /* width is in negative-x half */
+ v2d->tot.xmin = (float)-width;
+ v2d->tot.xmax = 0.0f;
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
+ /* width is in positive-x half */
+ v2d->tot.xmin = 0.0f;
+ v2d->tot.xmax = (float)width;
+ }
+ else {
+ /* width is centered around (x == 0) */
+ const float dx = (float)width / 2.0f;
+
+ v2d->tot.xmin = -dx;
+ v2d->tot.xmax = dx;
+ }
+
+ /* handle height - posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
+ /* height is in negative-y half */
+ v2d->tot.ymin = (float)-height;
+ v2d->tot.ymax = 0.0f;
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
+ /* height is in positive-y half */
+ v2d->tot.ymin = 0.0f;
+ v2d->tot.ymax = (float)height;
+ }
+ else {
+ /* height is centered around (y == 0) */
+ const float dy = (float)height / 2.0f;
+
+ v2d->tot.ymin = -dy;
+ v2d->tot.ymax = dy;
+ }
+
+ /* make sure that 'cur' rect is in a valid state as a result of these changes */
+ ui_view2d_curRect_validate_resize(v2d, resize, 1);
}
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
{
- int scroll = view2d_scroll_mapped(v2d->scroll);
-
- UI_view2d_totRect_set_resize(v2d, width, height, 0);
+ int scroll = view2d_scroll_mapped(v2d->scroll);
- /* solve bad recursion... if scroller state changed,
- * mask is different, so you get different rects */
- if (scroll != view2d_scroll_mapped(v2d->scroll)) {
- UI_view2d_totRect_set_resize(v2d, width, height, 0);
- }
+ UI_view2d_totRect_set_resize(v2d, width, height, 0);
+ /* solve bad recursion... if scroller state changed,
+ * mask is different, so you get different rects */
+ if (scroll != view2d_scroll_mapped(v2d->scroll)) {
+ UI_view2d_totRect_set_resize(v2d, width, height, 0);
+ }
}
bool UI_view2d_tab_set(View2D *v2d, int tab)
{
- float default_offset[2] = {0.0f, 0.0f};
- float *offset, *new_offset;
- bool changed = false;
+ float default_offset[2] = {0.0f, 0.0f};
+ float *offset, *new_offset;
+ bool changed = false;
- /* if tab changed, change offset */
- if (tab != v2d->tab_cur && v2d->tab_offset) {
- if (tab < v2d->tab_num) {
- offset = &v2d->tab_offset[tab * 2];
- }
- else {
- offset = default_offset;
- }
+ /* if tab changed, change offset */
+ if (tab != v2d->tab_cur && v2d->tab_offset) {
+ if (tab < v2d->tab_num) {
+ offset = &v2d->tab_offset[tab * 2];
+ }
+ else {
+ offset = default_offset;
+ }
- v2d->cur.xmax += offset[0] - v2d->cur.xmin;
- v2d->cur.xmin = offset[0];
+ v2d->cur.xmax += offset[0] - v2d->cur.xmin;
+ v2d->cur.xmin = offset[0];
- v2d->cur.ymin += offset[1] - v2d->cur.ymax;
- v2d->cur.ymax = offset[1];
+ v2d->cur.ymin += offset[1] - v2d->cur.ymax;
+ v2d->cur.ymax = offset[1];
- /* validation should happen in subsequent totRect_set */
+ /* validation should happen in subsequent totRect_set */
- changed = true;
- }
+ changed = true;
+ }
- /* resize array if needed */
- if (tab >= v2d->tab_num) {
- new_offset = MEM_callocN(sizeof(float) * (tab + 1) * 2, "view2d tab offset");
+ /* resize array if needed */
+ if (tab >= v2d->tab_num) {
+ new_offset = MEM_callocN(sizeof(float) * (tab + 1) * 2, "view2d tab offset");
- if (v2d->tab_offset) {
- memcpy(new_offset, v2d->tab_offset, sizeof(float) * v2d->tab_num * 2);
- MEM_freeN(v2d->tab_offset);
- }
+ if (v2d->tab_offset) {
+ memcpy(new_offset, v2d->tab_offset, sizeof(float) * v2d->tab_num * 2);
+ MEM_freeN(v2d->tab_offset);
+ }
- v2d->tab_offset = new_offset;
- v2d->tab_num = tab + 1;
- }
+ v2d->tab_offset = new_offset;
+ v2d->tab_num = tab + 1;
+ }
- /* set current tab and offset */
- v2d->tab_cur = tab;
- v2d->tab_offset[2 * tab + 0] = v2d->cur.xmin;
- v2d->tab_offset[2 * tab + 1] = v2d->cur.ymax;
+ /* set current tab and offset */
+ v2d->tab_cur = tab;
+ v2d->tab_offset[2 * tab + 0] = v2d->cur.xmin;
+ v2d->tab_offset[2 * tab + 1] = v2d->cur.ymax;
- return changed;
+ return changed;
}
void UI_view2d_zoom_cache_reset(void)
{
- /* TODO(sergey): This way we avoid threading conflict with sequencer rendering
- * text strip. But ideally we want to make glyph cache to be fully safe
- * for threading.
- */
- if (G.is_rendering) {
- return;
- }
- /* While scaling we can accumulate fonts at many sizes (~20 or so).
- * Not an issue with embedded font, but can use over 500Mb with i18n ones! See [#38244]. */
-
- /* note: only some views draw text, we could check for this case to avoid clearning cache */
- BLF_cache_clear();
+ /* TODO(sergey): This way we avoid threading conflict with sequencer rendering
+ * text strip. But ideally we want to make glyph cache to be fully safe
+ * for threading.
+ */
+ if (G.is_rendering) {
+ return;
+ }
+ /* While scaling we can accumulate fonts at many sizes (~20 or so).
+ * Not an issue with embedded font, but can use over 500Mb with i18n ones! See [#38244]. */
+
+ /* note: only some views draw text, we could check for this case to avoid clearning cache */
+ BLF_cache_clear();
}
/* *********************************************************************** */
@@ -1117,74 +1111,74 @@ void UI_view2d_zoom_cache_reset(void)
/* mapping function to ensure 'cur' draws extended over the area where sliders are */
static void view2d_map_cur_using_mask(View2D *v2d, rctf *r_curmasked)
{
- *r_curmasked = v2d->cur;
-
- if (view2d_scroll_mapped(v2d->scroll)) {
- float sizex = BLI_rcti_size_x(&v2d->mask);
- float sizey = BLI_rcti_size_y(&v2d->mask);
-
- /* prevent tiny or narrow regions to get
- * invalid coordinates - mask can get negative even... */
- if (sizex > 0.0f && sizey > 0.0f) {
- float dx = BLI_rctf_size_x(&v2d->cur) / (sizex + 1);
- float dy = BLI_rctf_size_y(&v2d->cur) / (sizey + 1);
-
- if (v2d->mask.xmin != 0) {
- r_curmasked->xmin -= dx * (float)v2d->mask.xmin;
- }
- if (v2d->mask.xmax + 1 != v2d->winx) {
- r_curmasked->xmax += dx * (float)(v2d->winx - v2d->mask.xmax - 1);
- }
-
- if (v2d->mask.ymin != 0) {
- r_curmasked->ymin -= dy * (float)v2d->mask.ymin;
- }
- if (v2d->mask.ymax + 1 != v2d->winy) {
- r_curmasked->ymax += dy * (float)(v2d->winy - v2d->mask.ymax - 1);
- }
- }
- }
+ *r_curmasked = v2d->cur;
+
+ if (view2d_scroll_mapped(v2d->scroll)) {
+ float sizex = BLI_rcti_size_x(&v2d->mask);
+ float sizey = BLI_rcti_size_y(&v2d->mask);
+
+ /* prevent tiny or narrow regions to get
+ * invalid coordinates - mask can get negative even... */
+ if (sizex > 0.0f && sizey > 0.0f) {
+ float dx = BLI_rctf_size_x(&v2d->cur) / (sizex + 1);
+ float dy = BLI_rctf_size_y(&v2d->cur) / (sizey + 1);
+
+ if (v2d->mask.xmin != 0) {
+ r_curmasked->xmin -= dx * (float)v2d->mask.xmin;
+ }
+ if (v2d->mask.xmax + 1 != v2d->winx) {
+ r_curmasked->xmax += dx * (float)(v2d->winx - v2d->mask.xmax - 1);
+ }
+
+ if (v2d->mask.ymin != 0) {
+ r_curmasked->ymin -= dy * (float)v2d->mask.ymin;
+ }
+ if (v2d->mask.ymax + 1 != v2d->winy) {
+ r_curmasked->ymax += dy * (float)(v2d->winy - v2d->mask.ymax - 1);
+ }
+ }
+ }
}
/* Set view matrices to use 'cur' rect as viewing frame for View2D drawing */
void UI_view2d_view_ortho(View2D *v2d)
{
- rctf curmasked;
- const int sizex = BLI_rcti_size_x(&v2d->mask);
- const int sizey = BLI_rcti_size_y(&v2d->mask);
- const float eps = 0.001f;
- float xofs = 0.0f, yofs = 0.0f;
-
- /* pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 correspondence with pixels for smooth UI drawing,
- * but only applied where requested
- */
- /* XXX brecht: instead of zero at least use a tiny offset, otherwise
- * pixel rounding is effectively random due to float inaccuracy */
- if (sizex > 0) {
- xofs = eps * BLI_rctf_size_x(&v2d->cur) / sizex;
- }
- if (sizey > 0) {
- yofs = eps * BLI_rctf_size_y(&v2d->cur) / sizey;
- }
-
- /* apply mask-based adjustments to cur rect (due to scrollers),
- * to eliminate scaling artifacts */
- view2d_map_cur_using_mask(v2d, &curmasked);
-
- BLI_rctf_translate(&curmasked, -xofs, -yofs);
-
- /* XXX ton: this flag set by outliner, for icons */
- if (v2d->flag & V2D_PIXELOFS_X) {
- curmasked.xmin = floorf(curmasked.xmin) - (eps + xofs);
- curmasked.xmax = floorf(curmasked.xmax) - (eps + xofs);
- }
- if (v2d->flag & V2D_PIXELOFS_Y) {
- curmasked.ymin = floorf(curmasked.ymin) - (eps + yofs);
- curmasked.ymax = floorf(curmasked.ymax) - (eps + yofs);
- }
-
- /* set matrix on all appropriate axes */
- wmOrtho2(curmasked.xmin, curmasked.xmax, curmasked.ymin, curmasked.ymax);
+ rctf curmasked;
+ const int sizex = BLI_rcti_size_x(&v2d->mask);
+ const int sizey = BLI_rcti_size_y(&v2d->mask);
+ const float eps = 0.001f;
+ float xofs = 0.0f, yofs = 0.0f;
+
+ /* pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 correspondence with pixels for smooth UI drawing,
+ * but only applied where requested
+ */
+ /* XXX brecht: instead of zero at least use a tiny offset, otherwise
+ * pixel rounding is effectively random due to float inaccuracy */
+ if (sizex > 0) {
+ xofs = eps * BLI_rctf_size_x(&v2d->cur) / sizex;
+ }
+ if (sizey > 0) {
+ yofs = eps * BLI_rctf_size_y(&v2d->cur) / sizey;
+ }
+
+ /* apply mask-based adjustments to cur rect (due to scrollers),
+ * to eliminate scaling artifacts */
+ view2d_map_cur_using_mask(v2d, &curmasked);
+
+ BLI_rctf_translate(&curmasked, -xofs, -yofs);
+
+ /* XXX ton: this flag set by outliner, for icons */
+ if (v2d->flag & V2D_PIXELOFS_X) {
+ curmasked.xmin = floorf(curmasked.xmin) - (eps + xofs);
+ curmasked.xmax = floorf(curmasked.xmax) - (eps + xofs);
+ }
+ if (v2d->flag & V2D_PIXELOFS_Y) {
+ curmasked.ymin = floorf(curmasked.ymin) - (eps + yofs);
+ curmasked.ymax = floorf(curmasked.ymax) - (eps + yofs);
+ }
+
+ /* set matrix on all appropriate axes */
+ wmOrtho2(curmasked.xmin, curmasked.xmax, curmasked.ymin, curmasked.ymax);
}
/**
@@ -1194,41 +1188,40 @@ void UI_view2d_view_ortho(View2D *v2d)
*/
void UI_view2d_view_orthoSpecial(ARegion *ar, View2D *v2d, const bool xaxis)
{
- rctf curmasked;
- float xofs, yofs;
-
- /* pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 correspondence with pixels for smooth UI drawing,
- * but only applied where requested
- */
- /* XXX temp (ton) */
- xofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_X) ? GLA_PIXEL_OFS : 0.0f;
- yofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_Y) ? GLA_PIXEL_OFS : 0.0f;
-
- /* apply mask-based adjustments to cur rect (due to scrollers),
- * to eliminate scaling artifacts */
- view2d_map_cur_using_mask(v2d, &curmasked);
-
- /* only set matrix with 'cur' coordinates on relevant axes */
- if (xaxis) {
- wmOrtho2(curmasked.xmin - xofs, curmasked.xmax - xofs, -yofs, ar->winy - yofs);
- }
- else {
- wmOrtho2(-xofs, ar->winx - xofs, curmasked.ymin - yofs, curmasked.ymax - yofs);
- }
+ rctf curmasked;
+ float xofs, yofs;
+
+ /* pixel offsets (-GLA_PIXEL_OFS) are needed to get 1:1 correspondence with pixels for smooth UI drawing,
+ * but only applied where requested
+ */
+ /* XXX temp (ton) */
+ xofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_X) ? GLA_PIXEL_OFS : 0.0f;
+ yofs = 0.0f; // (v2d->flag & V2D_PIXELOFS_Y) ? GLA_PIXEL_OFS : 0.0f;
+
+ /* apply mask-based adjustments to cur rect (due to scrollers),
+ * to eliminate scaling artifacts */
+ view2d_map_cur_using_mask(v2d, &curmasked);
+
+ /* only set matrix with 'cur' coordinates on relevant axes */
+ if (xaxis) {
+ wmOrtho2(curmasked.xmin - xofs, curmasked.xmax - xofs, -yofs, ar->winy - yofs);
+ }
+ else {
+ wmOrtho2(-xofs, ar->winx - xofs, curmasked.ymin - yofs, curmasked.ymax - yofs);
+ }
}
-
/* Restore view matrices after drawing */
void UI_view2d_view_restore(const bContext *C)
{
- ARegion *ar = CTX_wm_region(C);
- int width = BLI_rcti_size_x(&ar->winrct) + 1;
- int height = BLI_rcti_size_y(&ar->winrct) + 1;
+ ARegion *ar = CTX_wm_region(C);
+ int width = BLI_rcti_size_x(&ar->winrct) + 1;
+ int height = BLI_rcti_size_y(&ar->winrct) + 1;
- wmOrtho2(0.0f, (float)width, 0.0f, (float)height);
- GPU_matrix_identity_set();
+ wmOrtho2(0.0f, (float)width, 0.0f, (float)height);
+ GPU_matrix_identity_set();
- // ED_region_pixelspace(CTX_wm_region(C));
+ // ED_region_pixelspace(CTX_wm_region(C));
}
/* *********************************************************************** */
@@ -1236,9 +1229,9 @@ void UI_view2d_view_restore(const bContext *C)
/* View2DGrid is typedef'd in UI_view2d.h */
struct View2DGrid {
- float dx, dy; /* stepsize (in pixels) between gridlines */
- float startx, starty; /* initial coordinates to start drawing grid from */
- int powerx, powery; /* step as power of 10 */
+ float dx, dy; /* stepsize (in pixels) between gridlines */
+ float startx, starty; /* initial coordinates to start drawing grid from */
+ int powerx, powery; /* step as power of 10 */
};
/* --------------- */
@@ -1246,61 +1239,61 @@ struct View2DGrid {
/* try to write step as a power of 10 */
static void step_to_grid(float *step, const int unit, int *r_power)
{
- const float loga = (float)log10(*step);
- float rem;
-
- int power = (int)(loga);
-
- rem = loga - power;
- rem = (float)pow(10.0, rem);
-
- if (loga < 0.0f) {
- if (rem < 0.2f) {
- rem = 0.2f;
- }
- else if (rem < 0.5f) {
- rem = 0.5f;
- }
- else {
- rem = 1.0f;
- }
-
- *step = rem * (float)pow(10.0, power);
-
- /* for frames, we want 1.0 frame intervals only */
- if (unit == V2D_UNIT_FRAMES) {
- rem = 1.0f;
- /* use 2 since there are grid lines drawn in between,
- * this way to get 1 line per frame */
- *step = 2.0f;
- }
-
- /* prevents printing 1.0 2.0 3.0 etc */
- if (rem == 1.0f) {
- power++;
- }
- }
- else {
- if (rem < 2.0f) {
- rem = 2.0f;
- }
- else if (rem < 5.0f) {
- rem = 5.0f;
- }
- else {
- rem = 10.0f;
- }
-
- *step = rem * (float)pow(10.0, power);
-
- power++;
- /* prevents printing 1.0, 2.0, 3.0, etc. */
- if (rem == 10.0f) {
- power++;
- }
- }
-
- *r_power = power;
+ const float loga = (float)log10(*step);
+ float rem;
+
+ int power = (int)(loga);
+
+ rem = loga - power;
+ rem = (float)pow(10.0, rem);
+
+ if (loga < 0.0f) {
+ if (rem < 0.2f) {
+ rem = 0.2f;
+ }
+ else if (rem < 0.5f) {
+ rem = 0.5f;
+ }
+ else {
+ rem = 1.0f;
+ }
+
+ *step = rem * (float)pow(10.0, power);
+
+ /* for frames, we want 1.0 frame intervals only */
+ if (unit == V2D_UNIT_FRAMES) {
+ rem = 1.0f;
+ /* use 2 since there are grid lines drawn in between,
+ * this way to get 1 line per frame */
+ *step = 2.0f;
+ }
+
+ /* prevents printing 1.0 2.0 3.0 etc */
+ if (rem == 1.0f) {
+ power++;
+ }
+ }
+ else {
+ if (rem < 2.0f) {
+ rem = 2.0f;
+ }
+ else if (rem < 5.0f) {
+ rem = 5.0f;
+ }
+ else {
+ rem = 10.0f;
+ }
+
+ *step = rem * (float)pow(10.0, power);
+
+ power++;
+ /* prevents printing 1.0, 2.0, 3.0, etc. */
+ if (rem == 10.0f) {
+ power++;
+ }
+ }
+
+ *r_power = power;
}
/**
@@ -1317,540 +1310,539 @@ static void step_to_grid(float *step, const int unit, int *r_power)
* - winx = width of region we're drawing to, note: not used but keeping for completeness.
* - winy = height of region we're drawing into
*/
-View2DGrid *UI_view2d_grid_calc(
- Scene *scene, View2D *v2d,
- short xunits, short xclamp, short yunits, short yclamp, int UNUSED(winx), int winy)
+View2DGrid *UI_view2d_grid_calc(Scene *scene,
+ View2D *v2d,
+ short xunits,
+ short xclamp,
+ short yunits,
+ short yclamp,
+ int UNUSED(winx),
+ int winy)
{
- View2DGrid *grid;
- float space, seconddiv;
-
- /* check that there are at least some workable args */
- if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) && ELEM(V2D_ARG_DUMMY, yunits, yclamp)) {
- return NULL;
- }
-
- /* grid here is allocated... */
- grid = MEM_callocN(sizeof(View2DGrid), "View2DGrid");
-
- /* rule: gridstep is minimal GRIDSTEP pixels */
- if (xunits == V2D_UNIT_SECONDS) {
- seconddiv = (float)(0.01 * FPS);
- }
- else {
- seconddiv = 1.0f;
- }
-
- /* calculate x-axis grid scale (only if both args are valid) */
- if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) {
- space = BLI_rctf_size_x(&v2d->cur);
-
- if (space != 0.0f) {
- const float pixels = (float)BLI_rcti_size_x(&v2d->mask);
- if (pixels != 0.0f) {
- grid->dx = (U.v2d_min_gridsize * UI_DPI_FAC * space) / (seconddiv * pixels);
- step_to_grid(&grid->dx, xunits, &grid->powerx);
- grid->dx *= seconddiv;
- }
- }
-
- if (xclamp == V2D_GRID_CLAMP) {
- CLAMP_MIN(grid->dx, 0.1f);
- CLAMP_MIN(grid->powerx, 0);
- grid->powerx -= 2;
- }
- }
-
- /* calculate y-axis grid scale (only if both args are valid) */
- if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) {
- space = BLI_rctf_size_y(&v2d->cur);
- if (space != 0.0f) {
- const float pixels = (float)winy;
- if (pixels != 0.0f) {
- grid->dy = U.v2d_min_gridsize * UI_DPI_FAC * space / pixels;
- step_to_grid(&grid->dy, yunits, &grid->powery);
- }
- }
-
- if (yclamp == V2D_GRID_CLAMP) {
- CLAMP_MIN(grid->dy, 1.0f);
- CLAMP_MIN(grid->powery, 1);
- }
- }
-
- /* calculate start position */
- if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) {
- grid->startx = seconddiv * (v2d->cur.xmin / seconddiv - (float)fmod(v2d->cur.xmin / seconddiv, grid->dx / seconddiv));
- if (v2d->cur.xmin < 0.0f) {
- grid->startx -= grid->dx;
- }
- }
- else {
- grid->startx = v2d->cur.xmin;
- }
-
- if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) {
- grid->starty = (v2d->cur.ymin - (float)fmod(v2d->cur.ymin, grid->dy));
- if (v2d->cur.ymin < 0.0f) {
- grid->starty -= grid->dy;
- }
- }
- else {
- grid->starty = v2d->cur.ymin;
- }
-
- return grid;
+ View2DGrid *grid;
+ float space, seconddiv;
+
+ /* check that there are at least some workable args */
+ if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) && ELEM(V2D_ARG_DUMMY, yunits, yclamp)) {
+ return NULL;
+ }
+
+ /* grid here is allocated... */
+ grid = MEM_callocN(sizeof(View2DGrid), "View2DGrid");
+
+ /* rule: gridstep is minimal GRIDSTEP pixels */
+ if (xunits == V2D_UNIT_SECONDS) {
+ seconddiv = (float)(0.01 * FPS);
+ }
+ else {
+ seconddiv = 1.0f;
+ }
+
+ /* calculate x-axis grid scale (only if both args are valid) */
+ if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) {
+ space = BLI_rctf_size_x(&v2d->cur);
+
+ if (space != 0.0f) {
+ const float pixels = (float)BLI_rcti_size_x(&v2d->mask);
+ if (pixels != 0.0f) {
+ grid->dx = (U.v2d_min_gridsize * UI_DPI_FAC * space) / (seconddiv * pixels);
+ step_to_grid(&grid->dx, xunits, &grid->powerx);
+ grid->dx *= seconddiv;
+ }
+ }
+
+ if (xclamp == V2D_GRID_CLAMP) {
+ CLAMP_MIN(grid->dx, 0.1f);
+ CLAMP_MIN(grid->powerx, 0);
+ grid->powerx -= 2;
+ }
+ }
+
+ /* calculate y-axis grid scale (only if both args are valid) */
+ if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) {
+ space = BLI_rctf_size_y(&v2d->cur);
+ if (space != 0.0f) {
+ const float pixels = (float)winy;
+ if (pixels != 0.0f) {
+ grid->dy = U.v2d_min_gridsize * UI_DPI_FAC * space / pixels;
+ step_to_grid(&grid->dy, yunits, &grid->powery);
+ }
+ }
+
+ if (yclamp == V2D_GRID_CLAMP) {
+ CLAMP_MIN(grid->dy, 1.0f);
+ CLAMP_MIN(grid->powery, 1);
+ }
+ }
+
+ /* calculate start position */
+ if (ELEM(V2D_ARG_DUMMY, xunits, xclamp) == 0) {
+ grid->startx = seconddiv * (v2d->cur.xmin / seconddiv -
+ (float)fmod(v2d->cur.xmin / seconddiv, grid->dx / seconddiv));
+ if (v2d->cur.xmin < 0.0f) {
+ grid->startx -= grid->dx;
+ }
+ }
+ else {
+ grid->startx = v2d->cur.xmin;
+ }
+
+ if (ELEM(V2D_ARG_DUMMY, yunits, yclamp) == 0) {
+ grid->starty = (v2d->cur.ymin - (float)fmod(v2d->cur.ymin, grid->dy));
+ if (v2d->cur.ymin < 0.0f) {
+ grid->starty -= grid->dy;
+ }
+ }
+ else {
+ grid->starty = v2d->cur.ymin;
+ }
+
+ return grid;
}
/* Draw gridlines in the given 2d-region */
void UI_view2d_grid_draw(View2D *v2d, View2DGrid *grid, int flag)
{
- float vec1[2], vec2[2];
- int a, step;
- int vertical_minor_step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
- int horizontal_major_step = (BLI_rcti_size_y(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
- uchar grid_line_color[3];
-
- /* check for grid first, as it may not exist */
- if (grid == NULL) {
- return;
- }
-
- /* Count the needed vertices for the gridlines */
- unsigned vertex_count = 0;
- if (flag & V2D_VERTICAL_LINES) {
- /* vertical lines */
- vertex_count += 2 * vertical_minor_step; /* minor gridlines */
- vertex_count += 2 * (vertical_minor_step + 2); /* major gridlines */
- }
- if (flag & V2D_HORIZONTAL_LINES) {
- /* horizontal lines */
- vertex_count += 2 * (horizontal_major_step + 1); /* major gridlines */
-
- /* fine lines */
- if (flag & V2D_HORIZONTAL_FINELINES) {
- vertex_count += 2 * (horizontal_major_step + 1);
- }
- }
- /* axes */
- if (flag & V2D_HORIZONTAL_AXIS) {
- vertex_count += 2;
- }
- if (flag & V2D_VERTICAL_AXIS) {
- vertex_count += 2;
- }
-
- /* If there is nothing to render, exit early */
- if (vertex_count == 0) {
- return;
- }
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GPU_PRIM_LINES, vertex_count);
-
- /* vertical lines */
- if (flag & V2D_VERTICAL_LINES) {
- /* initialize initial settings */
- vec1[0] = vec2[0] = grid->startx;
- vec1[1] = grid->starty;
- vec2[1] = v2d->cur.ymax;
-
- /* minor gridlines */
- step = vertical_minor_step;
- if (step != 0) {
- UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
-
- for (a = 0; a < step; a++) {
- immAttrSkip(color);
- immVertex2fv(pos, vec1);
- immAttr3ubv(color, grid_line_color);
- immVertex2fv(pos, vec2);
-
- vec2[0] = vec1[0] += grid->dx;
- }
- }
-
- /* major gridlines */
- vec2[0] = vec1[0] -= 0.5f * grid->dx;
-
- UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
-
- step++;
- for (a = 0; a <= step; a++) {
- immAttrSkip(color);
- immVertex2fv(pos, vec1);
- immAttr3ubv(color, grid_line_color);
- immVertex2fv(pos, vec2);
-
- vec2[0] = vec1[0] -= grid->dx;
- }
- }
-
- /* horizontal lines */
- if (flag & V2D_HORIZONTAL_LINES) {
- /* only major gridlines */
- vec1[1] = vec2[1] = grid->starty;
- vec1[0] = grid->startx;
- vec2[0] = v2d->cur.xmax;
-
- step = horizontal_major_step;
-
- UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
-
- for (a = 0; a <= step; a++) {
- immAttrSkip(color);
- immVertex2fv(pos, vec1);
- immAttr3ubv(color, grid_line_color);
- immVertex2fv(pos, vec2);
-
- vec2[1] = vec1[1] += grid->dy;
- }
-
- /* fine grid lines */
- vec2[1] = vec1[1] -= 0.5f * grid->dy;
- step++;
-
- if (flag & V2D_HORIZONTAL_FINELINES) {
- UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
- for (a = 0; a < step; a++) {
- immAttrSkip(color);
- immVertex2fv(pos, vec1);
- immAttr3ubv(color, grid_line_color);
- immVertex2fv(pos, vec2);
-
- vec2[1] = vec1[1] -= grid->dy;
- }
- }
- }
-
- /* Axes are drawn as darker lines */
- UI_GetThemeColorShade3ubv(TH_GRID, -50, grid_line_color);
-
- /* horizontal axis */
- if (flag & V2D_HORIZONTAL_AXIS) {
- vec1[0] = v2d->cur.xmin;
- vec2[0] = v2d->cur.xmax;
- vec1[1] = vec2[1] = 0.0f;
-
- immAttrSkip(color);
- immVertex2fv(pos, vec1);
- immAttr3ubv(color, grid_line_color);
- immVertex2fv(pos, vec2);
- }
-
- /* vertical axis */
- if (flag & V2D_VERTICAL_AXIS) {
- vec1[1] = v2d->cur.ymin;
- vec2[1] = v2d->cur.ymax;
- vec1[0] = vec2[0] = 0.0f;
-
- immAttrSkip(color);
- immVertex2fv(pos, vec1);
- immAttr3ubv(color, grid_line_color);
- immVertex2fv(pos, vec2);
- }
-
- immEnd();
- immUnbindProgram();
+ float vec1[2], vec2[2];
+ int a, step;
+ int vertical_minor_step = (BLI_rcti_size_x(&v2d->mask) + 1) / (U.v2d_min_gridsize * UI_DPI_FAC);
+ int horizontal_major_step = (BLI_rcti_size_y(&v2d->mask) + 1) /
+ (U.v2d_min_gridsize * UI_DPI_FAC);
+ uchar grid_line_color[3];
+
+ /* check for grid first, as it may not exist */
+ if (grid == NULL) {
+ return;
+ }
+
+ /* Count the needed vertices for the gridlines */
+ unsigned vertex_count = 0;
+ if (flag & V2D_VERTICAL_LINES) {
+ /* vertical lines */
+ vertex_count += 2 * vertical_minor_step; /* minor gridlines */
+ vertex_count += 2 * (vertical_minor_step + 2); /* major gridlines */
+ }
+ if (flag & V2D_HORIZONTAL_LINES) {
+ /* horizontal lines */
+ vertex_count += 2 * (horizontal_major_step + 1); /* major gridlines */
+
+ /* fine lines */
+ if (flag & V2D_HORIZONTAL_FINELINES) {
+ vertex_count += 2 * (horizontal_major_step + 1);
+ }
+ }
+ /* axes */
+ if (flag & V2D_HORIZONTAL_AXIS) {
+ vertex_count += 2;
+ }
+ if (flag & V2D_VERTICAL_AXIS) {
+ vertex_count += 2;
+ }
+
+ /* If there is nothing to render, exit early */
+ if (vertex_count == 0) {
+ return;
+ }
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(
+ format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(GPU_PRIM_LINES, vertex_count);
+
+ /* vertical lines */
+ if (flag & V2D_VERTICAL_LINES) {
+ /* initialize initial settings */
+ vec1[0] = vec2[0] = grid->startx;
+ vec1[1] = grid->starty;
+ vec2[1] = v2d->cur.ymax;
+
+ /* minor gridlines */
+ step = vertical_minor_step;
+ if (step != 0) {
+ UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
+
+ for (a = 0; a < step; a++) {
+ immAttrSkip(color);
+ immVertex2fv(pos, vec1);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
+
+ vec2[0] = vec1[0] += grid->dx;
+ }
+ }
+
+ /* major gridlines */
+ vec2[0] = vec1[0] -= 0.5f * grid->dx;
+
+ UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
+
+ step++;
+ for (a = 0; a <= step; a++) {
+ immAttrSkip(color);
+ immVertex2fv(pos, vec1);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
+
+ vec2[0] = vec1[0] -= grid->dx;
+ }
+ }
+
+ /* horizontal lines */
+ if (flag & V2D_HORIZONTAL_LINES) {
+ /* only major gridlines */
+ vec1[1] = vec2[1] = grid->starty;
+ vec1[0] = grid->startx;
+ vec2[0] = v2d->cur.xmax;
+
+ step = horizontal_major_step;
+
+ UI_GetThemeColor3ubv(TH_GRID, grid_line_color);
+
+ for (a = 0; a <= step; a++) {
+ immAttrSkip(color);
+ immVertex2fv(pos, vec1);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
+
+ vec2[1] = vec1[1] += grid->dy;
+ }
+
+ /* fine grid lines */
+ vec2[1] = vec1[1] -= 0.5f * grid->dy;
+ step++;
+
+ if (flag & V2D_HORIZONTAL_FINELINES) {
+ UI_GetThemeColorShade3ubv(TH_GRID, 16, grid_line_color);
+ for (a = 0; a < step; a++) {
+ immAttrSkip(color);
+ immVertex2fv(pos, vec1);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
+
+ vec2[1] = vec1[1] -= grid->dy;
+ }
+ }
+ }
+
+ /* Axes are drawn as darker lines */
+ UI_GetThemeColorShade3ubv(TH_GRID, -50, grid_line_color);
+
+ /* horizontal axis */
+ if (flag & V2D_HORIZONTAL_AXIS) {
+ vec1[0] = v2d->cur.xmin;
+ vec2[0] = v2d->cur.xmax;
+ vec1[1] = vec2[1] = 0.0f;
+
+ immAttrSkip(color);
+ immVertex2fv(pos, vec1);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
+ }
+
+ /* vertical axis */
+ if (flag & V2D_VERTICAL_AXIS) {
+ vec1[1] = v2d->cur.ymin;
+ vec2[1] = v2d->cur.ymax;
+ vec1[0] = vec2[0] = 0.0f;
+
+ immAttrSkip(color);
+ immVertex2fv(pos, vec1);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2fv(pos, vec2);
+ }
+
+ immEnd();
+ immUnbindProgram();
}
/* Draw a constant grid in given 2d-region */
void UI_view2d_constant_grid_draw(View2D *v2d, float step)
{
- float start_x, start_y;
- int count_x, count_y;
-
- start_x = v2d->cur.xmin;
- if (start_x < 0.0) {
- start_x += -(float)fmod(v2d->cur.xmin, step);
- }
- else {
- start_x += (step - (float)fmod(v2d->cur.xmin, step));
- }
-
- if (start_x > v2d->cur.xmax) {
- count_x = 0;
- }
- else {
- count_x = (v2d->cur.xmax - start_x) / step + 1;
- }
-
- start_y = v2d->cur.ymin;
- if (start_y < 0.0) {
- start_y += -(float)fmod(v2d->cur.ymin, step);
- }
- else {
- start_y += (step - (float)fabs(fmod(v2d->cur.ymin, step)));
- }
-
- if (start_y > v2d->cur.ymax) {
- count_y = 0;
- }
- else {
- count_y = (v2d->cur.ymax - start_y) / step + 1;
- }
-
- if (count_x > 0 || count_y > 0) {
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- float theme_color[3];
-
- UI_GetThemeColorShade3fv(TH_BACK, -10, theme_color);
-
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBegin(GPU_PRIM_LINES, count_x * 2 + count_y * 2 + 4);
-
- immAttr3fv(color, theme_color);
- for (int i = 0; i < count_x ; start_x += step, i++) {
- immVertex2f(pos, start_x, v2d->cur.ymin);
- immVertex2f(pos, start_x, v2d->cur.ymax);
- }
-
- for (int i = 0; i < count_y; start_y += step, i++) {
- immVertex2f(pos, v2d->cur.xmin, start_y);
- immVertex2f(pos, v2d->cur.xmax, start_y);
- }
-
- /* X and Y axis */
- UI_GetThemeColorShade3fv(TH_BACK, -18, theme_color);
-
- immAttr3fv(color, theme_color);
- immVertex2f(pos, 0.0f, v2d->cur.ymin);
- immVertex2f(pos, 0.0f, v2d->cur.ymax);
- immVertex2f(pos, v2d->cur.xmin, 0.0f);
- immVertex2f(pos, v2d->cur.xmax, 0.0f);
-
- immEnd();
- immUnbindProgram();
- }
+ float start_x, start_y;
+ int count_x, count_y;
+
+ start_x = v2d->cur.xmin;
+ if (start_x < 0.0) {
+ start_x += -(float)fmod(v2d->cur.xmin, step);
+ }
+ else {
+ start_x += (step - (float)fmod(v2d->cur.xmin, step));
+ }
+
+ if (start_x > v2d->cur.xmax) {
+ count_x = 0;
+ }
+ else {
+ count_x = (v2d->cur.xmax - start_x) / step + 1;
+ }
+
+ start_y = v2d->cur.ymin;
+ if (start_y < 0.0) {
+ start_y += -(float)fmod(v2d->cur.ymin, step);
+ }
+ else {
+ start_y += (step - (float)fabs(fmod(v2d->cur.ymin, step)));
+ }
+
+ if (start_y > v2d->cur.ymax) {
+ count_y = 0;
+ }
+ else {
+ count_y = (v2d->cur.ymax - start_y) / step + 1;
+ }
+
+ if (count_x > 0 || count_y > 0) {
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ float theme_color[3];
+
+ UI_GetThemeColorShade3fv(TH_BACK, -10, theme_color);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBegin(GPU_PRIM_LINES, count_x * 2 + count_y * 2 + 4);
+
+ immAttr3fv(color, theme_color);
+ for (int i = 0; i < count_x; start_x += step, i++) {
+ immVertex2f(pos, start_x, v2d->cur.ymin);
+ immVertex2f(pos, start_x, v2d->cur.ymax);
+ }
+
+ for (int i = 0; i < count_y; start_y += step, i++) {
+ immVertex2f(pos, v2d->cur.xmin, start_y);
+ immVertex2f(pos, v2d->cur.xmax, start_y);
+ }
+
+ /* X and Y axis */
+ UI_GetThemeColorShade3fv(TH_BACK, -18, theme_color);
+
+ immAttr3fv(color, theme_color);
+ immVertex2f(pos, 0.0f, v2d->cur.ymin);
+ immVertex2f(pos, 0.0f, v2d->cur.ymax);
+ immVertex2f(pos, v2d->cur.xmin, 0.0f);
+ immVertex2f(pos, v2d->cur.xmax, 0.0f);
+
+ immEnd();
+ immUnbindProgram();
+ }
}
/* Draw a multi-level grid in given 2d-region */
void UI_view2d_multi_grid_draw(View2D *v2d, int colorid, float step, int level_size, int totlevels)
{
- /* Exit if there is nothing to draw */
- if (totlevels == 0) {
- return;
- }
-
- int offset = -10;
- float lstep = step;
- uchar grid_line_color[3];
-
- /* Make an estimate of at least how many vertices will be needed */
- unsigned vertex_count = 4;
- vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1);
- vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
-
- GPU_line_width(1.0f);
-
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- immBeginAtMost(GPU_PRIM_LINES, vertex_count);
-
- for (int level = 0; level < totlevels; ++level) {
- UI_GetThemeColorShade3ubv(colorid, offset, grid_line_color);
-
- int i = (int)(v2d->cur.xmin / lstep);
- if (v2d->cur.xmin > 0.0f) {
- i++;
- }
- float start = i * lstep;
-
- for (; start < v2d->cur.xmax; start += lstep, ++i) {
- if (i == 0 || (level < totlevels - 1 && i % level_size == 0)) {
- continue;
- }
-
- immAttrSkip(color);
- immVertex2f(pos, start, v2d->cur.ymin);
- immAttr3ubv(color, grid_line_color);
- immVertex2f(pos, start, v2d->cur.ymax);
- }
-
- i = (int)(v2d->cur.ymin / lstep);
- if (v2d->cur.ymin > 0.0f) {
- i++;
- }
- start = i * lstep;
-
- for (; start < v2d->cur.ymax; start += lstep, ++i) {
- if (i == 0 || (level < totlevels - 1 && i % level_size == 0)) {
- continue;
- }
-
- immAttrSkip(color);
- immVertex2f(pos, v2d->cur.xmin, start);
- immAttr3ubv(color, grid_line_color);
- immVertex2f(pos, v2d->cur.xmax, start);
- }
-
- lstep *= level_size;
- offset -= 6;
- }
-
- /* X and Y axis */
- UI_GetThemeColorShade3ubv(colorid, -18 + ((totlevels - 1) * -6), grid_line_color);
-
- immAttrSkip(color);
- immVertex2f(pos, 0.0f, v2d->cur.ymin);
- immAttr3ubv(color, grid_line_color);
- immVertex2f(pos, 0.0f, v2d->cur.ymax);
-
- immAttrSkip(color);
- immVertex2f(pos, v2d->cur.xmin, 0.0f);
- immAttr3ubv(color, grid_line_color);
- immVertex2f(pos, v2d->cur.xmax, 0.0f);
-
- immEnd();
- immUnbindProgram();
+ /* Exit if there is nothing to draw */
+ if (totlevels == 0) {
+ return;
+ }
+
+ int offset = -10;
+ float lstep = step;
+ uchar grid_line_color[3];
+
+ /* Make an estimate of at least how many vertices will be needed */
+ unsigned vertex_count = 4;
+ vertex_count += 2 * ((int)((v2d->cur.xmax - v2d->cur.xmin) / lstep) + 1);
+ vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(
+ format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
+ GPU_line_width(1.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+ immBeginAtMost(GPU_PRIM_LINES, vertex_count);
+
+ for (int level = 0; level < totlevels; ++level) {
+ UI_GetThemeColorShade3ubv(colorid, offset, grid_line_color);
+
+ int i = (int)(v2d->cur.xmin / lstep);
+ if (v2d->cur.xmin > 0.0f) {
+ i++;
+ }
+ float start = i * lstep;
+
+ for (; start < v2d->cur.xmax; start += lstep, ++i) {
+ if (i == 0 || (level < totlevels - 1 && i % level_size == 0)) {
+ continue;
+ }
+
+ immAttrSkip(color);
+ immVertex2f(pos, start, v2d->cur.ymin);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2f(pos, start, v2d->cur.ymax);
+ }
+
+ i = (int)(v2d->cur.ymin / lstep);
+ if (v2d->cur.ymin > 0.0f) {
+ i++;
+ }
+ start = i * lstep;
+
+ for (; start < v2d->cur.ymax; start += lstep, ++i) {
+ if (i == 0 || (level < totlevels - 1 && i % level_size == 0)) {
+ continue;
+ }
+
+ immAttrSkip(color);
+ immVertex2f(pos, v2d->cur.xmin, start);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2f(pos, v2d->cur.xmax, start);
+ }
+
+ lstep *= level_size;
+ offset -= 6;
+ }
+
+ /* X and Y axis */
+ UI_GetThemeColorShade3ubv(colorid, -18 + ((totlevels - 1) * -6), grid_line_color);
+
+ immAttrSkip(color);
+ immVertex2f(pos, 0.0f, v2d->cur.ymin);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2f(pos, 0.0f, v2d->cur.ymax);
+
+ immAttrSkip(color);
+ immVertex2f(pos, v2d->cur.xmin, 0.0f);
+ immAttr3ubv(color, grid_line_color);
+ immVertex2f(pos, v2d->cur.xmax, 0.0f);
+
+ immEnd();
+ immUnbindProgram();
}
static void get_scale_indicator_text(
- const Scene *scene,
- float value,
- int brevity_level,
- short unit,
- uint max_length,
- char *r_str)
+ const Scene *scene, float value, int brevity_level, short unit, uint max_length, char *r_str)
{
- if (unit == V2D_UNIT_SECONDS) {
- BLI_timecode_string_from_time(r_str, max_length, brevity_level, value / (float)FPS, FPS, U.timecode_style);
- }
- else {
- BLI_timecode_string_from_time_seconds(r_str, max_length, brevity_level, value);
- }
+ if (unit == V2D_UNIT_SECONDS) {
+ BLI_timecode_string_from_time(
+ r_str, max_length, brevity_level, value / (float)FPS, FPS, U.timecode_style);
+ }
+ else {
+ BLI_timecode_string_from_time_seconds(r_str, max_length, brevity_level, value);
+ }
}
-void UI_view2d_grid_draw_numbers_horizontal(
- const Scene *scene,
- const View2D *v2d,
- const View2DGrid *grid,
- const rcti *rect,
- int unit,
- bool whole_numbers_only)
+void UI_view2d_grid_draw_numbers_horizontal(const Scene *scene,
+ const View2D *v2d,
+ const View2DGrid *grid,
+ const rcti *rect,
+ int unit,
+ bool whole_numbers_only)
{
- BLI_assert(grid);
- float xstep = grid->dx * UI_view2d_scale_get_x(v2d);
- if (xstep <= 0.0f) {
- return;
- }
-
- float initial_xpos = UI_view2d_view_to_region_x(v2d, grid->startx);
- float ypos = (float)rect->ymin + 2 * UI_DPI_FAC;
- float initial_value = grid->startx;
- float value_step = grid->dx;
- int brevity_level = grid->powerx;
-
- /* Make sure that the value_step is >= 1 when only whole numbers are displayed.
- * Otherwise the same number could be displayed more than once. */
- if (whole_numbers_only) {
- while (value_step < 0.9999f) {
- xstep *= 2.0f;
- value_step *= 2.0f;
- }
- }
-
- /* Skip first few steps if they don't intersect
- * the rectangle that will contain the numbers. */
- while (initial_xpos < rect->xmin) {
- initial_xpos += xstep;
- initial_value += value_step;
- }
-
- if (unit == V2D_UNIT_FRAMES) {
- brevity_level = 1;
- }
-
- const int font_id = BLF_default();
- UI_FontThemeColor(font_id, TH_TEXT);
-
- BLF_batch_draw_begin();
-
- for (float xpos = initial_xpos, value = initial_value;
- xpos < rect->xmax;
- xpos += xstep, value += value_step)
- {
- char text[32];
- get_scale_indicator_text(scene, value, brevity_level, unit, sizeof(text), text);
- float text_width = BLF_width(font_id, text, strlen(text));
- BLF_draw_default_ascii(xpos - text_width / 2.0f, ypos, 0.0f, text, sizeof(text));
- }
-
- BLF_batch_draw_end();
+ BLI_assert(grid);
+ float xstep = grid->dx * UI_view2d_scale_get_x(v2d);
+ if (xstep <= 0.0f) {
+ return;
+ }
+
+ float initial_xpos = UI_view2d_view_to_region_x(v2d, grid->startx);
+ float ypos = (float)rect->ymin + 2 * UI_DPI_FAC;
+ float initial_value = grid->startx;
+ float value_step = grid->dx;
+ int brevity_level = grid->powerx;
+
+ /* Make sure that the value_step is >= 1 when only whole numbers are displayed.
+ * Otherwise the same number could be displayed more than once. */
+ if (whole_numbers_only) {
+ while (value_step < 0.9999f) {
+ xstep *= 2.0f;
+ value_step *= 2.0f;
+ }
+ }
+
+ /* Skip first few steps if they don't intersect
+ * the rectangle that will contain the numbers. */
+ while (initial_xpos < rect->xmin) {
+ initial_xpos += xstep;
+ initial_value += value_step;
+ }
+
+ if (unit == V2D_UNIT_FRAMES) {
+ brevity_level = 1;
+ }
+
+ const int font_id = BLF_default();
+ UI_FontThemeColor(font_id, TH_TEXT);
+
+ BLF_batch_draw_begin();
+
+ for (float xpos = initial_xpos, value = initial_value; xpos < rect->xmax;
+ xpos += xstep, value += value_step) {
+ char text[32];
+ get_scale_indicator_text(scene, value, brevity_level, unit, sizeof(text), text);
+ float text_width = BLF_width(font_id, text, strlen(text));
+ BLF_draw_default_ascii(xpos - text_width / 2.0f, ypos, 0.0f, text, sizeof(text));
+ }
+
+ BLF_batch_draw_end();
}
-void UI_view2d_grid_draw_numbers_vertical(
- const Scene *scene,
- const View2D *v2d,
- const View2DGrid *grid,
- const rcti *rect,
- int unit,
- float text_offset)
+void UI_view2d_grid_draw_numbers_vertical(const Scene *scene,
+ const View2D *v2d,
+ const View2DGrid *grid,
+ const rcti *rect,
+ int unit,
+ float text_offset)
{
- BLI_assert(grid);
- float ystep = grid->dy * UI_view2d_scale_get_y(v2d);
- if (ystep <= 0.0f) {
- return;
- }
-
- const int font_id = BLF_default();
- UI_FontThemeColor(font_id, TH_TEXT);
-
- BLF_enable(font_id, BLF_ROTATION);
- BLF_rotation(font_id, M_PI_2);
-
- float initial_value = grid->starty;
- float value_step = grid->dy;
- float xpos = rect->xmax - 2.0f * UI_DPI_FAC;
- float initial_ypos = UI_view2d_view_to_region_y(v2d, grid->starty);
-
- /* Currently only used by the sequencer to display
- * channel numbers in the center. */
- initial_ypos += text_offset * ystep;
-
- /* Skip first few steps if they don't intersect
- * the rectangle that will contain the numbers. */
- while (initial_ypos < rect->ymin) {
- initial_ypos += ystep;
- initial_value += value_step;
- }
-
- for (float ypos = initial_ypos, value = initial_value;
- ypos < rect->ymax;
- ypos += ystep, value += value_step)
- {
- char text[32];
- get_scale_indicator_text(scene, value, grid->powery, unit, sizeof(text), text);
- float text_width = BLF_width(font_id, text, sizeof(text));
- BLF_draw_default_ascii(xpos, ypos - text_width / 2.0f, 0.0f, text, sizeof(text));
- }
-
- BLF_disable(font_id, BLF_ROTATION);
+ BLI_assert(grid);
+ float ystep = grid->dy * UI_view2d_scale_get_y(v2d);
+ if (ystep <= 0.0f) {
+ return;
+ }
+
+ const int font_id = BLF_default();
+ UI_FontThemeColor(font_id, TH_TEXT);
+
+ BLF_enable(font_id, BLF_ROTATION);
+ BLF_rotation(font_id, M_PI_2);
+
+ float initial_value = grid->starty;
+ float value_step = grid->dy;
+ float xpos = rect->xmax - 2.0f * UI_DPI_FAC;
+ float initial_ypos = UI_view2d_view_to_region_y(v2d, grid->starty);
+
+ /* Currently only used by the sequencer to display
+ * channel numbers in the center. */
+ initial_ypos += text_offset * ystep;
+
+ /* Skip first few steps if they don't intersect
+ * the rectangle that will contain the numbers. */
+ while (initial_ypos < rect->ymin) {
+ initial_ypos += ystep;
+ initial_value += value_step;
+ }
+
+ for (float ypos = initial_ypos, value = initial_value; ypos < rect->ymax;
+ ypos += ystep, value += value_step) {
+ char text[32];
+ get_scale_indicator_text(scene, value, grid->powery, unit, sizeof(text), text);
+ float text_width = BLF_width(font_id, text, sizeof(text));
+ BLF_draw_default_ascii(xpos, ypos - text_width / 2.0f, 0.0f, text, sizeof(text));
+ }
+
+ BLF_disable(font_id, BLF_ROTATION);
}
/* the price we pay for not exposting structs :( */
void UI_view2d_grid_size(View2DGrid *grid, float *r_dx, float *r_dy)
{
- *r_dx = grid->dx;
- *r_dy = grid->dy;
+ *r_dx = grid->dx;
+ *r_dy = grid->dy;
}
/* free temporary memory used for drawing grid */
void UI_view2d_grid_free(View2DGrid *grid)
{
- /* only free if there's a grid */
- if (grid) {
- MEM_freeN(grid);
- }
+ /* only free if there's a grid */
+ if (grid) {
+ MEM_freeN(grid);
+ }
}
/* *********************************************************************** */
@@ -1863,288 +1855,290 @@ void UI_view2d_grid_free(View2DGrid *grid)
* For now, we don't need to have a separate (internal) header for structs like this...
*/
struct View2DScrollers {
- /* focus bubbles */
- int vert_min, vert_max; /* vertical scrollbar */
- int hor_min, hor_max; /* horizontal scrollbar */
+ /* focus bubbles */
+ int vert_min, vert_max; /* vertical scrollbar */
+ int hor_min, hor_max; /* horizontal scrollbar */
- rcti hor, vert; /* exact size of slider backdrop */
- int horfull, vertfull; /* set if sliders are full, we don't draw them */
+ rcti hor, vert; /* exact size of slider backdrop */
+ int horfull, vertfull; /* set if sliders are full, we don't draw them */
- /* scales */
- View2DGrid *grid; /* grid for coordinate drawing */
- short xunits, xclamp; /* units and clamping options for x-axis */
- short yunits, yclamp; /* units and clamping options for y-axis */
+ /* scales */
+ View2DGrid *grid; /* grid for coordinate drawing */
+ short xunits, xclamp; /* units and clamping options for x-axis */
+ short yunits, yclamp; /* units and clamping options for y-axis */
};
/* Calculate relevant scroller properties */
-View2DScrollers *UI_view2d_scrollers_calc(
- const bContext *C, View2D *v2d, const rcti *mask_custom,
- short xunits, short xclamp, short yunits, short yclamp)
+View2DScrollers *UI_view2d_scrollers_calc(const bContext *C,
+ View2D *v2d,
+ const rcti *mask_custom,
+ short xunits,
+ short xclamp,
+ short yunits,
+ short yclamp)
{
- View2DScrollers *scrollers;
- rcti vert, hor;
- float fac1, fac2, totsize, scrollsize;
- int scroll = view2d_scroll_mapped(v2d->scroll);
- int smaller;
-
- /* scrollers is allocated here... */
- scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
-
- /* Always update before drawing (for dynamically sized scrollers). */
- view2d_masks(v2d, false, mask_custom);
-
- vert = v2d->vert;
- hor = v2d->hor;
-
- /* slider rects need to be smaller than region and not interfere with splitter areas */
- hor.xmin += UI_HEADER_OFFSET;
- hor.xmax -= UI_HEADER_OFFSET;
- vert.ymin += UI_HEADER_OFFSET;
- vert.ymax -= UI_HEADER_OFFSET;
-
- /* width of sliders */
- smaller = (int)(0.1f * U.widget_unit);
- if (scroll & V2D_SCROLL_BOTTOM) {
- hor.ymin += smaller;
- }
- else {
- hor.ymax -= smaller;
- }
-
- if (scroll & V2D_SCROLL_LEFT) {
- vert.xmin += smaller;
- }
- else {
- vert.xmax -= smaller;
- }
-
- CLAMP(vert.ymin, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
- CLAMP(hor.xmin, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
-
- /* store in scrollers, used for drawing */
- scrollers->vert = vert;
- scrollers->hor = hor;
-
- /* scroller 'buttons':
- * - These should always remain within the visible region of the scrollbar
- * - They represent the region of 'tot' that is visible in 'cur'
- */
-
- /* horizontal scrollers */
- if (scroll & V2D_SCROLL_HORIZONTAL) {
- /* scroller 'button' extents */
- totsize = BLI_rctf_size_x(&v2d->tot);
- scrollsize = (float)BLI_rcti_size_x(&hor);
- if (totsize == 0.0f) {
- totsize = 1.0f; /* avoid divide by zero */
- }
-
- fac1 = (v2d->cur.xmin - v2d->tot.xmin) / totsize;
- if (fac1 <= 0.0f) {
- scrollers->hor_min = hor.xmin;
- }
- else {
- scrollers->hor_min = (int)(hor.xmin + (fac1 * scrollsize));
- }
-
- fac2 = (v2d->cur.xmax - v2d->tot.xmin) / totsize;
- if (fac2 >= 1.0f) {
- scrollers->hor_max = hor.xmax;
- }
- else {
- scrollers->hor_max = (int)(hor.xmin + (fac2 * scrollsize));
- }
-
- /* prevent inverted sliders */
- if (scrollers->hor_min > scrollers->hor_max) {
- scrollers->hor_min = scrollers->hor_max;
- }
- /* prevent sliders from being too small, and disappearing */
- if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLLER_HANDLE_SIZE) {
- scrollers->hor_max = scrollers->hor_min + V2D_SCROLLER_HANDLE_SIZE;
-
- CLAMP(scrollers->hor_max, hor.xmin + V2D_SCROLLER_HANDLE_SIZE, hor.xmax);
- CLAMP(scrollers->hor_min, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
- }
-
- }
-
- /* vertical scrollers */
- if (scroll & V2D_SCROLL_VERTICAL) {
- /* scroller 'button' extents */
- totsize = BLI_rctf_size_y(&v2d->tot);
- scrollsize = (float)BLI_rcti_size_y(&vert);
- if (totsize == 0.0f) {
- totsize = 1.0f; /* avoid divide by zero */
- }
-
- fac1 = (v2d->cur.ymin - v2d->tot.ymin) / totsize;
- if (fac1 <= 0.0f) {
- scrollers->vert_min = vert.ymin;
- }
- else {
- scrollers->vert_min = (int)(vert.ymin + (fac1 * scrollsize));
- }
-
- fac2 = (v2d->cur.ymax - v2d->tot.ymin) / totsize;
- if (fac2 >= 1.0f) {
- scrollers->vert_max = vert.ymax;
- }
- else {
- scrollers->vert_max = (int)(vert.ymin + (fac2 * scrollsize));
- }
-
- /* prevent inverted sliders */
- if (scrollers->vert_min > scrollers->vert_max) {
- scrollers->vert_min = scrollers->vert_max;
- }
- /* prevent sliders from being too small, and disappearing */
- if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLLER_HANDLE_SIZE) {
-
- scrollers->vert_max = scrollers->vert_min + V2D_SCROLLER_HANDLE_SIZE;
-
- CLAMP(scrollers->vert_max, vert.ymin + V2D_SCROLLER_HANDLE_SIZE, vert.ymax);
- CLAMP(scrollers->vert_min, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
- }
-
- }
-
- /* grid markings on scrollbars */
- if (scroll & (V2D_SCROLL_SCALE_HORIZONTAL | V2D_SCROLL_SCALE_VERTICAL)) {
- /* store clamping */
- scrollers->xclamp = xclamp;
- scrollers->xunits = xunits;
- scrollers->yclamp = yclamp;
- scrollers->yunits = yunits;
-
- scrollers->grid = UI_view2d_grid_calc(
- CTX_data_scene(C), v2d,
- xunits, xclamp, yunits, yclamp,
- BLI_rcti_size_x(&hor), BLI_rcti_size_y(&vert));
- }
-
- /* return scrollers */
- return scrollers;
+ View2DScrollers *scrollers;
+ rcti vert, hor;
+ float fac1, fac2, totsize, scrollsize;
+ int scroll = view2d_scroll_mapped(v2d->scroll);
+ int smaller;
+
+ /* scrollers is allocated here... */
+ scrollers = MEM_callocN(sizeof(View2DScrollers), "View2DScrollers");
+
+ /* Always update before drawing (for dynamically sized scrollers). */
+ view2d_masks(v2d, false, mask_custom);
+
+ vert = v2d->vert;
+ hor = v2d->hor;
+
+ /* slider rects need to be smaller than region and not interfere with splitter areas */
+ hor.xmin += UI_HEADER_OFFSET;
+ hor.xmax -= UI_HEADER_OFFSET;
+ vert.ymin += UI_HEADER_OFFSET;
+ vert.ymax -= UI_HEADER_OFFSET;
+
+ /* width of sliders */
+ smaller = (int)(0.1f * U.widget_unit);
+ if (scroll & V2D_SCROLL_BOTTOM) {
+ hor.ymin += smaller;
+ }
+ else {
+ hor.ymax -= smaller;
+ }
+
+ if (scroll & V2D_SCROLL_LEFT) {
+ vert.xmin += smaller;
+ }
+ else {
+ vert.xmax -= smaller;
+ }
+
+ CLAMP(vert.ymin, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
+ CLAMP(hor.xmin, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
+
+ /* store in scrollers, used for drawing */
+ scrollers->vert = vert;
+ scrollers->hor = hor;
+
+ /* scroller 'buttons':
+ * - These should always remain within the visible region of the scrollbar
+ * - They represent the region of 'tot' that is visible in 'cur'
+ */
+
+ /* horizontal scrollers */
+ if (scroll & V2D_SCROLL_HORIZONTAL) {
+ /* scroller 'button' extents */
+ totsize = BLI_rctf_size_x(&v2d->tot);
+ scrollsize = (float)BLI_rcti_size_x(&hor);
+ if (totsize == 0.0f) {
+ totsize = 1.0f; /* avoid divide by zero */
+ }
+
+ fac1 = (v2d->cur.xmin - v2d->tot.xmin) / totsize;
+ if (fac1 <= 0.0f) {
+ scrollers->hor_min = hor.xmin;
+ }
+ else {
+ scrollers->hor_min = (int)(hor.xmin + (fac1 * scrollsize));
+ }
+
+ fac2 = (v2d->cur.xmax - v2d->tot.xmin) / totsize;
+ if (fac2 >= 1.0f) {
+ scrollers->hor_max = hor.xmax;
+ }
+ else {
+ scrollers->hor_max = (int)(hor.xmin + (fac2 * scrollsize));
+ }
+
+ /* prevent inverted sliders */
+ if (scrollers->hor_min > scrollers->hor_max) {
+ scrollers->hor_min = scrollers->hor_max;
+ }
+ /* prevent sliders from being too small, and disappearing */
+ if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLLER_HANDLE_SIZE) {
+ scrollers->hor_max = scrollers->hor_min + V2D_SCROLLER_HANDLE_SIZE;
+
+ CLAMP(scrollers->hor_max, hor.xmin + V2D_SCROLLER_HANDLE_SIZE, hor.xmax);
+ CLAMP(scrollers->hor_min, hor.xmin, hor.xmax - V2D_SCROLLER_HANDLE_SIZE);
+ }
+ }
+
+ /* vertical scrollers */
+ if (scroll & V2D_SCROLL_VERTICAL) {
+ /* scroller 'button' extents */
+ totsize = BLI_rctf_size_y(&v2d->tot);
+ scrollsize = (float)BLI_rcti_size_y(&vert);
+ if (totsize == 0.0f) {
+ totsize = 1.0f; /* avoid divide by zero */
+ }
+
+ fac1 = (v2d->cur.ymin - v2d->tot.ymin) / totsize;
+ if (fac1 <= 0.0f) {
+ scrollers->vert_min = vert.ymin;
+ }
+ else {
+ scrollers->vert_min = (int)(vert.ymin + (fac1 * scrollsize));
+ }
+
+ fac2 = (v2d->cur.ymax - v2d->tot.ymin) / totsize;
+ if (fac2 >= 1.0f) {
+ scrollers->vert_max = vert.ymax;
+ }
+ else {
+ scrollers->vert_max = (int)(vert.ymin + (fac2 * scrollsize));
+ }
+
+ /* prevent inverted sliders */
+ if (scrollers->vert_min > scrollers->vert_max) {
+ scrollers->vert_min = scrollers->vert_max;
+ }
+ /* prevent sliders from being too small, and disappearing */
+ if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLLER_HANDLE_SIZE) {
+
+ scrollers->vert_max = scrollers->vert_min + V2D_SCROLLER_HANDLE_SIZE;
+
+ CLAMP(scrollers->vert_max, vert.ymin + V2D_SCROLLER_HANDLE_SIZE, vert.ymax);
+ CLAMP(scrollers->vert_min, vert.ymin, vert.ymax - V2D_SCROLLER_HANDLE_SIZE);
+ }
+ }
+
+ /* grid markings on scrollbars */
+ if (scroll & (V2D_SCROLL_SCALE_HORIZONTAL | V2D_SCROLL_SCALE_VERTICAL)) {
+ /* store clamping */
+ scrollers->xclamp = xclamp;
+ scrollers->xunits = xunits;
+ scrollers->yclamp = yclamp;
+ scrollers->yunits = yunits;
+
+ scrollers->grid = UI_view2d_grid_calc(CTX_data_scene(C),
+ v2d,
+ xunits,
+ xclamp,
+ yunits,
+ yclamp,
+ BLI_rcti_size_x(&hor),
+ BLI_rcti_size_y(&vert));
+ }
+
+ /* return scrollers */
+ return scrollers;
}
/* Draw scrollbars in the given 2d-region */
void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *vs)
{
- bTheme *btheme = UI_GetTheme();
- rcti vert, hor;
- const int scroll = view2d_scroll_mapped(v2d->scroll);
- const char emboss_alpha = btheme->tui.widget_emboss[3];
- uchar scrollers_back_color[4];
-
- /* Color for scrollbar backs */
- UI_GetThemeColor4ubv(TH_BACK, scrollers_back_color);
-
- /* make copies of rects for less typing */
- vert = vs->vert;
- hor = vs->hor;
-
- /* horizontal scrollbar */
- if (scroll & V2D_SCROLL_HORIZONTAL) {
- uiWidgetColors wcol = btheme->tui.wcol_scroll;
- const float alpha_fac = v2d->alpha_hor / 255.0f;
- rcti slider;
- int state;
-
- slider.xmin = vs->hor_min;
- slider.xmax = vs->hor_max;
- slider.ymin = hor.ymin;
- slider.ymax = hor.ymax;
-
- state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-
- wcol.inner[3] *= alpha_fac;
- wcol.item[3] *= alpha_fac;
- wcol.outline[3] *= alpha_fac;
- btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
-
- /* show zoom handles if:
- * - zooming on x-axis is allowed (no scroll otherwise)
- * - slider bubble is large enough (no overdraw confusion)
- * - scale is shown on the scroller
- * (workaround to make sure that button windows don't show these,
- * and only the time-grids with their zoomability can do so)
- */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 &&
- (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) &&
- (BLI_rcti_size_x(&slider) > V2D_SCROLLER_HANDLE_SIZE))
- {
- state |= UI_SCROLL_ARROWS;
- }
-
- UI_draw_widget_scroll(&wcol, &hor, &slider, state);
-
- {
- if (scroll & V2D_SCROLL_SCALE_HORIZONTAL) {
- UI_view2d_grid_draw_numbers_horizontal(
- CTX_data_scene(C), v2d, vs->grid, &vs->hor, vs->xunits, vs->xclamp == V2D_GRID_CLAMP);
- }
- }
- }
-
- /* vertical scrollbar */
- if (scroll & V2D_SCROLL_VERTICAL) {
- uiWidgetColors wcol = btheme->tui.wcol_scroll;
- rcti slider;
- const float alpha_fac = v2d->alpha_vert / 255.0f;
- int state;
-
- slider.xmin = vert.xmin;
- slider.xmax = vert.xmax;
- slider.ymin = vs->vert_min;
- slider.ymax = vs->vert_max;
-
- state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
-
- wcol.inner[3] *= alpha_fac;
- wcol.item[3] *= alpha_fac;
- wcol.outline[3] *= alpha_fac;
- btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
-
- /* show zoom handles if:
- * - zooming on y-axis is allowed (no scroll otherwise)
- * - slider bubble is large enough (no overdraw confusion)
- * - scale is shown on the scroller
- * (workaround to make sure that button windows don't show these,
- * and only the time-grids with their zoomability can do so)
- */
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 &&
- (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) &&
- (BLI_rcti_size_y(&slider) > V2D_SCROLLER_HANDLE_SIZE))
- {
- state |= UI_SCROLL_ARROWS;
- }
-
- UI_draw_widget_scroll(&wcol, &vert, &slider, state);
-
- {
- if (scroll & V2D_SCROLL_SCALE_VERTICAL) {
- float text_offset = 0.0f;
- if (vs->yclamp & V2D_GRID_CLAMP) {
- text_offset = 0.5f;
- }
- UI_view2d_grid_draw_numbers_vertical(
- CTX_data_scene(C), v2d, vs->grid, &vs->vert, vs->yunits, text_offset);
- }
- }
- }
-
- /* Was changed above, so reset. */
- btheme->tui.widget_emboss[3] = emboss_alpha;
+ bTheme *btheme = UI_GetTheme();
+ rcti vert, hor;
+ const int scroll = view2d_scroll_mapped(v2d->scroll);
+ const char emboss_alpha = btheme->tui.widget_emboss[3];
+ uchar scrollers_back_color[4];
+
+ /* Color for scrollbar backs */
+ UI_GetThemeColor4ubv(TH_BACK, scrollers_back_color);
+
+ /* make copies of rects for less typing */
+ vert = vs->vert;
+ hor = vs->hor;
+
+ /* horizontal scrollbar */
+ if (scroll & V2D_SCROLL_HORIZONTAL) {
+ uiWidgetColors wcol = btheme->tui.wcol_scroll;
+ const float alpha_fac = v2d->alpha_hor / 255.0f;
+ rcti slider;
+ int state;
+
+ slider.xmin = vs->hor_min;
+ slider.xmax = vs->hor_max;
+ slider.ymin = hor.ymin;
+ slider.ymax = hor.ymax;
+
+ state = (v2d->scroll_ui & V2D_SCROLL_H_ACTIVE) ? UI_SCROLL_PRESSED : 0;
+
+ wcol.inner[3] *= alpha_fac;
+ wcol.item[3] *= alpha_fac;
+ wcol.outline[3] *= alpha_fac;
+ btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
+
+ /* show zoom handles if:
+ * - zooming on x-axis is allowed (no scroll otherwise)
+ * - slider bubble is large enough (no overdraw confusion)
+ * - scale is shown on the scroller
+ * (workaround to make sure that button windows don't show these,
+ * and only the time-grids with their zoomability can do so)
+ */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0 && (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) &&
+ (BLI_rcti_size_x(&slider) > V2D_SCROLLER_HANDLE_SIZE)) {
+ state |= UI_SCROLL_ARROWS;
+ }
+
+ UI_draw_widget_scroll(&wcol, &hor, &slider, state);
+
+ {
+ if (scroll & V2D_SCROLL_SCALE_HORIZONTAL) {
+ UI_view2d_grid_draw_numbers_horizontal(
+ CTX_data_scene(C), v2d, vs->grid, &vs->hor, vs->xunits, vs->xclamp == V2D_GRID_CLAMP);
+ }
+ }
+ }
+
+ /* vertical scrollbar */
+ if (scroll & V2D_SCROLL_VERTICAL) {
+ uiWidgetColors wcol = btheme->tui.wcol_scroll;
+ rcti slider;
+ const float alpha_fac = v2d->alpha_vert / 255.0f;
+ int state;
+
+ slider.xmin = vert.xmin;
+ slider.xmax = vert.xmax;
+ slider.ymin = vs->vert_min;
+ slider.ymax = vs->vert_max;
+
+ state = (v2d->scroll_ui & V2D_SCROLL_V_ACTIVE) ? UI_SCROLL_PRESSED : 0;
+
+ wcol.inner[3] *= alpha_fac;
+ wcol.item[3] *= alpha_fac;
+ wcol.outline[3] *= alpha_fac;
+ btheme->tui.widget_emboss[3] *= alpha_fac; /* will be reset later */
+
+ /* show zoom handles if:
+ * - zooming on y-axis is allowed (no scroll otherwise)
+ * - slider bubble is large enough (no overdraw confusion)
+ * - scale is shown on the scroller
+ * (workaround to make sure that button windows don't show these,
+ * and only the time-grids with their zoomability can do so)
+ */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0 && (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) &&
+ (BLI_rcti_size_y(&slider) > V2D_SCROLLER_HANDLE_SIZE)) {
+ state |= UI_SCROLL_ARROWS;
+ }
+
+ UI_draw_widget_scroll(&wcol, &vert, &slider, state);
+
+ {
+ if (scroll & V2D_SCROLL_SCALE_VERTICAL) {
+ float text_offset = 0.0f;
+ if (vs->yclamp & V2D_GRID_CLAMP) {
+ text_offset = 0.5f;
+ }
+ UI_view2d_grid_draw_numbers_vertical(
+ CTX_data_scene(C), v2d, vs->grid, &vs->vert, vs->yunits, text_offset);
+ }
+ }
+ }
+
+ /* Was changed above, so reset. */
+ btheme->tui.widget_emboss[3] = emboss_alpha;
}
/* free temporary memory used for drawing scrollers */
void UI_view2d_scrollers_free(View2DScrollers *scrollers)
{
- /* need to free grid as well... */
- if (scrollers->grid) {
- MEM_freeN(scrollers->grid);
- }
- MEM_freeN(scrollers);
+ /* need to free grid as well... */
+ if (scrollers->grid) {
+ MEM_freeN(scrollers->grid);
+ }
+ MEM_freeN(scrollers);
}
/* *********************************************************************** */
@@ -2162,41 +2156,45 @@ void UI_view2d_scrollers_free(View2DScrollers *scrollers)
* \param rect: coordinates of the cell
* (passed as single var instead of 4 separate, as it's more useful this way)
*/
-void UI_view2d_listview_cell_to_view(
- View2D *v2d, float columnwidth, float rowheight,
- float startx, float starty,
- int column, int row, rctf *rect)
+void UI_view2d_listview_cell_to_view(View2D *v2d,
+ float columnwidth,
+ float rowheight,
+ float startx,
+ float starty,
+ int column,
+ int row,
+ rctf *rect)
{
- /* sanity checks */
- if (ELEM(NULL, v2d, rect)) {
- return;
- }
-
- if ((columnwidth <= 0) && (rowheight <= 0)) {
- rect->xmin = rect->xmax = 0.0f;
- rect->ymin = rect->ymax = 0.0f;
- return;
- }
-
- /* x-coordinates */
- rect->xmin = startx + (float)(columnwidth * column);
- rect->xmax = startx + (float)(columnwidth * (column + 1));
-
- if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
- /* simply negate the values for the coordinates if in negative half */
- rect->xmin = -rect->xmin;
- rect->xmax = -rect->xmax;
- }
-
- /* y-coordinates */
- rect->ymin = starty + (float)(rowheight * row);
- rect->ymax = starty + (float)(rowheight * (row + 1));
-
- if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
- /* simply negate the values for the coordinates if in negative half */
- rect->ymin = -rect->ymin;
- rect->ymax = -rect->ymax;
- }
+ /* sanity checks */
+ if (ELEM(NULL, v2d, rect)) {
+ return;
+ }
+
+ if ((columnwidth <= 0) && (rowheight <= 0)) {
+ rect->xmin = rect->xmax = 0.0f;
+ rect->ymin = rect->ymax = 0.0f;
+ return;
+ }
+
+ /* x-coordinates */
+ rect->xmin = startx + (float)(columnwidth * column);
+ rect->xmax = startx + (float)(columnwidth * (column + 1));
+
+ if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
+ /* simply negate the values for the coordinates if in negative half */
+ rect->xmin = -rect->xmin;
+ rect->xmax = -rect->xmax;
+ }
+
+ /* y-coordinates */
+ rect->ymin = starty + (float)(rowheight * row);
+ rect->ymax = starty + (float)(rowheight * (row + 1));
+
+ if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
+ /* simply negate the values for the coordinates if in negative half */
+ rect->ymin = -rect->ymin;
+ rect->ymax = -rect->ymax;
+ }
}
/**
@@ -2210,41 +2208,47 @@ void UI_view2d_listview_cell_to_view(
* \param viewx, viewy: 2D-coordinates (in 2D-view / 'tot' rect space) to get the cell for
* \param r_column, r_row: the 'coordinates' of the relevant 'cell'
*/
-void UI_view2d_listview_view_to_cell(
- View2D *v2d, float columnwidth, float rowheight, float startx, float starty,
- float viewx, float viewy, int *r_column, int *r_row)
+void UI_view2d_listview_view_to_cell(View2D *v2d,
+ float columnwidth,
+ float rowheight,
+ float startx,
+ float starty,
+ float viewx,
+ float viewy,
+ int *r_column,
+ int *r_row)
{
- /* adjust view coordinates to be all positive ints, corrected for the start offset */
- const int x = (int)(floorf(fabsf(viewx) + 0.5f) - startx);
- const int y = (int)(floorf(fabsf(viewy) + 0.5f) - starty);
-
- /* sizes must not be negative */
- if ((v2d == NULL) || ((columnwidth <= 0) && (rowheight <= 0))) {
- if (r_column) {
- *r_column = 0;
- }
- if (r_row) {
- *r_row = 0;
- }
-
- return;
- }
-
- /* get column */
- if ((r_column) && (columnwidth > 0)) {
- *r_column = x / columnwidth;
- }
- else if (r_column) {
- *r_column = 0;
- }
-
- /* get row */
- if ((r_row) && (rowheight > 0)) {
- *r_row = y / rowheight;
- }
- else if (r_row) {
- *r_row = 0;
- }
+ /* adjust view coordinates to be all positive ints, corrected for the start offset */
+ const int x = (int)(floorf(fabsf(viewx) + 0.5f) - startx);
+ const int y = (int)(floorf(fabsf(viewy) + 0.5f) - starty);
+
+ /* sizes must not be negative */
+ if ((v2d == NULL) || ((columnwidth <= 0) && (rowheight <= 0))) {
+ if (r_column) {
+ *r_column = 0;
+ }
+ if (r_row) {
+ *r_row = 0;
+ }
+
+ return;
+ }
+
+ /* get column */
+ if ((r_column) && (columnwidth > 0)) {
+ *r_column = x / columnwidth;
+ }
+ else if (r_column) {
+ *r_column = 0;
+ }
+
+ /* get row */
+ if ((r_row) && (rowheight > 0)) {
+ *r_row = y / rowheight;
+ }
+ else if (r_row) {
+ *r_row = 0;
+ }
}
/**
@@ -2254,22 +2258,40 @@ void UI_view2d_listview_view_to_cell(
* \param startx, starty: Coordinates that the list starts from, which should be (0,0) for most views
* \param column_min, column_max, row_min, row_max: The starting and ending column/row indices
*/
-void UI_view2d_listview_visible_cells(
- View2D *v2d, float columnwidth, float rowheight, float startx, float starty,
- int *column_min, int *column_max, int *row_min, int *row_max)
+void UI_view2d_listview_visible_cells(View2D *v2d,
+ float columnwidth,
+ float rowheight,
+ float startx,
+ float starty,
+ int *column_min,
+ int *column_max,
+ int *row_min,
+ int *row_max)
{
- /* using 'cur' rect coordinates, call the cell-getting function to get the cells for this */
- if (v2d) {
- /* min */
- UI_view2d_listview_view_to_cell(
- v2d, columnwidth, rowheight, startx, starty,
- v2d->cur.xmin, v2d->cur.ymin, column_min, row_min);
-
- /* max*/
- UI_view2d_listview_view_to_cell(
- v2d, columnwidth, rowheight, startx, starty,
- v2d->cur.xmax, v2d->cur.ymax, column_max, row_max);
- }
+ /* using 'cur' rect coordinates, call the cell-getting function to get the cells for this */
+ if (v2d) {
+ /* min */
+ UI_view2d_listview_view_to_cell(v2d,
+ columnwidth,
+ rowheight,
+ startx,
+ starty,
+ v2d->cur.xmin,
+ v2d->cur.ymin,
+ column_min,
+ row_min);
+
+ /* max*/
+ UI_view2d_listview_view_to_cell(v2d,
+ columnwidth,
+ rowheight,
+ startx,
+ starty,
+ v2d->cur.xmax,
+ v2d->cur.ymax,
+ column_max,
+ row_max);
+ }
}
/* *********************************************************************** */
@@ -2277,11 +2299,13 @@ void UI_view2d_listview_visible_cells(
float UI_view2d_region_to_view_x(const struct View2D *v2d, float x)
{
- return (v2d->cur.xmin + (BLI_rctf_size_x(&v2d->cur) * (x - v2d->mask.xmin) / BLI_rcti_size_x(&v2d->mask)));
+ return (v2d->cur.xmin +
+ (BLI_rctf_size_x(&v2d->cur) * (x - v2d->mask.xmin) / BLI_rcti_size_x(&v2d->mask)));
}
float UI_view2d_region_to_view_y(const struct View2D *v2d, float y)
{
- return (v2d->cur.ymin + (BLI_rctf_size_y(&v2d->cur) * (y - v2d->mask.ymin) / BLI_rcti_size_y(&v2d->mask)));
+ return (v2d->cur.ymin +
+ (BLI_rctf_size_y(&v2d->cur) * (y - v2d->mask.ymin) / BLI_rcti_size_y(&v2d->mask)));
}
/**
@@ -2290,30 +2314,37 @@ float UI_view2d_region_to_view_y(const struct View2D *v2d, float y)
* \param x, y: coordinates to convert
* \param r_view_x, r_view_y: resultant coordinates
*/
-void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y)
+void UI_view2d_region_to_view(
+ const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y)
{
- *r_view_x = UI_view2d_region_to_view_x(v2d, x);
- *r_view_y = UI_view2d_region_to_view_y(v2d, y);
+ *r_view_x = UI_view2d_region_to_view_x(v2d, x);
+ *r_view_y = UI_view2d_region_to_view_y(v2d, y);
}
void UI_view2d_region_to_view_rctf(const View2D *v2d, const rctf *rect_src, rctf *rect_dst)
{
- const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
- const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
-
- rect_dst->xmin = (v2d->cur.xmin + (cur_size[0] * (rect_src->xmin - v2d->mask.xmin) / mask_size[0]));
- rect_dst->xmax = (v2d->cur.xmin + (cur_size[0] * (rect_src->xmax - v2d->mask.xmin) / mask_size[0]));
- rect_dst->ymin = (v2d->cur.ymin + (cur_size[1] * (rect_src->ymin - v2d->mask.ymin) / mask_size[1]));
- rect_dst->ymax = (v2d->cur.ymin + (cur_size[1] * (rect_src->ymax - v2d->mask.ymin) / mask_size[1]));
+ const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
+ const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
+
+ rect_dst->xmin = (v2d->cur.xmin +
+ (cur_size[0] * (rect_src->xmin - v2d->mask.xmin) / mask_size[0]));
+ rect_dst->xmax = (v2d->cur.xmin +
+ (cur_size[0] * (rect_src->xmax - v2d->mask.xmin) / mask_size[0]));
+ rect_dst->ymin = (v2d->cur.ymin +
+ (cur_size[1] * (rect_src->ymin - v2d->mask.ymin) / mask_size[1]));
+ rect_dst->ymax = (v2d->cur.ymin +
+ (cur_size[1] * (rect_src->ymax - v2d->mask.ymin) / mask_size[1]));
}
float UI_view2d_view_to_region_x(const View2D *v2d, float x)
{
- return (v2d->mask.xmin + (((x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur)) * BLI_rcti_size_x(&v2d->mask)));
+ return (v2d->mask.xmin +
+ (((x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur)) * BLI_rcti_size_x(&v2d->mask)));
}
float UI_view2d_view_to_region_y(const View2D *v2d, float y)
{
- return (v2d->mask.ymin + (((y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur)) * BLI_rcti_size_y(&v2d->mask)));
+ return (v2d->mask.ymin +
+ (((y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur)) * BLI_rcti_size_y(&v2d->mask)));
}
/**
@@ -2323,25 +2354,26 @@ float UI_view2d_view_to_region_y(const View2D *v2d, float y)
* \param x, y: Coordinates to convert.
* \param r_region_x, r_region_y: Resultant coordinates.
*/
-bool UI_view2d_view_to_region_clip(const View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
+bool UI_view2d_view_to_region_clip(
+ const View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
{
- /* express given coordinates as proportional values */
- x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
- y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
-
- /* check if values are within bounds */
- if ((x >= 0.0f) && (x <= 1.0f) && (y >= 0.0f) && (y <= 1.0f)) {
- *r_region_x = (int)(v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask)));
- *r_region_y = (int)(v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask)));
-
- return true;
- }
- else {
- /* set initial value in case coordinate lies outside of bounds */
- *r_region_x = *r_region_y = V2D_IS_CLIPPED;
-
- return false;
- }
+ /* express given coordinates as proportional values */
+ x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
+ y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
+
+ /* check if values are within bounds */
+ if ((x >= 0.0f) && (x <= 1.0f) && (y >= 0.0f) && (y <= 1.0f)) {
+ *r_region_x = (int)(v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask)));
+ *r_region_y = (int)(v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask)));
+
+ return true;
+ }
+ else {
+ /* set initial value in case coordinate lies outside of bounds */
+ *r_region_x = *r_region_y = V2D_IS_CLIPPED;
+
+ return false;
+ }
}
/**
@@ -2354,92 +2386,91 @@ bool UI_view2d_view_to_region_clip(const View2D *v2d, float x, float y, int *r_r
*/
void UI_view2d_view_to_region(View2D *v2d, float x, float y, int *r_region_x, int *r_region_y)
{
- /* step 1: express given coordinates as proportional values */
- x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
- y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
+ /* step 1: express given coordinates as proportional values */
+ x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
+ y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
- /* step 2: convert proportional distances to screen coordinates */
- x = v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask));
- y = v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask));
+ /* step 2: convert proportional distances to screen coordinates */
+ x = v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask));
+ y = v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask));
- /* although we don't clamp to lie within region bounds, we must avoid exceeding size of ints */
- *r_region_x = clamp_float_to_int(x);
- *r_region_y = clamp_float_to_int(y);
+ /* although we don't clamp to lie within region bounds, we must avoid exceeding size of ints */
+ *r_region_x = clamp_float_to_int(x);
+ *r_region_y = clamp_float_to_int(y);
}
-void UI_view2d_view_to_region_fl(View2D *v2d, float x, float y, float *r_region_x, float *r_region_y)
+void UI_view2d_view_to_region_fl(
+ View2D *v2d, float x, float y, float *r_region_x, float *r_region_y)
{
- /* express given coordinates as proportional values */
- x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
- y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
+ /* express given coordinates as proportional values */
+ x = (x - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
+ y = (y - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
- /* convert proportional distances to screen coordinates */
- *r_region_x = v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask));
- *r_region_y = v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask));
+ /* convert proportional distances to screen coordinates */
+ *r_region_x = v2d->mask.xmin + (x * BLI_rcti_size_x(&v2d->mask));
+ *r_region_y = v2d->mask.ymin + (y * BLI_rcti_size_y(&v2d->mask));
}
void UI_view2d_view_to_region_rcti(View2D *v2d, const rctf *rect_src, rcti *rect_dst)
{
- const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
- const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
- rctf rect_tmp;
-
- /* step 1: express given coordinates as proportional values */
- rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
- rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
- rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
- rect_tmp.ymax = (rect_src->ymax - v2d->cur.ymin) / cur_size[1];
-
-
- /* step 2: convert proportional distances to screen coordinates */
- rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
- rect_tmp.xmax = v2d->mask.xmin + (rect_tmp.xmax * mask_size[0]);
- rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
- rect_tmp.ymax = v2d->mask.ymin + (rect_tmp.ymax * mask_size[1]);
-
- clamp_rctf_to_rcti(rect_dst, &rect_tmp);
+ const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
+ const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
+ rctf rect_tmp;
+
+ /* step 1: express given coordinates as proportional values */
+ rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
+ rect_tmp.ymax = (rect_src->ymax - v2d->cur.ymin) / cur_size[1];
+
+ /* step 2: convert proportional distances to screen coordinates */
+ rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
+ rect_tmp.xmax = v2d->mask.xmin + (rect_tmp.xmax * mask_size[0]);
+ rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
+ rect_tmp.ymax = v2d->mask.ymin + (rect_tmp.ymax * mask_size[1]);
+
+ clamp_rctf_to_rcti(rect_dst, &rect_tmp);
}
void UI_view2d_view_to_region_m4(View2D *v2d, float matrix[4][4])
{
- rctf mask;
- unit_m4(matrix);
- BLI_rctf_rcti_copy(&mask, &v2d->mask);
- BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &mask, matrix);
+ rctf mask;
+ unit_m4(matrix);
+ BLI_rctf_rcti_copy(&mask, &v2d->mask);
+ BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &mask, matrix);
}
bool UI_view2d_view_to_region_rcti_clip(View2D *v2d, const rctf *rect_src, rcti *rect_dst)
{
- const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
- const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
- rctf rect_tmp;
-
- BLI_assert(rect_src->xmin <= rect_src->xmax && rect_src->ymin <= rect_src->ymax);
-
- /* step 1: express given coordinates as proportional values */
- rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
- rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
- rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
- rect_tmp.ymax = (rect_src->ymax - v2d->cur.ymin) / cur_size[1];
-
- if (((rect_tmp.xmax < 0.0f) || (rect_tmp.xmin > 1.0f) ||
- (rect_tmp.ymax < 0.0f) || (rect_tmp.ymin > 1.0f)) == 0)
- {
- /* step 2: convert proportional distances to screen coordinates */
- rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
- rect_tmp.xmax = v2d->mask.ymin + (rect_tmp.xmax * mask_size[0]);
- rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
- rect_tmp.ymax = v2d->mask.ymin + (rect_tmp.ymax * mask_size[1]);
-
- clamp_rctf_to_rcti(rect_dst, &rect_tmp);
-
- return true;
- }
- else {
- rect_dst->xmin = rect_dst->xmax = rect_dst->ymin = rect_dst->ymax = V2D_IS_CLIPPED;
-
- return false;
- }
+ const float cur_size[2] = {BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)};
+ const float mask_size[2] = {BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask)};
+ rctf rect_tmp;
+
+ BLI_assert(rect_src->xmin <= rect_src->xmax && rect_src->ymin <= rect_src->ymax);
+
+ /* step 1: express given coordinates as proportional values */
+ rect_tmp.xmin = (rect_src->xmin - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.xmax = (rect_src->xmax - v2d->cur.xmin) / cur_size[0];
+ rect_tmp.ymin = (rect_src->ymin - v2d->cur.ymin) / cur_size[1];
+ rect_tmp.ymax = (rect_src->ymax - v2d->cur.ymin) / cur_size[1];
+
+ if (((rect_tmp.xmax < 0.0f) || (rect_tmp.xmin > 1.0f) || (rect_tmp.ymax < 0.0f) ||
+ (rect_tmp.ymin > 1.0f)) == 0) {
+ /* step 2: convert proportional distances to screen coordinates */
+ rect_tmp.xmin = v2d->mask.xmin + (rect_tmp.xmin * mask_size[0]);
+ rect_tmp.xmax = v2d->mask.ymin + (rect_tmp.xmax * mask_size[0]);
+ rect_tmp.ymin = v2d->mask.ymin + (rect_tmp.ymin * mask_size[1]);
+ rect_tmp.ymax = v2d->mask.ymin + (rect_tmp.ymax * mask_size[1]);
+
+ clamp_rctf_to_rcti(rect_dst, &rect_tmp);
+
+ return true;
+ }
+ else {
+ rect_dst->xmin = rect_dst->xmax = rect_dst->ymin = rect_dst->ymax = V2D_IS_CLIPPED;
+
+ return false;
+ }
}
/* *********************************************************************** */
@@ -2448,38 +2479,37 @@ bool UI_view2d_view_to_region_rcti_clip(View2D *v2d, const rctf *rect_src, rcti
/* View2D data by default resides in region, so get from region stored in context */
View2D *UI_view2d_fromcontext(const bContext *C)
{
- ScrArea *area = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
-
- if (area == NULL) {
- return NULL;
- }
- if (region == NULL) {
- return NULL;
- }
- return &(region->v2d);
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+
+ if (area == NULL) {
+ return NULL;
+ }
+ if (region == NULL) {
+ return NULL;
+ }
+ return &(region->v2d);
}
/* same as above, but it returns regionwindow. Utility for pulldowns or buttons */
View2D *UI_view2d_fromcontext_rwin(const bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *region = CTX_wm_region(C);
-
- if (sa == NULL) {
- return NULL;
- }
- if (region == NULL) {
- return NULL;
- }
- if (region->regiontype != RGN_TYPE_WINDOW) {
- ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- return ar ? &(ar->v2d) : NULL;
- }
- return &(region->v2d);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+
+ if (sa == NULL) {
+ return NULL;
+ }
+ if (region == NULL) {
+ return NULL;
+ }
+ if (region->regiontype != RGN_TYPE_WINDOW) {
+ ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ return ar ? &(ar->v2d) : NULL;
+ }
+ return &(region->v2d);
}
-
/**
* Calculate the scale per-axis of the drawing-area
*
@@ -2490,32 +2520,32 @@ View2D *UI_view2d_fromcontext_rwin(const bContext *C)
*/
void UI_view2d_scale_get(View2D *v2d, float *r_x, float *r_y)
{
- if (r_x) {
- *r_x = UI_view2d_scale_get_x(v2d);
- }
- if (r_y) {
- *r_y = UI_view2d_scale_get_y(v2d);
- }
+ if (r_x) {
+ *r_x = UI_view2d_scale_get_x(v2d);
+ }
+ if (r_y) {
+ *r_y = UI_view2d_scale_get_y(v2d);
+ }
}
float UI_view2d_scale_get_x(const View2D *v2d)
{
- return BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur);
+ return BLI_rcti_size_x(&v2d->mask) / BLI_rctf_size_x(&v2d->cur);
}
float UI_view2d_scale_get_y(const View2D *v2d)
{
- return BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur);
+ return BLI_rcti_size_y(&v2d->mask) / BLI_rctf_size_y(&v2d->cur);
}
/**
* Same as ``UI_view2d_scale_get() - 1.0f / x, y``
*/
void UI_view2d_scale_get_inverse(View2D *v2d, float *r_x, float *r_y)
{
- if (r_x) {
- *r_x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
- }
- if (r_y) {
- *r_y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
- }
+ if (r_x) {
+ *r_x = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
+ }
+ if (r_y) {
+ *r_y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
+ }
}
/**
@@ -2524,20 +2554,20 @@ void UI_view2d_scale_get_inverse(View2D *v2d, float *r_x, float *r_y)
*/
void UI_view2d_center_get(struct View2D *v2d, float *r_x, float *r_y)
{
- /* get center */
- if (r_x) {
- *r_x = BLI_rctf_cent_x(&v2d->cur);
- }
- if (r_y) {
- *r_y = BLI_rctf_cent_y(&v2d->cur);
- }
+ /* get center */
+ if (r_x) {
+ *r_x = BLI_rctf_cent_x(&v2d->cur);
+ }
+ if (r_y) {
+ *r_y = BLI_rctf_cent_y(&v2d->cur);
+ }
}
void UI_view2d_center_set(struct View2D *v2d, float x, float y)
{
- BLI_rctf_recenter(&v2d->cur, x, y);
+ BLI_rctf_recenter(&v2d->cur, x, y);
- /* make sure that 'cur' rect is in a valid state as a result of these changes */
- UI_view2d_curRect_validate(v2d);
+ /* make sure that 'cur' rect is in a valid state as a result of these changes */
+ UI_view2d_curRect_validate(v2d);
}
/**
@@ -2548,25 +2578,25 @@ void UI_view2d_center_set(struct View2D *v2d, float x, float y)
*/
void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac)
{
- if (xfac != -1.0f) {
- const float xsize = BLI_rctf_size_x(&v2d->cur);
- const float xmin = v2d->tot.xmin;
- const float xmax = v2d->tot.xmax - xsize;
+ if (xfac != -1.0f) {
+ const float xsize = BLI_rctf_size_x(&v2d->cur);
+ const float xmin = v2d->tot.xmin;
+ const float xmax = v2d->tot.xmax - xsize;
- v2d->cur.xmin = (xmin * (1.0f - xfac)) + (xmax * xfac);
- v2d->cur.xmax = v2d->cur.xmin + xsize;
- }
+ v2d->cur.xmin = (xmin * (1.0f - xfac)) + (xmax * xfac);
+ v2d->cur.xmax = v2d->cur.xmin + xsize;
+ }
- if (yfac != -1.0f) {
- const float ysize = BLI_rctf_size_y(&v2d->cur);
- const float ymin = v2d->tot.ymin;
- const float ymax = v2d->tot.ymax - ysize;
+ if (yfac != -1.0f) {
+ const float ysize = BLI_rctf_size_y(&v2d->cur);
+ const float ymin = v2d->tot.ymin;
+ const float ymax = v2d->tot.ymax - ysize;
- v2d->cur.ymin = (ymin * (1.0f - yfac)) + (ymax * yfac);
- v2d->cur.ymax = v2d->cur.ymin + ysize;
- }
+ v2d->cur.ymin = (ymin * (1.0f - yfac)) + (ymax * yfac);
+ v2d->cur.ymax = v2d->cur.ymin + ysize;
+ }
- UI_view2d_curRect_validate(v2d);
+ UI_view2d_curRect_validate(v2d);
}
/**
@@ -2581,169 +2611,166 @@ void UI_view2d_offset(struct View2D *v2d, float xfac, float yfac)
* - 0 = not in scroller.
*/
char UI_view2d_mouse_in_scrollers_ex(
- const ARegion *ar, const View2D *v2d, int x, int y,
- int *r_scroll)
+ const ARegion *ar, const View2D *v2d, int x, int y, int *r_scroll)
{
- int co[2];
- int scroll = view2d_scroll_mapped(v2d->scroll);
- *r_scroll = scroll;
-
- /* clamp x,y to region-coordinates first */
- co[0] = x - ar->winrct.xmin;
- co[1] = y - ar->winrct.ymin;
-
- /* check if within scrollbars */
- if (scroll & V2D_SCROLL_HORIZONTAL) {
- if (IN_2D_HORIZ_SCROLL(v2d, co)) {
- return 'h';
- }
- }
- if (scroll & V2D_SCROLL_VERTICAL) {
- if (IN_2D_VERT_SCROLL(v2d, co)) {
- return 'v';
- }
- }
-
- /* not found */
- return 0;
+ int co[2];
+ int scroll = view2d_scroll_mapped(v2d->scroll);
+ *r_scroll = scroll;
+
+ /* clamp x,y to region-coordinates first */
+ co[0] = x - ar->winrct.xmin;
+ co[1] = y - ar->winrct.ymin;
+
+ /* check if within scrollbars */
+ if (scroll & V2D_SCROLL_HORIZONTAL) {
+ if (IN_2D_HORIZ_SCROLL(v2d, co)) {
+ return 'h';
+ }
+ }
+ if (scroll & V2D_SCROLL_VERTICAL) {
+ if (IN_2D_VERT_SCROLL(v2d, co)) {
+ return 'v';
+ }
+ }
+
+ /* not found */
+ return 0;
}
-char UI_view2d_mouse_in_scrollers(
- const ARegion *ar, const View2D *v2d, int x, int y)
+char UI_view2d_mouse_in_scrollers(const ARegion *ar, const View2D *v2d, int x, int y)
{
- int scroll_dummy = 0;
- return UI_view2d_mouse_in_scrollers_ex(ar, v2d, x, y, &scroll_dummy);
+ int scroll_dummy = 0;
+ return UI_view2d_mouse_in_scrollers_ex(ar, v2d, x, y, &scroll_dummy);
}
/* ******************* view2d text drawing cache ******************** */
typedef struct View2DString {
- struct View2DString *next;
- union {
- uchar ub[4];
- int pack;
- } col;
- rcti rect;
- int mval[2];
-
- /* str is allocated past the end */
- char str[0];
+ struct View2DString *next;
+ union {
+ uchar ub[4];
+ int pack;
+ } col;
+ rcti rect;
+ int mval[2];
+
+ /* str is allocated past the end */
+ char str[0];
} View2DString;
/* assumes caches are used correctly, so for time being no local storage in v2d */
-static MemArena *g_v2d_strings_arena = NULL;
+static MemArena *g_v2d_strings_arena = NULL;
static View2DString *g_v2d_strings = NULL;
void UI_view2d_text_cache_add(
- View2D *v2d, float x, float y,
- const char *str, size_t str_len, const char col[4])
+ View2D *v2d, float x, float y, const char *str, size_t str_len, const char col[4])
{
- int mval[2];
+ int mval[2];
- BLI_assert(str_len == strlen(str));
+ BLI_assert(str_len == strlen(str));
- if (UI_view2d_view_to_region_clip(v2d, x, y, &mval[0], &mval[1])) {
- int alloc_len = str_len + 1;
- View2DString *v2s;
+ if (UI_view2d_view_to_region_clip(v2d, x, y, &mval[0], &mval[1])) {
+ int alloc_len = str_len + 1;
+ View2DString *v2s;
- if (g_v2d_strings_arena == NULL) {
- g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
- }
+ if (g_v2d_strings_arena == NULL) {
+ g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
+ }
- v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
+ v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
- BLI_LINKS_PREPEND(g_v2d_strings, v2s);
+ BLI_LINKS_PREPEND(g_v2d_strings, v2s);
- v2s->col.pack = *((const int *)col);
+ v2s->col.pack = *((const int *)col);
- memset(&v2s->rect, 0, sizeof(v2s->rect));
+ memset(&v2s->rect, 0, sizeof(v2s->rect));
- v2s->mval[0] = mval[0];
- v2s->mval[1] = mval[1];
+ v2s->mval[0] = mval[0];
+ v2s->mval[1] = mval[1];
- memcpy(v2s->str, str, alloc_len);
- }
+ memcpy(v2s->str, str, alloc_len);
+ }
}
/* no clip (yet) */
void UI_view2d_text_cache_add_rectf(
- View2D *v2d, const rctf *rect_view,
- const char *str, size_t str_len, const char col[4])
+ View2D *v2d, const rctf *rect_view, const char *str, size_t str_len, const char col[4])
{
- rcti rect;
+ rcti rect;
- BLI_assert(str_len == strlen(str));
+ BLI_assert(str_len == strlen(str));
- if (UI_view2d_view_to_region_rcti_clip(v2d, rect_view, &rect)) {
- int alloc_len = str_len + 1;
- View2DString *v2s;
+ if (UI_view2d_view_to_region_rcti_clip(v2d, rect_view, &rect)) {
+ int alloc_len = str_len + 1;
+ View2DString *v2s;
- if (g_v2d_strings_arena == NULL) {
- g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
- }
+ if (g_v2d_strings_arena == NULL) {
+ g_v2d_strings_arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 14), __func__);
+ }
- v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
+ v2s = BLI_memarena_alloc(g_v2d_strings_arena, sizeof(View2DString) + alloc_len);
- BLI_LINKS_PREPEND(g_v2d_strings, v2s);
+ BLI_LINKS_PREPEND(g_v2d_strings, v2s);
- v2s->col.pack = *((const int *)col);
+ v2s->col.pack = *((const int *)col);
- v2s->rect = rect;
+ v2s->rect = rect;
- v2s->mval[0] = v2s->rect.xmin;
- v2s->mval[1] = v2s->rect.ymin;
+ v2s->mval[0] = v2s->rect.xmin;
+ v2s->mval[1] = v2s->rect.ymin;
- memcpy(v2s->str, str, alloc_len);
- }
+ memcpy(v2s->str, str, alloc_len);
+ }
}
-
void UI_view2d_text_cache_draw(ARegion *ar)
{
- View2DString *v2s;
- int col_pack_prev = 0;
-
- /* investigate using BLF_ascender() */
- const int font_id = BLF_default();
-
- BLF_set_default();
- const float default_height = g_v2d_strings ? BLF_height(font_id, "28", 3) : 0.0f;
-
- wmOrtho2_region_pixelspace(ar);
-
- for (v2s = g_v2d_strings; v2s; v2s = v2s->next) {
- int xofs = 0, yofs;
-
- yofs = ceil(0.5f * (BLI_rcti_size_y(&v2s->rect) - default_height));
- if (yofs < 1) {
- yofs = 1;
- }
-
- if (col_pack_prev != v2s->col.pack) {
- BLF_color3ubv(font_id, v2s->col.ub);
- col_pack_prev = v2s->col.pack;
- }
-
- if (v2s->rect.xmin >= v2s->rect.xmax) {
- BLF_draw_default(
- (float)(v2s->mval[0] + xofs), (float)(v2s->mval[1] + yofs), 0.0,
- v2s->str, BLF_DRAW_STR_DUMMY_MAX);
- }
- else {
- BLF_enable(font_id, BLF_CLIPPING);
- BLF_clipping(font_id, v2s->rect.xmin - 4, v2s->rect.ymin - 4, v2s->rect.xmax + 4, v2s->rect.ymax + 4);
- BLF_draw_default(v2s->rect.xmin + xofs, v2s->rect.ymin + yofs, 0.0f,
- v2s->str, BLF_DRAW_STR_DUMMY_MAX);
- BLF_disable(font_id, BLF_CLIPPING);
- }
- }
- g_v2d_strings = NULL;
-
- if (g_v2d_strings_arena) {
- BLI_memarena_free(g_v2d_strings_arena);
- g_v2d_strings_arena = NULL;
- }
+ View2DString *v2s;
+ int col_pack_prev = 0;
+
+ /* investigate using BLF_ascender() */
+ const int font_id = BLF_default();
+
+ BLF_set_default();
+ const float default_height = g_v2d_strings ? BLF_height(font_id, "28", 3) : 0.0f;
+
+ wmOrtho2_region_pixelspace(ar);
+
+ for (v2s = g_v2d_strings; v2s; v2s = v2s->next) {
+ int xofs = 0, yofs;
+
+ yofs = ceil(0.5f * (BLI_rcti_size_y(&v2s->rect) - default_height));
+ if (yofs < 1) {
+ yofs = 1;
+ }
+
+ if (col_pack_prev != v2s->col.pack) {
+ BLF_color3ubv(font_id, v2s->col.ub);
+ col_pack_prev = v2s->col.pack;
+ }
+
+ if (v2s->rect.xmin >= v2s->rect.xmax) {
+ BLF_draw_default((float)(v2s->mval[0] + xofs),
+ (float)(v2s->mval[1] + yofs),
+ 0.0,
+ v2s->str,
+ BLF_DRAW_STR_DUMMY_MAX);
+ }
+ else {
+ BLF_enable(font_id, BLF_CLIPPING);
+ BLF_clipping(
+ font_id, v2s->rect.xmin - 4, v2s->rect.ymin - 4, v2s->rect.xmax + 4, v2s->rect.ymax + 4);
+ BLF_draw_default(
+ v2s->rect.xmin + xofs, v2s->rect.ymin + yofs, 0.0f, v2s->str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_disable(font_id, BLF_CLIPPING);
+ }
+ }
+ g_v2d_strings = NULL;
+
+ if (g_v2d_strings_arena) {
+ BLI_memarena_free(g_v2d_strings_arena);
+ g_v2d_strings_arena = NULL;
+ }
}
-
/* ******************************************************** */
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 62d434584fe..855ad0306c4 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -21,7 +21,6 @@
* \ingroup edinterface
*/
-
#include <math.h>
#include "MEM_guardedalloc.h"
@@ -50,13 +49,13 @@
static bool view2d_poll(bContext *C)
{
- ARegion *ar = CTX_wm_region(C);
+ ARegion *ar = CTX_wm_region(C);
- return (ar != NULL) && (ar->v2d.flag & V2D_IS_INITIALISED);
+ return (ar != NULL) && (ar->v2d.flag & V2D_IS_INITIALISED);
}
/* ********************************************************* */
-/* VIEW PANNING OPERATOR */
+/* VIEW PANNING OPERATOR */
/**
* This group of operators come in several forms:
@@ -71,139 +70,135 @@ static bool view2d_poll(bContext *C)
/* temp customdata for operator */
typedef struct v2dViewPanData {
- /** screen where view pan was initiated */
- bScreen *sc;
- /** area where view pan was initiated */
- ScrArea *sa;
- /** region where view pan was initiated */
- ARegion *ar;
- /** view2d we're operating in */
- View2D *v2d;
-
- /** amount to move view relative to zoom */
- float facx, facy;
-
- /* options for version 1 */
- /** mouse x/y values in window when operator was initiated */
- int startx, starty;
- /** previous x/y values of mouse in window */
- int lastx, lasty;
- /** event starting pan, for modal exit */
- int invoke_event;
-
- /** for MMB in scrollers (old feature in past, but now not that useful) */
- short in_scroller;
+ /** screen where view pan was initiated */
+ bScreen *sc;
+ /** area where view pan was initiated */
+ ScrArea *sa;
+ /** region where view pan was initiated */
+ ARegion *ar;
+ /** view2d we're operating in */
+ View2D *v2d;
+
+ /** amount to move view relative to zoom */
+ float facx, facy;
+
+ /* options for version 1 */
+ /** mouse x/y values in window when operator was initiated */
+ int startx, starty;
+ /** previous x/y values of mouse in window */
+ int lastx, lasty;
+ /** event starting pan, for modal exit */
+ int invoke_event;
+
+ /** for MMB in scrollers (old feature in past, but now not that useful) */
+ short in_scroller;
} v2dViewPanData;
/* initialize panning customdata */
static int view_pan_init(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- v2dViewPanData *vpd;
- View2D *v2d;
- float winx, winy;
-
- /* regions now have v2d-data by default, so check for region */
- if (ar == NULL) {
- return 0;
- }
-
- /* check if panning is allowed at all */
- v2d = &ar->v2d;
- if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y)) {
- return 0;
- }
-
- /* set custom-data for operator */
- vpd = MEM_callocN(sizeof(v2dViewPanData), "v2dViewPanData");
- op->customdata = vpd;
-
- /* set pointers to owners */
- vpd->sc = CTX_wm_screen(C);
- vpd->sa = CTX_wm_area(C);
- vpd->v2d = v2d;
- vpd->ar = ar;
-
- /* calculate translation factor - based on size of view */
- winx = (float)(BLI_rcti_size_x(&ar->winrct) + 1);
- winy = (float)(BLI_rcti_size_y(&ar->winrct) + 1);
- vpd->facx = (BLI_rctf_size_x(&v2d->cur)) / winx;
- vpd->facy = (BLI_rctf_size_y(&v2d->cur)) / winy;
-
- return 1;
+ ARegion *ar = CTX_wm_region(C);
+ v2dViewPanData *vpd;
+ View2D *v2d;
+ float winx, winy;
+
+ /* regions now have v2d-data by default, so check for region */
+ if (ar == NULL) {
+ return 0;
+ }
+
+ /* check if panning is allowed at all */
+ v2d = &ar->v2d;
+ if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y)) {
+ return 0;
+ }
+
+ /* set custom-data for operator */
+ vpd = MEM_callocN(sizeof(v2dViewPanData), "v2dViewPanData");
+ op->customdata = vpd;
+
+ /* set pointers to owners */
+ vpd->sc = CTX_wm_screen(C);
+ vpd->sa = CTX_wm_area(C);
+ vpd->v2d = v2d;
+ vpd->ar = ar;
+
+ /* calculate translation factor - based on size of view */
+ winx = (float)(BLI_rcti_size_x(&ar->winrct) + 1);
+ winy = (float)(BLI_rcti_size_y(&ar->winrct) + 1);
+ vpd->facx = (BLI_rctf_size_x(&v2d->cur)) / winx;
+ vpd->facy = (BLI_rctf_size_y(&v2d->cur)) / winy;
+
+ return 1;
}
#ifdef WITH_INPUT_NDOF
static bool view_pan_poll(bContext *C)
{
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d;
-
- /* check if there's a region in context to work with */
- if (ar == NULL) {
- return 0;
- }
- v2d = &ar->v2d;
-
- /* check that 2d-view can pan */
- if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y)) {
- return 0;
- }
-
- /* view can pan */
- return 1;
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d;
+
+ /* check if there's a region in context to work with */
+ if (ar == NULL) {
+ return 0;
+ }
+ v2d = &ar->v2d;
+
+ /* check that 2d-view can pan */
+ if ((v2d->keepofs & V2D_LOCKOFS_X) && (v2d->keepofs & V2D_LOCKOFS_Y)) {
+ return 0;
+ }
+
+ /* view can pan */
+ return 1;
}
#endif
/* apply transform to view (i.e. adjust 'cur' rect) */
static void view_pan_apply_ex(bContext *C, v2dViewPanData *vpd, float dx, float dy)
{
- View2D *v2d = vpd->v2d;
+ View2D *v2d = vpd->v2d;
- /* calculate amount to move view by */
- dx *= vpd->facx;
- dy *= vpd->facy;
+ /* calculate amount to move view by */
+ dx *= vpd->facx;
+ dy *= vpd->facy;
- /* only move view on an axis if change is allowed */
- if ((v2d->keepofs & V2D_LOCKOFS_X) == 0) {
- v2d->cur.xmin += dx;
- v2d->cur.xmax += dx;
- }
- if ((v2d->keepofs & V2D_LOCKOFS_Y) == 0) {
- v2d->cur.ymin += dy;
- v2d->cur.ymax += dy;
- }
+ /* only move view on an axis if change is allowed */
+ if ((v2d->keepofs & V2D_LOCKOFS_X) == 0) {
+ v2d->cur.xmin += dx;
+ v2d->cur.xmax += dx;
+ }
+ if ((v2d->keepofs & V2D_LOCKOFS_Y) == 0) {
+ v2d->cur.ymin += dy;
+ v2d->cur.ymax += dy;
+ }
- /* validate that view is in valid configuration after this operation */
- UI_view2d_curRect_validate(v2d);
+ /* validate that view is in valid configuration after this operation */
+ UI_view2d_curRect_validate(v2d);
- /* don't rebuild full tree in outliner, since we're just changing our view */
- ED_region_tag_redraw_no_rebuild(vpd->ar);
+ /* don't rebuild full tree in outliner, since we're just changing our view */
+ ED_region_tag_redraw_no_rebuild(vpd->ar);
- /* request updates to be done... */
- WM_event_add_mousemove(C);
+ /* request updates to be done... */
+ WM_event_add_mousemove(C);
- UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
+ UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
}
static void view_pan_apply(bContext *C, wmOperator *op)
{
- v2dViewPanData *vpd = op->customdata;
-
- view_pan_apply_ex(
- C, vpd,
- RNA_int_get(op->ptr, "deltax"),
- RNA_int_get(op->ptr, "deltay"));
+ v2dViewPanData *vpd = op->customdata;
+ view_pan_apply_ex(C, vpd, RNA_int_get(op->ptr, "deltax"), RNA_int_get(op->ptr, "deltay"));
}
/* cleanup temp customdata */
static void view_pan_exit(wmOperator *op)
{
- if (op->customdata) {
- MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
}
/* ------------------ Modal Drag Version (1) ---------------------- */
@@ -211,141 +206,140 @@ static void view_pan_exit(wmOperator *op)
/* for 'redo' only, with no user input */
static int view_pan_exec(bContext *C, wmOperator *op)
{
- if (!view_pan_init(C, op)) {
- return OPERATOR_CANCELLED;
- }
+ if (!view_pan_init(C, op)) {
+ return OPERATOR_CANCELLED;
+ }
- view_pan_apply(C, op);
- view_pan_exit(op);
- return OPERATOR_FINISHED;
+ view_pan_apply(C, op);
+ view_pan_exit(op);
+ return OPERATOR_FINISHED;
}
/* set up modal operator and relevant settings */
static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- wmWindow *window = CTX_wm_window(C);
- v2dViewPanData *vpd;
- View2D *v2d;
-
- /* set up customdata */
- if (!view_pan_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
-
- vpd = op->customdata;
- v2d = vpd->v2d;
-
- /* set initial settings */
- vpd->startx = vpd->lastx = event->x;
- vpd->starty = vpd->lasty = event->y;
- vpd->invoke_event = event->type;
-
- if (event->type == MOUSEPAN) {
- RNA_int_set(op->ptr, "deltax", event->prevx - event->x);
- RNA_int_set(op->ptr, "deltay", event->prevy - event->y);
-
- view_pan_apply(C, op);
- view_pan_exit(op);
- return OPERATOR_FINISHED;
- }
-
- RNA_int_set(op->ptr, "deltax", 0);
- RNA_int_set(op->ptr, "deltay", 0);
-
- if (v2d->keepofs & V2D_LOCKOFS_X) {
- WM_cursor_modal_set(window, BC_NS_SCROLLCURSOR);
- }
- else if (v2d->keepofs & V2D_LOCKOFS_Y) {
- WM_cursor_modal_set(window, BC_EW_SCROLLCURSOR);
- }
- else {
- WM_cursor_modal_set(window, BC_NSEW_SCROLLCURSOR);
- }
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- return OPERATOR_RUNNING_MODAL;
+ wmWindow *window = CTX_wm_window(C);
+ v2dViewPanData *vpd;
+ View2D *v2d;
+
+ /* set up customdata */
+ if (!view_pan_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ vpd = op->customdata;
+ v2d = vpd->v2d;
+
+ /* set initial settings */
+ vpd->startx = vpd->lastx = event->x;
+ vpd->starty = vpd->lasty = event->y;
+ vpd->invoke_event = event->type;
+
+ if (event->type == MOUSEPAN) {
+ RNA_int_set(op->ptr, "deltax", event->prevx - event->x);
+ RNA_int_set(op->ptr, "deltay", event->prevy - event->y);
+
+ view_pan_apply(C, op);
+ view_pan_exit(op);
+ return OPERATOR_FINISHED;
+ }
+
+ RNA_int_set(op->ptr, "deltax", 0);
+ RNA_int_set(op->ptr, "deltay", 0);
+
+ if (v2d->keepofs & V2D_LOCKOFS_X) {
+ WM_cursor_modal_set(window, BC_NS_SCROLLCURSOR);
+ }
+ else if (v2d->keepofs & V2D_LOCKOFS_Y) {
+ WM_cursor_modal_set(window, BC_EW_SCROLLCURSOR);
+ }
+ else {
+ WM_cursor_modal_set(window, BC_NSEW_SCROLLCURSOR);
+ }
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
}
/* handle user input - calculations of mouse-movement
* need to be done here, not in the apply callback! */
static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- v2dViewPanData *vpd = op->customdata;
-
- /* execute the events */
- switch (event->type) {
- case MOUSEMOVE:
- {
- /* calculate new delta transform, then store mouse-coordinates for next-time */
- RNA_int_set(op->ptr, "deltax", (vpd->lastx - event->x));
- RNA_int_set(op->ptr, "deltay", (vpd->lasty - event->y));
-
- vpd->lastx = event->x;
- vpd->lasty = event->y;
-
- view_pan_apply(C, op);
- break;
- }
- /* XXX - Mode switching isn't implemented. See comments in 36818.
- * switch to zoom */
+ v2dViewPanData *vpd = op->customdata;
+
+ /* execute the events */
+ switch (event->type) {
+ case MOUSEMOVE: {
+ /* calculate new delta transform, then store mouse-coordinates for next-time */
+ RNA_int_set(op->ptr, "deltax", (vpd->lastx - event->x));
+ RNA_int_set(op->ptr, "deltay", (vpd->lasty - event->y));
+
+ vpd->lastx = event->x;
+ vpd->lasty = event->y;
+
+ view_pan_apply(C, op);
+ break;
+ }
+ /* XXX - Mode switching isn't implemented. See comments in 36818.
+ * switch to zoom */
#if 0
- case LEFTMOUSE:
- if (event->val == KM_PRESS) {
- /* calculate overall delta mouse-movement for redo */
- RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
- RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
-
- view_pan_exit(op);
- WM_cursor_modal_restore(CTX_wm_window(C));
- WM_operator_name_call(C, "VIEW2D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
- return OPERATOR_FINISHED;
- }
+ case LEFTMOUSE:
+ if (event->val == KM_PRESS) {
+ /* calculate overall delta mouse-movement for redo */
+ RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
+ RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
+
+ view_pan_exit(op);
+ WM_cursor_modal_restore(CTX_wm_window(C));
+ WM_operator_name_call(C, "VIEW2D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
+ return OPERATOR_FINISHED;
+ }
#endif
- default:
- if (event->type == vpd->invoke_event || event->type == ESCKEY) {
- if (event->val == KM_RELEASE) {
- /* calculate overall delta mouse-movement for redo */
- RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
- RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
-
- view_pan_exit(op);
- WM_cursor_modal_restore(CTX_wm_window(C));
-
- return OPERATOR_FINISHED;
- }
- }
- break;
- }
-
- return OPERATOR_RUNNING_MODAL;
+ default:
+ if (event->type == vpd->invoke_event || event->type == ESCKEY) {
+ if (event->val == KM_RELEASE) {
+ /* calculate overall delta mouse-movement for redo */
+ RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
+ RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
+
+ view_pan_exit(op);
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ return OPERATOR_FINISHED;
+ }
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
static void view_pan_cancel(bContext *UNUSED(C), wmOperator *op)
{
- view_pan_exit(op);
+ view_pan_exit(op);
}
static void VIEW2D_OT_pan(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Pan View";
- ot->description = "Pan the view";
- ot->idname = "VIEW2D_OT_pan";
-
- /* api callbacks */
- ot->exec = view_pan_exec;
- ot->invoke = view_pan_invoke;
- ot->modal = view_pan_modal;
- ot->cancel = view_pan_cancel;
-
- /* operator is modal */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
-
- /* rna - must keep these in sync with the other operators */
- RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
+ /* identifiers */
+ ot->name = "Pan View";
+ ot->description = "Pan the view";
+ ot->idname = "VIEW2D_OT_pan";
+
+ /* api callbacks */
+ ot->exec = view_pan_exec;
+ ot->invoke = view_pan_invoke;
+ ot->modal = view_pan_modal;
+ ot->cancel = view_pan_cancel;
+
+ /* operator is modal */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
+
+ /* rna - must keep these in sync with the other operators */
+ RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
}
/* ------------------ Scrollwheel Versions (2) ---------------------- */
@@ -353,196 +347,191 @@ static void VIEW2D_OT_pan(wmOperatorType *ot)
/* this operator only needs this single callback, where it calls the view_pan_*() methods */
static int view_scrollright_exec(bContext *C, wmOperator *op)
{
- v2dViewPanData *vpd;
+ v2dViewPanData *vpd;
- /* initialize default settings (and validate if ok to run) */
- if (!view_pan_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
+ /* initialize default settings (and validate if ok to run) */
+ if (!view_pan_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
- /* also, check if can pan in horizontal axis */
- vpd = op->customdata;
- if (vpd->v2d->keepofs & V2D_LOCKOFS_X) {
- view_pan_exit(op);
- return OPERATOR_PASS_THROUGH;
- }
+ /* also, check if can pan in horizontal axis */
+ vpd = op->customdata;
+ if (vpd->v2d->keepofs & V2D_LOCKOFS_X) {
+ view_pan_exit(op);
+ return OPERATOR_PASS_THROUGH;
+ }
- /* set RNA-Props - only movement in positive x-direction */
- RNA_int_set(op->ptr, "deltax", 40);
- RNA_int_set(op->ptr, "deltay", 0);
+ /* set RNA-Props - only movement in positive x-direction */
+ RNA_int_set(op->ptr, "deltax", 40);
+ RNA_int_set(op->ptr, "deltay", 0);
- /* apply movement, then we're done */
- view_pan_apply(C, op);
- view_pan_exit(op);
+ /* apply movement, then we're done */
+ view_pan_apply(C, op);
+ view_pan_exit(op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void VIEW2D_OT_scroll_right(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Scroll Right";
- ot->description = "Scroll the view right";
- ot->idname = "VIEW2D_OT_scroll_right";
+ /* identifiers */
+ ot->name = "Scroll Right";
+ ot->description = "Scroll the view right";
+ ot->idname = "VIEW2D_OT_scroll_right";
- /* api callbacks */
- ot->exec = view_scrollright_exec;
+ /* api callbacks */
+ ot->exec = view_scrollright_exec;
- /* rna - must keep these in sync with the other operators */
- RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
+ /* rna - must keep these in sync with the other operators */
+ RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
}
-
-
/* this operator only needs this single callback, where it calls the view_pan_*() methods */
static int view_scrollleft_exec(bContext *C, wmOperator *op)
{
- v2dViewPanData *vpd;
+ v2dViewPanData *vpd;
- /* initialize default settings (and validate if ok to run) */
- if (!view_pan_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
+ /* initialize default settings (and validate if ok to run) */
+ if (!view_pan_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
- /* also, check if can pan in horizontal axis */
- vpd = op->customdata;
- if (vpd->v2d->keepofs & V2D_LOCKOFS_X) {
- view_pan_exit(op);
- return OPERATOR_PASS_THROUGH;
- }
+ /* also, check if can pan in horizontal axis */
+ vpd = op->customdata;
+ if (vpd->v2d->keepofs & V2D_LOCKOFS_X) {
+ view_pan_exit(op);
+ return OPERATOR_PASS_THROUGH;
+ }
- /* set RNA-Props - only movement in negative x-direction */
- RNA_int_set(op->ptr, "deltax", -40);
- RNA_int_set(op->ptr, "deltay", 0);
+ /* set RNA-Props - only movement in negative x-direction */
+ RNA_int_set(op->ptr, "deltax", -40);
+ RNA_int_set(op->ptr, "deltay", 0);
- /* apply movement, then we're done */
- view_pan_apply(C, op);
- view_pan_exit(op);
+ /* apply movement, then we're done */
+ view_pan_apply(C, op);
+ view_pan_exit(op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void VIEW2D_OT_scroll_left(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Scroll Left";
- ot->description = "Scroll the view left";
- ot->idname = "VIEW2D_OT_scroll_left";
+ /* identifiers */
+ ot->name = "Scroll Left";
+ ot->description = "Scroll the view left";
+ ot->idname = "VIEW2D_OT_scroll_left";
- /* api callbacks */
- ot->exec = view_scrollleft_exec;
+ /* api callbacks */
+ ot->exec = view_scrollleft_exec;
- /* rna - must keep these in sync with the other operators */
- RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
+ /* rna - must keep these in sync with the other operators */
+ RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
}
-
/* this operator only needs this single callback, where it calls the view_pan_*() methods */
static int view_scrolldown_exec(bContext *C, wmOperator *op)
{
- v2dViewPanData *vpd;
-
- /* initialize default settings (and validate if ok to run) */
- if (!view_pan_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
-
- /* also, check if can pan in vertical axis */
- vpd = op->customdata;
- if (vpd->v2d->keepofs & V2D_LOCKOFS_Y) {
- view_pan_exit(op);
- return OPERATOR_PASS_THROUGH;
- }
-
- /* set RNA-Props */
- RNA_int_set(op->ptr, "deltax", 0);
- RNA_int_set(op->ptr, "deltay", -40);
-
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
- if (RNA_property_is_set(op->ptr, prop) && RNA_property_boolean_get(op->ptr, prop)) {
- ARegion *ar = CTX_wm_region(C);
- RNA_int_set(op->ptr, "deltay", ar->v2d.mask.ymin - ar->v2d.mask.ymax);
- }
-
- /* apply movement, then we're done */
- view_pan_apply(C, op);
- view_pan_exit(op);
-
- return OPERATOR_FINISHED;
+ v2dViewPanData *vpd;
+
+ /* initialize default settings (and validate if ok to run) */
+ if (!view_pan_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ /* also, check if can pan in vertical axis */
+ vpd = op->customdata;
+ if (vpd->v2d->keepofs & V2D_LOCKOFS_Y) {
+ view_pan_exit(op);
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ /* set RNA-Props */
+ RNA_int_set(op->ptr, "deltax", 0);
+ RNA_int_set(op->ptr, "deltay", -40);
+
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
+ if (RNA_property_is_set(op->ptr, prop) && RNA_property_boolean_get(op->ptr, prop)) {
+ ARegion *ar = CTX_wm_region(C);
+ RNA_int_set(op->ptr, "deltay", ar->v2d.mask.ymin - ar->v2d.mask.ymax);
+ }
+
+ /* apply movement, then we're done */
+ view_pan_apply(C, op);
+ view_pan_exit(op);
+
+ return OPERATOR_FINISHED;
}
static void VIEW2D_OT_scroll_down(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Scroll Down";
- ot->description = "Scroll the view down";
- ot->idname = "VIEW2D_OT_scroll_down";
-
- /* api callbacks */
- ot->exec = view_scrolldown_exec;
-
- /* rna - must keep these in sync with the other operators */
- RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
- RNA_def_boolean(ot->srna, "page", 0, "Page", "Scroll down one page");
+ /* identifiers */
+ ot->name = "Scroll Down";
+ ot->description = "Scroll the view down";
+ ot->idname = "VIEW2D_OT_scroll_down";
+
+ /* api callbacks */
+ ot->exec = view_scrolldown_exec;
+
+ /* rna - must keep these in sync with the other operators */
+ RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
+ RNA_def_boolean(ot->srna, "page", 0, "Page", "Scroll down one page");
}
-
-
/* this operator only needs this single callback, where it calls the view_pan_*() methods */
static int view_scrollup_exec(bContext *C, wmOperator *op)
{
- v2dViewPanData *vpd;
-
- /* initialize default settings (and validate if ok to run) */
- if (!view_pan_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
-
- /* also, check if can pan in vertical axis */
- vpd = op->customdata;
- if (vpd->v2d->keepofs & V2D_LOCKOFS_Y) {
- view_pan_exit(op);
- return OPERATOR_PASS_THROUGH;
- }
-
- /* set RNA-Props */
- RNA_int_set(op->ptr, "deltax", 0);
- RNA_int_set(op->ptr, "deltay", 40);
-
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
- if (RNA_property_is_set(op->ptr, prop) && RNA_property_boolean_get(op->ptr, prop)) {
- ARegion *ar = CTX_wm_region(C);
- RNA_int_set(op->ptr, "deltay", BLI_rcti_size_y(&ar->v2d.mask));
- }
-
- /* apply movement, then we're done */
- view_pan_apply(C, op);
- view_pan_exit(op);
-
- return OPERATOR_FINISHED;
+ v2dViewPanData *vpd;
+
+ /* initialize default settings (and validate if ok to run) */
+ if (!view_pan_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ /* also, check if can pan in vertical axis */
+ vpd = op->customdata;
+ if (vpd->v2d->keepofs & V2D_LOCKOFS_Y) {
+ view_pan_exit(op);
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ /* set RNA-Props */
+ RNA_int_set(op->ptr, "deltax", 0);
+ RNA_int_set(op->ptr, "deltay", 40);
+
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
+ if (RNA_property_is_set(op->ptr, prop) && RNA_property_boolean_get(op->ptr, prop)) {
+ ARegion *ar = CTX_wm_region(C);
+ RNA_int_set(op->ptr, "deltay", BLI_rcti_size_y(&ar->v2d.mask));
+ }
+
+ /* apply movement, then we're done */
+ view_pan_apply(C, op);
+ view_pan_exit(op);
+
+ return OPERATOR_FINISHED;
}
static void VIEW2D_OT_scroll_up(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Scroll Up";
- ot->description = "Scroll the view up";
- ot->idname = "VIEW2D_OT_scroll_up";
-
- /* api callbacks */
- ot->exec = view_scrollup_exec;
-
- /* rna - must keep these in sync with the other operators */
- RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
- RNA_def_boolean(ot->srna, "page", 0, "Page", "Scroll up one page");
+ /* identifiers */
+ ot->name = "Scroll Up";
+ ot->description = "Scroll the view up";
+ ot->idname = "VIEW2D_OT_scroll_up";
+
+ /* api callbacks */
+ ot->exec = view_scrollup_exec;
+
+ /* rna - must keep these in sync with the other operators */
+ RNA_def_int(ot->srna, "deltax", 0, INT_MIN, INT_MAX, "Delta X", "", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "deltay", 0, INT_MIN, INT_MAX, "Delta Y", "", INT_MIN, INT_MAX);
+ RNA_def_boolean(ot->srna, "page", 0, "Page", "Scroll up one page");
}
/* ********************************************************* */
-/* SINGLE-STEP VIEW ZOOMING OPERATOR */
+/* SINGLE-STEP VIEW ZOOMING OPERATOR */
/**
* This group of operators come in several forms:
@@ -562,17 +551,17 @@ static void VIEW2D_OT_scroll_up(wmOperatorType *ot)
/* temp customdata for operator */
typedef struct v2dViewZoomData {
- View2D *v2d; /* view2d we're operating in */
- ARegion *ar;
+ View2D *v2d; /* view2d we're operating in */
+ ARegion *ar;
- /* needed for continuous zoom */
- wmTimer *timer;
- double timer_lastdraw;
+ /* needed for continuous zoom */
+ wmTimer *timer;
+ double timer_lastdraw;
- int lastx, lasty; /* previous x/y values of mouse in window */
- int invoke_event; /* event type that invoked, for modal exits */
- float dx, dy; /* running tally of previous delta values (for obtaining final zoom) */
- float mx_2d, my_2d; /* initial mouse location in v2d coords */
+ int lastx, lasty; /* previous x/y values of mouse in window */
+ int invoke_event; /* event type that invoked, for modal exits */
+ float dx, dy; /* running tally of previous delta values (for obtaining final zoom) */
+ float mx_2d, my_2d; /* initial mouse location in v2d coords */
} v2dViewZoomData;
/**
@@ -581,195 +570,190 @@ typedef struct v2dViewZoomData {
*/
static void view_zoom_axis_lock_defaults(bContext *C, bool r_do_zoom_xy[2])
{
- ScrArea *sa = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
- r_do_zoom_xy[0] = true;
- r_do_zoom_xy[1] = true;
+ r_do_zoom_xy[0] = true;
+ r_do_zoom_xy[1] = true;
- /* default not to zoom the sequencer vertically */
- if (sa && sa->spacetype == SPACE_SEQ) {
- ARegion *ar = CTX_wm_region(C);
+ /* default not to zoom the sequencer vertically */
+ if (sa && sa->spacetype == SPACE_SEQ) {
+ ARegion *ar = CTX_wm_region(C);
- if (ar && ar->regiontype == RGN_TYPE_WINDOW) {
- r_do_zoom_xy[1] = false;
- }
- }
+ if (ar && ar->regiontype == RGN_TYPE_WINDOW) {
+ r_do_zoom_xy[1] = false;
+ }
+ }
}
/* initialize panning customdata */
static int view_zoomdrag_init(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- v2dViewZoomData *vzd;
- View2D *v2d;
-
- /* regions now have v2d-data by default, so check for region */
- if (ar == NULL) {
- return 0;
- }
- v2d = &ar->v2d;
-
- /* check that 2d-view is zoomable */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) && (v2d->keepzoom & V2D_LOCKZOOM_Y)) {
- return 0;
- }
-
- /* set custom-data for operator */
- vzd = MEM_callocN(sizeof(v2dViewZoomData), "v2dViewZoomData");
- op->customdata = vzd;
-
- /* set pointers to owners */
- vzd->v2d = v2d;
- vzd->ar = ar;
-
- return 1;
+ ARegion *ar = CTX_wm_region(C);
+ v2dViewZoomData *vzd;
+ View2D *v2d;
+
+ /* regions now have v2d-data by default, so check for region */
+ if (ar == NULL) {
+ return 0;
+ }
+ v2d = &ar->v2d;
+
+ /* check that 2d-view is zoomable */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) && (v2d->keepzoom & V2D_LOCKZOOM_Y)) {
+ return 0;
+ }
+
+ /* set custom-data for operator */
+ vzd = MEM_callocN(sizeof(v2dViewZoomData), "v2dViewZoomData");
+ op->customdata = vzd;
+
+ /* set pointers to owners */
+ vzd->v2d = v2d;
+ vzd->ar = ar;
+
+ return 1;
}
/* check if step-zoom can be applied */
static bool view_zoom_poll(bContext *C)
{
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d;
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d;
- /* check if there's a region in context to work with */
- if (ar == NULL) {
- return false;
- }
+ /* check if there's a region in context to work with */
+ if (ar == NULL) {
+ return false;
+ }
- /* Do not show that in 3DView context. */
- if (CTX_wm_region_view3d(C)) {
- return false;
- }
+ /* Do not show that in 3DView context. */
+ if (CTX_wm_region_view3d(C)) {
+ return false;
+ }
- v2d = &ar->v2d;
+ v2d = &ar->v2d;
- /* check that 2d-view is zoomable */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) && (v2d->keepzoom & V2D_LOCKZOOM_Y)) {
- return false;
- }
+ /* check that 2d-view is zoomable */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) && (v2d->keepzoom & V2D_LOCKZOOM_Y)) {
+ return false;
+ }
- /* view is zoomable */
- return true;
+ /* view is zoomable */
+ return true;
}
/* apply transform to view (i.e. adjust 'cur' rect) */
static void view_zoomstep_apply_ex(
- bContext *C, v2dViewZoomData *vzd, const bool use_mousepos,
- const float facx, const float facy)
+ bContext *C, v2dViewZoomData *vzd, const bool use_mousepos, const float facx, const float facy)
{
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
- const rctf cur_old = v2d->cur;
- float dx, dy;
- const int snap_test = ED_region_snap_size_test(ar);
-
- /* calculate amount to move view by, ensuring symmetry so the
- * old zoom level is restored after zooming back the same amount
- */
- if (facx >= 0.0f) {
- dx = BLI_rctf_size_x(&v2d->cur) * facx;
- dy = BLI_rctf_size_y(&v2d->cur) * facy;
- }
- else {
- dx = (BLI_rctf_size_x(&v2d->cur) / (1.0f + 2.0f * facx)) * facx;
- dy = (BLI_rctf_size_y(&v2d->cur) / (1.0f + 2.0f * facy)) * facy;
- }
-
- /* only resize view on an axis if change is allowed */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
- if (v2d->keepofs & V2D_LOCKOFS_X) {
- v2d->cur.xmax -= 2 * dx;
- }
- else if (v2d->keepofs & V2D_KEEPOFS_X) {
- if (v2d->align & V2D_ALIGN_NO_POS_X) {
- v2d->cur.xmin += 2 * dx;
- }
- else {
- v2d->cur.xmax -= 2 * dx;
- }
- }
- else {
-
- v2d->cur.xmin += dx;
- v2d->cur.xmax -= dx;
-
- if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
- /* get zoom fac the same way as in
- * ui_view2d_curRect_validate_resize - better keep in sync! */
- const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
-
- /* only move view to mouse if zoom fac is inside minzoom/maxzoom */
- if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
- IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom))
- {
- float mval_fac = (vzd->mx_2d - cur_old.xmin) / BLI_rctf_size_x(&cur_old);
- float mval_faci = 1.0f - mval_fac;
- float ofs = (mval_fac * dx) - (mval_faci * dx);
-
- v2d->cur.xmin += ofs;
- v2d->cur.xmax += ofs;
- }
- }
- }
- }
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
- if (v2d->keepofs & V2D_LOCKOFS_Y) {
- v2d->cur.ymax -= 2 * dy;
- }
- else if (v2d->keepofs & V2D_KEEPOFS_Y) {
- if (v2d->align & V2D_ALIGN_NO_POS_Y) {
- v2d->cur.ymin += 2 * dy;
- }
- else {
- v2d->cur.ymax -= 2 * dy;
- }
- }
- else {
-
- v2d->cur.ymin += dy;
- v2d->cur.ymax -= dy;
-
- if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
- /* get zoom fac the same way as in
- * ui_view2d_curRect_validate_resize - better keep in sync! */
- const float zoomy = (float)(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur);
-
- /* only move view to mouse if zoom fac is inside minzoom/maxzoom */
- if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
- IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom))
- {
- float mval_fac = (vzd->my_2d - cur_old.ymin) / BLI_rctf_size_y(&cur_old);
- float mval_faci = 1.0f - mval_fac;
- float ofs = (mval_fac * dy) - (mval_faci * dy);
-
- v2d->cur.ymin += ofs;
- v2d->cur.ymax += ofs;
- }
- }
- }
- }
-
- /* validate that view is in valid configuration after this operation */
- UI_view2d_curRect_validate(v2d);
-
- if (ED_region_snap_size_apply(ar, snap_test)) {
- ScrArea *sa = CTX_wm_area(C);
- ED_area_tag_redraw(sa);
- WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
- }
-
- /* request updates to be done... */
- ED_region_tag_redraw_no_rebuild(vzd->ar);
- UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ const rctf cur_old = v2d->cur;
+ float dx, dy;
+ const int snap_test = ED_region_snap_size_test(ar);
+
+ /* calculate amount to move view by, ensuring symmetry so the
+ * old zoom level is restored after zooming back the same amount
+ */
+ if (facx >= 0.0f) {
+ dx = BLI_rctf_size_x(&v2d->cur) * facx;
+ dy = BLI_rctf_size_y(&v2d->cur) * facy;
+ }
+ else {
+ dx = (BLI_rctf_size_x(&v2d->cur) / (1.0f + 2.0f * facx)) * facx;
+ dy = (BLI_rctf_size_y(&v2d->cur) / (1.0f + 2.0f * facy)) * facy;
+ }
+
+ /* only resize view on an axis if change is allowed */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
+ if (v2d->keepofs & V2D_LOCKOFS_X) {
+ v2d->cur.xmax -= 2 * dx;
+ }
+ else if (v2d->keepofs & V2D_KEEPOFS_X) {
+ if (v2d->align & V2D_ALIGN_NO_POS_X) {
+ v2d->cur.xmin += 2 * dx;
+ }
+ else {
+ v2d->cur.xmax -= 2 * dx;
+ }
+ }
+ else {
+
+ v2d->cur.xmin += dx;
+ v2d->cur.xmax -= dx;
+
+ if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
+ /* get zoom fac the same way as in
+ * ui_view2d_curRect_validate_resize - better keep in sync! */
+ const float zoomx = (float)(BLI_rcti_size_x(&v2d->mask) + 1) / BLI_rctf_size_x(&v2d->cur);
+
+ /* only move view to mouse if zoom fac is inside minzoom/maxzoom */
+ if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
+ IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom)) {
+ float mval_fac = (vzd->mx_2d - cur_old.xmin) / BLI_rctf_size_x(&cur_old);
+ float mval_faci = 1.0f - mval_fac;
+ float ofs = (mval_fac * dx) - (mval_faci * dx);
+
+ v2d->cur.xmin += ofs;
+ v2d->cur.xmax += ofs;
+ }
+ }
+ }
+ }
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
+ if (v2d->keepofs & V2D_LOCKOFS_Y) {
+ v2d->cur.ymax -= 2 * dy;
+ }
+ else if (v2d->keepofs & V2D_KEEPOFS_Y) {
+ if (v2d->align & V2D_ALIGN_NO_POS_Y) {
+ v2d->cur.ymin += 2 * dy;
+ }
+ else {
+ v2d->cur.ymax -= 2 * dy;
+ }
+ }
+ else {
+
+ v2d->cur.ymin += dy;
+ v2d->cur.ymax -= dy;
+
+ if (use_mousepos && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)) {
+ /* get zoom fac the same way as in
+ * ui_view2d_curRect_validate_resize - better keep in sync! */
+ const float zoomy = (float)(BLI_rcti_size_y(&v2d->mask) + 1) / BLI_rctf_size_y(&v2d->cur);
+
+ /* only move view to mouse if zoom fac is inside minzoom/maxzoom */
+ if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) ||
+ IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom)) {
+ float mval_fac = (vzd->my_2d - cur_old.ymin) / BLI_rctf_size_y(&cur_old);
+ float mval_faci = 1.0f - mval_fac;
+ float ofs = (mval_fac * dy) - (mval_faci * dy);
+
+ v2d->cur.ymin += ofs;
+ v2d->cur.ymax += ofs;
+ }
+ }
+ }
+ }
+
+ /* validate that view is in valid configuration after this operation */
+ UI_view2d_curRect_validate(v2d);
+
+ if (ED_region_snap_size_apply(ar, snap_test)) {
+ ScrArea *sa = CTX_wm_area(C);
+ ED_area_tag_redraw(sa);
+ WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
+ }
+
+ /* request updates to be done... */
+ ED_region_tag_redraw_no_rebuild(vzd->ar);
+ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
}
static void view_zoomstep_apply(bContext *C, wmOperator *op)
{
- v2dViewZoomData *vzd = op->customdata;
- view_zoomstep_apply_ex(
- C, vzd, true,
- RNA_float_get(op->ptr, "zoomfacx"),
- RNA_float_get(op->ptr, "zoomfacy"));
+ v2dViewZoomData *vzd = op->customdata;
+ view_zoomstep_apply_ex(
+ C, vzd, true, RNA_float_get(op->ptr, "zoomfacx"), RNA_float_get(op->ptr, "zoomfacy"));
}
/* --------------- Individual Operators ------------------- */
@@ -777,153 +761,150 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op)
/* cleanup temp customdata */
static void view_zoomstep_exit(wmOperator *op)
{
- UI_view2d_zoom_cache_reset();
+ UI_view2d_zoom_cache_reset();
- if (op->customdata) {
- MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
}
/* this operator only needs this single callback, where it calls the view_zoom_*() methods */
static int view_zoomin_exec(bContext *C, wmOperator *op)
{
- bool do_zoom_xy[2];
-
- /* check that there's an active region, as View2D data resides there */
- if (!view_zoom_poll(C)) {
- return OPERATOR_PASS_THROUGH;
- }
+ bool do_zoom_xy[2];
+ /* check that there's an active region, as View2D data resides there */
+ if (!view_zoom_poll(C)) {
+ return OPERATOR_PASS_THROUGH;
+ }
- view_zoom_axis_lock_defaults(C, do_zoom_xy);
+ view_zoom_axis_lock_defaults(C, do_zoom_xy);
- /* set RNA-Props - zooming in by uniform factor */
- RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? 0.0375f : 0.0f);
- RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? 0.0375f : 0.0f);
+ /* set RNA-Props - zooming in by uniform factor */
+ RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? 0.0375f : 0.0f);
+ RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? 0.0375f : 0.0f);
- /* apply movement, then we're done */
- view_zoomstep_apply(C, op);
+ /* apply movement, then we're done */
+ view_zoomstep_apply(C, op);
- view_zoomstep_exit(op);
+ view_zoomstep_exit(op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int view_zoomin_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- v2dViewZoomData *vzd;
+ v2dViewZoomData *vzd;
- if (!view_zoomdrag_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
+ if (!view_zoomdrag_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
- vzd = op->customdata;
+ vzd = op->customdata;
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
- ARegion *ar = CTX_wm_region(C);
+ if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ ARegion *ar = CTX_wm_region(C);
- /* store initial mouse position (in view space) */
- UI_view2d_region_to_view(
- &ar->v2d,
- event->mval[0], event->mval[1],
- &vzd->mx_2d, &vzd->my_2d);
- }
+ /* store initial mouse position (in view space) */
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d);
+ }
- return view_zoomin_exec(C, op);
+ return view_zoomin_exec(C, op);
}
static void VIEW2D_OT_zoom_in(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Zoom In";
- ot->description = "Zoom in the view";
- ot->idname = "VIEW2D_OT_zoom_in";
-
- /* api callbacks */
- ot->invoke = view_zoomin_invoke;
- ot->exec = view_zoomin_exec; // XXX, needs view_zoomdrag_init called first.
- ot->poll = view_zoom_poll;
-
- /* rna - must keep these in sync with the other operators */
- prop = RNA_def_float(ot->srna, "zoomfacx", 0, -FLT_MAX, FLT_MAX, "Zoom Factor X", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- prop = RNA_def_float(ot->srna, "zoomfacy", 0, -FLT_MAX, FLT_MAX, "Zoom Factor Y", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Zoom In";
+ ot->description = "Zoom in the view";
+ ot->idname = "VIEW2D_OT_zoom_in";
+
+ /* api callbacks */
+ ot->invoke = view_zoomin_invoke;
+ ot->exec = view_zoomin_exec; // XXX, needs view_zoomdrag_init called first.
+ ot->poll = view_zoom_poll;
+
+ /* rna - must keep these in sync with the other operators */
+ prop = RNA_def_float(
+ ot->srna, "zoomfacx", 0, -FLT_MAX, FLT_MAX, "Zoom Factor X", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ prop = RNA_def_float(
+ ot->srna, "zoomfacy", 0, -FLT_MAX, FLT_MAX, "Zoom Factor Y", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* this operator only needs this single callback, where it calls the view_zoom_*() methods */
static int view_zoomout_exec(bContext *C, wmOperator *op)
{
- bool do_zoom_xy[2];
+ bool do_zoom_xy[2];
- /* check that there's an active region, as View2D data resides there */
- if (!view_zoom_poll(C)) {
- return OPERATOR_PASS_THROUGH;
- }
+ /* check that there's an active region, as View2D data resides there */
+ if (!view_zoom_poll(C)) {
+ return OPERATOR_PASS_THROUGH;
+ }
- view_zoom_axis_lock_defaults(C, do_zoom_xy);
+ view_zoom_axis_lock_defaults(C, do_zoom_xy);
- /* set RNA-Props - zooming in by uniform factor */
- RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? -0.0375f : 0.0f);
- RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? -0.0375f : 0.0f);
+ /* set RNA-Props - zooming in by uniform factor */
+ RNA_float_set(op->ptr, "zoomfacx", do_zoom_xy[0] ? -0.0375f : 0.0f);
+ RNA_float_set(op->ptr, "zoomfacy", do_zoom_xy[1] ? -0.0375f : 0.0f);
- /* apply movement, then we're done */
- view_zoomstep_apply(C, op);
+ /* apply movement, then we're done */
+ view_zoomstep_apply(C, op);
- view_zoomstep_exit(op);
+ view_zoomstep_exit(op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int view_zoomout_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- v2dViewZoomData *vzd;
+ v2dViewZoomData *vzd;
- if (!view_zoomdrag_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
+ if (!view_zoomdrag_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
- vzd = op->customdata;
+ vzd = op->customdata;
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
- ARegion *ar = CTX_wm_region(C);
+ if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ ARegion *ar = CTX_wm_region(C);
- /* store initial mouse position (in view space) */
- UI_view2d_region_to_view(
- &ar->v2d,
- event->mval[0], event->mval[1],
- &vzd->mx_2d, &vzd->my_2d);
- }
+ /* store initial mouse position (in view space) */
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d);
+ }
- return view_zoomout_exec(C, op);
+ return view_zoomout_exec(C, op);
}
static void VIEW2D_OT_zoom_out(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Zoom Out";
- ot->description = "Zoom out the view";
- ot->idname = "VIEW2D_OT_zoom_out";
-
- /* api callbacks */
- ot->invoke = view_zoomout_invoke;
-// ot->exec = view_zoomout_exec; // XXX, needs view_zoomdrag_init called first.
- ot->poll = view_zoom_poll;
-
- /* rna - must keep these in sync with the other operators */
- prop = RNA_def_float(ot->srna, "zoomfacx", 0, -FLT_MAX, FLT_MAX, "Zoom Factor X", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- prop = RNA_def_float(ot->srna, "zoomfacy", 0, -FLT_MAX, FLT_MAX, "Zoom Factor Y", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Zoom Out";
+ ot->description = "Zoom out the view";
+ ot->idname = "VIEW2D_OT_zoom_out";
+
+ /* api callbacks */
+ ot->invoke = view_zoomout_invoke;
+ // ot->exec = view_zoomout_exec; // XXX, needs view_zoomdrag_init called first.
+ ot->poll = view_zoom_poll;
+
+ /* rna - must keep these in sync with the other operators */
+ prop = RNA_def_float(
+ ot->srna, "zoomfacx", 0, -FLT_MAX, FLT_MAX, "Zoom Factor X", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ prop = RNA_def_float(
+ ot->srna, "zoomfacy", 0, -FLT_MAX, FLT_MAX, "Zoom Factor Y", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* ********************************************************* */
-/* DRAG-ZOOM OPERATOR */
+/* DRAG-ZOOM OPERATOR */
/**
* MMB Drag - allows non-uniform scaling by dragging mouse
@@ -935,339 +916,337 @@ static void VIEW2D_OT_zoom_out(wmOperatorType *ot)
/* apply transform to view (i.e. adjust 'cur' rect) */
static void view_zoomdrag_apply(bContext *C, wmOperator *op)
{
- v2dViewZoomData *vzd = op->customdata;
- View2D *v2d = vzd->v2d;
- float dx, dy;
- const int snap_test = ED_region_snap_size_test(vzd->ar);
-
- /* get amount to move view by */
- dx = RNA_float_get(op->ptr, "deltax");
- dy = RNA_float_get(op->ptr, "deltay");
-
- if (U.uiflag & USER_ZOOM_INVERT) {
- dx *= -1;
- dy *= -1;
- }
-
- /* continuous zoom shouldn't move that fast... */
- if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop?
- double time = PIL_check_seconds_timer();
- float time_step = (float)(time - vzd->timer_lastdraw);
-
- dx *= time_step * 0.5f;
- dy *= time_step * 0.5f;
-
- vzd->timer_lastdraw = time;
- }
-
- /* only move view on an axis if change is allowed */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
- if (v2d->keepofs & V2D_LOCKOFS_X) {
- v2d->cur.xmax -= 2 * dx;
- }
- else {
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
- float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
- float mval_faci = 1.0f - mval_fac;
- float ofs = (mval_fac * dx) - (mval_faci * dx);
-
- v2d->cur.xmin += ofs + dx;
- v2d->cur.xmax += ofs - dx;
- }
- else {
- v2d->cur.xmin += dx;
- v2d->cur.xmax -= dx;
- }
- }
- }
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
- if (v2d->keepofs & V2D_LOCKOFS_Y) {
- v2d->cur.ymax -= 2 * dy;
- }
- else {
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
- float mval_fac = (vzd->my_2d - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
- float mval_faci = 1.0f - mval_fac;
- float ofs = (mval_fac * dy) - (mval_faci * dy);
-
- v2d->cur.ymin += ofs + dy;
- v2d->cur.ymax += ofs - dy;
- }
- else {
- v2d->cur.ymin += dy;
- v2d->cur.ymax -= dy;
- }
- }
- }
-
- /* validate that view is in valid configuration after this operation */
- UI_view2d_curRect_validate(v2d);
-
- if (ED_region_snap_size_apply(vzd->ar, snap_test)) {
- ScrArea *sa = CTX_wm_area(C);
- ED_area_tag_redraw(sa);
- WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
- }
-
- /* request updates to be done... */
- ED_region_tag_redraw_no_rebuild(vzd->ar);
- UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+ v2dViewZoomData *vzd = op->customdata;
+ View2D *v2d = vzd->v2d;
+ float dx, dy;
+ const int snap_test = ED_region_snap_size_test(vzd->ar);
+
+ /* get amount to move view by */
+ dx = RNA_float_get(op->ptr, "deltax");
+ dy = RNA_float_get(op->ptr, "deltay");
+
+ if (U.uiflag & USER_ZOOM_INVERT) {
+ dx *= -1;
+ dy *= -1;
+ }
+
+ /* continuous zoom shouldn't move that fast... */
+ if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop?
+ double time = PIL_check_seconds_timer();
+ float time_step = (float)(time - vzd->timer_lastdraw);
+
+ dx *= time_step * 0.5f;
+ dy *= time_step * 0.5f;
+
+ vzd->timer_lastdraw = time;
+ }
+
+ /* only move view on an axis if change is allowed */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
+ if (v2d->keepofs & V2D_LOCKOFS_X) {
+ v2d->cur.xmax -= 2 * dx;
+ }
+ else {
+ if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur);
+ float mval_faci = 1.0f - mval_fac;
+ float ofs = (mval_fac * dx) - (mval_faci * dx);
+
+ v2d->cur.xmin += ofs + dx;
+ v2d->cur.xmax += ofs - dx;
+ }
+ else {
+ v2d->cur.xmin += dx;
+ v2d->cur.xmax -= dx;
+ }
+ }
+ }
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
+ if (v2d->keepofs & V2D_LOCKOFS_Y) {
+ v2d->cur.ymax -= 2 * dy;
+ }
+ else {
+ if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ float mval_fac = (vzd->my_2d - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur);
+ float mval_faci = 1.0f - mval_fac;
+ float ofs = (mval_fac * dy) - (mval_faci * dy);
+
+ v2d->cur.ymin += ofs + dy;
+ v2d->cur.ymax += ofs - dy;
+ }
+ else {
+ v2d->cur.ymin += dy;
+ v2d->cur.ymax -= dy;
+ }
+ }
+ }
+
+ /* validate that view is in valid configuration after this operation */
+ UI_view2d_curRect_validate(v2d);
+
+ if (ED_region_snap_size_apply(vzd->ar, snap_test)) {
+ ScrArea *sa = CTX_wm_area(C);
+ ED_area_tag_redraw(sa);
+ WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
+ }
+
+ /* request updates to be done... */
+ ED_region_tag_redraw_no_rebuild(vzd->ar);
+ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
}
/* cleanup temp customdata */
static void view_zoomdrag_exit(bContext *C, wmOperator *op)
{
- UI_view2d_zoom_cache_reset();
+ UI_view2d_zoom_cache_reset();
- if (op->customdata) {
- v2dViewZoomData *vzd = op->customdata;
+ if (op->customdata) {
+ v2dViewZoomData *vzd = op->customdata;
- if (vzd->timer) {
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), vzd->timer);
- }
+ if (vzd->timer) {
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), vzd->timer);
+ }
- MEM_freeN(op->customdata);
- op->customdata = NULL;
- }
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
}
static void view_zoomdrag_cancel(bContext *C, wmOperator *op)
{
- view_zoomdrag_exit(C, op);
+ view_zoomdrag_exit(C, op);
}
/* for 'redo' only, with no user input */
static int view_zoomdrag_exec(bContext *C, wmOperator *op)
{
- if (!view_zoomdrag_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
+ if (!view_zoomdrag_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
- view_zoomdrag_apply(C, op);
- view_zoomdrag_exit(C, op);
- return OPERATOR_FINISHED;
+ view_zoomdrag_apply(C, op);
+ view_zoomdrag_exit(C, op);
+ return OPERATOR_FINISHED;
}
/* set up modal operator and relevant settings */
static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- wmWindow *window = CTX_wm_window(C);
- v2dViewZoomData *vzd;
- View2D *v2d;
-
- /* set up customdata */
- if (!view_zoomdrag_init(C, op)) {
- return OPERATOR_PASS_THROUGH;
- }
-
- vzd = op->customdata;
- v2d = vzd->v2d;
-
- if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
- float dx, dy, fac;
-
- vzd->lastx = event->prevx;
- vzd->lasty = event->prevy;
-
- /* As we have only 1D information (magnify value), feed both axes
- * with magnify information that is stored in x axis
- */
- fac = 0.01f * (event->prevx - event->x);
- dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f;
- if (event->type == MOUSEPAN) {
- fac = 0.01f * (event->prevy - event->y);
- }
- dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f;
-
- /* support trackpad zoom to always zoom entirely - the v2d code uses portrait or
- * landscape exceptions */
- if (v2d->keepzoom & V2D_KEEPASPECT) {
- if (fabsf(dx) > fabsf(dy)) {
- dy = dx;
- }
- else {
- dx = dy;
- }
- }
- RNA_float_set(op->ptr, "deltax", dx);
- RNA_float_set(op->ptr, "deltay", dy);
-
- view_zoomdrag_apply(C, op);
- view_zoomdrag_exit(C, op);
- return OPERATOR_FINISHED;
- }
-
- /* set initial settings */
- vzd->lastx = event->x;
- vzd->lasty = event->y;
- RNA_float_set(op->ptr, "deltax", 0);
- RNA_float_set(op->ptr, "deltay", 0);
-
- /* for modal exit test */
- vzd->invoke_event = event->type;
-
- if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
- ARegion *ar = CTX_wm_region(C);
-
- /* store initial mouse position (in view space) */
- UI_view2d_region_to_view(
- &ar->v2d,
- event->mval[0], event->mval[1],
- &vzd->mx_2d, &vzd->my_2d);
- }
-
- if (v2d->keepofs & V2D_LOCKOFS_X) {
- WM_cursor_modal_set(window, BC_NS_SCROLLCURSOR);
- }
- else if (v2d->keepofs & V2D_LOCKOFS_Y) {
- WM_cursor_modal_set(window, BC_EW_SCROLLCURSOR);
- }
- else {
- WM_cursor_modal_set(window, BC_NSEW_SCROLLCURSOR);
- }
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
-
- if (U.viewzoom == USER_ZOOM_CONT) {
- /* needs a timer to continue redrawing */
- vzd->timer = WM_event_add_timer(CTX_wm_manager(C), window, TIMER, 0.01f);
- vzd->timer_lastdraw = PIL_check_seconds_timer();
- }
-
- return OPERATOR_RUNNING_MODAL;
+ wmWindow *window = CTX_wm_window(C);
+ v2dViewZoomData *vzd;
+ View2D *v2d;
+
+ /* set up customdata */
+ if (!view_zoomdrag_init(C, op)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ vzd = op->customdata;
+ v2d = vzd->v2d;
+
+ if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
+ float dx, dy, fac;
+
+ vzd->lastx = event->prevx;
+ vzd->lasty = event->prevy;
+
+ /* As we have only 1D information (magnify value), feed both axes
+ * with magnify information that is stored in x axis
+ */
+ fac = 0.01f * (event->prevx - event->x);
+ dx = fac * BLI_rctf_size_x(&v2d->cur) / 10.0f;
+ if (event->type == MOUSEPAN) {
+ fac = 0.01f * (event->prevy - event->y);
+ }
+ dy = fac * BLI_rctf_size_y(&v2d->cur) / 10.0f;
+
+ /* support trackpad zoom to always zoom entirely - the v2d code uses portrait or
+ * landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(dx) > fabsf(dy)) {
+ dy = dx;
+ }
+ else {
+ dx = dy;
+ }
+ }
+ RNA_float_set(op->ptr, "deltax", dx);
+ RNA_float_set(op->ptr, "deltay", dy);
+
+ view_zoomdrag_apply(C, op);
+ view_zoomdrag_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+
+ /* set initial settings */
+ vzd->lastx = event->x;
+ vzd->lasty = event->y;
+ RNA_float_set(op->ptr, "deltax", 0);
+ RNA_float_set(op->ptr, "deltay", 0);
+
+ /* for modal exit test */
+ vzd->invoke_event = event->type;
+
+ if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+ ARegion *ar = CTX_wm_region(C);
+
+ /* store initial mouse position (in view space) */
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d);
+ }
+
+ if (v2d->keepofs & V2D_LOCKOFS_X) {
+ WM_cursor_modal_set(window, BC_NS_SCROLLCURSOR);
+ }
+ else if (v2d->keepofs & V2D_LOCKOFS_Y) {
+ WM_cursor_modal_set(window, BC_EW_SCROLLCURSOR);
+ }
+ else {
+ WM_cursor_modal_set(window, BC_NSEW_SCROLLCURSOR);
+ }
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ if (U.viewzoom == USER_ZOOM_CONT) {
+ /* needs a timer to continue redrawing */
+ vzd->timer = WM_event_add_timer(CTX_wm_manager(C), window, TIMER, 0.01f);
+ vzd->timer_lastdraw = PIL_check_seconds_timer();
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
/* handle user input - calculations of mouse-movement need to be done here,
* not in the apply callback! */
static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- v2dViewZoomData *vzd = op->customdata;
- View2D *v2d = vzd->v2d;
-
- /* execute the events */
- if (event->type == TIMER && event->customdata == vzd->timer) {
- view_zoomdrag_apply(C, op);
- }
- else if (event->type == MOUSEMOVE) {
- float dx, dy;
-
- /* calculate new delta transform, based on zooming mode */
- if (U.viewzoom == USER_ZOOM_SCALE) {
- /* 'scale' zooming */
- float dist;
-
- /* x-axis transform */
- dist = BLI_rcti_size_x(&v2d->mask) / 2.0f;
- dx = 1.0f - (fabsf(vzd->lastx - vzd->ar->winrct.xmin - dist) + 2.0f) / (fabsf(event->mval[0] - dist) + 2.0f);
- dx *= 0.5f * BLI_rctf_size_x(&v2d->cur);
-
- /* y-axis transform */
- dist = BLI_rcti_size_y(&v2d->mask) / 2.0f;
- dy = 1.0f - (fabsf(vzd->lasty - vzd->ar->winrct.ymin - dist) + 2.0f) / (fabsf(event->mval[1] - dist) + 2.0f);
- dy *= 0.5f * BLI_rctf_size_y(&v2d->cur);
- }
- else {
- /* 'continuous' or 'dolly' */
- float fac, zoomfac = 0.01f;
-
- /* some view2d's (graph) don't have min/max zoom, or extreme ones */
- if (v2d->maxzoom > 0.0f) {
- zoomfac = clamp_f(0.001f * v2d->maxzoom, 0.001f, 0.01f);
- }
-
- /* x-axis transform */
- fac = zoomfac * (event->x - vzd->lastx);
- dx = fac * BLI_rctf_size_x(&v2d->cur);
-
- /* y-axis transform */
- fac = zoomfac * (event->y - vzd->lasty);
- dy = fac * BLI_rctf_size_y(&v2d->cur);
-
- }
-
- /* support zoom to always zoom entirely - the v2d code uses portrait or
- * landscape exceptions */
- if (v2d->keepzoom & V2D_KEEPASPECT) {
- if (fabsf(dx) > fabsf(dy)) {
- dy = dx;
- }
- else {
- dx = dy;
- }
- }
-
- /* set transform amount, and add current deltas to stored total delta (for redo) */
- RNA_float_set(op->ptr, "deltax", dx);
- RNA_float_set(op->ptr, "deltay", dy);
-
- vzd->dx += dx;
- vzd->dy += dy;
-
- /* store mouse coordinates for next time, if not doing continuous zoom
- * - continuous zoom only depends on distance of mouse to starting point to determine rate of change
- */
- if (U.viewzoom != USER_ZOOM_CONT) { // XXX store this setting as RNA prop?
- vzd->lastx = event->x;
- vzd->lasty = event->y;
- }
-
- /* apply zooming */
- view_zoomdrag_apply(C, op);
- }
- else if (event->type == vzd->invoke_event || event->type == ESCKEY) {
- if (event->val == KM_RELEASE) {
-
- /* for redo, store the overall deltas - need to respect zoom-locks here... */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
- RNA_float_set(op->ptr, "deltax", vzd->dx);
- }
- else {
- RNA_float_set(op->ptr, "deltax", 0);
- }
-
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
- RNA_float_set(op->ptr, "deltay", vzd->dy);
- }
- else {
- RNA_float_set(op->ptr, "deltay", 0);
- }
-
- /* free customdata */
- view_zoomdrag_exit(C, op);
- WM_cursor_modal_restore(CTX_wm_window(C));
-
- return OPERATOR_FINISHED;
- }
- }
-
- return OPERATOR_RUNNING_MODAL;
+ v2dViewZoomData *vzd = op->customdata;
+ View2D *v2d = vzd->v2d;
+
+ /* execute the events */
+ if (event->type == TIMER && event->customdata == vzd->timer) {
+ view_zoomdrag_apply(C, op);
+ }
+ else if (event->type == MOUSEMOVE) {
+ float dx, dy;
+
+ /* calculate new delta transform, based on zooming mode */
+ if (U.viewzoom == USER_ZOOM_SCALE) {
+ /* 'scale' zooming */
+ float dist;
+
+ /* x-axis transform */
+ dist = BLI_rcti_size_x(&v2d->mask) / 2.0f;
+ dx = 1.0f - (fabsf(vzd->lastx - vzd->ar->winrct.xmin - dist) + 2.0f) /
+ (fabsf(event->mval[0] - dist) + 2.0f);
+ dx *= 0.5f * BLI_rctf_size_x(&v2d->cur);
+
+ /* y-axis transform */
+ dist = BLI_rcti_size_y(&v2d->mask) / 2.0f;
+ dy = 1.0f - (fabsf(vzd->lasty - vzd->ar->winrct.ymin - dist) + 2.0f) /
+ (fabsf(event->mval[1] - dist) + 2.0f);
+ dy *= 0.5f * BLI_rctf_size_y(&v2d->cur);
+ }
+ else {
+ /* 'continuous' or 'dolly' */
+ float fac, zoomfac = 0.01f;
+
+ /* some view2d's (graph) don't have min/max zoom, or extreme ones */
+ if (v2d->maxzoom > 0.0f) {
+ zoomfac = clamp_f(0.001f * v2d->maxzoom, 0.001f, 0.01f);
+ }
+
+ /* x-axis transform */
+ fac = zoomfac * (event->x - vzd->lastx);
+ dx = fac * BLI_rctf_size_x(&v2d->cur);
+
+ /* y-axis transform */
+ fac = zoomfac * (event->y - vzd->lasty);
+ dy = fac * BLI_rctf_size_y(&v2d->cur);
+ }
+
+ /* support zoom to always zoom entirely - the v2d code uses portrait or
+ * landscape exceptions */
+ if (v2d->keepzoom & V2D_KEEPASPECT) {
+ if (fabsf(dx) > fabsf(dy)) {
+ dy = dx;
+ }
+ else {
+ dx = dy;
+ }
+ }
+
+ /* set transform amount, and add current deltas to stored total delta (for redo) */
+ RNA_float_set(op->ptr, "deltax", dx);
+ RNA_float_set(op->ptr, "deltay", dy);
+
+ vzd->dx += dx;
+ vzd->dy += dy;
+
+ /* store mouse coordinates for next time, if not doing continuous zoom
+ * - continuous zoom only depends on distance of mouse to starting point to determine rate of change
+ */
+ if (U.viewzoom != USER_ZOOM_CONT) { // XXX store this setting as RNA prop?
+ vzd->lastx = event->x;
+ vzd->lasty = event->y;
+ }
+
+ /* apply zooming */
+ view_zoomdrag_apply(C, op);
+ }
+ else if (event->type == vzd->invoke_event || event->type == ESCKEY) {
+ if (event->val == KM_RELEASE) {
+
+ /* for redo, store the overall deltas - need to respect zoom-locks here... */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
+ RNA_float_set(op->ptr, "deltax", vzd->dx);
+ }
+ else {
+ RNA_float_set(op->ptr, "deltax", 0);
+ }
+
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
+ RNA_float_set(op->ptr, "deltay", vzd->dy);
+ }
+ else {
+ RNA_float_set(op->ptr, "deltay", 0);
+ }
+
+ /* free customdata */
+ view_zoomdrag_exit(C, op);
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ return OPERATOR_FINISHED;
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
static void VIEW2D_OT_zoom(wmOperatorType *ot)
{
- PropertyRNA *prop;
- /* identifiers */
- ot->name = "Zoom 2D View";
- ot->description = "Zoom in/out the view";
- ot->idname = "VIEW2D_OT_zoom";
-
- /* api callbacks */
- ot->exec = view_zoomdrag_exec;
- ot->invoke = view_zoomdrag_invoke;
- ot->modal = view_zoomdrag_modal;
- ot->cancel = view_zoomdrag_cancel;
-
- ot->poll = view_zoom_poll;
-
- /* operator is repeatable */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
-
- /* rna - must keep these in sync with the other operators */
- prop = RNA_def_float(ot->srna, "deltax", 0, -FLT_MAX, FLT_MAX, "Delta X", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- prop = RNA_def_float(ot->srna, "deltay", 0, -FLT_MAX, FLT_MAX, "Delta Y", "", -FLT_MAX, FLT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+ /* identifiers */
+ ot->name = "Zoom 2D View";
+ ot->description = "Zoom in/out the view";
+ ot->idname = "VIEW2D_OT_zoom";
+
+ /* api callbacks */
+ ot->exec = view_zoomdrag_exec;
+ ot->invoke = view_zoomdrag_invoke;
+ ot->modal = view_zoomdrag_modal;
+ ot->cancel = view_zoomdrag_cancel;
+
+ ot->poll = view_zoom_poll;
+
+ /* operator is repeatable */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
+
+ /* rna - must keep these in sync with the other operators */
+ prop = RNA_def_float(ot->srna, "deltax", 0, -FLT_MAX, FLT_MAX, "Delta X", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ prop = RNA_def_float(ot->srna, "deltay", 0, -FLT_MAX, FLT_MAX, "Delta Y", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* ********************************************************* */
@@ -1286,160 +1265,158 @@ static void VIEW2D_OT_zoom(wmOperatorType *ot)
static int view_borderzoom_exec(bContext *C, wmOperator *op)
{
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
- rctf rect;
- rctf cur_new = v2d->cur;
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
-
- /* convert coordinates of rect to 'tot' rect coordinates */
- WM_operator_properties_border_to_rctf(op, &rect);
- UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
-
- /* check if zooming in/out view */
- const bool zoom_in = !RNA_boolean_get(op->ptr, "zoom_out");
-
- if (zoom_in) {
- /* zoom in:
- * - 'cur' rect will be defined by the coordinates of the border region
- * - just set the 'cur' rect to have the same coordinates as the border region
- * if zoom is allowed to be changed
- */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
- cur_new.xmin = rect.xmin;
- cur_new.xmax = rect.xmax;
- }
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
- cur_new.ymin = rect.ymin;
- cur_new.ymax = rect.ymax;
- }
- }
- else {
- /* zoom out:
- * - the current 'cur' rect coordinates are going to end up where the 'rect' ones are,
- * but the 'cur' rect coordinates will need to be adjusted to take in more of the view
- * - calculate zoom factor, and adjust using center-point
- */
- float zoom, center, size;
-
- /* TODO: is this zoom factor calculation valid?
- * It seems to produce same results every time... */
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
- size = BLI_rctf_size_x(&cur_new);
- zoom = size / BLI_rctf_size_x(&rect);
- center = BLI_rctf_cent_x(&cur_new);
-
- cur_new.xmin = center - (size * zoom);
- cur_new.xmax = center + (size * zoom);
- }
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
- size = BLI_rctf_size_y(&cur_new);
- zoom = size / BLI_rctf_size_y(&rect);
- center = BLI_rctf_cent_y(&cur_new);
-
- cur_new.ymin = center - (size * zoom);
- cur_new.ymax = center + (size * zoom);
- }
- }
-
- UI_view2d_smooth_view(C, ar, &cur_new, smooth_viewtx);
-
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ rctf rect;
+ rctf cur_new = v2d->cur;
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+
+ /* convert coordinates of rect to 'tot' rect coordinates */
+ WM_operator_properties_border_to_rctf(op, &rect);
+ UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
+
+ /* check if zooming in/out view */
+ const bool zoom_in = !RNA_boolean_get(op->ptr, "zoom_out");
+
+ if (zoom_in) {
+ /* zoom in:
+ * - 'cur' rect will be defined by the coordinates of the border region
+ * - just set the 'cur' rect to have the same coordinates as the border region
+ * if zoom is allowed to be changed
+ */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
+ cur_new.xmin = rect.xmin;
+ cur_new.xmax = rect.xmax;
+ }
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
+ cur_new.ymin = rect.ymin;
+ cur_new.ymax = rect.ymax;
+ }
+ }
+ else {
+ /* zoom out:
+ * - the current 'cur' rect coordinates are going to end up where the 'rect' ones are,
+ * but the 'cur' rect coordinates will need to be adjusted to take in more of the view
+ * - calculate zoom factor, and adjust using center-point
+ */
+ float zoom, center, size;
+
+ /* TODO: is this zoom factor calculation valid?
+ * It seems to produce same results every time... */
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) == 0) {
+ size = BLI_rctf_size_x(&cur_new);
+ zoom = size / BLI_rctf_size_x(&rect);
+ center = BLI_rctf_cent_x(&cur_new);
+
+ cur_new.xmin = center - (size * zoom);
+ cur_new.xmax = center + (size * zoom);
+ }
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) == 0) {
+ size = BLI_rctf_size_y(&cur_new);
+ zoom = size / BLI_rctf_size_y(&rect);
+ center = BLI_rctf_cent_y(&cur_new);
+
+ cur_new.ymin = center - (size * zoom);
+ cur_new.ymax = center + (size * zoom);
+ }
+ }
+
+ UI_view2d_smooth_view(C, ar, &cur_new, smooth_viewtx);
+
+ return OPERATOR_FINISHED;
}
static void VIEW2D_OT_zoom_border(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Zoom to Border";
- ot->description = "Zoom in the view to the nearest item contained in the border";
- ot->idname = "VIEW2D_OT_zoom_border";
+ /* identifiers */
+ ot->name = "Zoom to Border";
+ ot->description = "Zoom in the view to the nearest item contained in the border";
+ ot->idname = "VIEW2D_OT_zoom_border";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = view_borderzoom_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = view_borderzoom_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = view_zoom_poll;
+ ot->poll = view_zoom_poll;
- /* rna */
- WM_operator_properties_gesture_box_zoom(ot);
+ /* rna */
+ WM_operator_properties_gesture_box_zoom(ot);
}
#ifdef WITH_INPUT_NDOF
static int view2d_ndof_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (event->type != NDOF_MOTION) {
- return OPERATOR_CANCELLED;
- }
- else {
- const wmNDOFMotionData *ndof = event->customdata;
+ if (event->type != NDOF_MOTION) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ const wmNDOFMotionData *ndof = event->customdata;
- /* tune these until it feels right */
- const float zoom_sensitivity = 0.5f;
- const float speed = 10.0f; /* match view3d ortho */
- const bool has_translate = (ndof->tvec[0] && ndof->tvec[1]) && view_pan_poll(C);
- const bool has_zoom = (ndof->tvec[2] != 0.0f) && view_zoom_poll(C);
+ /* tune these until it feels right */
+ const float zoom_sensitivity = 0.5f;
+ const float speed = 10.0f; /* match view3d ortho */
+ const bool has_translate = (ndof->tvec[0] && ndof->tvec[1]) && view_pan_poll(C);
+ const bool has_zoom = (ndof->tvec[2] != 0.0f) && view_zoom_poll(C);
- if (has_translate) {
- if (view_pan_init(C, op)) {
- v2dViewPanData *vpd;
- float pan_vec[3];
+ if (has_translate) {
+ if (view_pan_init(C, op)) {
+ v2dViewPanData *vpd;
+ float pan_vec[3];
- WM_event_ndof_pan_get(ndof, pan_vec, false);
+ WM_event_ndof_pan_get(ndof, pan_vec, false);
- pan_vec[0] *= speed;
- pan_vec[1] *= speed;
+ pan_vec[0] *= speed;
+ pan_vec[1] *= speed;
- vpd = op->customdata;
+ vpd = op->customdata;
- view_pan_apply_ex(C, vpd, pan_vec[0], pan_vec[1]);
+ view_pan_apply_ex(C, vpd, pan_vec[0], pan_vec[1]);
- view_pan_exit(op);
- }
- }
+ view_pan_exit(op);
+ }
+ }
- if (has_zoom) {
- if (view_zoomdrag_init(C, op)) {
- v2dViewZoomData *vzd;
- float zoom_factor = zoom_sensitivity * ndof->dt * -ndof->tvec[2];
+ if (has_zoom) {
+ if (view_zoomdrag_init(C, op)) {
+ v2dViewZoomData *vzd;
+ float zoom_factor = zoom_sensitivity * ndof->dt * -ndof->tvec[2];
- bool do_zoom_xy[2];
+ bool do_zoom_xy[2];
- if (U.ndof_flag & NDOF_ZOOM_INVERT) {
- zoom_factor = -zoom_factor;
- }
+ if (U.ndof_flag & NDOF_ZOOM_INVERT) {
+ zoom_factor = -zoom_factor;
+ }
- view_zoom_axis_lock_defaults(C, do_zoom_xy);
+ view_zoom_axis_lock_defaults(C, do_zoom_xy);
- vzd = op->customdata;
+ vzd = op->customdata;
- view_zoomstep_apply_ex(
- C, vzd, false,
- do_zoom_xy[0] ? zoom_factor : 0.0f,
- do_zoom_xy[1] ? zoom_factor : 0.0f);
+ view_zoomstep_apply_ex(
+ C, vzd, false, do_zoom_xy[0] ? zoom_factor : 0.0f, do_zoom_xy[1] ? zoom_factor : 0.0f);
- view_zoomstep_exit(op);
- }
- }
+ view_zoomstep_exit(op);
+ }
+ }
- return OPERATOR_FINISHED;
- }
+ return OPERATOR_FINISHED;
+ }
}
static void VIEW2D_OT_ndof(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "NDOF Pan/Zoom";
- ot->idname = "VIEW2D_OT_ndof";
- ot->description = "Use a 3D mouse device to pan/zoom the view";
+ /* identifiers */
+ ot->name = "NDOF Pan/Zoom";
+ ot->idname = "VIEW2D_OT_ndof";
+ ot->description = "Use a 3D mouse device to pan/zoom the view";
- /* api callbacks */
- ot->invoke = view2d_ndof_invoke;
- ot->poll = view2d_poll;
+ /* api callbacks */
+ ot->invoke = view2d_ndof_invoke;
+ ot->poll = view2d_poll;
- /* flags */
- ot->flag = OPTYPE_LOCK_BYPASS;
+ /* flags */
+ ot->flag = OPTYPE_LOCK_BYPASS;
}
#endif /* WITH_INPUT_NDOF */
@@ -1447,9 +1424,9 @@ static void VIEW2D_OT_ndof(wmOperatorType *ot)
/* SMOOTH VIEW */
struct SmoothView2DStore {
- rctf orig_cur, new_cur;
+ rctf orig_cur, new_cur;
- double time_allowed;
+ double time_allowed;
};
/**
@@ -1462,177 +1439,167 @@ struct SmoothView2DStore {
*/
static float smooth_view_rect_to_fac(const rctf *rect_a, const rctf *rect_b)
{
- const float size_a[2] = {
- BLI_rctf_size_x(rect_a),
- BLI_rctf_size_y(rect_a)};
- const float size_b[2] = {
- BLI_rctf_size_x(rect_b),
- BLI_rctf_size_y(rect_b)};
- const float cent_a[2] = {
- BLI_rctf_cent_x(rect_a),
- BLI_rctf_cent_y(rect_a)};
- const float cent_b[2] = {
- BLI_rctf_cent_x(rect_b),
- BLI_rctf_cent_y(rect_b)};
-
- float fac_max = 0.0f;
- float tfac;
-
- int i;
-
- for (i = 0; i < 2; i++) {
- /* axis translation normalized to scale */
- tfac = fabsf(cent_a[i] - cent_b[i]) / min_ff(size_a[i], size_b[i]);
- fac_max = max_ff(fac_max, tfac);
- if (fac_max >= 1.0f) {
- break;
- }
-
- /* axis scale difference, x2 so doubling or half gives 1.0f */
- tfac = (1.0f - (min_ff(size_a[i], size_b[i]) / max_ff(size_a[i], size_b[i]))) * 2.0f;
- fac_max = max_ff(fac_max, tfac);
- if (fac_max >= 1.0f) {
- break;
- }
- }
- return min_ff(fac_max, 1.0f);
+ const float size_a[2] = {BLI_rctf_size_x(rect_a), BLI_rctf_size_y(rect_a)};
+ const float size_b[2] = {BLI_rctf_size_x(rect_b), BLI_rctf_size_y(rect_b)};
+ const float cent_a[2] = {BLI_rctf_cent_x(rect_a), BLI_rctf_cent_y(rect_a)};
+ const float cent_b[2] = {BLI_rctf_cent_x(rect_b), BLI_rctf_cent_y(rect_b)};
+
+ float fac_max = 0.0f;
+ float tfac;
+
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ /* axis translation normalized to scale */
+ tfac = fabsf(cent_a[i] - cent_b[i]) / min_ff(size_a[i], size_b[i]);
+ fac_max = max_ff(fac_max, tfac);
+ if (fac_max >= 1.0f) {
+ break;
+ }
+
+ /* axis scale difference, x2 so doubling or half gives 1.0f */
+ tfac = (1.0f - (min_ff(size_a[i], size_b[i]) / max_ff(size_a[i], size_b[i]))) * 2.0f;
+ fac_max = max_ff(fac_max, tfac);
+ if (fac_max >= 1.0f) {
+ break;
+ }
+ }
+ return min_ff(fac_max, 1.0f);
}
/* will start timer if appropriate */
/* the arguments are the desired situation */
-void UI_view2d_smooth_view(
- bContext *C, ARegion *ar,
- const rctf *cur, const int smooth_viewtx)
+void UI_view2d_smooth_view(bContext *C, ARegion *ar, const rctf *cur, const int smooth_viewtx)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmWindow *win = CTX_wm_window(C);
-
- View2D *v2d = &ar->v2d;
- struct SmoothView2DStore sms = {{0}};
- bool ok = false;
- float fac = 1.0f;
-
- /* initialize sms */
- sms.new_cur = v2d->cur;
-
- /* store the options we want to end with */
- if (cur) {
- sms.new_cur = *cur;
- }
-
- if (cur) {
- fac = smooth_view_rect_to_fac(&v2d->cur, cur);
- }
-
- if (smooth_viewtx && fac > FLT_EPSILON) {
- bool changed = false;
-
- if (BLI_rctf_compare(&sms.new_cur, &v2d->cur, FLT_EPSILON) == false) {
- changed = true;
- }
-
- /* The new view is different from the old one
- * so animate the view */
- if (changed) {
- sms.orig_cur = v2d->cur;
-
- sms.time_allowed = (double)smooth_viewtx / 1000.0;
-
- /* scale the time allowed the change in view */
- sms.time_allowed *= (double)fac;
-
- /* keep track of running timer! */
- if (v2d->sms == NULL) {
- v2d->sms = MEM_mallocN(sizeof(struct SmoothView2DStore), "smoothview v2d");
- }
- *v2d->sms = sms;
- if (v2d->smooth_timer) {
- WM_event_remove_timer(wm, win, v2d->smooth_timer);
- }
- /* TIMER1 is hardcoded in keymap */
- /* max 30 frs/sec */
- v2d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0);
-
- ok = true;
- }
- }
-
- /* if we get here nothing happens */
- if (ok == false) {
- v2d->cur = sms.new_cur;
-
- UI_view2d_curRect_validate(v2d);
- ED_region_tag_redraw_no_rebuild(ar);
- UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
- }
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
+
+ View2D *v2d = &ar->v2d;
+ struct SmoothView2DStore sms = {{0}};
+ bool ok = false;
+ float fac = 1.0f;
+
+ /* initialize sms */
+ sms.new_cur = v2d->cur;
+
+ /* store the options we want to end with */
+ if (cur) {
+ sms.new_cur = *cur;
+ }
+
+ if (cur) {
+ fac = smooth_view_rect_to_fac(&v2d->cur, cur);
+ }
+
+ if (smooth_viewtx && fac > FLT_EPSILON) {
+ bool changed = false;
+
+ if (BLI_rctf_compare(&sms.new_cur, &v2d->cur, FLT_EPSILON) == false) {
+ changed = true;
+ }
+
+ /* The new view is different from the old one
+ * so animate the view */
+ if (changed) {
+ sms.orig_cur = v2d->cur;
+
+ sms.time_allowed = (double)smooth_viewtx / 1000.0;
+
+ /* scale the time allowed the change in view */
+ sms.time_allowed *= (double)fac;
+
+ /* keep track of running timer! */
+ if (v2d->sms == NULL) {
+ v2d->sms = MEM_mallocN(sizeof(struct SmoothView2DStore), "smoothview v2d");
+ }
+ *v2d->sms = sms;
+ if (v2d->smooth_timer) {
+ WM_event_remove_timer(wm, win, v2d->smooth_timer);
+ }
+ /* TIMER1 is hardcoded in keymap */
+ /* max 30 frs/sec */
+ v2d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0);
+
+ ok = true;
+ }
+ }
+
+ /* if we get here nothing happens */
+ if (ok == false) {
+ v2d->cur = sms.new_cur;
+
+ UI_view2d_curRect_validate(v2d);
+ ED_region_tag_redraw_no_rebuild(ar);
+ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+ }
}
/* only meant for timer usage */
static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
- struct SmoothView2DStore *sms = v2d->sms;
- float step;
-
- /* escape if not our timer */
- if (v2d->smooth_timer == NULL || v2d->smooth_timer != event->customdata) {
- return OPERATOR_PASS_THROUGH;
- }
-
- if (sms->time_allowed != 0.0) {
- step = (float)((v2d->smooth_timer->duration) / sms->time_allowed);
- }
- else {
- step = 1.0f;
- }
-
- /* end timer */
- if (step >= 1.0f) {
- v2d->cur = sms->new_cur;
-
- MEM_freeN(v2d->sms);
- v2d->sms = NULL;
-
- WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), v2d->smooth_timer);
- v2d->smooth_timer = NULL;
-
- /* Event handling won't know if a UI item has been moved under the pointer. */
- WM_event_add_mousemove(C);
- }
- else {
- /* ease in/out */
- step = (3.0f * step * step - 2.0f * step * step * step);
-
- BLI_rctf_interp(&v2d->cur, &sms->orig_cur, &sms->new_cur, step);
- }
-
- UI_view2d_curRect_validate(v2d);
- UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
- ED_region_tag_redraw_no_rebuild(ar);
-
- if (v2d->sms == NULL) {
- UI_view2d_zoom_cache_reset();
- }
-
- return OPERATOR_FINISHED;
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ struct SmoothView2DStore *sms = v2d->sms;
+ float step;
+
+ /* escape if not our timer */
+ if (v2d->smooth_timer == NULL || v2d->smooth_timer != event->customdata) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ if (sms->time_allowed != 0.0) {
+ step = (float)((v2d->smooth_timer->duration) / sms->time_allowed);
+ }
+ else {
+ step = 1.0f;
+ }
+
+ /* end timer */
+ if (step >= 1.0f) {
+ v2d->cur = sms->new_cur;
+
+ MEM_freeN(v2d->sms);
+ v2d->sms = NULL;
+
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), v2d->smooth_timer);
+ v2d->smooth_timer = NULL;
+
+ /* Event handling won't know if a UI item has been moved under the pointer. */
+ WM_event_add_mousemove(C);
+ }
+ else {
+ /* ease in/out */
+ step = (3.0f * step * step - 2.0f * step * step * step);
+
+ BLI_rctf_interp(&v2d->cur, &sms->orig_cur, &sms->new_cur, step);
+ }
+
+ UI_view2d_curRect_validate(v2d);
+ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+ ED_region_tag_redraw_no_rebuild(ar);
+
+ if (v2d->sms == NULL) {
+ UI_view2d_zoom_cache_reset();
+ }
+
+ return OPERATOR_FINISHED;
}
static void VIEW2D_OT_smoothview(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Smooth View 2D";
- ot->idname = "VIEW2D_OT_smoothview";
+ /* identifiers */
+ ot->name = "Smooth View 2D";
+ ot->idname = "VIEW2D_OT_smoothview";
- /* api callbacks */
- ot->invoke = view2d_smoothview_invoke;
- ot->poll = view2d_poll;
+ /* api callbacks */
+ ot->invoke = view2d_smoothview_invoke;
+ ot->poll = view2d_poll;
- /* flags */
- ot->flag = OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_INTERNAL;
- /* rna */
- WM_operator_properties_gesture_box(ot);
+ /* rna */
+ WM_operator_properties_gesture_box(ot);
}
/* ********************************************************* */
@@ -1650,35 +1617,34 @@ static void VIEW2D_OT_smoothview(wmOperatorType *ot)
/* customdata for scroller-invoke data */
typedef struct v2dScrollerMove {
- /** View2D data that this operation affects */
- View2D *v2d;
- /** region that the scroller is in */
- ARegion *ar;
-
- /** scroller that mouse is in ('h' or 'v') */
- char scroller;
-
- /* XXX find some way to provide visual feedback of this (active color?) */
- /** -1 is min zoomer, 0 is bar, 1 is max zoomer */
- short zone;
-
- /** view adjustment factor, based on size of region */
- float fac;
- /** for pixel rounding (avoid visible UI jitter) */
- float fac_round;
- /** amount moved by mouse on axis of interest */
- float delta;
-
- /** width of the scrollbar itself, used for page up/down clicks */
- float scrollbarwidth;
- /** initial location of scrollbar x/y, mouse relative */
- int scrollbar_orig;
-
- /** previous mouse coordinates (in screen coordinates) for determining movement */
- int lastx, lasty;
+ /** View2D data that this operation affects */
+ View2D *v2d;
+ /** region that the scroller is in */
+ ARegion *ar;
+
+ /** scroller that mouse is in ('h' or 'v') */
+ char scroller;
+
+ /* XXX find some way to provide visual feedback of this (active color?) */
+ /** -1 is min zoomer, 0 is bar, 1 is max zoomer */
+ short zone;
+
+ /** view adjustment factor, based on size of region */
+ float fac;
+ /** for pixel rounding (avoid visible UI jitter) */
+ float fac_round;
+ /** amount moved by mouse on axis of interest */
+ float delta;
+
+ /** width of the scrollbar itself, used for page up/down clicks */
+ float scrollbarwidth;
+ /** initial location of scrollbar x/y, mouse relative */
+ int scrollbar_orig;
+
+ /** previous mouse coordinates (in screen coordinates) for determining movement */
+ int lastx, lasty;
} v2dScrollerMove;
-
/**
* #View2DScrollers is typedef'd in UI_view2d.h
* This is a CUT DOWN VERSION of the 'real' version, which is defined in view2d.c, as we only need focus bubble info
@@ -1687,18 +1653,18 @@ typedef struct v2dScrollerMove {
* For now, we don't need to have a separate (internal) header for structs like this...
*/
struct View2DScrollers {
- /* focus bubbles */
- int vert_min, vert_max; /* vertical scrollbar */
- int hor_min, hor_max; /* horizontal scrollbar */
+ /* focus bubbles */
+ int vert_min, vert_max; /* vertical scrollbar */
+ int hor_min, hor_max; /* horizontal scrollbar */
};
/* quick enum for vsm->zone (scroller handles) */
enum {
- SCROLLHANDLE_MIN = -1,
- SCROLLHANDLE_BAR,
- SCROLLHANDLE_MAX,
- SCROLLHANDLE_MIN_OUTSIDE,
- SCROLLHANDLE_MAX_OUTSIDE,
+ SCROLLHANDLE_MIN = -1,
+ SCROLLHANDLE_BAR,
+ SCROLLHANDLE_MAX,
+ SCROLLHANDLE_MIN_OUTSIDE,
+ SCROLLHANDLE_MAX_OUTSIDE,
} /*eV2DScrollerHandle_Zone*/;
/* ------------------------ */
@@ -1712,240 +1678,241 @@ enum {
*/
static short mouse_in_scroller_handle(int mouse, int sc_min, int sc_max, int sh_min, int sh_max)
{
- bool in_min, in_max, in_bar, out_min, out_max, in_view = 1;
-
- /* firstly, check if
- * - 'bubble' fills entire scroller
- * - 'bubble' completely out of view on either side
- */
- if ((sh_min <= sc_min) && (sh_max >= sc_max)) {
- in_view = 0;
- }
- if (sh_min == sh_max) {
- if (sh_min <= sc_min) {
- in_view = 0;
- }
- if (sh_max >= sc_max) {
- in_view = 0;
- }
- }
- else {
- if (sh_max <= sc_min) {
- in_view = 0;
- }
- if (sh_min >= sc_max) {
- in_view = 0;
- }
- }
-
-
- if (in_view == 0) {
- return SCROLLHANDLE_BAR;
- }
-
- /* check if mouse is in or past either handle */
- /* TODO: check if these extents are still valid or not */
- in_max = ((mouse >= (sh_max - V2D_SCROLLER_HANDLE_SIZE)) && (mouse <= (sh_max + V2D_SCROLLER_HANDLE_SIZE)));
- in_min = ((mouse <= (sh_min + V2D_SCROLLER_HANDLE_SIZE)) && (mouse >= (sh_min - V2D_SCROLLER_HANDLE_SIZE)));
- in_bar = ((mouse < (sh_max - V2D_SCROLLER_HANDLE_SIZE)) && (mouse > (sh_min + V2D_SCROLLER_HANDLE_SIZE)));
- out_min = mouse < (sh_min - V2D_SCROLLER_HANDLE_SIZE);
- out_max = mouse > (sh_max + V2D_SCROLLER_HANDLE_SIZE);
-
- if (in_bar) {
- return SCROLLHANDLE_BAR;
- }
- else if (in_max) {
- return SCROLLHANDLE_MAX;
- }
- else if (in_min) {
- return SCROLLHANDLE_MIN;
- }
- else if (out_min) {
- return SCROLLHANDLE_MIN_OUTSIDE;
- }
- else if (out_max) {
- return SCROLLHANDLE_MAX_OUTSIDE;
- }
-
- /* unlikely to happen, though we just cover it in case */
- return SCROLLHANDLE_BAR;
+ bool in_min, in_max, in_bar, out_min, out_max, in_view = 1;
+
+ /* firstly, check if
+ * - 'bubble' fills entire scroller
+ * - 'bubble' completely out of view on either side
+ */
+ if ((sh_min <= sc_min) && (sh_max >= sc_max)) {
+ in_view = 0;
+ }
+ if (sh_min == sh_max) {
+ if (sh_min <= sc_min) {
+ in_view = 0;
+ }
+ if (sh_max >= sc_max) {
+ in_view = 0;
+ }
+ }
+ else {
+ if (sh_max <= sc_min) {
+ in_view = 0;
+ }
+ if (sh_min >= sc_max) {
+ in_view = 0;
+ }
+ }
+
+ if (in_view == 0) {
+ return SCROLLHANDLE_BAR;
+ }
+
+ /* check if mouse is in or past either handle */
+ /* TODO: check if these extents are still valid or not */
+ in_max = ((mouse >= (sh_max - V2D_SCROLLER_HANDLE_SIZE)) &&
+ (mouse <= (sh_max + V2D_SCROLLER_HANDLE_SIZE)));
+ in_min = ((mouse <= (sh_min + V2D_SCROLLER_HANDLE_SIZE)) &&
+ (mouse >= (sh_min - V2D_SCROLLER_HANDLE_SIZE)));
+ in_bar = ((mouse < (sh_max - V2D_SCROLLER_HANDLE_SIZE)) &&
+ (mouse > (sh_min + V2D_SCROLLER_HANDLE_SIZE)));
+ out_min = mouse < (sh_min - V2D_SCROLLER_HANDLE_SIZE);
+ out_max = mouse > (sh_max + V2D_SCROLLER_HANDLE_SIZE);
+
+ if (in_bar) {
+ return SCROLLHANDLE_BAR;
+ }
+ else if (in_max) {
+ return SCROLLHANDLE_MAX;
+ }
+ else if (in_min) {
+ return SCROLLHANDLE_MIN;
+ }
+ else if (out_min) {
+ return SCROLLHANDLE_MIN_OUTSIDE;
+ }
+ else if (out_max) {
+ return SCROLLHANDLE_MAX_OUTSIDE;
+ }
+
+ /* unlikely to happen, though we just cover it in case */
+ return SCROLLHANDLE_BAR;
}
static bool scroller_activate_poll(bContext *C)
{
- if (!view2d_poll(C)) {
- return false;
- }
+ if (!view2d_poll(C)) {
+ return false;
+ }
- wmWindow *win = CTX_wm_window(C);
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
- wmEvent *event = win->eventstate;
+ wmWindow *win = CTX_wm_window(C);
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ wmEvent *event = win->eventstate;
- /* check if mouse in scrollbars, if they're enabled */
- return (UI_view2d_mouse_in_scrollers(ar, v2d, event->x, event->y) != 0);
+ /* check if mouse in scrollbars, if they're enabled */
+ return (UI_view2d_mouse_in_scrollers(ar, v2d, event->x, event->y) != 0);
}
/* initialize customdata for scroller manipulation operator */
-static void scroller_activate_init(bContext *C, wmOperator *op, const wmEvent *event, const char in_scroller)
+static void scroller_activate_init(bContext *C,
+ wmOperator *op,
+ const wmEvent *event,
+ const char in_scroller)
{
- v2dScrollerMove *vsm;
- View2DScrollers *scrollers;
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
- rctf tot_cur_union;
- float mask_size;
-
- /* set custom-data for operator */
- vsm = MEM_callocN(sizeof(v2dScrollerMove), "v2dScrollerMove");
- op->customdata = vsm;
-
- /* set general data */
- vsm->v2d = v2d;
- vsm->ar = ar;
- vsm->scroller = in_scroller;
-
- /* store mouse-coordinates, and convert mouse/screen coordinates to region coordinates */
- vsm->lastx = event->x;
- vsm->lasty = event->y;
- /* 'zone' depends on where mouse is relative to bubble
- * - zooming must be allowed on this axis, otherwise, default to pan
- */
- scrollers = UI_view2d_scrollers_calc(C, v2d, NULL, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
-
- /* use a union of 'cur' & 'tot' incase the current view is far outside 'tot'. In this cases
- * moving the scroll bars has far too little effect and the view can get stuck T31476. */
- tot_cur_union = v2d->tot;
- BLI_rctf_union(&tot_cur_union, &v2d->cur);
-
- if (in_scroller == 'h') {
- /* horizontal scroller - calculate adjustment factor first */
- mask_size = (float)BLI_rcti_size_x(&v2d->hor);
- vsm->fac = BLI_rctf_size_x(&tot_cur_union) / mask_size;
-
- /* pixel rounding */
- vsm->fac_round = (BLI_rctf_size_x(&v2d->cur)) / (float)(BLI_rcti_size_x(&ar->winrct) + 1);
-
- /* get 'zone' (i.e. which part of scroller is activated) */
- vsm->zone = mouse_in_scroller_handle(
- event->mval[0],
- v2d->hor.xmin, v2d->hor.xmax,
- scrollers->hor_min, scrollers->hor_max);
-
- if ((v2d->keepzoom & V2D_LOCKZOOM_X) && ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
- /* default to scroll, as handles not usable */
- vsm->zone = SCROLLHANDLE_BAR;
- }
-
- vsm->scrollbarwidth = scrollers->hor_max - scrollers->hor_min;
- vsm->scrollbar_orig = ((scrollers->hor_max + scrollers->hor_min) / 2) + ar->winrct.xmin;
- }
- else {
- /* vertical scroller - calculate adjustment factor first */
- mask_size = (float)BLI_rcti_size_y(&v2d->vert);
- vsm->fac = BLI_rctf_size_y(&tot_cur_union) / mask_size;
-
- /* pixel rounding */
- vsm->fac_round = (BLI_rctf_size_y(&v2d->cur)) / (float)(BLI_rcti_size_y(&ar->winrct) + 1);
-
- /* get 'zone' (i.e. which part of scroller is activated) */
- vsm->zone = mouse_in_scroller_handle(
- event->mval[1],
- v2d->vert.ymin, v2d->vert.ymax,
- scrollers->vert_min, scrollers->vert_max);
-
- if ((v2d->keepzoom & V2D_LOCKZOOM_Y) && ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
- /* default to scroll, as handles not usable */
- vsm->zone = SCROLLHANDLE_BAR;
- }
-
- vsm->scrollbarwidth = scrollers->vert_max - scrollers->vert_min;
- vsm->scrollbar_orig = ((scrollers->vert_max + scrollers->vert_min) / 2) + ar->winrct.ymin;
- }
-
- UI_view2d_scrollers_free(scrollers);
- ED_region_tag_redraw_no_rebuild(ar);
+ v2dScrollerMove *vsm;
+ View2DScrollers *scrollers;
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ rctf tot_cur_union;
+ float mask_size;
+
+ /* set custom-data for operator */
+ vsm = MEM_callocN(sizeof(v2dScrollerMove), "v2dScrollerMove");
+ op->customdata = vsm;
+
+ /* set general data */
+ vsm->v2d = v2d;
+ vsm->ar = ar;
+ vsm->scroller = in_scroller;
+
+ /* store mouse-coordinates, and convert mouse/screen coordinates to region coordinates */
+ vsm->lastx = event->x;
+ vsm->lasty = event->y;
+ /* 'zone' depends on where mouse is relative to bubble
+ * - zooming must be allowed on this axis, otherwise, default to pan
+ */
+ scrollers = UI_view2d_scrollers_calc(
+ C, v2d, NULL, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+
+ /* use a union of 'cur' & 'tot' incase the current view is far outside 'tot'. In this cases
+ * moving the scroll bars has far too little effect and the view can get stuck T31476. */
+ tot_cur_union = v2d->tot;
+ BLI_rctf_union(&tot_cur_union, &v2d->cur);
+
+ if (in_scroller == 'h') {
+ /* horizontal scroller - calculate adjustment factor first */
+ mask_size = (float)BLI_rcti_size_x(&v2d->hor);
+ vsm->fac = BLI_rctf_size_x(&tot_cur_union) / mask_size;
+
+ /* pixel rounding */
+ vsm->fac_round = (BLI_rctf_size_x(&v2d->cur)) / (float)(BLI_rcti_size_x(&ar->winrct) + 1);
+
+ /* get 'zone' (i.e. which part of scroller is activated) */
+ vsm->zone = mouse_in_scroller_handle(
+ event->mval[0], v2d->hor.xmin, v2d->hor.xmax, scrollers->hor_min, scrollers->hor_max);
+
+ if ((v2d->keepzoom & V2D_LOCKZOOM_X) && ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
+ /* default to scroll, as handles not usable */
+ vsm->zone = SCROLLHANDLE_BAR;
+ }
+
+ vsm->scrollbarwidth = scrollers->hor_max - scrollers->hor_min;
+ vsm->scrollbar_orig = ((scrollers->hor_max + scrollers->hor_min) / 2) + ar->winrct.xmin;
+ }
+ else {
+ /* vertical scroller - calculate adjustment factor first */
+ mask_size = (float)BLI_rcti_size_y(&v2d->vert);
+ vsm->fac = BLI_rctf_size_y(&tot_cur_union) / mask_size;
+
+ /* pixel rounding */
+ vsm->fac_round = (BLI_rctf_size_y(&v2d->cur)) / (float)(BLI_rcti_size_y(&ar->winrct) + 1);
+
+ /* get 'zone' (i.e. which part of scroller is activated) */
+ vsm->zone = mouse_in_scroller_handle(
+ event->mval[1], v2d->vert.ymin, v2d->vert.ymax, scrollers->vert_min, scrollers->vert_max);
+
+ if ((v2d->keepzoom & V2D_LOCKZOOM_Y) && ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
+ /* default to scroll, as handles not usable */
+ vsm->zone = SCROLLHANDLE_BAR;
+ }
+
+ vsm->scrollbarwidth = scrollers->vert_max - scrollers->vert_min;
+ vsm->scrollbar_orig = ((scrollers->vert_max + scrollers->vert_min) / 2) + ar->winrct.ymin;
+ }
+
+ UI_view2d_scrollers_free(scrollers);
+ ED_region_tag_redraw_no_rebuild(ar);
}
/* cleanup temp customdata */
static void scroller_activate_exit(bContext *C, wmOperator *op)
{
- if (op->customdata) {
- v2dScrollerMove *vsm = op->customdata;
+ if (op->customdata) {
+ v2dScrollerMove *vsm = op->customdata;
- vsm->v2d->scroll_ui &= ~(V2D_SCROLL_H_ACTIVE | V2D_SCROLL_V_ACTIVE);
+ vsm->v2d->scroll_ui &= ~(V2D_SCROLL_H_ACTIVE | V2D_SCROLL_V_ACTIVE);
- MEM_freeN(op->customdata);
- op->customdata = NULL;
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
- ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
- }
+ ED_region_tag_redraw_no_rebuild(CTX_wm_region(C));
+ }
}
static void scroller_activate_cancel(bContext *C, wmOperator *op)
{
- scroller_activate_exit(C, op);
+ scroller_activate_exit(C, op);
}
/* apply transform to view (i.e. adjust 'cur' rect) */
static void scroller_activate_apply(bContext *C, wmOperator *op)
{
- v2dScrollerMove *vsm = op->customdata;
- View2D *v2d = vsm->v2d;
- float temp;
-
- /* calculate amount to move view by */
- temp = vsm->fac * vsm->delta;
-
- /* round to pixel */
- temp = roundf(temp / vsm->fac_round) * vsm->fac_round;
-
- /* type of movement */
- switch (vsm->zone) {
- case SCROLLHANDLE_MIN:
- /* only expand view on axis if zoom is allowed */
- if ((vsm->scroller == 'h') && !(v2d->keepzoom & V2D_LOCKZOOM_X)) {
- v2d->cur.xmin -= temp;
- }
- if ((vsm->scroller == 'v') && !(v2d->keepzoom & V2D_LOCKZOOM_Y)) {
- v2d->cur.ymin -= temp;
- }
- break;
-
- case SCROLLHANDLE_MAX:
-
- /* only expand view on axis if zoom is allowed */
- if ((vsm->scroller == 'h') && !(v2d->keepzoom & V2D_LOCKZOOM_X)) {
- v2d->cur.xmax += temp;
- }
- if ((vsm->scroller == 'v') && !(v2d->keepzoom & V2D_LOCKZOOM_Y)) {
- v2d->cur.ymax += temp;
- }
- break;
-
- case SCROLLHANDLE_MIN_OUTSIDE:
- case SCROLLHANDLE_MAX_OUTSIDE:
- case SCROLLHANDLE_BAR:
- default:
- /* only move view on an axis if panning is allowed */
- if ((vsm->scroller == 'h') && !(v2d->keepofs & V2D_LOCKOFS_X)) {
- v2d->cur.xmin += temp;
- v2d->cur.xmax += temp;
- }
- if ((vsm->scroller == 'v') && !(v2d->keepofs & V2D_LOCKOFS_Y)) {
- v2d->cur.ymin += temp;
- v2d->cur.ymax += temp;
- }
- break;
-
- }
-
- /* validate that view is in valid configuration after this operation */
- UI_view2d_curRect_validate(v2d);
-
- /* request updates to be done... */
- ED_region_tag_redraw_no_rebuild(vsm->ar);
- UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+ v2dScrollerMove *vsm = op->customdata;
+ View2D *v2d = vsm->v2d;
+ float temp;
+
+ /* calculate amount to move view by */
+ temp = vsm->fac * vsm->delta;
+
+ /* round to pixel */
+ temp = roundf(temp / vsm->fac_round) * vsm->fac_round;
+
+ /* type of movement */
+ switch (vsm->zone) {
+ case SCROLLHANDLE_MIN:
+ /* only expand view on axis if zoom is allowed */
+ if ((vsm->scroller == 'h') && !(v2d->keepzoom & V2D_LOCKZOOM_X)) {
+ v2d->cur.xmin -= temp;
+ }
+ if ((vsm->scroller == 'v') && !(v2d->keepzoom & V2D_LOCKZOOM_Y)) {
+ v2d->cur.ymin -= temp;
+ }
+ break;
+
+ case SCROLLHANDLE_MAX:
+
+ /* only expand view on axis if zoom is allowed */
+ if ((vsm->scroller == 'h') && !(v2d->keepzoom & V2D_LOCKZOOM_X)) {
+ v2d->cur.xmax += temp;
+ }
+ if ((vsm->scroller == 'v') && !(v2d->keepzoom & V2D_LOCKZOOM_Y)) {
+ v2d->cur.ymax += temp;
+ }
+ break;
+
+ case SCROLLHANDLE_MIN_OUTSIDE:
+ case SCROLLHANDLE_MAX_OUTSIDE:
+ case SCROLLHANDLE_BAR:
+ default:
+ /* only move view on an axis if panning is allowed */
+ if ((vsm->scroller == 'h') && !(v2d->keepofs & V2D_LOCKOFS_X)) {
+ v2d->cur.xmin += temp;
+ v2d->cur.xmax += temp;
+ }
+ if ((vsm->scroller == 'v') && !(v2d->keepofs & V2D_LOCKOFS_Y)) {
+ v2d->cur.ymin += temp;
+ v2d->cur.ymax += temp;
+ }
+ break;
+ }
+
+ /* validate that view is in valid configuration after this operation */
+ UI_view2d_curRect_validate(v2d);
+
+ /* request updates to be done... */
+ ED_region_tag_redraw_no_rebuild(vsm->ar);
+ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
}
/**
@@ -1954,187 +1921,181 @@ static void scroller_activate_apply(bContext *C, wmOperator *op)
*/
static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- v2dScrollerMove *vsm = op->customdata;
-
- /* execute the events */
- switch (event->type) {
- case MOUSEMOVE:
- {
- /* calculate new delta transform, then store mouse-coordinates for next-time */
- if (ELEM(vsm->zone, SCROLLHANDLE_BAR, SCROLLHANDLE_MAX)) {
- /* if using bar (i.e. 'panning') or 'max' zoom widget */
- switch (vsm->scroller) {
- case 'h': /* horizontal scroller - so only horizontal movement
- * ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->x - vsm->lastx);
- break;
- case 'v': /* vertical scroller - so only vertical movement
- * ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->y - vsm->lasty);
- break;
- }
- }
- else if (vsm->zone == SCROLLHANDLE_MIN) {
- /* using 'min' zoom widget */
- switch (vsm->scroller) {
- case 'h': /* horizontal scroller - so only horizontal movement
- * ('cur' moves with mouse) */
- vsm->delta = (float)(vsm->lastx - event->x);
- break;
- case 'v': /* vertical scroller - so only vertical movement
- * ('cur' moves with to mouse) */
- vsm->delta = (float)(vsm->lasty - event->y);
- break;
- }
- }
-
- /* store previous coordinates */
- vsm->lastx = event->x;
- vsm->lasty = event->y;
-
- scroller_activate_apply(C, op);
- break;
- }
- case LEFTMOUSE:
- case MIDDLEMOUSE:
- if (event->val == KM_RELEASE) {
- /* single-click was in empty space outside bubble, so scroll by 1 'page' */
- if (ELEM(vsm->zone, SCROLLHANDLE_MIN_OUTSIDE, SCROLLHANDLE_MAX_OUTSIDE)) {
- if (vsm->zone == SCROLLHANDLE_MIN_OUTSIDE) {
- vsm->delta = -vsm->scrollbarwidth * 0.8f;
- }
- else if (vsm->zone == SCROLLHANDLE_MAX_OUTSIDE) {
- vsm->delta = vsm->scrollbarwidth * 0.8f;
- }
-
- scroller_activate_apply(C, op);
- scroller_activate_exit(C, op);
- return OPERATOR_FINISHED;
- }
-
- /* otherwise, end the drag action */
- if (vsm->lastx || vsm->lasty) {
- scroller_activate_exit(C, op);
- return OPERATOR_FINISHED;
- }
- }
- break;
-
- }
-
- return OPERATOR_RUNNING_MODAL;
+ v2dScrollerMove *vsm = op->customdata;
+
+ /* execute the events */
+ switch (event->type) {
+ case MOUSEMOVE: {
+ /* calculate new delta transform, then store mouse-coordinates for next-time */
+ if (ELEM(vsm->zone, SCROLLHANDLE_BAR, SCROLLHANDLE_MAX)) {
+ /* if using bar (i.e. 'panning') or 'max' zoom widget */
+ switch (vsm->scroller) {
+ case 'h': /* horizontal scroller - so only horizontal movement
+ * ('cur' moves opposite to mouse) */
+ vsm->delta = (float)(event->x - vsm->lastx);
+ break;
+ case 'v': /* vertical scroller - so only vertical movement
+ * ('cur' moves opposite to mouse) */
+ vsm->delta = (float)(event->y - vsm->lasty);
+ break;
+ }
+ }
+ else if (vsm->zone == SCROLLHANDLE_MIN) {
+ /* using 'min' zoom widget */
+ switch (vsm->scroller) {
+ case 'h': /* horizontal scroller - so only horizontal movement
+ * ('cur' moves with mouse) */
+ vsm->delta = (float)(vsm->lastx - event->x);
+ break;
+ case 'v': /* vertical scroller - so only vertical movement
+ * ('cur' moves with to mouse) */
+ vsm->delta = (float)(vsm->lasty - event->y);
+ break;
+ }
+ }
+
+ /* store previous coordinates */
+ vsm->lastx = event->x;
+ vsm->lasty = event->y;
+
+ scroller_activate_apply(C, op);
+ break;
+ }
+ case LEFTMOUSE:
+ case MIDDLEMOUSE:
+ if (event->val == KM_RELEASE) {
+ /* single-click was in empty space outside bubble, so scroll by 1 'page' */
+ if (ELEM(vsm->zone, SCROLLHANDLE_MIN_OUTSIDE, SCROLLHANDLE_MAX_OUTSIDE)) {
+ if (vsm->zone == SCROLLHANDLE_MIN_OUTSIDE) {
+ vsm->delta = -vsm->scrollbarwidth * 0.8f;
+ }
+ else if (vsm->zone == SCROLLHANDLE_MAX_OUTSIDE) {
+ vsm->delta = vsm->scrollbarwidth * 0.8f;
+ }
+
+ scroller_activate_apply(C, op);
+ scroller_activate_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+
+ /* otherwise, end the drag action */
+ if (vsm->lastx || vsm->lasty) {
+ scroller_activate_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
-
/* a click (or click drag in progress)
* should have occurred, so check if it happened in scrollbar */
static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
-
- /* check if mouse in scrollbars, if they're enabled */
- const char in_scroller = UI_view2d_mouse_in_scrollers(ar, v2d, event->x, event->y);
-
- /* if in a scroller, init customdata then set modal handler which will
- * catch mousedown to start doing useful stuff */
- if (in_scroller) {
- v2dScrollerMove *vsm;
-
- /* initialize customdata */
- scroller_activate_init(C, op, event, in_scroller);
- vsm = (v2dScrollerMove *)op->customdata;
-
- /* support for quick jump to location - gtk and qt do this on linux */
- if (event->type == MIDDLEMOUSE) {
- switch (vsm->scroller) {
- case 'h': /* horizontal scroller - so only horizontal movement
- * ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->x - vsm->scrollbar_orig);
- break;
- case 'v': /* vertical scroller - so only vertical movement
- * ('cur' moves opposite to mouse) */
- vsm->delta = (float)(event->y - vsm->scrollbar_orig);
- break;
- }
- scroller_activate_apply(C, op);
-
- vsm->zone = SCROLLHANDLE_BAR;
- }
-
- /* check if zoom zones are inappropriate (i.e. zoom widgets not shown), so cannot continue
- * NOTE: see view2d.c for latest conditions, and keep this in sync with that
- */
- if (ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
- if (((vsm->scroller == 'h') && (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) == 0) ||
- ((vsm->scroller == 'v') && (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) == 0))
- {
- /* switch to bar (i.e. no scaling gets handled) */
- vsm->zone = SCROLLHANDLE_BAR;
- }
- }
-
- /* check if zone is inappropriate (i.e. 'bar' but panning is banned), so cannot continue */
- if (vsm->zone == SCROLLHANDLE_BAR) {
- if (((vsm->scroller == 'h') && (v2d->keepofs & V2D_LOCKOFS_X)) ||
- ((vsm->scroller == 'v') && (v2d->keepofs & V2D_LOCKOFS_Y)))
- {
- /* free customdata initialized */
- scroller_activate_exit(C, op);
-
- /* can't catch this event for ourselves, so let it go to someone else? */
- return OPERATOR_PASS_THROUGH;
- }
- }
-
- /* zone is also inappropriate if scroller is not visible... */
- if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_FULLR))) ||
- ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_FULLR))) )
- {
- /* free customdata initialized */
- scroller_activate_exit(C, op);
-
- /* can't catch this event for ourselves, so let it go to someone else? */
- /* XXX note: if handlers use mask rect to clip input, input will fail for this case */
- return OPERATOR_PASS_THROUGH;
- }
-
- /* activate the scroller */
- if (vsm->scroller == 'h') {
- v2d->scroll_ui |= V2D_SCROLL_H_ACTIVE;
- }
- else {
- v2d->scroll_ui |= V2D_SCROLL_V_ACTIVE;
- }
-
- /* still ok, so can add */
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
- else {
- /* not in scroller, so nothing happened...
- * (pass through let's something else catch event) */
- return OPERATOR_PASS_THROUGH;
- }
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+
+ /* check if mouse in scrollbars, if they're enabled */
+ const char in_scroller = UI_view2d_mouse_in_scrollers(ar, v2d, event->x, event->y);
+
+ /* if in a scroller, init customdata then set modal handler which will
+ * catch mousedown to start doing useful stuff */
+ if (in_scroller) {
+ v2dScrollerMove *vsm;
+
+ /* initialize customdata */
+ scroller_activate_init(C, op, event, in_scroller);
+ vsm = (v2dScrollerMove *)op->customdata;
+
+ /* support for quick jump to location - gtk and qt do this on linux */
+ if (event->type == MIDDLEMOUSE) {
+ switch (vsm->scroller) {
+ case 'h': /* horizontal scroller - so only horizontal movement
+ * ('cur' moves opposite to mouse) */
+ vsm->delta = (float)(event->x - vsm->scrollbar_orig);
+ break;
+ case 'v': /* vertical scroller - so only vertical movement
+ * ('cur' moves opposite to mouse) */
+ vsm->delta = (float)(event->y - vsm->scrollbar_orig);
+ break;
+ }
+ scroller_activate_apply(C, op);
+
+ vsm->zone = SCROLLHANDLE_BAR;
+ }
+
+ /* check if zoom zones are inappropriate (i.e. zoom widgets not shown), so cannot continue
+ * NOTE: see view2d.c for latest conditions, and keep this in sync with that
+ */
+ if (ELEM(vsm->zone, SCROLLHANDLE_MIN, SCROLLHANDLE_MAX)) {
+ if (((vsm->scroller == 'h') && (v2d->scroll & V2D_SCROLL_SCALE_HORIZONTAL) == 0) ||
+ ((vsm->scroller == 'v') && (v2d->scroll & V2D_SCROLL_SCALE_VERTICAL) == 0)) {
+ /* switch to bar (i.e. no scaling gets handled) */
+ vsm->zone = SCROLLHANDLE_BAR;
+ }
+ }
+
+ /* check if zone is inappropriate (i.e. 'bar' but panning is banned), so cannot continue */
+ if (vsm->zone == SCROLLHANDLE_BAR) {
+ if (((vsm->scroller == 'h') && (v2d->keepofs & V2D_LOCKOFS_X)) ||
+ ((vsm->scroller == 'v') && (v2d->keepofs & V2D_LOCKOFS_Y))) {
+ /* free customdata initialized */
+ scroller_activate_exit(C, op);
+
+ /* can't catch this event for ourselves, so let it go to someone else? */
+ return OPERATOR_PASS_THROUGH;
+ }
+ }
+
+ /* zone is also inappropriate if scroller is not visible... */
+ if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_FULLR))) ||
+ ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_FULLR)))) {
+ /* free customdata initialized */
+ scroller_activate_exit(C, op);
+
+ /* can't catch this event for ourselves, so let it go to someone else? */
+ /* XXX note: if handlers use mask rect to clip input, input will fail for this case */
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ /* activate the scroller */
+ if (vsm->scroller == 'h') {
+ v2d->scroll_ui |= V2D_SCROLL_H_ACTIVE;
+ }
+ else {
+ v2d->scroll_ui |= V2D_SCROLL_V_ACTIVE;
+ }
+
+ /* still ok, so can add */
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ /* not in scroller, so nothing happened...
+ * (pass through let's something else catch event) */
+ return OPERATOR_PASS_THROUGH;
+ }
}
/* LMB-Drag in Scrollers - not repeatable operator! */
static void VIEW2D_OT_scroller_activate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Scroller Activate";
- ot->description = "Scroll view by mouse click and drag";
- ot->idname = "VIEW2D_OT_scroller_activate";
+ /* identifiers */
+ ot->name = "Scroller Activate";
+ ot->description = "Scroll view by mouse click and drag";
+ ot->idname = "VIEW2D_OT_scroller_activate";
- /* flags */
- ot->flag = OPTYPE_BLOCKING;
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING;
- /* api callbacks */
- ot->invoke = scroller_activate_invoke;
- ot->modal = scroller_activate_modal;
- ot->cancel = scroller_activate_cancel;
+ /* api callbacks */
+ ot->invoke = scroller_activate_invoke;
+ ot->modal = scroller_activate_modal;
+ ot->cancel = scroller_activate_cancel;
- ot->poll = scroller_activate_poll;
+ ot->poll = scroller_activate_poll;
}
/* ********************************************************* */
@@ -2142,70 +2103,70 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot)
static int reset_exec(bContext *C, wmOperator *UNUSED(op))
{
- uiStyle *style = UI_style_get();
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = &ar->v2d;
- int winx, winy;
- const int snap_test = ED_region_snap_size_test(ar);
-
- /* zoom 1.0 */
- winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
- winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
-
- v2d->cur.xmax = v2d->cur.xmin + winx;
- v2d->cur.ymax = v2d->cur.ymin + winy;
-
- /* align */
- if (v2d->align) {
- /* posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
- v2d->cur.xmax = 0.0f;
- v2d->cur.xmin = -winx * style->panelzoom;
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
- v2d->cur.xmax = winx * style->panelzoom;
- v2d->cur.xmin = 0.0f;
- }
-
- /* - posx and negx flags are mutually exclusive, so watch out */
- if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
- v2d->cur.ymax = 0.0f;
- v2d->cur.ymin = -winy * style->panelzoom;
- }
- else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
- v2d->cur.ymax = winy * style->panelzoom;
- v2d->cur.ymin = 0.0f;
- }
- }
-
- /* validate that view is in valid configuration after this operation */
- UI_view2d_curRect_validate(v2d);
-
- if (ED_region_snap_size_apply(ar, snap_test)) {
- ScrArea *sa = CTX_wm_area(C);
- ED_area_tag_redraw(sa);
- WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
- }
-
- /* request updates to be done... */
- ED_region_tag_redraw(ar);
- UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
-
- UI_view2d_zoom_cache_reset();
-
- return OPERATOR_FINISHED;
+ uiStyle *style = UI_style_get();
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ int winx, winy;
+ const int snap_test = ED_region_snap_size_test(ar);
+
+ /* zoom 1.0 */
+ winx = (float)(BLI_rcti_size_x(&v2d->mask) + 1);
+ winy = (float)(BLI_rcti_size_y(&v2d->mask) + 1);
+
+ v2d->cur.xmax = v2d->cur.xmin + winx;
+ v2d->cur.ymax = v2d->cur.ymin + winy;
+
+ /* align */
+ if (v2d->align) {
+ /* posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_X) && !(v2d->align & V2D_ALIGN_NO_NEG_X)) {
+ v2d->cur.xmax = 0.0f;
+ v2d->cur.xmin = -winx * style->panelzoom;
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_X) && !(v2d->align & V2D_ALIGN_NO_POS_X)) {
+ v2d->cur.xmax = winx * style->panelzoom;
+ v2d->cur.xmin = 0.0f;
+ }
+
+ /* - posx and negx flags are mutually exclusive, so watch out */
+ if ((v2d->align & V2D_ALIGN_NO_POS_Y) && !(v2d->align & V2D_ALIGN_NO_NEG_Y)) {
+ v2d->cur.ymax = 0.0f;
+ v2d->cur.ymin = -winy * style->panelzoom;
+ }
+ else if ((v2d->align & V2D_ALIGN_NO_NEG_Y) && !(v2d->align & V2D_ALIGN_NO_POS_Y)) {
+ v2d->cur.ymax = winy * style->panelzoom;
+ v2d->cur.ymin = 0.0f;
+ }
+ }
+
+ /* validate that view is in valid configuration after this operation */
+ UI_view2d_curRect_validate(v2d);
+
+ if (ED_region_snap_size_apply(ar, snap_test)) {
+ ScrArea *sa = CTX_wm_area(C);
+ ED_area_tag_redraw(sa);
+ WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
+ }
+
+ /* request updates to be done... */
+ ED_region_tag_redraw(ar);
+ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
+
+ UI_view2d_zoom_cache_reset();
+
+ return OPERATOR_FINISHED;
}
static void VIEW2D_OT_reset(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Reset View";
- ot->description = "Reset the view";
- ot->idname = "VIEW2D_OT_reset";
-
- /* api callbacks */
- ot->exec = reset_exec;
- ot->poll = view2d_poll;
+ /* identifiers */
+ ot->name = "Reset View";
+ ot->description = "Reset the view";
+ ot->idname = "VIEW2D_OT_reset";
+
+ /* api callbacks */
+ ot->exec = reset_exec;
+ ot->poll = view2d_poll;
}
/* ********************************************************* */
@@ -2213,31 +2174,31 @@ static void VIEW2D_OT_reset(wmOperatorType *ot)
void ED_operatortypes_view2d(void)
{
- WM_operatortype_append(VIEW2D_OT_pan);
+ WM_operatortype_append(VIEW2D_OT_pan);
- WM_operatortype_append(VIEW2D_OT_scroll_left);
- WM_operatortype_append(VIEW2D_OT_scroll_right);
- WM_operatortype_append(VIEW2D_OT_scroll_up);
- WM_operatortype_append(VIEW2D_OT_scroll_down);
+ WM_operatortype_append(VIEW2D_OT_scroll_left);
+ WM_operatortype_append(VIEW2D_OT_scroll_right);
+ WM_operatortype_append(VIEW2D_OT_scroll_up);
+ WM_operatortype_append(VIEW2D_OT_scroll_down);
- WM_operatortype_append(VIEW2D_OT_zoom_in);
- WM_operatortype_append(VIEW2D_OT_zoom_out);
+ WM_operatortype_append(VIEW2D_OT_zoom_in);
+ WM_operatortype_append(VIEW2D_OT_zoom_out);
- WM_operatortype_append(VIEW2D_OT_zoom);
- WM_operatortype_append(VIEW2D_OT_zoom_border);
+ WM_operatortype_append(VIEW2D_OT_zoom);
+ WM_operatortype_append(VIEW2D_OT_zoom_border);
#ifdef WITH_INPUT_NDOF
- WM_operatortype_append(VIEW2D_OT_ndof);
+ WM_operatortype_append(VIEW2D_OT_ndof);
#endif
- WM_operatortype_append(VIEW2D_OT_smoothview);
+ WM_operatortype_append(VIEW2D_OT_smoothview);
- WM_operatortype_append(VIEW2D_OT_scroller_activate);
+ WM_operatortype_append(VIEW2D_OT_scroller_activate);
- WM_operatortype_append(VIEW2D_OT_reset);
+ WM_operatortype_append(VIEW2D_OT_reset);
}
void ED_keymap_view2d(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "View2D", 0, 0);
+ WM_keymap_ensure(keyconf, "View2D", 0, 0);
}