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.LineReader; 023 import org.crsh.text.LineRenderer; 024 import org.crsh.text.RenderAppendable; 025 026 import java.util.ArrayList; 027 import java.util.Iterator; 028 import java.util.LinkedList; 029 import java.util.List; 030 031 class TreeLineRenderer extends LineRenderer { 032 033 /** . */ 034 private final LineRenderer value; 035 036 /** . */ 037 private final List<LineRenderer> children; 038 039 TreeLineRenderer(TreeElement tree) { 040 041 ArrayList<LineRenderer> children = new ArrayList<LineRenderer>(tree.children.size()); 042 for (Element child : tree.children) { 043 children.add(child.renderer()); 044 } 045 046 // 047 this.children = children; 048 this.value = tree.value != null ? tree.value.renderer() : null; 049 } 050 051 @Override 052 public int getActualWidth() { 053 int width = value != null ? value.getActualWidth() : 0; 054 for (LineRenderer child : children) { 055 width = Math.max(width, 2 + child.getActualWidth()); 056 } 057 return width; 058 } 059 060 @Override 061 public int getMinWidth() { 062 int width = value != null ? value.getMinWidth() : 0; 063 for (LineRenderer child : children) { 064 width = Math.max(width, 2 + child.getMinWidth()); 065 } 066 return width; 067 } 068 069 @Override 070 public int getActualHeight(int width) { 071 throw new UnsupportedOperationException("Implement me"); 072 } 073 074 @Override 075 public int getMinHeight(int width) { 076 throw new UnsupportedOperationException("Implement me"); 077 } 078 079 @Override 080 public LineReader reader(final int width) { 081 082 083 final LinkedList<LineReader> readers = new LinkedList<LineReader>(); 084 for (LineRenderer child : children) { 085 readers.addLast(child.reader(width - 2)); 086 } 087 088 // 089 return new LineReader() { 090 091 /** . */ 092 LineReader value = TreeLineRenderer.this.value != null ? TreeLineRenderer.this.value.reader(width) : null; 093 094 /** . */ 095 boolean node = true; 096 097 public boolean hasLine() { 098 if (value != null) { 099 if (value.hasLine()) { 100 return true; 101 } else { 102 value = null; 103 } 104 } 105 while (readers.size() > 0) { 106 if (readers.peekFirst().hasLine()) { 107 return true; 108 } else { 109 readers.removeFirst(); 110 node = true; 111 } 112 } 113 return false; 114 } 115 116 public void renderLine(RenderAppendable to) { 117 if (value != null) { 118 if (value.hasLine()) { 119 value.renderLine(to); 120 } else { 121 value = null; 122 } 123 } 124 if (value == null) { 125 while (readers.size() > 0) { 126 LineReader first = readers.peekFirst(); 127 if (first.hasLine()) { 128 if (node) { 129 to.append("+-"); 130 node = false; 131 } else { 132 Iterator<LineReader> i = readers.descendingIterator(); 133 boolean rest = false; 134 while (i.hasNext()) { 135 LineReader renderer = i.next(); 136 if (i.hasNext()) { 137 if (renderer.hasLine()) { 138 rest = true; 139 break; 140 } 141 } 142 } 143 if (rest) { 144 to.append("| "); 145 } else { 146 to.append(" "); 147 } 148 } 149 first.renderLine(to); 150 break; 151 } 152 } 153 } 154 } 155 }; 156 } 157 }