diff --git a/NoFences/FenceWindow.Designer.cs b/NoFences/FenceWindow.Designer.cs index d48df18..144bd86 100644 --- a/NoFences/FenceWindow.Designer.cs +++ b/NoFences/FenceWindow.Designer.cs @@ -128,9 +128,11 @@ private void InitializeComponent() this.Paint += new System.Windows.Forms.PaintEventHandler(this.FenceWindow_Paint); this.DoubleClick += new System.EventHandler(this.FenceWindow_DoubleClick); this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.FenceWindow_MouseClick); + this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FenceWindow_Down); this.MouseEnter += new System.EventHandler(this.FenceWindow_MouseEnter); this.MouseLeave += new System.EventHandler(this.FenceWindow_MouseLeave); this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FenceWindow_MouseMove); + this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FenceWindow_Up); this.Resize += new System.EventHandler(this.FenceWindow_Resize); this.appContextMenu.ResumeLayout(false); this.ResumeLayout(false); diff --git a/NoFences/FenceWindow.cs b/NoFences/FenceWindow.cs index 56dcb6d..fdfe95a 100644 --- a/NoFences/FenceWindow.cs +++ b/NoFences/FenceWindow.cs @@ -20,6 +20,7 @@ public partial class FenceWindow : Form private const int textHeight = 35; private const int itemPadding = 15; private const float shadowDist = 1.5f; + private const int mouseClickMaxOffset = 10; private readonly FenceInfo fenceInfo; @@ -28,6 +29,7 @@ public partial class FenceWindow : Form private string selectedItem; private string hoveringItem; + private string draggedItem; private bool shouldUpdateSelection; private bool shouldRunDoubleClick; private bool hasSelectionUpdated; @@ -38,6 +40,8 @@ public partial class FenceWindow : Form private int scrollHeight; private int scrollOffset; + private Point mouseDragStartingPosition; + private readonly ThrottledExecution throttledMove = new ThrottledExecution(TimeSpan.FromSeconds(4)); private readonly ThrottledExecution throttledResize = new ThrottledExecution(TimeSpan.FromSeconds(4)); @@ -111,7 +115,7 @@ protected override void WndProc(ref Message m) // Prevent foreground if (m.Msg == WM_SETFOCUS) - { + { SetWindowPos(Handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); return; } @@ -204,7 +208,18 @@ private void FenceWindow_Resize(object sender, EventArgs e) private void FenceWindow_MouseMove(object sender, MouseEventArgs e) { - Refresh(); + if (!lockedToolStripMenuItem.Checked) + { + bool mouseIsDown = e.Button == MouseButtons.Left; + bool isDragging = mouseIsDown && Extensions.Distance(mouseDragStartingPosition, PointToClient(MousePosition)) > mouseClickMaxOffset; + if (isDragging && hoveringItem != null && draggedItem == null) + { + + draggedItem = hoveringItem; + } + } + + Refresh(); } private void FenceWindow_MouseEnter(object sender, EventArgs e) @@ -246,12 +261,46 @@ private void minifyToolStripMenuItem_Click(object sender, EventArgs e) } - private void FenceWindow_Click(object sender, EventArgs e) + private void FenceWindow_Down(object sender, MouseEventArgs e) { + if (!lockedToolStripMenuItem.Checked) + { + if (e.Button == MouseButtons.Left) + { + mouseDragStartingPosition = PointToClient(MousePosition); + } + } shouldUpdateSelection = true; Refresh(); } + private void FenceWindow_Up(object sender, MouseEventArgs e) + { + + if (e.Button == MouseButtons.Left) + { + if (!lockedToolStripMenuItem.Checked && hoveringItem != null && draggedItem != hoveringItem) + { + fenceInfo.Files.Remove(draggedItem); + int hoveringItemIndex = fenceInfo.Files.IndexOf(hoveringItem); + fenceInfo.Files.Insert(hoveringItemIndex, draggedItem); + } + + mouseDragStartingPosition = PointToClient(Point.Empty); + draggedItem = null; + } + Refresh(); + } + + private void FenceWindow_Click(object sender, EventArgs e) + { + double distanceFromMouseDown = Extensions.Distance(mouseDragStartingPosition, PointToClient(MousePosition)); + if (distanceFromMouseDown <= mouseClickMaxOffset) + { + shouldUpdateSelection = true; + Refresh(); + } + } private void FenceWindow_DoubleClick(object sender, EventArgs e) { shouldRunDoubleClick = true; @@ -340,6 +389,8 @@ private void RenderEntry(Graphics g, FenceEntry entry, int x, int y) var mousePos = PointToClient(MousePosition); var mouseOver = mousePos.X >= x && mousePos.Y >= y && mousePos.X < x + outlineRect.Width && mousePos.Y < y + outlineRect.Height; + var isBeingDragged = draggedItem == entry.Path; + if (mouseOver) { hoveringItem = entry.Path; @@ -359,22 +410,41 @@ private void RenderEntry(Graphics g, FenceEntry entry, int x, int y) entry.Open(); } - if (selectedItem == entry.Path) + if (draggedItem != null) { - if (mouseOver) + if (isBeingDragged) { - g.DrawRectangle(new Pen(Color.FromArgb(120, SystemColors.ActiveBorder)), outlineRectInner); - g.FillRectangle(new SolidBrush(Color.FromArgb(100, SystemColors.GradientActiveCaption)), outlineRect); + g.DrawRectangle(new Pen(Color.FromArgb(30, SystemColors.ActiveBorder)), outlineRectInner); + g.FillRectangle(new SolidBrush(Color.FromArgb(20, SystemColors.GradientActiveCaption)), outlineRect); } - else + else if (mouseOver) { - g.DrawRectangle(new Pen(Color.FromArgb(120, SystemColors.ActiveBorder)), outlineRectInner); - g.FillRectangle(new SolidBrush(Color.FromArgb(80, SystemColors.GradientInactiveCaption)), outlineRect); + int markerHeight = itemHeight / 2; + int markerX = x - itemPadding / 2; + int verticalCenter = y + 32; + g.DrawLine( + new Pen(Color.FromArgb(120, SystemColors.ActiveBorder), 1f), + new Point(markerX, verticalCenter - markerHeight / 2), + new Point(markerX, verticalCenter + markerHeight / 2) + ); } } - else + else { - if (mouseOver) + if (selectedItem == entry.Path) + { + if (mouseOver) + { + g.DrawRectangle(new Pen(Color.FromArgb(120, SystemColors.ActiveBorder)), outlineRectInner); + g.FillRectangle(new SolidBrush(Color.FromArgb(100, SystemColors.GradientActiveCaption)), outlineRect); + } + else + { + g.DrawRectangle(new Pen(Color.FromArgb(120, SystemColors.ActiveBorder)), outlineRectInner); + g.FillRectangle(new SolidBrush(Color.FromArgb(80, SystemColors.GradientInactiveCaption)), outlineRect); + } + } + else if (mouseOver) { g.DrawRectangle(new Pen(Color.FromArgb(120, SystemColors.ActiveBorder)), outlineRectInner); g.FillRectangle(new SolidBrush(Color.FromArgb(80, SystemColors.ActiveCaption)), outlineRect); @@ -382,8 +452,8 @@ private void RenderEntry(Graphics g, FenceEntry entry, int x, int y) } g.DrawIcon(icon, x + itemWidth / 2 - icon.Width / 2, y); - g.DrawString(name, iconFont, new SolidBrush(Color.FromArgb(180, 15, 15, 15)), new RectangleF(textPosition.Move(shadowDist, shadowDist), textMaxSize), stringFormat); - g.DrawString(name, iconFont, Brushes.White, new RectangleF(textPosition, textMaxSize), stringFormat); + g.DrawString(name, iconFont, new SolidBrush(Color.FromArgb(isBeingDragged ? 50 : 180, 15, 15, 15)), new RectangleF(textPosition.Move(shadowDist, shadowDist), textMaxSize), stringFormat); + g.DrawString(name, iconFont, new SolidBrush(Color.FromArgb(isBeingDragged ? 100 : 255, 255, 255, 255)), new RectangleF(textPosition, textMaxSize), stringFormat); } private void renameToolStripMenuItem_Click(object sender, EventArgs e) @@ -497,6 +567,5 @@ private bool ItemExists(string path) return File.Exists(path) || Directory.Exists(path); } } - } diff --git a/NoFences/Util/Extensions.cs b/NoFences/Util/Extensions.cs index 3d7d5fd..175f8fd 100644 --- a/NoFences/Util/Extensions.cs +++ b/NoFences/Util/Extensions.cs @@ -1,4 +1,5 @@ -using System.Drawing; +using System; +using System.Drawing; namespace NoFences.Util { @@ -16,5 +17,10 @@ public static Rectangle Shrink(this Rectangle rect, int offset) return new Rectangle(rect.X + offset, rect.Y + offset, rect.Width - offset * 2, rect.Height - offset * 2); } + public static double Distance(this Point p1, Point p2) + { + return Math.Round(Math.Sqrt(Math.Pow((p2.X - p1.X), 2) + Math.Pow((p2.Y - p1.Y), 2)), 1); + } + } }