Package hidb2.gui.util

Source Code of hidb2.gui.util.ImageCanvas

/**
* This file is part of HIDB2.
*
* HIDB2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HIDB2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser Public License
* along with HIDB2.  If not, see <http://www.gnu.org/licenses/>.
*/
package hidb2.gui.util;

import hidb2.gui.ressources.RscMan;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;

/**
* Canvas specialization for Image display with scroll bars and zoom actions.
*
*/
public class ImageCanvas extends Canvas
  {

  public final static int OPTIMAL_ZOOM = -1;

  public final static int SCROLLBAR_WIDTH = 17;

  private int _minZoom = 10;

  private int _maxZoom = 400;

  private int _defaultWidth = 512;

  private int _defaultHeight = 512;

  private ScrollBar _vBar;

  private ScrollBar _hBar;

  private ImageData _imgData = null;

  private Image _displayedImage = null;

  private Point _origin = new Point(0, 0);

  /** Zoom Factor in percent for the displayed Image. if set to OPTIMAL_ZOOM, the image size fits the dialog */
  private int _zoomFactor = OPTIMAL_ZOOM;

  private String _curPath = null;

  private boolean _sizeComputed = false;

  /**
   * Ugly preference setter to have an roughtly independant object.
   * @param minZoom
   * @param maxZoom
   * @param DefaultWidth
   * @param DefaultHeight
   */
  public void setPref(int minZoom, int maxZoom, int DefaultWidth, int DefaultHeight)
    {
    _minZoom = minZoom;

    _maxZoom = maxZoom;

    _defaultWidth = DefaultWidth;

    _defaultHeight = DefaultHeight;
    }

  /**
   * Create a new image canvas for image browsing/zooming.
   *
   * @param parent
   * @param style
   */
  public ImageCanvas(Composite parent, int style)
    {
    super(parent, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);

    _hBar = getHorizontalBar();
    _hBar.addListener(SWT.Selection, new Listener()
      {
        public void handleEvent(Event e)
          {
          int hSelection = _hBar.getSelection();
          int destX = -hSelection - _origin.x;
          Rectangle rect = _displayedImage.getBounds();
          scroll(destX, 0, 0, 0, rect.width, rect.height, false);
          _origin.x = -hSelection;
          }
      });

    _vBar = getVerticalBar();
    _vBar.addListener(SWT.Selection, new Listener()
      {
        public void handleEvent(Event e)
          {
          int vSelection = _vBar.getSelection();
          int destY = -vSelection - _origin.y;
          Rectangle rect = _displayedImage.getBounds();
          scroll(0, destY, 0, 0, rect.width, rect.height, false);
          _origin.y = -vSelection;
          }
      });

    addListener(SWT.Resize, new Listener()
      {
        public void handleEvent(Event e)
          {
          if (_displayedImage != null)
            {
            computeScroll();

            redraw();
            }
          }
      });

    addListener(SWT.Paint, new Listener()
      {
        public void handleEvent(Event e)
          {
          if (_displayedImage != null)
            {
            GC gc = e.gc;
            gc.drawImage(_displayedImage, _origin.x, _origin.y);
            Rectangle rect = _displayedImage.getBounds();
            Rectangle client = getClientArea();
            int marginWidth = client.width - rect.width;
            if (marginWidth > 0)
              {
              gc.fillRectangle(rect.width, 0, marginWidth, client.height);
              }
            int marginHeight = client.height - rect.height;
            if (marginHeight > 0)
              {
              gc.fillRectangle(0, rect.height, client.width, marginHeight);
              }
            }
          }
      });

    }

  private Menu initMenu()
    {
    // Setup a popup menu (if needed)
    Menu menu = getMenu();
    if (menu == null)
      {
      menu = new Menu(this); // Implicit : SWT.POP_UP
      setMenu(menu);
      }

    return menu;
    }

  /**
   * Add a menu item at the end of the current popup menu.
   * The popup menu is created if needed.
   * @param label Label of the menu item
   * @param s Callback
   */
  public void addMenuItem(String label, SelectionListener s)
    {
    Menu menu = initMenu();

    MenuItem item = new MenuItem(menu, SWT.PUSH);
    item.setText(label);

    item.addSelectionListener(s);
    }

  public void initZoomMenu()
    {
    Menu menu = initMenu();

    MenuItem item3 = new MenuItem(menu, SWT.CASCADE);
    item3.setText("Zoom");
    Menu subMenu = new Menu(menu);
    item3.setMenu(subMenu);
    MenuItem subItem1 = new MenuItem(subMenu, SWT.PUSH);
    subItem1.setText("Optimal");
    subItem1.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
          {
          setZoom(OPTIMAL_ZOOM);
          }
      });

    MenuItem subItem2 = new MenuItem(subMenu, SWT.PUSH);
    subItem2.setText("100%");
    subItem2.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
          {
          setZoom(100);
          }
      });

    MenuItem subItem3 = new MenuItem(subMenu, SWT.PUSH);
    subItem3.setText("200%");
    subItem3.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
          {
          setZoom(200);
          }
      });

    MenuItem subItem4 = new MenuItem(subMenu, SWT.PUSH);
    subItem4.setText("300%");
    subItem4.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
          {
          setZoom(300);
          }
      });

    MenuItem subItem5 = new MenuItem(subMenu, SWT.PUSH);
    subItem5.setText("400%");
    subItem5.addSelectionListener(new SelectionAdapter()
      {
        @Override
        public void widgetSelected(SelectionEvent e)
          {
          setZoom(400);
          }
      });
    }

  /**
   * Manage Zoom bounds and apply it. (generates a redraw on the canvas)
   * @param zoomLevel
   */
  public void setZoom(int zoomLevel)
    {
    _zoomFactor = (zoomLevel == OPTIMAL_ZOOM) ? OPTIMAL_ZOOM : (zoomLevel < _minZoom) ? _minZoom
        : ((zoomLevel > _maxZoom) ? _maxZoom : zoomLevel);
    zoom();
    redraw();
    }

  public int getZoom()
    {
    return _zoomFactor;
    }

  public void freeImage()
    {
    // Release Image (if needed)
    if (_displayedImage != null)
      {
      _displayedImage.dispose();
      _displayedImage = null;

      _imgData = null;
      }
    }

  public void setImagePath(String path)
    {
    _curPath = path;

    freeImage();

    // Load the image
    try
      {
      _imgData = new ImageData(path);
      }

    catch (SWTException swex)
      {
      // Manage bad image format or missing image file
      _imgData = RscMan.getImage(RscMan.IN_NOFILE).getImageData();
      }

    zoom();
    }

  public void setImage(Image img)
    {
    _curPath = "--internal--";

    freeImage();

    // Load the image
    _imgData = img.getImageData();

    zoom();
    }

  public String getImagePath()
    {
    return _curPath;
    }

  private void zoom()
    {
    ImageData isrcData = null;

    // Take into account the current zoom factor
    if (_zoomFactor == 100)
      {
      isrcData = _imgData;
      }
    else
      {
      int width = _imgData.width;
      int height = _imgData.height;

      int zoom = _zoomFactor;

      if (_zoomFactor == OPTIMAL_ZOOM)
        {
        Rectangle client = _sizeComputed ? getClientArea() : new Rectangle(0, 0, _defaultWidth, _defaultHeight);

        zoom = Math.min((100 * client.width) / width, (100 * client.height) / height);
        }

      int nWidth = (width * zoom) / 100;
      int nHeight = (height * zoom) / 100;

      isrcData = _imgData.scaledTo(nWidth, nHeight);
      }

    // Dispose OS Ressources
    if (_displayedImage != null)
      {
      _displayedImage.dispose();
      _displayedImage = null;
      }

    _displayedImage = new Image(getParent().getDisplay(), isrcData);

    computeScroll();
    }

  private void computeScroll()
    {
    Rectangle rect = _displayedImage.getBounds();
    Rectangle client = getClientArea();
    _hBar.setMaximum(rect.width);
    _vBar.setMaximum(rect.height);
    _hBar.setThumb(Math.min(rect.width, client.width));
    _vBar.setThumb(Math.min(rect.height, client.height));
    int hPage = rect.width - client.width;
    int vPage = rect.height - client.height;
    int hSelection = _hBar.getSelection();
    int vSelection = _vBar.getSelection();
    if (hSelection >= hPage)
      {
      if (hPage <= 0)
        hSelection = 0;
      _origin.x = -hSelection;
      }
    if (vSelection >= vPage)
      {
      if (vPage <= 0)
        vSelection = 0;
      _origin.y = -vSelection;
      }
    }

  /**
   * Convient function to adapt the size of the (toplevel or dialog) shell to the Canvas area.
   *
   */
  public void computeDialogSize(Shell dlg)
    {
    Rectangle winRect = dlg.getDisplay().getBounds();

    Rectangle rect = _displayedImage.getBounds();

    // On WinXP : scrollbar are 17 pixels wide
    int width = Math.min(winRect.width, Math.max(_defaultWidth, rect.width + _vBar.getSize().x + SCROLLBAR_WIDTH));

    int height = Math.min(winRect.height, Math.max(_defaultHeight, rect.height + _hBar.getSize().y));

    dlg.setSize(width, height);

    dlg.setLocation((winRect.width - width) / 2, (winRect.height - height) / 2);

    _sizeComputed = true;
    }

  @Override
  public void dispose()
    {
    freeImage();
    super.dispose();
    }
  }
TOP

Related Classes of hidb2.gui.util.ImageCanvas

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.