Skip to content

Commit

Permalink
Implement move camera using mouse
Browse files Browse the repository at this point in the history
Add a camera setting that enables a camera that supports motion to be moved by holding down the Control key and dragging the mouse over the camera image. This feature was already part of the camera control (default turned off). These changes enable the user to enable/disable the feature as part of the camera settings.
  • Loading branch information
victor-david committed Mar 7, 2021
1 parent 637f6b4 commit ca99d81
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 27 deletions.
62 changes: 35 additions & 27 deletions src/Camera.App/Core/CameraControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,13 @@ public string CameraName

#region Plugin (general / motion)
private ICameraPlugin Plugin { get; set; }
private bool IsMouseCameraMotionAvailable;
/// <summary>
/// Holds a boolean that determines if moving the camera using the mouse is activated.
/// When this property is true (and camera supports motion), the user can pan and tilt the camera
/// by holding down the Control key and dragging the mouse over the camera image.
/// This property is initialized in the <see cref="InitializeIsMouseCameraMotion"/> method.
/// </summary>
private bool IsMouseCameraMotion;

/// <summary>
/// Gets a boolean value that indicates if we have a plugin
Expand Down Expand Up @@ -214,23 +220,6 @@ public ICommand MotionCommand
/// </summary>
public static readonly DependencyProperty MotionCommandProperty = MotionCommandPropertyKey.DependencyProperty;

/// <summary>
/// Gets or sets a boolean that determines if moving the camera using the mouse is activated
/// </summary>
public bool IsMouseCameraMotion
{
get => (bool)GetValue(IsMouseCameraMotionProperty);
set => SetValue(IsMouseCameraMotionProperty, value);
}

/// <summary>
/// Identifies the <see cref="IsMouseCameraMotion"/> dependency property.
/// </summary>
public static readonly DependencyProperty IsMouseCameraMotionProperty = DependencyProperty.Register
(
nameof(IsMouseCameraMotion), typeof(bool), typeof(CameraControl), new PropertyMetadata(false)
);

/// <summary>
/// Gets or sets the command to stop video
/// </summary>
Expand Down Expand Up @@ -809,7 +798,7 @@ public override void OnApplyTemplate()

statusControl.RenderTransform = BannerTranslate;

InitializeIsMouseCameraMotionAvailable();
InitializeIsMouseCameraMotion();
/*
* A camera can attempt to initialize before OnAppyTemplate(), which gets
* the error control from the template. If an error occurs during camera
Expand Down Expand Up @@ -929,7 +918,7 @@ private void ImageControlMouseLeftButtonDown(object sender, MouseButtonEventArgs
private void ImageControlMouseMove(object sender, MouseEventArgs e)
{
if (!isMouseDown) return;
if (isLeftControlKeyDown && !IsMouseCameraMotionAvailable) return;
if (isLeftControlKeyDown && !IsMouseCameraMotion) return;

Point point = e.GetPosition(imageControl);
double deltaX = point.X - mouseDownPoint.X;
Expand All @@ -939,7 +928,7 @@ private void ImageControlMouseMove(object sender, MouseEventArgs e)
{
PanImage(deltaX, deltaY);
}
else if (IsMouseCameraMotionAvailable && !isCameraMotionStarted)
else if (IsMouseCameraMotion && !isCameraMotionStarted)
{
MoveCamera(deltaX, deltaY);
}
Expand Down Expand Up @@ -1031,7 +1020,11 @@ private void CameraControlUnloaded(object sender, RoutedEventArgs e)

private void CameraControlKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl) isLeftControlKeyDown = true;
if (e.Key == Key.LeftCtrl)
{
isLeftControlKeyDown = true;
SetImageControlCursor(IsMouseCameraMotion ? Cursors.SizeAll : Cursors.No);
}
if (e.Key == Key.Escape)
{
ResetImageTransforms();
Expand All @@ -1041,7 +1034,19 @@ private void CameraControlKeyDown(object sender, KeyEventArgs e)

private void CameraControlKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl) isLeftControlKeyDown = false;
if (e.Key == Key.LeftCtrl)
{
isLeftControlKeyDown = false;
SetImageControlCursor(Cursors.Hand);
}
}

private void SetImageControlCursor(Cursor cursor)
{
if (imageControl != null)
{
imageControl.Cursor = cursor;
}
}
#endregion

Expand Down Expand Up @@ -1097,7 +1102,7 @@ private void InitializeCamera()

Plugin.VideoFrameReceived += PluginVideoFrameReceived;
Plugin.PluginException += PluginPluginException;
InitializeIsMouseCameraMotionAvailable();
InitializeIsMouseCameraMotion();
HavePlugin = true;
}
catch (Exception ex)
Expand All @@ -1106,10 +1111,13 @@ private void InitializeCamera()
}
}

private void InitializeIsMouseCameraMotionAvailable()
private void InitializeIsMouseCameraMotion()
{
IsMouseCameraMotionAvailable =
IsMouseCameraMotion && IsPluginMotion && imageControl != null;
IsMouseCameraMotion =
IsPluginMotion &&
imageControl != null &&
Camera != null &&
Camera.Flags.HasFlag(CameraFlags.MouseMotion);
}

private void StartStopVideo()
Expand Down
2 changes: 2 additions & 0 deletions src/Camera.App/View/CameraManageWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
xmlns:d="http:https://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http:https://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:core="clr-namespace:Restless.App.Camera.Core"
xmlns:camera="clr-namespace:Restless.App.Camera" d:DataContext="{d:DesignInstance Type=camera:CameraManageViewModel}"
mc:Ignorable="d"
Icon="{StaticResource ImageApp}"
Title="{Binding DisplayName}" Height="450" Width="800">
Expand Down Expand Up @@ -145,6 +146,7 @@
Value="{Binding MotionSpeed, Mode=TwoWay, Delay=500}"/>
<CheckBox Content="Translate X movement" IsChecked="{Binding TranslateX}"/>
<CheckBox Content="Translate Y movement" IsChecked="{Binding TranslateY}"/>
<CheckBox Content="Move camera with mouse" IsChecked="{Binding MouseMotion}"/>
</StackPanel>
</Border>

Expand Down
13 changes: 13 additions & 0 deletions src/Camera.App/ViewModel/CameraManageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,19 @@ public bool TranslateY
set => Camera.ToggleFlag(CameraFlags.TranslateY, value);
}

/// <summary>
/// Gets or sets a boolean value that determines if the camera can be moved using the mouse.
/// When this property is true (and the camera supports motion), the user can pan and tilt
/// the camera by holding down the Control key and dragging the mouse over the camera image.
/// If false, the user pans and tilts the camera using the arrow controls that appear at the
/// bottom of the camera image.
/// </summary>
public bool MouseMotion
{
get => Camera.Flags.HasFlag(CameraFlags.MouseMotion);
set => Camera.ToggleFlag(CameraFlags.MouseMotion, value);
}

/// <summary>
/// Gets or sets a boolean value that determines if the camers status banner is on the top.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions src/Restless.App.Database/Core/CameraFlags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,9 @@ public enum CameraFlags : long
/// Mirror the video image.
/// </summary>
Mirror = 512,
/// <summary>
/// Pan and tilt the camera by using the mouse.
/// </summary>
MouseMotion = 1024,
}
}

0 comments on commit ca99d81

Please sign in to comment.