Blender  V3.3
ed_draw.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2008 Blender Foundation. All rights reserved. */
3 
8 #include <math.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLI_listbase.h"
15 #include "BLI_path_util.h"
16 #include "BLI_rect.h"
17 #include "BLI_string.h"
18 #include "BLI_utildefines.h"
19 
20 #include "BLT_translation.h"
21 
22 #include "BKE_context.h"
23 #include "BKE_image.h"
24 
25 #include "BLF_api.h"
26 
27 #include "IMB_imbuf_types.h"
28 #include "IMB_metadata.h"
29 
30 #include "ED_screen.h"
31 #include "ED_space_api.h"
32 #include "ED_util.h"
33 
34 #include "GPU_immediate.h"
35 #include "GPU_matrix.h"
36 #include "GPU_state.h"
37 
38 #include "UI_interface.h"
39 #include "UI_resources.h"
40 
41 #include "RNA_access.h"
42 #include "WM_api.h"
43 #include "WM_types.h"
44 
45 /* -------------------------------------------------------------------- */
56 #define SLIDE_PIXEL_DISTANCE (300.0f * U.dpi_fac)
57 #define OVERSHOOT_RANGE_DELTA 0.2f
58 
59 typedef struct tSlider {
60  struct Scene *scene;
61  struct ScrArea *area;
62 
65 
67  void *draw_handle;
68 
70  float raw_factor;
71 
73  float factor;
74 
76  float last_cursor[2];
77 
80 
82  bool overshoot;
83 
85  bool increments;
86 
88  bool precision;
90 
91 static void draw_overshoot_triangle(const uint8_t color[4],
92  const bool facing_right,
93  const float x,
94  const float y)
95 {
96  const uint shdr_pos_2d = GPU_vertformat_attr_add(
100  GPU_polygon_smooth(true);
102  const float triangle_side_length = facing_right ? 6 * U.pixelsize : -6 * U.pixelsize;
103  const float triangle_offset = facing_right ? 2 * U.pixelsize : -2 * U.pixelsize;
104 
106  immVertex2f(shdr_pos_2d, x + triangle_offset + triangle_side_length, y);
107  immVertex2f(shdr_pos_2d, x + triangle_offset, y + triangle_side_length / 2);
108  immVertex2f(shdr_pos_2d, x + triangle_offset, y - triangle_side_length / 2);
109  immEnd();
110 
111  GPU_polygon_smooth(false);
114 }
115 
116 static void draw_ticks(const float start_factor,
117  const float end_factor,
118  const float line_start[2],
119  const float base_tick_height,
120  const float line_width,
121  const uint8_t color_overshoot[4],
122  const uint8_t color_line[4])
123 {
124  /* Use factor represented as 0-100 int to avoid floating point precision problems. */
125  const int tick_increment = 10;
126 
127  /* Round initial_tick_factor up to the next tick_increment. */
128  int tick_percentage = ceil((start_factor * 100) / tick_increment) * tick_increment;
129 
130  while (tick_percentage <= (int)(end_factor * 100)) {
131  float tick_height;
132  /* Different ticks have different heights. Multiples of 100% are the tallest, 50% is a bit
133  * smaller and the rest is the minimum size. */
134  if (tick_percentage % 100 == 0) {
135  tick_height = base_tick_height;
136  }
137  else if (tick_percentage % 50 == 0) {
138  tick_height = base_tick_height * 0.8;
139  }
140  else {
141  tick_height = base_tick_height * 0.5;
142  }
143 
144  const float x = line_start[0] +
145  (((float)tick_percentage / 100) - start_factor) * SLIDE_PIXEL_DISTANCE;
146  const rctf tick_rect = {
147  .xmin = x - (line_width / 2),
148  .xmax = x + (line_width / 2),
149  .ymin = line_start[1] - (tick_height / 2),
150  .ymax = line_start[1] + (tick_height / 2),
151  };
152 
153  if (tick_percentage < 0 || tick_percentage > 100) {
154  UI_draw_roundbox_3ub_alpha(&tick_rect, true, 1, color_overshoot, 255);
155  }
156  else {
157  UI_draw_roundbox_3ub_alpha(&tick_rect, true, 1, color_line, 255);
158  }
159  tick_percentage += tick_increment;
160  }
161 }
162 
163 static void draw_main_line(const rctf *main_line_rect,
164  const float factor,
165  const bool overshoot,
166  const uint8_t color_overshoot[4],
167  const uint8_t color_line[4])
168 {
169  if (overshoot) {
170  /* In overshoot mode, draw the 0-100% range differently to provide a visual reference. */
171  const float line_zero_percent = main_line_rect->xmin -
172  ((factor - 0.5f - OVERSHOOT_RANGE_DELTA) *
174 
175  const float clamped_line_zero_percent = clamp_f(
176  line_zero_percent, main_line_rect->xmin, main_line_rect->xmax);
177  const float clamped_line_hundred_percent = clamp_f(
178  line_zero_percent + SLIDE_PIXEL_DISTANCE, main_line_rect->xmin, main_line_rect->xmax);
179 
180  const rctf left_overshoot_line_rect = {
181  .xmin = main_line_rect->xmin,
182  .xmax = clamped_line_zero_percent,
183  .ymin = main_line_rect->ymin,
184  .ymax = main_line_rect->ymax,
185  };
186  const rctf right_overshoot_line_rect = {
187  .xmin = clamped_line_hundred_percent,
188  .xmax = main_line_rect->xmax,
189  .ymin = main_line_rect->ymin,
190  .ymax = main_line_rect->ymax,
191  };
192  UI_draw_roundbox_3ub_alpha(&left_overshoot_line_rect, true, 0, color_overshoot, 255);
193  UI_draw_roundbox_3ub_alpha(&right_overshoot_line_rect, true, 0, color_overshoot, 255);
194 
195  const rctf non_overshoot_line_rect = {
196  .xmin = clamped_line_zero_percent,
197  .xmax = clamped_line_hundred_percent,
198  .ymin = main_line_rect->ymin,
199  .ymax = main_line_rect->ymax,
200  };
201  UI_draw_roundbox_3ub_alpha(&non_overshoot_line_rect, true, 0, color_line, 255);
202  }
203  else {
204  UI_draw_roundbox_3ub_alpha(main_line_rect, true, 0, color_line, 255);
205  }
206 }
207 
208 static void draw_backdrop(const int fontid,
209  const rctf *main_line_rect,
210  const uint8_t color_bg[4],
211  const short region_y_size,
212  const float base_tick_height)
213 {
214  float string_pixel_size[2];
215  const char *percentage_string_placeholder = "000%%";
216  BLF_width_and_height(fontid,
217  percentage_string_placeholder,
218  sizeof(percentage_string_placeholder),
219  &string_pixel_size[0],
220  &string_pixel_size[1]);
221  const float pad[2] = {(region_y_size - base_tick_height) / 2, 2.0f * U.pixelsize};
222  const rctf backdrop_rect = {
223  .xmin = main_line_rect->xmin - string_pixel_size[0] - pad[0],
224  .xmax = main_line_rect->xmax + pad[0],
225  .ymin = pad[1],
226  .ymax = region_y_size - pad[1],
227  };
228  UI_draw_roundbox_3ub_alpha(&backdrop_rect, true, 4.0f, color_bg, color_bg[3]);
229 }
230 
234 static void slider_draw(const struct bContext *UNUSED(C), ARegion *region, void *arg)
235 {
236  tSlider *slider = arg;
237 
238  /* Only draw in region from which the Operator was started. */
239  if (region != slider->region_header) {
240  return;
241  }
242 
243  uint8_t color_text[4];
244  uint8_t color_line[4];
245  uint8_t color_handle[4];
246  uint8_t color_overshoot[4];
247  uint8_t color_bg[4];
248 
249  /* Get theme colors. */
253  UI_GetThemeColor4ubv(TH_HEADER_TEXT, color_overshoot);
254  UI_GetThemeColor4ubv(TH_HEADER, color_bg);
255 
256  color_overshoot[0] = color_overshoot[0] * 0.8;
257  color_overshoot[1] = color_overshoot[1] * 0.8;
258  color_overshoot[2] = color_overshoot[2] * 0.8;
259  color_bg[3] = 160;
260 
261  /* Get the default font. */
262  const uiStyle *style = UI_style_get();
263  const uiFontStyle *fstyle = &style->widget;
264  const int fontid = fstyle->uifont_id;
265  BLF_color3ubv(fontid, color_text);
266  BLF_rotation(fontid, 0.0f);
267 
268  const float line_width = 1.5 * U.pixelsize;
269  const float base_tick_height = 12.0 * U.pixelsize;
270  const float line_y = region->winy / 2;
271 
272  rctf main_line_rect = {
273  .xmin = (region->winx / 2) - (SLIDE_PIXEL_DISTANCE / 2),
274  .xmax = (region->winx / 2) + (SLIDE_PIXEL_DISTANCE / 2),
275  .ymin = line_y - line_width / 2,
276  .ymax = line_y + line_width / 2,
277  };
278  float line_start_factor = 0;
279  int handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * slider->factor;
280 
281  if (slider->overshoot) {
282  main_line_rect.xmin = main_line_rect.xmin - SLIDE_PIXEL_DISTANCE * OVERSHOOT_RANGE_DELTA;
283  main_line_rect.xmax = main_line_rect.xmax + SLIDE_PIXEL_DISTANCE * OVERSHOOT_RANGE_DELTA;
284  line_start_factor = slider->factor - 0.5f - OVERSHOOT_RANGE_DELTA;
285  handle_pos_x = region->winx / 2;
286  }
287 
288  draw_backdrop(fontid, &main_line_rect, color_bg, slider->region_header->winy, base_tick_height);
289 
290  draw_main_line(&main_line_rect, slider->factor, slider->overshoot, color_overshoot, color_line);
291 
292  const float factor_range = slider->overshoot ? 1 + OVERSHOOT_RANGE_DELTA * 2 : 1;
293  const float line_start_position[2] = {main_line_rect.xmin, line_y};
294  draw_ticks(line_start_factor,
295  line_start_factor + factor_range,
296  line_start_position,
297  base_tick_height,
298  line_width,
299  color_overshoot,
300  color_line);
301 
302  /* Draw triangles at the ends of the line in overshoot mode to indicate direction of 0-100%
303  * range. */
304  if (slider->overshoot) {
305  if (slider->factor > 1 + OVERSHOOT_RANGE_DELTA + 0.5) {
306  draw_overshoot_triangle(color_line, false, main_line_rect.xmin, line_y);
307  }
308  if (slider->factor < 0 - OVERSHOOT_RANGE_DELTA - 0.5) {
309  draw_overshoot_triangle(color_line, true, main_line_rect.xmax, line_y);
310  }
311  }
312 
313  char percentage_string[256];
314 
315  /* Draw handle indicating current factor. */
316  const rctf handle_rect = {
317  .xmin = handle_pos_x - (line_width),
318  .xmax = handle_pos_x + (line_width),
319  .ymin = line_y - (base_tick_height / 2),
320  .ymax = line_y + (base_tick_height / 2),
321  };
322 
323  UI_draw_roundbox_3ub_alpha(&handle_rect, true, 1, color_handle, 255);
324  BLI_snprintf(percentage_string, sizeof(percentage_string), "%.0f%%", slider->factor * 100);
325 
326  /* Draw percentage string. */
327  float percentage_string_pixel_size[2];
328  BLF_width_and_height(fontid,
329  percentage_string,
330  sizeof(percentage_string),
331  &percentage_string_pixel_size[0],
332  &percentage_string_pixel_size[1]);
333 
334  BLF_position(fontid,
335  main_line_rect.xmin - 24.0 * U.pixelsize - percentage_string_pixel_size[0] / 2,
336  (region->winy / 2) - percentage_string_pixel_size[1] / 2,
337  0.0f);
338  BLF_draw(fontid, percentage_string, sizeof(percentage_string));
339 }
340 
341 static void slider_update_factor(tSlider *slider, const wmEvent *event)
342 {
343  const float factor_delta = (event->xy[0] - slider->last_cursor[0]) / SLIDE_PIXEL_DISTANCE;
344  /* Reduced factor delta in precision mode (shift held). */
345  slider->raw_factor += slider->precision ? (factor_delta / 8) : factor_delta;
346  slider->factor = slider->raw_factor;
347  copy_v2fl_v2i(slider->last_cursor, event->xy);
348 
349  if (!slider->overshoot) {
350  slider->factor = clamp_f(slider->factor, 0, 1);
351  }
352 
353  if (slider->increments) {
354  slider->factor = round(slider->factor * 10) / 10;
355  }
356 }
357 
359 {
360  tSlider *slider = MEM_callocN(sizeof(tSlider), "tSlider");
361  slider->scene = CTX_data_scene(C);
362  slider->area = CTX_wm_area(C);
363  slider->region_header = CTX_wm_region(C);
364 
365  /* Default is true, caller needs to manually set to false. */
366  slider->allow_overshoot = true;
367 
368  /* Set initial factor. */
369  slider->raw_factor = 0.5f;
370  slider->factor = 0.5;
371 
372  /* Add draw callback. Always in header. */
373  if (slider->area) {
374  LISTBASE_FOREACH (ARegion *, region, &slider->area->regionbase) {
375  if (region->regiontype == RGN_TYPE_HEADER) {
376  slider->region_header = region;
378  region->type, slider_draw, slider, REGION_DRAW_POST_PIXEL);
379  }
380  }
381  }
382 
383  return slider;
384 }
385 
386 void ED_slider_init(struct tSlider *slider, const wmEvent *event)
387 {
388  copy_v2fl_v2i(slider->last_cursor, event->xy);
389 }
390 
391 bool ED_slider_modal(tSlider *slider, const wmEvent *event)
392 {
393  bool event_handled = true;
394  /* Handle key presses. */
395  switch (event->type) {
396  case EVT_EKEY:
397  if (slider->allow_overshoot) {
398  slider->overshoot = event->val == KM_PRESS ? !slider->overshoot : slider->overshoot;
399  slider_update_factor(slider, event);
400  }
401  break;
402  case EVT_LEFTSHIFTKEY:
403  case EVT_RIGHTSHIFTKEY:
404  slider->precision = event->val == KM_PRESS;
405  break;
406  case EVT_LEFTCTRLKEY:
407  case EVT_RIGHTCTRLKEY:
408  slider->increments = event->val == KM_PRESS;
409  break;
410  case MOUSEMOVE:;
411  /* Update factor. */
412  slider_update_factor(slider, event);
413  break;
414  default:
415  event_handled = false;
416  break;
417  }
418 
420 
421  return event_handled;
422 }
423 
424 void ED_slider_status_string_get(const struct tSlider *slider,
425  char *status_string,
426  const size_t size_of_status_string)
427 {
428  /* 50 characters is enough to fit the individual setting strings. Extend if message is longer. */
429  char overshoot_str[50];
430  char precision_str[50];
431  char increments_str[50];
432 
433  if (slider->allow_overshoot) {
434  if (slider->overshoot) {
435  STRNCPY(overshoot_str, TIP_("[E] - Disable overshoot"));
436  }
437  else {
438  STRNCPY(overshoot_str, TIP_("[E] - Enable overshoot"));
439  }
440  }
441  else {
442  STRNCPY(overshoot_str, TIP_("Overshoot disabled"));
443  }
444 
445  if (slider->precision) {
446  STRNCPY(precision_str, TIP_("[Shift] - Precision active"));
447  }
448  else {
449  STRNCPY(precision_str, TIP_("Shift - Hold for precision"));
450  }
451 
452  if (slider->increments) {
453  STRNCPY(increments_str, TIP_("[Ctrl] - Increments active"));
454  }
455  else {
456  STRNCPY(increments_str, TIP_("Ctrl - Hold for 10% increments"));
457  }
458 
459  BLI_snprintf(status_string,
460  size_of_status_string,
461  "%s | %s | %s",
462  overshoot_str,
463  precision_str,
464  increments_str);
465 }
466 
467 void ED_slider_destroy(struct bContext *C, tSlider *slider)
468 {
469  /* Remove draw callback. */
470  if (slider->draw_handle) {
472  }
473  ED_area_status_text(slider->area, NULL);
475  MEM_freeN(slider);
476 }
477 
478 /* Setters & Getters */
479 
480 float ED_slider_factor_get(struct tSlider *slider)
481 {
482  return slider->factor;
483 }
484 
485 void ED_slider_factor_set(struct tSlider *slider, const float factor)
486 {
487  slider->factor = factor;
488  if (!slider->overshoot) {
489  slider->factor = clamp_f(slider->factor, 0, 1);
490  }
491 }
492 
494 {
495  return slider->allow_overshoot;
496 }
497 
498 void ED_slider_allow_overshoot_set(struct tSlider *slider, const bool value)
499 {
500  slider->allow_overshoot = value;
501 }
502 
505 void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *region, void *arg_info)
506 {
507  wmWindow *win = CTX_wm_window(C);
508  const float *mval_src = (float *)arg_info;
509  const float mval_dst[2] = {
510  win->eventstate->xy[0] - region->winrct.xmin,
511  win->eventstate->xy[1] - region->winrct.ymin,
512  };
513 
514  const uint shdr_pos = GPU_vertformat_attr_add(
516 
517  GPU_line_width(1.0f);
518 
520 
521  float viewport_size[4];
522  GPU_viewport_size_get_f(viewport_size);
523  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
524 
525  immUniform1i("colors_len", 0); /* "simple" mode */
527  immUniform1f("dash_width", 6.0f);
528  immUniform1f("dash_factor", 0.5f);
529 
531  immVertex2fv(shdr_pos, mval_src);
532  immVertex2fv(shdr_pos, mval_dst);
533  immEnd();
534 
536 }
537 
538 #define MAX_METADATA_STR 1024
539 
540 static const char *meta_data_list[] = {
541  "File",
542  "Strip",
543  "Date",
544  "RenderTime",
545  "Note",
546  "Marker",
547  "Time",
548  "Frame",
549  "Camera",
550  "Scene",
551 };
552 
553 BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index, int offset)
554 {
555  return (IMB_metadata_get_field(
556  ibuf->metadata, meta_data_list[index], r_str + offset, MAX_METADATA_STR - offset) &&
557  r_str[0]);
558 }
559 
561 {
562  /* Metadata field stored by Blender for multi-layer EXR images. Is rather
563  * useless to be viewed all the time. Can still be seen in the Metadata
564  * panel. */
565  if (STREQ(field, "BlenderMultiChannel")) {
566  return false;
567  }
568  /* Is almost always has value "scanlineimage", also useless to be seen
569  * all the time. */
570  if (STREQ(field, "type")) {
571  return false;
572  }
573  return !BKE_stamp_is_known_field(field);
574 }
575 
577  int fontid;
578  int xmin, ymin;
582 
583 static void metadata_custom_draw_fields(const char *field, const char *value, void *ctx_v)
584 {
585  if (!metadata_is_custom_drawable(field)) {
586  return;
587  }
589  char temp_str[MAX_METADATA_STR];
590  SNPRINTF(temp_str, "%s: %s", field, value);
591  BLF_position(ctx->fontid, ctx->xmin, ctx->ymin + ctx->current_y, 0.0f);
592  BLF_draw(ctx->fontid, temp_str, sizeof(temp_str));
593  ctx->current_y += ctx->vertical_offset;
594 }
595 
596 static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const bool is_top)
597 {
598  char temp_str[MAX_METADATA_STR];
599  int ofs_y = 0;
600  const float height = BLF_height_max(fontid);
601  const float margin = height / 8;
602  const float vertical_offset = (height + margin);
603 
604  /* values taking margins into account */
605  const float descender = BLF_descender(fontid);
606  const float xmin = (rect->xmin + margin);
607  const float xmax = (rect->xmax - margin);
608  const float ymin = (rect->ymin + margin) - descender;
609  const float ymax = (rect->ymax - margin) - descender;
610 
611  if (is_top) {
612  for (int i = 0; i < 4; i++) {
613  /* first line */
614  if (i == 0) {
615  bool do_newline = false;
616  int len = SNPRINTF_RLEN(temp_str, "%s: ", meta_data_list[0]);
617  if (metadata_is_valid(ibuf, temp_str, 0, len)) {
618  BLF_position(fontid, xmin, ymax - vertical_offset, 0.0f);
619  BLF_draw(fontid, temp_str, sizeof(temp_str));
620  do_newline = true;
621  }
622 
623  len = SNPRINTF_RLEN(temp_str, "%s: ", meta_data_list[1]);
624  if (metadata_is_valid(ibuf, temp_str, 1, len)) {
625  int line_width = BLF_width(fontid, temp_str, sizeof(temp_str));
626  BLF_position(fontid, xmax - line_width, ymax - vertical_offset, 0.0f);
627  BLF_draw(fontid, temp_str, sizeof(temp_str));
628  do_newline = true;
629  }
630 
631  if (do_newline) {
632  ofs_y += vertical_offset;
633  }
634  } /* Strip */
635  else if (ELEM(i, 1, 2)) {
636  int len = SNPRINTF_RLEN(temp_str, "%s: ", meta_data_list[i + 1]);
637  if (metadata_is_valid(ibuf, temp_str, i + 1, len)) {
638  BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f);
639  BLF_draw(fontid, temp_str, sizeof(temp_str));
640  ofs_y += vertical_offset;
641  }
642  } /* Note (wrapped) */
643  else if (i == 3) {
644  int len = SNPRINTF_RLEN(temp_str, "%s: ", meta_data_list[i + 1]);
645  if (metadata_is_valid(ibuf, temp_str, i + 1, len)) {
646  struct ResultBLF info;
647  BLF_enable(fontid, BLF_WORD_WRAP);
648  BLF_wordwrap(fontid, ibuf->x - (margin * 2));
649  BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f);
650  BLF_draw_ex(fontid, temp_str, sizeof(temp_str), &info);
651  BLF_wordwrap(fontid, 0);
652  BLF_disable(fontid, BLF_WORD_WRAP);
653  ofs_y += vertical_offset * info.lines;
654  }
655  }
656  else {
657  int len = SNPRINTF_RLEN(temp_str, "%s: ", meta_data_list[i + 1]);
658  if (metadata_is_valid(ibuf, temp_str, i + 1, len)) {
659  int line_width = BLF_width(fontid, temp_str, sizeof(temp_str));
660  BLF_position(fontid, xmax - line_width, ymax - vertical_offset - ofs_y, 0.0f);
661  BLF_draw(fontid, temp_str, sizeof(temp_str));
662  ofs_y += vertical_offset;
663  }
664  }
665  }
666  }
667  else {
669  ctx.fontid = fontid;
670  ctx.xmin = xmin;
671  ctx.ymin = ymin;
672  ctx.current_y = ofs_y;
673  ctx.vertical_offset = vertical_offset;
675  int ofs_x = 0;
676  ofs_y = ctx.current_y;
677  for (int i = 5; i < 10; i++) {
678  int len = SNPRINTF_RLEN(temp_str, "%s: ", meta_data_list[i]);
679  if (metadata_is_valid(ibuf, temp_str, i, len)) {
680  BLF_position(fontid, xmin + ofs_x, ymin + ofs_y, 0.0f);
681  BLF_draw(fontid, temp_str, sizeof(temp_str));
682 
683  ofs_x += BLF_width(fontid, temp_str, sizeof(temp_str)) + UI_UNIT_X;
684  }
685  }
686  }
687 }
688 
690  int count;
692 
693 static void metadata_custom_count_fields(const char *field, const char *UNUSED(value), void *ctx_v)
694 {
695  if (!metadata_is_custom_drawable(field)) {
696  return;
697  }
699  ctx->count++;
700 }
701 
702 static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top)
703 {
704  const float height = BLF_height_max(fontid);
705  const float margin = (height / 8);
706  char str[MAX_METADATA_STR] = "";
707  short count = 0;
708 
709  if (is_top) {
710  if (metadata_is_valid(ibuf, str, 0, 0) || metadata_is_valid(ibuf, str, 1, 0)) {
711  count++;
712  }
713  for (int i = 2; i < 5; i++) {
714  if (metadata_is_valid(ibuf, str, i, 0)) {
715  if (i == 4) {
716  struct {
717  struct ResultBLF info;
718  rcti rect;
719  } wrap;
720 
721  BLF_enable(fontid, BLF_WORD_WRAP);
722  BLF_wordwrap(fontid, ibuf->x - (margin * 2));
723  BLF_boundbox_ex(fontid, str, sizeof(str), &wrap.rect, &wrap.info);
724  BLF_wordwrap(fontid, 0);
725  BLF_disable(fontid, BLF_WORD_WRAP);
726 
727  count += wrap.info.lines;
728  }
729  else {
730  count++;
731  }
732  }
733  }
734  }
735  else {
736  for (int i = 5; i < 10; i++) {
737  if (metadata_is_valid(ibuf, str, i, 0)) {
738  count = 1;
739  break;
740  }
741  }
743  ctx.count = 0;
745  count += ctx.count;
746  }
747 
748  if (count) {
749  return (height + margin) * count;
750  }
751 
752  return 0;
753 }
754 
756  int x, int y, ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
757 {
758  const uiStyle *style = UI_style_get_dpi();
759 
760  if (!ibuf->metadata) {
761  return;
762  }
763 
764  /* find window pixel coordinates of origin */
765  GPU_matrix_push();
766 
767  /* Offset and zoom using GPU viewport. */
769  GPU_matrix_scale_2f(zoomx, zoomy);
770 
771  BLF_size(blf_mono_font, style->widgetlabel.points * 1.5f * U.pixelsize, U.dpi);
772 
773  /* *** upper box*** */
774 
775  /* get needed box height */
776  float box_y = metadata_box_height_get(ibuf, blf_mono_font, true);
777 
778  if (box_y) {
779  /* set up rect */
780  rctf rect;
781  BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymax, frame->ymax + box_y);
782  /* draw top box */
787  immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
789 
790  BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
792 
794  metadata_draw_imbuf(ibuf, &rect, blf_mono_font, true);
795 
797  }
798 
799  /* *** lower box*** */
800 
801  box_y = metadata_box_height_get(ibuf, blf_mono_font, false);
802 
803  if (box_y) {
804  /* set up box rect */
805  rctf rect;
806  BLI_rctf_init(&rect, frame->xmin, frame->xmax, frame->ymin - box_y, frame->ymin);
807  /* draw top box */
812  immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
814 
815  BLF_clipping(blf_mono_font, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
817 
819  metadata_draw_imbuf(ibuf, &rect, blf_mono_font, false);
820 
822  }
823 
824  GPU_matrix_pop();
825 }
826 
827 #undef MAX_METADATA_STR
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
bool BKE_stamp_is_known_field(const char *field_name)
@ BLF_WORD_WRAP
Definition: BLF_api.h:340
@ BLF_CLIPPING
Definition: BLF_api.h:335
int BLF_descender(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:744
void BLF_color3ubv(int fontid, const unsigned char rgb[3])
Definition: blf.c:407
void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax)
Definition: blf.c:775
void BLF_width_and_height(int fontid, const char *str, size_t str_len, float *r_width, float *r_height) ATTR_NONNULL()
Definition: blf.c:662
void BLF_boundbox_ex(int fontid, const char *str, size_t str_len, struct rcti *box, struct ResultBLF *r_info) ATTR_NONNULL(2)
Definition: blf.c:640
void BLF_disable(int fontid, int option)
Definition: blf.c:279
void BLF_rotation(int fontid, float angle)
Definition: blf.c:766
void BLF_draw_ex(int fontid, const char *str, size_t str_len, struct ResultBLF *r_info) ATTR_NONNULL(2)
Definition: blf.c:521
float BLF_width(int fontid, const char *str, size_t str_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:688
void BLF_draw(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2)
Definition: blf.c:538
int blf_mono_font
Definition: blf.c:48
void BLF_enable(int fontid, int option)
Definition: blf.c:270
int BLF_height_max(int fontid) ATTR_WARN_UNUSED_RESULT
Definition: blf.c:722
void BLF_size(int fontid, float size, int dpi)
Definition: blf.c:363
void BLF_wordwrap(int fontid, int wrap_width)
Definition: blf.c:787
void BLF_position(int fontid, float x, float y, float z)
Definition: blf.c:308
#define BLI_INLINE
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
MINLINE float clamp_f(float value, float min, float max)
MINLINE void copy_v2fl_v2i(float r[2], const int a[2])
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition: rct.c:407
#define STRNCPY(dst, src)
Definition: BLI_string.h:483
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
#define SNPRINTF_RLEN(dst, format,...)
Definition: BLI_string.h:486
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define TIP_(msgid)
@ RGN_TYPE_HEADER
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:792
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
void ED_workspace_status_text(struct bContext *C, const char *str)
Definition: area.c:816
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
Definition: spacetypes.c:226
#define REGION_DRAW_POST_PIXEL
Definition: ED_space_api.h:63
bool ED_region_draw_cb_exit(struct ARegionType *art, void *handle)
Definition: spacetypes.c:241
void immUniform2f(const char *name, float x, float y)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immUniformThemeColor(int color_id)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2fv(uint attr_id, const float data[2])
void immUniform1i(const char *name, int x)
void immUniformThemeColor3(int color_id)
void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat(void)
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
_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
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:216
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
void GPU_matrix_translate_2f(float x, float y)
Definition: gpu_matrix.cc:174
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:21
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:349
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_line_width(float width)
Definition: gpu_state.cc:158
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:259
void GPU_polygon_smooth(bool enable)
Definition: gpu_state.cc:80
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Contains defines and structs used throughout the imbuf module.
bool IMB_metadata_get_field(struct IDProperty *metadata, const char *key, char *value, size_t len)
Definition: metadata.c:44
void IMB_metadata_foreach(struct ImBuf *ibuf, IMBMetadataForeachCb callback, void *userdata)
Definition: metadata.c:91
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
#define C
Definition: RandGen.cpp:25
const struct uiStyle * UI_style_get_dpi(void)
const struct uiStyle * UI_style_get(void)
#define UI_DPI_FAC
Definition: UI_interface.h:305
void UI_draw_roundbox_3ub_alpha(const struct rctf *rect, bool filled, float rad, const unsigned char col[3], unsigned char alpha)
#define UI_UNIT_X
@ TH_HEADER
Definition: UI_resources.h:50
@ TH_METADATA_TEXT
Definition: UI_resources.h:332
@ TH_HEADER_TEXT
Definition: UI_resources.h:52
@ TH_VIEW_OVERLAY
Definition: UI_resources.h:327
@ TH_HEADER_TEXT_HI
Definition: UI_resources.h:53
@ TH_METADATA_BG
Definition: UI_resources.h:331
void UI_FontThemeColor(int fontid, int colorid)
Definition: resources.c:1134
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1352
@ KM_PRESS
Definition: WM_types.h:267
int pad[32 - sizeof(int)]
unsigned int U
Definition: btGjkEpa3.h:78
int len
Definition: draw_manager.c:108
void ED_region_image_metadata_draw(int x, int y, ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
Definition: ed_draw.c:755
static void draw_backdrop(const int fontid, const rctf *main_line_rect, const uint8_t color_bg[4], const short region_y_size, const float base_tick_height)
Definition: ed_draw.c:208
#define MAX_METADATA_STR
Definition: ed_draw.c:538
struct MetadataCustomCountContext MetadataCustomCountContext
void ED_slider_allow_overshoot_set(struct tSlider *slider, const bool value)
Definition: ed_draw.c:498
static void metadata_custom_count_fields(const char *field, const char *UNUSED(value), void *ctx_v)
Definition: ed_draw.c:693
static void draw_overshoot_triangle(const uint8_t color[4], const bool facing_right, const float x, const float y)
Definition: ed_draw.c:91
static void draw_ticks(const float start_factor, const float end_factor, const float line_start[2], const float base_tick_height, const float line_width, const uint8_t color_overshoot[4], const uint8_t color_line[4])
Definition: ed_draw.c:116
static void metadata_custom_draw_fields(const char *field, const char *value, void *ctx_v)
Definition: ed_draw.c:583
static float metadata_box_height_get(ImBuf *ibuf, int fontid, const bool is_top)
Definition: ed_draw.c:702
#define SLIDE_PIXEL_DISTANCE
Definition: ed_draw.c:56
float ED_slider_factor_get(struct tSlider *slider)
Definition: ed_draw.c:480
static const char * meta_data_list[]
Definition: ed_draw.c:540
BLI_INLINE bool metadata_is_custom_drawable(const char *field)
Definition: ed_draw.c:560
struct MetadataCustomDrawContext MetadataCustomDrawContext
static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const bool is_top)
Definition: ed_draw.c:596
bool ED_slider_allow_overshoot_get(struct tSlider *slider)
Definition: ed_draw.c:493
static void slider_draw(const struct bContext *UNUSED(C), ARegion *region, void *arg)
Definition: ed_draw.c:234
void ED_slider_factor_set(struct tSlider *slider, const float factor)
Definition: ed_draw.c:485
static void draw_main_line(const rctf *main_line_rect, const float factor, const bool overshoot, const uint8_t color_overshoot[4], const uint8_t color_line[4])
Definition: ed_draw.c:163
struct tSlider tSlider
BLI_INLINE bool metadata_is_valid(ImBuf *ibuf, char *r_str, short index, int offset)
Definition: ed_draw.c:553
bool ED_slider_modal(tSlider *slider, const wmEvent *event)
Definition: ed_draw.c:391
void ED_slider_destroy(struct bContext *C, tSlider *slider)
Definition: ed_draw.c:467
#define OVERSHOOT_RANGE_DELTA
Definition: ed_draw.c:57
void ED_slider_status_string_get(const struct tSlider *slider, char *status_string, const size_t size_of_status_string)
Definition: ed_draw.c:424
void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *region, void *arg_info)
Definition: ed_draw.c:505
tSlider * ED_slider_create(struct bContext *C)
Definition: ed_draw.c:358
static void slider_update_factor(tSlider *slider, const wmEvent *event)
Definition: ed_draw.c:341
void ED_slider_init(struct tSlider *slider, const wmEvent *event)
Definition: ed_draw.c:386
#define str(s)
uint pos
int count
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float3 ceil(const float3 &a)
Definition: math_float3.h:363
static struct PartialUpdateUser * wrap(PartialUpdateUserImpl *user)
unsigned char uint8_t
Definition: stdint.h:78
struct ARegionType * type
struct IDProperty * metadata
int lines
Definition: BLF_api.h:369
ListBase regionbase
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
struct ScrArea * area
Definition: ed_draw.c:61
bool overshoot
Definition: ed_draw.c:82
struct Scene * scene
Definition: ed_draw.c:60
bool precision
Definition: ed_draw.c:88
float raw_factor
Definition: ed_draw.c:70
float last_cursor[2]
Definition: ed_draw.c:76
bool allow_overshoot
Definition: ed_draw.c:79
bool increments
Definition: ed_draw.c:85
void * draw_handle
Definition: ed_draw.c:67
struct ARegion * region_header
Definition: ed_draw.c:64
float factor
Definition: ed_draw.c:73
uiFontStyle widget
uiFontStyle widgetlabel
int xy[2]
Definition: WM_types.h:682
short type
Definition: WM_types.h:678
struct wmEvent * eventstate
@ EVT_EKEY
@ EVT_RIGHTCTRLKEY
@ EVT_LEFTCTRLKEY
@ MOUSEMOVE
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY