Skip to content

Commit

Permalink
MovableForm: show mover control for frameless dragging
Browse files Browse the repository at this point in the history
  • Loading branch information
d2phap committed Jun 23, 2024
1 parent b11e4e4 commit ffa7fd1
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

using ImageGlass.Base;
using ImageGlass.Base.WinApi;
using Windows.Win32;
using Windows.Win32.Foundation;

namespace ImageGlass.Base.WinApi;
namespace ImageGlass.UI;


/// <summary>
Expand All @@ -31,8 +33,10 @@ public class MovableForm
private const int WM_NCLBUTTONDOWN = 0xA1;
private const int HT_CAPTION = 0x2;

private readonly Form _form;
private readonly ModernForm _form;
private bool _isKeyDown = true;
private Control? _moverControl = null;
private bool _isMoverControlDarkMode = true;


#region Public props
Expand All @@ -42,6 +46,11 @@ public class MovableForm
/// </summary>
public bool EnableFreeMoving { get; set; } = true;

/// <summary>
/// Sets visibility of mover control.
/// </summary>
public bool ShowMover { get; set; } = false;

/// <summary>
/// Gets, sets the mouse button press for moving
/// </summary>
Expand All @@ -64,56 +73,43 @@ public class MovableForm
/// Initialize the MovableForm
/// </summary>
/// <param name="form">The form to make it movable</param>
public MovableForm(Form form) => _form = form;
public MovableForm(ModernForm form) => _form = form;


#region Public methods

/// <summary>
/// Enable moving ability on this form
/// Enable moving ability on the given controls
/// </summary>
public void Enable()
/// <param name="controls"></param>
public void Enable(params Control[] controls)
{
_isKeyDown = Key == Keys.None;

_form.KeyDown += Form_KeyDown;
_form.KeyUp += Form_KeyUp;
_form.MouseDown += Event_MouseDown;
}

/// <summary>
/// Enable moving ability on the given controls
/// </summary>
/// <param name="controls"></param>
public void Enable(params Control[] controls)
{
_isKeyDown = Key == Keys.None;

foreach (var item in controls)
foreach (var ctr in controls)
{
item.MouseDown += Event_MouseDown;
ctr.MouseDown += Event_MouseDown;
}
}

/// <summary>
/// Disable moving ability on this form
/// Disable moving ability on the given controls
/// </summary>
public void Disable()
/// <param name="controls"></param>
public void Disable(params Control[] controls)
{
_form.KeyDown -= Form_KeyDown;
_form.KeyUp -= Form_KeyUp;
_form.MouseDown -= Event_MouseDown;
}

/// <summary>
/// Disable moving ability on the given controls
/// </summary>
/// <param name="controls"></param>
public void Disable(params Control[] controls)
{
foreach (var item in controls)
foreach (var ctr in controls)
{
item.MouseDown -= Event_MouseDown;
ctr.MouseDown -= Event_MouseDown;
}
}

Expand All @@ -132,19 +128,28 @@ private void Form_KeyDown(object? sender, KeyEventArgs e)
{
_isKeyDown = e.KeyData == Key;
}

if (_isKeyDown && ShowMover)
{
SetMoverControlVisibility(true);
}
}


private void Form_KeyUp(object? sender, KeyEventArgs e)
{
_isKeyDown = Key == Keys.None;
SetMoverControlVisibility(false);
}


private void Event_MouseDown(object? sender, MouseEventArgs e)
{
// check if 'sender' can move without keydown event
var control = (Control?)sender;
var isFreeMove = FreeMoveControlNames.Count > 0
&& FreeMoveControlNames.Contains(control.Name);
var isFreeMove = control.Name == _moverControl?.Name
|| (FreeMoveControlNames.Count > 0
&& FreeMoveControlNames.Contains(control.Name));

if (e.Clicks == 1
&& e.Button == MouseButton
Expand All @@ -156,6 +161,52 @@ private void Event_MouseDown(object? sender, MouseEventArgs e)
}
}


private void SetMoverControlVisibility(bool visible)
{
if (_moverControl != null)
{
_form.Controls.Remove(_moverControl);
_moverControl.MouseDown -= Event_MouseDown;
}


if (visible)
{
_moverControl ??= new Panel()
{
Name = "PanMoverControl",
Width = DpiApi.Scale(100),
Height = DpiApi.Scale(100),
ForeColor = Color.White,
BackgroundImageLayout = ImageLayout.Center,
Cursor = Cursors.SizeAll,
};

// set movable icon
if (_moverControl.BackgroundImage == null || _isMoverControlDarkMode != _form.DarkMode)
{
_isMoverControlDarkMode = _form.DarkMode;

var iconSize = DpiApi.Scale(50);
var svgPath = IconFile.GetFullPath(IconName.ArrowMove);
_moverControl.BackgroundImage?.Dispose();
_moverControl.BackgroundImage = BHelper.ToGdiPlusBitmapFromSvg(svgPath, _form.DarkMode, iconSize, iconSize);
}

// set center position
_moverControl.Left = _form.Width / 2 - _moverControl.Width / 2;
_moverControl.Top = _form.Height / 2 - _moverControl.Height / 2 - SystemInformation.CaptionHeight;

// set mouse event
_moverControl.MouseDown += Event_MouseDown;

_form.Controls.Add(_moverControl);
_moverControl.BringToFront();
}
}


#endregion // Events: Free form moving


Expand Down
2 changes: 2 additions & 0 deletions Source/Components/ImageGlass.UI/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
DwmIsCompositionEnabled
DwmSetWindowAttribute
DwmExtendFrameIntoClientArea
ReleaseCapture
SendMessage
1 change: 1 addition & 0 deletions Source/Components/ImageGlass.UI/Themes/IconFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@ public enum IconName
ArrowDown,
ArrowLeft,
ArrowRight,
ArrowMove,
ArrowExchange,
}
13 changes: 9 additions & 4 deletions Source/ImageGlass/FrmMain/FrmMain.IGMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2418,6 +2418,13 @@ public bool IG_ToggleFrameless(bool? enable = null, bool showInAppMessage = true
WindowApi.SetRoundCorner(Handle);
}

// enable mover control
if (_movableForm != null)
{
_movableForm.ShowMover = Config.EnableFrameless;
}


// update toolbar items state
UpdateToolbarItemsState();

Expand Down Expand Up @@ -2775,13 +2782,11 @@ public void IG_SetWindowMoveable(bool? enable = null)

if (enable.Value)
{
_movableForm.Enable();
_movableForm.Enable(Toolbar, ToolbarContext, PicMain);
_movableForm.Enable(Toolbar, ToolbarContext);
}
else
{
_movableForm.Disable();
_movableForm.Disable(Toolbar, ToolbarContext, PicMain);
_movableForm.Disable(Toolbar, ToolbarContext);
}
}

Expand Down
8 changes: 8 additions & 0 deletions Source/ImageGlass/Icons/ArrowMove.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Source/ImageGlass/ImageGlass.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
<Content Include="License\WicNet.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Update="Icons\ArrowMove.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="License\ZString.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
8 changes: 6 additions & 2 deletions Source/igcmd/Tools/FrmSlideshow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,12 @@ private bool IG_ToggleFrameless(bool? enable = null, bool showInAppMessage = tru
// update menu item state
MnuFrameless.Checked = Config.EnableFrameless;

// enable mover control
if (_movableForm != null)
{
_movableForm.ShowMover = Config.EnableFrameless;
}

if (showInAppMessage)
{
var langPath = $"FrmMain.{nameof(MnuFrameless)}";
Expand Down Expand Up @@ -1803,12 +1809,10 @@ public void IG_SetWindowMoveable(bool? enable = null)
if (enable.Value)
{
_movableForm.Enable();
_movableForm.Enable(PicMain);
}
else
{
_movableForm.Disable();
_movableForm.Disable(PicMain);
}

}
Expand Down

0 comments on commit ffa7fd1

Please sign in to comment.