diff options
Diffstat (limited to 'NET/worlds/scape/ScrollingImagePanel.java')
| -rw-r--r-- | NET/worlds/scape/ScrollingImagePanel.java | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/NET/worlds/scape/ScrollingImagePanel.java b/NET/worlds/scape/ScrollingImagePanel.java new file mode 100644 index 0000000..31bb498 --- /dev/null +++ b/NET/worlds/scape/ScrollingImagePanel.java @@ -0,0 +1,398 @@ +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()); + } +} |