Fortschritt, .NET-Prüfung, Updates, Fenster merken, Box-Funktionen
- Große Kopien laufen im Hintergrund mit Fortschritt und Abbrechen; abgebrochene Kopien werden aufgeräumt, das Original bleibt unverändert - Sichern/Wiederherstellen mit Fortschritt, keine halben ZIP-Dateien - Installer auf .NET Framework 4.8: erkennt fehlende .NET 9 Desktop Runtime und installiert sie auf Wunsch (Microsoft-Signatur wird geprüft) - Update-Hinweis über Gitea-Releases, Update mit automatischem Neustart - Fenstergröße und -position werden gemerkt - Desktop-Boxen: umbenennen, löschen, verschieben, herausziehen - Fenster und Boxen kehren auf sichtbare Bildschirme zurück - README ergänzt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+78
-10
@@ -51,15 +51,34 @@ public partial class FenceWindow : Window
|
||||
{
|
||||
_applying = true;
|
||||
var m = Meta;
|
||||
var wa = SystemParameters.WorkArea;
|
||||
Width = Math.Max(MinWidth, m.FenceW);
|
||||
Height = m.FenceCollapsed ? CollapsedHeight : Math.Max(120, m.FenceH);
|
||||
Left = Math.Clamp(m.FenceX ?? wa.Left + 24, wa.Left - Width + 80, wa.Right - 80);
|
||||
Top = Math.Clamp(m.FenceY ?? wa.Top + 24, wa.Top, wa.Bottom - 40);
|
||||
var wa = Screens.PrimaryWorkArea;
|
||||
double left = m.FenceX ?? wa.Right - Width - 24, top = m.FenceY ?? wa.Top + 24;
|
||||
// Bildschirm abgesteckt? → zurück auf den Hauptbildschirm (oben rechts)
|
||||
if (!Screens.IsReachable(new Rect(left, top, Width, Height)))
|
||||
{
|
||||
left = wa.Right - Width - 24;
|
||||
top = wa.Top + 24;
|
||||
m.FenceX = left;
|
||||
m.FenceY = top;
|
||||
}
|
||||
Left = left;
|
||||
Top = top;
|
||||
Body.Visibility = m.FenceCollapsed ? Visibility.Collapsed : Visibility.Visible;
|
||||
_applying = false;
|
||||
}
|
||||
|
||||
/// <summary>Nach Bildschirm-Änderungen: Box wieder sichtbar machen.</summary>
|
||||
public void EnsureOnScreen()
|
||||
{
|
||||
if (Screens.IsReachable(new Rect(Left, Top, ActualWidth, ActualHeight))) return;
|
||||
Meta.FenceX = null;
|
||||
Meta.FenceY = null;
|
||||
ApplyBounds();
|
||||
AppSettings.Current.Save();
|
||||
}
|
||||
|
||||
private void RememberBounds()
|
||||
{
|
||||
if (_applying || !IsLoaded) return;
|
||||
@@ -114,20 +133,40 @@ public partial class FenceWindow : Window
|
||||
|
||||
private void Items_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Enter) Selected.ForEach(i => Open(i.Path));
|
||||
var sel = Selected;
|
||||
if (sel.Count == 0 || App.Win is not { } win) return;
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Enter: sel.ForEach(i => Open(i.Path)); e.Handled = true; break;
|
||||
case Key.Delete: win.DeleteIcons(sel); e.Handled = true; break;
|
||||
case Key.F2 when sel.Count == 1: win.RenameIcon(sel[0]); e.Handled = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Items_ContextMenuOpening(object sender, ContextMenuEventArgs e)
|
||||
{
|
||||
var sel = Selected;
|
||||
if (sel.Count == 0) { e.Handled = true; return; }
|
||||
if (sel.Count == 0 || App.Win is not { } win) { e.Handled = true; return; }
|
||||
ItemMenu.Items.Clear();
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("Öffnen", "", () => sel.ForEach(i => Open(i.Path)), bold: true));
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("Öffnen", "\uE8A7", () => sel.ForEach(i => Open(i.Path)), bold: true, gesture: "Enter"));
|
||||
if (sel.Count == 1)
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("Dateispeicherort öffnen", "", () =>
|
||||
{
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("Dateispeicherort öffnen", "\uED25", () =>
|
||||
Process.Start("explorer.exe", $"/select,\"{sel[0].Path}\"")));
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("Umbenennen", "\uE70F", () => win.RenameIcon(sel[0]), gesture: "F2"));
|
||||
}
|
||||
ItemMenu.Items.Add(new Separator());
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("In DeskCore zeigen", "", ShowInApp));
|
||||
|
||||
var moveTo = MainWindow.MenuItem("Verschieben nach", "\uE8DE", null);
|
||||
foreach (var c in Storage.Categories().Where(c => !string.Equals(c, Category, StringComparison.OrdinalIgnoreCase)))
|
||||
moveTo.Items.Add(MainWindow.MenuItem(c, AppSettings.Current.Categories.GetValueOrDefault(c)?.Glyph ?? "\uF12B",
|
||||
() => win.TransferAll(sel.Select(i => i.Path), Storage.CategoryPath(c))));
|
||||
if (moveTo.Items.Count > 0) ItemMenu.Items.Add(moveTo);
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("Zurück auf den Desktop legen", "\uE7F4",
|
||||
() => win.TransferAll(sel.Select(i => i.Path), Storage.UserDesktop)));
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("Löschen", "\uE74D", () => win.DeleteIcons(sel), gesture: "Entf"));
|
||||
ItemMenu.Items.Add(new Separator());
|
||||
ItemMenu.Items.Add(MainWindow.MenuItem("In DeskCore zeigen", "\uE8A7", ShowInApp));
|
||||
}
|
||||
|
||||
private void MenuButton_Click(object sender, RoutedEventArgs e)
|
||||
@@ -149,9 +188,33 @@ public partial class FenceWindow : Window
|
||||
|
||||
private void ShowInApp() => App.Win?.ShowCategory(Category);
|
||||
|
||||
private Point _dragStart;
|
||||
private bool _dragging;
|
||||
|
||||
private void Items_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) => _dragStart = e.GetPosition(null);
|
||||
|
||||
private void Items_PreviewMouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.LeftButton != MouseButtonState.Pressed || _dragging) return;
|
||||
var d = e.GetPosition(null) - _dragStart;
|
||||
if (Math.Abs(d.X) < SystemParameters.MinimumHorizontalDragDistance &&
|
||||
Math.Abs(d.Y) < SystemParameters.MinimumVerticalDragDistance) return;
|
||||
if (MainWindow.FindParent<ListBoxItem>(e.OriginalSource as DependencyObject) is null) return;
|
||||
var paths = Selected.Select(i => i.Path).ToArray();
|
||||
if (paths.Length == 0) return;
|
||||
_dragging = true;
|
||||
try
|
||||
{
|
||||
// nur "Kopieren" erlauben: der Explorer soll die Datei nicht aus der Kategorie entfernen.
|
||||
// In eine andere Box/Kategorie gezogen, verschiebt DeskCore selbst.
|
||||
DragDrop.DoDragDrop(Items, new DataObject(DataFormats.FileDrop, paths), DragDropEffects.Copy);
|
||||
}
|
||||
finally { _dragging = false; }
|
||||
}
|
||||
|
||||
private void Items_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop)
|
||||
e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop) && !_dragging
|
||||
? (e.AllowedEffects.HasFlag(DragDropEffects.Copy) ? DragDropEffects.Copy : DragDropEffects.Move)
|
||||
: DragDropEffects.None;
|
||||
e.Handled = true;
|
||||
@@ -159,7 +222,7 @@ public partial class FenceWindow : Window
|
||||
|
||||
private void Items_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetData(DataFormats.FileDrop) is string[] files)
|
||||
if (!_dragging && e.Data.GetData(DataFormats.FileDrop) is string[] files)
|
||||
App.Win?.TransferAll(files, Storage.CategoryPath(Category));
|
||||
}
|
||||
|
||||
@@ -265,6 +328,11 @@ public static class FenceManager
|
||||
foreach (var f in _open) f.Refresh();
|
||||
}
|
||||
|
||||
public static void EnsureOnScreen()
|
||||
{
|
||||
foreach (var f in _open) f.EnsureOnScreen();
|
||||
}
|
||||
|
||||
public static void Renamed(string oldName, string newName)
|
||||
{
|
||||
_open.FirstOrDefault(x => string.Equals(x.Category, oldName, StringComparison.OrdinalIgnoreCase))?.Rename(newName);
|
||||
|
||||
Reference in New Issue
Block a user