65.9K
CodeProject is changing. Read more.
Home

Night Vision

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (3 votes)

Feb 22, 2012

CPOL

1 min read

viewsIcon

20471

A Window with 80% opacity having a whole at mouse pointer

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);
          }
     }
}