This commit is contained in:
Paddy Xu
2017-08-06 17:27:30 +03:00
parent 3a20245304
commit 5b97e7ef60
17 changed files with 243 additions and 23 deletions

View File

@@ -21,6 +21,7 @@ using System.Windows.Media;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using LibAPNG; using LibAPNG;
using QuickLook.Helpers;
namespace QuickLook.Plugin.ImageViewer.AnimatedImage namespace QuickLook.Plugin.ImageViewer.AnimatedImage
{ {
@@ -99,7 +100,7 @@ namespace QuickLook.Plugin.ImageViewer.AnimatedImage
var bitmap = new RenderTargetBitmap( var bitmap = new RenderTargetBitmap(
header.Width, header.Height, header.Width, header.Height,
96, 96, DpiHelper.DefaultDpi, DpiHelper.DefaultDpi,
PixelFormats.Pbgra32); PixelFormats.Pbgra32);
bitmap.Render(visual); bitmap.Render(visual);
return bitmap; return bitmap;

View File

@@ -9,6 +9,12 @@
x:Name="imagePanel" x:Name="imagePanel"
d:DesignHeight="300" d:DesignWidth="300"> d:DesignHeight="300" d:DesignWidth="300">
<Grid> <Grid>
<Rectangle>
<Rectangle.Fill>
<ImageBrush x:Name="backgroundBrush" ImageSource="Resources/background.png" AlignmentY="Top" Viewport="0,0,32,32"
ViewportUnits="Absolute" Stretch="UniformToFill" TileMode="Tile" />
</Rectangle.Fill>
</Rectangle>
<ScrollViewer x:Name="viewPanel" BorderThickness="0" HorizontalScrollBarVisibility="Auto" <ScrollViewer x:Name="viewPanel" BorderThickness="0" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" Focusable="False" IsManipulationEnabled="True"> VerticalScrollBarVisibility="Auto" Focusable="False" IsManipulationEnabled="True">
<animatedImage:AnimatedImage x:Name="viewPanelImage" Stretch="None" <animatedImage:AnimatedImage x:Name="viewPanelImage" Stretch="None"

View File

@@ -28,6 +28,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Threading; using System.Windows.Threading;
using QuickLook.Annotations; using QuickLook.Annotations;
using QuickLook.Helpers;
namespace QuickLook.Plugin.ImageViewer namespace QuickLook.Plugin.ImageViewer
{ {
@@ -51,6 +52,11 @@ namespace QuickLook.Plugin.ImageViewer
{ {
InitializeComponent(); InitializeComponent();
var scale = DpiHelper.GetCurrentScaleFactor();
backgroundBrush.Viewport = new Rect(new Size(
backgroundBrush.ImageSource.Width / scale.Horizontal,
backgroundBrush.ImageSource.Height / scale.Vertical));
SizeChanged += ImagePanel_SizeChanged; SizeChanged += ImagePanel_SizeChanged;
viewPanel.PreviewMouseWheel += ViewPanel_PreviewMouseWheel; viewPanel.PreviewMouseWheel += ViewPanel_PreviewMouseWheel;

View File

@@ -112,6 +112,7 @@
<Content Include="dcraw.exe"> <Content Include="dcraw.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Resource Include="Resources\background.png" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -92,6 +92,7 @@ namespace QuickLook.Plugin.PDFViewer
{ {
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
if (_pdfControl != null)
_pdfControl.CurrentPageChanged -= UpdateVindowCaption; _pdfControl.CurrentPageChanged -= UpdateVindowCaption;
_pdfControl?.Dispose(); _pdfControl?.Dispose();
_pdfControl = null; _pdfControl = null;

View File

@@ -90,6 +90,7 @@ namespace QuickLook.Plugin.VideoViewer
public void Cleanup() public void Cleanup()
{ {
if (_vp != null)
_vp.mediaElement.VlcMediaPlayer.Opening -= MarkReady; _vp.mediaElement.VlcMediaPlayer.Opening -= MarkReady;
_vp?.Dispose(); _vp?.Dispose();
_vp = null; _vp = null;

View File

@@ -10,7 +10,7 @@
<Grid> <Grid>
<Rectangle Panel.ZIndex="100" Visibility="{Binding ElementName=glassLayer, Path=NoiseVisibility}"> <Rectangle Panel.ZIndex="100" Visibility="{Binding ElementName=glassLayer, Path=NoiseVisibility}">
<Rectangle.Fill> <Rectangle.Fill>
<ImageBrush ImageSource="100-50-5-monochrome.png" AlignmentY="Top" ViewportUnits="Absolute" <ImageBrush x:Name="noiseBrush" ImageSource="100-50-5-monochrome.png" AlignmentY="Top" ViewportUnits="Absolute"
Opacity="0.5" Opacity="0.5"
Viewport="0,0,100,100" TileMode="FlipY" Stretch="UniformToFill" /> Viewport="0,0,100,100" TileMode="FlipY" Stretch="UniformToFill" />
</Rectangle.Fill> </Rectangle.Fill>

View File

@@ -18,6 +18,7 @@
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
using QuickLook.Helpers;
namespace QuickLook.Controls.GlassLayer namespace QuickLook.Controls.GlassLayer
{ {
@@ -29,6 +30,11 @@ namespace QuickLook.Controls.GlassLayer
public GlassLayer() public GlassLayer()
{ {
InitializeComponent(); InitializeComponent();
var scale = DpiHelper.GetCurrentScaleFactor();
noiseBrush.Viewport = new Rect(new Size(
noiseBrush.ImageSource.Width / scale.Horizontal,
noiseBrush.ImageSource.Height / scale.Vertical));
} }
#region public Visual BlurredElement #region public Visual BlurredElement

View File

@@ -0,0 +1,55 @@
// 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.Windows;
using System.Windows.Interop;
using QuickLook.Helpers;
namespace QuickLook.Controls
{
public class MainWindowBase : Window
{
public MainWindowBase()
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
SourceInitialized += SourceInitializedHandler;
}
private void SourceInitializedHandler(object sender, EventArgs e)
{
var handle = new WindowInteropHelper(this).Handle;
var handleSource = HwndSource.FromHwnd(handle);
handleSource?.AddHook(WindowProc);
}
private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case 0x0024: /* WM_GETMINMAXINFO */
WindowHelper.WmGetMinMaxInfo(hwnd, lParam);
//handled = true;
break;
}
return (IntPtr) 0;
}
}
}

View File

@@ -0,0 +1,42 @@
// 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;
namespace QuickLook.Converters
{
public sealed class WindowStateToThicknessConverter : DependencyObject, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var def = parameter as Thickness? ?? new Thickness();
if (value == null)
return def;
return (WindowState) value == WindowState.Maximized ? new Thickness(0) : def;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -37,7 +37,7 @@ namespace QuickLook.ExtensionMethods
ImageLockMode.ReadOnly, source.PixelFormat); ImageLockMode.ReadOnly, source.PixelFormat);
bs = BitmapSource.Create(source.Width, source.Height, source.HorizontalResolution, bs = BitmapSource.Create(source.Width, source.Height, source.HorizontalResolution,
source.VerticalResolution, PixelFormats.Bgra32, null, source.VerticalResolution, ConvertPixelFormat(source.PixelFormat), null,
data.Scan0, data.Stride * source.Height, data.Stride); data.Scan0, data.Stride * source.Height, data.Stride);
source.UnlockBits(data); source.UnlockBits(data);
@@ -55,5 +55,22 @@ namespace QuickLook.ExtensionMethods
return bs; return bs;
} }
private static System.Windows.Media.PixelFormat ConvertPixelFormat(
System.Drawing.Imaging.PixelFormat sourceFormat)
{
switch (sourceFormat)
{
case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
return PixelFormats.Bgr24;
case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
return PixelFormats.Bgra32;
case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
return PixelFormats.Bgr32;
}
return new System.Windows.Media.PixelFormat();
}
} }
} }

View File

@@ -17,6 +17,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Interop; using System.Windows.Interop;
@@ -99,5 +100,53 @@ namespace QuickLook.Helpers
User32.GetWindowLong(window.Handle, User32.GWL_EXSTYLE) | User32.GetWindowLong(window.Handle, User32.GWL_EXSTYLE) |
User32.WS_EX_NOACTIVATE); User32.WS_EX_NOACTIVATE);
} }
internal static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
var mmi = (MinMaxInfo) Marshal.PtrToStructure(lParam, typeof(MinMaxInfo));
// Adjust the maximized size and position to fit the work area of the correct monitor
var currentScreen = Screen.FromHandle(hwnd);
var workArea = currentScreen.WorkingArea;
var monitorArea = currentScreen.Bounds;
mmi.ptMaxPosition.x = Math.Abs(workArea.Left - monitorArea.Left);
mmi.ptMaxPosition.y = Math.Abs(workArea.Top - monitorArea.Top);
mmi.ptMaxSize.x = Math.Abs(workArea.Right - workArea.Left);
mmi.ptMaxSize.y = Math.Abs(workArea.Bottom - workArea.Top);
Marshal.StructureToPtr(mmi, lParam, true);
}
[StructLayout(LayoutKind.Sequential)]
public struct MinMaxInfo
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
/// <summary>
/// x coordinate of point.
/// </summary>
public int x;
/// <summary>
/// y coordinate of point.
/// </summary>
public int y;
/// <summary>
/// Construct a point of coordinates (x,y).
/// </summary>
public POINT(int x, int y)
{
this.x = x;
this.y = y;
}
}
} }
} }

View File

@@ -1,4 +1,4 @@
<Window <controls:MainWindowBase
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -7,6 +7,7 @@
xmlns:busyDecorator="clr-namespace:QuickLook.Controls.BusyDecorator" xmlns:busyDecorator="clr-namespace:QuickLook.Controls.BusyDecorator"
xmlns:glassLayer="clr-namespace:QuickLook.Controls.GlassLayer" xmlns:glassLayer="clr-namespace:QuickLook.Controls.GlassLayer"
xmlns:converters="clr-namespace:QuickLook.Converters" xmlns:converters="clr-namespace:QuickLook.Converters"
xmlns:controls="clr-namespace:QuickLook.Controls"
mc:Ignorable="d" x:Class="QuickLook.MainWindowTransparent" x:Name="mainWindow" mc:Ignorable="d" x:Class="QuickLook.MainWindowTransparent" x:Name="mainWindow"
UseLayoutRounding="True" UseLayoutRounding="True"
d:DesignWidth="624" d:DesignHeight="700" d:DesignWidth="624" d:DesignHeight="700"
@@ -16,35 +17,50 @@
AllowsTransparency="True" AllowsTransparency="True"
Background="Transparent" Background="Transparent"
ShowActivated="False" ShowInTaskbar="False"> ShowActivated="False" ShowInTaskbar="False">
<Window.Resources> <controls:MainWindowBase.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/MainWindowStyles.xaml" /> <ResourceDictionary Source="Styles/MainWindowStyles.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<converters:BooleanToResizeModeConverter x:Key="BooleanToResizeModeConverter" /> <converters:BooleanToResizeModeConverter x:Key="BooleanToResizeModeConverter" />
<converters:WindowStateToThicknessConverter x:Key="WindowStateToThicknessConverter" />
<converters:BooleanToResizeBorderThicknessConverter x:Key="BooleanToResizeBorderThicknessConverter" /> <converters:BooleanToResizeBorderThicknessConverter x:Key="BooleanToResizeBorderThicknessConverter" />
<converters:BooleanToVisibilityCollapsedConverter x:Key="BooleanToVisibilityCollapsedConverter" /> <converters:BooleanToVisibilityCollapsedConverter x:Key="BooleanToVisibilityCollapsedConverter" />
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<converters:ScaledValueConverter x:Key="ScaledValueConverter" /> <converters:ScaledValueConverter x:Key="ScaledValueConverter" />
</ResourceDictionary> </ResourceDictionary>
</Window.Resources> </controls:MainWindowBase.Resources>
<WindowChrome.WindowChrome> <controls:MainWindowBase.Style>
<WindowChrome x:Name="chrome" <Style TargetType="controls:MainWindowBase">
CaptionHeight="0" <Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="0"
ResizeBorderThickness="{Binding ContextObject.CanResize, Converter={StaticResource BooleanToResizeBorderThicknessConverter}, ElementName=mainWindow}" ResizeBorderThickness="{Binding ContextObject.CanResize, Converter={StaticResource BooleanToResizeBorderThicknessConverter}, ElementName=mainWindow}"
UseAeroCaptionButtons="False" /> UseAeroCaptionButtons="False" />
</WindowChrome.WindowChrome> </Setter.Value>
<Window.ResizeMode> </Setter>
<Style.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</controls:MainWindowBase.Style>
<controls:MainWindowBase.ResizeMode>
<Binding ElementName="mainWindow" Path="ContextObject.CanResize" <Binding ElementName="mainWindow" Path="ContextObject.CanResize"
Converter="{StaticResource BooleanToResizeModeConverter}" /> Converter="{StaticResource BooleanToResizeModeConverter}" />
</Window.ResizeMode> </controls:MainWindowBase.ResizeMode>
<Border> <Border>
<Border.Effect> <Border.Effect>
<DropShadowEffect BlurRadius="{StaticResource MainWindowShadowBlurRadius}" ShadowDepth="0" Opacity="0.6" <DropShadowEffect BlurRadius="{StaticResource MainWindowShadowBlurRadius}" ShadowDepth="0" Opacity="0.6"
Color="Gray" /> Color="Gray" />
</Border.Effect> </Border.Effect>
<Grid Background="{StaticResource MainWindowBackground}" <Grid x:Name="windowFrameContainer" Background="{StaticResource MainWindowBackground}"
Margin="{StaticResource MainWindowShadowPaddingThinkness}"> Margin="{Binding WindowState, ElementName=mainWindow, Converter={StaticResource WindowStateToThicknessConverter}, ConverterParameter={StaticResource MainWindowShadowPaddingThinkness}}">
<Grid x:Name="viewerRootContainer" ZIndex="190"> <Grid x:Name="viewerRootContainer" ZIndex="190">
<Grid x:Name="windowCaptionContainer" Height="{StaticResource MainWindowCaptionHeight}" <Grid x:Name="windowCaptionContainer" Height="{StaticResource MainWindowCaptionHeight}"
VerticalAlignment="Top" VerticalAlignment="Top"
@@ -138,6 +154,18 @@
Visibility="{Binding ContextObject.TitlebarOverlap, ElementName=mainWindow, Converter={StaticResource BooleanToVisibilityCollapsedConverter}}" /> Visibility="{Binding ContextObject.TitlebarOverlap, ElementName=mainWindow, Converter={StaticResource BooleanToVisibilityCollapsedConverter}}" />
<ContentControl x:Name="container" <ContentControl x:Name="container"
Content="{Binding ContextObject.ViewerContent, ElementName=mainWindow}" /> Content="{Binding ContextObject.ViewerContent, ElementName=mainWindow}" />
<DockPanel.Style>
<Style TargetType="{x:Type DockPanel}">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger
Binding="{Binding ContextObject.IsBusy, ElementName=mainWindow}"
Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
</DockPanel> </DockPanel>
</Grid> </Grid>
<Grid x:Name="busyIndicatorLayer" Background="{StaticResource MainWindowBackground}" ZIndex="200"> <Grid x:Name="busyIndicatorLayer" Background="{StaticResource MainWindowBackground}" ZIndex="200">
@@ -160,4 +188,4 @@
</Grid> </Grid>
</Grid> </Grid>
</Border> </Border>
</Window> </controls:MainWindowBase>

View File

@@ -28,6 +28,7 @@ using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using QuickLook.Annotations; using QuickLook.Annotations;
using QuickLook.Controls;
using QuickLook.Helpers; using QuickLook.Helpers;
using QuickLook.Plugin; using QuickLook.Plugin;
@@ -36,7 +37,7 @@ namespace QuickLook
/// <summary> /// <summary>
/// Interaction logic for MainWindowTransparent.xaml /// Interaction logic for MainWindowTransparent.xaml
/// </summary> /// </summary>
public partial class MainWindowTransparent : Window, INotifyPropertyChanged public partial class MainWindowTransparent : MainWindowBase, INotifyPropertyChanged
{ {
private bool _pinned; private bool _pinned;
private bool _restoreForDragMove; private bool _restoreForDragMove;
@@ -116,6 +117,8 @@ namespace QuickLook
private void WindowDragMoving(object sender, MouseEventArgs e) private void WindowDragMoving(object sender, MouseEventArgs e)
{ {
if (e.LeftButton != MouseButtonState.Pressed)
return;
if (!_restoreForDragMove) if (!_restoreForDragMove)
return; return;
_restoreForDragMove = false; _restoreForDragMove = false;
@@ -281,9 +284,11 @@ namespace QuickLook
// revert UI changes // revert UI changes
ContextObject.IsBusy = true; ContextObject.IsBusy = true;
var newHeight = ContextObject.PreferredSize.Height + 10 + var margin = windowFrameContainer.Margin.Top * 2;
var newHeight = ContextObject.PreferredSize.Height + margin +
(ContextObject.TitlebarOverlap ? 0 : windowCaptionContainer.Height); (ContextObject.TitlebarOverlap ? 0 : windowCaptionContainer.Height);
var newWidth = ContextObject.PreferredSize.Width + 10; var newWidth = ContextObject.PreferredSize.Width + margin;
ResizeAndCenter(new Size(newWidth, newHeight)); ResizeAndCenter(new Size(newWidth, newHeight));

View File

@@ -115,6 +115,8 @@
<Compile Include="Controls\GlassLayer\GlassLayer.xaml.cs"> <Compile Include="Controls\GlassLayer\GlassLayer.xaml.cs">
<DependentUpon>GlassLayer.xaml</DependentUpon> <DependentUpon>GlassLayer.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Controls\MainWindowBase.cs" />
<Compile Include="Converters\WindowStateToThicknessConverter.cs" />
<Compile Include="Converters\BooleanToResizeModeConverter.cs" /> <Compile Include="Converters\BooleanToResizeModeConverter.cs" />
<Compile Include="Converters\BooleanToVisibilityCollapsedConverter.cs" /> <Compile Include="Converters\BooleanToVisibilityCollapsedConverter.cs" />
<Compile Include="Converters\BooleanToVisibilityConverter.cs" /> <Compile Include="Converters\BooleanToVisibilityConverter.cs" />

View File

@@ -2,8 +2,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib" xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:fa="http://schemas.fontawesome.io/icons/"> xmlns:fa="http://schemas.fontawesome.io/icons/">
<system:Double x:Key="MainWindowShadowBlurRadius">5</system:Double> <system:Double x:Key="MainWindowShadowBlurRadius">6</system:Double>
<Thickness x:Key="MainWindowShadowPaddingThinkness">5</Thickness> <Thickness x:Key="MainWindowShadowPaddingThinkness">6</Thickness>
<system:Double x:Key="MainWindowCaptionHeight">32</system:Double> <system:Double x:Key="MainWindowCaptionHeight">32</system:Double>
<SolidColorBrush x:Key="CaptionButtonIconForeground" Color="#E5868686" /> <SolidColorBrush x:Key="CaptionButtonIconForeground" Color="#E5868686" />
<SolidColorBrush x:Key="MainWindowBackground" Color="#FFF8F8FB" /> <SolidColorBrush x:Key="MainWindowBackground" Color="#FFF8F8FB" />