Refactor DrawingNode template
This commit is contained in:
Родитель
6116cd621d
Коммит
9ed8b6a920
|
@ -41,7 +41,7 @@
|
||||||
<Viewbox DockPanel.Dock="Left" Width="32" Height="32" DataContext="{Binding Preview}">
|
<Viewbox DockPanel.Dock="Left" Width="32" Height="32" DataContext="{Binding Preview}">
|
||||||
<editor:Node IsHitTestVisible="False">
|
<editor:Node IsHitTestVisible="False">
|
||||||
<editor:Node.Styles>
|
<editor:Node.Styles>
|
||||||
<Style Selector="editor|Node /template/ ItemsControl#PART_PinsItemsControl">
|
<Style Selector="editor|Pins /template/ ItemsControl#PART_PinsItemsControl">
|
||||||
<Setter Property="IsVisible" Value="False" />
|
<Setter Property="IsVisible" Value="False" />
|
||||||
</Style>
|
</Style>
|
||||||
</editor:Node.Styles>
|
</editor:Node.Styles>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
|
||||||
|
namespace NodeEditor.Controls;
|
||||||
|
|
||||||
|
public class Connectors : TemplatedControl
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
|
||||||
|
namespace NodeEditor.Controls;
|
||||||
|
|
||||||
|
public class Nodes : TemplatedControl
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
|
||||||
|
namespace NodeEditor.Controls;
|
||||||
|
|
||||||
|
public class Pins : TemplatedControl
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:m="clr-namespace:NodeEditor.Model;assembly=NodeEditorAvalonia.Model"
|
||||||
|
xmlns:converters="clr-namespace:NodeEditor.Converters"
|
||||||
|
xmlns:controls="clr-namespace:NodeEditor.Controls"
|
||||||
|
x:CompileBindings="True">
|
||||||
|
|
||||||
|
<ControlTheme x:Key="{x:Type controls:Connectors}" TargetType="controls:Connectors">
|
||||||
|
|
||||||
|
<Setter Property="ClipToBounds" Value="False" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate x:DataType="m:IDrawingNode">
|
||||||
|
<ItemsControl Name="PART_ConnectorsItemsControl"
|
||||||
|
Items="{Binding Connectors}"
|
||||||
|
Width="{Binding Width}"
|
||||||
|
Height="{Binding Height}"
|
||||||
|
Background="Transparent"
|
||||||
|
IsHitTestVisible="False"
|
||||||
|
ClipToBounds="False">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<Canvas />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate DataType="m:IConnector">
|
||||||
|
<controls:Connector Name="PART_Connector"
|
||||||
|
StartPoint="{Binding Start, Converter={x:Static converters:PinToPointConverter.Instance}}"
|
||||||
|
EndPoint="{Binding End, Converter={x:Static converters:PinToPointConverter.Instance}}"
|
||||||
|
Offset="{Binding Offset}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
</ControlTheme>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
|
@ -1,9 +1,6 @@
|
||||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:m="clr-namespace:NodeEditor.Model;assembly=NodeEditorAvalonia.Model"
|
xmlns:m="clr-namespace:NodeEditor.Model;assembly=NodeEditorAvalonia.Model"
|
||||||
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
|
|
||||||
xmlns:behaviors="clr-namespace:NodeEditor.Behaviors"
|
|
||||||
xmlns:converters="clr-namespace:NodeEditor.Converters"
|
|
||||||
xmlns:controls="clr-namespace:NodeEditor.Controls"
|
xmlns:controls="clr-namespace:NodeEditor.Controls"
|
||||||
x:CompileBindings="True">
|
x:CompileBindings="True">
|
||||||
|
|
||||||
|
@ -27,64 +24,12 @@
|
||||||
<controls:GridDecorator EnableGrid="{TemplateBinding EnableGrid}"
|
<controls:GridDecorator EnableGrid="{TemplateBinding EnableGrid}"
|
||||||
GridCellWidth="{TemplateBinding GridCellWidth}"
|
GridCellWidth="{TemplateBinding GridCellWidth}"
|
||||||
GridCellHeight="{TemplateBinding GridCellHeight}" />
|
GridCellHeight="{TemplateBinding GridCellHeight}" />
|
||||||
<ItemsControl Name="PART_NodesItemsControl"
|
<controls:Connectors Name="PART_Connectors" />
|
||||||
Items="{Binding Nodes}"
|
<controls:Nodes Name="PART_Nodes" />
|
||||||
Width="{Binding Width}"
|
|
||||||
Height="{Binding Height}"
|
|
||||||
Background="Transparent"
|
|
||||||
ClipToBounds="False">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<behaviors:NodesSelectedBehavior />
|
|
||||||
<behaviors:DrawingSelectionBehavior InputSource="{Binding $parent[controls:DrawingNode].InputSource}"
|
|
||||||
AdornerCanvas="{Binding $parent[controls:DrawingNode].AdornerCanvas}"
|
|
||||||
EnableSnap="{Binding $parent[controls:DrawingNode].EnableSnap}"
|
|
||||||
SnapX="{Binding $parent[controls:DrawingNode].SnapX}"
|
|
||||||
SnapY="{Binding $parent[controls:DrawingNode].SnapY}"
|
|
||||||
x:CompileBindings="False" />
|
|
||||||
<behaviors:DrawingPressedBehavior />
|
|
||||||
<behaviors:DrawingMovedBehavior />
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
<ItemsControl.Styles>
|
|
||||||
<Style Selector="ItemsControl > ContentPresenter" x:DataType="m:INode">
|
|
||||||
<Setter Property="Canvas.Left" Value="{Binding X}" />
|
|
||||||
<Setter Property="Canvas.Top" Value="{Binding Y}" />
|
|
||||||
</Style>
|
|
||||||
</ItemsControl.Styles>
|
|
||||||
<ItemsControl.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<Canvas />
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ItemsControl.ItemsPanel>
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate DataType="m:INode">
|
|
||||||
<controls:Node Name="PART_Node" />
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
<ItemsControl Name="PART_ConnectorsItemsControl"
|
|
||||||
Items="{Binding Connectors}"
|
|
||||||
Width="{Binding Width}"
|
|
||||||
Height="{Binding Height}"
|
|
||||||
Background="Transparent"
|
|
||||||
IsHitTestVisible="False"
|
|
||||||
ClipToBounds="False">
|
|
||||||
<ItemsControl.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<Canvas />
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ItemsControl.ItemsPanel>
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate DataType="m:IConnector">
|
|
||||||
<controls:Connector Name="PART_Connector"
|
|
||||||
StartPoint="{Binding Start, Converter={x:Static converters:PinToPointConverter.Instance}}"
|
|
||||||
EndPoint="{Binding End, Converter={x:Static converters:PinToPointConverter.Instance}}"
|
|
||||||
Offset="{Binding Offset}"/>
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
</Panel>
|
</Panel>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
|
||||||
</ControlTheme>
|
</ControlTheme>
|
||||||
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:m="clr-namespace:NodeEditor.Model;assembly=NodeEditorAvalonia.Model"
|
xmlns:m="clr-namespace:NodeEditor.Model;assembly=NodeEditorAvalonia.Model"
|
||||||
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
|
|
||||||
xmlns:behaviors="clr-namespace:NodeEditor.Behaviors"
|
|
||||||
xmlns:controls="clr-namespace:NodeEditor.Controls"
|
xmlns:controls="clr-namespace:NodeEditor.Controls"
|
||||||
x:CompileBindings="True">
|
x:CompileBindings="True">
|
||||||
|
|
||||||
|
@ -18,66 +16,17 @@
|
||||||
Height="{Binding Height}">
|
Height="{Binding Height}">
|
||||||
<ContentPresenter Name="PART_ContentPresenter"
|
<ContentPresenter Name="PART_ContentPresenter"
|
||||||
Content="{Binding Content}"/>
|
Content="{Binding Content}"/>
|
||||||
<ItemsControl Name="PART_PinsItemsControl"
|
<controls:Pins Name="PART_Pins" />
|
||||||
Items="{Binding Pins}"
|
|
||||||
Width="{Binding Width}"
|
|
||||||
Height="{Binding Height}"
|
|
||||||
ClipToBounds="False">
|
|
||||||
<ItemsControl.Styles>
|
|
||||||
<Style Selector="ItemsControl > ContentPresenter" x:DataType="m:IPin">
|
|
||||||
<Setter Property="Canvas.Left" Value="{Binding X}" />
|
|
||||||
<Setter Property="Canvas.Top" Value="{Binding Y}" />
|
|
||||||
</Style>
|
|
||||||
<!-- Workaround -->
|
|
||||||
<Style Selector="ItemsControl > :is(ContentPresenter)">
|
|
||||||
<Setter Property="(i:Interaction.Behaviors)">
|
|
||||||
<i:BehaviorCollectionTemplate>
|
|
||||||
<i:BehaviorCollection>
|
|
||||||
<behaviors:PinPressedBehavior />
|
|
||||||
</i:BehaviorCollection>
|
|
||||||
</i:BehaviorCollectionTemplate>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
</ItemsControl.Styles>
|
|
||||||
<ItemsControl.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<Canvas />
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ItemsControl.ItemsPanel>
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate DataType="m:IPin">
|
|
||||||
<controls:Pin Name="PART_Pin" />
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
</Panel>
|
</Panel>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
|
||||||
<!--
|
|
||||||
<Style Selector="^/template/ ItemsControl#PART_PinsItemsControl > :is(ContentPresenter)">
|
|
||||||
<Setter Property="(i:Interaction.Behaviors)">
|
|
||||||
<i:BehaviorCollectionTemplate>
|
|
||||||
<i:BehaviorCollection>
|
|
||||||
<behaviors:PinPressedBehavior />
|
|
||||||
</i:BehaviorCollection>
|
|
||||||
</i:BehaviorCollectionTemplate>
|
|
||||||
</Setter>
|
|
||||||
</Style>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<Style Selector="^/template/ ContentPresenter#PART_ContentPresenter">
|
<Style Selector="^/template/ ContentPresenter#PART_ContentPresenter">
|
||||||
<Setter Property="IsHitTestVisible" Value="{Binding $self.(controls:DrawingNode.IsEditMode), Mode=OneWay, Converter={x:Static BoolConverters.Not}}"
|
<Setter Property="IsHitTestVisible" Value="{Binding $self.(controls:DrawingNode.IsEditMode), Mode=OneWay, Converter={x:Static BoolConverters.Not}}"
|
||||||
x:DataType="controls:Node"
|
x:DataType="controls:Node"
|
||||||
x:CompileBindings="False"/>
|
x:CompileBindings="False"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<!--
|
|
||||||
<Style Selector="^/template/ ItemsControl#PART_PinsItemsControl">
|
|
||||||
<Setter Property="IsVisible" Value="False" />
|
|
||||||
</Style>
|
|
||||||
-->
|
|
||||||
|
|
||||||
</ControlTheme>
|
</ControlTheme>
|
||||||
|
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|
|
@ -16,9 +16,12 @@
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</ResourceDictionary.ThemeDictionaries>
|
</ResourceDictionary.ThemeDictionaries>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Node.axaml" />
|
|
||||||
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Connector.axaml" />
|
|
||||||
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Pin.axaml" />
|
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Pin.axaml" />
|
||||||
|
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Pins.axaml" />
|
||||||
|
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Node.axaml" />
|
||||||
|
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Nodes.axaml" />
|
||||||
|
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Connector.axaml" />
|
||||||
|
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/Connectors.axaml" />
|
||||||
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/DrawingNode.axaml" />
|
<ResourceInclude Source="avares://NodeEditorAvalonia/Themes/DrawingNode.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:m="clr-namespace:NodeEditor.Model;assembly=NodeEditorAvalonia.Model"
|
||||||
|
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
|
||||||
|
xmlns:behaviors="clr-namespace:NodeEditor.Behaviors"
|
||||||
|
xmlns:controls="clr-namespace:NodeEditor.Controls"
|
||||||
|
x:CompileBindings="True">
|
||||||
|
|
||||||
|
<ControlTheme x:Key="{x:Type controls:Nodes}" TargetType="controls:Nodes">
|
||||||
|
|
||||||
|
<Setter Property="ClipToBounds" Value="False" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate x:DataType="m:IDrawingNode">
|
||||||
|
<ItemsControl Name="PART_NodesItemsControl"
|
||||||
|
Items="{Binding Nodes}"
|
||||||
|
Width="{Binding Width}"
|
||||||
|
Height="{Binding Height}"
|
||||||
|
Background="Transparent"
|
||||||
|
ClipToBounds="False">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<behaviors:NodesSelectedBehavior />
|
||||||
|
<!-- TODO: Fix using $parent[controls:DrawingNode] -->
|
||||||
|
<behaviors:DrawingSelectionBehavior InputSource="{Binding $parent[controls:DrawingNode].InputSource}"
|
||||||
|
AdornerCanvas="{Binding $parent[controls:DrawingNode].AdornerCanvas}"
|
||||||
|
EnableSnap="{Binding $parent[controls:DrawingNode].EnableSnap}"
|
||||||
|
SnapX="{Binding $parent[controls:DrawingNode].SnapX}"
|
||||||
|
SnapY="{Binding $parent[controls:DrawingNode].SnapY}"
|
||||||
|
x:CompileBindings="False" />
|
||||||
|
<behaviors:DrawingPressedBehavior />
|
||||||
|
<behaviors:DrawingMovedBehavior />
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
<ItemsControl.Styles>
|
||||||
|
<Style Selector="ItemsControl > ContentPresenter" x:DataType="m:INode">
|
||||||
|
<Setter Property="Canvas.Left" Value="{Binding X}" />
|
||||||
|
<Setter Property="Canvas.Top" Value="{Binding Y}" />
|
||||||
|
</Style>
|
||||||
|
</ItemsControl.Styles>
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<Canvas />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate DataType="m:INode">
|
||||||
|
<controls:Node Name="PART_Node" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
</ControlTheme>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
|
@ -0,0 +1,70 @@
|
||||||
|
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:m="clr-namespace:NodeEditor.Model;assembly=NodeEditorAvalonia.Model"
|
||||||
|
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
|
||||||
|
xmlns:behaviors="clr-namespace:NodeEditor.Behaviors"
|
||||||
|
xmlns:controls="clr-namespace:NodeEditor.Controls"
|
||||||
|
x:CompileBindings="True">
|
||||||
|
|
||||||
|
<ControlTheme x:Key="{x:Type controls:Pins}" TargetType="controls:Pins">
|
||||||
|
|
||||||
|
<Setter Property="ClipToBounds" Value="False" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<ControlTemplate x:DataType="m:INode">
|
||||||
|
<ItemsControl Name="PART_PinsItemsControl"
|
||||||
|
Items="{Binding Pins}"
|
||||||
|
Width="{Binding Width}"
|
||||||
|
Height="{Binding Height}"
|
||||||
|
ClipToBounds="False">
|
||||||
|
<ItemsControl.Styles>
|
||||||
|
<Style Selector="ItemsControl > ContentPresenter" x:DataType="m:IPin">
|
||||||
|
<Setter Property="Canvas.Left" Value="{Binding X}" />
|
||||||
|
<Setter Property="Canvas.Top" Value="{Binding Y}" />
|
||||||
|
</Style>
|
||||||
|
<!-- TODO: Workaround -->
|
||||||
|
<Style Selector="ItemsControl > :is(ContentPresenter)">
|
||||||
|
<Setter Property="(i:Interaction.Behaviors)">
|
||||||
|
<i:BehaviorCollectionTemplate>
|
||||||
|
<i:BehaviorCollection>
|
||||||
|
<behaviors:PinPressedBehavior />
|
||||||
|
</i:BehaviorCollection>
|
||||||
|
</i:BehaviorCollectionTemplate>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
</ItemsControl.Styles>
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<Canvas />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate DataType="m:IPin">
|
||||||
|
<controls:Pin Name="PART_Pin" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<Style Selector="^/template/ ItemsControl#PART_PinsItemsControl > :is(ContentPresenter)">
|
||||||
|
<Setter Property="(i:Interaction.Behaviors)">
|
||||||
|
<i:BehaviorCollectionTemplate>
|
||||||
|
<i:BehaviorCollection>
|
||||||
|
<behaviors:PinPressedBehavior />
|
||||||
|
</i:BehaviorCollection>
|
||||||
|
</i:BehaviorCollectionTemplate>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<Style Selector="^/template/ ItemsControl#PART_PinsItemsControl">
|
||||||
|
<Setter Property="IsVisible" Value="False" />
|
||||||
|
</Style>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</ControlTheme>
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
Загрузка…
Ссылка в новой задаче