Hasty Badger
Small UI library (a branch of Turbo Badger)
 All Classes Namespaces Functions Variables Enumerations Enumerator Friends Groups Pages
tb_style_edit.h
1 // ================================================================================
2 // == This file is a part of Turbo Badger. (C) 2011-2014, Emil SegerÃ¥s ==
3 // == See tb_core.h for more information. ==
4 // ================================================================================
5 
6 #ifndef TBStyleEdit_H
7 #define TBStyleEdit_H
8 
9 #include "tb_core.h"
10 #include "tb_linklist.h"
11 #include "tb_widgets_common.h"
12 #include "tb_list.h"
13 
14 namespace tb {
15 
16 class TBStyleEdit;
17 class TBBlock;
18 class TBTextFragment;
19 class TBTextFragmentContent;
20 class TBTextFragmentContentFactory;
21 
25 {
26 public:
27  virtual ~TBStyleEditListener() {}
28 
29  virtual void OnChange() {};
30  virtual bool OnEnter() { return false; };
31  virtual void Invalidate(const TBRect &rect) = 0;
32  virtual void DrawString(int32_t x, int32_t y, TBFontFace *font, const TBColor &color, const char *str, int32_t len = TB_ALL_TO_TERMINATION) = 0;
33  virtual void DrawRect(const TBRect &rect, const TBColor &color) = 0;
34  virtual void DrawRectFill(const TBRect &rect, const TBColor &color) = 0;
35  virtual void DrawTextSelectionBg(const TBRect &rect) = 0;
36  virtual void DrawContentSelectionFg(const TBRect &rect) = 0;
37  virtual void DrawCaret(const TBRect &rect) = 0;
38  virtual void Scroll(int32_t dx, int32_t dy) = 0;
39  virtual void UpdateScrollbars() = 0;
40  virtual void CaretBlinkStart() = 0;
41  virtual void CaretBlinkStop() = 0;
42 };
43 
47 {
48 public:
49  virtual ~TBTextFragmentContentFactory() {}
55  virtual int GetContent(const char *text);
56 
58  virtual TBTextFragmentContent *CreateFragmentContent(const char *text, int text_len);
59 };
60 
61 class TBTextOfs
62 {
63 public:
64  TBTextOfs() : block(nullptr), ofs(0) {}
65  TBTextOfs(TBBlock *block, int32_t ofs) : block(block), ofs(ofs) {}
66 
67  void Set(TBBlock *new_block, int32_t new_ofs) { block = new_block; ofs = new_ofs; }
68  void Set(const TBTextOfs &pos) { block = pos.block; ofs = pos.ofs; }
69 
70  int32_t GetGlobalOfs(TBStyleEdit *se) const;
71  bool SetGlobalOfs(TBStyleEdit *se, int32_t gofs);
72 
73 public:
74  TBBlock *block;
75  int32_t ofs;
76 };
77 
81 {
82 public:
83  TBSelection(TBStyleEdit *styledit);
84  TBSelection(const TBStyleEdit *styledit);
85  void Invalidate() const;
86  void Select(const TBTextOfs &new_start, const TBTextOfs &new_stop);
87  void Select(const TBPoint &from, const TBPoint &to);
88  void Select(int glob_ofs_from, int glob_ofs_to);
89  void SelectToCaret(TBBlock *old_caret_block, int32_t old_caret_ofs);
90  void SelectAll();
91  void SelectNothing();
92  void CorrectOrder();
93  void CopyToClipboard();
94  bool IsBlockSelected(TBBlock *block) const;
95  bool IsFragmentSelected(TBTextFragment *elm) const;
96  bool IsSelected() const;
97  void RemoveContent();
98  bool GetText(TBStr &text) const;
99 public:
100  TBStyleEdit *styledit;
101  TBTextOfs start, stop;
102  bool m_const;
103 };
104 
105 enum TB_CARET_POS {
106  TB_CARET_POS_BEGINNING,
107  TB_CARET_POS_END
108 };
109 
112 class TBCaret
113 {
114 public:
115  TBCaret(TBStyleEdit *styledit);
116  void Invalidate();
117  void UpdatePos();
118  bool Move(bool forward, bool word);
119  bool Place(const TBPoint &point);
120  bool Place(TBBlock *block, int ofs, bool allow_snap = true, bool snap_forward = false);
121  void Place(TB_CARET_POS place);
122  void AvoidLineBreak();
123  void Paint(int32_t translate_x, int32_t translate_y);
124  void ResetBlink();
125  void UpdateWantedX();
126 
127  int32_t GetGlobalOfs() const { return pos.GetGlobalOfs(styledit); }
128  void SetGlobalOfs(int32_t gofs, bool allow_snap = true, bool snap_forward = false);
129 
130  TBTextFragment *GetFragment();
131 private:
132  void SwitchBlock(bool second);
133 public:
134  TBStyleEdit *styledit;
135  int32_t x, y;
136  int32_t width;
137  int32_t height;
138  int32_t wanted_x;
139  bool on;
140  bool prefer_first;
141  TBTextOfs pos;
142 };
143 
147 {
148 public:
149  class Data : public TBLinkOf<Data>
150  {
151  public:
152  TBFontDescription font_desc;
153  TBColor text_color;
154  bool underline;
155  };
156  TBTextProps(const TBFontDescription &font_desc, const TBColor &text_color);
157 
158  Data *Push();
159  void Pop();
160 
162  TBFontFace *GetFont();
163 public:
164  TBLinkListOf<Data> data_list;
165  Data base_data;
166  Data *data;
167 };
168 
171 class TBBlock : public TBLinkOf<TBBlock>
172 {
173 public:
174  TBBlock(TBStyleEdit *styledit);
175  ~TBBlock();
176 
177  void Clear();
178  void Set(TBStr newstr);
179  void SetAlign(TB_TEXT_ALIGN align);
180 
181  int32_t InsertText(int32_t ofs, const char * text, int32_t len, bool allow_line_recurse);
182  void RemoveContent(int32_t ofs, int32_t len);
183 
185  void Split();
186 
188  void Merge();
189 
193  void Layout(bool update_fragments, bool propagate_height);
194 
197  void SetSize(int32_t old_w, int32_t new_w, int32_t new_h, bool propagate_height);
198 
199  TBTextFragment *FindFragment(int32_t ofs, bool prefer_first = false) const;
200  TBTextFragment *FindFragment(int32_t x, int32_t y) const;
201 
202  int32_t CalculateStringWidth(TBFontFace *font, const char * str, int len = TB_ALL_TO_TERMINATION) const;
203  int32_t CalculateTabWidth(TBFontFace *font, int32_t xpos) const;
204  int32_t CalculateLineHeight(TBFontFace *font) const;
205  int32_t CalculateBaseline(TBFontFace *font) const;
206 
207  void Invalidate() const;
208  void BuildSelectionRegion(int32_t translate_x, int32_t translate_y, TBTextProps *props,
209  TBRegion &bg_region, TBRegion &fg_region);
210  void Paint(int32_t translate_x, int32_t translate_y, TBTextProps *props);
211 public:
212  TBStyleEdit *styledit;
214 
215  int32_t ypos;
216  int16_t height;
217  int8_t align;
218  int line_width_max;
219 
220  TBStr str;
221  int32_t str_len;
222 
223 private:
224  int GetStartIndentation(TBFontFace *font, int first_line_len) const;
225 };
226 
230 {
231 public:
232  int32_t gofs;
233  TBStr text;
234  bool insert;
235 };
236 
240 {
241 public:
242  TBUndoRedoStack() : applying(false) {}
243  ~TBUndoRedoStack();
244 
245  void Undo(TBStyleEdit *styledit);
246  void Redo(TBStyleEdit *styledit);
247  void Clear(bool clear_undo, bool clear_redo);
248 
249  TBUndoEvent *Commit(TBStyleEdit *styledit, int32_t gofs, int32_t len, const char *text, bool insert);
250 public:
251  TBListOf<TBUndoEvent> undos;
252  TBListOf<TBUndoEvent> redos;
253  bool applying;
254 private:
255  void Apply(TBStyleEdit *styledit, TBUndoEvent *e, bool reverse);
256 };
257 
265 class TBTextFragment : public TBLinkOf<TBTextFragment>
266 {
267 public:
268  TBTextFragment(TBTextFragmentContent *content = nullptr)
269  : xpos(0)
270  , ypos(0)
271  , ofs(0)
272  , len(0)
273  , line_ypos(0)
274  , line_height(0)
275  , block(nullptr)
276  , content(content) {}
277  ~TBTextFragment();
278 
279  void Init(TBBlock *block, uint16_t ofs, uint16_t len);
280 
281  void UpdateContentPos();
282 
283  void BuildSelectionRegion(int32_t translate_x, int32_t translate_y, TBTextProps *props,
284  TBRegion &bg_region, TBRegion &fg_region);
285  void Paint(int32_t translate_x, int32_t translate_y, TBTextProps *props);
286  void Click(int button, uint32_t modifierkeys);
287 
288  bool IsText() const { return !IsEmbedded(); }
289  bool IsEmbedded() const { return content ? true : false; }
290  bool IsBreak() const;
291  bool IsSpace() const;
292  bool IsTab() const;
293 
294  int32_t GetCharX(TBFontFace *font, int32_t ofs);
295  int32_t GetCharOfs(TBFontFace *font, int32_t x);
296 
298  int32_t GetStringWidth(TBFontFace *font, const char *str, int len);
299 
300  bool GetAllowBreakBefore() const;
301  bool GetAllowBreakAfter() const;
302 
303  const char *Str() const { return block->str.CStr() + ofs; }
304 
305  int32_t GetWidth(TBFontFace *font);
306  int32_t GetHeight(TBFontFace *font);
307  int32_t GetBaseline(TBFontFace *font);
308 public:
309  int16_t xpos, ypos;
310  uint16_t ofs, len;
311  uint16_t line_ypos;
312  uint16_t line_height;
313  TBBlock *block;
314  TBTextFragmentContent *content;
315 };
316 
320 {
321 public:
322  TBStyleEdit();
323  virtual ~TBStyleEdit();
324 
325  void SetListener(TBStyleEditListener *listener);
326  void SetContentFactory(TBTextFragmentContentFactory *content_factory);
327 
328  void SetFont(const TBFontDescription &font_desc);
329 
330  void Paint(const TBRect &rect, const TBFontDescription &font_desc, const TBColor &text_color);
331  bool KeyDown(int key, SPECIAL_KEY special_key, MODIFIER_KEYS modifierkeys);
332  bool MouseDown(const TBPoint &point, int button, int clicks, MODIFIER_KEYS modifierkeys, bool touch);
333  bool MouseUp(const TBPoint &point, int button, MODIFIER_KEYS modifierkeys, bool touch);
334  bool MouseMove(const TBPoint &point);
335  void Focus(bool focus);
336 
337  void Clear(bool init_new = true);
338  bool SetText(const TBStr & text, TB_CARET_POS pos = TB_CARET_POS_BEGINNING);
339  //bool SetText(const TBStr & text, int text_len, TB_CARET_POS pos = TB_CARET_POS_BEGINNING);
340  bool GetText(TBStr &text) const;
341  bool IsEmpty() const;
342 
345  void SetAlign(TB_TEXT_ALIGN align);
346  void SetMultiline(bool multiline = true);
347  void SetStyling(bool styling = true);
348  void SetReadOnly(bool readonly = true);
349  void SetSelection(bool selection = true);
350  void SetPassword(bool password = true);
351  void SetWrapping(bool wrapping = true);
352 
359  void SetWindowsStyleBreak(bool win_style_br) { packed.win_style_br = win_style_br; }
360 
361  void Cut();
362  void Copy();
363  void Paste();
364  void Delete();
365 
366  void Undo();
367  void Redo();
368  bool CanUndo() const { return undoredo.undos.GetNumItems() ? true : false; }
369  bool CanRedo() const { return undoredo.redos.GetNumItems() ? true : false; }
370 
371  void InsertText(const char *text, int32_t len = TB_ALL_TO_TERMINATION,
372  bool after_last = false, bool clear_undo_redo = false);
373  void AppendText(const char *text, int32_t len = TB_ALL_TO_TERMINATION,
374  bool clear_undo_redo = false) { InsertText(text, len, true, clear_undo_redo); }
375  void InsertBreak();
376 
377  TBBlock *FindBlock(int32_t y) const;
378 
379  void ScrollIfNeeded(bool x = true, bool y = true);
380  void SetScrollPos(int32_t x, int32_t y);
381  void SetLayoutSize(int32_t width, int32_t height, bool is_virtual_reformat);
382  void Reformat(bool update_fragments);
383 
384  int32_t GetContentWidth();
385  int32_t GetContentHeight() const;
386 
387  int32_t GetOverflowX() const { return MAX(content_width - layout_width, 0); }
388  int32_t GetOverflowY() const { return MAX(content_height - layout_height, 0); }
389 public:
390  TBStyleEditListener *listener;
391  TBTextFragmentContentFactory default_content_factory;
392  TBTextFragmentContentFactory *content_factory;
393  int32_t layout_width;
394  int32_t layout_height;
395  int32_t content_width;
396  int32_t content_height;
397 
398  TBLinkListOf<TBBlock> blocks;
399 
400  TBCaret caret;
401  TBSelection selection;
402  TBUndoRedoStack undoredo;
403 
404  int32_t scroll_x;
405  int32_t scroll_y;
406 
407  int8_t select_state;
408  TBPoint mousedown_point;
409  TBTextFragment *mousedown_fragment;
410 
413  TBFontDescription font_desc;
414 
415  TB_TEXT_ALIGN align;
416  union { struct {
417  uint32_t multiline_on : 1;
418  uint32_t styling_on : 1;
419  uint32_t read_only : 1;
420  uint32_t selection_on : 1;
421  uint32_t show_whitespace : 1;
422  uint32_t password_on : 1;
423  uint32_t wrapping : 1;
424  uint32_t win_style_br : 1;
426  uint32_t lock_scrollbars_counter : 5;
427  } packed;
428  uint32_t packed_init;
429  };
430 
434  void BeginLockScrollbars();
435  void EndLockScrollbars();
436 
438  bool GetSizeAffectsLayout() const;
439 };
440 
441 } // namespace tb
442 
443 #endif
Keeps track of all TBUndoEvents used for undo and redo functionality.
Definition: tb_style_edit.h:239
Event in the TBUndoRedoStack.
Definition: tb_style_edit.h:229
void SetLayoutSize(int32_t width, int32_t height, bool is_virtual_reformat)
Definition: tb_style_edit.cpp:1513
void SetAlign(TB_TEXT_ALIGN align)
Set the default text alignment and all currently selected blocks, or the block of the current caret p...
Definition: tb_style_edit.cpp:1964
bool GetSizeAffectsLayout() const
Return true if changing layout_width and layout_height requires relayouting.
Definition: tb_style_edit.cpp:1532
Listener for TBStyleEdit.
Definition: tb_style_edit.h:24
int32_t GetStringWidth(TBFontFace *font, const char *str, int len)
Get the stringwidth.
Definition: tb_style_edit.cpp:1334
void Merge()
Check if we&#39;ve lost the ending break on this block and if so merge it with the next block...
Definition: tb_style_edit.cpp:827
uint32_t lock_scrollbars_counter
Incremental counter for if UpdateScrollbar should be probhited.
Definition: tb_style_edit.h:426
Content for a non-text TBTextFragment.
Definition: tb_style_edit_content.h:17
Definition: tb_style_edit.h:149
TBFontFace represents a loaded font that can measure and render strings.
Definition: tb_font_renderer.h:142
A block of text (a line, that might be wrapped)
Definition: tb_style_edit.h:171
TBFontFace * font
DEPRECATED! This will be removed when using different fonts is properly supported! ...
Definition: tb_style_edit.h:412
TB_TEXT_ALIGN
TB_TEXT_ALIGN specifies horizontal text alignment.
Definition: tb_widgets_common.h:22
Simple point class.
Definition: tb_geometry.h:15
TBRegion does calculations on regions represented by a list of rectangles.
Definition: tb_geometry.h:63
void SetWindowsStyleBreak(bool win_style_br)
Set if line breaks should be inserted in windows style ( ) or unix style ( ).
Definition: tb_style_edit.h:359
Definition: tb_style_edit.h:61
void BeginLockScrollbars()
Call BeginLockScrollbars &amp; EndLockScrollbars around a scope which does lots of changes, to prevent UpdateScrollbar from happening for each block (May cause recalculation of content_width by iterating through all blocks)
Definition: tb_style_edit.cpp:1501
virtual TBTextFragmentContent * CreateFragmentContent(const char *text, int text_len)
Create content for a string previosly consumed by calling GetContent.
Definition: tb_style_edit_content.cpp:31
virtual int GetContent(const char *text)
Should return then length of the text that represents content that can be created by this factory...
Definition: tb_style_edit_content.cpp:15
TBFontFace * GetFont()
Get the font face from the current font description.
Definition: tb_style_edit.cpp:695
TBTextProps is a stack of properties used during layout &amp; paint of TBStyleEdit.
Definition: tb_style_edit.h:146
Edit and formats TBTextFragment&#39;s.
Definition: tb_style_edit.h:319
Handles the selected text in a TBStyleEdit.
Definition: tb_style_edit.h:80
void SetSize(int32_t old_w, int32_t new_w, int32_t new_h, bool propagate_height)
Update the size of this block.
Definition: tb_style_edit.cpp:1077
uint32_t calculate_content_width_needed
If content_width needs to be updated next GetContentWidth-.
Definition: tb_style_edit.h:425
void Layout(bool update_fragments, bool propagate_height)
Layout the block.
Definition: tb_style_edit.cpp:899
TBListOf is a list (array) of pointers to the specified object type.
Definition: tb_list.h:47
TBStr is a simple string class.
Definition: tb_str.h:62
void Split()
Check if this block contains extra line breaks and split into new blocks if it does.
Definition: tb_style_edit.cpp:798
Simple rectangle class.
Definition: tb_geometry.h:25
Creates TBTextFragmentContent if the sequence of text matches known content.
Definition: tb_style_edit.h:46
The textfragment baseclass for TBStyleEdit.
Definition: tb_style_edit.h:265
TBColor contains a 32bit color.
Definition: tb_color.h:21
The caret in a TBStyleEdit.
Definition: tb_style_edit.h:112
TBFontDescription describes a font.
Definition: tb_font_desc.h:18
char * CStr() const
Get the c-string raw (char *)
Definition: tb_str.h:93
int32_t y
Relative to the styledit.
Definition: tb_style_edit.h:135