Skip to content

Commit 1b93eb2

Browse files
author
Carl Chang
committed
numerous changes;
1 parent 58bc03f commit 1b93eb2

19 files changed

+768
-226
lines changed

App.xaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
<Application.Resources>
88
<ResourceDictionary>
99
<ResourceDictionary.MergedDictionaries>
10+
<ResourceDictionary>
11+
<SolidColorBrush x:Key="BackgroundBrush" Color="#FF333333"/>
12+
<SolidColorBrush x:Key="BackgroundDarkBrush" Color="#FF1F1F1F"/>
13+
<SolidColorBrush x:Key="BackgroundLightBrush" Color="#FF444444"/>
14+
<SolidColorBrush x:Key="BackgroundHighlightBrush" Color="#FF6E6E6E"/>
15+
<SolidColorBrush x:Key="ForegroundBrush" Color="LightGray"/>
16+
<SolidColorBrush x:Key="ForegroundGrayBrush" Color="#FFA6A6A6"/>
17+
</ResourceDictionary>
1018
<ResourceDictionary Source="UserControls/AppleStyleScrollBar.xaml"/>
1119
<ResourceDictionary Source="UserControls/StylesAndAnimations.xaml"/>
1220
<ResourceDictionary Source="UserControls/Generic.xaml"/>

App.xaml.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ public partial class App : Application
2929
//public const int PreviewCount = 4;
3030
public static Random Random = new Random();
3131

32-
internal static ImageSource fa_meh;
33-
internal static ImageSource fa_spinner;
34-
internal static ImageSource fa_exclamation;
35-
internal static ImageSource fa_file;
36-
internal static ImageSource fa_folder;
37-
internal static ImageSource fa_archive;
38-
internal static ImageSource fa_image;
32+
public static ImageSource fa_meh { get; private set; }
33+
public static ImageSource fa_spinner { get; private set; }
34+
public static ImageSource fa_exclamation { get; private set; }
35+
public static ImageSource fa_file { get; private set; }
36+
public static ImageSource fa_folder { get; private set; }
37+
public static ImageSource fa_archive { get; private set; }
38+
public static ImageSource fa_image { get; private set; }
3939

4040

4141
public static CubicEase CE_EaseIn => (CubicEase)Current.FindResource("CE_EaseIn");
@@ -67,15 +67,17 @@ private void App_Startup(object sender, StartupEventArgs e) {
6767
CheckThumbsDB();
6868

6969
#if DEBUG
70-
Execute(Table.Thumbs, (table, con) => {
71-
using (var cmd = new SQLiteCommand(con)) {
72-
cmd.CommandText = $@"delete from {table.Name}";
73-
cmd.ExecuteNonQuery();
74-
cmd.CommandText = @"vacuum";
75-
cmd.ExecuteNonQuery();
76-
}
77-
return 0;
78-
});
70+
if (e.Args?.Length > 0 && e.Args[0] == "-cleandb") {
71+
Execute(Table.Thumbs, (table, con) => {
72+
using (var cmd = new SQLiteCommand(con)) {
73+
cmd.CommandText = $@"delete from {table.Name}";
74+
cmd.ExecuteNonQuery();
75+
cmd.CommandText = @"vacuum";
76+
cmd.ExecuteNonQuery();
77+
}
78+
return 0;
79+
});
80+
}
7981
#endif
8082

8183
//handle immersion mode change

ContextMenuWindow.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
xmlns:fa="http://schemas.fontawesome.com/icons/"
77
xmlns:local="clr-namespace:ZipImageViewer" CloseBehavior="FadeOutAndHide" ButtonCloseVisible="False" ShowInTaskbar="False"
88
mc:Ignorable="d" ResizeMode="NoResize" SizeToContent="WidthAndHeight"
9-
Background="#FF444444" Foreground="LightGray">
9+
Background="{StaticResource BackgroundBrush}" Foreground="{StaticResource ForegroundBrush}">
1010
<Window.Resources>
1111
<Style TargetType="fa:ImageAwesome">
1212
<Setter Property="Width" Value="24"/>
1313
<Setter Property="Height" Value="24"/>
14-
<Setter Property="Foreground" Value="LightGray"/>
14+
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}"/>
1515
</Style>
1616
</Window.Resources>
1717
<local:PaddedGrid Padding="2">

ContextMenuWindow.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private void Menu_PreviewMouseUp(object sender, MouseButtonEventArgs e) {
6161
}
6262
break;
6363
case nameof(B_Slideshow):
64-
var sldWin = new SlideshowWindow(mainWin, ObjectInfo);
64+
var sldWin = new SlideshowWindow(ObjectInfo);
6565
sldWin.Show();
6666
break;
6767
}

Helpers/Helpers.cs

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -235,20 +235,15 @@ internal static void UpdateSourcePaths(ObjectInfo objInfo) {
235235
/// </summary>
236236
/// <param name="objInfo">The ObjectInfo of the container.</param>
237237
/// <param name="sourcePathIdx">Index of the file to load in ObjectInfo.SourcePaths.</param>
238-
public static async Task<ImageSource> GetImageSource(ObjectInfo objInfo, int sourcePathIdx, bool isThumb) {
239-
//var targetPath = objInfo.SourcePaths[sourcePathIdx];
240-
//var fsPath = objInfo.FileSystemPath;
241-
//var flags = objInfo.Flags;
242-
var size = isThumb ? (SizeInt)Setting.ThumbnailSize : default;
243-
//var imgSource = objInfo.ImageSource;
244-
return await Task.Run(() => GetImageSource(objInfo, sourcePathIdx, size));
238+
public static async Task<ImageSource> GetImageSourceAsync(ObjectInfo objInfo, int sourcePathIdx, SizeInt decodeSize = default, double? decodeScale = null) {
239+
return await Task.Run(() => GetImageSource(objInfo, sourcePathIdx, decodeSize, decodeScale));
245240
}
246241

247242
/// <summary>
248243
/// Used to get image from within a container.
249244
/// </summary>
250-
/// <param name="size">Decode size.</param>
251-
public static ImageSource GetImageSource(ObjectInfo objInfo, int sourcePathIdx, SizeInt size) {
245+
/// <param name="decodeSize">Decode size.</param>
246+
public static ImageSource GetImageSource(ObjectInfo objInfo, int sourcePathIdx, SizeInt decodeSize = default, double? decodeScale = null) {
252247
if (objInfo.Flags.HasFlag(FileFlags.Error)) return App.fa_exclamation;
253248
if (objInfo.Flags == FileFlags.Unknown) return App.fa_file;
254249

@@ -266,21 +261,21 @@ public static ImageSource GetImageSource(ObjectInfo objInfo, int sourcePathIdx,
266261
switch (objInfo.Flags) {
267262
case FileFlags.Directory:
268263
if (objInfo.SourcePaths?.Length > 0)
269-
source = GetImageSource(objInfo.SourcePaths[sourcePathIdx], size);
264+
source = GetImageSource(objInfo.SourcePaths[sourcePathIdx], decodeSize: decodeSize, decodeScale: decodeScale);
270265
if (source == null) {
271266
source = App.fa_folder;
272267
}
273268
break;
274269
case FileFlags.Image:
275-
source = GetImageSource(objInfo.FileSystemPath, size);
270+
source = GetImageSource(objInfo.FileSystemPath, decodeSize: decodeSize, decodeScale: decodeScale);
276271
if (source == null) {
277272
source = App.fa_image;
278273
}
279274
break;
280275
case FileFlags.Archive:
281276
if (objInfo.SourcePaths?.Length > 0) {
282277
MainWindow.LoadFile(new LoadOptions(objInfo.FileSystemPath) {
283-
DecodeSize = size,
278+
DecodeSize = decodeSize,
284279
LoadImage = true,
285280
FileNames = new[] { objInfo.SourcePaths[sourcePathIdx] },
286281
Flags = FileFlags.Archive,
@@ -312,75 +307,86 @@ public static ImageSource GetImageSource(ObjectInfo objInfo, int sourcePathIdx,
312307
}
313308

314309
/// <summary>
315-
/// Load image from disk if cache is not availble.
310+
/// <para>Load image from disk if cache is not availble.</para>
311+
/// <para>Setting <paramref name="decodeScale"/> to 1 is the same as leaving <paramref name="decodeSize"/> to default.</para>
316312
/// </summary>
317-
public static BitmapSource GetImageSource(string path, SizeInt decodeSize = default) {
313+
public static BitmapSource GetImageSource(string path, SizeInt decodeSize = default, double? decodeScale = null) {
318314
BitmapSource bs = null;
319315
try {
320-
var isThumb = decodeSize.Width + decodeSize.Height > 0;
316+
var isThumb = decodeSize.Width + decodeSize.Height > 0 && decodeScale == null;
321317
if (isThumb) {
322318
//try load from cache when decodeSize is non-zero
323319
bs = SQLiteHelper.GetFromThumbDB(path, decodeSize);
324320
if (bs != null) return bs;
325321
}
326-
327-
////avoid file dead locks
328-
//Monitor.Enter(lock_Loading);
329-
//var wait = loading.Contains(path);
330-
//Monitor.Exit(lock_Loading);
331-
//while (wait) {
332-
// Thread.Sleep(100);
333-
// Monitor.Enter(lock_Loading);
334-
// wait = loading.Contains(path);
335-
// Monitor.Exit(lock_Loading);
336-
//}
337-
//Monitor.Enter(lock_Loading);
338-
//loading.Add(path);
339-
//Monitor.Exit(lock_Loading);
340-
//load from disk
341322
#if DEBUG
342323
Console.WriteLine("Loading from disk: " + path);
343324
#endif
344325
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) {
345-
bs = GetImageSource(fs, decodeSize);
326+
bs = GetImageSource(fs, decodeSize, decodeScale);
346327
}
347328
if (isThumb && bs != null) SQLiteHelper.AddToThumbDB(bs, path, decodeSize);
348329
}
349330
catch (Exception ex) {
350331
MessageBox.Show($"Error loading file {path}.\r\n{ex.Message}", "Error Loading File", MessageBoxButton.OK, MessageBoxImage.Error);
351332
}
352-
finally {
353-
//loading.Remove(path);
354-
}
355333

356334
return bs;
357335
}
358336

359337
/// <summary>
360-
/// Decode image from stream (FileStream when loading from file or MemoryStream when loading from archive.
338+
/// <para>Decode image from stream (FileStream when loading from file or MemoryStream when loading from archive.</para>
339+
/// <para>A <paramref name="decodeSize"/> higher than the actual resolution will be ignored.
340+
/// Note that this is the size in pixel instead of the device-independent size used in WPF.</para>
341+
/// <para><paramref name="decodeScale"/> can be used to further scale up or down <paramref name="decodeSize"/>.</para>
361342
/// </summary>
362-
public static BitmapSource GetImageSource(Stream stream, SizeInt decodeSize) {
343+
public static BitmapSource GetImageSource(Stream stream, SizeInt decodeSize = default, double? decodeScale = null) {
363344
stream.Position = 0;
364345
var frame = BitmapFrame.Create(stream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
365-
var frameSize = new Size(frame.PixelWidth, frame.PixelHeight);
346+
var pixelSize = new SizeInt(frame.PixelWidth, frame.PixelHeight);
366347
ushort orien = 0;
367348
if ((frame.Metadata as BitmapMetadata)?.GetQuery("/app1/ifd/{ushort=274}") is ushort u)
368349
orien = u;
369350
frame = null;
370351

371-
//flip decodeSize according to orientation
372-
if (decodeSize.Width + decodeSize.Height > 0 && orien > 4 && orien < 9)
373-
decodeSize = new SizeInt(decodeSize.Height, decodeSize.Width);
352+
//calculate decode size
353+
double newW = 0d, newH = 0d;
354+
if (decodeSize.Width + decodeSize.Height > 0) {
355+
//use pixelSize if decodeSize is too big
356+
//DecodePixelWidth / Height is set to PixelWidth / Height anyway in reference source
357+
if (decodeSize.Width > pixelSize.Width) decodeSize.Width = pixelSize.Width;
358+
if (decodeSize.Height > pixelSize.Height) decodeSize.Height = pixelSize.Height;
359+
360+
//flip decodeSize according to orientation
361+
if (orien > 4 && orien < 9) {
362+
newW = decodeSize.Height;
363+
newH = decodeSize.Width;
364+
}
365+
//apply decode scale
366+
if (decodeScale > 0d) {
367+
newW *= decodeScale.Value;
368+
newH *= decodeScale.Value;
369+
}
370+
}
371+
//apply decode scale
372+
else if (decodeScale > 0d && decodeScale < 1d) {
373+
newW = pixelSize.Width * decodeScale.Value;
374+
newH = pixelSize.Height * decodeScale.Value;
375+
}
376+
377+
if (newW + newH > 0d)
378+
decodeSize = new SizeInt(Convert.ToInt32(newW), Convert.ToInt32(newH));
374379

375380
//init bitmapimage
376381
stream.Position = 0;
377382
var bi = new BitmapImage();
378383
bi.BeginInit();
379384
bi.CacheOption = BitmapCacheOption.OnLoad;
380-
if (frameSize.Width > 0 && frameSize.Height > 0) {
381-
var frameRatio = frameSize.Width / frameSize.Height;
385+
if (pixelSize.Width > 0 && pixelSize.Height > 0) {
386+
//setting both DecodePixelWidth and Height will break the aspect ratio
387+
var imgRatio = (double)pixelSize.Width / pixelSize.Height;
382388
if (decodeSize.Width > 0 && decodeSize.Height > 0) {
383-
if (frameRatio > (double)decodeSize.Width / decodeSize.Height)
389+
if (imgRatio > (double)decodeSize.Width / decodeSize.Height)
384390
bi.DecodePixelHeight = decodeSize.Height;
385391
else
386392
bi.DecodePixelWidth = decodeSize.Width;

Helpers/SQLiteHelper.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Windows;
99
using System.Windows.Media;
1010
using System.Windows.Media.Imaging;
11+
using SizeInt = System.Drawing.Size;
1112
using static ZipImageViewer.TableHelper;
1213

1314
namespace ZipImageViewer
@@ -58,10 +59,6 @@ internal static void CheckThumbsDB() {
5859
cmd.CommandText = $@"pragma table_info({table.Name})";
5960
using (var r = cmd.ExecuteReader()) {
6061
while (r.Read()) {
61-
Console.WriteLine(r["name"]);
62-
Console.WriteLine(r["type"]);
63-
Console.WriteLine(r["notnull"]);
64-
Console.WriteLine(r["pk"]);
6562
switch (r["name"]) {
6663
case nameof(Column.VirtualPath):
6764
if (r["type"].ToString() == "TEXT" &&
@@ -103,7 +100,7 @@ internal static void CheckThumbsDB() {
103100
});
104101
}
105102

106-
internal static int AddToThumbDB(ImageSource source, string path, System.Drawing.Size decodeSize) {
103+
internal static int AddToThumbDB(ImageSource source, string path, SizeInt decodeSize) {
107104
if (!(source is BitmapSource bs)) throw new NotSupportedException();
108105

109106
object[] affected = null;
@@ -137,7 +134,7 @@ internal static int AddToThumbDB(ImageSource source, string path, System.Drawing
137134
/// <summary>
138135
/// Returns null if thumb either does not exist in DB or has different size.
139136
/// </summary>
140-
internal static BitmapSource GetFromThumbDB(string path, System.Drawing.Size decodeSize) {
137+
internal static BitmapSource GetFromThumbDB(string path, SizeInt decodeSize) {
141138
var png = Execute(Table.Thumbs, (table, con) => {
142139
byte[] pngByte = null;
143140
using (var cmd = new SQLiteCommand(con)) {
@@ -149,7 +146,7 @@ internal static BitmapSource GetFromThumbDB(string path, System.Drawing.Size dec
149146
cmd.Parameters.Add(new SQLiteParameter("@path", DbType.String) { Value = path });
150147
using (var reader = cmd.ExecuteReader()) {
151148
while (reader.Read()) {
152-
pngByte = (byte[])reader["thumbData"];
149+
pngByte = (byte[])reader[0];
153150
break;
154151
}
155152
}
@@ -168,5 +165,22 @@ internal static BitmapSource GetFromThumbDB(string path, System.Drawing.Size dec
168165
return bi;
169166
}
170167
}
168+
169+
internal static bool ThumbExistInDB(string path, SizeInt decodeSize) {
170+
return (bool)Execute(Table.Thumbs, (table, con) => {
171+
using (var cmd = new SQLiteCommand(con)) {
172+
cmd.CommandText =
173+
$@"select count({Column.ThumbData}) from {table.Name} where
174+
{Column.VirtualPath} = @path and
175+
{Column.DecodeWidth} = {decodeSize.Width} and
176+
{Column.DecodeHeight} = {decodeSize.Height}";
177+
cmd.Parameters.Add(new SQLiteParameter("@path", DbType.String) { Value = path });
178+
using (var r = cmd.ExecuteReader()) {
179+
r.Read();
180+
return (long)r[0] > 0;
181+
}
182+
}
183+
})[0];
184+
}
171185
}
172186
}

0 commit comments

Comments
 (0)