package net.cakenet.jsaton.ui.tools.snippet;
import net.cakenet.jsaton.model.SimpleImage;
import net.cakenet.jsaton.model.clipboard.ColorTransferable;
import net.cakenet.jsaton.model.clipboard.SimpleImageTransferable;
import net.cakenet.jsaton.ui.tools.ToolWindow;
import net.cakenet.jsaton.util.ColorUtil;
import net.cakenet.jsaton.util.ImageUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.LinkedList;
public class SnippetManager extends ToolWindow implements ClipboardOwner {
public static SnippetManager instance;
private LinkedList<Transferable> data = new LinkedList<>();
private LinkedList<SnippetComposite> components = new LinkedList<>();
private Box panel;
private JPanel wrapper;
private JScrollPane scrolly;
public SnippetManager() {
super("Snippets");
panel = Box.createVerticalBox();
instance = this;
wrapper = new JPanel(new BorderLayout());
wrapper.add(panel, BorderLayout.NORTH);
scrolly = new JScrollPane(wrapper);
scrolly.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
public Component getContents() {
return scrolly;
}
public void addSnippet(Object o) {
Transferable tr;
if (o instanceof Color)
tr = new ColorTransferable((Color) o);
else if (o instanceof Image)
tr = new SimpleImageTransferable(SimpleImage.fromImage((Image) o));
else
tr = new StringSelection(String.valueOf(o));
Clipboard clip = getToolkit().getSystemClipboard();
clip.setContents(tr, this);
record(tr);
}
public void remove(SnippetComposite composite) {
components.remove(composite);
panel.remove(composite);
revalidate();
}
public Icon getIcon() {
return ImageUtil.loadIcon("icons/clipboard_sign.png");
}
public void lostOwnership(Clipboard clipboard, Transferable contents) {
// Don't care
}
private void record(Transferable t) {
SnippetComposite created;
if (t instanceof SimpleImageTransferable) {
created = createImageSnippetComposite((SimpleImageTransferable) t);
} else if (t instanceof StringSelection) {
created = createTextSnippetComposite((StringSelection) t);
} else if (t instanceof ColorTransferable) {
created = createColorSnippetComposite((ColorTransferable) t);
} else
throw new RuntimeException("TODO");
components.add(created);
// Move compnents around...
panel.removeAll();
for (int i = components.size() - 1; i >= 0; i--) {
SnippetComposite c = components.get(i);
panel.add(c);
}
panel.add(Box.createVerticalGlue());
revalidate();
}
private BufferedImage createPreviewImage(BufferedImage bi, int size) {
int ow = bi.getWidth();
int oh = bi.getHeight();
BufferedImage preview = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
float scale = Math.max(ow / (float) size, oh / (float) size);
int w = (int) (ow / scale);
int h = (int) (oh / scale);
int x = (size - w) / 2;
int y = (size - h) / 2;
preview.getGraphics().drawImage(bi, x, y, w, h, null);
return preview;
}
private SnippetComposite createImageSnippetComposite(final SimpleImageTransferable it) {
final BufferedImage bi = it.image.toImage();
JLabel idle = new JLabel(new ImageIcon(createPreviewImage(bi, 30)));
JPanel hovercontainer = new JPanel(new BorderLayout());
hovercontainer.add(new JLabel(new ImageIcon(
createPreviewImage(bi, Math.min(Math.max(bi.getWidth(), bi.getHeight()), 250)))), BorderLayout.CENTER);
JPanel hover = new JPanel(new FlowLayout());
hovercontainer.add(hover, BorderLayout.SOUTH);
final JComboBox<String> formatc = new JComboBox<>(new DefaultComboBoxModel<>(new String[]{"GZIP", "SCAR"}));
hover.add(formatc);
JButton copy = new JButton(ImageUtil.loadIcon("icons/clipboard_text.png"));
copy.setToolTipText("Copy encoded string to clipboard (for use in scripts)");
JButton copyImg = new JButton(ImageUtil.loadIcon("icons/clipboard_paste_image.png"));
copyImg.setToolTipText("Copy image to clipboard (to paste into an image editing program)");
copy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String format = (String) formatc.getSelectedItem();
String enc = "ERROR";
if (format.equals("GZIP"))
enc = it.image.encode();
else if (format.equals("SCAR"))
enc = it.image.encodeScar();
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(enc), null);
}
});
copyImg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(it, null);
}
});
hover.add(copy);
hover.add(copyImg);
return new SnippetComposite("bitmap", idle, hovercontainer);
}
private SnippetComposite createTextSnippetComposite(StringSelection ss) {
try {
String s = (String) ss.getTransferData(DataFlavor.stringFlavor);
String html = s.replace("<", "<").replace(">", ">").replace("&", "&").replace("\n", "<br/>");
html = "<html>" + html + "</html>";
JLabel t = new JLabel(html);
JPanel hover = new JPanel(new FlowLayout());
JTextArea jtf = new JTextArea(s, 5, 30);
jtf.setEditable(false);
jtf.setEnabled(true);
hover.add(new JScrollPane(jtf));
JButton copy = new JButton(ImageUtil.loadIcon("icons/clipboard_text.png"));
copy.setToolTipText("Copy to clipboard");
hover.add(copy);
return new SnippetComposite("text", t, hover);
} catch (UnsupportedFlavorException | IOException e) {
e.printStackTrace();
}
return null;
}
private SnippetComposite createColorSnippetComposite(ColorTransferable ct) {
Color c = ct.color;
int p = c.getRGB() & 0xffffff;
int r = (p >> 16) & 0xff;
int g = (p >> 8) & 0xff;
int b = p & 0xff;
Color contrasting = ColorUtil.contrasting(p);
String html = String.format("<html>0x%06x, (%02d, %02d, %02d)</html>", p, r, g, b);
JLabel t = new JLabel(html);
t.setOpaque(true);
final String codes = String.format("0x%06x", p);
StringBuilder data = new StringBuilder("<html><font color=");
data.append("#").append(String.format("%06x", (contrasting.getRGB() & 0xffffff))).append(">");
t.setBackground(new Color(r, g, b, 0xfe));
data.append(String.format("%s (%03d, %03d, %03d)", codes, r, g, b));
data.append("</html>");
t.setText(data.toString());
JPanel popup = new JPanel(new FlowLayout());
popup.add(new JLabel(codes, new ImageIcon(ColorUtil.toImage(16, 16, p)), SwingConstants.CENTER));
JButton copy = new JButton(ImageUtil.loadIcon("icons/clipboard_text.png"));
copy.setToolTipText("Copy to clipboard");
copy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(codes), null);
}
});
popup.add(copy);
return new SnippetComposite("color", t, popup);
}
}