Fix build on systems that have a separate libintl library
[centerim5.git] / cppconsui / TextEdit.h
blobe58f6b8c01bd68a1170e78fd30b2ba6503f861ef
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,
98 struct ScreenLine {
99 /// Pointer to the start of line (points into buffer).
100 const char *start;
102 /// Pointer to the first byte that is not part of this line.
103 const char *end;
105 /// Precalculated length.
106 std::size_t length;
108 ScreenLine(const char *start, const char *end, std::size_t length)
109 : start(start), end(end), length(length)
112 bool operator==(const ScreenLine &other) const;
115 struct CmpScreenLineEnd {
116 bool operator()(ScreenLine &sline, const char *tag);
119 typedef std::deque<ScreenLine> ScreenLines;
121 ScreenLines screen_lines_;
123 /// Bitmask indicating which input is accepted.
124 int flags_;
126 bool editable_;
127 bool overwrite_mode_;
128 bool single_line_mode_;
129 bool accept_tabs_;
130 bool masked_;
132 /// Character position from the start of buffer.
133 std::size_t current_pos_;
135 /// Cursor location in the buffer.
136 mutable char *point_;
138 /// Current cursor line (derived from current_pos_ and screen_lines_).
139 std::size_t current_sc_line_;
141 /// Current cursor character number (in the current line).
142 std::size_t current_sc_linepos_;
144 /// Holds index into screen_lines_ that marks the first screen line.
145 std::size_t view_top_;
147 /// Start of text buffer.
148 char *buffer_;
150 /// First location outside buffer.
151 char *bufend_;
153 /// Start of gap.
154 mutable char *gapstart_;
156 /// First location after the gap end.
157 mutable char *gapend_;
159 /// Length in use, in chars.
160 std::size_t text_length_;
162 mutable bool screen_lines_dirty_;
164 // Widget
165 virtual void updateArea() override;
167 virtual void initBuffer(std::size_t size);
168 virtual std::size_t getGapSize() const;
169 virtual void expandGap(std::size_t size);
170 virtual void moveGapToCursor();
172 virtual char *getTextStart() const;
173 virtual char *prevChar(const char *p) const;
174 virtual char *nextChar(const char *p) const;
175 virtual int width(const char *start, std::size_t chars) const;
177 /// Returns on-screen width of a given character in the same fashion as
178 /// Curses::onscreen_width() does but handles the tab character and wide
179 /// characters properly if the masked mode is active.
180 virtual int onScreenWidth(UTF8::UniChar uc, int w = 0) const;
182 virtual char *getScreenLine(
183 const char *text, int max_width, std::size_t *res_length) const;
185 /// Recalculates all screen lines.
186 virtual void updateScreenLines();
188 /// Recalculates necessary amout of screen lines.
189 virtual void updateScreenLines(const char *begin, const char *end);
191 virtual void assertUpdatedScreenLines();
193 /// Recalculates screen cursor position based on current_pos_ and
194 /// screen_lines_, sets current_sc_line_ and current_sc_linepos_ and handles
195 /// scrolling if necessary.
196 virtual void updateScreenCursor();
198 /// Inserts given text at the current cursor position.
199 virtual void insertTextAtCursor(
200 const char *new_text, std::size_t new_text_bytes);
201 virtual void insertTextAtCursor(const char *new_text);
202 virtual void deleteFromCursor(DeleteType type, Direction dir);
203 virtual void moveCursor(CursorMovement step, Direction dir);
205 virtual void toggleOverwrite();
207 virtual std::size_t moveLogicallyFromCursor(Direction dir) const;
208 virtual std::size_t moveWordFromCursor(Direction dir, bool word_end) const;
210 private:
211 CONSUI_DISABLE_COPY(TextEdit);
213 void actionMoveCursor(CursorMovement step, Direction dir);
214 void actionDelete(DeleteType type, Direction dir);
215 void actionToggleOverwrite();
217 void declareBindables();
220 } // namespace CppConsUI
222 #endif // TEXTEDIT_H
224 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: