Line data Source code
1 : #ifndef TEXTEDIT_H_
2 : #define TEXTEDIT_H_
3 :
4 : class EditLine final
5 : {
6 : public:
7 : enum { Chunk_Size = 256 };
8 :
9 : char *text;
10 : int len;
11 :
12 0 : EditLine() : text(nullptr), len(0), maxlen(0) {}
13 0 : EditLine(const char *init) : text(nullptr), len(0), maxlen(0)
14 : {
15 0 : set(init);
16 0 : }
17 :
18 : /**
19 : * @brief Returns whether the line's text has any content.
20 : *
21 : * @return true if the line has at least one character
22 : */
23 : bool empty() const;
24 : void clear();
25 : void set(const char *str, int slen = -1);
26 : void prepend(const char *str);
27 : void append(const char *str);
28 : bool read(std::fstream& f, int chop = -1);
29 : void del(int start, int count);
30 : void chop(int newlen);
31 : void insert(char *str, int start, int count = 0);
32 : void combinelines(std::vector<EditLine> &src);
33 : private:
34 : bool grow(int total, const char *fmt = "", ...);
35 :
36 : int maxlen;
37 :
38 : };
39 :
40 : enum
41 : {
42 : Editor_Focused = 1,
43 : Editor_Used,
44 : Editor_Forever
45 : };
46 :
47 : class Editor final
48 : {
49 : public:
50 : int mode; //editor mode - 1= keep while focused, 2= keep while used in gui, 3= keep forever (i.e. until mode changes)
51 : bool active, rendered;
52 : std::string name;
53 : const char *filename;
54 :
55 : int maxx, maxy; // maxy=-1 if unlimited lines, 1 if single line editor
56 :
57 : bool linewrap;
58 : int pixelwidth; // required for up/down/hit/draw/bounds
59 : int pixelheight; // -1 for variable sized, i.e. from bounds()
60 :
61 : std::vector<EditLine> lines; // MUST always contain at least one line!
62 :
63 0 : Editor(std::string name, int mode, const char *initval) :
64 0 : mode(mode), active(true), rendered(false), name(name), filename(nullptr),
65 0 : maxx(-1), maxy(-1), linewrap(false), pixelwidth(-1), pixelheight(-1),
66 0 : cx(0), cy(0), mx(-1), my(-1), scrolly(0)
67 : {
68 : //printf("editor %08x '%s'\n", this, name);
69 0 : lines.emplace_back();
70 0 : lines.back().set(initval ? initval : "");
71 0 : }
72 :
73 0 : ~Editor()
74 : {
75 : //printf("~editor %08x '%s'\n", this, name);
76 0 : delete[] filename;
77 :
78 0 : filename = nullptr;
79 0 : clear(nullptr);
80 0 : }
81 :
82 : /**
83 : * @brief Retuns if there are no lines added to this editor.
84 : *
85 : * There will be a single blank line with contents "" created by the ctor,
86 : * so the presence of this line will not cause this to return "true"
87 : *
88 : * @return true if any line other than the ctor's "" has been added
89 : */
90 : bool empty() const;
91 : void clear(const char *init = "");
92 : void init(const char *inittext);
93 : void updateheight();
94 : void setfile(const char *fname);
95 : void load();
96 :
97 : /**
98 : * @brief Writes contents of this editor to a file.
99 : *
100 : * The file path/name to write to is located in the `filename` field. If
101 : * this string is null, silently fails and does nothing; otherwise, attempts
102 : * to write to the file at `filename`.
103 : *
104 : * Silently fails if std::fstream cannot write to the file indicated.
105 : */
106 : void save();
107 :
108 : /**
109 : * @brief Sets the selection marker.
110 : *
111 : * If enable is false, sets mx to -1; otherwise sets it to the current cursor
112 : * x position. mx is the value checked to determine whether a marker exists.
113 : *
114 : * Sets my, marker y position, to the current cursor position.
115 : *
116 : * @param enable whether to set disabled (-1) flag, or position of cursor
117 : */
118 : void mark(bool enable);
119 :
120 : /**
121 : * @brief Selects all text in the editor.
122 : *
123 : * Sets the marker position to the beginning of the text, and the cursor
124 : * to the end. This selects all of the text.
125 : */
126 : void selectall();
127 : bool region();
128 : EditLine ¤tline();
129 : void copyselectionto(Editor *b);
130 :
131 : /**
132 : * @brief Returns heap-allocated char array containing whole contents of this editor.
133 : *
134 : * Creates a char array with size equal to the sum of all lines' values,
135 : * then copies the contents of those lines to the return array. Separates
136 : * each line with a `\n` newline character.
137 : *
138 : * @return char array of this editor's contents
139 : */
140 : char *tostring() const;
141 : char *selectiontostring();
142 : void insert(const char *s);
143 : void insertallfrom(const Editor *b);
144 :
145 : /**
146 : * @brief Moves the editor cursor position up one line.
147 : *
148 : * Sets the cursor y position (cy) to one line higher (reduces value of
149 : * cy). This can cause an underflow to negative values if cy is already
150 : * less than or equal to zero.
151 : */
152 : void scrollup();
153 :
154 : /**
155 : * @brief Moves the editor cursor position down one line.
156 : *
157 : * Sets the cursor y position (cy) to one line lower (increases value of
158 : * cy). This can cause an overflow to values above maxy if cy is already
159 : * greater than or equal to maxy.
160 : */
161 : void scrolldown();
162 : void key(int code);
163 : void input(const char *str, int len);
164 : void hit(int hitx, int hity, bool dragged);
165 : void draw(int x, int y, int color);
166 : private:
167 : int cx, cy; // cursor position - ensured to be valid after a region() or currentline()
168 : int mx, my; // selection mark, mx=-1 if following cursor - avoid direct access, instead use region()
169 : int scrolly; // vertical scroll offset
170 :
171 : void removelines(int start, int count);
172 : bool region(int &sx, int &sy, int &ex, int &ey);
173 : bool del(); // removes the current selection (if any)
174 : void insert(char ch);
175 : bool readback(std::fstream& file);
176 : };
177 :
178 : extern void readyeditors();
179 : extern void flusheditors();
180 : extern Editor *useeditor(std::string name, int mode, bool focus, const char *initval = nullptr);
181 :
182 : #endif
|