DAY 1: The core

This commit is contained in:
Alkaline Thunder 2018-12-29 01:36:35 -05:00
parent 301bdc77d2
commit 211fbac215
20 changed files with 2339 additions and 30 deletions

View file

@ -33,13 +33,23 @@
this.CurrentTime = new System.Windows.Forms.Label();
this.UpdateTimer = new System.Windows.Forms.Timer(this.components);
this.Workspace = new System.Windows.Forms.Panel();
this.AppLauncherStrip = new System.Windows.Forms.MenuStrip();
this.AppLauncherMenu = new System.Windows.Forms.ToolStripMenuItem();
this.PanelButtonList = new System.Windows.Forms.FlowLayoutPanel();
this.TimePanel = new System.Windows.Forms.Panel();
this.AppLauncherHolder = new System.Windows.Forms.Panel();
this.DesktopPanel.SuspendLayout();
this.AppLauncherStrip.SuspendLayout();
this.TimePanel.SuspendLayout();
this.AppLauncherHolder.SuspendLayout();
this.SuspendLayout();
//
// DesktopPanel
//
this.DesktopPanel.BackColor = System.Drawing.Color.Gray;
this.DesktopPanel.Controls.Add(this.CurrentTime);
this.DesktopPanel.Controls.Add(this.PanelButtonList);
this.DesktopPanel.Controls.Add(this.AppLauncherHolder);
this.DesktopPanel.Controls.Add(this.TimePanel);
this.DesktopPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.DesktopPanel.ForeColor = System.Drawing.Color.Black;
this.DesktopPanel.Location = new System.Drawing.Point(0, 0);
@ -49,10 +59,9 @@
//
// CurrentTime
//
this.CurrentTime.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.CurrentTime.AutoSize = true;
this.CurrentTime.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Bold);
this.CurrentTime.Location = new System.Drawing.Point(698, 4);
this.CurrentTime.Location = new System.Drawing.Point(0, 3);
this.CurrentTime.Name = "CurrentTime";
this.CurrentTime.Size = new System.Drawing.Size(101, 18);
this.CurrentTime.TabIndex = 0;
@ -61,7 +70,7 @@
// UpdateTimer
//
this.UpdateTimer.Enabled = true;
this.UpdateTimer.Interval = 50;
this.UpdateTimer.Interval = 10;
this.UpdateTimer.Tick += new System.EventHandler(this.UpdateTimer_Tick);
//
// Workspace
@ -73,6 +82,55 @@
this.Workspace.Size = new System.Drawing.Size(800, 426);
this.Workspace.TabIndex = 1;
//
// AppLauncherStrip
//
this.AppLauncherStrip.GripMargin = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.AppLauncherStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.AppLauncherMenu});
this.AppLauncherStrip.Location = new System.Drawing.Point(0, 0);
this.AppLauncherStrip.Name = "AppLauncherStrip";
this.AppLauncherStrip.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.AppLauncherStrip.Size = new System.Drawing.Size(88, 24);
this.AppLauncherStrip.TabIndex = 1;
this.AppLauncherStrip.Text = "menuStrip1";
//
// AppLauncherMenu
//
this.AppLauncherMenu.AutoSize = false;
this.AppLauncherMenu.Name = "AppLauncherMenu";
this.AppLauncherMenu.Padding = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.AppLauncherMenu.Size = new System.Drawing.Size(77, 24);
this.AppLauncherMenu.Text = "Applications";
//
// PanelButtonList
//
this.PanelButtonList.Dock = System.Windows.Forms.DockStyle.Fill;
this.PanelButtonList.Location = new System.Drawing.Point(88, 0);
this.PanelButtonList.Margin = new System.Windows.Forms.Padding(0);
this.PanelButtonList.Name = "PanelButtonList";
this.PanelButtonList.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
this.PanelButtonList.Size = new System.Drawing.Size(605, 24);
this.PanelButtonList.TabIndex = 2;
//
// TimePanel
//
this.TimePanel.Controls.Add(this.CurrentTime);
this.TimePanel.Dock = System.Windows.Forms.DockStyle.Right;
this.TimePanel.Location = new System.Drawing.Point(693, 0);
this.TimePanel.Name = "TimePanel";
this.TimePanel.Size = new System.Drawing.Size(107, 24);
this.TimePanel.TabIndex = 3;
//
// AppLauncherHolder
//
this.AppLauncherHolder.BackColor = System.Drawing.Color.Gray;
this.AppLauncherHolder.Controls.Add(this.AppLauncherStrip);
this.AppLauncherHolder.Dock = System.Windows.Forms.DockStyle.Left;
this.AppLauncherHolder.Location = new System.Drawing.Point(0, 0);
this.AppLauncherHolder.Name = "AppLauncherHolder";
this.AppLauncherHolder.Size = new System.Drawing.Size(88, 24);
this.AppLauncherHolder.TabIndex = 0;
//
// Desktop
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -83,13 +141,20 @@
this.Controls.Add(this.DesktopPanel);
this.ForeColor = System.Drawing.Color.White;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MainMenuStrip = this.AppLauncherStrip;
this.Name = "Desktop";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.TransparencyKey = System.Drawing.Color.FromArgb(((int)(((byte)(1)))), ((int)(((byte)(0)))), ((int)(((byte)(1)))));
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Desktop_KeyDown);
this.DesktopPanel.ResumeLayout(false);
this.DesktopPanel.PerformLayout();
this.AppLauncherStrip.ResumeLayout(false);
this.AppLauncherStrip.PerformLayout();
this.TimePanel.ResumeLayout(false);
this.TimePanel.PerformLayout();
this.AppLauncherHolder.ResumeLayout(false);
this.AppLauncherHolder.PerformLayout();
this.ResumeLayout(false);
}
@ -100,6 +165,11 @@
private System.Windows.Forms.Label CurrentTime;
private System.Windows.Forms.Timer UpdateTimer;
private System.Windows.Forms.Panel Workspace;
private System.Windows.Forms.MenuStrip AppLauncherStrip;
private System.Windows.Forms.ToolStripMenuItem AppLauncherMenu;
private System.Windows.Forms.FlowLayoutPanel PanelButtonList;
private System.Windows.Forms.Panel TimePanel;
private System.Windows.Forms.Panel AppLauncherHolder;
}
}

View file

@ -6,6 +6,7 @@ using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ShiftOS.Windowing;
using System.Windows.Forms;
namespace ShiftOS
@ -13,11 +14,40 @@ namespace ShiftOS
public partial class Desktop : Form
{
private SystemContext CurrentSystem = null;
private bool _inUnity = false;
private int _lastWorkspaceChildCount = -1;
public SystemContext GetCurrentSystem()
{
return CurrentSystem;
}
public Desktop(SystemContext InSystem)
{
this.CurrentSystem = InSystem;
this.DoubleBuffered = true;
InitializeComponent();
ResetAppLauncher();
}
private void ResetPanelButtons()
{
// Clear the panel button list.
this.PanelButtonList.Controls.Clear();
// Go through every control in the workspace.
foreach(Control ctrl in Workspace.Controls)
{
// Check if it's a Window.
if(ctrl is Window)
{
// Create a panel button for the window.
var panelButton = new PanelButton(this, ctrl as Window);
// Add it to our UI.
this.PanelButtonList.Controls.Add(panelButton);
}
}
}
private void UpdateTimer_Tick(object sender, EventArgs e)
@ -25,25 +55,243 @@ namespace ShiftOS
// Update current time of day.
this.CurrentTime.Text = CurrentSystem.GetTimeOfDay();
// We get our background colors from the skin.
this.BackColor = this.CurrentSystem.GetSkinContext().GetSkinData().DesktopBackgroundColor;
this.DesktopPanel.BackColor = this.CurrentSystem.GetSkinContext().GetSkinData().DesktopPanelBackgroundColor;
// Grab the skin context.
var skin = this.CurrentSystem.GetSkinContext();
// Desktop panel must get its height from the skin.
this.DesktopPanel.Height = this.CurrentSystem.GetSkinContext().GetSkinData().DesktopPanelHeight;
// Set up the panel clock's position.
this.CurrentTime.Top = this.CurrentSystem.GetSkinContext().GetSkinData().PanelClockFromTop;
this.CurrentTime.Left = (DesktopPanel.Width - CurrentTime.Width) - this.CurrentSystem.GetSkinContext().GetSkinData().PanelClockFromSide;
// Determine the desktop panel dock
if(this.CurrentSystem.GetSkinContext().GetSkinData().IsDesktopPanelAtTop)
// If we're in unity mode...
if(_inUnity)
{
this.DesktopPanel.Dock = DockStyle.Top;
// then we become transparent.
this.BackgroundImage = null;
this.BackColor = this.TransparencyKey;
}
else
{
this.DesktopPanel.Dock = DockStyle.Bottom;
// Otherwise, we get a wallpaper.
if(skin.HasImage("desktopbackground"))
{
this.BackgroundImage = skin.GetImage("desktopbackground");
this.BackgroundImageLayout = skin.GetSkinData().desktopbackgroundlayout;
}
else
{
this.BackgroundImage = null;
this.BackColor = skin.GetSkinData().desktopbackgroundcolour;
}
}
// Do we have the desktop panel?
if(CurrentSystem.HasShiftoriumUpgrade("desktoppanel"))
{
// Set the desktop panel background
if(skin.HasImage("desktoppanel"))
{
DesktopPanel.BackgroundImage = skin.GetImage("desktoppanel");
DesktopPanel.BackgroundImageLayout = skin.GetSkinData().desktoppanellayout;
DesktopPanel.BackColor = Color.Transparent;
}
else
{
DesktopPanel.BackgroundImage = null;
DesktopPanel.BackColor = skin.GetSkinData().desktoppanelcolour;
}
// Set the height of the desktop panel.
DesktopPanel.Height = skin.GetSkinData().desktoppanelheight;
// Position the desktop panel.
if(skin.GetSkinData().desktoppanelposition == "Top")
{
DesktopPanel.Dock = DockStyle.Top;
}
else
{
DesktopPanel.Dock = DockStyle.Bottom;
}
// Show it.
DesktopPanel.Show();
}
else
{
// Hide it.
DesktopPanel.Hide();
}
// Do we have the panel clock?
if(CurrentSystem.HasShiftoriumUpgrade("desktoppanelclock"))
{
CurrentTime.ForeColor = skin.GetSkinData().clocktextcolour;
if(skin.HasImage("panelclock"))
{
TimePanel.BackColor = Color.Transparent;
TimePanel.BackgroundImage = skin.GetImage("panelclock");
TimePanel.BackgroundImageLayout = skin.GetSkinData().panelclocklayout;
}
else
{
TimePanel.BackColor = skin.GetSkinData().clockbackgroundcolor;
TimePanel.BackgroundImage = null;
}
if(CurrentTime.Font.Name != skin.GetSkinData().panelclocktextfont || CurrentTime.Font.Size != skin.GetSkinData().panelclocktextsize || CurrentTime.Font.Style != skin.GetSkinData().panelclocktextstyle)
{
CurrentTime.Font = new Font(skin.GetSkinData().panelclocktextfont, skin.GetSkinData().panelclocktextsize, skin.GetSkinData().panelclocktextstyle);
}
TimePanel.Width = CurrentTime.Width + 3;
CurrentTime.Left = 0;
CurrentTime.Top = skin.GetSkinData().panelclocktexttop;
TimePanel.Show();
}
else
{
TimePanel.Hide();
}
// Set up the panel buttons.
if(CurrentSystem.HasShiftoriumUpgrade("panelbuttons"))
{
PanelButtonList.Padding = new Padding(skin.GetSkinData().panelbuttoninitialgap, 0, 0, 0);
PanelButtonList.Show();
}
else
{
PanelButtonList.Hide();
}
// Do we have an app launcher?
if (CurrentSystem.HasShiftoriumUpgrade("applaunchermenu"))
{
// Set up the font.
string appFontName = skin.GetSkinData().applicationbuttontextfont;
int appFontSize = skin.GetSkinData().applicationbuttontextsize;
FontStyle appFontStyle = skin.GetSkinData().applicationbuttontextstyle;
if (AppLauncherMenu.Font.Name != appFontName || AppLauncherMenu.Font.Size != appFontSize || AppLauncherMenu.Font.Style != appFontStyle)
{
AppLauncherMenu.Font = new Font(appFontName, appFontSize, appFontStyle);
}
string appItemFontName = skin.GetSkinData().launcheritemfont;
int appItemFontSize = skin.GetSkinData().launcheritemsize;
FontStyle appItemFontStyle = skin.GetSkinData().launcheritemstyle;
foreach(var child in AppLauncherMenu.DropDownItems)
{
if(child is ToolStripMenuItem)
{
ToolStripMenuItem menuItem = child as ToolStripMenuItem;
if(menuItem.Font.Name != appItemFontName || menuItem.Font.Size != appItemFontSize || menuItem.Font.Style != appItemFontStyle)
{
menuItem.Font = new Font(appItemFontName, appItemFontSize, appItemFontStyle);
}
}
}
if (skin.HasImage("applauncher"))
{
AppLauncherMenu.Text = "";
AppLauncherMenu.BackColor = Color.Transparent;
AppLauncherMenu.BackgroundImage = skin.GetImage("applauncher");
AppLauncherMenu.BackgroundImageLayout = skin.GetSkinData().applauncherlayout;
}
else
{
AppLauncherMenu.BackColor = skin.GetSkinData().applauncherbackgroundcolour;
AppLauncherMenu.Text = skin.GetSkinData().applicationlaunchername;
AppLauncherMenu.BackgroundImage = null;
}
AppLauncherMenu.Height = skin.GetSkinData().applicationbuttonheight;
AppLauncherHolder.Width = skin.GetSkinData().applaunchermenuholderwidth;
AppLauncherMenu.Width = AppLauncherHolder.Width;
AppLauncherStrip.Width = AppLauncherHolder.Width;
AppLauncherStrip.Height = AppLauncherMenu.Height;
AppLauncherHolder.Show();
}
else
{
AppLauncherHolder.Hide();
}
// Has the amount of children (windows) in the workspace changed?
if(_lastWorkspaceChildCount != this.Workspace.Controls.Count)
{
// Update it.
_lastWorkspaceChildCount = this.Workspace.Controls.Count;
// Reset panel buttons.
this.ResetPanelButtons();
}
// Tells any open programs that we've updated.
this.CurrentSystem.UpdateDesktop();
}
public Panel GetWorkspace()
{
return this.Workspace;
}
public void ResetAppLauncher()
{
// Clear out the existing app launcher items, if any.
this.AppLauncherMenu.DropDownItems.Clear();
// Go through every installed program.
foreach(var program in this.CurrentSystem.GetInstalledPrograms())
{
// Get the friendly (UI) name
string friendlyName = this.CurrentSystem.GetProgramName(program);
// Create a new toolstripmenuitem that runs the program when clicked.
var item = new ToolStripMenuItem(friendlyName);
// Bind click event to open program.
item.Click += (o, a) =>
{
this.CurrentSystem.LaunchProgram(program);
};
// Add it to the app launcher.
AppLauncherMenu.DropDownItems.Add(item);
}
// TODO: Check if we actually have unity mode toggle and shutdown.
var separator = new ToolStripSeparator();
AppLauncherMenu.DropDownItems.Add(separator);
var unityToggle = new ToolStripMenuItem("Toggle Unity Mode");
var shutdown = new ToolStripMenuItem("Shut Down");
shutdown.Click += (o, a) =>
{
// Closing this window causes the system context to shut down.
this.Close();
};
unityToggle.Click += (o, a) =>
{
_inUnity = !_inUnity;
};
AppLauncherMenu.DropDownItems.Add(unityToggle);
AppLauncherMenu.DropDownItems.Add(shutdown);
}
private void Desktop_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.T && e.Control)
{
CurrentSystem.LaunchProgram("terminal");
}
}
}

View file

@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="AppLauncherStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>139, 17</value>
</metadata>
<metadata name="UpdateTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>

View file

@ -4,16 +4,20 @@ using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Reflection;
using System.Windows.Forms;
namespace ShiftOS
{
public class FilesystemContext
{
private string _workingDirectory;
public FilesystemContext()
{
_workingDirectory = Path.Combine(Environment.CurrentDirectory, "ShiftFS");
_workingDirectory = Path.Combine(Application.StartupPath, "ShiftFS");
Console.WriteLine(" --> Working directory: {0}", _workingDirectory);
// Create the directory if it does not exist.
if (!Directory.Exists(_workingDirectory))
@ -53,14 +57,21 @@ namespace ShiftOS
string OutPath = "";
foreach(var Part in PathParts)
{
OutPath = "/" + Part;
OutPath = "/" + Part + OutPath;
}
return OutPath;
}
private string MapToEnvironmentPath(string InPath)
{
return Path.Combine(_workingDirectory, ResolveToAbsolutePath(InPath).Replace("/", Path.DirectorySeparatorChar.ToString()));
string abs = ResolveToAbsolutePath(InPath);
while (abs.StartsWith("/"))
abs = abs.Remove(0, 1);
string mapped = Path.Combine(_workingDirectory, abs.Replace("/", Path.DirectorySeparatorChar.ToString()));
Console.WriteLine("Mapped {0} to {1}.", InPath, mapped);
return mapped;
}
public Stream Open(string InPath, FileMode InFileMode)
@ -108,10 +119,11 @@ namespace ShiftOS
public void WriteAllBytes(string InPath, byte[] InBytes)
{
using (var s = OpenWrite(InPath))
using (var s = this.Open(InPath, FileMode.OpenOrCreate))
{
s.SetLength(InBytes.Length);
s.Write(InBytes, 0, InBytes.Length);
s.Flush();
}
}
@ -127,7 +139,21 @@ namespace ShiftOS
public void CreateDirectory(string InPath)
{
if (DirectoryExists(InPath))
return;
Directory.CreateDirectory(MapToEnvironmentPath(InPath));
Console.WriteLine("Creating directory: {0}", InPath);
}
public bool DirectoryExists(string InPath)
{
return Directory.Exists(MapToEnvironmentPath(InPath));
}
public bool FileExists(string InPath)
{
return File.Exists(MapToEnvironmentPath(InPath));
}
public void MoveDirectory(string InPath, string OutPath)
@ -148,12 +174,30 @@ namespace ShiftOS
public void DeleteFile(string InPath)
{
File.Delete(MapToEnvironmentPath(InPath));
Console.Write("Deleting file {0}", InPath);
}
public void DeleteDirectory(string InPath, bool Recurse = false)
{
Directory.Delete(MapToEnvironmentPath(InPath), Recurse);
Console.WriteLine("Deleting directory {0} (recursive: {1})", InPath, Recurse);
}
public string[] GetFiles(string InPath)
{
var files = Directory.GetFiles(MapToEnvironmentPath(InPath));
var ret = new string[files.Length];
for (int i = 0; i < ret.Length; i++)
{
ret[i] = InPath + "/" + Path.GetFileName(files[i]);
}
return ret;
}
}
}

View file

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ShiftOS.Metadata
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class ProgramAttribute : Attribute
{
private string _exeName = "";
private string _friendlyName = "";
private string _description = "";
public ProgramAttribute(string InExecutableName, string InFriendlyName, string InDescription)
{
_exeName = InExecutableName;
_friendlyName = InFriendlyName;
_description = InDescription;
}
public string ExecutableName => _exeName;
public string FriendlyName => _friendlyName;
public string Description => _description;
}
}

79
ShiftOS/ShiftOS/PanelButton.Designer.cs generated Normal file
View file

@ -0,0 +1,79 @@
namespace ShiftOS
{
partial class PanelButton
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.IconBox = new System.Windows.Forms.PictureBox();
this.TitleText = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit();
this.SuspendLayout();
//
// IconBox
//
this.IconBox.BackColor = System.Drawing.Color.White;
this.IconBox.Location = new System.Drawing.Point(2, 2);
this.IconBox.Name = "IconBox";
this.IconBox.Size = new System.Drawing.Size(16, 16);
this.IconBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.IconBox.TabIndex = 0;
this.IconBox.TabStop = false;
//
// TitleText
//
this.TitleText.AutoSize = true;
this.TitleText.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold);
this.TitleText.Location = new System.Drawing.Point(24, 3);
this.TitleText.Name = "TitleText";
this.TitleText.Size = new System.Drawing.Size(89, 15);
this.TitleText.TabIndex = 1;
this.TitleText.Text = "Window Title";
//
// PanelButton
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.Controls.Add(this.TitleText);
this.Controls.Add(this.IconBox);
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F);
this.ForeColor = System.Drawing.Color.White;
this.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.Name = "PanelButton";
this.Size = new System.Drawing.Size(204, 20);
((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox IconBox;
private System.Windows.Forms.Label TitleText;
}
}

View file

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ShiftOS.Windowing;
using System.Windows.Forms;
namespace ShiftOS
{
public partial class PanelButton : UserControl
{
private Window _window = null;
private Desktop _desktop = null;
public PanelButton(Desktop InDesktop, Window InWindow)
{
InitializeComponent();
_desktop = InDesktop;
_window = InWindow;
_desktop.GetCurrentSystem().DesktopUpdated += OnDesktopUpdated;
}
private void OnDesktopUpdated(object sender, EventArgs e)
{
// Update our window data.
TitleText.Text = _window.WindowTitle;
IconBox.Image = _window.WindowIcon;
// Get the current skin.
var skin = _window.CurrentSystem.GetSkinContext();
// Set up our margin to take in account our skin's "panel button from top" and "panel button gap" values.
this.Margin = new Padding(0, skin.GetSkinData().panelbuttonfromtop, skin.GetSkinData().panelbuttongap, 0);
// Set the location of the panel button icon.
this.IconBox.Left = skin.GetSkinData().panelbuttoniconside;
this.IconBox.Top = skin.GetSkinData().panelbuttonicontop;
// Set the size of the icon.
this.IconBox.Width = this.IconBox.Height = skin.GetSkinData().panelbuttoniconsize; // Some spoopy C++ shit right there.
// Update our width and height.
this.Width = skin.GetSkinData().panelbuttonwidth;
this.Height = skin.GetSkinData().panelbuttonheight;
// Set our background color/image.
if (skin.HasImage("panelbutton"))
{
this.BackColor = Color.Transparent;
this.BackgroundImage = skin.GetImage("panelbutton");
this.BackgroundImageLayout = skin.GetSkinData().panelbuttonlayout;
}
else
{
this.BackColor = skin.GetSkinData().panelbuttoncolour;
this.BackgroundImage = null;
}
// Set the text color.
this.TitleText.ForeColor = skin.GetSkinData().panelbuttontextcolour;
// Set the text location.
this.TitleText.Left = skin.GetSkinData().panelbuttontextside;
this.TitleText.Top = skin.GetSkinData().panelbuttontexttop;
// Get the font values for panel button text.
string fontname = skin.GetSkinData().panelbuttontextfont;
int fontsize = skin.GetSkinData().panelbuttontextsize;
FontStyle fontstyle = skin.GetSkinData().panelbuttontextstyle;
// Do we need to update our font?
if(TitleText.Font.Name != fontname || TitleText.Font.Size != fontsize || this.TitleText.Font.Style != fontstyle)
{
// Update it.
TitleText.Font = new Font(fontname, fontsize, fontstyle);
}
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -0,0 +1,64 @@
namespace ShiftOS.Programs
{
partial class Terminal
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.TerminalControl = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// TerminalControl
//
this.TerminalControl.BackColor = System.Drawing.Color.Black;
this.TerminalControl.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.TerminalControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.TerminalControl.Font = new System.Drawing.Font("Lucida Console", 8.25F);
this.TerminalControl.ForeColor = System.Drawing.Color.White;
this.TerminalControl.Location = new System.Drawing.Point(2, 30);
this.TerminalControl.Name = "TerminalControl";
this.TerminalControl.Size = new System.Drawing.Size(597, 314);
this.TerminalControl.TabIndex = 5;
this.TerminalControl.Text = "";
this.TerminalControl.TextChanged += new System.EventHandler(this.TerminalControl_TextChanged);
//
// Terminal
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.TerminalControl);
this.Name = "Terminal";
this.WindowTitle = "Terminal";
this.Controls.SetChildIndex(this.TerminalControl, 0);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.RichTextBox TerminalControl;
}
}

View file

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ShiftOS.Windowing;
using ShiftOS.Metadata;
using System.Windows.Forms;
namespace ShiftOS.Programs
{
[Program("terminal", "Terminal", "Run commands in a bash-like shell.")]
public partial class Terminal : Window
{
public Terminal()
{
InitializeComponent();
}
private void TerminalControl_TextChanged(object sender, EventArgs e)
{
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -5,7 +5,7 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{18E84DF0-695C-4D78-BE74-0D2C203469A6}</ProjectGuid>
<OutputType>WinExe</OutputType>
<OutputType>Exe</OutputType>
<RootNamespace>ShiftOS</RootNamespace>
<AssemblyName>ShiftOS</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
@ -32,7 +32,13 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@ -53,14 +59,40 @@
<DependentUpon>Desktop.cs</DependentUpon>
</Compile>
<Compile Include="FilesystemContext.cs" />
<Compile Include="Metadata\ProgramAttribute.cs" />
<Compile Include="PanelButton.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="PanelButton.Designer.cs">
<DependentUpon>PanelButton.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Programs\Terminal.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Programs\Terminal.Designer.cs">
<DependentUpon>Terminal.cs</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Skin.cs" />
<Compile Include="SkinContext.cs" />
<Compile Include="SystemContext.cs" />
<Compile Include="ToolStripSkinRenderer.cs" />
<Compile Include="Windowing\Window.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Windowing\Window.Designer.cs">
<DependentUpon>Window.cs</DependentUpon>
</Compile>
<EmbeddedResource Include="Desktop.resx">
<DependentUpon>Desktop.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="PanelButton.resx">
<DependentUpon>PanelButton.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Programs\Terminal.resx">
<DependentUpon>Terminal.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@ -71,6 +103,10 @@
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<EmbeddedResource Include="Windowing\Window.resx">
<DependentUpon>Window.cs</DependentUpon>
</EmbeddedResource>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>

View file

@ -3,17 +3,119 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Threading.Tasks;
namespace ShiftOS
{
public class Skin
{
public int DesktopPanelHeight = 24;
public Color DesktopPanelBackgroundColor = Color.Gray;
public Color DesktopBackgroundColor = Color.Black;
public int PanelClockFromTop = 2;
public int PanelClockFromSide = 4;
public bool IsDesktopPanelAtTop = true;
// WINDOW SETTINGS/IMAGES
public ImageLayout titlebarlayout = ImageLayout.Stretch;
public ImageLayout borderleftlayout = ImageLayout.Stretch;
public ImageLayout borderrightlayout = ImageLayout.Stretch;
public ImageLayout borderbottomlayout = ImageLayout.Stretch;
public ImageLayout closebtnlayout = ImageLayout.Stretch;
public ImageLayout rollbtnlayout = ImageLayout.Stretch;
public ImageLayout minbtnlayout = ImageLayout.Stretch;
public ImageLayout rightcornerlayout = ImageLayout.Stretch;
public ImageLayout leftcornerlayout = ImageLayout.Stretch;
public ImageLayout bottomleftcornerlayout = ImageLayout.Stretch;
public ImageLayout bottomrightcornerlayout = ImageLayout.Stretch;
public Color bottomleftcornercolour = Color.Gray;
public Color bottomrightcornercolour = Color.Gray;
public bool enablebordercorners = false;
// settings
public Size closebtnsize = new Size(22, 22);
public Size rollbtnsize = new Size(22, 22);
public Size minbtnsize = new Size(22, 22);
public int titlebarheight = 30;
public int closebtnfromtop = 5;
public int closebtnfromside = 2;
public int rollbtnfromtop = 5;
public int rollbtnfromside = 26;
public int minbtnfromtop = 5;
public int minbtnfromside = 52;
public int borderwidth = 2;
public bool enablecorners = false;
public int titlebarcornerwidth = 5;
public int titleiconfromside = 4;
public int titleiconfromtop = 4;
// colours
public Color titlebarcolour = Color.Gray;
public Color borderleftcolour = Color.Gray;
public Color borderrightcolour = Color.Gray;
public Color borderbottomcolour = Color.Gray;
public Color closebtncolour = Color.Black;
public Color closebtnhovercolour = Color.Black;
public Color closebtnclickcolour = Color.Black;
public Color rollbtncolour = Color.Black;
public Color rollbtnhovercolour = Color.Black;
public Color rollbtnclickcolour = Color.Black;
public Color minbtncolour = Color.Black;
public Color minbtnhovercolour = Color.Black;
public Color minbtnclickcolour = Color.Black;
public Color rightcornercolour = Color.Gray;
public Color leftcornercolour = Color.Gray;
// Text
public string titletextfontfamily = "Microsoft Sans Serif";
public int titletextfontsize = 10;
public FontStyle titletextfontstyle = FontStyle.Bold;
public string titletextpos = "Left";
public int titletextfromtop = 3;
public int titletextfromside = 24;
public Color titletextcolour = Color.White;
// DESKTOP
public Color desktoppanelcolour = Color.Gray;
public Color desktopbackgroundcolour = Color.Black;
public int desktoppanelheight = 24;
public string desktoppanelposition = "Top";
public Color clocktextcolour = Color.Black;
public Color clockbackgroundcolor = Color.Gray;
public int panelclocktexttop = 3;
public int panelclocktextsize = 10;
public string panelclocktextfont = "Byington";
public FontStyle panelclocktextstyle = FontStyle.Bold;
public Color applauncherbuttoncolour = Color.Gray;
public Color applauncherbuttonclickedcolour = Color.Gray;
public Color applauncherbackgroundcolour = Color.Gray;
public Color applaunchermouseovercolour = Color.Gray;
public Color applicationsbuttontextcolour = Color.Black;
public int applicationbuttonheight = 24;
public int applicationbuttontextsize = 10;
public string applicationbuttontextfont = "Byington";
public FontStyle applicationbuttontextstyle = FontStyle.Bold;
public string applicationlaunchername = "Applications";
public string titletextposition = "Left";
public int applaunchermenuholderwidth = 100;
public int panelbuttonicontop = 3;
public int panelbuttoniconside = 4;
public int panelbuttoniconsize = 16;
public int panelbuttonheight = 20;
public int panelbuttonwidth = 185;
public Color panelbuttoncolour = Color.Black;
public Color panelbuttontextcolour = Color.White;
public int panelbuttontextsize = 10;
public string panelbuttontextfont = "Byington";
public FontStyle panelbuttontextstyle = FontStyle.Regular;
public int panelbuttontextside = 16;
public int panelbuttontexttop = 2;
public int panelbuttongap = 4;
public int panelbuttonfromtop = 2;
public int panelbuttoninitialgap = 8;
public int launcheritemsize = 10;
public string launcheritemfont = "Byington";
public FontStyle launcheritemstyle = FontStyle.Regular;
public Color launcheritemcolour = Color.Black;
// Images
public ImageLayout desktoppanellayout = ImageLayout.Stretch;
public ImageLayout desktopbackgroundlayout = ImageLayout.Stretch;
public ImageLayout panelclocklayout = ImageLayout.Stretch;
public ImageLayout applauncherlayout = ImageLayout.Stretch;
public ImageLayout panelbuttonlayout = ImageLayout.Stretch;
}
}

View file

@ -1,13 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
namespace ShiftOS
{
public class SkinContext
{
const string PHIL_SKIN_00X_FORMAT_HEADER = "ShiftOS skin data - Beware: Editing may result in skinning errors";
const int PHIL_OLD_IMAGE_COUNT = 50;
private Dictionary<string, Image> _skinimages = new Dictionary<string, Image>();
private Skin _skin = null;
public SkinContext()
@ -19,5 +27,528 @@ namespace ShiftOS
{
return _skin;
}
public void LoadFromDisk(SystemContext InSystemContext)
{
var fs = InSystemContext.GetFilesystem();
if(!fs.DirectoryExists("/Shiftum42/Skins/Loaded") || !fs.FileExists("/Shiftum42/Skins/Loaded/data.dat"))
{
fs.CreateDirectory("/Shiftum42/Skins/Loaded");
_skin = new Skin();
_skinimages = new Dictionary<string, Image>();
Console.WriteLine("No existing skin found. Writing default skin as Michael skin format...");
fs.WriteAllText("/Shiftum42/Skins/Loaded/data.dat", JsonConvert.SerializeObject(_skin));
}
else
{
_skinimages.Clear();
Console.WriteLine("Existing skin found.");
Console.WriteLine("Opening skin data...");
using (var stream = fs.OpenText("/Shiftum42/Skins/Loaded/data.dat"))
{
Console.WriteLine(" --> Determining skin format...");
// Michael format is JSON, Phil format is not. JSON must start with a "{".
if(stream.Peek() == '{')
{
Console.WriteLine(" --> Detected Michael-formatted skin.");
_skin = JsonConvert.DeserializeObject<Skin>(stream.ReadToEnd());
Console.WriteLine(" --> JSON skin data loaded.");
}
else
{
Console.WriteLine(" --> Detected Philip Skin.");
Console.WriteLine(" --> Ladies and gentlemen, fasten your seatbelts. This is gonna fucking suck.");
LoadPhilipSkin(fs, stream);
}
}
Console.WriteLine(" --> Done loading skin data file.");
if (_skinimages.Keys.Count == 0)
{
Console.WriteLine(" --> Loading images...");
foreach (var path in fs.GetFiles("/Shiftum42/Skins/Loaded"))
{
if (!path.EndsWith("data.dat"))
{
using (var stream = fs.OpenRead(path))
{
var image = Image.FromStream(stream);
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
Console.WriteLine(" --> Loaded: {0}", path);
Console.WriteLine(" --> Storing as: {0}", filenameWithoutExtension);
_skinimages.Add(filenameWithoutExtension, image);
}
}
}
}
}
}
private void LoadOldPhilipSkin(FilesystemContext fs, StreamReader stream)
{
_skin = new Skin();
// First line is the title bar color.
Console.WriteLine(" --> Read titlebar color");
_skin.titlebarcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
// Line 2 is window border color, no individual colors it seems.
Console.WriteLine(" --> Read window border color");
_skin.borderleftcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.borderrightcolour = _skin.borderleftcolour;
_skin.borderbottomcolour = _skin.borderleftcolour;
// Line 3 is the window border size.
Console.WriteLine(" --> Read border width");
_skin.borderwidth = Convert.ToInt32(stream.ReadLine());
// Line 4 is the title bar's height.
Console.WriteLine(" --> Read title height");
_skin.titlebarheight = Convert.ToInt32(stream.ReadLine());
// Next 5 lines are all the close button's data.
Console.WriteLine(" --> Read close button color");
_skin.closebtncolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read close button size");
int closeHeight = Convert.ToInt32(stream.ReadLine());
int closeWidth = Convert.ToInt32(stream.ReadLine());
_skin.closebtnsize = new Size(closeWidth, closeHeight);
Console.WriteLine(" --> Read close button position");
_skin.closebtnfromside = Convert.ToInt32(stream.ReadLine());
_skin.closebtnfromtop = Convert.ToInt32(stream.ReadLine());
// Next 3 lines are the title text color and position.
Console.WriteLine(" --> Read title text color");
_skin.titletextcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read absolute title text position");
_skin.titletextfromtop = Convert.ToInt32(stream.ReadLine());
_skin.titletextfromside = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read title text font");
// Next 3 lines are a font descriptor for the title text.
_skin.titletextfontsize = Convert.ToInt32(stream.ReadLine());
_skin.titletextfontfamily = stream.ReadLine();
_skin.titletextfontstyle = (FontStyle)Convert.ToInt32(stream.ReadLine());
PhilLoadDesktopPanelAndClock(stream);
PhilLoadAppLauncher(stream);
Console.WriteLine(" --> Read roll button color");
_skin.rollbtncolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read roll button size");
int rollHeight = Convert.ToInt32(stream.ReadLine());
int rollWidth = Convert.ToInt32(stream.ReadLine());
_skin.rollbtnsize = new Size(rollWidth, rollHeight);
Console.WriteLine(" --> Read roll button position");
_skin.rollbtnfromside = Convert.ToInt32(stream.ReadLine());
_skin.rollbtnfromtop = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read title icon position");
_skin.titleiconfromside = Convert.ToInt32(stream.ReadLine());
_skin.titleiconfromtop = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read enable window corners...");
_skin.enablecorners = bool.Parse(stream.ReadLine());
Console.WriteLine(" --> Read titlebar corner width...");
_skin.titlebarcornerwidth = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read titlebar corner colors");
_skin.rightcornercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.leftcornercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read app launcher menu holder width");
_skin.applaunchermenuholderwidth = Convert.ToInt32(stream.ReadLine());
/// WARNING: Trey, if you're looking at this, I know this code looks like burning canine defecation.
/// So is Phil's 0.0.7 skin format. All these properties aren't even in the format, they were just
/// patched in - i.e, you need to check if they're there. FUCK.
string line = stream.ReadLine();
if(!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read left border color");
_skin.borderleftcolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read right border color");
_skin.borderrightcolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read bottom border color");
_skin.borderbottomcolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read bottom left border color");
_skin.bottomleftcornercolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read bottom right border color");
_skin.bottomrightcornercolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button icon from top");
_skin.panelbuttonicontop = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button icon from side");
_skin.panelbuttoniconside = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button icon size");
_skin.panelbuttoniconsize = Convert.ToInt32(line);
}
// Skip the next line - duplicate of above
stream.ReadLine();
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button height");
_skin.panelbuttonheight = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button width");
_skin.panelbuttonwidth = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button color");
_skin.panelbuttoncolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button text color");
_skin.panelbuttontextcolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button text size");
_skin.panelbuttontextsize = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button text font");
_skin.panelbuttontextfont = line;
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button text style");
_skin.panelbuttontextstyle = (FontStyle)Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button text side");
_skin.panelbuttontextside = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button text top");
_skin.panelbuttontexttop = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button gap");
_skin.panelbuttongap = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button from top");
_skin.panelbuttonfromtop = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read panel button initial gap");
_skin.panelbuttoninitialgap = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read minimize button color");
_skin.minbtncolour = Color.FromArgb(Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read minimize size");
_skin.minbtnsize = new Size(Convert.ToInt32(stream.ReadLine()), Convert.ToInt32(line));
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read minimize button from side");
_skin.minbtnfromside = Convert.ToInt32(line);
}
line = stream.ReadLine();
if (!string.IsNullOrEmpty(line))
{
Console.WriteLine(" --> Read minimize button from top");
_skin.minbtnfromtop = Convert.ToInt32(line);
}
// BLANK AREA
//
// Presumably this area is for newer features that were implemented in 0.0.8,
// but never made it into this format because of the 0.0.8 format being implemented
// by William.
for(int i = 0; i < (100 - 73); i++)
{
stream.ReadLine();
}
// IMAGE LOADER.
//
// 0.0.7 skins store direct paths (in Windows) to image assets.
// In order for us to load them, we need to get their file names and map them to in-game paths.
// Why, oh why, did Phil do this...
Console.WriteLine(" --> Reading image file paths from 0.0.7 skin data...");
string[] ImageFileNames = new string[PHIL_OLD_IMAGE_COUNT];
for(int i = 0; i < ImageFileNames.Length; i++)
{
string path = stream.ReadLine();
ImageFileNames[i] = "/Shiftum42/Skins/Loaded/" + Path.GetFileName(path);
}
_skinimages.Add("closebtn", GetImage(fs, ImageFileNames[0]));
_skinimages.Add("titlebar", GetImage(fs, ImageFileNames[3]));
_skinimages.Add("desktopbackground", GetImage(fs, ImageFileNames[6]));
_skinimages.Add("rollbtn", GetImage(fs, ImageFileNames[9]));
_skinimages.Add("titlebarright", GetImage(fs, ImageFileNames[12]));
_skinimages.Add("titlebarleft", GetImage(fs, ImageFileNames[15]));
_skinimages.Add("desktoppanel", GetImage(fs, ImageFileNames[18]));
_skinimages.Add("panelclock", GetImage(fs, ImageFileNames[21]));
_skinimages.Add("applauncher", GetImage(fs, ImageFileNames[24]));
}
private Image GetImage(FilesystemContext fs, string path)
{
if (!fs.FileExists(path))
return null;
using (var stream = fs.OpenRead(path))
{
return Image.FromStream(stream);
}
}
private void PhilLoadDesktopPanelAndClock(StreamReader stream)
{
Console.WriteLine(" --> Read desktop panel color");
_skin.desktoppanelcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read desktop background color");
_skin.desktopbackgroundcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read desktop panel height");
_skin.desktoppanelheight = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read desktop panel position");
_skin.desktoppanelposition = stream.ReadLine();
Console.WriteLine(" --> Read panel clock text and background color");
_skin.clocktextcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.clockbackgroundcolor = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read desktop panel clock position");
_skin.panelclocktexttop = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read desktop panel clock font");
_skin.panelclocktextsize = Convert.ToInt32(stream.ReadLine());
_skin.panelclocktextfont = stream.ReadLine();
_skin.panelclocktextstyle = (FontStyle)Convert.ToInt32(stream.ReadLine());
}
private void LoadPhilipSkin(FilesystemContext fs, StreamReader stream)
{
// Skip the first line in the file for it is a header.
string head = stream.ReadLine();
if(head == PHIL_SKIN_00X_FORMAT_HEADER)
{
Console.WriteLine(" --> Detected 0.0.8 skin file.");
Console.WriteLine(" --> {0}", head);
}
else
{
Console.WriteLine(" --> Detected 0.0.7 skin file.");
stream.BaseStream.Position = 0;
stream.DiscardBufferedData();
LoadOldPhilipSkin(fs, stream);
return;
}
_skin = new Skin();
// First 6 lines are the title button sizes.
_skin.closebtnsize = new Size(Convert.ToInt32(stream.ReadLine()), Convert.ToInt32(stream.ReadLine()));
_skin.rollbtnsize = new Size(Convert.ToInt32(stream.ReadLine()), Convert.ToInt32(stream.ReadLine()));
_skin.minbtnsize = new Size(Convert.ToInt32(stream.ReadLine()), Convert.ToInt32(stream.ReadLine()));
// Line 7 is the title bar height.
_skin.titlebarheight = Convert.ToInt32(stream.ReadLine());
// Next 6 lines are the title button positions.
_skin.closebtnfromtop = Convert.ToInt32(stream.ReadLine());
_skin.closebtnfromside = Convert.ToInt32(stream.ReadLine());
_skin.rollbtnfromtop = Convert.ToInt32(stream.ReadLine());
_skin.rollbtnfromside = Convert.ToInt32(stream.ReadLine());
_skin.minbtnfromtop = Convert.ToInt32(stream.ReadLine());
_skin.minbtnfromside = Convert.ToInt32(stream.ReadLine());
// Line 14 is the uniform window border width, for skins that don't set individual border widths.
_skin.borderwidth = Convert.ToInt32(stream.ReadLine());
// Line 15 contains whether title corners are enabled.
_skin.enablecorners = bool.Parse(stream.ReadLine());
// Line 16 is the width of those corners.
_skin.titlebarcornerwidth = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read title icon position");
_skin.titleiconfromside = Convert.ToInt32(stream.ReadLine());
_skin.titleiconfromtop = Convert.ToInt32(stream.ReadLine());
// Next 4 lines are packed RGB values for the titlebar and window border colors.
_skin.titlebarcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.borderleftcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.borderrightcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.borderbottomcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
// Next 9 lines are packed RGB values for the background colors for each state of the three title buttons.
_skin.closebtncolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.closebtnhovercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.closebtnclickcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.rollbtncolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.rollbtnhovercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.rollbtnclickcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.minbtncolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.minbtnhovercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.minbtnclickcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
// Next 4 lines are packed RGB values for the window border corner colors.
_skin.rightcornercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.leftcornercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.bottomrightcornercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.bottomleftcornercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
// Next 3 lines are a font descriptor for the title text.
_skin.titletextfontfamily = stream.ReadLine();
_skin.titletextfontsize = Convert.ToInt32(stream.ReadLine());
_skin.titletextfontstyle = (FontStyle)Convert.ToInt32(stream.ReadLine());
// Line 38 is a string representing the title text position - centered or
// left. Why Phil decided a string is a good idea instead of a boolean, we may never know.
_skin.titletextpos = stream.ReadLine();
// And right after that - line 39 and 40 - is the position for the title text as a 2d point.
_skin.titletextfromtop = Convert.ToInt32(stream.ReadLine());
_skin.titletextfromside = Convert.ToInt32(stream.ReadLine());
// Line 41 is the title text color.
_skin.titletextcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
PhilLoadDesktopPanelAndClock(stream);
PhilLoadAppLauncher(stream);
}
private void PhilLoadAppLauncher(StreamReader stream)
{
Console.WriteLine(" --> Read app launcher button colors");
_skin.applauncherbuttoncolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
_skin.applauncherbuttonclickedcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read app launcher background color");
_skin.applauncherbackgroundcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read app launcher mouse over color");
_skin.applaunchermouseovercolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read app launcher text color");
_skin.applicationsbuttontextcolour = Color.FromArgb(Convert.ToInt32(stream.ReadLine()));
Console.WriteLine(" --> Read app launcher height");
_skin.applicationbuttonheight = Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read App Launcher Font");
_skin.applicationbuttontextsize = Convert.ToInt32(stream.ReadLine());
_skin.applicationbuttontextfont = stream.ReadLine();
_skin.applicationbuttontextstyle = (FontStyle)Convert.ToInt32(stream.ReadLine());
Console.WriteLine(" --> Read App Launcher Name");
_skin.applicationlaunchername = stream.ReadLine();
Console.WriteLine(" --> Read Title Text Position");
_skin.titletextpos = stream.ReadLine();
}
public bool HasImage(string ImageKey)
{
return _skinimages.ContainsKey(ImageKey) && (_skinimages[ImageKey] != null);
}
public Image GetImage(string ImageKey)
{
if(_skinimages.ContainsKey(ImageKey))
{
return _skinimages[ImageKey];
}
return null;
}
}
}

View file

@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ShiftOS.Metadata;
using ShiftOS.Windowing;
using System.Reflection;
using System.Threading.Tasks;
namespace ShiftOS
@ -14,16 +17,120 @@ namespace ShiftOS
private FilesystemContext _filesystem = null;
private int _codepoints = 0;
private Dictionary<string, Type> _programTypeMap = new Dictionary<string, Type>();
private List<ProgramAttribute> _programMetadata = new List<ProgramAttribute>();
public event EventHandler DesktopUpdated;
public bool HasShiftoriumUpgrade(string InUpgrade)
{
// TODO: Shiftorium.
return true;
}
public bool LaunchProgram(string InExecutableName)
{
// Does the program exist in our typemap?
if(!_programTypeMap.ContainsKey(InExecutableName))
{
// Program doesn't exist.
return false;
}
Type ProgramType = this._programTypeMap[InExecutableName];
// TODO: Check if the program is installed...
// Create the program window.
var window = (Window)Activator.CreateInstance(ProgramType, null);
// Log that we've launched the program
Console.WriteLine(" --> Opening {0}...", window.WindowTitle);
// Set the system context of the window.
window.SetSystemContext(this);
// Add the window to the desktop's workspace.
var work = _desktop.GetWorkspace();
work.Controls.Add(window);
// Center the window on the workspace.
window.Left = (work.Width - window.Width) / 2;
window.Top = (work.Height - window.Height) / 2;
// Ensure the window is visible.
window.Show();
// Program was successfully launched.
return true;
}
public IEnumerable<string> GetInstalledPrograms()
{
// TODO: Check if programs are installed/unlocked first.
foreach(var program in _programMetadata.OrderBy(x=>x.FriendlyName))
{
yield return program.ExecutableName;
}
}
public string GetProgramName(string InExecutableName)
{
// TODO: Check if the program is installed or unlocked.
return this._programMetadata.FirstOrDefault(x => x.ExecutableName == InExecutableName)?.FriendlyName;
}
private void LoadProgramData()
{
Console.WriteLine("Loading program metadata...");
foreach(var type in Assembly.GetExecutingAssembly().GetTypes())
{
if(type.BaseType == typeof(Window))
{
ProgramAttribute ProgramData = type.GetCustomAttributes(false).FirstOrDefault(x => x is ProgramAttribute) as ProgramAttribute;
if(ProgramData != null)
{
if(this._programTypeMap.ContainsKey(ProgramData.ExecutableName))
{
throw new InvalidOperationException("Duplicate programs found.");
}
Console.WriteLine(" --> Found {0} ({1}) in {2}.", ProgramData.ExecutableName, ProgramData.FriendlyName, type.FullName);
this._programMetadata.Add(ProgramData);
this._programTypeMap.Add(ProgramData.ExecutableName, type);
}
}
}
}
private void LoadCurrentSkin()
{
// TODO: Load it from a filesystem of some sort.
_skinContext = new SkinContext();
_skinContext.LoadFromDisk(this);
}
private void LoadFilesystem()
{
Console.WriteLine("Loading filesystem context...");
this._filesystem = new FilesystemContext();
_filesystem.CreateDirectory("/Home");
_filesystem.CreateDirectory("/Home/Desktop");
_filesystem.CreateDirectory("/Home/Documents");
_filesystem.CreateDirectory("/Home/Music");
_filesystem.CreateDirectory("/Home/Pictures");
_filesystem.CreateDirectory("/Home/Videos");
_filesystem.CreateDirectory("/Shiftum42");
_filesystem.CreateDirectory("/Shiftum42/Drivers");
_filesystem.CreateDirectory("/Shiftum42/Languages");
_filesystem.CreateDirectory("/Shiftum42/Skins");
_filesystem.CreateDirectory("/SoftwareData");
_filesystem.CreateDirectory("/SoftwareData/KnowledgeInput");
}
public void Dispose()
@ -31,6 +138,11 @@ namespace ShiftOS
_desktop = null;
}
public void UpdateDesktop()
{
DesktopUpdated?.Invoke(this, EventArgs.Empty);
}
public int GetCodepoints()
{
return this._codepoints;
@ -58,6 +170,12 @@ namespace ShiftOS
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ToolStripManager.Renderer = new ToolStripSkinRenderer(this);
// Load all programs in the game.
this.LoadProgramData();
// Load up the filesystem.
this.LoadFilesystem();
Console.WriteLine("Loading current skin...");

View file

@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Drawing;
namespace ShiftOS
{
public class ToolStripSkinRenderer : ToolStripProfessionalRenderer
{
private SystemContext CurrentSystem = null;
public ToolStripSkinRenderer(SystemContext InSystem) : base(new ToolStripSkinColorTable(InSystem))
{
CurrentSystem = InSystem;
}
}
public class ToolStripSkinColorTable : ProfessionalColorTable
{
private SystemContext CurrentSystem;
public ToolStripSkinColorTable(SystemContext InSystem)
{
CurrentSystem = InSystem;
}
public override Color ButtonSelectedHighlight => ButtonSelectedGradientMiddle;
public override Color ButtonSelectedHighlightBorder => ButtonSelectedBorder;
public override Color ButtonPressedHighlight => ButtonPressedGradientMiddle;
public override Color ButtonPressedHighlightBorder => ButtonPressedBorder;
public override Color ButtonCheckedHighlight => ButtonCheckedGradientMiddle;
public override Color ButtonCheckedHighlightBorder => ButtonCheckedHighlightBorder;
public override Color ButtonPressedBorder => Color.Gray;
public override Color ButtonSelectedBorder => Color.Gray;
public override Color ButtonCheckedGradientBegin => Color.Gray;
public override Color ButtonCheckedGradientMiddle => Color.Gray;
public override Color ButtonCheckedGradientEnd => Color.Gray;
public override Color ButtonSelectedGradientBegin => Color.Gray;
public override Color ButtonSelectedGradientMiddle => Color.Gray;
public override Color ButtonSelectedGradientEnd => Color.Gray;
public override Color ButtonPressedGradientBegin => Color.Gray;
public override Color ButtonPressedGradientMiddle => Color.Gray;
public override Color ButtonPressedGradientEnd => Color.Gray;
public override Color CheckBackground => Color.Gray;
public override Color CheckSelectedBackground => Color.Gray;
public override Color CheckPressedBackground => Color.Gray;
public override Color GripDark => Color.Gray;
public override Color GripLight => Color.White;
public override Color ImageMarginGradientBegin => CurrentSystem.GetSkinContext().GetSkinData().applauncherbackgroundcolour;
public override Color ImageMarginGradientMiddle => ImageMarginGradientBegin;
public override Color ImageMarginGradientEnd => ImageMarginGradientBegin;
public override Color ImageMarginRevealedGradientBegin => Color.Gray;
public override Color ImageMarginRevealedGradientMiddle => Color.Gray;
public override Color ImageMarginRevealedGradientEnd => Color.Gray;
public override Color MenuStripGradientBegin => (CurrentSystem.GetSkinContext().HasImage("applauncher") ? Color.Transparent : CurrentSystem.GetSkinContext().GetSkinData().applauncherbuttoncolour);
public override Color MenuStripGradientEnd => MenuStripGradientBegin;
public override Color MenuItemSelected => CurrentSystem.GetSkinContext().GetSkinData().applaunchermouseovercolour;
public override Color MenuItemBorder => (CurrentSystem.GetSkinContext().HasImage("applauncher") ? Color.Transparent : MenuItemSelected);
public override Color MenuBorder => (CurrentSystem.GetSkinContext().HasImage("applauncher") ? Color.Transparent : CurrentSystem.GetSkinContext().GetSkinData().applauncherbackgroundcolour);
public override Color MenuItemSelectedGradientBegin => MenuItemSelected;
public override Color MenuItemSelectedGradientEnd => MenuItemSelectedGradientBegin;
public override Color MenuItemPressedGradientBegin => (CurrentSystem.GetSkinContext().HasImage("applauncher") ? Color.Transparent : CurrentSystem.GetSkinContext().GetSkinData().applauncherbuttonclickedcolour);
public override Color MenuItemPressedGradientMiddle => MenuItemPressedGradientBegin;
public override Color MenuItemPressedGradientEnd => MenuItemPressedGradientBegin;
public override Color RaftingContainerGradientBegin => Color.FromName("ButtonFace");
public override Color RaftingContainerGradientEnd => RaftingContainerGradientEnd;
public override Color SeparatorDark => Color.Black;
public override Color SeparatorLight => SeparatorDark;
public override Color StatusStripGradientBegin => Color.Gray;
public override Color StatusStripGradientEnd => Color.Gray;
public override Color ToolStripBorder => Color.Gray;
public override Color ToolStripDropDownBackground => MenuStripGradientBegin;
public override Color ToolStripGradientBegin => Color.Gray;
public override Color ToolStripGradientMiddle => Color.Gray;
public override Color ToolStripGradientEnd => Color.Gray;
public override Color ToolStripContentPanelGradientBegin => Color.Gray;
public override Color ToolStripContentPanelGradientEnd => Color.Gray;
public override Color ToolStripPanelGradientBegin => Color.Gray;
public override Color ToolStripPanelGradientEnd => Color.Gray;
public override Color OverflowButtonGradientBegin => Color.Gray;
public override Color OverflowButtonGradientMiddle => Color.Gray;
public override Color OverflowButtonGradientEnd => Color.Gray;
}
}

View file

@ -0,0 +1,229 @@
namespace ShiftOS.Windowing
{
partial class Window
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.TitleBarHolder = new System.Windows.Forms.Panel();
this.TitleBarLeft = new System.Windows.Forms.Panel();
this.TitleBarRight = new System.Windows.Forms.Panel();
this.BottomBarHolder = new System.Windows.Forms.Panel();
this.BottomBar = new System.Windows.Forms.Panel();
this.BottomRight = new System.Windows.Forms.Panel();
this.BottomLeft = new System.Windows.Forms.Panel();
this.RightBar = new System.Windows.Forms.Panel();
this.LeftBar = new System.Windows.Forms.Panel();
this.CloseButton = new System.Windows.Forms.Panel();
this.RollButton = new System.Windows.Forms.Panel();
this.MinimizeButton = new System.Windows.Forms.Panel();
this.TitleText = new System.Windows.Forms.Label();
this.IconBox = new System.Windows.Forms.PictureBox();
this.TitleBarHolder.SuspendLayout();
this.BottomBarHolder.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit();
this.SuspendLayout();
//
// TitleBarHolder
//
this.TitleBarHolder.BackColor = System.Drawing.Color.Gray;
this.TitleBarHolder.Controls.Add(this.IconBox);
this.TitleBarHolder.Controls.Add(this.TitleText);
this.TitleBarHolder.Controls.Add(this.MinimizeButton);
this.TitleBarHolder.Controls.Add(this.RollButton);
this.TitleBarHolder.Controls.Add(this.CloseButton);
this.TitleBarHolder.Controls.Add(this.TitleBarRight);
this.TitleBarHolder.Controls.Add(this.TitleBarLeft);
this.TitleBarHolder.Dock = System.Windows.Forms.DockStyle.Top;
this.TitleBarHolder.Location = new System.Drawing.Point(0, 0);
this.TitleBarHolder.Name = "TitleBarHolder";
this.TitleBarHolder.Size = new System.Drawing.Size(601, 30);
this.TitleBarHolder.TabIndex = 0;
//
// TitleBarLeft
//
this.TitleBarLeft.BackColor = System.Drawing.Color.Gray;
this.TitleBarLeft.Dock = System.Windows.Forms.DockStyle.Left;
this.TitleBarLeft.Location = new System.Drawing.Point(0, 0);
this.TitleBarLeft.Name = "TitleBarLeft";
this.TitleBarLeft.Size = new System.Drawing.Size(2, 30);
this.TitleBarLeft.TabIndex = 1;
//
// TitleBarRight
//
this.TitleBarRight.BackColor = System.Drawing.Color.Gray;
this.TitleBarRight.Dock = System.Windows.Forms.DockStyle.Right;
this.TitleBarRight.Location = new System.Drawing.Point(599, 0);
this.TitleBarRight.Name = "TitleBarRight";
this.TitleBarRight.Size = new System.Drawing.Size(2, 30);
this.TitleBarRight.TabIndex = 2;
//
// BottomBarHolder
//
this.BottomBarHolder.BackColor = System.Drawing.Color.Transparent;
this.BottomBarHolder.Controls.Add(this.BottomBar);
this.BottomBarHolder.Controls.Add(this.BottomRight);
this.BottomBarHolder.Controls.Add(this.BottomLeft);
this.BottomBarHolder.Dock = System.Windows.Forms.DockStyle.Bottom;
this.BottomBarHolder.Location = new System.Drawing.Point(0, 344);
this.BottomBarHolder.Name = "BottomBarHolder";
this.BottomBarHolder.Size = new System.Drawing.Size(601, 2);
this.BottomBarHolder.TabIndex = 1;
//
// BottomBar
//
this.BottomBar.BackColor = System.Drawing.Color.Gray;
this.BottomBar.Dock = System.Windows.Forms.DockStyle.Fill;
this.BottomBar.ForeColor = System.Drawing.Color.White;
this.BottomBar.Location = new System.Drawing.Point(2, 0);
this.BottomBar.Name = "BottomBar";
this.BottomBar.Size = new System.Drawing.Size(597, 2);
this.BottomBar.TabIndex = 0;
//
// BottomRight
//
this.BottomRight.BackColor = System.Drawing.Color.Gray;
this.BottomRight.Dock = System.Windows.Forms.DockStyle.Right;
this.BottomRight.Location = new System.Drawing.Point(599, 0);
this.BottomRight.Name = "BottomRight";
this.BottomRight.Size = new System.Drawing.Size(2, 2);
this.BottomRight.TabIndex = 2;
//
// BottomLeft
//
this.BottomLeft.BackColor = System.Drawing.Color.Gray;
this.BottomLeft.Dock = System.Windows.Forms.DockStyle.Left;
this.BottomLeft.Location = new System.Drawing.Point(0, 0);
this.BottomLeft.Name = "BottomLeft";
this.BottomLeft.Size = new System.Drawing.Size(2, 2);
this.BottomLeft.TabIndex = 1;
//
// RightBar
//
this.RightBar.BackColor = System.Drawing.Color.Gray;
this.RightBar.Dock = System.Windows.Forms.DockStyle.Right;
this.RightBar.Location = new System.Drawing.Point(599, 30);
this.RightBar.Name = "RightBar";
this.RightBar.Size = new System.Drawing.Size(2, 314);
this.RightBar.TabIndex = 3;
//
// LeftBar
//
this.LeftBar.BackColor = System.Drawing.Color.Gray;
this.LeftBar.Dock = System.Windows.Forms.DockStyle.Left;
this.LeftBar.Location = new System.Drawing.Point(0, 30);
this.LeftBar.Name = "LeftBar";
this.LeftBar.Size = new System.Drawing.Size(2, 314);
this.LeftBar.TabIndex = 4;
//
// CloseButton
//
this.CloseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.CloseButton.BackColor = System.Drawing.Color.Black;
this.CloseButton.Location = new System.Drawing.Point(574, 3);
this.CloseButton.Name = "CloseButton";
this.CloseButton.Size = new System.Drawing.Size(24, 24);
this.CloseButton.TabIndex = 5;
//
// RollButton
//
this.RollButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.RollButton.BackColor = System.Drawing.Color.Black;
this.RollButton.Location = new System.Drawing.Point(547, 3);
this.RollButton.Name = "RollButton";
this.RollButton.Size = new System.Drawing.Size(24, 24);
this.RollButton.TabIndex = 6;
//
// MinimizeButton
//
this.MinimizeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.MinimizeButton.BackColor = System.Drawing.Color.Black;
this.MinimizeButton.Location = new System.Drawing.Point(520, 3);
this.MinimizeButton.Name = "MinimizeButton";
this.MinimizeButton.Size = new System.Drawing.Size(24, 24);
this.MinimizeButton.TabIndex = 7;
//
// TitleText
//
this.TitleText.AutoSize = true;
this.TitleText.BackColor = System.Drawing.Color.Transparent;
this.TitleText.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
this.TitleText.ForeColor = System.Drawing.Color.White;
this.TitleText.Location = new System.Drawing.Point(26, 6);
this.TitleText.Name = "TitleText";
this.TitleText.Size = new System.Drawing.Size(100, 17);
this.TitleText.TabIndex = 5;
this.TitleText.Text = "Window Title";
//
// IconBox
//
this.IconBox.BackColor = System.Drawing.Color.Black;
this.IconBox.Location = new System.Drawing.Point(7, 7);
this.IconBox.Name = "IconBox";
this.IconBox.Size = new System.Drawing.Size(16, 16);
this.IconBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.IconBox.TabIndex = 8;
this.IconBox.TabStop = false;
//
// Window
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange;
this.BackColor = System.Drawing.Color.White;
this.Controls.Add(this.LeftBar);
this.Controls.Add(this.RightBar);
this.Controls.Add(this.BottomBarHolder);
this.Controls.Add(this.TitleBarHolder);
this.ForeColor = System.Drawing.Color.Black;
this.Name = "Window";
this.Size = new System.Drawing.Size(601, 346);
this.TitleBarHolder.ResumeLayout(false);
this.TitleBarHolder.PerformLayout();
this.BottomBarHolder.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel TitleBarHolder;
private System.Windows.Forms.Panel TitleBarRight;
private System.Windows.Forms.Panel TitleBarLeft;
private System.Windows.Forms.Panel BottomBarHolder;
private System.Windows.Forms.Panel BottomBar;
private System.Windows.Forms.Panel BottomRight;
private System.Windows.Forms.Panel BottomLeft;
private System.Windows.Forms.Panel RightBar;
private System.Windows.Forms.Panel LeftBar;
private System.Windows.Forms.Panel CloseButton;
private System.Windows.Forms.Panel MinimizeButton;
private System.Windows.Forms.Panel RollButton;
private System.Windows.Forms.Label TitleText;
private System.Windows.Forms.PictureBox IconBox;
}
}

View file

@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Design;
using System.Windows.Forms;
namespace ShiftOS.Windowing
{
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class Window : UserControl
{
private SystemContext _currentSystem = null;
public Window()
{
InitializeComponent();
}
public void SetSystemContext(SystemContext InSystemContext)
{
if (_currentSystem != null)
throw new InvalidOperationException("This window has already been initialized.");
if (InSystemContext == null)
throw new ArgumentNullException("InSystemContext");
_currentSystem = InSystemContext;
_currentSystem.DesktopUpdated += OnDesktopUpdated;
}
private void OnDesktopUpdated(object sender, EventArgs e)
{
// Get the skin data.
var skin = this.CurrentSystem.GetSkinContext();
var skindata = skin.GetSkinData();
// Set the titlebar height.
this.TitleBarHolder.Height = skindata.titlebarheight;
// Set the title text position.
this.TitleText.Top = skindata.titletextfromtop;
if(skindata.titletextpos == "Left")
{
this.TitleText.Left = skindata.titletextfromside;
}
else
{
this.TitleText.Left = (this.TitleBarHolder.Width - this.TitleText.Width) / 2;
}
// Set the title icon's position.
this.IconBox.Left = skindata.titleiconfromside;
this.IconBox.Top = skindata.titleiconfromtop;
// Set the title button sizes
this.CloseButton.Size = skindata.closebtnsize;
this.RollButton.Size = skindata.rollbtnsize;
this.MinimizeButton.Size = skindata.minbtnsize;
// Set the close button location.
this.CloseButton.Top = skindata.closebtnfromtop;
this.CloseButton.Left = (this.TitleBarHolder.Width - this.CloseButton.Width) - skindata.closebtnfromside;
// Set the rollup button's position.
this.RollButton.Top = skindata.rollbtnfromtop;
this.RollButton.Left = (this.TitleBarHolder.Width - this.RollButton.Width) - skindata.rollbtnfromside;
// Set the minimize button's position.
this.MinimizeButton.Top = skindata.minbtnfromtop;
this.MinimizeButton.Left = (this.TitleBarHolder.Width - this.MinimizeButton.Width) - skindata.minbtnfromside;
// Update the title text font if we need to.
if(TitleText.Font.Name != skindata.titletextfontfamily || TitleText.Font.Size != skindata.titletextfontsize || TitleText.Font.Style != skindata.titletextfontstyle)
{
this.TitleText.Font = new Font(skindata.titletextfontfamily, skindata.titletextfontsize, skindata.titletextfontstyle);
}
// Set the title text color.
this.TitleText.ForeColor = skindata.titletextcolour;
// Set up the close button background.
if(skin.HasImage("closebtn"))
{
CloseButton.BackColor = Color.Transparent;
if (CloseButton.BackgroundImage != skin.GetImage("closebtn"))
CloseButton.BackgroundImage = skin.GetImage("closebtn");
CloseButton.BackgroundImageLayout = skindata.closebtnlayout;
}
else
{
CloseButton.BackgroundImage = null;
CloseButton.BackColor = skindata.closebtncolour;
}
// Set up the roll button background.
if (skin.HasImage("rollbtn"))
{
RollButton.BackColor = Color.Transparent;
if (RollButton.BackgroundImage != skin.GetImage("rollbtn"))
RollButton.BackgroundImage = skin.GetImage("rollbtn");
RollButton.BackgroundImageLayout = skindata.rollbtnlayout;
}
else
{
RollButton.BackgroundImage = null;
RollButton.BackColor = skindata.rollbtncolour;
}
}
/// <summary>
/// Gets a reference to the current system context.
/// </summary>
public SystemContext CurrentSystem => _currentSystem;
/// <summary>
/// Gets or sets the title text of this Window.
/// </summary>
public string WindowTitle
{
get => this.TitleText.Text;
set => this.TitleText.Text = value;
}
public Image WindowIcon
{
get => this.IconBox.Image;
set => this.IconBox.Image = value;
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net461" />
</packages>