Blender  V2.93
numinput.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 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLI_math.h"
24 #include "BLI_string.h"
25 #include "BLI_string_cursor_utf8.h"
26 #include "BLI_string_utf8.h"
27 #include "BLI_utildefines.h"
28 
29 #include "BLT_translation.h"
30 
31 #include "BKE_context.h"
32 #include "BKE_report.h"
33 #include "BKE_scene.h"
34 #include "BKE_unit.h"
35 
36 #include "DNA_scene_types.h"
37 
38 #include "WM_api.h"
39 #include "WM_types.h"
40 
41 #ifdef WITH_PYTHON
42 # include "BPY_extern_run.h"
43 #endif
44 
45 #include "ED_numinput.h"
46 #include "UI_interface.h"
47 
48 /* Numeric input which isn't allowing full numeric editing. */
49 #define USE_FAKE_EDIT
50 
55 enum {
57  NUM_EDIT_FULL = (1 << 9),
58 #ifdef USE_FAKE_EDIT
60  NUM_FAKE_EDITED = (1 << 10),
61 #endif
62 };
63 
64 /* NumInput.val_flag[] */
65 enum {
66  /* (1 << 8) and below are reserved for public flags! */
68  NUM_EDITED = (1 << 9),
70  NUM_INVALID = (1 << 10),
71 #ifdef USE_FAKE_EDIT
73  NUM_NEGATE = (1 << 11),
75  NUM_INVERSE = (1 << 12),
76 #endif
77 };
78 
79 /* ************************** Functions *************************** */
80 
81 /* ************************** NUMINPUT **************************** */
82 
84 {
85  n->idx_max = 0;
88  n->unit_use_radians = false;
89 
90  n->flag = 0;
92  zero_v3(n->val);
95 
96  n->idx = 0;
97  n->str[0] = '\0';
98  n->str_cur = 0;
99 }
100 
101 /* str must be NUM_STR_REP_LEN * (idx_max + 1) length. */
102 void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings)
103 {
104  short j;
105  const int ln = NUM_STR_REP_LEN;
106  int prec = 2; /* draw-only, and avoids too much issues with radian->degrees conversion. */
107 
108  for (j = 0; j <= n->idx_max; j++) {
109  /* if AFFECTALL and no number typed and cursor not on number, use first number */
110  const short i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ?
111  0 :
112  j;
113 
114  /* Use scale_length if needed! */
115  const float fac = (float)BKE_scene_unit_scale(unit_settings, n->unit_type[j], 1.0);
116 
117  if (n->val_flag[i] & NUM_EDITED) {
118  /* Get the best precision, allows us to draw '10.0001' as '10' instead! */
119  prec = UI_calc_float_precision(prec, (double)n->val[i]);
120  if (i == n->idx) {
121  const char *heading_exp = "", *trailing_exp = "";
122  char before_cursor[NUM_STR_REP_LEN];
123  char val[16];
124 
125 #ifdef USE_FAKE_EDIT
126  if (n->val_flag[i] & NUM_NEGATE) {
127  heading_exp = (n->val_flag[i] & NUM_INVERSE) ? "-1/(" : "-(";
128  trailing_exp = ")";
129  }
130  else if (n->val_flag[i] & NUM_INVERSE) {
131  heading_exp = "1/(";
132  trailing_exp = ")";
133  }
134 #endif
135 
136  if (n->val_flag[i] & NUM_INVALID) {
137  BLI_strncpy(val, "Invalid", sizeof(val));
138  }
139  else {
141  sizeof(val),
142  (double)(n->val[i] * fac),
143  prec,
144  n->unit_sys,
145  n->unit_type[i],
146  true,
147  false);
148  }
149 
150  /* +1 because of trailing '\0' */
151  BLI_strncpy(before_cursor, n->str, n->str_cur + 1);
152  BLI_snprintf(&str[j * ln],
153  ln,
154  "[%s%s|%s%s] = %s",
155  heading_exp,
156  before_cursor,
157  &n->str[n->str_cur],
158  trailing_exp,
159  val);
160  }
161  else {
162  const char *cur = (i == n->idx) ? "|" : "";
163  if (n->unit_use_radians && n->unit_type[i] == B_UNIT_ROTATION) {
164  /* Radian exception... */
165  BLI_snprintf(&str[j * ln], ln, "%s%.6gr%s", cur, n->val[i], cur);
166  }
167  else {
168  char tstr[NUM_STR_REP_LEN];
170  tstr, ln, (double)n->val[i], prec, n->unit_sys, n->unit_type[i], true, false);
171  BLI_snprintf(&str[j * ln], ln, "%s%s%s", cur, tstr, cur);
172  }
173  }
174  }
175  else {
176  const char *cur = (i == n->idx) ? "|" : "";
177  BLI_snprintf(&str[j * ln], ln, "%sNONE%s", cur, cur);
178  }
179  /* We might have cut some multi-bytes utf8 chars
180  * (e.g. trailing '°' of degrees values can become only 'A')... */
181  BLI_utf8_invalid_strip(&str[j * ln], strlen(&str[j * ln]));
182  }
183 }
184 
185 bool hasNumInput(const NumInput *n)
186 {
187  short i;
188 
189 #ifdef USE_FAKE_EDIT
190  if (n->flag & NUM_FAKE_EDITED) {
191  return true;
192  }
193 #endif
194 
195  for (i = 0; i <= n->idx_max; i++) {
196  if (n->val_flag[i] & NUM_EDITED) {
197  return true;
198  }
199  }
200 
201  return false;
202 }
203 
207 bool applyNumInput(NumInput *n, float *vec)
208 {
209  short i, j;
210  float val;
211 
212  if (hasNumInput(n)) {
213  for (j = 0; j <= n->idx_max; j++) {
214 #ifdef USE_FAKE_EDIT
215  if (n->flag & NUM_FAKE_EDITED) {
216  val = n->val[j];
217  }
218  else
219 #endif
220  {
221  /* if AFFECTALL and no number typed and cursor not on number, use first number */
222  i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j;
223  val = (!(n->val_flag[i] & NUM_EDITED) && n->val_flag[i] & NUM_NULL_ONE) ? 1.0f : n->val[i];
224 
225  if (n->val_flag[i] & NUM_NO_NEGATIVE && val < 0.0f) {
226  val = 0.0f;
227  }
228  if (n->val_flag[i] & NUM_NO_FRACTION && val != floorf(val)) {
229  val = floorf(val + 0.5f);
230  if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) {
231  val = 1.0f;
232  }
233  }
234  else if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) {
235  val = 0.0001f;
236  }
237  }
238  vec[j] = val;
239  }
240 #ifdef USE_FAKE_EDIT
241  n->flag &= ~NUM_FAKE_EDITED;
242 #endif
243  return true;
244  }
245 
246  /* Else, we set the 'org' values for numinput! */
247  for (j = 0; j <= n->idx_max; j++) {
248  n->val[j] = n->val_org[j] = vec[j];
249  }
250  return false;
251 }
252 
253 static void value_to_editstr(NumInput *n, int idx)
254 {
255  const int prec = 6; /* editing, higher precision needed. */
258  (double)n->val[idx],
259  prec,
260  n->unit_sys,
261  n->unit_type[idx],
262  true,
263  false);
264 }
265 
266 static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf_len)
267 {
268  int cur = n->str_cur;
269  int len = strlen(&n->str[cur]) + 1; /* +1 for the trailing '\0'. */
270  int n_cur = cur + buf_len;
271 
272  if (n_cur + len >= NUM_STR_REP_LEN) {
273  return false;
274  }
275 
276  memmove(&n->str[n_cur], &n->str[cur], len);
277  memcpy(&n->str[cur], buf, sizeof(char) * buf_len);
278 
279  n->str_cur = n_cur;
280  return true;
281 }
282 
284  const char *str,
285  const UnitSettings *unit,
286  int type,
287  double *r_value,
288  const bool use_single_line_error,
289  char **r_error)
290 {
291 #ifdef WITH_PYTHON
292  struct BPy_RunErrInfo err_info = {
294  .r_string = r_error,
295  };
296  double unit_scale = BKE_scene_unit_scale(unit, type, 1.0);
298  char str_unit_convert[256];
299  BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert));
301  str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type);
302 
303  return BPY_run_string_as_number(C, NULL, str_unit_convert, &err_info, r_value);
304  }
305 
306  int success = BPY_run_string_as_number(C, NULL, str, &err_info, r_value);
307  *r_value = BKE_unit_apply_preferred_unit(unit, type, *r_value);
308  *r_value /= unit_scale;
309  return success;
310 
311 #else
312  UNUSED_VARS(C, unit, type);
313  *r_value = atof(str);
314  return true;
315 #endif
316 }
317 
318 static bool editstr_is_simple_numinput(const char ascii)
319 {
320  if (ascii >= '0' && ascii <= '9') {
321  return true;
322  }
323  if (ascii == '.') {
324  return true;
325  }
326  return false;
327 }
328 
329 bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
330 {
331  const char *utf8_buf = NULL;
332  char ascii[2] = {'\0', '\0'};
333  bool updated = false;
334  short idx = n->idx, idx_max = n->idx_max;
335  short dir = STRCUR_DIR_NEXT, mode = STRCUR_JUMP_NONE;
336  int cur;
337 
338 #ifdef USE_FAKE_EDIT
339  if (U.flag & USER_FLAG_NUMINPUT_ADVANCED)
340 #endif
341  {
342  if ((event->ctrl == 0) && (event->alt == 0) && (event->ascii != '\0') &&
343  strchr("01234567890@%^&*-+/{}()[]<>.|", event->ascii)) {
344  if (!(n->flag & NUM_EDIT_FULL)) {
345  n->flag |= NUM_EDITED;
346  n->flag |= NUM_EDIT_FULL;
347  n->val_flag[idx] |= NUM_EDITED;
348  }
349  }
350  }
351 
352 #ifdef USE_FAKE_EDIT
353  /* XXX Hack around keyboards without direct access to '=' nor '*'... */
354  if (ELEM(event->ascii, '=', '*')) {
355  if (!(n->flag & NUM_EDIT_FULL)) {
356  n->flag |= NUM_EDIT_FULL;
357  n->val_flag[idx] |= NUM_EDITED;
358  return true;
359  }
360  if (event->ctrl) {
361  n->flag &= ~NUM_EDIT_FULL;
362  return true;
363  }
364  }
365 #endif
366 
367  switch (event->type) {
368  case EVT_MODAL_MAP:
370  n->val[idx] += (event->val == NUM_MODAL_INCREMENT_UP) ? n->val_inc[idx] : -n->val_inc[idx];
371  value_to_editstr(n, idx);
372  n->val_flag[idx] |= NUM_EDITED;
373  updated = true;
374  }
375  else {
376  /* might be a char too... */
377  utf8_buf = event->utf8_buf;
378  ascii[0] = event->ascii;
379  }
380  break;
381  case EVT_BACKSPACEKEY:
382  /* Part specific to backspace... */
383  if (!(n->val_flag[idx] & NUM_EDITED)) {
384  copy_v3_v3(n->val, n->val_org);
385  n->val_flag[0] &= ~NUM_EDITED;
386  n->val_flag[1] &= ~NUM_EDITED;
387  n->val_flag[2] &= ~NUM_EDITED;
388 #ifdef USE_FAKE_EDIT
389  n->flag |= NUM_FAKE_EDITED;
390 #else
391  n->flag |= NUM_EDIT_FULL;
392 #endif
393  updated = true;
394  break;
395  }
396  else if (event->shift || !n->str[0]) {
397  n->val[idx] = n->val_org[idx];
398  n->val_flag[idx] &= ~NUM_EDITED;
399  n->str[0] = '\0';
400  n->str_cur = 0;
401  updated = true;
402  break;
403  }
404  /* Else, common behavior with DELKEY,
405  * only difference is remove char(s) before/after the cursor. */
406  dir = STRCUR_DIR_PREV;
408  case EVT_DELKEY:
409  if ((n->val_flag[idx] & NUM_EDITED) && n->str[0]) {
410  int t_cur = cur = n->str_cur;
411  if (event->ctrl) {
412  mode = STRCUR_JUMP_DELIM;
413  }
414  BLI_str_cursor_step_utf8(n->str, strlen(n->str), &t_cur, dir, mode, true);
415  if (t_cur != cur) {
416  if (t_cur < cur) {
417  SWAP(int, t_cur, cur);
418  n->str_cur = cur;
419  }
420  /* +1 for trailing '\0'. */
421  memmove(&n->str[cur], &n->str[t_cur], strlen(&n->str[t_cur]) + 1);
422  updated = true;
423  }
424  if (!n->str[0]) {
425  n->val[idx] = n->val_org[idx];
426  }
427  }
428  else {
429  return false;
430  }
431  break;
432  case EVT_LEFTARROWKEY:
433  dir = STRCUR_DIR_PREV;
435  case EVT_RIGHTARROWKEY:
436  cur = n->str_cur;
437  if (event->ctrl) {
438  mode = STRCUR_JUMP_DELIM;
439  }
440  BLI_str_cursor_step_utf8(n->str, strlen(n->str), &cur, dir, mode, true);
441  if (cur != n->str_cur) {
442  n->str_cur = cur;
443  return true;
444  }
445  return false;
446  case EVT_HOMEKEY:
447  if (n->str[0]) {
448  n->str_cur = 0;
449  return true;
450  }
451  return false;
452  case EVT_ENDKEY:
453  if (n->str[0]) {
454  n->str_cur = strlen(n->str);
455  return true;
456  }
457  return false;
458  case EVT_TABKEY:
459 #ifdef USE_FAKE_EDIT
460  n->val_flag[idx] &= ~(NUM_NEGATE | NUM_INVERSE);
461 #endif
462 
463  idx = (idx + idx_max + (event->ctrl ? 0 : 2)) % (idx_max + 1);
464  n->idx = idx;
465  if (n->val_flag[idx] & NUM_EDITED) {
466  value_to_editstr(n, idx);
467  }
468  else {
469  n->str[0] = '\0';
470  n->str_cur = 0;
471  }
472  return true;
473  case EVT_PADPERIOD:
474  case EVT_PERIODKEY:
475  /* Force numdot, some OSs/countries generate a comma char in this case,
476  * sic... (T37992) */
477  ascii[0] = '.';
478  utf8_buf = ascii;
479  break;
480 #if 0
481  /* Those keys are not directly accessible in all layouts,
482  * preventing to generate matching events.
483  * So we use a hack (ascii value) instead, see below.
484  */
485  case EQUALKEY:
486  case PADASTERKEY:
487  if (!(n->flag & NUM_EDIT_FULL)) {
488  n->flag |= NUM_EDIT_FULL;
489  n->val_flag[idx] |= NUM_EDITED;
490  return true;
491  }
492  else if (event->ctrl) {
493  n->flag &= ~NUM_EDIT_FULL;
494  return true;
495  }
496  break;
497 #endif
498 
499 #ifdef USE_FAKE_EDIT
500  case EVT_PADMINUS:
501  case EVT_MINUSKEY:
502  if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
503  n->val_flag[idx] ^= NUM_NEGATE;
504  updated = true;
505  }
506  break;
507  case EVT_PADSLASHKEY:
508  case EVT_SLASHKEY:
509  if (event->ctrl || !(n->flag & NUM_EDIT_FULL)) {
510  n->val_flag[idx] ^= NUM_INVERSE;
511  updated = true;
512  }
513  break;
514 #endif
515  case EVT_CKEY:
516  if (event->ctrl) {
517  /* Copy current `str` to the copy/paste buffer. */
518  WM_clipboard_text_set(n->str, 0);
519  updated = true;
520  }
521  break;
522  case EVT_VKEY:
523  if (event->ctrl) {
524  /* extract the first line from the clipboard */
525  int pbuf_len;
526  char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len);
527 
528  if (pbuf) {
529  const bool success = editstr_insert_at_cursor(n, pbuf, pbuf_len);
530 
531  MEM_freeN(pbuf);
532  if (!success) {
533  return false;
534  }
535 
536  n->val_flag[idx] |= NUM_EDITED;
537  }
538  updated = true;
539  }
540  break;
541  default:
542  break;
543  }
544 
545  if (!updated && !utf8_buf && (event->utf8_buf[0] || event->ascii)) {
546  utf8_buf = event->utf8_buf;
547  ascii[0] = event->ascii;
548  }
549 
550  /* Up to this point, if we have a ctrl modifier, skip.
551  * This allows to still access most of modals' shortcuts even in numinput mode.
552  */
553  if (!updated && event->ctrl) {
554  return false;
555  }
556 
557  if ((!utf8_buf || !utf8_buf[0]) && ascii[0]) {
558  /* Fallback to ascii. */
559  utf8_buf = ascii;
560  }
561 
562  if (utf8_buf && utf8_buf[0]) {
563  if (!(n->flag & NUM_EDIT_FULL)) {
564  /* In simple edit mode, we only keep a few chars as valid! */
565  /* no need to decode unicode, ascii is first char only */
566  if (!editstr_is_simple_numinput(utf8_buf[0])) {
567  return false;
568  }
569  }
570 
571  if (!editstr_insert_at_cursor(n, utf8_buf, BLI_str_utf8_size(utf8_buf))) {
572  return false;
573  }
574 
575  n->val_flag[idx] |= NUM_EDITED;
576  }
577  else if (!updated) {
578  return false;
579  }
580 
581  /* At this point, our value has changed, try to interpret it with python
582  * (if str is not empty!). */
583  if (n->str[0]) {
584  const float val_prev = n->val[idx];
585  Scene *sce = CTX_data_scene(C);
586  char *error = NULL;
587 
588  double val;
589  int success = user_string_to_number(
590  C, n->str, &sce->unit, n->unit_type[idx], &val, false, &error);
591 
592  if (error) {
594  printf("%s\n", error);
596  BKE_report(reports, RPT_ERROR, IFACE_("Numeric input evaluation"));
597  MEM_freeN(error);
598  }
599 
600  if (success) {
601  n->val[idx] = (float)val;
602  n->val_flag[idx] &= ~NUM_INVALID;
603  }
604  else {
605  n->val_flag[idx] |= NUM_INVALID;
606  }
607 
608 #ifdef USE_FAKE_EDIT
609  if (n->val_flag[idx] & NUM_NEGATE) {
610  n->val[idx] = -n->val[idx];
611  }
612  if (n->val_flag[idx] & NUM_INVERSE) {
613  val = n->val[idx];
614  /* If we invert on radians when user is in degrees,
615  * you get unexpected results... See T53463. */
616  if (!n->unit_use_radians && n->unit_type[idx] == B_UNIT_ROTATION) {
617  val = RAD2DEG(val);
618  }
619  val = 1.0 / val;
620  if (!n->unit_use_radians && n->unit_type[idx] == B_UNIT_ROTATION) {
621  val = DEG2RAD(val);
622  }
623  n->val[idx] = (float)val;
624  }
625 #endif
626 
627  if (UNLIKELY(!isfinite(n->val[idx]))) {
628  n->val[idx] = val_prev;
629  n->val_flag[idx] |= NUM_INVALID;
630  }
631  }
632 
633  /* REDRAW SINCE NUMBERS HAVE CHANGED */
634  return true;
635 }
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:751
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
double BKE_scene_unit_scale(const struct UnitSettings *unit, const int unit_type, double value)
size_t BKE_unit_value_as_string_adaptive(char *str, int len_max, double value, int prec, int system, int type, bool split, bool pad)
Definition: unit.c:665
@ B_UNIT_ROTATION
Definition: BKE_unit.h:83
@ B_UNIT_NONE
Definition: BKE_unit.h:78
bool BKE_unit_replace_string(char *str, int len_max, const char *str_prev, double scale_pref, int system, int type)
Definition: unit.c:1106
double BKE_unit_apply_preferred_unit(const struct UnitSettings *settings, int type, double value)
Definition: unit.c:1079
bool BKE_unit_string_contains_unit(const char *str, int type)
Definition: unit.c:1062
#define ATTR_FALLTHROUGH
#define DEG2RAD(_deg)
#define RAD2DEG(_rad)
void copy_vn_fl(float *array_tar, const int size, const float val)
Definition: math_vector.c:1410
void copy_vn_i(int *array_tar, const int size, const int val)
Definition: math_vector.c:1374
MINLINE void copy_v3_v3(float r[3], const float a[3])
void copy_vn_short(short *array_tar, const int size, const short val)
Definition: math_vector.c:1383
MINLINE void zero_v3(float r[3])
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
void BLI_str_cursor_step_utf8(const char *str, size_t maxlen, int *pos, eStrCursorJumpDirection direction, eStrCursorJumpType jump, bool use_init_step)
@ STRCUR_DIR_NEXT
@ STRCUR_DIR_PREV
@ STRCUR_JUMP_NONE
@ STRCUR_JUMP_DELIM
int BLI_str_utf8_size(const char *p) ATTR_NONNULL()
Definition: string_utf8.c:495
int BLI_utf8_invalid_strip(char *str, size_t length) ATTR_NONNULL()
Definition: string_utf8.c:203
#define UNUSED_VARS(...)
#define SWAP(type, a, b)
#define UNLIKELY(x)
#define ELEM(...)
#define IFACE_(msgid)
bool BPY_run_string_as_number(struct bContext *C, const char *imports[], const char *expr, struct BPy_RunErrInfo *err_info, double *r_value)
#define USER_UNIT_NONE
@ USER_FLAG_NUMINPUT_ADVANCED
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:27
@ NUM_NO_NEGATIVE
Definition: ED_numinput.h:70
@ NUM_NULL_ONE
Definition: ED_numinput.h:69
@ NUM_NO_ZERO
Definition: ED_numinput.h:71
@ NUM_NO_FRACTION
Definition: ED_numinput.h:72
#define NUM_MODAL_INCREMENT_DOWN
Definition: ED_numinput.h:104
#define NUM_MAX_ELEMENTS
Definition: ED_numinput.h:28
@ NUM_AFFECT_ALL
Definition: ED_numinput.h:62
#define NUM_MODAL_INCREMENT_UP
Definition: ED_numinput.h:103
_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
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
int UI_calc_float_precision(int prec, double value)
unsigned int U
Definition: btGjkEpa3.h:78
#define str(s)
#define floorf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
static void error(const char *str)
Definition: meshlaplacian.c:65
bool isfinite(uchar)
Definition: image.cpp:44
static void value_to_editstr(NumInput *n, int idx)
Definition: numinput.c:253
void initNumInput(NumInput *n)
Definition: numinput.c:83
void outputNumInput(NumInput *n, char *str, UnitSettings *unit_settings)
Definition: numinput.c:102
bool user_string_to_number(bContext *C, const char *str, const UnitSettings *unit, int type, double *r_value, const bool use_single_line_error, char **r_error)
Definition: numinput.c:283
@ NUM_INVERSE
Definition: numinput.c:75
@ NUM_NEGATE
Definition: numinput.c:73
@ NUM_INVALID
Definition: numinput.c:70
@ NUM_EDITED
Definition: numinput.c:68
static bool editstr_is_simple_numinput(const char ascii)
Definition: numinput.c:318
static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf_len)
Definition: numinput.c:266
#define USE_FAKE_EDIT
Definition: numinput.c:49
@ NUM_FAKE_EDITED
Definition: numinput.c:60
@ NUM_EDIT_FULL
Definition: numinput.c:57
bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
Definition: numinput.c:329
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:207
bool hasNumInput(const NumInput *n)
Definition: numinput.c:185
struct ReportList * reports
bool use_single_line_error
short idx_max
Definition: ED_numinput.h:34
float val[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:45
short val_flag[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:43
int unit_sys
Definition: ED_numinput.h:35
float val_inc[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:49
char str[NUM_STR_REP_LEN]
Definition: ED_numinput.h:54
float val_org[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:47
int unit_type[NUM_MAX_ELEMENTS]
Definition: ED_numinput.h:37
short flag
Definition: ED_numinput.h:41
bool unit_use_radians
Definition: ED_numinput.h:38
int str_cur
Definition: ED_numinput.h:57
short idx
Definition: ED_numinput.h:52
struct UnitSettings unit
short shift
Definition: WM_types.h:618
short ctrl
Definition: WM_types.h:618
short val
Definition: WM_types.h:579
char utf8_buf[6]
Definition: WM_types.h:589
short alt
Definition: WM_types.h:618
short type
Definition: WM_types.h:577
char ascii
Definition: WM_types.h:591
uint len
@ EVT_PADPERIOD
@ EVT_MODAL_MAP
@ EVT_VKEY
@ EVT_PERIODKEY
@ EVT_PADSLASHKEY
@ EVT_DELKEY
@ EVT_CKEY
@ EVT_TABKEY
@ EVT_MINUSKEY
@ EVT_RIGHTARROWKEY
@ EVT_HOMEKEY
@ EVT_ENDKEY
@ EVT_PADMINUS
@ EVT_SLASHKEY
@ EVT_LEFTARROWKEY
@ EVT_BACKSPACEKEY
void WM_clipboard_text_set(const char *buf, bool selection)
Definition: wm_window.c:1778
char * WM_clipboard_text_get_firstline(bool selection, int *r_len)
Definition: wm_window.c:1773