├── .config └── dotnet-tools.json ├── .gitignore ├── Assets ├── Font │ ├── Read Me.txt │ ├── demo-files │ │ ├── demo.css │ │ └── demo.js │ ├── demo.html │ ├── fonts │ │ ├── icomoon.eot │ │ ├── icomoon.svg │ │ ├── icomoon.ttf │ │ └── icomoon.woff │ ├── selection.json │ └── style.css ├── Gifs │ ├── css_add_only.gif │ ├── css_hot_reload.gif │ ├── playground_animations_ios.gif │ ├── playground_battle_test_ios.gif │ ├── playground_build_gradient_ios.gif │ ├── playground_gallery_ios.gif │ └── playground_paste_css_ios.gif ├── Images │ ├── clip_mode_exclude.png │ ├── clip_mode_include.png │ ├── home_large.png │ ├── home_small.png │ ├── mask_collection.png │ ├── mask_ellipse.png │ ├── mask_path.png │ ├── mask_rectangle.png │ ├── mask_text.png │ ├── masks.png │ ├── screens_large.png │ └── screens_small.png ├── PartOfRepeatedAngularGradient.png ├── RepeatedAngularGradient.png └── icon.png ├── Directory.Build.props ├── LICENSE ├── MagicGradients.Graphics.sln ├── MagicGradients.sln ├── README.md ├── Scripts ├── PublishNuGetsLocal.ps1 ├── PublishNuGetsLocal.sh ├── UpdateNuGetVersion.ps1 └── UpdateNuGetVersion.sh ├── build.cake ├── docs └── README.md ├── global.json ├── samples ├── GradientsApp │ ├── GradientsApp.Android │ │ ├── App.cs │ │ ├── GradientsApp.Android.csproj │ │ ├── Infrastructure │ │ │ ├── AppFragment.cs │ │ │ ├── BindableFragment.cs │ │ │ ├── IFragmentLoader.cs │ │ │ ├── IToolbarManager.cs │ │ │ └── NavigationService.cs │ │ ├── MainActivity.cs │ │ ├── Markup │ │ │ └── ViewExtensions.cs │ │ ├── Properties │ │ │ ├── AndroidManifest.xml │ │ │ └── AssemblyInfo.cs │ │ ├── Resources │ │ │ ├── Resource.designer.cs │ │ │ ├── layout │ │ │ │ ├── activity_main.xml │ │ │ │ ├── categories_fragment.xml │ │ │ │ ├── category_item.xml │ │ │ │ ├── home_fragment.xml │ │ │ │ ├── linear_fragment.xml │ │ │ │ ├── masks_fragment.xml │ │ │ │ └── radial_fragment.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_foreground.png │ │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ │ ├── colors.xml │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ └── Views │ │ │ ├── Adapters │ │ │ ├── CategoriesAdapter.cs │ │ │ └── CategoryViewHolder.cs │ │ │ ├── CategoriesFragment.cs │ │ │ ├── HomeFragment.cs │ │ │ ├── LinearFragment.cs │ │ │ ├── MarkupFragment.cs │ │ │ ├── MasksFragment.cs │ │ │ └── RadialFragment.cs │ ├── GradientsApp.Forms.Android │ │ ├── GradientsApp.Forms.Android.csproj │ │ ├── MainActivity.cs │ │ ├── Properties │ │ │ ├── AndroidManifest.xml │ │ │ └── AssemblyInfo.cs │ │ └── Resources │ │ │ ├── Resource.designer.cs │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── icon.xml │ │ │ └── icon_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ │ ├── mipmap-mdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ ├── GradientsApp.Forms.iOS │ │ ├── AppDelegate.cs │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon1024.png │ │ │ │ ├── Icon120.png │ │ │ │ ├── Icon152.png │ │ │ │ ├── Icon167.png │ │ │ │ ├── Icon180.png │ │ │ │ ├── Icon20.png │ │ │ │ ├── Icon29.png │ │ │ │ ├── Icon40.png │ │ │ │ ├── Icon58.png │ │ │ │ ├── Icon60.png │ │ │ │ ├── Icon76.png │ │ │ │ ├── Icon80.png │ │ │ │ └── Icon87.png │ │ ├── Entitlements.plist │ │ ├── GradientsApp.Forms.iOS.csproj │ │ ├── Info.plist │ │ ├── Main.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ └── Resources │ │ │ ├── Default-568h@2x.png │ │ │ ├── Default-Portrait.png │ │ │ ├── Default-Portrait@2x.png │ │ │ ├── Default.png │ │ │ ├── Default@2x.png │ │ │ └── LaunchScreen.storyboard │ ├── GradientsApp.Forms │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── AssemblyInfo.cs │ │ ├── FormsApp.cs │ │ ├── GradientsApp.Forms.csproj │ │ ├── Infrastructure │ │ │ ├── NavigateExtension.cs │ │ │ ├── NavigationService.cs │ │ │ └── ViewModelLocator.cs │ │ ├── Pages │ │ │ ├── AnimationsPage.xaml │ │ │ ├── AnimationsPage.xaml.cs │ │ │ ├── CategoriesPage.xaml │ │ │ ├── CategoriesPage.xaml.cs │ │ │ ├── GalleryPage.xaml │ │ │ ├── GalleryPage.xaml.cs │ │ │ ├── GradientPage.xaml │ │ │ ├── GradientPage.xaml.cs │ │ │ ├── HomePage.xaml │ │ │ ├── HomePage.xaml.cs │ │ │ ├── LinearPage.xaml │ │ │ ├── LinearPage.xaml.cs │ │ │ ├── MarkupPage.cs │ │ │ ├── MasksPage.xaml │ │ │ ├── MasksPage.xaml.cs │ │ │ ├── RadialPage.xaml │ │ │ └── RadialPage.xaml.cs │ │ └── Styles.css │ ├── GradientsApp.iOS │ │ ├── App.cs │ │ ├── AppDelegate.cs │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon1024.png │ │ │ │ ├── Icon120.png │ │ │ │ ├── Icon152.png │ │ │ │ ├── Icon167.png │ │ │ │ ├── Icon180.png │ │ │ │ ├── Icon20.png │ │ │ │ ├── Icon29.png │ │ │ │ ├── Icon40.png │ │ │ │ ├── Icon58.png │ │ │ │ ├── Icon60.png │ │ │ │ ├── Icon76.png │ │ │ │ ├── Icon80.png │ │ │ │ └── Icon87.png │ │ ├── Entitlements.plist │ │ ├── GradientsApp.iOS.csproj │ │ ├── Info.plist │ │ ├── Infrastructure │ │ │ ├── BindableViewController.cs │ │ │ └── NavigationService.cs │ │ ├── LaunchScreen.storyboard │ │ ├── Main.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── Resources │ │ │ └── LaunchScreen.xib │ │ ├── SceneDelegate.cs │ │ └── Views │ │ │ ├── HomeViewController.cs │ │ │ └── LinearViewController.cs │ └── GradientsApp │ │ ├── AppRoutes.cs │ │ ├── AppSetup.cs │ │ ├── GradientsApp.csproj │ │ ├── Infrastructure │ │ ├── IBindableView.cs │ │ ├── INavigationAware.cs │ │ ├── INavigationService.cs │ │ └── NavigationViewFactory.cs │ │ ├── Models │ │ ├── CategoryItem.cs │ │ └── GalleryItem.cs │ │ └── ViewModels │ │ ├── CategoriesViewModel.cs │ │ ├── GalleryViewModel.cs │ │ ├── GradientViewModel.cs │ │ ├── HomeViewModel.cs │ │ └── LinearViewModel.cs ├── MagicCrawler │ ├── MagicCrawler.sln │ └── MagicCrawler │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── AssemblyInfo.cs │ │ ├── Configuration.json │ │ ├── MagicCrawler.csproj │ │ ├── Models │ │ ├── Category.cs │ │ ├── Collection.cs │ │ ├── Configuration.cs │ │ ├── Gradient.cs │ │ ├── JobItem.cs │ │ └── Metadata.cs │ │ ├── Services │ │ ├── Crawler.cs │ │ ├── HtmlLoader.cs │ │ ├── HtmlParser.cs │ │ └── Storage.cs │ │ ├── ViewModels │ │ └── MainViewModel.cs │ │ └── Views │ │ ├── MainWindow.xaml │ │ └── MainWindow.xaml.cs └── Playground │ ├── Playground.Android │ ├── MainActivity.cs │ ├── Playground.Android.csproj │ ├── Properties │ │ ├── AndroidManifest.xml │ │ └── AssemblyInfo.cs │ ├── Resources │ │ ├── Resource.designer.cs │ │ ├── drawable-hdpi │ │ │ └── mg.png │ │ ├── drawable-ldpi │ │ │ └── mg.png │ │ ├── drawable-mdpi │ │ │ └── mg.png │ │ ├── drawable-xhdpi │ │ │ └── mg.png │ │ ├── drawable-xxhdpi │ │ │ └── mg.png │ │ ├── drawable-xxxhdpi │ │ │ └── mg.png │ │ ├── drawable │ │ │ ├── splash_screen.xml │ │ │ ├── tab_about.png │ │ │ ├── tab_feed.png │ │ │ └── xamarin_logo.png │ │ ├── layout │ │ │ ├── Tabbar.xml │ │ │ └── Toolbar.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── icon.xml │ │ │ └── icon_round.xml │ │ ├── mipmap-hdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── icon.png │ │ │ └── launcher_foreground.png │ │ └── values │ │ │ ├── colors.xml │ │ │ └── styles.xml │ └── appcenter-post-clone.sh │ ├── Playground.Data │ ├── Infrastructure │ │ ├── DatabaseProvider.cs │ │ ├── DatabaseUpdater.cs │ │ ├── IDatabaseProvider.cs │ │ └── IDatabaseUpdater.cs │ ├── Models │ │ ├── Category.cs │ │ ├── Gradient.cs │ │ ├── Metadata.cs │ │ └── Theme.cs │ ├── Playground.Data.csproj │ ├── Repositories │ │ ├── CategoryRepository.cs │ │ ├── DocumentRepository.cs │ │ ├── GradientRepository.cs │ │ ├── ICanUpdateMyself.cs │ │ ├── ICategoryRepository.cs │ │ ├── IDocumentRepository.cs │ │ └── IGradientRepository.cs │ └── Resources │ │ ├── Angular.json │ │ ├── BackGammon.json │ │ ├── BasicGrid.json │ │ ├── Burst.json │ │ ├── CarbonFiber.json │ │ ├── Categories.json │ │ ├── Checkered.json │ │ ├── ComplexCircles.json │ │ ├── ComplexGrid.json │ │ ├── ComplexPatterns.json │ │ ├── ComplexRepStripes.json │ │ ├── ComplexShapes.json │ │ ├── DarkBg.json │ │ ├── Diamond.json │ │ ├── Fracture.json │ │ ├── FutureStripes.json │ │ ├── Gingham.json │ │ ├── GinghamColored.json │ │ ├── LensFlare.json │ │ ├── LightBg.json │ │ ├── Metadata.json │ │ ├── NewRetro.json │ │ ├── RadialStripes.json │ │ ├── RainbowStandard.json │ │ ├── RepStripes.json │ │ ├── Retro.json │ │ ├── SimpleAngular.json │ │ ├── SimpleCircles.json │ │ ├── SimplePatterns.json │ │ ├── StainedGlass.json │ │ ├── Standard.json │ │ ├── StandardAsymmetrical.json │ │ ├── StandardCircle.json │ │ ├── StandardTexture.json │ │ ├── Stripes.json │ │ ├── SubtleGrid.json │ │ ├── Texture.json │ │ └── Themes.json │ ├── Playground.UWP │ ├── App.xaml │ ├── App.xaml.cs │ ├── Assets │ │ ├── LargeTile.scale-100.png │ │ ├── LargeTile.scale-200.png │ │ ├── LargeTile.scale-400.png │ │ ├── SmallTile.scale-100.png │ │ ├── SmallTile.scale-200.png │ │ ├── SmallTile.scale-400.png │ │ ├── SplashScreen.scale-100.png │ │ ├── SplashScreen.scale-200.png │ │ ├── SplashScreen.scale-400.png │ │ ├── Square150x150Logo.scale-100.png │ │ ├── Square150x150Logo.scale-200.png │ │ ├── Square150x150Logo.scale-400.png │ │ ├── Square44x44Logo.altform-unplated_targetsize-16.png │ │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ │ ├── Square44x44Logo.altform-unplated_targetsize-48.png │ │ ├── Square44x44Logo.scale-100.png │ │ ├── Square44x44Logo.scale-200.png │ │ ├── Square44x44Logo.scale-400.png │ │ ├── Square44x44Logo.targetsize-16.png │ │ ├── Square44x44Logo.targetsize-256.png │ │ ├── Square44x44Logo.targetsize-48.png │ │ ├── StoreLogo.scale-100.png │ │ ├── StoreLogo.scale-200.png │ │ ├── StoreLogo.scale-400.png │ │ ├── Wide310x150Logo.scale-100.png │ │ ├── Wide310x150Logo.scale-200.png │ │ └── Wide310x150Logo.scale-400.png │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Package.appxmanifest │ ├── Playground.UWP.csproj │ └── Properties │ │ ├── AssemblyInfo.cs │ │ └── Default.rd.xml │ ├── Playground.iOS │ ├── AppDelegate.cs │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon1024.png │ │ │ ├── Icon120.png │ │ │ ├── Icon152.png │ │ │ ├── Icon167.png │ │ │ ├── Icon180.png │ │ │ ├── Icon20.png │ │ │ ├── Icon29.png │ │ │ ├── Icon40.png │ │ │ ├── Icon58.png │ │ │ ├── Icon60.png │ │ │ ├── Icon76.png │ │ │ ├── Icon80.png │ │ │ └── Icon87.png │ │ ├── Contents.json │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── mg_splash-1.png │ │ │ ├── mg_splash-2.png │ │ │ └── mg_splash.png │ ├── Entitlements.plist │ ├── Info.plist │ ├── Main.cs │ ├── Playground.iOS.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Resources │ │ └── LaunchScreen.storyboard │ └── appcenter-post-clone.sh │ └── Playground │ ├── App.xaml │ ├── App.xaml.cs │ ├── AppSetup.cs │ ├── AppShell.xaml │ ├── AppShell.xaml.cs │ ├── Controls │ ├── ActionMenu │ │ ├── ActionItem.cs │ │ ├── ActionMenu.xaml │ │ └── ActionMenu.xaml.cs │ ├── AnimationClip.xaml │ ├── AnimationClip.xaml.cs │ ├── CheckeredView.cs │ ├── ColorEditor.xaml │ ├── ColorEditor.xaml.cs │ ├── ColorView.cs │ ├── CornersEditor.xaml │ ├── CornersEditor.xaml.cs │ ├── DimensionsEditor.xaml │ ├── DimensionsEditor.xaml.cs │ ├── EnumSwitch.xaml │ ├── EnumSwitch.xaml.cs │ ├── MenuSection.xaml │ ├── MenuSection.xaml.cs │ └── RadialMenu │ │ ├── RadialMenu.xaml │ │ ├── RadialMenu.xaml.cs │ │ ├── RadialMenuCircle.cs │ │ └── RadialMenuItem.cs │ ├── Converters │ ├── GradientIconConverter.cs │ ├── NegativeBoolConverter.cs │ ├── OffsetToPercenttConverter.cs │ ├── OffsetToRectConverter.cs │ ├── TabBoolConverter.cs │ └── TabEnumConverter.cs │ ├── Extensions │ ├── AdaptiveUtils.cs │ ├── ColorExtensions.cs │ ├── ColorUtils.cs │ ├── SafeAreaExtensions.cs │ └── VisualElementExtensions.cs │ ├── Features │ ├── Animation │ │ ├── AnimationItem.cs │ │ ├── AnimationsPage.xaml │ │ ├── AnimationsPage.xaml.cs │ │ └── AnimationsViewModel.cs │ ├── BattleTest │ │ ├── BattleItem.cs │ │ ├── BattleItemService.cs │ │ ├── BattleTestPage.xaml │ │ ├── BattleTestPage.xaml.cs │ │ └── BattleTestViewModel.cs │ ├── CssPreviewer │ │ ├── CssPreviewerBase.cs │ │ ├── CssPreviewerPage.xaml │ │ ├── CssPreviewerPage.xaml.cs │ │ ├── CssPreviewerViewModel.cs │ │ ├── CssSnippet.cs │ │ └── CssSnippetProvider.cs │ ├── Editor │ │ ├── BackgroundTab.xaml │ │ ├── BackgroundTab.xaml.cs │ │ ├── ColorInspector.xaml │ │ ├── ColorInspector.xaml.cs │ │ ├── ColorSpectrumGradient.cs │ │ ├── GradientEditorPage.xaml │ │ ├── GradientEditorPage.xaml.cs │ │ ├── GradientEditorViewModel.cs │ │ ├── Handlers │ │ │ ├── LinearHandler.cs │ │ │ ├── MaskHandler.cs │ │ │ ├── MaskTemplateSelector.cs │ │ │ └── RadialHandler.cs │ │ ├── MasksTab.xaml │ │ ├── MasksTab.xaml.cs │ │ ├── PropertiesTab.xaml │ │ ├── PropertiesTab.xaml.cs │ │ └── ShapePicker.cs │ ├── Gallery │ │ ├── GalleryCategoriesPage.xaml │ │ ├── GalleryCategoriesPage.xaml.cs │ │ ├── GalleryCategoriesViewModel.cs │ │ ├── GalleryListPage.xaml │ │ ├── GalleryListPage.xaml.cs │ │ ├── GalleryListViewModel.cs │ │ ├── Models │ │ │ ├── CategoryGroup.cs │ │ │ ├── CategoryItem.cs │ │ │ ├── GradientItem.cs │ │ │ └── ThemeItem.cs │ │ └── Services │ │ │ ├── CategoryService.cs │ │ │ ├── GalleryService.cs │ │ │ ├── ICategoryService.cs │ │ │ └── IGalleryService.cs │ ├── Home │ │ ├── HomePage.css │ │ ├── HomePage.xaml │ │ ├── HomePage.xaml.cs │ │ └── HomeViewModel.cs │ ├── Linear │ │ ├── LinearSamplesPage.css │ │ ├── LinearSamplesPage.xaml │ │ ├── LinearSamplesPage.xaml.cs │ │ └── LinearSamplesViewModel.cs │ ├── Masks │ │ ├── MasksPage.css │ │ ├── MasksPage.xaml │ │ ├── MasksPage.xaml.cs │ │ └── MasksViewModel.cs │ ├── Radial │ │ ├── RadialSamplesPage.css │ │ ├── RadialSamplesPage.xaml │ │ └── RadialSamplesPage.xaml.cs │ └── Share │ │ ├── ExportData.cs │ │ ├── GradientExporter.cs │ │ ├── IGradientExporter.cs │ │ ├── IShareService.cs │ │ └── ShareService.cs │ ├── Interactivity │ ├── BindableBehavior.cs │ ├── RotateTriggerAction.cs │ ├── RotateTriggerExtension.cs │ └── TapBehavior.cs │ ├── Playground.csproj │ ├── Properties │ └── AssemblyInfo.cs │ ├── Resources │ └── Fonts │ │ ├── IcoMoon.ttf │ │ ├── IcoMoonExtension.cs │ │ └── IcoMoonGlyph.cs │ ├── Styles │ └── Theme.xaml │ └── ViewModels │ ├── ObservableObject.cs │ └── ViewModelLocator.cs ├── src ├── MagicGradients.Core │ ├── AssemblyInfo.cs │ ├── Builder │ │ ├── CssGradientBuilder.cs │ │ ├── GradientBuilder.cs │ │ ├── GradientBuilderExtensions.cs │ │ ├── GradientFactory.cs │ │ ├── IChildBuilder.cs │ │ ├── IGradientFactory.cs │ │ ├── LinearGradientBuilder.cs │ │ ├── RadialGradientBuilder.cs │ │ └── StopsBuilder.cs │ ├── Converters │ │ ├── BackgroundRepeatTypeConverter.cs │ │ ├── CornersTypeConverter.cs │ │ ├── CssGradientSourceTypeConverter.cs │ │ ├── DimensionsTypeConverter.cs │ │ ├── FontAttributesTypeConverter.cs │ │ ├── OffsetTypeConverter.cs │ │ └── PositionTypeConverter.cs │ ├── Corners.cs │ ├── CssGradientSource.cs │ ├── Dimensions.cs │ ├── Drawing │ │ ├── DrawContext.cs │ │ ├── GradientDrawable.cs │ │ ├── GradientGeometry.cs │ │ ├── LinearGradientGeometry.cs │ │ ├── LinearGradientPaintEx.cs │ │ ├── MaskDrawable.cs │ │ ├── MaskLayout.cs │ │ ├── RadialGradientGeometry.cs │ │ └── RadialGradientPaintEx.cs │ ├── GlobalSetup.cs │ ├── Gradient.cs │ ├── GradientEnums.cs │ ├── GradientMath.cs │ ├── GradientView.cs │ ├── IGradient.cs │ ├── IGradientControl.cs │ ├── IGradientSource.cs │ ├── IGradientVisualElement.cs │ ├── MagicGradients.Core.csproj │ ├── Markup │ │ ├── GradientExtensions.cs │ │ ├── MaskExtensions.cs │ │ └── ViewExtensions.cs │ ├── Masks │ │ ├── EllipseMaskPainter.cs │ │ ├── GradientMask.cs │ │ ├── GradientMaskEnum.cs │ │ ├── IGradientMask.cs │ │ ├── PathMaskPainter.cs │ │ ├── RectangleMaskPainter.cs │ │ └── TextMaskPainter.cs │ ├── Offset.cs │ ├── Parser │ │ ├── CssGradientParser.cs │ │ ├── CssReader.cs │ │ ├── CssToken.cs │ │ ├── TokenDefinitions │ │ │ ├── ColorChannelDefinition.cs │ │ │ ├── ColorDefinition.cs │ │ │ ├── ColorHexDefinition.cs │ │ │ ├── ColorNameDefinition.cs │ │ │ ├── ITokenDefinition.cs │ │ │ ├── LinearGradientDefinition.cs │ │ │ └── RadialGradientDefinition.cs │ │ └── Vector2.cs │ ├── Platform │ │ ├── AttributeReader.Android.cs │ │ ├── GradientView.Android.cs │ │ ├── GradientView.Mac.cs │ │ └── GradientView.iOS.cs │ ├── Position.cs │ ├── PrimitivesExtensions.cs │ ├── Resources │ │ └── values │ │ │ └── attrs.xml │ └── TextEnums.cs ├── MagicGradients.Forms.Skia │ ├── AssemblyInfo.cs │ ├── Drawing │ │ └── SkiaCanvasEx.cs │ ├── GlobalSetupExtensions.cs │ ├── MagicGradients.Forms.Skia.csproj │ ├── Masks │ │ ├── SkiaEllipseMaskPainter.cs │ │ ├── SkiaPathMaskPainter.cs │ │ ├── SkiaRectangleMaskPainter.cs │ │ └── SkiaTextMaskPainter.cs │ ├── SkiaExtensions.cs │ ├── SkiaGradientGLView.cs │ └── SkiaGradientView.cs ├── MagicGradients.Forms.SkiaViews │ ├── CanvasLock.cs │ ├── Drawing │ │ ├── DrawContext.cs │ │ ├── GradientDrawable.cs │ │ ├── GradientPainter.cs │ │ ├── LinearGradientPainter.cs │ │ └── RadialGradientPainter.cs │ ├── GradientGLView.cs │ ├── GradientView.cs │ ├── MagicGradients.Forms.SkiaViews.csproj │ ├── Masks │ │ ├── EllipseMaskPainter.cs │ │ ├── GradientMaskPainter.cs │ │ ├── PathMaskPainter.cs │ │ ├── RectangleMaskPainter.cs │ │ └── TextMaskPainter.cs │ └── SkiaExtensions.cs ├── MagicGradients.Forms │ ├── Animation │ │ ├── ITweener.cs │ │ ├── Interactivity │ │ │ ├── AnimationBehavior.cs │ │ │ ├── AnimationTriggerExtension.cs │ │ │ ├── BeginAnimation.cs │ │ │ └── EndAnimation.cs │ │ ├── KeyFrame.cs │ │ ├── Library │ │ │ ├── ColorAnimation.cs │ │ │ ├── DimensionsAnimation.cs │ │ │ ├── DoubleAnimation.cs │ │ │ ├── IntegerAnimation.cs │ │ │ ├── OffsetAnimation.cs │ │ │ ├── PointAnimation.cs │ │ │ └── ThicknessAnimation.cs │ │ ├── PropertyAnimation.cs │ │ ├── PropertyAnimationUsingKeyFrames.cs │ │ ├── RepeatBehavior.cs │ │ ├── RepeatBehaviorTypeConverter.cs │ │ ├── Storyboard.cs │ │ └── Timeline.cs │ ├── AssemblyInfo.cs │ ├── Builder │ │ └── XamlGradientFactory.cs │ ├── CssGradient.cs │ ├── GlobalSetupExtensions.cs │ ├── Gradient.cs │ ├── GradientCollection.cs │ ├── GradientControl.cs │ ├── GradientElement.cs │ ├── GradientElements.cs │ ├── GradientStop.cs │ ├── GradientView.cs │ ├── GraphicsView.cs │ ├── LinearGradient.cs │ ├── MagicGradients.Forms.csproj │ ├── Masks │ │ ├── EllipseMask.cs │ │ ├── GradientMask.cs │ │ ├── MarkupExtensions │ │ │ ├── EllipseExtension.cs │ │ │ ├── MaskExtension.cs │ │ │ ├── PathExtension.cs │ │ │ ├── RectangleExtension.cs │ │ │ └── TextExtension.cs │ │ ├── MaskCollection.cs │ │ ├── PathMask.cs │ │ ├── RectangleMask.cs │ │ └── TextMask.cs │ ├── RadialGradient.cs │ ├── Renderer │ │ ├── GraphicsViewRenderer.Android.cs │ │ ├── GraphicsViewRenderer.Mac.cs │ │ └── GraphicsViewRenderer.iOS.cs │ ├── StyleSheets.cs │ └── ViewExtensions.cs ├── MagicGradients.Toolkit │ ├── Build │ │ ├── MagicGradients.Toolkit.targets │ │ └── PreserveMagicToolkit.cs │ ├── Controls │ │ ├── MagicButton.xaml │ │ ├── MagicButton.xaml.cs │ │ ├── TextContent.cs │ │ └── TextContentTypeConverter.cs │ ├── Initializer.cs │ ├── MagicGradients.Toolkit.csproj │ └── Properties │ │ ├── AssemblyInfo.cs │ │ └── PreserveAssemblyAttribute.cs ├── MagicGradients │ ├── Animation │ │ ├── Interactivity │ │ │ ├── AnimateBehavior.cs │ │ │ ├── AnimationTriggerExtension.cs │ │ │ ├── BeginAnimation.cs │ │ │ └── EndAnimation.cs │ │ ├── KeyFrame.cs │ │ ├── Library │ │ │ ├── ColorAnimation.cs │ │ │ ├── DimensionsAnimation.cs │ │ │ ├── DoubleAnimation.cs │ │ │ ├── IntegerAnimation.cs │ │ │ ├── OffsetAnimation.cs │ │ │ ├── PointAnimation.cs │ │ │ └── ThicknessAnimation.cs │ │ ├── PropertyAnimation.cs │ │ ├── PropertyAnimationUsingKeyFrames.cs │ │ ├── RepeatBehavior.cs │ │ ├── RepeatBehaviorTypeConverter.cs │ │ ├── Storyboard.cs │ │ ├── Timeline.cs │ │ └── Tween │ │ │ ├── ColorTweener.cs │ │ │ ├── DimensionsTweener.cs │ │ │ ├── DoubleTweener.cs │ │ │ ├── ITweener.cs │ │ │ ├── IntegerTweener.cs │ │ │ ├── OffsetTweener.cs │ │ │ ├── PointTweener.cs │ │ │ └── ThicknessTweener.cs │ ├── Build │ │ ├── MagicGradients.targets │ │ └── PreserveMagicGradients.cs │ ├── Builder │ │ ├── CssGradientBuilder.cs │ │ ├── DimenOptions.cs │ │ ├── GradientBuilder.cs │ │ ├── GradientBuilderExtensions.cs │ │ ├── IChildBuilder.cs │ │ ├── LinearGradientBuilder.cs │ │ ├── RadialGradientBuilder.cs │ │ ├── StopsBuilder.cs │ │ └── StopsFactory.cs │ ├── CssGradientSource.cs │ ├── Dimensions.cs │ ├── Gradient.cs │ ├── GradientCollection.cs │ ├── GradientControl.cs │ ├── GradientElement.cs │ ├── GradientElements.cs │ ├── GradientEnums.cs │ ├── GradientGLView.cs │ ├── GradientMath.cs │ ├── GradientStop.cs │ ├── GradientView.cs │ ├── IGradientControl.cs │ ├── IGradientSource.cs │ ├── IGradientVisualElement.cs │ ├── LinearGradient.cs │ ├── MagicGradients.csproj │ ├── MagicGradients.csproj.DotSettings │ ├── Masks │ │ ├── CanvasLock.cs │ │ ├── Corners.cs │ │ ├── CornersTypeConverter.cs │ │ ├── EllipseMask.cs │ │ ├── GradientMask.cs │ │ ├── GradientMaskEnum.cs │ │ ├── MarkupExtensions │ │ │ ├── EllipseExtension.cs │ │ │ ├── MaskExtension.cs │ │ │ ├── PathExtension.cs │ │ │ ├── RectangleExtension.cs │ │ │ └── TextExtension.cs │ │ ├── MaskCollection.cs │ │ ├── PathMask.cs │ │ ├── RectangleMask.cs │ │ └── TextMask.cs │ ├── Offset.cs │ ├── Parser │ │ ├── CssGradientParser.cs │ │ ├── CssReader.cs │ │ ├── CssToken.cs │ │ ├── TokenDefinitions │ │ │ ├── ColorChannelDefinition.cs │ │ │ ├── ColorDefinition.cs │ │ │ ├── ColorHexDefinition.cs │ │ │ ├── ColorNameDefinition.cs │ │ │ ├── ITokenDefinition.cs │ │ │ ├── LinearGradientDefinition.cs │ │ │ └── RadialGradientDefinition.cs │ │ └── Vector2.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── PreserveAssemblyAttribute.cs │ ├── RadialGradient.cs │ ├── Renderers │ │ ├── GradientRenderer.cs │ │ ├── IGradientShader.cs │ │ ├── LinearGradientShader.cs │ │ ├── LinearGradientShaderLegacy.cs │ │ ├── RadialGradientShader.cs │ │ └── RenderContext.cs │ ├── StringExtensions.cs │ ├── StyleSheets.cs │ └── Xaml │ │ ├── BackgroundRepeatTypeConverter.cs │ │ ├── CssGradientSourceTypeConverter.cs │ │ ├── DimensionsTypeConverter.cs │ │ └── OffsetTypeConverter.cs └── MultiTargeting.targets └── tests ├── MagicGradients.Benchmark ├── MagicGradients.Benchmark.csproj └── Program.cs ├── MagicGradients.Core.Tests ├── Builder │ ├── GradientBuilderTestCases.cs │ └── GradientBuilderTests.cs ├── Converters │ ├── BackgroundRepeatTypeConverterTests.cs │ ├── DimensionsTypeConverterTests.cs │ ├── OffsetTypeConverterTests.cs │ ├── PositionTypeConverterTests.cs │ └── TypeConverterTests.cs ├── DimensionsTests.cs ├── MagicGradients.Core.Tests.csproj ├── Markup │ └── MarkupTests.cs ├── OffsetTests.cs └── PositionTests.cs └── MagicGradients.Tests ├── Animation └── RepeatBehaviorTypeConverterTests.cs ├── Builder ├── GradientBuilderTestCases.cs └── GradientBuilderTests.cs ├── CssGradientSourceTests.cs ├── DimensionsTests.cs ├── FlagsHelperTests.cs ├── GradientTests.cs ├── MagicGradients.Tests.csproj ├── Mock ├── MockApplication.cs ├── MockDeserializer.cs ├── MockPlatformServices.cs ├── MockResourcesProvider.cs └── MockTicker.cs ├── OffsetTests.cs ├── Parser ├── CssGradientParserTests.cs ├── GradientsComplex.cs ├── GradientsLinear.cs ├── GradientsRadial.cs ├── GradientsWithoutOffsets.cs └── TokenDefinitions │ ├── ColorChannelDefinitionData.cs │ ├── ColorChannelDefinitionTests.cs │ ├── ColorHexDefinitionData.cs │ ├── ColorHexDefinitionTests.cs │ ├── ColorNameDefinitionData.cs │ ├── ColorNameDefinitionTests.cs │ ├── LinearGradientDefinitionData.cs │ ├── LinearGradientDefinitionTests.cs │ ├── RadialGradientDefinitionData.cs │ └── RadialGradientDefinitionTests.cs ├── StringExtensionsTests.cs └── Xaml ├── BackgroundRepeatTypeConverterTests.cs ├── DimensionsTypeConverterTests.cs ├── OffsetTypeConverterTests.cs └── TypeConverterTests.cs /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "cake.tool": { 6 | "version": "1.3.0", 7 | "commands": [ 8 | "dotnet-cake" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Assets/Font/Read Me.txt: -------------------------------------------------------------------------------- 1 | Open *demo.html* to see a list of all the glyphs in your font along with their codes/ligatures. 2 | 3 | To use the generated font in desktop programs, you can install the TTF font. In order to copy the character associated with each icon, refer to the text box at the bottom right corner of each glyph in demo.html. The character inside this text box may be invisible; but it can still be copied. See this guide for more info: https://icomoon.io/#docs/local-fonts 4 | 5 | You won't need any of the files located under the *demo-files* directory when including the generated font in your own projects. 6 | 7 | You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection. 8 | -------------------------------------------------------------------------------- /Assets/Font/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Font/fonts/icomoon.eot -------------------------------------------------------------------------------- /Assets/Font/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Font/fonts/icomoon.ttf -------------------------------------------------------------------------------- /Assets/Font/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Font/fonts/icomoon.woff -------------------------------------------------------------------------------- /Assets/Gifs/css_add_only.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Gifs/css_add_only.gif -------------------------------------------------------------------------------- /Assets/Gifs/css_hot_reload.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Gifs/css_hot_reload.gif -------------------------------------------------------------------------------- /Assets/Gifs/playground_animations_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Gifs/playground_animations_ios.gif -------------------------------------------------------------------------------- /Assets/Gifs/playground_battle_test_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Gifs/playground_battle_test_ios.gif -------------------------------------------------------------------------------- /Assets/Gifs/playground_build_gradient_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Gifs/playground_build_gradient_ios.gif -------------------------------------------------------------------------------- /Assets/Gifs/playground_gallery_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Gifs/playground_gallery_ios.gif -------------------------------------------------------------------------------- /Assets/Gifs/playground_paste_css_ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Gifs/playground_paste_css_ios.gif -------------------------------------------------------------------------------- /Assets/Images/clip_mode_exclude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/clip_mode_exclude.png -------------------------------------------------------------------------------- /Assets/Images/clip_mode_include.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/clip_mode_include.png -------------------------------------------------------------------------------- /Assets/Images/home_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/home_large.png -------------------------------------------------------------------------------- /Assets/Images/home_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/home_small.png -------------------------------------------------------------------------------- /Assets/Images/mask_collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/mask_collection.png -------------------------------------------------------------------------------- /Assets/Images/mask_ellipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/mask_ellipse.png -------------------------------------------------------------------------------- /Assets/Images/mask_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/mask_path.png -------------------------------------------------------------------------------- /Assets/Images/mask_rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/mask_rectangle.png -------------------------------------------------------------------------------- /Assets/Images/mask_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/mask_text.png -------------------------------------------------------------------------------- /Assets/Images/masks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/masks.png -------------------------------------------------------------------------------- /Assets/Images/screens_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/screens_large.png -------------------------------------------------------------------------------- /Assets/Images/screens_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/Images/screens_small.png -------------------------------------------------------------------------------- /Assets/PartOfRepeatedAngularGradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/PartOfRepeatedAngularGradient.png -------------------------------------------------------------------------------- /Assets/RepeatedAngularGradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/RepeatedAngularGradient.png -------------------------------------------------------------------------------- /Assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/Assets/icon.png -------------------------------------------------------------------------------- /Scripts/PublishNuGetsLocal.ps1: -------------------------------------------------------------------------------- 1 | Function Build-Solution{ 2 | param( 3 | [Parameter(Mandatory=$true)] 4 | [String] $Path 5 | ) 6 | process 7 | { 8 | $MsBuildExe = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\msbuild.exe' 9 | 10 | Write-Host "Building $($Path)" -foregroundcolor green 11 | & "$($MsBuildExe)" "$($Path)" /t:clean,restore,rebuild,pack /p:Configuration=Release /p:Platform="Any CPU" /m 12 | } 13 | } 14 | 15 | $NuGetPath = '..\src\MagicGradients\bin\**\Release\*.nupkg' 16 | 17 | Remove-Item $NuGetPath 18 | Build-Solution('..\src\MagicGradients\MagicGradients.csproj') 19 | 20 | Get-ChildItem -Path $NuGetPath -Recurse | Copy-Item -Destination 'C:\Packages' -------------------------------------------------------------------------------- /Scripts/PublishNuGetsLocal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | GREEN=`tput setaf 2` 4 | 5 | NuGetPath="../src/MagicGradients/bin/**/Release/*.nupkg" 6 | PackagesFolder="~/Packages" 7 | 8 | echo "${GREEN}Remove all nupkg's" 9 | rm $NuGetPath 10 | 11 | echo "Build NuGet & Copy for $1" 12 | nuget pack $1 -Build -Properties Configuration=Release -OutputDirectory ~/Packages 13 | 14 | echo "Completed." 15 | -------------------------------------------------------------------------------- /Scripts/UpdateNuGetVersion.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | GREEN=`tput setaf 2` 4 | 5 | Version=$1 6 | MagicGradients="../src/MagicGradients/MagicGradients.csproj" 7 | MagicGradientsToolkit="../src/MagicGradients.Toolkit/MagicGradients.Toolkit.csproj" 8 | 9 | echo "${GREEN}Set new $Version version for $MagicGradients" 10 | sed -i .tmp "s|.*|$Version<\/Version>|" $MagicGradients; 11 | rm -f "$magicGradients.tmp" 12 | 13 | echo "Set new $Version version for $MagicGradientsToolkit" 14 | sed -i .tmp "s|.*|$Version<\/Version>|" $MagicGradientsToolkit; 15 | rm -f "$MagicGradientsToolkit.tmp" 16 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "msbuild-sdks": { 3 | "MSBuild.Sdk.Extras": "3.0.23" 4 | } 5 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Infrastructure/IFragmentLoader.cs: -------------------------------------------------------------------------------- 1 | using Fragment = AndroidX.Fragment.App.Fragment; 2 | 3 | namespace GradientsApp.Android.Infrastructure 4 | { 5 | public interface IFragmentLoader 6 | { 7 | void LoadFragment(Fragment fragment); 8 | } 9 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Infrastructure/IToolbarManager.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Android.Infrastructure 2 | { 3 | public interface IToolbarManager 4 | { 5 | void SetTitle(string title); 6 | void Show(); 7 | void Hide(); 8 | } 9 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/layout/categories_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/layout/radial_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Android/Resources/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2c3e50 4 | #1B3147 5 | #3498db 6 | 7 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2C3E50 4 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Magic Gradients for Android 3 | Settings 4 | 5 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Views/Adapters/CategoryViewHolder.cs: -------------------------------------------------------------------------------- 1 | using Android.Views; 2 | using Android.Widget; 3 | using AndroidX.RecyclerView.Widget; 4 | using MagicGradients; 5 | 6 | namespace GradientsApp.Android.Views.Adapters 7 | { 8 | public class CategoryViewHolder : RecyclerView.ViewHolder 9 | { 10 | public TextView Name { get; set; } 11 | public GradientView Preview { get; set; } 12 | 13 | public CategoryViewHolder(View itemView) : base(itemView) 14 | { 15 | Name = itemView.FindViewById(Resource.Id.category_name); 16 | Preview = itemView.FindViewById(Resource.Id.category_preview); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Views/CategoriesFragment.cs: -------------------------------------------------------------------------------- 1 | using Android.OS; 2 | using Android.Views; 3 | using AndroidX.RecyclerView.Widget; 4 | using GradientsApp.Android.Infrastructure; 5 | using GradientsApp.Android.Views.Adapters; 6 | using GradientsApp.ViewModels; 7 | 8 | namespace GradientsApp.Android.Views 9 | { 10 | public class CategoriesFragment : BindableFragment 11 | { 12 | public CategoriesFragment() 13 | : base(Resource.Layout.categories_fragment) 14 | { 15 | } 16 | 17 | public override void OnViewCreated(View view, Bundle savedInstanceState) 18 | { 19 | base.OnViewCreated(view, savedInstanceState); 20 | 21 | var list = view.FindViewById(Resource.Id.categories_list); 22 | list.SetAdapter(new CategoriesAdapter(ViewModel.Categories)); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Views/MasksFragment.cs: -------------------------------------------------------------------------------- 1 | using GradientsApp.Android.Infrastructure; 2 | 3 | namespace GradientsApp.Android.Views 4 | { 5 | public class MasksFragment : AppFragment 6 | { 7 | public MasksFragment() 8 | : base(Resource.Layout.masks_fragment, "Masks") 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Android/Views/RadialFragment.cs: -------------------------------------------------------------------------------- 1 | using GradientsApp.Android.Infrastructure; 2 | 3 | namespace GradientsApp.Android.Views 4 | { 5 | public class RadialFragment : AppFragment 6 | { 7 | public RadialFragment() 8 | : base(Resource.Layout.radial_fragment, "Radial Gradients") 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-anydpi-v26/icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-anydpi-v26/icon_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-hdpi/icon.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-hdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-hdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-mdpi/icon.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-mdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-mdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xhdpi/icon.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxhdpi/icon.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxxhdpi/icon.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #3F51B5 5 | #303F9F 6 | #FF4081 7 | 8 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.Android/Resources/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using UIKit; 2 | 3 | namespace GradientsApp.Forms.iOS 4 | { 5 | public class Application 6 | { 7 | // This is the main entry point of the application. 8 | static void Main(string[] args) 9 | { 10 | // if you want to use a different Application Delegate class from "AppDelegate" 11 | // you can specify it here. 12 | UIApplication.Main(args, null, "AppDelegate"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default-568h@2x.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default-Portrait.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default-Portrait@2x.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.Forms.iOS/Resources/Default@2x.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using GradientsApp.Forms.Pages; 2 | using Xamarin.Forms; 3 | 4 | namespace GradientsApp.Forms 5 | { 6 | public partial class App : Application 7 | { 8 | public App() 9 | { 10 | InitializeComponent(); 11 | 12 | MainPage = new NavigationPage(new HomePage()); 13 | new FormsApp().ConfigureAndRun(); 14 | } 15 | 16 | protected override void OnStart() 17 | { 18 | } 19 | 20 | protected override void OnSleep() 21 | { 22 | } 23 | 24 | protected override void OnResume() 25 | { 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms.Xaml; 2 | 3 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)] -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/AnimationsPage.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Forms.Pages 2 | { 3 | public partial class AnimationsPage 4 | { 5 | public AnimationsPage() 6 | { 7 | InitializeComponent(); 8 | } 9 | 10 | protected override void OnDisappearing() 11 | { 12 | ColorAnimation.End(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/CategoriesPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace GradientsApp.Forms.Pages 4 | { 5 | public partial class CategoriesPage 6 | { 7 | public CategoriesPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | 12 | private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) 13 | { 14 | if (CategoriesList.SelectedItem != null) 15 | { 16 | CategoriesList.SelectedItem = null; 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/GalleryPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace GradientsApp.Forms.Pages 4 | { 5 | public partial class GalleryPage 6 | { 7 | public GalleryPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | 12 | private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) 13 | { 14 | if (GradientList.SelectedItem != null) 15 | { 16 | GradientList.SelectedItem = null; 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/GradientPage.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Forms.Pages 2 | { 3 | public partial class GradientPage 4 | { 5 | public GradientPage() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/HomePage.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Forms.Pages 2 | { 3 | public partial class HomePage 4 | { 5 | public HomePage() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/LinearPage.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Forms.Pages 2 | { 3 | public partial class LinearPage 4 | { 5 | public LinearPage() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/MasksPage.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Forms.Pages 2 | { 3 | public partial class MasksPage 4 | { 5 | public MasksPage() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.Forms/Pages/RadialPage.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Forms.Pages 2 | { 3 | public partial class RadialPage 4 | { 5 | public RadialPage() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/App.cs: -------------------------------------------------------------------------------- 1 | using GradientsApp.Infrastructure; 2 | using GradientsApp.iOS.Infrastructure; 3 | using GradientsApp.iOS.Views; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace GradientsApp.iOS 7 | { 8 | public class App : AppSetup 9 | { 10 | protected override void ConfigureServices(IServiceCollection services) 11 | { 12 | var navigation = new NavigationService(); 13 | SetupRoutes(navigation); 14 | 15 | services.AddSingleton(navigation); 16 | } 17 | 18 | private void SetupRoutes(INavigationService navigation) 19 | { 20 | navigation.RegisterRoute(AppRoutes.Linear, typeof(LinearViewController)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/GradientsApp/GradientsApp.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Infrastructure/BindableViewController.cs: -------------------------------------------------------------------------------- 1 | using GradientsApp.Infrastructure; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using UIKit; 4 | 5 | namespace GradientsApp.iOS.Infrastructure 6 | { 7 | public class BindableViewController : UIViewController, IBindableView where TViewModel : class 8 | { 9 | public object BindingContext => ViewModel; 10 | public TViewModel ViewModel { get; } 11 | 12 | public BindableViewController() 13 | { 14 | ViewModel = Ioc.Default.GetService(); 15 | } 16 | 17 | public override void ViewDidLoad() 18 | { 19 | base.ViewDidLoad(); 20 | 21 | if (BindingContext is IHaveTitle bindingTitle) 22 | { 23 | NavigationController.Title = bindingTitle.Title; 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using UIKit; 2 | 3 | namespace GradientsApp.iOS 4 | { 5 | public class Application 6 | { 7 | // This is the main entry point of the application. 8 | static void Main(string[] args) 9 | { 10 | // if you want to use a different Application Delegate class from "AppDelegate" 11 | // you can specify it here. 12 | UIApplication.Main(args, null, "AppDelegate"); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Views/HomeViewController.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using GradientsApp.iOS.Infrastructure; 3 | using GradientsApp.ViewModels; 4 | 5 | namespace GradientsApp.iOS.Views 6 | { 7 | [Register("HomeViewController")] 8 | public class HomeViewController : BindableViewController 9 | { 10 | public HomeViewController() 11 | { 12 | } 13 | 14 | public override void DidReceiveMemoryWarning() 15 | { 16 | // Releases the view if it doesn't have a superview. 17 | base.DidReceiveMemoryWarning(); 18 | 19 | // Release any cached data, images, etc that aren't in use. 20 | } 21 | 22 | public override void ViewDidLoad() 23 | { 24 | base.ViewDidLoad(); 25 | 26 | // Perform any additional setup after loading the view 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp.iOS/Views/LinearViewController.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using GradientsApp.iOS.Infrastructure; 3 | using GradientsApp.ViewModels; 4 | 5 | namespace GradientsApp.iOS.Views 6 | { 7 | [Register("LinearViewController")] 8 | public class LinearViewController : BindableViewController 9 | { 10 | public LinearViewController() 11 | { 12 | } 13 | 14 | public override void DidReceiveMemoryWarning() 15 | { 16 | // Releases the view if it doesn't have a superview. 17 | base.DidReceiveMemoryWarning(); 18 | 19 | // Release any cached data, images, etc that aren't in use. 20 | } 21 | 22 | public override void ViewDidLoad() 23 | { 24 | base.ViewDidLoad(); 25 | 26 | // Perform any additional setup after loading the view 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/AppRoutes.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp 2 | { 3 | public static class AppRoutes 4 | { 5 | public const string Linear = "Linear"; 6 | public const string Radial = "Radial"; 7 | public const string Masks = "Masks"; 8 | public const string Animations = "Animations"; 9 | public const string Categories = "Categories"; 10 | public const string Gallery = "Gallery"; 11 | public const string Gradient = "Gradient"; 12 | public const string Markup = "Markup"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/GradientsApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/Infrastructure/IBindableView.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Infrastructure 2 | { 3 | public interface IBindableView 4 | { 5 | object BindingContext { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/Infrastructure/INavigationAware.cs: -------------------------------------------------------------------------------- 1 | namespace GradientsApp.Infrastructure 2 | { 3 | public interface INavigationAware 4 | { 5 | void Prepare(); 6 | } 7 | 8 | public interface INavigationAware 9 | { 10 | void Prepare(TParameter parameter); 11 | } 12 | 13 | public interface IHaveTitle 14 | { 15 | string Title { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/Infrastructure/INavigationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace GradientsApp.Infrastructure 5 | { 6 | public interface INavigationService 7 | { 8 | Task NavigateTo(string route); 9 | Task NavigateTo(string route, TParameter parameter); 10 | void RegisterRoute(string route, Type type); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/Infrastructure/NavigationViewFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GradientsApp.Infrastructure 4 | { 5 | public class NavigationViewFactory 6 | { 7 | public TView CreateInstance(Type type) 8 | { 9 | return (TView)Activator.CreateInstance(type); 10 | } 11 | 12 | public void CallEvents(object bindingContext) 13 | { 14 | if (bindingContext is INavigationAware navAware) 15 | navAware.Prepare(); 16 | } 17 | 18 | public void CallEvents(object bindingContext, TParameter parameter) 19 | { 20 | if (bindingContext is INavigationAware navAware) 21 | navAware.Prepare(); 22 | 23 | if (bindingContext is INavigationAware navAwareParam) 24 | navAwareParam.Prepare(parameter); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/Models/CategoryItem.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | 3 | namespace GradientsApp.Models 4 | { 5 | public class CategoryItem 6 | { 7 | public string Name { get; set; } 8 | public IGradientSource Source { get; set; } 9 | public string Tag { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/Models/GalleryItem.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | 3 | namespace GradientsApp.Models 4 | { 5 | public class GalleryItem 6 | { 7 | public IGradientSource Source { get; set; } 8 | public Dimensions Size { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples/GradientsApp/GradientsApp/ViewModels/HomeViewModel.cs: -------------------------------------------------------------------------------- 1 | using GradientsApp.Infrastructure; 2 | using MvvmHelpers.Commands; 3 | using MvvmHelpers.Interfaces; 4 | 5 | namespace GradientsApp.ViewModels 6 | { 7 | public class HomeViewModel 8 | { 9 | public IAsyncCommand NavigateCommand { get; } 10 | 11 | public HomeViewModel(INavigationService navigationService) 12 | { 13 | NavigateCommand = new AsyncCommand(navigationService.NavigateTo); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace MagicCrawler 4 | { 5 | /// 6 | /// Interaction logic for App.xaml 7 | /// 8 | public partial class App : Application 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo( 4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 5 | //(used if a resource is not found in the page, 6 | // or application resource dictionaries) 7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 8 | //(used if a resource is not found in the page, 9 | // app, or any theme specific resource dictionaries) 10 | )] 11 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/MagicCrawler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | netcoreapp3.1 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Always 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/Models/Category.cs: -------------------------------------------------------------------------------- 1 | using System.Text.Json.Serialization; 2 | 3 | namespace MagicCrawler.Models 4 | { 5 | public class Category 6 | { 7 | public string Name { get; set; } 8 | public string Stylesheet { get; set; } 9 | public string Tag { get; set; } 10 | public string Group { get; set; } 11 | public string File { get; set; } 12 | 13 | [JsonIgnore] 14 | public int DisplayOrder { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/Models/Configuration.cs: -------------------------------------------------------------------------------- 1 | namespace MagicCrawler.Models 2 | { 3 | public class Configuration 4 | { 5 | public string Input { get; set; } 6 | public string Output { get; set; } 7 | public Collection[] Collections { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/Models/Gradient.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MagicCrawler.Models 4 | { 5 | public class Gradient 6 | { 7 | public string Slug { get; set; } 8 | public string Stylesheet { get; set; } 9 | public string Size { get; set; } 10 | public List Tags { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/Models/JobItem.cs: -------------------------------------------------------------------------------- 1 | using MvvmHelpers; 2 | 3 | namespace MagicCrawler.Models 4 | { 5 | public class JobItem : ObservableObject 6 | { 7 | public Collection Data { get; } 8 | 9 | public string Group => Data.Group; 10 | public string Title => Data.Title; 11 | public string Input => Data.GetFullUrl(); 12 | public string Output => Data.GetFile(); 13 | 14 | private string _status; 15 | public string Status 16 | { 17 | get => _status; 18 | set => SetProperty(ref _status, value); 19 | } 20 | 21 | public JobItem(Collection data) 22 | { 23 | Data = data; 24 | } 25 | 26 | public void Reset() 27 | { 28 | Status = string.Empty; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/Models/Metadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MagicCrawler.Models 4 | { 5 | public class Metadata 6 | { 7 | public DateTime Date { get; set; } 8 | public string NameSpace { get; set; } 9 | public string Categories { get; set; } 10 | public string Themes { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/MagicCrawler/MagicCrawler/Views/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using MagicCrawler.ViewModels; 2 | using System.Windows; 3 | 4 | namespace MagicCrawler.Views 5 | { 6 | /// 7 | /// Interaction logic for MainWindow.xaml 8 | /// 9 | public partial class MainWindow : Window 10 | { 11 | public MainWindow() 12 | { 13 | InitializeComponent(); 14 | Loaded += OnLoaded; 15 | } 16 | 17 | private void OnLoaded(object sender, RoutedEventArgs e) 18 | { 19 | ((MainViewModel)DataContext).Initialize(); 20 | ((MainViewModel)DataContext).HtmlLoader.Initialize(WebView); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Properties/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable-hdpi/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable-hdpi/mg.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable-ldpi/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable-ldpi/mg.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable-mdpi/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable-mdpi/mg.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable-xhdpi/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable-xhdpi/mg.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable-xxhdpi/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable-xxhdpi/mg.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable-xxxhdpi/mg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable-xxxhdpi/mg.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable/tab_about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable/tab_about.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable/tab_feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable/tab_feed.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/drawable/xamarin_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/drawable/xamarin_logo.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/layout/Tabbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/layout/Toolbar.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-anydpi-v26/icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-anydpi-v26/icon_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-hdpi/icon.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-hdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-hdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-mdpi/icon.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-mdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-mdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-xhdpi/icon.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-xhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-xhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-xxhdpi/icon.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-xxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-xxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-xxxhdpi/icon.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #3F51B5 5 | #303F9F 6 | #FF4081 7 | 8 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Android/appcenter-post-clone.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | SLN_PATH="$APPCENTER_SOURCE_DIRECTORY/MagicGradients.sln" 3 | UWP_PATH="$APPCENTER_SOURCE_DIRECTORY/samples/Playground/Playground.UWP/Playground.UWP.csproj" 4 | dotnet sln $SLN_PATH remove $UWP_PATH -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Infrastructure/DatabaseProvider.cs: -------------------------------------------------------------------------------- 1 | using LiteDB; 2 | using System; 3 | using System.IO; 4 | 5 | namespace Playground.Data.Infrastructure 6 | { 7 | public class DatabaseProvider : IDatabaseProvider 8 | { 9 | public LiteDatabase CreateDatabase() 10 | { 11 | return new LiteDatabase($"Filename={GetDbPath()};Upgrade=true"); 12 | } 13 | 14 | private string GetDbPath() 15 | { 16 | var dir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); 17 | return Path.Combine(dir, "Gradients.db"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Infrastructure/IDatabaseProvider.cs: -------------------------------------------------------------------------------- 1 | using LiteDB; 2 | 3 | namespace Playground.Data.Infrastructure 4 | { 5 | public interface IDatabaseProvider 6 | { 7 | LiteDatabase CreateDatabase(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Infrastructure/IDatabaseUpdater.cs: -------------------------------------------------------------------------------- 1 | using Playground.Data.Repositories; 2 | 3 | namespace Playground.Data.Infrastructure 4 | { 5 | public interface IDatabaseUpdater 6 | { 7 | void RunUpdate(params ICanUpdateMyself[] repositories); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Models/Category.cs: -------------------------------------------------------------------------------- 1 | using LiteDB; 2 | 3 | namespace Playground.Data.Models 4 | { 5 | public class Category 6 | { 7 | public int Id { get; set; } 8 | 9 | [BsonField("name")] 10 | public string Name { get; set; } 11 | 12 | [BsonField("stylesheet")] 13 | public string Stylesheet { get; set; } 14 | 15 | [BsonField("tag")] 16 | public string Tag { get; set; } 17 | 18 | [BsonField("group")] 19 | public string Group { get; set; } 20 | 21 | [BsonField("file")] 22 | public string File { get; set; } 23 | 24 | [BsonIgnore] 25 | public int Count { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Models/Gradient.cs: -------------------------------------------------------------------------------- 1 | using LiteDB; 2 | 3 | namespace Playground.Data.Models 4 | { 5 | public class Gradient 6 | { 7 | public int Id { get; set; } 8 | 9 | [BsonField("stylesheet")] 10 | public string Stylesheet { get; set; } 11 | 12 | [BsonField("size")] 13 | public string Size { get; set; } 14 | 15 | [BsonField("tags")] 16 | public string[] Tags { get; set; } 17 | 18 | [BsonField("slug")] 19 | public string Slug { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Models/Metadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using LiteDB; 3 | 4 | namespace Playground.Data.Models 5 | { 6 | public class Metadata 7 | { 8 | [BsonField("date")] 9 | public DateTime Date { get; set; } 10 | 11 | [BsonField("nameSpace")] 12 | public string NameSpace { get; set; } 13 | 14 | [BsonField("categories")] 15 | public string Categories { get; set; } 16 | 17 | [BsonField("themes")] 18 | public string Themes { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Models/Theme.cs: -------------------------------------------------------------------------------- 1 | using LiteDB; 2 | 3 | namespace Playground.Data.Models 4 | { 5 | public class Theme 6 | { 7 | public int Id { get; set; } 8 | 9 | [BsonField("color")] 10 | public string Color { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Repositories/ICanUpdateMyself.cs: -------------------------------------------------------------------------------- 1 | using LiteDB; 2 | using Playground.Data.Models; 3 | 4 | namespace Playground.Data.Repositories 5 | { 6 | public interface ICanUpdateMyself 7 | { 8 | void UpdateDatabase(LiteDatabase db, Metadata metadata, IDocumentRepository documentRepository); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Repositories/ICategoryRepository.cs: -------------------------------------------------------------------------------- 1 | using Playground.Data.Models; 2 | using System.Collections.Generic; 3 | 4 | namespace Playground.Data.Repositories 5 | { 6 | public interface ICategoryRepository : ICanUpdateMyself 7 | { 8 | List GetCategories(); 9 | List GetThemes(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Repositories/IDocumentRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Playground.Data.Repositories 4 | { 5 | public interface IDocumentRepository 6 | { 7 | void SetupMapper(); 8 | T GetDocument(string fullPath); 9 | IEnumerable GetDocumentCollection(string nameSpace, params string[] files); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Repositories/IGradientRepository.cs: -------------------------------------------------------------------------------- 1 | using Playground.Data.Models; 2 | using System.Collections.Generic; 3 | 4 | namespace Playground.Data.Repositories 5 | { 6 | public interface IGradientRepository : ICanUpdateMyself 7 | { 8 | Gradient GetById(int id); 9 | List GetByTag(string tag); 10 | List FilterByTags(string category, params string[] tags); 11 | List GetBySlugs(string[] slugs); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Resources/CarbonFiber.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "slug": "70a34ce1-3d0b-4fa4-8bbf-6777a81f8b2b", 4 | "stylesheet": "radial-gradient(circle at center, transparent, rgb(255, 255, 255)), repeating-linear-gradient(135deg, rgb(255, 255, 255) 0px, rgb(255, 255, 255) 12px, transparent 12px, transparent 19px, rgb(255, 255, 255) 19px, rgb(255, 255, 255) 24px, transparent 24px, transparent 28px), repeating-linear-gradient(45deg, rgb(245, 245, 245) 0px, rgb(245, 245, 245) 7px, transparent 7px, transparent 14px), linear-gradient(90deg, rgb(255, 255, 255), rgb(255, 255, 255))", 5 | "tags": [ 6 | "carbonfiber" 7 | ] 8 | } 9 | ] -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Resources/Metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "date": "2020-11-29T12:47:47", 3 | "nameSpace": "Playground.Data.Resources", 4 | "categories": "Categories.json", 5 | "themes": "Themes.json" 6 | } -------------------------------------------------------------------------------- /samples/Playground/Playground.Data/Resources/Themes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "color": "#eb4141" 4 | }, 5 | { 6 | "color": "#eb9641" 7 | }, 8 | { 9 | "color": "#e8eb41" 10 | }, 11 | { 12 | "color": "#4deb41" 13 | }, 14 | { 15 | "color": "#41bbeb" 16 | }, 17 | { 18 | "color": "#6641eb" 19 | }, 20 | { 21 | "color": "#e241eb" 22 | } 23 | ] -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/LargeTile.scale-200.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/LargeTile.scale-400.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/SmallTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/SmallTile.scale-200.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/SmallTile.scale-400.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.scale-100.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.targetsize-16.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.targetsize-256.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Square44x44Logo.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Square44x44Logo.targetsize-48.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Wide310x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Wide310x150Logo.scale-100.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/Assets/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.UWP/Assets/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  11 | 12 | -------------------------------------------------------------------------------- /samples/Playground/Playground.UWP/MainPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms.Platform.UWP; 2 | 3 | namespace Playground.UWP 4 | { 5 | /// 6 | /// An empty page that can be used on its own or navigated to within a Frame. 7 | /// 8 | public sealed partial class MainPage : WindowsPage 9 | { 10 | public MainPage() 11 | { 12 | InitializeComponent(); 13 | LoadApplication(new Playground.App()); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/LaunchImage.imageset/mg_splash-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/LaunchImage.imageset/mg_splash-1.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/LaunchImage.imageset/mg_splash-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/LaunchImage.imageset/mg_splash-2.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Assets.xcassets/LaunchImage.imageset/mg_splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground.iOS/Assets.xcassets/LaunchImage.imageset/mg_splash.png -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace Playground.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "AppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, "AppDelegate"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/Playground/Playground.iOS/appcenter-post-clone.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | SLN_PATH="$APPCENTER_SOURCE_DIRECTORY/MagicGradients.sln" 3 | UWP_PATH="$APPCENTER_SOURCE_DIRECTORY/samples/Playground/Playground.UWP/Playground.UWP.csproj" 4 | dotnet sln $SLN_PATH remove $UWP_PATH -------------------------------------------------------------------------------- /samples/Playground/Playground/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /samples/Playground/Playground/AppShell.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground 4 | { 5 | public partial class AppShell : Shell 6 | { 7 | public AppShell() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Controls/ActionMenu/ActionItem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Input; 3 | using Xamarin.Forms; 4 | 5 | namespace Playground.Controls 6 | { 7 | public class ActionItem : BindableObject 8 | { 9 | public static readonly BindableProperty CommandProperty = BindableProperty.Create( 10 | nameof(Command), typeof(ICommand), typeof(ActionItem)); 11 | 12 | public ICommand Command 13 | { 14 | get => (ICommand)GetValue(CommandProperty); 15 | set => SetValue(CommandProperty, value); 16 | } 17 | 18 | public ImageSource IconSource { get; set; } 19 | public string Text { get; set; } 20 | public bool IsVisible { get; set; } = true; 21 | } 22 | 23 | public class ActionItemCollection : List 24 | { 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Controls/AnimationClip.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Controls 4 | { 5 | public partial class AnimationClip : ContentView 6 | { 7 | public AnimationClip() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Controls/EnumSwitch.xaml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Controls/MenuSection.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Controls/MenuSection.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Controls 4 | { 5 | public partial class MenuSection : ContentView 6 | { 7 | public MenuSection() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Controls/RadialMenu/RadialMenuItem.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Controls 4 | { 5 | public class RadialMenuItem 6 | { 7 | public Color Background { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Converters/NegativeBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Xamarin.Forms; 4 | 5 | namespace Playground.Converters 6 | { 7 | public class NegativeBoolConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | return !(bool)value; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | throw new NotImplementedException(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Converters/OffsetToPercenttConverter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | using System; 3 | using System.Globalization; 4 | using Xamarin.Forms; 5 | 6 | namespace Playground.Converters 7 | { 8 | public class OffsetToPercentConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | return Math.Floor(((Offset)value).Value * 100); 13 | } 14 | 15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | if (double.TryParse((string) value, out var parsed)) 18 | { 19 | return Offset.Prop(parsed / 100); 20 | } 21 | return Offset.Zero; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Converters/OffsetToRectConverter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | using System; 3 | using System.Globalization; 4 | using Xamarin.Forms; 5 | 6 | namespace Playground.Converters 7 | { 8 | public class OffsetToRectConverter : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | return new Rectangle(((Offset)value).Value, 0, 60, 1); 13 | } 14 | 15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | var bounds = (Rectangle)value; 18 | return bounds.X; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Converters/TabBoolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Xamarin.Forms; 4 | 5 | namespace Playground.Converters 6 | { 7 | public class TabBoolConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | if (value is bool bValue) 12 | return bValue ? 1 : 0; 13 | 14 | return 0; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 18 | { 19 | if (value is int iValue) 20 | return iValue == 1; 21 | 22 | return false; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Converters/TabEnumConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Xamarin.Forms; 4 | 5 | namespace Playground.Converters 6 | { 7 | public class TabEnumConverter : IValueConverter 8 | { 9 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 10 | { 11 | return (int)value; 12 | } 13 | 14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | return Enum.ToObject(targetType, (int)value); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Extensions/AdaptiveUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | 4 | namespace Playground.Extensions 5 | { 6 | public static class AdaptiveUtils 7 | { 8 | private const int ColSize = 200; 9 | private const int MinCols = 2; 10 | 11 | public static void SetGridColumns(CollectionView view) 12 | { 13 | if (view.Width > ColSize * MinCols) 14 | { 15 | var cols = (int)Math.Floor(view.Width / ColSize); 16 | ((GridItemsLayout)view.ItemsLayout).Span = cols; 17 | } 18 | else 19 | { 20 | ((GridItemsLayout)view.ItemsLayout).Span = MinCols; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Extensions/ColorExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | 4 | namespace Playground.Extensions 5 | { 6 | public static class ColorExtensions 7 | { 8 | public static bool IsCloseTo(this Color self, Color[] others, double tolerance) 9 | { 10 | foreach (var other in others) 11 | { 12 | var isCloseTo = Math.Abs(self.R - other.R) < tolerance && 13 | Math.Abs(self.G - other.G) < tolerance && 14 | Math.Abs(self.B - other.B) < tolerance; 15 | 16 | if (isCloseTo) 17 | return true; 18 | } 19 | 20 | return false; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Extensions/ColorUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | 4 | namespace Playground.Extensions 5 | { 6 | public static class ColorUtils 7 | { 8 | public static Color GetRandom() 9 | { 10 | var random = new Random(); 11 | return new Color( 12 | random.NextDouble(), 13 | random.NextDouble(), 14 | random.NextDouble()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Extensions/VisualElementExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | 4 | namespace Playground.Extensions 5 | { 6 | public static class VisualElementExtensions 7 | { 8 | public static void Click(this VisualElement view, Action action) 9 | { 10 | Device.BeginInvokeOnMainThread(async () => 11 | { 12 | await view.ScaleTo(0.9, 50, Easing.CubicOut); 13 | action(); 14 | await view.ScaleTo(1, 50, Easing.CubicIn); 15 | }); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Animation/AnimationItem.cs: -------------------------------------------------------------------------------- 1 | using Playground.ViewModels; 2 | using System.Windows.Input; 3 | using Xamarin.Forms; 4 | 5 | namespace Playground.Features.Animation 6 | { 7 | public class AnimationItem : ObservableObject 8 | { 9 | public ICommand PlayCommand { get; } 10 | 11 | public string Title { get; } 12 | 13 | private bool _isRunning; 14 | public bool IsRunning 15 | { 16 | get => _isRunning; 17 | set => SetProperty(ref _isRunning, value, () => 18 | { 19 | RaisePropertyChanged(nameof(Text)); 20 | }); 21 | } 22 | 23 | public string Text => IsRunning ? "Stop" : "Play"; 24 | 25 | public AnimationItem(string title) 26 | { 27 | Title = title; 28 | PlayCommand = new Command(() => IsRunning = !IsRunning); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Animation/AnimationsPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.Animation 4 | { 5 | public partial class AnimationsPage : ContentPage 6 | { 7 | public AnimationsPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | 12 | protected override void OnDisappearing() 13 | { 14 | ((AnimationsViewModel)BindingContext).StopAnimations(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/BattleTest/BattleItem.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | using System.Drawing; 3 | 4 | namespace Playground.Features.BattleTest 5 | { 6 | public class BattleItem 7 | { 8 | public string Text { get; set; } 9 | public IGradientSource GradientSource { get; set; } 10 | public Color TextColor { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/BattleTest/BattleTestPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.BattleTest 4 | { 5 | public partial class BattleTestPage : ContentPage 6 | { 7 | public BattleTestPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/CssPreviewer/CssPreviewerPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.CssPreviewer 4 | { 5 | public partial class CssPreviewerPage : ContentPage 6 | { 7 | public CssPreviewerPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/CssPreviewer/CssSnippet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Playground.Features.CssPreviewer 4 | { 5 | public class CssSnippet 6 | { 7 | public string Name { get; set; } 8 | public string Code => GetCode?.Invoke(); 9 | public Func GetCode { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Editor/BackgroundTab.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.Editor 4 | { 5 | public partial class BackgroundTab : StackLayout 6 | { 7 | public BackgroundTab() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Editor/MasksTab.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | 4 | namespace Playground.Features.Editor 5 | { 6 | public partial class MasksTab : StackLayout 7 | { 8 | public MasksTab() 9 | { 10 | InitializeComponent(); 11 | } 12 | 13 | private void FontSize_OnValueChanged(object sender, ValueChangedEventArgs e) 14 | { 15 | var newStep = Math.Round(e.NewValue); 16 | ((Slider)sender).Value = newStep; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Editor/PropertiesTab.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.Editor 4 | { 5 | public partial class PropertiesTab : StackLayout 6 | { 7 | public PropertiesTab() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Gallery/Models/CategoryGroup.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Playground.Features.Gallery.Models 4 | { 5 | public class CategoryGroup : List 6 | { 7 | public string Name { get; } 8 | 9 | public CategoryGroup(string name, IEnumerable categories) 10 | : base(categories) 11 | { 12 | Name = name; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Gallery/Models/CategoryItem.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | 3 | namespace Playground.Features.Gallery.Models 4 | { 5 | public class CategoryItem 6 | { 7 | public string Name { get; set; } 8 | public string Tag { get; set; } 9 | public int Count { get; set; } 10 | public IGradientSource GradientSource { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Gallery/Models/GradientItem.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | using Playground.Extensions; 3 | using System.Linq; 4 | using Xamarin.Forms; 5 | 6 | namespace Playground.Features.Gallery.Models 7 | { 8 | public class GradientItem 9 | { 10 | public int Id { get; set; } 11 | public IGradientSource Source { get; set; } 12 | public Dimensions Size { get; set; } 13 | 14 | public bool HasColors(Color[] colors) 15 | { 16 | foreach (var gradient in Source.GetGradients()) 17 | { 18 | var hasTheme = gradient.Stops.Any(x => x.Color.IsCloseTo(colors, 0.3)); 19 | if (hasTheme) 20 | { 21 | return true; 22 | } 23 | } 24 | 25 | return false; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Gallery/Models/ThemeItem.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.Gallery.Models 4 | { 5 | public class ThemeItem 6 | { 7 | public string ColorRaw { get; set; } 8 | public Color Color { get; set; } 9 | public string Tag { get; set; } 10 | 11 | public override string ToString() 12 | { 13 | return ColorRaw; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Gallery/Services/ICategoryService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Playground.Features.Gallery.Models; 3 | 4 | namespace Playground.Features.Gallery.Services 5 | { 6 | public interface ICategoryService 7 | { 8 | IEnumerable GetCategories(); 9 | IEnumerable GetGroupedCategories(); 10 | IEnumerable GetThemes(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Gallery/Services/IGalleryService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Playground.Features.Gallery.Models; 3 | 4 | namespace Playground.Features.Gallery.Services 5 | { 6 | public interface IGalleryService 7 | { 8 | IEnumerable GetGradients(string tag); 9 | IEnumerable FilterGradients(string category, params string[] tags); 10 | GradientItem GetGradientById(int id); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Home/HomePage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Playground.Extensions; 2 | using System.ComponentModel; 3 | using Xamarin.Forms; 4 | 5 | namespace Playground.Features.Home 6 | { 7 | public partial class HomePage : ContentPage 8 | { 9 | public HomePage() 10 | { 11 | InitializeComponent(); 12 | PropertyChanged += ContentPageBase_PropertyChanged; 13 | } 14 | 15 | private void ContentPageBase_PropertyChanged(object sender, PropertyChangedEventArgs e) 16 | { 17 | if (e.PropertyName == "SafeAreaInsets") 18 | { 19 | this.InitSafeAreaInsets(); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Linear/LinearSamplesPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.Linear 4 | { 5 | public partial class LinearSamplesPage : ContentPage 6 | { 7 | public LinearSamplesPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Linear/LinearSamplesViewModel.cs: -------------------------------------------------------------------------------- 1 | using Playground.ViewModels; 2 | 3 | namespace Playground.Features.Linear 4 | { 5 | public class LinearSamplesViewModel : ObservableObject 6 | { 7 | private string _stylesheet; 8 | public string Stylesheet 9 | { 10 | get => _stylesheet; 11 | set => SetProperty(ref _stylesheet, value); 12 | } 13 | 14 | public LinearSamplesViewModel() 15 | { 16 | Stylesheet = "linear-gradient(red, yellow)"; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Masks/MasksPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.Masks 4 | { 5 | public partial class MasksPage : ContentPage 6 | { 7 | public MasksPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Masks/MasksViewModel.cs: -------------------------------------------------------------------------------- 1 | using Playground.ViewModels; 2 | 3 | namespace Playground.Features.Masks 4 | { 5 | public class MasksViewModel : ObservableObject 6 | { 7 | private int _selectedTabIndex; 8 | public int SelectedTabIndex 9 | { 10 | get => _selectedTabIndex; 11 | set => SetProperty(ref _selectedTabIndex, value); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Radial/RadialSamplesPage.css: -------------------------------------------------------------------------------- 1 | .terminatorEye { 2 | background: radial-gradient(circle farthest-side at 50% 50%, #FF0000 20%, #7F0000 60%, black 70%, gray); 3 | } 4 | 5 | .terminatorEyeWithSize { 6 | background: radial-gradient(circle farthest-side at 50% 50%, #FF0000 20%, #7F0000 60%, black 70%, gray); 7 | background-size: 60px 60px; 8 | } 9 | 10 | .repeatingCircles { 11 | background: repeating-radial-gradient(circle closest-side, #000000 0%, #8BC9BA 10%, #EDFFFF 15%, #8BC9BA 20%, #000000 30%); 12 | } 13 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Radial/RadialSamplesPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Features.Radial 4 | { 5 | public partial class RadialSamplesPage : ContentPage 6 | { 7 | public RadialSamplesPage() 8 | { 9 | InitializeComponent(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Share/ExportData.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients; 2 | 3 | namespace Playground.Features.Share 4 | { 5 | public class ExportData 6 | { 7 | public IGradientSource GradientSource { get; set; } 8 | public Dimensions GradientSize { get; set; } 9 | public BackgroundRepeat GradientRepeat { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Share/IGradientExporter.cs: -------------------------------------------------------------------------------- 1 | namespace Playground.Features.Share 2 | { 3 | public interface IGradientExporter 4 | { 5 | string ExportCss(ExportData data); 6 | string ExportRaw(ExportData data); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Share/IShareService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Playground.Features.Share 4 | { 5 | public interface IShareService 6 | { 7 | Task ShareText(string title, string text); 8 | Task CopyToClipboard(string text); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Features/Share/ShareService.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Xamarin.Essentials; 3 | 4 | namespace Playground.Features.Share 5 | { 6 | public class ShareService : IShareService 7 | { 8 | public Task ShareText(string title, string text) 9 | { 10 | return Xamarin.Essentials.Share.RequestAsync(new ShareTextRequest 11 | { 12 | Title = title, 13 | Text = text 14 | }); 15 | } 16 | 17 | public Task CopyToClipboard(string text) 18 | { 19 | return Clipboard.SetTextAsync(text); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Interactivity/RotateTriggerAction.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace Playground.Interactivity 4 | { 5 | public class RotateTriggerAction : TriggerAction 6 | { 7 | public uint Duration { get; set; } 8 | public double RotateTo { get; set; } 9 | 10 | protected override void Invoke(VisualElement sender) 11 | { 12 | sender.RotateTo(RotateTo, Duration); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /samples/Playground/Playground/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms.Xaml; 2 | 3 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)] -------------------------------------------------------------------------------- /samples/Playground/Playground/Resources/Fonts/IcoMoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mgierlasinski/MagicGradients/9ead8d6c58130ad54c43de149c946f7346142343/samples/Playground/Playground/Resources/Fonts/IcoMoon.ttf -------------------------------------------------------------------------------- /src/MagicGradients.Core/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly: InternalsVisibleTo("MagicGradients.Forms")] 4 | [assembly: InternalsVisibleTo("MagicGradients.Core.Tests")] 5 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Builder/CssGradientBuilder.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Parser; 2 | using System.Collections.Generic; 3 | 4 | namespace MagicGradients.Builder 5 | { 6 | public class CssGradientBuilder : StopsBuilder, IChildBuilder 7 | { 8 | protected override CssGradientBuilder Instance => this; 9 | 10 | internal string StyleSheet { get; } 11 | 12 | public CssGradientBuilder(string styleSheet) 13 | { 14 | StyleSheet = styleSheet; 15 | } 16 | 17 | public void AddConstructed(List gradients) 18 | { 19 | gradients.AddRange(new CssGradientParser().Parse(StyleSheet)); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Builder/GradientBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Builder 2 | { 3 | public static class GradientBuilderExtensions 4 | { 5 | public static IGradientSource BuildSource(this GradientBuilder builder) 6 | { 7 | return new GenericGradientSource(builder.Build()); 8 | } 9 | 10 | public static void BuildFor(this GradientBuilder builder, IGradientControl control) 11 | { 12 | control.GradientSource = builder.BuildSource(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Builder/IChildBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MagicGradients.Builder 4 | { 5 | public interface IChildBuilder 6 | { 7 | IGradientFactory Factory { get; set; } 8 | List Stops { get; } 9 | void AddConstructed(List gradients); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Builder/IGradientFactory.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | 3 | namespace MagicGradients.Builder 4 | { 5 | public interface IGradientFactory 6 | { 7 | ILinearGradient Construct(LinearGradientBuilder builder); 8 | IRadialGradient Construct(RadialGradientBuilder builder); 9 | IGradientStop CreateStop(Color color, Offset? offset = null); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Converters/CssGradientSourceTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Globalization; 4 | 5 | namespace MagicGradients.Converters 6 | { 7 | public class CssGradientSourceTypeConverter : TypeConverter 8 | { 9 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 10 | => sourceType == typeof(string); 11 | 12 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 13 | { 14 | var valueStr = value?.ToString(); 15 | 16 | if (string.IsNullOrEmpty(valueStr)) 17 | throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(IGradientSource)}"); 18 | 19 | return new CssGradientSource(valueStr); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/CssGradientSource.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Parser; 2 | using System.Collections.Generic; 3 | 4 | namespace MagicGradients 5 | { 6 | public class CssGradientSource : IGradientSource 7 | { 8 | private readonly CssGradientParser _parser = new(); 9 | private List _gradients; 10 | 11 | public CssGradientSource() 12 | { 13 | _gradients = new List(); 14 | } 15 | 16 | public CssGradientSource(string css) 17 | { 18 | Parse(css); 19 | } 20 | 21 | public void Parse(string css) 22 | { 23 | _gradients = _parser.Parse(css); 24 | } 25 | 26 | public IReadOnlyList GetGradients() 27 | { 28 | return _gradients; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Drawing/LinearGradientPaintEx.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | 3 | namespace MagicGradients.Drawing 4 | { 5 | public class LinearGradientPaintEx : LinearGradientPaint 6 | { 7 | public bool IsRepeating { get; set; } 8 | 9 | public LinearGradientPaintEx( 10 | PaintGradientStop[] gradientStops, 11 | Point startPoint, 12 | Point endPoint, 13 | bool isRepeating) : base(gradientStops, startPoint, endPoint) 14 | { 15 | IsRepeating = isRepeating; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Drawing/RadialGradientPaintEx.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | using System; 3 | 4 | namespace MagicGradients.Drawing 5 | { 6 | public class RadialGradientPaintEx : RadialGradientPaint 7 | { 8 | public Size Size { get; set; } 9 | public bool IsRepeating { get; set; } 10 | 11 | public RadialGradientPaintEx( 12 | PaintGradientStop[] gradientStops, 13 | Point center, 14 | Size size, 15 | bool isRepeating) : base(gradientStops) 16 | { 17 | Center = center; 18 | Size = size; 19 | Radius = Math.Max(Size.Width, Size.Height); 20 | IsRepeating = isRepeating; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/GlobalSetup.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Builder; 2 | 3 | namespace MagicGradients 4 | { 5 | public class GlobalSetup 6 | { 7 | public static GlobalSetup Current { get; } = new GlobalSetup(); 8 | 9 | public IGradientFactory GradientFactory { get; private set; } = new GradientFactory(); 10 | 11 | public GlobalSetup UseFactory(IGradientFactory factory) 12 | { 13 | GradientFactory = factory; 14 | return this; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/GradientMath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MagicGradients 4 | { 5 | internal static class GradientMath 6 | { 7 | public static double ToRadians(double degrees) => (Math.PI / 180) * degrees; 8 | public static double RotateBy180(double degrees) => (180 + degrees) % 360; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/IGradient.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | using System.Collections.Generic; 3 | 4 | namespace MagicGradients 5 | { 6 | public interface IGradient 7 | { 8 | bool IsRepeating { get; } 9 | IReadOnlyList GetStops(); 10 | } 11 | 12 | public interface IGradientStop 13 | { 14 | Color Color { get; } 15 | Offset Offset { get; } 16 | float RenderOffset { get; set; } 17 | } 18 | 19 | public interface ILinearGradient : IGradient 20 | { 21 | double Angle { get; } 22 | } 23 | 24 | public interface IRadialGradient : IGradient 25 | { 26 | Position Center { get; } 27 | Dimensions Radius { get; } 28 | RadialGradientShape Shape { get; } 29 | RadialGradientStretch Stretch { get; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/IGradientControl.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Masks; 2 | 3 | namespace MagicGradients 4 | { 5 | public interface IGradientControl 6 | { 7 | double ViewWidth { get; } 8 | IGradientSource GradientSource { get; set; } 9 | Dimensions GradientSize { get; set; } 10 | BackgroundRepeat GradientRepeat { get; set; } 11 | IGradientMask Mask { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/IGradientSource.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Converters; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | 5 | namespace MagicGradients 6 | { 7 | [TypeConverter(typeof(CssGradientSourceTypeConverter))] 8 | public interface IGradientSource 9 | { 10 | IReadOnlyList GetGradients(); 11 | } 12 | 13 | public class GenericGradientSource : IGradientSource 14 | { 15 | private readonly IReadOnlyList _gradients; 16 | 17 | public GenericGradientSource(IReadOnlyList gradients) 18 | { 19 | _gradients = gradients; 20 | } 21 | 22 | public IReadOnlyList GetGradients() 23 | { 24 | return _gradients; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/IGradientVisualElement.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients 2 | { 3 | public interface IGradientVisualElement 4 | { 5 | void InvalidateCanvas(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/MagicGradients.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1;netstandard2.0;Xamarin.iOS10;MonoAndroid12.0;Xamarin.Mac20 5 | MagicGradients 6 | MagicGradients 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Masks/EllipseMaskPainter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace MagicGradients.Masks 5 | { 6 | public class EllipseMaskPainter : IMaskPainter 7 | { 8 | public void Clip(IEllipseMask mask, DrawContext context) 9 | { 10 | if (!mask.IsActive) 11 | return; 12 | 13 | var bounds = mask.Size.GetDrawRectangle(context.CanvasRect, context.PixelScaling); 14 | 15 | var path = new PathF(); 16 | path.AppendEllipse(bounds); 17 | 18 | using var layout = ShapeMaskLayout.Create(mask, bounds, context, false); 19 | context.Canvas.ClipPath(path); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Masks/GradientMaskEnum.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Masks 2 | { 3 | public enum Stretch 4 | { 5 | None, 6 | AspectFit, 7 | AspectFill, 8 | Fill 9 | } 10 | 11 | public enum ClipMode 12 | { 13 | Include, 14 | Exclude 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Masks/PathMaskPainter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace MagicGradients.Masks 5 | { 6 | public class PathMaskPainter : IMaskPainter 7 | { 8 | public void Clip(IPathMask mask, DrawContext context) 9 | { 10 | if (!mask.IsActive || string.IsNullOrEmpty(mask.Data)) 11 | return; 12 | 13 | var path = PathBuilder.Build(mask.Data); 14 | //var bounds = path.Bounds; // Requires native GraphicsService 15 | var bounds = path.GetBoundsByFlattening(); 16 | 17 | using var layout = ShapeMaskLayout.Create(mask, bounds, context, false); 18 | context.Canvas.ClipPath(path); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Masks/TextMaskPainter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | 3 | namespace MagicGradients.Masks 4 | { 5 | public class TextMaskPainter : IMaskPainter 6 | { 7 | public void Clip(ITextMask mask, DrawContext context) 8 | { 9 | if (!mask.IsActive || string.IsNullOrEmpty(mask.Text)) 10 | return; 11 | 12 | // TODO: apply clipping 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Parser/CssToken.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Parser 2 | { 3 | public class CssToken 4 | { 5 | public const string LinearGradient = "linear-gradient"; 6 | public const string RepeatingLinearGradient = "repeating-linear-gradient"; 7 | public const string RadialGradient = "radial-gradient"; 8 | public const string RepeatingRadialGradient = "repeating-radial-gradient"; 9 | public const string Rgb = "rgb"; 10 | public const string Rgba = "rgba"; 11 | public const string Hsl = "hsl"; 12 | public const string Hsla = "hsla"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Parser/TokenDefinitions/ColorDefinition.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MagicGradients.Parser.TokenDefinitions 4 | { 5 | public class ColorDefinition 6 | { 7 | protected List GetOffsets(string[] tokens) 8 | { 9 | var offsets = new List(); 10 | 11 | foreach (var token in tokens) 12 | { 13 | if (Offset.TryParseWithUnit(token, out var offset)) 14 | offsets.Add(offset); 15 | } 16 | 17 | return offsets; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Parser/TokenDefinitions/ITokenDefinition.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Builder; 2 | 3 | namespace MagicGradients.Parser.TokenDefinitions 4 | { 5 | public interface ITokenDefinition 6 | { 7 | bool IsMatch(string token); 8 | 9 | void Parse(CssReader reader, GradientBuilder builder); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Platform/GradientView.Mac.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using Microsoft.Maui.Graphics.Platform; 3 | 4 | namespace MagicGradients 5 | { 6 | public partial class GradientView : PlatformGraphicsView 7 | { 8 | public GradientView() 9 | { 10 | // TODO: set ViewWidth to Bounds.Width 11 | Drawable = new GradientDrawable(this); 12 | } 13 | 14 | partial void InvalidateNative() 15 | { 16 | InvalidateDrawable(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/Platform/GradientView.iOS.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using Microsoft.Maui.Graphics.Platform; 3 | 4 | namespace MagicGradients 5 | { 6 | public partial class GradientView : PlatformGraphicsView 7 | { 8 | public GradientView() 9 | { 10 | // TODO: set ViewWidth to Bounds.Width 11 | Drawable = new GradientDrawable(this); 12 | } 13 | 14 | partial void InvalidateNative() 15 | { 16 | InvalidateDrawable(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MagicGradients.Core/TextEnums.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Converters; 2 | using System; 3 | using System.ComponentModel; 4 | 5 | namespace MagicGradients 6 | { 7 | [Flags] 8 | [TypeConverter(typeof(FontAttributesTypeConverter))] 9 | public enum FontAttributes 10 | { 11 | None = 0, 12 | Bold = 1 << 0, 13 | Italic = 1 << 1 14 | } 15 | 16 | public enum TextAlignment 17 | { 18 | Start, 19 | Center, 20 | End 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.Skia/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Internals; 3 | 4 | [assembly: Preserve] 5 | [assembly: XmlnsDefinition("http://magic.com/schemas/gradients", "MagicGradients.Forms.Skia")] -------------------------------------------------------------------------------- /src/MagicGradients.Forms.Skia/GlobalSetupExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Forms.Skia 2 | { 3 | public static class GlobalSetupExtensions 4 | { 5 | public static GlobalSetup UseFormsSkiaGradients(this GlobalSetup setup) 6 | { 7 | // Init() as GlobalSetup extension 8 | return setup; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.Skia/MagicGradients.Forms.Skia.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.Skia/Masks/SkiaEllipseMaskPainter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using MagicGradients.Masks; 3 | using Microsoft.Maui.Graphics.Skia; 4 | using SkiaSharp; 5 | 6 | namespace MagicGradients.Forms.Skia.Masks 7 | { 8 | public class SkiaEllipseMaskPainter : SkiaRectangleMaskPainter, IMaskPainter 9 | { 10 | public void Clip(IEllipseMask mask, DrawContext context) 11 | { 12 | if (!mask.IsActive) 13 | return; 14 | 15 | var ellipse = GetEllipse(mask, context); 16 | ClipRoundRect(ellipse, mask, context); 17 | } 18 | 19 | private SKRoundRect GetEllipse(IEllipseMask mask, DrawContext context) 20 | { 21 | var bounds = mask.Size.GetDrawRectangle(context.CanvasRect, context.PixelScaling).AsSKRect(); 22 | return new SKRoundRect(bounds, bounds.Width / 2, bounds.Height / 2); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.Skia/Masks/SkiaPathMaskPainter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using MagicGradients.Forms.Skia.Drawing; 3 | using MagicGradients.Masks; 4 | using Microsoft.Maui.Graphics.Skia; 5 | using SkiaSharp; 6 | 7 | namespace MagicGradients.Forms.Skia.Masks 8 | { 9 | public class SkiaPathMaskPainter : IMaskPainter 10 | { 11 | public void Clip(IPathMask mask, DrawContext context) 12 | { 13 | if (!mask.IsActive || string.IsNullOrEmpty(mask.Data)) 14 | return; 15 | 16 | using var path = SKPath.ParseSvgPathData(mask.Data); 17 | path.GetTightBounds(out var bounds); 18 | 19 | var canvas = context.GetNativeCanvas(); 20 | 21 | using var layout = ShapeMaskLayout.Create(mask, bounds.AsRectangleF(), context, true); 22 | canvas.ClipPath(path, mask.ClipMode.ToSkOperation()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.SkiaViews/CanvasLock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SkiaSharp; 3 | 4 | namespace MagicGradients.Forms.SkiaViews 5 | { 6 | public class CanvasLock : IDisposable 7 | { 8 | private readonly SKCanvas _canvas; 9 | private readonly SKMatrix _matrix; 10 | 11 | public CanvasLock(SKCanvas canvas) 12 | { 13 | _canvas = canvas; 14 | _matrix = canvas.TotalMatrix; 15 | } 16 | 17 | public void Dispose() 18 | { 19 | _canvas.SetMatrix(_matrix); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.SkiaViews/Drawing/GradientPainter.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace MagicGradients.Forms.SkiaViews.Drawing 4 | { 5 | public class GradientPainter 6 | { 7 | protected IGradientStop[] GetRenderStops(IGradient gradient) 8 | { 9 | var stops = gradient.GetStops(); 10 | if (stops.Count == 1) 11 | { 12 | return new[] 13 | { 14 | new GradientStop { RenderOffset = 0, Color = stops[0].Color }, 15 | new GradientStop { RenderOffset = 1, Color = stops[0].Color } 16 | }; 17 | } 18 | 19 | return stops.OrderBy(x => x.RenderOffset).ToArray(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.SkiaViews/MagicGradients.Forms.SkiaViews.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.SkiaViews/Masks/EllipseMaskPainter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using MagicGradients.Masks; 3 | using SkiaSharp; 4 | using DrawContext = MagicGradients.Forms.SkiaViews.Drawing.DrawContext; 5 | 6 | namespace MagicGradients.Forms.SkiaViews.Masks 7 | { 8 | public class EllipseMaskPainter : RectangleMaskPainter, IMaskPainter 9 | { 10 | public void Clip(IEllipseMask mask, DrawContext context) 11 | { 12 | if (!mask.IsActive) 13 | return; 14 | 15 | var ellipse = GetEllipse(mask, context); 16 | ClipRoundRect(ellipse, mask, context); 17 | } 18 | 19 | private SKRoundRect GetEllipse(IEllipseMask mask, DrawContext context) 20 | { 21 | var bounds = GetBounds(mask.Size, context); 22 | return new SKRoundRect(bounds, (float)bounds.Width / 2, (float)bounds.Height / 2); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms.SkiaViews/Masks/PathMaskPainter.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Drawing; 2 | using MagicGradients.Masks; 3 | using SkiaSharp; 4 | using DrawContext = MagicGradients.Forms.SkiaViews.Drawing.DrawContext; 5 | 6 | namespace MagicGradients.Forms.SkiaViews.Masks 7 | { 8 | public class PathMaskPainter : GradientMaskPainter, IMaskPainter 9 | { 10 | public void Clip(IPathMask mask, DrawContext context) 11 | { 12 | if (!mask.IsActive || string.IsNullOrEmpty(mask.Data)) 13 | return; 14 | 15 | using var path = SKPath.ParseSvgPathData(mask.Data); 16 | path.GetTightBounds(out var bounds); 17 | 18 | using var canvasLock = new CanvasLock(context.Canvas); 19 | LayoutBounds(mask, bounds, context, true); 20 | context.Canvas.ClipPath(path, mask.ClipMode.ToSkOperation()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/ITweener.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Forms.Animation 2 | { 3 | public interface ITweener 4 | { 5 | TValue Tween(TValue from, TValue to, double progress); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/Interactivity/BeginAnimation.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Forms.Animation 4 | { 5 | public class BeginAnimation : TriggerAction 6 | { 7 | public Timeline Animation { get; set; } 8 | 9 | protected override void Invoke(VisualElement sender) 10 | { 11 | if (Animation == null) 12 | return; 13 | 14 | if (Animation.Target == null) 15 | Animation.Target = sender; 16 | 17 | Animation.Begin(sender); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/Interactivity/EndAnimation.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Forms.Animation 4 | { 5 | public class EndAnimation : TriggerAction 6 | { 7 | public Timeline Animation { get; set; } 8 | 9 | protected override void Invoke(VisualElement sender) 10 | { 11 | Animation?.End(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/KeyFrame.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Forms.Animation 4 | { 5 | public class KeyFrame 6 | { 7 | public int KeyTime { get; set; } 8 | public Easing Easing { get; set; } = Easing.Linear; 9 | } 10 | 11 | public class KeyFrame : KeyFrame 12 | { 13 | public TValue Value { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/Library/DoubleAnimation.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Forms.Animation 2 | { 3 | public class DoubleTweener : ITweener 4 | { 5 | public double Tween(double @from, double to, double progress) 6 | { 7 | return from + (to - from) * progress; 8 | } 9 | } 10 | 11 | public class DoubleAnimation : PropertyAnimation 12 | { 13 | public override ITweener Tweener { get; } = new DoubleTweener(); 14 | } 15 | 16 | public class DoubleAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 17 | { 18 | public override ITweener Tweener { get; } = new DoubleTweener(); 19 | } 20 | 21 | public class DoubleKeyFrame : KeyFrame { } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/Library/IntegerAnimation.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Forms.Animation 2 | { 3 | public class IntegerTweener : ITweener 4 | { 5 | public int Tween(int @from, int to, double progress) 6 | { 7 | return (int)(from + (to - from) * progress); 8 | } 9 | } 10 | 11 | public class IntegerAnimation : PropertyAnimation 12 | { 13 | public override ITweener Tweener { get; } = new IntegerTweener(); 14 | } 15 | 16 | public class IntegerAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 17 | { 18 | public override ITweener Tweener { get; } = new IntegerTweener(); 19 | } 20 | 21 | public class IntegerKeyFrame : KeyFrame { } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/Library/OffsetAnimation.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Forms.Animation 2 | { 3 | public class OffsetTweener : ITweener 4 | { 5 | public Offset Tween(Offset @from, Offset to, double progress) 6 | { 7 | return new Offset(from.Value + (to.Value - from.Value) * progress, from.Type); 8 | } 9 | } 10 | 11 | public class OffsetAnimation : PropertyAnimation 12 | { 13 | public override ITweener Tweener { get; } = new OffsetTweener(); 14 | } 15 | 16 | public class OffsetAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 17 | { 18 | public override ITweener Tweener { get; } = new OffsetTweener(); 19 | } 20 | 21 | public class OffsetKeyFrame : KeyFrame { } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/Library/PointAnimation.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Forms.Animation 4 | { 5 | public class PointTweener : ITweener 6 | { 7 | public Point Tween(Point @from, Point to, double progress) 8 | { 9 | return new Point( 10 | from.X + (to.X - from.X) * progress, 11 | from.Y + (to.Y - from.Y) * progress); 12 | } 13 | } 14 | 15 | public class PointAnimation : PropertyAnimation 16 | { 17 | public override ITweener Tweener { get; } = new PointTweener(); 18 | } 19 | 20 | public class PointAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 21 | { 22 | public override ITweener Tweener { get; } = new PointTweener(); 23 | } 24 | 25 | public class PointKeyFrame : KeyFrame { } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Animation/RepeatBehavior.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace MagicGradients.Forms.Animation 4 | { 5 | [TypeConverter(typeof(RepeatBehaviorTypeConverter))] 6 | public struct RepeatBehavior 7 | { 8 | public RepeatBehavior(RepeatBehaviorType type, int count) 9 | { 10 | Type = type; 11 | Count = count; 12 | } 13 | 14 | public RepeatBehaviorType Type { get; set; } 15 | public int Count { get; set; } 16 | } 17 | 18 | public enum RepeatBehaviorType 19 | { 20 | Count, Forever 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Internals; 3 | 4 | [assembly: Preserve] 5 | [assembly: XmlnsDefinition("http://magic.com/schemas/gradients", "MagicGradients.Forms")] 6 | [assembly: XmlnsDefinition("http://magic.com/schemas/gradients", "MagicGradients.Forms.Animation")] 7 | [assembly: XmlnsDefinition("http://magic.com/schemas/gradients", "MagicGradients.Forms.Masks")] 8 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/GlobalSetupExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Forms 2 | { 3 | public static class GlobalSetupExtensions 4 | { 5 | public static GlobalSetup UseFormsGradients(this GlobalSetup setup) 6 | { 7 | // Init() as GlobalSetup extension 8 | return setup; 9 | } 10 | 11 | public static GlobalSetup UseCssStyles(this GlobalSetup setup) 12 | { 13 | StyleSheets.RegisterStyle("background", typeof(TControl), nameof(GradientControl.GradientSourceProperty)); 14 | StyleSheets.RegisterStyle("background-size", typeof(TControl), nameof(GradientControl.GradientSizeProperty)); 15 | StyleSheets.RegisterStyle("background-repeat", typeof(TControl), nameof(GradientControl.GradientRepeatProperty)); 16 | 17 | return setup; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/GradientElement.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Forms 4 | { 5 | public abstract class GradientElement : BindableObject, IGradientVisualElement 6 | { 7 | public IGradientVisualElement Parent { get; set; } 8 | 9 | public void InvalidateCanvas() 10 | { 11 | Parent?.InvalidateCanvas(); 12 | } 13 | 14 | protected override void OnPropertyChanged(string propertyName = null) 15 | { 16 | base.OnPropertyChanged(propertyName); 17 | InvalidateCanvas(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/GraphicsView.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | using Xamarin.Forms; 3 | 4 | namespace MagicGradients.Forms 5 | { 6 | public class GraphicsView : View 7 | { 8 | public static readonly BindableProperty DrawableProperty = BindableProperty.Create( 9 | nameof(Drawable), 10 | typeof(IDrawable), 11 | typeof(GraphicsView)); 12 | 13 | public IDrawable Drawable 14 | { 15 | get => (IDrawable) GetValue(DrawableProperty); 16 | set => SetValue(DrawableProperty, value); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/MagicGradients.Forms/LinearGradient.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Forms 4 | { 5 | public class LinearGradient : Gradient, ILinearGradient 6 | { 7 | public static readonly BindableProperty AngleProperty = BindableProperty.Create( 8 | nameof(Angle), typeof(double), typeof(LinearGradient), 0d); 9 | 10 | public double Angle 11 | { 12 | get => (double)GetValue(AngleProperty); 13 | set => SetValue(AngleProperty, value); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/MagicGradients.Forms.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.1;netstandard2.0;Xamarin.iOS10;MonoAndroid12.0;Xamarin.Mac20 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Masks/EllipseMask.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Masks; 2 | 3 | namespace MagicGradients.Forms.Masks 4 | { 5 | public class EllipseMask : RectangleMask, IEllipseMask 6 | { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Masks/MarkupExtensions/EllipseExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace MagicGradients.Forms.Masks 6 | { 7 | [ContentProperty(nameof(Size))] 8 | public class EllipseExtension : MaskExtension, IMarkupExtension 9 | { 10 | public Dimensions Size { get; set; } = Dimensions.Prop(1, 1); 11 | 12 | public EllipseMask ProvideValue(IServiceProvider serviceProvider) 13 | { 14 | var mask = new EllipseMask { Size = Size }; 15 | 16 | FillValues(mask); 17 | 18 | return mask; 19 | } 20 | 21 | object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) 22 | { 23 | return ProvideValue(serviceProvider); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Masks/MarkupExtensions/MaskExtension.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Masks; 2 | 3 | namespace MagicGradients.Forms.Masks 4 | { 5 | public class MaskExtension 6 | { 7 | public ClipMode ClipMode { get; set; } 8 | public Stretch Stretch { get; set; } 9 | 10 | protected void FillValues(GradientMask mask) 11 | { 12 | mask.ClipMode = ClipMode; 13 | mask.Stretch = Stretch; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Masks/MarkupExtensions/PathExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace MagicGradients.Forms.Masks 6 | { 7 | [ContentProperty(nameof(Data))] 8 | public class PathExtension : MaskExtension, IMarkupExtension 9 | { 10 | public string Data { get; set; } 11 | 12 | public PathMask ProvideValue(IServiceProvider serviceProvider) 13 | { 14 | var mask = new PathMask { Data = Data }; 15 | 16 | FillValues(mask); 17 | 18 | return mask; 19 | } 20 | 21 | object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) 22 | { 23 | return ProvideValue(serviceProvider); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Masks/PathMask.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Masks; 2 | using Xamarin.Forms; 3 | 4 | namespace MagicGradients.Forms.Masks 5 | { 6 | public class PathMask : GradientMask, IPathMask 7 | { 8 | public static readonly BindableProperty DataProperty = BindableProperty.Create(nameof(Data), 9 | typeof(string), typeof(PathMask)); 10 | 11 | public string Data 12 | { 13 | get => (string)GetValue(DataProperty); 14 | set => SetValue(DataProperty, value); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/Masks/RectangleMask.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Masks; 2 | using Xamarin.Forms; 3 | 4 | namespace MagicGradients.Forms.Masks 5 | { 6 | public class RectangleMask : GradientMask, IRectangleMask 7 | { 8 | public static readonly BindableProperty SizeProperty = BindableProperty.Create(nameof(Size), 9 | typeof(Dimensions), typeof(RectangleMask), Dimensions.Prop(1, 1)); 10 | 11 | public static readonly BindableProperty CornersProperty = BindableProperty.Create(nameof(Corners), 12 | typeof(Corners), typeof(RectangleMask)); 13 | 14 | public Dimensions Size 15 | { 16 | get => (Dimensions)GetValue(SizeProperty); 17 | set => SetValue(SizeProperty, value); 18 | } 19 | 20 | public Corners Corners 21 | { 22 | get => (Corners)GetValue(CornersProperty); 23 | set => SetValue(CornersProperty, value); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients.Forms/ViewExtensions.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Forms 4 | { 5 | public static class ViewExtensions 6 | { 7 | public static bool TryFindParent(this Element element, out TParent parent) where TParent : Element 8 | { 9 | while (element.Parent != null) 10 | { 11 | if (element.Parent is TParent foundParent) 12 | { 13 | parent = foundParent; 14 | return true; 15 | } 16 | 17 | element = element.Parent; 18 | } 19 | 20 | parent = null; 21 | return false; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/Build/MagicGradients.Toolkit.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/Build/PreserveMagicToolkit.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Toolkit.Properties; 2 | 3 | [assembly: PreserveAssembly] -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/Controls/TextContent.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Toolkit.Controls 4 | { 5 | public class TextContent : Label 6 | { 7 | public TextContent() 8 | { 9 | HorizontalOptions = LayoutOptions.Fill; 10 | VerticalOptions = LayoutOptions.Fill; 11 | HorizontalTextAlignment = TextAlignment.Center; 12 | VerticalTextAlignment = TextAlignment.Center; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/Controls/TextContentTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Xaml; 3 | 4 | namespace MagicGradients.Toolkit.Controls 5 | { 6 | [TypeConversion(typeof(TextContent))] 7 | public class TextContentTypeConverter : TypeConverter 8 | { 9 | public override object ConvertFromInvariantString(string value) 10 | { 11 | return new TextContent 12 | { 13 | Text = value 14 | }; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/Initializer.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Toolkit 2 | { 3 | public static class Initializer 4 | { 5 | public static void Init(){} 6 | } 7 | } -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/MagicGradients.Toolkit.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | MSBuild:UpdateDesignTimeXaml 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xamarin.Forms.Internals; 3 | 4 | [assembly: Preserve] 5 | [assembly: XmlnsDefinition("http://magic.com/schemas/toolkit", "MagicGradients.Toolkit")] 6 | [assembly: XmlnsDefinition("http://magic.com/schemas/toolkit", "MagicGradients.Toolkit.Controls")] 7 | -------------------------------------------------------------------------------- /src/MagicGradients.Toolkit/Properties/PreserveAssemblyAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace MagicGradients.Toolkit.Properties 5 | { 6 | [EditorBrowsable(EditorBrowsableState.Never)] 7 | [AttributeUsage(AttributeTargets.Assembly)] 8 | public sealed class PreserveAssemblyAttribute : Attribute 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Interactivity/BeginAnimation.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | public class BeginAnimation : TriggerAction 6 | { 7 | public Timeline Animation { get; set; } 8 | 9 | protected override void Invoke(VisualElement sender) 10 | { 11 | if (Animation == null) 12 | return; 13 | 14 | if (Animation.Target == null) 15 | Animation.Target = sender; 16 | 17 | Animation.Begin(sender); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Interactivity/EndAnimation.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | public class EndAnimation : TriggerAction 6 | { 7 | public Timeline Animation { get; set; } 8 | 9 | protected override void Invoke(VisualElement sender) 10 | { 11 | Animation?.End(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/KeyFrame.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | public class KeyFrame 6 | { 7 | public int KeyTime { get; set; } 8 | public Easing Easing { get; set; } = Easing.Linear; 9 | } 10 | 11 | public class KeyFrame : KeyFrame 12 | { 13 | public TValue Value { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Library/ColorAnimation.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Animation.Tween; 2 | using Xamarin.Forms; 3 | 4 | namespace MagicGradients.Animation 5 | { 6 | public class ColorAnimation : PropertyAnimation 7 | { 8 | public override ITweener Tweener { get; } = new ColorTweener(); 9 | } 10 | 11 | public class ColorAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 12 | { 13 | public override ITweener Tweener { get; } = new ColorTweener(); 14 | } 15 | 16 | public class ColorKeyFrame : KeyFrame 17 | { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Library/DimensionsAnimation.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Animation.Tween; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | public class DimensionsAnimation : PropertyAnimation 6 | { 7 | public override ITweener Tweener { get; } = new DimensionsTweener(); 8 | } 9 | 10 | public class DimensionsAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 11 | { 12 | public override ITweener Tweener { get; } = new DimensionsTweener(); 13 | } 14 | 15 | public class DimensionsKeyFrame : KeyFrame 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Library/DoubleAnimation.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Animation.Tween; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | public class DoubleAnimation : PropertyAnimation 6 | { 7 | public override ITweener Tweener { get; } = new DoubleTweener(); 8 | } 9 | 10 | public class DoubleAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 11 | { 12 | public override ITweener Tweener { get; } = new DoubleTweener(); 13 | } 14 | 15 | public class DoubleKeyFrame : KeyFrame 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Library/IntegerAnimation.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Animation.Tween; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | public class IntegerAnimation : PropertyAnimation 6 | { 7 | public override ITweener Tweener { get; } = new IntegerTweener(); 8 | } 9 | 10 | public class IntegerAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 11 | { 12 | public override ITweener Tweener { get; } = new IntegerTweener(); 13 | } 14 | 15 | public class IntegerKeyFrame : KeyFrame 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Library/OffsetAnimation.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Animation.Tween; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | public class OffsetAnimation : PropertyAnimation 6 | { 7 | public override ITweener Tweener { get; } = new OffsetTweener(); 8 | } 9 | 10 | public class OffsetAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 11 | { 12 | public override ITweener Tweener { get; } = new OffsetTweener(); 13 | } 14 | 15 | public class OffsetKeyFrame : KeyFrame 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Library/PointAnimation.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Animation.Tween; 2 | using Xamarin.Forms; 3 | 4 | namespace MagicGradients.Animation 5 | { 6 | public class PointAnimation : PropertyAnimation 7 | { 8 | public override ITweener Tweener { get; } = new PointTweener(); 9 | } 10 | 11 | public class PointAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 12 | { 13 | public override ITweener Tweener { get; } = new PointTweener(); 14 | } 15 | 16 | public class PointKeyFrame : KeyFrame 17 | { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Library/ThicknessAnimation.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Animation.Tween; 2 | using Xamarin.Forms; 3 | 4 | namespace MagicGradients.Animation 5 | { 6 | public class ThicknessAnimation : PropertyAnimation 7 | { 8 | public override ITweener Tweener { get; } = new ThicknessTweener(); 9 | } 10 | 11 | public class ThicknessAnimationUsingKeyFrames : PropertyAnimationUsingKeyFrames 12 | { 13 | public override ITweener Tweener { get; } = new ThicknessTweener(); 14 | } 15 | 16 | public class ThicknessKeyFrame : KeyFrame 17 | { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/RepeatBehavior.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Animation 4 | { 5 | [TypeConverter(typeof(RepeatBehaviorTypeConverter))] 6 | public struct RepeatBehavior 7 | { 8 | public RepeatBehavior(RepeatBehaviorType type, int count) 9 | { 10 | Type = type; 11 | Count = count; 12 | } 13 | 14 | public RepeatBehaviorType Type { get; set; } 15 | public int Count { get; set; } 16 | } 17 | 18 | public enum RepeatBehaviorType 19 | { 20 | Count, Forever 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/ColorTweener.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Animation.Tween 4 | { 5 | public class ColorTweener : ITweener 6 | { 7 | public Color Tween(Color @from, Color to, double progress) 8 | { 9 | return Color.FromRgb( 10 | from.R + (to.R - from.R) * progress, 11 | from.G + (to.G - from.G) * progress, 12 | from.B + (to.B - from.B) * progress); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/DimensionsTweener.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Animation.Tween 2 | { 3 | public class DimensionsTweener : ITweener 4 | { 5 | public Dimensions Tween(Dimensions @from, Dimensions to, double progress) 6 | { 7 | var typeWidth = from.Width.Type; 8 | var typeHeight = from.Height.Type; 9 | 10 | return new Dimensions( 11 | new Offset(from.Width.Value + (to.Width.Value - from.Width.Value) * progress, typeWidth), 12 | new Offset(from.Height.Value + (to.Height.Value - from.Height.Value) * progress, typeHeight)); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/DoubleTweener.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Animation.Tween 2 | { 3 | public class DoubleTweener : ITweener 4 | { 5 | public double Tween(double @from, double to, double progress) 6 | { 7 | return from + (to - from) * progress; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/ITweener.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Animation.Tween 2 | { 3 | public interface ITweener 4 | { 5 | TValue Tween(TValue from, TValue to, double progress); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/IntegerTweener.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Animation.Tween 2 | { 3 | public class IntegerTweener : ITweener 4 | { 5 | public int Tween(int @from, int to, double progress) 6 | { 7 | return (int)(from + (to - from) * progress); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/OffsetTweener.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Animation.Tween 2 | { 3 | public class OffsetTweener : ITweener 4 | { 5 | public Offset Tween(Offset @from, Offset to, double progress) 6 | { 7 | return new Offset(from.Value + (to.Value - from.Value) * progress, from.Type); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/PointTweener.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Animation.Tween 4 | { 5 | public class PointTweener : ITweener 6 | { 7 | public Point Tween(Point @from, Point to, double progress) 8 | { 9 | return new Point( 10 | from.X + (to.X - from.X) * progress, 11 | from.Y + (to.Y - from.Y) * progress); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/MagicGradients/Animation/Tween/ThicknessTweener.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Animation.Tween 4 | { 5 | public class ThicknessTweener : ITweener 6 | { 7 | public Thickness Tween(Thickness @from, Thickness to, double progress) 8 | { 9 | return new Thickness( 10 | from.Left + (to.Left - from.Left) * progress, 11 | from.Top + (to.Top - from.Top) * progress, 12 | from.Right + (to.Right - from.Right) * progress, 13 | from.Bottom + (to.Bottom - from.Bottom) * progress); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/MagicGradients/Build/MagicGradients.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /src/MagicGradients/Build/PreserveMagicGradients.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Properties; 2 | 3 | [assembly: PreserveAssembly] -------------------------------------------------------------------------------- /src/MagicGradients/Builder/CssGradientBuilder.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Parser; 2 | using System; 3 | using System.Linq; 4 | 5 | namespace MagicGradients.Builder 6 | { 7 | public class CssGradientBuilder : StopsBuilder, IChildBuilder 8 | { 9 | protected override CssGradientBuilder Instance => this; 10 | 11 | internal string StyleSheet { get; set; } 12 | 13 | public CssGradientBuilder(string styleSheet) 14 | { 15 | StyleSheet = styleSheet; 16 | } 17 | 18 | public Gradient Construct() 19 | { 20 | var parsed = new CssGradientParser().ParseCss(StyleSheet); 21 | if (parsed.Length != 1) 22 | { 23 | throw new InvalidOperationException("StyleSheet must contain single gradient function."); 24 | } 25 | return parsed.First(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/MagicGradients/Builder/DimenOptions.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Builder 2 | { 3 | public class DimenOptions 4 | { 5 | public bool IsProportional { get; private set; } 6 | 7 | public DimenOptions Absolute() 8 | { 9 | IsProportional = false; 10 | return this; 11 | } 12 | 13 | public DimenOptions Proportional() 14 | { 15 | IsProportional = true; 16 | return this; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/MagicGradients/Builder/GradientBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Builder 2 | { 3 | public static class GradientBuilderExtensions 4 | { 5 | public static IGradientSource ToSource(this GradientBuilder builder) 6 | { 7 | return new GradientCollection 8 | { 9 | Gradients = new GradientElements(builder.Build()) 10 | }; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/MagicGradients/Builder/IChildBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Builder 2 | { 3 | public interface IChildBuilder 4 | { 5 | StopsFactory StopsFactory { get; } 6 | Gradient Construct(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/MagicGradients/Builder/StopsFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Xamarin.Forms; 3 | 4 | namespace MagicGradients.Builder 5 | { 6 | public class StopsFactory 7 | { 8 | public List Stops { get; } = new List(); 9 | 10 | public void CreateStop(Color color, Offset? offset = null) 11 | { 12 | var stop = new GradientStop 13 | { 14 | Color = color, 15 | Offset = offset ?? Offset.Empty 16 | }; 17 | 18 | Stops.Add(stop); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/MagicGradients/GradientElement.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients 4 | { 5 | public abstract class GradientElement : BindableObject, IGradientVisualElement 6 | { 7 | public IGradientVisualElement Parent { get; set; } 8 | 9 | public void InvalidateCanvas() 10 | { 11 | Parent?.InvalidateCanvas(); 12 | } 13 | 14 | protected override void OnPropertyChanged(string propertyName = null) 15 | { 16 | base.OnPropertyChanged(propertyName); 17 | InvalidateCanvas(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MagicGradients/GradientMath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MagicGradients 4 | { 5 | public static class GradientMath 6 | { 7 | public static double ToRadians(double degrees) => (Math.PI / 180) * degrees; 8 | public static double FromDegrees(double degrees) => (180 + degrees) % 360; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/MagicGradients/IGradientControl.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Masks; 2 | 3 | namespace MagicGradients 4 | { 5 | public interface IGradientControl 6 | { 7 | IGradientSource GradientSource { get; set; } 8 | Dimensions GradientSize { get; set; } 9 | BackgroundRepeat GradientRepeat { get; set; } 10 | GradientMask Mask { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/MagicGradients/IGradientSource.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Xaml; 2 | using System.Collections.Generic; 3 | using Xamarin.Forms; 4 | 5 | namespace MagicGradients 6 | { 7 | [TypeConverter(typeof(CssGradientSourceTypeConverter))] 8 | public interface IGradientSource 9 | { 10 | IEnumerable GetGradients(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/MagicGradients/IGradientVisualElement.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients 2 | { 3 | public interface IGradientVisualElement 4 | { 5 | void InvalidateCanvas(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/MagicGradients/MagicGradients.csproj.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True 3 | True 4 | True -------------------------------------------------------------------------------- /src/MagicGradients/Masks/CanvasLock.cs: -------------------------------------------------------------------------------- 1 | using SkiaSharp; 2 | using System; 3 | 4 | namespace MagicGradients.Masks 5 | { 6 | public class CanvasLock : IDisposable 7 | { 8 | private readonly SKCanvas _canvas; 9 | private readonly SKMatrix _matrix; 10 | 11 | public CanvasLock(SKCanvas canvas) 12 | { 13 | _canvas = canvas; 14 | _matrix = canvas.TotalMatrix; 15 | } 16 | 17 | public void Dispose() 18 | { 19 | _canvas.SetMatrix(_matrix); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/MagicGradients/Masks/EllipseMask.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Renderers; 2 | using SkiaSharp; 3 | 4 | namespace MagicGradients.Masks 5 | { 6 | public class EllipseMask : RectangleMask 7 | { 8 | public override void Clip(RenderContext context) 9 | { 10 | if(!IsActive) 11 | return; 12 | 13 | var ellipse = GetEllipse(context); 14 | ClipRoundRect(context, ellipse); 15 | } 16 | 17 | private SKRoundRect GetEllipse(RenderContext context) 18 | { 19 | var width = (int)Size.Width.GetDrawPixels(context.CanvasRect.Width, context.PixelScaling); 20 | var height = (int)Size.Height.GetDrawPixels(context.CanvasRect.Height, context.PixelScaling); 21 | 22 | var bounds = new SKRectI(0, 0, width, height); 23 | return new SKRoundRect(bounds, (float)width / 2, (float)height / 2); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients/Masks/GradientMaskEnum.cs: -------------------------------------------------------------------------------- 1 | using SkiaSharp; 2 | 3 | namespace MagicGradients.Masks 4 | { 5 | public enum Stretch 6 | { 7 | None, 8 | AspectFit, 9 | AspectFill, 10 | Fill 11 | } 12 | 13 | public enum ClipMode 14 | { 15 | Include, 16 | Exclude 17 | } 18 | 19 | public static class ClipModeExtensions 20 | { 21 | public static SKClipOperation ToSkOperation(this ClipMode mode) 22 | { 23 | return mode == ClipMode.Include ? SKClipOperation.Intersect : SKClipOperation.Difference; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients/Masks/MarkupExtensions/EllipseExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace MagicGradients.Masks 6 | { 7 | [ContentProperty(nameof(Size))] 8 | public class EllipseExtension : MaskExtension, IMarkupExtension 9 | { 10 | public Dimensions Size { get; set; } = Dimensions.Prop(1, 1); 11 | 12 | public EllipseMask ProvideValue(IServiceProvider serviceProvider) 13 | { 14 | var mask = new EllipseMask { Size = Size }; 15 | 16 | FillValues(mask); 17 | 18 | return mask; 19 | } 20 | 21 | object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) 22 | { 23 | return ProvideValue(serviceProvider); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients/Masks/MarkupExtensions/MaskExtension.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Masks 2 | { 3 | public class MaskExtension 4 | { 5 | public ClipMode ClipMode { get; set; } 6 | public Stretch Stretch { get; set; } 7 | 8 | protected void FillValues(GradientMask mask) 9 | { 10 | mask.ClipMode = ClipMode; 11 | mask.Stretch = Stretch; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/MagicGradients/Masks/MarkupExtensions/PathExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace MagicGradients.Masks 6 | { 7 | [ContentProperty(nameof(Data))] 8 | public class PathExtension : MaskExtension, IMarkupExtension 9 | { 10 | public string Data { get; set; } 11 | 12 | public PathMask ProvideValue(IServiceProvider serviceProvider) 13 | { 14 | var mask = new PathMask { Data = Data }; 15 | 16 | FillValues(mask); 17 | 18 | return mask; 19 | } 20 | 21 | object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) 22 | { 23 | return ProvideValue(serviceProvider); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients/Masks/MarkupExtensions/RectangleExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace MagicGradients.Masks 6 | { 7 | [ContentProperty(nameof(Size))] 8 | public class RectangleExtension : MaskExtension, IMarkupExtension 9 | { 10 | public Dimensions Size { get; set; } = Dimensions.Prop(1, 1); 11 | public Corners Corners { get; set; } 12 | 13 | public RectangleMask ProvideValue(IServiceProvider serviceProvider) 14 | { 15 | var mask = new RectangleMask 16 | { 17 | Size = Size, 18 | Corners = Corners 19 | }; 20 | 21 | FillValues(mask); 22 | 23 | return mask; 24 | } 25 | 26 | object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) 27 | { 28 | return ProvideValue(serviceProvider); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/MagicGradients/Parser/CssToken.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Parser 2 | { 3 | public class CssToken 4 | { 5 | public const string LinearGradient = "linear-gradient"; 6 | public const string RepeatingLinearGradient = "repeating-linear-gradient"; 7 | public const string RadialGradient = "radial-gradient"; 8 | public const string RepeatingRadialGradient = "repeating-radial-gradient"; 9 | public const string Rgb = "rgb"; 10 | public const string Rgba = "rgba"; 11 | public const string Hsl = "hsl"; 12 | public const string Hsla = "hsla"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/MagicGradients/Parser/TokenDefinitions/ColorDefinition.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Xaml; 2 | using System.Collections.Generic; 3 | using Xamarin.Forms; 4 | 5 | namespace MagicGradients.Parser.TokenDefinitions 6 | { 7 | public class ColorDefinition 8 | { 9 | protected ColorTypeConverter ColorConverter { get; } = new ColorTypeConverter(); 10 | protected OffsetTypeConverter OffsetConverter { get; } = new OffsetTypeConverter(); 11 | 12 | protected List GetOffsets(string[] tokens) 13 | { 14 | var offsets = new List(); 15 | 16 | foreach (var token in tokens) 17 | { 18 | if (OffsetConverter.TryExtractOffset(token, out var offset)) 19 | offsets.Add(offset); 20 | } 21 | 22 | return offsets; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/MagicGradients/Parser/TokenDefinitions/ITokenDefinition.cs: -------------------------------------------------------------------------------- 1 | using MagicGradients.Builder; 2 | 3 | namespace MagicGradients.Parser.TokenDefinitions 4 | { 5 | public interface ITokenDefinition 6 | { 7 | bool IsMatch(string token); 8 | 9 | void Parse(CssReader reader, GradientBuilder builder); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/MagicGradients/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Internals; 4 | 5 | [assembly: InternalsVisibleTo("MagicGradients.Tests")] 6 | 7 | [assembly: Preserve] 8 | [assembly: XmlnsDefinition("http://magic.com/schemas/gradients", "MagicGradients")] 9 | [assembly: XmlnsDefinition("http://magic.com/schemas/gradients", "MagicGradients.Animation")] 10 | [assembly: XmlnsDefinition("http://magic.com/schemas/gradients", "MagicGradients.Masks")] 11 | -------------------------------------------------------------------------------- /src/MagicGradients/Properties/PreserveAssemblyAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace MagicGradients.Properties 5 | { 6 | [EditorBrowsable(EditorBrowsableState.Never)] 7 | [AttributeUsage(AttributeTargets.Assembly)] 8 | public sealed class PreserveAssemblyAttribute : Attribute 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/MagicGradients/Renderers/IGradientShader.cs: -------------------------------------------------------------------------------- 1 | using SkiaSharp; 2 | 3 | namespace MagicGradients.Renderers 4 | { 5 | public interface IGradientShader 6 | { 7 | SKShader Create(RenderContext context); 8 | double CalculateRenderOffset(double offset, int width, int height); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/MagicGradients/Renderers/RenderContext.cs: -------------------------------------------------------------------------------- 1 | using SkiaSharp; 2 | 3 | namespace MagicGradients.Renderers 4 | { 5 | public class RenderContext 6 | { 7 | public SKCanvas Canvas { get; set; } 8 | public SKPaint Paint { get; set; } 9 | public SKRectI CanvasRect { get; set; } 10 | public SKRectI RenderRect { get; set; } 11 | public double PixelScaling { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/MagicGradients/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace MagicGradients 5 | { 6 | public static class StringExtensions 7 | { 8 | public static bool TryExtractNumber(this string token, string unit, out double result) 9 | { 10 | if (token.EndsWith(unit)) 11 | { 12 | var index = token.LastIndexOf(unit, StringComparison.OrdinalIgnoreCase); 13 | var number = token.Substring(0, index); 14 | 15 | if (double.TryParse(number, NumberStyles.Any, CultureInfo.InvariantCulture, out var value)) 16 | { 17 | result = value; 18 | return true; 19 | } 20 | } 21 | 22 | result = 0; 23 | return false; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MagicGradients/Xaml/BackgroundRepeatTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace MagicGradients.Xaml 6 | { 7 | [TypeConversion(typeof(BackgroundRepeat))] 8 | public class BackgroundRepeatTypeConverter : TypeConverter 9 | { 10 | public override object ConvertFromInvariantString(string value) 11 | { 12 | if (!string.IsNullOrEmpty(value)) 13 | { 14 | value = value.Trim().Replace("-", ""); 15 | 16 | if (Enum.TryParse(value, true, out var result)) 17 | { 18 | return result; 19 | } 20 | } 21 | 22 | throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(BackgroundRepeat)}"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/MagicGradients/Xaml/CssGradientSourceTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xamarin.Forms; 3 | using Xamarin.Forms.Xaml; 4 | 5 | namespace MagicGradients.Xaml 6 | { 7 | [TypeConversion(typeof(IGradientSource))] 8 | public class CssGradientSourceTypeConverter : TypeConverter 9 | { 10 | public override object ConvertFromInvariantString(string value) 11 | { 12 | if (string.IsNullOrEmpty(value)) 13 | throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(CssGradientSource)}"); 14 | 15 | return CssGradientSource.Parse(value); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/MagicGradients.Benchmark/MagicGradients.Benchmark.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/DimensionsTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using System.Collections.Generic; 3 | using Xunit; 4 | 5 | namespace MagicGradients.Tests 6 | { 7 | [Trait("Feature", "Core")] 8 | public class DimensionsTests 9 | { 10 | public static IEnumerable TestCases => new List 11 | { 12 | new object[] { Dimensions.Zero, true }, 13 | new object[] { Dimensions.Abs(0, 0), true }, 14 | new object[] { Dimensions.Prop(0, 0), true }, 15 | new object[] { Dimensions.Abs(20, 0), false }, 16 | new object[] { Dimensions.Prop(0, 20), false } 17 | }; 18 | 19 | [Theory] 20 | [MemberData(nameof(TestCases))] 21 | public void ValueSet_IsZero_HasExpectedValue(Dimensions value, bool isZero) 22 | { 23 | // Assert 24 | value.IsZero.Should().Be(isZero); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/MagicGradients.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/Mock/MockApplication.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | 3 | namespace MagicGradients.Tests.Mock 4 | { 5 | internal class MockApplication : Application 6 | { 7 | public MockApplication() 8 | { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/Mock/MockDeserializer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Xamarin.Forms.Internals; 4 | 5 | namespace MagicGradients.Tests.Mock 6 | { 7 | internal class MockDeserializer : IDeserializer 8 | { 9 | public Task> DeserializePropertiesAsync() 10 | { 11 | return Task.FromResult>(new Dictionary()); 12 | } 13 | 14 | public Task SerializePropertiesAsync(IDictionary properties) 15 | { 16 | return Task.FromResult(false); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/Mock/MockTicker.cs: -------------------------------------------------------------------------------- 1 | namespace MagicGradients.Tests.Mock 2 | { 3 | internal class MockTicker : Xamarin.Forms.Internals.Ticker 4 | { 5 | bool _enabled; 6 | 7 | protected override void EnableTimer() 8 | { 9 | _enabled = true; 10 | 11 | while (_enabled) 12 | { 13 | SendSignals(16); 14 | } 15 | } 16 | 17 | protected override void DisableTimer() 18 | { 19 | _enabled = false; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/Parser/TokenDefinitions/ColorChannelDefinitionData.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xunit; 3 | 4 | namespace MagicGradients.Tests.Parser.TokenDefinitions 5 | { 6 | public class ColorChannelDefinitionData : TheoryData 7 | { 8 | public ColorChannelDefinitionData() 9 | { 10 | Add("rgb(255, 0, 0) 25%", Color.FromRgb(255, 0, 0), 0.25d); 11 | Add("rgba(255, 0, 0, 1)", Color.FromRgba(255, 0, 0, 255), -1); 12 | Add("hsl(180, 70%, 30%) 65%", Color.FromHsla(0.5, 0.7, 0.3), 0.65d); 13 | Add("hsla(180, 70%, 30%, 0.5)", Color.FromHsla(0.5, 0.7, 0.3, 0.5), -1); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/Parser/TokenDefinitions/ColorHexDefinitionData.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xunit; 3 | 4 | namespace MagicGradients.Tests.Parser.TokenDefinitions 5 | { 6 | public class ColorHexDefinitionData : TheoryData 7 | { 8 | public ColorHexDefinitionData() 9 | { 10 | Add("#ff0000", Color.FromHex("#ff0000"), -1); 11 | Add("#00ff00 30%", Color.FromHex("#00ff00"), 0.3d); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/Parser/TokenDefinitions/ColorNameDefinitionData.cs: -------------------------------------------------------------------------------- 1 | using Xamarin.Forms; 2 | using Xunit; 3 | 4 | namespace MagicGradients.Tests.Parser.TokenDefinitions 5 | { 6 | public class ColorNameDefinitionData : TheoryData 7 | { 8 | public ColorNameDefinitionData() 9 | { 10 | Add("red", Color.Red, -1); 11 | Add("Color.blue", Color.Blue, -1); 12 | Add("orange 60%", Color.Orange, 0.6d); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/MagicGradients.Tests/StringExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentAssertions.Execution; 3 | using Xunit; 4 | 5 | namespace MagicGradients.Tests 6 | { 7 | [Trait("Feature", "Core")] 8 | public class StringExtensionsTests 9 | { 10 | [Theory] 11 | [InlineData("15%", "%", 15)] 12 | [InlineData("20px", "px", 20)] 13 | [InlineData("4.5ss", "ss", 4.5)] 14 | public void TryExtractNumber_ValidValue_ExtractedNumber(string input, string unit, float expected) 15 | { 16 | // Act 17 | var success = input.TryExtractNumber(unit, out var result); 18 | 19 | // Assert 20 | using (new AssertionScope()) 21 | { 22 | success.Should().Be(true); 23 | result.Should().Be(expected); 24 | } 25 | } 26 | } 27 | } 28 | --------------------------------------------------------------------------------