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 }