<!-- Copyright © Northwoods Software Corporation, 2008-2026. All Rights Reserved. -->

<UserControl x:Class="DraggableLink.DraggableLink" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:go="http://schemas.nwoods.com/GoXam"
    xmlns:local="clr-namespace:DraggableLink">
  <UserControl.Resources>
    <DataTemplate x:Key="NodeSelectionAdornmentTemplate">
      <go:SelectionHandle go:Part.Selectable="False"
            Stroke="DeepSkyBlue" StrokeThickness="1" StrokeDashArray="2 2" />
    </DataTemplate>

    <DataTemplate x:Key="NodeResizeAdornmentTemplate">
      <go:SpotPanel>
        <go:ToolHandle go:SpotPanel.Spot="0.0 0.0" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />
        <go:ToolHandle go:SpotPanel.Spot="0.5 0.0" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />
        <go:ToolHandle go:SpotPanel.Spot="1.0 0.0" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />

        <go:ToolHandle go:SpotPanel.Spot="0.0 0.5" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />
        <go:ToolHandle go:SpotPanel.Spot="1.0 0.5" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />

        <go:ToolHandle go:SpotPanel.Spot="0.0 1.0" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />
        <go:ToolHandle go:SpotPanel.Spot="0.5 1.0" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />
        <go:ToolHandle go:SpotPanel.Spot="1.0 1.0" go:NodePanel.Figure="Rectangle" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />
      </go:SpotPanel>
    </DataTemplate>

    <DataTemplate x:Key="NodeRotateAdornmentTemplate">
      <go:ToolHandle go:NodePanel.Figure="Ellipse" Width="6" Height="6" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" Cursor="Hand" />
    </DataTemplate>
    
    <DataTemplate x:Key="NodeTemplate">
      <go:SpotPanel
          go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"
          go:Node.LocationSpot="Center"
          go:Part.SelectionAdorned="True"
          go:Part.SelectionAdornmentTemplate="{StaticResource NodeSelectionAdornmentTemplate}"
          go:Part.Resizable="True"
          go:Part.ResizeElementName="Icon"
          go:Part.ResizeAdornmentTemplate="{StaticResource NodeResizeAdornmentTemplate}"
          go:Node.RotationAngle="{Binding Path=Data.Angle, Mode=TwoWay}"
          go:Part.Rotatable="True"
          go:Part.RotateAdornmentTemplate="{StaticResource NodeRotateAdornmentTemplate}">
        <go:NodePanel>
          <go:NodeShape x:Name="Icon"
                go:NodePanel.Figure="{Binding Path=Data.Figure}"
                Stroke="Black" StrokeThickness="1"
                Fill="{Binding Path=Data.Color}"
                Width="{Binding Path=Data.Width, Mode=TwoWay}"
                Height="{Binding Path=Data.Height, Mode=TwoWay}"
                MinWidth="10" MinHeight="10"
                go:NodePanel.Spot1="0 0" go:NodePanel.Spot2="1 1"
                go:Node.PortId="" go:Node.LinkableFrom="True" go:Node.LinkableTo="True" Cursor="Hand"
                go:Node.LinkableDuplicates="True" go:Node.LinkableSelfNode="True" />
          <Rectangle Fill="Transparent" Margin="12" 
                     HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
          <TextBlock Text="{Binding Path=Data.Text, Mode=TwoWay}" TextWrapping="Wrap"
                     HorizontalAlignment="Center" VerticalAlignment="Center"
                     go:Part.TextEditable="True" />
        </go:NodePanel>
        <Rectangle Fill="Transparent" Width="6" Height="6"
                 go:SpotPanel.Spot="MiddleLeft" go:SpotPanel.Alignment="MiddleLeft"
                 go:Node.PortId="L" go:Node.LinkableFrom="True" go:Node.LinkableTo="True" Cursor="Hand"
                 go:Node.FromSpot="MiddleLeft" go:Node.ToSpot="MiddleLeft" />
        <Rectangle Fill="Transparent" Width="6" Height="6"
                 go:SpotPanel.Spot="MiddleTop" go:SpotPanel.Alignment="MiddleTop"
                 go:Node.PortId="T" go:Node.LinkableFrom="True" go:Node.LinkableTo="True" Cursor="Hand"
                 go:Node.FromSpot="MiddleTop" go:Node.ToSpot="MiddleTop" />
        <Rectangle Fill="Transparent" Width="6" Height="6"
                 go:SpotPanel.Spot="MiddleRight" go:SpotPanel.Alignment="MiddleRight"
                 go:Node.PortId="R" go:Node.LinkableFrom="True" go:Node.LinkableTo="True" Cursor="Hand"
                 go:Node.FromSpot="MiddleRight" go:Node.ToSpot="MiddleRight" />
        <Rectangle Fill="Transparent" Width="6" Height="6"
                 go:SpotPanel.Spot="MiddleBottom" go:SpotPanel.Alignment="MiddleBottom"
                 go:Node.PortId="B" go:Node.LinkableFrom="True" go:Node.LinkableTo="True" Cursor="Hand"
                 go:Node.FromSpot="MiddleBottom" go:Node.ToSpot="MiddleBottom" />
      </go:SpotPanel>
    </DataTemplate>

    <DataTemplate x:Key="PaletteNodeTemplate">
      <go:NodePanel go:Part.SelectionAdorned="True">
        <go:NodeShape go:NodePanel.Figure="{Binding Path=Data.Figure}"
              Stroke="Black" StrokeThickness="1"
              Fill="{Binding Path=Data.Color}"
              Width="{Binding Path=Data.Width, Mode=TwoWay}"
              Height="{Binding Path=Data.Height, Mode=TwoWay}"
              go:NodePanel.Spot1="0 0" go:NodePanel.Spot2="1 1" />
        <TextBlock Text="{Binding Path=Data.Text, Mode=TwoWay}" TextWrapping="Wrap"
                   HorizontalAlignment="Center" VerticalAlignment="Center" />
      </go:NodePanel>
    </DataTemplate>

    <DataTemplate x:Key="LinkSelectionAdornmentTemplate">
      <go:SelectionHandle go:NodePanel.Figure="None" Stroke="DeepSkyBlue" StrokeThickness="2" go:Part.Selectable="False" />
    </DataTemplate>

    <DataTemplate x:Key="LinkReshapeHandleTemplate">
      <go:ToolHandle go:NodePanel.Figure="Diamond" Width="7" Height="7" Fill="LightBlue" Stroke="DeepSkyBlue" StrokeThickness="1" />
    </DataTemplate>

    <DataTemplate x:Key="LinkTemplate">
      <go:LinkPanel go:Part.SelectionElementName="Path" go:Part.SelectionAdorned="True"
                    go:Part.SelectionAdornmentTemplate="{StaticResource LinkSelectionAdornmentTemplate}"
                    go:Part.Reshapable="True">
        <go:Link.Route>
          <go:Route Routing="AvoidsNodes" Curve="JumpGap"
                    FromEndSegmentDirection="RotatedNodeOrthogonal"
                    ToEndSegmentDirection="RotatedNodeOrthogonal"
                    RelinkableFrom="True" RelinkableTo="True"
                    LinkReshapeHandleTemplate="{StaticResource LinkReshapeHandleTemplate}" />
        </go:Link.Route>
        <go:LinkShape Stroke="Transparent" StrokeThickness="5" />
        <go:LinkShape x:Name="Path" Stroke="Black" StrokeThickness="1" />
        <Path Fill="Black" go:LinkPanel.ToArrow="Triangle" />
      </go:LinkPanel>
    </DataTemplate>

    <DataTemplate x:Key="PaletteLinkTemplate">
      <go:LinkPanel Background="Transparent"
          go:Part.SelectionElementName="Path" go:Part.SelectionAdorned="True"
          go:Part.SelectionAdornmentTemplate="{StaticResource LinkSelectionAdornmentTemplate}">
        <go:LinkShape Stroke="Transparent" StrokeThickness="5" />
        <go:LinkShape x:Name="Path" Stroke="Black" StrokeThickness="1" />
        <Path Fill="Black" go:LinkPanel.ToArrow="Triangle" />
      </go:LinkPanel>
    </DataTemplate>

    <DataTemplate x:Key="TemporaryLinkTemplate">
      <go:LinkPanel go:Part.Selectable="False" go:Link.LayerName="Tool">
        <go:Link.Route>
          <go:Route Routing="Orthogonal" />
        </go:Link.Route>
        <go:LinkShape x:Name="Path" Stroke="Blue" StrokeThickness="1" />
        <Path Fill="Black" go:LinkPanel.ToArrow="Triangle" />
      </go:LinkPanel>
    </DataTemplate>
  </UserControl.Resources>

  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="100" />
      <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0">
      <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <go:Palette Grid.Row="0"
                  x:Name="myPalette"
                  BorderBrush="Black" BorderThickness="1" Padding="5"
                  HorizontalContentAlignment="Left" VerticalContentAlignment="Top"
                  MaximumSelectionCount="1"
                  NodeTemplate="{StaticResource PaletteNodeTemplate}"
                  LinkTemplate="{StaticResource PaletteLinkTemplate}">
        <go:Diagram.PartManager>
          <local:CustomPartManager />
        </go:Diagram.PartManager>
        <go:Diagram.Layout>
          <go:GridLayout CellSize="10 10" />
        </go:Diagram.Layout>
      </go:Palette>
      <StackPanel Grid.Row="1">
        <Button Content="Save" Click="Save_Click" />
        <Button Content="Load" Click="Load_Click" x:Name="LoadButton" IsEnabled="False" />
      </StackPanel>
    </Grid>
    <go:Diagram Grid.Column="1"
                x:Name="myDiagram" AllowDrop="True"
                Padding="10"
                HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
                NodeTemplate="{StaticResource NodeTemplate}"
                LinkTemplate="{StaticResource LinkTemplate}"
                GridVisible="True" GridSnapEnabled="True">
      <go:Diagram.PartManager>
        <local:CustomPartManager />
      </go:Diagram.PartManager>
      <go:Diagram.LinkingTool>
        <go:LinkingTool PortGravity="20"
          TemporaryLinkTemplate="{StaticResource TemporaryLinkTemplate}" />
      </go:Diagram.LinkingTool>
      <go:Diagram.RelinkingTool>
        <go:RelinkingTool PortGravity="20"
          TemporaryLinkTemplate="{StaticResource TemporaryLinkTemplate}" />
      </go:Diagram.RelinkingTool>
      <go:Diagram.DraggingTool>
        <go:DraggingTool DraggableLinks="True" />
      </go:Diagram.DraggingTool>
      <go:Diagram.RotatingTool>
        <local:CustomRotatingTool SnapAngleMultiple="15" SnapAngleEpsilon="15" />
      </go:Diagram.RotatingTool>
      <go:Diagram.GridPattern>
        <go:GridPattern CellSize="10 10">
          <Path Stroke="LightGray" StrokeThickness="0.2" go:GridPattern.Figure="HorizontalLine" />
          <Path Stroke="LightGray" StrokeThickness="0.2" go:GridPattern.Figure="VerticalLine" />
          <Path Stroke="LightGray" StrokeThickness="0.3" go:GridPattern.Figure="HorizontalLine" go:GridPattern.Interval="2" />
          <Path Stroke="LightGray" StrokeThickness="0.3" go:GridPattern.Figure="VerticalLine" go:GridPattern.Interval="2" />
          <Path Stroke="Gray" StrokeThickness="0.3" go:GridPattern.Figure="HorizontalLine" go:GridPattern.Interval="4" />
          <Path Stroke="Gray" StrokeThickness="0.3" go:GridPattern.Figure="VerticalLine" go:GridPattern.Interval="4" />
          <Path Stroke="Black" StrokeThickness="0.3" go:GridPattern.Figure="HorizontalLine" go:GridPattern.Interval="8" />
          <Path Stroke="Black" StrokeThickness="0.3" go:GridPattern.Figure="VerticalLine" go:GridPattern.Interval="8" />
        </go:GridPattern>
      </go:Diagram.GridPattern>
    </go:Diagram>
  </Grid>
</UserControl>
