mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-10-02 05:06:35 -05:00
@@ -7,22 +7,33 @@
|
||||
<!-- Icons accessible using IconExtension -->
|
||||
<hsv:Icons x:Key="Icons"/>
|
||||
|
||||
<!-- Button Style -->
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Padding" Value="3"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource Backlight}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource Backlight}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Name="Border"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
Background="{TemplateBinding Background}">
|
||||
<ContentPresenter/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger SourceName="Border" Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Border" Property="BorderBrush" Value="{solarized:Theme Blue}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Scrollbar style. Based on normal style, but with solarize colors. -->
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Static.Background" Target="Background"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.MouseOver.Background" Target="Background"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Pressed.Background" Target="Background"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Disabled.Background" Target="Background"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Pressed.Glyph" Target="Primary"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.MouseOver.Glyph" Target="Primary"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Disabled.Glyph" Target="Primary"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Static.Glyph" Target="Primary"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Static.Border" Target="Backlight"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.MouseOver.Border" Target="Backlight"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Pressed.Border" Target="Backlight"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Disabled.Border" Target="Backlight"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.MouseOver.Thumb" Target="Secondary"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Pressed.Thumb" Target="Secondary"/>
|
||||
<solarized:ThemeExtension x:Key="ScrollBar.Static.Thumb" Target="Secondary"/>
|
||||
<Style x:Key="FocusVisual">
|
||||
<Setter Property="Control.Template">
|
||||
<Setter.Value>
|
||||
@@ -43,22 +54,22 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type RepeatButton}">
|
||||
<Border x:Name="border" BorderBrush="{StaticResource ScrollBar.Static.Border}" BorderThickness="1" Background="{StaticResource ScrollBar.Static.Background}" SnapsToDevicePixels="true">
|
||||
<Border x:Name="border" BorderBrush="{DynamicResource Backlight}" BorderThickness="1" Background="{DynamicResource Background}" SnapsToDevicePixels="true">
|
||||
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="Background" TargetName="border" Value="{StaticResource ScrollBar.MouseOver.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource ScrollBar.MouseOver.Border}"/>
|
||||
<Setter Property="Background" TargetName="border" Value="{DynamicResource Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Backlight}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter Property="Background" TargetName="border" Value="{StaticResource ScrollBar.Pressed.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource ScrollBar.Pressed.Border}"/>
|
||||
<Setter Property="Background" TargetName="border" Value="{DynamicResource Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Backlight}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.56"/>
|
||||
<Setter Property="Background" TargetName="border" Value="{StaticResource ScrollBar.Disabled.Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource ScrollBar.Disabled.Border}"/>
|
||||
<Setter Property="Background" TargetName="border" Value="{DynamicResource Background}"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Backlight}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
@@ -84,13 +95,13 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Rectangle x:Name="rectangle" Fill="{StaticResource ScrollBar.Static.Thumb}" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}"/>
|
||||
<Rectangle x:Name="rectangle" Fill="{DynamicResource Secondary}" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}"/>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{StaticResource ScrollBar.MouseOver.Thumb}"/>
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource Secondary}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsDragging" Value="true">
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{StaticResource ScrollBar.Pressed.Thumb}"/>
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource Secondary}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
@@ -103,13 +114,13 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Rectangle x:Name="rectangle" Fill="{StaticResource ScrollBar.Static.Thumb}" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}"/>
|
||||
<Rectangle x:Name="rectangle" Fill="{DynamicResource Secondary}" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}"/>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{StaticResource ScrollBar.MouseOver.Thumb}"/>
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource Secondary}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsDragging" Value="true">
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{StaticResource ScrollBar.Pressed.Thumb}"/>
|
||||
<Setter Property="Fill" TargetName="rectangle" Value="{DynamicResource Secondary}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
@@ -119,9 +130,9 @@
|
||||
<Style TargetType="{x:Type ScrollBar}">
|
||||
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
|
||||
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
|
||||
<Setter Property="Background" Value="{StaticResource ScrollBar.Static.Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource ScrollBar.Static.Border}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource Backlight}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource Primary}"/>
|
||||
<Setter Property="BorderThickness" Value="1,0"/>
|
||||
<Setter Property="Width" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
|
||||
<Setter Property="MinWidth" Value="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"/>
|
||||
@@ -136,7 +147,7 @@
|
||||
</Grid.RowDefinitions>
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Row="1"/>
|
||||
<RepeatButton x:Name="PART_LineUpButton" Command="{x:Static ScrollBar.LineUpCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}">
|
||||
<Path x:Name="ArrowTop" Data="M 0,4 C0,4 0,6 0,6 0,6 3.5,2.5 3.5,2.5 3.5,2.5 7,6 7,6 7,6 7,4 7,4 7,4 3.5,0.5 3.5,0.5 3.5,0.5 0,4 0,4 z" Fill="{StaticResource ScrollBar.Static.Glyph}" Margin="3,4,3,3" Stretch="Uniform"/>
|
||||
<Path x:Name="ArrowTop" Data="M 0,4 C0,4 0,6 0,6 0,6 3.5,2.5 3.5,2.5 3.5,2.5 7,6 7,6 7,6 7,4 7,4 7,4 3.5,0.5 3.5,0.5 3.5,0.5 0,4 0,4 z" Fill="{DynamicResource Primary}" Margin="3,4,3,3" Stretch="Uniform"/>
|
||||
</RepeatButton>
|
||||
<Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="1">
|
||||
<Track.DecreaseRepeatButton>
|
||||
@@ -150,7 +161,7 @@
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
<RepeatButton x:Name="PART_LineDownButton" Command="{x:Static ScrollBar.LineDownCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="2" Style="{StaticResource ScrollBarButton}">
|
||||
<Path x:Name="ArrowBottom" Data="M 0,2.5 C0,2.5 0,0.5 0,0.5 0,0.5 3.5,4 3.5,4 3.5,4 7,0.5 7,0.5 7,0.5 7,2.5 7,2.5 7,2.5 3.5,6 3.5,6 3.5,6 0,2.5 0,2.5 z" Fill="{StaticResource ScrollBar.Static.Glyph}" Margin="3,4,3,3" Stretch="Uniform"/>
|
||||
<Path x:Name="ArrowBottom" Data="M 0,2.5 C0,2.5 0,0.5 0,0.5 0,0.5 3.5,4 3.5,4 3.5,4 7,0.5 7,0.5 7,0.5 7,2.5 7,2.5 7,2.5 3.5,6 3.5,6 3.5,6 0,2.5 0,2.5 z" Fill="{DynamicResource Primary}" Margin="3,4,3,3" Stretch="Uniform"/>
|
||||
</RepeatButton>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
@@ -159,32 +170,32 @@
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineDownButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineDownButton}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowBottom" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowBottom" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineUpButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineUpButton}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowTop" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowTop" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineDownButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineDownButton}" Value="false"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowBottom" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowBottom" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineUpButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineUpButton}" Value="false"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowTop" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowTop" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Fill" TargetName="ArrowTop" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowBottom" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowTop" Value="{DynamicResource Primary}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowBottom" Value="{DynamicResource Primary}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
@@ -208,7 +219,7 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1"/>
|
||||
<RepeatButton x:Name="PART_LineLeftButton" Command="{x:Static ScrollBar.LineLeftCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}">
|
||||
<Path x:Name="ArrowLeft" Data="M 3.18,7 C3.18,7 5,7 5,7 5,7 1.81,3.5 1.81,3.5 1.81,3.5 5,0 5,0 5,0 3.18,0 3.18,0 3.18,0 0,3.5 0,3.5 0,3.5 3.18,7 3.18,7 z" Fill="{StaticResource ScrollBar.Static.Glyph}" Margin="3" Stretch="Uniform"/>
|
||||
<Path x:Name="ArrowLeft" Data="M 3.18,7 C3.18,7 5,7 5,7 5,7 1.81,3.5 1.81,3.5 1.81,3.5 5,0 5,0 5,0 3.18,0 3.18,0 3.18,0 0,3.5 0,3.5 0,3.5 3.18,7 3.18,7 z" Fill="{DynamicResource Primary}" Margin="3" Stretch="Uniform"/>
|
||||
</RepeatButton>
|
||||
<Track x:Name="PART_Track" Grid.Column="1" IsEnabled="{TemplateBinding IsMouseOver}">
|
||||
<Track.DecreaseRepeatButton>
|
||||
@@ -222,7 +233,7 @@
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
<RepeatButton x:Name="PART_LineRightButton" Grid.Column="2" Command="{x:Static ScrollBar.LineRightCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Style="{StaticResource ScrollBarButton}">
|
||||
<Path x:Name="ArrowRight" Data="M 1.81,7 C1.81,7 0,7 0,7 0,7 3.18,3.5 3.18,3.5 3.18,3.5 0,0 0,0 0,0 1.81,0 1.81,0 1.81,0 5,3.5 5,3.5 5,3.5 1.81,7 1.81,7 z" Fill="{StaticResource ScrollBar.Static.Glyph}" Margin="3" Stretch="Uniform"/>
|
||||
<Path x:Name="ArrowRight" Data="M 1.81,7 C1.81,7 0,7 0,7 0,7 3.18,3.5 3.18,3.5 3.18,3.5 0,0 0,0 0,0 1.81,0 1.81,0 1.81,0 5,3.5 5,3.5 5,3.5 1.81,7 1.81,7 z" Fill="{DynamicResource Primary}" Margin="3" Stretch="Uniform"/>
|
||||
</RepeatButton>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
@@ -231,32 +242,32 @@
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineRightButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineRightButton}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowRight" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowRight" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineLeftButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineLeftButton}" Value="true"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowLeft" Value="{StaticResource ScrollBar.Pressed.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowLeft" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineRightButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineRightButton}" Value="false"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowRight" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowRight" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<MultiDataTrigger>
|
||||
<MultiDataTrigger.Conditions>
|
||||
<Condition Binding="{Binding IsMouseOver, ElementName=PART_LineLeftButton}" Value="true"/>
|
||||
<Condition Binding="{Binding IsPressed, ElementName=PART_LineLeftButton}" Value="false"/>
|
||||
</MultiDataTrigger.Conditions>
|
||||
<Setter Property="Fill" TargetName="ArrowLeft" Value="{StaticResource ScrollBar.MouseOver.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowLeft" Value="{DynamicResource Primary}"/>
|
||||
</MultiDataTrigger>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
<Setter Property="Fill" TargetName="ArrowLeft" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowRight" Value="{StaticResource ScrollBar.Disabled.Glyph}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowLeft" Value="{DynamicResource Primary}"/>
|
||||
<Setter Property="Fill" TargetName="ArrowRight" Value="{DynamicResource Primary}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
@@ -267,10 +278,9 @@
|
||||
</Style>
|
||||
|
||||
<!-- Menu style -->
|
||||
<solarized:ThemeExtension x:Key="Menu.Static.Background" Target="Background"/>
|
||||
<Style TargetType="{x:Type Menu}">
|
||||
<Setter Property="Background" Value="{StaticResource Menu.Static.Background}"/>
|
||||
<Setter Property="Foreground" Value="{solarized:Theme Primary}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource Background}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource Primary}"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type MenuItem}">
|
||||
@@ -280,18 +290,16 @@
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type MenuItem}">
|
||||
<Grid Name="ItemBorder">
|
||||
<ContentPresenter Margin="10,2" ContentSource="Header" RecognizesAccessKey="True" TextBlock.Foreground="{solarized:Theme Emphasis}"/>
|
||||
<Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsSubmenuOpen}">
|
||||
<Border x:Name="SubmenuBorder" BorderThickness="1"
|
||||
Background="{solarized:Theme Background}"
|
||||
BorderBrush="{solarized:Theme Blue}">
|
||||
<ContentPresenter Margin="10,2" ContentSource="Header" RecognizesAccessKey="True" TextBlock.Foreground="{DynamicResource Emphasis}"/>
|
||||
<Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsSubmenuOpen}" SnapsToDevicePixels="True">
|
||||
<Border x:Name="SubmenuBorder" BorderThickness="1" Background="{DynamicResource Background}" BorderBrush="{solarized:Theme Blue}">
|
||||
<StackPanel Name="ItemsPresenter" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
|
||||
</Border>
|
||||
</Popup>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="ItemBorder" Property="Background" Value="{solarized:Theme Backlight}" />
|
||||
<Setter TargetName="ItemBorder" Property="Background" Value="{DynamicResource Backlight}" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
@@ -309,15 +317,15 @@
|
||||
<ColumnDefinition Width="100"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentPresenter Grid.Column="0" Margin="5,5,0,5" ContentSource="Icon" />
|
||||
<ContentPresenter Grid.Column="1" Name="MainContent" Margin="10,5" VerticalAlignment="Center" ContentSource="Header" RecognizesAccessKey="True" TextBlock.Foreground="{solarized:Theme Emphasis}" />
|
||||
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{TemplateBinding InputGestureText}" Foreground="{solarized:Theme Secondary}" />
|
||||
<ContentPresenter Grid.Column="1" Name="MainContent" Margin="10,5" VerticalAlignment="Center" ContentSource="Header" RecognizesAccessKey="True" TextBlock.Foreground="{DynamicResource Emphasis}" />
|
||||
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{TemplateBinding InputGestureText}" Foreground="{DynamicResource Secondary}" />
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="ItemBorder" Property="Background" Value="{solarized:Theme Backlight}" />
|
||||
<Setter TargetName="ItemBorder" Property="Background" Value="{DynamicResource Backlight}" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="MainContent" Property="TextBlock.Foreground" Value="{solarized:Theme Secondary}" />
|
||||
<Setter TargetName="MainContent" Property="TextBlock.Foreground" Value="{DynamicResource Secondary}" />
|
||||
<Setter TargetName="MainContent" Property="TextBlock.FontStyle" Value="Italic" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
@@ -328,35 +336,56 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type Separator}">
|
||||
<Setter Property="Background" Value="{solarized:Theme Background}"/>
|
||||
<!-- Separator Style has to specify that it's the style to use for MenuItems. This has something to do with the Menu searching for this key. -->
|
||||
<Style TargetType="{x:Type Separator}" x:Key="{x:Static MenuItem.SeparatorStyleKey}">
|
||||
<Setter Property="Background" Value="{DynamicResource Secondary}"/>
|
||||
<Setter Property="Margin" Value="0,2"/>
|
||||
<Setter Property="Focusable" Value="false"/>
|
||||
<Setter Property="BorderBrush" Value="{solarized:Theme Secondary}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource Secondary}"/>
|
||||
</Style>
|
||||
|
||||
<!-- TextBlock Style-->
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource Primary}"/>
|
||||
</Style>
|
||||
|
||||
<!-- TextBox Style -->
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="Background" Value="{DynamicResource Backlight}"/>
|
||||
<Setter Property="BorderBrush" Value="{solarized:Theme Blue}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource Primary}"/>
|
||||
<Setter Property="SelectionBrush" Value="{solarized:Theme Blue}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="TextBox">
|
||||
<Border Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
|
||||
<ScrollViewer Foreground="{TemplateBinding Foreground}" x:Name="PART_ContentHost" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- TabContol Styles -->
|
||||
<solarized:ThemeExtension x:Key="TabItem.Selected.Background" Target="Background"/>
|
||||
<solarized:ThemeExtension x:Key="TabItem.Selected.Border" Target="Background"/>
|
||||
<Style TargetType="{x:Type TabControl}">
|
||||
<Setter Property="Padding" Value="2"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Background" Value="{StaticResource TabItem.Selected.Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource TabItem.Selected.Border}"/>
|
||||
<Setter Property="Background" Value="{DynamicResource Background}"/>
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource Background}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Foreground" Value="{solarized:Theme Primary}"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource Primary}"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type TabItem}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type TabItem}">
|
||||
<Border Name="OuterBorder" BorderThickness="0,0,1,0" BorderBrush="{solarized:Theme Background}">
|
||||
<Border Name="OuterBorder" BorderThickness="0,0,1,0" BorderBrush="{DynamicResource Background}">
|
||||
<!-- used for the 1-pixel spacing between tabs -->
|
||||
<Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="{solarized:Theme Backlight}" Background="{solarized:Theme Backlight}">
|
||||
<Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="{DynamicResource Backlight}" Background="{DynamicResource Backlight}">
|
||||
<!-- used for selection -->
|
||||
<Border Name="InnerBorder" BorderThickness="1,1,1,0" Padding="5,3" BorderBrush="{solarized:Theme Backlight}">
|
||||
<Border Name="InnerBorder" BorderThickness="1,1,1,0" Padding="5,3" BorderBrush="{DynamicResource Backlight}">
|
||||
<!-- used for hover-over before selection -->
|
||||
<ContentPresenter ContentSource="Header" />
|
||||
</Border>
|
||||
@@ -364,10 +393,10 @@
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter TargetName="Border" Property="Background" Value="{solarized:Theme Background}"/>
|
||||
<Setter TargetName="Border" Property="Background" Value="{DynamicResource Background}"/>
|
||||
<Setter TargetName="Border" Property="BorderBrush" Value="{solarized:Theme Blue}"/>
|
||||
<Setter TargetName="InnerBorder" Property="BorderBrush" Value="{solarized:Theme Blue}"/>
|
||||
<Setter TargetName="OuterBorder" Property="BorderBrush" Value="{solarized:Theme Background}"/>
|
||||
<Setter TargetName="OuterBorder" Property="BorderBrush" Value="{DynamicResource Background}"/>
|
||||
<Setter TargetName="Border" Property="Panel.ZIndex" Value="10"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using HavenSoft.Gen3Hex.Model;
|
||||
using HavenSoft.Gen3Hex.ViewModel;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
@@ -10,12 +11,27 @@ namespace HavenSoft.Gen3Hex.View {
|
||||
public partial class App {
|
||||
protected override void OnStartup(StartupEventArgs e) {
|
||||
base.OnStartup(e);
|
||||
UpdateThemeDictionary();
|
||||
Solarized.Theme.VariantChanged += (sender, args) => UpdateThemeDictionary();
|
||||
|
||||
var fileName = e.Args?.Length == 1 ? e.Args[0] : string.Empty;
|
||||
var viewPort = GetViewModel(fileName);
|
||||
MainWindow = new MainWindow(viewPort);
|
||||
MainWindow.Show();
|
||||
}
|
||||
|
||||
private void UpdateThemeDictionary() {
|
||||
var dict = new ResourceDictionary {
|
||||
{ "Emphasis", Solarized.Theme.Emphasis },
|
||||
{ "Primary", Solarized.Theme.Primary },
|
||||
{ "Secondary", Solarized.Theme.Secondary },
|
||||
{ "Background", Solarized.Theme.Background },
|
||||
{ "Backlight", Solarized.Theme.Backlight },
|
||||
};
|
||||
Resources.MergedDictionaries.Clear();
|
||||
Resources.MergedDictionaries.Add(dict);
|
||||
}
|
||||
|
||||
private EditorViewModel GetViewModel(string fileName) {
|
||||
var editor = new EditorViewModel(new WindowsFileSystem());
|
||||
if (!File.Exists(fileName)) return editor;
|
||||
|
||||
@@ -11,7 +11,7 @@ using System.Windows.Media;
|
||||
|
||||
namespace HavenSoft.Gen3Hex.View {
|
||||
public class HexContent : FrameworkElement {
|
||||
public const int CellWidth = 30, CellHeight = 20;
|
||||
public const double CellWidth = 30, CellHeight = 20;
|
||||
|
||||
public static readonly Rect CellRect = new Rect(0, 0, CellWidth, CellHeight);
|
||||
|
||||
@@ -152,13 +152,13 @@ namespace HavenSoft.Gen3Hex.View {
|
||||
}
|
||||
|
||||
private void UpdateViewPortSize() {
|
||||
ViewPort.Width = (int)ActualWidth / CellWidth;
|
||||
ViewPort.Height = (int)ActualHeight / CellHeight;
|
||||
ViewPort.Width = (int)(ActualWidth / CellWidth);
|
||||
ViewPort.Height = (int)(ActualHeight / CellHeight);
|
||||
}
|
||||
|
||||
private Model.Point ControlCoordinatesToModelCoordinates(MouseEventArgs e) {
|
||||
var point = e.GetPosition(this);
|
||||
return new Model.Point((int)point.X / CellWidth, (int)point.Y / CellHeight);
|
||||
return new Model.Point((int)(point.X / CellWidth), (int)(point.Y / CellHeight));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:hsg3hv="clr-namespace:HavenSoft.Gen3Hex.View"
|
||||
xmlns:hsv="clr-namespace:HavenSoft.View;assembly=HavenSoft"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:solarized="clr-namespace:Solarized;assembly=HavenSoft"
|
||||
Icon="..\Snorlax.ico"
|
||||
Title="Gen3Hex" Height="450" Width="800" AllowDrop="True" Background="{solarized:Theme Background}">
|
||||
Title="Gen3Hex" Height="450" Width="800" AllowDrop="True" Background="{DynamicResource Background}">
|
||||
<Window.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
|
||||
</Window.Resources>
|
||||
<Window.InputBindings>
|
||||
<KeyBinding Key="N" Modifiers="Ctrl" Command="{Binding New}" />
|
||||
<KeyBinding Key="O" Modifiers="Ctrl" Command="{Binding Open}" />
|
||||
@@ -16,53 +20,95 @@
|
||||
|
||||
<KeyBinding Key="Z" Modifiers="Ctrl" Command="{Binding Undo}" />
|
||||
<KeyBinding Key="Y" Modifiers="Ctrl" Command="{Binding Redo}" />
|
||||
<KeyBinding Key="Esc" Command="{Binding ClearError}"/>
|
||||
<KeyBinding Key="G" Modifiers="Ctrl" Command="{Binding ShowGoto}">
|
||||
<KeyBinding.CommandParameter>
|
||||
<sys:Boolean>true</sys:Boolean>
|
||||
</KeyBinding.CommandParameter>
|
||||
</KeyBinding>
|
||||
<KeyBinding Key="OemMinus" Modifiers="Ctrl" Command="{Binding Back}" />
|
||||
<KeyBinding Key="OemMinus" Modifiers="Ctrl+Shift" Command="{Binding Forward}" />
|
||||
|
||||
<KeyBinding Key="T" Modifiers="Ctrl" Command="ToggleBullets" /> <!-- Stealing this routed command for toggling theme -->
|
||||
</Window.InputBindings>
|
||||
<Window.CommandBindings>
|
||||
<CommandBinding Command="ToggleBullets" Executed="ToggleTheme"/>
|
||||
</Window.CommandBindings>
|
||||
<DockPanel>
|
||||
<Menu DockPanel.Dock="Top">
|
||||
<MenuItem Header="_File">
|
||||
<MenuItem Header="_New" Command="{Binding New}" InputGestureText="Ctrl+N">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon New}" Fill="{solarized:Theme Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
<DockPanel DockPanel.Dock="Top">
|
||||
<StackPanel Orientation="Horizontal" DockPanel.Dock="Right" Visibility="{Binding GotoControlVisible, Converter={StaticResource BoolToVisibility}}">
|
||||
<TextBlock Text="Goto :" Margin="10,0" />
|
||||
<TextBox Name="GotoBox" MinWidth="200" IsVisibleChanged="GotoBoxVisibilityChanged">
|
||||
<TextBox.InputBindings>
|
||||
<KeyBinding Key="Esc" Command="{Binding ShowGoto}">
|
||||
<KeyBinding.CommandParameter>
|
||||
<sys:Boolean>false</sys:Boolean>
|
||||
</KeyBinding.CommandParameter>
|
||||
</KeyBinding>
|
||||
<KeyBinding Key="Return" Command="{Binding Goto}" CommandParameter="{Binding Text, ElementName=GotoBox}"/>
|
||||
</TextBox.InputBindings>
|
||||
</TextBox>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Background="{DynamicResource Backlight}" DockPanel.Dock="Right" Visibility="{Binding ShowError, Converter={StaticResource BoolToVisibility}}">
|
||||
<TextBlock Margin="10,0" VerticalAlignment="Center" Text="{Binding ErrorMessage}" Foreground="{solarized:Theme Red}"/>
|
||||
<Button Command="{Binding ClearError}" Width="15">
|
||||
<Path Data="{hsv:Icon Exit}" Fill="{DynamicResource Secondary}" Stretch="Uniform"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<Menu>
|
||||
<MenuItem Header="_File">
|
||||
<MenuItem Header="_New" Command="{Binding New}" InputGestureText="Ctrl+N">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon New}" Fill="{DynamicResource Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Open" Command="{Binding Open}" InputGestureText="Ctrl+O">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon Open}" Fill="{DynamicResource Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="_Save" Command="{Binding Save}" InputGestureText="Ctrl+S">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon Save}" Fill="{DynamicResource Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Save _As" Command="{Binding SaveAs}" InputGestureText="Ctrl+Shift+S" />
|
||||
<MenuItem Header="Save A_ll" Command="{Binding SaveAll}" InputGestureText="Ctrl+Shift+A" />
|
||||
<Separator />
|
||||
<MenuItem Header="_Close Current Tab" Command="{Binding Close}" InputGestureText="Ctrl+W" />
|
||||
<MenuItem Header="E_xit" Click="ExitClicked" InputGestureText="Alt+F4">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon Exit}" Fill="{DynamicResource Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Open" Command="{Binding Open}" InputGestureText="Ctrl+O">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon Open}" Fill="{solarized:Theme Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem Header="_Edit">
|
||||
<MenuItem Header="_Undo" Command="{Binding Undo}" InputGestureText="Ctrl+Z">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon UndoArrow}" Fill="{DynamicResource Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Redo" Command="{Binding Redo}" InputGestureText="Ctrl+Y">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon RedoArrow}" Fill="{DynamicResource Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<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+-"/>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="_Save" Command="{Binding Save}" InputGestureText="Ctrl+S">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon Save}" Fill="{solarized:Theme Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
<MenuItem Header="_View">
|
||||
<MenuItem Header="_Toggle Theme" Click="ToggleTheme" InputGestureText="Ctrl+T"/>
|
||||
<MenuItem Header="_Clear Error" Command="{Binding ClearError}" InputGestureText="Esc"/>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Save _As" Command="{Binding SaveAs}" InputGestureText="Ctrl+Shift+S" />
|
||||
<MenuItem Header="Save A_ll" Command="{Binding SaveAll}" InputGestureText="Ctrl+Shift+A" />
|
||||
<Separator />
|
||||
<MenuItem Header="_Close Current Tab" Command="{Binding Close}" InputGestureText="Ctrl+W" />
|
||||
<MenuItem Header="E_xit" Click="ExitClicked" InputGestureText="Alt+F4">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon Exit}" Fill="{solarized:Theme Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Edit">
|
||||
<MenuItem Header="_Undo" Command="{Binding Undo}" InputGestureText="Ctrl+Z">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon UndoArrow}" Fill="{solarized:Theme Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="_Redo" Command="{Binding Redo}" InputGestureText="Ctrl+Y">
|
||||
<MenuItem.Icon>
|
||||
<Path Data="{hsv:Icon RedoArrow}" Fill="{solarized:Theme Secondary}" Stretch="Uniform"/>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</Menu>
|
||||
</DockPanel>
|
||||
<TabControl Name="Tabs" ItemsSource="{Binding}" SelectedIndex="{Binding SelectedIndex}">
|
||||
<TabControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Name="TabTextBlock" Background="Transparent" Text="{Binding Name}" Foreground="{solarized:Theme Primary}" MouseDown="TabMouseDown" MouseMove="TabMouseMove" MouseUp="TabMouseUp">
|
||||
<TextBlock Name="TabTextBlock" Background="Transparent" Text="{Binding Name}" Foreground="{DynamicResource Primary}" MouseDown="TabMouseDown" MouseMove="TabMouseMove" MouseUp="TabMouseUp">
|
||||
<TextBlock.InputBindings>
|
||||
<MouseBinding MouseAction="MiddleClick" Command="{Binding Close}"/>
|
||||
</TextBlock.InputBindings>
|
||||
@@ -72,10 +118,18 @@
|
||||
<TabControl.ContentTemplate>
|
||||
<DataTemplate>
|
||||
<DockPanel>
|
||||
<ItemsControl DockPanel.Dock="Left" Width="60" ItemsSource="{Binding Headers}" Background="{DynamicResource Backlight}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Foreground="{DynamicResource Secondary}" Text="{Binding}" FontFamily="Consolas" HorizontalAlignment="Right" Height="{x:Static hsg3hv:HexContent.CellHeight}" Padding="4"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<Line Width="1" DockPanel.Dock="Left" Stroke="{DynamicResource Background}"/>
|
||||
<ScrollBar DockPanel.Dock="Right"
|
||||
Minimum="{Binding MinimumScroll}" Maximum="{Binding MaximumScroll}" Value="{Binding ScrollValue}"
|
||||
SmallChange="1" LargeChange="{Binding Height}" />
|
||||
<hsg3hv:HexContent ViewPort="{Binding}"/>
|
||||
<hsg3hv:HexContent Name="HexContent" ViewPort="{Binding}"/>
|
||||
</DockPanel>
|
||||
</DataTemplate>
|
||||
</TabControl.ContentTemplate>
|
||||
|
||||
@@ -93,9 +93,24 @@ namespace HavenSoft.Gen3Hex.View {
|
||||
|
||||
#endregion
|
||||
|
||||
private void ToggleTheme(object sender, EventArgs e) {
|
||||
Solarized.Theme.CurrentVariant = 1 - Solarized.Theme.CurrentVariant;
|
||||
}
|
||||
|
||||
private void ExitClicked(object sender, EventArgs e) {
|
||||
ViewModel.CloseAll.Execute();
|
||||
if (ViewModel.Count == 0) Close();
|
||||
}
|
||||
|
||||
private void GotoBoxVisibilityChanged(object sender, DependencyPropertyChangedEventArgs e) {
|
||||
if (GotoBox.IsVisible) {
|
||||
GotoBox.SelectAll();
|
||||
Keyboard.Focus(GotoBox);
|
||||
} else {
|
||||
if (ViewModel.SelectedIndex == -1) return;
|
||||
var selectedElement = (HexContent)GetChild(Tabs, "HexContent", ViewModel[ViewModel.SelectedIndex]);
|
||||
Keyboard.Focus(selectedElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,9 @@ 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;
|
||||
private readonly StubCommand newCommand, open, save, saveAs, saveAll, close, closeAll, undo, redo, back, forward, gotoCommand, showGoto, clearError;
|
||||
private readonly Dictionary<Func<ITabContent, ICommand>, EventHandler> forwardExecuteChangeNotifications;
|
||||
|
||||
private int selectedIndex;
|
||||
|
||||
public ICommand New => newCommand;
|
||||
public ICommand Open => open;
|
||||
public ICommand Save => save;
|
||||
@@ -25,6 +23,36 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
public ICommand CloseAll => closeAll;
|
||||
public ICommand Undo => undo;
|
||||
public ICommand Redo => redo;
|
||||
public ICommand Back => back;
|
||||
public ICommand Forward => forward;
|
||||
public ICommand Goto => gotoCommand;
|
||||
public ICommand ShowGoto => showGoto;
|
||||
public ICommand ClearError => clearError;
|
||||
|
||||
private bool gotoControlVisible;
|
||||
public bool GotoControlVisible {
|
||||
get => gotoControlVisible;
|
||||
private set {
|
||||
TryUpdate(ref gotoControlVisible, value);
|
||||
if (value) ClearError.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
private bool showError;
|
||||
public bool ShowError {
|
||||
get => showError;
|
||||
private set {
|
||||
if (TryUpdate(ref showError, value)) clearError.CanExecuteChanged.Invoke(clearError, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private string errorMessage;
|
||||
public string ErrorMessage {
|
||||
get => errorMessage;
|
||||
private set {
|
||||
if (TryUpdate(ref errorMessage, value)) ShowError = !string.IsNullOrEmpty(ErrorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
#region Collection Properties
|
||||
|
||||
@@ -34,6 +62,7 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
|
||||
public int Count => tabs.Count;
|
||||
|
||||
private int selectedIndex;
|
||||
public int SelectedIndex {
|
||||
get => selectedIndex;
|
||||
set {
|
||||
@@ -66,6 +95,21 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
Add(new ViewPort(file));
|
||||
},
|
||||
};
|
||||
gotoCommand = new StubCommand {
|
||||
CanExecute = arg => SelectedTab?.Goto?.CanExecute(arg) ?? false,
|
||||
Execute = arg => {
|
||||
SelectedTab?.Goto?.Execute(arg);
|
||||
GotoControlVisible = false;
|
||||
},
|
||||
};
|
||||
showGoto = new StubCommand {
|
||||
CanExecute = CanAlwaysExecute,
|
||||
Execute = arg => GotoControlVisible = (bool)arg,
|
||||
};
|
||||
clearError = new StubCommand {
|
||||
CanExecute = arg => showError,
|
||||
Execute = arg => ErrorMessage = string.Empty,
|
||||
};
|
||||
save = CreateWrapperForSelected(tab => tab.Save);
|
||||
saveAs = CreateWrapperForSelected(tab => tab.SaveAs);
|
||||
saveAll = CreateWrapperForAll(tab => tab.Save);
|
||||
@@ -73,6 +117,8 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
closeAll = CreateWrapperForAll(tab => tab.Close);
|
||||
undo = CreateWrapperForSelected(tab => tab.Undo);
|
||||
redo = CreateWrapperForSelected(tab => tab.Redo);
|
||||
back = CreateWrapperForSelected(tab => tab.Back);
|
||||
forward = CreateWrapperForSelected(tab => tab.Forward);
|
||||
|
||||
forwardExecuteChangeNotifications = new Dictionary<Func<ITabContent, ICommand>, EventHandler> {
|
||||
{ tab => tab.Save, (sender, e) => save.CanExecuteChanged.Invoke(this, e) },
|
||||
@@ -80,6 +126,8 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
{ tab => tab.Close, (sender, e) => close.CanExecuteChanged.Invoke(this, e) },
|
||||
{ tab => tab.Undo, (sender, e) => undo.CanExecuteChanged.Invoke(this, e) },
|
||||
{ tab => tab.Redo, (sender, e) => redo.CanExecuteChanged.Invoke(this, e) },
|
||||
{ tab => tab.Back, (sender, e) => back.CanExecuteChanged.Invoke(this, e) },
|
||||
{ tab => tab.Forward, (sender, e) => forward.CanExecuteChanged.Invoke(this, e) },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -88,6 +136,7 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
SelectedIndex = tabs.Count - 1;
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, content));
|
||||
content.Closed += RemoveTab;
|
||||
content.OnError += AcceptError;
|
||||
if (content.Save != null) content.Save.CanExecuteChanged += RaiseSaveAllCanExecuteChanged;
|
||||
}
|
||||
|
||||
@@ -163,9 +212,12 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
|
||||
tabs.Remove(tab);
|
||||
tab.Closed -= RemoveTab;
|
||||
tab.OnError -= AcceptError;
|
||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, tab, index));
|
||||
}
|
||||
|
||||
private void AcceptError(object sender, string message) => ErrorMessage = message;
|
||||
|
||||
private void StartListeningToCommandsFromCurrentTab() {
|
||||
var commandsToRefresh = new List<StubCommand> {
|
||||
undo,
|
||||
@@ -173,6 +225,8 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
save,
|
||||
saveAs,
|
||||
close,
|
||||
back,
|
||||
forward,
|
||||
};
|
||||
commandsToRefresh.ForEach(command => command.CanExecuteChanged.Invoke(command, EventArgs.Empty));
|
||||
|
||||
|
||||
@@ -11,8 +11,12 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
ICommand SaveAs { get; }
|
||||
ICommand Undo { get; }
|
||||
ICommand Redo { get; }
|
||||
ICommand Goto { get; }
|
||||
ICommand Back { get; }
|
||||
ICommand Forward { get; }
|
||||
ICommand Close { get; }
|
||||
|
||||
event EventHandler<string> OnError;
|
||||
event EventHandler Closed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using HavenSoft.Gen3Hex.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
@@ -24,21 +23,28 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
get => dataIndex;
|
||||
private set {
|
||||
var dif = value - dataIndex;
|
||||
if (TryUpdate(ref dataIndex, value)) ScrollChanged?.Invoke(this, dif);
|
||||
if (TryUpdate(ref dataIndex, value)) {
|
||||
ScrollChanged?.Invoke(this, dif);
|
||||
UpdateScrollRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Width {
|
||||
get => width;
|
||||
set {
|
||||
if (TryUpdate(ref width, value.LimitToRange(4, int.MaxValue))) UpdateScrollRange();
|
||||
if (TryUpdate(ref width, value.LimitToRange(4, int.MaxValue))) {
|
||||
UpdateScrollRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Height {
|
||||
get => height;
|
||||
set {
|
||||
if (TryUpdate(ref height, value.LimitToRange(4, int.MaxValue))) UpdateScrollRange();
|
||||
if (TryUpdate(ref height, value.LimitToRange(4, int.MaxValue))) {
|
||||
UpdateScrollRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +74,8 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<string> Headers { get; } = new ObservableCollection<string>();
|
||||
|
||||
public event EventHandler<int> ScrollChanged;
|
||||
|
||||
public ScrollRegion() {
|
||||
@@ -77,6 +85,7 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
CanExecute = args => dataLength > 0,
|
||||
Execute = args => ScrollExecuted((Direction)args),
|
||||
};
|
||||
UpdateHeaders();
|
||||
}
|
||||
|
||||
public int ViewPointToDataIndex(Point p) => p.Y * width + p.X + dataIndex;
|
||||
@@ -120,7 +129,6 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
ScrollValue += dif.Y;
|
||||
} else {
|
||||
DataIndex = (dataIndex + dif.X).LimitToRange(1 - width, dataLength - 1);
|
||||
UpdateScrollRange();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +147,23 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
|
||||
// Call Update instead of ScrollValue.set to avoid changing the dataIndex.
|
||||
TryUpdate(ref scrollValue, newCurrentScroll, nameof(ScrollValue));
|
||||
UpdateHeaders();
|
||||
}
|
||||
|
||||
private void UpdateHeaders() {
|
||||
while (Headers.Count > Height) Headers.RemoveAt(Headers.Count - 1);
|
||||
for (int i = 0; i < Height; i++) {
|
||||
var address = dataIndex + i * Width;
|
||||
var hexAddress = address.ToString("X6");
|
||||
if (address >= DataLength) hexAddress = string.Empty;
|
||||
if (address < 0) hexAddress = string.Empty;
|
||||
|
||||
if (Headers.Count > i) {
|
||||
Headers[i] = hexAddress;
|
||||
} else {
|
||||
Headers.Add(hexAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using HavenSoft.Gen3Hex.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows.Input;
|
||||
|
||||
@@ -9,10 +11,17 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
|
||||
private readonly StubCommand
|
||||
moveSelectionStart = new StubCommand(),
|
||||
moveSelectionEnd = new StubCommand();
|
||||
moveSelectionEnd = new StubCommand(),
|
||||
gotoCommand = new StubCommand(),
|
||||
forward = new StubCommand(),
|
||||
backward = new StubCommand();
|
||||
|
||||
private readonly ScrollRegion scroll;
|
||||
|
||||
// these back/forward stacks are not encapsulated in a history object because we want to be able to change a remembered address each time we visit it.
|
||||
// if we navigate back, then scroll, then navigate forward, we want to remember the scroll if we go back again.
|
||||
private readonly Stack<int> backStack = new Stack<int>(), forwardStack = new Stack<int>();
|
||||
|
||||
private Point selectionStart, selectionEnd;
|
||||
|
||||
public Point SelectionStart {
|
||||
@@ -45,8 +54,12 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
}
|
||||
|
||||
public ICommand MoveSelectionStart => moveSelectionStart;
|
||||
|
||||
public ICommand MoveSelectionEnd => moveSelectionEnd;
|
||||
public ICommand Goto => gotoCommand;
|
||||
public ICommand Forward => forward;
|
||||
public ICommand Back => backward;
|
||||
|
||||
public event EventHandler<string> OnError;
|
||||
|
||||
/// <summary>
|
||||
/// The owner may have something special going on with the selected point.
|
||||
@@ -62,6 +75,40 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
moveSelectionStart.Execute = args => MoveSelectionStartExecuted((Direction)args);
|
||||
moveSelectionEnd.CanExecute = args => true;
|
||||
moveSelectionEnd.Execute = args => MoveSelectionEndExecuted((Direction)args);
|
||||
|
||||
gotoCommand = new StubCommand {
|
||||
CanExecute = args => true,
|
||||
Execute = args => {
|
||||
var address = args.ToString();
|
||||
if (int.TryParse(address, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out int result)) {
|
||||
backStack.Push(scroll.DataIndex);
|
||||
forwardStack.Clear();
|
||||
SelectionStart = scroll.DataIndexToViewPoint(result);
|
||||
scroll.ScrollValue += selectionStart.Y;
|
||||
} else {
|
||||
OnError?.Invoke(this, $"Unable to goto address '{address}'");
|
||||
}
|
||||
},
|
||||
};
|
||||
backward = new StubCommand {
|
||||
CanExecute = args => backStack.Count > 0,
|
||||
Execute = args => {
|
||||
if (backStack.Count == 0) return;
|
||||
forwardStack.Push(scroll.DataIndex);
|
||||
SelectionStart = scroll.DataIndexToViewPoint(backStack.Pop());
|
||||
scroll.ScrollValue += selectionStart.Y;
|
||||
},
|
||||
};
|
||||
forward = new StubCommand {
|
||||
CanExecute = args => forwardStack.Count > 0,
|
||||
Execute = args => {
|
||||
if (forwardStack.Count == 0) return;
|
||||
backStack.Push(scroll.DataIndex);
|
||||
SelectionStart = scroll.DataIndexToViewPoint(forwardStack.Pop());
|
||||
scroll.ScrollValue += selectionStart.Y;
|
||||
},
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public bool IsSelected(Point point) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using HavenSoft.ViewModel.DataFormats;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
@@ -52,7 +53,11 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
|
||||
public int MaximumScroll => scroll.MaximumScroll;
|
||||
|
||||
public ObservableCollection<string> Headers => scroll.Headers;
|
||||
public ICommand Scroll => scroll.Scroll;
|
||||
public ICommand Goto => selection.Goto;
|
||||
public ICommand Back => selection.Back;
|
||||
public ICommand Forward => selection.Forward;
|
||||
|
||||
private void ScrollPropertyChanged(object sender, PropertyChangedEventArgs e) {
|
||||
if (e.PropertyName == nameof(scroll.DataIndex)) {
|
||||
@@ -188,6 +193,8 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<string> OnError;
|
||||
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
|
||||
public ViewPort() : this(new LoadedFile(string.Empty, new byte[0])) { }
|
||||
@@ -202,6 +209,7 @@ namespace HavenSoft.Gen3Hex.ViewModel {
|
||||
selection = new Selection(scroll);
|
||||
selection.PropertyChanged += SelectionPropertyChanged;
|
||||
selection.PreviewSelectionStartChanged += ClearActiveEditBeforeSelectionChanges;
|
||||
selection.OnError += (sender, e) => OnError?.Invoke(this, e);
|
||||
|
||||
history = new ChangeHistory<Dictionary<int, HexElement>>(RevertChanges);
|
||||
history.PropertyChanged += HistoryPropertyChanged;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Windows.Markup;
|
||||
using System.Windows.Media;
|
||||
|
||||
using System.Xaml;
|
||||
using static Solarized.Brushes;
|
||||
using static Solarized.Colors;
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Solarized {
|
||||
return brush;
|
||||
}
|
||||
|
||||
public static readonly Brush
|
||||
public static readonly SolidColorBrush
|
||||
Yellow = Brush(Colors.Yellow),
|
||||
Orange = Brush(Colors.Orange),
|
||||
Red = Brush(Colors.Red),
|
||||
@@ -127,7 +127,20 @@ namespace Solarized {
|
||||
public ThemeExtension() { }
|
||||
public ThemeExtension(ThemeProperties target) => Target = target;
|
||||
public override object ProvideValue(IServiceProvider serviceProvider) {
|
||||
switch (Target) {
|
||||
return ThemeColorExtension.GetBrush(Target);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ThemeColorExtension : MarkupExtension {
|
||||
public ThemeProperties Target { get; set; }
|
||||
public ThemeColorExtension() { }
|
||||
public ThemeColorExtension(ThemeProperties target) => Target = target;
|
||||
public override object ProvideValue(IServiceProvider serviceProvider) {
|
||||
return GetBrush(Target).Color;
|
||||
}
|
||||
|
||||
public static SolidColorBrush GetBrush(ThemeProperties property) {
|
||||
switch (property) {
|
||||
case ThemeProperties.Emphasis: return Theme.Emphasis;
|
||||
case ThemeProperties.Primary: return Theme.Primary;
|
||||
case ThemeProperties.Secondary: return Theme.Secondary;
|
||||
|
||||
@@ -251,6 +251,47 @@ namespace HavenSoft.HexTests {
|
||||
Assert.Equal(1, count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditorShowsErrors() {
|
||||
var tab = new StubTabContent();
|
||||
editor.Add(tab);
|
||||
var clearErrorChangedNotifications = 0;
|
||||
editor.ClearError.CanExecuteChanged += (sender, e) => clearErrorChangedNotifications += 1;
|
||||
|
||||
tab.OnError.Invoke(tab, "Some Message");
|
||||
|
||||
Assert.True(editor.ShowError);
|
||||
Assert.Equal(editor.ErrorMessage, "Some Message");
|
||||
Assert.Equal(1, clearErrorChangedNotifications);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EditorCanClearErrors() {
|
||||
var tab = new StubTabContent();
|
||||
editor.Add(tab);
|
||||
var clearErrorChangedNotifications = 0;
|
||||
editor.ClearError.CanExecuteChanged += (sender, e) => clearErrorChangedNotifications += 1;
|
||||
|
||||
tab.OnError.Invoke(tab, "Some Message");
|
||||
editor.ClearError.Execute();
|
||||
|
||||
Assert.False(editor.ShowError);
|
||||
Assert.Equal(editor.ErrorMessage, string.Empty);
|
||||
Assert.Equal(2, clearErrorChangedNotifications);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShowingGotoClearsErrors() {
|
||||
var tab = new StubTabContent();
|
||||
editor.Add(tab);
|
||||
|
||||
tab.OnError.Invoke(tab, "Some Message");
|
||||
editor.ShowGoto.Execute(true);
|
||||
|
||||
Assert.True(editor.GotoControlVisible);
|
||||
Assert.False(editor.ShowError);
|
||||
}
|
||||
|
||||
private StubTabContent CreateClosableTab() {
|
||||
var tab = new StubTabContent();
|
||||
var close = new StubCommand { CanExecute = arg => true };
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
<Compile Include="GeneralAppTests.cs" />
|
||||
<Compile Include="generatedCode\StubFileSystem.cs" />
|
||||
<Compile Include="generatedCode\StubTabContent.cs" />
|
||||
<Compile Include="NavigationTests.cs" />
|
||||
<Compile Include="ViewPortCursorTests.cs" />
|
||||
<Compile Include="ViewPortEditTests.cs" />
|
||||
<Compile Include="ViewPortSaveTests.cs" />
|
||||
|
||||
173
HexTests/NavigationTests.cs
Normal file
173
HexTests/NavigationTests.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
using HavenSoft.Gen3Hex.Model;
|
||||
using HavenSoft.Gen3Hex.ViewModel;
|
||||
using Xunit;
|
||||
|
||||
namespace HavenSoft.HexTests {
|
||||
public class NavigationTests {
|
||||
[Fact]
|
||||
public void AddressesAreCorrect() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x200])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
Assert.Equal("000000", viewPort.Headers[0]);
|
||||
Assert.Equal("000010", viewPort.Headers[1]);
|
||||
Assert.Equal(viewPort.Height, viewPort.Headers.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddressUpdateOnWidthChanged() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x200])) { Width = 0x10, Height = 0x10 };
|
||||
var changeCount = 0;
|
||||
viewPort.Headers.CollectionChanged += (sender, e) => changeCount += 1;
|
||||
|
||||
viewPort.Width++;
|
||||
|
||||
Assert.InRange(changeCount, 1, viewPort.Height);
|
||||
Assert.Equal("000011", viewPort.Headers[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddressUpdateOnScroll() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x200])) { Width = 0x10, Height = 0x10 };
|
||||
var changeCount = 0;
|
||||
viewPort.Headers.CollectionChanged += (sender, e) => changeCount += 1;
|
||||
|
||||
viewPort.ScrollValue++;
|
||||
|
||||
Assert.InRange(changeCount, 1, viewPort.Height);
|
||||
Assert.Equal("000020", viewPort.Headers[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddressExtendOnHeightChanged() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x200])) { Width = 0x10, Height = 0x10 };
|
||||
var changeCount = 0;
|
||||
viewPort.Headers.CollectionChanged += (sender, e) => changeCount += 1;
|
||||
|
||||
viewPort.Height++;
|
||||
|
||||
Assert.InRange(changeCount, 1, viewPort.Height);
|
||||
Assert.Equal(viewPort.Height, viewPort.Headers.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddressMissingIfBeforeFile() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x200])) { Width = 0x10, Height = 0x10 };
|
||||
var changeCount = 0;
|
||||
viewPort.Headers.CollectionChanged += (sender, e) => changeCount += 1;
|
||||
|
||||
viewPort.Scroll.Execute(Direction.Left);
|
||||
|
||||
Assert.InRange(changeCount, 1, viewPort.Height);
|
||||
Assert.Equal(string.Empty, viewPort.Headers[0]);
|
||||
Assert.Equal("00000F", viewPort.Headers[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddressMissingIfAfterEndOfFile() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x200])) { Width = 0x10, Height = 0x10 };
|
||||
var changeCount = 0;
|
||||
viewPort.Headers.CollectionChanged += (sender, e) => changeCount += 1;
|
||||
|
||||
viewPort.ScrollValue = viewPort.MaximumScroll;
|
||||
|
||||
Assert.InRange(changeCount, 1, viewPort.Height);
|
||||
Assert.Equal("0001F0", viewPort.Headers[0]);
|
||||
Assert.Equal(string.Empty, viewPort.Headers[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddressAddedIfFileGrows() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x200])) { Width = 0x10, Height = 0x10 };
|
||||
var changeCount = 0;
|
||||
viewPort.Headers.CollectionChanged += (sender, e) => changeCount += 1;
|
||||
|
||||
viewPort.ScrollValue = viewPort.MaximumScroll;
|
||||
viewPort.SelectionStart = new Point(0, 1);
|
||||
viewPort.Edit("FF");
|
||||
|
||||
Assert.Equal("000200", viewPort.Headers[1]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotoWorks() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
viewPort.Goto.Execute("000300");
|
||||
|
||||
Assert.Equal("000300", viewPort.Headers[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotoIsNotCaseSensitive() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
viewPort.Goto.Execute("000a00");
|
||||
|
||||
Assert.Equal("000A00", viewPort.Headers[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotoIsReversable() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
viewPort.Goto.Execute("000A00");
|
||||
viewPort.Back.Execute();
|
||||
|
||||
Assert.Equal("000000", viewPort.Headers[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BackIsReversable() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
viewPort.Goto.Execute("000A00");
|
||||
viewPort.Back.Execute();
|
||||
viewPort.Forward.Execute();
|
||||
|
||||
Assert.Equal("000A00", viewPort.Headers[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BackRecallsYourLastScrollPosition() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
viewPort.ScrollValue++;
|
||||
viewPort.Goto.Execute("000A00");
|
||||
viewPort.ScrollValue++;
|
||||
viewPort.Back.Execute();
|
||||
Assert.Equal("000010", viewPort.Headers[0]);
|
||||
|
||||
viewPort.Forward.Execute();
|
||||
Assert.Equal("000A10", viewPort.Headers[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotoMovesScroll() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
viewPort.Goto.Execute("000A00");
|
||||
|
||||
Assert.NotEqual(0, viewPort.ScrollValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotoErrorsOnBadAddress() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
int errorCount = 0;
|
||||
viewPort.OnError += (sender, e) => errorCount += 1;
|
||||
|
||||
viewPort.Goto.Execute("BadAddress");
|
||||
|
||||
Assert.Equal(1, errorCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GotoMovesSelection() {
|
||||
var viewPort = new ViewPort(new LoadedFile("test.txt", new byte[0x1000])) { Width = 0x10, Height = 0x10 };
|
||||
|
||||
viewPort.Goto.Execute("000C00");
|
||||
|
||||
Assert.Equal(new Point(0, 0), viewPort.SelectionStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,10 +163,14 @@ namespace HavenSoft.HexTests {
|
||||
public void ScrollingRightUpdatesScrollValueIfNeeded() {
|
||||
var loadedFile = new LoadedFile("test", new byte[25]);
|
||||
var viewPort = new ViewPort(loadedFile) { Width = 5, Height = 5 };
|
||||
var changeCount = 0;
|
||||
|
||||
viewPort.CollectionChanged += (sender, e) => changeCount += 1;
|
||||
|
||||
viewPort.Scroll.Execute(Direction.Right);
|
||||
|
||||
Assert.Equal(1, viewPort.ScrollValue);
|
||||
Assert.NotEqual(0, changeCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user