257 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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)
 | |
|         {
 | |
|             Item item = items.Where(x => x.Tile.Equals(panel)).FirstOrDefault();
 | |
|             if (item == null)
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             Point newPosition = convertLocationToPosition(posX, posY);
 | |
|             if (!isTileInBounds(newPosition))
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             if (hasTile(newPosition))
 | |
|             {
 | |
|                 Item swapItem = items.Where(x => x.Coord.Equals(newPosition)).FirstOrDefault();
 | |
|                 if (swapItem != null)
 | |
|                 {
 | |
|                     swapItem.Coord = item.Coord;
 | |
|                     swapItem.Tile.Location = convertPositionToLocation(item.Coord);
 | |
|                 }
 | |
| 
 | |
|                 item.Coord = newPosition;
 | |
|                 panel.Location = convertPositionToLocation(newPosition);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 item.Coord = newPosition;
 | |
|                 panel.Location = convertPositionToLocation(newPosition);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         protected Point convertPositionToLocation(Point position) => new Point((position.X * this.TileSize), (position.Y * this.TileSize));
 | |
| 
 | |
|         protected Point convertLocationToPosition(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);
 | |
|         }
 | |
| 
 | |
|         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;
 | |
|         }
 | |
| 
 | |
|     }
 | |
| } | 
