/*******************************************************************************
* Copyright (c) 2003-2005, 2013 Till Zoppke.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Till Zoppke - initial API and implementation
******************************************************************************/
/*
* Created on 25.10.2003
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package eniac.data.view.parent;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import eniac.data.CableManager;
import eniac.data.model.EData;
import eniac.data.type.EType;
import eniac.data.view.EPanel;
import eniac.skin.Descriptor;
import eniac.skin.Skin;
import eniac.util.EProperties;
import eniac.util.Status;
import eniac.util.StatusListener;
import eniac.util.StringConverter;
/**
* @author zoppke
*
* To change the template for this generated type comment go to Window -
* Preferences - Java - Code Generation - Code and Comments
*/
public class ConfigPanel extends ParentPanel implements Scrollable, StatusListener {
/*
* ============================== fields ===================================
*/
// cableManager tracking all cables
private CableManager _cableManager = new CableManager();
// current lod for detaied view
private int _lod;
// temporary Point for computation speed up
private Point _p = new Point();
/*
* =============================== lifecycle ===============================
*/
public void init() {
// super call for initiating the guiGarten and adding children
super.init();
// init cables
_cableManager.init();
// add as propertychangelistener to status to receive simulation time
// updates
Status.HIGHLIGHT_PULSE.addListener(this);
Status.ZOOMED_HEIGHT.addListener(this);
}
public void dispose() {
super.dispose();
Status.HIGHLIGHT_PULSE.removeListener(this);
Status.ZOOMED_HEIGHT.removeListener(this);
removeAll();
_cableManager = null;
}
/*
* ============================== methods ==================================
*/
public int getLod() {
return _lod;
}
public CableManager getCableManager() {
return _cableManager;
}
/*
* =========================== gui methods =================================
*/
/**
* Computes the preferred size of this configPanel. The preferred width is
* always a multiple of the numberOfUnits. So every unit will have the same
* width.
*/
public Dimension getPreferredSize() {
// get current configuration height
int height = (int) Status.ZOOMED_HEIGHT.getValue();
// set lod
Skin skin = (Skin) Status.SKIN.getValue();
_lod = skin.getLodByHeight(height);
// get descriptor for this configuration
EType type = _data.getType();
int lod = skin.getLodByHeight(height);
Descriptor descriptor = type.getDescriptor(lod);
// if no descriptor, return a default dimension
if (descriptor == null) {
return new Dimension(0, 0);
}
// otherwise compute wanted width by the rule of three and return
int width = height * descriptor.getWidth() / descriptor.getHeight();
return new Dimension(width, height);
}
public void doLayout() {
// compute bounds for all children
Rectangle[] rectangles = getRectangles(_lod, getWidth(), getHeight());
// set bounds for all of the children
EPanel[] children = getChildren();
for (int i = 0; i < children.length; ++i) {
Rectangle r = rectangles[i];
children[i].setBounds(r.x, r.y, r.width, r.height);
}
}
public void paintAsIcon(Graphics g, int x, int y, int w, int h, int lod) {
// paint background and children, then paint cables
super.paintAsIcon(g, x, y, w, h, lod);
_cableManager.paintOnBufferedImage(g, lod);
}
public void paintChildren(Graphics g) {
// paint children by supercall, then paint cables
super.paintChildren(g);
_cableManager.paintOnConfigPanel(g, _lod);
}
/*
* ========================== scrollable methods ===========================
*/
public boolean getScrollableTracksViewportHeight() {
return false;
}
public boolean getScrollableTracksViewportWidth() {
return false;
}
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 30;
}
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 30;
}
/*
* ============================ event listening ============================
*/
@Override
public void statusChanged(Status status, Object newValue) {
if (status == Status.HIGHLIGHT_PULSE) {
// highlight mode changed by user action.
// Because this won't happen too often don't be cheap:
// just repaint.
update(_data, EData.REPAINT);
}
else if (status == Status.ZOOMED_HEIGHT) {
// zoom changed.
// init with default values
double scrollPercentageX = 0.5;
double scrollPercentageY = 0.5;
// get values
Dimension preferredSize = getPreferredSize();
JViewport viewPort = ((JViewport) getParent());
Dimension viewPortSize = viewPort.getSize();
Point currentPosition = viewPort.getViewPosition();
// check, if preferred width > viewport width
int widthDiff = preferredSize.width - viewPortSize.width;
if (widthDiff > 0) {
// compute relative scroll position x
scrollPercentageX = currentPosition.x / (double) (getSize().width - viewPortSize.width);
}
// check, if preferred height > viewport height
int heightDiff = preferredSize.height - viewPortSize.height;
if (heightDiff > 0) {
// compute relative scroll position y
scrollPercentageY = currentPosition.y / (double) (getSize().height - viewPortSize.height);
}
// default _p to current position
_p = getLocation();
// check, if need to update x location
if (widthDiff > 0) {
// we cannot see the complete configuration in x direction
_p.x = (int) (widthDiff * scrollPercentageX);
}
// check, if need to update x location
if (heightDiff > 0) {
// we cannot see the complete configuration in x direction
_p.y = (int) (heightDiff * scrollPercentageY);
}
setSize(preferredSize);
viewPort.setViewPosition(_p);
revalidate();
}
}
/*
* ========================== static methods ===============================
*/
public static float heightToPercentage() {
// determine zoom and lod
int basicHeight = StringConverter.toInt(EProperties.getInstance().getProperty("BASIC_CONFIGURATION_HEIGHT"));
int zoomedHeight = (int) Status.ZOOMED_HEIGHT.getValue();
return (float) zoomedHeight / (float) basicHeight;
}
}