bring in all the stuff we've moved out of MBS.Framework.UserInterface

This commit is contained in:
Michael Becker 2020-11-06 22:24:50 -05:00
parent f87b6ab79c
commit 10290a037b
No known key found for this signature in database
GPG Key ID: 506F54899E2BFED7
12 changed files with 923 additions and 1 deletions

View File

@ -0,0 +1,229 @@
//
// Application.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2020 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WAR+RANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace MBS.Framework
{
public class Application
{
public static Application Instance { get; set; } = null;
public Guid ID { get; set; } = Guid.Empty;
public string UniqueName { get; set; } = null;
public string ShortName { get; set; }
public string Title { get; set; } = String.Empty;
public int ExitCode { get; protected set; } = 0;
public CommandLine CommandLine { get; protected set; } = null;
public Application()
{
CommandLine = new DefaultCommandLine();
}
private Dictionary<string, List<EventHandler>> _CommandEventHandlers = new Dictionary<string, List<EventHandler>>();
public Command.CommandCollection Commands { get; } = new Command.CommandCollection();
public bool AttachCommandEventHandler(string commandID, EventHandler handler)
{
Command cmd = Commands[commandID];
if (cmd != null)
{
cmd.Executed += handler;
return true;
}
Console.WriteLine("attempted to attach handler for unknown command '" + commandID + "'");
// handle command event handlers attached without a Command instance
if (!_CommandEventHandlers.ContainsKey(commandID))
{
_CommandEventHandlers.Add(commandID, new List<EventHandler>());
}
if (!_CommandEventHandlers[commandID].Contains(handler))
{
_CommandEventHandlers[commandID].Add(handler);
}
return false;
}
public void ExecuteCommand(string id, KeyValuePair<string, object>[] namedParameters = null)
{
Command cmd = Commands[id];
// handle command event handlers attached without a Command instance
if (_CommandEventHandlers.ContainsKey(id))
{
List<EventHandler> c = _CommandEventHandlers[id];
for (int i = 0; i < c.Count; i++)
{
c[i](cmd, new CommandEventArgs(cmd, namedParameters));
}
return;
}
// handle command event handlers attached in a context, most recently added first
for (int i = Contexts.Count - 1; i >= 0; i--)
{
if (Contexts[i].ExecuteCommand(id))
return;
}
if (cmd == null)
return;
cmd.Execute();
}
protected virtual void InitializeInternal()
{
}
[System.Diagnostics.DebuggerNonUserCode()]
public void Initialize()
{
if (ShortName == null)
throw new ArgumentException("must specify a ShortName for the application");
InitializeInternal();
}
protected virtual int StartInternal()
{
return 0;
}
public int Start()
{
int exitCode = StartInternal();
return exitCode;
}
// CONTEXTS
/// <summary>
/// Gets a collection of <see cref="Context" /> objects representing system, application, user, and custom contexts for settings and other items.
/// </summary>
/// <value>A collection of <see cref="Context" /> objects representing cpublic for settings and other items.</value>
public Context.ContextCollection Contexts { get; } = new Context.ContextCollection();
public ContextChangedEventHandler ContextAdded;
protected virtual void OnContextAdded(ContextChangedEventArgs e)
{
ContextAdded?.Invoke(this, e);
}
public ContextChangedEventHandler ContextRemoved;
protected virtual void OnContextRemoved(ContextChangedEventArgs e)
{
ContextRemoved?.Invoke(this, e);
}
/// <summary>
/// Handles updating the menus, toolbars, keyboard shortcuts, and other UI elements associated with the application <see cref="Context" />.
/// </summary>
internal void AddContext(Context ctx)
{
OnContextAdded(new ContextChangedEventArgs(ctx));
}
/// <summary>
/// Handles updating the menus, toolbars, keyboard shortcuts, and other UI elements associated with the application <see cref="Context" />.
/// </summary>
internal void RemoveContext(Context ctx)
{
OnContextRemoved(new ContextChangedEventArgs(ctx));
}
// LOGGING
public void Log(string message)
{
Log(null, 0, message);
}
public void Log(object obj, int lineNumber, string message)
{
if (obj is Type)
{
Console.WriteLine("{0}: {1}", ((Type)obj).FullName, message);
}
else if (obj != null)
{
Console.WriteLine("{0}: {1}", obj.GetType().FullName, message);
}
else
{
Console.WriteLine("{0}", message);
}
}
public bool Stopping { get; private set; } = false;
protected virtual void OnStopping(System.ComponentModel.CancelEventArgs e)
{
}
protected virtual void OnStopped(EventArgs e)
{
}
public event System.ComponentModel.CancelEventHandler BeforeShutdown;
protected virtual void OnBeforeShutdown(System.ComponentModel.CancelEventArgs e)
{
BeforeShutdown?.Invoke(this, e);
}
public event EventHandler Shutdown;
private void OnShutdown(EventArgs e)
{
Shutdown?.Invoke(this, e);
}
protected virtual void StopInternal(int exitCode)
{
}
public void Stop(int exitCode = 0)
{
if (Stopping)
return;
Stopping = true;
System.ComponentModel.CancelEventArgs ce = new System.ComponentModel.CancelEventArgs();
OnStopping(ce);
if (ce.Cancel)
return;
ce = new System.ComponentModel.CancelEventArgs();
OnBeforeShutdown(ce);
if (ce.Cancel)
{
return;
}
StopInternal(exitCode);
OnShutdown(EventArgs.Empty);
OnStopped(EventArgs.Empty);
Stopping = false;
}
}
}

104
MBS.Framework/Command.cs Normal file
View File

@ -0,0 +1,104 @@
using System;
namespace MBS.Framework
{
public class Command
{
public class CommandCollection
: System.Collections.ObjectModel.Collection<Command>
{
public Command this[string ID]
{
get
{
foreach (Command command in this)
{
if (command.ID == ID) return command;
}
return null;
}
}
}
public Command()
{
}
public Command(string id, string title, CommandItem[] items = null)
{
ID = id;
Title = title;
if (items != null)
{
for (int i = 0; i < items.Length; i++)
{
Items.Add(items[i]);
}
}
}
/// <summary>
/// Determines whether this command displays as checked.
/// </summary>
public bool Checked { get; set; } = false;
/// <summary>
/// The ID of the command, used to reference it in <see cref="CommandReferenceCommandItem"/>.
/// </summary>
public string ID { get; set; } = String.Empty;
/// <summary>
/// The title of the command (including mnemonic prefix, if applicable).
/// </summary>
public string Title { get; set; } = String.Empty;
private string mvarDefaultCommandID = String.Empty;
public string DefaultCommandID { get { return mvarDefaultCommandID; } set { mvarDefaultCommandID = value; } }
/// <summary>
/// A <see cref="StockType"/> that represents a predefined, platform-themed command.
/// </summary>
public StockType StockType { get; set; } = StockType.None;
private string mvarImageFileName = String.Empty;
/// <summary>
/// The file name of the image to be displayed on the command.
/// </summary>
public string ImageFileName { get { return mvarImageFileName; } set { mvarImageFileName = value; } }
/// <summary>
/// The child <see cref="CommandItem"/>s that are contained within this <see cref="Command"/>.
/// </summary>
public CommandItem.CommandItemCollection Items { get; } = new CommandItem.CommandItemCollection();
/// <summary>
/// The event that is fired when the command is executed.
/// </summary>
public event EventHandler Executed;
/// <summary>
/// Determines whether this <see cref="Command" /> is enabled in all <see cref="CommandBar" />s and <see cref="MenuBar" />s
/// that reference it.
/// </summary>
/// <value><c>true</c> if visible; otherwise, <c>false</c>.</value>
public bool Enabled { get; set; } = true;
/// <summary>
/// Determines whether this <see cref="Command" /> is visible in all <see cref="CommandBar" />s and <see cref="MenuBar" />s
/// that reference it.
/// </summary>
/// <value><c>true</c> if visible; otherwise, <c>false</c>.</value>
public bool Visible { get; set; }
/// <summary>
/// Executes this <see cref="Command"/>.
/// </summary>
public void Execute()
{
if (Executed != null) Executed(this, EventArgs.Empty);
}
public override string ToString()
{
return String.Format("{0} [{1}]", ID, Title);
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
namespace MBS.Framework
{
public class CommandEventArgs : EventArgs
{
public Command Command { get; private set; }
private Dictionary<string, object> _NamedParameters = new Dictionary<string, object>();
public T GetNamedParameter<T>(string key, T defaultValue = default(T))
{
if (_NamedParameters.ContainsKey(key))
return (T)_NamedParameters[key];
return defaultValue;
}
public object GetNamedParameter(string key, object defaultValue = null)
{
if (_NamedParameters.ContainsKey(key))
return _NamedParameters[key];
return defaultValue;
}
public CommandEventArgs(Command command, KeyValuePair<string, object>[] namedParameters = null)
{
Command = command;
if (namedParameters != null)
{
for (int i = 0; i < namedParameters.Length; i++)
{
_NamedParameters[namedParameters[i].Key] = namedParameters[i].Value;
}
}
}
}
public delegate void CommandEventHandler(object sender, CommandEventArgs e);
}

View File

@ -0,0 +1,55 @@
using System;
namespace MBS.Framework
{
public abstract class CommandItem
{
public string InsertAfterID { get; set; } = null;
public string InsertBeforeID { get; set; } = null;
public class CommandItemCollection
: System.Collections.ObjectModel.Collection<CommandItem>
{
public int IndexOf(string value)
{
for (int i = 0; i < Count; i++)
{
if (this[i] is CommandReferenceCommandItem)
{
if ((this[i] as CommandReferenceCommandItem).CommandID.Equals(value))
return i;
}
}
return -1;
}
}
}
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 CommandPlaceholderCommandItem : CommandItem
{
private string mvarPlaceholderID = String.Empty;
public string PlaceholderID { get { return mvarPlaceholderID; } set { mvarPlaceholderID = value; } }
public CommandPlaceholderCommandItem(string placeholderID)
{
mvarPlaceholderID = placeholderID;
}
}
public class SeparatorCommandItem : CommandItem
{
}
public class GroupCommandItem : CommandItem
{
public CommandItemCollection Items { get; } = new CommandItemCollection();
}
}

View File

@ -0,0 +1,50 @@
//
// CommandLine.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace MBS.Framework
{
public abstract class CommandLine
{
/// <summary>
/// Gets the original <see cref="String" /> array of arguments.
/// </summary>
/// <value>The arguments.</value>
public string[] Arguments { get; private set; }
/// <summary>
/// Gets the list of file names passed on the command line.
/// </summary>
/// <value>The file names.</value>
public List<string> FileNames { get; } = new List<string>();
public CommandLineOption.CommandLineOptionCollection Options { get; } = new CommandLineOption.CommandLineOptionCollection();
protected CommandLine()
{
}
protected internal CommandLine(string[] arguments)
{
this.Arguments = arguments;
}
}
}

View File

@ -0,0 +1,129 @@
//
// CommandLineOption.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace MBS.Framework
{
public class CommandLineOption
{
public class CommandLineOptionCollection
: System.Collections.ObjectModel.Collection<CommandLineOption>
{
private Dictionary<char, CommandLineOption> _byAbbreviation = new Dictionary<char, CommandLineOption>();
private Dictionary<string, CommandLineOption> _byName = new Dictionary<string, CommandLineOption>();
public bool Contains(char abbreviation)
{
return _byAbbreviation.ContainsKey(abbreviation);
}
public bool Contains(string name)
{
return _byName.ContainsKey(name);
}
public CommandLineOption this[char abbreviation]
{
get
{
if (_byAbbreviation.ContainsKey(abbreviation))
return _byAbbreviation[abbreviation];
return null;
}
}
public CommandLineOption this[string name]
{
get
{
if (_byName.ContainsKey(name))
return _byName[name];
return null;
}
}
protected override void ClearItems()
{
base.ClearItems();
_byName.Clear();
_byAbbreviation.Clear();
}
protected override void InsertItem(int index, CommandLineOption item)
{
base.InsertItem(index, item);
if (item.Name != null)
_byName[item.Name] = item;
if (item.Abbreviation != '\0')
_byAbbreviation[item.Abbreviation] = item;
}
public CommandLineOption Add(string name, char abbreviation = '\0', object defaultValue = null, CommandLineOptionValueType type = CommandLineOptionValueType.None, string description = null)
{
CommandLineOption option = new CommandLineOption();
option.Name = name;
option.Abbreviation = abbreviation;
option.DefaultValue = defaultValue;
option.Type = type;
option.Description = description;
Add(option);
return option;
}
protected override void RemoveItem(int index)
{
_byName.Remove(this[index].Name);
_byAbbreviation.Remove(this[index].Abbreviation);
base.RemoveItem(index);
}
public T GetValueOrDefault<T>(string name, T defaultValue = default(T))
{
if (_byName.ContainsKey(name))
{
return (T) _byName[name].Value;
}
return defaultValue;
}
}
public string Name { get; set; } = null;
public char Abbreviation { get; set; } = '\0';
public object DefaultValue { get; set; } = null;
/// <summary>
/// The description displayed in the help text.
/// </summary>
/// <value>The description.</value>
public string Description { get; set; } = null;
public object Value { get; set; } = null;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="T:MBS.Framework.UserInterface.CommandLineOption"/> expects a value to be passed in after this option.
/// </summary>
/// <value><c>true</c> if a value is expected to be passed in after this option; otherwise, <c>false</c>.</value>
public CommandLineOptionValueType Type { get; set; } = CommandLineOptionValueType.None;
}
}

View File

@ -0,0 +1,30 @@
//
// CommandLineOptionValueType.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace MBS.Framework
{
public enum CommandLineOptionValueType
{
None = 0,
Single = 1,
Multiple = 2
}
}

95
MBS.Framework/Context.cs Normal file
View File

@ -0,0 +1,95 @@
//
// Context.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace MBS.Framework
{
public class Context
{
public class ContextCollection
: System.Collections.ObjectModel.Collection<Context>
{
protected override void ClearItems()
{
for (int i = 0; i < this.Count; i++)
{
Application.Instance.RemoveContext(this[i]);
}
base.ClearItems();
}
protected override void InsertItem(int index, Context item)
{
base.InsertItem(index, item);
Application.Instance.AddContext(item);
}
protected override void RemoveItem(int index)
{
Application.Instance.RemoveContext(this[index]);
base.RemoveItem(index);
}
}
public Guid ID { get; private set; } = Guid.Empty;
public string Name { get; private set; } = String.Empty;
// public MenuBar MenuBar { get; } = new MenuBar();
public Command.CommandCollection Commands { get; } = new Command.CommandCollection();
public Context(Guid id, string name)
{
ID = id;
Name = name;
}
public override string ToString()
{
return String.Format("{0} {1}", Name, ID);
}
private Dictionary<string, List<EventHandler>> _CommandEventHandlers = new Dictionary<string, List<EventHandler>>();
public bool AttachCommandEventHandler(string commandID, EventHandler handler)
{
// handle command event handlers attached without a Command instance
if (!_CommandEventHandlers.ContainsKey(commandID))
{
_CommandEventHandlers.Add(commandID, new List<EventHandler>());
}
if (!_CommandEventHandlers[commandID].Contains(handler))
{
_CommandEventHandlers[commandID].Add(handler);
return true;
}
return false;
}
public bool ExecuteCommand(string commandID, KeyValuePair<string, object>[] namedParameters = null)
{
if (_CommandEventHandlers.ContainsKey(commandID))
{
for (int i = 0; i < _CommandEventHandlers[commandID].Count; i++)
{
_CommandEventHandlers[commandID][i](this, new CommandEventArgs(Commands[commandID], namedParameters));
}
}
return false;
}
}
}

View File

@ -0,0 +1,33 @@
//
// ContextChangedEvent.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace MBS.Framework
{
public class ContextChangedEventArgs
{
public Context Context { get; private set; } = null;
public ContextChangedEventArgs(Context ctx)
{
Context = ctx;
}
}
public delegate void ContextChangedEventHandler(object sender, ContextChangedEventArgs e);
}

View File

@ -0,0 +1,27 @@
//
// DefaultCommandLine.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace MBS.Framework
{
public class DefaultCommandLine : CommandLine
{
}
}

View File

@ -11,7 +11,6 @@
<SchemaVersion>2.0</SchemaVersion>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\..\Production.snk</AssemblyOriginatorKeyFile>
<ReleaseVersion>4.0.2019.12</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -76,6 +75,17 @@
<Compile Include="NumericStringSplitter.cs" />
<Compile Include="Plugin.cs" />
<Compile Include="Feature.cs" />
<Compile Include="Application.cs" />
<Compile Include="CommandLine.cs" />
<Compile Include="CommandLineOption.cs" />
<Compile Include="CommandLineOptionValueType.cs" />
<Compile Include="DefaultCommandLine.cs" />
<Compile Include="Context.cs" />
<Compile Include="Command.cs" />
<Compile Include="CommandEvent.cs" />
<Compile Include="CommandItem.cs" />
<Compile Include="StockType.cs" />
<Compile Include="ContextChangedEvent.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Logic\" />

122
MBS.Framework/StockType.cs Normal file
View File

@ -0,0 +1,122 @@
using System;
namespace MBS.Framework
{
public enum StockType
{
None,
About,
Add,
Apply,
// these four do not have gtk-stock equivalents
ArrowDown,
ArrowLeft,
ArrowRight,
ArrowUp,
Bold,
Cancel,
CapsLockWarning, // not for buttons
CDROM,
Clear,
Close,
ColorPicker, // not for buttons
Connect,
Convert,
Copy,
Cut,
Delete,
DialogAuthentication, // not for buttons
DialogInfo,
DialogWarning,
DialogError,
DialogQuestion,
Directory, // not for buttons
Discard,
Disconnect,
DragAndDrop, // not for buttons
DragAndDropMultiple, // not for buttons
Edit,
Execute,
File,
Find,
FindAndReplace,
Floppy,
Fullscreen,
GotoBottom,
GotoFirst,
GotoLast,
GotoTop,
GoBack,
GoDown,
GoForward,
GoUp,
HardDisk,
Help,
Home,
Index,
Indent,
Info,
Italic,
JumpTo,
JustifyCenter,
JustifyFill,
JustifyLeft,
JustifyRight,
LeaveFullscreen,
MissingImage, // not for buttons
MediaForward,
MediaNext,
MediaPause,
MediaPlay,
MediaPrevious,
MediaRecord,
MediaRewind,
MediaStop,
Network,
New,
No,
OK,
Open,
OrientationPortrait,
OrientationLandscape,
OrientationReverseLandscape,
OrientationReversePortrait,
PageSetup,
Paste,
Preferences,
Print,
PrintError, // not for buttons
PrintPaused, // not for buttons
PrintPreview,
PrintReport, // not for buttons
PrintWarning, // not for buttons
Properties,
Quit,
Redo,
Refresh,
Remove,
RevertToSaved,
Save,
SaveAs,
SelectAll,
SelectColor,
SelectFont,
SortAscending,
SortDescending,
SpellCheck,
Stop,
Strikethrough,
Undelete,
Underline,
Undo,
Unindent,
Yes,
Zoom100,
ZoomFit,
ZoomIn,
ZoomOut
}
}