/* Copyright (c) 2013 yvt This file is part of OpenSpades. OpenSpades is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenSpades is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSpades. If not, see . */ #include "Label.as" namespace spades { namespace ui { class TextViewerModel: ListViewModel { UIManager@ manager; string[]@ lines = array(); Vector4[]@ colors = array(); Font@ font; float width; void AddLine(string text, Vector4 color) { int startPos = 0; if(font.Measure(text).x <= width) { lines.insertLast(text); colors.insertLast(color); return; } int pos = 0; int len = int(text.length); bool charMode = false; while(startPos < len) { int nextPos = pos + 1; if(charMode) { // skip to the next UTF-8 character boundary while(nextPos < len && ((text[nextPos] & 0x80) != 0) && ((text[nextPos] & 0xc0) != 0xc0)) nextPos++; } else { while(nextPos < len && text[nextPos] != 0x20) nextPos++; } if(font.Measure(text.substr(startPos, nextPos - startPos)).x > width) { if(pos == startPos) { if(charMode) { pos = nextPos; }else{ charMode = true; } continue; }else{ lines.insertLast(text.substr(startPos, pos - startPos)); colors.insertLast(color); startPos = pos; while(startPos < len && text[startPos] == 0x20) startPos++; pos = startPos; charMode = false; continue; } }else{ pos = nextPos; if(nextPos >= len) { lines.insertLast(text.substr(startPos, nextPos - startPos)); colors.insertLast(color); break; } } } } TextViewerModel(UIManager@ manager, string text, Font@ font, float width) { @this.manager = manager; @this.font = font; this.width = width; string[]@ lines = text.split("\n"); for(uint i = 0; i < lines.length; i++) AddLine(lines[i], Vector4(1.f, 1.f, 1.f, 1.f)); } int NumRows { get { return int(lines.length); } } UIElement@ CreateElement(int row) { Label i(manager); i.Text = lines[row]; i.TextColor = colors[row]; return i; } void RecycleElement(UIElement@ elem) {} } class TextViewer: ListViewBase { private string text; private TextViewerModel@ textmodel; TextViewer(UIManager@ manager) { super(manager); } /** Sets the displayed text. Ensure TextViewer.Font is not null before setting this proeprty. */ string Text { get final { return text; } set { text = value; @textmodel = TextViewerModel(Manager, text, Font, ItemWidth); @Model = textmodel; } } void AddLine(string line, bool autoscroll = false, Vector4 color = Vector4(1.f, 1.f, 1.f, 1.f)) { if(textmodel is null) { this.Text = ""; } if(autoscroll){ this.Layout(); if(this.scrollBar.Value < this.scrollBar.MaxValue) { autoscroll = false; } } textmodel.AddLine(line, color); if(autoscroll) { this.Layout(); this.ScrollToEnd(); } } } } }