<Window x:Class="WpfDisplay.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfDisplay.Views"
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:vm="clr-namespace:WpfDisplay.ViewModels"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:conv="clr-namespace:WpfDisplay.Converters"
xmlns:disp="clr-namespace:IFSEngine.WPF.InteractiveDisplay;assembly=IFSEngine.WPF.InteractiveDisplay"
xmlns:animation="clr-namespace:WpfDisplay.Views.Animation"
mc:Ignorable="d"
Title="{Binding WindowTitle}"
Width="1920" Height="1080" WindowState="Maximized"
AllowDrop="True" DragOver="mainWindow_DragOver" Drop="mainWindow_Drop"
Style="{StaticResource MaterialDesignWindow}"
x:Name="mainWindow"
d:DataContext="{d:DesignInstance Type=vm:MainViewModel, IsDesignTimeCreatable=False}">
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Undo" Executed="Undo_Executed" CanExecute="Undo_CanExecute"/>
<CommandBinding Command="ApplicationCommands.Redo" Executed="Redo_Executed" CanExecute="Redo_CanExecute"/>
<CommandBinding Command="ApplicationCommands.Copy" Executed="Copy_Executed" CanExecute="Copy_CanExecute"/>
<CommandBinding Command="ApplicationCommands.Paste" Executed="Paste_Executed" CanExecute="Paste_CanExecute"/>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Gesture="CTRL+N" Command="{Binding NewCommand}"/>
<KeyBinding Gesture="CTRL+O" Command="{Binding ShowLoadParamsDialogCommand}"/>
<KeyBinding Gesture="CTRL+S" Command="{Binding SaveParamsCommand}"/>
<KeyBinding Gesture="CTRL+SHIFT+S" Command="{Binding SaveParamsAsCommand}"/>
<KeyBinding Gesture="CTRL+SHIFT+C" Command="{Binding ExportToClipboardCommand}"/>
<KeyBinding Gesture="CTRL+SHIFT+E" Command="{Binding SaveExrCommand}"/>
<KeyBinding Gesture="CTRL+E" Command="{Binding SaveImageCommand}"/>
<KeyBinding Gesture="CTRL+A" Command="{Binding AnimationViewModel.StartExportingFramesCommand}"/>
<KeyBinding Gesture="CTRL+R" Command="{Binding LoadRandomCommand}"/>
<KeyBinding Gesture="PAUSE" Command="{Binding StartStopRenderingCommand}"/>
<KeyBinding Gesture="F1" Command="{Binding VisitWikiCommand}"/>
</Window.InputBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ToolBarTray IsLocked="True" Grid.Row="0">
<ToolBar>
<Menu IsMainMenu="True">
<MenuItem Header="📑 _File">
<MenuItem Header="📑 _New" Command="{Binding NewCommand}" InputGestureText="Ctrl+N"/>
<MenuItem Header="🗂️ _Templates" ItemsSource="{Binding Templates}">
<MenuItem.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}"/>
</DataTemplate>
</MenuItem.ItemTemplate>
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding DataContext.LoadTemplateCommand, ElementName=mainWindow}"/>
<Setter Property="CommandParameter" Value="{Binding Key}"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="📜 Recents" ItemsSource="{Binding RecentFilePaths}" IsEnabled="{Binding HasRecentFiles}">
<MenuItem.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</MenuItem.ItemTemplate>
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding DataContext.DropParamsCommand, ElementName=mainWindow}"/>
<Setter Property="CommandParameter" Value="{Binding}"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="📂 _Load..." Command="{Binding ShowLoadParamsDialogCommand}" InputGestureText="Ctrl+O"/>
<MenuItem Header="💾 _Save" Command="{Binding SaveParamsCommand}" InputGestureText="Ctrl+S"/>
<MenuItem Header="💾 _Save as..." Command="{Binding SaveParamsAsCommand}" InputGestureText="Ctrl+Shift+S"/>
<Separator/>
<MenuItem Header="📝 Copy params" Command="ApplicationCommands.Copy" CommandTarget="{Binding ElementName=mainWindow}" ToolTip="Copy params to Clipboard (Ctrl+C)" InputGestureText="Ctrl+C"/>
<MenuItem Header="📋 Paste params" Command="ApplicationCommands.Paste" CommandTarget="{Binding ElementName=mainWindow}" ToolTip="Paste params from Clipboard (Ctrl+V)" InputGestureText="Ctrl+V"/>
<Separator/>
<MenuItem Header="⚙️ Settings..." Click="SettingsButton_Click"/>
<Separator/>
<MenuItem Header="🏃 Exit" Command="{Binding ExitApplicationCommand}" InputGestureText="Alt+F4"/>
</MenuItem>
<MenuItem Header="💾" Command="{Binding SaveParamsCommand}" ToolTip="Save (Ctrl+S)" InputGestureText="Ctrl+S"/>
<MenuItem Header="↩️" Command="ApplicationCommands.Undo" CommandTarget="{Binding ElementName=mainWindow}" ToolTip="Undo (Ctrl+Z)" InputGestureText="Ctrl+Z"/>
<MenuItem Header="↪️" Command="ApplicationCommands.Redo" CommandTarget="{Binding ElementName=mainWindow}" ToolTip="Redo (Ctrl+Y)" InputGestureText="Ctrl+Y"/>
</Menu>
<Separator/>
<Menu>
<MenuItem Icon="{md:PackIcon Kind=VectorPolyline}" Header="Editor" Click="EditorButton_Click" ToolTip="Open the editor window"/>
<MenuItem Header="🔮 Generator" Click="GeneratorButton_Click" ToolTip="Open the generator window"/>
<MenuItem Header="🎨 Palettes" Click="PalettesButton_Click" ToolTip="Open the palette manager window"/>
<Separator/>
<MenuItem Header="🎲 _Random" Command="{Binding LoadRandomCommand}" ToolTip="Generate random params (Ctrl+R)" InputGestureText="Ctrl+R"/>
</Menu>
<Separator/>
<local:TitleBox Width="200" Height="30"/>
<Menu>
<MenuItem Icon="{md:PackIcon Kind=ImageMove}" Header="E_xport">
<MenuItem Icon="📋" Header="Export to _clipboard" Command="{Binding ExportToClipboardCommand}" InputGestureText="Ctrl+Shift+C"/>
<MenuItem Icon="📊" Header="Export to _EXR..." Command="{Binding SaveExrCommand}" InputGestureText="Ctrl+Shift+E"/>
<MenuItem Icon="🖼" Header="Export to _PNG..." Command="{Binding SaveImageCommand}" InputGestureText="Ctrl+E"/>
<Separator/>
<MenuItem Icon="🎥" Header="Export _animation frames..." Command="{Binding AnimationViewModel.StartExportingFramesCommand}" InputGestureText="Ctrl+A"/>
</MenuItem>
</Menu>
</ToolBar>
</ToolBarTray>
<Menu Grid.Row="0" HorizontalAlignment="Right">
<MenuItem Header="🎓 Tutorials..." InputGestureText="F1" Command="{Binding VisitWikiCommand}"/>
<MenuItem Icon="{md:PackIcon Kind=InfoCircleOutline}" Header="Help">
<MenuItem Icon="📚" Header="Wiki..." InputGestureText="F1" Command="{Binding VisitWikiCommand}"/>
<MenuItem Icon="🏛️" Header="Forum..." Command="{Binding VisitForumCommand}"/>
<MenuItem Icon="🙋" Header="Send Feedback">
<MenuItem Icon="🐞" Header="Report a bug..." Command="{Binding ReportBugCommand}"/>
<MenuItem Icon="🙋" Header="File an issue..." Command="{Binding VisitIssuesCommand}"/>
</MenuItem>
<Separator/>
<MenuItem Icon="👷" Header="About..." Click="AboutButton_Click"/>
<MenuItem Icon="💿" Header="Check for updates..." Command="{Binding CheckUpdatesCommand}"/>
</MenuItem>
</Menu>
<DockingManager x:Name="dockManager"
Grid.Row="1"
AllowMixedOrientation="True"
AutoWindowSizeWhenOpened="True"
DocumentClosing="dockManager_DocumentClosing"
IsVirtualizingAnchorable="True"
IsVirtualizingDocument="True">
<DockingManager.Theme>
<ArcDarkTheme/>
</DockingManager.Theme>
<DockingManager.DocumentHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.IFSTitle, ElementName=mainWindow, Mode=OneWay, StringFormat='\{0\}'}"/>
</DataTemplate>
</DockingManager.DocumentHeaderTemplate>
<LayoutRoot>
<LayoutPanel Orientation="Vertical">
<LayoutPanel Orientation="Horizontal">
<!--Left Side-->
<LayoutAnchorablePaneGroup Orientation="Vertical" DockWidth="200">
<LayoutAnchorablePane x:Name="tonemappingPane" DockHeight="auto">
<LayoutAnchorable
Title="Tonemapping" ToolTip="Tonemapping" ContentId="Tonemapping"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<local:ToneMappingView DataContext="{Binding ToneMappingViewModel}"/>
</ScrollViewer>
</LayoutAnchorable>
</LayoutAnchorablePane>
<LayoutAnchorablePane x:Name="environmentPane" DockHeight="auto">
<LayoutAnchorable
Title="Environment" ToolTip="Environment" ContentId="Environment"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False" >
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Margin="8">
<Label>Background</Label>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<xctk:ColorPicker Grid.Column="0" Margin="0,0,8,0"
SelectedColor="{Binding IFSViewModel.BackgroundColor}"
IsEnabled="{Binding IsColorPickerEnabled}"/>
<CheckBox Grid.Column="1" ToolTip="Transparent background"
IsChecked="{Binding TransparentBackground}">🙾🙾</CheckBox>
</Grid>
<local:ValueSlider Value="{Binding Ifs.FogEffect}" SliderSettings="{Binding IFSViewModel.FogEffectSlider}"/>
</StackPanel>
</ScrollViewer>
</LayoutAnchorable>
</LayoutAnchorablePane>
<LayoutAnchorablePane DockHeight="*">
<LayoutAnchorable
Title="Camera" ToolTip="Camera" ContentId="Camera"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False" >
<ScrollViewer VerticalScrollBarVisibility="Auto">
<local:CameraSettingsView DataContext="{Binding CameraSettingsViewModel}"/>
</ScrollViewer>
</LayoutAnchorable>
<LayoutAnchorable
Title="Navigation" ToolTip="Transforms to navigate the camera" ContentId="Navigation"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<local:CameraNavigationPanel DataContext="{Binding CameraSettingsViewModel}"/>
</ScrollViewer>
</LayoutAnchorable>
</LayoutAnchorablePane>
</LayoutAnchorablePaneGroup>
<!--Middle-->
<LayoutPanel Orientation="Vertical">
<LayoutDocumentPaneGroup>
<LayoutDocumentPane>
<LayoutDocument
CanFloat="True"
CanClose="False"
ContentId="mainDocument"
IconSource="/Resources/icon_128.png">
<Grid Background="Black">
<disp:InteractiveDisplay x:Name="mainDisplay"
Visibility="{Binding Path=., Converter={StaticResource nullVisibilityConverter}}"
DisplayResolutionChanged="mainDisplay_DisplayResolutionChanged"
InteractionStartedCommand="{Binding TakeSnapshotCommand}"
InteractionFinishedCommand="{Binding InteractionFinishedCommand}"
GamepadConnectionStateChanged="mainDisplay_GamepadConnectionStateChanged"
Sensitivity="{Binding Sensitivity}"
InvertRotationAxisY="{Binding InvertAxisY}"/>
<local:ControlHintsPanel
Visibility="{Binding IsHintsPanelVisible, Converter={ StaticResource booleanToVisibilityConverter }}"
HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="16"/>
<ProgressBar Style="{StaticResource MaterialDesignCircularProgressBar}"
Visibility="{Binding Path=., Converter={StaticResource nullVisibilityConverter}, ConverterParameter=true}"
Width="50" Height="50"
IsIndeterminate="True"/>
</Grid>
</LayoutDocument>
</LayoutDocumentPane>
</LayoutDocumentPaneGroup>
<LayoutAnchorablePaneGroup DockHeight="300">
<LayoutAnchorablePane>
<LayoutAnchorable x:Name="animationsPanel" IsActiveChanged="animationsPanel_IsActiveChanged"
Title="Animations" ToolTip="Animations" ContentId="Animations"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False"
>
<animation:AnimationPanel DataContext="{Binding AnimationViewModel}"/>
</LayoutAnchorable>
</LayoutAnchorablePane>
</LayoutAnchorablePaneGroup>
</LayoutPanel>
<!--Right Side-->
<LayoutAnchorablePaneGroup Orientation="Vertical" DockWidth="250">
<LayoutAnchorablePane>
<LayoutAnchorable
Title="Rendering Settings" ToolTip="Rendering Settings" ContentId="Rendering Settings"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False" >
<ScrollViewer VerticalScrollBarVisibility="Auto">
<local:QualitySettingsView DataContext="{Binding QualitySettingsViewModel}"/>
</ScrollViewer>
</LayoutAnchorable>
<LayoutAnchorable
Title="Post Fx" ToolTip="Post effects" ContentId="PostFx"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False" >
<local:PostFxPanel DataContext="{Binding PostFxPanelViewModel}"/>
</LayoutAnchorable>
</LayoutAnchorablePane>
<LayoutAnchorablePane x:Name="performancePane" DockHeight="auto">
<LayoutAnchorable
Title="Performance" ToolTip="Performance" ContentId="Performance"
CanHide="False" CanClose="False" CanFloat="True" CanMove="True" CanShowOnHover="False">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<local:PerformanceView DataContext="{Binding PerformanceViewModel}"/>
</ScrollViewer>
</LayoutAnchorable>
</LayoutAnchorablePane>
</LayoutAnchorablePaneGroup>
</LayoutPanel>
</LayoutPanel>
<!--<LayoutRoot.LeftSide>
<LayoutAnchorSide>
<LayoutAnchorGroup>
<LayoutAnchorable
Title="AutoHide1 Content"
ContentId="AutoHide1Content"
IconSource="/Resources/icon_128.png">
<TextBox Text="{Binding TestTimer, Mode=OneWay, StringFormat='AutoHide Attached to Timer ->\{0\}'}" />
</LayoutAnchorable>
<LayoutAnchorable Title="AutoHide2 Content" ContentId="AutoHide2Content">
<StackPanel Orientation="Vertical">
<TextBox />
<TextBox />
</StackPanel>
</LayoutAnchorable>
</LayoutAnchorGroup>
</LayoutAnchorSide>
</LayoutRoot.LeftSide>-->
</LayoutRoot>
</DockingManager>
<md:Card Grid.Row="3" Padding="3" Margin="8" VerticalAlignment="Stretch">
<StatusBar Background="Transparent">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<!--Avoid filling up unused space on status bar-->
<DockPanel LastChildFill="False" />
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem>
<TextBlock
Text="{Binding StatusBarText, NotifyOnTargetUpdated=True}"
Foreground="LightGray">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" BeginTime="0:0:0" Duration="0:0:1" From="0.0" To="1.0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</StatusBarItem>
<StatusBarItem DockPanel.Dock="Right" VerticalContentAlignment="Stretch">
<Grid>
<ProgressBar Width="100" Value="{Binding IterationProgressPercent, Mode=OneWay}" VerticalAlignment="Bottom"/>
<TextBlock VerticalAlignment="Top" Margin="0 -4" TextAlignment="Center"
ToolTip="Iteration progress" Style="{StaticResource MaterialDesignLabelSmallTextBlock}" Foreground="White">
Progress: <Run Text="{Binding IterationLevel, Mode=OneWay}"/> / <Run Text="{Binding Ifs.TargetIterationLevel, Mode=OneWay}"/>
</TextBlock>
</Grid>
</StatusBarItem>
<StatusBarItem DockPanel.Dock="Right" Padding="0">
<ToggleButton
Content="{Binding IsRenderingIcon}" Command="{Binding StartStopRenderingCommand}"
Width="20" Height="20" Padding="0" Margin="0"
Style="{StaticResource MaterialDesignFlatButton}" FontFamily="Monospace" ToolTip="Resume/Pause rendering (Pause key)" d:Content="||"/>
</StatusBarItem>
<Separator DockPanel.Dock="Right"/>
<StatusBarItem DockPanel.Dock="Right"
Visibility="{Binding IsGamepadConnected, Converter={StaticResource booleanToVisibilityConverter}, FallbackValue=Hidden}" d:Visibility="Visible">
<StatusBarItem.Style>
<Style TargetType="{x:Type StatusBarItem}">
<Style.Triggers>
<!--Blink icon after gamepad connected-->
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard Duration="0:0:3">
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0"
Duration="0:0:0.5" AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</StatusBarItem.Style>
<md:PackIcon Kind="MicrosoftXboxGamepad" Foreground="White"/>
</StatusBarItem>
</StatusBar>
</md:Card>
</Grid>
</Window>