/*
* Copyright © 2010-2011 Rebecca G. Bettencourt / Kreative Software
* <p>
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
* <p>
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* <p>
* Alternatively, the contents of this file may be used under the terms
* of the GNU Lesser General Public License (the "LGPL License"), in which
* case the provisions of LGPL License are applicable instead of those
* above. If you wish to allow use of your version of this file only
* under the terms of the LGPL License and not to allow others to use
* your version of this file under the MPL, indicate your decision by
* deleting the provisions above and replace them with the notice and
* other provisions required by the LGPL License. If you do not delete
* the provisions above, a recipient may use your version of this file
* under either the MPL or the LGPL License.
* @since PowerPaint 1.0
* @author Rebecca G. Bettencourt, Kreative Software
*/
package com.kreative.paint.tool.ui;
import java.awt.*;
import java.awt.event.*;
import java.util.HashSet;
import java.util.Set;
import javax.swing.*;
import javax.swing.border.Border;
import com.kreative.paint.ToolContext;
import com.kreative.paint.ToolContextConstants;
import com.kreative.paint.ToolContextListener;
import com.kreative.paint.material.alphabet.Alphabet;
import com.kreative.paint.tool.Tool;
import com.kreative.paint.util.SwingUtils;
import com.kreative.paint.util.UpdateLock;
public class AlphabetsUI extends JPanel implements ToolContextListener {
private static final long serialVersionUID = 1L;
private UpdateLock u = new UpdateLock();
private ToolContext tc;
private JComboBox apop;
private JPanel apanel;
private CardLayout alyt;
private Set<LetterPanel> apanels;
private JTextField afld;
public AlphabetsUI(ToolContext tc, boolean mini) {
this.tc = tc;
apop = new JComboBox(tc.getAlphabets().toNameArray());
apop.setEditable(false);
apop.setMaximumRowCount(48);
if (mini) SwingUtils.shrink(apop);
apop.setSelectedIndex(tc.getAlphabetIndex());
apop.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (u.lock()) {
AlphabetsUI.this.tc.setAlphabetIndex(apop.getSelectedIndex());
alyt.show(apanel, Integer.toString(AlphabetsUI.this.tc.getAlphabetIndex()));
afld.setText(String.valueOf(Character.toChars(AlphabetsUI.this.tc.getLetter())));
u.unlock();
}
}
});
apanel = new JPanel(alyt = new CardLayout());
apanels = new HashSet<LetterPanel>();
for (int n = 0; n < tc.getAlphabets().size(); n++) {
LetterPanel a = new LetterPanel(tc.getAlphabets().getValue(n), mini);
JScrollPane s = new JScrollPane(a, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
apanel.add(s, Integer.toString(n));
apanels.add(a);
}
afld = new JTextField(String.valueOf(Character.toChars(tc.getLetter())), 2);
afld.setEditable(false);
if (mini) SwingUtils.shrink(afld);
afld.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) { e.consume(); }
public void keyReleased(KeyEvent e) { e.consume(); }
public void keyTyped(KeyEvent e) {
if ((e.getKeyChar() > 0x20 && e.getKeyChar() < 0x7F) || (e.getKeyChar() >= 0xA0 && e.getKeyChar() < 0xFFFD)) {
if (u.lock()) {
afld.setText(Character.toString(e.getKeyChar()));
AlphabetsUI.this.tc.setLetter(e.getKeyChar());
for (LetterPanel a : apanels) a.updateSelection();
u.unlock();
}
}
e.consume();
}
});
JPanel afp = new JPanel(new FlowLayout());
afp.add(afld);
setLayout(new BorderLayout());
add(apop, BorderLayout.PAGE_START);
add(apanel, BorderLayout.CENTER);
add(afp, BorderLayout.PAGE_END);
tc.addToolContextListener(this);
}
public void modeChanged(ToolContext src, boolean drawMode) {}
public void toolChanged(ToolContext src, Tool previousTool, Tool nextTool) {}
public void toolDoubleClicked(ToolContext src, Tool tool) {}
public void toolSettingsChanged(ToolContext src, long delta) {
if ((delta & ToolContextConstants.CHANGED_ALPHABET_SET) != 0L) {
if (u.lock()) {
apop.setSelectedIndex(tc.getAlphabetIndex());
alyt.show(apanel, Integer.toString(tc.getAlphabetIndex()));
afld.setText(String.valueOf(Character.toChars(tc.getLetter())));
u.unlock();
}
for (LetterPanel a : apanels) a.updateSelection();
} else if ((delta & ToolContextConstants.CHANGED_ALPHABET_LETTER) != 0L) {
if (u.lock()) {
afld.setText(String.valueOf(Character.toChars(tc.getLetter())));
u.unlock();
}
for (LetterPanel a : apanels) a.updateSelection();
}
}
private class LetterPanel extends JPanel implements Scrollable {
private static final long serialVersionUID = 1L;
private Set<LetterLabel> labels;
public LetterPanel(Alphabet ch, boolean mini) {
super(new GridLayout(0,14,-1,-1));
labels = new HashSet<LetterLabel>();
for (int c : ch.letters) {
LetterLabel l = new LetterLabel(ch, c, mini);
add(l);
labels.add(l);
}
}
public void updateSelection() {
for (LetterLabel l : labels) l.updateSelection();
}
public Dimension getPreferredScrollableViewportSize() {
if (!labels.isEmpty()) {
int h = (labels.iterator().next().getHeight()-1)*6 + 1;
Dimension p = getPreferredSize();
if (p.height < h) return p;
else return new Dimension(p.width, h);
} else {
return getPreferredSize();
}
}
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
if (!labels.isEmpty()) {
return (labels.iterator().next().getHeight()-1)*6;
} else {
return visibleRect.height;
}
}
public boolean getScrollableTracksViewportHeight() {
return false;
}
public boolean getScrollableTracksViewportWidth() {
return true;
}
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
if (!labels.isEmpty()) {
return labels.iterator().next().getHeight()-1;
} else {
return 1;
}
}
}
private class LetterLabel extends JLabel {
private static final long serialVersionUID = 1L;
private final int ch;
public LetterLabel(Alphabet a, int ch, boolean mini) {
super(String.valueOf(Character.toChars(ch)));
setOpaque(true);
setBackground(Color.white);
setForeground(Color.black);
setFont(mini ? a.font.deriveFont(a.font.getSize2D() / 2.0f) : a.font);
setHorizontalAlignment(JLabel.CENTER);
this.ch = ch;
updateSelection();
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
tc.setLetter(LetterLabel.this.ch);
}
});
}
public void updateSelection() {
if (tc.getLetter() == ch) {
Border inner = BorderFactory.createEmptyBorder(4, 2, 0, 2);
Border outer = BorderFactory.createLineBorder(Color.black, 3);
setBorder(BorderFactory.createCompoundBorder(outer, inner));
} else {
Border inner = BorderFactory.createEmptyBorder(6, 4, 2, 4);
Border outer = BorderFactory.createLineBorder(Color.black, 1);
setBorder(BorderFactory.createCompoundBorder(outer, inner));
}
}
}
}