// Near Infinity - An Infinity Engine Browser and Editor // Copyright (C) 2001 - 2005 Jon Olav Hauglid // See LICENSE.txt for license information package org.infinity.datatype; import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.infinity.gui.StructViewer; import org.infinity.icon.Icons; import org.infinity.resource.AbstractStruct; import org.infinity.resource.ResourceFactory; import org.infinity.resource.StructEntry; import org.infinity.resource.graphics.GraphicsResource; public final class ColorValue extends Datatype implements Editable, IsNumeric, ChangeListener, ActionListener { private static BufferedImage image; private JLabel colors[], infolabel; private JSlider slider; private JTextField tfield; private int shownnumber; private int number; private static Color getColor(int index, int brightness) { if (image == null) initImage(); if (index >= image.getHeight() || brightness >= image.getWidth()) return null; return new Color(image.getRGB(brightness, index)); } private static int getNumColors() { if (image == null) initImage(); return image.getHeight(); } private static int getRangeSize() { if (image == null) initImage(); return image.getWidth(); } private static void initImage() { try { if (ResourceFactory.resourceExists("RANGES12.BMP")) image = new GraphicsResource(ResourceFactory.getResourceEntry("RANGES12.BMP")).getImage(); else image = new GraphicsResource(ResourceFactory.getResourceEntry("MPALETTE.BMP")).getImage(); } catch (Exception e) { e.printStackTrace(); } } public ColorValue(ByteBuffer buffer, int offset, int length, String name) { this(null, buffer, offset, length, name); } public ColorValue(StructEntry parent, ByteBuffer buffer, int offset, int length, String name) { super(parent, offset, length, name); read(buffer, offset); } // --------------------- Begin Interface ActionListener --------------------- @Override public void actionPerformed(ActionEvent event) { if (event.getSource() == tfield) { try { int newnumber = Integer.parseInt(tfield.getText()); if (newnumber < (1L << (8*getSize()))) { shownnumber = newnumber; } else { tfield.setText(String.valueOf(shownnumber)); } } catch (NumberFormatException e) { tfield.setText(String.valueOf(shownnumber)); } slider.setValue(shownnumber); setColors(); } } // --------------------- End Interface ActionListener --------------------- // --------------------- Begin Interface ChangeListener --------------------- @Override public void stateChanged(ChangeEvent event) { if (event.getSource() == slider) { tfield.setText(String.valueOf(slider.getValue())); shownnumber = slider.getValue(); setColors(); } } // --------------------- End Interface ChangeListener --------------------- // --------------------- Begin Interface Editable --------------------- @Override public JComponent edit(ActionListener container) { if (tfield == null) { tfield = new JTextField(4); tfield.setHorizontalAlignment(JTextField.CENTER); colors = new JLabel[getRangeSize()]; for (int i = 0; i < colors.length; i++) { colors[i] = new JLabel(" "); colors[i].setOpaque(true); } tfield.addActionListener(this); slider = new JSlider(0, Math.max(number, getNumColors() - 1), number); slider.addChangeListener(this); slider.setMajorTickSpacing(25); slider.setMinorTickSpacing(5); slider.setPaintTicks(true); infolabel = new JLabel(" ", JLabel.CENTER); } tfield.setText(String.valueOf(number)); shownnumber = number; setColors(); JButton bUpdate = new JButton("Update value", Icons.getIcon(Icons.ICON_REFRESH_16)); bUpdate.addActionListener(container); bUpdate.setActionCommand(StructViewer.UPDATE_VALUE); JLabel label = new JLabel(getName() + ": "); JPanel cpanel = new JPanel(); cpanel.setLayout(new GridLayout(1, colors.length)); for (final JLabel color : colors) cpanel.add(color); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); JPanel panel = new JPanel(gbl); gbc.insets = new Insets(3, 0, 3, 3); gbl.setConstraints(label, gbc); panel.add(label); gbl.setConstraints(tfield, gbc); panel.add(tfield); gbc.gridwidth = GridBagConstraints.REMAINDER; gbl.setConstraints(slider, gbc); panel.add(slider); gbl.setConstraints(cpanel, gbc); panel.add(cpanel); gbl.setConstraints(infolabel, gbc); panel.add(infolabel); gbl.setConstraints(bUpdate, gbc); panel.add(bUpdate); return panel; } @Override public void select() { } @Override public boolean updateValue(AbstractStruct struct) { try { int newnumber = Integer.parseInt(tfield.getText()); if (newnumber >= (1L << (8*getSize()))) { return false; } number = newnumber; shownnumber = number; setColors(); // notifying listeners fireValueUpdated(new UpdateEvent(this, struct)); return true; } catch (NumberFormatException e) { e.printStackTrace(); } return false; } // --------------------- End Interface Editable --------------------- // --------------------- Begin Interface Writeable --------------------- @Override public void write(OutputStream os) throws IOException { writeInt(os, number); } // --------------------- End Interface Writeable --------------------- //--------------------- Begin Interface Readable --------------------- @Override public int read(ByteBuffer buffer, int offset) { buffer.position(offset); switch (getSize()) { case 1: number = buffer.get(); break; case 2: number = buffer.getShort(); break; case 4: number = buffer.getInt(); break; default: throw new IllegalArgumentException(); } return offset + getSize(); } //--------------------- End Interface Readable --------------------- //--------------------- Begin Interface IsNumeric --------------------- @Override public long getLongValue() { return (long)number & 0xffffffffL; } @Override public int getValue() { return number; } //--------------------- End Interface IsNumeric --------------------- @Override public String toString() { return "Color index " + number; } private void setColors() { for (int i = 0; i < colors.length; i++) { Color c = getColor(shownnumber, i); if (c != null) { colors[i].setText(" "); colors[i].setBackground(c); } else { colors[i].setText(" ? "); colors[i].setBackground(Color.white); } colors[i].repaint(); } if (shownnumber > 199 && ResourceFactory.resourceExists("RANDCOLR.2DA")) infolabel.setText("Color drawn from RANDCOLR.2DA"); else infolabel.setText(""); } }