[tiled] r711 - in trunk: . src/tiled/core src/tiled/mapeditor src/tiled/mapeditor/dialogs src/tiled/mapeditor/selection src/tiled/mapeditor/widget

svn at biggeruniverse.com svn at biggeruniverse.com
Sun Dec 17 02:26:04 PST 2006


Author: aturk
Date: 2006-12-17 04:26:03 -0600 (Sun, 17 Dec 2006)
New Revision: 711

Added:
   trunk/src/tiled/mapeditor/widget/TilePaletteQuickPanel.java
Modified:
   trunk/CHANGES
   trunk/INSTALL
   trunk/README
   trunk/src/tiled/core/Sprite.java
   trunk/src/tiled/core/TileLayer.java
   trunk/src/tiled/mapeditor/MapEditor.java
   trunk/src/tiled/mapeditor/dialogs/BrushDialog.java
   trunk/src/tiled/mapeditor/dialogs/TilePaletteDialog.java
   trunk/src/tiled/mapeditor/selection/SelectionLayer.java
   trunk/src/tiled/mapeditor/widget/TabbedTilesetsPane.java
Log:
+ Added brush memory
+ Fixed split for TabbedTilesetPanel
+ Added a new TilesetPalette for the tabbed tilesets

Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/CHANGES	2006-12-17 10:26:03 UTC (rev 711)
@@ -4,11 +4,13 @@
 * Added ability to create stamp brushes from the tile palette
 * Added import/export of configuration
 * Added option to automatically open the last map on startup (by Pedro Miller)
+* Added brush memory, so that going to another tool and coming back does not reset the brush
 * Embedded the tile palette
 * Report out of memory error when saving map as image
 * Properties table now displays the properties in alphabetical order
 * Fixed properties dialog to also save values that were still being edited
 * Fixed automatically adding the file extension when not given
+* Fixed default tabbed tilesets panel height
 * Worked around an issue with the open file dialog on GNU classpath
 * Worked around an issue with setting a null cursor on GNU classpath
 

Modified: trunk/INSTALL
===================================================================
--- trunk/INSTALL	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/INSTALL	2006-12-17 10:26:03 UTC (rev 711)
@@ -3,26 +3,38 @@
 ----------------
 
 NOTE: If you have downloaded the binary archive (bin), then you can skip this
-as you will already have the tiled.jar file. Continue to "running Tiled" below.
+as you will already have the tiled.jar file. Continue to "Running Tiled" below.
 
 Take the following steps to build Tiled from source:
 
 - Install j2sdk       (http://java.sun.com/)
 - Install apache-ant  (http://ant.apache.org/)
-- Run ant in the directory where you placed Tiled
+- Run: 'ant dist' in the directory where you placed Tiled
+  This will create a new subdirectory dist/
 
 ---------------
  RUNNING TILED
 ---------------
 
-- Install JRE 5.0     (http://java.sun.com/)
+~ Getting the JVM ~
 
+  Install JRE 1.4 or 5.0 from http://java.sun.com/ . Either will work, though 
+  in the future we aim toward 5.0. If you already have the J2SDK, then you can
+  safely skip this step.
+
+~ Running ~
 - From the command line, you can run the following from the directory where you
   placed Tiled:
 
-  java -jar dist/tiled.jar
+  (*nix)    java -jar dist/tiled.jar
+  
+  (Windows) java -jar dist\tiled.jet
+  
+~ Notes ~
 
 - You can also use the Java webstart link on the website, see "Start Now!"
 
 - Windows users that have JRE 5.0 installed should be able to double click the
   tiled.jar file to run it.
+
+- Make sure java binaries are in your path.
\ No newline at end of file

Modified: trunk/README
===================================================================
--- trunk/README	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/README	2006-12-17 10:26:03 UTC (rev 711)
@@ -56,3 +56,4 @@
 - GNOME and GIMP for their magnificent icons
 - Nephilim for suggesting layer opacity
 - Rainer Deyke for useful suggestions and many code contributions
+- Jerome Blouin for some meticulous testing

Modified: trunk/src/tiled/core/Sprite.java
===================================================================
--- trunk/src/tiled/core/Sprite.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/core/Sprite.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -147,6 +147,10 @@
         createKey("", frames, KeyFrame.KEY_LOOP);
     }
 
+    public Sprite(TileSet set) {
+        
+    }
+    
     public void setFrames(Tile[] frames) {
         frameSize = new Rectangle(0, 0, frames[0].getWidth(), frames[0].getHeight());
 

Modified: trunk/src/tiled/core/TileLayer.java
===================================================================
--- trunk/src/tiled/core/TileLayer.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/core/TileLayer.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -293,6 +293,7 @@
      * @param ti the tile object to place
      */
     public void setTileAt(int tx, int ty, Tile ti) {
+        if(!bounds.contains(tx, ty)) return; //quicker than a trap
         try {
             if (canEdit()) {
                 map[ty - bounds.y][tx - bounds.x] = ti;

Modified: trunk/src/tiled/mapeditor/MapEditor.java
===================================================================
--- trunk/src/tiled/mapeditor/MapEditor.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/mapeditor/MapEditor.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -18,6 +18,7 @@
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.Stack;
 import java.util.Vector;
@@ -37,7 +38,6 @@
 import tiled.io.MapReader;
 import tiled.mapeditor.actions.*;
 import tiled.mapeditor.brush.AbstractBrush;
-import tiled.mapeditor.brush.Brush;
 import tiled.mapeditor.brush.CustomBrush;
 import tiled.mapeditor.brush.ShapeBrush;
 import tiled.mapeditor.dialogs.*;
@@ -114,7 +114,8 @@
     private JTable      layerTable;
     private JList       editHistoryList;
     private MiniMapViewer miniMap;
-
+    private JSplitPane  paletteSplit;
+    
     private TileButton  tilePaletteButton;
     private JFrame      appFrame;
     private JSlider     opacitySlider;
@@ -133,8 +134,7 @@
     private JButton tileInstancePropertiesButton;
 
     /** Available brushes */
-    private Vector brushes = new Vector();
-    private Brush eraserBrush;
+    private Hashtable brushes = new Hashtable();
 
     // Actions
     private final SaveAction saveAction;
@@ -150,14 +150,17 @@
 
     private static final String IMPORT_ERROR_MSG = Resources.getString("dialog.newtileset.import.error.message");
 
-    private static final String TOOL_PAINT = Resources.getString("tool.paint.name");
-    private static final String TOOL_ERASE = Resources.getString("tool.erase.name");
-    private static final String TOOL_FILL = Resources.getString("tool.fill.name");
-    private static final String TOOL_EYE_DROPPER = Resources.getString("tool.eyedropper.name");
-    private static final String TOOL_SELECT = Resources.getString("tool.select.name");
-    private static final String TOOL_MOVE_LAYER = Resources.getString("tool.movelayer.name");
-    private static final String TOOL_MOVE_OBJECT = Resources.getString("tool.moveobject.name");
+    public static final String TOOL_PAINT = Resources.getString("tool.paint.name");
+    public static final String TOOL_ERASE = Resources.getString("tool.erase.name");
+    public static final String TOOL_FILL = Resources.getString("tool.fill.name");
+    public static final String TOOL_EYE_DROPPER = Resources.getString("tool.eyedropper.name");
+    public static final String TOOL_SELECT = Resources.getString("tool.select.name");
+    public static final String TOOL_MOVE_LAYER = Resources.getString("tool.movelayer.name");
+    public static final String TOOL_MOVE_OBJECT = Resources.getString("tool.moveobject.name");
+    public static final String TOOL_POINTER = "__pointer"; //used internally for brushes
 
+    private String currentTool = TOOL_POINTER;
+    
     public MapEditor() {
         /*
         eraserBrush = new Eraser();
@@ -301,9 +304,10 @@
         mainSplit.setBorder(null);
 
         tabbedTilesetsPane = new TabbedTilesetsPane(this);
-        JSplitPane paletteSplit = new JSplitPane(
+        paletteSplit = new JSplitPane(
                 JSplitPane.VERTICAL_SPLIT, true, mainSplit,
                 tabbedTilesetsPane);
+        
         paletteSplit.setOneTouchExpandable(true);
         paletteSplit.setResizeWeight(1.0);
 
@@ -1068,7 +1072,8 @@
                         Resources.getString("dialog.selection.empty"),
                         JOptionPane.WARNING_MESSAGE);
             } else {
-                setBrush(new CustomBrush(brushLayer));
+                setBrush(TOOL_PAINT, new CustomBrush(brushLayer));
+                setCurrentBrush(TOOL_PAINT);
             }
 
             //get rid of any visible marquee
@@ -1153,28 +1158,28 @@
 
         if ("paint".equals(command)) {
             setCurrentPointerState(PS_PAINT);
-            resetBrush();
+            currentTool = TOOL_PAINT;
         } else if ("erase".equals(command)) {
             setCurrentPointerState(PS_ERASE);
-            resetBrush();
+            currentTool = TOOL_ERASE;
         } else if ("point".equals(command)) {
             setCurrentPointerState(PS_POINT);
-            resetBrush();
+            currentTool = TOOL_POINTER;
         } else if ("pour".equals(command)) {
             setCurrentPointerState(PS_POUR);
-            resetBrush();
+            currentTool = TOOL_FILL;
         } else if ("eyed".equals(command)) {
             setCurrentPointerState(PS_EYED);
-            resetBrush();
+            currentTool = TOOL_EYE_DROPPER;
         } else if ("marquee".equals(command)) {
             setCurrentPointerState(PS_MARQUEE);
-            resetBrush();
+            currentTool = TOOL_SELECT;
         } else if ("move".equals(command)) {
             setCurrentPointerState(PS_MOVE);
-            resetBrush();
+            currentTool = TOOL_MOVE_LAYER;
         } else if ("moveobject".equals(command)) {
             setCurrentPointerState(PS_MOVEOBJ);
-            resetBrush();
+            currentTool = TOOL_MOVE_OBJECT;
         } else if ("palette".equals(command)) {
             if (currentMap != null) {
                 if (tilePaletteDialog == null) {
@@ -1190,6 +1195,8 @@
         } else {
             handleEvent(event);
         }
+        
+        setCurrentBrush(currentTool);
     }
 
     // TODO: Most if not all of the below should be moved into action objects,
@@ -1778,39 +1785,71 @@
         undoSupport.postEdit(mle);
     }
 
-    public void resetBrush() {
-        //FIXME: this is an in-elegant hack, but it gets the user out
-        //       of custom brush mode
-        //(reset the brush if necessary)
-        if (currentBrush instanceof CustomBrush) {
-            if (prefs.getBoolean("cursorhighlight", true)) {
-                Rectangle redraw = cursorHighlight.getBounds();
-                mapView.repaintRegion(redraw);
-            }
-            ShapeBrush sb = new ShapeBrush();
-            sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
-            sb.setTile(currentTile);
-            setBrush(sb);
-        }
+    public void resetBrushes() {
+        ShapeBrush sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        sb.setTile(currentTile);
+        setBrush(TOOL_PAINT, sb);
+        sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        setBrush(TOOL_ERASE, sb);
+        sb.setTile(null);
+        sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        setBrush(TOOL_EYE_DROPPER, sb);
+        sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        setBrush(TOOL_FILL, sb);
+        sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        setBrush(TOOL_SELECT, sb);
+        sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        setBrush(TOOL_MOVE_OBJECT, sb);
+        sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        setBrush(TOOL_MOVE_LAYER, sb);
+        sb = new ShapeBrush();
+        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+        setBrush(TOOL_POINTER, sb);
     }
 
-    public void setBrush(AbstractBrush brush) {
-        currentBrush = brush;
-
+    public void setCurrentBrush(String brush) {
+        
+        if (prefs.getBoolean("cursorhighlight", true) && mapView != null) {
+            Rectangle redraw = cursorHighlight.getBounds();
+            mapView.repaintRegion(redraw);
+        }
+        
+        //is it wrong that Tiled thinks in languages? ;)
+        currentBrush = (AbstractBrush) brushes.get(brush);
+        
         Rectangle brushRedraw = currentBrush.getBounds();
 
-        // Make sure it's clean
+        //Make sure it's clean
+        cursorHighlight.unselectAll();
+        
         cursorHighlight.setOffset(0, 0);
 
         // Resize and select the region
         cursorHighlight.resize(brushRedraw.width, brushRedraw.height, 0, 0);
         cursorHighlight.selectRegion(currentBrush.getShape());
+        
+        if(!(currentBrush instanceof CustomBrush)) {
+            ((ShapeBrush)currentBrush).setTile(currentTile);
+        }
+        
         /*if (currentBrush instanceof CustomBrush) {
             cursorHighlight.setVisible(false);
         } else {
             cursorHighlight.setVisible(true);
         }*/
     }
+    
+    public void setBrush(String tool, AbstractBrush brush) {
+        System.out.println("setting "+tool+" to "+brush);
+        brushes.put(tool, brush);
+    }
 
     public void updateTitle() {
         String title = Resources.getString("dialog.main.title");
@@ -1831,6 +1870,11 @@
         appFrame.setTitle(title);
     }
 
+    /**
+     * Checks to see if the undo stack is empty
+     * 
+     * @return <code>true</code> if there is an undo history, <code>false</code> otherwise.
+     */
     public boolean unsavedChanges() {
         return currentMap != null && undoHandler.canUndo() &&
                 !undoHandler.isAllSaved();
@@ -1969,10 +2013,9 @@
         boolean mapLoaded = currentMap != null;
 
         // Create a default brush (protect against a bug with custom brushes)
-        ShapeBrush sb = new ShapeBrush();
-        sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
-        setBrush(sb);
-
+        resetBrushes();
+        setCurrentBrush(TOOL_PAINT);
+        
         if (tilePaletteDialog != null) {
             tilePaletteDialog.setMap(currentMap);
         }
@@ -1988,6 +2031,7 @@
             tileCoordsLabel.setText(" ");
             zoomLabel.setText(" ");
             setCurrentTile(null);
+            paletteSplit.setDividerLocation(1.0f);
         } else {
             final Preferences display = prefs.node("display");
             mapEventAdapter.fireEvent(MapEventAdapter.ME_MAPACTIVE);
@@ -2029,13 +2073,20 @@
             Tile firstTile = null;
             if (!tilesets.isEmpty()) {
                 Iterator it = tilesets.iterator();
-                while (it.hasNext() && firstTile == null) {
-                    firstTile = ((TileSet) it.next()).getFirstTile();
+                while (it.hasNext()) {
+                    if( firstTile == null )
+                        firstTile = ((TileSet) it.next()).getFirstTile();
+                    
                 }
             }
             setCurrentTile(firstTile);
 
             currentMap.addLayerSpecial(cursorHighlight);
+            
+            Dimension d = paletteSplit.getSize();
+            //Doesn't this look icky? Still, proportional is better.
+            //FIXME: the constant is an expedient fudge factor- should be tileset max height + scrollbar height + tab height
+            paletteSplit.setDividerLocation(1.0 - ((currentMap.getTileHeightMax() + 45) / d.getHeight()));
         }
 
         zoomInAction.setEnabled(mapLoaded);
@@ -2091,12 +2142,19 @@
      * @param tile the new tile to be selected
      */
     public void setCurrentTile(Tile tile) {
-        resetBrush();
 
         if (currentTile != tile) {
             currentTile = tile;
             if (!(currentBrush instanceof CustomBrush)) {
                 ((ShapeBrush) currentBrush).setTile(tile);
+            } else {
+            	//if setCurrentTile() is called directly, we reset the brush
+            	//to get out of custom brush mode
+                ShapeBrush sb = new ShapeBrush();
+                sb.makeQuadBrush(new Rectangle(0, 0, 1, 1));
+                sb.setTile(currentTile);
+                setBrush(currentTool, sb);
+                setCurrentBrush(currentTool);
             }
             tilePaletteButton.setTile(currentTile);
         }

Modified: trunk/src/tiled/mapeditor/dialogs/BrushDialog.java
===================================================================
--- trunk/src/tiled/mapeditor/dialogs/BrushDialog.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/mapeditor/dialogs/BrushDialog.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -278,12 +278,14 @@
 
         if (source == okButton) {
             createFromOptions();
-            editor.setBrush(myBrush);
+            editor.setBrush(MapEditor.TOOL_PAINT, myBrush);
+            editor.setCurrentBrush(MapEditor.TOOL_PAINT);
             dispose();
         }
         else if (source == bApply) {
             createFromOptions();
-            editor.setBrush(myBrush);
+            editor.setBrush(MapEditor.TOOL_PAINT, myBrush);
+            editor.setCurrentBrush(MapEditor.TOOL_PAINT);
             bApply.setEnabled(false);
         }
         else if (source == bCancel) {

Modified: trunk/src/tiled/mapeditor/dialogs/TilePaletteDialog.java
===================================================================
--- trunk/src/tiled/mapeditor/dialogs/TilePaletteDialog.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/mapeditor/dialogs/TilePaletteDialog.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -117,7 +117,8 @@
     }
 
     public void tileRegionSelected(TileRegionSelectionEvent e) {
-        editor.setBrush(new CustomBrush(e.getTileRegion()));
+        editor.setBrush(MapEditor.TOOL_PAINT, new CustomBrush(e.getTileRegion()));
+        editor.setCurrentBrush(MapEditor.TOOL_PAINT);
     }
 
     public void valueChanged(ListSelectionEvent e) {

Modified: trunk/src/tiled/mapeditor/selection/SelectionLayer.java
===================================================================
--- trunk/src/tiled/mapeditor/selection/SelectionLayer.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/mapeditor/selection/SelectionLayer.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -97,6 +97,14 @@
     }
 
     /**
+     * Clears the entire selection
+     *
+     */
+    public void unselectAll() {
+        clearRegion(selection);
+    }
+    
+    /**
      * Sets the selected area to the given Shape.
      *
      * @param region
@@ -151,9 +159,9 @@
         for (int i = bounded.y; i < bounded.y + bounded.height; i++) {
             for (int j = bounded.x; j < bounded.x + bounded.width; j++) {
                 if (region.contains(j, i)) {
-                    setTileAt(j, i, fill);
+                    setTileAt(j+bounds.x, i+bounds.y, fill);
                 } else {
-                    setTileAt(j, i, null);
+                    setTileAt(j+bounds.x, i+bounds.y, null);
                 }
             }
         }

Modified: trunk/src/tiled/mapeditor/widget/TabbedTilesetsPane.java
===================================================================
--- trunk/src/tiled/mapeditor/widget/TabbedTilesetsPane.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/mapeditor/widget/TabbedTilesetsPane.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -15,6 +15,7 @@
 
 package tiled.mapeditor.widget;
 
+import java.awt.Dimension;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -67,13 +68,27 @@
         this.map = map;
     }
 
+    public Dimension getPreferredSize() {
+        Dimension d = new Dimension(0,0);
+        for (Iterator it = tilePanels.iterator(); it.hasNext();) {
+            TilePaletteQuickPanel panel = (TilePaletteQuickPanel) it.next();
+            Dimension e = panel.getPreferredSize();
+            if(d.width < e.width)
+                d.width = e.width;
+            if(d.height < e.height)
+                d.height = e.height;
+        }
+        
+        return d;
+    }
+    
     /**
      * Creates the panels for the tilesets.
      */
     private void recreateTabs(List tilesets) {
         // Stop listening to the tile palette panels
         for (Iterator it = tilePanels.iterator(); it.hasNext();) {
-            TilePalettePanel panel = (TilePalettePanel) it.next();
+            TilePaletteQuickPanel panel = (TilePaletteQuickPanel) it.next();
             panel.removeTileSelectionListener(this);
         }
         tilePanels.clear();
@@ -99,11 +114,11 @@
      * @param tileset the given tileset
      */
     private void addTabForTileset(TileSet tileset) {
-        TilePalettePanel tilePanel = new TilePalettePanel();
+        TilePaletteQuickPanel tilePanel = new TilePaletteQuickPanel();
         tilePanel.setTileset(tileset);
         tilePanel.addTileSelectionListener(this);
         JScrollPane paletteScrollPane = new JScrollPane(tilePanel,
-                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+                JScrollPane.VERTICAL_SCROLLBAR_NEVER,
                 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
         addTab(tileset.getName(), paletteScrollPane);
     }
@@ -120,7 +135,8 @@
      * current brush.
      */
     public void tileRegionSelected(TileRegionSelectionEvent e) {
-        mapEditor.setBrush(new CustomBrush(e.getTileRegion()));
+        mapEditor.setBrush(MapEditor.TOOL_PAINT, new CustomBrush(e.getTileRegion()));
+        mapEditor.setCurrentBrush(MapEditor.TOOL_PAINT);
     }
 
     private class MyMapChangeListener implements MapChangeListener

Added: trunk/src/tiled/mapeditor/widget/TilePaletteQuickPanel.java
===================================================================
--- trunk/src/tiled/mapeditor/widget/TilePaletteQuickPanel.java	2006-12-15 10:12:04 UTC (rev 710)
+++ trunk/src/tiled/mapeditor/widget/TilePaletteQuickPanel.java	2006-12-17 10:26:03 UTC (rev 711)
@@ -0,0 +1,256 @@
+/*
+ *  Tiled Map Editor, (c) 2004-2006
+ *
+ *  This program 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 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Adam Turk <aturk at biggeruniverse.com>
+ *  Bjorn Lindeijer <b.lindeijer at xs4all.nl>
+ */
+
+package tiled.mapeditor.widget;
+
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+import javax.swing.JPanel;
+import javax.swing.Scrollable;
+import javax.swing.event.MouseInputAdapter;
+
+import tiled.core.*;
+import tiled.mapeditor.util.TileSelectionEvent;
+import tiled.mapeditor.util.TileSelectionListener;
+
+/**
+ * Works very much like TilePalettePanel, but is more specialized, in that it 
+ * always displays all tiles in one row, and stamps cannot be made from it.
+ *
+ * @version $Id: TilePaletteQuickPanel.java 701 2006-10-14 20:23:44Z bjorn $
+ */
+public class TilePaletteQuickPanel extends JPanel implements Scrollable,
+       TilesetChangeListener
+{
+    private TileSet tileset;
+    private List tileSelectionListeners;
+    private Vector tilesetMap;
+    
+    public TilePaletteQuickPanel() {
+        tileSelectionListeners = new LinkedList();
+
+        MouseInputAdapter mouseInputAdapter = new MouseInputAdapter() {
+            private Point origin;
+
+            public void mousePressed(MouseEvent e) {
+                origin = new Point(e.getX() / (tileset.getTileWidth() + 1), 0);
+                Tile clickedTile = getTileAt(origin.x, origin.y);
+                if (clickedTile != null) {
+                    fireTileSelectionEvent(clickedTile);
+                }
+            }
+        };
+        addMouseListener(mouseInputAdapter);
+        addMouseMotionListener(mouseInputAdapter);
+    }
+    
+    /**
+     * Adds tile selection listener. The listener will be notified when the
+     * user selects a tile.
+     *
+     * @param listener the listener to add
+     */
+    public void addTileSelectionListener(TileSelectionListener listener) {
+        tileSelectionListeners.add(listener);
+    }
+
+    /**
+     * Removes tile selection listener.
+     *
+     * @param listener the listener to remove
+     */
+    public void removeTileSelectionListener(TileSelectionListener listener) {
+        tileSelectionListeners.remove(listener);
+    }
+
+    private void fireTileSelectionEvent(Tile selectedTile) {
+        TileSelectionEvent event = new TileSelectionEvent(this, selectedTile);
+        Iterator iterator = tileSelectionListeners.iterator();
+
+        while (iterator.hasNext()) {
+            ((TileSelectionListener) iterator.next()).tileSelected(event);
+        }
+    }
+    
+    /**
+     * Draws checkerboard background.
+     *
+     * @param g the {@link Graphics} instance to draw on
+     */
+    private static void paintBackground(Graphics g) {
+        Rectangle clip = g.getClipBounds();
+        int side = 10;
+
+        int startX = clip.x / side;
+        int startY = clip.y / side;
+        int endX = (clip.x + clip.width) / side + 1;
+        int endY = (clip.y + clip.height) / side + 1;
+
+        // Fill with white background
+        g.setColor(Color.WHITE);
+        g.fillRect(clip.x, clip.y, clip.width, clip.height);
+
+        // Draw darker squares
+        g.setColor(Color.LIGHT_GRAY);
+        for (int y = startY; y < endY; y++) {
+            for (int x = startX; x < endX; x++) {
+                if ((y + x) % 2 == 1) {
+                    g.fillRect(x * side, y * side, side, side);
+                }
+            }
+        }
+    }
+
+    public Dimension getPreferredSize() {
+        if (tileset == null) {
+            return new Dimension(0, 0);
+        }
+        else {
+            int twidth = tileset.getTileWidth() + 1;
+            int theight = tileset.getTileHeight() + 1;
+            int tileCount = tilesetMap.size();
+
+            return new Dimension(tileCount * (twidth + 1), theight + 1);
+        }
+    }
+
+
+    // Scrollable interface
+
+    public Dimension getPreferredScrollableViewportSize() {
+        if (tileset != null) {
+            int twidth = tileset.getTileWidth() + 1;
+            int theight = tileset.getTileHeight() + 1;
+            int tileCount = tilesetMap.size();
+
+            return new Dimension(Math.max(1, (getWidth() - 1)), theight);
+        } else {
+            return new Dimension(0, 0);
+        }
+    }
+
+    public int getScrollableUnitIncrement(Rectangle visibleRect,
+            int orientation, int direction) {
+        if (tileset != null) {
+            return tileset.getTileWidth();
+        } else {
+            return 0;
+        }
+    }
+
+    public int getScrollableBlockIncrement(Rectangle visibleRect,
+            int orientation, int direction) {
+        if (tileset != null) {
+            return tileset.getTileWidth();
+        } else {
+            return 0;
+        }
+    }
+
+    public boolean getScrollableTracksViewportWidth() {
+        // todo: Update when this has become an option
+        return false;
+    }
+
+    public boolean getScrollableTracksViewportHeight() {
+        return tileset == null || tileset.getTilesPerRow() == 0;
+    }
+
+    public void paint(Graphics g) {
+        Rectangle clip = g.getClipBounds();
+
+        paintBackground(g);
+
+        if (tileset != null) {
+            // Draw the tiles
+            int twidth = tileset.getTileWidth() + 1;
+            int theight = tileset.getTileHeight() + 1;
+            int tilesPerRow = Math.max(1, (getWidth() - 1) / twidth);
+
+            int startY = clip.y / theight;
+            int endY = (clip.y + clip.height) / theight + 1;
+            int tileAt = tilesPerRow * startY;
+            int gx;
+            int gy = startY * theight;
+
+            for (int y = startY; y < endY; y++) {
+                gx = 1;
+
+                for (int x = 0;
+                     x < tilesPerRow && tileAt < tilesetMap.size();
+                     x++, tileAt++)
+                {
+                    Tile tile = (Tile) tilesetMap.get(tileAt);
+
+                    if (tile != null) {
+                        tile.drawRaw(g, gx, gy + theight, 1.0);
+                    }
+                    gx += twidth;
+                }
+                gy += theight;
+            }
+        }
+    }
+    
+    /**
+     * Retrieves the tile at the given tile coordinates. It assumes the tile
+     * coordinates are adjusted to the number of tiles per row.
+     *
+     * @param x x tile coordinate
+     * @param y y tile coordinate
+     * @return the tile at the given tile coordinates, or <code>null</code>
+     *         if the index is out of range
+     */
+    private Tile getTileAt(int x, int y) {
+        //we don't care about y, but it's here for convention
+
+        if (x >= tilesetMap.size()) {
+            return null;
+        } else {
+            return (Tile) tilesetMap.get(x);
+        }
+    }
+    
+    /**
+     * Change the tileset displayed by this palette panel.
+     *
+     * @param tileset the tileset to be displayed by this palette panel
+     */
+    public void setTileset(TileSet tileset) {
+        // Remove any existing listener
+        if (this.tileset != null) {
+            this.tileset.removeTilesetChangeListener(this);
+        }
+
+        this.tileset = tileset;
+
+        // Listen to changes in the new tileset
+        if (this.tileset != null) {
+            this.tileset.addTilesetChangeListener(this);
+        }
+
+        if (tileset != null) tilesetMap = tileset.generateGaplessVector();
+        revalidate();
+        repaint();
+    }
+
+    public void tilesetChanged(TilesetChangedEvent event) {
+        tilesetMap = tileset.generateGaplessVector();
+        revalidate();
+        repaint();
+    }
+
+}




More information about the tiled-commit mailing list