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