diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/TabbedPanel.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/scape/TabbedPanel.java')
| -rw-r--r-- | NET/worlds/scape/TabbedPanel.java | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/NET/worlds/scape/TabbedPanel.java b/NET/worlds/scape/TabbedPanel.java new file mode 100644 index 0000000..3e7b3fd --- /dev/null +++ b/NET/worlds/scape/TabbedPanel.java @@ -0,0 +1,274 @@ +package NET.worlds.scape; + +import NET.worlds.console.Console; +import NET.worlds.console.DialogDisabled; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Panel; +import java.awt.Point; +import java.util.Vector; + +public class TabbedPanel extends Panel implements ClickEventHandler, DialogDisabled { + private Vector entries = new Vector(); + private int rows; + private int itemWidth; + private int itemHeight; + private int itemsPerRow; + private int choice; + private Font nFont; + private FontMetrics nFontMetrics; + private Font bFont; + private FontMetrics bFontMetrics; + private int fontHeight; + private TabbedDisplayPanel disp = new TabbedDisplayPanel(); + private ClickEventHandler handler; + private boolean needRecalc; + private boolean isDialogDisabled; + + public TabbedPanel(ClickEventHandler handler) { + this.handler = handler; + this.setLayout(new BorderLayout()); + this.add("Center", this.disp); + } + + public TabbedPanel() { + this(null); + this.handler = this; + } + + public void addItem(String name, Component c) { + this.entries.addElement(name); + this.needRecalc = true; + this.repaint(); + this.disp.addItem(c); + } + + public void insertItem(int index, String name, Component c) { + this.entries.insertElementAt(name, index); + this.disp.insertItem(index, c); + if (index <= this.choice) { + this.choice = Math.min(this.choice + 1, this.entries.size() - 1); + } + + this.needRecalc = true; + this.repaint(); + } + + public void removeItem(int index) { + this.entries.removeElementAt(index); + this.disp.removeItem(index); + if (index == this.choice) { + int count = this.entries.size(); + if (count > 0) { + this.choice = Math.min(this.choice, count - 1); + this.disp.setChoice(this.choice); + } + } else if (index < this.choice) { + this.choice--; + } + + this.needRecalc = true; + this.repaint(); + } + + public void select(int index) { + this.choice = index; + this.repaint(); + this.disp.setChoice(index); + } + + public String getName(int index) { + return (String)this.entries.elementAt(index); + } + + public void setName(int index, String name) { + this.entries.setElementAt(name, index); + this.needRecalc = true; + this.repaint(); + } + + @Override + public Component getComponent(int index) { + return index < this.entries.size() ? this.disp.getComponent(index) : null; + } + + public int selected() { + return this.choice; + } + + public int itemAt(Point p) { + if (!this.needRecalc) { + Point tab = new Point(0, 0); + int count = this.entries.size(); + + for (int i = 0; i < count; i++) { + this.getPosition(i, tab); + if (p.x >= tab.x && p.y >= tab.y && p.x < tab.x + this.itemWidth && p.y < tab.y + this.itemHeight) { + return i; + } + } + } + + return -1; + } + + @Override + public void addNotify() { + super.addNotify(); + this.nFont = new Font(Console.message("NotifyFont"), 0, 13); + this.nFontMetrics = this.getFontMetrics(this.nFont); + this.bFont = new Font(Console.message("NotifyFont"), 1, 14); + this.bFontMetrics = this.getFontMetrics(this.bFont); + this.fontHeight = Math.max(this.nFontMetrics.getHeight(), this.bFontMetrics.getHeight()); + this.itemHeight = this.fontHeight + 5; + } + + @Override + public Insets insets() { + if (this.needRecalc) { + this.recalc(); + } + + return new Insets(this.rows * this.itemHeight, 0, 0, 0); + } + + @Override + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + this.needRecalc = true; + this.repaint(); + } + + private void recalc() { + int row = 0; + int itemsOnRow = 0; + int x = 0; + int count = this.entries.size(); + this.itemWidth = 0; + + for (int i = 0; i < count; i++) { + String name = (String)this.entries.elementAt(i); + int w = Math.max(this.bFontMetrics.stringWidth(name), this.nFontMetrics.stringWidth(" " + name + " ")); + this.itemWidth = Math.max(w, this.itemWidth); + } + + this.itemWidth += 4; + this.itemsPerRow = Math.max(1, this.size().width / this.itemWidth); + this.rows = (count + this.itemsPerRow - 1) / this.itemsPerRow; + this.needRecalc = false; + this.invalidate(); + this.validate(); + } + + private void getPosition(int entry, Point pos) { + int count = this.entries.size(); + int firstRow = this.choice / this.itemsPerRow; + int entryRow = entry / this.itemsPerRow; + int column = entry - entryRow * this.itemsPerRow; + pos.x = column * this.itemWidth; + pos.y = (this.rows - 1 - entryRow) * this.itemHeight - 2; + } + + private static void vLine(Graphics g, int x1, int y1, int y2) { + g.drawLine(x1, y1, x1, y2); + } + + private static void hLine(Graphics g, int x1, int y1, int x2) { + g.drawLine(x1, y1, x2, y1); + } + + @Override + public void paint(Graphics g) { + if (this.needRecalc) { + this.recalc(); + } + + g.setColor(this.getBackground()); + g.fillRect(0, 0, this.size().width, this.size().height); + int count = this.entries.size(); + if (count != 0) { + Point p = new Point(0, 0); + int maxWidth = this.itemWidth - 4; + + for (int i = 0; i < count; i++) { + this.getPosition(i, p); + String ent = (String)this.entries.elementAt(i); + int x1 = p.x; + int y1 = p.y + 4; + int y2 = y1 + this.fontHeight; + int yFont = y1; + Font font = this.nFont; + FontMetrics fm = this.nFontMetrics; + boolean selected = i == this.choice; + if (selected) { + y1 = p.y + 2; + y2 = y1 + this.fontHeight + 4; + yFont = y1 + 1; + font = this.bFont; + fm = this.bFontMetrics; + } + + int width = fm.stringWidth(ent); + int spacing = (maxWidth - width) / 2; + int x2 = x1 + maxWidth; + g.setFont(font); + g.setColor(this.getBackground().brighter()); + if (selected) { + hLine(g, 0, y2, x1); + hLine(g, x2 + 3, y2, this.size().width); + } + + vLine(g, x1, y2, y1 + 2); + g.drawLine(x1, y1 + 2, x1 + 2, y1); + hLine(g, x1 + 2, y1, x2); + g.setColor(this.getBackground().darker()); + vLine(g, x2 + 1, y1 + 1, y2); + vLine(g, x2 + 2, y1 + 2, y2); + g.setColor(this.getForeground()); + g.drawString(ent, x1 + 1 + spacing, yFont + fm.getAscent() + fm.getLeading()); + } + } + } + + @Override + public void clickEvent(Component who, Point location, int flags) { + } + + @Override + public boolean mouseDown(java.awt.Event event, int x, int y) { + Point p = new Point(x, y); + int tmp = this.itemAt(p); + if (tmp != -1) { + this.choice = tmp; + this.repaint(); + this.disp.setChoice(this.choice); + int flags = 1; + if (event.metaDown()) { + flags |= 4; + } + + this.handler.clickEvent(this, p, flags); + return true; + } else { + return false; + } + } + + @Override + public boolean handleEvent(java.awt.Event event) { + return this.isDialogDisabled ? false : super.handleEvent(event); + } + + @Override + public void dialogDisable(boolean disable) { + this.isDialogDisabled = disable; + Component c = this.getComponent(this.selected()); + if (c != null && c instanceof DialogDisabled) { + ((DialogDisabled)c).dialogDisable(disable); + } + } +} |