Fix so that the vnc viewer properly sizes on resizes. Using the LWScrollPane from the vncviewer.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@2543 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/src/com/tightvnc/rfbplayer/LWScrollPane.java b/java/src/com/tightvnc/rfbplayer/LWScrollPane.java
new file mode 100644
index 0000000..c9b4960
--- /dev/null
+++ b/java/src/com/tightvnc/rfbplayer/LWScrollPane.java
@@ -0,0 +1,260 @@
+
+package com.HorizonLive.RfbPlayer;
+
+import java.awt.*;
+import java.awt.event.*;
+
+class LWScrollPane extends Container implements AdjustmentListener {
+
+  /** position info */
+  private Point scrollPosition = new Point(0, 0);
+
+  /** panel to hold component to scroll */
+  private Panel innerPanel = new Panel() {
+
+    public void update(Graphics g) {
+      if (needClear) {
+        super.update(g);
+        needClear = false;
+      } else
+        this.paint(g);
+    }
+
+  };
+
+  /** component to display */
+  private Component containedComp;
+
+  /** layout info */
+  private GridBagLayout gb;
+  private GridBagConstraints gbc;
+
+  /** scroll bars */
+  private Scrollbar xScroller;
+  private Scrollbar yScroller;
+
+  /** flags indicating which scollbars are visible */
+  private boolean showingXScroll = false;
+  private boolean showingYScroll = false;
+
+  /** flag indicating when innerpanel needs to repaint background */
+  private boolean needClear = false;
+
+  /** dimensions for our preferred size */
+  private int width = 0;
+  private int height = 0;
+
+  /** c'tor for a new scroll pane */
+  public LWScrollPane() {
+    // create scroll bars
+    xScroller = new Scrollbar(Scrollbar.HORIZONTAL) {
+
+      public boolean isFocusable() {
+        return false;
+      }
+
+    };
+    yScroller = new Scrollbar(Scrollbar.VERTICAL) {
+
+      public boolean isFocusable() {
+        return false;
+      }
+
+    };
+    xScroller.addAdjustmentListener(this);
+    yScroller.addAdjustmentListener(this);
+
+    // layout info 
+    gb = new GridBagLayout();
+    gbc = new GridBagConstraints();
+    setLayout(gb);
+    setBackground(Color.white);
+
+    // added inner panel
+    //innerPanel.setBackground(Color.blue);
+    gbc.fill = GridBagConstraints.BOTH;
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+    gbc.weightx = 100;
+    gbc.weighty = 100;
+    gb.setConstraints(innerPanel, gbc);
+    add(innerPanel);
+    innerPanel.setLayout(null);
+  }
+  /*
+  public void update(Graphics g) {
+  paint(g);
+  }
+   */
+  /*
+  public void paint(Graphics g) {
+  super.paint(g);
+  }
+   */
+
+  /**
+   * Provided to allow the containing frame to resize.
+   * OS X JVM 1.3 would not allow a frame to be made
+   * smaller without overriding getMinimumSize.
+   */
+  public Dimension getMinimumSize() {
+    return new Dimension(0, 0);
+  }
+
+  public Dimension getPreferredSize() {
+    return new Dimension(width, height);
+  }
+
+  public void setSize(int width, int height) {
+    this.width = width;
+    this.height = height;
+    super.setSize(width, height);
+  }
+
+  public void setSize(Dimension d) {
+    setSize(d.width, d.height);
+  }
+
+  /** 
+   * Force component to clear itself before repainting. 
+   * Primarily useful if the contained component shrinks
+   * without the scroll pane reducing in size.
+   */
+  public void clearAndRepaint() {
+    needClear = true;
+    innerPanel.repaint();
+  }
+
+  /** Add the component to be scrolled by scroll pane */
+  void addComp(Component comp) {
+    containedComp = comp;
+    innerPanel.add(containedComp);
+  }
+
+  /** 
+   * Set the point of the component to display in the
+   * upper left corner of the viewport.
+   */
+  void setScrollPosition(int x, int y) {
+    Dimension vps = getViewportSize();
+    Dimension ccs = containedComp.getPreferredSize();
+
+    // skip entirely if component smaller than viewer
+    if (ccs.width <= vps.width && ccs.height <= vps.height)
+      return;
+
+    // don't scroll too far left or up 
+    if (x < 0)
+      x = 0;
+    if (y < 0)
+      y = 0;
+
+    // don't scroll too far right or down 
+    if (ccs.width <= vps.width)
+      x = 0;
+    else if (x > (ccs.width - vps.width))
+      x = ccs.width - vps.width;
+    if (ccs.height <= vps.height)
+      y = 0;
+    else if (y > (ccs.height - vps.height))
+      y = ccs.height - vps.height;
+
+    scrollPosition = new Point(x, y);
+    containedComp.setLocation(-scrollPosition.x, -scrollPosition.y);
+    xScroller.setValue(scrollPosition.x);
+    yScroller.setValue(scrollPosition.y);
+  }
+
+  /** Returns the point at the upper left corner of viewport */
+  Point getScrollPosition() {
+    return new Point(scrollPosition);
+  }
+
+  /** Return the dimensions of the viewport */
+  public Dimension getViewportSize() {
+    int vpW, vpH;
+    Dimension size = getSize();
+    vpW = size.width;
+    vpH = size.height;
+    if (showingYScroll)
+      vpW -= yScroller.getSize().width;
+    if (showingXScroll)
+      vpH -= xScroller.getSize().height;
+
+    return new Dimension(vpW, vpH);
+  }
+
+  /** 
+   * Ensure that the scroll pane is properly arranged after
+   * a component is added, the pane is resized, etc.
+   */
+  public void doLayout() {
+    /** Add scroll bars as necessary */
+    boolean needX = false, needY = false;
+    Dimension innerSize = containedComp.getPreferredSize();
+    Dimension scrollDimension = getSize();
+
+    if (innerSize.width > scrollDimension.width)
+      needX = true;
+    if (innerSize.height > scrollDimension.height)
+      needY = true;
+
+    showingXScroll = false;
+    showingYScroll = false;
+    remove(yScroller);
+    remove(xScroller);
+
+    if (needY) {
+      gbc.gridy = 0;
+      gbc.gridx = 1;
+      gbc.weightx = 0;
+      gb.setConstraints(yScroller, gbc);
+      add(yScroller);
+      showingYScroll = true;
+    }
+
+    if (needX) {
+      gbc.gridy = 1;
+      gbc.gridx = 0;
+      gbc.weightx = 100;
+      gbc.weighty = 0;
+      gb.setConstraints(xScroller, gbc);
+      add(xScroller);
+      showingXScroll = true;
+    }
+
+    /* set scroll bar values */
+    int vpW, vpH;
+    vpW = scrollDimension.width;
+    vpH = scrollDimension.height;
+    if (showingYScroll)
+      vpW -= yScroller.getSize().width;
+    if (showingXScroll)
+      vpH -= xScroller.getSize().height;
+    yScroller.setValues(0, vpH, 0, innerSize.height);
+    xScroller.setValues(0, vpW, 0, innerSize.width);
+
+    containedComp.setLocation(0, 0);
+    super.doLayout();
+  }
+
+  /**
+   * Adjustment listener method for receiving callbacks
+   * from scroll actions. 
+   *	
+   * @param e the AdjustmentEvent
+   * @return void
+   */
+  public void adjustmentValueChanged(AdjustmentEvent e) {
+    Point p = containedComp.getLocation();
+    if (e.getAdjustable() == xScroller) {
+      p.x = -e.getValue();
+      scrollPosition.x = e.getValue();
+    } else {
+      p.y = -e.getValue();
+      scrollPosition.y = e.getValue();
+    }
+    containedComp.setLocation(p);
+  }
+
+}