1 // Copyright (C) 2010-2015 Petr Pavlu <setup@dagobah.cz>
3 // This file is part of CenterIM.
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.
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/>.
21 /// @ingroup cppconsui
32 class TextEdit
: public Widget
{
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
;
44 virtual bool processInputText(const TermKeyKey
&key
) override
;
47 virtual int draw(Curses::ViewPort area
, Error
&error
) override
;
50 virtual void setText(const char *new_text
);
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
;
81 MOVE_LOGICAL_POSITIONS
,
82 MOVE_VISUAL_POSITIONS
,
85 MOVE_DISPLAY_LINE_ENDS
,
90 MOVE_HORIZONTAL_PAGES
,
100 /// Pointer to the start of line (points into buffer).
103 /// Pointer to the first byte that is not part of this line.
106 /// Precalculated 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.
128 bool overwrite_mode_
;
129 bool single_line_mode_
;
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.
151 /// First location outside buffer.
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_
;
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;
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
226 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: