Skip to content

Commit 6fadea0

Browse files
committed
Init
1 parent bfc6ee1 commit 6fadea0

15 files changed

+243
-185
lines changed

src/Files.App.CsWin32/ManualGuid.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public static Guid* IID_IStorageProviderStatusUISourceFactory
4141

4242
[GuidRVAGen.Guid("00021500-0000-0000-C000-000000000046")]
4343
public static partial Guid* IID_IQueryInfo { get; }
44+
45+
[GuidRVAGen.Guid("000214F9-0000-0000-C000-000000000046")]
46+
public static partial Guid* IID_IShellLinkW { get; }
4447
}
4548

4649
public static unsafe partial class CLSID

src/Files.App.CsWin32/NativeMethods.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,6 @@ _SICHINTF
226226
RoGetAgileReference
227227
IQueryInfo
228228
QITIPF_FLAGS
229+
GetDiskFreeSpaceEx
230+
GetDriveType
231+
SLGP_FLAGS
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.App.Storage
5+
{
6+
public interface IWindowsFile : IWindowsStorable, IChildFile
7+
{
8+
}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.App.Storage
5+
{
6+
public interface IWindowsFolder : IWindowsStorable, IChildFolder
7+
{
8+
}
9+
}

src/Files.App.Storage/Storables/WindowsStorage/IWindowsStorable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Files.App.Storage
88
{
9-
public interface IWindowsStorable : IDisposable
9+
public interface IWindowsStorable : IStorableChild, IEquatable<IWindowsStorable>, IDisposable
1010
{
1111
ComPtr<IShellItem> ThisPtr { get; }
1212
}

src/Files.App.Storage/Storables/WindowsStorage/WindowsFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
namespace Files.App.Storage
99
{
1010
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
11-
public sealed class WindowsFile : WindowsStorable, IChildFile
11+
public sealed class WindowsFile : WindowsStorable, IWindowsFile
1212
{
1313
public WindowsFile(ComPtr<IShellItem> nativeObject)
1414
{

src/Files.App.Storage/Storables/WindowsStorage/WindowsFolder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace Files.App.Storage
1111
{
1212
[DebuggerDisplay("{" + nameof(ToString) + "()}")]
13-
public sealed class WindowsFolder : WindowsStorable, IChildFolder
13+
public sealed class WindowsFolder : WindowsStorable, IWindowsFolder
1414
{
1515
public WindowsFolder(ComPtr<IShellItem> nativeObject)
1616
{

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Files.App.Storage
1010
{
11-
public abstract class WindowsStorable : IWindowsStorable, IStorableChild, IEquatable<IWindowsStorable>
11+
public abstract class WindowsStorable : IWindowsStorable
1212
{
1313
public ComPtr<IShellItem> ThisPtr { get; protected set; }
1414

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Shell.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,19 @@ public unsafe static HRESULT TryGetShellTooltip(this IWindowsStorable storable,
143143

144144
return HRESULT.S_OK;
145145
}
146+
147+
public unsafe static HRESULT TryGetShellLink(this IWindowsStorable storable, out ComPtr<IShellLinkW> pShellLink)
148+
{
149+
pShellLink = default;
150+
151+
using ComPtr<IShellLinkW> pShellLinkW = default;
152+
HRESULT hr = storable.ThisPtr.Get()->BindToHandler(null, BHID.BHID_SFUIObject, IID.IID_IShellLinkW, (void**)pShellLinkW.GetAddressOf());
153+
if (hr.ThrowIfFailedOnDebug().Failed)
154+
return hr;
155+
156+
pShellLink = pShellLinkW;
157+
158+
return HRESULT.S_OK;
159+
}
146160
}
147161
}

src/Files.App.Storage/Storables/WindowsStorage/WindowsStorableHelpers.Storage.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using Windows.Win32;
55
using Windows.Win32.Foundation;
6+
using Windows.Win32.NetworkManagement.WNet;
67
using Windows.Win32.Storage.FileSystem;
78
using Windows.Win32.UI.Shell;
89

@@ -84,5 +85,37 @@ public static bool TryShowFormatDriveDialog(HWND hWnd, uint driveLetterIndex, SH
8485
var result = PInvoke.SHFormatDrive(hWnd, driveLetterIndex, id, options);
8586
return result is 0xFFFF;
8687
}
88+
89+
public static bool TryGetDriveTotalSpace(this IWindowsStorable storable, out ulong totalSize)
90+
{
91+
ulong ulTotalSize = 0UL;
92+
bool res = PInvoke.GetDiskFreeSpaceEx(storable.GetDisplayName(), null, &ulTotalSize, null);
93+
94+
totalSize = ulTotalSize;
95+
96+
return res;
97+
}
98+
99+
public static bool TryGetDriveFreeSpace(this IWindowsStorable storable, out ulong freeSize)
100+
{
101+
ulong ulFreeSize = 0UL;
102+
bool res = PInvoke.GetDiskFreeSpaceEx(storable.GetDisplayName(), null, null, &ulFreeSize);
103+
104+
freeSize = ulFreeSize;
105+
106+
return res;
107+
}
108+
109+
public static bool TryGetDriveType(this IWindowsStorable storable, out uint driveType)
110+
{
111+
driveType = PInvoke.GetDriveType(storable.GetDisplayName());
112+
113+
return driveType is 0U; // DRIVE_UNKNOWN
114+
}
115+
116+
public static bool TryDisconnectNetworkDrive(this IWindowsStorable storable)
117+
{
118+
return PInvoke.WNetCancelConnection2W(storable.GetDisplayName().TrimEnd('\\'), NET_CONNECT_FLAGS.CONNECT_UPDATE_PROFILE, true) is WIN32_ERROR.NO_ERROR;
119+
}
87120
}
88121
}

src/Files.App/Data/Items/WidgetDriveCardItem.cs

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,63 @@
22
// Licensed under the MIT License.
33

44
using Microsoft.UI.Xaml.Media.Imaging;
5+
using Windows.Win32;
6+
using Windows.Win32.UI.Shell;
57

68
namespace Files.App.Data.Items
79
{
8-
public sealed partial class WidgetDriveCardItem : WidgetCardItem, IWidgetCardItem<DriveItem>, IComparable<WidgetDriveCardItem>
10+
public sealed partial class WidgetDriveCardItem : WidgetCardItem, IWidgetCardItem<IWindowsFolder>, IDisposable
911
{
10-
private byte[] thumbnailData;
12+
// Properties
1113

12-
public new DriveItem Item { get; private set; }
14+
public required IWindowsFolder Item { get; set; }
1315

14-
private BitmapImage thumbnail;
15-
public BitmapImage Thumbnail
16-
{
17-
get => thumbnail;
18-
set => SetProperty(ref thumbnail, value);
19-
}
16+
public required new string Path { get; set; }
17+
18+
public required string Text { get; set; }
19+
20+
public bool ShowStorageSense => UsedSize.GigaBytes / TotalSize.GigaBytes >= Constants.Widgets.Drives.LowStorageSpacePercentageThreshold;
21+
22+
public bool ShowDriveUsage => TotalSize.GigaBytes > 0D;
23+
24+
public ByteSizeLib.ByteSize TotalSize { get; set; } = default;
25+
26+
public ByteSizeLib.ByteSize FreeSize { get; set; } = default;
27+
28+
public ByteSizeLib.ByteSize UsedSize => ByteSizeLib.ByteSize.FromBytes(TotalSize.Bytes - FreeSize.Bytes);
29+
30+
public string? UsageText => string.Format(Strings.DriveFreeSpaceAndCapacity.GetLocalizedResource(), FreeSize.ToSizeString(), TotalSize.ToSizeString());
2031

21-
public WidgetDriveCardItem(DriveItem item)
32+
public required SystemIO.DriveType DriveType { get; set; }
33+
34+
private BitmapImage? _Thumbnail;
35+
public BitmapImage? Thumbnail { get => _Thumbnail; set => SetProperty(ref _Thumbnail, value); }
36+
37+
// Constructor
38+
39+
public WidgetDriveCardItem()
2240
{
23-
Item = item;
24-
Path = item.Path;
2541
}
2642

43+
// Methods
44+
2745
public async Task LoadCardThumbnailAsync()
2846
{
29-
var result = await FileThumbnailHelper.GetIconAsync(
30-
Item.Path,
31-
Constants.ShellIconSizes.Large,
32-
true,
33-
IconOptions.ReturnIconOnly | IconOptions.UseCurrentScale);
34-
35-
if (result is null)
36-
{
37-
using var thumbnail = await DriveHelpers.GetThumbnailAsync(Item.Root);
38-
result ??= await thumbnail.ToByteArrayAsync();
39-
}
40-
41-
thumbnailData = result;
42-
43-
var bitmapImage = await MainWindow.Instance.DispatcherQueue.EnqueueOrInvokeAsync(() => thumbnailData.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal);
44-
if (bitmapImage is not null)
45-
Thumbnail = bitmapImage;
47+
if (string.IsNullOrEmpty(Path) || Item is not IWindowsStorable windowsStorable)
48+
return;
49+
50+
windowsStorable.TryGetThumbnail((int)(Constants.ShellIconSizes.Large * App.AppModel.AppWindowDPI), SIIGBF.SIIGBF_ICONONLY, out var rawThumbnailData);
51+
if (rawThumbnailData is null)
52+
return;
53+
54+
Thumbnail = await rawThumbnailData.ToBitmapAsync();
4655
}
4756

48-
public int CompareTo(WidgetDriveCardItem? other)
49-
=> Item.Path.CompareTo(other?.Item?.Path);
57+
// Disposer
58+
59+
public void Dispose()
60+
{
61+
Item.Dispose();
62+
}
5063
}
5164
}

src/Files.App/UserControls/Widgets/DrivesWidget.xaml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@
3131
VerticalAlignment="Stretch"
3232
HorizontalContentAlignment="Stretch"
3333
VerticalContentAlignment="Stretch"
34-
AutomationProperties.Name="{x:Bind Item.Text, Mode=OneWay}"
34+
AutomationProperties.Name="{x:Bind Text, Mode=OneWay}"
3535
Click="Button_Click"
3636
CornerRadius="{StaticResource ControlCornerRadius}"
3737
DataContext="{x:Bind}"
3838
PointerPressed="Button_PointerPressed"
3939
RightTapped="Button_RightTapped"
40-
Tag="{x:Bind Item.Path}"
41-
ToolTipService.ToolTip="{x:Bind Item.Text, Mode=OneWay}">
40+
Tag="{x:Bind Path}"
41+
ToolTipService.ToolTip="{x:Bind Text, Mode=OneWay}">
4242
<Grid
4343
Margin="8"
4444
HorizontalAlignment="Stretch"
@@ -75,7 +75,7 @@
7575
VerticalAlignment="Center"
7676
FontSize="14"
7777
FontWeight="Medium"
78-
Text="{x:Bind Item.Text, Mode=OneWay}"
78+
Text="{x:Bind Text, Mode=OneWay}"
7979
TextTrimming="CharacterEllipsis"
8080
TextWrapping="NoWrap" />
8181

@@ -85,10 +85,10 @@
8585
Grid.Column="1"
8686
VerticalAlignment="Stretch"
8787
VerticalContentAlignment="Stretch"
88-
x:Load="{x:Bind Item.ShowDriveDetails, Mode=OneWay}"
88+
x:Load="{x:Bind ShowDriveUsage, Mode=OneWay}"
8989
AutomationProperties.AccessibilityView="Raw"
90-
Maximum="{x:Bind Item.MaxSpace.GigaBytes, Mode=OneWay}"
91-
Value="{x:Bind Item.SpaceUsed.GigaBytes, Mode=OneWay}" />
90+
Maximum="{x:Bind TotalSize.GigaBytes, Mode=OneWay}"
91+
Value="{x:Bind UsedSize.GigaBytes, Mode=OneWay}" />
9292

9393
<Button
9494
x:Name="GoToStorageSense"
@@ -100,12 +100,12 @@
100100
Padding="0"
101101
HorizontalContentAlignment="Center"
102102
VerticalContentAlignment="Center"
103-
x:Load="{x:Bind Item.ShowStorageSense, Mode=OneWay}"
103+
x:Load="{x:Bind ShowStorageSense, Mode=OneWay}"
104104
AutomationProperties.Name="{helpers:ResourceString Name=OpenStorageSense}"
105105
Background="Transparent"
106106
BorderBrush="Transparent"
107107
Click="GoToStorageSense_Click"
108-
Tag="{x:Bind Item.Path}"
108+
Tag="{x:Bind Path}"
109109
ToolTipService.ToolTip="{helpers:ResourceString Name=OpenStorageSense}">
110110
<FontIcon
111111
HorizontalAlignment="Center"
@@ -121,13 +121,13 @@
121121
Grid.ColumnSpan="2"
122122
HorizontalAlignment="Stretch"
123123
VerticalAlignment="Center"
124-
x:Load="{x:Bind Item.ShowDriveDetails, Mode=OneWay}"
124+
x:Load="{x:Bind ShowDriveUsage, Mode=OneWay}"
125125
x:Phase="1"
126126
FontSize="12"
127-
Text="{x:Bind Item.SpaceText, Mode=OneWay}"
127+
Text="{x:Bind UsageText, Mode=OneWay}"
128128
TextTrimming="CharacterEllipsis"
129129
TextWrapping="NoWrap"
130-
ToolTipService.ToolTip="{x:Bind Item.SpaceText, Mode=OneWay}" />
130+
ToolTipService.ToolTip="{x:Bind UsageText, Mode=OneWay}" />
131131
</Grid>
132132
</Button>
133133
</DataTemplate>

src/Files.App/UserControls/Widgets/NetworkLocationsWidget.xaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@
5858
VerticalAlignment="Stretch"
5959
HorizontalContentAlignment="Stretch"
6060
VerticalContentAlignment="Stretch"
61-
AutomationProperties.Name="{x:Bind Item.Text, Mode=OneWay}"
61+
AutomationProperties.Name="{x:Bind Text, Mode=OneWay}"
6262
Click="Button_Click"
6363
CornerRadius="{StaticResource ControlCornerRadius}"
6464
DataContext="{x:Bind}"
6565
PointerPressed="Button_PointerPressed"
6666
RightTapped="Button_RightTapped"
67-
Tag="{x:Bind Item.Path}"
68-
ToolTipService.ToolTip="{x:Bind Item.Text, Mode=OneWay}">
67+
Tag="{x:Bind Path}"
68+
ToolTipService.ToolTip="{x:Bind Text, Mode=OneWay}">
6969
<Grid
7070
Margin="8"
7171
HorizontalAlignment="Stretch"
@@ -101,7 +101,7 @@
101101
VerticalAlignment="Center"
102102
FontSize="14"
103103
FontWeight="Medium"
104-
Text="{x:Bind Item.Text, Mode=OneWay}"
104+
Text="{x:Bind Text, Mode=OneWay}"
105105
TextTrimming="CharacterEllipsis"
106106
TextWrapping="NoWrap" />
107107

@@ -111,24 +111,24 @@
111111
Grid.Column="1"
112112
VerticalAlignment="Stretch"
113113
VerticalContentAlignment="Stretch"
114-
x:Load="{x:Bind Item.ShowDriveDetails, Mode=OneWay}"
114+
x:Load="{x:Bind ShowDriveUsage, Mode=OneWay}"
115115
AutomationProperties.AccessibilityView="Raw"
116-
Maximum="{x:Bind Item.MaxSpace.GigaBytes, Mode=OneWay}"
117-
Value="{x:Bind Item.SpaceUsed.GigaBytes, Mode=OneWay}" />
116+
Maximum="{x:Bind TotalSize.GigaBytes, Mode=OneWay}"
117+
Value="{x:Bind UsedSize.GigaBytes, Mode=OneWay}" />
118118

119119
<TextBlock
120120
x:Name="DriveSpaceTextBlock"
121121
Grid.Row="2"
122122
Grid.Column="1"
123123
HorizontalAlignment="Stretch"
124124
VerticalAlignment="Center"
125-
x:Load="{x:Bind Item.ShowDriveDetails, Mode=OneWay}"
125+
x:Load="{x:Bind ShowDriveUsage, Mode=OneWay}"
126126
x:Phase="1"
127127
FontSize="12"
128-
Text="{x:Bind Item.SpaceText, Mode=OneWay}"
128+
Text="{x:Bind UsageText, Mode=OneWay}"
129129
TextTrimming="CharacterEllipsis"
130130
TextWrapping="NoWrap"
131-
ToolTipService.ToolTip="{x:Bind Item.SpaceText, Mode=OneWay}" />
131+
ToolTipService.ToolTip="{x:Bind UsageText, Mode=OneWay}" />
132132
</Grid>
133133
</Button>
134134
</DataTemplate>

0 commit comments

Comments
 (0)