Mercurial > repos > IBDev-IBBoard.WarFoundry.GUI.GTK
comparison FrmMainWindow.cs @ 0:1bb28f84d567
Initial commit of WarFoundry code
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 19 Dec 2008 15:57:51 +0000 |
parents | |
children | 65279b85446f |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1bb28f84d567 |
---|---|
1 // FrmMainWindow.cs | |
2 // | |
3 // Copyright (C) 2007 IBBoard | |
4 // | |
5 // This library is free software; you can redistribute it and/or | |
6 // modify it under the terms of the GNU Lesser General Public | |
7 // License version 2.1 of the License as published by the Free | |
8 // Software Foundation. | |
9 // | |
10 // This library is distributed in the hope that it will be useful, | |
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 // Lesser General Public License for more details. | |
14 // | |
15 // You should have received a copy of the GNU Lesser General Public | |
16 // License along with this library; if not, write to the Free Software | |
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 // | |
19 // | |
20 | |
21 using System; | |
22 using System.IO; | |
23 using System.Collections.Generic; | |
24 using System.Configuration; | |
25 using Gtk; | |
26 using IBBoard; | |
27 using IBBoard.Commands; | |
28 using IBBoard.IO; | |
29 using IBBoard.Lang; | |
30 using IBBoard.Logging; | |
31 using IBBoard.CustomMath; | |
32 using IBBoard.Log4Net; | |
33 using IBBoard.WarFoundry.API; | |
34 using IBBoard.WarFoundry.API.Factories; | |
35 using IBBoard.WarFoundry.API.Factories.Xml; | |
36 using IBBoard.WarFoundry.API.Objects; | |
37 using IBBoard.WarFoundry.API.Commands; | |
38 using IBBoard.WarFoundry.API.Savers; | |
39 using IBBoard.WarFoundry.API.Requirements; | |
40 using IBBoard.WarFoundry.Widgets; | |
41 using IBBoard.WarFoundry.Plugin.Rollcall; | |
42 using IBBoard.Xml; | |
43 using log4net; | |
44 | |
45 namespace IBBoard.WarFoundry | |
46 { | |
47 public partial class FrmMainWindow: Gtk.Window | |
48 { | |
49 private static readonly string AppTitle = "WarFoundry"; | |
50 private const int CATEGORY_BUTTON_SEPARATOR_INDEX = 6; | |
51 | |
52 private Preferences preferences; | |
53 private ILog logger = LogManager.GetLogger(typeof(FrmMainWindow)); | |
54 | |
55 private CommandStack commandStack; | |
56 private Type factoryType = typeof(WarFoundryXmlFactory); | |
57 private Dictionary<ToolButton, Category> categoryMap = new Dictionary<ToolButton, Category>(); | |
58 private Dictionary<IBBoard.WarFoundry.API.Objects.Unit, UnitDisplayWidget> unitToWidgetMap = new Dictionary<IBBoard.WarFoundry.API.Objects.Unit,UnitDisplayWidget>(); | |
59 | |
60 private ObjectAddDelegate UnitAddedMethod; | |
61 private ObjectRemoveDelegate UnitRemovedMethod; | |
62 private DoubleValChangedDelegate PointsValueChangedMethod; | |
63 private FailedUnitRequirementDelegate FailedUnitRequirementMethod; | |
64 private StringValChangedDelegate UnitNameChangedMethod; | |
65 | |
66 private GameSystem system; | |
67 private string loadedArmyPath; | |
68 | |
69 private MenuToolButton undoMenuButton, redoMenuButton; | |
70 | |
71 public static void Main (string[] args) | |
72 { | |
73 try | |
74 { | |
75 Application.Init(); | |
76 FrmMainWindow win = new FrmMainWindow(args); | |
77 win.Show(); | |
78 Application.Run(); | |
79 LogManager.GetLogger(typeof(FrmMainWindow)).Debug("Application ended"); | |
80 } | |
81 catch(Exception ex) | |
82 { | |
83 LogManager.GetLogger(typeof(FrmMainWindow)).Fatal(ex.Message + Environment.NewLine + ex.StackTrace); | |
84 } | |
85 } | |
86 | |
87 public FrmMainWindow() : this(new string[0]) | |
88 { | |
89 //Do nothing extra | |
90 } | |
91 | |
92 public FrmMainWindow (string[] args): base (Gtk.WindowType.Toplevel) | |
93 { | |
94 logger.Info("Opening FrmMainWindow"); | |
95 LogNotifierHandler.RegisterNotifierHandler(); | |
96 Build (); | |
97 //Replace the undo/redo buttons with menu versions, which Monodevelop's GUI editor doesn't currently support | |
98 redoMenuButton = new MenuToolButton("gtk-redo"); | |
99 redoMenuButton.Label = "Redo"; | |
100 redoMenuButton.SetTooltip(new Tooltips(), "Redo", ""); | |
101 redoMenuButton.Clicked+= redoTBButtonActivated; | |
102 toolbar.Insert(redoMenuButton, CATEGORY_BUTTON_SEPARATOR_INDEX); | |
103 undoMenuButton = new MenuToolButton("gtk-undo"); | |
104 undoMenuButton.Label = "Undo"; | |
105 undoMenuButton.SetTooltip(new Tooltips(), "Undo", ""); | |
106 undoMenuButton.Clicked+= undoTBButtonActivated; | |
107 toolbar.Insert(undoMenuButton, CATEGORY_BUTTON_SEPARATOR_INDEX); | |
108 toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX-1]); | |
109 toolbar.Remove(toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX-2]); | |
110 toolbar.ShowAll(); | |
111 | |
112 Title = AppTitle; | |
113 TreeViewColumn mainColumn = new TreeViewColumn (); | |
114 mainColumn.Title = "Army Categories"; | |
115 CellRendererText mainCell = new CellRendererText (); | |
116 mainColumn.PackStart (mainCell, true); | |
117 treeUnits.AppendColumn(mainColumn); | |
118 mainColumn.SetCellDataFunc(mainCell, new TreeCellDataFunc(RenderCategoryTreeObjectName)); | |
119 treeUnits.Model = new TreeStore(typeof(WarFoundryObject)); | |
120 logger.Debug("Loading preferences"); | |
121 Preferences = new Preferences("WarFoundryGTK"); | |
122 logger.Debug("Loading translations"); | |
123 Translation.InitialiseTranslations(Constants.ExecutablePath, Preferences["language"].ToString()); | |
124 logger.Debug("Initialising"); | |
125 commandStack = new CommandStack(); | |
126 commandStack.CommandStackUpdated+=new MethodInvoker(commandStack_CommandStackUpdated); | |
127 WarFoundryCore.GameSystemChanged+= new GameSystemChangedDelegate(OnGameSystemChanged); | |
128 WarFoundryCore.ArmyChanged+= new ArmyChangedDelegate(OnArmyChanged); | |
129 Destroyed+= new EventHandler(OnWindowDestroyed); | |
130 //TODO: Translate and subscribe to other events | |
131 UnitAddedMethod = new ObjectAddDelegate(OnUnitAdded); | |
132 UnitRemovedMethod = new ObjectRemoveDelegate(OnUnitRemoved); | |
133 PointsValueChangedMethod = new DoubleValChangedDelegate(OnPointsValueChanged); | |
134 FailedUnitRequirementMethod = new FailedUnitRequirementDelegate(OnFailedUnitRequirement); | |
135 UnitNameChangedMethod = new StringValChangedDelegate(OnUnitNameChanged); | |
136 logger.Debug("Initialising complete - trying to load default army or system"); | |
137 | |
138 //FIXME: Temporary hack to add paths and factories | |
139 WarFoundryLoader.GetDefault().AddLoadDirectory(new DirectoryInfo(Constants.ExecutablePath + Constants.DirectoryString + "data")); | |
140 IWarFoundryFactory factory = WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(typeof(WarFoundryXmlFactory)); | |
141 | |
142 if (factory!=null && factory is WarFoundryXmlFactory) | |
143 { | |
144 WarFoundryLoader.GetDefault().RegisterFactory((WarFoundryXmlFactory)factory); | |
145 } | |
146 | |
147 factory = WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(typeof(RollcallFactory)); | |
148 | |
149 if (factory!=null && factory is RollcallFactory) | |
150 { | |
151 WarFoundryLoader.GetDefault().RegisterNonNativeFactory((INonNativeWarFoundryFactory)factory); | |
152 } | |
153 | |
154 if (args.Length == 1) | |
155 { | |
156 logger.Debug("Attempting to load from file"); | |
157 FileInfo file = new FileInfo(args[0]); | |
158 | |
159 try | |
160 { | |
161 //TODO: Try to load files | |
162 /*if (file.Extension.Equals("."+Factory.GetArmyFileExtension())) | |
163 { | |
164 WarFoundryCore.CurrentArmy = Factory.CreateArmyFromFile(file); | |
165 logger.InfoFormat("Loaded army from {0}", file.FullName); | |
166 } | |
167 else if (file.Extension.Equals("."+Factory.GetSystemFileExtension())) | |
168 { | |
169 WarFoundryCore.CurrentGameSystem = Factory.CreateGameSystemFromFile(file); | |
170 logger.InfoFormat("Loaded game system from {0}", file.FullName); | |
171 }*/ | |
172 } | |
173 catch (InvalidFileException ex) | |
174 { | |
175 //TODO: show error dialog | |
176 logger.Error(ex); | |
177 } | |
178 } | |
179 else | |
180 { | |
181 string gameSystemID = Preferences.GetStringProperty("currSystem"); | |
182 | |
183 if (gameSystemID!=null && !"".Equals(gameSystemID)) | |
184 { | |
185 logger.Debug("Attempting to load current game system from properties"); | |
186 GameSystem sys = WarFoundryLoader.GetDefault().GetGameSystem(gameSystemID); | |
187 | |
188 if (sys!=null) | |
189 { | |
190 WarFoundryCore.CurrentGameSystem = sys; | |
191 logger.InfoFormat("Loaded game system {0} from properties", gameSystemID); | |
192 } | |
193 } | |
194 } | |
195 } | |
196 | |
197 private void RenderCategoryTreeObjectName(TreeViewColumn column, CellRenderer cell, TreeModel model, TreeIter iter) | |
198 { | |
199 object o = model.GetValue(iter, 0); | |
200 | |
201 if (o is ArmyCategory) | |
202 { | |
203 ArmyCategory c = (ArmyCategory)o; | |
204 string name = ""; | |
205 | |
206 if (Preferences.GetBooleanProperty("ShowCatPercentage")) | |
207 { | |
208 name = Translation.GetTranslation("categoryTreeCatName", "{0} - {1}pts", c.Name, c.PointsTotal); | |
209 } | |
210 else | |
211 { | |
212 name = Translation.GetTranslation("categoryTreeCatNamePercentage", "{0} - {1}pts ({2}%)", c.Name, c.PointsTotal, (c.ParentArmy.PointsTotal > 0 ? Math.Round((c.PointsTotal / c.ParentArmy.PointsTotal) * 100) : 0)); | |
213 } | |
214 | |
215 (cell as CellRendererText).Text = name; | |
216 } | |
217 else if (o is IBBoard.WarFoundry.API.Objects.Unit) | |
218 { | |
219 IBBoard.WarFoundry.API.Objects.Unit u = (IBBoard.WarFoundry.API.Objects.Unit)o; | |
220 string name = Translation.GetTranslation("categoryTreeCatName", "{0} - {1}pts", u.Name, u.PointsValue); | |
221 (cell as CellRendererText).Text = name; | |
222 } | |
223 } | |
224 | |
225 private void OnWindowDestroyed(object source, EventArgs args) | |
226 { | |
227 logger.Info("Exiting"); | |
228 Application.Quit(); | |
229 } | |
230 | |
231 private void OnUnitNameChanged(WarFoundryObject val, string oldValue, string newValue) | |
232 { | |
233 IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)val; | |
234 UnitDisplayWidget widget; | |
235 unitToWidgetMap.TryGetValue(unit, out widget); | |
236 | |
237 if (widget!=null) | |
238 { | |
239 unitsNotebook.SetTabLabelText(widget, newValue); | |
240 } | |
241 } | |
242 | |
243 private void OnUnitAdded(WarFoundryObject val) | |
244 { | |
245 IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)val; | |
246 unit.NameChanged+= UnitNameChangedMethod; | |
247 AddUnitToTree(unit); | |
248 } | |
249 | |
250 private void AddUnitToTree(IBBoard.WarFoundry.API.Objects.Unit unit) | |
251 { | |
252 TreeStore model = (TreeStore)treeUnits.Model; | |
253 TreeIter iter; | |
254 model.GetIterFirst(out iter); | |
255 | |
256 do | |
257 { | |
258 object obj = model.GetValue(iter, 0); | |
259 | |
260 if (obj is ArmyCategory) | |
261 { | |
262 ArmyCategory cat = (ArmyCategory)obj; | |
263 | |
264 if (cat.Equals(unit.Category)) | |
265 { | |
266 model.AppendValues(iter, unit); | |
267 TreePath path = model.GetPath(iter); | |
268 treeUnits.ExpandToPath(path); | |
269 } | |
270 } | |
271 } | |
272 while (model.IterNext(ref iter)); | |
273 } | |
274 | |
275 private void OnUnitRemoved(WarFoundryObject obj) | |
276 { | |
277 IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)obj; | |
278 unit.NameChanged-= UnitNameChangedMethod; | |
279 RemoveUnitFromTree(unit); | |
280 | |
281 //See if unit has a tab open and close it if it does | |
282 } | |
283 | |
284 private void RemoveUnitFromTree(IBBoard.WarFoundry.API.Objects.Unit unit) | |
285 { | |
286 TreeStore model = (TreeStore)treeUnits.Model; | |
287 TreeIter iter; | |
288 model.GetIterFirst(out iter); | |
289 bool removed = false; | |
290 | |
291 do | |
292 { | |
293 object obj = model.GetValue(iter, 0); | |
294 | |
295 if (obj is ArmyCategory) | |
296 { | |
297 ArmyCategory cat = (ArmyCategory)obj; | |
298 | |
299 if (unit.Category == null || cat.Equals(unit.Category)) | |
300 { | |
301 TreeIter innerIter; | |
302 model.IterChildren(out innerIter, iter); | |
303 | |
304 do | |
305 { | |
306 object innerObj = model.GetValue(innerIter, 0); | |
307 | |
308 if (unit.Equals(innerObj)) | |
309 { | |
310 model.Remove(ref innerIter); | |
311 removed = true; | |
312 break; | |
313 } | |
314 } | |
315 while (model.IterNext(ref innerIter)); | |
316 | |
317 if (removed) | |
318 { | |
319 break; | |
320 } | |
321 } | |
322 } | |
323 } | |
324 while (model.IterNext(ref iter)); | |
325 } | |
326 | |
327 private void OnPointsValueChanged(WarFoundryObject obj, double before, double after) | |
328 { | |
329 //Set points in panel | |
330 } | |
331 | |
332 private void OnFailedUnitRequirement(List<FailedUnitRequirement> failedRequirement) | |
333 { | |
334 //Show error message in panel | |
335 } | |
336 | |
337 public Preferences Preferences | |
338 { | |
339 get { return preferences; } | |
340 set { preferences = value; } | |
341 } | |
342 | |
343 /*public AbstractNativeWarFoundryFactory Factory | |
344 { | |
345 get { return WarFoundryFactoryFactory.GetFactoryFactory().GetFactory(Constants.ExecutablePath, factoryType); } | |
346 }*/ | |
347 | |
348 protected void OnDeleteEvent (object sender, DeleteEventArgs a) | |
349 { | |
350 Application.Quit (); | |
351 a.RetVal = true; | |
352 } | |
353 | |
354 protected virtual void OnExitActivated(object sender, System.EventArgs e) | |
355 { | |
356 Application.Quit(); | |
357 } | |
358 | |
359 protected virtual void OnChangeGameSystemActivated(object sender, System.EventArgs e) | |
360 { | |
361 ChangeCurrentGameSystem(); | |
362 } | |
363 | |
364 protected virtual void OnCreateArmyActivated(object sender, System.EventArgs e) | |
365 { | |
366 CreateNewArmy(); | |
367 } | |
368 | |
369 protected virtual void OnReloadFilesActivated(object sender, System.EventArgs e) | |
370 { | |
371 } | |
372 | |
373 protected virtual void OnSaveArmyAsActivated(object sender, System.EventArgs e) | |
374 { | |
375 SaveCurrentArmyAs(); | |
376 } | |
377 | |
378 protected virtual void OnCloseArmyActivated(object sender, System.EventArgs e) | |
379 { | |
380 CloseCurrentArmy(); | |
381 } | |
382 | |
383 protected virtual void OnOpenArmyActivated(object sender, System.EventArgs e) | |
384 { | |
385 OpenArmy(); | |
386 } | |
387 | |
388 protected virtual void OnSaveArmyActivated(object sender, System.EventArgs e) | |
389 { | |
390 SaveCurrentArmy(); | |
391 } | |
392 | |
393 protected virtual void OnAddUnitActivated(object sender, System.EventArgs e) | |
394 { | |
395 if (sender is ToolButton) | |
396 { | |
397 Category cat = null; | |
398 categoryMap.TryGetValue((ToolButton)sender, out cat); | |
399 | |
400 if (cat!=null) | |
401 { | |
402 logger.DebugFormat("Show FrmNewUnit for {0}", cat.Name); | |
403 FrmNewUnit newUnit = new FrmNewUnit(WarFoundryCore.CurrentArmy.Race, cat, WarFoundryCore.CurrentArmy); | |
404 ResponseType response = (ResponseType)newUnit.Run(); | |
405 newUnit.Hide(); | |
406 | |
407 if (response==ResponseType.Ok) | |
408 { | |
409 CreateAndAddUnitCommand cmd = new CreateAndAddUnitCommand(newUnit.SelectedUnit, cat, WarFoundryCore.CurrentArmy); | |
410 commandStack.Execute(cmd); | |
411 } | |
412 | |
413 newUnit.Dispose(); | |
414 } | |
415 } | |
416 } | |
417 | |
418 public CommandStack CommandStack | |
419 { | |
420 get { return commandStack; } | |
421 } | |
422 | |
423 private void SetAppTitle() | |
424 { | |
425 if (WarFoundryCore.CurrentArmy!=null) | |
426 { | |
427 Title = AppTitle + " - " + WarFoundryCore.CurrentGameSystem.Name + " - " + WarFoundryCore.CurrentArmy.Name; | |
428 } | |
429 else if (WarFoundryCore.CurrentGameSystem!=null) | |
430 { | |
431 Title = AppTitle + " - " + WarFoundryCore.CurrentGameSystem.Name; | |
432 } | |
433 else | |
434 { | |
435 Title = AppTitle; | |
436 } | |
437 } | |
438 | |
439 private void OnGameSystemChanged(GameSystem oldSys, GameSystem newSys) | |
440 { | |
441 system = newSys; | |
442 SetAppTitle(); | |
443 miCreateArmy.Sensitive = system!=null; | |
444 newArmyButton.Sensitive = system!=null; | |
445 RemoveCategoryButtons(); | |
446 | |
447 if (system!=null) | |
448 { | |
449 AddCategoryButtons(system.Categories); | |
450 } | |
451 } | |
452 | |
453 private void OnArmyChanged(Army oldArmy, Army newArmy) | |
454 { | |
455 loadedArmyPath = null; | |
456 SetAppTitle(); | |
457 SetArmyTree(newArmy); | |
458 | |
459 if (oldArmy!=null) | |
460 { | |
461 oldArmy.UnitAdded-= UnitAddedMethod; | |
462 oldArmy.UnitRemoved-= UnitRemovedMethod; | |
463 oldArmy.PointsValueChanged-= PointsValueChangedMethod; | |
464 oldArmy.FailedRequirement-=FailedUnitRequirementMethod; | |
465 } | |
466 | |
467 unitToWidgetMap.Clear(); | |
468 | |
469 while (unitsNotebook.NPages > 0) | |
470 { | |
471 unitsNotebook.RemovePage(0); | |
472 } | |
473 | |
474 if (newArmy==null) | |
475 { | |
476 DisableCategoryButtons(); | |
477 } | |
478 else | |
479 { | |
480 newArmy.UnitAdded+= UnitAddedMethod; | |
481 newArmy.UnitRemoved+= UnitRemovedMethod; | |
482 newArmy.PointsValueChanged+= PointsValueChangedMethod; | |
483 newArmy.FailedRequirement+=FailedUnitRequirementMethod; | |
484 //TODO: Clear all buttons | |
485 EnableCategoryButtons(); | |
486 | |
487 if (newArmy.Race.HasCategoryOverrides()) | |
488 { | |
489 RemoveCategoryButtons(); | |
490 AddCategoryButtons(newArmy.Race.Categories); | |
491 } | |
492 } | |
493 | |
494 miCloseArmy.Sensitive = newArmy!=null; | |
495 miSaveArmyAs.Sensitive = newArmy!=null; | |
496 //New army has no changes, so we can't save it | |
497 miSaveArmy.Sensitive = false; | |
498 saveArmyButton.Sensitive = false; | |
499 | |
500 CommandStack.Reset(); | |
501 SetPointsPanelText(); | |
502 } | |
503 | |
504 private void SetArmyTree(Army army) | |
505 { | |
506 logger.Debug("Resetting tree"); | |
507 TreeStore store = (TreeStore)treeUnits.Model; | |
508 store.Clear(); | |
509 TreeIter iter; | |
510 | |
511 if (army!=null) | |
512 { | |
513 logger.Debug("Loading in categories to tree"); | |
514 | |
515 foreach (ArmyCategory cat in army.Categories) | |
516 { | |
517 logger.DebugFormat("Append category {0}", cat.Name); | |
518 iter = store.AppendValues(cat); | |
519 | |
520 foreach (IBBoard.WarFoundry.API.Objects.Unit unit in cat.GetUnits()) | |
521 { | |
522 store.AppendValues(iter, unit); | |
523 } | |
524 } | |
525 | |
526 logger.Debug("Finished loading tree categories"); | |
527 } | |
528 } | |
529 | |
530 private void DisableCategoryButtons() | |
531 { | |
532 SetCategoryButtonsSensitive(false); | |
533 } | |
534 | |
535 private void EnableCategoryButtons() | |
536 { | |
537 SetCategoryButtonsSensitive(true); | |
538 } | |
539 | |
540 private void SetCategoryButtonsSensitive(bool state) | |
541 { | |
542 int toolbarButtonCount = toolbar.Children.Length - 1; | |
543 logger.Debug("Last button index: "+toolbarButtonCount); | |
544 | |
545 for (int i = toolbarButtonCount; i > CATEGORY_BUTTON_SEPARATOR_INDEX; i--) | |
546 { | |
547 logger.DebugFormat("Setting button {0} state to {1}", i, state); | |
548 toolbar.Children[i].Sensitive = state; | |
549 } | |
550 } | |
551 | |
552 private void RemoveCategoryButtons() | |
553 { | |
554 int toolbarButtonCount = toolbar.Children.Length - 1; | |
555 | |
556 for (int i = toolbarButtonCount; i > CATEGORY_BUTTON_SEPARATOR_INDEX; i--) | |
557 { | |
558 toolbar.Remove(toolbar.Children[i]); | |
559 } | |
560 | |
561 categoryMap.Clear(); | |
562 } | |
563 | |
564 private void AddCategoryButtons(Category[] cats) | |
565 { | |
566 if (cats!=null && cats.Length > 0) | |
567 { | |
568 logger.DebugFormat("Toolbar button count: {0}. Adding {1} categories.", toolbar.Children.Length, cats.Length); | |
569 | |
570 foreach (Category cat in cats) | |
571 { | |
572 ToolButton button = new ToolButton("gtk-add"); | |
573 button.Label = cat.Name; | |
574 button.SetTooltip(new Tooltips(), "Add unit from "+cat.Name, ""); | |
575 //TODO: See if we can associate data in some way, the same as we can with SWF. For now we just use the map. | |
576 categoryMap.Add(button, cat); | |
577 button.Clicked+= new System.EventHandler(OnAddUnitActivated); | |
578 toolbar.Insert(button, -1); | |
579 } | |
580 } | |
581 | |
582 toolbar.Children[CATEGORY_BUTTON_SEPARATOR_INDEX].Visible = cats!=null && cats.Length>0; | |
583 | |
584 toolbar.ShowAll(); | |
585 } | |
586 | |
587 private void SetPointsPanelText() | |
588 { | |
589 //TODO: Set the points value in the status bar | |
590 } | |
591 | |
592 private void commandStack_CommandStackUpdated() | |
593 { | |
594 undoMenuButton.Sensitive = commandStack.CanUndo(); | |
595 miUndo.Sensitive = undoMenuButton.Sensitive; | |
596 redoMenuButton.Sensitive = commandStack.CanRedo(); | |
597 miRedo.Sensitive = redoMenuButton.Sensitive; | |
598 int redoLength = commandStack.RedoLength; | |
599 //TODO: Build menus for undo/redo and find way of adding tooltips | |
600 /*int maxRedo = Math.Min(10, redoLength); | |
601 MenuItem[] menuItems = null; | |
602 | |
603 if (redoLength > 0) | |
604 { | |
605 menuItems = new MenuItem[maxRedo]; | |
606 Command com; | |
607 MenuItem mi; | |
608 | |
609 for (int i = 0; i < maxRedo; i++) | |
610 { | |
611 com = commandStack.PeekRedoCommand(i+1); | |
612 | |
613 if (com == null) | |
614 { | |
615 break; | |
616 } | |
617 | |
618 mi = new MenuItem(com.Description); | |
619 mi.Click+=new EventHandler(redoMenu_Click); | |
620 menuItems[i] = mi; | |
621 } | |
622 } | |
623 | |
624 redoMenu.MenuItems.Clear(); | |
625 | |
626 if (menuItems!=null && menuItems[0]!=null) | |
627 { | |
628 bttnRedo.ToolTipText = menuItems[0].Text; | |
629 redoMenu.MenuItems.AddRange(menuItems); | |
630 }*/ | |
631 //TODO: Put above code back when we have a dropdown version of the redo button | |
632 if (redoLength > 0) | |
633 { | |
634 //redoMenuButton.Tooltip = CommandStack.PeekRedoCommand().Description; | |
635 } | |
636 | |
637 int undoLength = commandStack.UndoLength; | |
638 /*int maxUndo = Math.Min(10, undoLength); | |
639 MenuItem[] menuItemsUndo = null; | |
640 | |
641 if (undoLength > 0) | |
642 { | |
643 menuItemsUndo = new MenuItem[maxUndo]; | |
644 Command com; | |
645 MenuItem mi; | |
646 | |
647 for (int i = 0; i < maxUndo; i++) | |
648 { | |
649 com = commandStack.PeekUndoCommand(i+1); | |
650 | |
651 if (com == null) | |
652 { | |
653 break; | |
654 } | |
655 | |
656 mi = new MenuItem(com.UndoDescription); | |
657 mi.Click+=new EventHandler(undoMenu_Click); | |
658 menuItemsUndo[i] = mi; | |
659 } | |
660 } | |
661 | |
662 undoMenu.MenuItems.Clear(); | |
663 | |
664 if (menuItemsUndo!=null && menuItemsUndo[0]!=null) | |
665 { | |
666 bttnUndo.ToolTipText = menuItemsUndo[0].Text; | |
667 undoMenu.MenuItems.AddRange(menuItemsUndo); | |
668 }*/ | |
669 //TODO: Put above code back when we have a dropdown version of the undo button | |
670 if (undoLength > 0) | |
671 { | |
672 //undoMenuButton.Tooltip = CommandStack.PeekUndoCommand().UndoDescription; | |
673 } | |
674 | |
675 saveArmyButton.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy!=null && CanSave(); | |
676 miSaveArmy.Sensitive = commandStack.IsDirty() && WarFoundryCore.CurrentArmy!=null && CanSave(); | |
677 } | |
678 | |
679 private bool CanSave() | |
680 { | |
681 return loadedArmyPath!=null && WarFoundryCore.CurrentArmy!=null && WarFoundrySaver.GetSaver()!=null; | |
682 } | |
683 | |
684 private bool SaveCurrentArmyOrSaveAs() | |
685 { | |
686 if (CanSave()) | |
687 { | |
688 return SaveCurrentArmy(); | |
689 } | |
690 else | |
691 { | |
692 return SaveCurrentArmyAs(); | |
693 } | |
694 } | |
695 | |
696 private bool OpenArmy() | |
697 { | |
698 //TODO: Open dialog for file selection then open army | |
699 bool success = false; | |
700 loadedArmyPath = null;//TODO: Set loaded file path | |
701 return success; | |
702 } | |
703 | |
704 private bool SaveCurrentArmy() | |
705 { | |
706 bool success = false; | |
707 | |
708 if (CanSave()) | |
709 { | |
710 try | |
711 { | |
712 if (WarFoundrySaver.GetSaver().Save(WarFoundryCore.CurrentArmy, loadedArmyPath)) | |
713 { | |
714 saveArmyButton.Sensitive = false; | |
715 miSaveArmy.Sensitive = false; | |
716 CommandStack.setCleanMark(); | |
717 success = true; | |
718 } | |
719 } | |
720 catch (IOException ex) | |
721 { | |
722 logger.Error("Saving army failed", ex); | |
723 MessageDialog md = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, "An error occured while saving the army. Please check the logs for details on what failed"); | |
724 md.Show(); | |
725 } | |
726 } | |
727 | |
728 return success; | |
729 } | |
730 | |
731 private bool SaveCurrentArmyAs() | |
732 { | |
733 /*if (saveArmyDialog.Filter == "") | |
734 { | |
735 string savePath = UserDataPath+Constants.DirectoryString+"armies"+Constants.DirectoryString; | |
736 | |
737 if (!Directory.Exists(savePath)) | |
738 { | |
739 Directory.CreateDirectory(savePath); | |
740 } | |
741 | |
742 saveArmyDialog.InitialDirectory = savePath; | |
743 saveArmyDialog.Filter = Translation.GetTranslation("armyFileFilter")+"|*.army"; | |
744 saveArmyDialog.Title = Translation.GetTranslation("saveArmyDialog"); | |
745 } | |
746 | |
747 DialogResult dr = saveArmyDialog.ShowDialog(this); | |
748 | |
749 if (dr == DialogResult.OK) | |
750 { | |
751 if (WarFoundrySaver.GetSaver().Save(WarFoundryCore.CurrentArmy, saveArmyDialog.FileName)) | |
752 { | |
753 miSaveArmy.Enabled = false; | |
754 bttnSaveArmy.Enabled = false; | |
755 CommandStack.setCleanMark(); | |
756 loadedArmyPath = saveArmyDialog.FileName; | |
757 return true; | |
758 } | |
759 else | |
760 { | |
761 MessageBox.Show(this, Translation.GetTranslation("SaveFailed"), Translation.GetTranslation("SaveFailedTitle"), MessageBoxButtons.OK, MessageBoxIcon.Error); | |
762 return false; | |
763 } | |
764 } | |
765 else | |
766 { | |
767 return false; | |
768 }*/ | |
769 return false; | |
770 } | |
771 | |
772 private bool CloseCurrentArmy() | |
773 { | |
774 if (WarFoundryCore.CurrentArmy!=null) | |
775 { | |
776 bool canClose = false; | |
777 | |
778 if (CommandStack.IsDirty()) | |
779 { | |
780 MessageDialog dia = new MessageDialog(this, DialogFlags.DestroyWithParent, MessageType.Question, ButtonsType.YesNo | ButtonsType.Cancel, "The army \""+WarFoundryCore.CurrentArmy.Name+"\" has been modified.\r\nSave changes before closing army?"); | |
781 ResponseType dr = (ResponseType)dia.Run(); | |
782 | |
783 if (dr == ResponseType.Yes) | |
784 { | |
785 //They want to save so try to save it or prompt for save as | |
786 //If they cancel the save as then assume they don't want to close | |
787 canClose = SaveCurrentArmyOrSaveAs(); | |
788 } | |
789 else if (dr == ResponseType.No) | |
790 { | |
791 //They don't care about their changes | |
792 canClose = true; | |
793 } | |
794 else | |
795 { | |
796 //Assume cancel or close with the X button | |
797 canClose = false; | |
798 } | |
799 | |
800 dia.Dispose(); | |
801 } | |
802 else | |
803 { | |
804 //Nothing has changed so we can safely close | |
805 canClose = true; | |
806 } | |
807 | |
808 if (canClose) | |
809 { | |
810 //do close | |
811 WarFoundryCore.CurrentArmy = null; | |
812 return true; | |
813 } | |
814 else | |
815 { | |
816 return false; | |
817 } | |
818 } | |
819 else | |
820 { | |
821 //pretend we succeeded | |
822 return true; | |
823 } | |
824 } | |
825 | |
826 private void CreateNewArmy() | |
827 { | |
828 logger.Debug("Create new army"); | |
829 FrmNewArmy newArmy = new FrmNewArmy(WarFoundryCore.CurrentGameSystem); | |
830 ResponseType type = (ResponseType)newArmy.Run(); | |
831 newArmy.Hide(); | |
832 | |
833 if (type == ResponseType.Ok) | |
834 { | |
835 if (CloseCurrentArmy()) | |
836 { | |
837 WarFoundryCore.CurrentArmy = new Army(newArmy.SelectedRace, newArmy.ArmyName, newArmy.ArmySize); | |
838 } | |
839 } | |
840 else | |
841 { | |
842 logger.Debug("Create new army cancelled"); | |
843 } | |
844 | |
845 newArmy.Destroy(); | |
846 } | |
847 | |
848 private void ChangeCurrentGameSystem() | |
849 { | |
850 logger.Debug("Changing game system"); | |
851 FrmChangeGameSystem dialog = new FrmChangeGameSystem(this); | |
852 ResponseType type = (ResponseType)dialog.Run(); | |
853 dialog.Hide(); | |
854 | |
855 if (type == ResponseType.Ok) | |
856 { | |
857 WarFoundryCore.CurrentGameSystem = dialog.SelectedSystem; | |
858 } | |
859 else | |
860 { | |
861 logger.Debug("Game system change cancelled"); | |
862 } | |
863 | |
864 dialog.Destroy(); | |
865 } | |
866 | |
867 protected virtual void undoTBButtonActivated (object sender, System.EventArgs e) | |
868 { | |
869 CommandStack.Undo(); | |
870 } | |
871 | |
872 protected virtual void redoTBButtonActivated (object sender, System.EventArgs e) | |
873 { | |
874 CommandStack.Redo(); | |
875 } | |
876 | |
877 protected virtual void saveTBButtonActivated (object sender, System.EventArgs e) | |
878 { | |
879 SaveCurrentArmy(); | |
880 } | |
881 | |
882 protected virtual void openTBButtonActivated (object sender, System.EventArgs e) | |
883 { | |
884 OpenArmy(); | |
885 } | |
886 | |
887 protected virtual void newTBButtonActivated (object sender, System.EventArgs e) | |
888 { | |
889 CreateNewArmy(); | |
890 } | |
891 | |
892 protected virtual void ArmyRowActivated (object o, Gtk.RowActivatedArgs args) | |
893 { | |
894 TreeModel model = treeUnits.Model; | |
895 TreeIter iter; | |
896 model.GetIter(out iter, args.Path); | |
897 object obj = model.GetValue(iter, 0); | |
898 | |
899 if (obj is IBBoard.WarFoundry.API.Objects.Unit) | |
900 { | |
901 IBBoard.WarFoundry.API.Objects.Unit unit = (IBBoard.WarFoundry.API.Objects.Unit)obj; | |
902 | |
903 UnitDisplayWidget widget; | |
904 unitToWidgetMap.TryGetValue(unit, out widget); | |
905 | |
906 if (widget!=null) | |
907 { | |
908 logger.DebugFormat("Selecting existing page for "+unit.Name); | |
909 unitsNotebook.Page = unitsNotebook.PageNum(widget); | |
910 } | |
911 else | |
912 { | |
913 widget = new UnitDisplayWidget(unit, CommandStack); | |
914 Label label = new Label(unit.Name); | |
915 logger.Debug("Adding page for "+unit.Name); | |
916 unitToWidgetMap[unit] = widget; | |
917 int pageNum = unitsNotebook.AppendPage(widget, label); | |
918 logger.Debug("Page added at index "+pageNum); | |
919 unitsNotebook.ShowAll(); | |
920 unitsNotebook.Page = pageNum; | |
921 } | |
922 } | |
923 } | |
924 } | |
925 } |