diff --git a/Gen3Hex/Gen3Hex.csproj b/Gen3Hex/Gen3Hex.csproj
index d21e431d..cf2b278f 100644
--- a/Gen3Hex/Gen3Hex.csproj
+++ b/Gen3Hex/Gen3Hex.csproj
@@ -68,7 +68,14 @@
+
+ AboutWindow.xaml
+
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
@@ -96,6 +103,7 @@
+
\ No newline at end of file
diff --git a/Gen3Hex/Model/IFileSystem.cs b/Gen3Hex/Model/IFileSystem.cs
index c9890996..8811ac8d 100644
--- a/Gen3Hex/Model/IFileSystem.cs
+++ b/Gen3Hex/Model/IFileSystem.cs
@@ -1,5 +1,7 @@
namespace HavenSoft.Gen3Hex.Model {
public interface IFileSystem {
+ string CopyText { get; set; }
+
///
/// Have the filesystem ask the user for a new name for a file.
/// If no extensionOptions are provided, the user may specify any extension.
diff --git a/Gen3Hex/View/AboutWindow.xaml b/Gen3Hex/View/AboutWindow.xaml
new file mode 100644
index 00000000..2ddf7114
--- /dev/null
+++ b/Gen3Hex/View/AboutWindow.xaml
@@ -0,0 +1,27 @@
+
+
+
+ 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.
+
+
+
+
+
+
+ MIT License
+
+
+ Solarized
+
+
+
+
diff --git a/Gen3Hex/View/AboutWindow.xaml.cs b/Gen3Hex/View/AboutWindow.xaml.cs
new file mode 100644
index 00000000..baddc078
--- /dev/null
+++ b/Gen3Hex/View/AboutWindow.xaml.cs
@@ -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;
+ }
+ }
+}
diff --git a/Gen3Hex/View/MainWindow.xaml b/Gen3Hex/View/MainWindow.xaml
index c23e7424..d532b32c 100644
--- a/Gen3Hex/View/MainWindow.xaml
+++ b/Gen3Hex/View/MainWindow.xaml
@@ -20,7 +20,9 @@
-
+
+
+
true
@@ -30,6 +32,7 @@
+
@@ -95,6 +98,11 @@
+
+
+
+
+
@@ -103,6 +111,11 @@
+
diff --git a/Gen3Hex/View/MainWindow.xaml.cs b/Gen3Hex/View/MainWindow.xaml.cs
index 17d44e0a..02b6995d 100644
--- a/Gen3Hex/View/MainWindow.xaml.cs
+++ b/Gen3Hex/View/MainWindow.xaml.cs
@@ -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();
diff --git a/Gen3Hex/View/WindowsFileSystem.cs b/Gen3Hex/View/WindowsFileSystem.cs
index 4458c579..bfa9e425 100644
--- a/Gen3Hex/View/WindowsFileSystem.cs
+++ b/Gen3Hex/View/WindowsFileSystem.cs
@@ -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();
diff --git a/Gen3Hex/ViewModel/EditorViewModel.cs b/Gen3Hex/ViewModel/EditorViewModel.cs
index 4b3e7c35..3dec8f56 100644
--- a/Gen3Hex/ViewModel/EditorViewModel.cs
+++ b/Gen3Hex/ViewModel/EditorViewModel.cs
@@ -11,7 +11,7 @@ namespace HavenSoft.Gen3Hex.ViewModel {
private readonly IFileSystem fileSystem;
private readonly List 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, 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);
diff --git a/Gen3Hex/ViewModel/ITabContent.cs b/Gen3Hex/ViewModel/ITabContent.cs
index c84eadca..4edabff4 100644
--- a/Gen3Hex/ViewModel/ITabContent.cs
+++ b/Gen3Hex/ViewModel/ITabContent.cs
@@ -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; }
diff --git a/Gen3Hex/ViewModel/ViewPort.cs b/Gen3Hex/ViewModel/ViewPort.cs
index 019475b9..58b4e1dd 100644
--- a/Gen3Hex/ViewModel/ViewPort.cs
+++ b/Gen3Hex/ViewModel/ViewPort.cs
@@ -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 {
///
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>(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),
diff --git a/Gen3Hex/snorlax.png b/Gen3Hex/snorlax.png
new file mode 100644
index 00000000..3492d6ff
Binary files /dev/null and b/Gen3Hex/snorlax.png differ
diff --git a/HexTests/ViewPortEditTests.cs b/HexTests/ViewPortEditTests.cs
index 2446642d..fc139df9 100644
--- a/HexTests/ViewPortEditTests.cs
+++ b/HexTests/ViewPortEditTests.cs
@@ -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);
+ }
}
}