Update list of wide characters
[centerim5.git] / cppconsui / TextEdit.h
blob077cdab992219e679dc7e200da7432ca5ceaba3a
1 // Copyright (C) 2010-2015 Petr Pavlu <setup@dagobah.cz>
2 //
3 // This file is part of CenterIM.
4 //
5 // CenterIM is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // CenterIM is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
18 /// @file
19 /// TextEdit class
20 ///
21 /// @ingroup cppconsui
23 #ifndef TEXTEDIT_H
24 #define TEXTEDIT_H
26 #include "Widget.h"
28 #include <deque>
30 namespace CppConsUI {
32 class TextEdit : public Widget {
33 public:
34 enum Flag {
35 FLAG_NUMERIC = 1 << 0,
36 FLAG_NOSPACE = 1 << 1,
39 TextEdit(int w, int h, const char *text_ = nullptr, int flags_ = 0,
40 bool single_line = false, bool accept_tabs_ = true, bool masked_ = false);
41 virtual ~TextEdit() override;
43 // InputProcessor
44 virtual bool processInputText(const TermKeyKey &key) override;
46 // Widget
47 virtual int draw(Curses::ViewPort area, Error &error) override;
49 /// Sets new text.
50 virtual void setText(const char *new_text);
52 /// Removes all text.
53 virtual void clear();
55 /// Returns inserted text.
56 virtual const char *getText() const;
58 virtual std::size_t getTextLength() const { return text_length_; }
60 virtual void setFlags(int new_flags, bool revalidate = true);
61 virtual int getFlags() const { return flags_; }
63 virtual void setSingleLineMode(bool new_single_line_mode);
64 virtual bool isSingleLineMode() const { return single_line_mode_; }
66 virtual void setAcceptTabs(bool new_accept_tabs);
67 virtual bool doesAcceptTabs() const { return accept_tabs_; }
69 virtual void setMasked(bool new_masked);
70 virtual bool isMasked() const { return masked_; }
72 sigc::signal<void, TextEdit &> signal_text_change;
74 protected:
75 enum Direction {
76 DIR_BACK,
77 DIR_FORWARD,
80 enum CursorMovement {
81 MOVE_LOGICAL_POSITIONS,
82 MOVE_VISUAL_POSITIONS,
83 MOVE_WORDS,
84 MOVE_DISPLAY_LINES,
85 MOVE_DISPLAY_LINE_ENDS,
86 MOVE_PARAGRAPHS,
87 MOVE_PARAGRAPH_ENDS,
88 MOVE_PAGES,
89 MOVE_BUFFER_ENDS,
90 MOVE_HORIZONTAL_PAGES,
93 enum DeleteType {
94 DELETE_CHARS,
95 DELETE_WORD_ENDS,
96 DELETE_LINE_ENDS,
99 struct ScreenLine {
100 /// Pointer to the start of line (points into buffer).
101 const char *start;
103 /// Pointer to the first byte that is not part of this line.
104 const char *end;
106 /// Precalculated length.
107 std::size_t length;
109 ScreenLine(const char *start, const char *end, std::size_t length)
110 : start(start), end(end), length(length)
113 bool operator==(const ScreenLine &other) const;
116 struct CmpScreenLineEnd {
117 bool operator()(ScreenLine &sline, const char *tag);
120 typedef std::deque<ScreenLine> ScreenLines;
122 ScreenLines screen_lines_;
124 /// Bitmask indicating which input is accepted.
125 int flags_;
127 bool editable_;
128 bool overwrite_mode_;
129 bool single_line_mode_;
130 bool accept_tabs_;
131 bool masked_;
133 /// Character position from the start of buffer.
134 std::size_t current_pos_;
136 /// Cursor location in the buffer.
137 mutable char *point_;
139 /// Current cursor line (derived from current_pos_ and screen_lines_).
140 std::size_t current_sc_line_;
142 /// Current cursor character number (in the current line).
143 std::size_t current_sc_linepos_;
145 /// Holds index into screen_lines_ that marks the first screen line.
146 std::size_t view_top_;
148 /// Start of text buffer.
149 char *buffer_;
151 /// First location outside buffer.
152 char *bufend_;
154 /// Start of gap.
155 mutable char *gapstart_;
157 /// First location after the gap end.
158 mutable char *gapend_;
160 /// Length in use, in chars.
161 std::size_t text_length_;
163 mutable bool screen_lines_dirty_;
165 // Widget
166 virtual void updateArea() override;
168 virtual void initBuffer(std::size_t size);
169 virtual std::size_t getGapSize() const;
170 virtual void expandGap(std::size_t size);
171 virtual void moveGapToCursor();
173 virtual char *getTextStart() const;
174 virtual char *prevChar(const char *p) const;
175 virtual char *nextChar(const char *p) const;
176 virtual int width(const char *start, std::size_t chars) const;
178 /// Returns on-screen width of a given character in the same fashion as
179 /// Curses::onscreen_width() does but handles the tab character and wide
180 /// characters properly if the masked mode is active.
181 virtual int onScreenWidth(UTF8::UniChar uc, int w = 0) const;
183 virtual char *getScreenLine(
184 const char *text, int max_width, std::size_t *res_length) const;
186 /// Recalculates all screen lines.
187 virtual void updateScreenLines();
189 /// Recalculates necessary amout of screen lines.
190 virtual void updateScreenLines(const char *begin, const char *end);
192 virtual void assertUpdatedScreenLines();
194 /// Recalculates screen cursor position based on current_pos_ and
195 /// screen_lines_, sets current_sc_line_ and current_sc_linepos_ and handles
196 /// scrolling if necessary.
197 virtual void updateScreenCursor();
199 /// Inserts given text at the current cursor position.
200 virtual void insertTextAtCursor(
201 const char *new_text, std::size_t new_text_bytes);
202 virtual void insertTextAtCursor(const char *new_text);
203 virtual void deleteFromCursor(DeleteType type, Direction dir);
204 virtual void moveCursor(CursorMovement step, Direction dir);
206 virtual void toggleOverwrite();
208 virtual std::size_t moveLogicallyFromCursor(Direction dir) const;
209 virtual std::size_t moveWordFromCursor(Direction dir, bool word_end) const;
210 virtual std::size_t moveLineFromCursor(Direction dir) const;
212 private:
213 CONSUI_DISABLE_COPY(TextEdit);
215 void actionMoveCursor(CursorMovement step, Direction dir);
216 void actionDelete(DeleteType type, Direction dir);
217 void actionToggleOverwrite();
219 void declareBindables();
222 } // namespace CppConsUI
224 #endif // TEXTEDIT_H
226 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: