Icon Manager and various icon bugfixes.

This commit is contained in:
Michael 2017-06-01 17:09:22 -04:00
parent 324104eb0b
commit 03cf891c53
9 changed files with 774 additions and 1 deletions

View file

@ -0,0 +1,163 @@
namespace ShiftOS.WinForms.Applications
{
partial class IconManager
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.btnclose = new System.Windows.Forms.Button();
this.btnreset = new System.Windows.Forms.Button();
this.btnapply = new System.Windows.Forms.Button();
this.flbody = new System.Windows.Forms.FlowLayoutPanel();
this.lbcurrentpage = new System.Windows.Forms.Label();
this.btnprev = new System.Windows.Forms.Button();
this.btnnext = new System.Windows.Forms.Button();
this.flowLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.AutoSize = true;
this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.flowLayoutPanel1.Controls.Add(this.btnclose);
this.flowLayoutPanel1.Controls.Add(this.btnreset);
this.flowLayoutPanel1.Controls.Add(this.btnapply);
this.flowLayoutPanel1.Controls.Add(this.lbcurrentpage);
this.flowLayoutPanel1.Controls.Add(this.btnprev);
this.flowLayoutPanel1.Controls.Add(this.btnnext);
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 416);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(393, 29);
this.flowLayoutPanel1.TabIndex = 0;
//
// btnclose
//
this.btnclose.AutoSize = true;
this.btnclose.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.btnclose.Location = new System.Drawing.Point(3, 3);
this.btnclose.Name = "btnclose";
this.btnclose.Size = new System.Drawing.Size(43, 23);
this.btnclose.TabIndex = 0;
this.btnclose.Text = "Close";
this.btnclose.UseVisualStyleBackColor = true;
this.btnclose.Click += new System.EventHandler(this.btnclose_Click);
//
// btnreset
//
this.btnreset.AutoSize = true;
this.btnreset.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.btnreset.Location = new System.Drawing.Point(52, 3);
this.btnreset.Name = "btnreset";
this.btnreset.Size = new System.Drawing.Size(45, 23);
this.btnreset.TabIndex = 1;
this.btnreset.Text = "Reset";
this.btnreset.UseVisualStyleBackColor = true;
this.btnreset.Click += new System.EventHandler(this.btnreset_Click);
//
// btnapply
//
this.btnapply.AutoSize = true;
this.btnapply.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.btnapply.Location = new System.Drawing.Point(103, 3);
this.btnapply.Name = "btnapply";
this.btnapply.Size = new System.Drawing.Size(43, 23);
this.btnapply.TabIndex = 2;
this.btnapply.Text = "Apply";
this.btnapply.UseVisualStyleBackColor = true;
this.btnapply.Click += new System.EventHandler(this.btnapply_Click);
//
// flbody
//
this.flbody.Dock = System.Windows.Forms.DockStyle.Fill;
this.flbody.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flbody.Location = new System.Drawing.Point(0, 0);
this.flbody.Name = "flbody";
this.flbody.Size = new System.Drawing.Size(393, 416);
this.flbody.TabIndex = 1;
this.flbody.WrapContents = false;
//
// lbcurrentpage
//
this.lbcurrentpage.AutoSize = true;
this.lbcurrentpage.Location = new System.Drawing.Point(152, 0);
this.lbcurrentpage.Name = "lbcurrentpage";
this.lbcurrentpage.Size = new System.Drawing.Size(71, 13);
this.lbcurrentpage.TabIndex = 3;
this.lbcurrentpage.Text = "Current page:";
//
// btnprev
//
this.btnprev.AutoSize = true;
this.btnprev.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.btnprev.Location = new System.Drawing.Point(229, 3);
this.btnprev.Name = "btnprev";
this.btnprev.Size = new System.Drawing.Size(51, 23);
this.btnprev.TabIndex = 4;
this.btnprev.Text = " < Prev";
this.btnprev.UseVisualStyleBackColor = true;
this.btnprev.Click += new System.EventHandler(this.btnprev_Click);
//
// btnnext
//
this.btnnext.AutoSize = true;
this.btnnext.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.btnnext.Location = new System.Drawing.Point(286, 3);
this.btnnext.Name = "btnnext";
this.btnnext.Size = new System.Drawing.Size(48, 23);
this.btnnext.TabIndex = 5;
this.btnnext.Text = "Next >";
this.btnnext.UseVisualStyleBackColor = true;
this.btnnext.Click += new System.EventHandler(this.btnnext_Click);
//
// IconManager
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flbody);
this.Controls.Add(this.flowLayoutPanel1);
this.Name = "IconManager";
this.Size = new System.Drawing.Size(393, 445);
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Button btnclose;
private System.Windows.Forms.Button btnreset;
private System.Windows.Forms.Button btnapply;
private System.Windows.Forms.FlowLayoutPanel flbody;
private System.Windows.Forms.Label lbcurrentpage;
private System.Windows.Forms.Button btnprev;
private System.Windows.Forms.Button btnnext;
}
}

View file

@ -0,0 +1,244 @@
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.Windows.Forms;
using ShiftOS.Engine;
using System.Reflection;
using ShiftOS.WinForms.Tools;
using Newtonsoft.Json;
namespace ShiftOS.WinForms.Applications
{
[RequiresUpgrade("icon_manager")]
[Launcher("Icon Manager", true, "al_icon_manager", "Customization")]
[DefaultTitle("Icon Manager")]
[DefaultIcon("iconIconManager")]
public partial class IconManager : UserControl, IShiftOSWindow
{
public IconManager()
{
InitializeComponent();
}
public void OnLoad()
{
LoadIconsFromEngine();
SetupUI();
}
public void OnSkinLoad()
{
LoadIconsFromEngine();
SetupUI();
}
public bool OnUnload()
{
Icons = null;
return true;
}
private Dictionary<string, byte[]> Icons = null;
private const int pageSize = 10;
private int currentPage = 0;
private int pageCount = 0;
public Image GetIcon(string id)
{
if (!Icons.ContainsKey(id))
Icons.Add(id, null);
if (Icons[id] == null)
{
var img = SkinEngine.GetDefaultIcon(id);
using (var mstr = new System.IO.MemoryStream())
{
img.Save(mstr, System.Drawing.Imaging.ImageFormat.Png);
Icons[id] = mstr.ToArray();
}
return img;
}
else
{
using (var sr = new System.IO.MemoryStream(Icons[id]))
{
return Image.FromStream(sr);
}
}
}
public void SetIcon(string key, byte[] raw)
{
if (!Icons.ContainsKey(key))
Icons.Add(key, raw);
Icons[key] = raw;
}
public void LoadIconsFromEngine()
{
//We have to serialize the engine icon list to JSON to break references with the data.
string json = JsonConvert.SerializeObject(SkinEngine.LoadedSkin.AppIcons);
//And deserialize to the local instance...essentially making a clone.
Icons = JsonConvert.DeserializeObject<Dictionary<string, byte[]>>(json);
}
public void SetupUI()
{
flbody.Controls.Clear(); //Clear the icon list.
List<Type> types = new List<Type>();
foreach(var exe in System.IO.Directory.GetFiles(Environment.CurrentDirectory))
{
if(exe.ToLower().EndsWith(".exe") || exe.ToLower().EndsWith(".dll"))
{
try
{
var asm = Assembly.LoadFile(exe);
var typeList = asm.GetTypes().Where(x => x.GetCustomAttributes(false).FirstOrDefault(y => y is DefaultIconAttribute) != null);
types.AddRange(typeList);
}
catch { }
}
}
pageCount = types.ToArray().GetPageCount(pageSize);
foreach (var type in types.ToArray().GetItemsOnPage(currentPage, pageSize))
{
if (Shiftorium.UpgradeAttributesUnlocked(type))
{
var pnl = new Panel();
pnl.Height = 30;
pnl.Width = flbody.Width - 15;
flbody.Controls.Add(pnl);
pnl.Show();
var pic = new PictureBox();
pic.SizeMode = PictureBoxSizeMode.StretchImage;
pic.Size = new Size(24, 24);
pic.Image = GetIcon(type.Name);
pnl.Controls.Add(pic);
pic.Left = 5;
pic.Top = (pnl.Height - pic.Height) / 2;
pic.Show();
var lbl = new Label();
lbl.Tag = "header3";
lbl.AutoSize = true;
lbl.Text = NameChangerBackend.GetNameRaw(type);
ControlManager.SetupControl(lbl);
pnl.Controls.Add(lbl);
lbl.CenterParent();
lbl.Show();
var btn = new Button();
btn.Text = "Change...";
btn.AutoSize = true;
btn.AutoSizeMode = AutoSizeMode.GrowAndShrink;
pnl.Controls.Add(btn);
btn.Left = (pnl.Width - btn.Width) - 5;
btn.Top = (pnl.Height - btn.Height) / 2;
btn.Click += (o, a) =>
{
var gfp = new GraphicPicker(pic.Image, lbl.Text + " icon", ImageLayout.Stretch, (raw, img, layout) =>
{
pic.Image = img;
SetIcon(type.Name, raw);
});
AppearanceManager.SetupDialog(gfp);
};
btn.Show();
ControlManager.SetupControls(pnl);
}
}
btnnext.Visible = (currentPage < pageCount - 1);
btnprev.Visible = (currentPage > 0);
lbcurrentpage.Text = "Page " + (currentPage + 1).ToString() + " of " + pageCount.ToString();
}
public void OnUpgrade()
{
LoadIconsFromEngine();
SetupUI();
}
private void btnprev_Click(object sender, EventArgs e)
{
currentPage--;
SetupUI();
}
public void ResetToDefaults()
{
currentPage = 0;
foreach (var key in Icons.Keys)
{
var img = SkinEngine.GetDefaultIcon(key);
using(var ms = new System.IO.MemoryStream())
{
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
Icons[key] = ms.ToArray();
}
}
SetupUI();
}
private void btnnext_Click(object sender, EventArgs e)
{
currentPage++;
SetupUI();
}
private void btnclose_Click(object sender, EventArgs e)
{
AppearanceManager.Close(this);
}
private void btnreset_Click(object sender, EventArgs e)
{
ResetToDefaults();
}
private void btnapply_Click(object sender, EventArgs e)
{
SkinEngine.LoadedSkin.AppIcons = Icons;
SkinEngine.SaveSkin();
SkinEngine.LoadSkin();
Infobox.Show("Icons applied!", "The new icons have been applied to ShiftOS successfully!");
}
}
public static class PaginationExtensions
{
public static int GetPageCount<T>(this IEnumerable<T> collection, int pageSize)
{
return (collection.Count() + pageSize - 1) / pageSize;
}
public static T[] GetItemsOnPage<T>(this T[] collection, int page, int pageSize)
{
List<T> obj = new List<T>();
for (int i = pageSize * page; i <= pageSize + (pageSize * page) && i < collection.Count(); i++)
{
try
{
obj.Add(collection[i]);
}
catch
{
}
}
return obj.ToArray();
}
}
}

View file

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

View file

@ -7,6 +7,20 @@
Dependencies: "desktop",
Category: "Enhancements",
},
{
Name: "Icon Manager",
Cost: 450,
Description: "This tool allows you to add and edit application icons within ShiftOS for the small prive of 450 Codepoints!",
Dependencies: "skinning",
Category: "Application"
},
{
Name: "AL Icon Manager",
Costs: 150,
Description: "Add an App Launcher entry for the Icon Manager.",
Dependencies: "icon_manager;app_launcher",
Category: "Customization"
},
{
Name: "Shift Progress Bar",
Cost: 150,

View file

@ -70,6 +70,12 @@
<Compile Include="Applications\About.Designer.cs">
<DependentUpon>About.cs</DependentUpon>
</Compile>
<Compile Include="Applications\IconManager.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Applications\IconManager.Designer.cs">
<DependentUpon>IconManager.cs</DependentUpon>
</Compile>
<Compile Include="Applications\TriPresent.cs">
<SubType>UserControl</SubType>
</Compile>
@ -409,6 +415,12 @@
<Compile Include="StatusIcons\ShiftnetStatus.Designer.cs">
<DependentUpon>ShiftnetStatus.cs</DependentUpon>
</Compile>
<Compile Include="StatusIcons\TestStatus.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="StatusIcons\TestStatus.Designer.cs">
<DependentUpon>TestStatus.cs</DependentUpon>
</Compile>
<Compile Include="StatusIcons\Volume.cs">
<SubType>UserControl</SubType>
</Compile>
@ -461,6 +473,9 @@
<EmbeddedResource Include="Applications\About.resx">
<DependentUpon>About.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Applications\IconManager.resx">
<DependentUpon>IconManager.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Applications\TriPresent.resx">
<DependentUpon>TriPresent.cs</DependentUpon>
</EmbeddedResource>
@ -616,6 +631,9 @@
<EmbeddedResource Include="StatusIcons\ShiftnetStatus.resx">
<DependentUpon>ShiftnetStatus.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="StatusIcons\TestStatus.resx">
<DependentUpon>TestStatus.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="StatusIcons\Volume.resx">
<DependentUpon>Volume.cs</DependentUpon>
</EmbeddedResource>

View file

@ -0,0 +1,60 @@
namespace ShiftOS.WinForms.StatusIcons
{
partial class TestStatus
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(264, 52);
this.label1.TabIndex = 0;
this.label1.Tag = "header1";
this.label1.Text = "This is a test.";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// TestStatus
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label1);
this.Name = "TestStatus";
this.Size = new System.Drawing.Size(264, 52);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
}
}

View file

@ -0,0 +1,26 @@
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.Windows.Forms;
using ShiftOS.Engine;
namespace ShiftOS.WinForms.StatusIcons
{
[DefaultIcon("iconShiftorium")]
public partial class TestStatus : UserControl, IStatusIcon
{
public TestStatus()
{
InitializeComponent();
}
public void Setup()
{
}
}
}

View file

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

View file

@ -287,7 +287,15 @@ namespace ShiftOS.Engine
LoadedSkin.AppIcons.Add(id, null);
if (LoadedSkin.AppIcons[id] == null)
return GetDefaultIcon(id);
{
var img = GetDefaultIcon(id);
using (var mstr = new MemoryStream())
{
img.Save(mstr, System.Drawing.Imaging.ImageFormat.Png);
LoadedSkin.AppIcons[id] = mstr.ToArray();
}
return img;
}
else
{
using (var sr = new MemoryStream(LoadedSkin.AppIcons[id]))