summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/TabbedPanel.java
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-12 22:33:32 -0800
committerFuwn <[email protected]>2026-02-12 22:33:32 -0800
commitc7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch)
treedf9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/TabbedPanel.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/TabbedPanel.java')
-rw-r--r--NET/worlds/scape/TabbedPanel.java274
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);
+ }
+ }
+}