package NET.worlds.console; import NET.worlds.scape.FrameEvent; import java.awt.Container; import java.awt.Dimension; import java.awt.Event; import java.awt.Graphics; import java.awt.PopupMenu; import java.awt.Rectangle; import java.awt.event.MouseEvent; public class ImageButtons extends ImageCanvas implements FramePart, DialogDisabled { private static final long serialVersionUID = -1495360044843592740L; protected static final int BLANK = 0; protected static final int NORMAL = 1; protected static final int CURSED = 2; protected static final int DOWN = 3; private static final int TITLE = 0; private static final int BUTTON = 1; private int width; private int height; private Dimension ghostImageDimension; protected Rectangle[] buttons; private int[] types; private boolean background = false; private int cursedButton = -1; private int clickedButton = -1; private boolean clickedButtonDown; private ImageButtonsCallback handler; private ImageButtonsCallback downUpHandler; private PopupMenu menu; private boolean isDialogDisabled; private void initEvents() { this.enableEvents(16L); this.enableEvents(32L); } protected ImageButtons() { this.buttons = new Rectangle[0]; this.initEvents(); } public ImageButtons(String imageName, int buttonWidth, int buttonHeight, ImageButtonsCallback handler) { this(imageName, buttonWidth, intToInts(buttonHeight), handler); } public ImageButtons(String imageName, Rectangle[] buttonRects, ImageButtonsCallback handler) { super(imageName); this.handler = handler; this.background = true; this.setHotspots(buttonRects); this.initEvents(); } public ImageButtons(String imageName, int buttonWidth, int[] buttonHeights, ImageButtonsCallback handler) { super(imageName); this.handler = handler; this.buttons = new Rectangle[buttonHeights.length]; this.types = new int[buttonHeights.length]; int y = 0; for (int i = 0; i < buttonHeights.length; i++) { int h = buttonHeights[i]; int rh; if (h > 0) { rh = h; this.types[i] = 1; } else { rh = -h; this.types[i] = 0; } this.buttons[i] = new Rectangle(0, y, buttonWidth, rh); y += rh; } this.ghostImageDimension = new Dimension(buttonWidth * 4, buttonHeights[0]); this.initEvents(); } public void setHandler(ImageButtonsCallback handler) { this.handler = handler; } public void setDownUpHandler(ImageButtonsCallback handler) { this.downUpHandler = handler; } protected void setBackground(boolean background) { this.background = background; } protected void setWidth(int width) { this.width = width; } protected void setHeight(int height) { this.height = height; } protected synchronized void setHotspots(Rectangle[] buttonRects) { this.buttons = new Rectangle[buttonRects.length]; this.types = new int[buttonRects.length]; for (int i = 0; i < buttonRects.length; i++) { this.types[i] = 1; this.buttons[i] = new Rectangle(buttonRects[i]); } this.cursedButton = -1; this.clickedButton = -1; this.clickedButtonDown = false; } @Override public synchronized void paint(Graphics g) { g.clipRect(0, 0, this.width, this.height); if (this.background && this.image_ != null) { g.drawImage(this.image_, -1 * this.width, 0, null); } for (int i = 0; i < this.buttons.length; i++) { int state = 1; if (i == this.cursedButton) { state = 2; } if (i == this.clickedButton) { state = this.clickedButtonDown ? 3 : 1; } this.drawButton(g, i, state); } } @Override public Dimension preferredSize() { Dimension d = super.preferredSize(); if (d.width == 0 && d.height == 0 && this.ghostImageDimension != null) { d = this.ghostImageDimension; } return new Dimension(this.width = d.width / 4, this.height = d.height); } @Override public Dimension minimumSize() { return this.preferredSize(); } @Override public void processMouseMotionEvent(MouseEvent e) { if (!this.isDialogDisabled) { switch (e.getID()) { case 503: case 506: this.buttonAction(e.getX(), e.getY(), e.getID()); case 504: case 505: } } super.processMouseEvent(e); } @Override public void processMouseEvent(MouseEvent e) { if (!this.isDialogDisabled) { switch (e.getID()) { case 501: case 502: case 504: case 505: this.buttonAction(e.getX(), e.getY(), e.getID()); case 503: } } super.processMouseEvent(e); } @Override public boolean mouseMove(Event e, int x, int y) { return this.buttonAction(x, y, 503); } @Override public boolean mouseDown(Event e, int x, int y) { return (e.modifiers & 12) != 0 ? false : this.buttonAction(x, y, 501); } @Override public boolean mouseUp(Event e, int x, int y) { return (e.modifiers & 12) != 0 ? false : this.buttonAction(x, y, 502); } @Override public boolean mouseDrag(Event e, int x, int y) { return this.buttonAction(x, y, 506); } @Override public boolean mouseEnter(Event e, int x, int y) { return this.buttonAction(x, y, 504); } @Override public boolean mouseExit(Event e, int x, int y) { return this.buttonAction(x, y, 505); } @Override public boolean handleEvent(Event event) { return this.isDialogDisabled ? false : super.handleEvent(event); } protected Graphics drawButton(Graphics g, int button, int state) { if (button != -1) { Rectangle r = this.buttons[button]; if (this.image_ != null && (g != null || (g = this.getGraphics()) != null)) { Graphics g1 = g.create(r.x, r.y, r.width, r.height); g1.drawImage(this.image_, -state * this.width - r.x, -r.y, null); g1.dispose(); } } return g; } private synchronized boolean buttonAction(int x, int y, int action) { return this.buttonAction(this.locateButton(x, y), action); } private int locateButton(int x, int y) { for (int i = 0; i < this.buttons.length; i++) { if (this.types[i] == 1 && this.buttons[i].inside(x, y)) { return i; } } return -1; } public void drawFirstButton(int state) { if (this.buttons.length > 0) { Graphics g = this.drawButton(null, 0, state); if (g != null) { g.dispose(); } } } public void drawNormal() { this.drawFirstButton(1); } public void drawCursed() { this.drawFirstButton(2); } public void drawDown() { this.drawFirstButton(3); } boolean buttonAction(int button, int action) { Graphics g = null; if (action != 503 && action != 504) { if (action == 505) { if (this.cursedButton != -1) { g = this.drawButton(g, this.cursedButton, 1); this.cursedButton = -1; } if (this.downUpHandler == null && this.clickedButton != -1 && this.clickedButtonDown) { g = this.drawButton(g, this.clickedButton, 1); this.clickedButtonDown = false; } } else if (action == 501) { if (this.clickedButton != -1) { g = this.drawButton(g, this.clickedButton, 1); if (this.downUpHandler != null) { this.downUpHandler.imageButtonsCallback(this, -1); } this.clickedButtonDown = false; } if (this.cursedButton != -1) { g = this.drawButton(g, this.cursedButton, 1); this.cursedButton = -1; } if ((this.clickedButton = button) != -1) { g = this.drawButton(g, this.clickedButton, 3); this.clickedButtonDown = true; if (this.downUpHandler != null) { this.downUpHandler.imageButtonsCallback(this, button); } } } else if (action == 506) { if (this.downUpHandler == null && this.clickedButton != -1) { if (this.clickedButtonDown) { if (button != this.clickedButton) { g = this.drawButton(g, this.clickedButton, 1); this.clickedButtonDown = false; } } else if (button == this.clickedButton) { g = this.drawButton(g, this.clickedButton, 3); this.clickedButtonDown = true; } } } else if (action == 502) { this.cursedButton = button; if (this.cursedButton != -1) { g = this.drawButton(g, this.cursedButton, 2); } if (this.clickedButtonDown) { if (this.cursedButton != this.clickedButton) { g = this.drawButton(g, this.clickedButton, 1); } Object ret = this.handler.imageButtonsCallback(this, this.clickedButton); if (ret instanceof PopupMenu && this.clickedButton != -1) { if (this.menu != null) { this.remove(this.menu); } this.add(this.menu = (PopupMenu)ret); this.menu.show(this, this.buttons[this.clickedButton].x, this.buttons[this.clickedButton].y + this.buttons[this.clickedButton].height); } if (this.downUpHandler != null && this.downUpHandler.imageButtonsCallback(this, -1) != null) { this.cursedButton = -1; } this.clickedButtonDown = false; this.clickedButton = -1; } } } else { if (button != this.cursedButton) { g = this.drawButton(g, this.cursedButton, 1); g = this.drawButton(g, this.cursedButton = button, 2); } if (this.clickedButton != -1 && this.clickedButton != button && this.downUpHandler == null) { g = this.drawButton(g, this.clickedButton, 1); this.clickedButtonDown = false; } } if (g != null) { g.dispose(); } return true; } public static int[] intToInts(int value) { return new int[]{value}; } @Override public void activate(Console c, Container f, Console prev) { } @Override public void deactivate() { } @Override public boolean action(Event event, Object what) { return false; } @Override public boolean handle(FrameEvent f) { return false; } @Override public void dialogDisable(boolean disable) { if (this.isDialogDisabled = disable) { this.cursedButton = -1; this.clickedButton = -1; this.clickedButtonDown = false; this.repaint(); } } }