diff --git a/ShiftOS/ShiftOS/Desktop.Designer.cs b/ShiftOS/ShiftOS/Desktop.Designer.cs
index 12be50a..d9f7d64 100644
--- a/ShiftOS/ShiftOS/Desktop.Designer.cs
+++ b/ShiftOS/ShiftOS/Desktop.Designer.cs
@@ -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;
}
}
diff --git a/ShiftOS/ShiftOS/Desktop.cs b/ShiftOS/ShiftOS/Desktop.cs
index 25d01f2..f2e9442 100644
--- a/ShiftOS/ShiftOS/Desktop.cs
+++ b/ShiftOS/ShiftOS/Desktop.cs
@@ -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");
}
}
}
diff --git a/ShiftOS/ShiftOS/Desktop.resx b/ShiftOS/ShiftOS/Desktop.resx
index 05f1355..22acd2d 100644
--- a/ShiftOS/ShiftOS/Desktop.resx
+++ b/ShiftOS/ShiftOS/Desktop.resx
@@ -117,6 +117,9 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 139, 17
+
17, 17
diff --git a/ShiftOS/ShiftOS/FilesystemContext.cs b/ShiftOS/ShiftOS/FilesystemContext.cs
index 5927782..1d03343 100644
--- a/ShiftOS/ShiftOS/FilesystemContext.cs
+++ b/ShiftOS/ShiftOS/FilesystemContext.cs
@@ -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;
+ }
+
+
+
}
}
diff --git a/ShiftOS/ShiftOS/Metadata/ProgramAttribute.cs b/ShiftOS/ShiftOS/Metadata/ProgramAttribute.cs
new file mode 100644
index 0000000..5aa77ad
--- /dev/null
+++ b/ShiftOS/ShiftOS/Metadata/ProgramAttribute.cs
@@ -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;
+ }
+}
diff --git a/ShiftOS/ShiftOS/PanelButton.Designer.cs b/ShiftOS/ShiftOS/PanelButton.Designer.cs
new file mode 100644
index 0000000..46c9a4c
--- /dev/null
+++ b/ShiftOS/ShiftOS/PanelButton.Designer.cs
@@ -0,0 +1,79 @@
+namespace ShiftOS
+{
+ partial class PanelButton
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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;
+ }
+}
diff --git a/ShiftOS/ShiftOS/PanelButton.cs b/ShiftOS/ShiftOS/PanelButton.cs
new file mode 100644
index 0000000..f449bf3
--- /dev/null
+++ b/ShiftOS/ShiftOS/PanelButton.cs
@@ -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);
+ }
+
+
+ }
+ }
+}
diff --git a/ShiftOS/ShiftOS/PanelButton.resx b/ShiftOS/ShiftOS/PanelButton.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/ShiftOS/ShiftOS/PanelButton.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ShiftOS/ShiftOS/Programs/Terminal.Designer.cs b/ShiftOS/ShiftOS/Programs/Terminal.Designer.cs
new file mode 100644
index 0000000..1376aa0
--- /dev/null
+++ b/ShiftOS/ShiftOS/Programs/Terminal.Designer.cs
@@ -0,0 +1,64 @@
+namespace ShiftOS.Programs
+{
+ partial class Terminal
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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;
+ }
+}
diff --git a/ShiftOS/ShiftOS/Programs/Terminal.cs b/ShiftOS/ShiftOS/Programs/Terminal.cs
new file mode 100644
index 0000000..d35fec2
--- /dev/null
+++ b/ShiftOS/ShiftOS/Programs/Terminal.cs
@@ -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)
+ {
+
+ }
+ }
+}
diff --git a/ShiftOS/ShiftOS/Programs/Terminal.resx b/ShiftOS/ShiftOS/Programs/Terminal.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/ShiftOS/ShiftOS/Programs/Terminal.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ShiftOS/ShiftOS/ShiftOS.csproj b/ShiftOS/ShiftOS/ShiftOS.csproj
index 8cbaa6a..50a3234 100644
--- a/ShiftOS/ShiftOS/ShiftOS.csproj
+++ b/ShiftOS/ShiftOS/ShiftOS.csproj
@@ -5,7 +5,7 @@
Debug
AnyCPU
{18E84DF0-695C-4D78-BE74-0D2C203469A6}
- WinExe
+ Exe
ShiftOS
ShiftOS
v4.6.1
@@ -32,7 +32,13 @@
prompt
4
+
+
+
+
+ ..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll
+
@@ -53,14 +59,40 @@
Desktop.cs
+
+
+ UserControl
+
+
+ PanelButton.cs
+
+
+ UserControl
+
+
+ Terminal.cs
+
+
+
+ UserControl
+
+
+ Window.cs
+
Desktop.cs
+
+ PanelButton.cs
+
+
+ Terminal.cs
+
ResXFileCodeGenerator
Resources.Designer.cs
@@ -71,6 +103,10 @@
Resources.resx
True
+
+ Window.cs
+
+
SettingsSingleFileGenerator
Settings.Designer.cs
diff --git a/ShiftOS/ShiftOS/Skin.cs b/ShiftOS/ShiftOS/Skin.cs
index 8aa3329..a7745b8 100644
--- a/ShiftOS/ShiftOS/Skin.cs
+++ b/ShiftOS/ShiftOS/Skin.cs
@@ -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;
}
}
diff --git a/ShiftOS/ShiftOS/SkinContext.cs b/ShiftOS/ShiftOS/SkinContext.cs
index dbab213..56b8258 100644
--- a/ShiftOS/ShiftOS/SkinContext.cs
+++ b/ShiftOS/ShiftOS/SkinContext.cs
@@ -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 _skinimages = new Dictionary();
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();
+
+ 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(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;
+ }
}
}
diff --git a/ShiftOS/ShiftOS/SystemContext.cs b/ShiftOS/ShiftOS/SystemContext.cs
index ef6972f..45c4e63 100644
--- a/ShiftOS/ShiftOS/SystemContext.cs
+++ b/ShiftOS/ShiftOS/SystemContext.cs
@@ -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 _programTypeMap = new Dictionary();
+ private List _programMetadata = new List();
+
+
+ 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 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...");
diff --git a/ShiftOS/ShiftOS/ToolStripSkinRenderer.cs b/ShiftOS/ShiftOS/ToolStripSkinRenderer.cs
new file mode 100644
index 0000000..b6129a9
--- /dev/null
+++ b/ShiftOS/ShiftOS/ToolStripSkinRenderer.cs
@@ -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;
+ }
+}
diff --git a/ShiftOS/ShiftOS/Windowing/Window.Designer.cs b/ShiftOS/ShiftOS/Windowing/Window.Designer.cs
new file mode 100644
index 0000000..f52b4f6
--- /dev/null
+++ b/ShiftOS/ShiftOS/Windowing/Window.Designer.cs
@@ -0,0 +1,229 @@
+namespace ShiftOS.Windowing
+{
+ partial class Window
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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;
+ }
+}
diff --git a/ShiftOS/ShiftOS/Windowing/Window.cs b/ShiftOS/ShiftOS/Windowing/Window.cs
new file mode 100644
index 0000000..e8ec4c0
--- /dev/null
+++ b/ShiftOS/ShiftOS/Windowing/Window.cs
@@ -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;
+ }
+
+ }
+
+
+ ///
+ /// Gets a reference to the current system context.
+ ///
+ public SystemContext CurrentSystem => _currentSystem;
+
+ ///
+ /// Gets or sets the title text of this Window.
+ ///
+ public string WindowTitle
+ {
+ get => this.TitleText.Text;
+ set => this.TitleText.Text = value;
+ }
+
+ public Image WindowIcon
+ {
+ get => this.IconBox.Image;
+ set => this.IconBox.Image = value;
+ }
+ }
+}
diff --git a/ShiftOS/ShiftOS/Windowing/Window.resx b/ShiftOS/ShiftOS/Windowing/Window.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/ShiftOS/ShiftOS/Windowing/Window.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ShiftOS/ShiftOS/packages.config b/ShiftOS/ShiftOS/packages.config
new file mode 100644
index 0000000..466ab76
--- /dev/null
+++ b/ShiftOS/ShiftOS/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file