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