adding cut/copy/paste/delete

adding 'help' to menu, with links to GitHub and credit to Solarized.
This commit is contained in:
Benjamin Popp
2018-11-11 15:57:30 -06:00
parent 67154009df
commit b65f3eadfb
12 changed files with 151 additions and 2 deletions

View File

@@ -68,7 +68,14 @@
<Compile Include="ViewModel\Selection.cs" />
<Compile Include="ViewModel\ViewModelCore.cs" />
<Compile Include="ViewModel\ViewPort.cs" />
<Compile Include="View\AboutWindow.xaml.cs">
<DependentUpon>AboutWindow.xaml</DependentUpon>
</Compile>
<Compile Include="View\WindowsFileSystem.cs" />
<Page Include="View\AboutWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="View\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -96,6 +103,7 @@
</ItemGroup>
<ItemGroup>
<Resource Include="Snorlax.ico" />
<Resource Include="snorlax.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,5 +1,7 @@
namespace HavenSoft.Gen3Hex.Model {
public interface IFileSystem {
string CopyText { get; set; }
/// <summary>
/// Have the filesystem ask the user for a new name for a file.
/// If no extensionOptions are provided, the user may specify any extension.

View File

@@ -0,0 +1,27 @@
<Window x:Class="HavenSoft.Gen3Hex.View.AboutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:solarized="clr-namespace:Solarized;assembly=HavenSoft"
Background="{DynamicResource Background}"
WindowStyle="ToolWindow"
Title="About Gen3Hex" Height="300" Width="400">
<DockPanel Margin="15">
<TextBlock DockPanel.Dock="Bottom" FontStyle="Italic" TextWrapping="Wrap">
Gen3Hex is a non-profit open-source fan-made tool.
Only use it with legally purchased software.
Pokemon is the property of Nintendo and GameFreak.
Please support the official release.
</TextBlock>
<TextBlock DockPanel.Dock="Top" VerticalAlignment="Center" FontWeight="Bold" Text="Gen3Hex" FontSize="20"/>
<Image Source="..\Snorlax.png" DockPanel.Dock="Left" RenderOptions.BitmapScalingMode="Fant"/>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="Version 1.0.0"/>
<TextBlock>
<Hyperlink Foreground="{solarized:Theme Blue}" NavigateUri="https://github.com/haven1433/gen3hex/blob/master/LICENSE" RequestNavigate="Navigate">MIT License</Hyperlink>
</TextBlock>
<TextBlock>
<Hyperlink Foreground="{solarized:Theme Blue}" NavigateUri="https://ethanschoonover.com/solarized" RequestNavigate="Navigate">Solarized</Hyperlink>
</TextBlock>
</StackPanel>
</DockPanel>
</Window>

View File

@@ -0,0 +1,13 @@
using System.Diagnostics;
using System.Windows.Navigation;
namespace HavenSoft.Gen3Hex.View {
public partial class AboutWindow {
public AboutWindow() => InitializeComponent();
private void Navigate(object sender, RequestNavigateEventArgs e) {
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
}
}

View File

@@ -20,7 +20,9 @@
<KeyBinding Key="Z" Modifiers="Ctrl" Command="{Binding Undo}" />
<KeyBinding Key="Y" Modifiers="Ctrl" Command="{Binding Redo}" />
<KeyBinding Key="Esc" Command="{Binding ClearError}"/>
<KeyBinding Key="X" Modifiers="Ctrl" Command="{Binding Cut}" />
<KeyBinding Key="C" Modifiers="Ctrl" Command="{Binding Copy}" />
<KeyBinding Key="P" Modifiers="Ctrl" Command="{Binding Paste}" />
<KeyBinding Key="G" Modifiers="Ctrl" Command="{Binding ShowGoto}">
<KeyBinding.CommandParameter>
<sys:Boolean>true</sys:Boolean>
@@ -30,6 +32,7 @@
<KeyBinding Key="OemMinus" Modifiers="Ctrl+Shift" Command="{Binding Forward}" />
<KeyBinding Key="T" Modifiers="Ctrl" Command="ToggleBullets" /> <!-- Stealing this routed command for toggling theme -->
<KeyBinding Key="Esc" Command="{Binding ClearError}"/>
</Window.InputBindings>
<Window.CommandBindings>
<CommandBinding Command="ToggleBullets" Executed="ToggleTheme"/>
@@ -95,6 +98,11 @@
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Cu_t" Command="{Binding Cut}" InputGestureText="Ctrl+X"/>
<MenuItem Header="_Copy" Command="{Binding Copy}" InputGestureText="Ctrl+C"/>
<MenuItem Header="_Paste" Command="{Binding Paste}" InputGestureText="Ctrl+V"/>
<MenuItem Header="_Delete" Command="{Binding Delete}" InputGestureText="Del"/>
<Separator />
<MenuItem Header="_Goto" Command="GoToPage" InputGestureText="Ctrl+G"/>
<MenuItem Header="Go _Back" Command="{Binding Back}" InputGestureText="Ctrl+-"/>
<MenuItem Header="Go _Forward" Command="{Binding Forward}" InputGestureText="Ctrl+Shift+-"/>
@@ -103,6 +111,11 @@
<MenuItem Header="_Toggle Theme" Click="ToggleTheme" InputGestureText="Ctrl+T"/>
<MenuItem Header="_Clear Error" Command="{Binding ClearError}" InputGestureText="Esc"/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_Wiki" Click="WikiClick"/>
<MenuItem Header="_Report an Issue" Click="ReportIssueClick"/>
<MenuItem Header="_About" Click="AboutClick"/>
</MenuItem>
</Menu>
</DockPanel>
<TabControl Name="Tabs" ItemsSource="{Binding}" SelectedIndex="{Binding SelectedIndex}">

View File

@@ -102,6 +102,10 @@ namespace HavenSoft.Gen3Hex.View {
if (ViewModel.Count == 0) Close();
}
private void WikiClick(object sender, EventArgs e) => System.Diagnostics.Process.Start("https://github.com/haven1433/gen3hex/wiki");
private void ReportIssueClick(object sender, EventArgs e) => System.Diagnostics.Process.Start("https://github.com/haven1433/gen3hex/issues");
private void AboutClick(object sender, EventArgs e) => new AboutWindow().ShowDialog();
private void GotoBoxVisibilityChanged(object sender, DependencyPropertyChangedEventArgs e) {
if (GotoBox.IsVisible) {
GotoBox.SelectAll();

View File

@@ -6,6 +6,11 @@ using System.Windows;
namespace HavenSoft.Gen3Hex.View {
public class WindowsFileSystem : IFileSystem {
public string CopyText {
get => Clipboard.ContainsText() ? Clipboard.GetText() : string.Empty;
set => Clipboard.SetText(value);
}
public LoadedFile OpenFile(params string[] extensionOptions) {
var dialog = new OpenFileDialog { Filter = CreateFilterFromOptions(extensionOptions) };
var result = dialog.ShowDialog();

View File

@@ -11,7 +11,7 @@ namespace HavenSoft.Gen3Hex.ViewModel {
private readonly IFileSystem fileSystem;
private readonly List<ITabContent> tabs;
private readonly StubCommand newCommand, open, save, saveAs, saveAll, close, closeAll, undo, redo, back, forward, gotoCommand, showGoto, clearError;
private readonly StubCommand newCommand, open, save, saveAs, saveAll, close, closeAll, undo, redo, cut, copy, paste, delete, back, forward, gotoCommand, showGoto, clearError;
private readonly Dictionary<Func<ITabContent, ICommand>, EventHandler> forwardExecuteChangeNotifications;
public ICommand New => newCommand;
@@ -23,6 +23,10 @@ namespace HavenSoft.Gen3Hex.ViewModel {
public ICommand CloseAll => closeAll;
public ICommand Undo => undo;
public ICommand Redo => redo;
public ICommand Cut => cut;
public ICommand Copy => copy;
public ICommand Paste => paste;
public ICommand Delete => delete;
public ICommand Back => back;
public ICommand Forward => forward;
public ICommand Goto => gotoCommand;
@@ -110,6 +114,21 @@ namespace HavenSoft.Gen3Hex.ViewModel {
CanExecute = arg => showError,
Execute = arg => ErrorMessage = string.Empty,
};
cut = new StubCommand {
CanExecute = arg => SelectedTab?.Copy?.CanExecute(arg) ?? false,
Execute = arg => {
if (SelectedTab != null && SelectedTab.Copy != null && SelectedTab.Clear != null) {
SelectedTab.Copy.Execute(fileSystem);
SelectedTab.Clear.Execute();
}
}
};
copy = CreateWrapperForSelected(tab => tab.Copy);
paste = new StubCommand {
CanExecute = arg => SelectedTab is ViewPort,
Execute = arg => (SelectedTab as ViewPort)?.Edit(fileSystem.CopyText),
};
delete = CreateWrapperForSelected(tab => tab.Clear);
save = CreateWrapperForSelected(tab => tab.Save);
saveAs = CreateWrapperForSelected(tab => tab.SaveAs);
saveAll = CreateWrapperForAll(tab => tab.Save);

View File

@@ -11,6 +11,8 @@ namespace HavenSoft.Gen3Hex.ViewModel {
ICommand SaveAs { get; }
ICommand Undo { get; }
ICommand Redo { get; }
ICommand Copy { get; }
ICommand Clear { get; }
ICommand Goto { get; }
ICommand Back { get; }
ICommand Forward { get; }

View File

@@ -8,6 +8,7 @@ using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Input;
namespace HavenSoft.Gen3Hex.ViewModel {
@@ -16,6 +17,9 @@ namespace HavenSoft.Gen3Hex.ViewModel {
/// </summary>
public class ViewPort : ViewModelCore, ITabContent, INotifyCollectionChanged {
private static readonly NotifyCollectionChangedEventArgs ResetArgs = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
private readonly StubCommand
clear = new StubCommand(),
copy = new StubCommand();
private byte[] data;
private HexElement[,] currentView;
@@ -184,6 +188,9 @@ namespace HavenSoft.Gen3Hex.ViewModel {
#endregion
public ICommand Copy => copy;
public ICommand Clear => clear;
public HexElement this[int x, int y] {
get {
if (x < 0 || x >= Width) return HexElement.Undefined;
@@ -214,6 +221,29 @@ namespace HavenSoft.Gen3Hex.ViewModel {
history = new ChangeHistory<Dictionary<int, HexElement>>(RevertChanges);
history.PropertyChanged += HistoryPropertyChanged;
clear.CanExecute = arg => true;
clear.Execute = arg => {
var selectionStart = scroll.ViewPointToDataIndex(selection.SelectionStart);
var selectionEnd = scroll.ViewPointToDataIndex(selection.SelectionEnd);
var left = Math.Min(selectionStart, selectionEnd);
var right = Math.Max(selectionStart, selectionEnd);
for (int i = left; i <= right; i++) data[i] = 0xFF;
RefreshBackingData();
};
copy.CanExecute = arg => true;
copy.Execute = arg => {
var selectionStart = scroll.ViewPointToDataIndex(selection.SelectionStart);
var selectionEnd = scroll.ViewPointToDataIndex(selection.SelectionEnd);
var left = Math.Min(selectionStart, selectionEnd);
var right = Math.Max(selectionStart, selectionEnd);
var buffer = new StringBuilder();
for (int i = left; i <= right; i++) {
buffer.Append(data[i].ToString("X2"));
if (i < right) buffer.Append(" ");
}
((IFileSystem)arg).CopyText = buffer.ToString();
};
save = new StubCommand {
CanExecute = arg => !history.IsSaved,
Execute = arg => SaveExecuted((IFileSystem)arg),

BIN
Gen3Hex/snorlax.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -252,5 +252,31 @@ namespace HavenSoft.HexTests {
Assert.NotEqual(Undefined.Instance, viewPort[0, 4].Format);
Assert.Equal(new Point(1, 4), viewPort.SelectionStart);
}
[Fact]
void CanClearData() {
var loadedFile = new LoadedFile("test", new byte[1000]);
var viewPort = new ViewPort(loadedFile) { Width = 5, Height = 5 };
viewPort.SelectionStart = new Point(0, 0);
viewPort.SelectionEnd = new Point(3, 3);
viewPort.Clear.Execute();
Assert.Equal(0xFF, viewPort[2, 2].Value);
}
[Fact]
void CanCopyData() {
var loadedFile = new LoadedFile("test", new byte[1000]);
var viewPort = new ViewPort(loadedFile) { Width = 5, Height = 5 };
var fileSystem = new StubFileSystem();
viewPort.Edit("Cafe Babe");
viewPort.SelectionStart = new Point(0, 0);
viewPort.SelectionEnd = new Point(3, 0);
viewPort.Copy.Execute(fileSystem);
Assert.Equal("CA FE BA BE", fileSystem.CopyText);
}
}
}