/*
* Copyright (C) 2014 James Lawrence.
*
* This file is part of GrimEdi.
*
* GrimEdi is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Created by JFormDesigner on Sat Mar 16 10:40:39 GMT 2013
*/
package com.sqrt4.grimedi.ui.editor;
import com.sqrt.liblab.entry.graphics.FontGlyph;
import com.sqrt.liblab.entry.graphics.GrimFont;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Map;
/**
* @author James Lawrence
*/
public class FontView extends EditorPanel<GrimFont> {
private String _previewedText;
private static final int mult = 8;
private BufferedImage _glyphPreview;
public FontView() {
initComponents();
}
ImageIcon icon = new ImageIcon(getClass().getResource("/font.png"));
public ImageIcon getIcon() {
return icon;
}
private void updatePreview() {
int height = data.height;
int width = 0;
int y = data.yOffset;
int x = 0;
String text = previewText.getText();
char[] charArray = text.toCharArray();
for (char c : charArray) {
FontGlyph g = data.getGlyph(c);
if (g == null)
g = data.getGlyph('?');
width += g.charWidth;
}
// Todo: move all this stuff into the font model
if(width == 0)
width = 1; // so bufferedimage doesn't bitch...
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
for (char c : charArray) {
FontGlyph g = data.getGlyph(c);
if (g == null)
g = data.getGlyph('?');
result.getGraphics().drawImage(g.mask, x+g.xOff, y+g.yOff, null);
x += g.charWidth;
}
fontPreview.setIcon(new ImageIcon(result));
}
public void onNewData() {
int height = data.height;
int width = 0;
for(FontGlyph glyph: data.glyphs)
if(glyph.mask.getWidth() > width)
width = glyph.mask.getWidth();
_glyphPreview = new BufferedImage(width*mult, height*mult, BufferedImage.TYPE_INT_ARGB);
list1.setModel(new ListModel<FontGlyph>() {
public int getSize() {
return data.glyphs.size();
}
public FontGlyph getElementAt(int index) {
return data.glyphs.get(index);
}
public void addListDataListener(ListDataListener l) {
//To change body of implemented methods use File | Settings | File Templates.
}
public void removeListDataListener(ListDataListener l) {
//To change body of implemented methods use File | Settings | File Templates.
}
});
list1.setCellRenderer(new ListCellRenderer<FontGlyph>() {
private Map<FontGlyph, JLabel> cache = new HashMap<FontGlyph, JLabel>();
public Component getListCellRendererComponent(JList list, FontGlyph value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label;
if(cache.containsKey(value))
label = cache.get(value);
else {
label = new JLabel();
label.setOpaque(true);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setVerticalAlignment(SwingConstants.BOTTOM);
label.setVerticalTextPosition(SwingConstants.BOTTOM);
label.setIcon(new ImageIcon(value.mask));
cache.put(value, label);
}
if (isSelected) {
label.setBackground(list.getSelectionBackground());
label.setForeground(list.getSelectionForeground());
} else {
label.setBackground(list.getBackground());
label.setForeground(list.getForeground());
}
label.setBorder(BorderFactory.createLineBorder(isSelected? list.getSelectionBackground().darker(): list.getBackground().darker()));
label.setText(String.valueOf(value.index));
return label;
}
});
list1.setVisibleRowCount(0);
list1.setSelectedIndex(0);
updatePreview();
}
private void previewTextChanged(CaretEvent e) {
if(!previewText.getText().equals(_previewedText)) {
updatePreview();
_previewedText = previewText.getText();
}
}
private void updateGlyphPreview() {
FontGlyph glyph = (FontGlyph) list1.getSelectedValue();
if(glyph == null) {
glyphPreview.setIcon(null);
return;
}
int w = glyph.charWidth;
int h = data.height;
int x = glyph.xOff;
int y = data.yOffset+glyph.yOff;
Graphics g = _glyphPreview.getGraphics();
((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));
g.setColor(Color.WHITE);
g.fillRect(0, 0, _glyphPreview.getWidth(), _glyphPreview.getHeight());
((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
g.drawImage(glyph.mask, x*mult, y*mult, glyph.mask.getWidth()*mult, glyph.mask.getHeight()*mult, null);
g.setColor(Color.RED);
g.drawLine(x*mult, 0, x*mult, h*mult);
g.setColor(Color.BLUE);
g.drawLine(0, y*mult, w*mult, y*mult);
g.setColor(Color.GREEN);
g.drawRect(0, 0, w*mult, h*mult-1);
glyphPreview.setIcon(new ImageIcon(_glyphPreview));
}
private boolean initial = false;
private void glyphSelected(ListSelectionEvent e) {
if(e.getValueIsAdjusting())
return;
updateGlyphPreview();
FontGlyph glyph = (FontGlyph) list1.getSelectedValue();
boolean valid = glyph != null;
xEntry.setEnabled(valid);
yEntry.setEnabled(valid);
charEntry.setEnabled(valid);
widthEntry.setEnabled(valid);
if(!valid)
return;
initial = true;
xEntry.getModel().setValue(glyph.xOff);
yEntry.getModel().setValue(glyph.yOff);
widthEntry.getModel().setValue(glyph.charWidth);
charEntry.getModel().setValue(glyph.index);
initial = false;
}
private void valueChanged(ChangeEvent e) {
if(initial)
return;
FontGlyph glyph = (FontGlyph) list1.getSelectedValue();
if(glyph == null)
return;
glyph.xOff = (Integer) xEntry.getValue();
glyph.yOff = (Integer) yEntry.getValue();
glyph.charWidth = (Integer) widthEntry.getValue();
glyph.index = (Integer) charEntry.getValue();
updateGlyphPreview();
updatePreview();
}
private void previewTextPropertyChange(PropertyChangeEvent e) {
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
panel2 = new JPanel();
fontPreview = new JLabel();
panel4 = new JPanel();
previewText = new JTextField();
label1 = new JLabel();
panel3 = new JPanel();
scrollPane1 = new JScrollPane();
list1 = new JList();
panel5 = new JPanel();
glyphPreview = new JLabel();
panel6 = new JPanel();
label5 = new JLabel();
charEntry = new JSpinner();
label4 = new JLabel();
widthEntry = new JSpinner();
label2 = new JLabel();
xEntry = new JSpinner();
label3 = new JLabel();
yEntry = new JSpinner();
//======== this ========
setLayout(new GridBagLayout());
((GridBagLayout)getLayout()).columnWidths = new int[] {0, 0};
((GridBagLayout)getLayout()).rowHeights = new int[] {0, 0, 0};
((GridBagLayout)getLayout()).columnWeights = new double[] {1.0, 1.0E-4};
((GridBagLayout)getLayout()).rowWeights = new double[] {0.0, 1.0, 1.0E-4};
//======== panel2 ========
{
panel2.setBorder(new TitledBorder("Font Preview"));
panel2.setLayout(new BorderLayout());
//---- fontPreview ----
fontPreview.setHorizontalAlignment(SwingConstants.CENTER);
fontPreview.setBackground(Color.white);
fontPreview.setPreferredSize(new Dimension(0, 50));
fontPreview.setMinimumSize(new Dimension(0, 50));
panel2.add(fontPreview, BorderLayout.NORTH);
//======== panel4 ========
{
panel4.setLayout(new BorderLayout());
//---- previewText ----
previewText.setText("!\"\u00a3 $%^&*()_+-=`[]{};:'@#~?/>.<,\\|0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
previewText.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
previewTextChanged(e);
}
});
previewText.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent e) {
previewTextPropertyChange(e);
}
});
panel4.add(previewText, BorderLayout.CENTER);
//---- label1 ----
label1.setText("Preview Text: ");
label1.setHorizontalAlignment(SwingConstants.TRAILING);
label1.setLabelFor(previewText);
panel4.add(label1, BorderLayout.WEST);
}
panel2.add(panel4, BorderLayout.SOUTH);
}
add(panel2, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
//======== panel3 ========
{
panel3.setBorder(new TitledBorder("Font Glyphs"));
panel3.setLayout(new BorderLayout());
//======== scrollPane1 ========
{
//---- list1 ----
list1.setLayoutOrientation(JList.HORIZONTAL_WRAP);
list1.setMaximumSize(null);
list1.setMinimumSize(null);
list1.setVisibleRowCount(0);
list1.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
glyphSelected(e);
}
});
scrollPane1.setViewportView(list1);
}
panel3.add(scrollPane1, BorderLayout.CENTER);
//======== panel5 ========
{
panel5.setBorder(new TitledBorder("Glyph Properties"));
panel5.setLayout(new BorderLayout());
//---- glyphPreview ----
glyphPreview.setHorizontalAlignment(SwingConstants.CENTER);
glyphPreview.setBackground(Color.white);
panel5.add(glyphPreview, BorderLayout.NORTH);
//======== panel6 ========
{
panel6.setLayout(new GridBagLayout());
((GridBagLayout)panel6.getLayout()).columnWidths = new int[] {0, 0, 0, 0, 0};
((GridBagLayout)panel6.getLayout()).rowHeights = new int[] {0, 0, 0};
((GridBagLayout)panel6.getLayout()).columnWeights = new double[] {0.0, 0.0, 0.0, 0.0, 1.0E-4};
((GridBagLayout)panel6.getLayout()).rowWeights = new double[] {0.0, 0.0, 1.0E-4};
//---- label5 ----
label5.setText("Char: ");
label5.setHorizontalAlignment(SwingConstants.TRAILING);
panel6.add(label5, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//---- charEntry ----
charEntry.setModel(new SpinnerNumberModel(0, 0, 65535, 1));
charEntry.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
valueChanged(e);
}
});
panel6.add(charEntry, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//---- label4 ----
label4.setText("Width: ");
label4.setHorizontalAlignment(SwingConstants.TRAILING);
label4.setLabelFor(widthEntry);
panel6.add(label4, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//---- widthEntry ----
widthEntry.setModel(new SpinnerNumberModel(0, -128, 127, 1));
widthEntry.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
valueChanged(e);
}
});
panel6.add(widthEntry, new GridBagConstraints(3, 0, 1, 1, 2.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
//---- label2 ----
label2.setText("X: ");
label2.setHorizontalAlignment(SwingConstants.TRAILING);
label2.setLabelFor(xEntry);
panel6.add(label2, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
//---- xEntry ----
xEntry.setModel(new SpinnerNumberModel(0, -128, 127, 1));
xEntry.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
valueChanged(e);
}
});
panel6.add(xEntry, new GridBagConstraints(1, 1, 1, 1, 2.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
//---- label3 ----
label3.setText("Y: ");
label3.setHorizontalAlignment(SwingConstants.TRAILING);
label3.setLabelFor(yEntry);
panel6.add(label3, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
//---- yEntry ----
yEntry.setModel(new SpinnerNumberModel(0, -128, 127, 1));
yEntry.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
valueChanged(e);
}
});
panel6.add(yEntry, new GridBagConstraints(3, 1, 1, 1, 2.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
}
panel5.add(panel6, BorderLayout.CENTER);
}
panel3.add(panel5, BorderLayout.PAGE_END);
}
add(panel3, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
// Generated using JFormDesigner non-commercial license
private JPanel panel2;
private JLabel fontPreview;
private JPanel panel4;
private JTextField previewText;
private JLabel label1;
private JPanel panel3;
private JScrollPane scrollPane1;
private JList list1;
private JPanel panel5;
private JLabel glyphPreview;
private JPanel panel6;
private JLabel label5;
private JSpinner charEntry;
private JLabel label4;
private JSpinner widthEntry;
private JLabel label2;
private JSpinner xEntry;
private JLabel label3;
private JSpinner yEntry;
// JFormDesigner - End of variables declaration //GEN-END:variables
}