/* * Copyright (C) 2007 Clam <clamisgood@gmail.com> * Copyright (C) 2008, 2011 IsmAvatar <IsmAvatar@gmail.com> * Copyright (C) 2009 Quadduc <quadduc@gmail.com> * * This file is part of LateralGM. * LateralGM is free software and comes with ABSOLUTELY NO WARRANTY. * See LICENSE for details. */ package org.lateralgm.components.visual; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Shape; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import org.lateralgm.main.UpdateSource.UpdateEvent; import org.lateralgm.main.UpdateSource.UpdateListener; import org.lateralgm.resources.Sprite; import org.lateralgm.resources.Sprite.PSprite; import org.lateralgm.util.PropertyMap.PropertyUpdateEvent; import org.lateralgm.util.PropertyMap.PropertyUpdateListener; public class SubimagePreview extends AbstractImagePreview implements UpdateListener { private static final long serialVersionUID = 1L; private int subIndex = 0; private boolean showBbox = true; private final Sprite sprite; private final SpritePropertyListener spl = new SpritePropertyListener(); private static final int ORIGIN_SIZE = 20; public SubimagePreview(Sprite s) { super(); sprite = s; s.properties.updateSource.addListener(spl); s.reference.updateSource.addListener(this); enableEvents(MouseEvent.MOUSE_PRESSED); enableEvents(MouseEvent.MOUSE_DRAGGED); } public void paintComponent(Graphics g) { super.paintComponent(g); BufferedImage img = getImage(); if (img != null && showBbox) { setPreferredSize(new Dimension(img.getWidth(),img.getHeight())); int originX = sprite.get(PSprite.ORIGIN_X); int originY = sprite.get(PSprite.ORIGIN_Y); int bboxLeft = sprite.get(PSprite.BB_LEFT); int bboxRight = sprite.get(PSprite.BB_RIGHT); int bboxTop = sprite.get(PSprite.BB_TOP); int bboxBottom = sprite.get(PSprite.BB_BOTTOM); int left = Math.min(bboxLeft,bboxRight); int right = Math.max(bboxLeft,bboxRight); int top = Math.min(bboxTop,bboxBottom); int bottom = Math.max(bboxTop,bboxBottom); Shape oldClip = reclip(g); g.setXORMode(Color.BLACK); //XOR mode so that bbox and origin can counter g.setColor(Color.WHITE); g.drawRect(left,top,right - left,bottom - top); g.drawLine(originX - ORIGIN_SIZE,originY,originX + ORIGIN_SIZE,originY); g.drawLine(originX,originY - ORIGIN_SIZE,originX,originY + ORIGIN_SIZE); g.setPaintMode(); //just in case g.setClip(oldClip); //restore the clip } else setPreferredSize(new Dimension(0,0)); } private void setBoundedOrigin(int x, int y) { Dimension d = getPreferredSize(); x = Math.max(0,Math.min(d.width - 1,x)); y = Math.max(0,Math.min(d.height - 1,y)); sprite.put(PSprite.ORIGIN_X,x); sprite.put(PSprite.ORIGIN_Y,y); } public void setIndex(int i) { subIndex = i; updateUI(); } public void setShowBbox(boolean show) { showBbox = show; } protected void processMouseEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_PRESSED && e.getButton() == MouseEvent.BUTTON1 && e.getX() < getPreferredSize().width && e.getY() < getPreferredSize().height) setBoundedOrigin(e.getX(),e.getY()); super.processMouseEvent(e); } protected void processMouseMotionEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_DRAGGED && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) setBoundedOrigin(e.getX(),e.getY()); super.processMouseMotionEvent(e); } protected BufferedImage getImage() { if (sprite == null) return null; int s = sprite.subImages.size(); return s == 0 || subIndex < 0 ? null : sprite.subImages.get(subIndex % s); } public void updated(UpdateEvent e) { updateUI(); } private class SpritePropertyListener extends PropertyUpdateListener<PSprite> { public void updated(PropertyUpdateEvent<PSprite> e) { switch (e.key) { case PRELOAD: case SMOOTH_EDGES: case TRANSPARENT: case SHAPE: return; default: repaint(); } } } }