Skip to content

Commit e9e5f97

Browse files
authored
Changed the Base64 Image tool to use the Code editor instead of a Text box (#532)
* Changed the Base64 Image tool to use the Code editor instead of a Text box * Fixed keyboard navigation
1 parent cbf688e commit e9e5f97

File tree

8 files changed

+95
-26
lines changed

8 files changed

+95
-26
lines changed

src/dev/impl/DevToys/DevToys.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
<Compile Include="ViewModels\Tools\Converters\Timestamp\TimestampToolViewModel.cs" />
9999
<Compile Include="ViewModels\Tools\EncodersDecoders\Base64ImageEncoderDecoder\Base64ImageEncoderDecoderToolProvider.cs" />
100100
<Compile Include="ViewModels\Tools\EncodersDecoders\Base64ImageEncoderDecoder\Base64ImageEncoderDecoderToolViewModel.cs" />
101+
<Compile Include="ViewModels\Tools\EncodersDecoders\Base64ImageEncoderDecoder\MockSettingsProvider.cs" />
101102
<Compile Include="ViewModels\Tools\EncodersDecoders\GZipEncoderDecoder\GZipEncoderDecoderToolProvider.cs" />
102103
<Compile Include="ViewModels\Tools\EncodersDecoders\GZipEncoderDecoder\GZipEncoderDecoderToolViewModel.cs" />
103104
<Compile Include="Helpers\JsonYaml\Core\DecimalJsonConverter.cs" />

src/dev/impl/DevToys/UI/Controls/CodeEditor.xaml

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<converters:NullToVisibilityConverter x:Key="InvertedNullToVisibilityConverter" IsInverted="True"/>
1818
<converters:InvertedBooleanConverter x:Key="InvertedBooleanConverter"/>
1919
<converters:BooleanToTextWrappingConverter x:Key="BooleanToTextWrappingConverter" TextWrappingOnTrue="Wrap" TextWrappingOnFalse="NoWrap"/>
20+
<converters:BooleanToIntegerConverter x:Key="ReadOnlyToClearButtonTabIndexConverter" ValueOnTrue="3" ValueOnFalse="0"/>
2021
</UserControl.Resources>
2122

2223
<Grid>
@@ -46,7 +47,6 @@
4647
Grid.Column="1"
4748
Orientation="Horizontal"
4849
HorizontalAlignment="Right"
49-
Spacing="8"
5050
Margin="0,0,0,8"
5151
AutomationProperties.LabeledBy="{x:Bind HeaderTextBlock}">
5252
<Button
@@ -66,25 +66,17 @@
6666
x:DeferLoadStrategy="Lazy"
6767
Visibility="Collapsed"
6868
TabIndex="0"
69+
Margin="8,0,0,0"
6970
ToolTipService.ToolTip="{Binding Instance.Common.OpenFile, Mode=OneTime, Source={StaticResource LanguageManager}}"
7071
AutomationProperties.Name="{Binding Instance.Common.OpenFile, Mode=OneTime, Source={StaticResource LanguageManager}}"
7172
Click="OpenFileButton_Click">
7273
<FontIcon Glyph="&#xF378;"/>
7374
</Button>
74-
<Button
75-
x:Name="ClearButton"
76-
x:DeferLoadStrategy="Lazy"
77-
Visibility="Collapsed"
78-
TabIndex="0"
79-
ToolTipService.ToolTip="{Binding Instance.Common.Clear, Mode=OneTime, Source={StaticResource LanguageManager}}"
80-
AutomationProperties.Name="{Binding Instance.Common.Clear, Mode=OneTime, Source={StaticResource LanguageManager}}"
81-
Click="ClearButton_Click">
82-
<FontIcon Glyph="&#xF369;"/>
83-
</Button>
8475
<Button
8576
x:Name="CopyButton"
8677
x:DeferLoadStrategy="Lazy"
87-
TabIndex="2"
78+
TabIndex="{x:Bind IsReadOnly, Mode=OneWay, Converter={StaticResource ReadOnlyToClearButtonTabIndexConverter}}"
79+
Margin="8,0,0,0"
8880
Visibility="Collapsed"
8981
AutomationProperties.Name="{Binding Instance.Common.Copy, Mode=OneTime, Source={StaticResource LanguageManager}}"
9082
Click="CopyButton_Click">
@@ -93,6 +85,17 @@
9385
<TextBlock VerticalAlignment="Center" Text="{Binding Instance.Common.Copy, Mode=OneTime, Source={StaticResource LanguageManager}}"/>
9486
</StackPanel>
9587
</Button>
88+
<Button
89+
x:Name="ClearButton"
90+
x:DeferLoadStrategy="Lazy"
91+
Visibility="Collapsed"
92+
TabIndex="{x:Bind IsReadOnly, Mode=OneWay, Converter={StaticResource ReadOnlyToClearButtonTabIndexConverter}}"
93+
Margin="8,0,0,0"
94+
ToolTipService.ToolTip="{Binding Instance.Common.Clear, Mode=OneTime, Source={StaticResource LanguageManager}}"
95+
AutomationProperties.Name="{Binding Instance.Common.Clear, Mode=OneTime, Source={StaticResource LanguageManager}}"
96+
Click="ClearButton_Click">
97+
<FontIcon Glyph="&#xF369;"/>
98+
</Button>
9699
</StackPanel>
97100
<Grid
98101
x:Name="CodeEditorCoreContainer"

src/dev/impl/DevToys/UI/Controls/CodeEditor.xaml.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ public bool IsReadOnly
8585
set => SetValue(IsReadOnlyProperty, value);
8686
}
8787

88+
public static readonly DependencyProperty CanCopyWhenNotReadOnlyProperty
89+
= DependencyProperty.Register(
90+
nameof(CanCopyWhenNotReadOnly),
91+
typeof(bool),
92+
typeof(CodeEditor),
93+
new PropertyMetadata(false, OnIsReadOnlyPropertyChangedCalled));
94+
95+
public bool CanCopyWhenNotReadOnly
96+
{
97+
get => (bool)GetValue(CanCopyWhenNotReadOnlyProperty);
98+
set => SetValue(CanCopyWhenNotReadOnlyProperty, value);
99+
}
100+
88101
public static DependencyProperty CodeLanguageProperty { get; }
89102
= DependencyProperty.Register(
90103
nameof(CodeLanguage),
@@ -301,6 +314,7 @@ private CodeEditorCore ReloadCodeEditorCore()
301314
_codeEditorCore = new CodeEditorCore();
302315
_codeEditorCore.EditorLoading += CodeEditorCore_Loading;
303316
_codeEditorCore.InternalException += CodeEditorCore_InternalException;
317+
_codeEditorCore.TabIndex = 0;
304318

305319
_codeEditorCore.SetBinding(
306320
CodeEditorCore.CodeLanguageProperty,
@@ -406,14 +420,19 @@ private void UpdateUI()
406420
}
407421
else
408422
{
409-
if (CopyButton is not null)
423+
if (CanCopyWhenNotReadOnly)
424+
{
425+
GetCopyButton().Visibility = Visibility.Visible;
426+
}
427+
else if (CopyButton is not null)
410428
{
411429
CopyButton.Visibility = Visibility.Collapsed;
412430
}
413431

414432
GetPasteButton().Visibility = Visibility.Visible;
415433
GetOpenFileButton().Visibility = Visibility.Visible;
416434
GetClearButton().Visibility = Visibility.Visible;
435+
GetPasteButton().Visibility = Visibility.Visible;
417436
}
418437

419438
if (IsDiffViewMode)

src/dev/impl/DevToys/UI/Controls/CustomTextBox.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
<Button
8787
x:Name="CopyButton"
8888
x:DeferLoadStrategy="Lazy"
89-
TabIndex="2"
89+
TabIndex="{x:Bind IsReadOnly, Mode=OneWay, Converter={StaticResource ReadOnlyToClearButtonTabIndexConverter}}"
9090
Visibility="Collapsed"
9191
AutomationProperties.Name="{Binding Instance.Common.Copy, Mode=OneTime, Source={StaticResource LanguageManager}}"
9292
Click="CopyButton_Click">

src/dev/impl/DevToys/ViewModels/Tools/EncodersDecoders/Base64ImageEncoderDecoder/Base64ImageEncoderDecoderToolViewModel.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
using System.Composition;
66
using System.Diagnostics;
77
using System.IO;
8-
using System.Linq;
98
using System.Runtime.InteropServices.WindowsRuntime;
10-
using System.Text;
119
using System.Threading;
1210
using System.Threading.Tasks;
1311
using DevToys.Api.Core;
@@ -19,11 +17,8 @@
1917
using DevToys.Views.Tools.Base64ImageEncoderDecoder;
2018
using Microsoft.Toolkit.Mvvm.ComponentModel;
2119
using Microsoft.Toolkit.Mvvm.Input;
22-
using Windows.Graphics.Imaging;
2320
using Windows.Storage;
2421
using Windows.Storage.Streams;
25-
using Windows.UI.Xaml.Media;
26-
using Windows.UI.Xaml.Media.Imaging;
2722

2823
namespace DevToys.ViewModels.Tools.Base64ImageEncoderDecoder
2924
{
@@ -44,7 +39,6 @@ private static readonly SettingDefinition<string> Encoder
4439
private readonly object _lockObject = new();
4540
private readonly List<string> _tempFileNames = new();
4641
private readonly IMarketingService _marketingService;
47-
private readonly ISettingsProvider _settingsProvider;
4842

4943
private CancellationTokenSource? _cancellationTokenSource;
5044
private string? _base64Data;
@@ -55,6 +49,8 @@ private static readonly SettingDefinition<string> Encoder
5549

5650
internal Base64ImageEncoderDecoderStrings Strings => LanguageManager.Instance.Base64ImageEncoderDecoder;
5751

52+
internal MockSettingsProvider MockSettingsProvider { get; }
53+
5854
internal string? Base64Data
5955
{
6056
get => _base64Data;
@@ -88,7 +84,7 @@ internal StorageFile? ImageFile
8884
[ImportingConstructor]
8985
public Base64ImageEncoderDecoderToolViewModel(ISettingsProvider settingsProvider, IMarketingService marketingService)
9086
{
91-
_settingsProvider = settingsProvider;
87+
MockSettingsProvider = new MockSettingsProvider(settingsProvider);
9288
_marketingService = marketingService;
9389

9490
FilesSelectedCommand = new RelayCommand<StorageFile[]>(ExecuteFilesSelectedCommand);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#nullable enable
2+
3+
using System;
4+
using System.Diagnostics;
5+
using DevToys.Api.Core.Settings;
6+
using DevToys.Core.Settings;
7+
8+
namespace DevToys.ViewModels.Tools.Base64ImageEncoderDecoder
9+
{
10+
internal class MockSettingsProvider : ISettingsProvider
11+
{
12+
private readonly ISettingsProvider _realSettingsProvider;
13+
14+
public event EventHandler<SettingChangedEventArgs>? SettingChanged;
15+
16+
public MockSettingsProvider(ISettingsProvider realSettingsProvider)
17+
{
18+
_realSettingsProvider = realSettingsProvider;
19+
}
20+
21+
public T GetSetting<T>(SettingDefinition<T> settingDefinition)
22+
{
23+
if (settingDefinition.Name == PredefinedSettings.TextEditorTextWrapping.Name)
24+
{
25+
// Force to wrap the text of the code editor.
26+
Debug.Assert(typeof(T) == typeof(bool));
27+
return (T)(object)true;
28+
}
29+
else if (settingDefinition.Name == PredefinedSettings.TextEditorLineNumbers.Name)
30+
{
31+
// Force to hide the line numbers of the code editor.
32+
Debug.Assert(typeof(T) == typeof(bool));
33+
return (T)(object)false;
34+
}
35+
36+
return _realSettingsProvider.GetSetting(settingDefinition);
37+
}
38+
39+
public void ResetSetting<T>(SettingDefinition<T> settingDefinition)
40+
{
41+
throw new NotImplementedException();
42+
}
43+
44+
public void SetSetting<T>(SettingDefinition<T> settingDefinition, T value)
45+
{
46+
throw new NotImplementedException();
47+
}
48+
}
49+
}

src/dev/impl/DevToys/Views/Tools/EncodersDecoders/Base64ImageEncoderDecoder/Base64ImageEncoderDecoderToolPage.xaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
xmlns:ex="using:DevToys.UI.Extensions"
99
xmlns:toolkit="using:Microsoft.Toolkit.Uwp.UI.Controls"
1010
mc:Ignorable="d"
11-
NavigationCacheMode="Disabled">
11+
NavigationCacheMode="Required">
1212

1313
<Grid x:Name="RootGrid" RowSpacing="12" Margin="0,0,0,16">
1414
<VisualStateManager.VisualStateGroups>
@@ -61,17 +61,17 @@
6161
<RowDefinition MinHeight="100"/>
6262
</Grid.RowDefinitions>
6363

64-
<controls:CustomTextBox
64+
<controls:CodeEditor
6565
x:Name="Base64TextEditor"
6666
Grid.Column="0"
6767
Grid.Row="0"
6868
Grid.RowSpan="3"
6969
MinHeight="150"
70-
AcceptsReturn="True"
71-
IsRichTextEdit="True"
7270
CanCopyWhenNotReadOnly="True"
7371
Header="{x:Bind ViewModel.Strings.Base64InputTitle}"
74-
Text="{x:Bind ViewModel.Base64Data, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
72+
SettingsProvider="{x:Bind ViewModel.MockSettingsProvider}"
73+
Text="{x:Bind ViewModel.Base64Data, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
74+
CodeLanguage="text"/>
7575

7676
<toolkit:GridSplitter
7777
x:Name="VerticalGridSplitter"

src/dev/impl/DevToys/Views/Tools/Text/StringUtilities/StringUtilitiesToolPage.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
Header="{x:Bind ViewModel.Strings.String}"
5858
AcceptsReturn="True"
5959
IsRichTextEdit="False"
60+
CanCopyWhenNotReadOnly="True"
6061
Text="{x:Bind ViewModel.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
6162
SelectionStart="{x:Bind ViewModel.SelectionStart, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
6263

0 commit comments

Comments
 (0)