Blender  V3.3
interface.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <cctype>
9 #include <cfloat>
10 #include <climits>
11 #include <cmath>
12 #include <cstddef> /* `offsetof()` */
13 #include <cstring>
14 
15 #include "MEM_guardedalloc.h"
16 
17 #include "DNA_object_types.h"
18 #include "DNA_scene_types.h"
19 #include "DNA_screen_types.h"
20 #include "DNA_userdef_types.h"
21 #include "DNA_workspace_types.h"
22 
23 #include "BLI_ghash.h"
24 #include "BLI_listbase.h"
25 #include "BLI_math.h"
26 #include "BLI_rect.h"
27 #include "BLI_string.h"
28 #include "BLI_string_search.h"
29 #include "BLI_string_utf8.h"
30 #include "BLI_vector.hh"
31 
32 #include "BLI_utildefines.h"
33 
34 #include "BLO_readfile.h"
35 
36 #include "BKE_animsys.h"
37 #include "BKE_context.h"
38 #include "BKE_idprop.h"
39 #include "BKE_main.h"
40 #include "BKE_report.h"
41 #include "BKE_scene.h"
42 #include "BKE_screen.h"
43 #include "BKE_unit.h"
44 
45 #include "ED_asset.h"
46 
47 #include "GPU_matrix.h"
48 #include "GPU_state.h"
49 
50 #include "BLF_api.h"
51 #include "BLT_translation.h"
52 
53 #include "UI_interface.h"
54 #include "UI_interface_icons.h"
55 #include "UI_view2d.h"
56 
57 #include "IMB_imbuf.h"
58 
59 #include "WM_api.h"
60 #include "WM_message.h"
61 #include "WM_types.h"
62 
63 #include "RNA_access.h"
64 
65 #ifdef WITH_PYTHON
66 # include "BPY_extern_run.h"
67 #endif
68 
69 #include "ED_numinput.h"
70 #include "ED_screen.h"
71 
72 #include "IMB_colormanagement.h"
73 
74 #include "DEG_depsgraph_query.h"
75 
76 #include "interface_intern.h"
77 
78 using blender::Vector;
79 
80 /* prototypes. */
81 static void ui_but_to_pixelrect(struct rcti *rect,
82  const struct ARegion *region,
83  struct uiBlock *block,
84  const struct uiBut *but);
85 static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p);
86 static void ui_def_but_rna__panel_type(bContext *UNUSED(C), uiLayout *layout, void *but_p);
87 static void ui_def_but_rna__menu_type(bContext *UNUSED(C), uiLayout *layout, void *but_p);
88 
89 /* avoid unneeded calls to ui_but_value_get */
90 #define UI_BUT_VALUE_UNSET DBL_MAX
91 #define UI_GET_BUT_VALUE_INIT(_but, _value) \
92  if (_value == DBL_MAX) { \
93  (_value) = ui_but_value_get(_but); \
94  } \
95  ((void)0)
96 
97 #define B_NOP -1
98 
106 static void ui_but_free(const bContext *C, uiBut *but);
107 
108 static bool ui_but_is_unit_radians_ex(UnitSettings *unit, const int unit_type)
109 {
110  return (unit->system_rotation == USER_UNIT_ROT_RADIANS && unit_type == PROP_UNIT_ROTATION);
111 }
112 
113 static bool ui_but_is_unit_radians(const uiBut *but)
114 {
115  UnitSettings *unit = but->block->unit;
116  const int unit_type = UI_but_unit_type_get(but);
117 
118  return ui_but_is_unit_radians_ex(unit, unit_type);
119 }
120 
121 /* ************* window matrix ************** */
122 
123 void ui_block_to_region_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
124 {
125  const int getsizex = BLI_rcti_size_x(&region->winrct) + 1;
126  const int getsizey = BLI_rcti_size_y(&region->winrct) + 1;
127 
128  float gx = *r_x;
129  float gy = *r_y;
130 
131  if (block->panel) {
132  gx += block->panel->ofsx;
133  gy += block->panel->ofsy;
134  }
135 
136  *r_x = ((float)getsizex) * (0.5f + 0.5f * (gx * block->winmat[0][0] + gy * block->winmat[1][0] +
137  block->winmat[3][0]));
138  *r_y = ((float)getsizey) * (0.5f + 0.5f * (gx * block->winmat[0][1] + gy * block->winmat[1][1] +
139  block->winmat[3][1]));
140 }
141 
142 void ui_block_to_window_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
143 {
144  ui_block_to_region_fl(region, block, r_x, r_y);
145  *r_x += region->winrct.xmin;
146  *r_y += region->winrct.ymin;
147 }
148 
149 void ui_block_to_window(const ARegion *region, uiBlock *block, int *r_x, int *r_y)
150 {
151  float fx = *r_x;
152  float fy = *r_y;
153 
154  ui_block_to_window_fl(region, block, &fx, &fy);
155 
156  *r_x = (int)(fx + 0.5f);
157  *r_y = (int)(fy + 0.5f);
158 }
159 
160 void ui_block_to_region_rctf(const ARegion *region,
161  uiBlock *block,
162  rctf *rct_dst,
163  const rctf *rct_src)
164 {
165  *rct_dst = *rct_src;
166  ui_block_to_region_fl(region, block, &rct_dst->xmin, &rct_dst->ymin);
167  ui_block_to_region_fl(region, block, &rct_dst->xmax, &rct_dst->ymax);
168 }
169 
170 void ui_block_to_window_rctf(const ARegion *region,
171  uiBlock *block,
172  rctf *rct_dst,
173  const rctf *rct_src)
174 {
175  *rct_dst = *rct_src;
176  ui_block_to_window_fl(region, block, &rct_dst->xmin, &rct_dst->ymin);
177  ui_block_to_window_fl(region, block, &rct_dst->xmax, &rct_dst->ymax);
178 }
179 
180 float ui_block_to_window_scale(const ARegion *region, uiBlock *block)
181 {
182  /* We could have function for this to avoid dummy arg. */
183  float min_y = 0, max_y = 1;
184  float dummy_x = 0.0f;
185  ui_block_to_window_fl(region, block, &dummy_x, &min_y);
186  dummy_x = 0.0f;
187  ui_block_to_window_fl(region, block, &dummy_x, &max_y);
188  return max_y - min_y;
189 }
190 
191 void ui_window_to_block_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
192 {
193  const int getsizex = BLI_rcti_size_x(&region->winrct) + 1;
194  const int getsizey = BLI_rcti_size_y(&region->winrct) + 1;
195  const int sx = region->winrct.xmin;
196  const int sy = region->winrct.ymin;
197 
198  const float a = 0.5f * ((float)getsizex) * block->winmat[0][0];
199  const float b = 0.5f * ((float)getsizex) * block->winmat[1][0];
200  const float c = 0.5f * ((float)getsizex) * (1.0f + block->winmat[3][0]);
201 
202  const float d = 0.5f * ((float)getsizey) * block->winmat[0][1];
203  const float e = 0.5f * ((float)getsizey) * block->winmat[1][1];
204  const float f = 0.5f * ((float)getsizey) * (1.0f + block->winmat[3][1]);
205 
206  const float px = *r_x - sx;
207  const float py = *r_y - sy;
208 
209  *r_y = (a * (py - f) + d * (c - px)) / (a * e - d * b);
210  *r_x = (px - b * (*r_y) - c) / a;
211 
212  if (block->panel) {
213  *r_x -= block->panel->ofsx;
214  *r_y -= block->panel->ofsy;
215  }
216 }
217 
218 void ui_window_to_block_rctf(const struct ARegion *region,
219  uiBlock *block,
220  rctf *rct_dst,
221  const rctf *rct_src)
222 {
223  *rct_dst = *rct_src;
224  ui_window_to_block_fl(region, block, &rct_dst->xmin, &rct_dst->ymin);
225  ui_window_to_block_fl(region, block, &rct_dst->xmax, &rct_dst->ymax);
226 }
227 
228 void ui_window_to_block(const ARegion *region, uiBlock *block, int *r_x, int *r_y)
229 {
230  float fx = *r_x;
231  float fy = *r_y;
232 
233  ui_window_to_block_fl(region, block, &fx, &fy);
234 
235  *r_x = (int)(fx + 0.5f);
236  *r_y = (int)(fy + 0.5f);
237 }
238 
239 void ui_window_to_region(const ARegion *region, int *r_x, int *r_y)
240 {
241  *r_x -= region->winrct.xmin;
242  *r_y -= region->winrct.ymin;
243 }
244 
245 void ui_window_to_region_rcti(const ARegion *region, rcti *rect_dst, const rcti *rct_src)
246 {
247  rect_dst->xmin = rct_src->xmin - region->winrct.xmin;
248  rect_dst->xmax = rct_src->xmax - region->winrct.xmin;
249  rect_dst->ymin = rct_src->ymin - region->winrct.ymin;
250  rect_dst->ymax = rct_src->ymax - region->winrct.ymin;
251 }
252 
253 void ui_window_to_region_rctf(const ARegion *region, rctf *rect_dst, const rctf *rct_src)
254 {
255  rect_dst->xmin = rct_src->xmin - region->winrct.xmin;
256  rect_dst->xmax = rct_src->xmax - region->winrct.xmin;
257  rect_dst->ymin = rct_src->ymin - region->winrct.ymin;
258  rect_dst->ymax = rct_src->ymax - region->winrct.ymin;
259 }
260 
261 void ui_region_to_window(const ARegion *region, int *r_x, int *r_y)
262 {
263  *r_x += region->winrct.xmin;
264  *r_y += region->winrct.ymin;
265 }
266 
267 static void ui_update_flexible_spacing(const ARegion *region, uiBlock *block)
268 {
269  int sepr_flex_len = 0;
270  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
271  if (but->type == UI_BTYPE_SEPR_SPACER) {
272  sepr_flex_len++;
273  }
274  }
275 
276  if (sepr_flex_len == 0) {
277  return;
278  }
279 
280  rcti rect;
281  ui_but_to_pixelrect(&rect, region, block, static_cast<const uiBut *>(block->buttons.last));
282  const float buttons_width = (float)rect.xmax + UI_HEADER_OFFSET;
283  const float region_width = (float)region->sizex * U.dpi_fac;
284 
285  if (region_width <= buttons_width) {
286  return;
287  }
288 
289  /* We could get rid of this loop if we agree on a max number of spacer */
290  Vector<int, 8> spacers_pos;
291  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
292  if (but->type == UI_BTYPE_SEPR_SPACER) {
293  ui_but_to_pixelrect(&rect, region, block, but);
294  spacers_pos.append(rect.xmax + UI_HEADER_OFFSET);
295  }
296  }
297 
298  const float view_scale_x = UI_view2d_scale_get_x(&region->v2d);
299  const float segment_width = region_width / (float)sepr_flex_len;
300  float offset = 0, remaining_space = region_width - buttons_width;
301  int i = 0;
302  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
303  BLI_rctf_translate(&but->rect, offset / view_scale_x, 0);
304  if (but->type == UI_BTYPE_SEPR_SPACER) {
305  /* How much the next block overlap with the current segment */
306  int overlap = ((i == sepr_flex_len - 1) ? buttons_width - spacers_pos[i] :
307  (spacers_pos[i + 1] - spacers_pos[i]) / 2);
308  const int segment_end = segment_width * (i + 1);
309  const int spacer_end = segment_end - overlap;
310  const int spacer_sta = spacers_pos[i] + offset;
311  if (spacer_end > spacer_sta) {
312  const float step = min_ff(remaining_space, spacer_end - spacer_sta);
313  remaining_space -= step;
314  offset += step;
315  }
316  i++;
317  }
318  }
319  ui_block_bounds_calc(block);
320 }
321 
322 static void ui_update_window_matrix(const wmWindow *window, const ARegion *region, uiBlock *block)
323 {
324  /* window matrix and aspect */
325  if (region && region->visible) {
326  /* Get projection matrix which includes View2D translation and zoom. */
328  block->aspect = 2.0f / fabsf(region->winx * block->winmat[0][0]);
329  }
330  else {
331  /* No subwindow created yet, for menus for example, so we use the main
332  * window instead, since buttons are created there anyway. */
333  const int width = WM_window_pixels_x(window);
334  const int height = WM_window_pixels_y(window);
335  const rcti winrct = {0, width - 1, 0, height - 1};
336 
337  wmGetProjectionMatrix(block->winmat, &winrct);
338  block->aspect = 2.0f / fabsf(width * block->winmat[0][0]);
339  }
340 }
341 
342 void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r_rect)
343 {
344  uiBlock *block = static_cast<uiBlock *>(region->uiblocks.first);
345  if (block && (block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_RADIAL) == 0) {
346  BLI_rcti_rctf_copy_floor(r_rect, &block->rect);
347  BLI_rcti_translate(r_rect, region->winrct.xmin, region->winrct.ymin);
348  }
349  else {
350  *r_rect = region->winrct;
351  }
352 }
353 
354 /* ******************* block calc ************************* */
355 
356 void UI_block_translate(uiBlock *block, int x, int y)
357 {
358  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
359  BLI_rctf_translate(&but->rect, x, y);
360  }
361 
362  BLI_rctf_translate(&block->rect, x, y);
363 }
364 
366 {
367  const bool is_same_align_group = (left->alignnr && (left->alignnr == right->alignnr));
368  return is_same_align_group && (left->rect.xmin < right->rect.xmin);
369 }
370 
371 static void ui_block_bounds_calc_text(uiBlock *block, float offset)
372 {
373  const uiStyle *style = UI_style_get();
374  uiBut *col_bt;
375  int i = 0, j, x1addval = offset;
376 
377  UI_fontstyle_set(&style->widget);
378 
379  uiBut *init_col_bt = static_cast<uiBut *>(block->buttons.first);
380  LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
382  j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr));
383 
384  if (j > i) {
385  i = j;
386  }
387  }
388 
389  /* Skip all buttons that are in a horizontal alignment group.
390  * We don't want to split them apart (but still check the row's width and apply current
391  * offsets). */
392  if (bt->next && ui_but_is_row_alignment_group(bt, bt->next)) {
393  int width = 0;
394  const int alignnr = bt->alignnr;
395  for (col_bt = bt; col_bt && col_bt->alignnr == alignnr; col_bt = col_bt->next) {
396  width += BLI_rctf_size_x(&col_bt->rect);
397  col_bt->rect.xmin += x1addval;
398  col_bt->rect.xmax += x1addval;
399  }
400  if (width > i) {
401  i = width;
402  }
403  /* Give the following code the last button in the alignment group, there might have to be a
404  * split immediately after. */
405  bt = col_bt ? col_bt->prev : nullptr;
406  }
407 
408  if (bt && bt->next && bt->rect.xmin < bt->next->rect.xmin) {
409  /* End of this column, and it's not the last one. */
410  for (col_bt = init_col_bt; col_bt->prev != bt; col_bt = col_bt->next) {
411  col_bt->rect.xmin = x1addval;
412  col_bt->rect.xmax = x1addval + i + block->bounds;
413 
414  ui_but_update(col_bt); /* clips text again */
415  }
416 
417  /* And we prepare next column. */
418  x1addval += i + block->bounds;
419  i = 0;
420  init_col_bt = col_bt;
421  }
422  }
423 
424  /* Last column. */
425  for (col_bt = init_col_bt; col_bt; col_bt = col_bt->next) {
426  /* Recognize a horizontally arranged alignment group and skip its items. */
427  if (col_bt->next && ui_but_is_row_alignment_group(col_bt, col_bt->next)) {
428  const int alignnr = col_bt->alignnr;
429  for (; col_bt && col_bt->alignnr == alignnr; col_bt = col_bt->next) {
430  /* pass */
431  }
432  }
433  if (!col_bt) {
434  break;
435  }
436 
437  col_bt->rect.xmin = x1addval;
438  col_bt->rect.xmax = max_ff(x1addval + i + block->bounds, offset + block->minbounds);
439 
440  ui_but_update(col_bt); /* clips text again */
441  }
442 }
443 
445 {
446  if (BLI_listbase_is_empty(&block->buttons)) {
447  if (block->panel) {
448  block->rect.xmin = 0.0;
449  block->rect.xmax = block->panel->sizex;
450  block->rect.ymin = 0.0;
451  block->rect.ymax = block->panel->sizey;
452  }
453  }
454  else {
455 
456  BLI_rctf_init_minmax(&block->rect);
457 
458  LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
459  BLI_rctf_union(&block->rect, &bt->rect);
460  }
461 
462  block->rect.xmin -= block->bounds;
463  block->rect.ymin -= block->bounds;
464  block->rect.xmax += block->bounds;
465  block->rect.ymax += block->bounds;
466  }
467 
468  block->rect.xmax = block->rect.xmin + max_ff(BLI_rctf_size_x(&block->rect), block->minbounds);
469 
470  /* hardcoded exception... but that one is annoying with larger safety */
471  uiBut *bt = static_cast<uiBut *>(block->buttons.first);
472  const int xof = ((bt && STRPREFIX(bt->str, "ERROR")) ? 10 : 40) * U.dpi_fac;
473 
474  block->safety.xmin = block->rect.xmin - xof;
475  block->safety.ymin = block->rect.ymin - xof;
476  block->safety.xmax = block->rect.xmax + xof;
477  block->safety.ymax = block->rect.ymax + xof;
478 }
479 
480 static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block)
481 {
482  /* NOTE: this is used for the splash where window bounds event has not been
483  * updated by ghost, get the window bounds from ghost directly */
484 
485  const int xmax = WM_window_pixels_x(window);
486  const int ymax = WM_window_pixels_y(window);
487 
488  ui_block_bounds_calc(block);
489 
490  const int width = BLI_rctf_size_x(&block->rect);
491  const int height = BLI_rctf_size_y(&block->rect);
492 
493  const int startx = (xmax * 0.5f) - (width * 0.5f);
494  const int starty = (ymax * 0.5f) - (height * 0.5f);
495 
496  UI_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
497 
498  /* now recompute bounds and safety */
499  ui_block_bounds_calc(block);
500 }
501 
503 {
504  const int xy[2] = {
505  (int)block->pie_data.pie_center_spawned[0],
506  (int)block->pie_data.pie_center_spawned[1],
507  };
508 
509  UI_block_translate(block, xy[0], xy[1]);
510 
511  /* now recompute bounds and safety */
512  ui_block_bounds_calc(block);
513 }
514 
516  wmWindow *window, uiBlock *block, eBlockBoundsCalc bounds_calc, const int xy[2], int r_xy[2])
517 {
518  const int oldbounds = block->bounds;
519 
520  /* compute mouse position with user defined offset */
521  ui_block_bounds_calc(block);
522 
523  const int xmax = WM_window_pixels_x(window);
524  const int ymax = WM_window_pixels_y(window);
525 
526  int oldwidth = BLI_rctf_size_x(&block->rect);
527  int oldheight = BLI_rctf_size_y(&block->rect);
528 
529  /* first we ensure wide enough text bounds */
530  if (bounds_calc == UI_BLOCK_BOUNDS_POPUP_MENU) {
531  if (block->flag & UI_BLOCK_LOOP) {
532  block->bounds = 2.5f * UI_UNIT_X;
533  ui_block_bounds_calc_text(block, block->rect.xmin);
534  }
535  }
536 
537  /* next we recompute bounds */
538  block->bounds = oldbounds;
539  ui_block_bounds_calc(block);
540 
541  /* and we adjust the position to fit within window */
542  const int width = BLI_rctf_size_x(&block->rect);
543  const int height = BLI_rctf_size_y(&block->rect);
544 
545  /* avoid divide by zero below, caused by calling with no UI, but better not crash */
546  oldwidth = oldwidth > 0 ? oldwidth : MAX2(1, width);
547  oldheight = oldheight > 0 ? oldheight : MAX2(1, height);
548 
549  /* offset block based on mouse position, user offset is scaled
550  * along in case we resized the block in ui_block_bounds_calc_text */
551  rcti rect;
552  const int raw_x = rect.xmin = xy[0] + block->rect.xmin +
553  (block->bounds_offset[0] * width) / oldwidth;
554  int raw_y = rect.ymin = xy[1] + block->rect.ymin +
555  (block->bounds_offset[1] * height) / oldheight;
556  rect.xmax = rect.xmin + width;
557  rect.ymax = rect.ymin + height;
558 
559  rcti rect_bounds;
560  const int margin = UI_SCREEN_MARGIN;
561  rect_bounds.xmin = margin;
562  rect_bounds.ymin = margin;
563  rect_bounds.xmax = xmax - margin;
564  rect_bounds.ymax = ymax - UI_POPUP_MENU_TOP;
565 
566  int ofs_dummy[2];
567  BLI_rcti_clamp(&rect, &rect_bounds, ofs_dummy);
568  UI_block_translate(block, rect.xmin - block->rect.xmin, rect.ymin - block->rect.ymin);
569 
570  /* now recompute bounds and safety */
571  ui_block_bounds_calc(block);
572 
573  /* If given, adjust input coordinates such that they would generate real final popup position.
574  * Needed to handle correctly floating panels once they have been dragged around,
575  * see T52999. */
576  if (r_xy) {
577  r_xy[0] = xy[0] + block->rect.xmin - raw_x;
578  r_xy[1] = xy[1] + block->rect.ymin - raw_y;
579  }
580 }
581 
582 void UI_block_bounds_set_normal(uiBlock *block, int addval)
583 {
584  if (block == nullptr) {
585  return;
586  }
587 
588  block->bounds = addval;
589  block->bounds_type = UI_BLOCK_BOUNDS;
590 }
591 
592 void UI_block_bounds_set_text(uiBlock *block, int addval)
593 {
594  block->bounds = addval;
596 }
597 
598 void UI_block_bounds_set_popup(uiBlock *block, int addval, const int bounds_offset[2])
599 {
600  block->bounds = addval;
602  if (bounds_offset != nullptr) {
603  block->bounds_offset[0] = bounds_offset[0];
604  block->bounds_offset[1] = bounds_offset[1];
605  }
606  else {
607  block->bounds_offset[0] = 0;
608  block->bounds_offset[1] = 0;
609  }
610 }
611 
612 void UI_block_bounds_set_menu(uiBlock *block, int addval, const int bounds_offset[2])
613 {
614  block->bounds = addval;
616  if (bounds_offset != nullptr) {
617  copy_v2_v2_int(block->bounds_offset, bounds_offset);
618  }
619  else {
620  zero_v2_int(block->bounds_offset);
621  }
622 }
623 
624 void UI_block_bounds_set_centered(uiBlock *block, int addval)
625 {
626  block->bounds = addval;
628 }
629 
630 void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy)
631 {
632  block->rect.xmin = minx;
633  block->rect.ymin = miny;
634  block->rect.xmax = maxx;
635  block->rect.ymax = maxy;
637 }
638 
640 {
641  if (but->type == UI_BTYPE_NUM) {
642  return ((uiButNumber *)but)->precision;
643  }
644 
645  return but->a2;
646 }
647 
649 {
650  if (but->type == UI_BTYPE_NUM) {
651  return ((uiButNumber *)but)->step_size;
652  }
653 
654  return but->a1;
655 }
656 
657 static bool ui_but_hide_fraction(uiBut *but, double value)
658 {
659  /* Hide the fraction if both the value and the step are exact integers. */
660  if (floor(value) == value) {
661  const float step = ui_but_get_float_step_size(but) * UI_PRECISION_FLOAT_SCALE;
662 
663  if (floorf(step) == step) {
664  /* Don't hide if it has any unit except frame count. */
665  switch (UI_but_unit_type_get(but)) {
666  case PROP_UNIT_NONE:
667  case PROP_UNIT_TIME:
668  return true;
669 
670  default:
671  return false;
672  }
673  }
674  }
675 
676  return false;
677 }
678 
679 static int ui_but_calc_float_precision(uiBut *but, double value)
680 {
681  if (ui_but_hide_fraction(but, value)) {
682  return 0;
683  }
684 
685  int prec = (int)ui_but_get_float_precision(but);
686 
687  /* first check for various special cases:
688  * * If button is radians, we want additional precision (see T39861).
689  * * If prec is not set, we fallback to a simple default */
690  if (ui_but_is_unit_radians(but) && prec < 5) {
691  prec = 5;
692  }
693  else if (prec == -1) {
694  prec = (but->hardmax < 10.001f) ? 3 : 2;
695  }
696  else {
697  CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
698  }
699 
700  return UI_calc_float_precision(prec, value);
701 }
702 
703 /* ************** BLOCK ENDING FUNCTION ************* */
704 
705 bool ui_but_rna_equals(const uiBut *a, const uiBut *b)
706 {
707  return ui_but_rna_equals_ex(a, &b->rnapoin, b->rnaprop, b->rnaindex);
708 }
709 
710 bool ui_but_rna_equals_ex(const uiBut *but,
711  const PointerRNA *ptr,
712  const PropertyRNA *prop,
713  int index)
714 {
715  if (but->rnapoin.data != ptr->data) {
716  return false;
717  }
718  if (but->rnaprop != prop || but->rnaindex != index) {
719  return false;
720  }
721 
722  return true;
723 }
724 
725 /* NOTE: if `but->poin` is allocated memory for every `uiDefBut*`, things fail. */
726 static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
727 {
728  if (but->identity_cmp_func) {
729  /* If the buttons have own identity comparator callbacks (and they match), use this to
730  * determine equality. */
731  if (but->identity_cmp_func && (but->type == oldbut->type) &&
732  (but->identity_cmp_func == oldbut->identity_cmp_func)) {
733  /* Test if the comparison is symmetrical (if a == b then b == a), may help catch some issues.
734  */
735  BLI_assert(but->identity_cmp_func(but, oldbut) == but->identity_cmp_func(oldbut, but));
736 
737  return but->identity_cmp_func(but, oldbut);
738  }
739  }
740 
741  /* various properties are being compared here, hopefully sufficient
742  * to catch all cases, but it is simple to add more checks later */
743  if (but->retval != oldbut->retval) {
744  return false;
745  }
746  if (!ui_but_rna_equals(but, oldbut)) {
747  return false;
748  }
749  if (but->func != oldbut->func) {
750  return false;
751  }
752  if (but->funcN != oldbut->funcN) {
753  return false;
754  }
755  if (!ELEM(oldbut->func_arg1, oldbut, but->func_arg1)) {
756  return false;
757  }
758  if (!ELEM(oldbut->func_arg2, oldbut, but->func_arg2)) {
759  return false;
760  }
761  if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) ||
762  (but->pointype != oldbut->pointype))) {
763  return false;
764  }
765  if (but->optype != oldbut->optype) {
766  return false;
767  }
768  if (but->dragtype != oldbut->dragtype) {
769  return false;
770  }
771 
772  if ((but->type == UI_BTYPE_VIEW_ITEM) && (oldbut->type == UI_BTYPE_VIEW_ITEM)) {
773  uiButViewItem *but_item = (uiButViewItem *)but;
774  uiButViewItem *oldbut_item = (uiButViewItem *)oldbut;
775  if (!but_item->view_item || !oldbut_item->view_item ||
776  !UI_view_item_matches(but_item->view_item, oldbut_item->view_item)) {
777  return false;
778  }
779  }
780 
781  return true;
782 }
783 
784 uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new)
785 {
786  LISTBASE_FOREACH (uiBut *, but, &block_old->buttons) {
787  if (ui_but_equals_old(but_new, but)) {
788  return but;
789  }
790  }
791  return nullptr;
792 }
793 
794 uiBut *ui_but_find_new(uiBlock *block_new, const uiBut *but_old)
795 {
796  LISTBASE_FOREACH (uiBut *, but, &block_new->buttons) {
797  if (ui_but_equals_old(but, but_old)) {
798  return but;
799  }
800  }
801  return nullptr;
802 }
803 
804 static bool ui_but_extra_icons_equals_old(const uiButExtraOpIcon *new_extra_icon,
805  const uiButExtraOpIcon *old_extra_icon)
806 {
807  return (new_extra_icon->optype_params->optype == old_extra_icon->optype_params->optype) &&
808  (new_extra_icon->icon == old_extra_icon->icon);
809 }
810 
812  const uiBut *old_but)
813 {
814  LISTBASE_FOREACH (uiButExtraOpIcon *, op_icon, &old_but->extra_op_icons) {
815  if (ui_but_extra_icons_equals_old(new_extra_icon, op_icon)) {
816  return op_icon;
817  }
818  }
819  return nullptr;
820 }
821 
822 static void ui_but_extra_icons_update_from_old_but(const uiBut *new_but, const uiBut *old_but)
823 {
824  /* Specifically for keeping some state info for the active button. */
825  BLI_assert(old_but->active);
826 
827  LISTBASE_FOREACH (uiButExtraOpIcon *, new_extra_icon, &new_but->extra_op_icons) {
828  uiButExtraOpIcon *old_extra_icon = ui_but_extra_icon_find_old(new_extra_icon, old_but);
829  /* Keep the highlighting state, and let handling update it later. */
830  if (old_extra_icon) {
831  new_extra_icon->highlighted = old_extra_icon->highlighted;
832  }
833  }
834 }
835 
847 {
848  BLI_assert(oldbut->active);
849 
850  /* flags from the buttons we want to refresh, may want to add more here... */
851  const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON | UI_SELECT_DRAW;
852  const int drawflag_copy = 0; /* None currently. */
853 
854  /* still stuff needs to be copied */
855  oldbut->rect = but->rect;
856  oldbut->context = but->context; /* set by Layout */
857 
858  /* drawing */
859  oldbut->icon = but->icon;
860  oldbut->iconadd = but->iconadd;
861  oldbut->alignnr = but->alignnr;
862 
863  /* typically the same pointers, but not on undo/redo */
864  /* XXX some menu buttons store button itself in but->poin. Ugly */
865  if (oldbut->poin != (char *)oldbut) {
866  SWAP(char *, oldbut->poin, but->poin);
867  SWAP(void *, oldbut->func_argN, but->func_argN);
868  }
869 
870  /* Move tooltip from new to old. */
871  SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func);
872  SWAP(void *, oldbut->tip_arg, but->tip_arg);
874 
875  oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy);
876  oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy);
877 
879  SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons);
880 
881  if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
882  uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
883 
884  SWAP(uiFreeArgFunc, search_oldbut->arg_free_fn, search_but->arg_free_fn);
885  SWAP(void *, search_oldbut->arg, search_but->arg);
886  }
887 
888  /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
889  * when scrolling without moving mouse (see T28432) */
890  if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
891  oldbut->hardmax = but->hardmax;
892  }
893 
894  switch (oldbut->type) {
895  case UI_BTYPE_PROGRESS_BAR: {
896  uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut;
897  uiButProgressbar *progress_but = (uiButProgressbar *)but;
898  progress_oldbut->progress = progress_but->progress;
899  break;
900  }
901  case UI_BTYPE_VIEW_ITEM: {
902  uiButViewItem *view_item_oldbut = (uiButViewItem *)oldbut;
903  uiButViewItem *view_item_newbut = (uiButViewItem *)but;
904  SWAP(uiViewItemHandle *, view_item_newbut->view_item, view_item_oldbut->view_item);
905  break;
906  }
907  default:
908  break;
909  }
910 
911  /* move/copy string from the new button to the old */
912  /* needed for alt+mouse wheel over enums */
913  if (but->str != but->strdata) {
914  if (oldbut->str != oldbut->strdata) {
915  SWAP(char *, but->str, oldbut->str);
916  }
917  else {
918  oldbut->str = but->str;
919  but->str = but->strdata;
920  }
921  }
922  else {
923  if (oldbut->str != oldbut->strdata) {
924  MEM_freeN(oldbut->str);
925  oldbut->str = oldbut->strdata;
926  }
927  BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata));
928  }
929 
930  if (but->dragpoin) {
931  SWAP(void *, but->dragpoin, oldbut->dragpoin);
932  }
933  if (but->imb) {
934  SWAP(ImBuf *, but->imb, oldbut->imb);
935  }
936 
937  /* NOTE: if layout hasn't been applied yet, it uses old button pointers... */
938 }
939 
944  uiBlock *block,
945  uiBut **but_p,
946  uiBut **but_old_p)
947 {
948  uiBlock *oldblock = block->oldblock;
949  uiBut *but = *but_p;
950 
951 #if 0
952  /* Simple method - search every time. Keep this for easy testing of the "fast path." */
953  uiBut *oldbut = ui_but_find_old(oldblock, but);
954  UNUSED_VARS(but_old_p);
955 #else
956  BLI_assert(*but_old_p == nullptr || BLI_findindex(&oldblock->buttons, *but_old_p) != -1);
957 
958  /* As long as old and new buttons are aligned, avoid loop-in-loop (calling #ui_but_find_old). */
959  uiBut *oldbut;
960  if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) {
961  oldbut = *but_old_p;
962  }
963  else {
964  /* Fallback to block search. */
965  oldbut = ui_but_find_old(oldblock, but);
966  }
967  (*but_old_p) = oldbut ? oldbut->next : nullptr;
968 #endif
969 
970  bool found_active = false;
971 
972  if (!oldbut) {
973  return false;
974  }
975 
976  if (oldbut->active) {
977  /* Move button over from oldblock to new block. */
978  BLI_remlink(&oldblock->buttons, oldbut);
979  BLI_insertlinkafter(&block->buttons, but, oldbut);
980  /* Add the old button to the button groups in the new block. */
981  ui_button_group_replace_but_ptr(block, but, oldbut);
982  oldbut->block = block;
983  *but_p = oldbut;
984 
986 
987  if (!BLI_listbase_is_empty(&block->butstore)) {
988  UI_butstore_register_update(block, oldbut, but);
989  }
990 
991  BLI_remlink(&block->buttons, but);
992  ui_but_free(C, but);
993 
994  found_active = true;
995  }
996  else {
997  int flag_copy = UI_BUT_DRAG_MULTI;
998 
999  /* Stupid special case: The active button may be inside (as in, overlapped on top) a view-item
1000  * button which we also want to keep highlighted then. */
1001  if (but->type == UI_BTYPE_VIEW_ITEM) {
1002  flag_copy |= UI_ACTIVE;
1003  }
1004 
1005  but->flag = (but->flag & ~flag_copy) | (oldbut->flag & flag_copy);
1006 
1007  /* ensures one button can get activated, and in case the buttons
1008  * draw are the same this gives O(1) lookup for each button */
1009  BLI_remlink(&oldblock->buttons, oldbut);
1010  ui_but_free(C, oldbut);
1011  }
1012 
1013  return found_active;
1014 }
1015 
1017  const bContext *C, ARegion *region, uiBlock *block, uiBut *but, const bool remove_on_failure)
1018 {
1019  bool activate = false, found = false, isactive = false;
1020 
1021  uiBlock *oldblock = block->oldblock;
1022  if (!oldblock) {
1023  activate = true;
1024  }
1025  else {
1026  uiBut *oldbut = ui_but_find_old(oldblock, but);
1027  if (oldbut) {
1028  found = true;
1029 
1030  if (oldbut->active) {
1031  isactive = true;
1032  }
1033  }
1034  }
1035  if ((activate == true) || (found == false)) {
1036  /* There might still be another active button. */
1037  uiBut *old_active = ui_region_find_active_but(region);
1038  if (old_active) {
1039  ui_but_active_free(C, old_active);
1040  }
1041 
1042  ui_but_activate_event((bContext *)C, region, but);
1043  }
1044  else if ((found == true) && (isactive == false)) {
1045  if (remove_on_failure) {
1046  BLI_remlink(&block->buttons, but);
1047  if (but->layout) {
1048  ui_layout_remove_but(but->layout, but);
1049  }
1050  ui_but_free(C, but);
1051  }
1052  return false;
1053  }
1054 
1055  return true;
1056 }
1057 
1058 bool UI_but_active_only(const bContext *C, ARegion *region, uiBlock *block, uiBut *but)
1059 {
1060  return UI_but_active_only_ex(C, region, block, but, true);
1061 }
1062 
1064 {
1065  /* Running this command before end-block has run, means buttons that open menus
1066  * won't have those menus correctly positioned, see T83539. */
1067  BLI_assert(block->endblock);
1068 
1069  bool done = false;
1070  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1071  if (but->flag & UI_BUT_ACTIVATE_ON_INIT) {
1072  but->flag &= ~UI_BUT_ACTIVATE_ON_INIT;
1073  if (ui_but_is_editable(but)) {
1074  if (UI_but_active_only_ex(C, region, block, but, false)) {
1075  done = true;
1076  break;
1077  }
1078  }
1079  }
1080  }
1081 
1082  if (done) {
1083  /* Run this in a second pass since it's possible activating the button
1084  * removes the buttons being looped over. */
1085  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1086  but->flag &= ~UI_BUT_ACTIVATE_ON_INIT;
1087  }
1088  }
1089 
1090  return done;
1091 }
1092 
1093 void UI_but_execute(const bContext *C, ARegion *region, uiBut *but)
1094 {
1095  void *active_back;
1096  ui_but_execute_begin((bContext *)C, region, but, &active_back);
1097  /* Value is applied in begin. No further action required. */
1098  ui_but_execute_end((bContext *)C, region, but, active_back);
1099 }
1100 
1101 /* use to check if we need to disable undo, but don't make any changes
1102  * returns false if undo needs to be disabled. */
1103 static bool ui_but_is_rna_undo(const uiBut *but)
1104 {
1105  if (but->rnapoin.owner_id) {
1106  /* avoid undo push for buttons who's ID are screen or wm level
1107  * we could disable undo for buttons with no ID too but may have
1108  * unforeseen consequences, so best check for ID's we _know_ are not
1109  * handled by undo - campbell */
1110  ID *id = but->rnapoin.owner_id;
1111  if (ID_CHECK_UNDO(id) == false) {
1112  return false;
1113  }
1114  }
1115  if (but->rnapoin.type && !RNA_struct_undo_check(but->rnapoin.type)) {
1116  return false;
1117  }
1118 
1119  return true;
1120 }
1121 
1122 /* assigns automatic keybindings to menu items for fast access
1123  * (underline key in menu) */
1125 {
1126  uint menu_key_mask = 0;
1127  int tot_missing = 0;
1128 
1129  /* only do it before bounding */
1130  if (block->rect.xmin != block->rect.xmax) {
1131  return;
1132  }
1133 
1134  for (int pass = 0; pass < 2; pass++) {
1135  /* 2 Passes: One for first letter only, second for any letter if the first pass fails.
1136  * Run first pass on all buttons so first word chars always get first priority. */
1137 
1138  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1139  if (!ELEM(but->type,
1140  UI_BTYPE_BUT,
1142  UI_BTYPE_MENU,
1145  /* For PIE-menus. */
1146  UI_BTYPE_ROW) ||
1147  (but->flag & UI_HIDDEN)) {
1148  continue;
1149  }
1150 
1151  if (but->menu_key != '\0') {
1152  continue;
1153  }
1154 
1155  if (but->str == nullptr || but->str[0] == '\0') {
1156  continue;
1157  }
1158 
1159  const char *str_pt = but->str;
1160  uchar menu_key;
1161  do {
1162  menu_key = tolower(*str_pt);
1163  if ((menu_key >= 'a' && menu_key <= 'z') && !(menu_key_mask & 1 << (menu_key - 'a'))) {
1164  menu_key_mask |= 1 << (menu_key - 'a');
1165  break;
1166  }
1167 
1168  if (pass == 0) {
1169  /* Skip to next delimiter on first pass (be picky) */
1170  while (isalpha(*str_pt)) {
1171  str_pt++;
1172  }
1173 
1174  if (*str_pt) {
1175  str_pt++;
1176  }
1177  }
1178  else {
1179  /* just step over every char second pass and find first usable key */
1180  str_pt++;
1181  }
1182  } while (*str_pt);
1183 
1184  if (*str_pt) {
1185  but->menu_key = menu_key;
1186  }
1187  else {
1188  /* run second pass */
1189  tot_missing++;
1190  }
1191 
1192  /* if all keys have been used just exit, unlikely */
1193  if (menu_key_mask == (1 << 26) - 1) {
1194  return;
1195  }
1196  }
1197 
1198  /* check if second pass is needed */
1199  if (!tot_missing) {
1200  break;
1201  }
1202  }
1203 }
1204 
1205 void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_strip)
1206 {
1207  if (do_strip && (but->flag & UI_BUT_HAS_SEP_CHAR)) {
1208  char *cpoin = strrchr(but->str, UI_SEP_CHAR);
1209  if (cpoin) {
1210  *cpoin = '\0';
1211  }
1212  but->flag &= ~UI_BUT_HAS_SEP_CHAR;
1213  }
1214 
1215  /* without this, just allow stripping of the shortcut */
1216  if (shortcut_str == nullptr) {
1217  return;
1218  }
1219 
1220  char *butstr_orig;
1221  if (but->str != but->strdata) {
1222  butstr_orig = but->str; /* free after using as source buffer */
1223  }
1224  else {
1225  butstr_orig = BLI_strdup(but->str);
1226  }
1227  BLI_snprintf(
1228  but->strdata, sizeof(but->strdata), "%s" UI_SEP_CHAR_S "%s", butstr_orig, shortcut_str);
1229  MEM_freeN(butstr_orig);
1230  but->str = but->strdata;
1231  but->flag |= UI_BUT_HAS_SEP_CHAR;
1232  ui_but_update(but);
1233 }
1234 
1235 /* -------------------------------------------------------------------- */
1243  wmOperatorCallParams *op_call_params,
1244  char *buf,
1245  const size_t buf_len)
1246 {
1247  BLI_assert(op_call_params->optype != nullptr);
1248  bool found = false;
1249  IDProperty *prop = reinterpret_cast<IDProperty *>(op_call_params->opptr) ?
1250  static_cast<IDProperty *>(op_call_params->opptr->data) :
1251  nullptr;
1252 
1254  op_call_params->optype->idname,
1255  op_call_params->opcontext,
1256  prop,
1257  true,
1258  buf,
1259  buf_len)) {
1260  found = true;
1261  }
1262  return found;
1263 }
1264 
1266  uiBut *but,
1267  char *buf,
1268  const size_t buf_len)
1269 {
1270  MenuType *mt = UI_but_menutype_get(but);
1271  BLI_assert(mt != nullptr);
1272 
1273  bool found = false;
1274 
1275  /* annoying, create a property */
1276  const IDPropertyTemplate val = {0};
1277  IDProperty *prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* Dummy, name is unimportant. */
1278  IDP_AddToGroup(prop_menu, IDP_NewString(mt->idname, "name", sizeof(mt->idname)));
1279 
1281  C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, true, buf, buf_len)) {
1282  found = true;
1283  }
1284 
1285  IDP_FreeProperty(prop_menu);
1286  return found;
1287 }
1288 
1290  uiBut *but,
1291  char *buf,
1292  const size_t buf_len)
1293 {
1295  PanelType *pt = UI_but_paneltype_get(but);
1296  BLI_assert(pt != nullptr);
1297 
1298  bool found = false;
1299 
1300  /* annoying, create a property */
1301  const IDPropertyTemplate group_val = {0};
1302  IDProperty *prop_panel = IDP_New(
1303  IDP_GROUP, &group_val, __func__); /* Dummy, name is unimportant. */
1304  IDP_AddToGroup(prop_panel, IDP_NewString(pt->idname, "name", sizeof(pt->idname)));
1305  IDPropertyTemplate space_type_val = {0};
1306  space_type_val.i = pt->space_type;
1307  IDP_AddToGroup(prop_panel, IDP_New(IDP_INT, &space_type_val, "space_type"));
1308  IDPropertyTemplate region_type_val = {0};
1309  region_type_val.i = pt->region_type;
1310  IDP_AddToGroup(prop_panel, IDP_New(IDP_INT, &region_type_val, "region_type"));
1311 
1312  for (int i = 0; i < 2; i++) {
1313  /* FIXME(campbell): We can't reasonably search all configurations - long term. */
1314  IDPropertyTemplate val = {0};
1315  val.i = i;
1316 
1317  IDP_ReplaceInGroup(prop_panel, IDP_New(IDP_INT, &val, "keep_open"));
1319  C, "WM_OT_call_panel", WM_OP_INVOKE_REGION_WIN, prop_panel, true, buf, buf_len)) {
1320  found = true;
1321  break;
1322  }
1323  }
1324 
1325  IDP_FreeProperty(prop_panel);
1326  return found;
1327 }
1328 
1330  uiBut *but,
1331  char *buf,
1332  const size_t buf_len)
1333 {
1334  bool found = false;
1335 
1336  if (but->optype != nullptr) {
1338  params.optype = but->optype;
1339  params.opptr = but->opptr;
1340  params.opcontext = but->opcontext;
1341  found = ui_but_event_operator_string_from_operator(C, &params, buf, buf_len);
1342  }
1343  else if (UI_but_menutype_get(but) != nullptr) {
1344  found = ui_but_event_operator_string_from_menu(C, but, buf, buf_len);
1345  }
1346  else if (UI_but_paneltype_get(but) != nullptr) {
1347  found = ui_but_event_operator_string_from_panel(C, but, buf, buf_len);
1348  }
1349 
1350  return found;
1351 }
1352 
1354  uiButExtraOpIcon *extra_icon,
1355  char *buf,
1356  const size_t buf_len)
1357 {
1358  wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon);
1359 
1360  if (extra_icon_optype) {
1361  return ui_but_event_operator_string_from_operator(C, extra_icon->optype_params, buf, buf_len);
1362  }
1363 
1364  return false;
1365 }
1366 
1368  uiBut *but,
1369  char *buf,
1370  const size_t buf_len)
1371 {
1372  /* Context toggle operator names to check. */
1373 
1374  /* This function could use a refactor to generalize button type to operator relationship
1375  * as well as which operators use properties. - Campbell */
1376  const char *ctx_toggle_opnames[] = {
1377  "WM_OT_context_toggle",
1378  "WM_OT_context_toggle_enum",
1379  "WM_OT_context_cycle_int",
1380  "WM_OT_context_cycle_enum",
1381  "WM_OT_context_cycle_array",
1382  "WM_OT_context_menu_enum",
1383  nullptr,
1384  };
1385 
1386  const char *ctx_enum_opnames[] = {
1387  "WM_OT_context_set_enum",
1388  nullptr,
1389  };
1390 
1391  const char *ctx_enum_opnames_for_Area_ui_type[] = {
1392  "SCREEN_OT_space_type_set_or_cycle",
1393  nullptr,
1394  };
1395 
1396  const char **opnames = ctx_toggle_opnames;
1397  int opnames_len = ARRAY_SIZE(ctx_toggle_opnames);
1398 
1399  int prop_enum_value = -1;
1400  bool prop_enum_value_ok = false;
1401  bool prop_enum_value_is_int = false;
1402  const char *prop_enum_value_id = "value";
1403  PointerRNA *ptr = &but->rnapoin;
1404  PropertyRNA *prop = but->rnaprop;
1405  int prop_index = but->rnaindex;
1406  if ((but->type == UI_BTYPE_BUT_MENU) && (but->block->handle != nullptr)) {
1407  uiBut *but_parent = but->block->handle->popup_create_vars.but;
1408  if ((but->type == UI_BTYPE_BUT_MENU) && (but_parent && but_parent->rnaprop) &&
1409  (RNA_property_type(but_parent->rnaprop) == PROP_ENUM) &&
1410  ELEM(but_parent->menu_create_func,
1414  prop_enum_value = (int)but->hardmin;
1415  ptr = &but_parent->rnapoin;
1416  prop = but_parent->rnaprop;
1417  prop_enum_value_ok = true;
1418 
1419  opnames = ctx_enum_opnames;
1420  opnames_len = ARRAY_SIZE(ctx_enum_opnames);
1421  }
1422  }
1423  /* Don't use the button again. */
1424  but = nullptr;
1425 
1426  if (prop == nullptr) {
1427  return false;
1428  }
1429 
1430  /* This version is only for finding hotkeys for properties.
1431  * These are set via a data-path which is appended to the context,
1432  * manipulated using operators (see #ctx_toggle_opnames). */
1433 
1434  if (ptr->owner_id) {
1435  ID *id = ptr->owner_id;
1436 
1437  if (GS(id->name) == ID_SCR) {
1438  if (RNA_struct_is_a(ptr->type, &RNA_Area)) {
1439  /* data should be directly on here... */
1440  const char *prop_id = RNA_property_identifier(prop);
1441  /* Hack since keys access 'type', UI shows 'ui_type'. */
1442  if (STREQ(prop_id, "ui_type")) {
1443  prop_id = "type";
1444  prop_enum_value >>= 16;
1445  prop = RNA_struct_find_property(ptr, prop_id);
1446  prop_index = -1;
1447 
1448  opnames = ctx_enum_opnames_for_Area_ui_type;
1449  opnames_len = ARRAY_SIZE(ctx_enum_opnames_for_Area_ui_type);
1450  prop_enum_value_id = "space_type";
1451  prop_enum_value_is_int = true;
1452  }
1453  }
1454  }
1455  }
1456 
1457  char *data_path = WM_context_path_resolve_property_full(C, ptr, prop, prop_index);
1458 
1459  /* We have a data-path! */
1460  bool found = false;
1461  if (data_path || (prop_enum_value_ok && prop_enum_value_id)) {
1462  /* Create a property to host the "data_path" property we're sending to the operators. */
1463  IDProperty *prop_path;
1464 
1465  const IDPropertyTemplate group_val = {0};
1466  prop_path = IDP_New(IDP_GROUP, &group_val, __func__);
1467  if (data_path) {
1468  IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path", strlen(data_path) + 1));
1469  }
1470  if (prop_enum_value_ok) {
1471  const EnumPropertyItem *item;
1472  bool free;
1473  RNA_property_enum_items((bContext *)C, ptr, prop, &item, nullptr, &free);
1474  const int index = RNA_enum_from_value(item, prop_enum_value);
1475  if (index != -1) {
1476  IDProperty *prop_value;
1477  if (prop_enum_value_is_int) {
1478  const int value = item[index].value;
1479  IDPropertyTemplate val = {};
1480  val.i = value;
1481  prop_value = IDP_New(IDP_INT, &val, prop_enum_value_id);
1482  }
1483  else {
1484  const char *id = item[index].identifier;
1485  prop_value = IDP_NewString(id, prop_enum_value_id, strlen(id) + 1);
1486  }
1487  IDP_AddToGroup(prop_path, prop_value);
1488  }
1489  else {
1490  opnames_len = 0; /* Do nothing. */
1491  }
1492  if (free) {
1493  MEM_freeN((void *)item);
1494  }
1495  }
1496 
1497  /* check each until one works... */
1498 
1499  for (int i = 0; (i < opnames_len) && (opnames[i]); i++) {
1501  C, opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false, buf, buf_len)) {
1502  found = true;
1503  break;
1504  }
1505  }
1506 
1507  /* cleanup */
1508  IDP_FreeProperty(prop_path);
1509  if (data_path) {
1510  MEM_freeN(data_path);
1511  }
1512  }
1513 
1514  return found;
1515 }
1516 
1544 const char ui_radial_dir_order[8] = {
1545  UI_RADIAL_W,
1546  UI_RADIAL_E,
1547  UI_RADIAL_S,
1548  UI_RADIAL_N,
1549  UI_RADIAL_NW,
1550  UI_RADIAL_NE,
1551  UI_RADIAL_SW,
1552  UI_RADIAL_SE,
1553 };
1554 
1555 const char ui_radial_dir_to_numpad[8] = {8, 9, 6, 3, 2, 1, 4, 7};
1556 const short ui_radial_dir_to_angle[8] = {90, 45, 0, 315, 270, 225, 180, 135};
1557 
1558 static void ui_but_pie_direction_string(uiBut *but, char *buf, int size)
1559 {
1561  BLI_snprintf(buf, size, "%d", ui_radial_dir_to_numpad[but->pie_dir]);
1562 }
1563 
1564 static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
1565 {
1566  char buf[128];
1567 
1569 
1570  /* only do it before bounding */
1571  if (block->rect.xmin != block->rect.xmax) {
1572  return;
1573  }
1574  if (STREQ(block->name, "splash")) {
1575  return;
1576  }
1577 
1578  if (block->flag & UI_BLOCK_RADIAL) {
1579  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1580  if (but->pie_dir != UI_RADIAL_NONE) {
1581  ui_but_pie_direction_string(but, buf, sizeof(buf));
1582  ui_but_add_shortcut(but, buf, false);
1583  }
1584  }
1585  }
1586  else {
1587  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1588  if (block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) {
1589  /* Skip icon-only buttons (as used in the toolbar). */
1590  if (but->drawstr[0] == '\0') {
1591  continue;
1592  }
1593  if (((block->flag & UI_BLOCK_POPOVER) == 0) && UI_but_is_tool(but)) {
1594  /* For non-popovers, shown in shortcut only
1595  * (has special shortcut handling code). */
1596  continue;
1597  }
1598  }
1599  else if (but->emboss != UI_EMBOSS_PULLDOWN) {
1600  continue;
1601  }
1602 
1603  if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
1604  ui_but_add_shortcut(but, buf, false);
1605  }
1606  else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) {
1607  ui_but_add_shortcut(but, buf, false);
1608  }
1609  }
1610  }
1611 }
1612 
1613 void ui_but_override_flag(Main *bmain, uiBut *but)
1614 {
1615  const uint override_status = RNA_property_override_library_status(
1616  bmain, &but->rnapoin, but->rnaprop, but->rnaindex);
1617 
1618  if (override_status & RNA_OVERRIDE_STATUS_OVERRIDDEN) {
1619  but->flag |= UI_BUT_OVERRIDDEN;
1620  }
1621  else {
1622  but->flag &= ~UI_BUT_OVERRIDDEN;
1623  }
1624 }
1625 
1626 /* -------------------------------------------------------------------- */
1642 };
1643 
1645  wmOperatorType *optype,
1646  wmOperatorCallContext opcontext,
1647  int icon)
1648 {
1649  uiButExtraOpIcon *extra_op_icon = MEM_new<uiButExtraOpIcon>(__func__);
1650 
1651  extra_op_icon->icon = (BIFIconID)icon;
1652  extra_op_icon->optype_params = MEM_cnew<wmOperatorCallParams>(__func__);
1653  extra_op_icon->optype_params->optype = optype;
1654  extra_op_icon->optype_params->opptr = MEM_cnew<PointerRNA>(__func__);
1656  extra_op_icon->optype_params->optype);
1657  extra_op_icon->optype_params->opcontext = opcontext;
1658  extra_op_icon->highlighted = false;
1659  extra_op_icon->disabled = false;
1660 
1661  BLI_addtail(&but->extra_op_icons, extra_op_icon);
1662 
1663  return extra_op_icon->optype_params->opptr;
1664 }
1665 
1667 {
1669  MEM_freeN(extra_icon->optype_params->opptr);
1670  MEM_freeN(extra_icon->optype_params);
1671  MEM_freeN(extra_icon);
1672 }
1673 
1675 {
1678  }
1680 }
1681 
1683  const char *opname,
1684  wmOperatorCallContext opcontext,
1685  int icon)
1686 {
1687  wmOperatorType *optype = WM_operatortype_find(opname, false);
1688 
1689  if (optype) {
1690  return ui_but_extra_operator_icon_add_ptr(but, optype, opcontext, icon);
1691  }
1692 
1693  return nullptr;
1694 }
1695 
1697 {
1698  return extra_icon ? extra_icon->optype_params->optype : nullptr;
1699 }
1700 
1702 {
1703  return extra_icon->optype_params->opptr;
1704 }
1705 
1707 {
1708  BLI_assert(but->type == UI_BTYPE_TEXT);
1709  return ((but->flag & UI_BUT_VALUE_CLEAR) && but->drawstr[0]);
1710 }
1711 
1713 {
1715  return ((but->editstr == nullptr) && (but->drawstr[0] != '\0') &&
1716  (but->flag & UI_BUT_VALUE_CLEAR));
1717 }
1718 
1720 {
1722 
1723  if (but->rnaprop == nullptr) {
1724  return false;
1725  }
1726 
1728  const short idcode = RNA_type_to_ID_code(type);
1729 
1730  return ((but->editstr == nullptr) && (idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode)));
1731 }
1732 
1734 {
1735  switch (but->type) {
1736  case UI_BTYPE_TEXT:
1739  }
1740  break;
1741  case UI_BTYPE_SEARCH_MENU:
1742  if ((but->flag & UI_BUT_VALUE_CLEAR) == 0) {
1743  /* pass */
1744  }
1747  }
1750  }
1751  break;
1752  default:
1753  break;
1754  }
1755 
1757 }
1758 
1765 {
1766  const PredefinedExtraOpIconType extra_icon = ui_but_icon_extra_get(but);
1767  wmOperatorType *optype = nullptr;
1768  BIFIconID icon = ICON_NONE;
1769 
1770  switch (extra_icon) {
1772  static wmOperatorType *id_eyedropper_ot = nullptr;
1773  if (!id_eyedropper_ot) {
1774  id_eyedropper_ot = WM_operatortype_find("UI_OT_eyedropper_id", false);
1775  }
1776  BLI_assert(id_eyedropper_ot);
1777 
1778  optype = id_eyedropper_ot;
1779  icon = ICON_EYEDROPPER;
1780 
1781  break;
1782  }
1784  static wmOperatorType *clear_ot = nullptr;
1785  if (!clear_ot) {
1786  clear_ot = WM_operatortype_find("UI_OT_button_string_clear", false);
1787  }
1788  BLI_assert(clear_ot);
1789 
1790  optype = clear_ot;
1791  icon = ICON_PANEL_CLOSE;
1792 
1793  break;
1794  }
1795  default:
1796  break;
1797  }
1798 
1799  if (optype) {
1800  LISTBASE_FOREACH (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
1801  if ((op_icon->optype_params->optype == optype) && (op_icon->icon == icon)) {
1802  /* Don't add the same operator icon twice (happens if button is kept alive while active).
1803  */
1804  return;
1805  }
1806  }
1808  }
1809 }
1810 
1814 {
1815  if (!block->oldblock) {
1816  return;
1817  }
1818 
1819  uiBut *but_old = static_cast<uiBut *>(block->oldblock->buttons.first);
1820 
1821  if (BLI_listbase_is_empty(&block->oldblock->butstore) == false) {
1822  UI_butstore_update(block);
1823  }
1824 
1825  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1826  if (ui_but_update_from_old_block(C, block, &but, &but_old)) {
1827  ui_but_update(but);
1828 
1829  /* redraw dynamic tooltip if we have one open */
1830  if (but->tip_func) {
1832  }
1833  }
1834  }
1835 
1836  block->auto_open = block->oldblock->auto_open;
1837  block->auto_open_last = block->oldblock->auto_open_last;
1838  block->tooltipdisabled = block->oldblock->tooltipdisabled;
1840 
1841  block->oldblock = nullptr;
1842 }
1843 
1844 #ifndef NDEBUG
1848 static void ui_but_validate(const uiBut *but)
1849 {
1850  /* Number buttons must have a click-step,
1851  * assert instead of correcting the value to ensure the caller knows what they're doing. */
1852  if (but->type == UI_BTYPE_NUM) {
1853  uiButNumber *number_but = (uiButNumber *)but;
1854 
1856  BLI_assert((int)number_but->step_size > 0);
1857  }
1858  }
1859 }
1860 #endif
1861 
1863  const uiBut *but,
1864  const wmOperatorCallParams *optype_params)
1865 {
1866  bool result;
1867  int old_but_flag = 0;
1868 
1869  if (but) {
1870  old_but_flag = but->flag;
1871 
1872  /* Temporarily make this button override the active one, in case the poll acts on the active
1873  * button. */
1874  const_cast<uiBut *>(but)->flag |= UI_BUT_ACTIVE_OVERRIDE;
1875 
1876  if (but->context) {
1877  CTX_store_set(C, but->context);
1878  }
1879  }
1880 
1881  result = WM_operator_poll_context(C, optype_params->optype, optype_params->opcontext);
1882 
1883  if (but) {
1885  (old_but_flag & ~UI_BUT_ACTIVE_OVERRIDE),
1886  "Operator polls shouldn't change button flags");
1887 
1888  const_cast<uiBut *>(but)->flag = old_but_flag;
1889 
1890  if (but->context) {
1891  CTX_store_set(C, nullptr);
1892  }
1893  }
1894 
1895  return result;
1896 }
1897 
1899 {
1900  const wmOperatorCallContext opcontext = but ? but->opcontext : WM_OP_INVOKE_DEFAULT;
1902  params.optype = ot;
1903  params.opcontext = opcontext;
1904  return ui_but_context_poll_operator_ex(C, but, &params);
1905 }
1906 
1907 void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
1908 {
1909  wmWindow *window = CTX_wm_window(C);
1911  ARegion *region = CTX_wm_region(C);
1913 
1914  BLI_assert(block->active);
1915 
1916  /* Extend button data. This needs to be done before the block updating. */
1917  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1919  }
1920 
1921  UI_block_update_from_old(C, block);
1922 
1923  /* inherit flags from 'old' buttons that was drawn here previous, based
1924  * on matching buttons, we need this to make button event handling non
1925  * blocking, while still allowing buttons to be remade each redraw as it
1926  * is expected by blender code */
1927  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
1928  /* temp? Proper check for graying out */
1929  if (but->optype) {
1930  wmOperatorType *ot = but->optype;
1931 
1932  if (ot == nullptr || !ui_but_context_poll_operator((bContext *)C, ot, but)) {
1933  but->flag |= UI_BUT_DISABLED;
1934  }
1935  }
1936 
1937  LISTBASE_FOREACH (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
1938  if (!ui_but_context_poll_operator_ex((bContext *)C, but, op_icon->optype_params)) {
1939  op_icon->disabled = true;
1940  }
1941  }
1942 
1943  const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
1944  depsgraph, (scene) ? scene->r.cfra : 0.0f);
1945  ui_but_anim_flag(but, &anim_eval_context);
1947  if (UI_but_is_decorator(but)) {
1949  }
1950 
1951 #ifndef NDEBUG
1952  ui_but_validate(but);
1953 #endif
1954  }
1955 
1956  /* handle pending stuff */
1957  if (block->layouts.first) {
1958  UI_block_layout_resolve(block, nullptr, nullptr);
1959  }
1961  if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) {
1962  ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
1963  }
1964 
1966  ui_menu_block_set_keymaps(C, block);
1967  }
1968 
1969  /* after keymaps! */
1970  switch (block->bounds_type) {
1971  case UI_BLOCK_BOUNDS_NONE:
1972  break;
1973  case UI_BLOCK_BOUNDS:
1974  ui_block_bounds_calc(block);
1975  break;
1976  case UI_BLOCK_BOUNDS_TEXT:
1977  ui_block_bounds_calc_text(block, 0.0f);
1978  break;
1980  ui_block_bounds_calc_centered(window, block);
1981  break;
1984  break;
1985 
1986  /* fallback */
1989  ui_block_bounds_calc_popup(window, block, block->bounds_type, xy, r_xy);
1990  break;
1991  }
1992 
1993  if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
1994  UI_block_bounds_set_normal(block, 0);
1995  }
1996  if (block->flag & UI_BUT_ALIGN) {
1997  UI_block_align_end(block);
1998  }
1999 
2000  ui_update_flexible_spacing(region, block);
2001 
2002  block->endblock = true;
2003 }
2004 
2005 void UI_block_end(const bContext *C, uiBlock *block)
2006 {
2007  wmWindow *window = CTX_wm_window(C);
2008 
2009  UI_block_end_ex(C, block, window->eventstate->xy, nullptr);
2010 }
2011 
2012 /* ************** BLOCK DRAWING FUNCTION ************* */
2013 
2014 void ui_fontscale(float *points, float aspect)
2015 {
2016  *points /= aspect;
2017 }
2018 
2019 /* Project button or block (but==nullptr) to pixels in region-space. */
2020 static void ui_but_to_pixelrect(rcti *rect,
2021  const ARegion *region,
2022  uiBlock *block,
2023  const uiBut *but)
2024 {
2025  rctf rectf;
2026 
2027  ui_block_to_window_rctf(region, block, &rectf, (but) ? &but->rect : &block->rect);
2028  BLI_rcti_rctf_copy_round(rect, &rectf);
2029  BLI_rcti_translate(rect, -region->winrct.xmin, -region->winrct.ymin);
2030 }
2031 
2032 static bool ui_but_pixelrect_in_view(const ARegion *region, const rcti *rect)
2033 {
2034  rcti rect_winspace = *rect;
2035  BLI_rcti_translate(&rect_winspace, region->winrct.xmin, region->winrct.ymin);
2036  return BLI_rcti_isect(&region->winrct, &rect_winspace, nullptr);
2037 }
2038 
2039 void UI_block_draw(const bContext *C, uiBlock *block)
2040 {
2041  uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */
2042 
2043  /* get menu region or area region */
2044  ARegion *region = CTX_wm_menu(C);
2045  if (!region) {
2046  region = CTX_wm_region(C);
2047  }
2048 
2049  if (!block->endblock) {
2050  UI_block_end(C, block);
2051  }
2052 
2053  /* we set this only once */
2055 
2056  /* scale fonts */
2057  ui_fontscale(&style.paneltitle.points, block->aspect);
2058  ui_fontscale(&style.grouplabel.points, block->aspect);
2059  ui_fontscale(&style.widgetlabel.points, block->aspect);
2060  ui_fontscale(&style.widget.points, block->aspect);
2061 
2062  /* scale block min/max to rect */
2063  rcti rect;
2064  ui_but_to_pixelrect(&rect, region, block, nullptr);
2065 
2066  /* pixel space for AA widgets */
2068  GPU_matrix_push();
2070 
2072 
2073  /* back */
2074  if (block->flag & UI_BLOCK_RADIAL) {
2075  ui_draw_pie_center(block);
2076  }
2077  else if (block->flag & UI_BLOCK_POPOVER) {
2078  ui_draw_popover_back(region, &style, block, &rect);
2079  }
2080  else if (block->flag & UI_BLOCK_LOOP) {
2081  ui_draw_menu_back(&style, block, &rect);
2082  }
2083  else if (block->panel) {
2084  ui_draw_aligned_panel(&style,
2085  block,
2086  &rect,
2088  UI_panel_should_show_background(region, block->panel->type),
2090  }
2091 
2095 
2096  /* widgets */
2097  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
2098  if (but->flag & (UI_HIDDEN | UI_SCROLLED)) {
2099  continue;
2100  }
2101 
2102  ui_but_to_pixelrect(&rect, region, block, but);
2103  /* Optimization: Don't draw buttons that are not visible (outside view bounds). */
2104  if (!ui_but_pixelrect_in_view(region, &rect)) {
2105  continue;
2106  }
2107 
2108  /* XXX: figure out why invalid coordinates happen when closing render window */
2109  /* and material preview is redrawn in main window (temp fix for bug T23848) */
2110  if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) {
2111  ui_draw_but(C, region, &style, but, &rect);
2112  }
2113  }
2114 
2118 
2119  /* restore matrix */
2121  GPU_matrix_pop();
2122 }
2123 
2124 static void ui_block_message_subscribe(ARegion *region, struct wmMsgBus *mbus, uiBlock *block)
2125 {
2126  uiBut *but_prev = nullptr;
2127  /* possibly we should keep the region this block is contained in? */
2128  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
2129  if (but->rnapoin.type && but->rnaprop) {
2130  /* quick check to avoid adding buttons representing a vector, multiple times. */
2131  if ((but_prev && (but_prev->rnaprop == but->rnaprop) &&
2132  (but_prev->rnapoin.type == but->rnapoin.type) &&
2133  (but_prev->rnapoin.data == but->rnapoin.data) &&
2134  (but_prev->rnapoin.owner_id == but->rnapoin.owner_id)) == false) {
2135  /* TODO: could make this into utility function. */
2136  wmMsgSubscribeValue value = {};
2137  value.owner = region;
2138  value.user_data = region;
2140  WM_msg_subscribe_rna(mbus, &but->rnapoin, but->rnaprop, &value, __func__);
2141  but_prev = but;
2142  }
2143  }
2144  }
2145 }
2146 
2147 void UI_region_message_subscribe(ARegion *region, struct wmMsgBus *mbus)
2148 {
2149  LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
2150  ui_block_message_subscribe(region, mbus, block);
2151  }
2152 }
2153 
2154 /* ************* EVENTS ************* */
2155 
2156 int ui_but_is_pushed_ex(uiBut *but, double *value)
2157 {
2158  int is_push = 0;
2159  if (but->pushed_state_func) {
2160  return but->pushed_state_func(but, but->pushed_state_arg);
2161  }
2162 
2163  if (but->bit) {
2164  const bool state = !ELEM(
2166  int lvalue;
2167  UI_GET_BUT_VALUE_INIT(but, *value);
2168  lvalue = (int)*value;
2169  if (UI_BITBUT_TEST(lvalue, (but->bitnr))) {
2170  is_push = state;
2171  }
2172  else {
2173  is_push = !state;
2174  }
2175  }
2176  else {
2177  switch (but->type) {
2178  case UI_BTYPE_BUT:
2179  case UI_BTYPE_HOTKEY_EVENT:
2180  case UI_BTYPE_KEY_EVENT:
2181  case UI_BTYPE_COLOR:
2182  case UI_BTYPE_DECORATOR:
2183  is_push = -1;
2184  break;
2185  case UI_BTYPE_BUT_TOGGLE:
2186  case UI_BTYPE_TOGGLE:
2187  case UI_BTYPE_ICON_TOGGLE:
2188  case UI_BTYPE_CHECKBOX:
2189  UI_GET_BUT_VALUE_INIT(but, *value);
2190  if (*value != (double)but->hardmin) {
2191  is_push = true;
2192  }
2193  break;
2195  case UI_BTYPE_TOGGLE_N:
2196  case UI_BTYPE_CHECKBOX_N:
2197  UI_GET_BUT_VALUE_INIT(but, *value);
2198  if (*value == 0.0) {
2199  is_push = true;
2200  }
2201  break;
2202  case UI_BTYPE_ROW:
2203  case UI_BTYPE_LISTROW:
2204  case UI_BTYPE_TAB:
2205  if ((but->type == UI_BTYPE_TAB) && but->rnaprop && but->custom_data) {
2206  /* uiBut.custom_data points to data this tab represents (e.g. workspace).
2207  * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
2208  if (RNA_property_type(but->rnaprop) == PROP_POINTER) {
2209  const PointerRNA active_ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop);
2210  if (active_ptr.data == but->custom_data) {
2211  is_push = true;
2212  }
2213  }
2214  break;
2215  }
2216  else if (but->optype) {
2217  break;
2218  }
2219 
2220  UI_GET_BUT_VALUE_INIT(but, *value);
2221  /* support for rna enum buts */
2222  if (but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
2223  if ((int)*value & (int)but->hardmax) {
2224  is_push = true;
2225  }
2226  }
2227  else {
2228  if (*value == (double)but->hardmax) {
2229  is_push = true;
2230  }
2231  }
2232  break;
2233  case UI_BTYPE_VIEW_ITEM: {
2234  const uiButViewItem *view_item_but = (const uiButViewItem *)but;
2235 
2236  is_push = -1;
2237  if (view_item_but->view_item) {
2238  is_push = UI_view_item_is_active(view_item_but->view_item);
2239  }
2240  break;
2241  }
2242  default:
2243  is_push = -1;
2244  break;
2245  }
2246  }
2247 
2248  if ((but->drawflag & UI_BUT_CHECKBOX_INVERT) && (is_push != -1)) {
2249  is_push = !((bool)is_push);
2250  }
2251  return is_push;
2252 }
2254 {
2255  double value = UI_BUT_VALUE_UNSET;
2256  return ui_but_is_pushed_ex(but, &value);
2257 }
2258 
2259 static void ui_but_update_select_flag(uiBut *but, double *value)
2260 {
2261  switch (ui_but_is_pushed_ex(but, value)) {
2262  case true:
2263  but->flag |= UI_SELECT;
2264  break;
2265  case false:
2266  but->flag &= ~UI_SELECT;
2267  break;
2268  }
2269 }
2270 
2271 /* ************************************************ */
2272 
2273 void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
2274 {
2275  if (val) {
2276  block->lock = val;
2277  block->lockstr = lockstr;
2278  }
2279 }
2280 
2282 {
2283  block->lock = false;
2284  block->lockstr = nullptr;
2285 }
2286 
2287 /* *********************** data get/set ***********************
2288  * this either works with the pointed to data, or can work with
2289  * an edit override pointer while dragging for example */
2290 
2291 void ui_but_v3_get(uiBut *but, float vec[3])
2292 {
2293  if (but->editvec) {
2294  copy_v3_v3(vec, but->editvec);
2295  }
2296 
2297  if (but->rnaprop) {
2298  PropertyRNA *prop = but->rnaprop;
2299 
2300  zero_v3(vec);
2301 
2302  if (RNA_property_type(prop) == PROP_FLOAT) {
2303  int tot = RNA_property_array_length(&but->rnapoin, prop);
2304  BLI_assert(tot > 0);
2305  if (tot == 3) {
2306  RNA_property_float_get_array(&but->rnapoin, prop, vec);
2307  }
2308  else {
2309  tot = min_ii(tot, 3);
2310  for (int a = 0; a < tot; a++) {
2311  vec[a] = RNA_property_float_get_index(&but->rnapoin, prop, a);
2312  }
2313  }
2314  }
2315  }
2316  else if (but->pointype == UI_BUT_POIN_CHAR) {
2317  const char *cp = (char *)but->poin;
2318  vec[0] = ((float)cp[0]) / 255.0f;
2319  vec[1] = ((float)cp[1]) / 255.0f;
2320  vec[2] = ((float)cp[2]) / 255.0f;
2321  }
2322  else if (but->pointype == UI_BUT_POIN_FLOAT) {
2323  const float *fp = (float *)but->poin;
2324  copy_v3_v3(vec, fp);
2325  }
2326  else {
2327  if (but->editvec == nullptr) {
2328  fprintf(stderr, "%s: can't get color, should never happen\n", __func__);
2329  zero_v3(vec);
2330  }
2331  }
2332 
2333  if (but->type == UI_BTYPE_UNITVEC) {
2334  normalize_v3(vec);
2335  }
2336 }
2337 
2338 void ui_but_v3_set(uiBut *but, const float vec[3])
2339 {
2340  if (but->editvec) {
2341  copy_v3_v3(but->editvec, vec);
2342  }
2343 
2344  if (but->rnaprop) {
2345  PropertyRNA *prop = but->rnaprop;
2346 
2347  if (RNA_property_type(prop) == PROP_FLOAT) {
2348  int tot;
2349  int a;
2350 
2351  tot = RNA_property_array_length(&but->rnapoin, prop);
2352  BLI_assert(tot > 0);
2353  if (tot == 3) {
2354  RNA_property_float_set_array(&but->rnapoin, prop, vec);
2355  }
2356  else {
2357  tot = min_ii(tot, 3);
2358  for (a = 0; a < tot; a++) {
2359  RNA_property_float_set_index(&but->rnapoin, prop, a, vec[a]);
2360  }
2361  }
2362  }
2363  }
2364  else if (but->pointype == UI_BUT_POIN_CHAR) {
2365  char *cp = (char *)but->poin;
2366  cp[0] = (char)(0.5f + vec[0] * 255.0f);
2367  cp[1] = (char)(0.5f + vec[1] * 255.0f);
2368  cp[2] = (char)(0.5f + vec[2] * 255.0f);
2369  }
2370  else if (but->pointype == UI_BUT_POIN_FLOAT) {
2371  float *fp = (float *)but->poin;
2372  copy_v3_v3(fp, vec);
2373  }
2374 }
2375 
2376 bool ui_but_is_float(const uiBut *but)
2377 {
2378  if (but->pointype == UI_BUT_POIN_FLOAT && but->poin) {
2379  return true;
2380  }
2381 
2382  if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_FLOAT) {
2383  return true;
2384  }
2385 
2386  return false;
2387 }
2388 
2390 {
2391  if (but->rnaprop) {
2392  return RNA_property_ui_scale(but->rnaprop);
2393  }
2394  return PROP_SCALE_LINEAR;
2395 }
2396 
2397 bool ui_but_is_bool(const uiBut *but)
2398 {
2399  if (ELEM(but->type,
2404  UI_BTYPE_TAB)) {
2405  return true;
2406  }
2407 
2408  if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_BOOLEAN) {
2409  return true;
2410  }
2411 
2412  if ((but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) &&
2413  (but->type == UI_BTYPE_ROW)) {
2414  return true;
2415  }
2416 
2417  return false;
2418 }
2419 
2420 bool ui_but_is_unit(const uiBut *but)
2421 {
2422  UnitSettings *unit = but->block->unit;
2423  const int unit_type = UI_but_unit_type_get(but);
2424 
2425  if (unit_type == PROP_UNIT_NONE) {
2426  return false;
2427  }
2428 
2429 #if 1 /* removed so angle buttons get correct snapping */
2430  if (ui_but_is_unit_radians_ex(unit, unit_type)) {
2431  return false;
2432  }
2433 #endif
2434 
2435  /* for now disable time unit conversion */
2436  if (unit_type == PROP_UNIT_TIME) {
2437  return false;
2438  }
2439 
2440  if (unit->system == USER_UNIT_NONE) {
2441  if (unit_type != PROP_UNIT_ROTATION) {
2442  return false;
2443  }
2444  }
2445 
2446  return true;
2447 }
2448 
2449 bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b)
2450 {
2451  if (but_a->type != but_b->type) {
2452  return false;
2453  }
2454  if (but_a->pointype != but_b->pointype) {
2455  return false;
2456  }
2457 
2458  if (but_a->rnaprop) {
2459  /* skip 'rnapoin.data', 'rnapoin.owner_id'
2460  * allow different data to have the same props edited at once */
2461  if (but_a->rnapoin.type != but_b->rnapoin.type) {
2462  return false;
2463  }
2464  if (RNA_property_type(but_a->rnaprop) != RNA_property_type(but_b->rnaprop)) {
2465  return false;
2466  }
2467  if (RNA_property_subtype(but_a->rnaprop) != RNA_property_subtype(but_b->rnaprop)) {
2468  return false;
2469  }
2470  }
2471 
2472  return true;
2473 }
2474 
2476 {
2477  if (but->rnaprop == nullptr || RNA_struct_contains_property(&but->rnapoin, but->rnaprop)) {
2478  return true;
2479  }
2480  printf("property removed %s: %p\n", but->drawstr, but->rnaprop);
2481  return false;
2482 }
2483 
2485 {
2487  (but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) ||
2488  (but->type == UI_BTYPE_COLOR && ((uiButColor *)but)->is_pallete_color) ||
2489  (but->menu_step_func != nullptr));
2490 }
2491 
2493 {
2494  double value = 0.0;
2495 
2496  if (but->editval) {
2497  return *(but->editval);
2498  }
2499  if (but->poin == nullptr && but->rnapoin.data == nullptr) {
2500  return 0.0;
2501  }
2502 
2503  if (but->rnaprop) {
2504  PropertyRNA *prop = but->rnaprop;
2505 
2506  BLI_assert(but->rnaindex != -1);
2507 
2508  switch (RNA_property_type(prop)) {
2509  case PROP_BOOLEAN:
2510  if (RNA_property_array_check(prop)) {
2511  value = RNA_property_boolean_get_index(&but->rnapoin, prop, but->rnaindex);
2512  }
2513  else {
2514  value = RNA_property_boolean_get(&but->rnapoin, prop);
2515  }
2516  break;
2517  case PROP_INT:
2518  if (RNA_property_array_check(prop)) {
2519  value = RNA_property_int_get_index(&but->rnapoin, prop, but->rnaindex);
2520  }
2521  else {
2522  value = RNA_property_int_get(&but->rnapoin, prop);
2523  }
2524  break;
2525  case PROP_FLOAT:
2526  if (RNA_property_array_check(prop)) {
2527  value = RNA_property_float_get_index(&but->rnapoin, prop, but->rnaindex);
2528  }
2529  else {
2530  value = RNA_property_float_get(&but->rnapoin, prop);
2531  }
2532  break;
2533  case PROP_ENUM:
2534  value = RNA_property_enum_get(&but->rnapoin, prop);
2535  break;
2536  default:
2537  value = 0.0;
2538  break;
2539  }
2540  }
2541  else if (but->pointype == UI_BUT_POIN_CHAR) {
2542  value = *(char *)but->poin;
2543  }
2544  else if (but->pointype == UI_BUT_POIN_SHORT) {
2545  value = *(short *)but->poin;
2546  }
2547  else if (but->pointype == UI_BUT_POIN_INT) {
2548  value = *(int *)but->poin;
2549  }
2550  else if (but->pointype == UI_BUT_POIN_FLOAT) {
2551  value = *(float *)but->poin;
2552  }
2553 
2554  return value;
2555 }
2556 
2557 void ui_but_value_set(uiBut *but, double value)
2558 {
2559  /* Value is a HSV value: convert to RGB. */
2560  if (but->rnaprop) {
2561  PropertyRNA *prop = but->rnaprop;
2562 
2563  if (RNA_property_editable(&but->rnapoin, prop)) {
2564  switch (RNA_property_type(prop)) {
2565  case PROP_BOOLEAN:
2566  if (RNA_property_array_check(prop)) {
2567  RNA_property_boolean_set_index(&but->rnapoin, prop, but->rnaindex, value);
2568  }
2569  else {
2570  RNA_property_boolean_set(&but->rnapoin, prop, value);
2571  }
2572  break;
2573  case PROP_INT:
2574  if (RNA_property_array_check(prop)) {
2575  RNA_property_int_set_index(&but->rnapoin, prop, but->rnaindex, (int)value);
2576  }
2577  else {
2578  RNA_property_int_set(&but->rnapoin, prop, (int)value);
2579  }
2580  break;
2581  case PROP_FLOAT:
2582  if (RNA_property_array_check(prop)) {
2583  RNA_property_float_set_index(&but->rnapoin, prop, but->rnaindex, value);
2584  }
2585  else {
2586  RNA_property_float_set(&but->rnapoin, prop, value);
2587  }
2588  break;
2589  case PROP_ENUM:
2590  if (RNA_property_flag(prop) & PROP_ENUM_FLAG) {
2591  int ivalue = (int)value;
2592  /* toggle for enum/flag buttons */
2593  ivalue ^= RNA_property_enum_get(&but->rnapoin, prop);
2594  RNA_property_enum_set(&but->rnapoin, prop, ivalue);
2595  }
2596  else {
2597  RNA_property_enum_set(&but->rnapoin, prop, value);
2598  }
2599  break;
2600  default:
2601  break;
2602  }
2603  }
2604 
2605  /* we can't be sure what RNA set functions actually do,
2606  * so leave this unset */
2607  value = UI_BUT_VALUE_UNSET;
2608  }
2609  else if (but->pointype == 0) {
2610  /* pass */
2611  }
2612  else {
2613  /* first do rounding */
2614  if (but->pointype == UI_BUT_POIN_CHAR) {
2615  value = round_db_to_uchar_clamp(value);
2616  }
2617  else if (but->pointype == UI_BUT_POIN_SHORT) {
2618  value = round_db_to_short_clamp(value);
2619  }
2620  else if (but->pointype == UI_BUT_POIN_INT) {
2621  value = round_db_to_int_clamp(value);
2622  }
2623  else if (but->pointype == UI_BUT_POIN_FLOAT) {
2624  float fval = (float)value;
2625  if (fval >= -0.00001f && fval <= 0.00001f) {
2626  /* prevent negative zero */
2627  fval = 0.0f;
2628  }
2629  value = fval;
2630  }
2631 
2632  /* then set value with possible edit override */
2633  if (but->editval) {
2634  value = *but->editval = value;
2635  }
2636  else if (but->pointype == UI_BUT_POIN_CHAR) {
2637  value = *((char *)but->poin) = (char)value;
2638  }
2639  else if (but->pointype == UI_BUT_POIN_SHORT) {
2640  value = *((short *)but->poin) = (short)value;
2641  }
2642  else if (but->pointype == UI_BUT_POIN_INT) {
2643  value = *((int *)but->poin) = (int)value;
2644  }
2645  else if (but->pointype == UI_BUT_POIN_FLOAT) {
2646  value = *((float *)but->poin) = (float)value;
2647  }
2648  }
2649 
2650  ui_but_update_select_flag(but, &value);
2651 }
2652 
2654 {
2656  return but->hardmax;
2657  }
2658  return UI_MAX_DRAW_STR;
2659 }
2660 
2662 {
2663  uiBut *return_but = nullptr;
2664 
2666 
2667  LISTBASE_FOREACH (uiBut *, but_iter, &but->block->buttons) {
2668  if (but_iter->editstr) {
2669  return_but = but_iter;
2670  break;
2671  }
2672  }
2673 
2674  return return_but;
2675 }
2676 
2677 static double ui_get_but_scale_unit(uiBut *but, double value)
2678 {
2679  UnitSettings *unit = but->block->unit;
2680  const int unit_type = UI_but_unit_type_get(but);
2681 
2682  /* Time unit is a bit special, not handled by BKE_scene_unit_scale() for now. */
2683  if (unit_type == PROP_UNIT_TIME) { /* WARNING: using evil_C :| */
2684  Scene *scene = CTX_data_scene(static_cast<const bContext *>(but->block->evil_C));
2685  return FRA2TIME(value);
2686  }
2687  return BKE_scene_unit_scale(unit, RNA_SUBTYPE_UNIT_VALUE(unit_type), value);
2688 }
2689 
2690 void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
2691 {
2692  if (!ui_but_is_unit(but)) {
2693  return;
2694  }
2695 
2696  UnitSettings *unit = but->block->unit;
2697  const int unit_type = UI_but_unit_type_get(but);
2698  char *orig_str;
2699 
2700  orig_str = BLI_strdup(str);
2701 
2702  BKE_unit_name_to_alt(str, maxlen, orig_str, unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type));
2703 
2704  MEM_freeN(orig_str);
2705 }
2706 
2711  uiBut *but, char *str, int len_max, double value, bool pad, int float_precision)
2712 {
2713  UnitSettings *unit = but->block->unit;
2714  const int unit_type = UI_but_unit_type_get(but);
2715  int precision;
2716 
2717  if (unit->scale_length < 0.0001f) {
2718  unit->scale_length = 1.0f; /* XXX do_versions */
2719  }
2720 
2721  /* Use precision override? */
2722  if (float_precision == -1) {
2723  /* Sanity checks */
2724  precision = (int)ui_but_get_float_precision(but);
2725  if (precision > UI_PRECISION_FLOAT_MAX) {
2726  precision = UI_PRECISION_FLOAT_MAX;
2727  }
2728  else if (precision == -1) {
2729  precision = 2;
2730  }
2731  }
2732  else {
2733  precision = float_precision;
2734  }
2735 
2737  len_max,
2738  ui_get_but_scale_unit(but, value),
2739  precision,
2740  RNA_SUBTYPE_UNIT_VALUE(unit_type),
2741  unit,
2742  pad);
2743 }
2744 
2745 static float ui_get_but_step_unit(uiBut *but, float step_default)
2746 {
2747  const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
2748  const double step_orig = step_default * UI_PRECISION_FLOAT_SCALE;
2749  /* Scaling up 'step_origg ' here is a bit arbitrary,
2750  * its just giving better scales from user POV */
2751  const double scale_step = ui_get_but_scale_unit(but, step_orig * 10);
2752  const double step = BKE_unit_closest_scalar(scale_step, but->block->unit->system, unit_type);
2753 
2754  /* -1 is an error value */
2755  if (step == -1.0f) {
2756  return step_default;
2757  }
2758 
2759  const double scale_unit = ui_get_but_scale_unit(but, 1.0);
2760  const double step_unit = BKE_unit_closest_scalar(
2761  scale_unit, but->block->unit->system, unit_type);
2762  double step_final;
2763 
2764  BLI_assert(step > 0.0);
2765 
2766  step_final = (step / scale_unit) / (double)UI_PRECISION_FLOAT_SCALE;
2767 
2768  if (step == step_unit) {
2769  /* Logic here is to scale by the original 'step_orig'
2770  * only when the unit step matches the scaled step.
2771  *
2772  * This is needed for units that don't have a wide range of scales (degrees for eg.).
2773  * Without this we can't select between a single degree, or a 10th of a degree.
2774  */
2775  step_final *= step_orig;
2776  }
2777 
2778  return (float)step_final;
2779 }
2780 
2782  char *str,
2783  const size_t maxlen,
2784  const int float_precision,
2785  const bool use_exp_float,
2786  bool *r_use_exp_float)
2787 {
2788  if (r_use_exp_float) {
2789  *r_use_exp_float = false;
2790  }
2791 
2794 
2795  int buf_len;
2796  const char *buf = nullptr;
2797  if ((but->type == UI_BTYPE_TAB) && (but->custom_data)) {
2798  StructRNA *ptr_type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
2799  PointerRNA ptr;
2800 
2801  /* uiBut.custom_data points to data this tab represents (e.g. workspace).
2802  * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
2803  RNA_pointer_create(but->rnapoin.owner_id, ptr_type, but->custom_data, &ptr);
2804  buf = RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
2805  }
2806  else if (type == PROP_STRING) {
2807  /* RNA string */
2808  buf = RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, str, maxlen, &buf_len);
2809  }
2810  else if (type == PROP_ENUM) {
2811  /* RNA enum */
2812  const int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
2813  if (RNA_property_enum_name(static_cast<bContext *>(but->block->evil_C),
2814  &but->rnapoin,
2815  but->rnaprop,
2816  value,
2817  &buf)) {
2818  BLI_strncpy(str, buf, maxlen);
2819  buf = str;
2820  }
2821  }
2822  else if (type == PROP_POINTER) {
2823  /* RNA pointer */
2825  buf = RNA_struct_name_get_alloc(&ptr, str, maxlen, &buf_len);
2826  }
2827  else {
2828  BLI_assert(0);
2829  }
2830 
2831  if (buf == nullptr) {
2832  str[0] = '\0';
2833  }
2834  else if (buf != str) {
2835  BLI_assert(maxlen <= buf_len + 1);
2836  /* string was too long, we have to truncate */
2837  if (UI_but_is_utf8(but)) {
2838  BLI_strncpy_utf8(str, buf, maxlen);
2839  }
2840  else {
2841  BLI_strncpy(str, buf, maxlen);
2842  }
2843  MEM_freeN((void *)buf);
2844  }
2845  }
2846  else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
2847  /* string */
2848  BLI_strncpy(str, but->poin, maxlen);
2849  return;
2850  }
2851  else if (ui_but_anim_expression_get(but, str, maxlen)) {
2852  /* driver expression */
2853  }
2854  else {
2855  /* number editing */
2856  const double value = ui_but_value_get(but);
2857 
2858  PropertySubType subtype = PROP_NONE;
2859  if (but->rnaprop) {
2860  subtype = RNA_property_subtype(but->rnaprop);
2861  }
2862 
2863  if (ui_but_is_float(but)) {
2864  int prec = float_precision;
2865 
2866  if (float_precision == -1) {
2867  prec = ui_but_calc_float_precision(but, value);
2868  }
2869  else if (!use_exp_float && ui_but_hide_fraction(but, value)) {
2870  prec = 0;
2871  }
2872 
2873  if (ui_but_is_unit(but)) {
2874  ui_get_but_string_unit(but, str, maxlen, value, false, prec);
2875  }
2876  else if (subtype == PROP_FACTOR) {
2877  if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
2878  BLI_snprintf(str, maxlen, "%.*f", prec, value);
2879  }
2880  else {
2881  BLI_snprintf(str, maxlen, "%.*f", MAX2(0, prec - 2), value * 100);
2882  }
2883  }
2884  else {
2885  const int int_digits_num = integer_digits_f(value);
2886  if (use_exp_float) {
2887  if (int_digits_num < -6 || int_digits_num > 12) {
2888  BLI_snprintf(str, maxlen, "%.*g", prec, value);
2889  if (r_use_exp_float) {
2890  *r_use_exp_float = true;
2891  }
2892  }
2893  else {
2894  prec -= int_digits_num;
2895  CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
2896  BLI_snprintf(str, maxlen, "%.*f", prec, value);
2897  }
2898  }
2899  else {
2900  prec -= int_digits_num;
2901  CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
2902  BLI_snprintf(str, maxlen, "%.*f", prec, value);
2903  }
2904  }
2905  }
2906  else {
2907  BLI_snprintf(str, maxlen, "%d", (int)value);
2908  }
2909  }
2910 }
2911 void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
2912 {
2913  ui_but_string_get_ex(but, str, maxlen, -1, false, nullptr);
2914 }
2915 
2916 char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
2917 {
2918  char *str = nullptr;
2919  *r_str_size = 1;
2920 
2921  if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
2923 
2924  if (type == PROP_STRING) {
2925  /* RNA string */
2926  str = RNA_property_string_get_alloc(&but->rnapoin, but->rnaprop, nullptr, 0, r_str_size);
2927  (*r_str_size) += 1;
2928  }
2929  else if (type == PROP_ENUM) {
2930  /* RNA enum */
2931  const int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
2932  const char *value_id;
2933  if (!RNA_property_enum_name(static_cast<bContext *>(but->block->evil_C),
2934  &but->rnapoin,
2935  but->rnaprop,
2936  value,
2937  &value_id)) {
2938  value_id = "";
2939  }
2940 
2941  *r_str_size = strlen(value_id) + 1;
2942  str = BLI_strdupn(value_id, *r_str_size);
2943  }
2944  else if (type == PROP_POINTER) {
2945  /* RNA pointer */
2947  str = RNA_struct_name_get_alloc(&ptr, nullptr, 0, r_str_size);
2948  (*r_str_size) += 1;
2949  }
2950  else {
2951  BLI_assert(0);
2952  }
2953  }
2954  else {
2955  BLI_assert(0);
2956  }
2957 
2958  if (UNLIKELY(str == nullptr)) {
2959  /* should never happen, paranoid check */
2960  *r_str_size = 1;
2961  str = BLI_strdup("");
2962  BLI_assert(0);
2963  }
2964 
2965  return str;
2966 }
2967 
2972 #define UI_NUMBER_EVAL_ERROR_PREFIX IFACE_("Error evaluating number, see Info editor for details")
2973 
2975  bContext *C, const char *str, const int unit_type, const UnitSettings *unit, double *r_value)
2976 {
2977  char *error = nullptr;
2978  const bool ok = user_string_to_number(C, str, unit, unit_type, r_value, true, &error);
2979  if (error) {
2980  ReportList *reports = CTX_wm_reports(C);
2982  MEM_freeN(error);
2983  }
2984  return ok;
2985 }
2986 
2988  const char *str,
2989  const uiBut *but,
2990  double *r_value)
2991 {
2992  const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
2993  const UnitSettings *unit = but->block->unit;
2994  return ui_number_from_string_units(C, str, unit_type, unit, r_value);
2995 }
2996 
2997 static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
2998 {
2999  bool ok;
3000 #ifdef WITH_PYTHON
3001  BPy_RunErrInfo err_info = {};
3002  err_info.reports = CTX_wm_reports(C);
3004  ok = BPY_run_string_as_number(C, nullptr, str, &err_info, r_value);
3005 #else
3006  UNUSED_VARS(C);
3007  *r_value = atof(str);
3008  ok = true;
3009 #endif
3010  return ok;
3011 }
3012 
3013 static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value)
3014 {
3015  const int len = strlen(str);
3016  if (BLI_strn_endswith(str, "%", len)) {
3017  char *str_new = BLI_strdupn(str, len - 1);
3018  const bool success = ui_number_from_string(C, str_new, r_value);
3019  MEM_freeN(str_new);
3020  *r_value /= 100.0;
3021  return success;
3022  }
3023  if (!ui_number_from_string(C, str, r_value)) {
3024  return false;
3025  }
3026  if (U.factor_display_type == USER_FACTOR_AS_PERCENTAGE) {
3027  *r_value /= 100.0;
3028  }
3029  return true;
3030 }
3031 
3032 static bool ui_number_from_string_percentage(bContext *C, const char *str, double *r_value)
3033 {
3034  const int len = strlen(str);
3035  if (BLI_strn_endswith(str, "%", len)) {
3036  char *str_new = BLI_strdupn(str, len - 1);
3037  const bool success = ui_number_from_string(C, str_new, r_value);
3038  MEM_freeN(str_new);
3039  return success;
3040  }
3041  return ui_number_from_string(C, str, r_value);
3042 }
3043 
3044 bool ui_but_string_eval_number(bContext *C, const uiBut *but, const char *str, double *r_value)
3045 {
3046  if (str[0] == '\0') {
3047  *r_value = 0.0;
3048  return true;
3049  }
3050 
3051  PropertySubType subtype = PROP_NONE;
3052  if (but->rnaprop) {
3053  subtype = RNA_property_subtype(but->rnaprop);
3054  }
3055 
3056  if (ui_but_is_float(but)) {
3057  if (ui_but_is_unit(but)) {
3058  return ui_number_from_string_units_with_but(C, str, but, r_value);
3059  }
3060  if (subtype == PROP_FACTOR) {
3061  return ui_number_from_string_factor(C, str, r_value);
3062  }
3063  if (subtype == PROP_PERCENTAGE) {
3064  return ui_number_from_string_percentage(C, str, r_value);
3065  }
3066  return ui_number_from_string(C, str, r_value);
3067  }
3068  return ui_number_from_string(C, str, r_value);
3069 }
3070 
3071 /* just the assignment/free part */
3072 static void ui_but_string_set_internal(uiBut *but, const char *str, size_t str_len)
3073 {
3074  BLI_assert(str_len == strlen(str));
3075  BLI_assert(but->str == nullptr);
3076  str_len += 1;
3077 
3078  if (str_len > UI_MAX_NAME_STR) {
3079  but->str = static_cast<char *>(MEM_mallocN(str_len, "ui_def_but str"));
3080  }
3081  else {
3082  but->str = but->strdata;
3083  }
3084  memcpy(but->str, str, str_len);
3085 }
3086 
3088 {
3089  if (but->str) {
3090  if (but->str != but->strdata) {
3091  MEM_freeN(but->str);
3092  }
3093  /* must call 'ui_but_string_set_internal' after */
3094  but->str = nullptr;
3095  }
3096 }
3097 
3098 bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
3099 {
3100  if (but->rnaprop && but->rnapoin.data && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
3101  if (RNA_property_editable(&but->rnapoin, but->rnaprop)) {
3103 
3104  if (type == PROP_STRING) {
3105  /* RNA string */
3107  return true;
3108  }
3109 
3110  if (type == PROP_POINTER) {
3111  if (str[0] == '\0') {
3113  return true;
3114  }
3115 
3116  uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but :
3117  nullptr;
3118  /* RNA pointer */
3119  PointerRNA rptr;
3120 
3121  /* This is kind of hackish, in theory think we could only ever use the second member of
3122  * this if/else, since #ui_searchbox_apply() is supposed to always set that pointer when
3123  * we are storing pointers... But keeping str search first for now,
3124  * to try to break as little as possible existing code. All this is band-aids anyway.
3125  * Fact remains, using `editstr` as main 'reference' over whole search button thingy
3126  * is utterly weak and should be redesigned IMHO, but that's not a simple task. */
3127  if (search_but && search_but->rnasearchprop &&
3129  &search_but->rnasearchpoin, search_but->rnasearchprop, str, &rptr)) {
3130  RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, nullptr);
3131  }
3132  else if (search_but->item_active != nullptr) {
3133  RNA_pointer_create(nullptr,
3135  search_but->item_active,
3136  &rptr);
3137  RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, nullptr);
3138  }
3139 
3140  return true;
3141  }
3142 
3143  if (type == PROP_ENUM) {
3144  int value;
3145  if (RNA_property_enum_value(static_cast<bContext *>(but->block->evil_C),
3146  &but->rnapoin,
3147  but->rnaprop,
3148  str,
3149  &value)) {
3150  RNA_property_enum_set(&but->rnapoin, but->rnaprop, value);
3151  return true;
3152  }
3153  return false;
3154  }
3155  BLI_assert(0);
3156  }
3157  }
3158  else if (but->type == UI_BTYPE_TAB) {
3159  if (but->rnaprop && but->custom_data) {
3160  StructRNA *ptr_type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
3161  PointerRNA ptr;
3162  PropertyRNA *prop;
3163 
3164  /* uiBut.custom_data points to data this tab represents (e.g. workspace).
3165  * uiBut.rnapoin/prop store an active value (e.g. active workspace). */
3166  RNA_pointer_create(but->rnapoin.owner_id, ptr_type, but->custom_data, &ptr);
3167  prop = RNA_struct_name_property(ptr_type);
3168  if (RNA_property_editable(&ptr, prop)) {
3169  RNA_property_string_set(&ptr, prop, str);
3170  }
3171  }
3172  }
3173  else if (but->type == UI_BTYPE_TEXT) {
3174  /* string */
3175  if (!but->poin) {
3176  str = "";
3177  }
3178  else if (UI_but_is_utf8(but)) {
3179  BLI_strncpy_utf8(but->poin, str, but->hardmax);
3180  }
3181  else {
3182  BLI_strncpy(but->poin, str, but->hardmax);
3183  }
3184 
3185  return true;
3186  }
3187  else if (but->type == UI_BTYPE_SEARCH_MENU) {
3188  /* string */
3189  BLI_strncpy(but->poin, str, but->hardmax);
3190  return true;
3191  }
3192  else if (ui_but_anim_expression_set(but, str)) {
3193  /* driver expression */
3194  return true;
3195  }
3196  else if (str[0] == '#') {
3197  /* Shortcut to create new driver expression (versus immediate Python-execution). */
3198  return ui_but_anim_expression_create(but, str + 1);
3199  }
3200  else {
3201  /* number editing */
3202  double value;
3203 
3204  if (ui_but_string_eval_number(C, but, str, &value) == false) {
3206  return false;
3207  }
3208 
3209  if (!ui_but_is_float(but)) {
3210  value = floor(value + 0.5);
3211  }
3212 
3213  /* not that we use hard limits here */
3214  if (value < (double)but->hardmin) {
3215  value = but->hardmin;
3216  }
3217  if (value > (double)but->hardmax) {
3218  value = but->hardmax;
3219  }
3220 
3221  ui_but_value_set(but, value);
3222  return true;
3223  }
3224 
3225  return false;
3226 }
3227 
3228 static double soft_range_round_up(double value, double max)
3229 {
3230  /* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, ..
3231  * checking for 0.0 prevents floating point exceptions */
3232  const double newmax = (value != 0.0) ? pow(10.0, ceil(log(value) / M_LN10)) : 0.0;
3233 
3234  if (newmax * 0.2 >= max && newmax * 0.2 >= value) {
3235  return newmax * 0.2;
3236  }
3237  if (newmax * 0.5 >= max && newmax * 0.5 >= value) {
3238  return newmax * 0.5;
3239  }
3240  return newmax;
3241 }
3242 
3243 static double soft_range_round_down(double value, double max)
3244 {
3245  /* round down to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, ..
3246  * checking for 0.0 prevents floating point exceptions */
3247  const double newmax = (value != 0.0) ? pow(10.0, floor(log(value) / M_LN10)) : 0.0;
3248 
3249  if (newmax * 5.0 <= max && newmax * 5.0 <= value) {
3250  return newmax * 5.0;
3251  }
3252  if (newmax * 2.0 <= max && newmax * 2.0 <= value) {
3253  return newmax * 2.0;
3254  }
3255  return newmax;
3256 }
3257 
3259 {
3260  if (but->rnaprop == nullptr) {
3261  return;
3262  }
3263 
3265 
3266  if (type == PROP_INT) {
3267  int imin, imax;
3268  RNA_property_int_range(&but->rnapoin, but->rnaprop, &imin, &imax);
3269  but->hardmin = imin;
3270  but->hardmax = imax;
3271  }
3272  else if (type == PROP_FLOAT) {
3273  float fmin, fmax;
3274  RNA_property_float_range(&but->rnapoin, but->rnaprop, &fmin, &fmax);
3275  but->hardmin = fmin;
3276  but->hardmax = fmax;
3277  }
3278 }
3279 
3281 {
3282  /* This could be split up into functions which handle arrays and not. */
3283 
3284  /* Ideally we would not limit this, but practically it's more than
3285  * enough. Worst case is very long vectors won't use a smart soft-range,
3286  * which isn't so bad. */
3287 
3288  if (but->rnaprop) {
3290  const PropertySubType subtype = RNA_property_subtype(but->rnaprop);
3291  double softmin, softmax /*, step, precision*/;
3292  double value_min;
3293  double value_max;
3294 
3295  /* clamp button range to something reasonable in case
3296  * we get -inf/inf from RNA properties */
3297  if (type == PROP_INT) {
3298  const bool is_array = RNA_property_array_check(but->rnaprop);
3299  int imin, imax, istep;
3300 
3301  RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
3302  softmin = (imin == INT_MIN) ? -1e4 : imin;
3303  softmax = (imin == INT_MAX) ? 1e4 : imax;
3304  // step = istep; /* UNUSED */
3305  // precision = 1; /* UNUSED */
3306 
3307  if (is_array) {
3308  int value_range[2];
3309  RNA_property_int_get_array_range(&but->rnapoin, but->rnaprop, value_range);
3310  value_min = (double)value_range[0];
3311  value_max = (double)value_range[1];
3312  }
3313  else {
3314  value_min = value_max = ui_but_value_get(but);
3315  }
3316  }
3317  else if (type == PROP_FLOAT) {
3318  const bool is_array = RNA_property_array_check(but->rnaprop);
3319  float fmin, fmax, fstep, fprecision;
3320 
3321  RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
3322  softmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
3323  softmax = (fmax == FLT_MAX) ? (float)1e4 : fmax;
3324  // step = fstep; /* UNUSED */
3325  // precision = fprecision; /* UNUSED */
3326 
3327  /* Use shared min/max for array values, except for color alpha. */
3328  if (is_array && !(subtype == PROP_COLOR && but->rnaindex == 3)) {
3329  float value_range[2];
3330  RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
3331  value_min = (double)value_range[0];
3332  value_max = (double)value_range[1];
3333  }
3334  else {
3335  value_min = value_max = ui_but_value_get(but);
3336  }
3337  }
3338  else {
3339  return;
3340  }
3341 
3342  /* if the value goes out of the soft/max range, adapt the range */
3343  if (value_min + 1e-10 < softmin) {
3344  if (value_min < 0.0) {
3345  softmin = -soft_range_round_up(-value_min, -softmin);
3346  }
3347  else {
3348  softmin = soft_range_round_down(value_min, softmin);
3349  }
3350 
3351  if (softmin < (double)but->hardmin) {
3352  softmin = (double)but->hardmin;
3353  }
3354  }
3355  if (value_max - 1e-10 > softmax) {
3356  if (value_max < 0.0) {
3357  softmax = -soft_range_round_down(-value_max, -softmax);
3358  }
3359  else {
3360  softmax = soft_range_round_up(value_max, softmax);
3361  }
3362 
3363  if (softmax > (double)but->hardmax) {
3364  softmax = but->hardmax;
3365  }
3366  }
3367 
3368  but->softmin = softmin;
3369  but->softmax = softmax;
3370  }
3371  else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) {
3372  float value = ui_but_value_get(but);
3373  if (isfinite(value)) {
3374  CLAMP(value, but->hardmin, but->hardmax);
3375  but->softmin = min_ff(but->softmin, value);
3376  but->softmax = max_ff(but->softmax, value);
3377  }
3378  }
3379 }
3380 
3381 /* ******************* Free ********************/
3382 
3389 {
3390  switch (but->type) {
3391  case UI_BTYPE_SEARCH_MENU: {
3392  uiButSearch *search_but = (uiButSearch *)but;
3393 
3394  if (search_but->arg_free_fn) {
3395  search_but->arg_free_fn(search_but->arg);
3396  search_but->arg = nullptr;
3397  }
3398  break;
3399  }
3400  default:
3401  break;
3402  }
3403 }
3404 
3405 /* can be called with C==nullptr */
3406 static void ui_but_free(const bContext *C, uiBut *but)
3407 {
3408  if (but->opptr) {
3410  MEM_freeN(but->opptr);
3411  }
3412 
3413  if (but->func_argN) {
3414  MEM_freeN(but->func_argN);
3415  }
3416 
3417  if (but->tip_arg_free) {
3418  but->tip_arg_free(but->tip_arg);
3419  }
3420 
3421  if (but->hold_argN) {
3422  MEM_freeN(but->hold_argN);
3423  }
3424 
3426 
3427  if (but->active) {
3428  /* XXX solve later, buttons should be free-able without context ideally,
3429  * however they may have open tooltips or popup windows, which need to
3430  * be closed using a context pointer */
3431  if (C) {
3432  ui_but_active_free(C, but);
3433  }
3434  else {
3435  if (but->active) {
3436  MEM_freeN(but->active);
3437  }
3438  }
3439  }
3440  if (but->str && but->str != but->strdata) {
3441  MEM_freeN(but->str);
3442  }
3443 
3444  if ((but->type == UI_BTYPE_IMAGE) && but->poin) {
3445  IMB_freeImBuf((struct ImBuf *)but->poin);
3446  }
3447 
3448  ui_but_drag_free(but);
3450 
3451  BLI_assert(UI_butstore_is_registered(but->block, but) == false);
3452 
3453  MEM_freeN(but);
3454 }
3455 
3456 void UI_block_free(const bContext *C, uiBlock *block)
3457 {
3458  UI_butstore_clear(block);
3459 
3460  uiBut *but;
3461  while ((but = static_cast<uiBut *>(BLI_pophead(&block->buttons)))) {
3462  ui_but_free(C, but);
3463  }
3464 
3465  if (block->unit) {
3466  MEM_freeN(block->unit);
3467  }
3468 
3469  if (block->func_argN) {
3470  MEM_freeN(block->func_argN);
3471  }
3472 
3473  CTX_store_free_list(&block->contexts);
3474 
3475  BLI_freelistN(&block->saferct);
3476  BLI_freelistN(&block->color_pickers.list);
3477 
3479  ui_block_free_views(block);
3480 
3481  MEM_freeN(block);
3482 }
3483 
3485 {
3486  ARegion *region = CTX_wm_region(C);
3487  wmWindow *window = CTX_wm_window(C);
3488 
3489  LISTBASE_FOREACH (uiBlock *, block, lb) {
3490  if (block->active) {
3491  ui_update_window_matrix(window, region, block);
3492  }
3493  }
3494 }
3495 
3497 {
3498  LISTBASE_FOREACH (uiBlock *, block, lb) {
3499  if (block->active) {
3501  }
3502  }
3503 }
3504 
3505 void UI_blocklist_draw(const bContext *C, const ListBase *lb)
3506 {
3507  LISTBASE_FOREACH (uiBlock *, block, lb) {
3508  if (block->active) {
3509  UI_block_draw(C, block);
3510  }
3511  }
3512 }
3513 
3514 void UI_blocklist_free(const bContext *C, ARegion *region)
3515 {
3516  ListBase *lb = &region->uiblocks;
3517  uiBlock *block;
3518  while ((block = static_cast<uiBlock *>(BLI_pophead(lb)))) {
3519  UI_block_free(C, block);
3520  }
3521  if (region->runtime.block_name_map != nullptr) {
3522  BLI_ghash_free(region->runtime.block_name_map, nullptr, nullptr);
3523  region->runtime.block_name_map = nullptr;
3524  }
3525 }
3526 
3528 {
3529  ListBase *lb = &region->uiblocks;
3530 
3531  LISTBASE_FOREACH_MUTABLE (uiBlock *, block, lb) {
3532  if (!block->handle) {
3533  if (block->active) {
3534  block->active = false;
3535  }
3536  else {
3537  if (region->runtime.block_name_map != nullptr) {
3538  uiBlock *b = static_cast<uiBlock *>(
3539  BLI_ghash_lookup(region->runtime.block_name_map, block->name));
3540  if (b == block) {
3541  BLI_ghash_remove(region->runtime.block_name_map, b->name, nullptr, nullptr);
3542  }
3543  }
3544  BLI_remlink(lb, block);
3545  UI_block_free(C, block);
3546  }
3547  }
3548  }
3549 }
3550 
3551 void UI_block_region_set(uiBlock *block, ARegion *region)
3552 {
3553  ListBase *lb = &region->uiblocks;
3554  uiBlock *oldblock = nullptr;
3555 
3556  /* each listbase only has one block with this name, free block
3557  * if is already there so it can be rebuilt from scratch */
3558  if (lb) {
3559  if (region->runtime.block_name_map == nullptr) {
3560  region->runtime.block_name_map = BLI_ghash_str_new(__func__);
3561  }
3562  oldblock = (uiBlock *)BLI_ghash_lookup(region->runtime.block_name_map, block->name);
3563 
3564  if (oldblock) {
3565  oldblock->active = false;
3566  oldblock->panel = nullptr;
3567  oldblock->handle = nullptr;
3568  }
3569 
3570  /* at the beginning of the list! for dynamical menus/blocks */
3571  BLI_addhead(lb, block);
3572  BLI_ghash_reinsert(region->runtime.block_name_map, block->name, block, nullptr, nullptr);
3573  }
3574 
3575  block->oldblock = oldblock;
3576 }
3577 
3578 uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eUIEmbossType emboss)
3579 {
3580  wmWindow *window = CTX_wm_window(C);
3582 
3583  uiBlock *block = MEM_cnew<uiBlock>(__func__);
3584  block->active = true;
3585  block->emboss = emboss;
3586  block->evil_C = (void *)C; /* XXX */
3587 
3589 
3590  if (scene) {
3591  /* store display device name, don't lookup for transformations yet
3592  * block could be used for non-color displays where looking up for transformation
3593  * would slow down redraw, so only lookup for actual transform when it's indeed
3594  * needed
3595  */
3597 
3598  /* copy to avoid crash when scene gets deleted with ui still open */
3599  block->unit = MEM_new<UnitSettings>(__func__);
3600  memcpy(block->unit, &scene->unit, sizeof(scene->unit));
3601  }
3602  else {
3604  }
3605 
3606  BLI_strncpy(block->name, name, sizeof(block->name));
3607 
3608  if (region) {
3609  UI_block_region_set(block, region);
3610  }
3611 
3612  /* Set window matrix and aspect for region and OpenGL state. */
3613  ui_update_window_matrix(window, region, block);
3614 
3615  /* Tag as popup menu if not created within a region. */
3616  if (!(region && region->visible)) {
3617  block->auto_open = true;
3618  block->flag |= UI_BLOCK_LOOP;
3619  }
3620 
3621  return block;
3622 }
3623 
3625 {
3626  return block->emboss;
3627 }
3628 
3630 {
3631  block->emboss = emboss;
3632 }
3633 
3634 void UI_block_theme_style_set(uiBlock *block, char theme_style)
3635 {
3636  block->theme_style = theme_style;
3637 }
3638 
3640 {
3641  return block->flag & UI_BLOCK_SEARCH_ONLY;
3642 }
3643 
3644 void UI_block_set_search_only(uiBlock *block, bool search_only)
3645 {
3646  SET_FLAG_FROM_TEST(block->flag, search_only, UI_BLOCK_SEARCH_ONLY);
3647 }
3648 
3649 static void ui_but_build_drawstr_float(uiBut *but, double value)
3650 {
3651  size_t slen = 0;
3652  STR_CONCAT(but->drawstr, slen, but->str);
3653 
3654  PropertySubType subtype = PROP_NONE;
3655  if (but->rnaprop) {
3656  subtype = RNA_property_subtype(but->rnaprop);
3657  }
3658 
3659  /* Change negative zero to regular zero, without altering anything else. */
3660  value += +0.0f;
3661 
3662  if (value == (double)FLT_MAX) {
3663  STR_CONCAT(but->drawstr, slen, "inf");
3664  }
3665  else if (value == (double)-FLT_MAX) {
3666  STR_CONCAT(but->drawstr, slen, "-inf");
3667  }
3668  else if (subtype == PROP_PERCENTAGE) {
3669  const int prec = ui_but_calc_float_precision(but, value);
3670  STR_CONCATF(but->drawstr, slen, "%.*f%%", prec, value);
3671  }
3672  else if (subtype == PROP_PIXEL) {
3673  const int prec = ui_but_calc_float_precision(but, value);
3674  STR_CONCATF(but->drawstr, slen, "%.*f px", prec, value);
3675  }
3676  else if (subtype == PROP_FACTOR) {
3677  const int precision = ui_but_calc_float_precision(but, value);
3678 
3679  if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
3680  STR_CONCATF(but->drawstr, slen, "%.*f", precision, value);
3681  }
3682  else {
3683  STR_CONCATF(but->drawstr, slen, "%.*f%%", MAX2(0, precision - 2), value * 100);
3684  }
3685  }
3686  else if (ui_but_is_unit(but)) {
3687  char new_str[sizeof(but->drawstr)];
3688  ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1);
3689  STR_CONCAT(but->drawstr, slen, new_str);
3690  }
3691  else {
3692  const int prec = ui_but_calc_float_precision(but, value);
3693  STR_CONCATF(but->drawstr, slen, "%.*f", prec, value);
3694  }
3695 }
3696 
3697 static void ui_but_build_drawstr_int(uiBut *but, int value)
3698 {
3699  size_t slen = 0;
3700  STR_CONCAT(but->drawstr, slen, but->str);
3701 
3702  PropertySubType subtype = PROP_NONE;
3703  if (but->rnaprop) {
3704  subtype = RNA_property_subtype(but->rnaprop);
3705  }
3706 
3707  STR_CONCATF(but->drawstr, slen, "%d", value);
3708 
3709  if (subtype == PROP_PERCENTAGE) {
3710  STR_CONCAT(but->drawstr, slen, "%");
3711  }
3712  else if (subtype == PROP_PIXEL) {
3713  STR_CONCAT(but->drawstr, slen, " px");
3714  }
3715 }
3716 
3722 static void ui_but_update_ex(uiBut *but, const bool validate)
3723 {
3724  /* if something changed in the button */
3725  double value = UI_BUT_VALUE_UNSET;
3726 
3727  ui_but_update_select_flag(but, &value);
3728 
3729  /* only update soft range while not editing */
3730  if (!ui_but_is_editing(but)) {
3731  if ((but->rnaprop != nullptr) || (but->poin && (but->pointype & UI_BUT_POIN_TYPES))) {
3732  ui_but_range_set_soft(but);
3733  }
3734  }
3735 
3736  /* test for min and max, icon sliders, etc */
3737  switch (but->type) {
3738  case UI_BTYPE_NUM:
3739  case UI_BTYPE_SCROLL:
3740  case UI_BTYPE_NUM_SLIDER:
3741  if (validate) {
3742  UI_GET_BUT_VALUE_INIT(but, value);
3743  if (value < (double)but->hardmin) {
3744  ui_but_value_set(but, but->hardmin);
3745  }
3746  else if (value > (double)but->hardmax) {
3747  ui_but_value_set(but, but->hardmax);
3748  }
3749 
3750  /* max must never be smaller than min! Both being equal is allowed though */
3751  BLI_assert(but->softmin <= but->softmax && but->hardmin <= but->hardmax);
3752  }
3753  break;
3754 
3755  case UI_BTYPE_ICON_TOGGLE:
3757  if ((but->rnaprop == nullptr) ||
3759  if (but->rnaprop && RNA_property_flag(but->rnaprop) & PROP_ICONS_REVERSE) {
3760  but->drawflag |= UI_BUT_ICON_REVERSE;
3761  }
3762 
3763  but->iconadd = (but->flag & UI_SELECT) ? 1 : 0;
3764  }
3765  break;
3766 
3767  /* quiet warnings for unhandled types */
3768  default:
3769  break;
3770  }
3771 
3772  /* safety is 4 to enable small number buttons (like 'users') */
3773  // okwidth = -4 + (BLI_rcti_size_x(&but->rect)); /* UNUSED */
3774 
3775  /* name: */
3776  switch (but->type) {
3777 
3778  case UI_BTYPE_MENU:
3779  if (BLI_rctf_size_x(&but->rect) >= (UI_UNIT_X * 2)) {
3780  /* only needed for menus in popup blocks that don't recreate buttons on redraw */
3781  if (but->block->flag & UI_BLOCK_LOOP) {
3782  if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) {
3783  const int value_enum = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
3784 
3785  EnumPropertyItem item;
3787  static_cast<bContext *>(but->block->evil_C),
3788  &but->rnapoin,
3789  but->rnaprop,
3790  value_enum,
3791  &item)) {
3792  const size_t slen = strlen(item.name);
3794  ui_but_string_set_internal(but, item.name, slen);
3795  but->icon = (BIFIconID)item.icon;
3796  }
3797  }
3798  }
3799  BLI_strncpy(but->drawstr, but->str, sizeof(but->drawstr));
3800  }
3801  break;
3802 
3803  case UI_BTYPE_NUM:
3804  case UI_BTYPE_NUM_SLIDER:
3805  if (but->editstr) {
3806  break;
3807  }
3808  UI_GET_BUT_VALUE_INIT(but, value);
3809  if (ui_but_is_float(but)) {
3810  ui_but_build_drawstr_float(but, value);
3811  }
3812  else {
3813  ui_but_build_drawstr_int(but, (int)value);
3814  }
3815  break;
3816 
3817  case UI_BTYPE_LABEL:
3818  if (ui_but_is_float(but)) {
3819  UI_GET_BUT_VALUE_INIT(but, value);
3820  const int prec = ui_but_calc_float_precision(but, value);
3821  BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
3822  }
3823  else {
3824  BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
3825  }
3826 
3827  break;
3828 
3829  case UI_BTYPE_TEXT:
3830  case UI_BTYPE_SEARCH_MENU:
3831  if (!but->editstr) {
3832  char str[UI_MAX_DRAW_STR];
3833 
3835  BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str);
3836  }
3837  break;
3838 
3839  case UI_BTYPE_KEY_EVENT: {
3840  const char *str;
3841  if (but->flag & UI_SELECT) {
3842  str = "Press a key";
3843  }
3844  else {
3845  UI_GET_BUT_VALUE_INIT(but, value);
3846  str = WM_key_event_string((short)value, false);
3847  }
3848  BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str);
3849  break;
3850  }
3851  case UI_BTYPE_HOTKEY_EVENT:
3852  if (but->flag & UI_SELECT) {
3853  const uiButHotkeyEvent *hotkey_but = (uiButHotkeyEvent *)but;
3854 
3855  if (hotkey_but->modifier_key) {
3856  char *str = but->drawstr;
3857  but->drawstr[0] = '\0';
3858 
3859  if (hotkey_but->modifier_key & KM_SHIFT) {
3860  str += BLI_strcpy_rlen(str, "Shift ");
3861  }
3862  if (hotkey_but->modifier_key & KM_CTRL) {
3863  str += BLI_strcpy_rlen(str, "Ctrl ");
3864  }
3865  if (hotkey_but->modifier_key & KM_ALT) {
3866  str += BLI_strcpy_rlen(str, "Alt ");
3867  }
3868  if (hotkey_but->modifier_key & KM_OSKEY) {
3869  str += BLI_strcpy_rlen(str, "Cmd ");
3870  }
3871 
3872  (void)str; /* UNUSED */
3873  }
3874  else {
3875  BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR);
3876  }
3877  }
3878  else {
3879  BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
3880  }
3881 
3882  break;
3883 
3884  case UI_BTYPE_HSVCUBE:
3885  case UI_BTYPE_HSVCIRCLE:
3886  break;
3887  default:
3888  BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
3889  break;
3890  }
3891 
3892  /* if we are doing text editing, this will override the drawstr */
3893  if (but->editstr) {
3894  but->drawstr[0] = '\0';
3895  }
3896 
3897  /* text clipping moved to widget drawing code itself */
3898 }
3899 
3901 {
3902  ui_but_update_ex(but, false);
3903 }
3904 
3906 {
3907  ui_but_update_ex(but, true);
3908 }
3909 
3911 {
3912  /* if other align was active, end it */
3913  if (block->flag & UI_BUT_ALIGN) {
3914  UI_block_align_end(block);
3915  }
3916 
3917  block->flag |= UI_BUT_ALIGN_DOWN;
3918  block->alignnr++;
3919 
3920  /* buttons declared after this call will get this align nr */ /* XXX flag? */
3921 }
3922 
3924 {
3925  block->flag &= ~UI_BUT_ALIGN; /* all 4 flags */
3926 }
3927 
3929 {
3931 }
3932 
3933 void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3])
3934 {
3935  struct ColorManagedDisplay *display = ui_block_cm_display_get(block);
3936 
3938 }
3939 
3940 static void ui_but_alloc_info(const eButType type,
3941  size_t *r_alloc_size,
3942  const char **r_alloc_str,
3943  bool *r_has_custom_type)
3944 {
3945  size_t alloc_size;
3946  const char *alloc_str;
3947  bool has_custom_type = true;
3948 
3949  switch (type) {
3950  case UI_BTYPE_NUM:
3951  alloc_size = sizeof(uiButNumber);
3952  alloc_str = "uiButNumber";
3953  break;
3954  case UI_BTYPE_COLOR:
3955  alloc_size = sizeof(uiButColor);
3956  alloc_str = "uiButColor";
3957  break;
3958  case UI_BTYPE_DECORATOR:
3959  alloc_size = sizeof(uiButDecorator);
3960  alloc_str = "uiButDecorator";
3961  break;
3962  case UI_BTYPE_TAB:
3963  alloc_size = sizeof(uiButTab);
3964  alloc_str = "uiButTab";
3965  break;
3966  case UI_BTYPE_SEARCH_MENU:
3967  alloc_size = sizeof(uiButSearch);
3968  alloc_str = "uiButSearch";
3969  break;
3970  case UI_BTYPE_PROGRESS_BAR:
3971  alloc_size = sizeof(uiButProgressbar);
3972  alloc_str = "uiButProgressbar";
3973  break;
3974  case UI_BTYPE_HSVCUBE:
3975  alloc_size = sizeof(uiButHSVCube);
3976  alloc_str = "uiButHSVCube";
3977  break;
3978  case UI_BTYPE_COLORBAND:
3979  alloc_size = sizeof(uiButColorBand);
3980  alloc_str = "uiButColorBand";
3981  break;
3982  case UI_BTYPE_CURVE:
3983  alloc_size = sizeof(uiButCurveMapping);
3984  alloc_str = "uiButCurveMapping";
3985  break;
3986  case UI_BTYPE_CURVEPROFILE:
3987  alloc_size = sizeof(uiButCurveProfile);
3988  alloc_str = "uiButCurveProfile";
3989  break;
3990  case UI_BTYPE_HOTKEY_EVENT:
3991  alloc_size = sizeof(uiButHotkeyEvent);
3992  alloc_str = "uiButHotkeyEvent";
3993  break;
3994  case UI_BTYPE_VIEW_ITEM:
3995  alloc_size = sizeof(uiButViewItem);
3996  alloc_str = "uiButViewItem";
3997  break;
3998  default:
3999  alloc_size = sizeof(uiBut);
4000  alloc_str = "uiBut";
4001  has_custom_type = false;
4002  break;
4003  }
4004 
4005  if (r_alloc_size) {
4006  *r_alloc_size = alloc_size;
4007  }
4008  if (r_alloc_str) {
4009  *r_alloc_str = alloc_str;
4010  }
4011  if (r_has_custom_type) {
4012  *r_has_custom_type = has_custom_type;
4013  }
4014 }
4015 
4017 {
4018  size_t alloc_size;
4019  const char *alloc_str;
4020  ui_but_alloc_info(type, &alloc_size, &alloc_str, nullptr);
4021 
4022  return static_cast<uiBut *>(MEM_callocN(alloc_size, alloc_str));
4023 }
4024 
4026 {
4027  if (but->type == new_type) {
4028  /* Nothing to do. */
4029  return but;
4030  }
4031 
4032  size_t alloc_size;
4033  const char *alloc_str;
4034  uiBut *insert_after_but = but->prev;
4035  bool new_has_custom_type, old_has_custom_type;
4036 
4037  /* Remove old button address */
4038  BLI_remlink(&but->block->buttons, but);
4039 
4040  ui_but_alloc_info(but->type, nullptr, nullptr, &old_has_custom_type);
4041  ui_but_alloc_info(new_type, &alloc_size, &alloc_str, &new_has_custom_type);
4042 
4043  if (new_has_custom_type || old_has_custom_type) {
4044  const void *old_but_ptr = but;
4045  /* Button may have pointer to a member within itself, this will have to be updated. */
4046  const bool has_str_ptr_to_self = but->str == but->strdata;
4047  const bool has_poin_ptr_to_self = but->poin == (char *)but;
4048 
4049  but = static_cast<uiBut *>(MEM_recallocN_id(but, alloc_size, alloc_str));
4050  but->type = new_type;
4051  if (has_str_ptr_to_self) {
4052  but->str = but->strdata;
4053  }
4054  if (has_poin_ptr_to_self) {
4055  but->poin = (char *)but;
4056  }
4057 
4058  BLI_insertlinkafter(&but->block->buttons, insert_after_but, but);
4059 
4060  if (but->layout) {
4061  const bool found_layout = ui_layout_replace_but_ptr(but->layout, old_but_ptr, but);
4062  BLI_assert(found_layout);
4063  UNUSED_VARS_NDEBUG(found_layout);
4064  ui_button_group_replace_but_ptr(uiLayoutGetBlock(but->layout), old_but_ptr, but);
4065  }
4066 #ifdef WITH_PYTHON
4068  UI_editsource_but_replace(static_cast<const uiBut *>(old_but_ptr), but);
4069  }
4070 #endif
4071  }
4072 
4073  return but;
4074 }
4075 
4087 static uiBut *ui_def_but(uiBlock *block,
4088  int type,
4089  int retval,
4090  const char *str,
4091  int x,
4092  int y,
4093  short width,
4094  short height,
4095  void *poin,
4096  float min,
4097  float max,
4098  float a1,
4099  float a2,
4100  const char *tip)
4101 {
4102  BLI_assert(width >= 0 && height >= 0);
4103 
4104  /* we could do some more error checks here */
4105  if ((type & BUTTYPE) == UI_BTYPE_LABEL) {
4106  BLI_assert((poin != nullptr || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) ||
4107  (a1 != 0.0f && a1 != 1.0f)) == false);
4108  }
4109 
4110  if (type & UI_BUT_POIN_TYPES) { /* a pointer is required */
4111  if (poin == nullptr) {
4112  BLI_assert(0);
4113  return nullptr;
4114  }
4115  }
4116 
4117  uiBut *but = ui_but_alloc((eButType)(type & BUTTYPE));
4118 
4119  but->type = (eButType)(type & BUTTYPE);
4121  but->bit = type & UI_BUT_POIN_BIT;
4122  but->bitnr = type & 31;
4123  but->icon = ICON_NONE;
4124  but->iconadd = 0;
4125 
4126  but->retval = retval;
4127 
4128  const int slen = strlen(str);
4129  ui_but_string_set_internal(but, str, slen);
4130 
4131  but->rect.xmin = x;
4132  but->rect.ymin = y;
4133  but->rect.xmax = but->rect.xmin + width;
4134  but->rect.ymax = but->rect.ymin + height;
4135 
4136  but->poin = (char *)poin;
4137  but->hardmin = but->softmin = min;
4138  but->hardmax = but->softmax = max;
4139  but->a1 = a1;
4140  but->a2 = a2;
4141  but->tip = tip;
4142 
4143  but->disabled_info = block->lockstr;
4144  but->emboss = block->emboss;
4145  but->pie_dir = UI_RADIAL_NONE;
4146 
4147  but->block = block; /* pointer back, used for front-buffer status, and picker. */
4148 
4149  if ((block->flag & UI_BUT_ALIGN) && ui_but_can_align(but)) {
4150  but->alignnr = block->alignnr;
4151  }
4152 
4153  but->func = block->func;
4154  but->func_arg1 = block->func_arg1;
4155  but->func_arg2 = block->func_arg2;
4156 
4157  but->funcN = block->funcN;
4158  if (block->func_argN) {
4159  but->func_argN = MEM_dupallocN(block->func_argN);
4160  }
4161 
4162  but->pos = -1; /* cursor invisible */
4163 
4164  if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) { /* add a space to name */
4165  /* slen remains unchanged from previous assignment, ensure this stays true */
4166  if (slen > 0 && slen < UI_MAX_NAME_STR - 2) {
4167  if (but->str[slen - 1] != ' ') {
4168  but->str[slen] = ' ';
4169  but->str[slen + 1] = 0;
4170  }
4171  }
4172  }
4173 
4174  if (block->flag & UI_BLOCK_RADIAL) {
4175  but->drawflag |= UI_BUT_TEXT_LEFT;
4176  if (but->str && but->str[0]) {
4177  but->drawflag |= UI_BUT_ICON_LEFT;
4178  }
4179  }
4180  else if (((block->flag & UI_BLOCK_LOOP) && !ui_block_is_popover(block) &&
4181  !(block->flag & UI_BLOCK_QUICK_SETUP)) ||
4182  ELEM(but->type,
4183  UI_BTYPE_MENU,
4184  UI_BTYPE_TEXT,
4189  UI_BTYPE_POPOVER)) {
4191  }
4192 #ifdef USE_NUMBUTS_LR_ALIGN
4193  else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
4194  if (slen != 0) {
4195  but->drawflag |= UI_BUT_TEXT_LEFT;
4196  }
4197  }
4198 #endif
4199 
4200  but->drawflag |= (block->flag & UI_BUT_ALIGN);
4201 
4202  if (block->lock == true) {
4203  but->flag |= UI_BUT_DISABLED;
4204  }
4205 
4206  /* keep track of UI_interface.h */
4207  if (ELEM(but->type,
4209  UI_BTYPE_BUT,
4217  UI_BTYPE_GRIP,
4218  UI_BTYPE_SEPR,
4221  (but->type >= UI_BTYPE_SEARCH_MENU)) {
4222  /* pass */
4223  }
4224  else {
4225  but->flag |= UI_BUT_UNDO;
4226  }
4227 
4228  BLI_addtail(&block->buttons, but);
4229 
4230  if (block->curlayout) {
4231  ui_layout_add_but(block->curlayout, but);
4232  }
4233 
4234 #ifdef WITH_PYTHON
4235  /* If the 'UI_OT_editsource' is running, extract the source info from the button. */
4238  }
4239 #endif
4240 
4241  return but;
4242 }
4243 
4244 void ui_def_but_icon(uiBut *but, const int icon, const int flag)
4245 {
4246  if (icon) {
4247  ui_icon_ensure_deferred(static_cast<const bContext *>(but->block->evil_C),
4248  icon,
4249  (flag & UI_BUT_ICON_PREVIEW) != 0);
4250  }
4251  but->icon = (BIFIconID)icon;
4252  but->flag |= flag;
4253 
4254  if (but->str && but->str[0]) {
4255  but->drawflag |= UI_BUT_ICON_LEFT;
4256  }
4257 }
4258 
4260 {
4261  but->icon = ICON_NONE;
4262  but->flag &= ~UI_HAS_ICON;
4263  but->drawflag &= ~UI_BUT_ICON_LEFT;
4264 }
4265 
4266 static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p)
4267 {
4268  uiBlock *block = uiLayoutGetBlock(layout);
4269  uiPopupBlockHandle *handle = block->handle;
4270  uiBut *but = (uiBut *)but_p;
4271 
4272  /* see comment in ui_item_enum_expand, re: `uiname`. */
4273  const EnumPropertyItem *item_array;
4274 
4276 
4277  bool free;
4278  RNA_property_enum_items_gettexted(static_cast<bContext *>(block->evil_C),
4279  &but->rnapoin,
4280  but->rnaprop,
4281  &item_array,
4282  nullptr,
4283  &free);
4284 
4285  /* We don't want nested rows, cols in menus. */
4286  UI_block_layout_set_current(block, layout);
4287 
4288  int totitems = 0;
4289  int categories = 0;
4290  int entries_nosepr_count = 0;
4291  for (const EnumPropertyItem *item = item_array; item->identifier; item++, totitems++) {
4292  if (!item->identifier[0]) {
4293  /* inconsistent, but menus with categories do not look good flipped */
4294  if (item->name) {
4295  block->flag |= UI_BLOCK_NO_FLIP;
4296  categories++;
4297  entries_nosepr_count++;
4298  }
4299  /* We do not want simple separators in `entries_nosepr_count`. */
4300  continue;
4301  }
4302  entries_nosepr_count++;
4303  }
4304 
4305  /* Columns and row estimation. Ignore simple separators here. */
4306  int columns = (entries_nosepr_count + 20) / 20;
4307  if (columns < 1) {
4308  columns = 1;
4309  }
4310  if (columns > 8) {
4311  columns = (entries_nosepr_count + 25) / 25;
4312  }
4313 
4314  int rows = totitems / columns;
4315  if (rows < 1) {
4316  rows = 1;
4317  }
4318  while (rows * columns < totitems) {
4319  rows++;
4320  }
4321 
4322  const char *title = RNA_property_ui_name(but->rnaprop);
4323 
4324  if (title[0] && (categories == 0) && (block->flag & UI_BLOCK_NO_FLIP)) {
4325  /* Title at the top for menus with categories. */
4326  uiDefBut(block,
4328  0,
4329  title,
4330  0,
4331  0,
4332  UI_UNIT_X * 5,
4333  UI_UNIT_Y,
4334  nullptr,
4335  0.0,
4336  0.0,
4337  0,
4338  0,
4339  "");
4340  uiItemS(layout);
4341  }
4342 
4343  /* NOTE: `item_array[...]` is reversed on access. */
4344 
4345  /* create items */
4346  uiLayout *split = uiLayoutSplit(layout, 0.0f, false);
4347 
4348  bool new_column;
4349 
4350  int column_end = 0;
4351  uiLayout *column = nullptr;
4352  for (int a = 0; a < totitems; a++) {
4353  new_column = (a == column_end);
4354  if (new_column) {
4355  /* start new column, and find out where it ends in advance, so we
4356  * can flip the order of items properly per column */
4357  column_end = totitems;
4358 
4359  for (int b = a + 1; b < totitems; b++) {
4360  const EnumPropertyItem *item = &item_array[b];
4361 
4362  /* new column on N rows or on separation label */
4363  if (((b - a) % rows == 0) || (!item->identifier[0] && item->name)) {
4364  column_end = b;
4365  break;
4366  }
4367  }
4368 
4369  column = uiLayoutColumn(split, false);
4370  }
4371 
4372  const EnumPropertyItem *item = &item_array[a];
4373 
4374  if (new_column && (categories > 0) && item->identifier[0]) {
4375  uiItemL(column, "", ICON_NONE);
4376  uiItemS(column);
4377  }
4378 
4379  if (!item->identifier[0]) {
4380  if (item->name) {
4381  if (item->icon) {
4382  uiItemL(column, item->name, item->icon);
4383  }
4384  else {
4385  /* Do not use uiItemL here, as our root layout is a menu one,
4386  * it will add a fake blank icon! */
4387  uiDefBut(block,
4389  0,
4390  item->name,
4391  0,
4392  0,
4393  UI_UNIT_X * 5,
4394  UI_UNIT_Y,
4395  nullptr,
4396  0.0,
4397  0.0,
4398  0,
4399  0,
4400  "");
4401  }
4402  }
4403  uiItemS(column);
4404  }
4405  else {
4406  if (item->icon) {
4407  uiDefIconTextButI(block,
4409  B_NOP,
4410  item->icon,
4411  item->name,
4412  0,
4413  0,
4414  UI_UNIT_X * 5,
4415  UI_UNIT_Y,
4416  &handle->retvalue,
4417  item->value,
4418  0.0,
4419  0,
4420  -1,
4421  item->description);
4422  }
4423  else {
4424  uiDefButI(block,
4426  B_NOP,
4427  item->name,
4428  0,
4429  0,
4430  UI_UNIT_X * 5,
4431  UI_UNIT_X,
4432  &handle->retvalue,
4433  item->value,
4434  0.0,
4435  0,
4436  -1,
4437  item->description);
4438  }
4439  }
4440  }
4441 
4442  if (title[0] && (categories == 0) && !(block->flag & UI_BLOCK_NO_FLIP)) {
4443  /* Title at the bottom for menus without categories. */
4444  uiItemS(layout);
4445  uiDefBut(block,
4447  0,
4448  title,
4449  0,
4450  0,
4451  UI_UNIT_X * 5,
4452  UI_UNIT_Y,
4453  nullptr,
4454  0.0,
4455  0.0,
4456  0,
4457  0,
4458  "");
4459  }
4460 
4461  UI_block_layout_set_current(block, layout);
4462 
4463  if (free) {
4464  MEM_freeN((void *)item_array);
4465  }
4466  BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0);
4467  block->flag |= UI_BLOCK_IS_FLIP;
4468 }
4469 
4470 static void ui_def_but_rna__panel_type(bContext *C, uiLayout *layout, void *but_p)
4471 {
4472  uiBut *but = static_cast<uiBut *>(but_p);
4473  const char *panel_type = static_cast<const char *>(but->func_argN);
4474  PanelType *pt = WM_paneltype_find(panel_type, true);
4475  if (pt) {
4476  ui_item_paneltype_func(C, layout, pt);
4477  }
4478  else {
4479  char msg[256];
4480  SNPRINTF(msg, TIP_("Missing Panel: %s"), panel_type);
4481  uiItemL(layout, msg, ICON_NONE);
4482  }
4483 }
4484 
4485 void ui_but_rna_menu_convert_to_panel_type(uiBut *but, const char *panel_type)
4486 {
4488  // BLI_assert(but->menu_create_func == ui_def_but_rna__menu);
4489  // BLI_assert((void *)but->poin == but);
4491  but->func_argN = BLI_strdup(panel_type);
4492 }
4493 
4495 {
4497 }
4498 
4499 static void ui_def_but_rna__menu_type(bContext *C, uiLayout *layout, void *but_p)
4500 {
4501  uiBut *but = static_cast<uiBut *>(but_p);
4502  const char *menu_type = static_cast<const char *>(but->func_argN);
4503  MenuType *mt = WM_menutype_find(menu_type, true);
4504  if (mt) {
4505  ui_item_menutype_func(C, layout, mt);
4506  }
4507  else {
4508  char msg[256];
4509  SNPRINTF(msg, TIP_("Missing Menu: %s"), menu_type);
4510  uiItemL(layout, msg, ICON_NONE);
4511  }
4512 }
4513 
4514 void ui_but_rna_menu_convert_to_menu_type(uiBut *but, const char *menu_type)
4515 {
4516  BLI_assert(but->type == UI_BTYPE_MENU);
4518  BLI_assert((void *)but->poin == but);
4520  but->func_argN = BLI_strdup(menu_type);
4521 }
4522 
4523 static void ui_but_submenu_enable(uiBlock *block, uiBut *but)
4524 {
4525  but->flag |= UI_BUT_ICON_SUBMENU;
4527 }
4528 
4538  int type,
4539  int retval,
4540  const char *str,
4541  int x,
4542  int y,
4543  short width,
4544  short height,
4545  PointerRNA *ptr,
4546  PropertyRNA *prop,
4547  int index,
4548  float min,
4549  float max,
4550  float a1,
4551  float a2,
4552  const char *tip)
4553 {
4554  const PropertyType proptype = RNA_property_type(prop);
4555  int icon = 0;
4556  uiMenuCreateFunc func = nullptr;
4557  const bool always_set_a1_a2 = ELEM(type, UI_BTYPE_NUM);
4558 
4560  BLI_assert(index == -1);
4561  }
4562 
4563  /* use rna values if parameters are not specified */
4564  if ((proptype == PROP_ENUM) && ELEM(type, UI_BTYPE_MENU, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
4565  bool free;
4566  const EnumPropertyItem *item;
4568  static_cast<bContext *>(block->evil_C), ptr, prop, &item, nullptr, &free);
4569 
4570  int value;
4571  /* UI_BTYPE_MENU is handled a little differently here */
4572  if (type == UI_BTYPE_MENU) {
4573  value = RNA_property_enum_get(ptr, prop);
4574  }
4575  else {
4576  value = (int)max;
4577  }
4578 
4579  const int i = RNA_enum_from_value(item, value);
4580  if (i != -1) {
4581 
4582  if (!str) {
4583  str = item[i].name;
4584 #ifdef WITH_INTERNATIONAL
4586 #endif
4587  }
4588 
4589  icon = item[i].icon;
4590  }
4591  else {
4592  if (!str) {
4593  if (type == UI_BTYPE_MENU) {
4594  str = "";
4595  }
4596  else {
4597  str = RNA_property_ui_name(prop);
4598  }
4599  }
4600  }
4601 
4602  if (type == UI_BTYPE_MENU) {
4603  func = ui_def_but_rna__menu;
4604  }
4605 
4606  if (free) {
4607  MEM_freeN((void *)item);
4608  }
4609  }
4610  else {
4611  if (!str) {
4612  str = RNA_property_ui_name(prop);
4613  }
4614  icon = RNA_property_ui_icon(prop);
4615  }
4616 
4617  if (!tip && proptype != PROP_ENUM) {
4618  tip = RNA_property_ui_description(prop);
4619  }
4620 
4621  if (min == max || a1 == -1 || a2 == -1 || always_set_a1_a2) {
4622  if (proptype == PROP_INT) {
4623  int hardmin, hardmax, softmin, softmax, step;
4624 
4625  RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
4626  RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
4627 
4628  if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
4629  min = hardmin;
4630  max = hardmax;
4631  }
4632  if (a1 == -1 || always_set_a1_a2) {
4633  a1 = step;
4634  }
4635  if (a2 == -1 || always_set_a1_a2) {
4636  a2 = 0;
4637  }
4638  }
4639  else if (proptype == PROP_FLOAT) {
4640  float hardmin, hardmax, softmin, softmax, step, precision;
4641 
4642  RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
4643  RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
4644 
4645  if (!ELEM(type, UI_BTYPE_ROW, UI_BTYPE_LISTROW) && min == max) {
4646  min = hardmin;
4647  max = hardmax;
4648  }
4649  if (a1 == -1 || always_set_a1_a2) {
4650  a1 = step;
4651  }
4652  if (a2 == -1 || always_set_a1_a2) {
4653  a2 = precision;
4654  }
4655  }
4656  else if (proptype == PROP_STRING) {
4657  min = 0;
4659  /* NOTE: 'max' may be zero (code for dynamically resized array). */
4660  }
4661  }
4662 
4663  /* now create button */
4664  uiBut *but = ui_def_but(
4665  block, type, retval, str, x, y, width, height, nullptr, min, max, a1, a2, tip);
4666 
4667  if (but->type == UI_BTYPE_NUM) {
4668  /* Set default values, can be overridden later. */
4669  UI_but_number_step_size_set(but, a1);
4670  UI_but_number_precision_set(but, a2);
4671  }
4672 
4673  but->rnapoin = *ptr;
4674  but->rnaprop = prop;
4675 
4676  if (RNA_property_array_check(but->rnaprop)) {
4677  but->rnaindex = index;
4678  }
4679  else {
4680  but->rnaindex = 0;
4681  }
4682 
4683  if (icon) {
4684  ui_def_but_icon(but, icon, UI_HAS_ICON);
4685  }
4686 
4687  if (type == UI_BTYPE_MENU) {
4688  if (but->emboss == UI_EMBOSS_PULLDOWN) {
4689  ui_but_submenu_enable(block, but);
4690  }
4691  }
4692  else if (type == UI_BTYPE_SEARCH_MENU) {
4693  if (proptype == PROP_POINTER) {
4694  /* Search buttons normally don't get undo, see: T54580. */
4695  but->flag |= UI_BUT_UNDO;
4696  }
4697  }
4698 
4699  const char *info;
4700  if (but->rnapoin.data && !RNA_property_editable_info(&but->rnapoin, prop, &info)) {
4701  UI_but_disable(but, info);
4702  }
4703 
4704  if (proptype == PROP_POINTER) {
4705  /* If the button shows an ID, automatically set it as focused in context so operators can
4706  * access it. */
4707  const PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
4708  if (pptr.data && RNA_struct_is_ID(pptr.type)) {
4709  but->context = CTX_store_add(&block->contexts, "id", &pptr);
4710  }
4711  }
4712 
4713  if (but->flag & UI_BUT_UNDO && (ui_but_is_rna_undo(but) == false)) {
4714  but->flag &= ~UI_BUT_UNDO;
4715  }
4716 
4717  /* If this button uses units, calculate the step from this */
4718  if ((proptype == PROP_FLOAT) && ui_but_is_unit(but)) {
4719  if (type == UI_BTYPE_NUM) {
4720  uiButNumber *number_but = (uiButNumber *)but;
4721  number_but->step_size = ui_get_but_step_unit(but, number_but->step_size);
4722  }
4723  else {
4724  but->a1 = ui_get_but_step_unit(but, but->a1);
4725  }
4726  }
4727 
4728  if (func) {
4729  but->menu_create_func = func;
4730  but->poin = (char *)but;
4731  }
4732 
4733  return but;
4734 }
4735 
4737  int type,
4738  int retval,
4739  const char *str,
4740  int x,
4741  int y,
4742  short width,
4743  short height,
4744  PointerRNA *ptr,
4745  const char *propname,
4746  int index,
4747  float min,
4748  float max,
4749  float a1,
4750  float a2,
4751  const char *tip)
4752 {
4753  PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
4754 
4755  uiBut *but;
4756  if (prop) {
4757  but = ui_def_but_rna(
4758  block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
4759  }
4760  else {
4761  but = ui_def_but(
4762  block, type, retval, propname, x, y, width, height, nullptr, min, max, a1, a2, tip);
4763 
4764  UI_but_disable(but, "Unknown Property.");
4765  }
4766 
4767  return but;
4768 }
4769 
4771  int type,
4772  wmOperatorType *ot,
4773  wmOperatorCallContext opcontext,
4774  const char *str,
4775  int x,
4776  int y,
4777  short width,
4778  short height,
4779  const char *tip)
4780 {
4781  if (!str) {
4782  if (ot && ot->srna) {
4783  str = WM_operatortype_name(ot, nullptr);
4784  }
4785  else {
4786  str = "";
4787  }
4788  }
4789 
4790  if ((!tip || tip[0] == '\0') && ot && ot->srna && !ot->get_description) {
4792  }
4793 
4794  uiBut *but = ui_def_but(block, type, -1, str, x, y, width, height, nullptr, 0, 0, 0, 0, tip);
4795  but->optype = ot;
4796  but->opcontext = opcontext;
4797  but->flag &= ~UI_BUT_UNDO; /* no need for ui_but_is_rna_undo(), we never need undo here */
4798 
4799  if (!ot) {
4800  UI_but_disable(but, "");
4801  }
4802 
4803  return but;
4804 }
4805 
4807  int type,
4808  int retval,
4809  const char *str,
4810  int x,
4811  int y,
4812  short width,
4813  short height,
4814  void *poin,
4815  float min,
4816  float max,
4817  float a1,
4818  float a2,
4819  const char *tip)
4820 {
4821  uiBut *but = ui_def_but(
4822  block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
4823 
4824  ui_but_update(but);
4825 
4826  return but;
4827 }
4828 
4830  uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4])
4831 {
4832  uiBut *but = ui_def_but(
4833  block, UI_BTYPE_IMAGE, 0, "", x, y, width, height, imbuf, 0, 0, 0, 0, "");
4834  if (color) {
4835  copy_v4_v4_uchar(but->col, color);
4836  }
4837  else {
4838  but->col[0] = 255;
4839  but->col[1] = 255;
4840  but->col[2] = 255;
4841  but->col[3] = 255;
4842  }
4843  ui_but_update(but);
4844  return but;
4845 }
4846 
4847 uiBut *uiDefButAlert(uiBlock *block, int icon, int x, int y, short width, short height)
4848 {
4849  struct ImBuf *ibuf = UI_icon_alert_imbuf_get((eAlertIcon)icon);
4850  bTheme *btheme = UI_GetTheme();
4851  return uiDefButImage(block, ibuf, x, y, width, height, btheme->tui.wcol_menu_back.text);
4852 }
4853 
4863 static int findBitIndex(uint x)
4864 {
4865  if (!x || !is_power_of_2_i(x)) { /* is_power_of_2_i(x) strips lowest bit */
4866  return -1;
4867  }
4868  int idx = 0;
4869 
4870  if (x & 0xFFFF0000) {
4871  idx += 16;
4872  x >>= 16;
4873  }
4874  if (x & 0xFF00) {
4875  idx += 8;
4876  x >>= 8;
4877  }
4878  if (x & 0xF0) {
4879  idx += 4;
4880  x >>= 4;
4881  }
4882  if (x & 0xC) {
4883  idx += 2;
4884  x >>= 2;
4885  }
4886  if (x & 0x2) {
4887  idx += 1;
4888  }
4889 
4890  return idx;
4891 }
4892 
4893 /* Auto-complete helper functions. */
4895  size_t maxlen;
4896  int matches;
4897  char *truncate;
4898  const char *startname;
4899 };
4900 
4901 AutoComplete *UI_autocomplete_begin(const char *startname, size_t maxlen)
4902 {
4903  AutoComplete *autocpl;
4904 
4905  autocpl = MEM_cnew<AutoComplete>(__func__);
4906  autocpl->maxlen = maxlen;
4907  autocpl->matches = 0;
4908  autocpl->truncate = static_cast<char *>(MEM_callocN(sizeof(char) * maxlen, __func__));
4909  autocpl->startname = startname;
4910 
4911  return autocpl;
4912 }
4913 
4914 void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name)
4915 {
4916  char *truncate = autocpl->truncate;
4917  const char *startname = autocpl->startname;
4918  int match_index = 0;
4919  for (int a = 0; a < autocpl->maxlen - 1; a++) {
4920  if (startname[a] == 0 || startname[a] != name[a]) {
4921  match_index = a;
4922  break;
4923  }
4924  }
4925 
4926  /* found a match */
4927  if (startname[match_index] == 0) {
4928  autocpl->matches++;
4929  /* first match */
4930  if (truncate[0] == 0) {
4931  BLI_strncpy(truncate, name, autocpl->maxlen);
4932  }
4933  else {
4934  /* remove from truncate what is not in bone->name */
4935  for (int a = 0; a < autocpl->maxlen - 1; a++) {
4936  if (name[a] == 0) {
4937  truncate[a] = 0;
4938  break;
4939  }
4940  if (truncate[a] != name[a]) {
4941  truncate[a] = 0;
4942  }
4943  }
4944  }
4945  }
4946 }
4947 
4948 int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
4949 {
4950  int match = AUTOCOMPLETE_NO_MATCH;
4951  if (autocpl->truncate[0]) {
4952  if (autocpl->matches == 1) {
4953  match = AUTOCOMPLETE_FULL_MATCH;
4954  }
4955  else {
4957  }
4958  BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen);
4959  }
4960  else {
4961  if (autoname != autocpl->startname) { /* don't copy a string over itself */
4962  BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen);
4963  }
4964  }
4965 
4966  MEM_freeN(autocpl->truncate);
4967  MEM_freeN(autocpl);
4968  return match;
4969 }
4970 
4971 #define PREVIEW_TILE_PAD (0.15f * UI_UNIT_X)
4972 
4974 {
4975  const float pad = PREVIEW_TILE_PAD;
4976  return round_fl_to_int((96.0f / 20.0f) * UI_UNIT_X + 2.0f * pad);
4977 }
4978 
4980 {
4981  const uiStyle *style = UI_style_get();
4982  const float font_height = style->widget.points * UI_DPI_FAC;
4983  const float pad = PREVIEW_TILE_PAD;
4984 
4985  return round_fl_to_int(UI_preview_tile_size_y_no_label() + font_height +
4986  /* Add some extra padding to make things less tight vertically. */
4987  pad);
4988 }
4989 
4991 {
4992  const float pad = PREVIEW_TILE_PAD;
4993  return round_fl_to_int((96.0f / 20.0f) * UI_UNIT_Y + 2.0f * pad);
4994 }
4995 
4996 #undef PREVIEW_TILE_PAD
4997 
4998 static void ui_but_update_and_icon_set(uiBut *but, int icon)
4999 {
5000  if (icon) {
5001  ui_def_but_icon(but, icon, UI_HAS_ICON);
5002  }
5003 
5004  ui_but_update(but);
5005 }
5006 
5007 static uiBut *uiDefButBit(uiBlock *block,
5008  int type,
5009  int bit,
5010  int retval,
5011  const char *str,
5012  int x,
5013  int y,
5014  short width,
5015  short height,
5016  void *poin,
5017  float min,
5018  float max,
5019  float a1,
5020  float a2,
5021  const char *tip)
5022 {
5023  const int bitIdx = findBitIndex(bit);
5024  if (bitIdx == -1) {
5025  return nullptr;
5026  }
5027  return uiDefBut(block,
5028  type | UI_BUT_POIN_BIT | bitIdx,
5029  retval,
5030  str,
5031  x,
5032  y,
5033  width,
5034  height,
5035  poin,
5036  min,
5037  max,
5038  a1,
5039  a2,
5040  tip);
5041 }
5043  int type,
5044  int retval,
5045  const char *str,
5046  int x,
5047  int y,
5048  short width,
5049  short height,
5050  float *poin,
5051  float min,
5052  float max,
5053  float a1,
5054  float a2,
5055  const char *tip)
5056 {
5057  return uiDefBut(block,
5059  retval,
5060  str,
5061  x,
5062  y,
5063  width,
5064  height,
5065  (void *)poin,
5066  min,
5067  max,
5068  a1,
5069  a2,
5070  tip);
5071 }
5073  int type,
5074  int retval,
5075  const char *str,
5076  int x,
5077  int y,
5078  short width,
5079  short height,
5080  int *poin,
5081  float min,
5082  float max,
5083  float a1,
5084  float a2,
5085  const char *tip)
5086 {
5087  return uiDefBut(block,
5089  retval,
5090  str,
5091  x,
5092  y,
5093  width,
5094  height,
5095  (void *)poin,
5096  min,
5097  max,
5098  a1,
5099  a2,
5100  tip);
5101 }
5103  int type,
5104  int bit,
5105  int retval,
5106  const char *str,
5107  int x,
5108  int y,
5109  short width,
5110  short height,
5111  int *poin,
5112  float min,
5113  float max,
5114  float a1,
5115  float a2,
5116  const char *tip)
5117 {
5118  return uiDefButBit(block,
5120  bit,
5121  retval,
5122  str,
5123  x,
5124  y,
5125  width,
5126  height,
5127  (void *)poin,
5128  min,
5129  max,
5130  a1,
5131  a2,
5132  tip);
5133 }
5135  int type,
5136  int retval,
5137  const char *str,
5138  int x,
5139  int y,
5140  short width,
5141  short height,
5142  short *poin,
5143  float min,
5144  float max,
5145  float a1,
5146  float a2,
5147  const char *tip)
5148 {
5149  return uiDefBut(block,
5151  retval,
5152  str,
5153  x,
5154  y,
5155  width,
5156  height,
5157  (void *)poin,
5158  min,
5159  max,
5160  a1,
5161  a2,
5162  tip);
5163 }
5165  int type,
5166  int bit,
5167  int retval,
5168  const char *str,
5169  int x,
5170  int y,
5171  short width,
5172  short height,
5173  short *poin,
5174  float min,
5175  float max,
5176  float a1,
5177  float a2,
5178  const char *tip)
5179 {
5180  return uiDefButBit(block,
5182  bit,
5183  retval,
5184  str,
5185  x,
5186  y,
5187  width,
5188  height,
5189  (void *)poin,
5190  min,
5191  max,
5192  a1,
5193  a2,
5194  tip);
5195 }
5197  int type,
5198  int retval,
5199  const char *str,
5200  int x,
5201  int y,
5202  short width,
5203  short height,
5204  char *poin,
5205  float min,
5206  float max,
5207  float a1,
5208  float a2,
5209  const char *tip)
5210 {
5211  return uiDefBut(block,
5213  retval,
5214  str,
5215  x,
5216  y,
5217  width,
5218  height,
5219  (void *)poin,
5220  min,
5221  max,
5222  a1,
5223  a2,
5224  tip);
5225 }
5227  int type,
5228  int bit,
5229  int retval,
5230  const char *str,
5231  int x,
5232  int y,
5233  short width,
5234  short height,
5235  char *poin,
5236  float min,
5237  float max,
5238  float a1,
5239  float a2,
5240  const char *tip)
5241 {
5242  return uiDefButBit(block,
5244  bit,
5245  retval,
5246  str,
5247  x,
5248  y,
5249  width,
5250  height,
5251  (void *)poin,
5252  min,
5253  max,
5254  a1,
5255  a2,
5256  tip);
5257 }
5259  int type,
5260  int retval,
5261  const char *str,
5262  int x,
5263  int y,
5264  short width,
5265  short height,
5266  PointerRNA *ptr,
5267  const char *propname,
5268  int index,
5269  float min,
5270  float max,
5271  float a1,
5272  float a2,
5273  const char *tip)
5274 {
5276  block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
5277  ui_but_update(but);
5278  return but;
5279 }
5281  int type,
5282  int retval,
5283  const char *str,
5284  int x,
5285  int y,
5286  short width,
5287  short height,
5288  PointerRNA *ptr,
5289  PropertyRNA *prop,
5290  int index,
5291  float min,
5292  float max,
5293  float a1,
5294  float a2,
5295  const char *tip)
5296 {
5297  uiBut *but = ui_def_but_rna(
5298  block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
5299  ui_but_update(but);
5300  return but;
5301 }
5302 
5304  int type,
5305  wmOperatorType *ot,
5306  wmOperatorCallContext opcontext,
5307  const char *str,
5308  int x,
5309  int y,
5310  short width,
5311  short height,
5312  const char *tip)
5313 {
5314  uiBut *but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
5315  ui_but_update(but);
5316  return but;
5317 }
5319  int type,
5320  const char *opname,
5321  wmOperatorCallContext opcontext,
5322  const char *str,
5323  int x,
5324  int y,
5325  short width,
5326  short height,
5327  const char *tip)
5328 {
5329  wmOperatorType *ot = WM_operatortype_find(opname, false);
5330  if (str == nullptr && ot == nullptr) {
5331  str = opname;
5332  }
5333  return uiDefButO_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
5334 }
5335 
5337  int type,
5338  int retval,
5339  int icon,
5340  int x,
5341  int y,
5342  short width,
5343  short height,
5344  void *poin,
5345  float min,
5346  float max,
5347  float a1,
5348  float a2,
5349  const char *tip)
5350 {
5351  uiBut *but = ui_def_but(
5352  block, type, retval, "", x, y, width, height, poin, min, max, a1, a2, tip);
5353  ui_but_update_and_icon_set(but, icon);
5354  return but;
5355 }
5357  int type,
5358  int bit,
5359  int retval,
5360  int icon,
5361  int x,
5362  int y,
5363  short width,
5364  short height,
5365  void *poin,
5366  float min,
5367  float max,
5368  float a1,
5369  float a2,
5370  const char *tip)
5371 {
5372  const int bitIdx = findBitIndex(bit);
5373  if (bitIdx == -1) {
5374  return nullptr;
5375  }
5376  return uiDefIconBut(block,
5377  type | UI_BUT_POIN_BIT | bitIdx,
5378  retval,
5379  icon,
5380  x,
5381  y,
5382  width,
5383  height,
5384  poin,
5385  min,
5386  max,
5387  a1,
5388  a2,
5389  tip);
5390 }
5391 
5393  int type,
5394  int retval,
5395  int icon,
5396  int x,
5397  int y,
5398  short width,
5399  short height,
5400  int *poin,
5401  float min,
5402  float max,
5403  float a1,
5404  float a2,
5405  const char *tip)
5406 {
5407  return uiDefIconBut(block,
5409  retval,
5410  icon,
5411  x,
5412  y,
5413  width,
5414  height,
5415  (void *)poin,
5416  min,
5417  max,
5418  a1,
5419  a2,
5420  tip);
5421 }
5423  int type,
5424  int bit,
5425  int retval,
5426  int icon,
5427  int x,
5428  int y,
5429  short width,
5430  short height,
5431  int *poin,
5432  float min,
5433  float max,
5434  float a1,
5435  float a2,
5436  const char *tip)
5437 {
5438  return uiDefIconButBit(block,
5440  bit,
5441  retval,
5442  icon,
5443  x,
5444  y,
5445  width,
5446  height,
5447  (void *)poin,
5448  min,
5449  max,
5450  a1,
5451  a2,
5452  tip);
5453 }
5455  int type,
5456  int retval,
5457  int icon,
5458  int x,
5459  int y,
5460  short width,
5461  short height,
5462  short *poin,
5463  float min,
5464  float max,
5465  float a1,
5466  float a2,
5467  const char *tip)
5468 {
5469  return uiDefIconBut(block,
5471  retval,
5472  icon,
5473  x,
5474  y,
5475  width,
5476  height,
5477  (void *)poin,
5478  min,
5479  max,
5480  a1,
5481  a2,
5482  tip);
5483 }
5485  int type,
5486  int bit,
5487  int retval,
5488  int icon,
5489  int x,
5490  int y,
5491  short width,
5492  short height,
5493  short *poin,
5494  float min,
5495  float max,
5496  float a1,
5497  float a2,
5498  const char *tip)
5499 {
5500  return uiDefIconButBit(block,
5502  bit,
5503  retval,
5504  icon,
5505  x,
5506  y,
5507  width,
5508  height,
5509  (void *)poin,
5510  min,
5511  max,
5512  a1,
5513  a2,
5514  tip);
5515 }
5517  int type,
5518  int bit,
5519  int retval,
5520  int icon,
5521  int x,
5522  int y,
5523  short width,
5524  short height,
5525  char *poin,
5526  float min,
5527  float max,
5528  float a1,
5529  float a2,
5530  const char *tip)
5531 {
5532  return uiDefIconButBit(block,
5534  bit,
5535  retval,
5536  icon,
5537  x,
5538  y,
5539  width,
5540  height,
5541  (void *)poin,
5542  min,
5543  max,
5544  a1,
5545  a2,
5546  tip);
5547 }
5549  int type,
5550  int retval,
5551  int icon,
5552  int x,
5553  int y,
5554  short width,
5555  short height,
5556  PointerRNA *ptr,
5557  const char *propname,
5558  int index,
5559  float min,
5560  float max,
5561  float a1,
5562  float a2,
5563  const char *tip)
5564 {
5566  block, type, retval, "", x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
5567  ui_but_update_and_icon_set(but, icon);
5568  return but;
5569 }
5571  int type,
5572  int retval,
5573  int icon,
5574  int x,
5575  int y,
5576  short width,
5577  short height,
5578  PointerRNA *ptr,
5579  PropertyRNA *prop,
5580  int index,
5581  float min,
5582  float max,
5583  float a1,
5584  float a2,
5585  const char *tip)
5586 {
5587  uiBut *but = ui_def_but_rna(
5588  block, type, retval, "", x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
5589  ui_but_update_and_icon_set(but, icon);
5590  return but;
5591 }
5592 
5594  int type,
5595  wmOperatorType *ot,
5596  wmOperatorCallContext opcontext,
5597  int icon,
5598  int x,
5599  int y,
5600  short width,
5601  short height,
5602  const char *tip)
5603 {
5604  uiBut *but = ui_def_but_operator_ptr(block, type, ot, opcontext, "", x, y, width, height, tip);
5605  ui_but_update_and_icon_set(but, icon);
5606  return but;
5607 }
5609  int type,
5610  const char *opname,
5611  wmOperatorCallContext opcontext,
5612  int icon,
5613  int x,
5614  int y,
5615  short width,
5616  short height,
5617  const char *tip)
5618 {
5619  wmOperatorType *ot = WM_operatortype_find(opname, false);
5620  return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, tip);
5621 }
5622 
5624  int type,
5625  int retval,
5626  int icon,
5627  const char *str,
5628  int x,
5629  int y,
5630  short width,
5631  short height,
5632  void *poin,
5633  float min,
5634  float max,
5635  float a1,
5636  float a2,
5637  const char *tip)
5638 {
5639  uiBut *but = ui_def_but(
5640  block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip);
5641  ui_but_update_and_icon_set(but, icon);
5642  but->drawflag |= UI_BUT_ICON_LEFT;
5643  return but;
5644 }
5646  int type,
5647  int retval,
5648  int icon,
5649  const char *str,
5650  int x,
5651  int y,
5652  short width,
5653  short height,
5654  float *poin,
5655  float min,
5656  float max,
5657  float a1,
5658  float a2,
5659  const char *tip)
5660 {
5661  return uiDefIconTextBut(block,
5663  retval,
5664  icon,
5665  str,
5666  x,
5667  y,
5668  width,
5669  height,
5670  (void *)poin,
5671  min,
5672  max,
5673  a1,
5674  a2,
5675  tip);
5676 }
5678  int type,
5679  int retval,
5680  int icon,
5681  const char *str,
5682  int x,
5683  int y,
5684  short width,
5685  short height,
5686  int *poin,
5687  float min,
5688  float max,
5689  float a1,
5690  float a2,
5691  const char *tip)
5692 {
5693  return uiDefIconTextBut(block,
5695  retval,
5696  icon,
5697  str,
5698  x,
5699  y,
5700  width,
5701  height,
5702  (void *)poin,
5703  min,
5704  max,
5705  a1,
5706  a2,
5707  tip);
5708 }
5710  int type,
5711  int retval,
5712  int icon,
5713  const char *str,
5714  int x,
5715  int y,
5716  short width,
5717  short height,
5718  PointerRNA *ptr,
5719  const char *propname,
5720  int index,
5721  float min,
5722  float max,
5723  float a1,
5724  float a2,
5725  const char *tip)
5726 {
5728  block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip);
5729  ui_but_update_and_icon_set(but, icon);
5730  but->drawflag |= UI_BUT_ICON_LEFT;
5731  return but;
5732 }
5734  int type,
5735  int retval,
5736  int icon,
5737  const char *str,
5738  int x,
5739  int y,
5740  short width,
5741  short height,
5742  PointerRNA *ptr,
5743  PropertyRNA *prop,
5744  int index,
5745  float min,
5746  float max,
5747  float a1,
5748  float a2,
5749  const char *tip)
5750 {
5751  uiBut *but = ui_def_but_rna(
5752  block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip);
5753  ui_but_update_and_icon_set(but, icon);
5754  but->drawflag |= UI_BUT_ICON_LEFT;
5755  return but;
5756 }
5758  int type,
5759  wmOperatorType *ot,
5760  wmOperatorCallContext opcontext,
5761  int icon,
5762  const char *str,
5763  int x,
5764  int y,
5765  short width,
5766  short height,
5767  const char *tip)
5768 {
5769  uiBut *but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip);
5770  ui_but_update_and_icon_set(but, icon);
5771  but->drawflag |= UI_BUT_ICON_LEFT;
5772  return but;
5773 }
5775  int type,
5776  const char *opname,
5777  wmOperatorCallContext opcontext,
5778  int icon,
5779  const char *str,
5780  int x,
5781  int y,
5782  short width,
5783  short height,
5784  const char *tip)
5785 {
5786  wmOperatorType *ot = WM_operatortype_find(opname, false);
5787  if (str && str[0] == '\0') {
5788  return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, tip);
5789  }
5790  return uiDefIconTextButO_ptr(block, type, ot, opcontext, icon, str, x, y, width, height, tip);
5791 }
5792 
5793 /* END Button containing both string label and icon */
5794 
5795 /* cruft to make uiBlock and uiBut private */
5796 
5798 {
5799  int min = 0;
5800 
5801  LISTBASE_FOREACH (uiBlock *, block, lb) {
5802  if (block == lb->first || block->rect.ymin < min) {
5803  min = block->rect.ymin;
5804  }
5805  }
5806 
5807  return min;
5808 }
5809 
5810 void UI_block_direction_set(uiBlock *block, char direction)
5811 {
5812  block->direction = direction;
5813 }
5814 
5816 {
5817  float centy, miny = 10000, maxy = -10000;
5818 
5819  if (U.uiflag & USER_MENUFIXEDORDER) {
5820  return;
5821  }
5822  if (block->flag & UI_BLOCK_NO_FLIP) {
5823  return;
5824  }
5825 
5826  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
5827  if (but->drawflag & UI_BUT_ALIGN) {
5828  return;
5829  }
5830  if (but->rect.ymin < miny) {
5831  miny = but->rect.ymin;
5832  }
5833  if (but->rect.ymax > maxy) {
5834  maxy = but->rect.ymax;
5835  }
5836  }
5837  /* mirror trick */
5838  centy = (miny + maxy) / 2.0f;
5839  LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
5840  but->rect.ymin = centy - (but->rect.ymin - centy);
5841  but->rect.ymax = centy - (but->rect.ymax - centy);
5842  SWAP(float, but->rect.ymin, but->rect.ymax);
5843  }
5844 
5845  block->flag ^= UI_BLOCK_IS_FLIP;
5846 }
5847 
5848 void UI_block_flag_enable(uiBlock *block, int flag)
5849 {
5850  block->flag |= flag;
5851 }
5852 
5853 void UI_block_flag_disable(uiBlock *block, int flag)
5854 {
5855  block->flag &= ~flag;
5856 }
5857 
5858 void UI_but_flag_enable(uiBut *but, int flag)
5859 {
5860  but->flag |= flag;
5861 }
5862 
5863 void UI_but_flag_disable(uiBut *but, int flag)
5864 {
5865  but->flag &= ~flag;
5866 }
5867 
5868 bool UI_but_flag_is_set(uiBut *but, int flag)
5869 {
5870  return (but->flag & flag) != 0;
5871 }
5872 
5873 void UI_but_drawflag_enable(uiBut *but, int flag)
5874 {
5875  but->drawflag |= flag;
5876 }
5877 
5878 void UI_but_drawflag_disable(uiBut *but, int flag)
5879 {
5880  but->drawflag &= ~flag;
5881 }
5882 
5883 void UI_but_disable(uiBut *but, const char *disabled_hint)
5884 {
5886 
5887  /* Only one disabled hint at a time currently. Don't override the previous one here. */
5888  if (but->disabled_info && but->disabled_info[0]) {
5889  return;
5890  }
5891 
5892  but->disabled_info = disabled_hint;
5893 }
5894 
5896 {
5898  but->type = UI_BTYPE_MENU;
5901 }
5902 
5904 {
5905  return but->retval;
5906 }
5907 
5909 {
5910  if (but->optype && !but->opptr) {
5911  but->opptr = MEM_cnew<PointerRNA>(__func__);
5913  }
5914 
5915  return but->opptr;
5916 }
5917 
5918 void UI_but_context_ptr_set(uiBlock *block, uiBut *but, const char *name, const PointerRNA *ptr)
5919 {
5920  but->context = CTX_store_add(&block->contexts, name, ptr);
5921  but->context->used = true;
5922 }
5923 
5924 const PointerRNA *UI_but_context_ptr_get(const uiBut *but, const char *name, const StructRNA *type)
5925 {
5926  return CTX_store_ptr_lookup(but->context, name, type);
5927 }
5928 
5930 {
5931  return but->context;
5932 }
5933 
5934 void UI_but_unit_type_set(uiBut *but, const int unit_type)
5935 {
5936  but->unit_type = (uchar)(RNA_SUBTYPE_UNIT_VALUE(unit_type));
5937 }
5938 
5940 {
5941  const int ownUnit = (int)but->unit_type;
5942 
5943  /* own unit define always takes precedence over RNA provided, allowing for overriding
5944  * default value provided in RNA in a few special cases (i.e. Active Keyframe in Graph Edit)
5945  */
5946  /* XXX: this doesn't allow clearing unit completely, though the same could be said for icons */
5947  if ((ownUnit != 0) || (but->rnaprop == nullptr)) {
5948  return ownUnit << 16;
5949  }
5951 }
5952 
5954 {
5955  block->handle_func = func;
5956  block->handle_func_arg = arg;
5957 }
5958 
5960 {
5961  block->butm_func = func;
5962  block->butm_func_arg = arg;
5963 }
5964 
5965 void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
5966 {
5967  block->func = func;
5968  block->func_arg1 = arg1;
5969  block->func_arg2 = arg2;
5970 }
5971 
5972 void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2)
5973 {
5974  if (block->func_argN) {
5975  MEM_freeN(block->func_argN);
5976  }
5977 
5978  block->funcN = funcN;
5979  block->func_argN = argN;
5980  block->func_arg2 = arg2;
5981 }
5982 
5984 {
5985  but->rename_func = func;
5986  but->rename_arg1 = arg1;
5987 }
5988 
5990  uiBlock *block,
5991  void (*func)(const bContext *C, void *idv, void *arg1, void *arg2, rcti *rect),
5992  void *arg1,
5993  void *arg2)
5994 {
5995  block->drawextra = func;
5996  block->drawextra_arg1 = arg1;
5997  block->drawextra_arg2 = arg2;
5998 }
5999 
6000 void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
6001 {
6002  but->func = func;
6003  but->func_arg1 = arg1;
6004  but->func_arg2 = arg2;
6005 }
6006 
6007 void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
6008 {
6009  if (but->func_argN) {
6010  MEM_freeN(but->func_argN);
6011  }
6012 
6013  but->funcN = funcN;
6014  but->func_argN = argN;
6015  but->func_arg2 = arg2;
6016 }
6017 
6019 {
6020  but->autocomplete_func = func;
6021  but->autofunc_arg = arg;
6022 }
6023 
6025 {
6026  but->menu_step_func = func;
6027 }
6028 
6029 void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg)
6030 {
6031  but->tip_func = func;
6032  if (but->tip_arg_free) {
6033  but->tip_arg_free(but->tip_arg);
6034  }
6035  but->tip_arg = arg;
6036  but->tip_arg_free = free_arg;
6037 }
6038 
6040 {
6041  but->pushed_state_func = func;
6042  but->pushed_state_arg = arg;
6043  ui_but_update(but);
6044 }
6045 
6047  uiBlockCreateFunc func,
6048  void *arg,
6049  const char *str,
6050  int x,
6051  int y,
6052  short width,
6053  short height,
6054  const char *tip)
6055 {
6056  uiBut *but = ui_def_but(
6057  block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
6058  but->block_create_func = func;
6059  ui_but_update(but);
6060  return but;
6061 }
6062 
6064  uiBlockCreateFunc func,
6065  void *argN,
6066  const char *str,
6067  int x,
6068  int y,
6069  short width,
6070  short height,
6071  const char *tip)
6072 {
6073  uiBut *but = ui_def_but(
6074  block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, nullptr, 0.0, 0.0, 0.0, 0.0, tip);
6075  but->block_create_func = func;
6076  if (but->func_argN) {
6077  MEM_freeN(but->func_argN);
6078  }
6079  but->func_argN = argN;
6080  ui_but_update(but);
6081  return but;
6082 }
6083 
6085  uiBlockCreateFunc func,
6086  void *arg,
6087  const char *str,
6088  int x,
6089  int y,
6090  short width,
6091  short height,
6092  const char *tip)
6093 {
6094  uiBut *but = ui_def_but(
6095  block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
6096  but->block_create_func = func;
6097  ui_but_update(but);
6098  return but;
6099 }
6100 
6102  uiMenuCreateFunc func,
6103  void *arg,
6104  const char *str,
6105  int x,
6106  int y,
6107  short width,
6108  short height,
6109  const char *tip)
6110 {
6111  uiBut *but = ui_def_but(
6112  block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
6113  but->menu_create_func = func;
6114  ui_but_update(but);
6115  return but;
6116 }
6117 
6119  uiMenuCreateFunc func,
6120  void *arg,
6121  int icon,
6122  const char *str,
6123  int x,
6124  int y,
6125  short width,
6126  short height,
6127  const char *tip)
6128 {
6129  uiBut *but = ui_def_but(
6130  block, UI_BTYPE_PULLDOWN, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
6131 
6132  ui_def_but_icon(but, icon, UI_HAS_ICON);
6133 
6134  but->drawflag |= UI_BUT_ICON_LEFT;
6135  ui_but_submenu_enable(block, but);
6136 
6137  but->menu_create_func = func;
6138  ui_but_update(but);
6139 
6140  return but;
6141 }
6142 
6144  uiMenuCreateFunc func,
6145  void *arg,
6146  int icon,
6147  int x,
6148  int y,
6149  short width,
6150  short height,
6151  const char *tip)
6152 {
6153  uiBut *but = ui_def_but(
6154  block, UI_BTYPE_PULLDOWN, 0, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
6155 
6156  ui_def_but_icon(but, icon, UI_HAS_ICON);
6157  but->drawflag &= ~UI_BUT_ICON_LEFT;
6158 
6159  but->menu_create_func = func;
6160  ui_but_update(but);
6161 
6162  return but;
6163 }
6164 
6166  uiBlockCreateFunc func,
6167  void *arg,
6168  int icon,
6169  const char *str,
6170  int x,
6171  int y,
6172  short width,
6173  short height,
6174  const char *tip)
6175 {
6176  uiBut *but = ui_def_but(
6177  block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
6178 
6179  /* XXX temp, old menu calls pass on icon arrow, which is now UI_BUT_ICON_SUBMENU flag */
6180  if (icon != ICON_RIGHTARROW_THIN) {
6181  ui_def_but_icon(but, icon, 0);
6182  but->drawflag |= UI_BUT_ICON_LEFT;
6183  }
6184  but->flag |= UI_HAS_ICON;
6185  ui_but_submenu_enable(block, but);
6186 
6187  but->block_create_func = func;
6188  ui_but_update(but);
6189 
6190  return but;
6191 }
6192 
6194  uiBlockCreateFunc func,
6195  void *arg,
6196  int retval,
6197  int icon,
6198  int x,
6199  int y,
6200  short width,
6201  short height,
6202  const char *tip)
6203 {
6204  uiBut *but = ui_def_but(
6205  block, UI_BTYPE_BLOCK, retval, "", x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip);
6206 
6207  ui_def_but_icon(but, icon, UI_HAS_ICON);
6208 
6209  but->drawflag |= UI_BUT_ICON_LEFT;
6210 
6211  but->block_create_func = func;
6212  ui_but_update(but);
6213 
6214  return but;
6215 }
6216 
6218  void *arg,
6219  int retval,
6220  int icon,
6221  int maxlen,
6222  int x,
6223  int y,
6224  short width,
6225  short height,
6226  float a1,
6227  float a2,
6228  const char *tip)
6229 {
6230  uiBut *but = ui_def_but(
6231  block, UI_BTYPE_SEARCH_MENU, retval, "", x, y, width, height, arg, 0.0, maxlen, a1, a2, tip);
6232 
6233  ui_def_but_icon(but, icon, UI_HAS_ICON);
6234 
6236 
6237  ui_but_update(but);
6238 
6239  return but;
6240 }
6241 
6243  uiButSearchCreateFn search_create_fn,
6244  uiButSearchUpdateFn search_update_fn,
6245  void *arg,
6246  const bool free_arg,
6247  uiFreeArgFunc search_arg_free_fn,
6248  uiButHandleFunc search_exec_fn,
6249  void *active)
6250 {
6251  uiButSearch *search_but = (uiButSearch *)but;
6252 
6254 
6255  /* needed since callers don't have access to internal functions
6256  * (as an alternative we could expose it) */
6257  if (search_create_fn == nullptr) {
6258  search_create_fn = ui_searchbox_create_generic;
6259  }
6260 
6261  if (search_but->arg_free_fn != nullptr) {
6262  search_but->arg_free_fn(search_but->arg);
6263  search_but->arg = nullptr;
6264  }
6265 
6266  search_but->popup_create_fn = search_create_fn;
6267  search_but->items_update_fn = search_update_fn;
6268  search_but->item_active = active;
6269 
6270  search_but->arg = arg;
6271  search_but->arg_free_fn = search_arg_free_fn;
6272 
6273  if (search_exec_fn) {
6274 #ifdef DEBUG
6275  if (search_but->but.func) {
6276  /* watch this, can be cause of much confusion, see: T47691 */
6277  printf("%s: warning, overwriting button callback with search function callback!\n",
6278  __func__);
6279  }
6280 #endif
6281  /* Handling will pass the active item as arg2 later, so keep it nullptr here. */
6282  if (free_arg) {
6283  UI_but_funcN_set(but, search_exec_fn, search_but->arg, nullptr);
6284  }
6285  else {
6286  UI_but_func_set(but, search_exec_fn, search_but->arg, nullptr);
6287  }
6288  }
6289 
6290  /* search buttons show red-alert if item doesn't exist, not for menus. Don't do this for
6291  * buttons where any result is valid anyway, since any string will be valid anyway. */
6292  if (0 == (but->block->flag & UI_BLOCK_LOOP) && !search_but->results_are_suggestions) {
6293  /* skip empty buttons, not all buttons need input, we only show invalid */
6294  if (but->drawstr[0]) {
6295  ui_but_search_refresh(search_but);
6296  }
6297  }
6298 }
6299 
6301 {
6302  uiButSearch *but_search = (uiButSearch *)but;
6304 
6305  but_search->item_context_menu_fn = context_menu_fn;
6306 }
6307 
6308 void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
6309 {
6310  uiButSearch *but_search = (uiButSearch *)but;
6312 
6313  but_search->item_sep_string = search_sep_string;
6314 }
6315 
6317 {
6318  uiButSearch *but_search = (uiButSearch *)but;
6320 
6321  but_search->item_tooltip_fn = tooltip_fn;
6322 }
6323 
6325 {
6326  uiButSearch *but_search = (uiButSearch *)but;
6328 
6329  but_search->results_are_suggestions = value;
6330 }
6331 
6332 /* Callbacks for operator search button. */
6333 static void operator_enum_search_update_fn(const struct bContext *C,
6334  void *but,
6335  const char *str,
6336  uiSearchItems *items,
6337  const bool UNUSED(is_first))
6338 {
6339  wmOperatorType *ot = ((uiBut *)but)->optype;
6340  PropertyRNA *prop = ot->prop;
6341 
6342  if (prop == nullptr) {
6343  printf("%s: %s has no enum property set\n", __func__, ot->idname);
6344  }
6345  else if (RNA_property_type(prop) != PROP_ENUM) {
6346  printf("%s: %s \"%s\" is not an enum property\n",
6347  __func__,
6348  ot->idname,
6349  RNA_property_identifier(prop));
6350  }
6351  else {
6352  /* Will create it if needed! */
6353  PointerRNA *ptr = UI_but_operator_ptr_get(static_cast<uiBut *>(but));
6354 
6355  bool do_free;
6356  const EnumPropertyItem *all_items;
6357  RNA_property_enum_items_gettexted((bContext *)C, ptr, prop, &all_items, nullptr, &do_free);
6358 
6359  StringSearch *search = BLI_string_search_new();
6360  for (const EnumPropertyItem *item = all_items; item->identifier; item++) {
6361  BLI_string_search_add(search, item->name, (void *)item, 0);
6362  }
6363 
6364  const EnumPropertyItem **filtered_items;
6365  const int filtered_amount = BLI_string_search_query(search, str, (void ***)&filtered_items);
6366 
6367  for (int i = 0; i < filtered_amount; i++) {
6368  const EnumPropertyItem *item = filtered_items[i];
6369  /* NOTE: need to give the index rather than the
6370  * identifier because the enum can be freed */
6371  if (!UI_search_item_add(
6372  items, item->name, POINTER_FROM_INT(item->value), item->icon, 0, 0)) {
6373  break;
6374  }
6375  }
6376 
6377  MEM_freeN((void *)filtered_items);
6378  BLI_string_search_free(search);
6379 
6380  if (do_free) {
6381  MEM_freeN((void *)all_items);
6382  }
6383  }
6384 }
6385 
6386 static void operator_enum_search_exec_fn(struct bContext *UNUSED(C), void *but, void *arg2)
6387 {
6388  wmOperatorType *ot = ((uiBut *)but)->optype;
6389  /* Will create it if needed! */
6390  PointerRNA *opptr = UI_but_operator_ptr_get(static_cast<uiBut *>(but));
6391 
6392  if (ot) {
6393  if (ot->prop) {
6394  RNA_property_enum_set(opptr, ot->prop, POINTER_AS_INT(arg2));
6395  /* We do not call op from here, will be called by button code.
6396  * ui_apply_but_funcs_after() (in interface_handlers.c)
6397  * called this func before checking operators,
6398  * because one of its parameters is the button itself! */
6399  }
6400  else {
6401  printf("%s: op->prop for '%s' is nullptr\n", __func__, ot->idname);
6402  }
6403  }
6404 }
6405 
6407  wmOperatorType *ot,
6408  IDProperty *properties,
6409  void *arg,
6410  int retval,
6411  int icon,
6412  int maxlen,
6413  int x,
6414  int y,
6415  short width,
6416  short height,
6417  float a1,
6418  float a2,
6419  const char *tip)
6420 {
6421  uiBut *but = uiDefSearchBut(block, arg, retval, icon, maxlen, x, y, width, height, a1, a2, tip);
6425  but,
6426  false,
6427  nullptr,
6429  nullptr);
6430 
6431  but->optype = ot;
6433 
6434  if (properties) {
6436  /* Copy id-properties. */
6437  ptr->data = IDP_CopyProperty(properties);
6438  }
6439 
6440  return but;
6441 }
6442 
6443 void UI_but_hint_drawstr_set(uiBut *but, const char *string)
6444 {
6445  ui_but_add_shortcut(but, string, false);
6446 }
6447 
6448 void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4])
6449 {
6450  but->flag |= UI_BUT_NODE_LINK;
6451  but->custom_data = socket;
6452  rgba_float_to_uchar(but->col, draw_color);
6453 }
6454 
6455 void UI_but_number_step_size_set(uiBut *but, float step_size)
6456 {
6457  uiButNumber *but_number = (uiButNumber *)but;
6458  BLI_assert(but->type == UI_BTYPE_NUM);
6459 
6460  but_number->step_size = step_size;
6461  BLI_assert(step_size > 0);
6462 }
6463 
6464 void UI_but_number_precision_set(uiBut *but, float precision)
6465 {
6466  uiButNumber *but_number = (uiButNumber *)but;
6467  BLI_assert(but->type == UI_BTYPE_NUM);
6468 
6469  but_number->precision = precision;
6470  /* -1 is a valid value, UI code figures out an appropriate precision then. */
6471  BLI_assert(precision > -2);
6472 }
6473 
6475 {
6476  wmEvent event;
6477  wm_event_init_from_window(win, &event);
6478 
6479  event.type = EVT_BUT_OPEN;
6480  event.val = KM_PRESS;
6481  event.flag = static_cast<eWM_EventFlag>(0);
6482  event.customdata = but;
6483  event.customdata_free = false;
6484 
6485  wm_event_add(win, &event);
6486 }
6487 
6488 void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN)
6489 {
6490  but->hold_func = func;
6491  but->hold_argN = argN;
6492 }
6493 
6495 {
6496  va_list args;
6497  uiStringInfo *si;
6498 
6499  const EnumPropertyItem *items = nullptr, *item = nullptr;
6500  int totitems;
6501  bool free_items = false;
6502 
6503  va_start(args, but);
6504  while ((si = (uiStringInfo *)va_arg(args, void *))) {
6505  uiStringInfoType type = si->type;
6506  char *tmp = nullptr;
6507 
6508  if (type == BUT_GET_LABEL) {
6509  if (but->str && but->str[0]) {
6510  const char *str_sep;
6511  size_t str_len;
6512 
6513  if ((but->flag & UI_BUT_HAS_SEP_CHAR) && (str_sep = strrchr(but->str, UI_SEP_CHAR))) {
6514  str_len = (str_sep - but->str);
6515  }
6516  else {
6517  str_len = strlen(but->str);
6518  }
6519 
6520  tmp = BLI_strdupn(but->str, str_len);
6521  }
6522  else {
6523  type = BUT_GET_RNA_LABEL; /* Fail-safe solution... */
6524  }
6525  }
6526  else if (type == BUT_GET_TIP) {
6527  if (but->tip_func) {
6528  tmp = but->tip_func(C, but->tip_arg, but->tip);
6529  }
6530  else if (but->tip && but->tip[0]) {
6531  tmp = BLI_strdup(but->tip);
6532  }
6533  else {
6534  type = BUT_GET_RNA_TIP; /* Fail-safe solution... */
6535  }
6536  }
6537 
6539  if (but->rnaprop) {
6541  }
6542  }
6543  else if (type == BUT_GET_RNASTRUCT_IDENTIFIER) {
6544  if (but->rnaprop && but->rnapoin.data) {
6546  }
6547  else if (but->optype) {
6548  tmp = BLI_strdup(but->optype->idname);
6549  }
6550  else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
6551  MenuType *mt = UI_but_menutype_get(but);
6552  if (mt) {
6553  tmp = BLI_strdup(mt->idname);
6554  }
6555  }
6556  else if (but->type == UI_BTYPE_POPOVER) {
6557  PanelType *pt = UI_but_paneltype_get(but);
6558  if (pt) {
6559  tmp = BLI_strdup(pt->idname);
6560  }
6561  }
6562  }
6564  if (but->rnaprop) {
6565  if (type == BUT_GET_RNA_LABEL) {
6567  }
6568  else {
6569  const char *t = RNA_property_ui_description(but->rnaprop);
6570  if (t && t[0]) {
6571  tmp = BLI_strdup(t);
6572  }
6573  }
6574  }
6575  else if (but->optype) {
6576  if (type == BUT_GET_RNA_LABEL) {
6577  tmp = BLI_strdup(WM_operatortype_name(but->optype, but->opptr));
6578  }
6579  else {
6580  tmp = WM_operatortype_description(C, but->optype, but->opptr);
6581  }
6582  }
6584  {
6585  MenuType *mt = UI_but_menutype_get(but);
6586  if (mt) {
6587  if (type == BUT_GET_RNA_LABEL) {
6588  tmp = BLI_strdup(CTX_TIP_(mt->translation_context, mt->label));
6589  }
6590  else {
6591  /* Not all menus are from Python. */
6592  if (mt->rna_ext.srna) {
6593  const char *t = RNA_struct_ui_description(mt->rna_ext.srna);
6594  if (t && t[0]) {
6595  tmp = BLI_strdup(t);
6596  }
6597  }
6598  }
6599  }
6600  }
6601 
6602  if (tmp == nullptr) {
6604  if (ot) {
6605  if (type == BUT_GET_RNA_LABEL) {
6606  tmp = BLI_strdup(WM_operatortype_name(ot, nullptr));
6607  }
6608  else {
6609  tmp = WM_operatortype_description(C, ot, nullptr);
6610  }
6611  }
6612  }
6613 
6614  if (tmp == nullptr) {
6615  PanelType *pt = UI_but_paneltype_get(but);
6616  if (pt) {
6617  if (type == BUT_GET_RNA_LABEL) {
6618  tmp = BLI_strdup(CTX_TIP_(pt->translation_context, pt->label));
6619  }
6620  else {
6621  /* Not all panels are from Python. */
6622  if (pt->rna_ext.srna) {
6623  /* Panels don't yet have descriptions, this may be added. */
6624  }
6625  }
6626  }
6627  }
6628  }
6629  }
6630  else if (type == BUT_GET_RNA_LABEL_CONTEXT) {
6631  const char *_tmp = BLT_I18NCONTEXT_DEFAULT;
6632  if (but->rnaprop) {
6634  }
6635  else if (but->optype) {
6637  }
6638  else if (ELEM(but->type, UI_BTYPE_MENU, UI_BTYPE_PULLDOWN)) {
6639  MenuType *mt = UI_but_menutype_get(but);
6640  if (mt) {
6642  }
6643  }
6644  if (BLT_is_default_context(_tmp)) {
6646  }
6647  tmp = BLI_strdup(_tmp);
6648  }
6650  PointerRNA *ptr = nullptr;
6651  PropertyRNA *prop = nullptr;
6652  int value = 0;
6653 
6654  /* get the enum property... */
6655  if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
6656  /* enum property */
6657  ptr = &but->rnapoin;
6658  prop = but->rnaprop;
6659  value = (ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_TAB)) ? (int)but->hardmax :
6660  (int)ui_but_value_get(but);
6661  }
6662  else if (but->optype) {
6663  PointerRNA *opptr = UI_but_operator_ptr_get(but);
6664  wmOperatorType *ot = but->optype;
6665 
6666  /* So the context is passed to `itemf` functions. */
6667  WM_operator_properties_sanitize(opptr, false);
6668 
6669  /* if the default property of the operator is enum and it is set,
6670  * fetch the tooltip of the selected value so that "Snap" and "Mirror"
6671  * operator menus in the Anim Editors will show tooltips for the different
6672  * operations instead of the meaningless generic operator tooltip
6673  */
6674  if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) {
6675  if (RNA_struct_contains_property(opptr, ot->prop)) {
6676  ptr = opptr;
6677  prop = ot->prop;
6678  value = RNA_property_enum_get(opptr, ot->prop);
6679  }
6680  }
6681  }
6682 
6683  /* get strings from matching enum item */
6684  if (ptr && prop) {
6685  if (!item) {
6686  int i;
6687 
6688  RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items);
6689  for (i = 0, item = items; i < totitems; i++, item++) {
6690  if (item->identifier[0] && item->value == value) {
6691  break;
6692  }
6693  }
6694  }
6695  if (item && item->identifier) {
6697  tmp = BLI_strdup(item->identifier);
6698  }
6699  else if (type == BUT_GET_RNAENUM_LABEL) {
6700  tmp = BLI_strdup(item->name);
6701  }
6702  else if (item->description && item->description[0]) {
6703  tmp = BLI_strdup(item->description);
6704  }
6705  }
6706  }
6707  }
6708  else if (type == BUT_GET_OP_KEYMAP) {
6709  if (!ui_block_is_menu(but->block)) {
6710  char buf[128];
6711  if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
6712  tmp = BLI_strdup(buf);
6713  }
6714  }
6715  }
6716  else if (type == BUT_GET_PROP_KEYMAP) {
6717  /* for properties that are bound to one of the context cycle, etc. keys... */
6718  char buf[128];
6719  if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) {
6720  tmp = BLI_strdup(buf);
6721  }
6722  }
6723 
6724  si->strinfo = tmp;
6725  }
6726  va_end(args);
6727 
6728  if (free_items && items) {
6729  MEM_freeN((void *)items);
6730  }
6731 }
6732 
6734 {
6735  va_list args;
6736  uiStringInfo *si;
6737 
6739  PointerRNA *opptr = UI_but_extra_operator_icon_opptr_get(extra_icon);
6740 
6741  va_start(args, extra_icon);
6742  while ((si = (uiStringInfo *)va_arg(args, void *))) {
6743  char *tmp = nullptr;
6744 
6745  switch (si->type) {
6746  case BUT_GET_LABEL:
6747  tmp = BLI_strdup(WM_operatortype_name(optype, opptr));
6748  break;
6749  case BUT_GET_TIP:
6750  tmp = WM_operatortype_description(C, optype, opptr);
6751  break;
6752  case BUT_GET_OP_KEYMAP: {
6753  char buf[128];
6754  if (ui_but_extra_icon_event_operator_string(C, extra_icon, buf, sizeof(buf))) {
6755  tmp = BLI_strdup(buf);
6756  }
6757  }
6758  /* Other types not supported. The caller should expect that outcome, no need to message or
6759  * assert here. */
6760  default:
6761  break;
6762  }
6763 
6764  si->strinfo = tmp;
6765  }
6766  va_end(args);
6767 }
6768 
6769 /* Program Init/Exit */
6770 
6771 void UI_init(void)
6772 {
6774 }
6775 
6777 {
6778  /* Initialize UI variables from values set in the preferences. */
6779  uiStyleInit();
6780 }
6781 
6782 void UI_reinit_font(void)
6783 {
6784  uiStyleInit();
6785 }
6786 
6787 void UI_exit(void)
6788 {
6791 }
6792 
6794 {
6796 }
typedef float(TangentPoint)[2]
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
Definition: anim_sys.c:761
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
void CTX_store_set(bContext *C, bContextStore *store)
Definition: context.c:188
struct ARegion * CTX_wm_menu(const bContext *C)
Definition: context.c:760
bContextStore * CTX_store_add(ListBase *contexts, const char *name, const PointerRNA *ptr)
Definition: context.c:128
void CTX_store_free_list(ListBase *contexts)
Definition: context.c:223
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:775
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
const PointerRNA * CTX_store_ptr_lookup(const bContextStore *store, const char *name, const StructRNA *type CPP_ARG_DEFAULT(nullptr))
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL()
Definition: idprop.c:578
struct IDProperty * IDP_New(char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: idprop.c:887
struct IDProperty * IDP_NewString(const char *st, const char *name, int maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2)
Definition: idprop.c:339
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1093
bool IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL()
Definition: idprop.c:631
struct IDProperty * IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
double BKE_scene_unit_scale(const struct UnitSettings *unit, int unit_type, double value)
void BKE_unit_name_to_alt(char *str, int len_max, const char *orig_str, int system, int type)
Definition: unit.c:1180
size_t BKE_unit_value_as_string(char *str, int len_max, double value, int prec, int type, const struct UnitSettings *settings, bool pad)
double BKE_unit_closest_scalar(double value, int system, int type)
Definition: unit.c:1220
float BLF_width(int fontid, const char *str, size_t str_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:688
void BLF_batch_draw_begin(void)
Definition: blf.c:466
void BLF_batch_draw_end(void)
Definition: blf.c:479
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:715
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:790
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:221
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:301
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int integer_digits_f(float f)
#define M_LN10
Definition: BLI_math_base.h:56
MINLINE int round_fl_to_int(float a)
MINLINE short round_db_to_short_clamp(double a)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int round_db_to_int_clamp(double a)
MINLINE int is_power_of_2_i(int n)
MINLINE unsigned char round_db_to_uchar_clamp(double a)
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
Definition: math_color.c:396
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
void BLI_rctf_translate(struct rctf *rect, float x, float y)
Definition: rct.c:566
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
void BLI_rctf_union(struct rctf *rct_a, const struct rctf *rct_b)
void BLI_rcti_rctf_copy_round(struct rcti *dst, const struct rctf *src)
void BLI_rcti_rctf_copy_floor(struct rcti *dst, const struct rctf *src)
void BLI_rcti_translate(struct rcti *rect, int x, int y)
Definition: rct.c:559
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
bool BLI_rcti_clamp(struct rcti *rect, const struct rcti *rect_bounds, int r_xy[2])
void BLI_rctf_init_minmax(struct rctf *rect)
Definition: rct.c:483
#define STRNCPY(dst, src)
Definition: BLI_string.h:483
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t length) ATTR_NONNULL()
Definition: string.c:871
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:134
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:33
#define STR_CONCATF(dst, len, format,...)
Definition: BLI_string.h:490
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define STR_CONCAT(dst, len, suffix)
Definition: BLI_string.h:488
void BLI_string_search_add(StringSearch *search, const char *str, void *user_data, int weight)
void BLI_string_search_free(StringSearch *search)
StringSearch * BLI_string_search_new(void)
int BLI_string_search_query(StringSearch *search, const char *query, void ***r_data)
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL(1
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
#define STRPREFIX(a, b)
#define ARRAY_SIZE(arr)
#define UNUSED_VARS(...)
#define SWAP(type, a, b)
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define POINTER_AS_INT(i)
#define MAX2(a, b)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define LIKELY(x)
external readfile function prototypes.
#define TIP_(msgid)
#define CTX_IFACE_(context, msgid)
#define BLT_I18NCONTEXT_DEFAULT
bool BLT_is_default_context(const char *msgctxt)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
#define CTX_TIP_(context, msgid)
bool BPY_run_string_as_number(struct bContext *C, const char *imports[], const char *expr, struct BPy_RunErrInfo *err_info, double *r_value) ATTR_NONNULL(1
typedef double(DMatrix)[4][4]
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ IDP_INT
Definition: DNA_ID.h:137
@ IDP_GROUP
Definition: DNA_ID.h:141
#define ID_CHECK_UNDO(id)
Definition: DNA_ID.h:556
@ ID_SCR
Definition: DNA_ID_enums.h:60
@ ID_OB
Definition: DNA_ID_enums.h:47
Object is a sort of wrapper for general info.
#define OB_DATA_SUPPORT_ID(_id_type)
#define USER_UNIT_NONE
#define USER_UNIT_ROT_RADIANS
#define FRA2TIME(a)
@ RGN_FLAG_SEARCH_FILTER_ACTIVE
@ USER_MENUFIXEDORDER
@ USER_FACTOR_AS_FACTOR
@ USER_FACTOR_AS_PERCENTAGE
bool user_string_to_number(bContext *C, const char *str, const struct UnitSettings *unit, int type, double *r_value, bool use_single_line_error, char **r_error)
void ED_region_do_msg_notify_tag_redraw(struct bContext *C, struct wmMsgSubscribeKey *msg_key, struct wmMsgSubscribeValue *msg_val)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:140
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
#define GPU_matrix_projection_get(x)
Definition: GPU_matrix.h:228
void GPU_matrix_identity_set(void)
Definition: gpu_matrix.cc:168
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:133
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
const char * IMB_colormanagement_display_get_default_name(void)
void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], struct ColorManagedDisplay *display)
struct ColorManagedDisplay * IMB_colormanagement_display_get_named(const char *name)
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
@ RNA_OVERRIDE_STATUS_OVERRIDDEN
Definition: RNA_access.h:819
short RNA_type_to_ID_code(const StructRNA *type)
PropertyScaleType
Definition: RNA_types.h:96
@ PROP_SCALE_LINEAR
Definition: RNA_types.h:98
#define RNA_SUBTYPE_UNIT_VALUE(subtype)
Definition: RNA_types.h:113
PropertyType
Definition: RNA_types.h:58
@ PROP_FLOAT
Definition: RNA_types.h:61
@ PROP_BOOLEAN
Definition: RNA_types.h:59
@ PROP_ENUM
Definition: RNA_types.h:63
@ PROP_INT
Definition: RNA_types.h:60
@ PROP_STRING
Definition: RNA_types.h:62
@ PROP_POINTER
Definition: RNA_types.h:64
@ PROP_UNIT_ROTATION
Definition: RNA_types.h:75
@ PROP_UNIT_NONE
Definition: RNA_types.h:70
@ PROP_UNIT_TIME
Definition: RNA_types.h:76
#define RNA_SUBTYPE_UNIT(subtype)
Definition: RNA_types.h:111
@ PROP_ENUM_FLAG
Definition: RNA_types.h:266
@ PROP_ICONS_CONSECUTIVE
Definition: RNA_types.h:212
@ PROP_ICONS_REVERSE
Definition: RNA_types.h:213
PropertySubType
Definition: RNA_types.h:125
@ PROP_COLOR
Definition: RNA_types.h:153
@ PROP_PIXEL
Definition: RNA_types.h:141
@ PROP_NONE
Definition: RNA_types.h:126
@ PROP_PERCENTAGE
Definition: RNA_types.h:143
@ PROP_FACTOR
Definition: RNA_types.h:144
#define C
Definition: RandGen.cpp:25
@ UI_BUT_TEXT_RIGHT
Definition: UI_interface.h:261
@ UI_BUT_ICON_LEFT
Definition: UI_interface.h:260
@ UI_BUT_ALIGN_DOWN
Definition: UI_interface.h:272
@ UI_BUT_ALIGN
Definition: UI_interface.h:273
@ UI_BUT_CHECKBOX_INVERT
Definition: UI_interface.h:300
@ UI_BUT_TEXT_LEFT
Definition: UI_interface.h:259
@ UI_BUT_ICON_REVERSE
Definition: UI_interface.h:294
#define UI_UNIT_Y
void UI_widgetbase_draw_cache_begin(void)
#define UI_SEP_CHAR_S
Definition: UI_interface.h:84
uiBlock * uiLayoutGetBlock(uiLayout *layout)
#define AUTOCOMPLETE_FULL_MATCH
@ UI_BUT_REDALERT
Definition: UI_interface.h:201
@ UI_BUT_UNDO
Definition: UI_interface.h:205
@ UI_BUT_ACTIVATE_ON_INIT
Definition: UI_interface.h:219
@ UI_BUT_DISABLED
Definition: UI_interface.h:196
@ UI_BUT_OVERRIDDEN
Definition: UI_interface.h:231
@ UI_BUT_HAS_SEP_CHAR
Definition: UI_interface.h:222
@ UI_BUT_NODE_LINK
Definition: UI_interface.h:192
@ UI_BUT_ICON_PREVIEW
Definition: UI_interface.h:190
@ UI_BUT_DRAG_MULTI
Definition: UI_interface.h:217
@ UI_BUT_ICON_SUBMENU
Definition: UI_interface.h:189
@ UI_BUT_VALUE_CLEAR
Definition: UI_interface.h:228
eUIEmbossType
Definition: UI_interface.h:107
@ UI_EMBOSS_PULLDOWN
Definition: UI_interface.h:110
void UI_fontstyle_set(const struct uiFontStyle *fs)
const struct uiStyle * UI_style_get_dpi(void)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
struct ARegion *(* uiButSearchCreateFn)(struct bContext *C, struct ARegion *butregion, struct uiButSearch *search_but)
Definition: UI_interface.h:516
int(* uiButCompleteFunc)(struct bContext *C, char *str, void *arg)
Definition: UI_interface.h:509
#define UI_SEP_CHAR
Definition: UI_interface.h:83
void(* uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2)
Definition: UI_interface.h:507
void(* uiButHandleHoldFunc)(struct bContext *C, struct ARegion *butregion, uiBut *but)
Definition: UI_interface.h:508
void(* uiBlockHandleFunc)(struct bContext *C, void *arg, int event)
Definition: UI_interface.h:540
void uiItemL(uiLayout *layout, const char *name, int icon)
const struct uiStyle * UI_style_get(void)
int(* uiButPushedStateFunc)(struct uiBut *but, const void *arg)
Definition: UI_interface.h:538
bool UI_view_item_is_active(const uiViewItemHandle *item_handle)
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int but_flag, uint8_t name_prefix_offset)
struct uiBut uiBut
Definition: UI_interface.h:71
bool UI_but_is_utf8(const uiBut *but)
#define UI_BUT_POIN_TYPES
Definition: UI_interface.h:326
#define AUTOCOMPLETE_PARTIAL_MATCH
#define AUTOCOMPLETE_NO_MATCH
char *(* uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip)
Definition: UI_interface.h:537
void UI_butstore_update(uiBlock *block)
void UI_but_tooltip_refresh(struct bContext *C, uiBut *but)
void(* uiButSearchUpdateFn)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items, bool is_first)
Definition: UI_interface.h:524
void uiItemS(uiLayout *layout)
#define UI_PRECISION_FLOAT_MAX
#define UI_PRECISION_FLOAT_SCALE
struct PanelType * UI_but_paneltype_get(uiBut *but)
void UI_editsource_but_replace(const uiBut *old_but, uiBut *new_but)
#define UI_HEADER_OFFSET
void(* uiFreeArgFunc)(void *arg)
Definition: UI_interface.h:603
bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src)
void UI_widgetbase_draw_cache_end(void)
void UI_editsource_active_but_test(uiBut *but)
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:91
eBlockBoundsCalc
Definition: UI_interface.h:810
@ UI_BLOCK_BOUNDS_PIE_CENTER
Definition: UI_interface.h:817
@ UI_BLOCK_BOUNDS_POPUP_MOUSE
Definition: UI_interface.h:814
@ UI_BLOCK_BOUNDS_POPUP_CENTER
Definition: UI_interface.h:816
@ UI_BLOCK_BOUNDS_POPUP_MENU
Definition: UI_interface.h:815
@ UI_BLOCK_BOUNDS_TEXT
Definition: UI_interface.h:813
@ UI_BLOCK_BOUNDS
Definition: UI_interface.h:812
@ UI_BLOCK_BOUNDS_NONE
Definition: UI_interface.h:811
struct ARegion *(* uiButSearchTooltipFn)(struct bContext *C, struct ARegion *region, const struct rcti *item_rect, void *arg, void *active)
Definition: UI_interface.h:530
void(* uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr)
Definition: UI_interface.h:506
bool UI_editsource_enable_check(void)
#define BUTTYPE
Definition: UI_interface.h:396
#define UI_DPI_FAC
Definition: UI_interface.h:305
bool UI_view_item_matches(const uiViewItemHandle *a_handle, const uiViewItemHandle *b_handle)
struct wmOperatorType * UI_but_operatortype_get_from_enum_menu(struct uiBut *but, struct PropertyRNA **r_prop)
void(* uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2)
Definition: UI_interface.h:505
bool UI_butstore_is_registered(uiBlock *block, uiBut *but)
struct MenuType * UI_but_menutype_get(uiBut *but)
bool UI_panel_category_is_visible(const struct ARegion *region)
uiStringInfoType
@ BUT_GET_RNA_TIP
@ BUT_GET_RNA_LABEL
@ BUT_GET_LABEL
@ BUT_GET_PROP_KEYMAP
@ BUT_GET_TIP
@ BUT_GET_RNAENUM_TIP
@ BUT_GET_RNASTRUCT_IDENTIFIER
@ BUT_GET_RNAENUM_LABEL
@ BUT_GET_RNAPROP_IDENTIFIER
@ BUT_GET_RNA_LABEL_CONTEXT
@ BUT_GET_RNAENUM_IDENTIFIER
@ BUT_GET_OP_KEYMAP
bool UI_panel_should_show_background(const struct ARegion *region, const struct PanelType *panel_type)
void UI_butstore_clear(uiBlock *block)
uiLayout * uiLayoutSplit(uiLayout *layout, float percentage, bool align)
bool(* uiButSearchContextMenuFn)(struct bContext *C, void *arg, void *active, const struct wmEvent *event)
Definition: UI_interface.h:526
void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
void(* uiMenuCreateFunc)(struct bContext *C, struct uiLayout *layout, void *arg1)
Definition: UI_interface.h:592
#define UI_SCREEN_MARGIN
Definition: UI_interface.h:104
void(* uiMenuHandleFunc)(struct bContext *C, void *arg, int event)
Definition: UI_interface.h:593
bool(* uiMenuStepFunc)(struct bContext *C, int direction, void *arg1)
Definition: UI_interface.h:600
eButPointerType
Definition: UI_interface.h:316
@ UI_BUT_POIN_SHORT
Definition: UI_interface.h:318
@ UI_BUT_POIN_INT
Definition: UI_interface.h:319
@ UI_BUT_POIN_BIT
Definition: UI_interface.h:322
@ UI_BUT_POIN_CHAR
Definition: UI_interface.h:317
@ UI_BUT_POIN_FLOAT
Definition: UI_interface.h:320
void UI_block_layout_set_current(uiBlock *block, uiLayout *layout)
#define UI_UNIT_X
struct uiViewItemHandle uiViewItemHandle
Definition: UI_interface.h:78
eButType
Definition: UI_interface.h:329
@ UI_BTYPE_BUT
Definition: UI_interface.h:330
@ UI_BTYPE_TOGGLE
Definition: UI_interface.h:340
@ UI_BTYPE_TAB
Definition: UI_interface.h:350
@ UI_BTYPE_HOTKEY_EVENT
Definition: UI_interface.h:377
@ UI_BTYPE_LISTBOX
Definition: UI_interface.h:366
@ UI_BTYPE_SEPR_SPACER
Definition: UI_interface.h:388
@ UI_BTYPE_ROUNDBOX
Definition: UI_interface.h:359
@ UI_BTYPE_COLORBAND
Definition: UI_interface.h:360
@ UI_BTYPE_BUT_MENU
Definition: UI_interface.h:335
@ UI_BTYPE_TOGGLE_N
Definition: UI_interface.h:341
@ UI_BTYPE_BLOCK
Definition: UI_interface.h:353
@ UI_BTYPE_NUM_SLIDER
Definition: UI_interface.h:339
@ UI_BTYPE_HSVCIRCLE
Definition: UI_interface.h:368
@ UI_BTYPE_LISTROW
Definition: UI_interface.h:367
@ UI_BTYPE_TEXT
Definition: UI_interface.h:332
@ UI_BTYPE_BUT_TOGGLE
Definition: UI_interface.h:345
@ UI_BTYPE_VIEW_ITEM
Definition: UI_interface.h:393
@ UI_BTYPE_HSVCUBE
Definition: UI_interface.h:356
@ UI_BTYPE_LABEL
Definition: UI_interface.h:354
@ UI_BTYPE_CURVE
Definition: UI_interface.h:363
@ UI_BTYPE_ICON_TOGGLE_N
Definition: UI_interface.h:343
@ UI_BTYPE_DECORATOR
Definition: UI_interface.h:391
@ UI_BTYPE_ROW
Definition: UI_interface.h:331
@ UI_BTYPE_SEARCH_MENU
Definition: UI_interface.h:372
@ UI_BTYPE_UNITVEC
Definition: UI_interface.h:362
@ UI_BTYPE_SEPR_LINE
Definition: UI_interface.h:386
@ UI_BTYPE_KEY_EVENT
Definition: UI_interface.h:355
@ UI_BTYPE_PROGRESS_BAR
Definition: UI_interface.h:383
@ UI_BTYPE_POPOVER
Definition: UI_interface.h:351
@ UI_BTYPE_CHECKBOX_N
Definition: UI_interface.h:348
@ UI_BTYPE_SEPR
Definition: UI_interface.h:385
@ UI_BTYPE_NUM
Definition: UI_interface.h:337
@ UI_BTYPE_PULLDOWN
Definition: UI_interface.h:358
@ UI_BTYPE_CURVEPROFILE
Definition: UI_interface.h:365
@ UI_BTYPE_COLOR
Definition: UI_interface.h:349
@ UI_BTYPE_CHECKBOX
Definition: UI_interface.h:347
@ UI_BTYPE_GRIP
Definition: UI_interface.h:390
@ UI_BTYPE_MENU
Definition: UI_interface.h:334
@ UI_BTYPE_ICON_TOGGLE
Definition: UI_interface.h:342
@ UI_BTYPE_IMAGE
Definition: UI_interface.h:379
@ UI_BTYPE_SCROLL
Definition: UI_interface.h:352
#define UI_MAX_NAME_STR
Definition: UI_interface.h:92
int UI_calc_float_precision(int prec, double value)
bool UI_but_is_tool(const uiBut *but)
uiBlock *(* uiBlockCreateFunc)(struct bContext *C, struct ARegion *region, void *arg1)
Definition: UI_interface.h:714
#define UI_but_is_decorator(but)
Definition: UI_interface.h:611
@ UI_BLOCK_SEARCH_ONLY
Definition: UI_interface.h:165
@ UI_BLOCK_NUMSELECT
Definition: UI_interface.h:138
@ UI_BLOCK_RADIAL
Definition: UI_interface.h:156
@ UI_BLOCK_LOOP
Definition: UI_interface.h:135
@ UI_BLOCK_MOVEMOUSE_QUIT
Definition: UI_interface.h:143
@ UI_BLOCK_IS_FLIP
Definition: UI_interface.h:136
@ UI_BLOCK_SHOW_SHORTCUT_ALWAYS
Definition: UI_interface.h:160
@ UI_BLOCK_NO_FLIP
Definition: UI_interface.h:137
@ UI_BLOCK_POPOVER
Definition: UI_interface.h:157
@ UI_BLOCK_QUICK_SETUP
Definition: UI_interface.h:167
void UI_icon_draw_cache_end(void)
void UI_icon_draw_cache_begin(void)
eAlertIcon
struct ImBuf * UI_icon_alert_imbuf_get(eAlertIcon icon)
BIFIconID
Definition: UI_resources.h:18
struct bTheme * UI_GetTheme(void)
Definition: resources.c:1067
float UI_view2d_scale_get_x(const struct View2D *v2d)
@ KM_PRESS
Definition: WM_types.h:267
eWM_EventFlag
Definition: WM_types.h:600
wmOperatorCallContext
Definition: WM_types.h:199
@ WM_OP_INVOKE_REGION_WIN
Definition: WM_types.h:202
@ WM_OP_INVOKE_DEFAULT
Definition: WM_types.h:201
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:208
@ KM_CTRL
Definition: WM_types.h:239
@ KM_ALT
Definition: WM_types.h:240
@ KM_OSKEY
Definition: WM_types.h:242
@ KM_SHIFT
Definition: WM_types.h:238
int pad[32 - sizeof(int)]
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void activate(bool forceActivation=false) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
void append(const T &value)
Definition: BLI_vector.hh:433
Scene scene
const Depsgraph * depsgraph
SyclQueue void void size_t num_bytes void
int len
Definition: draw_manager.c:108
#define str(s)
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
void UI_block_update_from_old(const bContext *C, uiBlock *block)
Definition: interface.cc:1813
void UI_but_flag_disable(uiBut *but, int flag)
Definition: interface.cc:5863
void UI_but_disable(uiBut *but, const char *disabled_hint)
Definition: interface.cc:5883
void UI_but_func_pushed_state_set(uiBut *but, uiButPushedStateFunc func, const void *arg)
Definition: interface.cc:6039
static void ui_but_predefined_extra_operator_icons_add(uiBut *but)
Definition: interface.cc:1764
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)
Definition: interface.cc:5196
static uiButExtraOpIcon * ui_but_extra_icon_find_old(const uiButExtraOpIcon *new_extra_icon, const uiBut *old_but)
Definition: interface.cc:811
void UI_blocklist_update_window_matrix(const bContext *C, const ListBase *lb)
Definition: interface.cc:3484
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)
Definition: interface.cc:5623
bool ui_but_is_unit(const uiBut *but)
Definition: interface.cc:2420
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)
Definition: interface.cc:4537
static PredefinedExtraOpIconType ui_but_icon_extra_get(uiBut *but)
Definition: interface.cc:1733
uiBut * uiDefButO_ptr(uiBlock *block, int type, wmOperatorType *ot, wmOperatorCallContext opcontext, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5303
void ui_but_range_set_hard(uiBut *but)
Definition: interface.cc:3258
void ui_but_extra_operator_icons_free(uiBut *but)
Definition: interface.cc:1674
PointerRNA * UI_but_operator_ptr_get(uiBut *but)
Definition: interface.cc:5908
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)
Definition: interface.cc:5102
static float ui_but_get_float_precision(uiBut *but)
Definition: interface.cc:639
static PointerRNA * ui_but_extra_operator_icon_add_ptr(uiBut *but, wmOperatorType *optype, wmOperatorCallContext opcontext, int icon)
Definition: interface.cc:1644
eUIEmbossType UI_block_emboss_get(uiBlock *block)
Definition: interface.cc:3624
static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len)
Definition: interface.cc:1367
static void ui_but_free_type_specific(uiBut *but)
Definition: interface.cc:3388
bool UI_but_active_only_ex(const bContext *C, ARegion *region, uiBlock *block, uiBut *but, const bool remove_on_failure)
Definition: interface.cc:1016
bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b)
Definition: interface.cc:2449
static double soft_range_round_down(double value, double max)
Definition: interface.cc:3243
uiBut * uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6084
uiBut * uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6118
const short ui_radial_dir_to_angle[8]
Definition: interface.cc:1556
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)
Definition: interface.cc:6406
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)
Definition: interface.cc:5336
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)
Definition: interface.cc:5548
void UI_block_theme_style_set(uiBlock *block, char theme_style)
Definition: interface.cc:3634
uiBut * uiDefButImage(uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4])
Definition: interface.cc:4829
void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but)
Definition: interface.cc:6474
static bool ui_number_from_string_units_with_but(bContext *C, const char *str, const uiBut *but, double *r_value)
Definition: interface.cc:2987
static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
Definition: interface.cc:846
static void ui_block_bounds_calc_popup(wmWindow *window, uiBlock *block, eBlockBoundsCalc bounds_calc, const int xy[2], int r_xy[2])
Definition: interface.cc:515
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)
Definition: interface.cc:5709
static bool ui_but_is_unit_radians(const uiBut *but)
Definition: interface.cc:113
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)
ui_def_but is the function that draws many button types
Definition: interface.cc:4087
void ui_but_range_set_soft(uiBut *but)
Definition: interface.cc:3280
void ui_but_update(uiBut *but)
Definition: interface.cc:3900
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)
Definition: interface.cc:5516
static uiBut * ui_but_alloc(const eButType type)
Definition: interface.cc:4016
uiBut * uiDefButO(uiBlock *block, int type, const char *opname, wmOperatorCallContext opcontext, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5318
void UI_blocklist_free(const bContext *C, ARegion *region)
Definition: interface.cc:3514
wmOperatorType * UI_but_extra_operator_icon_optype_get(uiButExtraOpIcon *extra_icon)
Definition: interface.cc:1696
void UI_init(void)
Definition: interface.cc:6771
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)
Definition: interface.cc:4806
uiBut * ui_but_change_type(uiBut *but, eButType new_type)
Definition: interface.cc:4025
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)
Definition: interface.cc:5042
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)
Definition: interface.cc:5392
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)
Definition: interface.cc:5733
void UI_block_lock_clear(uiBlock *block)
Definition: interface.cc:2281
static void operator_enum_search_exec_fn(struct bContext *UNUSED(C), void *but, void *arg2)
Definition: interface.cc:6386
void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *arg, uiFreeArgFunc free_arg)
Definition: interface.cc:6029
uiBlock * UI_block_begin(const bContext *C, ARegion *region, const char *name, eUIEmbossType emboss)
Definition: interface.cc:3578
static bool ui_but_is_row_alignment_group(const uiBut *left, const uiBut *right)
Definition: interface.cc:365
void UI_block_bounds_set_popup(uiBlock *block, int addval, const int bounds_offset[2])
Definition: interface.cc:598
void ui_block_to_window_rctf(const ARegion *region, uiBlock *block, rctf *rct_dst, const rctf *rct_src)
Definition: interface.cc:170
int UI_but_unit_type_get(const uiBut *but)
Definition: interface.cc:5939
float ui_block_to_window_scale(const ARegion *region, uiBlock *block)
Definition: interface.cc:180
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)
Definition: interface.cc:5677
uiBut * uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6165
void UI_but_func_search_set(uiBut *but, uiButSearchCreateFn search_create_fn, uiButSearchUpdateFn search_update_fn, void *arg, const bool free_arg, uiFreeArgFunc search_arg_free_fn, uiButHandleFunc search_exec_fn, void *active)
Definition: interface.cc:6242
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)
Definition: interface.cc:5570
void ui_def_but_icon_clear(uiBut *but)
Definition: interface.cc:4259
void UI_block_bounds_set_normal(uiBlock *block, int addval)
Definition: interface.cc:582
static bool ui_number_from_string_percentage(bContext *C, const char *str, double *r_value)
Definition: interface.cc:3032
int ui_but_is_pushed(uiBut *but)
Definition: interface.cc:2253
bool ui_but_is_float(const uiBut *but)
Definition: interface.cc:2376
bool ui_but_context_poll_operator_ex(bContext *C, const uiBut *but, const wmOperatorCallParams *optype_params)
Definition: interface.cc:1862
uiBut * ui_but_drag_multi_edit_get(uiBut *but)
Definition: interface.cc:2661
static int ui_but_calc_float_precision(uiBut *but, double value)
Definition: interface.cc:679
void UI_blocklist_update_view_for_buttons(const bContext *C, const ListBase *lb)
Definition: interface.cc:3496
void UI_but_extra_icon_string_info_get(struct bContext *C, uiButExtraOpIcon *extra_icon,...)
Definition: interface.cc:6733
PropertyScaleType ui_but_scale_type(const uiBut *but)
Definition: interface.cc:2389
uiBut * uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int retval, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6193
static bool ui_but_event_operator_string_from_operator(const bContext *C, wmOperatorCallParams *op_call_params, char *buf, const size_t buf_len)
Definition: interface.cc:1242
void UI_but_func_menu_step_set(uiBut *but, uiMenuStepFunc func)
Definition: interface.cc:6024
static void ui_but_extra_operator_icon_free(uiButExtraOpIcon *extra_icon)
Definition: interface.cc:1666
void UI_but_string_info_get(bContext *C, uiBut *but,...)
Definition: interface.cc:6494
static int findBitIndex(uint x)
Definition: interface.cc:4863
static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *but_p)
Definition: interface.cc:4266
static void ui_update_window_matrix(const wmWindow *window, const ARegion *region, uiBlock *block)
Definition: interface.cc:322
void ui_block_bounds_calc(uiBlock *block)
Definition: interface.cc:444
static void ui_but_update_and_icon_set(uiBut *but, int icon)
Definition: interface.cc:4998
void UI_block_flag_disable(uiBlock *block, int flag)
Definition: interface.cc:5853
void ui_but_override_flag(Main *bmain, uiBut *but)
Definition: interface.cc:1613
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.cc:5873
static void ui_but_validate(const uiBut *but)
Definition: interface.cc:1848
static void ui_block_bounds_calc_centered(wmWindow *window, uiBlock *block)
Definition: interface.cc:480
int UI_but_return_value_get(uiBut *but)
Definition: interface.cc:5903
void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
Definition: interface.cc:6316
const PointerRNA * UI_but_context_ptr_get(const uiBut *but, const char *name, const StructRNA *type)
Definition: interface.cc:5924
uiBut * uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, wmOperatorCallContext opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5757
double ui_but_value_get(uiBut *but)
Definition: interface.cc:2492
void UI_but_number_step_size_set(uiBut *but, float step_size)
Definition: interface.cc:6455
AutoComplete * UI_autocomplete_begin(const char *startname, size_t maxlen)
Definition: interface.cc:4901
void UI_block_func_handle_set(uiBlock *block, uiBlockHandleFunc func, void *arg)
Definition: interface.cc:5953
void ui_def_but_icon(uiBut *but, const int icon, const int flag)
Definition: interface.cc:4244
void ui_window_to_region_rcti(const ARegion *region, rcti *rect_dst, const rcti *rct_src)
Definition: interface.cc:245
bool UI_block_active_only_flagged_buttons(const bContext *C, ARegion *region, uiBlock *block)
Definition: interface.cc:1063
void ui_region_to_window(const ARegion *region, int *r_x, int *r_y)
Definition: interface.cc:261
int ui_but_is_pushed_ex(uiBut *but, double *value)
Definition: interface.cc:2156
void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
Definition: interface.cc:2911
#define PREVIEW_TILE_PAD
Definition: interface.cc:4971
bContextStore * UI_but_context_get(const uiBut *but)
Definition: interface.cc:5929
void ui_block_to_window(const ARegion *region, uiBlock *block, int *r_x, int *r_y)
Definition: interface.cc:149
static void ui_but_extra_icons_update_from_old_but(const uiBut *new_but, const uiBut *old_but)
Definition: interface.cc:822
void ui_block_to_region_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
Definition: interface.cc:123
void UI_but_execute(const bContext *C, ARegion *region, uiBut *but)
Definition: interface.cc:1093
static bool ui_but_is_unit_radians_ex(UnitSettings *unit, const int unit_type)
Definition: interface.cc:108
const char ui_radial_dir_to_numpad[8]
Definition: interface.cc:1555
static void ui_menu_block_set_keyaccels(uiBlock *block)
Definition: interface.cc:1124
static bool ui_but_event_operator_string_from_menu(const bContext *C, uiBut *but, char *buf, const size_t buf_len)
Definition: interface.cc:1265
static bool ui_but_pixelrect_in_view(const ARegion *region, const rcti *rect)
Definition: interface.cc:2032
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)
Definition: interface.cc:5454
void UI_but_context_ptr_set(uiBlock *block, uiBut *but, const char *name, const PointerRNA *ptr)
Definition: interface.cc:5918
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)
Definition: interface.cc:5484
void ui_window_to_region(const ARegion *region, int *r_x, int *r_y)
Definition: interface.cc:239
int UI_autocomplete_end(AutoComplete *autocpl, char *autoname)
Definition: interface.cc:4948
bool ui_but_rna_equals(const uiBut *a, const uiBut *b)
Definition: interface.cc:705
void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3])
Definition: interface.cc:3933
#define UI_BUT_VALUE_UNSET
Definition: interface.cc:90
bool ui_but_is_rna_valid(uiBut *but)
Definition: interface.cc:2475
static void ui_block_bounds_calc_text(uiBlock *block, float offset)
Definition: interface.cc:371
bool UI_block_is_search_only(const uiBlock *block)
Definition: interface.cc:3639
uiBut * ui_but_find_old(uiBlock *block_old, const uiBut *but_new)
Definition: interface.cc:784
void UI_but_type_set_menu_from_pulldown(uiBut *but)
Definition: interface.cc:5895
void ui_window_to_block_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
Definition: interface.cc:191
void UI_region_message_subscribe(ARegion *region, struct wmMsgBus *mbus)
Definition: interface.cc:2147
bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
Definition: interface.cc:3098
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
Definition: interface.cc:3629
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)
Definition: interface.cc:5134
bool ui_but_menu_draw_as_popover(const uiBut *but)
Definition: interface.cc:4494
void ui_but_value_set(uiBut *but, double value)
Definition: interface.cc:2557
#define B_NOP
Definition: interface.cc:97
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)
Definition: interface.cc:5258
static void ui_but_update_ex(uiBut *but, const bool validate)
Definition: interface.cc:3722
bool ui_but_rna_equals_ex(const uiBut *but, const PointerRNA *ptr, const PropertyRNA *prop, int index)
Definition: interface.cc:710
uiBut * uiDefIconTextButO(uiBlock *block, int type, const char *opname, wmOperatorCallContext opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5774
void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.cc:5965
#define UI_GET_BUT_VALUE_INIT(_but, _value)
Definition: interface.cc:91
void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn)
Definition: interface.cc:6300
void ui_window_to_block_rctf(const struct ARegion *region, uiBlock *block, rctf *rct_dst, const rctf *rct_src)
Definition: interface.cc:218
static float ui_but_get_float_step_size(uiBut *but)
Definition: interface.cc:648
static bool ui_but_hide_fraction(uiBut *but, double value)
Definition: interface.cc:657
static bool ui_number_from_string_units(bContext *C, const char *str, const int unit_type, const UnitSettings *unit, double *r_value)
Definition: interface.cc:2974
void UI_block_bounds_set_menu(uiBlock *block, int addval, const int bounds_offset[2])
Definition: interface.cc:612
void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1)
Definition: interface.cc:5983
uiBut * uiDefBlockButN(uiBlock *block, uiBlockCreateFunc func, void *argN, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6063
void UI_but_unit_type_set(uiBut *but, const int unit_type)
Definition: interface.cc:5934
void UI_but_drawflag_disable(uiBut *but, int flag)
Definition: interface.cc:5878
void UI_block_draw(const bContext *C, uiBlock *block)
Definition: interface.cc:2039
static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but)
Definition: interface.cc:1706
int UI_preview_tile_size_x(void)
Definition: interface.cc:4973
uiBut * uiDefIconButO_ptr(uiBlock *block, int type, wmOperatorType *ot, wmOperatorCallContext opcontext, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5593
void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
Definition: interface.cc:1907
void UI_block_bounds_set_text(uiBlock *block, int addval)
Definition: interface.cc:592
static bool ui_but_is_rna_undo(const uiBut *but)
Definition: interface.cc:1103
static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len)
Definition: interface.cc:1329
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.cc:6000
static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
Definition: interface.cc:2997
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)
Definition: interface.cc:5164
void UI_block_align_begin(uiBlock *block)
Definition: interface.cc:3910
void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
Definition: interface.cc:2690
uiBut * uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6046
uiBut * uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6143
void ui_but_rna_menu_convert_to_panel_type(uiBut *but, const char *panel_type)
Definition: interface.cc:4485
PredefinedExtraOpIconType
Definition: interface.cc:1638
@ PREDEFINED_EXTRA_OP_ICON_CLEAR
Definition: interface.cc:1640
@ PREDEFINED_EXTRA_OP_ICON_EYEDROPPER
Definition: interface.cc:1641
@ PREDEFINED_EXTRA_OP_ICON_NONE
Definition: interface.cc:1639
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)
Definition: interface.cc:2781
void UI_blocklist_free_inactive(const bContext *C, ARegion *region)
Definition: interface.cc:3527
void ui_window_to_region_rctf(const ARegion *region, rctf *rect_dst, const rctf *rct_src)
Definition: interface.cc:253
static void ui_def_but_rna__menu_type(bContext *UNUSED(C), uiLayout *layout, void *but_p)
void ui_but_update_edited(uiBut *but)
Definition: interface.cc:3905
static void ui_but_build_drawstr_float(uiBut *but, double value)
Definition: interface.cc:3649
void ui_but_v3_set(uiBut *but, const float vec[3])
Definition: interface.cc:2338
void ui_but_v3_get(uiBut *but, float vec[3])
Definition: interface.cc:2291
static double ui_get_but_scale_unit(uiBut *but, double value)
Definition: interface.cc:2677
static bool ui_but_event_operator_string_from_panel(const bContext *C, uiBut *but, char *buf, const size_t buf_len)
Definition: interface.cc:1289
void UI_but_func_search_set_results_are_suggestions(uiBut *but, const bool value)
Definition: interface.cc:6324
#define UI_NUMBER_EVAL_ERROR_PREFIX
Definition: interface.cc:2972
void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
Definition: interface.cc:6308
void UI_but_hint_drawstr_set(uiBut *but, const char *string)
Definition: interface.cc:6443
void UI_interface_tag_script_reload(void)
Definition: interface.cc:6793
void UI_block_order_flip(uiBlock *block)
Definition: interface.cc:5815
static void ui_but_build_drawstr_int(uiBut *but, int value)
Definition: interface.cc:3697
void UI_blocklist_draw(const bContext *C, const ListBase *lb)
Definition: interface.cc:3505
PointerRNA * UI_but_extra_operator_icon_opptr_get(uiButExtraOpIcon *extra_icon)
Definition: interface.cc:1701
int UI_blocklist_min_y_get(ListBase *lb)
Definition: interface.cc:5797
static void ui_but_to_pixelrect(struct rcti *rect, const struct ARegion *region, struct uiBlock *block, const struct uiBut *but)
uiBut * uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:6101
void UI_block_func_butmenu_set(uiBlock *block, uiMenuHandleFunc func, void *arg)
Definition: interface.cc:5959
void UI_but_number_precision_set(uiBut *but, float precision)
Definition: interface.cc:6464
void UI_block_bounds_set_centered(uiBlock *block, int addval)
Definition: interface.cc:624
bool UI_but_active_only(const bContext *C, ARegion *region, uiBlock *block, uiBut *but)
Definition: interface.cc:1058
bool ui_but_string_eval_number(bContext *C, const uiBut *but, const char *str, double *r_value)
Definition: interface.cc:3044
void ui_fontscale(float *points, float aspect)
Definition: interface.cc:2014
void ui_block_to_window_fl(const ARegion *region, uiBlock *block, float *r_x, float *r_y)
Definition: interface.cc:142
static bool ui_but_icon_extra_is_visible_search_eyedropper(uiBut *but)
Definition: interface.cc:1719
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)
Definition: interface.cc:5072
PointerRNA * UI_but_extra_operator_icon_add(uiBut *but, const char *opname, wmOperatorCallContext opcontext, int icon)
Definition: interface.cc:1682
void UI_block_free(const bContext *C, uiBlock *block)
Definition: interface.cc:3456
static void ui_but_alloc_info(const eButType type, size_t *r_alloc_size, const char **r_alloc_str, bool *r_has_custom_type)
Definition: interface.cc:3940
struct ColorManagedDisplay * ui_block_cm_display_get(uiBlock *block)
Definition: interface.cc:3928
static void ui_block_message_subscribe(ARegion *region, struct wmMsgBus *mbus, uiBlock *block)
Definition: interface.cc:2124
int ui_but_string_get_max_length(uiBut *but)
Definition: interface.cc:2653
static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, bool pad, int float_precision)
Definition: interface.cc:2710
void UI_block_region_set(uiBlock *block, ARegion *region)
Definition: interface.cc:3551
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)
Definition: interface.cc:6217
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)
Definition: interface.cc:5226
void UI_block_direction_set(uiBlock *block, char direction)
Definition: interface.cc:5810
static void ui_update_flexible_spacing(const ARegion *region, uiBlock *block)
Definition: interface.cc:267
void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN)
Definition: interface.cc:6488
int UI_preview_tile_size_y(void)
Definition: interface.cc:4979
static uiBut * ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType *ot, wmOperatorCallContext opcontext, const char *str, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:4770
static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
Definition: interface.cc:1564
static void ui_block_bounds_calc_centered_pie(uiBlock *block)
Definition: interface.cc:502
void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg)
Definition: interface.cc:6018
void UI_exit(void)
Definition: interface.cc:6787
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
Definition: interface.cc:6007
void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_strip)
Definition: interface.cc:1205
uiBut * ui_but_find_new(uiBlock *block_new, const uiBut *but_old)
Definition: interface.cc:794
void UI_reinit_font(void)
Definition: interface.cc:6782
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)
Definition: interface.cc:5007
static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value)
Definition: interface.cc:3013
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.cc:5848
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)
Definition: interface.cc:5422
void ui_but_rna_menu_convert_to_menu_type(uiBut *but, const char *menu_type)
Definition: interface.cc:4514
void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r_rect)
Definition: interface.cc:342
void UI_block_translate(uiBlock *block, int x, int y)
Definition: interface.cc:356
int UI_preview_tile_size_y_no_label(void)
Definition: interface.cc:4990
static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
Definition: interface.cc:726
static bool ui_but_extra_icon_event_operator_string(const bContext *C, uiButExtraOpIcon *extra_icon, char *buf, const size_t buf_len)
Definition: interface.cc:1353
static void ui_but_update_select_flag(uiBut *but, double *value)
Definition: interface.cc:2259
static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but)
Definition: interface.cc:1712
const char ui_radial_dir_order[8]
Definition: interface.cc:1544
void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2)
Definition: interface.cc:5972
static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut **but_p, uiBut **but_old_p)
Definition: interface.cc:943
static void ui_but_string_free_internal(uiBut *but)
Definition: interface.cc:3087
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)
Definition: interface.cc:5356
uiBut * uiDefButAlert(uiBlock *block, int icon, int x, int y, short width, short height)
Definition: interface.cc:4847
void UI_init_userdef(void)
Definition: interface.cc:6776
static void ui_but_free(const bContext *C, uiBut *but)
Definition: interface.cc:3406
void ui_window_to_block(const ARegion *region, uiBlock *block, int *r_x, int *r_y)
Definition: interface.cc:228
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)
Definition: interface.cc:5280
static void ui_but_submenu_enable(uiBlock *block, uiBut *but)
Definition: interface.cc:4523
void UI_block_end(const bContext *C, uiBlock *block)
Definition: interface.cc:2005
void ui_block_to_region_rctf(const ARegion *region, uiBlock *block, rctf *rct_dst, const rctf *rct_src)
Definition: interface.cc:160
void UI_block_set_search_only(uiBlock *block, bool search_only)
Definition: interface.cc:3644
void UI_but_node_link_set(uiBut *but, bNodeSocket *socket, const float draw_color[4])
Definition: interface.cc:6448
void UI_block_lock_set(uiBlock *block, bool val, const char *lockstr)
Definition: interface.cc:2273
static void operator_enum_search_update_fn(const struct bContext *C, void *but, const char *str, uiSearchItems *items, const bool UNUSED(is_first))
Definition: interface.cc:6333
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)
Definition: interface.cc:5989
void UI_autocomplete_update_name(AutoComplete *autocpl, const char *name)
Definition: interface.cc:4914
char * ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
Definition: interface.cc:2916
static float ui_get_but_step_unit(uiBut *but, float step_default)
Definition: interface.cc:2745
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.cc:5858
static void ui_def_but_rna__panel_type(bContext *UNUSED(C), uiLayout *layout, void *but_p)
static void ui_but_string_set_internal(uiBut *but, const char *str, size_t str_len)
Definition: interface.cc:3072
bool ui_but_context_poll_operator(bContext *C, wmOperatorType *ot, const uiBut *but)
Definition: interface.cc:1898
static bool ui_but_extra_icons_equals_old(const uiButExtraOpIcon *new_extra_icon, const uiButExtraOpIcon *old_extra_icon)
Definition: interface.cc:804
bool ui_but_supports_cycling(const uiBut *but)
Definition: interface.cc:2484
static double soft_range_round_up(double value, double max)
Definition: interface.cc:3228
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)
Definition: interface.cc:4736
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)
Definition: interface.cc:5645
bool UI_but_flag_is_set(uiBut *but, int flag)
Definition: interface.cc:5868
bool ui_but_is_bool(const uiBut *but)
Definition: interface.cc:2397
static void ui_but_pie_direction_string(uiBut *but, char *buf, int size)
Definition: interface.cc:1558
uiBut * uiDefIconButO(uiBlock *block, int type, const char *opname, wmOperatorCallContext opcontext, int icon, int x, int y, short width, short height, const char *tip)
Definition: interface.cc:5608
void UI_block_bounds_set_explicit(uiBlock *block, int minx, int miny, int maxx, int maxy)
Definition: interface.cc:630
void UI_block_align_end(uiBlock *block)
Definition: interface.cc:3923
bool ui_but_can_align(const uiBut *but)
void ui_block_align_calc(uiBlock *block, const ARegion *region)
bool ui_but_anim_expression_create(uiBut *but, const char *str)
void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen)
void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but)
bool ui_but_anim_expression_set(uiBut *but, const char *str)
void ui_button_group_replace_but_ptr(uiBlock *block, const void *old_but_ptr, uiBut *new_but)
void ui_block_free_button_groups(uiBlock *block)
void ui_but_drag_free(uiBut *but)
void ui_but_execute_end(struct bContext *C, struct ARegion *UNUSED(region), uiBut *but, void *active_back)
bool ui_but_is_editing(const uiBut *but)
void ui_but_clipboard_free(void)
void ui_but_active_free(const bContext *C, uiBut *but)
void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but)
void ui_but_update_view_for_active(const bContext *C, const uiBlock *block)
void ui_but_execute_begin(struct bContext *UNUSED(C), struct ARegion *region, uiBut *but, void **active_back)
void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big)
#define UI_POPUP_MENU_TOP
#define UI_BITBUT_TEST(a, b)
bool ui_but_menu_step_poll(const uiBut *but)
uiBut * ui_region_find_active_but(struct ARegion *region) ATTR_WARN_UNUSED_RESULT
struct uiButViewItem uiButViewItem
@ UI_RADIAL_W
@ UI_RADIAL_E
@ UI_RADIAL_NONE
@ UI_RADIAL_N
@ UI_RADIAL_SE
@ UI_RADIAL_SW
@ UI_RADIAL_S
@ UI_RADIAL_NE
@ UI_RADIAL_NW
bool ui_block_is_popover(const uiBlock *block) ATTR_WARN_UNUSED_RESULT
struct uiButNumber uiButNumber
void ui_but_search_refresh(uiButSearch *but)
void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect)
bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but)
struct ARegion * ui_searchbox_create_generic(struct bContext *C, struct ARegion *butregion, uiButSearch *search_but)
struct uiButTab uiButTab
void ui_draw_popover_back(struct ARegion *region, struct uiStyle *style, uiBlock *block, rcti *rect)
void ui_draw_but(const struct bContext *C, struct ARegion *region, struct uiStyle *style, uiBut *but, rcti *rect)
struct uiButHSVCube uiButHSVCube
void ui_resources_init(void)
Definition: resources.c:53
bool ui_block_is_menu(const uiBlock *block) ATTR_WARN_UNUSED_RESULT
struct uiButProgressbar uiButProgressbar
struct uiButSearch uiButSearch
struct uiButDecorator uiButDecorator
struct uiButColor uiButColor
void ui_item_paneltype_func(struct bContext *C, struct uiLayout *layout, void *arg_pt)
struct uiButCurveMapping uiButCurveMapping
void ui_interface_tag_script_reload_queries(void)
bool ui_but_is_editable(const uiBut *but) ATTR_WARN_UNUSED_RESULT
void ui_block_free_views(struct uiBlock *block)
struct uiButColorBand uiButColorBand
@ UI_BLOCK_CONTAINS_SUBMENU_BUT
void uiStyleInit(void)
struct uiButCurveProfile uiButCurveProfile
void ui_item_menutype_func(struct bContext *C, struct uiLayout *layout, void *arg_mt)
void ui_draw_aligned_panel(const struct uiStyle *style, const uiBlock *block, const rcti *rect, bool show_pin, bool show_background, bool region_search_filter_active)
void ui_layout_remove_but(uiLayout *layout, const uiBut *but)
void ui_layout_add_but(uiLayout *layout, uiBut *but)
void ui_resources_free(void)
Definition: resources.c:58
struct uiButHotkeyEvent uiButHotkeyEvent
@ UI_ACTIVE
@ UI_SELECT_DRAW
@ UI_HIDDEN
@ UI_SCROLLED
@ UI_HAS_ICON
@ UI_SELECT
@ UI_BUT_ACTIVE_OVERRIDE
void ui_draw_pie_center(uiBlock *block)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define GS(x)
Definition: iris.c:225
ccl_gpu_kernel_postfix ccl_global float int int sy
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
const int state
ccl_gpu_kernel_postfix ccl_global float int sx
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_recallocN_id)(void *vmemh, size_t len, const char *str)
Definition: mallocn.c:30
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
ccl_device_inline float3 log(float3 v)
Definition: math_float3.h:397
MINLINE void zero_v2_int(int r[2])
static int left
static void error(const char *str)
Definition: meshlaplacian.c:51
#define floorf(x)
Definition: metal/compat.h:224
#define fabsf(x)
Definition: metal/compat.h:219
bool isfinite(uchar)
Definition: scene/image.cpp:31
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
bool active
all scheduled work for the GPU.
void split(const std::string &s, const char delim, std::vector< std::string > &tokens)
Definition: abc_util.cc:92
T floor(const T &a)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
Definition: rna_access.c:1639
const char * RNA_struct_identifier(const StructRNA *type)
Definition: rna_access.c:586
bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1966
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
Definition: rna_access.c:2352
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:2449
void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
Definition: rna_access.c:1227
bool RNA_property_array_check(PropertyRNA *prop)
Definition: rna_access.c:1080
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:695
void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *values)
Definition: rna_access.c:2879
PropertyScaleType RNA_property_ui_scale(PropertyRNA *prop)
Definition: rna_access.c:1037
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
bool RNA_struct_is_ID(const StructRNA *type)
Definition: rna_access.c:655
int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2581
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
Definition: rna_access.c:1311
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
Definition: rna_access.c:3036
int RNA_property_ui_icon(const PropertyRNA *prop)
Definition: rna_access.c:1900
const char * RNA_struct_ui_description(const StructRNA *type)
Definition: rna_access.c:609
char * RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:907
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2954
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value, ReportList *reports)
Definition: rna_access.c:3532
void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin, float *hardmax)
Definition: rna_access.c:1274
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
const PointerRNA PointerRNA_NULL
Definition: rna_access.c:61
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3421
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3493
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
Definition: rna_access.c:758
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2153
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:3178
void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, float values[2])
Definition: rna_access.c:2917
void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
Definition: rna_access.c:2652
void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
Definition: rna_access.c:1560
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2429
const char * RNA_property_translation_context(const PropertyRNA *prop)
Definition: rna_access.c:1895
int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr)
Definition: rna_access.c:4184
bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
Definition: rna_access.c:1971
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1405
int RNA_property_flag(PropertyRNA *prop)
Definition: rna_access.c:1055
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2180
void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int values[2])
Definition: rna_access.c:2544
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
Definition: rna_access.c:624
bool RNA_property_enum_item_from_value_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, EnumPropertyItem *r_item)
Definition: rna_access.c:1842
bool RNA_struct_undo_check(const StructRNA *type)
Definition: rna_access.c:660
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1075
int RNA_property_string_maxlength(PropertyRNA *prop)
Definition: rna_access.c:1399
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
Definition: rna_access.c:2978
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2790
int RNA_enum_from_value(const EnumPropertyItem *item, const int value)
Definition: rna_access.c:1736
PropertySubType RNA_property_subtype(PropertyRNA *prop)
Definition: rna_access.c:1015
const char * RNA_struct_translation_context(const StructRNA *type)
Definition: rna_access.c:619
void RNA_property_int_range(PointerRNA *ptr, PropertyRNA *prop, int *hardmin, int *hardmax)
Definition: rna_access.c:1190
void RNA_property_enum_items(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **r_item, int *r_totitem, bool *r_free)
Definition: rna_access.c:1495
bool RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: rna_access.c:2275
const char * RNA_property_ui_description(const PropertyRNA *prop)
Definition: rna_access.c:1885
const char * RNA_property_ui_name(const PropertyRNA *prop)
Definition: rna_access.c:1875
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
Definition: rna_access.c:3239
bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
Definition: rna_access.c:1777
eRNAOverrideStatus RNA_property_override_library_status(Main *bmain, PointerRNA *ptr, PropertyRNA *prop, const int index)
#define min(a, b)
Definition: sort.c:35
struct GHash * block_name_map
ARegion_Runtime runtime
ListBase uiblocks
size_t maxlen
Definition: interface.cc:4895
const char * startname
Definition: interface.cc:4898
char * truncate
Definition: interface.cc:4897
const char * report_prefix
struct ReportList * reports
const char * identifier
Definition: RNA_types.h:461
const char * name
Definition: RNA_types.h:465
const char * description
Definition: RNA_types.h:467
StructRNA * srna
Definition: RNA_types.h:766
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:362
ExtensionRNA rna_ext
Definition: BKE_screen.h:373
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:361
char translation_context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:363
ExtensionRNA rna_ext
Definition: BKE_screen.h:274
short region_type
Definition: BKE_screen.h:234
char idname[BKE_ST_MAXNAME]
Definition: BKE_screen.h:223
short space_type
Definition: BKE_screen.h:233
char translation_context[BKE_ST_MAXNAME]
Definition: BKE_screen.h:226
char label[BKE_ST_MAXNAME]
Definition: BKE_screen.h:224
struct PanelType * type
float pie_center_spawned[2]
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
struct RenderData r
struct UnitSettings unit
ColorManagedDisplaySettings display_settings
uiWidgetColors wcol_menu_back
ThemeUI tui
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63
float winmat[4][4]
eUIEmbossType emboss
void * func_argN
void * drawextra_arg2
bool tooltipdisabled
char display_device[64]
ListBase layouts
ListBase button_groups
uiButHandleNFunc funcN
struct Panel * panel
struct UnitSettings * unit
void * drawextra_arg1
ColorPickerData color_pickers
ListBase saferct
uiBlock * oldblock
uiPopupBlockHandle * handle
struct PieMenuData pie_data
uiBlockHandleFunc handle_func
double auto_open_last
int bounds_offset[2]
ListBase buttons
void * butm_func_arg
const char * lockstr
eBlockBoundsCalc bounds_type
uiMenuHandleFunc butm_func
char name[UI_MAX_NAME_STR]
uiButHandleFunc func
char theme_style
void * handle_func_arg
short content_hints
ListBase butstore
struct uiLayout * curlayout
void * func_arg1
void(* drawextra)(const struct bContext *C, void *idv, void *arg1, void *arg2, rcti *rect)
void * evil_C
void * func_arg2
ListBase contexts
struct wmOperatorCallParams * optype_params
uiButSearchUpdateFn items_update_fn
bool results_are_suggestions
const char * item_sep_string
uiButSearchCreateFn popup_create_fn
uiFreeArgFunc arg_free_fn
struct PointerRNA rnasearchpoin
uiButSearchTooltipFn item_tooltip_fn
struct PropertyRNA * rnasearchprop
uiButSearchContextMenuFn item_context_menu_fn
uiViewItemHandle * view_item
wmOperatorCallContext opcontext
const char * tip
uiButCompleteFunc autocomplete_func
struct bContextStore * context
ListBase extra_op_icons
struct uiBut * prev
void * custom_data
struct uiBut * next
uiButIdentityCompareFunc identity_cmp_func
uiButHandleNFunc funcN
void * func_arg2
RadialDirection pie_dir
struct uiHandleButtonData * active
float * editvec
void * dragpoin
char * editstr
eButType type
float softmin
double * editval
const void * pushed_state_arg
float hardmax
uiButHandleFunc func
eButPointerType pointype
const char * disabled_info
uchar unit_type
void * tip_arg
uiBlock * block
eUIEmbossType emboss
short bitnr
uiMenuCreateFunc menu_create_func
char * poin
uiButToolTipFunc tip_func
void * func_arg1
short alignnr
float hardmin
uiButHandleHoldFunc hold_func
void * hold_argN
short retval
struct ImBuf * imb
BIFIconID icon
struct PointerRNA * opptr
struct wmOperatorType * optype
uiButHandleRenameFunc rename_func
uiBlockCreateFunc block_create_func
uiFreeArgFunc tip_arg_free
float softmax
short iconadd
char dragtype
char drawstr[UI_MAX_DRAW_STR]
void * autofunc_arg
char strdata[UI_MAX_NAME_STR]
void * rename_arg1
uiMenuStepFunc menu_step_func
uiLayout * layout
struct PropertyRNA * rnaprop
void * func_argN
char * str
uiButPushedStateFunc pushed_state_func
uchar col[4]
struct PointerRNA rnapoin
struct uiPopupBlockCreate popup_create_vars
uiStringInfoType type
uiFontStyle paneltitle
uiFontStyle grouplabel
uiFontStyle widget
uiFontStyle widgetlabel
unsigned char text[4]
int xy[2]
Definition: WM_types.h:682
wmMsgNotifyFn notify
struct wmOperatorType * optype
Definition: WM_types.h:1008
struct PointerRNA * opptr
Definition: WM_types.h:1009
wmOperatorCallContext opcontext
Definition: WM_types.h:1010
const char * idname
Definition: WM_types.h:890
char *(* get_description)(struct bContext *C, struct wmOperatorType *, struct PointerRNA *)
Definition: WM_types.h:966
struct StructRNA * srna
Definition: WM_types.h:969
PropertyRNA * prop
Definition: WM_types.h:981
struct wmEvent * eventstate
float max
int xy[2]
Definition: wm_draw.c:135
bool WM_operator_poll_context(bContext *C, wmOperatorType *ot, short context)
wmEvent * wm_event_add(wmWindow *win, const wmEvent *event_to_add)
void WM_report_banner_show(void)
void wm_event_init_from_window(wmWindow *win, wmEvent *event)
@ EVT_BUT_OPEN
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479
const char * WM_key_event_string(const short type, const bool compact)
Definition: wm_keymap.c:1046
char * WM_key_event_operator_string(const bContext *C, const char *opname, wmOperatorCallContext opcontext, IDProperty *properties, const bool is_strict, char *result, const int result_len)
Definition: wm_keymap.c:1636
MenuType * WM_menutype_find(const char *idname, bool quiet)
Definition: wm_menu_type.c:30
void WM_msg_subscribe_rna(struct wmMsgBus *mbus, PointerRNA *ptr, const PropertyRNA *prop, const wmMsgSubscribeValue *msg_val_params, const char *id_repr)
char * WM_operatortype_description(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *properties)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
const char * WM_operatortype_name(struct wmOperatorType *ot, struct PointerRNA *properties)
char * WM_context_path_resolve_property_full(const bContext *C, const PointerRNA *ptr, PropertyRNA *prop, int index)
Definition: wm_operators.c:569
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
Definition: wm_operators.c:661
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:783
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
Definition: wm_operators.c:701
PanelType * WM_paneltype_find(const char *idname, bool quiet)
Definition: wm_panel_type.c:28
void wmGetProjectionMatrix(float mat[4][4], const rcti *winrct)
Definition: wm_subwindow.c:113
void wmOrtho2_region_pixelspace(const ARegion *region)
Definition: wm_subwindow.c:103
int WM_window_pixels_y(const wmWindow *win)
Definition: wm_window.c:2082
int WM_window_pixels_x(const wmWindow *win)
Definition: wm_window.c:2076