3 using System.Collections;
9 public class Application {
11 private Gtk.Window MainWindow;
13 private Gtk.DrawingArea DrawingArea;
15 private Gtk.CheckButton SolidCheckButton;
17 private Gtk.CheckButton UniSolidCheckButton;
19 private Gtk.CheckButton IceCheckButton;
21 private Gtk.CheckButton WaterCheckButton;
23 private Gtk.CheckButton SlopeCheckButton;
25 private Gtk.CheckButton DontUseCheckButton;
27 private Gtk.CheckButton HiddenCheckButton;
29 private Gtk.Entry DataEntry;
31 private Gtk.Entry AnimFpsEntry;
33 private Gtk.Entry IDEntry;
35 private Gnome.AppBar AppBar;
37 private Gtk.VBox MainLayout;
39 private Gtk.TreeView TileList;
41 private Gtk.Combo TileGroupComboBox;
43 private Gtk.MenuItem AddTileGroupMenu;
45 private string tilesetdir;
46 private string tilesetfile;
47 private TileSet tileset;
48 private TileGroup selectedgroup;
51 private bool[] SelectionArray;
52 private ArrayList Selection = new ArrayList();
55 private bool toggling;
56 private bool selecting;
58 private string currentimage;
59 private Gdk.Pixbuf pixbuf;
61 public static int Main(string[] args) {
62 Program kit = new Program("tiler", "0.0.1", Modules.UI, args);
64 Application app = new Application();
66 /* that's no proper commandlineparsing, but who'll notice... */
68 app.LoadTileSet(args[0]);
74 public Application() {
75 Glade.XML gxml = new Glade.XML(null, "tiler.glade", null, null);
76 gxml.Autoconnect(this);
78 if(MainWindow == null || DrawingArea == null || AppBar == null)
79 throw new Exception("some widgets not found");
81 DrawingArea.AddEvents((int) Gdk.EventMask.ButtonPressMask);
82 DrawingArea.AddEvents((int) Gdk.EventMask.ButtonReleaseMask);
83 DrawingArea.AddEvents((int) Gdk.EventMask.ButtonMotionMask);
85 // libglade missed interactivity property :-/
86 MainLayout.Remove(AppBar);
87 AppBar = new AppBar(true, true, PreferencesType.Always);
88 AppBar.UserResponse += new EventHandler(OnAppBarUserResponse);
89 MainLayout.PackStart(AppBar, false, false, 0);
92 TileGroupComboBox.Entry.Activated
93 += new EventHandler (OnTileGroupComboBoxEntryActivated);
98 private void OnOpen(object o, EventArgs e) {
99 FileSelection selection = new FileSelection("Select TileSet");
100 selection.OkButton.Clicked += new EventHandler(OnSelectTileSetOk);
101 selection.CancelButton.Clicked += new EventHandler(OnSelectImageCancel);
105 private void OnSelectTileSetOk(object o, EventArgs e) {
106 FileSelection selection = ((FileSelection.FSButton) o).FileSelection;
107 string file = selection.Filename;
113 private void LoadTileSet(string file) {
115 tileset = new TileSet();
118 tilesetdir = new FileInfo(file).Directory.ToString();
119 } catch(Exception exception) {
120 ShowException(exception);
125 FillTileGroupComboBox();
129 private void OnImportImage(object o, EventArgs e) {
130 FileSelection selection = new FileSelection("Select ImageFile");
131 selection.OkButton.Clicked += new EventHandler(OnSelectImageOk);
132 selection.CancelButton.Clicked += new EventHandler(OnSelectImageCancel);
136 private void OnSelectImageCancel(object o, EventArgs args) {
137 FileSelection selection = ((FileSelection.FSButton) o).FileSelection;
141 private void OnSelectImageOk(object o, EventArgs args) {
142 FileSelection selection = ((FileSelection.FSButton) o).FileSelection;
143 string file = selection.Filename;
146 ChangeImage(new FileInfo(file).Name);
148 int startid = tileset.Tiles.Count;
149 for(int y = 0; y < TilesY; ++y) {
150 for(int x = 0; x < TilesX; ++x) {
152 Tile tile = new Tile();
153 tile.ID = startid + i;
154 ImageRegion region = new ImageRegion();
155 region.ImageFile = currentimage;
156 region.Region = new System.Drawing.Rectangle(x*32, y*32, 32, 32);
157 tile.Images.Add(region);
158 if(Tiles[i] != null) {
160 "Warning Tile in this region already existed...");
163 tileset.Tiles.Add(tile);
170 private void ChangeImage(string file) {
177 pixbuf = new Pixbuf(tilesetdir + "/" + file);
178 if(pixbuf.Width % 32 != 0 || pixbuf.Height % 32 != 0)
179 Console.WriteLine("Warning: Image Width or Height is not a multiple of 32");
180 } catch(Exception e) {
184 currentimage = new FileInfo(file).Name;
185 TilesX = pixbuf.Width / 32;
186 TilesY = pixbuf.Height / 32;
187 SelectionArray = new bool[TilesX * TilesY];
188 Tiles = new Tile[TilesX * TilesY];
190 // search tileset for tiles with matching image
191 foreach(Tile tile in tileset.Tiles) {
194 if(tile.Images.Count == 0)
196 ImageRegion region = (ImageRegion) tile.Images[0];
197 if(region.ImageFile == currentimage) {
198 int px = region.Region.X / 32;
199 int py = region.Region.Y / 32;
200 int i = py*TilesX+px;
201 if(i < 0 || i >= Tiles.Length) {
202 Console.WriteLine("Invalid Imageregion at tile " +
206 if(Tiles[i] != null) {
207 Console.WriteLine("Multiple tiles for region " +
208 px*32 + " , " + py*32);
215 /* DrawingArea.Allocation
216 = new Gdk.Rectangle(0, 0, pixbuf.Width, pixbuf.Height);*/
217 DrawingArea.WidthRequest = pixbuf.Width;
218 DrawingArea.HeightRequest = pixbuf.Height;
219 DrawingArea.QueueResize();
222 private void OnSave(object o, EventArgs e) {
223 tileset.Write(tilesetfile);
226 private void OnQuit(object o, EventArgs e) {
227 Gtk.Application.Quit();
230 private void OnAbout(object o, EventArgs e) {
233 private void OnRemapTiles(object o, EventArgs e) {
234 AppBar.SetPrompt("Start-ID:", true);
237 private void OnCreateTileGroup(object o, EventArgs e) {
240 private void OnRenameTileGroup(object o, EventArgs e) {
243 private void OnAppBarUserResponse(object o, EventArgs e) {
245 if(AppBar.Response == null || AppBar.Response == ""
252 id = Int32.Parse(AppBar.Response);
253 } catch(Exception exception) {
254 ShowException(exception);
257 foreach(Tile tile in Selection) {
263 // remap in all tilegroups...
264 foreach(TileGroup tilegroup in tileset.TileGroups) {
265 int idx = tilegroup.Tiles.IndexOf(oldid);
267 tilegroup.Tiles[idx] = tile.ID;
274 AppBar.ClearPrompt();
278 private void OnDrawingAreaExpose(object o, ExposeEventArgs e) {
282 Drawable drawable = e.Event.Window;
283 Gdk.GC gc = new Gdk.GC(drawable);
284 drawable.DrawPixbuf(gc, pixbuf, 0, 0, 0, 0,
285 pixbuf.Width, pixbuf.Height, RgbDither.None, 0, 0);
287 gc.RgbFgColor = new Color(0xff, 0, 0);
288 foreach(Tile tile in Selection) {
289 System.Drawing.Rectangle rect
290 = ((ImageRegion) tile.Images[0]).Region;
291 drawable.DrawRectangle(gc, false, rect.X, rect.Y, rect.Width,
298 private void OnDrawingAreaButtonPress(object o, ButtonPressEventArgs e) {
299 if(SelectionArray == null)
304 for(int i = 0; i < SelectionArray.Length; ++i)
305 SelectionArray[i] = false;
306 select((int) e.Event.X, (int) e.Event.Y);
309 private void select(int x, int y) {
310 int tile = y/32 * TilesX + x/32;
311 if(tile < 0 || tile >= SelectionArray.Length)
314 SelectionArray[tile] = true;
315 SelectionArrayChanged();
318 private void OnDrawingAreaMotionNotify(object i, MotionNotifyEventArgs e) {
321 select((int) e.Event.X, (int) e.Event.Y);
324 private void OnDrawingAreaButtonRelease(object o, ButtonPressEventArgs e) {
328 private void OnCheckButtonToggled(object sender, EventArgs e) {
331 foreach(Tile tile in Selection) {
332 if(sender == SolidCheckButton)
333 tile.Solid = SolidCheckButton.Active;
334 if(sender == UniSolidCheckButton)
335 tile.UniSolid = UniSolidCheckButton.Active;
336 if(sender == IceCheckButton)
337 tile.Ice = IceCheckButton.Active;
338 if(sender == WaterCheckButton)
339 tile.Water = WaterCheckButton.Active;
340 if(sender == SlopeCheckButton)
341 tile.Slope = SlopeCheckButton.Active;
342 if(sender == HiddenCheckButton)
343 tile.Hidden = HiddenCheckButton.Active;
344 if(sender == DontUseCheckButton)
345 tile.ID = DontUseCheckButton.Active ? -1 : 0;
349 private void OnEntryChanged(object sender, EventArgs e) {
352 foreach(Tile tile in Selection) {
354 if(sender == IDEntry)
355 tile.ID = Int32.Parse(IDEntry.Text);
356 if(sender == DataEntry)
357 tile.Data = Int32.Parse(DataEntry.Text);
358 if(sender == AnimFpsEntry)
359 tile.AnimFps = Single.Parse(AnimFpsEntry.Text);
360 } catch(Exception exception) {
361 // ignore parse errors for now...
366 private void SelectionArrayChanged() {
368 for(int i = 0; i < SelectionArray.Length; ++i) {
369 if(!SelectionArray[i])
372 if(Tiles[i] == null) {
373 Console.WriteLine("Tile doesn't exist yet");
374 // TODO ask user to create new tile...
377 Selection.Add(Tiles[i]);
383 private void SelectionChanged() {
386 string nextimage = "";
387 foreach(Tile tile in Selection) {
389 SolidCheckButton.Active = tile.Solid;
390 UniSolidCheckButton.Active = tile.UniSolid;
391 IceCheckButton.Active = tile.Ice;
392 WaterCheckButton.Active = tile.Water;
393 SlopeCheckButton.Active = tile.Slope;
394 HiddenCheckButton.Active = tile.Hidden;
395 DontUseCheckButton.Active = tile.ID == -1;
396 DataEntry.Text = tile.Data.ToString();
397 AnimFpsEntry.Text = tile.AnimFps.ToString();
398 IDEntry.Text = tile.ID.ToString();
399 IDEntry.Editable = true;
402 if(tile.Images.Count > 0) {
403 nextimage = ((ImageRegion) tile.Images[0]).ImageFile;
406 IDEntry.Text += "," + tile.ID.ToString();
407 IDEntry.Editable = false;
408 if(tile.Images.Count > 0
409 && ((ImageRegion) tile.Images[0]).ImageFile != nextimage) {
415 if(nextimage != currentimage)
416 ChangeImage(nextimage);
418 DrawingArea.QueueDraw();
421 private void FillTileList() {
422 TileList.HeadersVisible = true;
423 if(TileList.Columns.Length == 0)
424 TileList.AppendColumn("Tile", new CellRendererText(), "text", 0);
426 ListStore store = new ListStore(typeof(string));
428 if(selectedgroup == null) {
429 foreach(Tile tile in tileset.Tiles) {
432 store.AppendValues(new object[] { tile.ID.ToString() });
435 foreach(int id in selectedgroup.Tiles) {
436 Tile tile = (Tile) tileset.Tiles[id];
438 Console.WriteLine("tilegroup contains deleted tile");
441 store.AppendValues(new object[] { id.ToString() });
445 TileList.Model = store;
446 TileList.Selection.Mode = SelectionMode.Multiple;
449 private void FillTileGroupComboBox() {
450 string[] groups = new string[tileset.TileGroups.Count+1];
453 //Submenu submenu = new Submenu();
454 for(int i = 0; i < tileset.TileGroups.Count; ++i) {
455 String tilegroup = ((TileGroup) tileset.TileGroups[i]).Name;
456 groups[i+1] = tilegroup;
457 //submenu.Add(new MenuItem(tilegroup));
459 TileGroupComboBox.PopdownStrings = groups;
460 TileGroupComboBox.Entry.Editable = false;
462 //AddTileGroupMenu.Submenu = submenu;
465 private void OnTileGroupComboBoxEntryActivated(object o, EventArgs args) {
466 if(TileGroupComboBox.Entry.Text == "All") {
467 selectedgroup = null;
469 foreach(TileGroup tilegroup in tileset.TileGroups) {
470 if(tilegroup.Name == TileGroupComboBox.Entry.Text) {
471 selectedgroup = tilegroup;
479 private void OnTileListCursorChanged(object sender, EventArgs e) {
481 TreePath[] selectpaths =
482 TileList.Selection.GetSelectedRows(out model);
485 foreach(TreePath path in selectpaths) {
487 model.GetIter(out iter, path);
488 int id = Int32.Parse(model.GetValue(iter, 0).ToString());
489 Selection.Add(tileset.Tiles[id]);
494 private void ShowException(Exception e) {
495 MessageDialog dialog = new MessageDialog(MainWindow,
496 DialogFlags.Modal | DialogFlags.DestroyWithParent,
497 MessageType.Error, ButtonsType.Ok,