refactor(app): replace AddressInfoWindow with in-app overlay
The address detail panel is now rendered as a modal overlay inside MainWindow instead of a separate top-level Window, avoiding the create/destroy cost of a dialog and working better under WSLg. Backdrop tap and Esc both close the overlay.
This commit is contained in:
@@ -249,6 +249,17 @@ public partial class MainWindowViewModel : ViewModelBase
|
||||
[ObservableProperty]
|
||||
private AddressRow? selectedAddressRow;
|
||||
|
||||
/// <summary>Dettaglio indirizzo mostrato nell'overlay in-app; null = nascosto.</summary>
|
||||
[ObservableProperty]
|
||||
private AddressInfo? addressInfo;
|
||||
|
||||
/// <summary>Apre l'overlay con i dati dell'indirizzo passato.</summary>
|
||||
public void ShowAddressInfo(AddressRow row) =>
|
||||
AddressInfo = new AddressInfo(Loc, row.Indirizzo, row.DerivPath, row.PubKey, row.PrivKey);
|
||||
|
||||
[RelayCommand]
|
||||
private void CloseAddressInfo() => AddressInfo = null;
|
||||
|
||||
// ---- rubrica contatti ----
|
||||
|
||||
public ObservableCollection<ContactEntry> Contacts { get; } = [];
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:PalladiumWallet.App.ViewModels"
|
||||
x:Class="PalladiumWallet.App.Views.AddressInfoWindow"
|
||||
x:DataType="vm:AddressInfo"
|
||||
Title="{Binding Loc[addr.info.title]}"
|
||||
Width="560" SizeToContent="Height"
|
||||
CanResize="False"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<StackPanel Margin="24" Spacing="16">
|
||||
|
||||
<!-- Indirizzo -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="{Binding Loc[addr.address]}" FontSize="11" Foreground="Gray"/>
|
||||
<SelectableTextBlock Text="{Binding Address}"
|
||||
FontFamily="monospace" FontSize="13"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Derivation path -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="{Binding Loc[addr.derivpath]}" FontSize="11" Foreground="Gray"/>
|
||||
<SelectableTextBlock Text="{Binding DerivPath}"
|
||||
FontFamily="monospace" FontSize="13"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Chiave pubblica -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="{Binding Loc[addr.pubkey]}" FontSize="11" Foreground="Gray"/>
|
||||
<SelectableTextBlock Text="{Binding PubKey}"
|
||||
FontFamily="monospace" FontSize="12"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Chiave privata (solo se disponibile) -->
|
||||
<StackPanel Spacing="4" IsVisible="{Binding HasPrivKey}">
|
||||
<TextBlock Text="{Binding Loc[addr.privkey]}" FontSize="11" Foreground="OrangeRed"/>
|
||||
<SelectableTextBlock Text="{Binding PrivKey}"
|
||||
FontFamily="monospace" FontSize="12"
|
||||
Foreground="OrangeRed"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<Button Content="{Binding Loc[addr.close]}"
|
||||
HorizontalAlignment="Right"
|
||||
Click="OnCloseClick"/>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
@@ -1,20 +0,0 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using PalladiumWallet.App.ViewModels;
|
||||
|
||||
namespace PalladiumWallet.App.Views;
|
||||
|
||||
public partial class AddressInfoWindow : Window
|
||||
{
|
||||
public AddressInfoWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public AddressInfoWindow(AddressInfo info) : this()
|
||||
{
|
||||
DataContext = info;
|
||||
}
|
||||
|
||||
private void OnCloseClick(object? sender, RoutedEventArgs e) => Close();
|
||||
}
|
||||
@@ -375,5 +375,60 @@
|
||||
Padding="10,6">
|
||||
<TextBlock Text="{Binding StatusMessage}" FontSize="12" TextWrapping="Wrap"/>
|
||||
</Border>
|
||||
|
||||
<!-- ============ OVERLAY DETTAGLIO INDIRIZZO ============ -->
|
||||
<!-- Overlay in-app invece di una Window separata: apertura/chiusura
|
||||
istantanee (niente create/destroy di una top-level window). -->
|
||||
<Border Grid.Row="0" Grid.RowSpan="3"
|
||||
Background="#99000000"
|
||||
Tapped="OnAddressOverlayBackdropTapped"
|
||||
IsVisible="{Binding AddressInfo, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||
<Border Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
|
||||
BorderBrush="Gray" BorderThickness="1" CornerRadius="8"
|
||||
Width="560" Padding="0"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
DataContext="{Binding AddressInfo}">
|
||||
<StackPanel Margin="24" Spacing="16">
|
||||
<TextBlock Text="{Binding Loc[addr.info.title]}"
|
||||
FontSize="18" FontWeight="Bold"/>
|
||||
|
||||
<!-- Indirizzo -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="{Binding Loc[addr.address]}" FontSize="11" Foreground="Gray"/>
|
||||
<SelectableTextBlock Text="{Binding Address}"
|
||||
FontFamily="monospace" FontSize="13"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Derivation path -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="{Binding Loc[addr.derivpath]}" FontSize="11" Foreground="Gray"/>
|
||||
<SelectableTextBlock Text="{Binding DerivPath}"
|
||||
FontFamily="monospace" FontSize="13"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Chiave pubblica -->
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="{Binding Loc[addr.pubkey]}" FontSize="11" Foreground="Gray"/>
|
||||
<SelectableTextBlock Text="{Binding PubKey}"
|
||||
FontFamily="monospace" FontSize="12"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Chiave privata (solo se disponibile) -->
|
||||
<StackPanel Spacing="4" IsVisible="{Binding HasPrivKey}">
|
||||
<TextBlock Text="{Binding Loc[addr.privkey]}" FontSize="11" Foreground="OrangeRed"/>
|
||||
<SelectableTextBlock Text="{Binding PrivKey}"
|
||||
FontFamily="monospace" FontSize="12"
|
||||
Foreground="OrangeRed"
|
||||
TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<Button Content="{Binding Loc[addr.close]}"
|
||||
HorizontalAlignment="Right"
|
||||
Command="{Binding $parent[Window].((vm:MainWindowViewModel)DataContext).CloseAddressInfoCommand}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -37,15 +37,14 @@ public partial class MainWindow : Window
|
||||
vm.OpenFromPath(path);
|
||||
}
|
||||
|
||||
private async void OnAddressListTapped(object? sender, TappedEventArgs e)
|
||||
private void OnAddressListTapped(object? sender, TappedEventArgs e)
|
||||
{
|
||||
if (DataContext is not MainWindowViewModel vm || vm.SelectedAddressRow is not { } row)
|
||||
return;
|
||||
var info = new AddressInfo(vm.Loc, row.Indirizzo, row.DerivPath, row.PubKey, row.PrivKey);
|
||||
await new AddressInfoWindow(info).ShowDialog(this);
|
||||
vm.ShowAddressInfo(row);
|
||||
}
|
||||
|
||||
private async void OnAddressListPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||
private void OnAddressListPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (!e.GetCurrentPoint(null).Properties.IsRightButtonPressed) return;
|
||||
if (sender is not ListBox lb || DataContext is not MainWindowViewModel vm) return;
|
||||
@@ -54,8 +53,26 @@ public partial class MainWindow : Window
|
||||
if (item is not { DataContext: AddressRow row }) return;
|
||||
|
||||
lb.SelectedItem = row;
|
||||
vm.ShowAddressInfo(row);
|
||||
}
|
||||
|
||||
var info = new AddressInfo(vm.Loc, row.Indirizzo, row.DerivPath, row.PubKey, row.PrivKey);
|
||||
await new AddressInfoWindow(info).ShowDialog(this);
|
||||
// Chiusura dell'overlay dettaglio indirizzo: click sullo sfondo scuro
|
||||
// (solo sullo sfondo, non sulla scheda) o tasto Esc.
|
||||
private void OnAddressOverlayBackdropTapped(object? sender, TappedEventArgs e)
|
||||
{
|
||||
if (!ReferenceEquals(e.Source, sender)) return;
|
||||
if (DataContext is MainWindowViewModel vm)
|
||||
vm.AddressInfo = null;
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape && DataContext is MainWindowViewModel { AddressInfo: not null } vm)
|
||||
{
|
||||
vm.AddressInfo = null;
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
base.OnKeyDown(e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user