Add MVVM-pure clipboard copy for history: hover-only copy button with flyout on Desktop/Web and long-press/right-click context menu; View writes to clipboard via CopyRequested event

This commit is contained in:
Codex CLI 2025-08-27 23:44:29 -05:00
commit 2f803db1c8
3 changed files with 157 additions and 23 deletions

View file

@ -70,28 +70,94 @@
<SplitView.Content>
<Grid RowDefinitions="*,Auto">
<!-- History -->
<Grid Grid.Row="0">
<ListBox ItemsSource="{Binding History}" SelectedIndex="{Binding SelectedHistoryIndex}"
AutomationProperties.Name="History list">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="m:HistoryItem">
<Grid ColumnDefinitions="Auto,*" Margin="4,2">
<TextBlock FontFamily="{StaticResource MDI}" Text="{x:Static m:IconFont.ArrowRightDropCircle}"
FontSize="{DynamicResource IconSizeM}" VerticalAlignment="Center" Margin="0,0,8,0" />
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding Input}" MaxLines="3" />
<TextBlock Text="{Binding Output}" FontWeight="Bold" MaxLines="2" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="No history yet. Enter an expression and Evaluate."
IsVisible="{Binding History.Count, Converter={StaticResource IsZeroConverter}}"
IsHitTestVisible="False"
Opacity="0.6"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="0">
<ListBox ItemsSource="{Binding History}" SelectedIndex="{Binding SelectedHistoryIndex}"
AutomationProperties.Name="History list">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="m:HistoryItem">
<!-- Root row container so we can bind IsPointerOver for hover-only controls -->
<Grid x:Name="HistoryRow" ColumnDefinitions="Auto,*,Auto" Margin="4,2">
<TextBlock Grid.Column="0" FontFamily="{StaticResource MDI}" Text="{x:Static m:IconFont.ArrowRightDropCircle}"
FontSize="{DynamicResource IconSizeM}" VerticalAlignment="Center" Margin="0,0,8,0" />
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding Input}" MaxLines="3" />
<TextBlock Text="{Binding Output}" FontWeight="Bold" MaxLines="2" />
</StackPanel>
<!-- Hover-only copy button for Desktop/Web with options flyout -->
<Button Grid.Column="2"
IsVisible="{Binding #HistoryRow.IsPointerOver}"
Margin="8,0,0,0"
Padding="8,4"
MinHeight="28"
Background="Transparent"
AutomationProperties.Name="Copy options">
<Button.Flyout>
<Flyout Placement="BottomEdgeAlignedRight">
<StackPanel>
<Button x:DataType="vm:MainViewModel"
DataContext="{Binding #Root.DataContext}"
Command="{Binding CopyHistoryInputCommand}"
CommandParameter="{Binding #HistoryRow.DataContext}"
AutomationProperties.Name="Copy input"
Background="Transparent" BorderThickness="0" Padding="8,4">
<TextBlock Text="Copy Input"/>
</Button>
<Button x:DataType="vm:MainViewModel"
DataContext="{Binding #Root.DataContext}"
Command="{Binding CopyHistoryOutputCommand}"
CommandParameter="{Binding #HistoryRow.DataContext}"
AutomationProperties.Name="Copy output"
Background="Transparent" BorderThickness="0" Padding="8,4">
<TextBlock Text="Copy Output"/>
</Button>
<Button x:DataType="vm:MainViewModel"
DataContext="{Binding #Root.DataContext}"
Command="{Binding CopyHistoryBothCommand}"
CommandParameter="{Binding #HistoryRow.DataContext}"
AutomationProperties.Name="Copy input and output"
Background="Transparent" BorderThickness="0" Padding="8,4">
<TextBlock Text="Copy Input = Output"/>
</Button>
</StackPanel>
</Flyout>
</Button.Flyout>
<TextBlock Text="Copy"/>
</Button>
<!-- Context menu for right-click / long-press (Android) -->
<Grid.ContextMenu>
<ContextMenu>
<MenuItem x:DataType="vm:MainViewModel"
DataContext="{Binding #Root.DataContext}"
Header="Copy Input"
Command="{Binding CopyHistoryInputCommand}"
CommandParameter="{Binding #HistoryRow.DataContext}"
/>
<MenuItem x:DataType="vm:MainViewModel"
DataContext="{Binding #Root.DataContext}"
Header="Copy Output"
Command="{Binding CopyHistoryOutputCommand}"
CommandParameter="{Binding #HistoryRow.DataContext}"
/>
<MenuItem x:DataType="vm:MainViewModel"
DataContext="{Binding #Root.DataContext}"
Header="Copy Input = Output"
Command="{Binding CopyHistoryBothCommand}"
CommandParameter="{Binding #HistoryRow.DataContext}"
/>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock Text="No history yet. Enter an expression and Evaluate."
IsVisible="{Binding History.Count, Converter={StaticResource IsZeroConverter}}"
IsHitTestVisible="False"
Opacity="0.6"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<!-- Input Row -->
<Grid Grid.Row="1" ColumnDefinitions="Auto,Auto,*,Auto" Margin="4">