Inexor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
textedit.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 
6 
9 
10 
11 struct editline
12 {
13  enum { CHUNKSIZE = 256 };
14 
15  char *text;
16  int len, maxlen;
17 
18  editline() : text(nullptr), len(0), maxlen(0) {}
19  editline(const char *init) : text(nullptr), len(0), maxlen(0)
20  {
21  set(init);
22  }
23 
24  bool empty() { return len <= 0; }
25 
26  void clear()
27  {
28  DELETEA(text);
29  len = maxlen = 0;
30  }
31 
32  bool grow(int total, const char *fmt = nullptr, ...) PRINTFARGS(3, 4)
33  {
34  if(total + 1 <= maxlen) return false;
35  maxlen = (total + CHUNKSIZE) - total%CHUNKSIZE;
36  char *newtext = new char[maxlen];
37  if(fmt)
38  {
39  va_list args;
40  va_start(args, fmt);
41  vformatstring(newtext, fmt, args, maxlen);
42  va_end(args);
43  } else newtext[0] = '\0';
44  DELETEA(text);
46  return true;
47  }
48 
49  void set(const char *str, int slen = -1)
50  {
51  if(slen < 0)
52  {
53  slen = strlen(str);
54  if(!grow(slen, "%s", str)) memcpy(text, str, slen + 1);
55  }
56  else
57  {
58  grow(slen);
59  memcpy(text, str, slen);
60  text[slen] = '\0';
61  }
62  len = slen;
63  }
64 
65  void prepend(const char *str)
66  {
67  int slen = strlen(str);
68  if(!grow(slen + len, "%s%s", str, text ? text : ""))
69  {
70  memmove(&text[slen], text, len + 1);
71  memcpy(text, str, slen + 1);
72  }
73  len += slen;
74  }
75 
76  void append(const char *str)
77  {
78  int slen = strlen(str);
79  if(!grow(len + slen, "%s%s", text ? text : "", str)) memcpy(&text[len], str, slen + 1);
80  len += slen;
81  }
82 
83  bool read(stream *f, int chop = -1)
84  {
85  if(chop < 0) chop = INT_MAX; else chop++;
86  set("");
87  while(len + 1 < chop && f->getline(&text[len], min(maxlen, chop) - len))
88  {
89  len += strlen(&text[len]);
90  if(len > 0 && text[len-1] == '\n')
91  {
92  text[--len] = '\0';
93  return true;
94  }
95  if(len + 1 >= maxlen && len + 1 < chop) grow(len + CHUNKSIZE, "%s", text);
96  }
97  if(len + 1 >= chop)
98  {
99  char buf[CHUNKSIZE];
100  while(f->getline(buf, sizeof(buf)))
101  {
102  int blen = strlen(buf);
103  if(blen > 0 && buf[blen-1] == '\n') return true;
104  }
105  }
106  return len > 0;
107  }
108 
109  void del(int start, int count)
110  {
111  if(!text) return;
112  if(start < 0) { count += start; start = 0; }
113  if(count <= 0 || start >= len) return;
114  if(start + count > len) count = len - start - 1;
115  memmove(&text[start], &text[start+count], len + 1 - (start + count));
116  len -= count;
117  }
118 
119  void chop(int newlen)
120  {
121  if(!text) return;
122  len = clamp(newlen, 0, len);
123  text[len] = '\0';
124  }
125 
126  void insert(char *str, int start, int count = 0)
127  {
128  if(count <= 0) count = strlen(str);
129  start = clamp(start, 0, len);
130  grow(len + count, "%s", text ? text : "");
131  memmove(&text[start + count], &text[start], len - start + 1);
132  memcpy(&text[start], str, count);
133  len += count;
134  }
135 
137  {
138  if(src.empty()) set("");
139  else loopv(src)
140  {
141  if(i) append("\n");
142  if(!i) set(src[i].text, src[i].len);
143  else insert(src[i].text, len, src[i].len);
144  }
145  }
146 };
147 
148 struct editor
149 {
150  int mode; //editor mode - 1= keep while focused, 2= keep while used in gui, 3= keep forever (i.e. until mode changes)
152  const char *name;
153  const char *filename;
154 
155  int cx, cy; // cursor position - ensured to be valid after a region() or currentline()
156  int mx, my; // selection mark, mx=-1 if following cursor - avoid direct access, instead use region()
157  int maxx, maxy; // maxy=-1 if unlimited lines, 1 if single line editor
158 
159  int scrolly; // vertical scroll offset
160 
161  bool linewrap;
162  int pixelwidth; // required for up/down/hit/draw/bounds
163  int pixelheight; // -1 for variable sized, i.e. from bounds()
164 
165  vector<editline> lines; // MUST always contain at least one line!
166 
167  editor(const char *name, int mode, const char *initval) :
168  mode(mode), active(true), rendered(false), name(newstring(name)), filename(nullptr),
169  cx(0), cy(0), mx(-1), maxx(-1), maxy(-1), scrolly(0), linewrap(false), pixelwidth(-1), pixelheight(-1)
170  {
171  //printf("editor %08x '%s'\n", this, name);
172  lines.add().set(initval ? initval : "");
173  }
174 
176  {
177  //printf("~editor %08x '%s'\n", this, name);
178  DELETEA(name);
179  DELETEA(filename);
180  clear(nullptr);
181  }
182 
183  void clear(const char *init = "")
184  {
185  cx = cy = 0;
186  mark(false);
187  loopv(lines) lines[i].clear();
188  lines.shrink(0);
189  if(init) lines.add().set(init);
190  }
191 
192  void setfile(const char *fname)
193  {
194  DELETEA(filename);
195  if(fname) filename = newstring(fname);
196  }
197 
198  void load()
199  {
200  if(!filename) return;
201  clear(nullptr);
202  stream *file = openutf8file(filename, "r");
203  if(file)
204  {
205  while(lines.add().read(file, maxx) && (maxy < 0 || lines.length() <= maxy));
206  lines.pop().clear();
207  delete file;
208  }
209  if(lines.empty()) lines.add().set("");
210  }
211 
212  void save()
213  {
214  if(!filename) return;
215  stream *file = openutf8file(filename, "w");
216  if(!file) return;
217  loopv(lines) file->putline(lines[i].text);
218  delete file;
219  }
220 
221  void mark(bool enable)
222  {
223  mx = (enable) ? cx : -1;
224  my = cy;
225  }
226 
227  void selectall()
228  {
229  mx = my = INT_MAX;
230  cx = cy = 0;
231  }
232 
233  // constrain results to within buffer - s=start, e=end, return true if a selection range
234  // also ensures that cy is always within lines[] and cx is valid
235  bool region(int &sx, int &sy, int &ex, int &ey)
236  {
237  int n = lines.length();
238  ASSERT(n != 0);
239  if(cy < 0) cy = 0; else if(cy >= n) cy = n-1;
240  int len = lines[cy].len;
241  if(cx < 0) cx = 0; else if(cx > len) cx = len;
242  if(mx >= 0)
243  {
244  if(my < 0) my = 0; else if(my >= n) my = n-1;
245  len = lines[my].len;
246  if(mx > len) mx = len;
247  }
248  sx = (mx >= 0) ? mx : cx;
249  sy = (mx >= 0) ? my : cy;
250  ex = cx;
251  ey = cy;
252  if(sy > ey) { swap(sy, ey); swap(sx, ex); }
253  else if(sy==ey && sx > ex) swap(sx, ex);
254  return (sx != ex) || (sy != ey);
255  }
256 
257  bool region() { int sx, sy, ex, ey; return region(sx, sy, ex, ey); }
258 
259  // also ensures that cy is always within lines[] and cx is valid
261  {
262  int n = lines.length();
263  ASSERT(n != 0);
264  if(cy < 0) cy = 0; else if(cy >= n) cy = n-1;
265  if(cx < 0) cx = 0; else if(cx > lines[cy].len) cx = lines[cy].len;
266  return lines[cy];
267  }
268 
270  {
271  if(b==this) return;
272 
273  b->clear(nullptr);
274  int sx, sy, ex, ey;
275  region(sx, sy, ex, ey);
276  loopi(1+ey-sy)
277  {
278  if(b->maxy != -1 && b->lines.length() >= b->maxy) break;
279  int y = sy+i;
280  char *line = lines[y].text;
281  int len = lines[y].len;
282  if(y == sy && y == ey)
283  {
284  line += sx;
285  len = ex - sx;
286  }
287  else if(y == sy) line += sx;
288  else if(y == ey) len = ex;
289  b->lines.add().set(line, len);
290  }
291  if(b->lines.empty()) b->lines.add().set("");
292  }
293 
294  char *tostring()
295  {
296  int len = 0;
297  loopv(lines) len += lines[i].len + 1;
298  char *str = newstring(len);
299  int offset = 0;
300  loopv(lines)
301  {
302  editline &l = lines[i];
303  memcpy(&str[offset], l.text, l.len);
304  offset += l.len;
305  str[offset++] = '\n';
306  }
307  str[offset] = '\0';
308  return str;
309  }
310 
312  {
313  vector<char> buf;
314  int sx, sy, ex, ey;
315  region(sx, sy, ex, ey);
316  loopi(1+ey-sy)
317  {
318  int y = sy+i;
319  char *line = lines[y].text;
320  int len = lines[y].len;
321  if(y == sy && y == ey)
322  {
323  line += sx;
324  len = ex - sx;
325  }
326  else if(y == sy) line += sx;
327  else if(y == ey) len = ex;
328  buf.put(line, len);
329  buf.add('\n');
330  }
331  buf.add('\0');
332  return newstring(buf.getbuf(), buf.length()-1);
333  }
334 
335  void removelines(int start, int count)
336  {
337  loopi(count) lines[start+i].clear();
338  lines.remove(start, count);
339  }
340 
341  bool del() // removes the current selection (if any)
342  {
343  int sx, sy, ex, ey;
344  if(!region(sx, sy, ex, ey))
345  {
346  mark(false);
347  return false;
348  }
349  if(sy == ey)
350  {
351  if(sx == 0 && ex == lines[ey].len) removelines(sy, 1);
352  else lines[sy].del(sx, ex - sx);
353  }
354  else
355  {
356  if(ey > sy+1) { removelines(sy+1, ey-(sy+1)); ey = sy+1; }
357  if(ex == lines[ey].len) removelines(ey, 1); else lines[ey].del(0, ex);
358  if(sx == 0) removelines(sy, 1); else lines[sy].del(sx, lines[sy].len - sx);
359  }
360  if(lines.empty()) lines.add().set("");
361  mark(false);
362  cx = sx;
363  cy = sy;
364  editline &current = currentline();
365  if(cx >= current.len && cy < lines.length() - 1)
366  {
367  current.append(lines[cy+1].text);
368  removelines(cy + 1, 1);
369  }
370  return true;
371  }
372 
373  void insert(char ch)
374  {
375  del();
376  editline &current = currentline();
377  if(ch == '\n')
378  {
379  if(maxy == -1 || cy < maxy-1)
380  {
381  editline newline(&current.text[cx]);
382  current.chop(cx);
383  cy = min(lines.length(), cy+1);
384  lines.insert(cy, newline);
385  }
386  else current.chop(cx);
387  cx = 0;
388  }
389  else
390  {
391  int len = current.len;
392  if(maxx >= 0 && len > maxx-1) len = maxx-1;
393  if(cx <= len) current.insert(&ch, cx++, 1);
394  }
395  }
396 
397  void insert(const char *s)
398  {
399  while(*s) insert(*s++);
400  }
401 
403  {
404  if(b==this) return;
405 
406  del();
407 
408  if(b->lines.length() == 1 || maxy == 1)
409  {
410  editline &current = currentline();
411  char *str = b->lines[0].text;
412  int slen = b->lines[0].len;
413  if(maxx >= 0 && b->lines[0].len + cx > maxx) slen = maxx-cx;
414  if(slen > 0)
415  {
416  int len = current.len;
417  if(maxx >= 0 && slen + cx + len > maxx) len = max(0, maxx-(cx+slen));
418  current.insert(str, cx, slen);
419  cx += slen;
420  }
421  }
422  else
423  {
424  loopv(b->lines)
425  {
426  if(!i)
427  {
428  lines[cy++].append(b->lines[i].text);
429  }
430  else if(i >= b->lines.length())
431  {
432  cx = b->lines[i].len;
433  lines[cy].prepend(b->lines[i].text);
434  }
435  else if(maxy < 0 || lines.length() < maxy) lines.insert(cy++, editline(b->lines[i].text));
436  }
437  }
438  }
439 
440  void key(int code)
441  {
442  switch(code)
443  {
444  case SDLK_UP:
445  if(linewrap)
446  {
447  int x, y;
448  char *str = currentline().text;
449  text_pos(str, cx+1, x, y, pixelwidth);
450  if(y > 0) { cx = text_visible(str, x, y-FONTH, pixelwidth); break; }
451  }
452  cy--;
453  break;
454  case SDLK_DOWN:
455  if(linewrap)
456  {
457  int x, y, width, height;
458  char *str = currentline().text;
459  text_pos(str, cx, x, y, pixelwidth);
460  text_bounds(str, width, height, pixelwidth);
461  y += FONTH;
462  if(y < height) { cx = text_visible(str, x, y, pixelwidth); break; }
463  }
464  cy++;
465  break;
466  case -4:
467  cy--;
468  break;
469  case -5:
470  cy++;
471  break;
472  case SDLK_PAGEUP:
474  break;
475  case SDLK_PAGEDOWN:
477  break;
478  case SDLK_HOME:
479  cx = cy = 0;
480  break;
481  case SDLK_END:
482  cx = cy = INT_MAX;
483  break;
484  case SDLK_LEFT:
485  cx--;
486  break;
487  case SDLK_RIGHT:
488  cx++;
489  break;
490  case SDLK_DELETE:
491  if(!del())
492  {
493  editline &current = currentline();
494  if(cx < current.len) current.del(cx, 1);
495  else if(cy < lines.length()-1)
496  { //combine with next line
497  current.append(lines[cy+1].text);
498  removelines(cy+1, 1);
499  }
500  }
501  break;
502  case SDLK_BACKSPACE:
503  if(!del())
504  {
505  editline &current = currentline();
506  if(cx > 0) current.del(--cx, 1);
507  else if(cy > 0)
508  { //combine with previous line
509  cx = lines[cy-1].len;
510  lines[cy-1].append(current.text);
511  removelines(cy--, 1);
512  }
513  }
514  break;
515  case SDLK_LSHIFT:
516  case SDLK_RSHIFT:
517  break;
518  case SDLK_RETURN:
519  insert('\n');
520  break;
521  }
522  }
523 
524  void input(const char *str, int len)
525  {
526  loopi(len) insert(str[i]);
527  }
528 
529  void hit(int hitx, int hity, bool dragged)
530  {
531  int maxwidth = linewrap?pixelwidth:-1;
532  int h = 0;
533  for(int i = scrolly; i < lines.length(); i++)
534  {
535  int width, height;
536  text_bounds(lines[i].text, width, height, maxwidth);
537  if(h + height > pixelheight) break;
538 
539  if(hity >= h && hity <= h+height)
540  {
541  int x = text_visible(lines[i].text, hitx, hity-h, maxwidth);
542  if(dragged) { mx = x; my = i; } else { cx = x; cy = i; };
543  break;
544  }
545  h+=height;
546  }
547  }
548 
550  {
551  int maxwidth = linewrap?pixelwidth:-1;
552  int slines = lines.length();
553  for(int ph = pixelheight; slines > 0 && ph > 0;)
554  {
555  int width, height;
556  text_bounds(lines[slines-1].text, width, height, maxwidth);
557  if(height > ph) break;
558  ph -= height;
559  slines--;
560  }
561  return slines;
562  }
563 
564  void draw(int x, int y, int color, bool hit)
565  {
566  int maxwidth = linewrap?pixelwidth:-1;
567 
568  int sx, sy, ex, ey;
569  bool selection = region(sx, sy, ex, ey);
570 
571  // fix scrolly so that <cx, cy> is always on screen
572  if(cy < scrolly) scrolly = cy;
573  else
574  {
575  if(scrolly < 0) scrolly = 0;
576  int h = 0;
577  for(int i = cy; i >= scrolly; i--)
578  {
579  int width, height;
580  text_bounds(lines[i].text, width, height, maxwidth);
581  if(h + height > pixelheight) { scrolly = i+1; break; }
582  h += height;
583  }
584  }
585 
586  if(selection)
587  {
588  // convert from cursor coords into pixel coords
589  int psx, psy, pex, pey;
590  text_pos(lines[sy].text, sx, psx, psy, maxwidth);
591  text_pos(lines[ey].text, ex, pex, pey, maxwidth);
592  int maxy = lines.length();
593  int h = 0;
594  for(int i = scrolly; i < maxy; i++)
595  {
596  int width, height;
597  text_bounds(lines[i].text, width, height, maxwidth);
598  if(h + height > pixelheight) { maxy = i; break; }
599  if(i == sy) psy += h;
600  if(i == ey) { pey += h; break; }
601  h += height;
602  }
603  maxy--;
604 
605  if(ey >= scrolly && sy <= maxy)
606  {
607  // crop top/bottom within window
608  if(sy < scrolly) { sy = scrolly; psy = 0; psx = 0; }
609  if(ey > maxy) { ey = maxy; pey = pixelheight - FONTH; pex = pixelwidth; }
610 
612  gle::colorub(0xA0, 0x80, 0x80);
613  gle::defvertex(2);
614  gle::begin(GL_QUADS);
615  if(psy == pey)
616  {
617  gle::attribf(x+psx, y+psy);
618  gle::attribf(x+pex, y+psy);
619  gle::attribf(x+pex, y+pey+FONTH);
620  gle::attribf(x+psx, y+pey+FONTH);
621  }
622  else
623  { gle::attribf(x+psx, y+psy);
624  gle::attribf(x+psx, y+psy+FONTH);
625  gle::attribf(x+pixelwidth, y+psy+FONTH);
626  gle::attribf(x+pixelwidth, y+psy);
627  if(pey-psy > FONTH)
628  {
629  gle::attribf(x, y+psy+FONTH);
630  gle::attribf(x+pixelwidth, y+psy+FONTH);
631  gle::attribf(x+pixelwidth, y+pey);
632  gle::attribf(x, y+pey);
633  }
634  gle::attribf(x, y+pey);
635  gle::attribf(x, y+pey+FONTH);
636  gle::attribf(x+pex, y+pey+FONTH);
637  gle::attribf(x+pex, y+pey);
638  }
639  gle::end();
640  hudshader->set();
641  }
642  }
643 
644  int h = 0;
645  for(int i = scrolly; i < lines.length(); i++)
646  {
647  int width, height;
648  text_bounds(lines[i].text, width, height, maxwidth);
649  if(h + height > pixelheight) break;
650 
651  draw_text(lines[i].text, x, y+h, color>>16, (color>>8)&0xFF, color&0xFF, 0xFF, hit&&(cy==i)?cx:-1, maxwidth);
652  if(linewrap && height > FONTH) // line wrap indicator
653  {
655  gle::colorub(0x80, 0xA0, 0x80);
656  gle::defvertex(2);
657  gle::begin(GL_TRIANGLE_STRIP);
658  gle::attribf(x, y+h+FONTH);
659  gle::attribf(x, y+h+height);
660  gle::attribf(x-FONTW/2, y+h+FONTH);
661  gle::attribf(x-FONTW/2, y+h+height);
662  gle::end();
663  hudshader->set();
664  }
665  h+=height;
666  }
667  }
668 };
669 
670 // a 'stack' where the last is the current focused editor
672 
673 static editor *currentfocus() { return editors.length() ? editors.last() : nullptr; }
674 
675 static void readyeditors()
676 {
677  loopv(editors) editors[i]->active = (editors[i]->mode==EDITORFOREVER);
678 }
679 
680 static void flusheditors()
681 {
682  loopvrev(editors) if(!editors[i]->active)
683  {
684  editor *e = editors.remove(i);
685  DELETEP(e);
686  }
687 }
688 
689 static editor *useeditor(const char *name, int mode, bool focus, const char *initval = nullptr)
690 {
691  loopv(editors) if(strcmp(editors[i]->name, name) == 0)
692  {
693  editor *e = editors[i];
694  if(focus) { editors.add(e); editors.remove(i); } // re-position as last
695  e->active = true;
696  return e;
697  }
698  editor *e = new editor(name, mode, initval);
699  if(focus) editors.add(e); else editors.insert(0, e);
700  return e;
701 }
702 
703 
704 #define TEXTCOMMAND(f, s, d, body) ICOMMAND(f, s, d,\
705  editor *top = currentfocus();\
706  if(!top || identflags&IDF_OVERRIDDEN) return;\
707  body\
708 )
709 
710 ICOMMAND(textlist, "", (), // @DEBUG return list of all the editors
711  vector<char> s;
712  loopv(editors)
713  {
714  if(i > 0) s.put(", ", 2);
715  s.put(editors[i]->name, strlen(editors[i]->name));
716  }
717  s.add('\0');
718  result(s.getbuf());
719 );
720 TEXTCOMMAND(textshow, "", (), // @DEBUG return the start of the buffer
721  editline line;
722  line.combinelines(top->lines);
723  result(line.text);
724  line.clear();
725 );
726 ICOMMAND(textfocus, "si", (char *name, int *mode), // focus on a (or create a persistent) specific editor, else returns current name
727  if(*name) useeditor(name, *mode<=0 ? EDITORFOREVER : *mode, true);
728  else if(editors.length() > 0) result(editors.last()->name);
729 );
730 TEXTCOMMAND(textprev, "", (), editors.insert(0, top); editors.pop();); // return to the previous editor
731 TEXTCOMMAND(textmode, "i", (int *m), // (1= keep while focused, 2= keep while used in gui, 3= keep forever (i.e. until mode changes)) topmost editor, return current setting if no args
732  if(*m) top->mode = *m;
733  else intret(top->mode);
734 );
735 TEXTCOMMAND(textsave, "s", (char *file), // saves the topmost (filename is optional)
736  if(*file) top->setfile(path(file, true));
737  top->save();
738 );
739 TEXTCOMMAND(textload, "s", (char *file), // loads into the topmost editor, returns filename if no args
740  if(*file)
741  {
742  top->setfile(path(file, true));
743  top->load();
744  }
745  else if(top->filename) result(top->filename);
746 );
747 TEXTCOMMAND(textinit, "sss", (char *name, char *file, char *initval), // loads into named editor if no file assigned and editor has been rendered
748 {
749  editor *e = NULL;
750  loopv(editors) if(!strcmp(editors[i]->name, name)) { e = editors[i]; break; }
751  if(e && e->rendered && !e->filename && *file && (e->lines.empty() || (e->lines.length() == 1 && !strcmp(e->lines[0].text, initval))))
752  {
753  e->setfile(path(file, true));
754  e->load();
755  }
756 });
757 
758 #define PASTEBUFFER "#pastebuffer"
759 
760 TEXTCOMMAND(textcopy, "", (), editor *b = useeditor(PASTEBUFFER, EDITORFOREVER, false); top->copyselectionto(b););
761 TEXTCOMMAND(textpaste, "", (), editor *b = useeditor(PASTEBUFFER, EDITORFOREVER, false); top->insertallfrom(b););
762 TEXTCOMMAND(textmark, "i", (int *m), // (1=mark, 2=unmark), return current mark setting if no args
763  if(*m) top->mark(*m==1);
764  else intret(top->region() ? 1 : 2);
765 );
766 TEXTCOMMAND(textselectall, "", (), top->selectall(););
767 TEXTCOMMAND(textclear, "", (), top->clear(););
768 TEXTCOMMAND(textcurrentline, "", (), result(top->currentline().text););
769 
770 TEXTCOMMAND(textexec, "i", (int *selected), // execute script commands from the buffer (0=all, 1=selected region only)
771  char *script = *selected ? top->selectiontostring() : top->tostring();
772  execute(script);
773  delete[] script;
774 );
775 
char * text
Definition: textedit.hpp:15
editline(const char *init)
Definition: textedit.hpp:19
int cx
Definition: textedit.hpp:155
bool empty() const
is this vector empty?
Definition: cube_vector.hpp:141
void put(const T &v)
write bytes to vector
Definition: cube_vector.hpp:235
int cy
Definition: textedit.hpp:155
virtual bool putline(const char *str)
Definition: stream.hpp:49
int maxx
Definition: textedit.hpp:157
const T & max(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:224
void draw_text(const char *str, int left, int top, int r, int g, int b, int a, int cursor, int maxwidth)
Definition: rendertext.cpp:361
editline()
Definition: textedit.hpp:18
#define PASTEBUFFER
Definition: textedit.hpp:758
GLenum GLsizei GLsizei height
Definition: glexts.hpp:291
void shrink(int i)
shrink vector memory size AND DELETE UNUSED MEMORY
Definition: cube_vector.hpp:161
int my
Definition: textedit.hpp:156
void removelines(int start, int count)
Definition: textedit.hpp:335
Definition: textedit.hpp:13
void save()
Definition: textedit.hpp:212
void insert(const char *s)
Definition: textedit.hpp:397
void clear()
Definition: textedit.hpp:26
void append(const char *str)
Definition: textedit.hpp:76
StringFormatter::FmtMark fmt
Marker that starts formatting a string.
Definition: StringFormatter.cpp:5
Shader * hudnotextureshader
Definition: shader.cpp:33
const char * name
Definition: textedit.hpp:152
char * tostring()
Definition: textedit.hpp:294
T * getbuf()
get the whole vector
Definition: cube_vector.hpp:169
void begin(GLenum mode)
Definition: glemu.cpp:220
void hit(int hitx, int hity, bool dragged)
Definition: textedit.hpp:529
T & last()
get the last index
Definition: cube_vector.hpp:131
GLenum GLsizei width
Definition: glexts.hpp:291
static editor * useeditor(const char *name, int mode, bool focus, const char *initval=nullptr)
Definition: textedit.hpp:689
void init(int slices, int stacks)
Definition: explosion.cpp:38
static void flusheditors()
Definition: textedit.hpp:680
void vformatstring(char *d, const char *fmt, va_list v, int len)
Internal: format string using variable parameter lists (va_list)
Definition: cube_formatting.hpp:15
#define PRINTFARGS(fmt, args)
Definition: cube_formatting.hpp:11
bool grow(int total, const char *fmt=nullptr,...) PRINTFARGS(3
bool del()
Definition: textedit.hpp:341
Definition: 3dgui.hpp:50
void prepend(const char *str)
Definition: textedit.hpp:65
void combinelines(vector< editline > &src)
Definition: textedit.hpp:136
int pixelheight
Definition: textedit.hpp:163
bool active
Definition: textedit.hpp:151
bool empty()
Definition: textedit.hpp:24
static void text_pos(const char *str, int cursor, int &cx, int &cy, int maxwidth)
Definition: rendertext.hpp:60
static vector< editor * > editors
Definition: textedit.hpp:671
#define FONTH
Definition: rendertext.hpp:29
int mode
Definition: textedit.hpp:150
ICOMMAND * f(float *a, float *b), floatret(*a **b)
static void readyeditors()
Definition: textedit.hpp:675
int pixelwidth
Definition: textedit.hpp:162
else loopi(numargs)
Definition: command.cpp:3019
#define NULL
Definition: cube_types.hpp:35
T & insert(int i, const T &e)
insertion functions
Definition: cube_vector.hpp:310
Shader * hudshader
Definition: shader.cpp:33
void start(const char *filename, int videofps, int videow, int videoh, bool sound)
Definition: movie.cpp:975
T & add(const T &x)
Add new index to vector.
Definition: cube_vector.hpp:73
void enable()
Definition: explosion.cpp:92
#define DELETEA(p)
Delete Array, Wrapper around delete[], sets pointer to NULL afterwards(!).
Definition: cube_tools.hpp:31
void remove(int i, int n)
remove indices from vector remove ordered?
Definition: cube_vector.hpp:248
int limitscrolly()
Definition: textedit.hpp:549
const T & min(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:210
void insertallfrom(editor *b)
Definition: textedit.hpp:402
char * selectiontostring()
Definition: textedit.hpp:311
void input(const char *str, int len)
Definition: textedit.hpp:524
bool read(stream *f, int chop=-1)
Definition: textedit.hpp:83
#define loopvrev(v)
Definition: cube_loops.hpp:24
void draw(int x, int y, int color, bool hit)
Definition: textedit.hpp:564
char * path(char *s)
Modifies the input string to only contain slashes in the direction the platform allows.
Definition: stream.cpp:63
static editor * currentfocus()
Definition: textedit.hpp:673
int scrolly
Definition: textedit.hpp:159
int maxlen
Definition: textedit.hpp:16
void setfile(const char *fname)
Definition: textedit.hpp:192
char * newtext
Definition: textedit.hpp:36
void result(tagval &v)
Definition: command.cpp:2562
void insert(char ch)
Definition: textedit.hpp:373
int length() const
return size of used memory
Definition: cube_vector.hpp:146
void del(int start, int count)
Definition: textedit.hpp:109
if(NOT DEFINED PROJECT_ARCH) message(FATAL_ERROR"You are generating from the wrong folder! \"Where is the Source
Definition: CMakeLists.txt:2
void copyselectionto(editor *b)
Definition: textedit.hpp:269
Legacy file system streams.
Definition: stream.hpp:22
void insert(char *str, int start, int count=0)
Definition: textedit.hpp:126
static aviwriter * file
Definition: movie.cpp:830
void set(const char *str, int slen=-1)
Definition: textedit.hpp:49
#define DELETEP(p)
Delete Pointer, Wrapper around delete, sets pointer to NULL afterwards(!).
Definition: cube_tools.hpp:28
int end()
Definition: glemu.cpp:256
bool rendered
Definition: textedit.hpp:151
const char * filename
Definition: textedit.hpp:153
GLintptr offset
Definition: glexts.hpp:354
#define TEXTCOMMAND(f, s, d, body)
Definition: textedit.hpp:704
virtual bool getline(char *str, size_t len)
Definition: stream.cpp:318
Definition: textedit.hpp:11
DELETEA(text)
stream * openutf8file(const char *filename, const char *mode, stream *file)
Definition: stream.cpp:929
GLsizei count
Definition: glexts.hpp:57
void selectall()
Definition: textedit.hpp:227
Definition: textedit.hpp:148
bool region()
Definition: textedit.hpp:257
int mx
Definition: textedit.hpp:156
static void color(const bvec &v, uchar alpha=255)
Definition: glemu.hpp:71
static void text_bounds(const char *str, int &width, int &height, int maxwidth=-1)
Definition: rendertext.hpp:52
void mark(bool enable)
Definition: textedit.hpp:221
editline & currentline()
Definition: textedit.hpp:260
void key(int code)
Definition: textedit.hpp:440
~editor()
Definition: textedit.hpp:175
execute(script)
bool region(int &sx, int &sy, int &ex, int &ey)
Definition: textedit.hpp:235
bool linewrap
Definition: textedit.hpp:161
void intret(int v)
Definition: command.cpp:2418
int text_visible(const char *str, float hitx, float hity, int maxwidth)
Definition: rendertext.cpp:303
void clear(const char *init="")
Definition: textedit.hpp:183
#define loopv(v)
Definition: cube_loops.hpp:21
T & pop()
get the last index and decrement the vector's size
Definition: cube_vector.hpp:129
void set()
Definition: shader.hpp:278
char * newstring(size_t l)
Definition: cube_tools.hpp:71
int maxy
Definition: textedit.hpp:157
editor(const char *name, int mode, const char *initval)
Definition: textedit.hpp:167
int len
Definition: textedit.hpp:16
char * script
Definition: textedit.hpp:771
ICOMMAND(textlist,"",(), vector< char > s;loopv(editors){if(i > 0) s.put(", ", 2);s.put(editors[i]->name, strlen(editors[i]->name));}s.add('\0');result(s.getbuf());)
void chop(int newlen)
Definition: textedit.hpp:119
void load()
Definition: textedit.hpp:198
vector< editline > lines
Definition: textedit.hpp:165
#define FONTW
Definition: rendertext.hpp:30
#define ASSERT(c)
Definition: cube_tools.hpp:12