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.messagelog; 7 8 import voxelman.math; 9 import voxelman.container.chunkedbuffer; 10 import voxelman.gui.textedit.cursor; 11 import voxelman.gui.textedit.textmodel; 12 import voxelman.gui.textedit.linebuffer; 13 import voxelman.gui.textedit.texteditor; 14 15 class MessageLogTextModel : TextModel 16 { 17 MessageLog* text; 18 19 this(MessageLog* text) { this.text = text; } 20 bool isEditable() { return false; } 21 22 int numLines() { return text.lines.numLines; } 23 int lastLine() { return text.lines.lastLine; } 24 ChunkedRange!char opSlice(size_t from, size_t to) { return (*text)[from..to]; } 25 LineInfo lineInfo(int line) { return text.lineInfo(line); } 26 27 void onCommand(EditorCommand com) { text.onCommand(com); } 28 void replaceSelection(const(char)[] str) {} 29 ref Selection selection() { return text.selection; } 30 //ivec2 textSizeInGlyphs() { return ivec2(0,0); } 31 void moveSelectionCursor(MoveCommand com, bool extendSelection) 32 { 33 text.selection.end = text.moveCursor(text.selection.end, com); 34 if (!extendSelection) text.selection.start = text.selection.end; 35 } 36 } 37 38 struct MessageLog 39 { 40 import std.format : formattedWrite; 41 private ChunkedBuffer!(char, 4096) textData; 42 private LineInfoBuffer lines; 43 Selection selection; 44 mixin ReadHelpers!(); 45 46 this(string text) 47 { 48 textData.put(text); 49 lines.calc(text); 50 } 51 52 ulong length() { return textData.length; } 53 alias opDollar = length; 54 LineInfo lineInfo(int line) { return lines.lineInfo(line); } 55 56 ChunkedRange!char opSlice(size_t from, size_t to) 57 { 58 return textData[from..to].toChunkedRange; 59 } 60 61 void onCommand(EditorCommand com) 62 { 63 switch(com.type) 64 { 65 case EditorCommandType.copy: 66 copySelection(); 67 break; 68 case EditorCommandType.select_all: 69 selection = Selection(Cursor(0,0), Cursor(lines.textEnd, lines.lastLine)); 70 break; 71 default: 72 break; 73 } 74 } 75 76 void clear() 77 { 78 lines.clear(); 79 textData.clear(); 80 selection = Selection(); 81 } 82 83 void put(in char[] str) 84 { 85 textData.put(str); 86 lines.onPaste(Cursor(lines.textEnd, lines.lastLine), str); 87 } 88 89 void putf(Args...)(const(char)[] fmt, Args args) 90 { 91 formattedWrite(&this, fmt, args); 92 } 93 94 void putfln(Args...)(const(char)[] fmt, Args args) 95 { 96 formattedWrite(&this, fmt, args); 97 put("\n"); 98 } 99 100 void putln(const(char)[] str) 101 { 102 put(str); 103 put("\n"); 104 } 105 } 106 107 unittest 108 { 109 import std.algorithm : equal; 110 import std.stdio; 111 MessageLog log; 112 log.putln("test1"); 113 log.putln("test2"); 114 log.putln("test3"); 115 116 auto from = log.lineInfo(1).startOffset; 117 auto to = log.lineInfo(2).endOffset; 118 auto text = log[from..to].byItem; 119 120 assert(text.equal("test2\ntest3")); 121 }