diff --git a/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/MainWindow.cs b/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/MainWindow.cs
index b450b52d..80163c2c 100644
--- a/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/MainWindow.cs
+++ b/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/MainWindow.cs
@@ -1,11 +1,74 @@
using System;
using Gtk;
+using UniversalEditor.UserInterface;
+
public partial class MainWindow: Gtk.Window
{
public MainWindow (): base (Gtk.WindowType.Toplevel)
{
Build ();
+ InitializeMenuBar();
+ }
+
+ private void InitializeMenuBar()
+ {
+ foreach (CommandItem item in Engine.CurrentEngine.MainMenu.Items)
+ {
+ CreateCommandItem(item, null);
+ }
+ menubar1.ShowAll ();
+ }
+ private void CreateCommandItem(CommandItem item, Menu parentMenu)
+ {
+ Gtk.MenuItem menuItem = null;
+
+ if (item is CommandReferenceCommandItem)
+ {
+ CommandReferenceCommandItem crci = (item as CommandReferenceCommandItem);
+ Command cmd = Engine.CurrentEngine.Commands[crci.CommandID];
+ if (cmd == null)
+ {
+ HostApplication.Messages.Add(HostApplicationMessageSeverity.Warning, "The command '" + crci.CommandID + "' was not found");
+ return;
+ }
+
+ menuItem = new Gtk.MenuItem(cmd.Title);
+ if (cmd.Items.Count > 0)
+ {
+ Menu submenu = CreateCommandItemSubmenu(cmd);
+ menuItem.Submenu = submenu;
+ }
+ }
+ else if (item is SeparatorCommandItem)
+ {
+ menuItem = new Gtk.SeparatorMenuItem();
+ }
+
+ if (menuItem != null)
+ {
+ if (parentMenu == null)
+ {
+ menubar1.Append(menuItem);
+ }
+ else
+ {
+ parentMenu.Append(menuItem);
+ }
+ }
+ }
+ private Menu CreateCommandItemSubmenu(Command cmd)
+ {
+ Menu menu = new Menu();
+ if (Engine.CurrentEngine.MainMenu.EnableTearoff && cmd.EnableTearoff)
+ {
+ menu.Append(new TearoffMenuItem());
+ }
+ foreach (CommandItem item in cmd.Items)
+ {
+ CreateCommandItem(item, menu);
+ }
+ return menu;
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
diff --git a/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/MainWindow.cs b/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/MainWindow.cs
index 93e8cd32..27727a31 100644
--- a/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/MainWindow.cs
+++ b/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/MainWindow.cs
@@ -20,6 +20,8 @@ public partial class MainWindow
private global::Gtk.Action CutAction;
private global::Gtk.VBox vbox1;
private global::Gtk.MenuBar menubar1;
+ private global::Gtk.Toolbar toolbar1;
+ private global::Gtk.Notebook notebook1;
private global::Gtk.Statusbar statusbar1;
private global::Gtk.Label lblStatus;
@@ -151,7 +153,7 @@ public partial class MainWindow
this.vbox1.Name = "vbox1";
this.vbox1.Spacing = 6;
// Container child vbox1.Gtk.Box+BoxChild
- this.UIManager.AddUiFromString ("");
+ this.UIManager.AddUiFromString ("");
this.menubar1 = ((global::Gtk.MenuBar)(this.UIManager.GetWidget ("/menubar1")));
this.menubar1.Name = "menubar1";
this.vbox1.Add (this.menubar1);
@@ -160,6 +162,24 @@ public partial class MainWindow
w2.Expand = false;
w2.Fill = false;
// Container child vbox1.Gtk.Box+BoxChild
+ this.UIManager.AddUiFromString ("");
+ this.toolbar1 = ((global::Gtk.Toolbar)(this.UIManager.GetWidget ("/toolbar1")));
+ this.toolbar1.Name = "toolbar1";
+ this.toolbar1.ShowArrow = false;
+ this.vbox1.Add (this.toolbar1);
+ global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.vbox1 [this.toolbar1]));
+ w3.Position = 1;
+ w3.Expand = false;
+ w3.Fill = false;
+ // Container child vbox1.Gtk.Box+BoxChild
+ this.notebook1 = new global::Gtk.Notebook ();
+ this.notebook1.CanFocus = true;
+ this.notebook1.Name = "notebook1";
+ this.notebook1.CurrentPage = -1;
+ this.vbox1.Add (this.notebook1);
+ global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox1 [this.notebook1]));
+ w4.Position = 2;
+ // Container child vbox1.Gtk.Box+BoxChild
this.statusbar1 = new global::Gtk.Statusbar ();
this.statusbar1.Name = "statusbar1";
this.statusbar1.Spacing = 6;
@@ -170,19 +190,19 @@ public partial class MainWindow
this.lblStatus.Xalign = 0F;
this.lblStatus.LabelProp = global::Mono.Unix.Catalog.GetString ("Ready");
this.statusbar1.Add (this.lblStatus);
- global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.statusbar1 [this.lblStatus]));
- w3.Position = 0;
+ global::Gtk.Box.BoxChild w5 = ((global::Gtk.Box.BoxChild)(this.statusbar1 [this.lblStatus]));
+ w5.Position = 0;
this.vbox1.Add (this.statusbar1);
- global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.vbox1 [this.statusbar1]));
- w4.Position = 2;
- w4.Expand = false;
- w4.Fill = false;
+ global::Gtk.Box.BoxChild w6 = ((global::Gtk.Box.BoxChild)(this.vbox1 [this.statusbar1]));
+ w6.Position = 3;
+ w6.Expand = false;
+ w6.Fill = false;
this.Add (this.vbox1);
if ((this.Child != null)) {
this.Child.ShowAll ();
}
this.DefaultWidth = 400;
- this.DefaultHeight = 300;
+ this.DefaultHeight = 299;
this.Show ();
this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent);
}
diff --git a/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/gui.stetic b/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/gui.stetic
index a37f2c64..0118b136 100644
--- a/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/gui.stetic
+++ b/CSharp/Environments/GTK/Engines/UniversalEditor.Environments.GTK/gtk-gui/gui.stetic
@@ -6,9 +6,9 @@
-
+
-
+
Action
@@ -93,27 +93,7 @@
0
@@ -123,7 +103,28 @@
-
+
+
+ False
+
+
+
+ 1
+ True
+ False
+ False
+
+
+
+
+
+ True
+ -1
+
+
+ 2
+ False
+
@@ -143,7 +144,7 @@
- 2
+ 3
True
False
False
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Command.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Command.cs
new file mode 100644
index 00000000..2aba0fb8
--- /dev/null
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/Command.cs
@@ -0,0 +1,71 @@
+using System;
+
+namespace UniversalEditor.UserInterface
+{
+ public class Command
+ {
+ public class CommandCollection
+ : System.Collections.ObjectModel.Collection
+ {
+ public Command this[string ID]
+ {
+ get
+ {
+ foreach (Command command in this)
+ {
+ if (command.ID == ID) return command;
+ }
+ return null;
+ }
+ }
+ }
+
+ private bool mvarEnableTearoff = false;
+ public bool EnableTearoff { get { return mvarEnableTearoff; } set { mvarEnableTearoff = value; } }
+
+ private string mvarID = String.Empty;
+ ///
+ /// The ID of the command, used to reference it in .
+ ///
+ public string ID { get { return mvarID; } set { mvarID = value; } }
+
+ private string mvarTitle = String.Empty;
+ ///
+ /// The title of the command (including mnemonic prefix, if applicable).
+ ///
+ public string Title { get { return mvarTitle; } set { mvarTitle = value; } }
+
+ private StockCommandType mvarStockCommandType = StockCommandType.None;
+ ///
+ /// A that represents a predefined, platform-themed command.
+ ///
+ public StockCommandType StockCommandType { get { return mvarStockCommandType; } set { mvarStockCommandType = value; } }
+
+ private string mvarImageFileName = String.Empty;
+ ///
+ /// The file name of the image to be displayed on the command.
+ ///
+ public string ImageFileName { get { return mvarImageFileName; } set { mvarImageFileName = value; } }
+
+
+ private CommandItem.CommandItemCollection mvarItems = new CommandItem.CommandItemCollection();
+ ///
+ /// The child s that are contained within this .
+ ///
+ public CommandItem.CommandItemCollection Items { get { return mvarItems; } }
+
+ ///
+ /// The event that is fired when the command is executed.
+ ///
+ public event EventHandler Executed;
+
+ ///
+ /// Executes this .
+ ///
+ public void Execute()
+ {
+ if (Executed != null) Executed(this, EventArgs.Empty);
+ }
+ }
+}
+
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/CommandItem.cs b/CSharp/Libraries/UniversalEditor.UserInterface/CommandItem.cs
new file mode 100644
index 00000000..e0775aa5
--- /dev/null
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/CommandItem.cs
@@ -0,0 +1,25 @@
+using System;
+namespace UniversalEditor.UserInterface
+{
+ public abstract class CommandItem
+ {
+ public class CommandItemCollection
+ : System.Collections.ObjectModel.Collection
+ {
+ }
+ }
+ public class CommandReferenceCommandItem : CommandItem
+ {
+ private string mvarCommandID = String.Empty;
+ public string CommandID { get { return mvarCommandID; } set { mvarCommandID = value; } }
+
+ public CommandReferenceCommandItem(string commandID)
+ {
+ mvarCommandID = commandID;
+ }
+ }
+ public class SeparatorCommandItem : CommandItem
+ {
+ }
+}
+
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs b/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs
index 90d98aaa..c2e4286e 100644
--- a/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/Engine.cs
@@ -3,10 +3,14 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
+
using UniversalEditor.Accessors;
using UniversalEditor.ObjectModels.FileSystem;
using UniversalEditor.ObjectModels.PropertyList;
+using UniversalEditor.DataFormats.Markup.XML;
+using UniversalEditor.ObjectModels.Markup;
+
namespace UniversalEditor.UserInterface
{
public abstract class Engine
@@ -77,6 +81,23 @@ namespace UniversalEditor.UserInterface
protected abstract void MainLoop();
+ private Command.CommandCollection mvarCommands = new Command.CommandCollection();
+ ///
+ /// The commands defined for this application.
+ ///
+ public Command.CommandCollection Commands { get { return mvarCommands; } }
+
+ private EngineMainMenu mvarMainMenu = new EngineMainMenu();
+ ///
+ /// The main menu of this application, which can hold multiple s.
+ ///
+ public EngineMainMenu MainMenu { get { return mvarMainMenu; } }
+
+ ///
+ /// The aggregated raw markup of all the various XML files loaded in the current search path.
+ ///
+ private MarkupObjectModel mvarRawMarkup = new MarkupObjectModel();
+
private PropertyListObjectModel mvarConfiguration = new PropertyListObjectModel();
public PropertyListObjectModel Configuration { get { return mvarConfiguration; } }
@@ -125,6 +146,108 @@ namespace UniversalEditor.UserInterface
}
}
+ protected virtual void InitializeXMLConfiguration()
+ {
+ #region Load the XML files
+ string[] xmlfiles = System.IO.Directory.GetFiles(mvarBasePath, "*.xml", System.IO.SearchOption.AllDirectories);
+
+ XMLDataFormat xdf = new XMLDataFormat();
+ foreach (string xmlfile in xmlfiles)
+ {
+ MarkupObjectModel markup = new MarkupObjectModel();
+ Document doc = new Document(markup, xdf, new FileAccessor(xmlfile));
+ doc.Accessor.Open ();
+ doc.Load ();
+ doc.Close ();
+
+ markup.CopyTo (mvarRawMarkup);
+ }
+
+ #endregion
+ #region Initialize the configuration with the loaded data
+
+ MarkupTagElement tagCommands = (mvarRawMarkup.FindElement ("UniversalEditor", "Application", "Commands") as MarkupTagElement);
+ if (tagCommands != null)
+ {
+ foreach (MarkupElement elCommand in tagCommands.Elements)
+ {
+ MarkupTagElement tagCommand = (elCommand as MarkupTagElement);
+ if (tagCommand == null) continue;
+ if (tagCommand.FullName != "Command") continue;
+
+ MarkupAttribute attID = tagCommand.Attributes["ID"];
+ if (attID == null) continue;
+
+ Command cmd = new Command();
+ cmd.ID = attID.Value;
+
+ MarkupAttribute attTitle = tagCommand.Attributes["Title"];
+ if (attTitle != null)
+ {
+ cmd.Title = attTitle.Value;
+ }
+
+ MarkupTagElement tagItems = (tagCommand.Elements["Items"] as MarkupTagElement);
+ if (tagItems != null)
+ {
+ foreach (MarkupElement el in tagItems.Elements)
+ {
+ MarkupTagElement tag = (el as MarkupTagElement);
+ if (tag == null) continue;
+
+ InitializeMainMenuItem(tag, cmd);
+ }
+ }
+
+ mvarCommands.Add (cmd);
+ }
+ }
+
+ MarkupTagElement tagMainMenuItems = (mvarRawMarkup.FindElement ("UniversalEditor", "Application", "MainMenu", "Items") as MarkupTagElement);
+ foreach (MarkupElement elItem in tagMainMenuItems.Elements)
+ {
+ MarkupTagElement tagItem = (elItem as MarkupTagElement);
+ if (tagItem == null) continue;
+ InitializeMainMenuItem(tagItem, null);
+ }
+
+ #endregion
+ }
+
+ private void InitializeMainMenuItem(MarkupTagElement tag, Command parent)
+ {
+ CommandItem item = null;
+ switch (tag.FullName)
+ {
+ case "CommandReference":
+ {
+ MarkupAttribute attCommandID = tag.Attributes["CommandID"];
+ if (attCommandID != null)
+ {
+ item = new CommandReferenceCommandItem(attCommandID.Value);
+ }
+ break;
+ }
+ case "Separator":
+ {
+ item = new SeparatorCommandItem();
+ break;
+ }
+ }
+
+ if (item != null)
+ {
+ if (parent == null)
+ {
+ mvarMainMenu.Items.Add(item);
+ }
+ else
+ {
+ parent.Items.Add(item);
+ }
+ }
+ }
+
protected virtual void InitializeBranding()
{
@@ -161,6 +284,9 @@ namespace UniversalEditor.UserInterface
// overridden with a switch (/basepath:...) ?
mvarBasePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
+ // Initialize the XML files
+ InitializeXMLConfiguration();
+
// Initialize the branding for the selected application
InitializeBranding();
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/EngineMainMenu.cs b/CSharp/Libraries/UniversalEditor.UserInterface/EngineMainMenu.cs
new file mode 100644
index 00000000..6c3a088b
--- /dev/null
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/EngineMainMenu.cs
@@ -0,0 +1,16 @@
+using System;
+namespace UniversalEditor.UserInterface
+{
+ public class EngineMainMenu
+ {
+ private bool mvarEnableTearoff = false;
+ ///
+ /// Determines whether menus can be torn off to display their contents in a separate window.
+ ///
+ public bool EnableTearoff { get { return mvarEnableTearoff; } set { mvarEnableTearoff = value; } }
+
+ private CommandItem.CommandItemCollection mvarItems = new CommandItem.CommandItemCollection();
+ public CommandItem.CommandItemCollection Items { get { return mvarItems; } }
+ }
+}
+
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/HostApplication.cs b/CSharp/Libraries/UniversalEditor.UserInterface/HostApplication.cs
index cb3f6c10..06f3b22a 100644
--- a/CSharp/Libraries/UniversalEditor.UserInterface/HostApplication.cs
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/HostApplication.cs
@@ -8,12 +8,21 @@ namespace UniversalEditor.UserInterface
public static class HostApplication
{
private static IHostApplicationWindow mvarCurrentWindow = null;
+ ///
+ /// Gets or sets the current window of the host application.
+ ///
public static IHostApplicationWindow CurrentWindow { get { return mvarCurrentWindow; } set { mvarCurrentWindow = value; } }
private static HostApplicationOutputWindow mvarOutputWindow = new HostApplicationOutputWindow();
+ ///
+ /// Gets or sets the output window of the host application, where other plugins can read from and write to.
+ ///
public static HostApplicationOutputWindow OutputWindow { get { return mvarOutputWindow; } set { mvarOutputWindow = value; } }
private static HostApplicationMessage.HostApplicationMessageCollection mvarMessages = new HostApplicationMessage.HostApplicationMessageCollection();
+ ///
+ /// A collection of messages to display in the Error List panel.
+ ///
public static HostApplicationMessage.HostApplicationMessageCollection Messages { get { return mvarMessages; } }
}
}
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/StockCommandType.cs b/CSharp/Libraries/UniversalEditor.UserInterface/StockCommandType.cs
new file mode 100644
index 00000000..6b1b38f6
--- /dev/null
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/StockCommandType.cs
@@ -0,0 +1,9 @@
+using System;
+namespace UniversalEditor.UserInterface
+{
+ public enum StockCommandType
+ {
+ None
+ }
+}
+
diff --git a/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj b/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj
index 981af14e..3de047ad 100644
--- a/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj
+++ b/CSharp/Libraries/UniversalEditor.UserInterface/UniversalEditor.UserInterface.csproj
@@ -74,6 +74,10 @@
+
+
+
+