From 5bb9d602f902c9ba80f786cc1358ad3f1b706c64 Mon Sep 17 00:00:00 2001 From: Martin Oberhuber Date: Thu, 20 May 2010 01:56:25 +0000 Subject: [PATCH] Bug 294468 - [terminal] When a horizontal scrollbar is visible, terminal size is missing 1 line --- .../terminal/textcanvas/GridCanvas.java | 71 ++++++++++++++----- .../terminal/textcanvas/TextCanvas.java | 47 +++++++----- .../terminal/textcanvas/TextLineRenderer.java | 5 +- .../terminal/textcanvas/VirtualCanvas.java | 37 +++++----- 4 files changed, 105 insertions(+), 55 deletions(-) diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/GridCanvas.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/GridCanvas.java index 491406f1e66..8c240973853 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/GridCanvas.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/GridCanvas.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Michael Scharf (Wind River) - initial API and implementation + * Anton Leherbauer (Wind River) - [294468] Fix scroller and text line rendering *******************************************************************************/ package org.eclipse.tm.internal.terminal.textcanvas; @@ -18,6 +19,7 @@ import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; /** * A Grid based Canvas. The canvas has rows and columns. @@ -45,20 +47,6 @@ abstract public class GridCanvas extends VirtualCanvas { } - public void setBounds(int x, int y, int width, int height) { - // adjust the height so that there are no characters cut - // Maybe it would be better to use a custom Layout... - int shiftH=0; - if(getCellHeight()!=0) - shiftH=height % getCellHeight(); - super.setBounds(x, y+shiftH, width, height-shiftH); - } - - public void setBounds(Rectangle rect) { - // just to be sure our set bounds is called! - setBounds(rect.x,rect.y,rect.width,rect.height); - } - /** template method paint. * iterates over all cells in the clipping rectangle and paints them. */ @@ -73,6 +61,9 @@ abstract public class GridCanvas extends VirtualCanvas { int colFirst=virtualXToCell(xOffset+clipping.x); if(colFirst>getCols()) colFirst=getCols(); + else if (colFirst < 0) { + colFirst = 0; + } int rowFirst=virtualYToCell(yOffset+clipping.y); // End coordinates int colLast=virtualXToCell(xOffset+clipping.x+clipping.width+fCellWidth); @@ -172,10 +163,10 @@ abstract public class GridCanvas extends VirtualCanvas { int cellX=virtualXToCell(x); int cellY=virtualYToCell(y); // End coordinates - int xE=virtualXToCell(x+fCellWidth+width-1); + int xE=virtualXToCell(x+width); // if(xE>getCols()) // xE=getCols(); - int yE=virtualYToCell(y+fCellHeight+height-1); + int yE=virtualYToCell(y+height); // if(yE>getRows()) // yE=getRows(); visibleCellRectangleChanged(cellX,cellY,xE-cellX,yE-cellY); @@ -193,5 +184,49 @@ abstract public class GridCanvas extends VirtualCanvas { protected void visibleCellRectangleChanged(int x, int y, int width, int height) { } + protected void setVirtualExtend(int width, int height) { + int cellHeight = getCellHeight(); + if (cellHeight > 0) { + height -= height % cellHeight; + } + super.setVirtualExtend(width, height); + } + + protected void setVirtualOrigin(int x, int y) { + int cellHeight = getCellHeight(); + if (cellHeight > 0) { + int remainder = y % cellHeight; + if (remainder < 0) { + y -= (cellHeight + remainder); + } else { + y -= remainder; + } + } + super.setVirtualOrigin(x, y); + } + + protected void scrollY(ScrollBar vBar) { + int vSelection = vBar.getSelection (); + Rectangle bounds = getVirtualBounds(); + int y = -vSelection; + int cellHeight = getCellHeight(); + if (cellHeight > 0) { + int remainder = y % cellHeight; + if (remainder < 0) { + y -= (cellHeight + remainder); + } else { + y -= remainder; + } + } + int deltaY = y - bounds.y; + if(deltaY!=0) { + scrollSmart(0,deltaY); + setVirtualOrigin(bounds.x, bounds.y += deltaY); + } + if (-bounds.y + getRows() * getCellHeight() >= bounds.height) { + // scrolled to bottom - need to redraw bottom area + Rectangle clientRect = getClientArea(); + redraw(0, clientRect.height - fCellHeight, clientRect.width, fCellHeight, false); + } + } } - diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java index 8326cc933a7..48f9eae2f79 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextCanvas.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ * Michael Scharf (Wind River) - [240098] The cursor should not blink when the terminal is disconnected * Uwe Stieber (Wind River) - [281328] The very first few characters might be missing in the terminal control if opened and connected programmatically * Martin Oberhuber (Wind River) - [294327] After logging in, the remote prompt is hidden + * Anton Leherbauer (Wind River) - [294468] Fix scroller and text line rendering *******************************************************************************/ package org.eclipse.tm.internal.terminal.textcanvas; @@ -66,7 +67,7 @@ public class TextCanvas extends GridCanvas { // since it allows switching the terminal viewport small/large as needed, // without destroying the backing store. For a complete solution, // Bug 196462 tracks the request for a user-defined fixed-widow-size-mode. - private int fMinColumns=20; + private int fMinColumns=80; private int fMinLines=4; private boolean fCursorEnabled; /** @@ -84,13 +85,15 @@ public class TextCanvas extends GridCanvas { repaintRange(col,line,width,height); } public void dimensionsChanged(int cols, int rows) { - setVirtualExtend(cols+getCellWidth(), rows+getCellHeight()); calculateGrid(); } public void terminalDataChanged() { if(isDisposed()) return; scrollToEnd(); + // make sure the scroll area is correct: + scrollY(getVerticalBar()); + scrollX(getHorizontalBar()); } }); // let the cursor blink if the text canvas gets the focus... @@ -206,8 +209,10 @@ public class TextCanvas extends GridCanvas { protected void onResize(boolean init) { if(fResizeListener!=null) { Rectangle bonds=getClientArea(); - int lines=bonds.height/getCellHeight(); - int columns=bonds.width/getCellWidth(); + int cellHeight = getCellHeight(); + int cellWidth = getCellWidth(); + int lines=bonds.height/cellHeight; + int columns=bonds.width/cellWidth; // when the view is minimised, its size is set to 0 // we don't sent this to the terminal! if((lines>0 && columns>0) || init) { @@ -215,15 +220,14 @@ public class TextCanvas extends GridCanvas { if(!isHorizontalBarVisble()) { setHorizontalBarVisible(true); bonds=getClientArea(); - lines=bonds.height/getCellHeight(); + lines=bonds.height/cellHeight; } columns=fMinColumns; } else if(columns>=fMinColumns && isHorizontalBarVisble()) { setHorizontalBarVisible(false); bonds=getClientArea(); - lines=bonds.height/getCellHeight(); - columns=bonds.width/getCellWidth(); - + lines=bonds.height/cellHeight; + columns=bonds.width/cellWidth; } if(lines 0) { + y = 0; + } Rectangle v=getViewRectangle(); - if(v.y!=y) { + if(v.y!=-y) { setVirtualOrigin(v.x,y); } } diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java index 9aa6ddc1290..da6adb7bbaf 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/TextLineRenderer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,6 +9,7 @@ * Michael Scharf (Wind River) - initial API and implementation * Michael Scharf (Wind River) - [205260] Terminal does not take the font from the preferences * Michael Scharf (Wind River) - [206328] Terminal does not draw correctly with proportional fonts + * Anton Leherbauer (Wind River) - [294468] Fix scroller and text line rendering *******************************************************************************/ package org.eclipse.tm.internal.terminal.textcanvas; @@ -47,7 +48,7 @@ public class TextLineRenderer implements ILinelRenderer { } public void drawLine(ITextCanvasModel model, GC gc, int line, int x, int y, int colFirst, int colLast) { if(line<0 || line>=getTerminalText().getHeight() || colFirst>=getTerminalText().getWidth() || colFirst-colLast==0) { - fillBackground(gc, x, y, getCellWidth()*(colFirst-colLast), getCellHeight()); + fillBackground(gc, x, y, getCellWidth()*(colLast-colFirst), getCellHeight()); } else { colLast=Math.min(colLast, getTerminalText().getWidth()); LineSegment[] segments=getTerminalText().getLineSegments(line, colFirst, colLast-colFirst); diff --git a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java index f89e988d856..42ced4a1930 100644 --- a/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java +++ b/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/textcanvas/VirtualCanvas.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Michael Scharf (Wind River) - initial API and implementation + * Anton Leherbauer (Wind River) - [294468] Fix scroller and text line rendering *******************************************************************************/ package org.eclipse.tm.internal.terminal.textcanvas; @@ -16,7 +17,6 @@ import org.eclipse.core.runtime.Status; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; @@ -99,9 +99,11 @@ public abstract class VirtualCanvas extends Canvas { } - private void scrollSmart(int deltaX, int deltaY) { - Rectangle rect = getBounds(); - scroll (deltaX, deltaY, 0, 0, rect.width, rect.height, false); + protected void scrollSmart(int deltaX, int deltaY) { + if (deltaX != 0 || deltaY != 0) { + Rectangle rect = getBounds(); + scroll (deltaX, deltaY, 0, 0, rect.width, rect.height, false); + } } /** @@ -155,8 +157,8 @@ public abstract class VirtualCanvas extends Canvas { return getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); } protected void paintUnoccupiedSpace(GC gc, Rectangle clipping) { - int width=fVirtualBounds.width; - int height=fVirtualBounds.height; + int width=fVirtualBounds.width + fVirtualBounds.x; + int height=fVirtualBounds.height + fVirtualBounds.y; int marginWidth = (clipping.x+clipping.width) - width; int marginHeight = (clipping.y+clipping.height) - height; if(marginWidth>0||marginHeight>0){ @@ -224,11 +226,13 @@ public abstract class VirtualCanvas extends Canvas { * @param y */ protected void setVirtualOrigin(int x, int y) { - fVirtualBounds.x=x; - fVirtualBounds.y=y; - getHorizontalBar().setSelection(-x); - getVerticalBar().setSelection(-y); - updateViewRectangle(); + if (fVirtualBounds.x != x || fVirtualBounds.y != y) { + fVirtualBounds.x=x; + fVirtualBounds.y=y; + getHorizontalBar().setSelection(-x); + getVerticalBar().setSelection(-y); + updateViewRectangle(); + } } protected Rectangle getVirtualBounds() { return cloneRectangle(fVirtualBounds); @@ -304,25 +308,24 @@ public abstract class VirtualCanvas extends Canvas { } } private void doUpdateScrollbar() { - Point size= getSize(); Rectangle clientArea= getClientArea(); ScrollBar horizontal= getHorizontalBar(); // even if setVisible was called on the scrollbar, isVisible // returns false if its parent is not visible. if(!isVisible() || horizontal.isVisible()) { horizontal.setPageIncrement(clientArea.width - horizontal.getIncrement()); - int max= fVirtualBounds.width + (size.x - clientArea.width); + int max= fVirtualBounds.width; horizontal.setMaximum(max); - horizontal.setThumb(size.x > max ? max : size.x); + horizontal.setThumb(clientArea.width); } ScrollBar vertical= getVerticalBar(); // even if setVisible was called on the scrollbar, isVisible // returns false if its parent is not visible. if(!isVisible() || vertical.isVisible()) { vertical.setPageIncrement(clientArea.height - vertical.getIncrement()); - int max= fVirtualBounds.height + (size.y - clientArea.height); + int max= fVirtualBounds.height; vertical.setMaximum(max); - vertical.setThumb(size.y > max ? max : size.y); + vertical.setThumb(clientArea.height); } } protected boolean isVertialBarVisible() {