finish auto-hide

This commit is contained in:
Paddy Xu
2017-08-06 21:01:02 +03:00
parent 5b97e7ef60
commit 56cb31fd2a
16 changed files with 241 additions and 71 deletions

View File

@@ -9,7 +9,7 @@
x:Name="imagePanel"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Rectangle>
<Rectangle Visibility="{Binding BackgroundVisibility, ElementName=imagePanel}">
<Rectangle.Fill>
<ImageBrush x:Name="backgroundBrush" ImageSource="Resources/background.png" AlignmentY="Top" Viewport="0,0,32,32"
ViewportUnits="Absolute" Stretch="UniformToFill" TileMode="Tile" />

View File

@@ -45,6 +45,7 @@ namespace QuickLook.Plugin.ImageViewer
private BitmapScalingMode _renderMode = BitmapScalingMode.HighQuality;
private BitmapSource _source;
private double _zoomFactor = 1d;
private Visibility _backgroundVisibility = Visibility.Visible;
private bool _zoomToFit = true;
@@ -88,6 +89,16 @@ namespace QuickLook.Plugin.ImageViewer
}
}
public Visibility BackgroundVisibility
{
get => _backgroundVisibility;
set
{
_backgroundVisibility = value;
OnPropertyChanged();
}
}
public double MinZoomFactor
{
get => _minZoomFactor;

View File

@@ -65,7 +65,6 @@ namespace QuickLook.Plugin.ImageViewer
Directory.SetCurrentDirectory(App.AppPath);
context.AutoHideTitlebar = true;
context.TitlebarOverlap = true;
}

View File

@@ -70,7 +70,7 @@
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Column="1" Background="#00EFEFEF">
<imageViewer:ImagePanel x:Name="pagePanel" RenderMode="NearestNeighbor" />
<imageViewer:ImagePanel x:Name="pagePanel" RenderMode="NearestNeighbor" BackgroundVisibility="Collapsed" />
</Grid>
</Grid>
</UserControl>

View File

@@ -64,7 +64,7 @@ namespace QuickLook.Plugin.TextViewer
public void View(string path, ContextObject context)
{
_tvp = new TextViewerPanel(path);
_tvp = new TextViewerPanel(path, context);
context.ViewerContent = _tvp;
context.Title = $"{Path.GetFileName(path)}";

View File

@@ -21,7 +21,6 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Highlighting;
using QuickLook.Helpers;
using UtfUnknown;
namespace QuickLook.Plugin.TextViewer
@@ -31,7 +30,7 @@ namespace QuickLook.Plugin.TextViewer
/// </summary>
public partial class TextViewerPanel : UserControl
{
public TextViewerPanel(string path)
public TextViewerPanel(string path, ContextObject context)
{
InitializeComponent();
@@ -42,7 +41,7 @@ namespace QuickLook.Plugin.TextViewer
viewer.PreviewMouseWheel += Viewer_MouseWheel;
viewer.FontFamily =
new FontFamily(TranslationHelper.GetString("Editor_FontFamily"));
new FontFamily(context.GetString("Editor_FontFamily"));
LoadFile(path);
}

View File

@@ -266,7 +266,7 @@ namespace QuickLook.Plugin.VideoViewer
[DebuggerNonUserCode]
private void ShowErrorNotification(object sender, EventArgs e)
{
TrayIconManager.GetInstance().ShowNotification("", "An error occurred while loading the video.");
_context.ShowNotification("", "An error occurred while loading the video.");
mediaElement?.Stop();
Dispose();

View File

@@ -0,0 +1,103 @@
// Copyright © 2017 Paddy Xu
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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 System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Markup;
namespace QuickLook.Actions
{
[ContentProperty("Actions")]
public class ConditionalEventTrigger : FrameworkContentElement
{
public static readonly DependencyProperty ConditionProperty =
DependencyProperty.Register("Condition", typeof(bool), typeof(ConditionalEventTrigger));
public static readonly DependencyProperty TriggersProperty = DependencyProperty.RegisterAttached("Triggers",
typeof(ConditionalEventTriggerCollection), typeof(ConditionalEventTrigger), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
// When "Triggers" is set, register handlers for each trigger in the list
var element = (FrameworkElement) obj;
var triggers = (List<ConditionalEventTrigger>) e.NewValue;
foreach (var trigger in triggers)
element.AddHandler(trigger.RoutedEvent, new RoutedEventHandler((obj2, e2) =>
trigger.OnRoutedEvent(element)));
}
});
private static readonly RoutedEvent TriggerActionsEvent = EventManager.RegisterRoutedEvent("",
RoutingStrategy.Direct,
typeof(EventHandler), typeof(ConditionalEventTrigger));
public ConditionalEventTrigger()
{
Actions = new List<TriggerAction>();
}
public RoutedEvent RoutedEvent { get; set; }
public List<TriggerAction> Actions { get; set; }
// Condition
public bool Condition
{
get => (bool) GetValue(ConditionProperty);
set => SetValue(ConditionProperty, value);
}
// "Triggers" attached property
public static ConditionalEventTriggerCollection GetTriggers(DependencyObject obj)
{
return (ConditionalEventTriggerCollection) obj.GetValue(TriggersProperty);
}
public static void SetTriggers(DependencyObject obj, ConditionalEventTriggerCollection value)
{
obj.SetValue(TriggersProperty, value);
}
// When an event fires, check the condition and if it is true fire the actions
private void OnRoutedEvent(FrameworkElement element)
{
DataContext = element.DataContext; // Allow data binding to access element properties
if (Condition)
{
// Construct an EventTrigger containing the actions, then trigger it
var dummyTrigger = new EventTrigger {RoutedEvent = TriggerActionsEvent};
foreach (var action in Actions)
dummyTrigger.Actions.Add(action);
element.Triggers.Add(dummyTrigger);
try
{
element.RaiseEvent(new RoutedEventArgs(TriggerActionsEvent));
}
finally
{
element.Triggers.Remove(dummyTrigger);
}
}
}
}
// Create collection type visible to XAML - since it is attached we cannot construct it in code
public class ConditionalEventTriggerCollection : List<ConditionalEventTrigger>
{
}
}

View File

@@ -0,0 +1,45 @@
// Copyright © 2017 Paddy Xu
//
// This file is part of QuickLook program.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// 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 System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media.Animation;
namespace QuickLook.Converters
{
public sealed class BooleanToKeyTimeConverter : DependencyObject, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return KeyTime.FromTimeSpan(TimeSpan.MaxValue);
var v = (bool) value;
return v
? KeyTime.FromTimeSpan(parameter as TimeSpan? ?? TimeSpan.MaxValue)
: KeyTime.FromTimeSpan(TimeSpan.MaxValue);
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -24,7 +24,7 @@ using System.Xml.XPath;
namespace QuickLook.Helpers
{
public class TranslationHelper
internal class TranslationHelper
{
private static readonly CultureInfo CurrentCultureInfo = CultureInfo.CurrentUICulture;
//private static readonly CultureInfo CurrentCultureInfo = CultureInfo.GetCultureInfo("zh-CN");

View File

@@ -8,6 +8,7 @@
xmlns:glassLayer="clr-namespace:QuickLook.Controls.GlassLayer"
xmlns:converters="clr-namespace:QuickLook.Converters"
xmlns:controls="clr-namespace:QuickLook.Controls"
xmlns:actions="clr-namespace:QuickLook.Actions"
mc:Ignorable="d" x:Class="QuickLook.MainWindowTransparent" x:Name="mainWindow"
UseLayoutRounding="True"
d:DesignWidth="624" d:DesignHeight="700"
@@ -23,6 +24,7 @@
<ResourceDictionary Source="Styles/MainWindowStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<converters:BooleanToResizeModeConverter x:Key="BooleanToResizeModeConverter" />
<converters:BooleanToKeyTimeConverter x:Key="BooleanToKeyTimeConverter" />
<converters:WindowStateToThicknessConverter x:Key="WindowStateToThicknessConverter" />
<converters:BooleanToResizeBorderThicknessConverter x:Key="BooleanToResizeBorderThicknessConverter" />
<converters:BooleanToVisibilityCollapsedConverter x:Key="BooleanToVisibilityCollapsedConverter" />
@@ -35,8 +37,8 @@
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="0"
ResizeBorderThickness="{Binding ContextObject.CanResize, Converter={StaticResource BooleanToResizeBorderThicknessConverter}, ElementName=mainWindow}"
UseAeroCaptionButtons="False" />
ResizeBorderThickness="{Binding ContextObject.CanResize, Converter={StaticResource BooleanToResizeBorderThicknessConverter}, ElementName=mainWindow}"
UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
<Style.Triggers>
@@ -61,45 +63,29 @@
</Border.Effect>
<Grid x:Name="windowFrameContainer" Background="{StaticResource MainWindowBackground}"
Margin="{Binding WindowState, ElementName=mainWindow, Converter={StaticResource WindowStateToThicknessConverter}, ConverterParameter={StaticResource MainWindowShadowPaddingThinkness}}">
<Grid.Resources>
<Storyboard x:Key="ShowCaptionStoryboard">
<DoubleAnimation
Storyboard.Target="{Binding Source={x:Reference windowCaptionContainer}}"
Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.05">
</DoubleAnimation>
</Storyboard>
<Storyboard x:Key="ShowAndHideTitlebarStoryboard">
<DoubleAnimationUsingKeyFrames
Storyboard.Target="{Binding Source={x:Reference windowCaptionContainer}}"
Storyboard.TargetProperty="Opacity">
<DoubleAnimationUsingKeyFrames.KeyFrames>
<LinearDoubleKeyFrame Value="1" KeyTime="0:0:0.05" />
<LinearDoubleKeyFrame Value="1" KeyTime="0:0:3" />
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:3.05" />
</DoubleAnimationUsingKeyFrames.KeyFrames>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>
<Grid x:Name="viewerRootContainer" ZIndex="190">
<Grid x:Name="windowCaptionContainer" Height="{StaticResource MainWindowCaptionHeight}"
VerticalAlignment="Top"
ZIndex="100">
<Grid.Resources>
<Storyboard x:Key="HideTitlebarStoryboard">
<DoubleAnimation
Storyboard.Target="{Binding Source={x:Reference windowCaptionContainer}}"
Storyboard.TargetProperty="Opacity" To="0" BeginTime="0:0:3"
Duration="0:0:0.05" />
</Storyboard>
<Storyboard x:Key="ShowTitlebarStoryboard">
<DoubleAnimation
Storyboard.Target="{Binding Source={x:Reference windowCaptionContainer}}"
Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.05" />
</Storyboard>
</Grid.Resources>
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition
Binding="{Binding IsMouseOver, ElementName=windowCaptionContainer}"
Value="False" />
<Condition
Binding="{Binding ContextObject.AutoHideTitlebar, ElementName=mainWindow}"
Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HideTitlebarStoryboard}" />
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource ShowTitlebarStoryboard}" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<glassLayer:GlassLayer BlurredElement="{Binding ElementName=containerPanel}" />
<DockPanel>
<Button x:Name="buttonCloseWindow" Style="{StaticResource CaptionCloseButtonStyle}"

View File

@@ -26,6 +26,7 @@ using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using QuickLook.Annotations;
using QuickLook.Controls;
@@ -55,6 +56,8 @@ namespace QuickLook
windowCaptionContainer.MouseMove += WindowDragMoving;
windowCaptionContainer.MouseLeftButtonUp += WindowDragMoveEnd;
windowFrameContainer.PreviewMouseMove += ShowWindowCaptionContainer;
buttonPin.Click += (sender, e) =>
{
if (Pinned)
@@ -93,6 +96,20 @@ namespace QuickLook
(sender, e) => RunWith("rundll32.exe", $"shell32.dll,OpenAs_RunDLL {Path}");
}
private void ShowWindowCaptionContainer(object sender, MouseEventArgs e)
{
if (!ContextObject.TitlebarOverlap)
return;
var show = (Storyboard) windowFrameContainer.FindResource("ShowCaptionStoryboard");
var showAndHide = (Storyboard) windowFrameContainer.FindResource("ShowAndHideTitlebarStoryboard");
if (windowCaptionContainer.IsMouseOver)
show.Begin();
else
showAndHide.Begin();
}
public bool Pinned
{
get => _pinned;
@@ -375,6 +392,16 @@ namespace QuickLook
ProcessHelper.PerformAggressiveGC();
}
public void ShowTitlebar()
{
}
public void HideTitlebar()
{
var sb = FindResource("HideTitlebarStoryboard") as Storyboard;
sb?.Begin();
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{

View File

@@ -17,6 +17,8 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
using QuickLook.Annotations;
@@ -125,20 +127,27 @@ namespace QuickLook.Plugin
}
}
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Set whether the title bar of viewer window should be auto-hidden.
/// Get a string from translation Xml document.
/// </summary>
public bool AutoHideTitlebar
[MethodImpl(MethodImplOptions.NoInlining)]
public string GetString(string id, string file = null, CultureInfo locale = null, string failsafe = null)
{
get => _autoHideTitlebar;
set
{
_autoHideTitlebar = value;
OnPropertyChanged();
}
return TranslationHelper.GetString(id, file, locale, failsafe, Assembly.GetCallingAssembly());
}
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Show a notification balloon.
/// </summary>
/// <param name="title">Title of the notification.</param>
/// <param name="content">The content.</param>
/// <param name="isError">Is this indicates a error?</param>
public void ShowNotification(string title, string content, bool isError = false)
{
TrayIconManager.GetInstance().ShowNotification(title, content, isError);
}
/// <summary>
/// Set the size of viewer window and shrink to fit (to screen resolution).
@@ -173,7 +182,6 @@ namespace QuickLook.Plugin
PreferredSize = new Size();
CanResize = true;
FullWindowDragging = false;
AutoHideTitlebar = false;
TitlebarOverlap = false;
}

View File

@@ -111,11 +111,13 @@
<Compile Include="..\GitVersion.cs">
<Link>Properties\GitVersion.cs</Link>
</Compile>
<Compile Include="Actions\ConditionalEventTrigger.cs" />
<Compile Include="Controls\GlassLayer\GaussianBlurEffect.cs" />
<Compile Include="Controls\GlassLayer\GlassLayer.xaml.cs">
<DependentUpon>GlassLayer.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\MainWindowBase.cs" />
<Compile Include="Converters\BooleanToKeyTimeConverter.cs" />
<Compile Include="Converters\WindowStateToThicknessConverter.cs" />
<Compile Include="Converters\BooleanToResizeModeConverter.cs" />
<Compile Include="Converters\BooleanToVisibilityCollapsedConverter.cs" />

View File

@@ -10,16 +10,6 @@
<SolidColorBrush x:Key="NormalBorderBrush" Color="#888" />
<SolidColorBrush x:Key="HorizontalNormalBrush" Color="#888" />
<SolidColorBrush x:Key="HorizontalNormalBorderBrush" Color="#888" />
<LinearGradientBrush x:Key="ListBoxBackgroundBrush"
StartPoint="0,0" EndPoint="1,0.001">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="White" Offset="0.0" />
<GradientStop Color="White" Offset="0.6" />
<GradientStop Color="#DDDDDD" Offset="1.2" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="StandardBrush"
StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
@@ -108,7 +98,7 @@
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.RowSpan="3" CornerRadius="2" Background="Transparent" />
<Border Grid.RowSpan="3" CornerRadius="2" Background="#F0F0F0" />
<Track x:Name="PART_Track" Grid.Row="0" IsDirectionReversed="true">
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource ScrollBarPageButton}" Command="ScrollBar.PageUpCommand" />
@@ -171,7 +161,7 @@
Value="{StaticResource HorizontalScrollBar}" />
</Trigger>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Width" Value="15" />
<Setter Property="Width" Value="13" />
<Setter Property="Height" Value="Auto" />
<Setter Property="Template"
Value="{StaticResource VerticalScrollBar}" />

View File

@@ -22,7 +22,7 @@ using QuickLook.Properties;
namespace QuickLook
{
public class TrayIconManager : IDisposable
internal class TrayIconManager : IDisposable
{
private static TrayIconManager _instance;