The previous fix put AcceptsReturn on the rows in the DataTemplate and missed the box you actually type new notes into, which still had it off and only a KeyBinding for Enter — so Shift+Enter there did nothing. Both now go through the same tunnel handler: Enter files the note, Shift+Enter is left to the TextBox for the line break. The KeyBinding is gone; with AcceptsReturn on it could never have fired anyway, because TextBox consumes Enter in its own OnKeyDown before bindings or bubbling handlers run. Verified against the running app: a note typed with Shift+Enter is stored as "fe\r\ndwa". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
114 lines
5.5 KiB
XML
114 lines
5.5 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:ClaudeDo.Ui.ViewModels.Islands"
|
|
xmlns:loc="using:ClaudeDo.Ui.Localization"
|
|
x:Class="ClaudeDo.Ui.Views.Islands.NotesEditorView"
|
|
x:DataType="vm:NotesEditorViewModel">
|
|
|
|
<UserControl.Styles>
|
|
<!-- A note reads as text, not as a form field: the box only shows itself under the pointer
|
|
and while it has focus. -->
|
|
<Style Selector="TextBox.note">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
<Setter Property="Padding" Value="4,3"/>
|
|
<Setter Property="MinHeight" Value="0"/>
|
|
</Style>
|
|
<Style Selector="TextBox.note /template/ Border#PART_BorderElement">
|
|
<Setter Property="Background" Value="Transparent"/>
|
|
<Setter Property="BorderThickness" Value="0"/>
|
|
</Style>
|
|
|
|
<Style Selector="Border.note-row">
|
|
<Setter Property="CornerRadius" Value="6"/>
|
|
<Setter Property="Padding" Value="10,1,6,1"/>
|
|
<Setter Property="Margin" Value="4,1"/>
|
|
</Style>
|
|
<Style Selector="Border.note-row:pointerover">
|
|
<Setter Property="Background" Value="{DynamicResource PeatSoftBrush}"/>
|
|
</Style>
|
|
<!-- Row actions stay out of the way until the row is hovered. -->
|
|
<Style Selector="Border.note-row Button.note-del">
|
|
<Setter Property="Opacity" Value="0"/>
|
|
</Style>
|
|
<Style Selector="Border.note-row:pointerover Button.note-del">
|
|
<Setter Property="Opacity" Value="1"/>
|
|
</Style>
|
|
</UserControl.Styles>
|
|
|
|
<DockPanel LastChildFill="True">
|
|
|
|
<!-- Today's capture box: Enter files the note and leaves the caret here for the next one. -->
|
|
<Border DockPanel.Dock="Top" Classes="add-task" Margin="16,14,16,10">
|
|
<Grid ColumnDefinitions="Auto,*,Auto">
|
|
<Border Grid.Column="0" Classes="add-task-plus" VerticalAlignment="Center">
|
|
<PathIcon Width="12" Height="12" Data="{StaticResource Icon.Plus}"
|
|
Foreground="{DynamicResource TextFaintBrush}"/>
|
|
</Border>
|
|
<!-- Enter/Shift+Enter are handled in the code-behind's tunnel handler, same as the note
|
|
rows: a KeyBinding would never fire, because AcceptsReturn makes TextBox consume
|
|
Enter first. -->
|
|
<TextBox Grid.Column="1" x:Name="NewNoteBox" Classes="add-task-input"
|
|
PlaceholderText="{loc:Tr notes.newNotePlaceholder}"
|
|
Text="{Binding NewBulletText, Mode=TwoWay}"
|
|
AcceptsReturn="True" TextWrapping="Wrap"
|
|
VerticalAlignment="Center" Margin="12,0,0,0"/>
|
|
<Border Grid.Column="2" Classes="kbd kbd-enter" VerticalAlignment="Center"
|
|
IsVisible="{Binding #NewNoteBox.IsFocused}">
|
|
<TextBlock Text="{loc:Tr tasks.enterKey}"/>
|
|
</Border>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<Panel>
|
|
<ScrollViewer>
|
|
<ItemsControl x:Name="RowsHost" ItemsSource="{Binding Rows}" Margin="10,0,10,12">
|
|
<ItemsControl.DataTemplates>
|
|
|
|
<DataTemplate DataType="vm:NoteDayHeaderViewModel">
|
|
<TextBlock Classes="eyebrow section-label" Margin="14,12,14,4" Text="{Binding Label}"/>
|
|
</DataTemplate>
|
|
|
|
<DataTemplate DataType="vm:NoteBulletViewModel">
|
|
<Border Classes="note-row">
|
|
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
|
|
<Ellipse Grid.Column="0" Width="4" Height="4" Margin="0,0,10,0"
|
|
VerticalAlignment="Center"
|
|
Fill="{DynamicResource TextFaintBrush}"/>
|
|
<!-- AcceptsReturn/TextWrapping are set here, not in the style above: TextBox
|
|
reads AcceptsReturn in its own OnKeyDown, which runs before any handler a
|
|
style or the XAML could attach. Enter is intercepted in the tunnel phase
|
|
(see code-behind) so the split still wins over the newline. -->
|
|
<TextBox Grid.Column="1" Classes="note" Text="{Binding Text, Mode=TwoWay}"
|
|
AcceptsReturn="True" TextWrapping="Wrap"
|
|
LostFocus="OnBulletLostFocus"/>
|
|
<PathIcon Grid.Column="2" Width="12" Height="12" Margin="6,0"
|
|
VerticalAlignment="Center"
|
|
IsVisible="{Binding FromAgent}"
|
|
ToolTip.Tip="{loc:Tr notes.fromAgentTip}"
|
|
Data="{StaticResource Icon.AgentSuggested}"
|
|
Foreground="{DynamicResource TextFaintBrush}"/>
|
|
<Button Grid.Column="3" Classes="icon-btn note-del"
|
|
VerticalAlignment="Center"
|
|
ToolTip.Tip="{loc:Tr notes.deleteTip}"
|
|
Click="OnDeleteBulletClick">
|
|
<PathIcon Classes="danger" Data="{StaticResource Icon.Trash}" Width="12" Height="12"/>
|
|
</Button>
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
|
|
</ItemsControl.DataTemplates>
|
|
</ItemsControl>
|
|
</ScrollViewer>
|
|
|
|
<TextBlock IsVisible="{Binding IsEmpty}"
|
|
Text="{loc:Tr notes.emptyHint}"
|
|
Foreground="{DynamicResource TextMuteBrush}"
|
|
MaxWidth="260" TextAlignment="Center" TextWrapping="Wrap"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
IsHitTestVisible="False"/>
|
|
</Panel>
|
|
</DockPanel>
|
|
</UserControl>
|