package NET.worlds.scape; import NET.worlds.console.Console; import NET.worlds.console.DialogDisabled; import NET.worlds.console.ExposedPanel; import NET.worlds.console.WiderScrollbar; import NET.worlds.network.URL; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Frame; import java.awt.Graphics; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Point; import java.awt.Scrollbar; import java.awt.Toolkit; import java.util.Enumeration; import java.util.Vector; public class ScrollingImagePanel extends ExposedPanel implements LibraryDropTarget, DialogDisabled { private Scrollbar scrollbar = new WiderScrollbar(); private Vector items; private int cellWidth; private int cellHeight; private Font font = new Font(Console.message("ScImageFont"), 1, 12); private FontMetrics metrics = this.getFontMetrics(this.font); private int ascent = this.metrics.getAscent(); private int descent = this.metrics.getDescent(); private int textHeight = this.ascent + this.descent; private int scrollPos = 0; private ClickEventHandler handler; private ScrollingListElement downClicked; private boolean isDownClicked; private int maxScrollPos; private boolean useIcons = false; private boolean isDialogDisabled; public ScrollingImagePanel(ClickEventHandler handler, Vector icons, boolean showIcons) { this.handler = handler; this.setFont(this.font); this.setForeground(Color.black); this.setBackground(Color.lightGray); this.items = new Vector(); this.setContents(icons, false); this.setLayout(new BorderLayout()); this.add("East", this.scrollbar); this.useIcons = showIcons; } public void resetContents(Vector icons) { this.setContents(icons); } protected void add(GridBagLayout gbag, Component comp, GridBagConstraints c) { gbag.setConstraints(comp, c); this.add(comp); } @Override public boolean handleEvent(java.awt.Event e) { if (this.isDialogDisabled) { return false; } else { switch (e.id) { case 601: return this.scrollLineUp(); case 602: return this.scrollLineDown(); case 603: return this.scrollPageUp(); case 604: return this.scrollPageDown(); case 605: return this.scrollAbsolute(); default: return super.handleEvent(e); } } } @Override public void dialogDisable(boolean disable) { this.isDialogDisabled = disable; } private void setContents(Vector icons) { this.setContents(icons, true); } private void setContents(Vector icons, boolean showIt) { this.items.removeAllElements(); int count = icons.size(); for (int i = 0; i < count; i++) { this.addIcon((Iconic)icons.elementAt(i), false); } if (showIt) { this.recalc(this.size().width, this.size().height); this.repaint(); } } private void addIcon(Iconic icon, boolean showIt) { String title = icon.getIconCaption(); int titleWidth = title != null ? this.metrics.stringWidth(title) : 0; URL name = icon.getIconURL(); Image image = null; if (name != null) { MediaTracker tracker = new MediaTracker(this); image = Toolkit.getDefaultToolkit().getImage(name.unalias()); tracker.addImage(image, 0); try { tracker.waitForID(0); } catch (InterruptedException var9) { } if (tracker.isErrorID(0)) { image = null; System.out.println("Error loading " + name); } } this.items.addElement(new ScrollingListElement(image, title, titleWidth)); } private void findCellSize() { this.cellWidth = 30; this.cellHeight = 0; if (this.useIcons) { this.cellHeight = 30; } Enumeration e = this.items.elements(); while (e.hasMoreElements()) { ScrollingListElement item = (ScrollingListElement)e.nextElement(); this.cellWidth = Math.max(this.cellWidth, item.titleWidth); if (this.useIcons && item.image != null) { this.cellWidth = Math.max(this.cellWidth, item.image.getWidth(this)); this.cellHeight = Math.max(this.cellHeight, item.image.getHeight(this)); } } this.cellWidth += 2; this.cellHeight = this.cellHeight + this.textHeight + 2; } @Override public void reshape(int x, int y, int w, int h) { super.reshape(x, y, w, h); this.recalc(w, h); this.repaint(); } private void recalc(int w, int h) { this.findCellSize(); this.scrollPos = 0; this.scrollbar.setValue(this.scrollPos); int pass = 0; while (pass < 2) { int scrollbarWidth = 0; if (pass == 1) { scrollbarWidth = this.scrollbar.size().width; } int lines = 0; if (this.cellWidth != 0) { int imagesPerLine = Math.max(1, (w - scrollbarWidth) / this.cellWidth); lines = (this.items.size() + imagesPerLine - 1) / imagesPerLine * this.cellHeight; } if (lines > h) { if (pass == 0) { if (!this.scrollbar.isVisible()) { this.scrollbar.show(); this.validate(); } pass++; continue; } this.maxScrollPos = lines; this.scrollbar.setValues(this.scrollPos, h, 0, lines); this.scrollbar.setPageIncrement(h); this.scrollbar.setLineIncrement(this.cellHeight); break; } if (this.scrollbar.isVisible()) { this.scrollbar.hide(); this.validate(); } break; } this.clearHitTest(); } private void clearHitTest() { int count = this.items.size(); for (int i = 0; i < count; i++) { ScrollingListElement e = (ScrollingListElement)this.items.elementAt(i); e.x = e.y = -1; } } private ScrollingListElement findCell(int x, int y) { int count = this.items.size(); for (int i = 0; i < count; i++) { ScrollingListElement e = (ScrollingListElement)this.items.elementAt(i); if (x >= 0 && y >= 0 && x < e.x && y < e.y) { return e; } } return null; } private void buttonAction(boolean down) { if (this.isDownClicked != down) { this.isDownClicked = down; Graphics g = this.getGraphics(); this.drawCell(g, this.downClicked, this.isDownClicked); g.dispose(); } } private Component findComponent(Point p) { Point screenLoc = this.getLocationOnScreen(); Container cur = null; for (Container tmp = this.getParent(); !(tmp instanceof Frame); tmp = tmp.getParent()) { cur = tmp; } Point parentCoords = cur.getLocationOnScreen(); p.x = p.x + screenLoc.x - parentCoords.x; p.y = p.y + screenLoc.y - parentCoords.y; Component found = cur; while (true) { Component c = found.locate(p.x, p.y); if (c == found || c == null) { return found; } Point tmp = c.location(); p.x = p.x - tmp.x; p.y = p.y - tmp.y; found = c; } } @Override public boolean mouseUp(java.awt.Event event, int x, int y) { if (this.downClicked != null) { Point p = new Point(x, y); this.buttonAction(false); this.handler.clickEvent(this.findComponent(p), p, 2); this.downClicked = null; return true; } else { return false; } } public int itemAt(Point p) { ScrollingListElement cell = this.findCell(p.x, p.y); return cell != null ? this.items.indexOf(cell) : -1; } @Override public boolean mouseDown(java.awt.Event event, int x, int y) { if (this.downClicked == null && (this.downClicked = this.findCell(x, y)) != null) { this.buttonAction(true); int flags = 1; if (event.metaDown()) { flags |= 4; } this.handler.clickEvent(this, new Point(x, y), flags); return true; } else { return false; } } @Override public boolean mouseDrag(java.awt.Event event, int x, int y) { if (this.downClicked != null) { Point p = new Point(x, y); this.handler.clickEvent(this.findComponent(p), p, 8); return true; } else { return false; } } private void drawCell(Graphics g, ScrollingListElement e, boolean depressed) { int x = e.x - this.cellWidth; int y = e.y - this.cellHeight; int imageBoxHeight = this.cellHeight - this.textHeight; int yTextOffset = imageBoxHeight + this.ascent; Color normColor = g.getColor(); g.setColor(this.getBackground()); g.draw3DRect(x, y, this.cellWidth - 1, this.cellHeight - 1, !depressed); g.setColor(normColor); if (this.useIcons && e.image != null) { int imageWidth = e.image.getWidth(this); int imageHeight = e.image.getHeight(this); g.drawImage(e.image, x + (this.cellWidth - imageWidth) / 2, y + (imageBoxHeight - imageHeight) / 2, null); } if (e.title != null) { g.drawString(e.title, x + (this.cellWidth - e.titleWidth) / 2, y + yTextOffset); } } @Override public void paint(Graphics g) { Color normColor = g.getColor(); super.paint(g); g.setColor(normColor); this.clearHitTest(); int width = this.size().width; int height = this.size().height; int x = 0; int y = -this.scrollbar.getValue(); int count = this.items.size(); for (int i = 0; i < count; i++) { if (y + this.cellHeight > 0) { ScrollingListElement e = (ScrollingListElement)this.items.elementAt(i); e.x = x + this.cellWidth; e.y = y + this.cellHeight; this.drawCell(g, e, false); } x += this.cellWidth; if (x + this.cellWidth > width) { x = 0; if ((y += this.cellHeight) >= height) { break; } } } } public boolean isIconsVisible() { return this.useIcons; } public void setIconsVisible(boolean showIcons) { this.useIcons = showIcons; this.recalc(this.size().width, this.size().height); this.repaint(); } private boolean setScrollValue(int value) { this.scrollPos = Math.max(this.scrollbar.getMinimum(), value); this.scrollPos = Math.min(this.maxScrollPos, this.scrollPos); this.scrollbar.setValue(this.scrollPos); this.repaint(); return true; } private boolean scrollLineUp() { return this.setScrollValue(this.scrollPos - this.scrollbar.getLineIncrement()); } private boolean scrollLineDown() { return this.setScrollValue(this.scrollPos + this.scrollbar.getLineIncrement()); } private boolean scrollPageUp() { return this.setScrollValue(this.scrollPos - this.scrollbar.getPageIncrement()); } private boolean scrollPageDown() { return this.setScrollValue(this.scrollPos + this.scrollbar.getPageIncrement()); } private boolean scrollAbsolute() { return this.setScrollValue(this.scrollbar.getValue()); } }