--- /dev/null
+using System;
+using System.IO;
+using System.Collections;
+using Gtk;
+using Gdk;
+using Gnome;
+using Glade;
+
+public class Application {
+ [Glade.Widget]
+ private Gtk.Window MainWindow;
+ [Glade.Widget]
+ private Gtk.DrawingArea DrawingArea;
+ [Glade.Widget]
+ private Gtk.CheckButton SolidCheckButton;
+ [Glade.Widget]
+ private Gtk.CheckButton UniSolidCheckButton;
+ [Glade.Widget]
+ private Gtk.CheckButton IceCheckButton;
+ [Glade.Widget]
+ private Gtk.CheckButton WaterCheckButton;
+ [Glade.Widget]
+ private Gtk.CheckButton SlopeCheckButton;
+ [Glade.Widget]
+ private Gtk.CheckButton DontUseCheckButton;
+ [Glade.Widget]
+ private Gtk.Entry DataEntry;
+ [Glade.Widget]
+ private Gtk.Entry AnimSpeedEntry;
+ [Glade.Widget]
+ private Gtk.Entry IDEntry;
+ [Glade.Widget]
+ private Gnome.AppBar AppBar;
+ [Glade.Widget]
+ private Gtk.VBox MainLayout;
+ [Glade.Widget]
+ private Gtk.TreeView TileList;
+ [Glade.Widget]
+ private Gtk.Combo TileGroupComboBox;
+ [Glade.Widget]
+ private Gtk.MenuItem AddTileGroupMenu;
+
+ private string tilesetdir;
+ private string tilesetfile;
+ private TileSet tileset;
+ private TileGroup selectedgroup;
+
+ private Tile[] Tiles;
+ private bool[] SelectionArray;
+ private ArrayList Selection = new ArrayList();
+ private int TilesX;
+ private int TilesY;
+ private bool toggling;
+ private bool selecting;
+
+ private string currentimage;
+ private Gdk.Pixbuf pixbuf;
+
+ public static int Main(string[] args) {
+ Program kit = new Program("tiler", "0.0.1", Modules.UI, args);
+
+ Application app = new Application();
+
+ kit.Run();
+ return 0;
+ }
+
+ public Application() {
+ Glade.XML gxml = new Glade.XML("tiler.glade", null, null);
+ gxml.Autoconnect(this);
+
+ if(MainWindow == null || DrawingArea == null || AppBar == null)
+ throw new Exception("soem 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();
+
+ try {
+ tileset = new TileSet();
+ tileset.Parse(file);
+ tilesetfile = file;
+ tilesetdir = new FileInfo(file).Directory.ToString();
+ } catch(Exception exception) {
+ ShowException(exception);
+ }
+
+ Selection.Clear();
+ SelectionChanged();
+ FillTileGroupComboBox();
+ 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();
+ }
+
+ 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.ID = startid + i;
+ ImageRegion region = new ImageRegion();
+ region.ImageFile = currentimage;
+ region.Region = new Rectangle(x*32, y*32, 32, 32);
+ tile.Images.Add(region);
+ if(Tiles[i] != null) {
+ Console.WriteLine(
+ "Warning Tile in this region already existed...");
+ }
+ Tiles[i] = tile;
+ tileset.Tiles.Add(tile);
+ }
+ }
+
+ FillTileList();
+ }
+
+ private void ChangeImage(string file) {
+ if(file == "") {
+ currentimage = "";
+ pixbuf = null;
+ return;
+ }
+ 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");
+ } catch(Exception e) {
+ ShowException(e);
+ return;
+ }
+ currentimage = new FileInfo(file).Name;
+ TilesX = pixbuf.Width / 32;
+ TilesY = pixbuf.Height / 32;
+ 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)
+ continue;
+ if(tile.Images.Count == 0)
+ continue;
+ ImageRegion region = (ImageRegion) tile.Images[0];
+ if(region.ImageFile == currentimage) {
+ int px = region.Region.X / 32;
+ int py = region.Region.Y / 32;
+ int i = py*TilesX+px;
+ if(i < 0 || i >= Tiles.Length) {
+ Console.WriteLine("Invalid Imageregion at tile " +
+ tile.ID);
+ continue;
+ }
+ if(Tiles[i] != null) {
+ Console.WriteLine("Multiple tiles for region " +
+ px*32 + " , " + py*32);
+ continue;
+ }
+ Tiles[i] = tile;
+ }
+ }
+
+ /* 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);
+ }
+
+ private void OnQuit(object o, EventArgs e) {
+ Gtk.Application.Quit();
+ }
+
+ private void OnAbout(object o, EventArgs e) {
+ }
+
+ private void OnRemapTiles(object o, EventArgs e) {
+ AppBar.SetPrompt("Start-ID:", true);
+ }
+
+ private void OnCreateTileGroup(object o, EventArgs e) {
+ }
+
+ private void OnRenameTileGroup(object o, EventArgs e) {
+ }
+
+ private void OnAppBarUserResponse(object o, EventArgs e) {
+ try {
+ if(AppBar.Response == null || AppBar.Response == ""
+ || Tiles == null)
+ return;
+
+ // remap tiles
+ int id;
+ try {
+ id = Int32.Parse(AppBar.Response);
+ } catch(Exception exception) {
+ ShowException(exception);
+ return;
+ }
+ foreach(Tile tile in Selection) {
+ if(tile.ID != -1)
+ tile.ID = id++;
+ }
+ FillTileList();
+ SelectionChanged();
+ } finally {
+ AppBar.ClearPrompt();
+ }
+ }
+
+ private void OnDrawingAreaExpose(object o, ExposeEventArgs e) {
+ if(pixbuf == null)
+ return;
+
+ Drawable drawable = e.Event.Window;
+ Gdk.GC gc = new Gdk.GC(drawable);
+ drawable.DrawPixbuf(gc, pixbuf, 0, 0, 0, 0,
+ pixbuf.Width, pixbuf.Height, RgbDither.None, 0, 0);
+
+ gc.RgbFgColor = new Color(0xff, 0, 0);
+ foreach(Tile tile in Selection) {
+ System.Drawing.Rectangle rect
+ = ((ImageRegion) tile.Images[0]).Region;
+ drawable.DrawRectangle(gc, false, rect.X, rect.Y, rect.Width,
+ rect.Height);
+ }
+
+ e.RetVal = false;
+ }
+
+ private void OnDrawingAreaButtonPress(object o, ButtonPressEventArgs e) {
+ 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;
+ if(tile < 0 || tile >= SelectionArray.Length)
+ return;
+
+ SelectionArray[tile] = true;
+ SelectionArrayChanged();
+ }
+
+ private 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) {
+ selecting = false;
+ }
+
+ private void OnCheckButtonToggled(object sender, EventArgs e) {
+ if(toggling)
+ return;
+ foreach(Tile tile in Selection) {
+ if(sender == SolidCheckButton)
+ tile.Solid = SolidCheckButton.Active;
+ if(sender == UniSolidCheckButton)
+ tile.UniSolid = UniSolidCheckButton.Active;
+ if(sender == IceCheckButton)
+ tile.Ice = IceCheckButton.Active;
+ if(sender == WaterCheckButton)
+ tile.Water = WaterCheckButton.Active;
+ if(sender == SlopeCheckButton)
+ tile.Slope = SlopeCheckButton.Active;
+ if(sender == DontUseCheckButton)
+ tile.ID = DontUseCheckButton.Active ? -1 : 0;
+ }
+ }
+
+ private void OnEntryChanged(object sender, EventArgs e) {
+ if(toggling)
+ return;
+ foreach(Tile tile in Selection) {
+ try {
+ if(sender == IDEntry)
+ tile.ID = Int32.Parse(IDEntry.Text);
+ if(sender == DataEntry)
+ tile.Data = Int32.Parse(DataEntry.Text);
+ if(sender == AnimSpeedEntry)
+ tile.AnimSpeed = Int32.Parse(AnimSpeedEntry.Text);
+ } catch(Exception exception) {
+ // ignore parse errors for now...
+ }
+ }
+ }
+
+ private void SelectionArrayChanged() {
+ Selection.Clear();
+ 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...
+ continue;
+ }
+ Selection.Add(Tiles[i]);
+ }
+
+ SelectionChanged();
+ }
+
+ private void SelectionChanged() {
+ bool first = true;
+ toggling = true;
+ 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;
+ DontUseCheckButton.Active = tile.ID == -1;
+ DataEntry.Text = tile.Data.ToString();
+ AnimSpeedEntry.Text = tile.AnimSpeed.ToString();
+ IDEntry.Text = tile.ID.ToString();
+ IDEntry.Editable = true;
+ first = false;
+
+ if(tile.Images.Count > 0) {
+ nextimage = ((ImageRegion) tile.Images[0]).ImageFile;
+ }
+ } else {
+ IDEntry.Text += "," + tile.ID.ToString();
+ IDEntry.Editable = false;
+ if(tile.Images.Count > 0
+ && ((ImageRegion) tile.Images[0]).ImageFile != nextimage) {
+ nextimage = "";
+ pixbuf = null;
+ }
+ }
+ }
+ if(nextimage != currentimage)
+ ChangeImage(nextimage);
+ toggling = false;
+ DrawingArea.QueueDraw();
+ }
+
+ private void FillTileList() {
+ TileList.HeadersVisible = true;
+ if(TileList.Columns.Length == 0)
+ TileList.AppendColumn("Tile", new CellRendererText(), "text", 0);
+
+ ListStore store = new ListStore(typeof(string));
+
+ if(selectedgroup == null) {
+ foreach(Tile tile in tileset.Tiles) {
+ if(tile == null)
+ continue;
+ store.AppendValues(new object[] { tile.ID.ToString() });
+ }
+ } else {
+ foreach(int id in selectedgroup.Tiles) {
+ Tile tile = (Tile) tileset.Tiles[id];
+ if(tile == null) {
+ Console.WriteLine("tilegroup contains deleted tile");
+ continue;
+ }
+ store.AppendValues(new object[] { id.ToString() });
+ }
+ }
+
+ TileList.Model = store;
+ TileList.Selection.Mode = SelectionMode.Multiple;
+ }
+
+ private void FillTileGroupComboBox() {
+ string[] groups = new string[tileset.TileGroups.Count+1];
+ groups[0] = "All";
+
+ //Submenu submenu = new Submenu();
+ for(int i = 0; i < tileset.TileGroups.Count; ++i) {
+ String tilegroup = ((TileGroup) tileset.TileGroups[i]).Name;
+ groups[i+1] = tilegroup;
+ //submenu.Add(new MenuItem(tilegroup));
+ }
+ TileGroupComboBox.PopdownStrings = groups;
+ TileGroupComboBox.Entry.Editable = false;
+
+ //AddTileGroupMenu.Submenu = submenu;
+ }
+
+ private void OnTileGroupComboBoxEntryActivated(object o, EventArgs args) {
+ if(TileGroupComboBox.Entry.Text == "All") {
+ selectedgroup = null;
+ } else {
+ foreach(TileGroup tilegroup in tileset.TileGroups) {
+ if(tilegroup.Name == TileGroupComboBox.Entry.Text) {
+ selectedgroup = tilegroup;
+ break;
+ }
+ }
+ }
+ FillTileList();
+ }
+
+ private void OnTileListCursorChanged(object sender, EventArgs e) {
+ Console.WriteLine("Cursor changed.");
+ TreeModel model;
+ TreePath[] selectpaths =
+ TileList.Selection.GetSelectedRows(out model);
+
+ Selection.Clear();
+ foreach(TreePath path in selectpaths) {
+ TreeIter iter;
+ model.GetIter(out iter, path);
+ int id = Int32.Parse(model.GetValue(iter, 0).ToString());
+ Selection.Add(tileset.Tiles[id]);
+ }
+ SelectionChanged();
+ }
+
+ private void ShowException(Exception e) {
+ MessageDialog dialog = new MessageDialog(MainWindow,
+ DialogFlags.Modal | DialogFlags.DestroyWithParent,
+ MessageType.Error, ButtonsType.Ok,
+ e.Message);
+ dialog.Run();
+ dialog.Destroy();
+ }
+}
--- /dev/null
+using System;
+using System.Text;
+using System.IO;
+
+namespace Lisp {
+
+public class Lexer {
+ private StreamReader stream;
+ private char[] buffer;
+ private char c;
+ int bufpos;
+ int buflen;
+
+ public class EOFException : Exception {
+ };
+
+ public enum TokenType {
+ EOF,
+ OPEN_PAREN,
+ CLOSE_PAREN,
+ SYMBOL,
+ STRING,
+ INTEGER,
+ REAL,
+ TRUE,
+ FALSE
+ };
+
+ private StringBuilder TokenStringBuilder;
+ public string TokenString {
+ get { return TokenStringBuilder.ToString(); }
+ }
+ public int LineNumber;
+
+ public Lexer(StreamReader stream) {
+ this.stream = stream;
+ buffer = new char[1025];
+ NextChar();
+ }
+
+ public TokenType GetNextToken() {
+ try {
+ while(Char.IsWhiteSpace(c)) {
+ NextChar();
+ if(c == '\n')
+ LineNumber++;
+ }
+
+ TokenStringBuilder = new StringBuilder();
+
+ switch(c) {
+ case ';': // comment
+ while(true) {
+ NextChar();
+ if(c == '\n') {
+ LineNumber++;
+ break;
+ }
+ }
+ NextChar();
+ return GetNextToken();
+ case '(':
+ NextChar();
+ return TokenType.OPEN_PAREN;
+ case ')':
+ NextChar();
+ return TokenType.CLOSE_PAREN;
+ case '"': { // string
+ int startline = LineNumber;
+ while(true) {
+ NextChar();
+ if(c == '"')
+ break;
+
+ if(c == '\\') {
+ NextChar();
+ switch(c) {
+ case 'n':
+ c = '\n';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ }
+ }
+ TokenStringBuilder.Append(c);
+ }
+ NextChar();
+ return TokenType.STRING;
+ }
+ case '#': // constant
+ NextChar();
+ while(Char.IsLetterOrDigit(c) || c == '_') {
+ TokenStringBuilder.Append(c);
+ NextChar();
+ }
+ if(TokenString == "t")
+ return TokenType.TRUE;
+ if(TokenString == "f")
+ return TokenType.FALSE;
+
+ throw new Exception("Unknown constant '"
+ + TokenString + "'");
+ default:
+ if(Char.IsDigit(c) || c == '-') {
+ bool have_nondigits = false;
+ bool have_digits = false;
+ int have_floating_point = 0;
+
+ do {
+ if(Char.IsDigit(c))
+ have_digits = true;
+ else if(c == '.')
+ have_floating_point++;
+ else if(Char.IsLetter(c) || c == '_')
+ have_nondigits = true;
+
+ TokenStringBuilder.Append(c);
+ NextChar();
+ } while(!Char.IsWhiteSpace(c) && c != '\"' && c != '('
+ && c != ')' && c != ';');
+
+ if(have_nondigits || !have_digits
+ || have_floating_point > 1)
+ return TokenType.SYMBOL;
+ else if(have_floating_point == 1)
+ return TokenType.REAL;
+ else
+ return TokenType.INTEGER;
+ } else {
+ do {
+ TokenStringBuilder.Append(c);
+ NextChar();
+ } while(!Char.IsWhiteSpace(c) && c != '\"' && c != '('
+ && c != ')' && c != ';');
+
+ return TokenType.SYMBOL;
+ }
+ }
+ } catch(EOFException e) {
+ return TokenType.EOF;
+ }
+ }
+
+ private void NextChar() {
+ if(bufpos >= buflen) {
+ if(!stream.BaseStream.CanRead)
+ throw new EOFException();
+ buflen = stream.Read(buffer, 0, 1024);
+ bufpos = 0;
+ // following hack appends an additional ' ' at the end of the file
+ // to avoid problems when parsing symbols/elements and a sudden EOF:
+ // This way we can avoid the need for an unget function.
+ if(!stream.BaseStream.CanRead) {
+ buffer[buflen] = ' ';
+ ++buflen;
+ }
+ }
+ c = buffer[bufpos++];
+ }
+}
+
+}
--- /dev/null
+using System;
+using System.IO;
+using System.Collections;
+
+public class LispWriter {
+ private TextWriter stream;
+ private int IndentDepth;
+ private Stack lists = new Stack();
+
+ public LispWriter(TextWriter stream) {
+ this.stream = stream;
+ }
+
+ public void WriteComment(string comment) {
+ stream.WriteLine("; " + comment);
+ }
+
+ public void StartList(string name) {
+ indent();
+ stream.WriteLine("(" + name);
+ IndentDepth += 2;
+ lists.Push(name);
+ }
+
+ public void EndList(string name) {
+ if(lists.Count == 0)
+ throw new Exception("Trying to close list while none is open");
+ string back = (string) lists.Pop();
+ if(name != back)
+ throw new Exception(
+ String.Format("Trying to close {0} which is not open", name));
+
+ IndentDepth -= 2;
+ indent();
+ stream.WriteLine(")");
+ }
+
+ public void Write(string name, object value) {
+ indent();
+ stream.Write("(" + name);
+ if(value is string) {
+ stream.Write(" \"" + value.ToString() + "\"");
+ } else if(value is IEnumerable) {
+ foreach(object o in (IEnumerable) value) {
+ stream.Write(" ");
+ WriteValue(o);
+ }
+ } else {
+ stream.Write(" ");
+ WriteValue(value);
+ }
+ stream.WriteLine(")");
+ }
+
+ private void WriteValue(object val) {
+ if(val is bool) {
+ stream.Write((bool) val ? "#t" : "#f");
+ } else if(val is int || val is float) {
+ stream.Write(val.ToString());
+ } else {
+ stream.Write("\"" + val.ToString() + "\"");
+ }
+ }
+
+ public void WriteVerbatimLine(string line) {
+ indent();
+ stream.WriteLine(line);
+ }
+
+ private void indent() {
+ for(int i = 0; i < IndentDepth; ++i)
+ stream.Write(" ");
+ }
+}
--- /dev/null
+using System;
+using System.IO;
+
+namespace Lisp
+{
+
+public class Parser {
+ public enum LispType {
+ START_LIST,
+ END_LIST,
+ SYMBOL,
+ INTEGER,
+ STRING,
+ REAL,
+ BOOLEAN
+ };
+ private Lexer lexer;
+ private Lexer.TokenType token;
+
+ public Parser(StreamReader stream) {
+ lexer = new Lexer(stream);
+ }
+
+ public bool Parse() {
+ token = lexer.GetNextToken();
+ if(delayinc) {
+ depth++;
+ delayinc = false;
+ }
+ if(token == Lexer.TokenType.EOF) {
+ depth = 0;
+ return false;
+ }
+
+ /*
+ Console.WriteLine("Token: " + token.ToString() + " - " +
+ lexer.TokenString);
+ */
+ switch(token) {
+ case Lexer.TokenType.CLOSE_PAREN:
+ if(depth == 0)
+ throw new Exception("Parse Error: unexpected )");
+ depth--;
+ type = LispType.END_LIST;
+ break;
+ case Lexer.TokenType.OPEN_PAREN:
+ type = LispType.START_LIST;
+ delayinc = true;
+ break;
+ case Lexer.TokenType.SYMBOL:
+ type = LispType.SYMBOL;
+ break;
+ case Lexer.TokenType.STRING:
+ type = LispType.STRING;
+ break;
+ case Lexer.TokenType.TRUE:
+ type = LispType.BOOLEAN;
+ break;
+ case Lexer.TokenType.INTEGER:
+ type = LispType.INTEGER;
+ break;
+ }
+ return true;
+ }
+
+ private LispType type;
+ public LispType Type {
+ get { return type; }
+ }
+ private bool delayinc;
+ private int depth;
+ public int Depth {
+ get { return depth; }
+ }
+ //public int IntValue
+ public string SymbolValue {
+ get { return lexer.TokenString; }
+ }
+ public string StringValue {
+ get { return lexer.TokenString; }
+ }
+ public int IntegerValue {
+ get { return Int32.Parse(lexer.TokenString); }
+ }
+ public bool BoolValue {
+ get { return StringValue == "t" ? true : false; }
+ }
+}
+
+}
--- /dev/null
+This Tool allows to edit supertux .stgt files in a comfortable manner.
+Warning: This tool is pre-alpha and meant for developers only.
+
+Compilation: You need to have mono and gtk-sharp (with gnome support) installed
+in order to compile and run the app.
+
--- /dev/null
+-display and allow editing of tilegroups
+-show tile images next to tile numbers
+-allow removing of tiles
+-undo ?
--- /dev/null
+using System;
+using System.Collections;
+using System.IO;
+using System.Drawing;
+using Lisp;
+
+public class ImageRegion {
+ public String ImageFile;
+ public Rectangle Region;
+}
+
+public class Tile {
+ public int ID;
+ public bool Solid;
+ public bool UniSolid;
+ public bool Ice;
+ public bool Water;
+ public bool Slope;
+ public bool Spike;
+ public bool FullBox;
+ public bool Brick;
+ public bool Coin;
+ public bool Goal;
+ public int NextTile;
+ public int Data;
+ public int AnimSpeed;
+ public string EditorImage;
+ public ArrayList Images = new ArrayList();
+
+ public Tile() {
+ ID = -1;
+ NextTile = -1;
+ AnimSpeed = 25;
+ }
+
+ public void Write(LispWriter writer) {
+ writer.StartList("tile");
+ writer.Write("id", ID);
+
+ if(Images.Count > 0) {
+ writer.StartList("images");
+ foreach(ImageRegion region in Images) {
+ if(region.Region.Width != 0) {
+ writer.WriteVerbatimLine(
+ String.Format("(region \"{0}\" {1} {2} {3} {4})",
+ region.ImageFile, region.Region.Left,
+ region.Region.Top, region.Region.Width,
+ region.Region.Height));
+ } else {
+ writer.WriteVerbatimLine(
+ "\"" + region.ImageFile + "\"");
+ }
+ }
+ writer.EndList("images");
+ } else {
+ Console.WriteLine("no images on tile " + ID);
+ }
+
+ if(Solid)
+ writer.Write("solid", true);
+ if(UniSolid)
+ writer.Write("unisolid", true);
+ if(Ice)
+ writer.Write("ice", true);
+ if(Water)
+ writer.Write("water", true);
+ if(Slope)
+ writer.Write("slope-type", Data);
+ if(Spike)
+ writer.Write("spike", true);
+ if(Coin)
+ writer.Write("distro", true);
+ if(FullBox)
+ writer.Write("fullbox", true);
+ if(Brick)
+ writer.Write("brick", true);
+ if(NextTile >= 0)
+ writer.Write("next-tile", NextTile);
+ if(Goal)
+ writer.Write("goal", true);
+ if(EditorImage != null)
+ writer.Write("editor-images", EditorImage);
+ if(Data != 0)
+ writer.Write("data", Data);
+ if(AnimSpeed != 25)
+ writer.Write("animspeed", AnimSpeed);
+ writer.EndList("tile");
+ }
+
+ public void Parse(Lisp.Parser parser) {
+ int d = parser.Depth;
+ while(parser.Parse() && parser.Depth >= d) {
+ if(parser.Depth == d+1) {
+ if(parser.Type != Parser.LispType.SYMBOL)
+ throw new Exception("expected SYMBOL");
+ string symbol = parser.SymbolValue;
+ parser.Parse();
+ switch(symbol) {
+ case "id":
+ ID = parser.IntegerValue;
+ break;
+ case "images":
+ ParseTileImages(parser);
+ break;
+ case "editor-images":
+ EditorImage = parser.StringValue;
+ break;
+ case "solid":
+ Solid = parser.BoolValue;
+ break;
+ case "unisolid":
+ UniSolid = parser.BoolValue;
+ break;
+ case "ice":
+ Ice = parser.BoolValue;
+ break;
+ case "water":
+ Water = parser.BoolValue;
+ break;
+ case "slope-type":
+ Slope = true;
+ Data = parser.IntegerValue;
+ break;
+ case "anim-speed":
+ AnimSpeed = parser.IntegerValue;
+ break;
+ case "spike":
+ Spike = parser.BoolValue;
+ break;
+ case "data":
+ Data = parser.IntegerValue;
+ break;
+ case "next-tile":
+ Data = parser.IntegerValue;
+ break;
+ case "brick":
+ Brick = parser.BoolValue;
+ break;
+ case "fullbox":
+ FullBox = parser.BoolValue;
+ break;
+ case "distro":
+ Coin = parser.BoolValue;
+ break;
+ case "goal":
+ Goal = parser.BoolValue;
+ break;
+ default:
+ Console.WriteLine("Unknown tile element " + symbol);
+ break;
+ }
+ }
+ }
+ }
+
+ private void ParseTileImages(Lisp.Parser parser) {
+ if(parser.Type == Parser.LispType.END_LIST)
+ return;
+
+ int d = parser.Depth;
+ do {
+ ImageRegion region = new ImageRegion();
+ if(parser.Type == Parser.LispType.STRING) {
+ region.ImageFile = parser.StringValue;
+ } else if(parser.Type == Parser.LispType.START_LIST) {
+ ParseImageRegion(parser, region);
+ } else {
+ throw new Exception("unexpected lisp data: " + parser.Type);
+ }
+ Images.Add(region);
+ } while(parser.Parse() && parser.Depth >= d);
+ }
+
+ private void ParseImageRegion(Lisp.Parser parser, ImageRegion region) {
+ parser.Parse();
+ if(parser.Type != Parser.LispType.SYMBOL)
+ throw new Exception("expected symbol");
+ if(parser.SymbolValue != "region")
+ throw new Exception("expected region symbol");
+ parser.Parse();
+ if(parser.Type != Parser.LispType.STRING)
+ throw new Exception("expected string");
+ region.ImageFile = parser.StringValue;
+
+ parser.Parse();
+ if(parser.Type != Parser.LispType.INTEGER)
+ throw new Exception("expected integer");
+ region.Region.X = parser.IntegerValue;
+
+ parser.Parse();
+ if(parser.Type != Parser.LispType.INTEGER)
+ throw new Exception("expected integer");
+ region.Region.Y = parser.IntegerValue;
+
+ parser.Parse();
+ if(parser.Type != Parser.LispType.INTEGER)
+ throw new Exception("expected integer");
+ region.Region.Width = parser.IntegerValue;
+
+ parser.Parse();
+ if(parser.Type != Parser.LispType.INTEGER)
+ throw new Exception("expected integer");
+ region.Region.Height = parser.IntegerValue;
+
+ parser.Parse();
+ if(parser.Type != Parser.LispType.END_LIST)
+ throw new Exception("expected END_LIST");
+ }
+}
+
--- /dev/null
+using System;
+using System.IO;
+using System.Collections;
+using Lisp;
+
+public class TileGroup {
+ public string Name;
+ public ArrayList Tiles = new ArrayList();
+
+ public void Write(LispWriter writer) {
+ writer.StartList("tilegroup");
+
+ writer.Write("name", Name);
+ writer.Write("tiles", Tiles);
+
+ writer.EndList("tilegroup");
+ }
+
+ public void Parse(Lisp.Parser parser) {
+ int d = parser.Depth;
+ while(parser.Parse() && parser.Depth >= d) {
+ if(parser.Depth == d+1) {
+ if(parser.Type != Parser.LispType.SYMBOL)
+ throw new Exception("expected SYMBOL");
+ string symbol = parser.SymbolValue;
+ parser.Parse();
+ switch(symbol) {
+ case "name":
+ Name = parser.StringValue;
+ break;
+ case "tiles":
+ do {
+ Tiles.Add(parser.IntegerValue);
+ } while(parser.Parse()
+ && parser.Type == Parser.LispType.INTEGER);
+ break;
+ default:
+ Console.WriteLine("Unknown section " + symbol);
+ break;
+ }
+ }
+ }
+ }
+}
+
+public class TileSet {
+ public ArrayList Tiles = new ArrayList();
+ public ArrayList TileGroups = new ArrayList();
+
+ public void Write(string filename) {
+ FileStream fs = new FileStream(filename, FileMode.Create);
+
+ TextWriter tw = new StreamWriter(fs);
+ LispWriter writer = new LispWriter(tw);
+
+ writer.WriteComment("Generated by tiler");
+ writer.StartList("supertux-tiles");
+ foreach(TileGroup tilegroup in TileGroups) {
+ tilegroup.Write(writer);
+ }
+ foreach(Tile tile in Tiles) {
+ if(tile == null)
+ continue;
+ if(tile.ID >= 0)
+ tile.Write(writer);
+ }
+ writer.EndList("supertux-tiles");
+ tw.Close();
+ fs.Close();
+ }
+
+ public void Parse(string filename) {
+ FileStream fs = new FileStream(filename, FileMode.Open);
+ StreamReader stream = new StreamReader(fs);
+
+ Lisp.Parser parser = new Lisp.Parser(stream);
+ parser.Parse();
+ if(parser.Type != Parser.LispType.START_LIST)
+ throw new Exception("Expected START_LIST");
+ parser.Parse();
+ if(parser.Type != Parser.LispType.SYMBOL)
+ throw new Exception("Expected symbol");
+ if(parser.SymbolValue != "supertux-tiles")
+ throw new Exception("not a supertux tile files but " +
+ parser.SymbolValue);
+ ParseTiles(parser);
+
+ stream.Close();
+ fs.Close();
+ }
+
+ public void ParseTiles(Lisp.Parser parser) {
+ Console.WriteLine("ParseTiles...");
+ int d = parser.Depth;
+ while(parser.Parse() && parser.Depth >= d) {
+ if(parser.Depth == d && parser.Type != Parser.LispType.START_LIST) {
+ Console.WriteLine("non-cons type in list...");
+ continue;
+ }
+
+ if(parser.Depth == d+1) {
+ if(parser.Type != Parser.LispType.SYMBOL) {
+ throw new Exception("Expected symbol in list element");
+ }
+ switch(parser.SymbolValue) {
+ case "properties":
+ SkipList(parser);
+ break;
+ case "tilegroup":
+ TileGroup tilegroup = new TileGroup();
+ tilegroup.Parse(parser);
+ TileGroups.Add(tilegroup);
+ break;
+ case "tile":
+ Tile tile = new Tile();
+ tile.Parse(parser);
+ Console.WriteLine("***ID: " + tile.ID);
+
+ while(tile.ID >= Tiles.Count)
+ Tiles.Add(null);
+ Tiles[tile.ID] = tile;
+ break;
+ default:
+ throw new Exception("Unexpected listentry: " +
+ parser.SymbolValue);
+ }
+ }
+ }
+ }
+
+ private void SkipList(Lisp.Parser parser) {
+ int d = parser.Depth;
+ while(parser.Parse() && parser.Depth >= d)
+ ;
+ }
+}
+
--- /dev/null
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+<requires lib="gnome"/>
+
+<widget class="GtkWindow" id="MainWindow">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Tile Manager</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="modal">False</property>
+ <property name="default_width">640</property>
+ <property name="default_height">480</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <signal name="delete_event" handler="OnQuit" last_modification_time="Sun, 21 Nov 2004 12:26:12 GMT"/>
+
+ <child>
+ <widget class="GtkVBox" id="MainLayout">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkMenuBar" id="menubar1">
+ <property name="visible">True</property>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Datei</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem1_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="open">
+ <property name="visible">True</property>
+ <property name="label">gtk-open</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="OnOpen" last_modification_time="Sun, 21 Nov 2004 12:08:44 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="save">
+ <property name="visible">True</property>
+ <property name="label">gtk-save</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="OnSave" last_modification_time="Sun, 21 Nov 2004 14:26:54 GMT"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="beenden1">
+ <property name="visible">True</property>
+ <property name="label">gtk-quit</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="OnQuit" last_modification_time="Sun, 21 Nov 2004 12:21:15 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="edit1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Edit</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="edit1_menu">
+
+ <child>
+ <widget class="GtkMenuItem" id="import_image1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Import Image</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="OnImportImage" last_modification_time="Sun, 21 Nov 2004 22:13:54 GMT"/>
+ <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="remap_tiles1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Remap Tiles</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="OnRemapTiles" last_modification_time="Sun, 21 Nov 2004 15:18:43 GMT"/>
+ <accelerator key="R" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="trennlinie1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="create_tilegroup1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Create TileGroup</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="OnCreateTileGroup" last_modification_time="Mon, 22 Nov 2004 00:20:28 GMT"/>
+ <accelerator key="C" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="item2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Rename TileGroup</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="OnRenameTileGroup" last_modification_time="Mon, 22 Nov 2004 00:21:52 GMT"/>
+ <accelerator key="R" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="AddTileGroupMenu">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add Tiles To Group</property>
+ <property name="use_underline">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkMenuItem" id="menuitem4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Hilfe</property>
+ <property name="use_underline">True</property>
+
+ <child>
+ <widget class="GtkMenu" id="menuitem4_menu">
+
+ <child>
+ <widget class="GtkImageMenuItem" id="info1">
+ <property name="visible">True</property>
+ <property name="label">gtk-dialog-info</property>
+ <property name="use_stock">True</property>
+ <signal name="activate" handler="OnAbout" last_modification_time="Sun, 21 Nov 2004 12:08:44 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkHPaned" id="hpaned1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">180</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+ <child>
+ <widget class="GtkTreeView" id="TileList">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <signal name="cursor_changed" handler="OnTileListCursorChanged" last_modification_time="Sun, 21 Nov 2004 23:04:22 GMT"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCombo" id="TileGroupComboBox">
+ <property name="visible">True</property>
+ <property name="value_in_list">False</property>
+ <property name="allow_empty">True</property>
+ <property name="case_sensitive">False</property>
+ <property name="enable_arrow_keys">True</property>
+ <property name="enable_arrows_always">False</property>
+
+ <child internal-child="entry">
+ <widget class="GtkEntry" id="entry1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ </widget>
+ </child>
+
+ <child internal-child="list">
+ <widget class="GtkList" id="list1">
+ <property name="visible">True</property>
+ <property name="selection_mode">GTK_SELECTION_BROWSE</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkDrawingArea" id="DrawingArea">
+ <property name="visible">True</property>
+ <signal name="expose_event" handler="OnDrawingAreaExpose" last_modification_time="Sun, 21 Nov 2004 13:01:22 GMT"/>
+ <signal name="button_press_event" handler="OnDrawingAreaButtonPress" last_modification_time="Sun, 21 Nov 2004 13:18:28 GMT"/>
+ <signal name="motion_notify_event" handler="OnDrawingAreaMotionNotify" last_modification_time="Sun, 21 Nov 2004 13:18:45 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Flags:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="padding">6</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="n_rows">6</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+
+ <child>
+ <widget class="GtkCheckButton" id="SolidCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Solid</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnCheckButtonToggled" last_modification_time="Sun, 21 Nov 2004 13:41:46 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="UniSolidCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">UniSolid</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnCheckButtonToggled" last_modification_time="Sun, 21 Nov 2004 13:42:00 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="IceCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Ice</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnCheckButtonToggled" last_modification_time="Sun, 21 Nov 2004 13:42:08 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="WaterCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Water</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnCheckButtonToggled" last_modification_time="Sun, 21 Nov 2004 13:42:17 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="SlopeCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Slope</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnCheckButtonToggled" last_modification_time="Sun, 21 Nov 2004 13:42:25 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Data:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="DataEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnEntryChanged" last_modification_time="Sun, 21 Nov 2004 13:42:39 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">AnimSpeed:</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="AnimSpeedEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnEntryChanged" last_modification_time="Sun, 21 Nov 2004 13:42:48 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">ID</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="IDEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char" translatable="yes">*</property>
+ <property name="activates_default">False</property>
+ <signal name="changed" handler="OnEntryChanged" last_modification_time="Sun, 21 Nov 2004 13:42:57 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkCheckButton" id="DontUseCheckButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Don't Use</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="OnCheckButtonToggled" last_modification_time="Sun, 21 Nov 2004 15:16:11 GMT"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="shrink">True</property>
+ <property name="resize">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GnomeAppBar" id="AppBar">
+ <property name="visible">True</property>
+ <property name="has_progress">True</property>
+ <property name="has_status">True</property>
+ <signal name="user_response" handler="OnAppBarUserResponse" last_modification_time="Sun, 21 Nov 2004 15:23:58 GMT"/>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>