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