Introduction
Most of the time I watch movies from my laptop. But I use my 22 inch LCD monitor, instead of laptop monitor. While I turn off the light the laptop monitor's light disturbs me. I could turn off the laptop monitor. But I need to turn it on if I want to do anything else in my laptop while watching movies. That experience is not good to me. So, I needed something which will reduce the opacity but at the mouse pointer I want a small region which should be transparent and I should be able to work with other application. So, I introduced the Night Vision mode at Media Assistant.
Using the code
To solve my problem at Media Assistant I used a full screen window having grid. I created a 3x3 grid and the center part represents the whole of my window. That means I need to move that with mouse movement.
Here is the XAML I used in the window:
<Window x:Class="MediaAssistant.Controls.NightVision.NightVisionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Converters="clr-namespace:MediaAssistant.Converters" Title="NightVisionWindow" WindowState="Maximized"
Background="Transparent" AllowsTransparency="True"
ResizeMode="NoResize"
WindowStyle="None"
ShowInTaskbar="False"
MouseMove="WindowMouseMove" Topmost="True"
KeyDown="KeyDownHandler"
>
<Window.Resources>
<Converters:NightOpacityToTextConverter x:Key="NightOpacityToTextConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding Y}"/>
<RowDefinition Height="{Binding WholeHeight}"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding X}"/>
<ColumnDefinition Width="{Binding WholeWidth}"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Grid.Row="0" Background="Black" Opacity="{Binding NightOpacity}"/>
<Border Grid.Column="0" Grid.Row="1" Background="Black" Opacity="{Binding NightOpacity}"/>
<Border Grid.Column="0" Grid.Row="2" Background="Black" Opacity="{Binding NightOpacity}"/>
<Border Grid.Column="1" Grid.Row="0" Background="Black" Opacity="{Binding NightOpacity}">
<TextBlock DockPanel.Dock="Top" Text="{Binding NightOpacity, Converter={StaticResource NightOpacityToTextConverter}}" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Bottom"/>
</Border>
<Border Grid.Column="1" Grid.Row="1" Background="Transparent" BorderThickness="2" BorderBrush="Black"/>
<Border Grid.Column="1" Grid.Row="2" Background="Black" Opacity="{Binding NightOpacity}"/>
<Border Grid.Column="2" Grid.Row="0" Background="Black" Opacity="{Binding NightOpacity}"/>
<Border Grid.Column="2" Grid.Row="1" Background="Black" Opacity="{Binding NightOpacity}"/>
<Border Grid.Column="2" Grid.Row="2" Background="Black" Opacity="{Binding NightOpacity}"/>
</Grid>
</Window>
I used the converter to display current opacity which can be controlled by the user. I bind the height and width with the property which I modify with mouse movement. So, the first row and column gets re-sized with mouse movement.
Here is the code to move the whole with mouse movement.
private void WindowMouseMove(object sender, MouseEventArgs e)
{
var position = e.GetPosition(this);
X = Math.Max(position.X - WholeWidth/2, 0);
Y = Math.Max(position.Y - WholeHeight/2, 0);
if(IsActive==false)
Activate();
}
I also controlled the opacity and exit behavior with keyboard interaction.
private void KeyDownHandler(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
{
Close();
}
else
{
const double delta = 0.05;
if(e.Key==Key.Left)
{
NightOpacity = Math.Max(0, NightOpacity - delta);
}
else if(e.Key==Key.Right)
{
NightOpacity = Math.Min(1, NightOpacity + delta);
}
}
}