001 /*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020 package org.crsh.text.ui;
021
022 import org.crsh.text.Chunk;
023 import org.crsh.text.Renderer;
024 import org.crsh.text.Style;
025 import org.crsh.text.Text;
026 import org.crsh.util.Utils;
027
028 import java.util.Iterator;
029
030 public class TextElement extends Element {
031
032 /** . */
033 final Iterable<Chunk> stream;
034
035 /** . */
036 final int minWidth;
037
038 /** . */
039 final int width;
040
041 private static int width(int width, Iterator<Chunk> stream, Text current, Integer from) {
042 while (current == null) {
043 if (stream.hasNext()) {
044 Chunk next = stream.next();
045 if (next instanceof Text) {
046 current = (Text)next;
047 from = 0;
048 }
049 } else {
050 break;
051 }
052 }
053 if (current == null) {
054 return width;
055 } else {
056 int pos = Utils.indexOf(current.getText(), from, '\n');
057 if (pos == -1) {
058 return width(width + current.getText().length() - from, stream, current, from);
059 } else {
060 return Math.max(width + pos - from, width(0, stream, null, 0));
061 }
062 }
063 }
064
065 public TextElement(Iterable<Chunk> stream, int minWidth) {
066 if (minWidth < 0) {
067 throw new IllegalArgumentException("No negative min size allowed");
068 }
069
070 // Determine width
071 int width = width(0, stream.iterator(), null, null);
072
073 //
074 this.minWidth = Math.min(width, minWidth);
075 this.stream = stream;
076 this.width = width;
077 }
078
079 public TextElement(Iterable<Chunk> stream) {
080 this(stream, 1);
081 }
082
083 public Renderer renderer() {
084 // return new LabelRenderer(this);
085 throw new UnsupportedOperationException();
086 }
087
088 @Override
089 public String toString() {
090 return "TextElement[]";
091 }
092
093 @Override
094 public TextElement style(Style.Composite style) {
095 return (TextElement)super.style(style);
096 }
097 }