1 /** 2 Copyright: Copyright (c) 2017-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.gui.textedit.textmodel; 7 8 public import voxelman.gui.textedit.linebuffer : LineInfo; 9 public import voxelman.container.chunkedrange; 10 public import voxelman.gui.textedit.cursor; 11 import voxelman.math; 12 import voxelman.graphics; 13 14 interface TextModel 15 { 16 bool isEditable(); 17 18 int numLines(); 19 int lastLine(); 20 ChunkedRange!char opSlice(size_t from, size_t to); 21 LineInfo lineInfo(int line); 22 23 void onCommand(EditorCommand com); 24 ref Selection selection(); 25 //ivec2 textSizeInGlyphs(); 26 } 27 28 Selection emptySelection(Cursor cur) { return Selection(cur, cur); } 29 30 struct Selection 31 { 32 Cursor start; 33 Cursor end; 34 35 /// Returns selection where start <= end 36 Selection normalized() 37 { 38 if (start.byteOffset < end.byteOffset) 39 return Selection(start, end); 40 else 41 return Selection(end, start); 42 } 43 44 bool empty() 45 { 46 return start.byteOffset == end.byteOffset; 47 } 48 } 49 50 alias TextViewSettingsRef = TextViewSettings*; 51 struct TextViewSettings 52 { 53 // visual 54 FontRef font; 55 int fontScale = 1; 56 int tabSize = 4; 57 bool monospaced = true; 58 Color4ub color = Colors.black; 59 60 ivec2 scaledGlyphSize() const { return ivec2(scaledGlyphW, scaledGlyphH); } 61 int scaledGlyphW() const { return font.metrics.advanceX * fontScale; } 62 int scaledGlyphH() const { return font.metrics.advanceY * fontScale; } 63 64 // scrolling 65 int scrollSpeedLines = 3; 66 67 this(FontRef font) 68 { 69 this.font = font; 70 } 71 } 72 73 enum EditorCommandType 74 { 75 none, // convertor function returns this if nothing matches 76 77 insert_eol, 78 insert_tab, 79 delete_left_char, 80 delete_left_word, 81 delete_left_line, 82 delete_right_char, 83 delete_right_word, 84 delete_right_line, 85 86 cut, 87 copy, 88 paste, 89 90 input, 91 92 select_all, 93 94 undo, 95 redo, 96 97 cur_move_first, 98 cur_move_right_char = cur_move_first, 99 cur_move_right_word, 100 cur_move_left_char, 101 cur_move_left_word, 102 cur_move_up_line, 103 cur_move_up_page, 104 cur_move_down_line, 105 cur_move_down_page, 106 cur_move_to_bol, 107 cur_move_to_eol, 108 cur_move_last = cur_move_to_eol, 109 } 110 111 enum EditorCommandFlags 112 { 113 extendSelection = 1, // 114 } 115 116 struct EditorCommand 117 { 118 EditorCommandType type; 119 uint flags; // set of EditorCommandFlags 120 const(char)[] inputText; // must be copied when handling command 121 122 bool extendSelection() { 123 return (flags & EditorCommandFlags.extendSelection) != 0; 124 } 125 126 MoveCommand toMoveCommand() 127 { 128 assert(type >= EditorCommandType.cur_move_first); 129 assert(type <= EditorCommandType.cur_move_last); 130 131 return cast(MoveCommand)(type - EditorCommandType.cur_move_first); 132 } 133 }