WIP: refactoring + tile layout

This commit is contained in:
Ray committed 2020-04-11 18:43:20 +01:00
1 parent 06f570122c
commit c9edc93e40
23 files changed
+1078 -491

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
namespace AppLauncher.Windows.Forms
{
partial class TileContainer
{
/// <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 AppLauncher.Windows.Forms.TileGroupLabel();
this.panel1 = new AppLauncher.Windows.Forms.TileLayoutPanel();
this.SuspendLayout();
//
// label1
//
this.label1.AutoScrollMargin = new System.Drawing.Size(0, 0);
this.label1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
this.label1.Checked = false;
this.label1.Location = new System.Drawing.Point(0, 0);
this.label1.Margin = new System.Windows.Forms.Padding(0, 0, 0, 3);
this.label1.MinimumSize = new System.Drawing.Size(100, 20);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(223, 20);
this.label1.TabIndex = 11;
this.label1.TileGroupPanel = null;
this.label1.TitleText = "Featured";
//
// panel1
//
this.panel1.AutoScrollMargin = new System.Drawing.Size(0, 0);
this.panel1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
this.panel1.BackColor = System.Drawing.Color.Transparent;
this.panel1.Location = new System.Drawing.Point(0, 23);
this.panel1.Margin = new System.Windows.Forms.Padding(2, 0, 0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(223, 127);
this.panel1.TabIndex = 27;
//
// TileContainer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Transparent;
this.Controls.Add(this.panel1);
this.Controls.Add(this.label1);
this.Name = "TileContainer";
this.Size = new System.Drawing.Size(370, 150);
this.ResumeLayout(false);
}
#endregion
private TileGroupLabel label1;
private TileLayoutPanel panel1;
}
}
+124
View File
@@ -0,0 +1,124 @@
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 System.Threading;
using AppLauncher.Models;
namespace AppLauncher.Windows.Forms
{
public partial class TileContainer : AUserControl
{
protected int collapseIncrement = 6;
protected int expandIncrement = 8;
protected TileGroupModel groupInfo = null;
public TileContainer(TileGroupModel model) : base()
{
InitializeComponent();
label1.TileGroupPanel = this;
groupInfo = model;
label1.TitleText = groupInfo.Title;
panel1.SetGridSize(groupInfo.GridSize.Width, groupInfo.GridSize.Height);
label1.Checked = groupInfo.IsExpanded;
//label1.Width = panel1.Width;
//label1.PanelHeight = panel1.Height;
//this.Margin = new Padding(0);
//this.Size = new Size(panel1.Width, (label1.Height + panel1.Height));
//this.MaximumSize = this.Size;
//this.MinimumSize = this.Size;
panel1.LoadTiles(model.Items);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
label1.Width = panel1.Width;
this.Margin = new Padding(0);
this.MaximumSize = new Size(panel1.Width, (label1.Height + panel1.ExpandedHeight));
this.MinimumSize = new Size(panel1.Width, label1.Height);
this.Size = this.MaximumSize;
}
protected int collapseHeight => label1.Height + panel1.CollapseHeight;
protected int expandedHeight => label1.Height + panel1.ExpandedHeight;
public async Task Collapse()
{
await Task.Run(() =>
{
while (this.Height > collapseHeight)
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(() => {
this.Height -= collapseIncrement;
}));
}
else
{
this.Height -= collapseIncrement;
}
Thread.Sleep(10);
}
});
}
public async Task CollapseNow()
{
await Task.Run(() =>
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(() => {
this.Height = collapseHeight;
}));
}
else
{
this.Height = collapseHeight;
}
});
}
public async Task Expand()
{
await Task.Run(() =>
{
while (this.Height < expandedHeight)
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(() => {
this.Height += expandIncrement;
this.Invalidate();
}));
}
else
{
this.Height += expandIncrement;
this.Invalidate();
}
Thread.Sleep(10);
}
});
}
}
}
+120
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>
+93
View File
@@ -0,0 +1,93 @@
namespace AppLauncher.Windows.Forms
{
partial class TileGroupLabel
{
/// <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.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(234)))), ((int)(((byte)(234)))), ((int)(((byte)(234)))));
this.label1.Location = new System.Drawing.Point(25, 0);
this.label1.Margin = new System.Windows.Forms.Padding(0);
this.label1.MinimumSize = new System.Drawing.Size(20, 20);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(575, 20);
this.label1.TabIndex = 8;
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.label1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.panel_MouseClick);
this.label1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.panel_MouseClick);
//
// pictureBox1
//
this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.pictureBox1.ErrorImage = null;
this.pictureBox1.InitialImage = null;
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.MaximumSize = new System.Drawing.Size(20, 20);
this.pictureBox1.MinimumSize = new System.Drawing.Size(20, 20);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(20, 20);
this.pictureBox1.TabIndex = 7;
this.pictureBox1.TabStop = false;
this.pictureBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.panel_MouseClick);
this.pictureBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.panel_MouseClick);
//
// HeadingPanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label1);
this.Controls.Add(this.pictureBox1);
this.MinimumSize = new System.Drawing.Size(100, 20);
this.Name = "HeadingPanel";
this.Size = new System.Drawing.Size(600, 20);
this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.panel_MouseClick);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.PictureBox pictureBox1;
}
}
+82
View File
@@ -0,0 +1,82 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AppLauncher.Windows.Forms
{
public partial class TileGroupLabel : AUserControl
{
protected bool isChecked = false;
public TileGroupLabel() : base()
{
InitializeComponent();
this.Checked = false;
}
[Category("Appearance"), Browsable(true)]
public string TitleText { get => label1.Text; set => label1.Text = value; }
[Category("Appearance"), Browsable(true)]
public bool Checked
{
get => isChecked;
set
{
isChecked = value;
pictureBox1.BackgroundImage = (value) ? Properties.Resources.toggle_right_ea_16 : Properties.Resources.toggle_left_ea_16;
}
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public TileContainer TileGroupPanel { get; set; } = null;
protected async override void OnLoad(EventArgs e)
{
base.OnLoad(e);
await invalidateToggle(false);
}
protected async void panel_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
{
return;
}
this.Checked = !this.Checked;
await invalidateToggle();
}
protected async Task invalidateToggle(bool animate = true)
{
if (this.TileGroupPanel == null)
{
return;
}
if (this.Checked)
{
await this.TileGroupPanel.Expand();
}
else
{
if (animate)
{
await this.TileGroupPanel.Collapse();
}
else
{
await this.TileGroupPanel.CollapseNow();
}
}
}
}
}
+120
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>
+220
View File
@@ -0,0 +1,220 @@
using AppLauncher.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AppLauncher.Windows.Forms
{
public class TileLayoutPanel : AUserControl
{
public class Item
{
public TilePanel Tile { get; set; }
public Point Coord { get; set; } = new Point(0, 0);
}
protected readonly int tileSize = 70;
protected readonly int margin = 3;
protected int collapseHeight = 0;
protected int expandedHeight = 0;
protected List<Item> items = new List<Item>();
public TileLayoutPanel() : base()
{
this.BackColor = System.Drawing.Color.Transparent;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
OnResize(e);
}
public Point GridSize
{
get
{
int w = (int)Math.Floor(decimal.Divide(this.Width, this.TileSize));
int h = (int)Math.Floor(decimal.Divide(this.Height, this.TileSize));
return new Point(w, h);
}
}
public int TileSize => (tileSize + margin);
public int CollapseHeight => collapseHeight;
public int ExpandedHeight => expandedHeight;
public void Clear()
{
this.Controls.Clear();
}
//public Point GetTileCoord(Point location) => this.GetTileCoord(location.X, location.Y);
//public Point GetTileCoord(int posX, int posY)
//{
// int x = (int)Math.Round(decimal.Divide(posX, this.TileSize));
// int y = (int)Math.Round(decimal.Divide(posY, this.TileSize));
// if (x < 0) x = 0;
// if (y < 0) y = 0;
// return new Point(x, y);
//}
//public Point GetTilePosition(Point location) => this.GetTilePosition(location.X, location.Y);
public Point GetTilePosition(int posX, int posY)
{
int x = (int)Math.Round(decimal.Divide(posX, this.TileSize));
int y = (int)Math.Round(decimal.Divide(posY, this.TileSize));
if (x < 0) x = 0;
if (y < 0) y = 0;
return new Point((x * this.TileSize), (y * this.TileSize));
}
public void SetGridSize(int width, int height)
{
expandedHeight = (this.TileSize * height);
this.Size = new Size((this.TileSize * width), expandedHeight);
}
public void LoadTiles(List<TileModel> tiles)
{
if (tiles == null)
{
return;
}
if (tiles.Count() <= 0)
{
return;
}
foreach (TileModel item in tiles)
{
// resolve final grid position
Point? confirmedPosition = resolvePosition(item.Position);
if (confirmedPosition == null)
{
continue;
}
// place control
TilePanel panel = new TilePanel();
panel.LoadInfo(item);
panel.Location = convertPositionToLocation(confirmedPosition.Value);
items.Add(new Item()
{
Tile = panel,
Coord = confirmedPosition.Value
});
this.Controls.Add(panel);
}
}
public void MoveTile(TilePanel panel, int posX, int posY)
{
}
protected Point convertPositionToLocation(Point position) => new Point((position.X * this.TileSize), (position.Y * this.TileSize));
protected Point? resolvePosition(Point position)
{
if (!isTileInBounds(position))
{
return null;
}
if (!hasTile(position))
{
return position;
}
return resolveNextPosition(position);
}
protected Point? resolveNextPosition(Point position)
{
Point gridSize = this.GridSize;
Point newPosition = position;
while (true)
{
newPosition.X++;
if (newPosition.X >= gridSize.X)
{
newPosition.Y++;
newPosition.X = 0;
}
if (!isTileInBounds(newPosition))
{
return null;
}
if (hasTile(newPosition))
{
continue;
}
return newPosition;
}
}
protected bool hasTile(Point position)
{
if (items == null)
{
return false;
}
if (items.Count <= 0)
{
return false;
}
return (items.Count(x => x.Coord.Equals(position)) > 0);
}
protected bool isTileInBounds(Point position)
{
Point gridSize = this.GridSize;
if (position.X > gridSize.X)
{
return false;
}
if (position.Y > gridSize.Y)
{
return false;
}
return true;
}
}
}
+120
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>
+90
View File
@@ -0,0 +1,90 @@
namespace AppLauncher.Windows.Forms
{
partial class TilePanel
{
/// <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.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.AutoEllipsis = true;
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(234)))), ((int)(((byte)(234)))), ((int)(((byte)(234)))));
this.label1.Location = new System.Drawing.Point(0, 47);
this.label1.Margin = new System.Windows.Forms.Padding(0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(70, 13);
this.label1.TabIndex = 24;
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label1.Click += new System.EventHandler(this.TilePanel_Click);
this.label1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.TilePanel_MouseDoubleClick);
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.pictureBox1.ErrorImage = null;
this.pictureBox1.InitialImage = null;
this.pictureBox1.Location = new System.Drawing.Point(0, 8);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(70, 38);
this.pictureBox1.TabIndex = 25;
this.pictureBox1.TabStop = false;
this.pictureBox1.Click += new System.EventHandler(this.TilePanel_Click);
this.pictureBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.TilePanel_MouseDoubleClick);
//
// TilePanel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(68)))), ((int)(((byte)(68)))), ((int)(((byte)(68)))));
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.label1);
this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(234)))), ((int)(((byte)(234)))), ((int)(((byte)(234)))));
this.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0);
this.MaximumSize = new System.Drawing.Size(70, 70);
this.MinimumSize = new System.Drawing.Size(70, 70);
this.Name = "TilePanel";
this.Size = new System.Drawing.Size(70, 70);
this.Click += new System.EventHandler(this.TilePanel_Click);
this.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.TilePanel_MouseDoubleClick);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.PictureBox pictureBox1;
}
}
+174
View File
@@ -0,0 +1,174 @@
using AppLauncher.Models;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace AppLauncher.Windows.Forms
{
public partial class TilePanel : AUserControl
{
protected bool isDragging = false;
protected Point startPosition = new Point();
protected TileModel model = new TileModel();
public TilePanel() : base()
{
InitializeComponent();
this.MouseDown += panel_MouseDown;
this.MouseUp += panel_MouseUp;
this.MouseMove += panel_MouseMove;
pictureBox1.MouseDown += panel_MouseDown;
pictureBox1.MouseUp += panel_MouseUp;
pictureBox1.MouseMove += panel_MouseMove;
label1.MouseDown += panel_MouseDown;
label1.MouseUp += panel_MouseUp;
label1.MouseMove += panel_MouseMove;
}
[Category("Appearance"), Browsable(true)]
public string Title { get => label1.Text; protected set => label1.Text = value; }
[Category("Appearance"), Browsable(true)]
public Image Image { get => pictureBox1.BackgroundImage; protected set => pictureBox1.BackgroundImage = value; }
[Browsable(false)]
public TileModel Info => model;
//[Browsable(false)]
//public string ProcessArgument { get; set; }
//[Browsable(false)]
//public string ProcessWorkingDirectory { get; set; }
//[Browsable(false)]
//public ProcessWindowStyle ProcessWindowStyle { get; set; } = ProcessWindowStyle.Normal;
public TileLayoutPanel PanelContainer
{
get
{
if (this.Parent == null)
{
return null;
}
if (this.Parent.GetType() != typeof(TileLayoutPanel))
{
return null;
}
return (TileLayoutPanel)this.Parent;
}
}
public void LoadInfo(TileModel model)
{
this.model = model;
this.Title = model.Title;
this.Image = model.Icon;
if (this.Image == null)
{
if (File.Exists(model.ProcessFilename))
{
try
{
this.Image = Icon.ExtractAssociatedIcon(model.ProcessFilename)?.ToBitmap();
}
catch
{
}
}
}
}
private void panel_MouseDown(object sender, MouseEventArgs e)
{
TileLayoutPanel container = this.PanelContainer;
if (container == null)
{
return;
}
if (e.Button != MouseButtons.Left)
{
return;
}
this.BringToFront();
isDragging = true;
startPosition = e.Location;
}
private void panel_MouseUp(object sender, MouseEventArgs e)
{
isDragging = false;
}
private void panel_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
TileLayoutPanel layoutPanel = this.PanelContainer;
if (layoutPanel == null)
{
return;
}
int x = (this.Location.X + (e.Location.X - startPosition.X));
int y = (this.Location.Y + (e.Location.Y - startPosition.Y));
//this.Location = layoutPanel.GetTilePosition(x, y);
layoutPanel.MoveTile(this, x, y);
}
}
private void TilePanel_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (this.Info == null)
{
return;
}
if (string.IsNullOrWhiteSpace(this.Info.ProcessFilename))
{
return;
}
if (!File.Exists(this.Info.ProcessFilename))
{
return;
}
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = this.Info.ProcessFilename;
p.WindowStyle = this.Info.ProcessWindowStyle;
if (!string.IsNullOrWhiteSpace(this.Info.ProcessArgument)) p.Arguments = this.Info.ProcessArgument;
if (!string.IsNullOrWhiteSpace(this.Info.ProcessWorkingDirectory)) p.WorkingDirectory = this.Info.ProcessWorkingDirectory;
if (this.Info.ProcessAsAdmin) p.Verb = "runas";
try
{
Process.Start(p);
}
catch
{
// do nothing
}
}
private void TilePanel_Click(object sender, EventArgs e)
{
// do nothing yet
}
}
}
+120
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>