Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,12 @@
</StackPanel>
</ScrollViewer>

<Rectangle Grid.Column="1" Width="2" Fill="{DynamicResource FolderStringColor}" HorizontalAlignment="Center" IsHitTestVisible="False"/>
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Background="Transparent"/>

<!-- File List -->
<ListView x:Name="FileListView" Grid.Column="2" BorderThickness="0" Background="{DynamicResource BackgroundColor}" Foreground="{DynamicResource TextColor}" MouseDoubleClick="FileListView_MouseDoubleClick" SelectionChanged="FileListView_SelectionChanged" GridViewColumnHeader.Click="GridViewColumnHeader_Click" PreviewMouseMove="FileListView_PreviewMouseMove" PreviewMouseWheel="FileListView_PreviewMouseWheel" IsTextSearchEnabled="False" PreviewTextInput="FileListView_PreviewTextInput">
<Grid Grid.Column="2">
<ListView x:Name="FileListView" BorderThickness="0" Background="{DynamicResource BackgroundColor}" Foreground="{DynamicResource TextColor}" MouseDoubleClick="FileListView_MouseDoubleClick" SelectionChanged="FileListView_SelectionChanged" GridViewColumnHeader.Click="GridViewColumnHeader_Click" PreviewMouseMove="FileListView_PreviewMouseMove" PreviewMouseWheel="FileListView_PreviewMouseWheel" IsTextSearchEnabled="False" PreviewTextInput="FileListView_PreviewTextInput" PreviewMouseLeftButtonDown="FileListView_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="FileListView_PreviewMouseLeftButtonUp">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
Expand Down Expand Up @@ -230,9 +232,15 @@
</ContextMenu>
</ListView.ContextMenu>

<!-- Default GridView mode setup in CodeBehind to handle references easier -->
</ListView>

<!-- Default GridView mode setup in CodeBehind to handle references easier -->
</ListView>
<Canvas x:Name="SelectionCanvas" IsHitTestVisible="False">
<Rectangle x:Name="SelectionRectangle" Fill="#330078D7" Stroke="#0078D7" StrokeThickness="1" Visibility="Collapsed" />
</Canvas>
</Grid>

<Rectangle Grid.Column="3" Width="2" Fill="{DynamicResource FolderStringColor}" HorizontalAlignment="Center" IsHitTestVisible="False" Visibility="{Binding Visibility, ElementName=PreviewSplitter}"/>
<GridSplitter Grid.Column="3" Width="5" HorizontalAlignment="Stretch" Background="Transparent" x:Name="PreviewSplitter" Visibility="Collapsed"/>

<!-- Preview Panel -->
Expand Down
118 changes: 117 additions & 1 deletion MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@
private ListSortDirection _lastDirection = ListSortDirection.Ascending;
private bool _previewVisible = false;
private char _lastSearchChar = '\0';

private Point _startPoint;
private bool _isSelecting = false;
private ScrollViewer? _listScrollViewer;

private static T? FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is T typedChild) return typedChild;
var childOfChild = FindVisualChild<T>(child);
if (childOfChild != null) return childOfChild;
}
return null;
}

private GridView _detailsView = null!;
private GridViewColumn _colName = null!, _colDateMod = null!, _colType = null!, _colSize = null!, _colCreation = null!, _colDimensions = null!;
Expand Down Expand Up @@ -579,10 +595,110 @@
}

// Drag Drop & Context Logic
private void FileListView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource is DependencyObject depObj)
{
// Check if user clicked on a ListViewItem
var item = FindVisualParent<ListViewItem>(depObj);
if (item == null)
{
// Clicked on empty space
_startPoint = e.GetPosition(SelectionCanvas);
FileListView.SelectedItems.Clear();
_isSelecting = true;
FileListView.CaptureMouse();

Canvas.SetLeft(SelectionRectangle, _startPoint.X);
Canvas.SetTop(SelectionRectangle, _startPoint.Y);
SelectionRectangle.Width = 0;
SelectionRectangle.Height = 0;
SelectionRectangle.Visibility = Visibility.Visible;

if (_listScrollViewer == null)
_listScrollViewer = FindVisualChild<ScrollViewer>(FileListView);
}
}
}

private static T? FindVisualParent<T>(DependencyObject child) where T : DependencyObject
{
DependencyObject parentObject = child;
while (parentObject != null)
{
if (parentObject is Visual || parentObject is System.Windows.Media.Media3D.Visual3D)
{
parentObject = VisualTreeHelper.GetParent(parentObject);
}
else
{
parentObject = LogicalTreeHelper.GetParent(parentObject);
}

if (parentObject is T parent) return parent;
}
return null;
}

private void FileListView_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed && FileListView.SelectedItem is FileSystemItem item && item.IsDirectory)
if (_isSelecting && e.LeftButton == MouseButtonState.Pressed)
{
Point pos = e.GetPosition(SelectionCanvas);

double x = Math.Min(pos.X, _startPoint.X);
double y = Math.Min(pos.Y, _startPoint.Y);
double w = Math.Abs(pos.X - _startPoint.X);
double h = Math.Abs(pos.Y - _startPoint.Y);

Canvas.SetLeft(SelectionRectangle, x);
Canvas.SetTop(SelectionRectangle, y);
SelectionRectangle.Width = w;
SelectionRectangle.Height = h;

Rect selectionRect = new Rect(x, y, w, h);

// Select items intersecting with rectangle
foreach (var item in FileListView.Items)
{
if (FileListView.ItemContainerGenerator.ContainerFromItem(item) is ListViewItem lvi)
{
Point itemPos = lvi.TransformToVisual(SelectionCanvas).Transform(new Point(0, 0));
Rect itemRect = new Rect(itemPos, new Size(lvi.ActualWidth, lvi.ActualHeight));

if (selectionRect.IntersectsWith(itemRect))
lvi.IsSelected = true;
else
lvi.IsSelected = false;
}
}

// Auto-scroll logic
if (_listScrollViewer != null)
{
Point listViewPos = e.GetPosition(FileListView);
double scrollZoneHeight = 20;

if (listViewPos.Y < scrollZoneHeight)
_listScrollViewer.LineUp();
else if (listViewPos.Y > FileListView.ActualHeight - scrollZoneHeight)
_listScrollViewer.LineDown();
}
}
else if (!_isSelecting && e.LeftButton == MouseButtonState.Pressed && FileListView.SelectedItem is FileSystemItem item && item.IsDirectory)
{
DragDrop.DoDragDrop(FileListView, item.Path, DragDropEffects.Link);
}
}

private void FileListView_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (_isSelecting)
{
_isSelecting = false;
FileListView.ReleaseMouseCapture();
SelectionRectangle.Visibility = Visibility.Collapsed;
}
}

private void FavoritesList_Drop(object sender, DragEventArgs e)
Expand Down Expand Up @@ -734,7 +850,7 @@
private ImageSource? _thumbnail;
public ImageSource Thumbnail
{
get => _thumbnail;

Check warning on line 853 in MainWindow.xaml.cs

View workflow job for this annotation

GitHub Actions / publish

Possible null reference return.
set
{
_thumbnail = value;
Expand Down
6 changes: 3 additions & 3 deletions UnifiedExplorer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ApplicationIcon>assets\app.ico</ApplicationIcon>
<Version>1.0.1</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.1.0</FileVersion>
<Version>1.0.2</Version>
<AssemblyVersion>1.0.2.0</AssemblyVersion>
<FileVersion>1.0.2.0</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading