using AppLauncher.Models; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace AppLauncher.Windows.Forms { public partial class TileLayoutContainer : AUserControl { protected TileGroupModel groupInfo = null; protected readonly int labelHeight = 20; protected readonly int collapseIncrement = 6; protected readonly int expandIncrement = 8; protected bool isAnimating = false; protected bool isChecked = true; public TileLayoutContainer(TileGroupModel model) : base() { InitializeComponent(); this.LoadModel(model); panel1.Resize += panel1_Resize; } protected override async void OnLoad(EventArgs e) { base.OnLoad(e); this.Margin = new Padding(0); this.Padding = new Padding(0, 0, 0, 10); //this.MaximumSize = new Size(panel1.Width, ExpandedHeight); //this.MinimumSize = new Size(panel1.Width, label1.Height); //this.Size = this.MaximumSize; this.Size = new Size(panel1.Width, this.ExpandedHeight); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; g.DrawImageUnscaled((isChecked ? Properties.Resources.toggle_right_ea_16 : Properties.Resources.toggle_left_ea_16), 2, 2); TextRenderer.DrawText(g, groupInfo?.Title, new Font(this.Font.FontFamily, 8.25F), new Point(25, 4), Color.FromArgb(99, 105, 119)); } private async void panel1_Resize(object sender, EventArgs e) => await this.InvalidateContainer(); public int CollapseHeight => labelHeight + panel1.CollapseHeight; public int ExpandedHeight => labelHeight + panel1.ExpandedHeight + this.Padding.Top + this.Padding.Bottom; public TileGroupModel Model { get { TileGroupModel rs = new TileGroupModel() { Title = groupInfo.Title, GridSize = new Size(panel1.GridSize.X, panel1.GridSize.Y), IsExpanded = isChecked, IsExclusive = groupInfo.IsExclusive, Items = panel1.Tiles }; return rs; } } public FlowLayoutPanel FlowLayoutPanel { get { if (this.Parent == null) { return null; } if (this.Parent.GetType() != typeof(FlowLayoutPanel)) { return null; } return this.Parent as FlowLayoutPanel; } } public async Task Collapse() { await Task.Run(() => { if (isAnimating) return; isAnimating = true; while (this.Height > this.CollapseHeight) { if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { this.Height -= collapseIncrement; })); } else { this.Height -= collapseIncrement; } Thread.Sleep(10); } isAnimating = false; }); } public async Task CollapseNow() { await Task.Run(() => { if (isAnimating) return; isAnimating = true; if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { this.Height = this.CollapseHeight; })); } else { this.Height = this.CollapseHeight; } isAnimating = false; }); } public async Task Expand() { await Task.Run(() => { if (isAnimating) return; isAnimating = true; while (this.Height < this.ExpandedHeight) { if (this.InvokeRequired) { this.Invoke(new MethodInvoker(() => { this.Height += expandIncrement; this.Invalidate(); })); } else { this.Height += expandIncrement; this.Invalidate(); } Thread.Sleep(10); } isAnimating = false; }); } public async Task InvalidateContainer(bool animate = true) { if (isAnimating) { return; } if (isChecked) { await this.Expand(); } else { if (animate) { await this.Collapse(); } else { await this.CollapseNow(); } } } public void AddGroup() { if (this.FlowLayoutPanel == null) { return; } this.FlowLayoutPanel.Controls.Add(new TileLayoutContainer(new TileGroupModel() { Title = "New Group", GridSize = new Size(8, 1) })); } public void AddRow() { panel1.SetGridSize(groupInfo.GridSize.Width, (groupInfo.GridSize.Height + 1)); } public void EditGroup() { EditGroupForm editForm = new EditGroupForm(this); editForm.ShowDialog(); } public void LoadModel(TileGroupModel model, bool loadTiles = true) { groupInfo = model; panel1.SetGridSize(groupInfo.GridSize.Width, groupInfo.GridSize.Height); this.Width = panel1.Width; isChecked = groupInfo.IsExpanded; if (loadTiles) { panel1.LoadTiles(model.Items); } this.Invalidate(); } public void MoveTop() { if (this.FlowLayoutPanel == null) { return; } this.FlowLayoutPanel.Controls.SetChildIndex(this, 0); } public void MoveUp() { if (this.FlowLayoutPanel == null) { return; } int pos = this.FlowLayoutPanel.Controls.GetChildIndex(this); if (pos <= 0) { return; } this.FlowLayoutPanel.Controls.SetChildIndex(this, (pos - 1)); } public void MoveDown() { if (this.FlowLayoutPanel == null) { return; } int pos = this.FlowLayoutPanel.Controls.GetChildIndex(this); if (pos >= (this.FlowLayoutPanel.Controls.Count - 1)) { return; } this.FlowLayoutPanel.Controls.SetChildIndex(this, (pos + 1)); } public void MoveBottom() { if (this.FlowLayoutPanel == null) { return; } this.FlowLayoutPanel.Controls.SetChildIndex(this, (this.FlowLayoutPanel.Controls.Count - 1)); } public void Remove() { if (this.FlowLayoutPanel == null) { return; } this.FlowLayoutPanel.Controls.Remove(this); } private void addTileMenuItem_Click(object sender, EventArgs e) => AddTileForm.ShowDialog(panel1); private void addListTileMenuItem_Click(object sender, EventArgs e) => AddListTileForm.ShowDialog(panel1); protected override async void OnMouseClick(MouseEventArgs e) { base.OnMouseClick(e); bool isLabel = ((e.Location.X >= 0) && (e.Location.X <= this.Width) && (e.Location.Y >= 0) && (e.Location.Y <= 20)); if (e.Button == MouseButtons.Left) { if (isLabel) { isChecked = !isChecked; this.Invalidate(); await this.InvalidateContainer(); } else { } } else if (e.Button == MouseButtons.Right) { if (isLabel) { contextMenuStrip2.Show(this, e.Location); } else { contextMenuStrip1.Show(this, e.Location); } } } protected override void OnMouseDoubleClick(MouseEventArgs e) => base.OnMouseClick(e); private void toolStripMenuItem2_Click(object sender, EventArgs e) => this.AddGroup(); private void toolStripMenuItem5_Click(object sender, EventArgs e) => this.AddRow(); private void toolStripMenuItem1_Click(object sender, EventArgs e) => this.EditGroup(); private void topToolStripMenuItem_Click(object sender, EventArgs e) => this.MoveTop(); private void upToolStripMenuItem_Click(object sender, EventArgs e) => this.MoveUp(); private void downToolStripMenuItem_Click(object sender, EventArgs e) => this.MoveDown(); private void bottomToolStripMenuItem_Click(object sender, EventArgs e) => this.MoveBottom(); private void toolStripMenuItem3_Click(object sender, EventArgs e) => this.Remove(); } }