Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions TgaBuilderAvaloniaUi/App.DI.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,12 @@ private void AddTabVMsToProvider(IServiceCollection services)
panel: sp.GetRequiredService<TargetTexturePanelViewModel>(),
messageBoxService: sp.GetRequiredService<IMessageBoxService>()));

services.AddTransient(sp => new ViewTabViewModel(
services.AddTransient<IViewTabViewModel>(sp => new ReadOnlyViewTabViewModel(
visualPanelSize: sp.GetServices<PanelVisualSizeViewModel>()
.ElementAt((int)PresenterType.Source),
panel: sp.GetRequiredService<SourceTexturePanelViewModel>()));

services.AddTransient(sp => new ViewTabViewModel(
services.AddTransient<IViewTabViewModel>(sp => new ReadOnlyViewTabViewModel(
visualPanelSize: sp.GetServices<PanelVisualSizeViewModel>()
.ElementAt((int)PresenterType.Target),
panel: sp.GetRequiredService<TargetTexturePanelViewModel>()));
Expand Down Expand Up @@ -297,9 +297,9 @@ private void AddViewVMsToProvider(IServiceCollection services)
.ElementAt((int)PresenterType.Target),


sourceViewTab: sp.GetServices<ViewTabViewModel>()
sourceViewTab: sp.GetServices<IViewTabViewModel>()
.ElementAt((int)PresenterType.Source),
destinationViewTab: sp.GetServices<ViewTabViewModel>()
destinationViewTab: sp.GetServices<IViewTabViewModel>()
.ElementAt((int)PresenterType.Target),

usageData: sp.GetRequiredService<IUsageData>()));
Expand Down
48 changes: 48 additions & 0 deletions TgaBuilderAvaloniaUi/View/MainWindow.Methods.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@

using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.PanAndZoom;
using Avalonia.Threading;
using Avalonia.VisualTree;
using System;
using TgaBuilderLib.ViewModel;

namespace TgaBuilderAvaloniaUi.View
{
Expand All @@ -27,5 +30,50 @@ public ZoomBorder GetPanelFromImage(Image image)

public void SetPanelFromImage(Image image)
=> CurrentPanel = GetPanelFromImage(image);

public void RegisterZoomBorderCallbacks(ReadOnlyViewTabViewModel viewTab, ZoomBorder panel)
{
viewTab.ApplyTransformCallback = (zoom, translateX, translateY) =>
{
Dispatcher.UIThread.Post(() =>
{
var matrix = Matrix.CreateScale(zoom, zoom) *
Matrix.CreateTranslation(translateX, translateY);
panel.SetMatrix(matrix);
});
};

viewTab.PanStepCallback = (deltaX, deltaY) =>
{
Dispatcher.UIThread.Post(() =>
{
panel.SetMatrix(panel.Matrix * Matrix.CreateTranslation(deltaX, deltaY));
});
};

viewTab.ZoomStepCallback = (zoomDelta) =>
{
Dispatcher.UIThread.Post(() =>
{
var currentMatrix = panel.Matrix;
double centerX = panel.Bounds.Width / 2;
double centerY = panel.Bounds.Height / 2;

var matrix = currentMatrix *
Matrix.CreateTranslation(-centerX, -centerY) *
Matrix.CreateScale(zoomDelta, zoomDelta) *
Matrix.CreateTranslation(centerX, centerY);
panel.SetMatrix(matrix);
});
};

viewTab.ResetViewCallback = () =>
{
Dispatcher.UIThread.Post(() =>
{
panel.ResetMatrix();
});
};
}
}
}
88 changes: 20 additions & 68 deletions TgaBuilderAvaloniaUi/View/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -422,17 +422,10 @@
ap:MouseOverInfoAP.InfoText="{Binding PanelHelp, Converter={StaticResource PanelHelpConverter}}"
ClipToBounds="True"
DropCommand="{Binding FileDropSourceCommand}">
<ScrollViewer
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
>
<paz:ZoomBorder
x:Name="SourcePanel"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ap:PanelAttributesAP.OffsetXAtr="{Binding MultipliedOffsetX}"
ap:PanelAttributesAP.OffsetYAtr="{Binding MultipliedOffsetY}"
ap:PanelAttributesAP.ZoomAtr="{Binding Zoom}"
ap:PanelMouseAP.ScrollCommand="{Binding ScrollCommand}"
ap:SizeObserverAP.ObserveSize="True"
ap:SizeObserverAP.ObservedHeight="{Binding VisualPanelSize.ViewportHeight, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}"
Expand All @@ -448,8 +441,6 @@
PanButton="Middle"
Stretch="None"
ZoomSpeed="1.5"
OffsetX="{Binding MultipliedOffsetX, Mode=OneWayToSource}"
OffsetY="{Binding MultipliedOffsetY, Mode=OneWayToSource}"
ZoomX="{Binding Zoom, Mode=OneWayToSource}"
ZoomY="{Binding Zoom, Mode=OneWayToSource}">

Expand Down Expand Up @@ -522,7 +513,6 @@
StrokeThickness="{Binding StrokeThickness}" />
</Canvas>
</paz:ZoomBorder>
</ScrollViewer>
</elements:FileDropBorder>
<TextBlock
Grid.Row="1"
Expand Down Expand Up @@ -578,30 +568,16 @@
DataContext="{Binding Source}"
DockPanel.Dock="Right"
Value="{Binding SelectedPickerSize, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<Path
Margin="0,5,0,0"
Fill="Black"
Data="{StaticResource zoom_out}"
ap:MouseOverInfoAP.InfoText="Zoom level (Ctrl + Mouse Wheel on the panel)"
DockPanel.Dock="Left"
/>
<Path
Margin="0,5,10,0"
Fill="Black"
Data="{StaticResource zoom_in}"
ap:MouseOverInfoAP.InfoText="Zoom level (Ctrl + Mouse Wheel on the panel)"
DockPanel.Dock="Right"
/>
<Slider
MinWidth="3"
Margin="5,0"
Padding="0,-10"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
ap:MouseOverInfoAP.InfoText="Zoom level (Ctrl + Mouse Wheel on the panel)"
Maximum="10"
Minimum="0.1"
Value="{Binding SourceViewTab.Zoom, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<elements:IconButton
Icon="{StaticResource zoom_out}"
ap:MouseOverInfoAP.InfoText="Zoom out (Ctrl + Mouse Wheel on the panel)"
Command="{Binding SourceViewTab.ZoomOutCommand}"
DockPanel.Dock="Left" />
<elements:IconButton
Icon="{StaticResource zoom_in}"
ap:MouseOverInfoAP.InfoText="Zoom in (Ctrl + Mouse Wheel on the panel)"
Command="{Binding SourceViewTab.ZoomInCommand}"
DockPanel.Dock="Left" />
</DockPanel>
</Grid>

Expand Down Expand Up @@ -1075,17 +1051,10 @@
ap:MouseOverInfoAP.InfoText="{Binding PanelHelp, Converter={StaticResource PanelHelpConverter}}"
ClipToBounds="True"
DropCommand="{Binding FileDropDestinationCommand}">
<ScrollViewer
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
>
<paz:ZoomBorder
x:Name="TargetPanel"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ap:PanelAttributesAP.OffsetXAtr="{Binding MultipliedOffsetX}"
ap:PanelAttributesAP.OffsetYAtr="{Binding MultipliedOffsetY}"
ap:PanelAttributesAP.ZoomAtr="{Binding Zoom}"
ap:PanelMouseAP.ScrollCommand="{Binding ScrollCommand}"
ap:SizeObserverAP.ObserveSize="True"
ap:SizeObserverAP.ObservedHeight="{Binding VisualPanelSize.ViewportHeight, Mode=OneWayToSource}"
Expand All @@ -1101,8 +1070,6 @@
PanButton="Middle"
Stretch="None"
ZoomSpeed="1.5"
OffsetX="{Binding MultipliedOffsetX, Mode=OneWayToSource}"
OffsetY="{Binding MultipliedOffsetY, Mode=OneWayToSource}"
ZoomX="{Binding Zoom, Mode=OneWayToSource}"
ZoomY="{Binding Zoom, Mode=OneWayToSource}">
<Canvas
Expand Down Expand Up @@ -1217,7 +1184,6 @@
</Canvas>

</paz:ZoomBorder>
</ScrollViewer>
</elements:FileDropBorder>
<TextBlock
Grid.Row="1"
Expand Down Expand Up @@ -1272,30 +1238,16 @@
DataContext="{Binding Destination}"
DockPanel.Dock="Right"
Value="{Binding SelectedPickerSize, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<Path
Margin="0,5,0,0"
Fill="Black"
Data="{StaticResource zoom_out}"
ap:MouseOverInfoAP.InfoText="Zoom level (Ctrl + Mouse Wheel on the panel)"
DockPanel.Dock="Left"
/>
<Path
Margin="0,5,10,0"
Fill="Black"
Data="{StaticResource zoom_in}"
ap:MouseOverInfoAP.InfoText="Zoom level (Ctrl + Mouse Wheel on the panel)"
DockPanel.Dock="Right"
/>
<Slider
MinWidth="3"
Margin="5,0"
Padding="0,-10"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
ap:MouseOverInfoAP.InfoText="Zoom level (Ctrl + Mouse Wheel on the panel)"
Maximum="10"
Minimum="0.1"
Value="{Binding DestinationViewTab.Zoom, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<elements:IconButton
Icon="{StaticResource zoom_out}"
ap:MouseOverInfoAP.InfoText="Zoom out (Ctrl + Mouse Wheel on the panel)"
Command="{Binding DestinationViewTab.ZoomOutCommand}"
DockPanel.Dock="Left" />
<elements:IconButton
Icon="{StaticResource zoom_in}"
ap:MouseOverInfoAP.InfoText="Zoom in (Ctrl + Mouse Wheel on the panel)"
Command="{Binding DestinationViewTab.ZoomInCommand}"
DockPanel.Dock="Left" />
</DockPanel>
</Grid>

Expand Down
13 changes: 13 additions & 0 deletions TgaBuilderAvaloniaUi/View/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ public MainWindow(INotifyPropertyChanged mainViewModel)

InitializeComponent();
base.DataContext = mainViewModel;

if (mainViewModel is MainViewModel vm)
{
this.Opened += (_, _) =>
{
var sourcePanel = this.FindControl<ZoomBorder>("SourcePanel");
var targetPanel = this.FindControl<ZoomBorder>("TargetPanel");
if (sourcePanel != null && vm.SourceViewTab is ReadOnlyViewTabViewModel sourceVm)
RegisterZoomBorderCallbacks(sourceVm, sourcePanel);
if (targetPanel != null && vm.DestinationViewTab is ReadOnlyViewTabViewModel targetVm)
RegisterZoomBorderCallbacks(targetVm, targetPanel);
};
}
}

[Obsolete("For designer use only")]
Expand Down
42 changes: 42 additions & 0 deletions TgaBuilderLib/Abstraction/IViewTabViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.ComponentModel;
using System.Windows.Input;
using TgaBuilderLib.ViewModel;

namespace TgaBuilderLib.Abstraction
{
/// <summary>
/// Interface for view tab view models that control zoom and pan behavior
/// for texture panels. Provides the common contract used by both
/// writable (WPF) and read-only (Avalonia) implementations.
/// </summary>
public interface IViewTabViewModel : INotifyPropertyChanged
{
bool IsScrolling { get; set; }

PanelVisualSizeViewModel VisualPanelSize { get; }

double ContentActualWidth { get; }
double ContentActualHeight { get; }

double OffsetX { get; set; }
double OffsetY { get; set; }
double Zoom { get; set; }

double MultipliedOffsetX { get; set; }
double MultipliedOffsetY { get; set; }

double HorizonatlMargin { get; set; }

ICommand FillCommand { get; }
ICommand FitCommand { get; }
ICommand Zoom100Command { get; }
ICommand ScrollCommand { get; }
ICommand ZoomInCommand { get; }
ICommand ZoomOutCommand { get; }

Task DefferedFill();
void Fill();
void Fit();
void Zoom100();
}
}
Loading