diff --git a/.gitignore b/.gitignore index af27fba5..13184f4d 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,4 @@ UpgradeLog*.XML #LocalHistory VS plugin .localhistory/ .settings/launch.json +/.vs/GraphX for .NET/v15/Server/sqlite3 diff --git a/Documents/AIV.cs b/Documents/AIV.cs index 2445cffa..888f72e7 100644 --- a/Documents/AIV.cs +++ b/Documents/AIV.cs @@ -8,5 +8,5 @@ [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("2.3.6.0")] -[assembly: AssemblyFileVersion("2.3.6.0")] +[assembly: AssemblyVersion("2.3.7.0")] +[assembly: AssemblyFileVersion("2.3.7.0")] diff --git a/Documents/CHANGELOG.txt b/Documents/CHANGELOG.txt index edc9c6c3..c72629db 100644 --- a/Documents/CHANGELOG.txt +++ b/Documents/CHANGELOG.txt @@ -1,8 +1,11 @@ -WIP 2.3.7 +RELEASE 2.3.7 - Added edge drag functionality to be able to reattach edge to another vertex (thanks to LaborJos) - Fixed SimpleTreeLayout vertex sizes supplement (thanks to edgardozoppi) - Fixed and improved parallel edge handling (thanks to perturbare) - Fixed RemoveEdge() method were not removing edges from data graph (thanks to perturbare) +- Removed METRO support and example +- Added UAP (UWP) support for Windows 10+ platform (VS2017) +- Minor bugfixes RELEASE 2.3.6 DETAILED CHANGELOG: diff --git a/Examples/METRO.SimpleGraph/METRO.SimpleGraph.csproj b/Examples/METRO.SimpleGraph/METRO.SimpleGraph.csproj deleted file mode 100644 index 59c00309..00000000 --- a/Examples/METRO.SimpleGraph/METRO.SimpleGraph.csproj +++ /dev/null @@ -1,230 +0,0 @@ - - - - - Debug - AnyCPU - {44841666-C547-4874-9BC9-B34D2A1FA6D8} - appcontainerexe - Properties - METRO.SimpleGraph - METRO.SimpleGraph - en-US - 512 - {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - METRO.SimpleGraph_TemporaryKey.pfx - 8.1 - 12 - - 0E531EEE26E7E3F2FBD6A8E1E9F889D31225622F - ..\..\ - true - - - AnyCPU - true - full - false - bin\Debug\ - TRACE;DEBUG;NETFX_CORE, METRO - prompt - 4 - true - 1591 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE;NETFX_CORE - prompt - 4 - 1591 - - - true - bin\ARM\Debug\ - DEBUG;TRACE;NETFX_CORE - ;2008 - full - ARM - false - prompt - true - - - bin\ARM\Release\ - TRACE;NETFX_CORE - true - ;2008 - pdbonly - ARM - false - prompt - true - - - true - bin\x64\Debug\ - DEBUG;TRACE;NETFX_CORE - ;2008 - full - x64 - false - prompt - true - - - bin\x64\Release\ - TRACE;NETFX_CORE - true - ;2008 - pdbonly - x64 - false - prompt - true - - - true - bin\x86\Debug\ - DEBUG;TRACE;NETFX_CORE - ;2008 - full - x86 - false - prompt - true - - - bin\x86\Release\ - TRACE;NETFX_CORE - true - ;2008 - pdbonly - x86 - false - prompt - true - - - - - {66f33708-c1c7-4385-8235-7201784d184c} - GraphX.METRO.Controls - - - {3644d44b-dec0-4b65-bba0-c68e34821aae} - GraphX.PCL.Common - - - {a30d218b-aaa4-483a-99f7-eaeb1b8b4610} - GraphX.PCL.Logic - - - - - App.xaml - - - MainPageDebug.xaml - - - MainPage.xaml - - - - - - - - - - - - - - - Designer - - - - - - - - - - - - - - - - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - PreserveNewest - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - PreserveNewest - - - - - ..\..\packages\QuickGraphPCL.3.6.61114.2\lib\portable-win+net4+sl5+wp8+win8+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\QuickGraph.dll - True - - - ..\..\packages\QuickGraphPCL.3.6.61114.2\lib\portable-win+net4+sl5+wp8+win8+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\QuickGraph.Graphviz.dll - True - - - - 12.0 - - - - - - true - - - METRO.SimpleGraph_TemporaryKey.pfx - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Examples/METRO.SimpleGraph/METRO.SimpleGraph_TemporaryKey.pfx b/Examples/METRO.SimpleGraph/METRO.SimpleGraph_TemporaryKey.pfx deleted file mode 100644 index 338d6dae..00000000 Binary files a/Examples/METRO.SimpleGraph/METRO.SimpleGraph_TemporaryKey.pfx and /dev/null differ diff --git a/Examples/METRO.SimpleGraph/Package.appxmanifest b/Examples/METRO.SimpleGraph/Package.appxmanifest deleted file mode 100644 index 3d7e87a8..00000000 --- a/Examples/METRO.SimpleGraph/Package.appxmanifest +++ /dev/null @@ -1,37 +0,0 @@ - - - - - METRO.SimpleGraph - panth_000 - Assets\StoreLogo.png - - - 6.3.0 - 6.3.0 - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Examples/METRO.SimpleGraph/Properties/AssemblyInfo.cs b/Examples/METRO.SimpleGraph/Properties/AssemblyInfo.cs deleted file mode 100644 index 9affc518..00000000 --- a/Examples/METRO.SimpleGraph/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("METRO.SimpleGraph")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("METRO.SimpleGraph")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Examples/METRO.SimpleGraph/packages.config b/Examples/METRO.SimpleGraph/packages.config deleted file mode 100644 index a3f91dfd..00000000 --- a/Examples/METRO.SimpleGraph/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Examples/METRO.SimpleGraph/App.xaml b/Examples/UAP.SimpleGraph/App.xaml similarity index 95% rename from Examples/METRO.SimpleGraph/App.xaml rename to Examples/UAP.SimpleGraph/App.xaml index 276b3134..f485eac4 100644 --- a/Examples/METRO.SimpleGraph/App.xaml +++ b/Examples/UAP.SimpleGraph/App.xaml @@ -1,5 +1,5 @@  diff --git a/Examples/METRO.SimpleGraph/App.xaml.cs b/Examples/UAP.SimpleGraph/App.xaml.cs similarity index 99% rename from Examples/METRO.SimpleGraph/App.xaml.cs rename to Examples/UAP.SimpleGraph/App.xaml.cs index 055debd2..6674dcb8 100644 --- a/Examples/METRO.SimpleGraph/App.xaml.cs +++ b/Examples/UAP.SimpleGraph/App.xaml.cs @@ -6,7 +6,7 @@ // The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227 -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph { /// /// Provides application-specific behavior to supplement the default Application class. diff --git a/Examples/UWA.SimpleGraph/Assets/100.png b/Examples/UAP.SimpleGraph/Assets/100.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/100.png rename to Examples/UAP.SimpleGraph/Assets/100.png diff --git a/Examples/UWA.SimpleGraph/Assets/150.png b/Examples/UAP.SimpleGraph/Assets/150.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/150.png rename to Examples/UAP.SimpleGraph/Assets/150.png diff --git a/Examples/UWA.SimpleGraph/Assets/300.png b/Examples/UAP.SimpleGraph/Assets/300.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/300.png rename to Examples/UAP.SimpleGraph/Assets/300.png diff --git a/Examples/UWA.SimpleGraph/Assets/44.png b/Examples/UAP.SimpleGraph/Assets/44.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/44.png rename to Examples/UAP.SimpleGraph/Assets/44.png diff --git a/Examples/UWA.SimpleGraph/Assets/50.png b/Examples/UAP.SimpleGraph/Assets/50.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/50.png rename to Examples/UAP.SimpleGraph/Assets/50.png diff --git a/Examples/UWA.SimpleGraph/Assets/88.png b/Examples/UAP.SimpleGraph/Assets/88.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/88.png rename to Examples/UAP.SimpleGraph/Assets/88.png diff --git a/Examples/METRO.SimpleGraph/Assets/Logo.png b/Examples/UAP.SimpleGraph/Assets/Logo.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/Logo.png rename to Examples/UAP.SimpleGraph/Assets/Logo.png diff --git a/Examples/UWA.SimpleGraph/Assets/Logo.scale-100.png b/Examples/UAP.SimpleGraph/Assets/Logo.scale-100.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/Logo.scale-100.png rename to Examples/UAP.SimpleGraph/Assets/Logo.scale-100.png diff --git a/Examples/UWA.SimpleGraph/Assets/Logo.scale-200.png b/Examples/UAP.SimpleGraph/Assets/Logo.scale-200.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/Logo.scale-200.png rename to Examples/UAP.SimpleGraph/Assets/Logo.scale-200.png diff --git a/Examples/METRO.SimpleGraph/Assets/MidLogo.png b/Examples/UAP.SimpleGraph/Assets/MidLogo.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/MidLogo.png rename to Examples/UAP.SimpleGraph/Assets/MidLogo.png diff --git a/Examples/METRO.SimpleGraph/Assets/SmallLogo.png b/Examples/UAP.SimpleGraph/Assets/SmallLogo.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/SmallLogo.png rename to Examples/UAP.SimpleGraph/Assets/SmallLogo.png diff --git a/Examples/METRO.SimpleGraph/Assets/SplashScreen.png b/Examples/UAP.SimpleGraph/Assets/SplashScreen.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/SplashScreen.png rename to Examples/UAP.SimpleGraph/Assets/SplashScreen.png diff --git a/Examples/METRO.SimpleGraph/Assets/SplashScreen.scale-100.png b/Examples/UAP.SimpleGraph/Assets/SplashScreen.scale-100.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/SplashScreen.scale-100.png rename to Examples/UAP.SimpleGraph/Assets/SplashScreen.scale-100.png diff --git a/Examples/UWA.SimpleGraph/Assets/SplashScreen.scale-200.png b/Examples/UAP.SimpleGraph/Assets/SplashScreen.scale-200.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/SplashScreen.scale-200.png rename to Examples/UAP.SimpleGraph/Assets/SplashScreen.scale-200.png diff --git a/Examples/METRO.SimpleGraph/Assets/StoreLogo.png b/Examples/UAP.SimpleGraph/Assets/StoreLogo.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/StoreLogo.png rename to Examples/UAP.SimpleGraph/Assets/StoreLogo.png diff --git a/Examples/UWA.SimpleGraph/Assets/newlogo_big.png b/Examples/UAP.SimpleGraph/Assets/newlogo_big.png similarity index 100% rename from Examples/UWA.SimpleGraph/Assets/newlogo_big.png rename to Examples/UAP.SimpleGraph/Assets/newlogo_big.png diff --git a/Examples/METRO.SimpleGraph/Assets/play.png b/Examples/UAP.SimpleGraph/Assets/play.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/play.png rename to Examples/UAP.SimpleGraph/Assets/play.png diff --git a/Examples/METRO.SimpleGraph/Assets/refresh.png b/Examples/UAP.SimpleGraph/Assets/refresh.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/refresh.png rename to Examples/UAP.SimpleGraph/Assets/refresh.png diff --git a/Examples/METRO.SimpleGraph/Assets/tr_grren.png b/Examples/UAP.SimpleGraph/Assets/tr_grren.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/tr_grren.png rename to Examples/UAP.SimpleGraph/Assets/tr_grren.png diff --git a/Examples/METRO.SimpleGraph/Assets/tr_red.png b/Examples/UAP.SimpleGraph/Assets/tr_red.png similarity index 100% rename from Examples/METRO.SimpleGraph/Assets/tr_red.png rename to Examples/UAP.SimpleGraph/Assets/tr_red.png diff --git a/Examples/METRO.SimpleGraph/Common/StandardStyles.xaml b/Examples/UAP.SimpleGraph/Common/StandardStyles.xaml similarity index 100% rename from Examples/METRO.SimpleGraph/Common/StandardStyles.xaml rename to Examples/UAP.SimpleGraph/Common/StandardStyles.xaml diff --git a/Examples/METRO.SimpleGraph/Common/templates.xaml b/Examples/UAP.SimpleGraph/Common/templates.xaml similarity index 100% rename from Examples/METRO.SimpleGraph/Common/templates.xaml rename to Examples/UAP.SimpleGraph/Common/templates.xaml diff --git a/Examples/METRO.SimpleGraph/Common/templates2.xaml b/Examples/UAP.SimpleGraph/Common/templates2.xaml similarity index 100% rename from Examples/METRO.SimpleGraph/Common/templates2.xaml rename to Examples/UAP.SimpleGraph/Common/templates2.xaml diff --git a/Examples/METRO.SimpleGraph/MainPage.xaml b/Examples/UAP.SimpleGraph/MainPage.xaml similarity index 90% rename from Examples/METRO.SimpleGraph/MainPage.xaml rename to Examples/UAP.SimpleGraph/MainPage.xaml index 32e6496e..d4be275b 100644 --- a/Examples/METRO.SimpleGraph/MainPage.xaml +++ b/Examples/UAP.SimpleGraph/MainPage.xaml @@ -1,16 +1,15 @@  - + @@ -18,7 +17,7 @@ - + diff --git a/Examples/METRO.SimpleGraph/MainPage.xaml.cs b/Examples/UAP.SimpleGraph/MainPage.xaml.cs similarity index 99% rename from Examples/METRO.SimpleGraph/MainPage.xaml.cs rename to Examples/UAP.SimpleGraph/MainPage.xaml.cs index bbb1ce4c..6200cb3a 100644 --- a/Examples/METRO.SimpleGraph/MainPage.xaml.cs +++ b/Examples/UAP.SimpleGraph/MainPage.xaml.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -12,10 +11,11 @@ using GraphX.PCL.Common.Enums; using GraphX.PCL.Logic.Algorithms.LayoutAlgorithms; using GraphX.PCL.Logic.Algorithms.OverlapRemoval; +using UAP.SimpleGraph.Models; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph { /// /// An empty page that can be used on its own or navigated to within a Frame. diff --git a/Examples/METRO.SimpleGraph/MainPageDebug.xaml b/Examples/UAP.SimpleGraph/MainPageDebug.xaml similarity index 94% rename from Examples/METRO.SimpleGraph/MainPageDebug.xaml rename to Examples/UAP.SimpleGraph/MainPageDebug.xaml index b542e457..abbf9eff 100644 --- a/Examples/METRO.SimpleGraph/MainPageDebug.xaml +++ b/Examples/UAP.SimpleGraph/MainPageDebug.xaml @@ -1,11 +1,12 @@  @@ -16,7 +17,7 @@ - + diff --git a/Examples/METRO.SimpleGraph/MainPageDebug.xaml.cs b/Examples/UAP.SimpleGraph/MainPageDebug.xaml.cs similarity index 98% rename from Examples/METRO.SimpleGraph/MainPageDebug.xaml.cs rename to Examples/UAP.SimpleGraph/MainPageDebug.xaml.cs index c7a821e1..91199cee 100644 --- a/Examples/METRO.SimpleGraph/MainPageDebug.xaml.cs +++ b/Examples/UAP.SimpleGraph/MainPageDebug.xaml.cs @@ -4,19 +4,17 @@ using System.Linq; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Navigation; -using GraphX.Controls; using GraphX.Controls.Animations; using GraphX.Controls.Models; using GraphX.PCL.Common.Enums; using GraphX.PCL.Logic.Algorithms.LayoutAlgorithms; using GraphX.PCL.Logic.Algorithms.OverlapRemoval; -using METRO.SimpleGraph.Models; +using UAP.SimpleGraph.Models; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph { /// /// An empty page that can be used on its own or navigated to within a Frame. diff --git a/Examples/METRO.SimpleGraph/Models/CurvedEr.cs b/Examples/UAP.SimpleGraph/Models/CurvedEr.cs similarity index 97% rename from Examples/METRO.SimpleGraph/Models/CurvedEr.cs rename to Examples/UAP.SimpleGraph/Models/CurvedEr.cs index 00a5552f..af4a1488 100644 --- a/Examples/METRO.SimpleGraph/Models/CurvedEr.cs +++ b/Examples/UAP.SimpleGraph/Models/CurvedEr.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Generic; using System.Threading; -using GraphX; using GraphX.Measure; using GraphX.PCL.Common.Interfaces; using GraphX.PCL.Logic.Algorithms.EdgeRouting; -using METRO.SimpleGraph; -namespace InteractiveGraph.Models +namespace UAP.SimpleGraph.Models { public class CurvedEr: EdgeRoutingAlgorithmBase { diff --git a/Examples/METRO.SimpleGraph/Models/CurvedErParameters.cs b/Examples/UAP.SimpleGraph/Models/CurvedErParameters.cs similarity index 90% rename from Examples/METRO.SimpleGraph/Models/CurvedErParameters.cs rename to Examples/UAP.SimpleGraph/Models/CurvedErParameters.cs index 13e620ff..d211ce51 100644 --- a/Examples/METRO.SimpleGraph/Models/CurvedErParameters.cs +++ b/Examples/UAP.SimpleGraph/Models/CurvedErParameters.cs @@ -1,6 +1,6 @@ using GraphX.PCL.Logic.Algorithms.EdgeRouting; -namespace InteractiveGraph.Models +namespace UAP.SimpleGraph.Models { public class CurvedErParameters: EdgeRoutingParameters { diff --git a/Examples/METRO.SimpleGraph/Models/DataEdge.cs b/Examples/UAP.SimpleGraph/Models/DataEdge.cs similarity index 98% rename from Examples/METRO.SimpleGraph/Models/DataEdge.cs rename to Examples/UAP.SimpleGraph/Models/DataEdge.cs index bf164fa9..08599a7e 100644 --- a/Examples/METRO.SimpleGraph/Models/DataEdge.cs +++ b/Examples/UAP.SimpleGraph/Models/DataEdge.cs @@ -1,8 +1,7 @@ using System.ComponentModel; -using GraphX; using GraphX.PCL.Common.Models; -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph.Models { /* DataEdge is the data class for the edges. It contains all custom edge data specified by the user. * This class also must be derived from EdgeBase class that provides properties and methods mandatory for diff --git a/Examples/METRO.SimpleGraph/Models/DataVertex.cs b/Examples/UAP.SimpleGraph/Models/DataVertex.cs similarity index 98% rename from Examples/METRO.SimpleGraph/Models/DataVertex.cs rename to Examples/UAP.SimpleGraph/Models/DataVertex.cs index 550b30a5..ac95b667 100644 --- a/Examples/METRO.SimpleGraph/Models/DataVertex.cs +++ b/Examples/UAP.SimpleGraph/Models/DataVertex.cs @@ -1,8 +1,7 @@ using System.ComponentModel; -using GraphX; using GraphX.PCL.Common.Models; -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph.Models { /* DataVertex is the data class for the vertices. It contains all custom vertex data specified by the user. * This class also must be derived from VertexBase that provides properties and methods mandatory for diff --git a/Examples/METRO.SimpleGraph/Models/DebugItems.cs b/Examples/UAP.SimpleGraph/Models/DebugItems.cs similarity index 73% rename from Examples/METRO.SimpleGraph/Models/DebugItems.cs rename to Examples/UAP.SimpleGraph/Models/DebugItems.cs index 9c419706..1f77b8bb 100644 --- a/Examples/METRO.SimpleGraph/Models/DebugItems.cs +++ b/Examples/UAP.SimpleGraph/Models/DebugItems.cs @@ -1,4 +1,4 @@ -namespace METRO.SimpleGraph.Models +namespace UAP.SimpleGraph.Models { public enum DebugItems { diff --git a/Examples/METRO.SimpleGraph/Models/GXLogicCoreExample.cs b/Examples/UAP.SimpleGraph/Models/GXLogicCoreExample.cs similarity index 89% rename from Examples/METRO.SimpleGraph/Models/GXLogicCoreExample.cs rename to Examples/UAP.SimpleGraph/Models/GXLogicCoreExample.cs index 33bdd289..7d4b8328 100644 --- a/Examples/METRO.SimpleGraph/Models/GXLogicCoreExample.cs +++ b/Examples/UAP.SimpleGraph/Models/GXLogicCoreExample.cs @@ -1,7 +1,7 @@ using GraphX.PCL.Logic.Models; using QuickGraph; -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph.Models { /// /// Logics core object which contains all algorithms and logic settings diff --git a/Examples/METRO.SimpleGraph/Models/GraphAreaExample.cs b/Examples/UAP.SimpleGraph/Models/GraphAreaExample.cs similarity index 92% rename from Examples/METRO.SimpleGraph/Models/GraphAreaExample.cs rename to Examples/UAP.SimpleGraph/Models/GraphAreaExample.cs index e3152815..6ad022e9 100644 --- a/Examples/METRO.SimpleGraph/Models/GraphAreaExample.cs +++ b/Examples/UAP.SimpleGraph/Models/GraphAreaExample.cs @@ -1,8 +1,7 @@ -using GraphX; using GraphX.Controls; using QuickGraph; -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph.Models { /// /// This is custom GraphArea representation using custom data types. diff --git a/Examples/METRO.SimpleGraph/Models/GraphExample.cs b/Examples/UAP.SimpleGraph/Models/GraphExample.cs similarity index 94% rename from Examples/METRO.SimpleGraph/Models/GraphExample.cs rename to Examples/UAP.SimpleGraph/Models/GraphExample.cs index 8fc216ae..376f3977 100644 --- a/Examples/METRO.SimpleGraph/Models/GraphExample.cs +++ b/Examples/UAP.SimpleGraph/Models/GraphExample.cs @@ -1,6 +1,6 @@ using QuickGraph; -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph.Models { /// /// This is our custom data graph derived from BidirectionalGraph class using custom data types. diff --git a/Examples/METRO.SimpleGraph/Models/MouseOverScaleAnimation.cs b/Examples/UAP.SimpleGraph/Models/MouseOverScaleAnimation.cs similarity index 98% rename from Examples/METRO.SimpleGraph/Models/MouseOverScaleAnimation.cs rename to Examples/UAP.SimpleGraph/Models/MouseOverScaleAnimation.cs index 6fb03090..16477580 100644 --- a/Examples/METRO.SimpleGraph/Models/MouseOverScaleAnimation.cs +++ b/Examples/UAP.SimpleGraph/Models/MouseOverScaleAnimation.cs @@ -1,13 +1,12 @@ -using Windows.Foundation; +using System; +using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Animation; -using GraphX; -using System; using GraphX.Controls; using GraphX.Controls.Animations; -namespace METRO.SimpleGraph +namespace UAP.SimpleGraph.Models { public sealed class MouseOverAnimation : IBidirectionalControlAnimation { diff --git a/Examples/UWA.SimpleGraph/Package.appxmanifest b/Examples/UAP.SimpleGraph/Package.appxmanifest similarity index 87% rename from Examples/UWA.SimpleGraph/Package.appxmanifest rename to Examples/UAP.SimpleGraph/Package.appxmanifest index 72e87f45..d9e4dafb 100644 --- a/Examples/UWA.SimpleGraph/Package.appxmanifest +++ b/Examples/UAP.SimpleGraph/Package.appxmanifest @@ -3,7 +3,7 @@ - UWA.SimpleGraph + UAP.SimpleGraph panth Assets/50.png @@ -14,8 +14,8 @@ - - + + diff --git a/Examples/UWA.SimpleGraph/Properties/AssemblyInfo.cs b/Examples/UAP.SimpleGraph/Properties/AssemblyInfo.cs similarity index 100% rename from Examples/UWA.SimpleGraph/Properties/AssemblyInfo.cs rename to Examples/UAP.SimpleGraph/Properties/AssemblyInfo.cs diff --git a/Examples/UWA.SimpleGraph/Properties/Default.rd.xml b/Examples/UAP.SimpleGraph/Properties/Default.rd.xml similarity index 100% rename from Examples/UWA.SimpleGraph/Properties/Default.rd.xml rename to Examples/UAP.SimpleGraph/Properties/Default.rd.xml diff --git a/Examples/UWA.SimpleGraph/UWA.SimpleGraph.csproj b/Examples/UAP.SimpleGraph/UAP.SimpleGraph.csproj similarity index 67% rename from Examples/UWA.SimpleGraph/UWA.SimpleGraph.csproj rename to Examples/UAP.SimpleGraph/UAP.SimpleGraph.csproj index 1c809225..54f4c03e 100644 --- a/Examples/UWA.SimpleGraph/UWA.SimpleGraph.csproj +++ b/Examples/UAP.SimpleGraph/UAP.SimpleGraph.csproj @@ -7,11 +7,11 @@ {51C7122B-AAD1-4C49-B2E9-1B09B367952F} AppContainerExe Properties - METRO.SimpleGraph - UWA.SimpleGraph + UAP.SimpleGraph + UAP.SimpleGraph en-US UAP - 10.0.10586.0 + 10.0.14393.0 10.0.10586.0 14 512 @@ -91,47 +91,26 @@ - - - MainPage.xaml.cs + + App.xaml + + MainPage.xaml - - MainPageDebug.xaml.cs + MainPageDebug.xaml - - Models\CurvedEr.cs - - - Models\CurvedErParameters.cs - - - Models\DataEdge.cs - - - Models\DataVertex.cs - - - Models\DebugItems.cs - - - Models\GraphAreaExample.cs - - - Models\GraphExample.cs - - - Models\GXLogicCoreExample.cs - - - Models\MouseOverScaleAnimation.cs - - - App.xaml - + + + + + + + + + @@ -140,37 +119,20 @@ - - Assets\Logo.png - - - Assets\MidLogo.png - - - Assets\play.png - - - Assets\refresh.png - - - Assets\SmallLogo.png - - - Assets\SplashScreen.png - - - Assets\StoreLogo.png - - - Assets\tr_grren.png - - - Assets\tr_red.png - + + + + + + + + + + @@ -178,37 +140,28 @@ MSBuild:Compile Designer - - Common\StandardStyles.xaml + MSBuild:Compile Designer - - Common\templates.xaml + MSBuild:Compile Designer - - Common\templates2.xaml + MSBuild:Compile Designer - - MainPage.xaml + MSBuild:Compile Designer - - MainPageDebug.xaml + MSBuild:Compile Designer - - {66f33708-c1c7-4385-8235-7201784d184c} - GraphX.METRO.Controls - {3644d44b-dec0-4b65-bba0-c68e34821aae} GraphX.PCL.Common @@ -217,6 +170,10 @@ {a30d218b-aaa4-483a-99f7-eaeb1b8b4610} GraphX.PCL.Logic + + {4bebc41e-2710-4613-80b1-198e08d10619} + GraphX.UAP.Controls + @@ -226,7 +183,8 @@ true - UWA.SimpleGraph_TemporaryKey.pfx + + @@ -352,8 +353,8 @@ True - - 12.0 + + 14.0 true diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/Converters/DoubleToLog10Converter.cs b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/DoubleToLog10Converter.cs new file mode 100644 index 00000000..4088bde2 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/DoubleToLog10Converter.cs @@ -0,0 +1,26 @@ +using System; +using Windows.UI.Xaml.Data; + +namespace GraphX.Controls +{ + public sealed class DoubleToLog10Converter : IValueConverter + { + #region IValueConverter Members + + public object Convert(object value, Type targetType, object parameter, string language) + { + var val = Math.Log10((double)value); + return double.IsNegativeInfinity(val) ? 0 : val; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + var val = Math.Pow(10, (double)value); + return double.IsNegativeInfinity(val) ? 0 : val; + } + + #endregion + + + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/Converters/EqualityToBooleanConverter.cs b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/EqualityToBooleanConverter.cs new file mode 100644 index 00000000..15969238 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/EqualityToBooleanConverter.cs @@ -0,0 +1,22 @@ +using System; +using Windows.UI.Xaml.Data; + +namespace GraphX.Controls +{ + public sealed class EqualityToBooleanConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + return Equals(value, parameter); + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + if ((bool)value) + return parameter; + + //it's false, so don't bind it back + return null; + } + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/Converters/RoundedValueConverter.cs b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/RoundedValueConverter.cs new file mode 100644 index 00000000..25d796c3 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/RoundedValueConverter.cs @@ -0,0 +1,64 @@ +/************************************************************************************* + + Extended WPF Toolkit + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at http://xceed.com/wpf_toolkit + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using Windows.Foundation; +using Windows.UI.Xaml.Data; + +namespace GraphX.Controls +{ + public class RoundedValueConverter : IValueConverter + { + #region Precision Property + + public int Precision + { + get + { + return _precision; + } + set + { + _precision = value; + } + } + + private int _precision = 0; + + #endregion + + public object Convert(object value, Type targetType, object parameter, string language) + { + if( value is double ) + { + return Math.Round( ( double )value, _precision ); + } + else if( value is Point ) + { + return new Point( Math.Round( ( ( Point )value ).X, _precision ), Math.Round( ( ( Point )value ).Y, _precision ) ); + } + else + { + return value; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + return value; + } + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/Converters/VisibilityToBoolConverter.cs b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/VisibilityToBoolConverter.cs new file mode 100644 index 00000000..ce7a4720 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/Converters/VisibilityToBoolConverter.cs @@ -0,0 +1,55 @@ +/************************************************************************************* + + Extended WPF Toolkit + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at http://xceed.com/wpf_toolkit + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Data; + +namespace GraphX.Controls + { + [Bindable] + public sealed class VisibilityToBoolConverter : IValueConverter + { + public bool Inverted { get; set; } + public bool Not { get; set; } + + public object Convert(object value, Type targetType, object parameter, string language) + { + return this.Inverted ? this.BoolToVisibility( value ) : this.VisibilityToBool( value ); + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + return this.Inverted ? this.VisibilityToBool( value ) : this.BoolToVisibility( value ); + } + + private object VisibilityToBool( object value ) + { + if( !( value is Visibility ) ) + throw new InvalidOperationException( "SuppliedValueWasNotVisibility" ); + + return ( ( ( Visibility )value ) == Visibility.Visible ) ^ Not; + } + + private object BoolToVisibility( object value ) + { + if( !( value is bool ) ) + throw new InvalidOperationException( "SuppliedValueWasNotBool" ); + + return ( ( bool )value ^ Not ) ? Visibility.Visible : Visibility.Collapsed; + } + } + } diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/DoubleHelper.cs b/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/DoubleHelper.cs new file mode 100644 index 00000000..88c8ad16 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/DoubleHelper.cs @@ -0,0 +1,94 @@ +/************************************************************************************* + + Extended WPF Toolkit + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at http://xceed.com/wpf_toolkit + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Runtime.InteropServices; +using GraphX.Measure; +using Point = Windows.Foundation.Point; +using Rect = Windows.Foundation.Rect; +using Size = Windows.Foundation.Size; + +namespace GraphX.Controls +{ + internal static class DoubleHelper + { + public static bool AreVirtuallyEqual( double d1, double d2 ) + { + if( double.IsPositiveInfinity( d1 ) ) + return double.IsPositiveInfinity( d2 ); + + if( double.IsNegativeInfinity( d1 ) ) + return double.IsNegativeInfinity( d2 ); + + if( IsNaN( d1 ) ) + return IsNaN( d2 ); + + var n = d1 - d2; + var d = ( Math.Abs( d1 ) + Math.Abs( d2 ) + 10 ) * 1.0e-15; + return ( -d < n ) && ( d > n ); + } + + public static bool AreVirtuallyEqual( Size s1, Size s2 ) + { + return ( AreVirtuallyEqual( s1.Width, s2.Width ) + && AreVirtuallyEqual( s1.Height, s2.Height ) ); + } + + public static bool AreVirtuallyEqual( Point p1, Point p2 ) + { + return ( AreVirtuallyEqual( p1.X, p2.X ) + && AreVirtuallyEqual( p1.Y, p2.Y ) ); + } + + public static bool AreVirtuallyEqual( Rect r1, Rect r2 ) + { + return ( AreVirtuallyEqual( r1.TopLeft(), r2.TopLeft() ) + && AreVirtuallyEqual( r1.BottomRight(), r2.BottomRight() ) ); + } + + public static bool AreVirtuallyEqual( Vector v1, Vector v2 ) + { + return ( AreVirtuallyEqual( v1.X, v2.X ) + && AreVirtuallyEqual( v1.Y, v2.Y ) ); + } + + + public static bool IsNaN( double value ) + { + // used reflector to borrow the high performance IsNan function + // from the WPF MS.Internal namespace + var t = new NanUnion {DoubleValue = value}; + + var exp = t.UintValue & 0xfff0000000000000; + var man = t.UintValue & 0x000fffffffffffff; + + return ( exp == 0x7ff0000000000000 || exp == 0xfff0000000000000 ) && ( man != 0 ); + } + + #region NanUnion Nested Types + + [StructLayout( LayoutKind.Explicit )] + private struct NanUnion + { + [FieldOffset( 0 )] + internal double DoubleValue; + [FieldOffset( 0 )] + internal UInt64 UintValue; + } + + #endregion + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/PointHelper.cs b/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/PointHelper.cs new file mode 100644 index 00000000..147a1408 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/PointHelper.cs @@ -0,0 +1,42 @@ +/************************************************************************************* + + Extended WPF Toolkit + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at http://xceed.com/wpf_toolkit + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using Windows.Foundation; + +namespace GraphX.Controls +{ + internal static class PointHelper + { + public static double DistanceBetween( Point p1, Point p2 ) + { + return Math.Sqrt( Math.Pow( p1.X - p2.X, 2 ) + Math.Pow( p1.Y - p2.Y, 2 ) ); + } + + public static Point Empty + { + get + { + return new Point( double.NaN, double.NaN ); + } + } + + public static bool IsEmpty( Point point ) + { + return DoubleHelper.IsNaN( point.X ) && DoubleHelper.IsNaN( point.Y ); + } + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/VisualTreeHelperEx.cs b/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/VisualTreeHelperEx.cs new file mode 100644 index 00000000..2ed5b64e --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/Helpers/VisualTreeHelperEx.cs @@ -0,0 +1,157 @@ +/************************************************************************************* + + Extended WPF Toolkit + + Copyright (C) 2007-2013 Xceed Software Inc. + + This program is provided to you under the terms of the Microsoft Public + License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license + + For more features, controls, and fast professional support, + pick up the Plus Edition at http://xceed.com/wpf_toolkit + + Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids + + ***********************************************************************************/ + +using System; +using System.Collections.Generic; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media; + +namespace GraphX.Controls +{ + public static class VisualTreeHelperEx + { + public static DependencyObject FindAncestorByType(DependencyObject element, Type type, bool specificTypeOnly) + { + if (element == null) + return null; + + if (element.GetType() == type) + return element; + + return FindAncestorByType(VisualTreeHelper.GetParent(element), type, specificTypeOnly); + } + + public static T FindAncestorByType(DependencyObject depObj) where T : DependencyObject + { + if (depObj == null) + { + return default(T); + } + if (depObj is T) + { + return (T) depObj; + } + + T parent = default(T); + + parent = FindAncestorByType(VisualTreeHelper.GetParent(depObj)); + + return parent; + } + + public static UIElement FindDescendantByName(UIElement element, string name) + { + if (element != null && (element is FrameworkElement) && (element as FrameworkElement).Name == name) + return element; + + UIElement foundElement = null; + if (element is FrameworkElement) + (element as FrameworkElement).InvalidateArrange(); + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) + { + var visual = VisualTreeHelper.GetChild(element, i) as UIElement; + foundElement = FindDescendantByName(visual, name); + if (foundElement != null) + break; + } + + return foundElement; + } + + public static UIElement FindDescendantByType(UIElement element, Type type) + { + return FindDescendantByType(element, type, true); + } + + public static UIElement FindDescendantByType(UIElement element, Type type, bool specificTypeOnly) + { + if (element == null) + return null; + + if (element.GetType() == type) + return element; + + UIElement foundElement = null; + if (element is FrameworkElement) + (element as FrameworkElement).InvalidateArrange(); + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) + { + var visual = VisualTreeHelper.GetChild(element, i) as UIElement; + foundElement = FindDescendantByType(visual, type, specificTypeOnly); + if (foundElement != null) + break; + } + + return foundElement; + } + + public static T FindDescendantByType(UIElement element) where T : UIElement + { + UIElement temp = FindDescendantByType(element, typeof (T)); + + return (T) temp; + } + + public static UIElement FindDescendantWithPropertyValue(UIElement element, + DependencyProperty dp, object value) + { + if (element == null) + return null; + + if (element.GetValue(dp).Equals(value)) + return element; + + UIElement foundElement = null; + if (element is FrameworkElement) + (element as FrameworkElement).InvalidateArrange(); + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) + { + var visual = VisualTreeHelper.GetChild(element, i) as UIElement; + foundElement = FindDescendantWithPropertyValue(visual, dp, value); + if (foundElement != null) + break; + } + + return foundElement; + } + + #region Find descendants of type + + public static IEnumerable FindDescendantsOfType(this UIElement element) where T : class + { + if (element == null) yield break; + if (element is T) + yield return element as T; + + var frameworkElement = element as FrameworkElement; + if (frameworkElement != null) + frameworkElement.InvalidateArrange(); + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) + { + var visual = VisualTreeHelper.GetChild(element, i) as UIElement; + if (visual == null) continue; + foreach (var item in visual.FindDescendantsOfType()) + yield return item; + } + } + + #endregion + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/AreaSelectedEventArgs.cs b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/AreaSelectedEventArgs.cs new file mode 100644 index 00000000..ee26582a --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/AreaSelectedEventArgs.cs @@ -0,0 +1,19 @@ +using System; +using Windows.Foundation; + +namespace GraphX.Controls +{ + public class AreaSelectedEventArgs : EventArgs + { + /// + /// Rectangle data in coordinates of content object + /// + public Rect Rectangle { get; set; } + + public AreaSelectedEventArgs(Rect rec) + : base() + { + Rectangle = rec; + } + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/AreaSelectedEventHandler.cs b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/AreaSelectedEventHandler.cs new file mode 100644 index 00000000..3fefb99c --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/AreaSelectedEventHandler.cs @@ -0,0 +1,4 @@ +namespace GraphX.Controls +{ + public delegate void AreaSelectedEventHandler(object sender, AreaSelectedEventArgs args); +} \ No newline at end of file diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ContentSizeChangedHandler.cs b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ContentSizeChangedHandler.cs new file mode 100644 index 00000000..d4b0f59e --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ContentSizeChangedHandler.cs @@ -0,0 +1,6 @@ +using Windows.Foundation; + +namespace GraphX.Controls +{ + public delegate void ContentSizeChangedHandler(object sender, Size newSize); +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/MouseWheelZoomingMode.cs b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/MouseWheelZoomingMode.cs new file mode 100644 index 00000000..ff8de5b0 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/MouseWheelZoomingMode.cs @@ -0,0 +1,8 @@ +namespace GraphX.Controls +{ + public enum MouseWheelZoomingMode + { + Positional = 0, + Absolute + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ZoomControlModes.cs b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ZoomControlModes.cs new file mode 100644 index 00000000..4700483f --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ZoomControlModes.cs @@ -0,0 +1,20 @@ +namespace GraphX.Controls +{ + public enum ZoomControlModes + { + /// + /// The content should fill the given space. + /// + Fill, + + /// + /// The content will be represented in its original size. + /// + Original, + + /// + /// The content will be zoomed with a custom percent. + /// + Custom + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ZoomViewModifierMode.cs b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ZoomViewModifierMode.cs new file mode 100644 index 00000000..36db13c5 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/SupportClasses/ZoomViewModifierMode.cs @@ -0,0 +1,30 @@ +namespace GraphX.Controls +{ + public enum ZoomViewModifierMode + { + /// + /// It does nothing at all. + /// + None, + + /// + /// You can pan the view with the mouse in this mode. + /// + Pan, + + /// + /// You can zoom in with the mouse in this mode. + /// + ZoomIn, + + /// + /// You can zoom out with the mouse in this mode. + /// + ZoomOut, + + /// + /// Zooming after the user has been selected the zooming box. + /// + ZoomBox + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/ZoomContentPresenter.cs b/GraphX.UAP.Controls/Controls/ZoomControl/ZoomContentPresenter.cs new file mode 100644 index 00000000..3ff94303 --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/ZoomContentPresenter.cs @@ -0,0 +1,71 @@ +using System.ComponentModel; +using Windows.Foundation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Media; + +namespace GraphX.Controls +{ + [Bindable] + public sealed class ZCP : ContentPresenter, INotifyPropertyChanged + { + public event ContentSizeChangedHandler ContentSizeChanged; + + private Size _contentSize; + + /* public Point ContentTopLeft { get; private set; } + public Point ContentBottomRight { get; private set; } + public Point ContentActualSize { get; private set; } + */ + public Size ContentSize + { + get { return _contentSize; } + private set { + if (value == _contentSize) + return; + + _contentSize = value; + if (ContentSizeChanged != null) + ContentSizeChanged(this, _contentSize); + } + } + + protected override Size MeasureOverride(Size constraint) + { + base.MeasureOverride(new Size(double.PositiveInfinity, double.PositiveInfinity)); + var max = 1000000000; + var x = double.IsInfinity(constraint.Width) ? max : constraint.Width; + var y = double.IsInfinity(constraint.Height) ? max : constraint.Height; + return new Size(x, y); + } + + protected override Size ArrangeOverride(Size arrangeBounds) + { + UIElement child = Content != null + ? VisualTreeHelper.GetChild(this, 0) as UIElement + : null; + if (child == null) + return arrangeBounds; + + //set the ContentSize + ContentSize = child.DesiredSize; + child.Arrange(new Rect(new Point(),child.DesiredSize)); + /* if (child is GraphAreaBase) + { + ContentBottomRight = (child as GraphAreaBase).BottomRight; + ContentTopLeft = (child as GraphAreaBase).TopLeft; + ContentActualSize = new Point((child as GraphAreaBase).ActualWidth, (child as GraphAreaBase).ActualHeight); + }*/ + + return arrangeBounds; + } + + public event PropertyChangedEventHandler PropertyChanged; + public void OnPropertyChanged(string name) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(name)); + } + } +} diff --git a/GraphX.UAP.Controls/Controls/ZoomControl/ZoomControl.cs b/GraphX.UAP.Controls/Controls/ZoomControl/ZoomControl.cs new file mode 100644 index 00000000..904aa92f --- /dev/null +++ b/GraphX.UAP.Controls/Controls/ZoomControl/ZoomControl.cs @@ -0,0 +1,911 @@ +using System; +using System.ComponentModel; +using Windows.ApplicationModel; +using Windows.System; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Media.Animation; +using GraphX.Measure; +using GraphX.Controls.Models; +using Point = Windows.Foundation.Point; +using Rect = Windows.Foundation.Rect; +using Thickness = Windows.UI.Xaml.Thickness; + +namespace GraphX.Controls +{ + [TemplatePart(Name = PART_PRESENTER, Type = typeof(ZCP))] + public class ZoomControl : ContentControl, IZoomControl, INotifyPropertyChanged + { + + #region Properties + + #region ViewFinderVisibility Attached Property + + public static readonly DependencyProperty ViewFinderVisibilityProperty = + DependencyProperty.RegisterAttached("ViewFinderVisibility", typeof(Visibility), typeof(ZoomControl), + new PropertyMetadata(Visibility.Visible)); + + public static Visibility GetViewFinderVisibility(DependencyObject d) + { + return (Visibility)(d.GetValue(ViewFinderVisibilityProperty)); + } + + public static void SetViewFinderVisibility(DependencyObject d, Visibility value) + { + d.SetValue(ViewFinderVisibilityProperty, value); + } + + #endregion + + public DelegateCommand ZoomToFillCommand { get { return new DelegateCommand((o) => ZoomToFill());} } + + public DelegateCommand CenterToContentCommand { get { return new DelegateCommand((o) => CenterContent());} } + + /// + /// Gets or sets if animation should be disabled + /// + public bool IsAnimationDisabled { get; set; } + + /// + /// Use Ctrl key to zoom with mouse wheel or without it + /// + public bool UseCtrlForMouseWheel { get; set; } + + /// + /// Gets or sets absolute zooming on mouse wheel which doesn't depend on mouse position + /// + public MouseWheelZoomingMode MouseWheelZoomingMode { get; set; } + + /// + /// Fires when area has been selected using SelectionModifiers + /// + public event AreaSelectedEventHandler AreaSelected; + + private void OnAreaSelected(Rect selection) + { + if (AreaSelected != null) + AreaSelected(this, new AreaSelectedEventArgs(selection)); + } + + private const string PART_PRESENTER = "PART_Presenter"; + + public static readonly DependencyProperty HideZoomProperty = + DependencyProperty.Register("HideZoom", typeof(Visibility), typeof(ZoomControl), + new PropertyMetadata(Visibility.Visible)); + + public static readonly DependencyProperty AnimationLengthProperty = + DependencyProperty.Register("AnimationLength", typeof(TimeSpan), typeof(ZoomControl), + new PropertyMetadata(TimeSpan.FromMilliseconds(500))); + + public static readonly DependencyProperty MaximumZoomStepProperty = + DependencyProperty.Register("MaximumZoomStep", typeof(double), typeof(ZoomControl), + new PropertyMetadata(5.0)); + + public static readonly DependencyProperty MaxZoomProperty = + DependencyProperty.Register("MaxZoom", typeof(double), typeof(ZoomControl), new PropertyMetadata(100.0)); + + public static readonly DependencyProperty MinZoomProperty = + DependencyProperty.Register("MinZoom", typeof(double), typeof(ZoomControl), new PropertyMetadata(0.01)); + + public static readonly DependencyProperty ModeProperty = + DependencyProperty.Register("Mode", typeof(ZoomControlModes), typeof(ZoomControl), + new PropertyMetadata(ZoomControlModes.Custom, Mode_PropertyChanged)); + + private static void Mode_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var zc = (ZoomControl)d; + var mode = (ZoomControlModes)e.NewValue; + switch (mode) + { + case ZoomControlModes.Fill: + zc.DoZoomToFill(); + break; + case ZoomControlModes.Original: + zc.DoZoomToOriginal(); + break; + case ZoomControlModes.Custom: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public static readonly DependencyProperty ModifierModeProperty = + DependencyProperty.Register("ModifierMode", typeof(ZoomViewModifierMode), typeof(ZoomControl), + new PropertyMetadata(ZoomViewModifierMode.None)); + + #region TranslateX TranslateY + public static readonly DependencyProperty TranslateXProperty = + DependencyProperty.Register("TranslateX", typeof(double), typeof(ZoomControl), + new PropertyMetadata(0.0, TranslateX_PropertyChanged)); + + public static readonly DependencyProperty TranslateYProperty = + DependencyProperty.Register("TranslateY", typeof(double), typeof(ZoomControl), + new PropertyMetadata(0.0, TranslateY_PropertyChanged)); + + + private static void TranslateX_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var zc = (ZoomControl)d; + if (zc._translateTransform == null) + return; + zc._translateTransform.X = (double)e.NewValue; + if (!zc._isZooming) + zc.Mode = ZoomControlModes.Custom; + zc.OnPropertyChanged("Presenter"); + zc.Presenter.OnPropertyChanged("RenderTransform"); + } + + private static void TranslateY_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var zc = (ZoomControl)d; + if (zc._translateTransform == null) + return; + zc._translateTransform.Y = (double)e.NewValue; + if (!zc._isZooming) + zc.Mode = ZoomControlModes.Custom; + zc.OnPropertyChanged("Presenter"); + zc.Presenter.OnPropertyChanged("RenderTransform"); + + } + + #endregion + + public static readonly DependencyProperty ZoomBoxBackgroundProperty = + DependencyProperty.Register("ZoomBoxBackground", typeof(Brush), typeof(ZoomControl), + new PropertyMetadata(null)); + + + public static readonly DependencyProperty ZoomBoxBorderBrushProperty = + DependencyProperty.Register("ZoomBoxBorderBrush", typeof(Brush), typeof(ZoomControl), + new PropertyMetadata(null)); + + + public static readonly DependencyProperty ZoomBoxBorderThicknessProperty = + DependencyProperty.Register("ZoomBoxBorderThickness", typeof(Thickness), typeof(ZoomControl), + new PropertyMetadata(null)); + + + public static readonly DependencyProperty ZoomBoxOpacityProperty = + DependencyProperty.Register("ZoomBoxOpacity", typeof(double), typeof(ZoomControl), + new PropertyMetadata(0.5)); + + + public static readonly DependencyProperty ZoomBoxProperty = + DependencyProperty.Register("ZoomBox", typeof(Rect), typeof(ZoomControl), + new PropertyMetadata(new Rect())); + + public static readonly DependencyProperty ZoomSensitivityProperty = + DependencyProperty.Register("ZoomSensitivity", typeof(double), typeof(ZoomControl), + new PropertyMetadata(100.0)); + + #region Zoom + public static readonly DependencyProperty ZoomProperty = + DependencyProperty.Register("Zoom", typeof(double), typeof(ZoomControl), + new PropertyMetadata(1.0, Zoom_PropertyChanged)); + + private static void Zoom_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var zc = (ZoomControl)d; + + if (zc._scaleTransform == null) + return; + + var zoom = (double)e.NewValue; + zc._scaleTransform.ScaleX = zoom; + zc._scaleTransform.ScaleY = zoom; + /* if (!zc._isZooming) + { + var delta = (double)e.NewValue / (double)e.OldValue; + zc.TranslateX *= delta; + zc.TranslateY *= delta; + zc.Mode = ZoomControlModes.Custom; + }*/ + zc.OnPropertyChanged("Presenter"); + zc.Presenter.OnPropertyChanged("RenderTransform"); + zc.OnPropertyChanged("Zoom"); + + //VF zc.UpdateViewport(); + } + #endregion + + private Point _mouseDownPos; + private ZCP _presenter; + + /// + /// Applied to the presenter. + /// + private ScaleTransform _scaleTransform; + private Vector _startTranslate; + private TransformGroup _transformGroup; + + /// + /// Applied to the scrollviewer. + /// + private TranslateTransform _translateTransform; + + private Storyboard _currentZoomAnimation; + + private bool _isZooming; + + public Brush ZoomBoxBackground + { + get { return (Brush)GetValue(ZoomBoxBackgroundProperty); } + set { SetValue(ZoomBoxBackgroundProperty, value); } + } + + public Brush ZoomBoxBorderBrush + { + get { return (Brush)GetValue(ZoomBoxBorderBrushProperty); } + set { SetValue(ZoomBoxBorderBrushProperty, value); } + } + + public Thickness ZoomBoxBorderThickness + { + get { return (Thickness)GetValue(ZoomBoxBorderThicknessProperty); } + set { SetValue(ZoomBoxBorderThicknessProperty, value); } + } + + public double ZoomBoxOpacity + { + get { return (double)GetValue(ZoomBoxOpacityProperty); } + set { SetValue(ZoomBoxOpacityProperty, value); } + } + + public Rect ZoomBox + { + get { return (Rect)GetValue(ZoomBoxProperty); } + set { SetValue(ZoomBoxProperty, value); } + } + + public Point OrigoPosition + { + get { return new Point(ActualWidth / 2, ActualHeight / 2); } + } + + private Storyboard _lastTranslateXAnimation; + public double TranslateX + { + get + { + var value = (double)GetValue(TranslateXProperty); + return double.IsNaN(value) ? 0 : value; + } + set + { + if (_lastTranslateXAnimation != null) + { + //_lastTranslateXAnimation.SkipToFill(); + _lastTranslateXAnimation.Stop(); + //SetValue(TranslateXProperty, TranslateX); + } + _lastTranslateXAnimation = AnimationHelper.CreateDoubleAnimation(TranslateX, value, 0, "TranslateX", this, null, (o, e) => SetValue(TranslateXProperty, value)); + // ((DoubleAnimation)_lastTranslateXAnimation.Children[0]).EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut }; + _lastTranslateXAnimation.Begin(); + //SetValue(TranslateXProperty, value); + } + } + + private Storyboard _lastTranslateYAnimation; + public double TranslateY + { + get { + var value = (double)GetValue(TranslateYProperty); + return double.IsNaN(value) ? 0 : value; + } + set + { + if (_lastTranslateYAnimation != null) + { + //_lastTranslateYAnimation.SkipToFill(); + _lastTranslateYAnimation.Stop(); + //SetValue(TranslateYProperty, TranslateY); + } + + _lastTranslateYAnimation = AnimationHelper.CreateDoubleAnimation(TranslateY, value, 0, "TranslateY", this, null, (o, e) => SetValue(TranslateYProperty, value)); + //((DoubleAnimation)_lastTranslateYAnimation.Children[0]).EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseOut }; + _lastTranslateYAnimation.Begin(); + //SetValue(TranslateYProperty, value); + } + } + + public TimeSpan AnimationLength + { + get { return (TimeSpan)GetValue(AnimationLengthProperty); } + set { SetValue(AnimationLengthProperty, value); } + } + + public double MinZoom + { + get { return (double)GetValue(MinZoomProperty); } + set { SetValue(MinZoomProperty, value); } + } + + public double MaxZoom + { + get { return (double)GetValue(MaxZoomProperty); } + set { SetValue(MaxZoomProperty, value); } + } + + public double MaximumZoomStep + { + get { return (double)GetValue(MaximumZoomStepProperty); } + set { SetValue(MaximumZoomStepProperty, value); } + } + + public double ZoomSensitivity + { + get { return (double)GetValue(ZoomSensitivityProperty); } + set { SetValue(ZoomSensitivityProperty, value); } + } + + public double Zoom + { + get { return (double)GetValue(ZoomProperty); } + set + { + if (value == (double)GetValue(ZoomProperty)) + return; + //TODO BeginAnimation(ZoomProperty, null); + SetValue(ZoomProperty, value); + } + } + + /// + /// Gets content object as UIElement + /// + public UIElement ContentVisual + { + get + { + return Content as UIElement; + } + } + /// + /// Gets content as ITrackableContent like GraphArea + /// + public ITrackableContent TrackableContent + { + get + { + return Content as ITrackableContent; + } + } + + bool _isga; + /// + /// Is loaded content represents ITrackableContent object + /// + public bool IsContentTrackable + { + get { return _isga; } + } + + + public ZCP Presenter + { + get { return _presenter; } + set + { + _presenter = value; + if (_presenter == null) + return; + + //add the ScaleTransform to the presenter + _transformGroup = new TransformGroup(); + _scaleTransform = new ScaleTransform(); + _translateTransform = new TranslateTransform(); + _transformGroup.Children.Add(_scaleTransform); + _transformGroup.Children.Add(_translateTransform); + _presenter.RenderTransform = _transformGroup; + _presenter.RenderTransformOrigin = new Point(0.5, 0.5); + } + } + + public UIElement PresenterVisual + { + get { return Presenter; } + } + + /// + /// Gets or sets the active modifier mode. + /// + public ZoomViewModifierMode ModifierMode + { + get { return (ZoomViewModifierMode)GetValue(ModifierModeProperty); } + set { SetValue(ModifierModeProperty, value); } + } + + /// + /// Gets or sets the mode of the zoom control. + /// + public ZoomControlModes Mode + { + get { return (ZoomControlModes)GetValue(ModeProperty); } + set { SetValue(ModeProperty, value); } + } + + #endregion + + public ZoomControl() + { + DefaultStyleKey = typeof (ZoomControl); + if (DesignMode.DesignModeEnabled) + { + //Mode = ZoomControlModes.Fill; + + Loaded += ZoomControl_DesignerLoaded; + } + else + { + PointerWheelChanged += ZoomControl_MouseWheel; + PointerPressed += ZoomControl_PreviewMouseDown; + PointerReleased += ZoomControl_MouseUp; + UseCtrlForMouseWheel = true; + Loaded += ZoomControl_Loaded; + } + + } + + void ZoomControl_Loaded(object sender, RoutedEventArgs e) + { + SetValue(ZoomProperty, Zoom); + } + + void ZoomControl_DesignerLoaded(object sender, RoutedEventArgs e) + { + Zoom = 1.0; + } + + #region ContentChanged + protected override void OnContentChanged(object oldContent, object newContent) + { + if (oldContent != null) + { + var old = oldContent as ITrackableContent; + if (old != null) old.ContentSizeChanged -= Content_ContentSizeChanged; + } + if (newContent != null) + { + //VF UpdateViewFinderDisplayContentBounds(); + //VF UpdateViewport(); + var newc = newContent as ITrackableContent; + if (newc != null) + { + _isga = true; + newc.ContentSizeChanged += Content_ContentSizeChanged; + } + else _isga = false; + } + + base.OnContentChanged(oldContent, newContent); + } + + void Content_ContentSizeChanged(object sender, ContentSizeChangedEventArgs e) + { + //VF UpdateViewFinderDisplayContentBounds(); + //VF UpdateViewport(); + } + #endregion + + #region Mouse controls + + /// + /// Converts screen rectangle area to rectangle in content coordinate space according to scale and translation + /// + /// Screen rectangle data + public Rect ToContentRectangle(Rect screenRectangle) + { + var transformer = TransformToVisual(ContentVisual); + var tl = transformer.TransformPoint(new Point(screenRectangle.X, screenRectangle.Y)); + var br = transformer.TransformPoint(new Point(screenRectangle.Right, screenRectangle.Bottom)); + return new Rect(tl.X, tl.Y, Math.Abs(Math.Abs(br.X) - Math.Abs(tl.X)), Math.Abs(Math.Abs(br.Y) - Math.Abs(tl.Y))); + } + + private void ZoomControl_MouseWheel(object sender, PointerRoutedEventArgs e) + { + + var handle = (e.KeyModifiers == VirtualKeyModifiers.Control && ModifierMode == ZoomViewModifierMode.None) || UseCtrlForMouseWheel; + if (!handle) return; + + e.Handled = true; + //var origoPosition = new Point(ActualWidth / 2, ActualHeight / 2); + //var mousePosition = e.GetCurrentPoint(this).Position; + MouseWheelAction(e.GetCurrentPoint(this).Properties.MouseWheelDelta, e.GetCurrentPoint(this).Position); + } + + /// + /// Defines action on mousewheel + /// + /// + /// + protected virtual void MouseWheelAction(int delta, Point mousePosition) + { + var origoPosition = OrigoPosition; + + DoZoom( + Math.Max(1 / MaximumZoomStep, Math.Min(MaximumZoomStep, (Math.Abs(delta) / 10000.0 * ZoomSensitivity + 1))), + delta < 0 ? -1 : 1, + origoPosition, + MouseWheelZoomingMode == MouseWheelZoomingMode.Absolute ? OrigoPosition : mousePosition, + MouseWheelZoomingMode == MouseWheelZoomingMode.Absolute ? OrigoPosition : mousePosition); + } + + + private void ZoomControl_MouseUp(object sender, PointerRoutedEventArgs e) + { + switch (ModifierMode) + { + case ZoomViewModifierMode.None: + return; + case ZoomViewModifierMode.Pan: + break; + case ZoomViewModifierMode.ZoomIn: + break; + case ZoomViewModifierMode.ZoomOut: + break; + case ZoomViewModifierMode.ZoomBox: + if (_startedAsAreaSelection) + { + _startedAsAreaSelection = false; + + OnAreaSelected(ToContentRectangle(ZoomBox)); + ZoomBox = Rect.Empty; + } + else ZoomToInternal(ZoomBox); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + ModifierMode = ZoomViewModifierMode.None; + PointerMoved -= ZoomControl_PreviewMouseMove; + ReleasePointerCapture(e.Pointer); + } + + private void ZoomControl_PreviewMouseMove(object sender, PointerRoutedEventArgs e) + { + var pos = e.GetCurrentPoint(this).Position; + switch (ModifierMode) + { + case ZoomViewModifierMode.None: + return; + case ZoomViewModifierMode.Pan: + var pps = pos.Subtract(_mouseDownPos); + var translatex = _startTranslate.X + pps.X; + var translatey = _startTranslate.Y + pps.Y; + TranslateX = translatex; + TranslateY = translatey; + //VF UpdateViewport(); + break; + case ZoomViewModifierMode.ZoomIn: + break; + case ZoomViewModifierMode.ZoomOut: + break; + case ZoomViewModifierMode.ZoomBox: + var x = Math.Min(_mouseDownPos.X, pos.X); + var y = Math.Min(_mouseDownPos.Y, pos.Y); + var sizeX = Math.Abs(_mouseDownPos.X - pos.X); + var sizeY = Math.Abs(_mouseDownPos.Y - pos.Y); + ZoomBox = new Rect(x, y, sizeX, sizeY); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + /* private void ZoomControl_MouseDown(object sender, PointerRoutedEventArgs e) + { + OnMouseDown(e, false); + }*/ + + private void ZoomControl_PreviewMouseDown(object sender, PointerRoutedEventArgs e) + { + OnMouseDown(e, false); + e.Handled = false; + } + + private bool _startedAsAreaSelection; + private void OnMouseDown(PointerRoutedEventArgs e, bool isPreview) + { + if (ModifierMode != ZoomViewModifierMode.None) + return; + _startedAsAreaSelection = false; + switch (e.KeyModifiers) + { + case VirtualKeyModifiers.None: + if (!isPreview) + ModifierMode = ZoomViewModifierMode.Pan; + break; + case VirtualKeyModifiers.Windows | VirtualKeyModifiers.Control: + _startedAsAreaSelection = true; + ModifierMode = ZoomViewModifierMode.ZoomBox; + break; + case VirtualKeyModifiers.Windows: + ModifierMode = ZoomViewModifierMode.ZoomBox; + break; + case VirtualKeyModifiers.Control: + break; + case VirtualKeyModifiers.Shift: + ModifierMode = ZoomViewModifierMode.Pan; + break; + default: + return; + } + + if (ModifierMode == ZoomViewModifierMode.None) + return; + + _mouseDownPos = e.GetCurrentPoint(this).Position; + _startTranslate = new Vector(TranslateX, TranslateY); + CapturePointer(e.Pointer); + PointerMoved += ZoomControl_PreviewMouseMove; + } + #endregion + + #region Animation + + public event EventHandler ZoomAnimationCompleted; + + private void OnZoomAnimationCompleted() + { + if (ZoomAnimationCompleted != null) + ZoomAnimationCompleted(this, EventArgs.Empty); + } + + + + + private void DoZoomAnimation(double targetZoom, double transformX, double transformY, bool isZooming = true) + { + if (targetZoom == 0d && double.IsNaN(transformX) && double.IsNaN(transformY)) return; + _isZooming = isZooming; + var duration = !IsAnimationDisabled ? new Duration(AnimationLength) : new Duration(new TimeSpan(0,0,0,0,100)); + var value = (double)GetValue(TranslateXProperty); + if (double.IsNaN(value) || double.IsInfinity(value)) SetValue(TranslateXProperty, 0d); + value = (double)GetValue(TranslateYProperty); + if (double.IsNaN(value) || double.IsInfinity(value)) SetValue(TranslateYProperty, 0d); + StartAnimation(TranslateXProperty, "TranslateX", transformX, duration); + if (double.IsNaN(transformY) || double.IsInfinity(transformY)) transformY = 0; + StartAnimation(TranslateYProperty, "TranslateY", transformY, duration); + if (double.IsNaN(targetZoom) || double.IsInfinity(targetZoom)) targetZoom = 1; + StartAnimation(ZoomProperty, "Zoom", targetZoom, duration); + } + + private void StartAnimation(DependencyProperty dp, string dpName, double toValue, Duration duration) + { + if (double.IsNaN(toValue) || double.IsInfinity(toValue)) + { + if (dp == ZoomProperty) + { + _isZooming = false; + } + return; + } + + _currentZoomAnimation = AnimationHelper.CreateDoubleAnimation(null, toValue, duration.TimeSpan.TotalMilliseconds, dpName, this); + if (dp == ZoomProperty) + { + _zoomAnimCount++; + _currentZoomAnimation.Completed += (s, args) => + { + _zoomAnimCount--; + if (_zoomAnimCount > 0 && _currentZoomAnimation != s) + return; + var zoom = Zoom; + SetValue(ZoomProperty, zoom); + _isZooming = false; + //VF UpdateViewport(); + OnZoomAnimationCompleted(); + }; + } + _currentZoomAnimation.Begin(); + } + + private int _zoomAnimCount; + + + #endregion + + /// + /// Zoom to rectangle area (MAY BE DEPRECATED). Use ZoomToContent method instead. + /// + /// + /// + public void ZoomTo(Rect rect, bool setDelta = false) + { + ZoomToInternal(rect, setDelta); + //VF UpdateViewFinderDisplayContentBounds(); + //VF UpdateViewport(); + } + + /// + /// Zoom to rectangle area of the content + /// + /// Rectangle area + /// Sets if content coordinates or screen coordinates was specified + public void ZoomToContent(Rect rectangle, bool usingContentCoordinates = true) + { + //if content isn't UIElement - return + if (ContentVisual == null) return; + // translate the region from the coordinate space of the content + // to the coordinate space of the content presenter + var transformer = ContentVisual.TransformToVisual(_presenter); + var region = usingContentCoordinates ? + new Rect( + transformer.TransformPoint(new Point(rectangle.Top, rectangle.Left)), + transformer.TransformPoint(new Point(rectangle.Bottom, rectangle.Right))) : rectangle; + + // calculate actual zoom, which must fit the entire selection + // while maintaining a 1:1 ratio + var aspectX = ActualWidth / region.Width; + var aspectY = ActualHeight / region.Height; + var newRelativeScale = aspectX < aspectY ? aspectX : aspectY; + // ensure that the scale value alls within the valid range + if (newRelativeScale > MaxZoom) + newRelativeScale = MaxZoom; + else if (newRelativeScale < MinZoom) + newRelativeScale = MinZoom; + + var center = new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2); + var newRelativePosition = new Point((ActualWidth / 2 - center.X) * Zoom, (ActualHeight / 2 - center.Y) * Zoom); + + TranslateX = newRelativePosition.X; + TranslateY = newRelativePosition.Y; + Zoom = newRelativeScale; + } + + /// + /// Zoom to original size + /// + public void ZoomToOriginal() + { + if (Mode == ZoomControlModes.Original) + DoZoomToOriginal(); + else Mode = ZoomControlModes.Original; + } + + /// + /// Centers content on the screen + /// + public void CenterContent() + { + if (_presenter == null) + return; + + var initialTranslate = GetTrackableTranslate(); + DoZoomAnimation(Zoom, initialTranslate.X*Zoom, initialTranslate.Y*Zoom); + } + + /// + /// Zoom to fill screen area with the content + /// + public void ZoomToFill() + { + if(Mode == ZoomControlModes.Fill) + DoZoomToFill(); + else Mode = ZoomControlModes.Fill; + } + + private void ZoomToInternal(Rect rect, bool setDelta = false) + { + var deltaZoom = Math.Min(ActualWidth / rect.Width, ActualHeight / rect.Height); + var startHandlePosition = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); + DoZoom(deltaZoom, 1, OrigoPosition, startHandlePosition, OrigoPosition, setDelta); + ZoomBox = new Rect(); + } + + /// + /// Returns initial translate depending on container graph settings (to deal with optinal new coord system) + /// + private Vector GetTrackableTranslate() + { + if (!IsContentTrackable) return new Vector(); + return DesignMode.DesignModeEnabled ? GetInitialTranslate(200,100) : GetInitialTranslate(TrackableContent.ContentSize.Width, TrackableContent.ContentSize.Height, TrackableContent.ContentSize.X, TrackableContent.ContentSize.Y); + } + + private void DoZoomToOriginal() + { + if (_presenter == null) + return; + + var initialTranslate = GetTrackableTranslate(); + DoZoomAnimation(1.0, initialTranslate.X, initialTranslate.Y); + } + + private Vector GetInitialTranslate(double contentWidth, double contentHeight, double offsetX = 0, double offsetY = 0) + { + if (_presenter == null) + return new Vector(0.0, 0.0); + var w = contentWidth - ActualWidth; + var h = contentHeight - ActualHeight; + var tX = -(w / 2.0 + offsetX); + var tY = -(h / 2.0 + offsetY); + + return new Vector(tX, tY); + } + + private void DoZoomToFill() + { + if (_presenter == null) + return; + var c = IsContentTrackable ? TrackableContent.ContentSize.Size() : ContentVisual.DesiredSize; + var deltaZoom = Math.Min(MaxZoom,Math.Min( ActualWidth / (c.Width), ActualHeight / (c.Height))); + var initialTranslate = IsContentTrackable ? GetTrackableTranslate() : GetInitialTranslate(c.Width, c.Height); + DoZoomAnimation(deltaZoom, initialTranslate.X * deltaZoom, initialTranslate.Y * deltaZoom); + } + + private double GetCoercedTranslate(double baseValue) + { + return _presenter == null ? 0.0 : baseValue; + } + + private void DoZoom(double deltaZoom, int mod, Point origoPosition, Point startHandlePosition, Point targetHandlePosition, bool setDelta = false) + { + var startZoom = Zoom; + var currentZoom = setDelta ? deltaZoom : (mod == -1 ? (startZoom / deltaZoom) : (startZoom * deltaZoom)); + currentZoom = Math.Max(MinZoom, Math.Min(MaxZoom, currentZoom)); + + var startTranslate = new Point(TranslateX, TranslateY); + + var v = startHandlePosition.Subtract(origoPosition); + var vTarget = targetHandlePosition.Subtract(origoPosition); + + var targetPoint = v.Subtract(startTranslate).Div(startZoom); + var zoomedTargetPointPos = targetPoint.Mul(currentZoom).Sum(startTranslate); + var endTranslate = vTarget.Subtract(zoomedTargetPointPos); + + + if (setDelta) + { + var transformX = GetCoercedTranslate(endTranslate.X); + var transformY = GetCoercedTranslate(endTranslate.Y); + DoZoomAnimation(currentZoom, transformX, transformY); + } + else + { + var transformX = GetCoercedTranslate(TranslateX + endTranslate.X); + var transformY = GetCoercedTranslate(TranslateY + endTranslate.Y); + DoZoomAnimation(currentZoom, transformX, transformY); + } + Mode = ZoomControlModes.Custom; + } + + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + //VF AttachToVisualTree(); + + //get the presenter, and initialize + Presenter = GetTemplateChild(PART_PRESENTER) as ZCP; + if (Presenter != null) + { + Presenter.SizeChanged += (s, a) => + { + //VF UpdateViewport(); + if (Mode == ZoomControlModes.Fill) + DoZoomToFill(); + }; + Presenter.ContentSizeChanged += (s, a) => + { + //UpdateViewFinderDisplayContentBounds(); + if (Mode == ZoomControlModes.Fill) + { + DoZoomToFill(); + //IsAnimationDisabled = false; + } + }; + } + ZoomToFill(); + } + + public event PropertyChangedEventHandler PropertyChanged; + public void OnPropertyChanged(string name) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(name)); + } + } +} diff --git a/GraphX.UAP.Controls/DesignerExampleData/EdgeDataExample.cs b/GraphX.UAP.Controls/DesignerExampleData/EdgeDataExample.cs new file mode 100644 index 00000000..d0e74f35 --- /dev/null +++ b/GraphX.UAP.Controls/DesignerExampleData/EdgeDataExample.cs @@ -0,0 +1,20 @@ +using GraphX.PCL.Common.Models; + +namespace GraphX.Controls.DesignerExampleData +{ + internal sealed class EdgeDataExample : EdgeBase + { + public EdgeDataExample(TVertex source, TVertex target) + : base(source, target) + { + + } + public EdgeDataExample(TVertex source, TVertex target, double weight) + : base(source, target, weight) + { + + } + + public string Text { get; set; } + } +} diff --git a/GraphX.UAP.Controls/DesignerExampleData/VertexDataExample.cs b/GraphX.UAP.Controls/DesignerExampleData/VertexDataExample.cs new file mode 100644 index 00000000..a02587ba --- /dev/null +++ b/GraphX.UAP.Controls/DesignerExampleData/VertexDataExample.cs @@ -0,0 +1,21 @@ +using GraphX.PCL.Common.Models; + +namespace GraphX.Controls.DesignerExampleData +{ + internal sealed class VertexDataExample : VertexBase + { + public VertexDataExample(int id, string name) + { + ID = id; Name = name; + //DataImage = new BitmapImage(new Uri(@"pack://application:,,,/GraphX.Controls;component/Images/help_black.png", UriKind.Absolute)); + } + + public string Name { get; set; } + //public ImageSource DataImage{ get; set; } + + public override string ToString() + { + return Name; + } + } +} diff --git a/GraphX.UAP.Controls/DpExtensions.cs b/GraphX.UAP.Controls/DpExtensions.cs new file mode 100644 index 00000000..1bb119d6 --- /dev/null +++ b/GraphX.UAP.Controls/DpExtensions.cs @@ -0,0 +1,70 @@ +using System; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Data; + +namespace GraphX.Controls +{ + public static class DependencyObjectExtensions + { + public static IDisposable WatchProperty(this DependencyObject target, + string propertyPath, + DependencyPropertyChangedEventHandler handler) + { + return new DependencyPropertyWatcher(target, propertyPath, handler); + } + + private class DependencyPropertyWatcher : DependencyObject, IDisposable + { + private DependencyPropertyChangedEventHandler _handler; + + public DependencyPropertyWatcher(DependencyObject target, + string propertyPath, + DependencyPropertyChangedEventHandler handler) + { + if (target == null) throw new ArgumentNullException("target"); + if (propertyPath == null) throw new ArgumentNullException("propertyPath"); + if (handler == null) throw new ArgumentNullException("handler"); + + _handler = handler; + + var binding = new Binding + { + Source = target, + Path = new PropertyPath(propertyPath), + Mode = BindingMode.OneWay, + }; + BindingOperations.SetBinding(this, ValueProperty, binding); + } + + private static readonly DependencyProperty ValueProperty = + DependencyProperty.Register( + "Value", + typeof (object), + typeof (DependencyPropertyWatcher), + new PropertyMetadata(null, ValuePropertyChanged)); + + private static void ValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var watcher = d as DependencyPropertyWatcher; + if (watcher == null) + return; + + watcher.OnValueChanged(e); + } + + private void OnValueChanged(DependencyPropertyChangedEventArgs e) + { + var handler = _handler; + if (handler != null) + handler(this, e); + } + + public void Dispose() + { + _handler = null; + // There is no ClearBinding method, so set a dummy binding instead + BindingOperations.SetBinding(this, ValueProperty, new Binding()); + } + } + } +} diff --git a/GraphX.UAP.Controls/GraphX.UAP.Controls.csproj b/GraphX.UAP.Controls/GraphX.UAP.Controls.csproj new file mode 100644 index 00000000..ca66aebe --- /dev/null +++ b/GraphX.UAP.Controls/GraphX.UAP.Controls.csproj @@ -0,0 +1,370 @@ + + + + + Debug + AnyCPU + {4BEBC41E-2710-4613-80B1-198E08D10619} + Library + Properties + GraphX.UAP.Controls + GraphX.UAP.Controls + ru-RU + UAP + 10.0.14393.0 + 10.0.10586.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + AnyCPU + true + full + false + bin\Debug\ + TRACE;DEBUG;NETFX_CORE;WINDOWS_UWP;METRO + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP;METRO + prompt + 4 + + + x86 + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + + + x86 + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + + + ARM + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + + + ARM + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + + + x64 + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + + + x64 + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + + + PackageReference + + + + Animations\DeleteFadeAnimation.cs + + + Animations\DeleteShrinkAnimation.cs + + + Animations\Enum\DeleteAnimation.cs + + + Animations\Enum\MouseOverAnimation.cs + + + Animations\Enum\MoveAnimation.cs + + + Animations\Interfaces\IBidirectionalControlAnimation.cs + + + Animations\Interfaces\IOneWayControlAnimation.cs + + + Animations\MouseOverScaleAnimation.cs + + + Animations\MoveAnimationBase.cs + + + Animations\MoveFadeAnimation.cs + + + Animations\MoveSimpleAnimation.cs + + + Behaviours\DragBehaviour.cs + + + Behaviours\HighlightBehaviour.cs + + + Controls\EdgeControl.cs + + + Controls\EdgeControlBase.cs + + + Controls\EdgeLabels\AttachableEdgeLabelControl.cs + + + Controls\EdgeLabels\EdgeLabelControl.cs + + + Controls\EdgePointers\DefaultEdgePointer.cs + + + Controls\GraphArea.cs + + + Controls\GraphAreaBase.cs + + + Controls\Misc\ControlDrawOrder.cs + + + Controls\Misc\EdgeDashStyle.cs + + + Controls\Misc\IEdgeLabelControl.cs + + + Controls\Misc\IEdgePointer.cs + + + Controls\Misc\IGraphArea.cs + + + Controls\Misc\IGraphAreaBase.cs + + + Controls\Misc\IGraphControl.cs + + + Controls\Misc\IPositionChangeNotify.cs + + + Controls\Misc\ITrackableContent.cs + + + Controls\Misc\IVertexConnectionPoint.cs + + + Controls\Misc\IVertexLabelControl.cs + + + Controls\Misc\IZoomControl.cs + + + Controls\Misc\LogicCoreChangedAction.cs + + + Controls\VertexConnectionPoints\StaticVertexConnectionPoint.cs + + + Controls\VertexControl.cs + + + Controls\VertexControlBase.cs + + + Controls\VertexLabels\AttachableVertexLabelControl.cs + + + Controls\VertexLabels\VertexLabelControl.cs + + + CustomHelper.cs + + + GeometryHelper.cs + + + MathHelper.cs + + + Models\AnimationFactory.cs + + + Models\ContentSizeChangedEventHandler.cs + + + Models\ControlEventArgs.cs + + + Models\DefaultLabelFactory.cs + + + Models\EdgeEventOptions.cs + + + Models\EdgeSelectedEventHandler.cs + + + Models\GraphControlFactory.cs + + + Models\Interfaces\IAttachableControl.cs + + + Models\Interfaces\IGraphControlFactory.cs + + + Models\Interfaces\ILabelFactory.cs + + + Models\RemoveControlEventHandler.cs + + + Models\StateStorage.cs + + + Models\VertexEventOptions.cs + + + Models\VertexPositionChangedEH.cs + + + Models\VertexPositionEventArgs.cs + + + Models\VertexSelectedEventHandler.cs + + + TypeExtensions.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6.0.6 + + + 3.6.61114.2 + + + + + {3644d44b-dec0-4b65-bba0-c68e34821aae} + GraphX.PCL.Common + + + + + + + + + + + MSBuild:Compile + Designer + + + + + + + 14.0 + + + true + + + uap_graphx.controls.pfx + + + + mkdir "$(SolutionDir)bin\$(ConfigurationName)" +copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)bin\$(ConfigurationName)\GraphX.UAP.Controls.dll" + + + \ No newline at end of file diff --git a/GraphX.UAP.Controls/Images/cross-icon.png b/GraphX.UAP.Controls/Images/cross-icon.png new file mode 100644 index 00000000..ba021279 Binary files /dev/null and b/GraphX.UAP.Controls/Images/cross-icon.png differ diff --git a/GraphX.UAP.Controls/Images/help_black.png b/GraphX.UAP.Controls/Images/help_black.png new file mode 100644 index 00000000..db81c881 Binary files /dev/null and b/GraphX.UAP.Controls/Images/help_black.png differ diff --git a/GraphX.UAP.Controls/Images/round1.png b/GraphX.UAP.Controls/Images/round1.png new file mode 100644 index 00000000..963e8ced Binary files /dev/null and b/GraphX.UAP.Controls/Images/round1.png differ diff --git a/GraphX.UAP.Controls/Images/round2.png b/GraphX.UAP.Controls/Images/round2.png new file mode 100644 index 00000000..7c8a14fc Binary files /dev/null and b/GraphX.UAP.Controls/Images/round2.png differ diff --git a/GraphX.UAP.Controls/Models/AnimationHelper.cs b/GraphX.UAP.Controls/Models/AnimationHelper.cs new file mode 100644 index 00000000..04356b41 --- /dev/null +++ b/GraphX.UAP.Controls/Models/AnimationHelper.cs @@ -0,0 +1,33 @@ +using System; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Media.Animation; + +namespace GraphX.Controls.Models +{ + public static class AnimationHelper + { + public static Storyboard CreateDoubleAnimation(double? from, double? to, double duration, string propertyName, FrameworkElement target, FillBehavior? fillBehavior = null, EventHandler onCompleted = null) + { + var animation = new DoubleAnimation + { + From = from, + To = to, + Duration = new Duration(TimeSpan.FromMilliseconds(duration)), + EnableDependentAnimation = true , + //FillBehavior = fillBehavior + //EasingFunction = new ExponentialEase() { EasingMode = EasingMode.EaseOut } + }; + + if (fillBehavior.HasValue) + animation.FillBehavior = fillBehavior.Value; + var sb = new Storyboard(); + Storyboard.SetTarget(animation, target); + Storyboard.SetTargetProperty(animation, propertyName); + sb.Children.Add(animation); + if(onCompleted != null) + sb.Completed += onCompleted; + return sb; + } + } + +} diff --git a/GraphX.UAP.Controls/Models/DelegateCommand.cs b/GraphX.UAP.Controls/Models/DelegateCommand.cs new file mode 100644 index 00000000..6c9786a1 --- /dev/null +++ b/GraphX.UAP.Controls/Models/DelegateCommand.cs @@ -0,0 +1,81 @@ +using System; +using System.Windows.Input; + +namespace GraphX.Controls.Models +{ + public class DelegateCommand : ICommand + { + private readonly Func _canExecuteMethod; + private readonly Action _executeMethod; + + #region Constructors + + public DelegateCommand(Action executeMethod) + : this(executeMethod, null) + { + } + + public DelegateCommand(Action executeMethod, Func canExecuteMethod) + { + _executeMethod = executeMethod; + _canExecuteMethod = canExecuteMethod; + } + + #endregion Constructors + + #region ICommand Members + + public event EventHandler CanExecuteChanged; + + bool ICommand.CanExecute(object parameter) + { + try + { + return CanExecute((T)parameter); + } + catch { return false; } + } + + void ICommand.Execute(object parameter) + { + Execute((T)parameter); + } + + #endregion ICommand Members + + #region Public Methods + + public bool CanExecute(T parameter) + { + return ((_canExecuteMethod == null) || _canExecuteMethod(parameter)); + } + + public void Execute(T parameter) + { + if (_executeMethod != null) + { + _executeMethod(parameter); + } + } + + public void RaiseCanExecuteChanged() + { + OnCanExecuteChanged(EventArgs.Empty); + } + + #endregion Public Methods + + #region Protected Methods + + protected virtual void OnCanExecuteChanged(EventArgs e) + { + var handler = CanExecuteChanged; + if (handler != null) + { + handler(this, e); + } + } + + #endregion Protected Methods + } +} diff --git a/GraphX.UAP.Controls/Models/DispatcherHelper.cs b/GraphX.UAP.Controls/Models/DispatcherHelper.cs new file mode 100644 index 00000000..422ecfd1 --- /dev/null +++ b/GraphX.UAP.Controls/Models/DispatcherHelper.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Windows.UI.Core; + +namespace GraphX.Controls.Models +{ + public static class DispatcherHelper + { + public static async Task CheckBeginInvokeOnUi(Action action) + { + var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher; + + if (dispatcher.HasThreadAccess) + action(); + else await dispatcher.RunAsync(CoreDispatcherPriority.Normal, + () => action()); + } + } +} diff --git a/GraphX.UAP.Controls/Models/EdgeSelectedEventArgs.cs b/GraphX.UAP.Controls/Models/EdgeSelectedEventArgs.cs new file mode 100644 index 00000000..8fec8a77 --- /dev/null +++ b/GraphX.UAP.Controls/Models/EdgeSelectedEventArgs.cs @@ -0,0 +1,29 @@ +using Windows.UI.Xaml.Input; + +namespace GraphX.Controls.Models +{ + public class EdgeSelectedEventArgs : System.EventArgs + { + public EdgeControl EdgeControl { get; set; } + public PointerRoutedEventArgs Args { get; set; } + + public EdgeSelectedEventArgs(EdgeControl ec, PointerRoutedEventArgs e) + : base() + { + EdgeControl = ec; + Args = e; + } + } + + public sealed class EdgeLabelSelectedEventArgs : EdgeSelectedEventArgs + { + public IEdgeLabelControl EdgeLabelControl { get; set; } + + + public EdgeLabelSelectedEventArgs(IEdgeLabelControl label, EdgeControl ec, PointerRoutedEventArgs e, object nu = null) + : base(ec, e) + { + EdgeLabelControl = label; + } + } +} diff --git a/GraphX.UAP.Controls/Models/FileServiceProviderMETRO.cs b/GraphX.UAP.Controls/Models/FileServiceProviderMETRO.cs new file mode 100644 index 00000000..f9839d4b --- /dev/null +++ b/GraphX.UAP.Controls/Models/FileServiceProviderMETRO.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using GraphX.PCL.Common.Interfaces; +using GraphX.PCL.Common.Models; + +namespace GraphX.Controls.Models +{ + /// + /// WPF implementation of IFileServiceProvider + /// + public static class FileServiceProviderMETRO + { + /// + /// Serializes data classes list to file + /// + /// File name + /// Data classes list + public static void SerializeDataToFile(string filename, List modelsList) + { + + } + /// + /// Deserializes data classes list from file + /// + /// File name + public static List DeserializeDataFromFile(string filename) + { + + return Deserialize(filename).Result; + } + +#pragma warning disable 1998 + private static async Task> Deserialize(string filename) +#pragma warning restore 1998 + { + return new List(); + } + } +} diff --git a/GraphX.UAP.Controls/Models/ModifierKeys.cs b/GraphX.UAP.Controls/Models/ModifierKeys.cs new file mode 100644 index 00000000..36cf89a2 --- /dev/null +++ b/GraphX.UAP.Controls/Models/ModifierKeys.cs @@ -0,0 +1,11 @@ +namespace GraphX.Controls.Models +{ + public class Keyboard + { + public static ModifierKeys Modifiers; + } + + public class ModifierKeys + { + } +} diff --git a/GraphX.UAP.Controls/Models/MouseButtonEventArgs.cs b/GraphX.UAP.Controls/Models/MouseButtonEventArgs.cs new file mode 100644 index 00000000..0aca0031 --- /dev/null +++ b/GraphX.UAP.Controls/Models/MouseButtonEventArgs.cs @@ -0,0 +1,6 @@ +namespace GraphX.Controls.Models +{ + public class MouseButtonEventArgs + { + } +} diff --git a/GraphX.UAP.Controls/Models/VertexMovedEventArgs.cs b/GraphX.UAP.Controls/Models/VertexMovedEventArgs.cs new file mode 100644 index 00000000..6ced638d --- /dev/null +++ b/GraphX.UAP.Controls/Models/VertexMovedEventArgs.cs @@ -0,0 +1,16 @@ +using Windows.UI.Xaml.Input; + +namespace GraphX.Controls.Models +{ + public sealed class VertexMovedEventArgs : System.EventArgs + { + public VertexControl VertexControl { get; private set; } + public PointerRoutedEventArgs Args { get; private set; } + + public VertexMovedEventArgs(VertexControl vc, PointerRoutedEventArgs e) + { + Args = e; + VertexControl = vc; + } + } +} diff --git a/GraphX.UAP.Controls/Models/VertexSelectedEventArgs.cs b/GraphX.UAP.Controls/Models/VertexSelectedEventArgs.cs new file mode 100644 index 00000000..c764b7a5 --- /dev/null +++ b/GraphX.UAP.Controls/Models/VertexSelectedEventArgs.cs @@ -0,0 +1,16 @@ +using Windows.UI.Xaml.Input; + +namespace GraphX.Controls.Models +{ + public sealed class VertexSelectedEventArgs : System.EventArgs + { + public VertexControl VertexControl { get; private set; } + public PointerRoutedEventArgs Args { get; private set; } + + public VertexSelectedEventArgs(VertexControl vc, PointerRoutedEventArgs e) + { + VertexControl = vc; + Args = e; + } + } +} \ No newline at end of file diff --git a/GraphX.UAP.Controls/Models/XamlTypes/ViewModelBase.cs b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelBase.cs new file mode 100644 index 00000000..5236045c --- /dev/null +++ b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelBase.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace FancyDevelopment.WinRtPluginSystem.MVVM +{ + public abstract class ViewModelBase : INotifyPropertyChanged + { + + + public event PropertyChangedEventHandler PropertyChanged; + + public ViewModelBase() + { + PropertyValues = new Dictionary(); + PropertyTypes = new Dictionary(); + } + + public IDictionary PropertyValues { get; set; } + + public IDictionary PropertyTypes { get; set; } + + protected T GetPropertyValue(string propertyName) + { + return (T)PropertyValues[propertyName]; + } + + protected void SetPropertyValue(string propertyName, T value) + { + if(!PropertyValues[propertyName].Equals(value)) + { + PropertyValues[propertyName] = value; + OnPropertyChanged(propertyName); + } + } + + public object GetPropertyValue(string propertyName) + { + return PropertyValues[propertyName]; + } + + public void SetPropertyValue(string propertyName, object value) + { + if(value.GetType() != PropertyTypes[propertyName]) + throw new InvalidOperationException("Wrong Type"); + + if (!PropertyValues[propertyName].Equals(value)) + { + PropertyValues[propertyName] = value; + OnPropertyChanged(propertyName); + } + } + + protected void CreateProperty(string propertyName) + { + PropertyTypes[propertyName] = typeof(T); + PropertyValues[propertyName] = default(T); + } + + protected void OnPropertyChanged(string propertyName) + { + if(PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + } +} diff --git a/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlMember.cs b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlMember.cs new file mode 100644 index 00000000..4cce1e37 --- /dev/null +++ b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlMember.cs @@ -0,0 +1,69 @@ +using System; +using Windows.UI.Xaml.Markup; + +namespace FancyDevelopment.WinRtPluginSystem.MVVM +{ + class ViewModelXamlMember : IXamlMember where T : ViewModelBase, new () + { + private readonly string _propertyName; + private readonly ViewModelXamlType _targetType; + private readonly IXamlType _propertyType; + + public ViewModelXamlMember(string propertyName, ViewModelXamlType targetType, IXamlType propertyType) + { + _propertyName = propertyName; + _targetType = targetType; + _propertyType = propertyType; + } + + public object GetValue(object instance) + { + ViewModelBase viewModel = instance as ViewModelBase; + + if(viewModel == null) + throw new InvalidOperationException("Only view model types are supported"); + + return viewModel.GetPropertyValue(_propertyName); + } + + public bool IsAttachable + { + get { return false; } + } + + public bool IsDependencyProperty + { + get { return false; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public string Name + { + get { return _propertyName; } + } + + public void SetValue(object instance, object value) + { + ViewModelBase viewModel = instance as ViewModelBase; + + if (viewModel == null) + throw new InvalidOperationException("Only view model types are supported"); + + viewModel.SetPropertyValue(_propertyName, value); + } + + public IXamlType TargetType + { + get { return _targetType; } + } + + public IXamlType Type + { + get { return _propertyType; } + } + } +} diff --git a/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlMetadataProvider.cs b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlMetadataProvider.cs new file mode 100644 index 00000000..1915f095 --- /dev/null +++ b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlMetadataProvider.cs @@ -0,0 +1,28 @@ +using System; +using Windows.UI.Xaml.Markup; + +namespace FancyDevelopment.WinRtPluginSystem.MVVM +{ + /* public class ViewModelXamlMetadataProvider : IXamlMetadataProvider + { + public IXamlType GetXamlType(string fullName) + { + return XamlTypeProvider.Instance.GetType(fullName); + } + + public IXamlType GetXamlType(Type type) + { + return XamlTypeProvider.Instance.GetType(type); + } + + public XmlnsDefinition[] GetXmlnsDefinitions() + { + return new[] + { + new XmlnsDefinition() { XmlNamespace = "http://schemas.panthernet.ru/graphx/", Namespace = "GraphX.Controls" }, + new XmlnsDefinition() { XmlNamespace = "http://schemas.panthernet.ru/graphx/", Namespace = "GraphX.Controls.Animations" }, + new XmlnsDefinition() { XmlNamespace = "http://schemas.panthernet.ru/graphx/", Namespace = "GraphX.Controls.Models" }, + }; + } + }*/ +} diff --git a/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlType.cs b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlType.cs new file mode 100644 index 00000000..7b3af84c --- /dev/null +++ b/GraphX.UAP.Controls/Models/XamlTypes/ViewModelXamlType.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using Windows.UI.Xaml.Markup; + +namespace FancyDevelopment.WinRtPluginSystem.MVVM +{ + class ViewModelXamlType : IXamlType where T : ViewModelBase, new() + { + private readonly IXamlType _baseType; + private IDictionary> _members; + + public ViewModelXamlType(IXamlType baseType) + { + _baseType = baseType; + } + + public object ActivateInstance() + { + return Activator.CreateInstance(); + } + + public void AddToMap(object instance, object key, object value) + { + throw new NotSupportedException(); + } + + public void AddToVector(object instance, object value) + { + throw new NotSupportedException(); + } + + public IXamlType BaseType + { + get { return _baseType; } + } + + public IXamlMember ContentProperty + { + get { return null; } + } + + public object CreateFromString(string value) + { + throw new NotSupportedException(); + } + + public string FullName + { + get { return typeof(T).FullName; } + } + + public IXamlMember GetMember(string name) + { + return _members[name]; + } + + public bool IsArray + { + get { return false; } + } + + public bool IsBindable + { + get { return true; } + } + + public bool IsCollection + { + get { return false; } + } + + public bool IsConstructible + { + get { return true; } + } + + public bool IsDictionary + { + get { return false; } + } + + public bool IsMarkupExtension + { + get { return false; } + } + + public IXamlType ItemType + { + get { throw new NotSupportedException(); } + } + + public IXamlType KeyType + { + get { throw new NotSupportedException(); } + } + + public void RunInitializer() + { + _members = new Dictionary>(); + + // Create a dummy view model to read the property information + T dummy = Activator.CreateInstance(); + + foreach (KeyValuePair property in dummy.PropertyTypes) + { + IXamlType propertyType = XamlTypeProvider.Instance.GetType(property.Value); + + _members.Add(property.Key, new ViewModelXamlMember(property.Key, this, propertyType)); + } + } + + public Type UnderlyingType + { + get { return typeof (T); } + } + } +} diff --git a/GraphX.UAP.Controls/Models/XamlTypes/XamlSystemType.cs b/GraphX.UAP.Controls/Models/XamlTypes/XamlSystemType.cs new file mode 100644 index 00000000..68392e86 --- /dev/null +++ b/GraphX.UAP.Controls/Models/XamlTypes/XamlSystemType.cs @@ -0,0 +1,105 @@ +using System; +using Windows.UI.Xaml.Markup; + +namespace FancyDevelopment.WinRtPluginSystem.MVVM +{ + class XamlSystemType : IXamlType + { + private readonly Type _type; + + public XamlSystemType(Type type) + { + _type = type; + } + + public object ActivateInstance() + { + throw new NotSupportedException(); + } + + public void AddToMap(object instance, object key, object value) + { + throw new NotSupportedException(); + } + + public void AddToVector(object instance, object value) + { + throw new NotSupportedException(); + } + + public IXamlType BaseType + { + get { throw new NotSupportedException(); } + } + + public IXamlMember ContentProperty + { + get { throw new NotSupportedException(); } + } + + public object CreateFromString(string value) + { + throw new NotSupportedException(); + } + + public string FullName + { + get { return _type.FullName; } + } + + public IXamlMember GetMember(string name) + { + throw new NotSupportedException(); + } + + public bool IsArray + { + get { throw new NotSupportedException(); } + } + + public bool IsBindable + { + get { throw new NotSupportedException(); } + } + + public bool IsCollection + { + get { throw new NotSupportedException(); } + } + + public bool IsConstructible + { + get { throw new NotSupportedException(); } + } + + public bool IsDictionary + { + get { throw new NotSupportedException(); } + } + + public bool IsMarkupExtension + { + get { throw new NotSupportedException(); } + } + + public IXamlType ItemType + { + get { throw new NotSupportedException(); } + } + + public IXamlType KeyType + { + get { throw new NotSupportedException(); } + } + + public void RunInitializer() + { + throw new NotSupportedException(); + } + + public Type UnderlyingType + { + get { return _type; } + } + } +} diff --git a/GraphX.UAP.Controls/Models/XamlTypes/XamlTypeProvider.cs b/GraphX.UAP.Controls/Models/XamlTypes/XamlTypeProvider.cs new file mode 100644 index 00000000..42369dbc --- /dev/null +++ b/GraphX.UAP.Controls/Models/XamlTypes/XamlTypeProvider.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using Windows.UI.Xaml.Markup; + +namespace FancyDevelopment.WinRtPluginSystem.MVVM +{ + public class XamlTypeProvider + { + private static XamlTypeProvider _instance; + + public static XamlTypeProvider Instance + { + get + { + if(_instance == null) + _instance = new XamlTypeProvider(); + + return _instance; + } + } + + private IDictionary _xamlTypesByType; + private IDictionary _xamlTypesByName; + + public XamlTypeProvider() + { + _xamlTypesByName = new Dictionary(); + _xamlTypesByType = new Dictionary(); + } + + public void RegisterViewModelType(IXamlType baseType = null) where T : ViewModelBase, new () + { + IXamlType xamlType = new ViewModelXamlType(baseType); + AddType(typeof(T), xamlType); + } + + public void AddType(Type underlyingType, IXamlType xamlType) + { + _xamlTypesByType[underlyingType] = xamlType; + _xamlTypesByName[underlyingType.FullName] = xamlType; + } + + public IXamlType GetType(Type underlyingType) + { + if(_xamlTypesByType.ContainsKey(underlyingType)) + { + return _xamlTypesByType[underlyingType]; + } + + return CreateSystemType(underlyingType); + } + + public IXamlType GetType(string fullName) + { + if(_xamlTypesByName.ContainsKey(fullName)) + { + return _xamlTypesByName[fullName]; + } + + return null; + } + + private IXamlType CreateSystemType(Type systemType) + { + XamlSystemType xamlType = new XamlSystemType(systemType); + _xamlTypesByType[systemType] = xamlType; + return xamlType; + } + } +} diff --git a/GraphX.UAP.Controls/PrintHelper.cs b/GraphX.UAP.Controls/PrintHelper.cs new file mode 100644 index 00000000..981f7fad --- /dev/null +++ b/GraphX.UAP.Controls/PrintHelper.cs @@ -0,0 +1,142 @@ +using System; +using GraphX.PCL.Common.Enums; + +namespace GraphX.Controls +{ + internal static class PrintHelper + { + /// + /// Default image resolution + /// + public const double DEFAULT_DPI = 96d; + + //Set pixelformat of image. + /////!!! private static PixelFormat pixelFormat = PixelFormats.Pbgra32; + + /// + /// Method exports the GraphArea to an png image. + /// + /// GraphArea control + /// Image destination path + /// Optional image DPI parameter + /// Optional image quality parameter (for some formats like JPEG) + public static void ExportToImage(GraphAreaBase surface, Uri path, ImageType itype, bool useZoomControlSurface = false, double imgdpi = DEFAULT_DPI, int imgQuality = 100) + { + //TODO + //Create a render bitmap and push the surface to it + /*Visual vis = surface; + if (useZoomControlSurface) + { + if (surface.Parent != null && surface.Parent is IZoomControl) + vis = (surface.Parent as IZoomControl).PresenterVisual; + else if(surface.Parent!=null && surface.Parent is FrameworkElement && (surface.Parent as FrameworkElement).Parent is IZoomControl) + vis = ((surface.Parent as FrameworkElement).Parent as IZoomControl).PresenterVisual; + } + var renderBitmap = + new RenderTargetBitmap( + //(int)surface.ActualWidth, + //(int)surface.ActualHeight, + (int)((vis as UIElement).DesiredSize.Width * (imgdpi / DefaultDPI) + 100), + (int)((vis as UIElement).DesiredSize.Height * (imgdpi / DefaultDPI) + 100), + imgdpi, + imgdpi, + pixelFormat); + + //Render the graphlayout onto the bitmap. + renderBitmap.Render(vis); + + + //Create a file stream for saving image + using (FileStream outStream = new FileStream(path.LocalPath, FileMode.Create)) + { + //Use png encoder for our data + BitmapEncoder encoder; + switch (itype) + { + case ImageType.PNG: encoder = new PngBitmapEncoder(); + break; + case ImageType.JPEG: encoder = new JpegBitmapEncoder() { QualityLevel = imgQuality }; + break; + case ImageType.BMP: encoder = new BmpBitmapEncoder(); + break; + case ImageType.GIF: encoder = new GifBitmapEncoder(); + break; + case ImageType.TIFF: encoder = new TiffBitmapEncoder(); + break; + default: throw new GX_InvalidDataException("ExportToImage() -> Unknown output image format specified!"); + } + + //Push the rendered bitmap to it + encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); + //Save the data to the stream + encoder.Save(outStream); + }*/ + } + + + public static void ShowPrintPreview(GraphAreaBase surface, string description = "") + { + //TODO + /* try + { + var printDialog = new PrintDialog(); + if (printDialog.ShowDialog() == true) + { + printDialog.PrintVisual(surface, description); + } + } + catch (Exception ex) + { + new MessageDialog("Unexpected exception occured while trying to acces default printer. Please ensure that default printer is installed in your OS!").Show(); + }*/ + } + + /*public static Bitmap RenderTargetBitmapToBitmap(RenderTargetBitmap source) + { + using (MemoryStream outStream = new MemoryStream()) + { + //Use png encoder for our data + PngBitmapEncoder encoder = new PngBitmapEncoder(); + + //Push the rendered bitmap to it + encoder.Frames.Add(BitmapFrame.Create(source)); + + //Save the data to the stream + encoder.Save(outStream); + return new Bitmap(outStream); + } + }*/ + + /* public static RenderTargetBitmap RenderTargetBitmap(GraphAreaBase surface, bool useZoomControlSurface, double imgdpi) + { + Visual vis = surface; + if (useZoomControlSurface) + { + if (surface.Parent != null && surface.Parent is IZoomControl) + vis = (surface.Parent as IZoomControl).PresenterVisual; + else if (surface.Parent != null && surface.Parent is FrameworkElement && + (surface.Parent as FrameworkElement).Parent is IZoomControl) + vis = ((surface.Parent as FrameworkElement).Parent as IZoomControl).PresenterVisual; + } + var renderBitmap = + new RenderTargetBitmap( + //(int)surface.ActualWidth, + //(int)surface.ActualHeight, + (int)((vis as UIElement).DesiredSize.Width * (imgdpi / 96) + 100), + (int)((vis as UIElement).DesiredSize.Height * (imgdpi / 96) + 100), + imgdpi, + imgdpi, + pixelFormat); + + vis.SetValue(Panel.BackgroundProperty, System.Windows.Media.Brushes.White); + //Render the graphlayout onto the bitmap. + renderBitmap.Render(vis); + + return renderBitmap; + + }*/ + + + + } +} diff --git a/GraphX.UAP.Controls/Properties/AssemblyInfo.cs b/GraphX.UAP.Controls/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..3f26bb70 --- /dev/null +++ b/GraphX.UAP.Controls/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GraphX.UAP.Controls")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("GraphX.UAP.Controls")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/GraphX.UAP.Controls/Properties/GraphX.UAP.Controls.rd.xml b/GraphX.UAP.Controls/Properties/GraphX.UAP.Controls.rd.xml new file mode 100644 index 00000000..efa140cc --- /dev/null +++ b/GraphX.UAP.Controls/Properties/GraphX.UAP.Controls.rd.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/GraphX.UAP.Controls/Themes/Generic.xaml b/GraphX.UAP.Controls/Themes/Generic.xaml new file mode 100644 index 00000000..cdcbc7ad --- /dev/null +++ b/GraphX.UAP.Controls/Themes/Generic.xaml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GraphX.UAP.Controls/uap_graphx.controls.pfx b/GraphX.UAP.Controls/uap_graphx.controls.pfx new file mode 100644 index 00000000..77650268 Binary files /dev/null and b/GraphX.UAP.Controls/uap_graphx.controls.pfx differ