/* Copyright 1996 Matthew Freedman and University of Washington mattf@cac.washington.edu This program may be freely used, modified, or redistributed for any non-commercial purpose as long as credit is given. This file contains the ColorFrame, ColorFrameRow, WideScroll, and WideLabel classes. */ import java.awt.*; import java.util.*; /* A simple HSB color picker in a pop-up frame. It uses a hard-wired Nina figure to show the current color. */ public class ColorFrame extends Frame { Nina nina = new Nina(); NinaParams p = new NinaParams(); Panel lpanel, rpanel, btn_panel; ColorFrameRow hue, sat, bright; Button ok, cancel; Color cur_color; float[] HSB; PaletteController parent; int which_button; /* Constructor, need a title string an initial color, a parent, and a handle to the button on the parent that needs to be changed. */ public ColorFrame(String s, Color color, PaletteController parent, int which_button) { super(s); cur_color = color; this.parent = parent; this.which_button = which_button; setLayout(null); /* Set up a small nina-draw-er */ p.num_colors = 1; p.ran_colors = false; p.palette[0] = color; p.ran_palette = false; p.ran_lines = p.ran_a_pulse = p.ran_b_pulse = false; p.num_lines = 38; p.a_pulse = 27; p.b_pulse = 22; p.show_lines = false; p.setup(); lpanel = new Panel(); lpanel.setLayout(new GridLayout(1, 1)); lpanel.resize(190, 190); lpanel.add(nina); add(lpanel); lpanel.move(10, 50); rpanel = new Panel(); rpanel.resize(300, 150); rpanel.setLayout(new GridLayout(5, 1)); rpanel.add(hue = new ColorFrameRow("Hue", 1, 360, this)); rpanel.add(sat = new ColorFrameRow("Saturation", 0, 100, this)); rpanel.add(bright = new ColorFrameRow("Brightness", 0, 100, this)); rpanel.add(new Panel()); /* Just a spacer */ rpanel.add(btn_panel = new Panel()); btn_panel.setFont(new Font("Helvetica", Font.BOLD, 14)); btn_panel.add(ok = new Button("Ok")); btn_panel.add(cancel = new Button("Cancel")); add(rpanel); rpanel.move(190, 75); resize(500, 250); show(); nina.drawFig(p); /* Initialize the HSB displays */ HSB = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), (new float[3])); hue.setVal((int)(HSB[0] * 360)); sat.setVal((int)(HSB[1] * 100)); bright.setVal((int)(HSB[2] * 100)); } /* Called from row-controllers when something changed */ void do_update() { cur_color = Color.getHSBColor((hue.getVal() == 360 ? 359 : hue.getVal()) / 360f, sat.getVal() / 100f, bright.getVal() / 100f); p.palette[0] = cur_color; nina.drawFig(p); } public boolean action(Event e, Object arg) { if (e.target instanceof Button) { if (e.target == ok) parent.set_color(cur_color, which_button); nina.die(); nina = null; hide(); dispose(); return(true); } return(false); } /* Make hitting return act like Ok button */ public boolean handleEvent(Event e) { if (e.id == e.KEY_RELEASE) if (e.key == '\n') { e.target = ok; return(action(e, e)); } return(super.handleEvent(e)); } } /* A row in the color frame, contains a label, scrollbar, and value */ class ColorFrameRow extends Panel { WideScroll scroll; TextField text; WideLabel name; String prev_text; int max, val; ColorFrame creator; ColorFrameRow(String label, int min, int max, ColorFrame creator) { this.max = max; this.creator = creator; add(name = new WideLabel(label, Label.RIGHT)); name.resize(30, 10); scroll = new WideScroll(Scrollbar.HORIZONTAL, 1, 10, min, max); add(scroll); add(text = new TextField(String.valueOf(max))); } public void setVal(int val) { scroll.setValue(val); text.setText(String.valueOf(val)); this.val = val; } public int getVal() { return(val); } public boolean handleEvent(Event e) { int new_val; String new_text; if (e.target == scroll) { val = scroll.getValue(); text.setText(String.valueOf(val)); creator.do_update(); return(false); } /* Handle typing into text */ if (e.target == text) { if (e.id == e.KEY_PRESS) { prev_text = text.getText(); return(false); } if (e.id == e.KEY_RELEASE) { new_text = text.getText(); try { new_val = Integer.parseInt(new_text); } catch (NumberFormatException err) { /* We must allow empty strings for backspace case */ if (new_text.length() > 0) text.setText(prev_text); return(false); } if (new_val > max) { text.setText(prev_text); return(false); } /* New value checks out ok, so make scrollbar match */ val = new_val; scroll.setValue(val); creator.do_update(); return(false); } } return(false); } } /* A scrollbar subclass that has a reasonable width. Need this because I can not get Scrollbar.resize to work */ class WideScroll extends Scrollbar { WideScroll(int a, int b, int c, int d, int e) { super(a, b, c, d, e); } public Dimension preferredSize() { return(new Dimension(150, 20)); } } /* A Label subclass that has a reasonable width. Need this because I can not get Label.resize to work either */ class WideLabel extends Label { WideLabel(String label, int align) { super(label, align); } public Dimension preferredSize() { return(new Dimension(75, 20)); } }