trying to add Id tags in tilemanager files
[supertux.git] / tools / tilemanager / Application.cs
index 457132f..22fbf8d 100644 (file)
@@ -1,9 +1,9 @@
+//  $Id$
 using System;
 using System.IO;
 using System.Collections;
 using Gtk;
 using Gdk;
-using Gnome;
 using Glade;
 
 public class Application {
@@ -24,15 +24,13 @@ public class Application {
     [Glade.Widget]
     private Gtk.CheckButton DontUseCheckButton;
     [Glade.Widget]
+    private Gtk.CheckButton HiddenCheckButton;
+    [Glade.Widget]
     private Gtk.Entry DataEntry;
     [Glade.Widget]
     private Gtk.Entry AnimFpsEntry;
-    [Glade.Widget]                 
-    private Gtk.Entry IDEntry;
-    [Glade.Widget]
-    private Gnome.AppBar AppBar;
     [Glade.Widget]
-    private Gtk.VBox MainLayout;
+    private Gtk.Entry IDEntry;
     [Glade.Widget]
     private Gtk.TreeView TileList;
     [Glade.Widget]
@@ -40,6 +38,11 @@ public class Application {
     [Glade.Widget]
     private Gtk.MenuItem AddTileGroupMenu;
 
+    [Glade.Widget]
+    private Gtk.Dialog RemapDialog;
+    [Glade.Widget]
+    private Gtk.SpinButton RD_spinButton;
+
     private string tilesetdir;
     private string tilesetfile;
     private TileSet tileset;
@@ -55,9 +58,9 @@ public class Application {
 
     private string currentimage;
     private Gdk.Pixbuf pixbuf;
-    
+
     public static int Main(string[] args) {
-        Program kit = new Program("tiler", "0.0.1", Modules.UI, args);
+        Gtk.Application.Init();
 
         Application app = new Application();
 
@@ -65,7 +68,7 @@ public class Application {
         if(args.Length == 1)
             app.LoadTileSet(args[0]);
 
-        kit.Run();
+        Gtk.Application.Run();
         return 0;
     }
 
@@ -73,39 +76,47 @@ public class Application {
         Glade.XML gxml = new Glade.XML(null, "tiler.glade", null, null);
         gxml.Autoconnect(this);
 
-        if(MainWindow == null || DrawingArea == null || AppBar == null)
-            throw new Exception("soem widgets not found");
+        if(MainWindow == null || DrawingArea == null || RemapDialog == null)
+            throw new Exception("some widgets not found");
 
         DrawingArea.AddEvents((int) Gdk.EventMask.ButtonPressMask);
         DrawingArea.AddEvents((int) Gdk.EventMask.ButtonReleaseMask);
         DrawingArea.AddEvents((int) Gdk.EventMask.ButtonMotionMask);
 
-        // libglade missed interactivity property :-/
-        MainLayout.Remove(AppBar);
-        AppBar = new AppBar(true, true, PreferencesType.Always);
-        AppBar.UserResponse += new EventHandler(OnAppBarUserResponse);
-        MainLayout.PackStart(AppBar, false, false, 0);
-        AppBar.Show();
-
-        TileGroupComboBox.Entry.Activated 
-            += new EventHandler (OnTileGroupComboBoxEntryActivated);
-        
         MainWindow.Show();
     }
 
-    private void OnOpen(object o, EventArgs e) {
-        FileSelection selection = new FileSelection("Select TileSet");
-        selection.OkButton.Clicked += new EventHandler(OnSelectTileSetOk);
-        selection.CancelButton.Clicked += new EventHandler(OnSelectImageCancel);
-        selection.Show();
-    }
-
-    private void OnSelectTileSetOk(object o, EventArgs e) {
-        FileSelection selection = ((FileSelection.FSButton) o).FileSelection;
-        string file = selection.Filename;
-        selection.Destroy();
-
-        LoadTileSet(file);
+    protected void OnOpen(object o, EventArgs e) {
+       FileChooserDialog fileChooser = new FileChooserDialog("Select TileSet", MainWindow, FileChooserAction.Open, new object[] {});
+
+       fileChooser.AddButton(Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+       fileChooser.AddButton(Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+       fileChooser.DefaultResponse = Gtk.ResponseType.Ok;
+       Gtk.FileFilter filter;
+       filter = new Gtk.FileFilter();
+       filter.Name = "Supertux tilesets";
+       filter.AddPattern("*.strf");
+       filter.AddPattern("*.stgt");
+       fileChooser.AddFilter( filter );
+       filter = new Gtk.FileFilter();
+       filter.Name = "Supertux 0.1.x tilesets";
+       filter.AddPattern("*.stgt");
+       fileChooser.AddFilter( filter );
+       filter = new Gtk.FileFilter();
+       filter.Name = "Supertux 0.3.x tilesets";
+       filter.AddPattern("*.strf");
+       fileChooser.AddFilter( filter );
+       Gtk.FileFilter all = new Gtk.FileFilter();
+       all.Name = "All Files";
+       all.AddPattern("*");
+       fileChooser.AddFilter( all );
+       int result = fileChooser.Run();
+       fileChooser.Hide();
+
+       if(result != (int) ResponseType.Ok)
+               return;
+
+        LoadTileSet(fileChooser.Filename);
     }
 
     private void LoadTileSet(string file) {
@@ -124,34 +135,42 @@ public class Application {
         FillTileList();
     }
 
-    private void OnImportImage(object o, EventArgs e) {
-        FileSelection selection = new FileSelection("Select ImageFile");
-        selection.OkButton.Clicked += new EventHandler(OnSelectImageOk);
-        selection.CancelButton.Clicked += new EventHandler(OnSelectImageCancel);
-        selection.Show();                           
-    }
+    protected void OnImportImage(object o, EventArgs e) {
+       FileChooserDialog fileChooser = new FileChooserDialog("Select ImageFile", MainWindow, FileChooserAction.Open, new object[] {});
+
+       fileChooser.AddButton(Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
+       fileChooser.AddButton(Gtk.Stock.Ok, Gtk.ResponseType.Ok);
+       fileChooser.DefaultResponse = Gtk.ResponseType.Ok;
+       Gtk.FileFilter all = new Gtk.FileFilter();
+       all.Name = "All Files";
+       all.AddPattern("*");
+       fileChooser.AddFilter( all );
+       int result = fileChooser.Run();
+       fileChooser.Hide();
+
+       if(result != (int) ResponseType.Ok)
+               return;
+
+       string file = fileChooser.Filename;
+       string trim = tilesetdir + "/";
+
+       if (!file.StartsWith(trim)){
+               Console.WriteLine(
+                       "Imported file must be located inside tileset directory");
+               return;
+       }
+
+        ChangeImage(file.TrimStart(trim.ToCharArray()));
 
-    private void OnSelectImageCancel(object o, EventArgs args) {
-        FileSelection selection = ((FileSelection.FSButton) o).FileSelection;
-        selection.Destroy();
-    }
-    
-    private void OnSelectImageOk(object o, EventArgs args) {
-        FileSelection selection = ((FileSelection.FSButton) o).FileSelection;
-        string file = selection.Filename;
-        selection.Destroy();
-
-        ChangeImage(new FileInfo(file).Name);
-        
         int startid = tileset.Tiles.Count;
         for(int y = 0; y < TilesY; ++y) {
             for(int x = 0; x < TilesX; ++x) {
                 int i = y*TilesX+x;
-                Tile tile = new Tile();                                   
+                Tile tile = new Tile();
                 tile.ID = startid + i;
                 ImageRegion region = new ImageRegion();
                 region.ImageFile = currentimage;
-                region.Region = new Rectangle(x*32, y*32, 32, 32);
+                region.Region = new System.Drawing.Rectangle(x*TileSet.TILE_WIDTH, y*TileSet.TILE_HEIGHT, TileSet.TILE_WIDTH, TileSet.TILE_HEIGHT);
                 tile.Images.Add(region);
                 if(Tiles[i] != null) {
                     Console.WriteLine(
@@ -173,19 +192,18 @@ public class Application {
         }
         try {
             pixbuf = new Pixbuf(tilesetdir + "/" + file);
-            if(pixbuf.Width % 32 != 0 || pixbuf.Height % 32 != 0)
-                throw new Exception(
-                        "Image Width or Height is not a multiple of 32");
+            if(pixbuf.Width % TileSet.TILE_WIDTH != 0 || pixbuf.Height % TileSet.TILE_HEIGHT != 0)
+                Console.WriteLine("Warning: Image Width or Height is not a multiple of 32");
         } catch(Exception e) {
             ShowException(e);
             return;
         }
         currentimage = new FileInfo(file).Name;
-        TilesX = pixbuf.Width / 32;
-        TilesY = pixbuf.Height / 32;
+        TilesX = pixbuf.Width / TileSet.TILE_WIDTH;
+        TilesY = pixbuf.Height / TileSet.TILE_HEIGHT;
         SelectionArray = new bool[TilesX * TilesY];
         Tiles = new Tile[TilesX * TilesY];
-        
+
         // search tileset for tiles with matching image
         foreach(Tile tile in tileset.Tiles) {
             if(tile == null)
@@ -194,8 +212,8 @@ public class Application {
                 continue;
             ImageRegion region = (ImageRegion) tile.Images[0];
             if(region.ImageFile == currentimage) {
-                int px = region.Region.X / 32;
-                int py = region.Region.Y / 32;
+                int px = region.Region.X / TileSet.TILE_WIDTH;
+                int py = region.Region.Y / TileSet.TILE_HEIGHT;
                 int i = py*TilesX+px;
                 if(i < 0 || i >= Tiles.Length) {
                     Console.WriteLine("Invalid Imageregion at tile " +
@@ -204,77 +222,127 @@ public class Application {
                 }
                 if(Tiles[i] != null) {
                     Console.WriteLine("Multiple tiles for region " +
-                            px*32 + " , " + py*32);
+                            px*TileSet.TILE_WIDTH + " , " + py*TileSet.TILE_HEIGHT);
                     continue;
                 }
                 Tiles[i] = tile;
             }
-        } 
+        }
 
-        /*   DrawingArea.Allocation 
+        /*   DrawingArea.Allocation
             = new Gdk.Rectangle(0, 0, pixbuf.Width, pixbuf.Height);*/
         DrawingArea.WidthRequest = pixbuf.Width;
         DrawingArea.HeightRequest = pixbuf.Height;
         DrawingArea.QueueResize();
     }
 
-    private void OnSave(object o, EventArgs e) {
-        tileset.Write(tilesetfile);
+    protected void OnSave(object o, EventArgs e) {
+       if (tileset.TooNew)
+               Console.WriteLine(
+               "Sorry, the file you are editing is too new, there will be huge data loss if you save this.");
+       else
+               tileset.Write(tilesetfile);
     }
 
-    private void OnQuit(object o, EventArgs e) {
+    protected void OnQuit(object o, EventArgs e) {
         Gtk.Application.Quit();
     }
 
-    private void OnAbout(object o, EventArgs e) {
+    protected void OnDeleteQuit(object o, DeleteEventArgs e) {
+        Gtk.Application.Quit();
     }
 
-    private void OnRemapTiles(object o, EventArgs e) {
-        AppBar.SetPrompt("Start-ID:", true);
+    protected void OnAbout(object o, EventArgs e) {
+//             string[] authors = new string[]{
+//                     "<autors?>",
+//             };
+
+               Gtk.AboutDialog dialog = new Gtk.AboutDialog();
+//             dialog.Icon = <icon>;
+               dialog.ProgramName = "SuperTux Tiler";
+               dialog.Version = "0.0.3";
+               dialog.Comments = "A tileset editor for SuperTux 0.1.x";
+//             dialog.Authors = authors;
+               dialog.Copyright = "Copyright (c) 2006 SuperTux Devel Team";
+               dialog.License =
+                       "This program is free software; you can redistribute it and/or modify" + Environment.NewLine +
+                       "it under the terms of the GNU General Public License as published by" + Environment.NewLine +
+                       "the Free Software Foundation; either version 2 of the License, or" + Environment.NewLine +
+                       "(at your option) any later version." + Environment.NewLine +
+                       Environment.NewLine +
+                       "This program is distributed in the hope that it will be useful," + Environment.NewLine +
+                       "but WITHOUT ANY WARRANTY; without even the implied warranty of" + Environment.NewLine +
+                       "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" + Environment.NewLine +
+                       "GNU General Public License for more details." + Environment.NewLine +
+                       Environment.NewLine +
+                       "You should have received a copy of the GNU General Public License" + Environment.NewLine +
+                       "along with this program; if not, write to the Free Software Foundation, Inc.," + Environment.NewLine +
+                       "59 Temple Place, Suite 330, Boston, MA 02111-1307 USA" + Environment.NewLine;
+               dialog.Website = "http://supertux.lethargik.org/";
+               dialog.WebsiteLabel = "SuperTux on the Web";
+               dialog.Run();
+               dialog.Destroy();
     }
 
-    private void OnCreateTileGroup(object o, EventArgs e) {
+    protected void OnRemapTiles(object o, EventArgs e) {
+       if(Tiles == null)
+               return;
+       RemapDialog.Show();
     }
 
-    private void OnRenameTileGroup(object o, EventArgs e) {
+    protected void OnRemapDialogCancel(object o, EventArgs e) {
+       RemapDialog.Hide();
     }
 
-    private void OnAppBarUserResponse(object o, EventArgs e) {
+    protected void OnRemapDialogApply(object o, EventArgs e) {
+       RemapDialog.Hide();
         try {
-            if(AppBar.Response == null || AppBar.Response == "" 
-                    || Tiles == null)
-                return;
-        
+
             // remap tiles
             int id;
             try {
-                id = Int32.Parse(AppBar.Response);
+                id = RD_spinButton.ValueAsInt;
             } catch(Exception exception) {
                 ShowException(exception);
                 return;
             }
-            foreach(Tile tile in Selection) {
-                if(tile.ID == -1)
-                    continue;
-                
-                int oldid = tile.ID;
-                tile.ID = id++;
-                // remap in all tilegroups...
-                foreach(TileGroup tilegroup in tileset.TileGroups) {
-                    int idx = tilegroup.Tiles.IndexOf(oldid);
-                    if(idx >= 0) {
-                        tilegroup.Tiles[idx] = tile.ID;
-                    }
-                }
-            }
-            FillTileList();
-            SelectionChanged();
+            RemapTiles(id);
         } finally {
-            AppBar.ClearPrompt();
+            RD_spinButton.Value = 1;
         }
     }
 
-    private void OnDrawingAreaExpose(object o, ExposeEventArgs e) {
+    protected void OnCreateTileGroup(object o, EventArgs e) {
+    }
+
+    protected void OnRenameTileGroup(object o, EventArgs e) {
+    }
+
+    protected void RemapTiles(int startID) {
+       if(Tiles == null)
+               return;
+
+       // remap tiles
+       int id = startID;
+       foreach(Tile tile in Selection) {
+               if(tile.ID == -1)
+                       continue;
+
+               int oldid = tile.ID;
+               tile.ID = id++;
+               // remap in all tilegroups...
+               foreach(TileGroup tilegroup in tileset.TileGroups) {
+                       int idx = tilegroup.Tiles.IndexOf(oldid);
+                       if(idx >= 0) {
+                               tilegroup.Tiles[idx] = tile.ID;
+                       }
+               }
+       }
+       FillTileList();
+       SelectionChanged();
+    }
+
+    protected void OnDrawingAreaExpose(object o, ExposeEventArgs e) {
         if(pixbuf == null)
             return;
 
@@ -285,7 +353,7 @@ public class Application {
 
         gc.RgbFgColor = new Color(0xff, 0, 0);
         foreach(Tile tile in Selection) {
-            System.Drawing.Rectangle rect 
+            System.Drawing.Rectangle rect
                 = ((ImageRegion) tile.Images[0]).Region;
             drawable.DrawRectangle(gc, false, rect.X, rect.Y, rect.Width,
                     rect.Height);
@@ -294,19 +362,19 @@ public class Application {
         e.RetVal = false;
     }
 
-    private void OnDrawingAreaButtonPress(object o, ButtonPressEventArgs e) {
+    protected void OnDrawingAreaButtonPress(object o, ButtonPressEventArgs e) {
         if(SelectionArray == null)
             return;
 
         selecting = true;
-        
+
         for(int i = 0; i < SelectionArray.Length; ++i)
             SelectionArray[i] = false;
         select((int) e.Event.X, (int) e.Event.Y);
     }
 
     private void select(int x, int y) {
-        int tile = y/32 * TilesX + x/32;
+        int tile = y/TileSet.TILE_HEIGHT * TilesX + x/TileSet.TILE_WIDTH;
         if(tile < 0 || tile >= SelectionArray.Length)
             return;
 
@@ -314,36 +382,38 @@ public class Application {
         SelectionArrayChanged();
     }
 
-    private void OnDrawingAreaMotionNotify(object i, MotionNotifyEventArgs e) {
+    protected void OnDrawingAreaMotionNotify(object i, MotionNotifyEventArgs e) {
         if(!selecting)
             return;
         select((int) e.Event.X, (int) e.Event.Y);
     }
 
-    private void OnDrawingAreaButtonRelease(object o, ButtonPressEventArgs e) {
+    protected void OnDrawingAreaButtonRelease(object o, ButtonPressEventArgs e) {
         selecting = false;
     }
 
-    private void OnCheckButtonToggled(object sender, EventArgs e) {
+    protected void OnCheckButtonToggled(object sender, EventArgs e) {
         if(toggling)
             return;
         foreach(Tile tile in Selection) {
             if(sender == SolidCheckButton)
-                tile.Solid = SolidCheckButton.Active;
+                tile.SetAttribute(Attribute.SOLID, SolidCheckButton.Active);
             if(sender == UniSolidCheckButton)
-                tile.UniSolid = UniSolidCheckButton.Active;
+                tile.SetAttribute(Attribute.UNISOLID, UniSolidCheckButton.Active);
             if(sender == IceCheckButton)
-                tile.Ice = IceCheckButton.Active;
+                tile.SetAttribute(Attribute.ICE, IceCheckButton.Active);
             if(sender == WaterCheckButton)
-                tile.Water = WaterCheckButton.Active;
+                tile.SetAttribute(Attribute.WATER, WaterCheckButton.Active);
             if(sender == SlopeCheckButton)
-                tile.Slope = SlopeCheckButton.Active;
+                tile.SetAttribute(Attribute.SLOPE, SlopeCheckButton.Active);
+            if(sender == HiddenCheckButton)
+                tile.Hidden = HiddenCheckButton.Active;
             if(sender == DontUseCheckButton)
                 tile.ID = DontUseCheckButton.Active ? -1 : 0;
         }
     }
 
-    private void OnEntryChanged(object sender, EventArgs e) {
+    protected void OnEntryChanged(object sender, EventArgs e) {
         if(toggling)
             return;
         foreach(Tile tile in Selection) {
@@ -354,7 +424,7 @@ public class Application {
                     tile.Data = Int32.Parse(DataEntry.Text);
                 if(sender == AnimFpsEntry)
                     tile.AnimFps = Single.Parse(AnimFpsEntry.Text);
-            } catch(Exception exception) {
+            } catch(Exception) {
                 // ignore parse errors for now...
             }
         }
@@ -365,7 +435,7 @@ public class Application {
         for(int i = 0; i < SelectionArray.Length; ++i) {
             if(!SelectionArray[i])
                 continue;
-            
+
             if(Tiles[i] == null) {
                 Console.WriteLine("Tile doesn't exist yet");
                 // TODO ask user to create new tile...
@@ -383,16 +453,17 @@ public class Application {
         string nextimage = "";
         foreach(Tile tile in Selection) {
             if(first) {
-                SolidCheckButton.Active = tile.Solid;
-                UniSolidCheckButton.Active = tile.UniSolid;
-                IceCheckButton.Active = tile.Ice;
-                WaterCheckButton.Active = tile.Water;
-                SlopeCheckButton.Active = tile.Slope;
+                SolidCheckButton.Active = tile.HasAttribute(Attribute.SOLID);
+                UniSolidCheckButton.Active = tile.HasAttribute(Attribute.UNISOLID);
+                IceCheckButton.Active = tile.HasAttribute(Attribute.ICE);
+                WaterCheckButton.Active = tile.HasAttribute(Attribute.WATER);
+                SlopeCheckButton.Active = tile.HasAttribute(Attribute.SLOPE);
+                HiddenCheckButton.Active = tile.Hidden;
                 DontUseCheckButton.Active = tile.ID == -1;
                 DataEntry.Text = tile.Data.ToString();
                 AnimFpsEntry.Text = tile.AnimFps.ToString();
                 IDEntry.Text = tile.ID.ToString();
-                IDEntry.Editable = true;
+                IDEntry.IsEditable = true;
                 first = false;
 
                 if(tile.Images.Count > 0) {
@@ -400,11 +471,11 @@ public class Application {
                 }
             } else {
                 IDEntry.Text += "," + tile.ID.ToString();
-                IDEntry.Editable = false;
-                if(tile.Images.Count > 0 
+                IDEntry.IsEditable = false;
+                if(tile.Images.Count > 0
                         && ((ImageRegion) tile.Images[0]).ImageFile != nextimage) {
                     nextimage = "";
-                    pixbuf = null;       
+                    pixbuf = null;
                 }
             }
         }
@@ -429,7 +500,13 @@ public class Application {
             }
         } else {
             foreach(int id in selectedgroup.Tiles) {
-                Tile tile = (Tile) tileset.Tiles[id];
+               Tile tile;
+               if (id >= tileset.Tiles.Count){
+                       Console.WriteLine("Tile ID is above Tiles.Count: " + id.ToString());
+                       continue;
+               } else {
+                       tile = (Tile) tileset.Tiles[id];
+               }
                 if(tile == null) {
                     Console.WriteLine("tilegroup contains deleted tile");
                     continue;
@@ -437,7 +514,7 @@ public class Application {
                 store.AppendValues(new object[] { id.ToString() });
             }
         }
-        
+
         TileList.Model = store;
         TileList.Selection.Mode = SelectionMode.Multiple;
     }
@@ -453,12 +530,12 @@ public class Application {
             //submenu.Add(new MenuItem(tilegroup));
         }
         TileGroupComboBox.PopdownStrings = groups;
-        TileGroupComboBox.Entry.Editable = false;
+        TileGroupComboBox.Entry.IsEditable = false;
 
         //AddTileGroupMenu.Submenu = submenu;
     }
 
-    private void OnTileGroupComboBoxEntryActivated(object o, EventArgs args) {
+    protected void OnTileGroupComboBoxEntryActivated(object o, EventArgs args) {
         if(TileGroupComboBox.Entry.Text == "All") {
             selectedgroup = null;
         } else {
@@ -472,10 +549,10 @@ public class Application {
         FillTileList();
     }
 
-    private void OnTileListCursorChanged(object sender, EventArgs e) {
+    protected void OnTileListCursorChanged(object sender, EventArgs e) {
         TreeModel model;
         TreePath[] selectpaths =
-            TileList.Selection.GetSelectedRows(out model); 
+            TileList.Selection.GetSelectedRows(out model);
 
         Selection.Clear();
         foreach(TreePath path in selectpaths) {