00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.gui.log;
00023
00024 import java.util.Collection;
00025 import org.jetbrains.annotations.NotNull;
00026
00034 public class RenderState {
00035
00039 @NotNull
00040 private final Object sync = new Object();
00041
00045 private int height = 1;
00046
00051 private int topIndex = 0;
00052
00060 private int topOffset = -height;
00061
00065 private int scrollPos = 0;
00066
00070 private boolean canScrollUp = false;
00071
00075 private boolean canScrollDown = false;
00076
00080 private boolean mustRepaint = true;
00081
00087 public void setHeight(@NotNull final Buffer buffer, final int h) {
00088 final int bufferHeight = buffer.getTotalHeight();
00089 synchronized (sync) {
00090 final int oldHeight = height;
00091 height = h;
00092 if (bufferHeight <= height) {
00093 scrollPos = 0;
00094 topIndex = 0;
00095 topOffset = 0;
00096 canScrollUp = false;
00097 canScrollDown = false;
00098 } else if (topOffset < 0) {
00099 scrollToBottom(buffer);
00100 } else if (scrollPos > bufferHeight-height || scrollPos == bufferHeight-oldHeight) {
00101 scrollToBottom(buffer);
00102 }
00103 }
00104 }
00105
00110 public void linesAdded(@NotNull final Buffer buffer) {
00111 synchronized (sync) {
00112 if (topOffset < 0) {
00113 scrollToBottom(buffer);
00114 } else if (!canScrollDown) {
00115 scrollToBottom(buffer);
00116 mustRepaint = true;
00117 } else {
00118 mustRepaint = true;
00119 }
00120 }
00121 }
00122
00127 public void linesReplaced(@NotNull final Buffer buffer) {
00128 synchronized (sync) {
00129 if (topOffset < 0) {
00130 scrollToBottom(buffer);
00131 } else if (!canScrollDown) {
00132 scrollToBottom(buffer);
00133 }
00134 mustRepaint = true;
00135 }
00136 }
00137
00143 public void linesRemoved(@NotNull final Buffer buffer, @NotNull final Collection<Line> lines) {
00144 final int bufferHeight = buffer.getTotalHeight();
00145 synchronized (sync) {
00146 if (bufferHeight <= height) {
00147 scrollPos = 0;
00148 topIndex = 0;
00149 topOffset = 0;
00150 canScrollUp = false;
00151 canScrollDown = false;
00152 mustRepaint = true;
00153 } else {
00154 for (final Line line : lines) {
00155 scrollPos -= line.getHeight();
00156 }
00157 topIndex -= lines.size();
00158 if (scrollPos < 0) {
00159 scrollPos = 0;
00160 topIndex = 0;
00161 topOffset = 0;
00162 canScrollUp = false;
00163 mustRepaint = true;
00164 } else {
00165 assert topIndex >= 0;
00166
00167 }
00168
00169 }
00170 }
00171 }
00172
00177 public int getTopIndex() {
00178 synchronized (sync) {
00179 return topIndex;
00180 }
00181 }
00182
00187 public int getTopOffset() {
00188 synchronized (sync) {
00189 return topOffset;
00190 }
00191 }
00192
00197 public int getScrollPos() {
00198 synchronized (sync) {
00199 return scrollPos;
00200 }
00201 }
00202
00207 public boolean canScrollUp() {
00208 synchronized (sync) {
00209 return canScrollUp;
00210 }
00211 }
00212
00217 public boolean canScrollDown() {
00218 synchronized (sync) {
00219 return canScrollDown;
00220 }
00221 }
00222
00230 public boolean mustRepaint() {
00231 synchronized (sync) {
00232 final boolean result = mustRepaint;
00233 mustRepaint = false;
00234 return result;
00235 }
00236 }
00237
00243 public void scrollTo(@NotNull final Buffer buffer, final int y) {
00244 final int bufferHeight = buffer.getTotalHeight();
00245 synchronized (sync) {
00246 if (bufferHeight > height) {
00247 scrollPos = Math.max(Math.min(y, bufferHeight-height), 0);
00248 topIndex = 0;
00249 int yPos = scrollPos;
00250 while (yPos > 0) {
00251 final int lineHeight = buffer.getLine(topIndex).getHeight();
00252 if (yPos < lineHeight) {
00253 break;
00254 }
00255
00256 yPos -= lineHeight;
00257 topIndex++;
00258 }
00259 assert yPos >= 0;
00260 topOffset = yPos;
00261 canScrollUp = topIndex > 0 || topOffset > 0;
00262 canScrollDown = y+height < bufferHeight;
00263
00264
00265 }
00266 }
00267 }
00268
00273 public void scrollToBottom(@NotNull final Buffer buffer) {
00274 final int bufferHeight = buffer.getTotalHeight();
00275 synchronized (sync) {
00276 if (bufferHeight <= height) {
00277 scrollPos = 0;
00278 topIndex = 0;
00279 topOffset = 0;
00280 canScrollUp = false;
00281 canScrollDown = false;
00282 } else {
00283 scrollPos = Math.max(bufferHeight-height, 0);
00284 topIndex = buffer.size();
00285 int y = height;
00286 while (y > 0) {
00287 topIndex--;
00288 assert topIndex >= 0;
00289 y -= buffer.getLine(topIndex).getHeight();
00290 }
00291 topOffset = -y;
00292 canScrollUp = topIndex > 0 || topOffset > 0;
00293 canScrollDown = false;
00294 }
00295 }
00296 }
00297
00298 }