mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-10-02 05:06:35 -05:00
adding cut/copy/paste/delete
adding 'help' to menu, with links to GitHub and credit to Solarized.
This commit is contained in:
@@ -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>
|
||||
@@ -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.
|
||||
|
||||
27
Gen3Hex/View/AboutWindow.xaml
Normal file
27
Gen3Hex/View/AboutWindow.xaml
Normal 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>
|
||||
13
Gen3Hex/View/AboutWindow.xaml.cs
Normal file
13
Gen3Hex/View/AboutWindow.xaml.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}">
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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
BIN
Gen3Hex/snorlax.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user