PEBL 2.2
Psychology Experiment Building Language - Cross-platform psychological experiment development system
TextEditor.h
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <vector>
5#include <array>
6#include <memory>
7#include <unordered_set>
8#include <unordered_map>
9#include <map>
10#include <regex>
11#include "imgui.h"
12
14{
15public:
41
42 enum class SelectionMode
43 {
44 Normal,
45 Word,
46 Line
47 };
48
50 {
51 int mLine;
53 std::string mCondition;
54
56 : mLine(-1)
57 , mEnabled(false)
58 {}
59 };
60
61 // Represents a character coordinate from the user's point of view,
62 // i. e. consider an uniform grid (assuming fixed-width font) on the
63 // screen as it is rendered, and each cell has its own coordinate, starting from 0.
64 // Tabs are counted as [1..mTabSize] count empty spaces, depending on
65 // how many space is necessary to reach the next tab stop.
66 // For example, coordinate (1, 5) represents the character 'B' in a line "\tABC", when mTabSize = 4,
67 // because it is rendered as " ABC" on the screen.
69 {
72 Coordinates(int aLine, int aColumn) : mLine(aLine), mColumn(aColumn)
73 {
74 assert(aLine >= 0);
75 assert(aColumn >= 0);
76 }
77 static Coordinates Invalid() { static Coordinates invalid(-1, -1); return invalid; }
78
79 bool operator ==(const Coordinates& o) const
80 {
81 return
82 mLine == o.mLine &&
83 mColumn == o.mColumn;
84 }
85
86 bool operator !=(const Coordinates& o) const
87 {
88 return
89 mLine != o.mLine ||
90 mColumn != o.mColumn;
91 }
92
93 bool operator <(const Coordinates& o) const
94 {
95 if (mLine != o.mLine)
96 return mLine < o.mLine;
97 return mColumn < o.mColumn;
98 }
99
100 bool operator >(const Coordinates& o) const
101 {
102 if (mLine != o.mLine)
103 return mLine > o.mLine;
104 return mColumn > o.mColumn;
105 }
106
107 bool operator <=(const Coordinates& o) const
108 {
109 if (mLine != o.mLine)
110 return mLine < o.mLine;
111 return mColumn <= o.mColumn;
112 }
113
114 bool operator >=(const Coordinates& o) const
115 {
116 if (mLine != o.mLine)
117 return mLine > o.mLine;
118 return mColumn >= o.mColumn;
119 }
120 };
121
123 {
125 std::string mDeclaration;
126 };
127
128 typedef std::string String;
129 typedef std::unordered_map<std::string, Identifier> Identifiers;
130 typedef std::unordered_set<std::string> Keywords;
131 typedef std::map<int, std::string> ErrorMarkers;
132 typedef std::unordered_set<int> Breakpoints;
133 typedef std::array<ImU32, (unsigned)PaletteIndex::Max> Palette;
134 typedef uint8_t Char;
135
136 struct Glyph
137 {
140 bool mComment : 1;
143
144 Glyph(Char aChar, PaletteIndex aColorIndex) : mChar(aChar), mColorIndex(aColorIndex),
145 mComment(false), mMultiLineComment(false), mPreprocessor(false) {}
146 };
147
148 typedef std::vector<Glyph> Line;
149 typedef std::vector<Line> Lines;
150
152 {
153 typedef std::pair<std::string, PaletteIndex> TokenRegexString;
154 typedef std::vector<TokenRegexString> TokenRegexStrings;
155 typedef bool(*TokenizeCallback)(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end, PaletteIndex & paletteIndex);
156
157 std::string mName;
164
166
168
170
172 : mPreprocChar('#'), mAutoIndentation(true), mTokenize(nullptr), mCaseSensitive(true)
173 {
174 }
175
176 static const LanguageDefinition& CPlusPlus();
177 static const LanguageDefinition& HLSL();
178 static const LanguageDefinition& GLSL();
179 static const LanguageDefinition& C();
180 static const LanguageDefinition& SQL();
181 static const LanguageDefinition& AngelScript();
182 static const LanguageDefinition& Lua();
183 };
184
185 TextEditor();
186 ~TextEditor();
187
188 void SetLanguageDefinition(const LanguageDefinition& aLanguageDef);
189 const LanguageDefinition& GetLanguageDefinition() const { return mLanguageDefinition; }
190
191 const Palette& GetPalette() const { return mPaletteBase; }
192 void SetPalette(const Palette& aValue);
193
194 void SetErrorMarkers(const ErrorMarkers& aMarkers) { mErrorMarkers = aMarkers; }
195 void SetBreakpoints(const Breakpoints& aMarkers) { mBreakpoints = aMarkers; }
196
197 void Render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false);
198 void SetText(const std::string& aText);
199 std::string GetText() const;
200
201 void SetTextLines(const std::vector<std::string>& aLines);
202 std::vector<std::string> GetTextLines() const;
203
204 std::string GetSelectedText() const;
205 std::string GetCurrentLineText()const;
206
207 int GetTotalLines() const { return (int)mLines.size(); }
208 bool IsOverwrite() const { return mOverwrite; }
209
210 void SetReadOnly(bool aValue);
211 bool IsReadOnly() const { return mReadOnly; }
212 bool IsTextChanged() const { return mTextChanged; }
213 bool IsCursorPositionChanged() const { return mCursorPositionChanged; }
214
215 bool IsColorizerEnabled() const { return mColorizerEnabled; }
216 void SetColorizerEnable(bool aValue);
217
218 Coordinates GetCursorPosition() const { return GetActualCursorCoordinates(); }
219 void SetCursorPosition(const Coordinates& aPosition);
220
221 inline void SetHandleMouseInputs (bool aValue){ mHandleMouseInputs = aValue;}
222 inline bool IsHandleMouseInputsEnabled() const { return mHandleKeyboardInputs; }
223
224 inline void SetHandleKeyboardInputs (bool aValue){ mHandleKeyboardInputs = aValue;}
225 inline bool IsHandleKeyboardInputsEnabled() const { return mHandleKeyboardInputs; }
226
227 inline void SetImGuiChildIgnored (bool aValue){ mIgnoreImGuiChild = aValue;}
228 inline bool IsImGuiChildIgnored() const { return mIgnoreImGuiChild; }
229
230 inline void SetShowWhitespaces(bool aValue) { mShowWhitespaces = aValue; }
231 inline bool IsShowingWhitespaces() const { return mShowWhitespaces; }
232
233 void SetTabSize(int aValue);
234 inline int GetTabSize() const { return mTabSize; }
235
236 void InsertText(const std::string& aValue);
237 void InsertText(const char* aValue);
238
239 void MoveUp(int aAmount = 1, bool aSelect = false);
240 void MoveDown(int aAmount = 1, bool aSelect = false);
241 void MoveLeft(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
242 void MoveRight(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
243 void MoveTop(bool aSelect = false);
244 void MoveBottom(bool aSelect = false);
245 void MoveHome(bool aSelect = false);
246 void MoveEnd(bool aSelect = false);
247
248 void SetSelectionStart(const Coordinates& aPosition);
249 void SetSelectionEnd(const Coordinates& aPosition);
250 void SetSelection(const Coordinates& aStart, const Coordinates& aEnd, SelectionMode aMode = SelectionMode::Normal);
252 void SelectAll();
253 bool HasSelection() const;
254
255 void Copy();
256 void Cut();
257 void Paste();
258 void Delete();
259
260 bool CanUndo() const;
261 bool CanRedo() const;
262 void Undo(int aSteps = 1);
263 void Redo(int aSteps = 1);
264
265 static const Palette& GetDarkPalette();
266 static const Palette& GetLightPalette();
267 static const Palette& GetRetroBluePalette();
268
269private:
270 typedef std::vector<std::pair<std::regex, PaletteIndex>> RegexList;
271
272 struct EditorState
273 {
274 Coordinates mSelectionStart;
275 Coordinates mSelectionEnd;
276 Coordinates mCursorPosition;
277 };
278
279 class UndoRecord
280 {
281 public:
282 UndoRecord() {}
283 ~UndoRecord() {}
284
285 UndoRecord(
286 const std::string& aAdded,
287 const TextEditor::Coordinates aAddedStart,
288 const TextEditor::Coordinates aAddedEnd,
289
290 const std::string& aRemoved,
291 const TextEditor::Coordinates aRemovedStart,
292 const TextEditor::Coordinates aRemovedEnd,
293
294 TextEditor::EditorState& aBefore,
295 TextEditor::EditorState& aAfter);
296
297 void Undo(TextEditor* aEditor);
298 void Redo(TextEditor* aEditor);
299
300 std::string mAdded;
301 Coordinates mAddedStart;
302 Coordinates mAddedEnd;
303
304 std::string mRemoved;
305 Coordinates mRemovedStart;
306 Coordinates mRemovedEnd;
307
308 EditorState mBefore;
309 EditorState mAfter;
310 };
311
312 typedef std::vector<UndoRecord> UndoBuffer;
313
314 void ProcessInputs();
315 void Colorize(int aFromLine = 0, int aCount = -1);
316 void ColorizeRange(int aFromLine = 0, int aToLine = 0);
317 void ColorizeInternal();
318 float TextDistanceToLineStart(const Coordinates& aFrom) const;
319 void EnsureCursorVisible();
320 int GetPageSize() const;
321 std::string GetText(const Coordinates& aStart, const Coordinates& aEnd) const;
322 Coordinates GetActualCursorCoordinates() const;
323 Coordinates SanitizeCoordinates(const Coordinates& aValue) const;
324 void Advance(Coordinates& aCoordinates) const;
325 void DeleteRange(const Coordinates& aStart, const Coordinates& aEnd);
326 int InsertTextAt(Coordinates& aWhere, const char* aValue);
327 void AddUndo(UndoRecord& aValue);
328 Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const;
329 Coordinates FindWordStart(const Coordinates& aFrom) const;
330 Coordinates FindWordEnd(const Coordinates& aFrom) const;
331 Coordinates FindNextWord(const Coordinates& aFrom) const;
332 int GetCharacterIndex(const Coordinates& aCoordinates) const;
333 int GetCharacterColumn(int aLine, int aIndex) const;
334 int GetLineCharacterCount(int aLine) const;
335 int GetLineMaxColumn(int aLine) const;
336 bool IsOnWordBoundary(const Coordinates& aAt) const;
337 void RemoveLine(int aStart, int aEnd);
338 void RemoveLine(int aIndex);
339 Line& InsertLine(int aIndex);
340 void EnterCharacter(ImWchar aChar, bool aShift);
341 void Backspace();
342 void DeleteSelection();
343 std::string GetWordUnderCursor() const;
344 std::string GetWordAt(const Coordinates& aCoords) const;
345 ImU32 GetGlyphColor(const Glyph& aGlyph) const;
346
347 void HandleKeyboardInputs();
348 void HandleMouseInputs();
349 void Render();
350
351 float mLineSpacing;
352 Lines mLines;
353 EditorState mState;
354 UndoBuffer mUndoBuffer;
355 int mUndoIndex;
356
357 int mTabSize;
358 bool mOverwrite;
359 bool mReadOnly;
360 bool mWithinRender;
361 bool mScrollToCursor;
362 bool mScrollToTop;
363 bool mTextChanged;
364 bool mColorizerEnabled;
365 float mTextStart; // position (in pixels) where a code line starts relative to the left of the TextEditor.
366 int mLeftMargin;
367 bool mCursorPositionChanged;
368 int mColorRangeMin, mColorRangeMax;
369 SelectionMode mSelectionMode;
370 bool mHandleKeyboardInputs;
371 bool mHandleMouseInputs;
372 bool mIgnoreImGuiChild;
373 bool mShowWhitespaces;
374
375 Palette mPaletteBase;
376 Palette mPalette;
377 LanguageDefinition mLanguageDefinition;
378 RegexList mRegexList;
379
380 bool mCheckComments;
381 Breakpoints mBreakpoints;
382 ErrorMarkers mErrorMarkers;
383 ImVec2 mCharAdvance;
384 Coordinates mInteractiveStart, mInteractiveEnd;
385 std::string mLineBuffer;
386 uint64_t mStartTime;
387
388 float mLastClick;
389};
void MoveBottom(bool aSelect=false)
int GetTabSize() const
Definition TextEditor.h:234
void InsertText(const std::string &aValue)
std::unordered_set< std::string > Keywords
Definition TextEditor.h:130
bool IsCursorPositionChanged() const
Definition TextEditor.h:213
bool IsShowingWhitespaces() const
Definition TextEditor.h:231
std::vector< std::string > GetTextLines() const
std::vector< Line > Lines
Definition TextEditor.h:149
void SelectWordUnderCursor()
static const Palette & GetLightPalette()
void MoveLeft(int aAmount=1, bool aSelect=false, bool aWordMode=false)
void SetColorizerEnable(bool aValue)
void MoveHome(bool aSelect=false)
void SetSelectionEnd(const Coordinates &aPosition)
static const Palette & GetDarkPalette()
void MoveEnd(bool aSelect=false)
static const Palette & GetRetroBluePalette()
Coordinates GetCursorPosition() const
Definition TextEditor.h:218
void SetShowWhitespaces(bool aValue)
Definition TextEditor.h:230
bool HasSelection() const
bool IsTextChanged() const
Definition TextEditor.h:212
std::unordered_map< std::string, Identifier > Identifiers
Definition TextEditor.h:129
void SetReadOnly(bool aValue)
std::string GetText() const
bool IsReadOnly() const
Definition TextEditor.h:211
void SetSelectionStart(const Coordinates &aPosition)
void MoveTop(bool aSelect=false)
int GetTotalLines() const
Definition TextEditor.h:207
void SetHandleKeyboardInputs(bool aValue)
Definition TextEditor.h:224
bool IsOverwrite() const
Definition TextEditor.h:208
std::string GetCurrentLineText() const
bool IsHandleMouseInputsEnabled() const
Definition TextEditor.h:222
bool IsColorizerEnabled() const
Definition TextEditor.h:215
const Palette & GetPalette() const
Definition TextEditor.h:191
void MoveUp(int aAmount=1, bool aSelect=false)
std::vector< Glyph > Line
Definition TextEditor.h:148
void Render(const char *aTitle, const ImVec2 &aSize=ImVec2(), bool aBorder=false)
void Undo(int aSteps=1)
void SetPalette(const Palette &aValue)
std::map< int, std::string > ErrorMarkers
Definition TextEditor.h:131
void SetImGuiChildIgnored(bool aValue)
Definition TextEditor.h:227
void SetBreakpoints(const Breakpoints &aMarkers)
Definition TextEditor.h:195
void SetText(const std::string &aText)
std::string String
Definition TextEditor.h:128
void SetTextLines(const std::vector< std::string > &aLines)
void SelectAll()
bool IsImGuiChildIgnored() const
Definition TextEditor.h:228
void MoveDown(int aAmount=1, bool aSelect=false)
void SetErrorMarkers(const ErrorMarkers &aMarkers)
Definition TextEditor.h:194
void Redo(int aSteps=1)
const LanguageDefinition & GetLanguageDefinition() const
Definition TextEditor.h:189
bool CanRedo() const
void SetCursorPosition(const Coordinates &aPosition)
std::unordered_set< int > Breakpoints
Definition TextEditor.h:132
std::string GetSelectedText() const
void SetTabSize(int aValue)
void SetHandleMouseInputs(bool aValue)
Definition TextEditor.h:221
std::array< ImU32,(unsigned) PaletteIndex::Max > Palette
Definition TextEditor.h:133
uint8_t Char
Definition TextEditor.h:134
bool IsHandleKeyboardInputsEnabled() const
Definition TextEditor.h:225
bool CanUndo() const
void SetSelection(const Coordinates &aStart, const Coordinates &aEnd, SelectionMode aMode=SelectionMode::Normal)
void SetLanguageDefinition(const LanguageDefinition &aLanguageDef)
void MoveRight(int aAmount=1, bool aSelect=false, bool aWordMode=false)
std::string mCondition
Definition TextEditor.h:53
bool operator<=(const Coordinates &o) const
Definition TextEditor.h:107
static Coordinates Invalid()
Definition TextEditor.h:77
bool operator==(const Coordinates &o) const
Definition TextEditor.h:79
bool operator<(const Coordinates &o) const
Definition TextEditor.h:93
bool operator>(const Coordinates &o) const
Definition TextEditor.h:100
Coordinates(int aLine, int aColumn)
Definition TextEditor.h:72
bool operator>=(const Coordinates &o) const
Definition TextEditor.h:114
bool operator!=(const Coordinates &o) const
Definition TextEditor.h:86
PaletteIndex mColorIndex
Definition TextEditor.h:139
Glyph(Char aChar, PaletteIndex aColorIndex)
Definition TextEditor.h:144
std::string mDeclaration
Definition TextEditor.h:125
static const LanguageDefinition & SQL()
TokenRegexStrings mTokenRegexStrings
Definition TextEditor.h:167
static const LanguageDefinition & Lua()
static const LanguageDefinition & C()
static const LanguageDefinition & GLSL()
bool(* TokenizeCallback)(const char *in_begin, const char *in_end, const char *&out_begin, const char *&out_end, PaletteIndex &paletteIndex)
Definition TextEditor.h:155
std::vector< TokenRegexString > TokenRegexStrings
Definition TextEditor.h:154
static const LanguageDefinition & AngelScript()
static const LanguageDefinition & CPlusPlus()
std::pair< std::string, PaletteIndex > TokenRegexString
Definition TextEditor.h:153
static const LanguageDefinition & HLSL()