Skip to content

Commit a5fb45a

Browse files
committed
feat: Quick select and copy note text by mouse hover, close #550
1 parent b12b08e commit a5fb45a

File tree

7 files changed

+210
-204
lines changed

7 files changed

+210
-204
lines changed

Ui/Controls/NoteDisplay/NoteDisplayAndEditor.xaml

Lines changed: 48 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
<RowDefinition Height="*"></RowDefinition>
2323
</Grid.RowDefinitions>
2424

25-
<!--you must ignore the click or it will be conflicted with the group drag and drop-->
2625
<Grid RowSpan="2" PreviewMouseDown="Ignore_OnPreviewMouseDown" PreviewMouseMove="Ignore_OnPreviewMouseMove" Background="Transparent"></Grid>
2726

2827
<Border Grid.Row="0" Background="{DynamicResource PrimaryMidBrush}" Height="{StaticResource LauncherGridKeywordHeight}"
@@ -34,12 +33,9 @@
3433
<CornerRadius TopLeft="{StaticResource LauncherOutlineCornerRadius}" TopRight="{StaticResource LauncherOutlineCornerRadius}"></CornerRadius>
3534
</Border.CornerRadius>
3635
<Grid>
37-
<!--you must ignore the click or it will be conflicted with the group drag and drop-->
38-
<Grid PreviewMouseDown="Ignore_OnPreviewMouseDown" PreviewMouseMove="Ignore_OnPreviewMouseMove" Background="Transparent">
39-
<TextBlock Text="{DynamicResource Note}"
40-
FontSize="18" VerticalAlignment="Center" HorizontalAlignment="Center"
41-
Foreground="{DynamicResource PrimaryTextBrush}"></TextBlock>
42-
</Grid>
36+
<TextBlock Text="{DynamicResource Note}"
37+
FontSize="18" VerticalAlignment="Center" HorizontalAlignment="Center"
38+
Foreground="{DynamicResource PrimaryTextBrush}"></TextBlock>
4339

4440
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
4541
<Button Name="ButtonEdit" Width="20" Height="20"
@@ -52,12 +48,11 @@
5248
attachProperty:VisionElement.OpacityAccent="0.9"
5349
Click="ButtonNoteStartEdit_OnClick"
5450
Margin="5 0">
55-
<Grid Width="18">
56-
<Path Data="M804.6 689.8l64-64c10-10 27.4-3 27.4 11.4V928c0 53-43 96-96 96H96c-53 0-96-43-96-96V224c0-53 43-96 96-96h547c14.2 0 21.4 17.2 11.4 27.4l-64 64c-3 3-7 4.6-11.4 4.6H96v704h704V701c0-4.2 1.6-8.2 4.6-11.2z m313.2-403.6L592.6 811.4l-180.8 20c-52.4 5.8-97-38.4-91.2-91.2l20-180.8L865.8 34.2c45.8-45.8 119.8-45.8 165.4 0l86.4 86.4c45.8 45.8 45.8 120 0.2 165.6zM920.2 348L804 231.8 432.4 603.6l-14.6 130.6 130.6-14.6L920.2 348z m129.6-159.4l-86.4-86.4c-8.2-8.2-21.6-8.2-29.6 0L872 164l116.2 116.2 61.8-61.8c8-8.4 8-21.6-0.2-29.8z"
57-
Stroke="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
58-
Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
59-
StrokeThickness="0" Stretch="Uniform" />
60-
</Grid>
51+
<Path Data="M804.6 689.8l64-64c10-10 27.4-3 27.4 11.4V928c0 53-43 96-96 96H96c-53 0-96-43-96-96V224c0-53 43-96 96-96h547c14.2 0 21.4 17.2 11.4 27.4l-64 64c-3 3-7 4.6-11.4 4.6H96v704h704V701c0-4.2 1.6-8.2 4.6-11.2z m313.2-403.6L592.6 811.4l-180.8 20c-52.4 5.8-97-38.4-91.2-91.2l20-180.8L865.8 34.2c45.8-45.8 119.8-45.8 165.4 0l86.4 86.4c45.8 45.8 45.8 120 0.2 165.6zM920.2 348L804 231.8 432.4 603.6l-14.6 130.6 130.6-14.6L920.2 348z m129.6-159.4l-86.4-86.4c-8.2-8.2-21.6-8.2-29.6 0L872 164l116.2 116.2 61.8-61.8c8-8.4 8-21.6-0.2-29.8z"
52+
Width="18"
53+
Stroke="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
54+
Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
55+
StrokeThickness="0" Stretch="Uniform" />
6156
</Button>
6257

6358

@@ -71,12 +66,11 @@
7166
attachProperty:VisionElement.OpacityAccent="0.9"
7267
Click="ButtonClose_OnClick"
7368
Margin="5 0">
74-
<Grid Width="12">
75-
<Path Data="{StaticResource GeometryCloseCross}"
76-
Stroke="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
77-
Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
78-
StrokeThickness="2" Stretch="Uniform" />
79-
</Grid>
69+
<Path Data="{StaticResource GeometryCloseCross}"
70+
Width="12"
71+
Stroke="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
72+
Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=Button}}"
73+
StrokeThickness="2" Stretch="Uniform" />
8074
</Button>
8175
</StackPanel>
8276
</Grid>
@@ -91,57 +85,54 @@
9185
<CommandBinding Command="{x:Static wpf:Commands.Hyperlink}" Executed="OpenHyperlink" />
9286
<CommandBinding Command="{x:Static wpf:Commands.Image}" Executed="ClickOnImage" />
9387
</FrameworkElement.CommandBindings>
94-
<Grid>
95-
<!--you must ignore the click or it will be conflicted with the group drag and drop-->
96-
<Grid PreviewMouseDown="Ignore_OnPreviewMouseDown" PreviewMouseMove="Ignore_OnPreviewMouseMove" Background="Transparent"></Grid>
97-
<Grid Margin="10">
98-
<wpf:MarkdownViewer Name="MarkdownViewer"
99-
PreviewMouseDown="Ignore_OnPreviewMouseDown"
100-
PreviewMouseMove="Ignore_OnPreviewMouseMove"
101-
Foreground="{DynamicResource PrimaryTextBrush}">
102-
</wpf:MarkdownViewer>
103-
104-
<Grid Name="GridEditor">
105-
<Grid.RowDefinitions>
106-
<RowDefinition Height="*"></RowDefinition>
107-
<RowDefinition Height="Auto"></RowDefinition>
108-
</Grid.RowDefinitions>
109-
110-
<!--you must ignore the click or it will be conflicted with the group drag and drop-->
111-
<Grid RowSpan="2" PreviewMouseDown="Ignore_OnPreviewMouseDown" PreviewMouseMove="Ignore_OnPreviewMouseMove" Background="Transparent"></Grid>
112-
113-
114-
<TextBox Grid.Row="0" Name="TbMarkdown" TextWrapping="Wrap" Width="Auto"
115-
MouseWheel="TbMarkdown_OnMouseWheel"
116-
TextAlignment="Left" Margin="0 5"
117-
VerticalContentAlignment="Top"
118-
AcceptsReturn="True"
119-
AcceptsTab="True"
120-
Tag="&#13;# Markdown support&#13;&#13;- write your note here&#13;- foo&#13;&#13;![pic](http://x/structure.png)&#13;&#13;[link](http://x/readme.md)" xml:space="preserve">
121-
</TextBox>
122-
123-
124-
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
125-
<Button Name="ButtonSave"
88+
<Grid Margin="10"
89+
MouseEnter="GridEditor_OnMouseEnter"
90+
MouseLeave="GridEditor_OnMouseLeave"
91+
>
92+
<wpf:MarkdownViewer Name="MarkdownViewer"
93+
PreviewMouseDown="Ignore_OnPreviewMouseDown"
94+
PreviewMouseMove="Ignore_OnPreviewMouseMove"
95+
Foreground="{DynamicResource PrimaryTextBrush}">
96+
</wpf:MarkdownViewer>
97+
98+
<Grid Name="GridEditor">
99+
<Grid.RowDefinitions>
100+
<RowDefinition Height="*"></RowDefinition>
101+
<RowDefinition Height="Auto"></RowDefinition>
102+
</Grid.RowDefinitions>
103+
104+
105+
<TextBox Grid.Row="0" Name="TbMarkdown" TextWrapping="Wrap" Width="Auto"
106+
MouseWheel="TbMarkdown_OnMouseWheel"
107+
PreviewMouseDown="TbMarkdown_OnPreviewMouseDown"
108+
TextAlignment="Left" Margin="0 5"
109+
VerticalContentAlignment="Top"
110+
AcceptsReturn="True"
111+
AcceptsTab="True"
112+
Tag="&#13;# Markdown support&#13;&#13;- write your note here&#13;- foo&#13;&#13;![pic](http://x/structure.png)&#13;&#13;[link](http://x/readme.md)" xml:space="preserve">
113+
</TextBox>
114+
115+
116+
<StackPanel Name="GridButtons" Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
117+
<Button Name="ButtonSave"
126118
Margin="0 0 15 0"
127119
Padding="0 1 0 0" Width="80" Height="25"
128120
HorizontalAlignment="Left"
129121
Click="ButtonSave_OnClick"
130122
Style="{StaticResource ButtonAccentStyle}"
131123
Content="{DynamicResource Save}">
132-
</Button>
124+
</Button>
133125

134-
<Button Padding="0 1 0 0" Width="80" Height="25"
126+
<Button Padding="0 1 0 0" Width="80" Height="25"
135127
Margin="15 0 0 0"
136128
HorizontalAlignment="Right"
137129
Click="ButtonCancelEdit_OnClick"
138130
Style="{StaticResource ButtonPrimaryStyle}"
139131
Content="{DynamicResource Cancel}">
140-
</Button>
141-
</StackPanel>
142-
</Grid>
143-
132+
</Button>
133+
</StackPanel>
144134
</Grid>
135+
145136
</Grid>
146137
</Border>
147138
</Grid>

Ui/Controls/NoteDisplay/NoteDisplayAndEditor.xaml.cs

Lines changed: 90 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Windows.Input;
66
using _1RM.Model;
77
using _1RM.Model.Protocol.Base;
8-
using _1RM.Service.DataSource;
98
using Shawn.Utils;
109
using Shawn.Utils.Wpf;
1110
using Shawn.Utils.Wpf.Controls;
@@ -20,18 +19,17 @@ public partial class NoteDisplayAndEditor : UserControl
2019
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnServerChanged));
2120
private static void OnServerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
2221
{
23-
if (d is NoteDisplayAndEditor control)
22+
if (d is not NoteDisplayAndEditor control) return;
23+
24+
control.SwitchToView(View.Normal);
25+
if (e.OldValue is ProtocolBase server0)
2426
{
25-
control.EndEdit();
26-
if (e.OldValue is ProtocolBase server0)
27-
{
28-
server0.PropertyChanged -= control.ServerOnPropertyChanged;
29-
}
30-
if (e.NewValue is ProtocolBase server1)
31-
{
32-
server1.PropertyChanged += control.ServerOnPropertyChanged;
33-
control.EditEnable = control.EditEnable && server1.DataSource?.IsWritable == true;
34-
}
27+
server0.PropertyChanged -= control.ServerOnPropertyChanged;
28+
}
29+
if (e.NewValue is ProtocolBase server1)
30+
{
31+
server1.PropertyChanged += control.ServerOnPropertyChanged;
32+
control.EditEnable = control.EditEnable && server1.DataSource?.IsWritable == true;
3533
}
3634
}
3735

@@ -49,36 +47,18 @@ public ProtocolBase? Server
4947
set => SetValue(ServerProperty, value);
5048
}
5149

52-
50+
// a callback for save launcher settings
5351
public static readonly DependencyProperty CommandOnCloseRequestProperty = DependencyProperty.Register(
5452
"CommandOnCloseRequest", typeof(RelayCommand), typeof(NoteDisplayAndEditor), new FrameworkPropertyMetadata(default(RelayCommand), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
55-
56-
5753
public RelayCommand CommandOnCloseRequest
5854
{
5955
get => (RelayCommand)GetValue(CommandOnCloseRequestProperty);
6056
set => SetValue(CommandOnCloseRequestProperty, value);
6157
}
6258

63-
public bool CloseEnable { get; set; }
64-
65-
private bool _editEnable;
66-
public bool EditEnable
67-
{
68-
get => _editEnable;
69-
set
70-
{
71-
_editEnable = value;
72-
if (IsLoaded)
73-
{
74-
Execute.OnUIThreadSync(() =>
75-
{
76-
ButtonSave.IsEnabled = EditEnable;
77-
TbMarkdown.IsReadOnly = !EditEnable;
78-
});
79-
}
80-
}
81-
}
59+
public Visibility CloseButtonVisibility { get; set; } = Visibility.Collapsed;
60+
public Visibility EditButtonVisibility { get; set; } = Visibility.Visible;
61+
public bool EditEnable { get; set; }
8262

8363
public NoteDisplayAndEditor()
8464
{
@@ -88,10 +68,7 @@ public NoteDisplayAndEditor()
8868

8969
private void NoteDisplayAndEditor_Loaded(object sender, RoutedEventArgs e)
9070
{
91-
ButtonSave.IsEnabled = EditEnable;
92-
TbMarkdown.IsReadOnly = !EditEnable;
93-
ButtonClose.IsEnabled = CloseEnable;
94-
ButtonClose.Visibility = CloseEnable ? Visibility.Visible : Visibility.Collapsed;
71+
SwitchToView(View.Normal);
9572
}
9673

9774
private void OpenHyperlink(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
@@ -112,7 +89,6 @@ private void OpenHyperlink(object sender, System.Windows.Input.ExecutedRoutedEve
11289

11390
private void ClickOnImage(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
11491
{
115-
//MessageBox.Show($"URL: {e.Parameter}");
11692
try
11793
{
11894
var url = e?.Parameter?.ToString();
@@ -127,40 +103,102 @@ private void ClickOnImage(object sender, System.Windows.Input.ExecutedRoutedEven
127103
}
128104
}
129105

130-
private void EndEdit()
106+
public enum View
131107
{
132-
MarkdownViewer.Markdown = Server?.Note ?? "";
133-
MarkdownViewer.Visibility = Visibility.Visible;
134-
GridEditor.Visibility = Visibility.Collapsed;
108+
Normal,
109+
Editor,
110+
Copy
135111
}
136-
private void StartEdit()
112+
private View? _currentView = null;
113+
public void SwitchToView(NoteDisplayAndEditor.View v)
137114
{
138-
MarkdownViewer.Visibility = Visibility.Collapsed;
139-
GridEditor.Visibility = Visibility.Visible;
115+
if (v == _currentView) return;
116+
ButtonClose.Visibility = CloseButtonVisibility;
117+
ButtonEdit.Visibility = EditButtonVisibility;
118+
Execute.OnUIThreadSync(() =>
119+
{
120+
switch (v)
121+
{
122+
case View.Normal:
123+
MarkdownViewer.Markdown = Server?.Note ?? "";
124+
MarkdownViewer.Visibility = Visibility.Visible;
125+
GridEditor.Visibility = Visibility.Collapsed;
126+
break;
127+
case View.Editor:
128+
TbMarkdown.Text = Server?.Note ?? "";
129+
GridButtons.Visibility = Visibility.Visible;
130+
ButtonSave.IsEnabled = true;
131+
TbMarkdown.IsReadOnly = false;
132+
MarkdownViewer.Visibility = Visibility.Collapsed;
133+
GridEditor.Visibility = Visibility.Visible;
134+
break;
135+
case View.Copy:
136+
if (_currentView == View.Normal)
137+
{
138+
TbMarkdown.Text = Server?.Note ?? "";
139+
// 只能拷贝,不能编辑
140+
GridButtons.Visibility = Visibility.Hidden;
141+
ButtonSave.IsEnabled = false;
142+
TbMarkdown.IsReadOnly = true;
143+
MarkdownViewer.Visibility = Visibility.Collapsed;
144+
GridEditor.Visibility = Visibility.Visible;
145+
}
146+
break;
147+
default:
148+
throw new ArgumentOutOfRangeException(nameof(v), v, null);
149+
}
150+
_currentView = v;
151+
});
140152
}
141153

142154
private void ButtonSave_OnClick(object sender, RoutedEventArgs e)
143155
{
144-
if (EditEnable && Server != null && Server.Note.Trim() != TbMarkdown.Text.Trim())
156+
if (Server?.DataSource?.IsWritable == true
157+
&& Server.Note.Trim() != TbMarkdown.Text.Trim())
145158
{
146159
Server.Note = TbMarkdown.Text.Trim();
147160
IoC.Get<GlobalData>().UpdateServer(Server);
148161
}
149-
EndEdit();
162+
SwitchToView(View.Normal);
150163
}
151164

152165
private void ButtonCancelEdit_OnClick(object sender, RoutedEventArgs e)
153166
{
154-
EndEdit();
167+
SwitchToView(View.Normal);
155168
}
156169

157170
private void ButtonNoteStartEdit_OnClick(object sender, RoutedEventArgs e)
158171
{
159172
TbMarkdown.Text = Server?.Note ?? "";
160-
if (MarkdownViewer.Visibility != Visibility.Collapsed)
161-
StartEdit();
173+
if (Server?.DataSource?.IsWritable == true)
174+
{
175+
SwitchToView(View.Editor);
176+
}
162177
else
163-
EndEdit();
178+
{
179+
SwitchToView(View.Copy);
180+
}
181+
}
182+
183+
private void GridEditor_OnMouseEnter(object sender, MouseEventArgs e)
184+
{
185+
if (_currentView == View.Normal)
186+
SwitchToView(View.Copy);
187+
}
188+
189+
private void GridEditor_OnMouseLeave(object sender, MouseEventArgs e)
190+
{
191+
if (_currentView == View.Copy)
192+
SwitchToView(View.Normal);
193+
}
194+
195+
private void TbMarkdown_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
196+
{
197+
if (_currentView == View.Copy
198+
&& Server?.DataSource?.IsWritable == true)
199+
{
200+
SwitchToView(View.Editor);
201+
}
164202
}
165203

166204
private void ButtonClose_OnClick(object sender, RoutedEventArgs e)

0 commit comments

Comments
 (0)