├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── dev.yml │ ├── main-template.yml │ └── main.yml ├── .gitignore ├── .gitmodules ├── CODE-OF-CONDUCT.md ├── Comet.Debug.sln ├── Comet.Reload.nuspec ├── Comet.Skia.nuspec ├── Comet.nuspec ├── Comet.sln ├── Comet.sln.DotSettings ├── Directory.Build.targets ├── LICENSE ├── README.md ├── art ├── CometLogo.ai ├── mvu-pattern.png └── mvvm-pattern.png ├── build ├── Comet-Nuget.sln ├── Comet-Tests.sln ├── DotNet │ ├── Dependencies │ │ ├── Directory.Build.props │ │ ├── Directory.Build.targets │ │ ├── Environment.Build.props │ │ ├── Packs.csproj │ │ ├── Versions.props │ │ └── Workloads.csproj │ ├── Directory.Build.props │ ├── DotNet.csproj │ └── NuGet.config ├── MauiVersionUpdater │ ├── MauiVersionUpdater.csproj │ └── Program.cs ├── install-vs.ps1 ├── package-github.yml └── package-nuget.yml ├── sample ├── .vscode │ ├── launch.json │ └── tasks.json └── Comet.Sample │ ├── ApiAudit │ └── ApiAuditManager.cs │ ├── Comet.Sample.csproj │ ├── CommunityQuestions │ ├── Question1.cs │ ├── Question1a.cs │ ├── Question1b.cs │ ├── Question1c.cs │ ├── Question1d.cs │ └── Question1e.cs │ ├── Comparisons │ ├── Section1.cs │ ├── Section2.cs │ ├── Section3.cs │ ├── Section4.cs │ ├── Section4b.cs │ ├── Section4c.cs │ └── Section5.cs │ ├── GitHubIssues │ ├── Issue123.cs │ ├── Issue125.cs │ ├── Issue125b.cs │ ├── Issue125c.cs │ ├── Issue133.cs │ ├── Issue133b.cs │ └── Issue133c.cs │ ├── GlobalUsings.cs │ ├── Graphics │ ├── BindableFingerPaint.cs │ ├── GraphicsSample5.cs │ ├── GraphicsSample6.cs │ ├── SimpleFingerPaint.cs │ ├── SkiaButtonSample.cs │ ├── SkiaSample1.cs │ ├── SkiaSample2.cs │ ├── SkiaSample3.cs │ ├── SkiaSample3WithScrollview.cs │ └── SkiaSample4.cs │ ├── LiveStreamIssues │ ├── DavidSample1.cs │ ├── DavidSample1a.cs │ ├── DavidSample1b.cs │ ├── DavidSample1c.cs │ └── DavidSample2.cs │ ├── Models │ └── Song.cs │ ├── MyApp.cs │ ├── Platforms │ ├── Android │ │ ├── AndroidManifest.xml │ │ ├── MainActivity.cs │ │ ├── MainApplication.cs │ │ └── Resources │ │ │ └── values │ │ │ └── colors.xml │ ├── MacCatalyst │ │ ├── AppDelegate.cs │ │ ├── Entitlements.Debug.plist │ │ ├── Entitlements.Release.plist │ │ ├── Info.plist │ │ └── Program.cs │ ├── Tizen │ │ ├── Main.cs │ │ └── tizen-manifest.xml │ ├── Windows │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── Package.appxmanifest │ │ └── app.manifest │ └── iOS │ │ ├── AppDelegate.cs │ │ ├── Info.plist │ │ └── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Reload.cs │ ├── Resources │ ├── AppIcon │ │ ├── appicon.svg │ │ └── appiconfg.svg │ ├── Fonts │ │ ├── OpenSans-Regular.ttf │ │ └── OpenSans-Semibold.ttf │ ├── Images │ │ ├── dotnet_bot.svg │ │ └── turtlerock.jpg │ ├── Raw │ │ └── AboutAssets.txt │ ├── Splash │ │ └── splash.svg │ ├── Styles │ │ ├── Colors.xaml │ │ └── Styles.xaml │ ├── appicon.svg │ └── appiconfg.svg │ └── Views │ ├── AnimationSample.cs │ ├── AuditReportPage.cs │ ├── BasicNavigationTestView.cs │ ├── BasicTestView.cs │ ├── BindingSample.cs │ ├── ButtonSample1.cs │ ├── ClipSample1.cs │ ├── ClipSample2.cs │ ├── ClipSample_AspectFill.cs │ ├── ClipSample_AspectFit.cs │ ├── ClipSample_Fill.cs │ ├── ClipSample_None.cs │ ├── ContinuosSample.cs │ ├── DatePickerSample.cs │ ├── DemoCreditCardView.cs │ ├── DemoCreditCardView2.cs │ ├── DemoCreditCardView3.cs │ ├── GridSample1.cs │ ├── InsaneDiffPage.cs │ ├── LabelSamples.cs │ ├── ListViewDetails.cs │ ├── ListViewSample1.cs │ ├── ListViewSample2.cs │ ├── MainPage.cs │ ├── MaterialSample.cs │ ├── MaterialStylePicker.cs │ ├── MenuItem.cs │ ├── NestedViews.cs │ ├── ProgressBarSample1.cs │ ├── RadioButtonSample.cs │ ├── RideTheCometSample.cs │ ├── SampleApp.cs │ ├── SectionedListViewSample.cs │ ├── SecureFieldSample1.cs │ ├── SecureFieldSample2.cs │ ├── SecureFieldSample3.cs │ ├── SecureFieldSample4.cs │ ├── ShapeSample1.cs │ ├── ShapeSample2.cs │ ├── ShapeViewSample.cs │ ├── SkiaControlsSample.cs │ ├── SliderSample1.cs │ ├── StepperSample1.cs │ ├── TabViewSample.cs │ ├── TextFieldSample1.cs │ ├── TextFieldSample2.cs │ ├── TextFieldSample3.cs │ ├── TextFieldSample4.cs │ ├── TextStylesSample.cs │ ├── TextWeightSample.cs │ ├── VGridNumberPad.cs │ ├── VGridSample.cs │ ├── VStackSample.cs │ ├── ViewLayoutTestCase.cs │ ├── VirtualListViewSample.cs │ └── VirtualSectionedListViewSample.cs ├── src ├── Comet.SourceGenerator │ ├── AutoNotifyGenerator.cs │ ├── Comet.SourceGenerator.csproj │ ├── CometViewSourceGenerator.cs │ ├── StateWrapperGenerator.cs │ ├── StringExtensions.cs │ └── ViewGeneratorData.cs └── Comet │ ├── Alignment.cs │ ├── Animations │ ├── Animation.cs │ ├── AnimationExtensions.cs │ └── AnimationSequence.cs │ ├── AppHostBuilderExtensions.cs │ ├── Attributes.cs │ ├── Binding.cs │ ├── BindingObject.cs │ ├── Comet.csproj │ ├── Comet.debug.csproj │ ├── Controls │ ├── AbstractLayout.cs │ ├── ContainerView.cs │ ├── ContentView.cs │ ├── ControlsGenerator.cs │ ├── FlyoutNavigationView.cs │ ├── GraphicsView.cs │ ├── Grid.cs │ ├── HGrid.cs │ ├── HStack.cs │ ├── IContainerView.cs │ ├── IContentTypeHash.cs │ ├── IControlState.cs │ ├── IThumbView.cs │ ├── IViewWrapperView.cs │ ├── Image.cs │ ├── ImageButton.cs │ ├── LayoutEventArgs.cs │ ├── ListView.cs │ ├── ModalView.cs │ ├── NavigationView.cs │ ├── Orientation.cs │ ├── RadioButton.cs │ ├── RadioGroup.cs │ ├── ResultView.cs │ ├── ScrollView.cs │ ├── ShapeView.cs │ ├── Spacer.cs │ ├── TabView.cs │ ├── VGrid.cs │ ├── VStack.cs │ ├── View.cs │ ├── WebView.cs │ └── ZStack.cs │ ├── EnvironmentAware.cs │ ├── EnvironmentData.cs │ ├── Exceptions │ └── ReadonlyRequiresException.cs │ ├── FrameConstraints.cs │ ├── Gestures │ ├── Gesture.cs │ ├── IGestureView.cs │ └── TapGesture.cs │ ├── GlobalUsings.cs │ ├── Graphics │ ├── AffineTransformF.cs │ ├── DrawingStyle.cs │ ├── Gradient.cs │ ├── GraphicsOperations.cs │ ├── IControlDelegate.cs │ ├── IDrawableControl.cs │ ├── LinearGradient.cs │ ├── PathBuilder.cs │ ├── PathF.cs │ ├── PathOperation.cs │ ├── RadialGradient.cs │ └── Stop.cs │ ├── Handlers │ ├── ListView │ │ ├── ListViewHandler.Android.cs │ │ ├── ListViewHandler.Standard.cs │ │ ├── ListViewHandler.Windows.cs │ │ ├── ListViewHandler.cs │ │ └── ListViewHandler.iOS.cs │ ├── Navigation │ │ ├── NavigationViewHandler.Android.cs │ │ ├── NavigationViewHandler.Standard.cs │ │ ├── NavigationViewHandler.Windows.cs │ │ ├── NavigationViewHandler.cs │ │ └── NavigationViewHandler.iOS.cs │ ├── RadioButton │ │ ├── RadioButtonHandler.Android.cs │ │ ├── RadioButtonHandler.iOS.cs │ │ ├── RadioGroupHandler.Android.cs │ │ └── RadioGroupHandler.iOS.cs │ ├── ScrollView │ │ ├── ScrollViewHandler.Android.cs │ │ ├── ScrollViewHandler.Standard.cs │ │ ├── ScrollViewHandler.Windows.cs │ │ ├── ScrollViewHandler.cs │ │ └── ScrollViewHandler.iOS.cs │ ├── ShapeView │ │ ├── ShapeViewHandler.Android.cs │ │ ├── ShapeViewHandler.Standard.cs │ │ ├── ShapeViewHandler.Windows.cs │ │ ├── ShapeViewHandler.cs │ │ └── ShapeViewHandler.iOS.cs │ ├── Spacer │ │ └── SpacerHandler.cs │ ├── TabView │ │ ├── TabViewHandler.Android.cs │ │ ├── TabViewHandler.Standard.cs │ │ ├── TabViewHandler.Windows.cs │ │ ├── TabViewHandler.cs │ │ └── TabViewHandler.iOS.cs │ └── View │ │ ├── CometViewHandler.Android.cs │ │ ├── CometViewHandler.cs │ │ └── CometViewHandler.iOS.cs │ ├── Helpers │ ├── BaseExtensions.cs │ ├── ColorExtensions.cs │ ├── ControlsExtensions.cs │ ├── DatabindingExtensions.cs │ ├── DrawingExtensions.cs │ ├── FixedSizeDictionary.cs │ ├── FixedSizedQueue.cs │ ├── FontExtensions.cs │ ├── GraphicsExtensions.cs │ ├── IDGenerator.cs │ ├── LayoutExtensions.cs │ ├── LineBreakModeExtensions.cs │ ├── ListExtensions.cs │ ├── MathExtensions.cs │ ├── MauiExtensions.cs │ ├── RectangleExtensions.cs │ ├── StringExtensions.cs │ ├── TabViewExtensions.cs │ ├── TextExtensions.cs │ ├── ThreadHelper.cs │ ├── ViewExtensions.cs │ └── WeakStack.cs │ ├── ImageSources │ └── ImageSources.cs │ ├── Internal │ ├── Extensions.cs │ └── ReflectionExtensions.cs │ ├── Layout │ ├── GridConstraints.cs │ ├── GridLayoutManager.cs │ ├── HStackLayoutManager.cs │ ├── VStackLayoutManager.cs │ └── ZStackLayoutManager.cs │ ├── Logger.cs │ ├── Maui │ ├── CometApp.cs │ ├── CometWindow.cs │ └── IMauiContextHolder.cs │ ├── MulticastAction.cs │ ├── Platform │ ├── Android │ │ ├── CometFragment.cs │ │ ├── CometNavigationView.cs │ │ ├── CometRecyclerView.cs │ │ ├── CometRecyclerViewAdapter.cs │ │ ├── CometRecyclerViewHolder.cs │ │ ├── CometScrollView.cs │ │ ├── CometTabView.cs │ │ ├── CometTouchGesterListener.cs │ │ ├── CometView.cs │ │ ├── CustomFrameLayout.cs │ │ ├── HandlerExtensions.cs │ │ └── ModalManager.cs │ ├── Standard │ │ └── HandlerExtensions.cs │ ├── Windows │ │ ├── HandlerExtensions.cs │ │ └── ListCell.cs │ └── iOS │ │ ├── CUIContainerView.cs │ │ ├── CUINavigationController.cs │ │ ├── CUIRadioButton.cs │ │ ├── CUIScrollView.cs │ │ ├── CUIShapeView.cs │ │ ├── CUITabView.cs │ │ ├── CUITableView.cs │ │ ├── CUITableViewCell.cs │ │ ├── CUITableViewSource.cs │ │ ├── CUITapGestures.cs │ │ ├── CometView.cs │ │ ├── CometViewController.cs │ │ ├── HandlerExtensions.cs │ │ └── iOSExtensions.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── ServiceContainer.cs │ ├── Shadow.cs │ ├── Shapes │ ├── Capsule.cs │ ├── Circle.cs │ ├── Ellipse.cs │ ├── Path.cs │ ├── PathScaling.cs │ ├── Pill.cs │ ├── Rectangle.cs │ ├── RoundedRectangle.cs │ ├── Shape.cs │ └── Squircle.cs │ ├── State.cs │ ├── StateManager.cs │ ├── Styles │ ├── ButtonStyle.cs │ ├── ControlState.cs │ ├── Material │ │ ├── ColorPalette.cs │ │ ├── Extensions.cs │ │ └── MaterialStyle.cs │ ├── NavbarStyle.cs │ ├── ProgressBarStyle.cs │ ├── SliderStyle.cs │ ├── Style.cs │ ├── StyleAwareValue.cs │ ├── StyleExtensions.cs │ ├── StyleType.cs │ ├── TextStyle.cs │ └── ViewStyle.cs │ ├── TextStyle.cs │ └── global.json ├── templates ├── comet-templates.nuspec └── single-project │ ├── .template.config │ └── template.json │ ├── .vscode │ └── launch.json │ ├── CometApp1.sln │ └── CometApp1 │ ├── App.cs │ ├── CometApp1.csproj │ ├── GlobalUsings.cs │ ├── Helpers │ └── Reload.cs │ ├── MainPage.cs │ ├── Platforms │ ├── Android │ │ ├── AndroidManifest.xml │ │ ├── MainActivity.cs │ │ ├── MainApplication.cs │ │ └── Resources │ │ │ └── values │ │ │ └── colors.xml │ ├── MacCatalyst │ │ ├── AppDelegate.cs │ │ ├── Info.plist │ │ └── Program.cs │ ├── Windows │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── Package.appxmanifest │ │ └── app.manifest │ └── iOS │ │ ├── AppDelegate.cs │ │ ├── Info.plist │ │ ├── Program.cs │ │ └── Resources │ │ └── LaunchScreen.xib │ ├── Properties │ └── launchSettings.json │ └── Resources │ ├── Fonts │ ├── OpenSans-Regular.ttf │ └── OpenSans-Semibold.ttf │ ├── Images │ └── dotnet_bot.svg │ ├── Raw │ └── AboutAssets.txt │ ├── appicon.svg │ └── appiconfg.svg └── tests ├── Comet.Blazor.Tests ├── Comet.Blazor.Tests.csproj └── RegistrarTests.cs └── Comet.Tests ├── Animations ├── AnimationTests.cs └── LerpTests.cs ├── AutoNotifyTest.cs ├── BindingTests.cs ├── Comet.Tests.csproj ├── EnvironmentTests.cs ├── GridTests.cs ├── HStackTests.cs ├── Handlers ├── GenericViewHandler.cs ├── ProgressBarHandler.cs ├── SecureFieldHandler.cs ├── SliderHandler.cs ├── TextFieldHandler.cs └── TextHandler.cs ├── Helpers └── ViewExtensions.cs ├── HotReloadTestsNoParameters.cs ├── HotReloadWithParameters.cs ├── LayoutTests.cs ├── MapperTests.cs ├── ReloadTransfersStateTest.cs ├── StateBindingTests.cs ├── TestBase.cs ├── UI.cs └── ViewTests.cs /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "External/Maui"] 2 | path = External/Maui 3 | url = https://github.com/dotnet/maui 4 | branch = net6.0 5 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant 4 | to clarify expected behavior in our community. 5 | 6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). 7 | -------------------------------------------------------------------------------- /Comet.Reload.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Clancey.Comet.Reload 5 | 0.0.19 6 | Comet.Reload 7 | James Clancey 8 | Clancey 9 | false 10 | Hot Reload plugin for Comet 11 | Comet Hot Reload plugin, Just call Comet.Reload.Init() for debug builds. 12 | James Clancey 13 | https://github.com/Clancey/Reloadify3000 14 | 15 | C# 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Comet.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | CUI 3 | IUI 4 | NS 5 | OS 6 | UI 7 | UWP 8 | WPF 9 | True 10 | True 11 | True 12 | True 13 | True 14 | 15 | 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /art/CometLogo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/art/CometLogo.ai -------------------------------------------------------------------------------- /art/mvu-pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/art/mvu-pattern.png -------------------------------------------------------------------------------- /art/mvvm-pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/art/mvvm-pattern.png -------------------------------------------------------------------------------- /build/DotNet/Dependencies/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /build/DotNet/Dependencies/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /build/DotNet/Dependencies/Environment.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | true 4 | 5 | 6 | 7 | false 8 | true 9 | 10 | 11 | 12 | 9.0 13 | 14 | 15 | 16 | 17 | False 18 | True 19 | 20 | 21 | -------------------------------------------------------------------------------- /build/DotNet/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /build/MauiVersionUpdater/MauiVersionUpdater.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sample/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Launch", 9 | "type": "comet", 10 | "request": "launch", 11 | "preLaunchTask": "build" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /sample/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "build", 8 | "type": "comet", 9 | "group": { 10 | "kind": "build", 11 | "isDefault": true 12 | } 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /sample/Comet.Sample/CommunityQuestions/Question1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Question1 : View 7 | { 8 | [Body] 9 | View body() 10 | { 11 | return new ScrollView { 12 | new VStack { 13 | new Image("turtlerock.jpg").Frame(75, 75).Padding(4), 14 | new Text("Title"), 15 | new Text("Description").FontSize(12).Color(Colors.Grey), 16 | }.FillHorizontal() 17 | 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/Comet.Sample/CommunityQuestions/Question1a.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Question1a : View 7 | { 8 | [Body] 9 | View body() => 10 | new VStack { 11 | new Image("turtlerock.jpg").Frame(75, 75).Padding(4), 12 | new Text("Title"), 13 | new Text("Description").FontSize(12).Color(Colors.Grey), 14 | }.FillHorizontal(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sample/Comet.Sample/CommunityQuestions/Question1b.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet.Samples 7 | { 8 | public class Question1b : View 9 | { 10 | [Body] 11 | View body() => 12 | new VStack { 13 | new Image("turtlerock.jpg") 14 | .Frame(75, 75) 15 | .Padding(4), 16 | new Text("Title") 17 | .HorizontalTextAlignment(TextAlignment.Center), 18 | new Text("Description") 19 | .HorizontalTextAlignment(TextAlignment.Center) 20 | .FontSize(12) 21 | .Color(Colors.Grey), 22 | }.FillHorizontal(); 23 | } 24 | } -------------------------------------------------------------------------------- /sample/Comet.Sample/CommunityQuestions/Question1c.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Question1c : View 7 | { 8 | [Body] 9 | View body() => 10 | new VStack { 11 | new Image("turtlerock.jpg") 12 | .Frame(75, 75) 13 | .Padding(4), 14 | new Text("Title") 15 | .FitHorizontal(), 16 | new Text("Description") 17 | .FitHorizontal() 18 | .FontSize(12) 19 | .Color(Colors.Grey), 20 | }.FillHorizontal(); 21 | } 22 | } -------------------------------------------------------------------------------- /sample/Comet.Sample/CommunityQuestions/Question1d.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Question1d : View 7 | { 8 | [Body] 9 | View body() 10 | { 11 | return new ScrollView { 12 | new VStack { 13 | new Image("turtlerock.jpg").Frame(75, 75).Padding(4), 14 | new Text("Title").FitHorizontal(), 15 | new Text("Description").FitHorizontal().FontSize(12).Color(Colors.Grey), 16 | }.FillHorizontal() 17 | 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/Comet.Sample/CommunityQuestions/Question1e.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet.Samples 7 | { 8 | public class Question1e : View 9 | { 10 | [Body] 11 | View body() 12 | { 13 | return new ScrollView { 14 | new VStack { 15 | new Image("turtlerock.jpg").Frame(75, 75).Padding(4), 16 | new Text("Title").HorizontalTextAlignment(TextAlignment.Center), 17 | new Text("Description").HorizontalTextAlignment(TextAlignment.Center).FontSize(12).Color(Colors.Grey), 18 | }.FillHorizontal() 19 | 20 | }; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Comparisons/Section1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | 6 | /* 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View { 11 | var body: some View { 12 | Text("Hello SwiftUI!") 13 | } 14 | } 15 | 16 | */ 17 | 18 | namespace Comet.Samples.Comparisons 19 | { 20 | public class Section1 : View 21 | { 22 | [Body] 23 | View body() 24 | => new Text("Hello Comet!"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Comparisons/Section2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui.Graphics; 6 | 7 | 8 | /* 9 | 10 | import SwiftUI 11 | 12 | struct ContentView: View { 13 | var body: some View { 14 | Text("Turtle Rock") 15 | .font(.title) 16 | .color(.green) 17 | } 18 | } 19 | 20 | */ 21 | 22 | namespace Comet.Samples.Comparisons 23 | { 24 | public class Section2 : View 25 | { 26 | [Body] 27 | View body() => 28 | new Text("Turtle Rock") 29 | .Color(Colors.Green); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Comparisons/Section3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui.Graphics; 6 | 7 | 8 | /* 9 | 10 | import SwiftUI 11 | 12 | struct ContentView: View { 13 | var body: some View { 14 | VStack(alignment: .leading) { 15 | Text("Turtle Rock") 16 | .font(.title) 17 | HStack { 18 | Text("Joshua Tree National Park") 19 | .font(.subheadline) 20 | Spacer() 21 | Text("California") 22 | .font(.subheadline) 23 | } 24 | } 25 | .padding() 26 | } 27 | } 28 | 29 | */ 30 | 31 | namespace Comet.Samples.Comparisons 32 | { 33 | public class Section3 : View 34 | { 35 | [Body] 36 | View body() => 37 | new VStack(alignment: LayoutAlignment.Start){ 38 | new Text("Turtle Rock"), 39 | new HStack { 40 | new Text("Joshua Tree National Park") 41 | .Background(Colors.Salmon), 42 | new Spacer(), 43 | new Text("California") 44 | .Background(Colors.Green), 45 | } 46 | }.Margin(); 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Comparisons/Section4.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui.Graphics; 6 | 7 | 8 | /* 9 | 10 | import SwiftUI 11 | 12 | struct CircleImage: View { 13 | var body: some View { 14 | Image("turtlerock") 15 | .clipShape(Circle()) 16 | .overlay( 17 | Circle().stroke(Color.white, lineWidth: 4)) 18 | .shadow(radius: 10) 19 | } 20 | } 21 | 22 | */ 23 | 24 | namespace Comet.Samples.Comparisons 25 | { 26 | public class Section4 : View 27 | { 28 | [Body] 29 | View body() => 30 | new Image("turtlerock.jpg") 31 | .ClipShape(new Circle()) 32 | .Border(new Circle().Stroke(Colors.White, lineWidth: 4)) 33 | .Shadow(radius: 10).Background(Colors.Green); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Comparisons/Section4b.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui.Graphics; 6 | 7 | 8 | /* 9 | 10 | import SwiftUI 11 | 12 | struct CircleImage: View { 13 | var body: some View { 14 | Image("turtlerock") 15 | .clipShape(Circle()) 16 | .overlay( 17 | Circle().stroke(Color.white, lineWidth: 4)) 18 | .shadow(radius: 10) 19 | } 20 | } 21 | 22 | */ 23 | 24 | namespace Comet.Samples.Comparisons 25 | { 26 | public class Section4b : View 27 | { 28 | [Body] 29 | View body() => new VStack { 30 | new Image("turtlerock.jpg") 31 | .ClipShape(new Circle()) 32 | .Border(new Circle().Stroke(Colors.White, lineWidth: 4)) 33 | .Shadow(radius: 10) 34 | }; 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Comparisons/Section4c.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | 6 | /* 7 | 8 | import SwiftUI 9 | 10 | struct CircleImage: View { 11 | var body: some View { 12 | Image("turtlerock") 13 | .clipShape(Circle()) 14 | .overlay( 15 | Circle().stroke(Color.white, lineWidth: 4)) 16 | .shadow(radius: 10) 17 | } 18 | } 19 | 20 | */ 21 | 22 | namespace Comet.Samples.Comparisons 23 | { 24 | public class Section4c : View 25 | { 26 | [Body] 27 | View body() => new VStack { 28 | new Image("turtlerock.jpg") 29 | .Shadow(radius: 10) 30 | }; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Comparisons/Section5.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Microsoft.Maui.Graphics; 5 | 6 | /* 7 | // Flutter only support if render 8 | class MyWidget extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Column( 12 | children: [ 13 | if (someCondition == true) 14 | Text('The condition is true!'), 15 | ], 16 | ); 17 | } 18 | } 19 | 20 | // Flutter render list 21 | class MyWidget extends StatelessWidget { 22 | @override 23 | Widget build(BuildContext context) { 24 | return Column( 25 | children: [ 26 | if (someCondition == true) ...[ 27 | Text('Widget A'), 28 | Text('Widget B'), 29 | Text('Widget C'), 30 | ], 31 | ], 32 | ); 33 | } 34 | } 35 | 36 | */ 37 | 38 | namespace Comet.Samples.Comparisons 39 | { 40 | public class Section5 : View 41 | { 42 | bool showMore = true; 43 | int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 44 | string fillColor = "Red"; 45 | [Body] 46 | View body() => new VStack { 47 | new Text("Hello Comet!"), 48 | () => { 49 | if(showMore) 50 | return new Text("If condition is working"); 51 | else 52 | return new Text("Else condition is working"); 53 | }, 54 | nums.Select(i => new Text($"Show rows {i}")), 55 | showMore?new Text("Ternary is working"):null, 56 | () => { 57 | switch(fillColor) 58 | { 59 | case "Red": 60 | return new ShapeView(new Rectangle().Fill(Colors.Red)).Frame(100, 60); 61 | default: 62 | return null; 63 | } 64 | } 65 | }; 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GitHubIssues/Issue123.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.ObjectModel; 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class Issue123 : View 8 | { 9 | private readonly State count = 0; 10 | 11 | [Body] 12 | View body() => new NavigationView{ new VStack 13 | { 14 | new Text(() => $"Value: {count.Value}") 15 | .Color(Colors.Black) 16 | .FontSize(32), 17 | new Button("Increment", () => count.Value ++ ) 18 | .Frame(width:320, height:44) 19 | .Background(Colors.Black) 20 | .Color(Colors.White) 21 | .Margin(20) 22 | , 23 | } 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GitHubIssues/Issue125.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Issue125 : View 7 | { 8 | private class TodoItem 9 | { 10 | public string Name { get; set; } 11 | public bool Done { get; set; } 12 | } 13 | 14 | readonly ObservableCollection items = new ObservableCollection{ 15 | new TodoItem{ 16 | Name = "Hi", 17 | Done = true, 18 | }, 19 | new TodoItem 20 | { 21 | Name ="Finish Tasky", 22 | } 23 | }; 24 | 25 | 26 | [Body] 27 | View body() => new NavigationView{ 28 | new ListView(items){ 29 | ViewFor = (item)=>new ContentView{ 30 | new HStack 31 | { 32 | new Text(item.Name).Alignment( Alignment.Leading), 33 | new Spacer(), 34 | new Toggle(item.Done).Alignment(Alignment.Center) 35 | }.Margin(6) 36 | }.FillHorizontal() 37 | }.Title("Tasky"), 38 | }; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GitHubIssues/Issue125b.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Issue125b : View 7 | { 8 | private class TodoItem 9 | { 10 | public string Name { get; set; } 11 | public bool Done { get; set; } 12 | } 13 | 14 | readonly ObservableCollection items = new ObservableCollection{ 15 | new TodoItem{ 16 | Name = "Hi", 17 | Done = true, 18 | }, 19 | new TodoItem 20 | { 21 | Name ="Finish Tasky", 22 | } 23 | }; 24 | 25 | 26 | [Body] 27 | View body() => new NavigationView{ 28 | new ListView(items){ 29 | ViewFor = (item)=>new HStack 30 | { 31 | new Text(item.Name).Alignment( Alignment.Leading), 32 | new Spacer(), 33 | new Toggle(item.Done).Alignment(Alignment.Center) 34 | }.Margin(6).FillHorizontal() 35 | }.Title("Tasky"), 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GitHubIssues/Issue125c.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Issue125c : View 7 | { 8 | private class TodoItem 9 | { 10 | public string Name { get; set; } 11 | public bool Done { get; set; } 12 | } 13 | 14 | readonly ObservableCollection items = new ObservableCollection{ 15 | new TodoItem{ 16 | Name = "Hi", 17 | Done = true, 18 | }, 19 | new TodoItem 20 | { 21 | Name ="Finish Tasky", 22 | } 23 | }; 24 | 25 | 26 | [Body] 27 | View body() => new NavigationView{ 28 | new ListView(items){ 29 | ViewFor = (item)=>new HStack 30 | { 31 | new Text(item.Name).Alignment( Alignment.Leading), 32 | new Spacer(), 33 | new Toggle(item.Done).Alignment(Alignment.Center) 34 | }.Margin(6).FillHorizontal().Frame(height:44) 35 | }.Title("Tasky"), 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GitHubIssues/Issue133.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Issue133 : View 7 | { 8 | [State] 9 | readonly CreditCard Card; 10 | 11 | readonly State remember = false; 12 | 13 | public Issue133() 14 | { 15 | Card = new CreditCard(); 16 | } 17 | 18 | 19 | [Body] 20 | View body() => new VStack(spacing: 20) 21 | { 22 | 23 | new BorderedEntry(Card.Number,"Enter CC Number", "\uf09d") 24 | .Margin(left:20, right: 20), 25 | 26 | new HStack(spacing:20) 27 | { 28 | new BorderedEntry(Card.Expiration, "MM/YYYY", "\uf783") 29 | .Frame(height: 40, width: 200) 30 | .Margin(left:20), 31 | 32 | new Spacer(), 33 | 34 | new BorderedEntry(Card.CVV, "CVV", "\uf023") 35 | .Frame( height: 40, width: 100) 36 | .Margin(right:20), 37 | }, 38 | 39 | 40 | }.FillHorizontal().Alignment(Alignment.Top); 41 | 42 | public class BorderedEntry : HStack 43 | { 44 | public BorderedEntry(Binding val, string placeholder, string icon) : base(spacing: 8) 45 | { 46 | Add(new Text(icon) 47 | .Frame(width: 20) 48 | .Margin(left: 8) 49 | .FontFamily("Font Awesome 5 Free")); 50 | 51 | Add(new TextField(val, placeholder)); 52 | 53 | this.Frame(height: 40).RoundedBorder(color: Colors.Grey); 54 | 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GitHubIssues/Issue133b.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Issue133b : View 7 | { 8 | [State] 9 | readonly CreditCard Card; 10 | 11 | readonly State remember = false; 12 | 13 | public Issue133b() 14 | { 15 | Card = new CreditCard(); 16 | } 17 | 18 | 19 | [Body] 20 | View body() => new VStack(spacing: 20) 21 | { 22 | 23 | new BorderedEntry(Card.Number,"Enter CC Number", "\uf09d") 24 | .Margin(left:20, right: 20), 25 | 26 | }.FillHorizontal().Alignment(Alignment.Top); 27 | 28 | public class BorderedEntry : HStack 29 | { 30 | public BorderedEntry(Binding val, string placeholder, string icon) : base(spacing: 8) 31 | { 32 | Add(new Text(icon) 33 | .Frame(width: 20) 34 | .Margin(left: 8) 35 | .FontFamily("Font Awesome 5 Free")); 36 | 37 | Add(new TextField(val, placeholder)); 38 | 39 | this.Frame(height: 40).RoundedBorder(color: Colors.Grey); 40 | 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GitHubIssues/Issue133c.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class Issue133c : View 7 | { 8 | [State] 9 | readonly CreditCard _card; 10 | 11 | public Issue133c() 12 | { 13 | _card = new CreditCard(); 14 | } 15 | 16 | 17 | [Body] 18 | View body() => new VStack(spacing: 20) 19 | { 20 | 21 | new BorderedEntry(_card.Number,"Enter CC Number", "\uf09d") 22 | .Margin(left:20, right: 20), 23 | 24 | }.FillHorizontal().Alignment(Alignment.Top); 25 | 26 | private class BorderedEntry : View 27 | { 28 | private Binding _val; 29 | private string _placeholder; 30 | private string _icon; 31 | 32 | public BorderedEntry(Binding val, string placeholder, string icon) 33 | { 34 | _val = val; 35 | _placeholder = placeholder; 36 | _icon = icon; 37 | } 38 | 39 | [Body] 40 | View body() => new HStack(spacing: 8) 41 | { 42 | new Text(_icon) 43 | .Frame(width: 20) 44 | .Margin(left: 8) 45 | .FontFamily("Font Awesome 5 Free"), 46 | 47 | new TextField(_val, _placeholder) 48 | } 49 | .Frame(height: 40) 50 | .RoundedBorder(color: Colors.Grey); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sample/Comet.Sample/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.Maui; 2 | global using Microsoft.Maui.Graphics; 3 | global using Comet; 4 | global using System.Linq; 5 | global using Microsoft.Maui.Primitives; 6 | global using Microsoft.Maui.Hosting; 7 | global using System; -------------------------------------------------------------------------------- /sample/Comet.Sample/Graphics/BindableFingerPaint.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | namespace Comet.Samples 3 | { 4 | public class BindableFingerPaint : SimpleFingerPaint, IDrawable, IGraphicsView 5 | { 6 | private Binding _strokeWidth = 2; 7 | private Binding _strokeColor = Colors.Black; 8 | 9 | public BindableFingerPaint( 10 | Binding strokeSize = null, 11 | Binding strokeColor = null) 12 | { 13 | StrokeWidth = strokeSize; 14 | StrokeColor = strokeColor; 15 | } 16 | 17 | public Binding StrokeWidth 18 | { 19 | get => _strokeWidth; 20 | private set => this.SetBindingValue(ref _strokeWidth, value); 21 | } 22 | 23 | public Binding StrokeColor 24 | { 25 | get => _strokeColor; 26 | private set => this.SetBindingValue(ref _strokeColor, value); 27 | } 28 | 29 | public override void ViewPropertyChanged(string property, object value) 30 | { 31 | base.ViewPropertyChanged(property, value); 32 | Invalidate(); 33 | } 34 | 35 | void IDrawable.Draw(ICanvas canvas, RectF dirtyRect) 36 | { 37 | //var paint = new SolidPaint(Colors.Blue); 38 | canvas.StrokeColor = _strokeColor; 39 | canvas.StrokeSize = (float)_strokeWidth.CurrentValue; 40 | 41 | foreach (var pointsList in _pointsLists) 42 | { 43 | for (var i = 0; i < pointsList.Count; i++) 44 | { 45 | var point = pointsList[i]; 46 | if (i > 0) 47 | { 48 | var lastPoint = pointsList[i - 1]; 49 | canvas.DrawLine(lastPoint.X, lastPoint.Y, point.X, point.Y); 50 | } 51 | } 52 | } 53 | } 54 | 55 | 56 | public override void Reset() 57 | { 58 | _pointsLists.Clear(); 59 | Invalidate(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Graphics/SimpleFingerPaint.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Comet.Samples 4 | { 5 | public class SimpleFingerPaint : GraphicsView, IDrawable, IGraphicsView 6 | { 7 | protected readonly List> _pointsLists = new List>(); 8 | 9 | void IDrawable.Draw(ICanvas canvas, RectF dirtyRect) 10 | { 11 | //var paint = new SolidPaint(Colors.Blue); 12 | canvas.StrokeColor = Colors.Blue; 13 | canvas.StrokeSize = 2; 14 | 15 | foreach (var pointsList in _pointsLists) 16 | { 17 | for (var i = 0; i < pointsList.Count; i++) 18 | { 19 | var point = pointsList[i]; 20 | if (i > 0) 21 | { 22 | var lastPoint = pointsList[i - 1]; 23 | canvas.DrawLine(lastPoint.X, lastPoint.Y, point.X, point.Y); 24 | } 25 | } 26 | } 27 | } 28 | 29 | void IGraphicsView.StartInteraction(PointF[] points) 30 | { 31 | var pointsList = new List { points[0] }; 32 | _pointsLists.Add(pointsList); 33 | //ViewHandler. 34 | } 35 | 36 | void IGraphicsView.DragInteraction(PointF[] points) 37 | { 38 | var pointsList = _pointsLists[_pointsLists.Count - 1]; 39 | pointsList.Add(points[0]); 40 | 41 | Invalidate(); 42 | } 43 | 44 | void IGraphicsView.EndInteraction(PointF[] points, bool contained) 45 | { 46 | var pointsList = _pointsLists[_pointsLists.Count - 1]; 47 | pointsList.Add(points[0]); 48 | 49 | Invalidate(); 50 | } 51 | 52 | public virtual void Reset() 53 | { 54 | _pointsLists.Clear(); 55 | Invalidate(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Graphics/SkiaButtonSample.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //namespace Comet.Samples 3 | //{ 4 | // public class SkiaButtonSample : View 5 | // { 6 | // [Body] 7 | // View body() => new VStack 8 | // { 9 | // new SKText("Hello").Color(Colors.Black) 10 | // .BeginAnimationSequence(repeats:true) 11 | // .Animate(duration:1,action:(text)=>{ 12 | // text.Color(Color.Fuchsia); 13 | // }).Animate(duration:1,action:(text)=>{ 14 | // text.Color(Color.AliceBlue); 15 | // }).Animate(duration:1,action:(text)=>{ 16 | // text.Color(Color.Beige); 17 | // }).Animate(duration:1,action:(text)=>{ 18 | // text.Color(Color.BlueViolet); 19 | // }).Animate(duration:1,action:(text)=>{ 20 | // text.Color(Color.Lavender); 21 | // }).Animate(duration:1,action:(text)=>{ 22 | // text.Color(Color.Fuchsia); 23 | // }).EndAnimationSequence(), 24 | // //TODO: Figure out why animation doesn't work 25 | // new SKButton("Hello").RoundedBorder(color:Colors.Black).Background(Colors.Black).Color(Colors.White).Animate(x => { 26 | // x.Background(Colors.White).Color(Colors.Black); 27 | // },duration:3, autoReverses:true, repeats: true) 28 | // }; 29 | // } 30 | //} 31 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Graphics/SkiaSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.Samples 6 | { 7 | /// 8 | /// This example how to use use a DrawableControl directly: you give it a control delegate 9 | /// in it's constructor. 10 | /// 11 | public class SkiaSample1 : View 12 | { 13 | [Body] 14 | View body() => new SimpleFingerPaint(); 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Graphics/SkiaSample2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.Samples 6 | { 7 | /// 8 | /// This example shows the cleaner way to use a drawable control. A control delegate can be 9 | /// implicitly converted into a drawable control, so there is no need to wrap it like in 10 | /// SkiaSample1. 11 | /// 12 | public class SkiaSample2 : View 13 | { 14 | [Body] 15 | View body() => new SimpleFingerPaint(); 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Graphics/SkiaSample3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class SkiaSample3 : View 8 | { 9 | readonly State _strokeSize = 2; 10 | readonly State _strokeColor = Colors.Black; 11 | 12 | [Body] 13 | View body() => 14 | new VStack() 15 | { 16 | new HStack() 17 | { 18 | new Text("Stroke Width:"), 19 | new Slider(_strokeSize, 1, 10).FillHorizontal() 20 | }.FillHorizontal(), 21 | 22 | new Text("Stroke Color!:").HorizontalTextAlignment(TextAlignment.Center), 23 | //new ScrollView{ 24 | new HStack 25 | { 26 | new Button("Black", () => 27 | { 28 | _strokeColor.Value = Colors.Black; 29 | }).Color(Colors.Black), 30 | new Button("Blue", () => 31 | { 32 | _strokeColor.Value = Colors.Blue; 33 | }).Color(Colors.Blue), 34 | new Button("Red", () => 35 | { 36 | _strokeColor.Value = Colors.Red; 37 | }).Color(Colors.Red), 38 | }.Alignment(Alignment.Center), 39 | //}, 40 | new BindableFingerPaint( 41 | strokeSize:_strokeSize, 42 | strokeColor:_strokeColor).Frame(width:400, height:400).RoundedBorder(color:Colors.White) 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Graphics/SkiaSample4.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | namespace Comet.Samples 5 | { 6 | public class SkiaSample4 : View 7 | { 8 | readonly State _strokeSize = 2; 9 | readonly State _strokeColor = Colors.White ; 10 | 11 | [Body] 12 | View body() 13 | { 14 | var fingerPaint = new BindableFingerPaint( 15 | strokeSize: _strokeSize, 16 | strokeColor: _strokeColor); 17 | 18 | return new VStack() 19 | { 20 | new VStack() 21 | { 22 | new HStack() 23 | { 24 | new Text("Stroke Width:"), 25 | new Slider(_strokeSize, 1, 10).FillHorizontal() 26 | }, 27 | new HStack() 28 | { 29 | new Text("Stroke Color:"), 30 | new TextField(new Binding(() => _strokeColor.Value.ToArgbHex(),(s) => _strokeColor.Value = Color.FromArgb(s))) 31 | }, 32 | new Button("Reset", () => fingerPaint.Reset()), 33 | fingerPaint.Frame(height: 400) 34 | }, 35 | }; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sample/Comet.Sample/LiveStreamIssues/DavidSample1.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples.LiveStreamIssues 6 | { 7 | public class DavidSample1 : View 8 | { 9 | [Body] 10 | View body() => 11 | new VStack(LayoutAlignment.Center) 12 | { 13 | new HStack 14 | { 15 | new ShapeView(new Circle().Stroke(Colors.Black, 2f)).Frame(44,44) 16 | } 17 | }.Alignment(Alignment.Top); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample/Comet.Sample/LiveStreamIssues/DavidSample1a.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples.LiveStreamIssues 6 | { 7 | public class DavidSample1a : View 8 | { 9 | [Body] 10 | View body() => 11 | new VStack(LayoutAlignment.Center) 12 | { 13 | new ShapeView(new Circle().Stroke(Colors.Black, 2f)).Frame(44,44) 14 | }; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sample/Comet.Sample/LiveStreamIssues/DavidSample1b.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples.LiveStreamIssues 6 | { 7 | public class DavidSample1b : View 8 | { 9 | [Body] 10 | View body() => 11 | new HStack(LayoutAlignment.Center) 12 | { 13 | new Spacer(), 14 | new ShapeView(new Circle().Stroke(Colors.Black, 2f)).Frame(44,44), 15 | new Spacer() 16 | }; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample/Comet.Sample/LiveStreamIssues/DavidSample1c.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples.LiveStreamIssues 6 | { 7 | public class DavidSample1c : View 8 | { 9 | [Body] 10 | View body() => 11 | new VStack(LayoutAlignment.Center) 12 | { 13 | new HStack 14 | { 15 | new ShapeView(new Circle().Stroke(Colors.Black, 2f)) 16 | .Frame(44,44) 17 | } 18 | }; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sample/Comet.Sample/LiveStreamIssues/DavidSample2.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples.LiveStreamIssues 6 | { 7 | public class DavidSample2 : View 8 | { 9 | [Body] 10 | View body() => 11 | new VStack() 12 | { 13 | new HStack 14 | { 15 | new ShapeView(new Circle().Stroke(Colors.Black, 2f)).Frame(44,44) 16 | } 17 | }.Alignment(Alignment.BottomTrailing); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Models/Song.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples.Models 3 | { 4 | public class Song : BindingObject 5 | { 6 | public string Title 7 | { 8 | get => GetProperty(); 9 | set => SetProperty(value); 10 | } 11 | 12 | public string Artist 13 | { 14 | get => GetProperty(); 15 | set => SetProperty(value); 16 | } 17 | 18 | public string Album 19 | { 20 | get => GetProperty(); 21 | set => SetProperty(value); 22 | } 23 | 24 | public int TrackNumber 25 | { 26 | get => GetProperty(); 27 | set => SetProperty(value); 28 | } 29 | 30 | public string ArtworkUrl 31 | { 32 | get => GetProperty(); 33 | set => SetProperty(value); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sample/Comet.Sample/MyApp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Comet.Graphics; 4 | using Comet.Samples.Models; 5 | using Microsoft.Maui; 6 | using Microsoft.Maui.Graphics; 7 | using Microsoft.Maui.Hosting; 8 | 9 | namespace Comet.Samples 10 | { 11 | public class MyApp : CometApp 12 | { 13 | [Body] 14 | View view() => new MainPage(); 15 | 16 | public static MauiApp CreateMauiApp() 17 | { 18 | var builder = MauiApp.CreateBuilder(); 19 | builder.UseCometApp() 20 | .ConfigureFonts(fonts => { 21 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); 22 | }); 23 | #if DEBUG 24 | builder.EnableHotReload(); 25 | #endif 26 | 27 | return builder.Build(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | 5 | namespace Comet.Sample 6 | { 7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] 8 | public class MainActivity : MauiAppCompatActivity 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Android/MainApplication.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Runtime; 3 | using Comet.Samples; 4 | 5 | namespace Comet.Sample 6 | { 7 | [Application] 8 | public class MainApplication : MauiApplication 9 | { 10 | public MainApplication(IntPtr handle, JniHandleOwnership ownership) 11 | : base(handle, ownership) 12 | { 13 | } 14 | 15 | protected override MauiApp CreateMauiApp() => MyApp.CreateMauiApp(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #512BD4 4 | #2B0B98 5 | #2B0B98 6 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/MacCatalyst/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Comet.Samples; 2 | using Foundation; 3 | 4 | namespace Comet.Sample 5 | { 6 | [Register("AppDelegate")] 7 | public class AppDelegate : MauiUIApplicationDelegate 8 | { 9 | protected override MauiApp CreateMauiApp() => MyApp.CreateMauiApp(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/MacCatalyst/Entitlements.Debug.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | com.apple.security.get-task-allow 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/MacCatalyst/Entitlements.Release.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | com.apple.security.app-sandbox 7 | 8 | com.apple.security.network.client 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/MacCatalyst/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | UIDeviceFamily 15 | 16 | 2 17 | 18 | UIRequiredDeviceCapabilities 19 | 20 | arm64 21 | 22 | UISupportedInterfaceOrientations 23 | 24 | UIInterfaceOrientationPortrait 25 | UIInterfaceOrientationLandscapeLeft 26 | UIInterfaceOrientationLandscapeRight 27 | 28 | UISupportedInterfaceOrientations~ipad 29 | 30 | UIInterfaceOrientationPortrait 31 | UIInterfaceOrientationPortraitUpsideDown 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | XSAppIconAssets 36 | Assets.xcassets/appicon.appiconset 37 | 38 | 39 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/MacCatalyst/Program.cs: -------------------------------------------------------------------------------- 1 | using ObjCRuntime; 2 | using UIKit; 3 | 4 | namespace Comet.Sample 5 | { 6 | public class Program 7 | { 8 | // This is the main entry point of the application. 9 | static void Main(string[] args) 10 | { 11 | // if you want to use a different Application Delegate class from "AppDelegate" 12 | // you can specify it here. 13 | UIApplication.Main(args, null, typeof(AppDelegate)); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Tizen/Main.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui; 2 | using Microsoft.Maui.Hosting; 3 | using System; 4 | 5 | namespace Comet.Sample 6 | { 7 | internal class Program : MauiApplication 8 | { 9 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); 10 | 11 | static void Main(string[] args) 12 | { 13 | var app = new Program(); 14 | app.Run(args); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Tizen/tizen-manifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | maui-appicon-placeholder 7 | 8 | 9 | 10 | 11 | http://tizen.org/privilege/internet 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Windows/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Windows/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Comet.Samples; 2 | using Microsoft.UI.Xaml; 3 | 4 | // To learn more about WinUI, the WinUI project structure, 5 | // and more about our project templates, see: http://aka.ms/winui-project-info. 6 | 7 | namespace Comet.Sample.WinUI 8 | { 9 | /// 10 | /// Provides application-specific behavior to supplement the default Application class. 11 | /// 12 | public partial class App : MauiWinUIApplication 13 | { 14 | /// 15 | /// Initializes the singleton application object. This is the first line of authored code 16 | /// executed, and as such is the logical equivalent of main() or WinMain(). 17 | /// 18 | public App() 19 | { 20 | this.InitializeComponent(); 21 | } 22 | 23 | protected override MauiApp CreateMauiApp() => MyApp.CreateMauiApp(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/Windows/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | true/PM 12 | PerMonitorV2, PerMonitor 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Comet.Samples; 2 | using Foundation; 3 | 4 | namespace Comet.Sample 5 | { 6 | [Register("AppDelegate")] 7 | public class AppDelegate : MauiUIApplicationDelegate 8 | { 9 | protected override MauiApp CreateMauiApp() => MyApp.CreateMauiApp(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSRequiresIPhoneOS 6 | 7 | UIDeviceFamily 8 | 9 | 1 10 | 2 11 | 12 | UIRequiredDeviceCapabilities 13 | 14 | arm64 15 | 16 | UISupportedInterfaceOrientations 17 | 18 | UIInterfaceOrientationPortrait 19 | UIInterfaceOrientationLandscapeLeft 20 | UIInterfaceOrientationLandscapeRight 21 | 22 | UISupportedInterfaceOrientations~ipad 23 | 24 | UIInterfaceOrientationPortrait 25 | UIInterfaceOrientationPortraitUpsideDown 26 | UIInterfaceOrientationLandscapeLeft 27 | UIInterfaceOrientationLandscapeRight 28 | 29 | XSAppIconAssets 30 | Assets.xcassets/appicon.appiconset 31 | 32 | 33 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Platforms/iOS/Program.cs: -------------------------------------------------------------------------------- 1 | using ObjCRuntime; 2 | using UIKit; 3 | 4 | namespace Comet.Sample 5 | { 6 | public class Program 7 | { 8 | // This is the main entry point of the application. 9 | static void Main(string[] args) 10 | { 11 | // if you want to use a different Application Delegate class from "AppDelegate" 12 | // you can specify it here. 13 | UIApplication.Main(args, null, typeof(AppDelegate)); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Windows Machine": { 4 | "commandName": "MsixPackage", 5 | "nativeDebugging": false 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /sample/Comet.Sample/Resources/AppIcon/appicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Resources/Fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/sample/Comet.Sample/Resources/Fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /sample/Comet.Sample/Resources/Fonts/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/sample/Comet.Sample/Resources/Fonts/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /sample/Comet.Sample/Resources/Images/turtlerock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/sample/Comet.Sample/Resources/Images/turtlerock.jpg -------------------------------------------------------------------------------- /sample/Comet.Sample/Resources/Raw/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories). Deployment of the asset to your application 3 | is automatically handled by the following `MauiAsset` Build Action within your `.csproj`. 4 | 5 | 6 | 7 | These files will be deployed with you package and will be accessible using Essentials: 8 | 9 | async Task LoadMauiAsset() 10 | { 11 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt"); 12 | using var reader = new StreamReader(stream); 13 | 14 | var contents = reader.ReadToEnd(); 15 | } 16 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Resources/appicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/BasicNavigationTestView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class BasicNavigationTestView : View 7 | { 8 | [Body] 9 | View body() => new NavigationView 10 | { 11 | new VStack() 12 | { 13 | new Button("Navigate!",()=>{ 14 | Navigation.Navigate(new BasicTestView()); 15 | }) 16 | } 17 | }; 18 | } 19 | 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/BasicTestView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class BasicTestView : View 8 | { 9 | class MyBindingObject : BindingObject 10 | { 11 | public bool CanEdit 12 | { 13 | get => GetProperty(); 14 | set => SetProperty(value); 15 | } 16 | 17 | public string Text 18 | { 19 | get => GetProperty(); 20 | set => SetProperty(value); 21 | } 22 | } 23 | 24 | [State] 25 | readonly MyBindingObject state; 26 | 27 | readonly State clickCount = new State(1); 28 | 29 | readonly State bar = new State(); 30 | 31 | public BasicTestView() 32 | { 33 | state = new MyBindingObject 34 | { 35 | Text = "Bar", 36 | CanEdit = true, 37 | }; 38 | Body = Build; 39 | } 40 | 41 | View Build() => 42 | new VStack 43 | { 44 | (state.CanEdit 45 | ? (View) new TextField(state.Text) 46 | : new Text(() => $"{state.Text}: multiText")), // Text will warn you. This should be done by TextBinding 47 | new Text(state.Text), 48 | new HStack 49 | { 50 | new Button("Toggle Entry/Label", 51 | () => state.CanEdit = !state.CanEdit) 52 | .Background(Colors.Salmon), 53 | new Button("Update Text", 54 | () => state.Text = $"Click Count: {clickCount.Value++}" ) 55 | } 56 | }; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/BindingSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class BindingSample : View 5 | { 6 | class MyBindingObject : BindingObject 7 | { 8 | public bool CanEdit 9 | { 10 | get => GetProperty(); 11 | set => SetProperty(value); 12 | } 13 | 14 | public string Text 15 | { 16 | get => GetProperty(); 17 | set => SetProperty(value); 18 | } 19 | } 20 | 21 | [State] 22 | readonly MyBindingObject state; 23 | 24 | readonly State clickCount = 1; 25 | 26 | readonly State bar = false; 27 | 28 | public BindingSample() 29 | { 30 | state = new MyBindingObject 31 | { 32 | Text = "Bar", 33 | CanEdit = true, 34 | }; 35 | Body = Build; 36 | } 37 | 38 | View Build() => 39 | new NavigationView{ new ScrollView 40 | { 41 | new VStack 42 | { 43 | (state.CanEdit 44 | ? (View) new TextField(state.Text) 45 | : new Text(() => $"{state.Text}: multiText")), // Formatted Text will warn you. This should be done by TextBinding 46 | new Text(state.Text), 47 | new HStack 48 | { 49 | new Button("Toggle Entry/Label", 50 | () => state.CanEdit = !state.CanEdit), 51 | new Button("Update Text", 52 | () => state.Text = $"Click Count: {clickCount.Value++}"), 53 | new Button("Update FontSize", 54 | () => { 55 | var font = View.GetGlobalEnvironment(EnvironmentKeys.Fonts.Size) ?? 14; 56 | var size = font + 5; 57 | View.SetGlobalEnvironment (EnvironmentKeys.Fonts.Size, size); 58 | }), 59 | }, 60 | new Toggle(state.CanEdit) 61 | } 62 | } 63 | }; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ButtonSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class ButtonSample1 : View 7 | { 8 | readonly State count = 0; 9 | 10 | [Body] 11 | View body() => new VStack 12 | { 13 | new Button("Increment Value", () => count.Value ++ ), 14 | new Text(() => $"Value: {count.Value}"), 15 | }; 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ClipSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui.Graphics; 6 | 7 | namespace Comet.Samples 8 | { 9 | public class ClipSample1 : View 10 | { 11 | [Body] 12 | View body() => new VStack { 13 | new Image("turtlerock.jpg") 14 | .Aspect(Aspect.AspectFill) 15 | .ClipShape(new Circle()) 16 | .Border(new Circle().Stroke(Colors.White, lineWidth: 4)) 17 | .Shadow(radius: 10) 18 | }; 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ClipSample2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class ClipSample2 : View 8 | { 9 | public static readonly string 10 | HighwayShield = 11 | "M45.00003 0.0003755092 C48.6566 3.115492 53.39751 4.995667 58.57761 4.995667 C63.75768 4.995667 68.49864 3.115117 72.15516 0 L90 17.84482 C86.71619 22.5125 84.78809 28.20319 84.78809 34.34386 C84.78809 38.76054 85.78532 42.94414 87.56722 46.68191 C89.10684 49.91339 90 53.59571 90 57.41377 C90 71.12593 78.88458 82.24136 65.17242 82.24136 L61.27555 82.24136 C54.7048 82.24136 48.84069 85.26647 45.00003 90 C41.15929 85.26647 35.29517 82.24136 28.72452 82.24136 L24.82755 82.24136 C11.1155 82.24136 0 71.12593 0 57.41377 C0 53.59571 0.8931539 49.91339 2.432828 46.68191 C4.21465 42.94414 5.212069 38.76054 5.212069 34.34386 C5.212069 28.20319 3.283775 22.5125 8.583069E-05 17.84482 L17.84488 0 C21.50145 3.115117 26.24229 4.995667 31.42246 4.995667 C36.60254 4.995667 41.3435 3.115492 45.00003 0.0003755092 Z "; 12 | [Body] 13 | View body() => new VStack { 14 | new Image("turtlerock.jpg") 15 | .ClipShape(new Path(HighwayShield)) 16 | .Shadow(radius: 10) 17 | }; 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ContinuosSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class ContinuosSample : View 5 | { 6 | readonly State _strokeColor = "#000000"; 7 | 8 | [Body] 9 | View body() 10 | { 11 | 12 | return new Grid( 13 | columns: new object[] { "*", "*" }, 14 | rows: null) 15 | { 16 | new TextField(_strokeColor, "Enter code here").Cell(row:0, column: 0), 17 | new Button("Controls appear here").Cell(row:0, column:1) 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/DatePickerSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class DatePickerSample : View 5 | { 6 | readonly State currentDate = DateTime.Today; 7 | public DatePickerSample() 8 | { 9 | currentDate.PropertyChanged += CurrentDate_PropertyChanged; 10 | } 11 | 12 | [Body] 13 | View body() => new VStack 14 | { 15 | new DatePicker(currentDate, minimumDate: new DateTime(2015, 10, 1), 16 | maximumDate: new DateTime(2018, 10, 01)).Format("dd/MM/yyyy") 17 | .Frame(width: 200) 18 | }; 19 | 20 | 21 | 22 | private void CurrentDate_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) 23 | { 24 | Console.WriteLine((sender as State)?.Value); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/GridSample1.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using System.Collections.Generic; 3 | //using System.Text; 4 | //using Comet.Skia; 5 | 6 | //namespace Comet.Samples.Skia 7 | //{ 8 | // public class GridSample1 : View 9 | // { 10 | // readonly State _strokeSize = 2; 11 | // readonly State _strokeColor = "#000000"; 12 | 13 | // [Body] 14 | // View body() 15 | // { 16 | // var fingerPaint = new BindableFingerPaint( 17 | // strokeSize: _strokeSize, 18 | // strokeColor: _strokeColor); 19 | 20 | // return new Grid( 21 | // columns: new object[] { 120, "*" }, 22 | // rows: new object[] { 44, 44, 44, "*" }) 23 | // { 24 | // new Text("Stroke Width:").Cell(row:0, column: 0), 25 | // new Slider(_strokeSize, 1, 10, 1).Cell(row:0, column: 1), 26 | // new Text("Stroke Color:").Cell(row:1, column: 0), 27 | // new TextField(_strokeColor).Cell(row:1, column: 1), 28 | // new Button("Reset", () => fingerPaint.Reset()).Cell(row:2, column: 0, colSpan: 2), 29 | // fingerPaint.ToView().Cell(row:3, column: 0, colSpan: 2) 30 | // }; 31 | // } 32 | // } 33 | //} 34 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/InsaneDiffPage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class InsaneDiffPage : View 5 | { 6 | readonly State myBoolean = new State(); 7 | readonly State myText = new State(); 8 | 9 | [Body] 10 | View body() 11 | { 12 | var stack = new VStack { 13 | new Button 14 | (()=> myBoolean.Value ? myText.Value : $"State: {myBoolean.Value}", 15 | ()=> myBoolean.Value = !myBoolean.Value), 16 | }; 17 | for (var i = 0; i < 100; i++) 18 | { 19 | stack.Add(new Text(i.ToString())); 20 | } 21 | return new ScrollView { stack }; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/LabelSamples.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class LabelSamples 5 | { 6 | public LabelSamples() 7 | { 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ListViewDetails.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Comet.Samples.Models; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class ListViewDetails : View 7 | { 8 | [Environment] 9 | readonly Song song; 10 | 11 | public ListViewDetails() 12 | { 13 | Body = () => new VStack { 14 | new Image(() => song.ArtworkUrl), 15 | new Text(() => song.Title), 16 | new Text(() => song.Artist), 17 | new Text(() => song.Album), 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ListViewSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Comet.Samples.Models; 5 | using Microsoft.Maui.Graphics; 6 | 7 | namespace Comet.Samples 8 | { 9 | public class ListViewSample1 : View 10 | { 11 | //This should come from a database or something 12 | List Songs = new List { 13 | new Song { 14 | Title = "All the Small Things", 15 | Artist = "Blink-182", 16 | Album = "Greatest Hits", 17 | ArtworkUrl = "https://lh3.googleusercontent.com/9Ofo9ZHQODFvahjpq2ZVUUOog4v5J1c4Gw9qjTw-KADTQZ6sG98GA1732mZA165RBoyxfoMblA" 18 | }, 19 | new Song { 20 | Title = "Monster", 21 | Artist = "Skillet", 22 | Album = "Awake", 23 | ArtworkUrl = "https://lh3.googleusercontent.com/uhjRXO19CiZbT46srdXSM-lQ8xCsurU-xaVg6lvJvNy8TisdjlaHrHsBwcWAzpu_vkKXAA9SdbA", 24 | } 25 | }; 26 | 27 | [Body] 28 | View body() => new ListView(Songs) 29 | { 30 | ViewFor = (song) => new HStack 31 | { 32 | new Image (song.ArtworkUrl).Frame(52, 52).Margin(4), 33 | new VStack(LayoutAlignment.Start, spacing:2) 34 | { 35 | new Text (song.Title).FontSize(17), 36 | new Text (song.Artist).Color(Colors.Grey), 37 | new Text (song.Album).Color(Colors.Grey), 38 | }.FontSize(12) 39 | }.Frame(height: 60).Alignment(Alignment.Leading), 40 | }.OnSelectedNavigate((song) => new ListViewDetails().SetEnvironment("song",song)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ListViewSample2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Comet.Samples.Models; 5 | 6 | namespace Comet.Samples 7 | { 8 | public class ListViewSample2 : View 9 | { 10 | //This should come from a database or something 11 | List Songs = new List 12 | { 13 | new Song 14 | { 15 | Title = "All the Small Things", 16 | Artist = "Blink-182", 17 | Album = "Dude Ranch", 18 | ArtworkUrl = "https://lh3.googleusercontent.com/9Ofo9ZHQODFvahjpq2ZVUUOog4v5J1c4Gw9qjTw-KADTQZ6sG98GA1732mZA165RBoyxfoMblA" 19 | }, 20 | new Song 21 | { 22 | Title = "Monster", 23 | Artist = "Skillet", 24 | Album = "Awake", 25 | ArtworkUrl = "https://lh3.googleusercontent.com/uhjRXO19CiZbT46srdXSM-lQ8xCsurU-xaVg6lvJvNy8TisdjlaHrHsBwcWAzpu_vkKXAA9SdbA", 26 | } 27 | }; 28 | 29 | public ListViewSample2() 30 | { 31 | Body = () => new ListView(Songs) 32 | { 33 | ViewFor = song => new HStack 34 | { 35 | new Image(song.ArtworkUrl) 36 | .Frame(44,44).Alignment(Alignment.Center) 37 | .Margin(left:10f) 38 | .ClipShape(new Circle()), 39 | new VStack(LayoutAlignment.Start) 40 | { 41 | new Text(song.Title), 42 | new Text(song.Artist), 43 | new Text(song.Album), 44 | }, 45 | }.Alignment(Alignment.Leading), 46 | Header = new VStack 47 | { 48 | new Text("Songs") 49 | }, 50 | }.OnSelected((song) => { Console.WriteLine("Song Selected"); }); 51 | } 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/MaterialSample.cs: -------------------------------------------------------------------------------- 1 | using Comet.Styles.Material; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Comet.Samples 7 | { 8 | public class MaterialSample : View 9 | { 10 | [Body] 11 | View body() => new VStack 12 | { 13 | new HStack 14 | { 15 | new Button("Contained Button").StyleAsContained(), 16 | new Button("Outlined Button").StyleAsOutlined(), 17 | new Button("Text Button").StyleAsText(), 18 | } 19 | }; 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/MaterialStylePicker.cs: -------------------------------------------------------------------------------- 1 | using Comet.Styles.Material; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Comet.Samples 7 | { 8 | public class MaterialStylePicker : View 9 | { 10 | public MaterialStylePicker() 11 | { 12 | this.Title("Material Style Picker"); 13 | 14 | } 15 | 16 | List colorPalettes = new List 17 | { 18 | ColorPalette.Amber, 19 | ColorPalette.Blue, 20 | ColorPalette.Cyan, 21 | ColorPalette.DeepOrange, 22 | ColorPalette.DeepPurple, 23 | ColorPalette.Green, 24 | ColorPalette.Indigo, 25 | ColorPalette.LightBlue, 26 | ColorPalette.LightGreen, 27 | ColorPalette.Lime, 28 | ColorPalette.Orange, 29 | ColorPalette.Pink, 30 | ColorPalette.Purple, 31 | ColorPalette.Red, 32 | ColorPalette.Teal, 33 | ColorPalette.Yellow, 34 | }; 35 | [Body] 36 | View body() => new ListView(colorPalettes) 37 | { 38 | ViewFor = (colorPalette) => new Text(colorPalette.Name).Background(colorPalette.P900).Color(colorPalette.PD900), 39 | }.OnSelectedNavigate((colorPallete) 40 | => new MaterialSample().ApplyStyle(new MaterialStyle(colorPallete)) 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/MenuItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class MenuItem 5 | { 6 | public MenuItem() 7 | { 8 | 9 | } 10 | public MenuItem(string title, Func page) 11 | { 12 | Title = title; 13 | Page = page; 14 | } 15 | public string Title { get; set; } 16 | public Func Page { get; set; } 17 | 18 | public override string ToString() => Title; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/NestedViews.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class NestedViews : View 5 | { 6 | public NestedViews() 7 | { 8 | Body = () => new View 9 | { 10 | Body = () => new View 11 | { 12 | Body = () => new Text("Hi!") 13 | } 14 | }; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ProgressBarSample1.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | namespace Comet.Samples 4 | { 5 | public class ProgressBarSample1 : View 6 | { 7 | readonly State percentage = new State(.1); 8 | private readonly Timer _timer; 9 | 10 | public ProgressBarSample1() 11 | { 12 | _timer = new Timer(state => { 13 | var p = (State)state; 14 | var current = p.Value; 15 | var value = current < 1 ? current + .001f : 0; 16 | p.Value = value; 17 | }, percentage, 100, 100); 18 | } 19 | 20 | [Body] 21 | View body() => new VStack() 22 | { 23 | new ProgressBar(percentage), 24 | new Text(()=>$"{percentage.Value.ToString("P2")}"), 25 | }; 26 | 27 | protected override void Dispose(bool disposing) 28 | { 29 | base.Dispose(disposing); 30 | 31 | // TODO: Stop when lifecycle events for views are available 32 | _timer.Dispose(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/RadioButtonSample.cs: -------------------------------------------------------------------------------- 1 | namespace Comet.Samples 2 | { 3 | public class RadioButtonSample : View 4 | { 5 | [Body] 6 | View body() => new VStack 7 | { 8 | new RadioGroup 9 | { 10 | new RadioButton( 11 | label: "Group 1: Option A", 12 | selected: true, 13 | onClick: () => System.Diagnostics.Debug.WriteLine("Option A selected")), 14 | new RadioButton( 15 | label: "Group 1: Option B", 16 | onClick: () => System.Diagnostics.Debug.WriteLine("Option B selected")), 17 | new RadioButton( 18 | label: "Group 1: Option C", 19 | onClick: () => System.Diagnostics.Debug.WriteLine("Option C selected")), 20 | }, 21 | new RadioGroup( 22 | orientation: Orientation.Horizontal) 23 | { 24 | new RadioButton( 25 | label: "Implicit Group: Option 1", 26 | onClick: () => System.Diagnostics.Debug.WriteLine("Option 1 selected")), 27 | new RadioButton( 28 | label: "Implicit Group: Option 2", 29 | selected: true, 30 | onClick: () => System.Diagnostics.Debug.WriteLine("Option 2 selected")), 31 | new RadioButton( 32 | label: "Implicit Group: Option 3", 33 | onClick: () => System.Diagnostics.Debug.WriteLine("Option 3 selected")) 34 | } 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/RideTheCometSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui; 6 | using Microsoft.Maui.Graphics; 7 | 8 | /* 9 | 10 | import SwiftUI 11 | 12 | struct ContentView: View { 13 | var body: some View { 14 | Text("Hello SwiftUI!") 15 | } 16 | } 17 | 18 | */ 19 | 20 | namespace Comet.Samples.Comparisons 21 | { 22 | public class RideSample : View 23 | { 24 | public RideSample() 25 | { 26 | //View.SetGlobalEnvironment(EnvironmentKeys.Colors.Color, Colors.Black); 27 | comet = new Comet(); 28 | } 29 | 30 | [State] 31 | readonly Comet comet; 32 | 33 | [Body] 34 | View body() 35 | => new VStack { 36 | new Text(()=> $"({comet.Rides}) rides taken:{comet.CometTrain}") 37 | .Frame(width:300) 38 | .LineBreakMode(LineBreakMode.CharacterWrap), 39 | 40 | new Button("Ride the Comet! ☄️", ()=>{ 41 | comet.Rides++; 42 | }) 43 | .Frame(height:44) 44 | .Margin(8) 45 | .Color(Colors.White) 46 | .Background(Colors.Green) 47 | .RoundedBorder(color:Colors.Blue) 48 | .Shadow(Colors.Grey,4,2,2), 49 | }; 50 | 51 | public class Comet : BindingObject 52 | { 53 | public int Rides 54 | { 55 | get => GetProperty(); 56 | set => SetProperty(value); 57 | } 58 | 59 | public string CometTrain 60 | { 61 | get 62 | { 63 | return "☄️".Repeat(Rides); 64 | } 65 | } 66 | } 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SampleApp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class SampleApp : CometApp 7 | { 8 | public SampleApp() 9 | { 10 | //Body = () => new MainPage(); 11 | Body = () => new VStack(spacing: 20) 12 | { 13 | new Text("Hey!!"), 14 | //new Text("Hey!!"), 15 | new Text("TEST PADDING").Frame(height:30).Margin(top:100), 16 | new Text("This top part is a Microsoft.Maui.VerticalStackLayout"), 17 | new HStack(spacing:2) 18 | { 19 | new Button("A Button").Frame(width:100).Color(Colors.White), 20 | new Button("Hello I'm a button") 21 | .Color(Colors.Green) 22 | .Background(Colors.Purple), 23 | new Text("And these buttons are in a HorizontalStackLayout"), 24 | }, 25 | new Text("Hey!!"), 26 | new Text("Hey!!"), 27 | //new SecondView(), 28 | 29 | }.Background(Colors.Beige).Margin(top:30); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SectionedListViewSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class SectionedListViewSample : View 7 | { 8 | public SectionedListViewSample() 9 | { 10 | int total = 10; 11 | var sections = Enumerable.Range(0, total).Select(s => new Section(header: new Text(s.ToString())) 12 | { 13 | Enumerable.Range(0, total).Select(r => new Text(r.ToString())), 14 | 15 | }).ToList(); 16 | Body = () => new SectionedListView(sections); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SecureFieldSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | /* 5 | 6 | struct ContentView : View { 7 | @State private var password: String = "" 8 | 9 | var body: some View { 10 | VStack { 11 | SecureField("Enter a password", text: $password) 12 | Text("You entered: \(password)") 13 | } 14 | } 15 | } 16 | 17 | */ 18 | namespace Comet.Samples 19 | { 20 | public class SecureFieldSample1 : View 21 | { 22 | readonly State password = new State(""); 23 | 24 | [Body] 25 | View body() => new VStack() 26 | { 27 | new SecureField(password, "Enter a password"), 28 | new Text(password) 29 | }.FillHorizontal(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SecureFieldSample2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | /* 5 | 6 | struct ContentView : View { 7 | @State private var password: String = "" 8 | 9 | var body: some View { 10 | VStack { 11 | SecureField("Enter a password", text: $password) 12 | Text("You entered: \(password)") 13 | } 14 | } 15 | } 16 | 17 | */ 18 | namespace Comet.Samples 19 | { 20 | public class SecureFieldSample2 : View 21 | { 22 | readonly State password = new State(""); 23 | 24 | [Body] 25 | View body() => new VStack() 26 | { 27 | new SecureField(password, "Enter a password"), 28 | new Text(password.Value) 29 | }.FillHorizontal(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SecureFieldSample3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | /* 5 | 6 | struct ContentView : View { 7 | @State private var password: String = "" 8 | 9 | var body: some View { 10 | VStack { 11 | SecureField("Enter a password", text: $password) 12 | Text("You entered: \(password)") 13 | } 14 | } 15 | } 16 | 17 | */ 18 | namespace Comet.Samples 19 | { 20 | public class SecureFieldSample3 : View 21 | { 22 | readonly State password = new State(""); 23 | 24 | [Body] 25 | View body() => new VStack() 26 | { 27 | new SecureField(password, "Enter a password"), 28 | new Text(password) 29 | }.FillHorizontal(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SecureFieldSample4.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | /* 5 | 6 | struct ContentView : View { 7 | @State private var password: String = "" 8 | 9 | var body: some View { 10 | VStack { 11 | SecureField("Enter a password", text: $password) 12 | Text("You entered: \(password)") 13 | } 14 | } 15 | } 16 | 17 | */ 18 | namespace Comet.Samples 19 | { 20 | public class SecureFieldSample4 : View 21 | { 22 | readonly State password = ""; 23 | 24 | [Body] 25 | View body() => new VStack() 26 | { 27 | new SecureField(password, "Enter a password"), 28 | new Text(password) 29 | }.FillHorizontal(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/ShapeViewSample.cs: -------------------------------------------------------------------------------- 1 | namespace Comet.Samples; 2 | public class ShapeViewSample : View 3 | { 4 | [Body] 5 | View body() => new ZStack { 6 | new ShapeView( 7 | new Circle() 8 | .Stroke(Colors.Blue, 4) 9 | .Fill(Colors.Black) 10 | ) 11 | .Frame(width:80,height:80), 12 | new ShapeView( 13 | new Rectangle() 14 | .Fill(Colors.Red) 15 | ).Frame(width:40,height:40) 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SkiaControlsSample.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using Comet.Skia; 3 | //namespace Comet.Samples 4 | //{ 5 | // public class SkiaControlsSample : View 6 | // { 7 | // readonly State progress = .5f; 8 | // [Body] 9 | // View body() => new VStack 10 | // { 11 | // new SKText("Text"), 12 | // new SKTextField("Text Field"), 13 | // new SKButton("Hello!"), 14 | // new SKSlider(progress,0,1,.01f), 15 | // new SKProgressBar(progress), 16 | // new SKToggle(), 17 | // }; 18 | // } 19 | //} 20 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/SliderSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | /* 5 | 6 | struct ContentView : View { 7 | @State var celsius: Double = 0 8 | 9 | var body: some View { 10 | VStack { 11 | Slider(value: $celsius, from: -100, through: 100, by: 0.1) 12 | Text("\(celsius) Celsius is \(celsius * 9 / 5 + 32) Fahrenheit") 13 | } 14 | } 15 | } 16 | 17 | */ 18 | namespace Comet.Samples 19 | { 20 | public class SliderSample1 : View 21 | { 22 | readonly State celsius = 50; 23 | 24 | [Body] 25 | View body() => new VStack 26 | { 27 | //new Slider(value: 12, from: -100, through: 100, by: 0.1f), 28 | //new Slider(value: () => 12f, from: -100, through: 100, by: 0.1f), 29 | //new Slider(value: new Binding( getValue: () => 12f, setValue:null), from: -100, through: 100), 30 | new Slider(value: celsius, minimum: -100, maximum: 100), 31 | new Text(()=>$"{celsius.Value} Celsius"), 32 | new Text(()=>$"{celsius.Value * 9 / 5 + 32} Fahrenheit"), 33 | }; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/StepperSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class StepperSample1 : View 5 | { 6 | readonly State min = 0; 7 | readonly State max = 10; 8 | readonly State increment = 1; 9 | readonly State number1 = 0; 10 | //private double currentValue; 11 | 12 | [Body] 13 | View body() => new VStack 14 | { 15 | new Text($"{number1.Value}"), 16 | new Stepper(number1,max,min, increment) 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/TabViewSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class TabViewSample : View 5 | { 6 | 7 | [Body] 8 | View body() => new TabView 9 | { 10 | new HStack{ 11 | new Text("Tab 1") 12 | }.TabText("Tab 1"), 13 | new HStack 14 | { 15 | new Text("Tab 2"), 16 | }.TabText("Tab 2") 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/TextFieldSample1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class TextFieldSample1 : View 7 | { 8 | readonly State name1 = ""; 9 | 10 | [Body] 11 | View body() => new VStack() 12 | { 13 | new TextField(name1, "Name", ()=>{ 14 | Console.WriteLine("Completed"); 15 | }), 16 | 17 | new HStack() 18 | { 19 | new Text("onCommit:"), 20 | new Text(name1), 21 | new Spacer() 22 | }, 23 | }.FillHorizontal(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/TextFieldSample2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class TextFieldSample2 : View 8 | { 9 | readonly State _textValue = "Edit Me"; 10 | 11 | [Body] 12 | View body() => new VStack() 13 | { 14 | new TextField(_textValue, "Name"), 15 | new HStack() 16 | { 17 | new Text("Current Value:") 18 | .Color(Colors.Grey), 19 | new Text(_textValue), 20 | new Spacer() 21 | }, 22 | }.FillHorizontal(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/TextFieldSample3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class TextFieldSample3 : View 8 | { 9 | class MyBindingObject : BindingObject 10 | { 11 | public string Text 12 | { 13 | get => GetProperty(); 14 | set => SetProperty(value); 15 | } 16 | } 17 | 18 | [State] private readonly MyBindingObject _state = new MyBindingObject { Text = "Edit Me" }; 19 | 20 | [Body] 21 | View Build() => new VStack() 22 | { 23 | new TextField(_state.Text, "Name"), 24 | new HStack() 25 | { 26 | new Text("Current Value:") 27 | .Color(Colors.Grey), 28 | new Text(_state.Text), 29 | new Spacer() 30 | }, 31 | }.FillHorizontal(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/TextFieldSample4.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class TextFieldSample4 : View 8 | { 9 | class MyBindingObject : BindingObject 10 | { 11 | public string Text 12 | { 13 | get => GetProperty(); 14 | set => SetProperty(value); 15 | } 16 | } 17 | 18 | [State] private readonly MyBindingObject _state = new MyBindingObject { Text = "Edit Me" }; 19 | 20 | [Body] 21 | View Build() => new VStack() 22 | { 23 | new TextField(_state.Text, "Name"), 24 | new HStack() 25 | { 26 | new Text("Current Value:") 27 | .Color(Colors.Grey), 28 | new Text(_state.Text), 29 | new Spacer() 30 | }, 31 | }.FillHorizontal(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/TextStylesSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.Samples 6 | { 7 | public class TextStylesSample : View 8 | { 9 | [Body] 10 | View body() => new ScrollView{ 11 | new VStack 12 | { 13 | new Text("H1").StyleAsH1(), 14 | new Text("H2").StyleAsH2(), 15 | new Text("H3").StyleAsH3(), 16 | new Text("H4").StyleAsH4(), 17 | new Text("H5").StyleAsH5(), 18 | new Text("H6").StyleAsH6(), 19 | new Text("Subtitle 1").StyleAsSubtitle1(), 20 | new Text("Subtitle 2").StyleAsSubtitle2(), 21 | new Text("Body 1").StyleAsBody1(), 22 | new Text("Body 2").StyleAsBody2(), 23 | new Text("Caption").StyleAsBody2(), 24 | new Text("OVERLINE").StyleAsOverline(), 25 | } 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/VGridNumberPad.cs: -------------------------------------------------------------------------------- 1 | namespace Comet.Samples; 2 | 3 | public class VGridNumberPad : View 4 | { 5 | [Body] 6 | View view() => new VGrid(3) 7 | { 8 | new Button("7"),new Button("8"),new Button("9"), 9 | new Button("4"),new Button("5"),new Button("6"), 10 | new Button("1"),new Button("2"),new Button("3"), 11 | new Button("0").NextColumn() 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/VGridSample.cs: -------------------------------------------------------------------------------- 1 | namespace Comet.Samples; 2 | 3 | public class VGridSample : View 4 | { 5 | [Body] 6 | View view() => new VGrid(4) 7 | { 8 | Enumerable.Range(0,20).Select(x=> 9 | new Text($"{x}") 10 | .HorizontalTextAlignment(TextAlignment.Center) 11 | ), 12 | }; 13 | } -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/VStackSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Comet.Samples 5 | { 6 | public class VStackSample : View 7 | { 8 | readonly State _textValue = "Edit Me"; 9 | readonly State _sliderValue = 50; 10 | 11 | [Body] 12 | View body() => new VStack() 13 | { 14 | new Text(_textValue), 15 | new TextField(_textValue, "Name"), 16 | new SecureField(_textValue, "Name"), 17 | new Slider(_sliderValue), 18 | new ProgressBar(_sliderValue) 19 | }.FillHorizontal(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/VirtualListViewSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class VirtualListViewSample : View 5 | { 6 | public VirtualListViewSample() 7 | { 8 | Body = () => new ListView 9 | { 10 | Count = () => 10, 11 | ItemFor = (i) => i, 12 | ViewFor = (i) => new Text(i.ToString()), 13 | }; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sample/Comet.Sample/Views/VirtualSectionedListViewSample.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Samples 3 | { 4 | public class VirtualSectionedListViewSample : View 5 | { 6 | public VirtualSectionedListViewSample() 7 | { 8 | Body = () => new SectionedListView 9 | { 10 | SectionCount = () => 10, 11 | SectionFor = (s) => new Section 12 | { 13 | Header = new Text($"Header: {s}"), 14 | Count = () => 10, 15 | ItemFor = (index) => index, 16 | ViewFor = (i) => new Text($"Row: {i}"), 17 | }, 18 | }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Comet.SourceGenerator/Comet.SourceGenerator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | preview 6 | 7 | 8 | 9 | 10 | 11 | true 12 | 13 | 14 | 15 | 16 | $(GetTargetPathDependsOn);GetDependencyTargetPaths 17 | 18 | 19 | 20 | 21 | 22 | 23 | $(GetTargetPathDependsOn);GetDependencyTargetPaths 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/Comet.SourceGenerator/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | static class StringExtensions 6 | { 7 | public static string LowercaseFirst(this string value) 8 | { 9 | if (string.IsNullOrWhiteSpace(value)) 10 | return value; 11 | var cleanValue = value.Trim(); 12 | var first = char.ToLower(cleanValue[0]); 13 | return $"{first}{cleanValue.Substring(1)}"; 14 | } 15 | 16 | 17 | } 18 | 19 | 20 | namespace Comet.SourceGenerator 21 | { 22 | public partial class ViewGenerator 23 | { 24 | 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /src/Comet.SourceGenerator/ViewGeneratorData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.SourceGenerator 6 | { 7 | public class ViewGeneratorData 8 | { 9 | public List NameSpaces { get; set; } = new List(); 10 | public string NameSpace { get; set; } 11 | 12 | public string ClassName { get; set; } 13 | 14 | public string BaseClassName { get; set; } 15 | 16 | public List<(string Type, string Name, string DefaultValueString)> Parameters { get; set; } = new (); 17 | 18 | public List<(string Type, string Name, string FullName, bool IsMethod, bool ShouldBeExtension)> Properties { get; set; } = new(); 19 | 20 | public List PropertiesWithSet { get; set; } = new(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Comet/Attributes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | 5 | [AttributeUsage(AttributeTargets.Field)] 6 | public class StateAttribute : Attribute 7 | { 8 | 9 | } 10 | 11 | [AttributeUsage(AttributeTargets.Method)] 12 | public class BodyAttribute : Attribute 13 | { 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/Comet/Controls/GraphicsView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet 5 | { 6 | public class GraphicsView : View, IDrawable, IGraphicsView 7 | { 8 | public Action Draw { get; set; } 9 | public Action CancelInteraction { get; set; } 10 | public Action DragInteraction { get; set; } 11 | public Action EndHoverInteraction { get; set; } 12 | public Action EndInteraction { get; set; } 13 | public Action MoveHoverInteraction { get; set; } 14 | public Action StartHoverInteraction { get; set; } 15 | public Action StartInteraction { get; set; } 16 | 17 | public void Invalidate() => ViewHandler?.Invoke(nameof(IGraphicsView.Invalidate)); 18 | 19 | IDrawable IGraphicsView.Drawable => this; 20 | 21 | void IDrawable.Draw(ICanvas canvas, RectF dirtyRect) => Draw?.Invoke(canvas, dirtyRect); 22 | 23 | void IGraphicsView.CancelInteraction() => CancelInteraction?.Invoke(); 24 | void IGraphicsView.DragInteraction(PointF[] points) => DragInteraction?.Invoke(points); 25 | void IGraphicsView.EndHoverInteraction() => EndHoverInteraction?.Invoke(); 26 | void IGraphicsView.EndInteraction(PointF[] points, bool isInsideBounds) => EndInteraction?.Invoke(points, isInsideBounds); 27 | void IGraphicsView.Invalidate() { } 28 | void IGraphicsView.MoveHoverInteraction(PointF[] points) => MoveHoverInteraction?.Invoke(points); 29 | void IGraphicsView.StartHoverInteraction(PointF[] points) => StartHoverInteraction?.Invoke(points); 30 | void IGraphicsView.StartInteraction(PointF[] points) => StartInteraction?.Invoke(points); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Comet/Controls/Grid.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Comet.Layout; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Layouts; 5 | 6 | namespace Comet 7 | { 8 | public class Grid : AbstractLayout 9 | { 10 | public Grid( 11 | object[] columns = null, 12 | object[] rows = null, 13 | float? spacing = null, 14 | object defaultRowHeight = null, 15 | object defaultColumnWidth = null) 16 | { 17 | Spacing = spacing; 18 | var layout = (Layout.GridLayoutManager)LayoutManager; 19 | 20 | layout.DefaultRowHeight = defaultRowHeight ?? "*"; 21 | layout.DefaultColumnWidth = defaultColumnWidth ?? "*"; 22 | 23 | if (columns != null) 24 | layout.AddColumns(columns); 25 | 26 | if (rows != null) 27 | layout.AddRows(rows); 28 | } 29 | 30 | public float? Spacing { get; } 31 | 32 | 33 | protected override ILayoutManager CreateLayoutManager() => new Comet.Layout.GridLayoutManager(this, Spacing); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Comet/Controls/HStack.cs: -------------------------------------------------------------------------------- 1 | using Comet.Layout; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Layouts; 4 | 5 | namespace Comet 6 | { 7 | public class HStack : AbstractLayout, IStackLayout 8 | { 9 | private readonly LayoutAlignment alignment; 10 | private readonly float? spacing; 11 | 12 | public HStack( 13 | LayoutAlignment alignment = LayoutAlignment.Center, 14 | float? spacing = null) : base() 15 | { 16 | this.alignment = alignment; 17 | this.spacing = spacing; 18 | } 19 | 20 | double IStackLayout.Spacing =>(spacing ?? 6); 21 | 22 | protected override ILayoutManager CreateLayoutManager() => new HStackLayoutManager(this,alignment,spacing); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Comet/Controls/IContainerView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Comet 5 | { 6 | public interface IContainerView : IView, IVisualTreeElement 7 | { 8 | 9 | IReadOnlyList IVisualTreeElement.GetVisualChildren() => Array.Empty(); 10 | IVisualTreeElement IVisualTreeElement.GetVisualParent() => this.Parent as IVisualTreeElement; 11 | IReadOnlyList GetChildren(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Comet/Controls/IContentTypeHash.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public interface IContentTypeHash 5 | { 6 | int GetContentTypeHashCode(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Comet/Controls/IControlState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public interface IControlState 5 | { 6 | ControlState CurrentState { get; set; } 7 | Action StateChanged { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Comet/Controls/IThumbView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | 4 | namespace Comet 5 | { 6 | public interface IThumbView : IView 7 | { 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Comet/Controls/LayoutEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Comet 5 | { 6 | public class LayoutEventArgs : EventArgs 7 | { 8 | public int Start { get; } 9 | public int Count { get; } 10 | public List Removed { get; } 11 | 12 | public LayoutEventArgs(int start, int count) 13 | { 14 | Start = start; 15 | Count = count; 16 | } 17 | 18 | public LayoutEventArgs(int start, int count, List removed) 19 | { 20 | Start = start; 21 | Count = count; 22 | Removed = removed; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Comet/Controls/ModalView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public class ModalView : ContentView 5 | { 6 | 7 | public static void Dismiss() => PerformDismiss?.Invoke(); 8 | public static Action PerformDismiss; 9 | 10 | public static void Present(View view) => PerformPresent?.Invoke(view); 11 | public static Action PerformPresent; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Comet/Controls/Orientation.cs: -------------------------------------------------------------------------------- 1 | namespace Comet 2 | { 3 | public enum Orientation 4 | { 5 | Vertical, 6 | Horizontal 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Comet/Controls/RadioButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Comet 4 | { 5 | public class RadioButton : View 6 | { 7 | public RadioButton( 8 | Binding label = null, 9 | Binding selected = null, 10 | Action onClick = null) 11 | { 12 | Label = label; 13 | Selected = selected; 14 | OnClick = onClick; 15 | } 16 | 17 | public RadioButton( 18 | Func label, 19 | Func selected = null, 20 | Action onClick = null) 21 | : this( 22 | (Binding)label, 23 | (Binding)selected, 24 | onClick) 25 | { 26 | 27 | } 28 | 29 | Binding _label; 30 | public Binding Label 31 | { 32 | get => _label; 33 | private set => this.SetBindingValue(ref _label, value); 34 | } 35 | 36 | Binding _selected; 37 | public Binding Selected 38 | { 39 | get => _selected; 40 | private set => this.SetBindingValue(ref _selected, value); 41 | } 42 | 43 | public Action OnClick { get; private set; } 44 | 45 | protected override View GetRenderView() 46 | { 47 | View view = base.GetRenderView(); 48 | 49 | if (view.Parent is RadioGroup) 50 | { 51 | return view; 52 | } 53 | 54 | // TODO: Create Comet-specific UI exceptions 55 | throw new Exception("A RadioButton must be in a RadioGroup"); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Comet/Controls/RadioGroup.cs: -------------------------------------------------------------------------------- 1 | using Comet.Layout; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Layouts; 4 | 5 | namespace Comet 6 | { 7 | public class RadioGroup : AbstractLayout, IStackLayout 8 | { 9 | public RadioGroup(Orientation orientation = Orientation.Vertical) 10 | : base() 11 | { 12 | Orientation = orientation; 13 | } 14 | 15 | public Orientation Orientation { get; } 16 | 17 | double IStackLayout.Spacing => 6; 18 | 19 | protected override ILayoutManager CreateLayoutManager() => Orientation == Orientation.Vertical 20 | ? new VerticalStackLayoutManager(this) : new HorizontalStackLayoutManager(this); 21 | 22 | protected override void OnAdded(View view) 23 | { 24 | if (view is RadioButton) 25 | { 26 | base.OnAdded(view); 27 | } 28 | else 29 | { 30 | throw new System.Exception("A RadioGroup may only contain RadioButtons"); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Comet/Controls/ResultView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Comet 5 | { 6 | public class ResultView : ContentView 7 | { 8 | TaskCompletionSource tcs = new TaskCompletionSource(); 9 | 10 | public Task GetResult() => tcs.Task; 11 | 12 | public void Cancel() => tcs.TrySetCanceled(); 13 | 14 | public void SetResult(T value) => tcs.TrySetResult(value); 15 | 16 | public void SetException(Exception ex) => tcs.TrySetException(ex); 17 | 18 | protected override void Dispose(bool disposing) 19 | { 20 | if (disposing) 21 | { 22 | tcs.TrySetCanceled(); 23 | } 24 | base.Dispose(disposing); 25 | } 26 | 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Comet/Controls/ShapeView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Comet.Graphics; 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet 6 | { 7 | /// 8 | /// A view that displays a shape. 9 | /// 10 | public class ShapeView : View, IDrawable 11 | { 12 | public ShapeView(Binding value) 13 | { 14 | Shape = value; 15 | } 16 | public ShapeView(Func value) 17 | { 18 | Shape = value; 19 | } 20 | 21 | Binding _shape; 22 | public Binding Shape 23 | { 24 | get => _shape; 25 | private set => this.SetBindingValue(ref _shape, value); 26 | } 27 | 28 | void IDrawable.Draw(ICanvas canvas, RectF dirtyRect) { 29 | var padding = this.GetPadding(); 30 | dirtyRect = dirtyRect.ApplyPadding(padding); 31 | 32 | var shape = Shape.CurrentValue; 33 | var drawingStyle = shape.GetDrawingStyle(this, DrawingStyle.StrokeFill); 34 | var strokeColor = shape.GetStrokeColor(this, Colors.Black); 35 | var strokeWidth = shape.GetLineWidth(this, 1); 36 | var fill = shape.GetFill(this); 37 | canvas.DrawShape(shape, dirtyRect, drawingStyle, strokeWidth, strokeColor, fill); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Comet/Controls/Spacer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet 6 | { 7 | public class Spacer : View 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Comet/Controls/TabView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public class TabView : ContainerView 5 | { 6 | public TabView() : base() 7 | { 8 | 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Controls/VStack.cs: -------------------------------------------------------------------------------- 1 | using Comet.Layout; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Layouts; 4 | 5 | namespace Comet 6 | { 7 | public class VStack : AbstractLayout, IStackLayout 8 | { 9 | private readonly LayoutAlignment alignment; 10 | private readonly float? spacing; 11 | 12 | public VStack( 13 | LayoutAlignment alignment = LayoutAlignment.Center, 14 | float? spacing = null) 15 | { 16 | this.alignment = alignment; 17 | this.spacing = spacing; 18 | } 19 | 20 | double IStackLayout.Spacing => (int)(spacing ?? 6); 21 | 22 | protected override ILayoutManager CreateLayoutManager() => new VStackLayoutManager(this, alignment,spacing); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Comet/Controls/WebView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public class WebView : View 5 | { 6 | Binding html; 7 | public Binding Html 8 | { 9 | get => html; 10 | set => this.SetBindingValue(ref html, value); 11 | } 12 | 13 | Binding source; 14 | public Binding Source 15 | { 16 | get => source; 17 | set => this.SetBindingValue(ref source, value); 18 | } 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Comet/Controls/ZStack.cs: -------------------------------------------------------------------------------- 1 | using Comet.Layout; 2 | using Microsoft.Maui.Layouts; 3 | 4 | namespace Comet 5 | { 6 | public class ZStack : AbstractLayout 7 | { 8 | protected override ILayoutManager CreateLayoutManager() => new ZStackLayoutManager(this); 9 | protected override Thickness GetDefaultPadding() => Thickness.Zero; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Exceptions/ReadonlyRequiresException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public class ReadonlyRequiresException : Exception 5 | { 6 | public ReadonlyRequiresException(string className, string propertyName) : base($"{className}.{propertyName} is not readonly") 7 | { 8 | ClassName = className; 9 | PropertyName = propertyName; 10 | } 11 | 12 | public string ClassName { get; } 13 | public string PropertyName { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Comet/FrameConstraints.cs: -------------------------------------------------------------------------------- 1 | namespace Comet 2 | { 3 | public class FrameConstraints 4 | { 5 | public FrameConstraints(float? width, float? height) 6 | { 7 | Width = width; 8 | Height = height; 9 | } 10 | 11 | public float? Width { get; } 12 | public float? Height { get; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Comet/Gestures/Gesture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public class Gesture : Gesture 5 | { 6 | public Gesture(Action action) 7 | { 8 | Action = action; 9 | } 10 | 11 | public Action Action { get; } 12 | public override void Invoke() => Action?.Invoke((T)Convert.ChangeType(this, typeof(T))); 13 | } 14 | public class Gesture 15 | { 16 | public const string AddGestureProperty = "AddGesture"; 17 | public const string RemoveGestureProperty = "RemoveGesture"; 18 | 19 | public object PlatformGesture { get; set; } 20 | 21 | public virtual void Invoke() 22 | { 23 | 24 | } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Comet/Gestures/IGestureView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public interface IGestureView 5 | { 6 | IReadOnlyList Gestures { get; } 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /src/Comet/Gestures/TapGesture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public class TapGesture : Gesture 5 | { 6 | public TapGesture(Action action) : base(action) 7 | { 8 | 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using Microsoft.Maui; 3 | global using Microsoft.Maui.Platform; 4 | global using Microsoft.Maui.Handlers; 5 | global using Microsoft.Maui.Graphics; 6 | global using System.Collections.Generic; 7 | global using System.Threading.Tasks; 8 | global using System.Linq; 9 | global using Microsoft.Maui.Primitives; 10 | global using Font = Microsoft.Maui.Font; -------------------------------------------------------------------------------- /src/Comet/Graphics/DrawingStyle.cs: -------------------------------------------------------------------------------- 1 | namespace Comet.Graphics 2 | { 3 | public enum DrawingStyle 4 | { 5 | StrokeFill, 6 | Stroke, 7 | Fill 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Comet/Graphics/Gradient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Graphics 5 | { 6 | public class Gradient 7 | { 8 | private Stop[] _sortedStops; 9 | 10 | /// 11 | /// The gradient synthesizes its location values to evenly space the colors along the gradient. 12 | /// 13 | /// 14 | public Gradient(Color[] colors) 15 | { 16 | if (colors == null) throw new ArgumentNullException(nameof(colors)); 17 | 18 | Stops = new Stop[colors.Length]; 19 | for (var i = 0; i < colors.Length; i++) 20 | { 21 | var offset = (float)i / (float)(colors.Length - 1); 22 | Stops[i] = new Stop(offset, colors[i]); 23 | } 24 | } 25 | 26 | /// 27 | /// Creates a gradient from an array of color stops. 28 | /// 29 | /// 30 | public Gradient(Stop[] stops) 31 | { 32 | if (stops == null) throw new ArgumentNullException(nameof(stops)); 33 | 34 | Stops = stops; 35 | } 36 | 37 | public Stop[] Stops { get; } 38 | 39 | public Stop[] GetSortedStops() 40 | { 41 | if (_sortedStops == null) 42 | { 43 | _sortedStops = new Stop[Stops.Length]; 44 | Array.Copy(Stops, _sortedStops, Stops.Length); 45 | Array.Sort(_sortedStops); 46 | } 47 | 48 | return _sortedStops; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Comet/Graphics/IControlDelegate.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using Microsoft.Maui; 3 | //using Microsoft.Maui.Graphics; 4 | 5 | //namespace Comet.Graphics 6 | //{ 7 | // public interface IControlDelegate 8 | // { 9 | // event Action Invalidated; 10 | // PropertyMapper Mapper { get; } 11 | // RectangleF Bounds { get; } 12 | // DrawableControl VirtualDrawableControl { get; set; } 13 | // IDrawableControl PlatformDrawableControl { get; set; } 14 | // void Invalidate(); 15 | // void Draw(ICanvas canvas, RectangleF dirtyRect); 16 | // void StartHoverInteraction(PointF[] points); 17 | // void HoverInteraction(PointF[] points); 18 | // void EndHoverInteraction(); 19 | // bool StartInteraction(PointF[] points); 20 | // void DragInteraction(PointF[] points); 21 | // void EndInteraction(PointF[] points); 22 | // void CancelInteraction(); 23 | // void Resized(RectangleF bounds); 24 | // void AddedToView(object nativeView, RectangleF bounds); 25 | // void RemovedFromView(object nativeView); 26 | // SizeF GetIntrinsicSize(SizeF availableSize); 27 | // void ViewPropertyChanged(string property, object value); 28 | // } 29 | //} 30 | -------------------------------------------------------------------------------- /src/Comet/Graphics/IDrawableControl.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //namespace Comet.Graphics 3 | //{ 4 | // public interface IDrawableControl 5 | // { 6 | // IControlDelegate ControlDelegate { get; set; } 7 | // } 8 | //} 9 | -------------------------------------------------------------------------------- /src/Comet/Graphics/LinearGradient.cs: -------------------------------------------------------------------------------- 1 |  2 | using System.Net; 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Graphics 6 | { 7 | public class LinearGradient : Gradient 8 | { 9 | public LinearGradient(Color[] colors, Point startPoint, Point endPoint) : base(colors) 10 | { 11 | StartPoint = startPoint; 12 | EndPoint = endPoint; 13 | } 14 | 15 | public LinearGradient(Stop[] stops, Point startPoint, Point endPoint) : base(stops) 16 | { 17 | StartPoint = startPoint; 18 | EndPoint = endPoint; 19 | } 20 | 21 | public Point StartPoint { get; } 22 | public Point EndPoint { get; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Comet/Graphics/PathOperation.cs: -------------------------------------------------------------------------------- 1 | namespace Comet.Graphics 2 | { 3 | public enum PathOperation 4 | { 5 | MoveTo, 6 | Line, 7 | Quad, 8 | Cubic, 9 | Arc, 10 | Close 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Comet/Graphics/RadialGradient.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Graphics 6 | { 7 | public class RadialGradient : Gradient 8 | { 9 | public RadialGradient(Color[] colors, Point center, float startRadius, float endRadius) : base(colors) 10 | { 11 | Center = center; 12 | StartRadius = startRadius; 13 | EndRadius = endRadius; 14 | } 15 | 16 | public RadialGradient(Stop[] stops, Point center, float startRadius, float endRadius) : base(stops) 17 | { 18 | Center = center; 19 | StartRadius = startRadius; 20 | EndRadius = endRadius; 21 | } 22 | 23 | public Point Center { get; } 24 | 25 | public float StartRadius { get; } 26 | 27 | public float EndRadius { get; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Comet/Graphics/Stop.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Graphics 5 | { 6 | public class Stop : IComparable 7 | { 8 | private Color _color; 9 | private float _offset; 10 | 11 | public Stop(float offset, Color color) 12 | { 13 | _color = color; 14 | _offset = offset; 15 | } 16 | 17 | public Stop(Stop source) 18 | { 19 | _color = source._color; 20 | _offset = source._offset; 21 | } 22 | 23 | public Color Color 24 | { 25 | get => _color; 26 | set => _color = value; 27 | } 28 | 29 | public float Offset 30 | { 31 | get => _offset; 32 | set => _offset = value; 33 | } 34 | 35 | public int CompareTo(Stop obj) 36 | { 37 | if (_offset < obj._offset) 38 | return -1; 39 | if (_offset > obj._offset) 40 | return 1; 41 | 42 | return 0; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ListView/ListViewHandler.Android.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.Views; 3 | using Android.Widget; 4 | using AndroidX.RecyclerView.Widget; 5 | using AView = Android.Views.View; 6 | using Comet.Android.Controls; 7 | using System.Drawing; 8 | using Android.Content; 9 | using Microsoft.Maui.Handlers; 10 | using Microsoft.Maui; 11 | 12 | namespace Comet.Handlers 13 | { 14 | public partial class ListViewHandler : ViewHandler 15 | { 16 | 17 | protected override CometRecyclerView CreatePlatformView() => new CometRecyclerView(MauiContext); 18 | 19 | 20 | public override Microsoft.Maui.Graphics.Size GetDesiredSize(double widthConstraint, double heightConstraint) => new Microsoft.Maui.Graphics.Size(widthConstraint, heightConstraint); 21 | //public override SizeF GetIntrinsicSize(SizeF availableSize) 22 | //{ 23 | // //base.GetIntrinsicSize(availableSize); 24 | // return Comet.View.UseAvailableWidthAndHeight; 25 | //} 26 | 27 | public static void MapListViewProperty(IElementHandler viewHandler, IListView virtualView) 28 | { 29 | var nativeView = (CometRecyclerView)viewHandler.PlatformView; 30 | nativeView.ListView = virtualView; 31 | } 32 | 33 | public static void MapReloadData(ListViewHandler viewHandler, IListView virtualView, object? value) 34 | { 35 | var nativeView = (CometRecyclerView)viewHandler.PlatformView; 36 | nativeView?.ReloadData(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ListView/ListViewHandler.Standard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Handlers; 4 | 5 | namespace Comet.Handlers 6 | { 7 | public partial class ListViewHandler : ViewHandler 8 | { 9 | public static void MapListViewProperty(IElementHandler viewHandler, IListView virtualView) 10 | { 11 | } 12 | 13 | public static void MapReloadData(ListViewHandler viewHandler, IListView virtualView, object? value) 14 | { 15 | } 16 | 17 | protected override object CreatePlatformView() => throw new NotImplementedException(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ListView/ListViewHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Graphics; 4 | using Microsoft.Maui.Handlers; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class ListViewHandler 9 | { 10 | public static readonly PropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper) 11 | { 12 | ["ListView"] = MapListViewProperty, 13 | 14 | }; 15 | public static readonly CommandMapper ActionMapper = new CommandMapper 16 | { 17 | [nameof(ListView.ReloadData)] = MapReloadData, 18 | }; 19 | 20 | public ListViewHandler() : base(Mapper, ActionMapper) 21 | { 22 | 23 | } 24 | public ListViewHandler(PropertyMapper mapper) : base(mapper) 25 | { 26 | 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ListView/ListViewHandler.iOS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Foundation; 3 | using UIKit; 4 | using Microsoft.Maui.Handlers; 5 | using Microsoft.Maui; 6 | using Comet.iOS; 7 | 8 | 9 | namespace Comet.Handlers 10 | { 11 | public partial class ListViewHandler : ViewHandler 12 | { 13 | 14 | 15 | public static void MapListViewProperty(IElementHandler viewHandler, IListView virtualView) 16 | { 17 | var PlatformView = (CUITableView)viewHandler.PlatformView; 18 | PlatformView.ListView = virtualView; 19 | PlatformView.SizeToFit(); 20 | } 21 | 22 | public static void MapReloadData(ListViewHandler viewHandler, IListView virtualView, object? value) 23 | { 24 | var PlatformView = (CUITableView)viewHandler.PlatformView; 25 | PlatformView?.ReloadData(); 26 | } 27 | 28 | protected override CUITableView CreatePlatformView() => new CUITableView(MauiContext); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Comet/Handlers/Navigation/NavigationViewHandler.Android.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Comet.Android.Controls; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics; 5 | using Microsoft.Maui.Handlers; 6 | //using Comet.iOS; 7 | namespace Comet.Handlers 8 | { 9 | public partial class NavigationViewHandler : ViewHandler, IPlatformViewHandler 10 | { 11 | protected override CometNavigationView CreatePlatformView() 12 | => new CometNavigationView(MauiContext); 13 | public override void SetVirtualView(IView view) 14 | { 15 | base.SetVirtualView(view); 16 | if (VirtualView != null) 17 | { 18 | PlatformView.SetRoot(VirtualView.Content); 19 | VirtualView?.SetPerformNavigate(PlatformView.NavigateTo); 20 | VirtualView?.SetPerformPop(PlatformView.Pop); 21 | } 22 | } 23 | protected override void DisconnectHandler(CometNavigationView nativeView) 24 | { 25 | base.DisconnectHandler(nativeView); 26 | 27 | if (VirtualView != null) 28 | { 29 | VirtualView.SetPerformNavigate(action: null); 30 | VirtualView.SetPerformPop(action: null); 31 | } 32 | 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Comet/Handlers/Navigation/NavigationViewHandler.Standard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | using Microsoft.Maui; 4 | namespace Comet.Handlers 5 | { 6 | public partial class NavigationViewHandler: ViewHandler 7 | { 8 | protected override object CreatePlatformView() => throw new NotImplementedException(); 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Handlers/Navigation/NavigationViewHandler.Windows.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | using Microsoft.Maui; 4 | using Microsoft.UI.Xaml.Controls; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class NavigationViewHandler : ViewHandler 9 | { 10 | protected override Panel CreatePlatformView() => new LayoutPanel(); 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Comet/Handlers/Navigation/NavigationViewHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Graphics; 4 | using Microsoft.Maui.Handlers; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class NavigationViewHandler 9 | { 10 | public NavigationViewHandler() : base(ViewHandler.ViewMapper) 11 | { 12 | 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Comet/Handlers/Navigation/NavigationViewHandler.iOS.cs: -------------------------------------------------------------------------------- 1 | using Comet.iOS; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Handlers; 4 | using UIKit; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class NavigationViewHandler : ViewHandler, IPlatformViewHandler 9 | { 10 | UIViewController viewController; 11 | UIViewController IPlatformViewHandler.ViewController => viewController; 12 | protected override UIView CreatePlatformView() 13 | { 14 | var vc = new Comet.iOS.CometViewController { MauiContext = MauiContext, CurrentView = VirtualView.Content }; 15 | var nav = VirtualView; 16 | if (nav.Navigation != null) 17 | { 18 | viewController = vc; 19 | return viewController.View; 20 | } 21 | var navigationController = new CUINavigationController(); 22 | viewController = navigationController; 23 | nav.SetPerformNavigate((toView) => { 24 | if (toView is NavigationView newNav) 25 | { 26 | newNav.SetPerformNavigate(nav); 27 | newNav.SetPerformPop(nav); 28 | } 29 | 30 | toView.Navigation = nav; 31 | var newVc = new Comet.iOS.CometViewController { MauiContext = MauiContext, CurrentView = toView }; 32 | navigationController.PushViewController(newVc, true); 33 | }); 34 | nav.SetPerformPop(() => navigationController.PopViewController(true)); 35 | navigationController.PushViewController(vc, true); 36 | 37 | return navigationController.View; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Comet/Handlers/RadioButton/RadioButtonHandler.Android.cs: -------------------------------------------------------------------------------- 1 | //using Android.Content; 2 | //using ARadioButton = Android.Widget.RadioButton; 3 | 4 | //namespace Comet.Android.Handlers 5 | //{ 6 | // public class RadioButtonHandler : AbstractControlHandler 7 | // { 8 | // public static readonly PropertyMapper Mapper = new PropertyMapper() 9 | // { 10 | // [nameof(RadioButton.Label)] = MapLabelProperty, 11 | // [nameof(RadioButton.Selected)] = MapSelectedProperty 12 | // }; 13 | 14 | // public RadioButtonHandler() : base(Mapper) 15 | // { 16 | // } 17 | 18 | // protected override ARadioButton CreateView(Context context) 19 | // { 20 | // var radioButton = new ARadioButton(context); 21 | // radioButton.Click += HandleClick; 22 | // return radioButton; 23 | // } 24 | 25 | // protected override void DisposeView(ARadioButton nativeView) 26 | // { 27 | // nativeView.Click -= HandleClick; 28 | // } 29 | 30 | // private void HandleClick(object sender, System.EventArgs e) 31 | // { 32 | // VirtualView?.OnClick?.Invoke(); 33 | // } 34 | 35 | // public static void MapLabelProperty(IViewHandler viewHandler, RadioButton virtualRadioButton) 36 | // { 37 | // var nativeRadioButton = (ARadioButton)viewHandler.PlatformView; 38 | // nativeRadioButton.Text = virtualRadioButton.Label?.CurrentValue; 39 | // } 40 | 41 | // public static void MapSelectedProperty(IViewHandler viewHandler, RadioButton virtualRadioButton) 42 | // { 43 | // var nativeRadioButton = (ARadioButton)viewHandler.PlatformView; 44 | // nativeRadioButton.Checked = virtualRadioButton.Selected; 45 | // } 46 | // } 47 | //} -------------------------------------------------------------------------------- /src/Comet/Handlers/RadioButton/RadioButtonHandler.iOS.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using Microsoft.Maui; 3 | //using Microsoft.Maui.Handlers; 4 | //using UIKit; 5 | 6 | //namespace Comet.iOS.Handlers 7 | //{ 8 | // class RadioButtonHandler : ViewHandler 9 | // { 10 | // public static readonly PropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper) 11 | // { 12 | // [nameof(RadioButton.Label)] = MapLabelProperty, 13 | // [nameof(RadioButton.Selected)] = MapSelectedProperty 14 | // }; 15 | 16 | // public RadioButtonHandler() : base(Mapper) 17 | // { 18 | // } 19 | 20 | // protected override CUIRadioButton CreateView() 21 | // { 22 | // var button = new CUIRadioButton(VirtualView.Selected); 23 | 24 | // button.TouchUpInside += HandleTouchUpInside; 25 | 26 | // return button; 27 | // } 28 | 29 | // protected override void DisposeView(CUIRadioButton nativeView) 30 | // { 31 | // nativeView.TouchUpInside -= HandleTouchUpInside; 32 | // } 33 | 34 | // private void HandleTouchUpInside(object sender, EventArgs e) => VirtualView?.OnClick?.Invoke(); 35 | 36 | // public static void MapLabelProperty(IViewHandler viewHandler, RadioButton virtualRadioButton) 37 | // { 38 | // var nativeRadioButton = (CUIRadioButton)viewHandler.PlatformView; 39 | // nativeRadioButton.SetTitle(virtualRadioButton.Label?.CurrentValue, UIControlState.Normal); 40 | // virtualRadioButton.InvalidateMeasurement(); 41 | // } 42 | 43 | // public static void MapSelectedProperty(IViewHandler viewHandler, RadioButton virtualRadioButton) 44 | // { 45 | // var nativeRadioButton = (CUIRadioButton)viewHandler.PlatformView; 46 | // nativeRadioButton.IsChecked = virtualRadioButton.Selected; 47 | // } 48 | // } 49 | //} -------------------------------------------------------------------------------- /src/Comet/Handlers/RadioButton/RadioGroupHandler.iOS.cs: -------------------------------------------------------------------------------- 1 | //using System.Collections.Generic; 2 | //using System.Linq; 3 | //using CoreGraphics; 4 | //using UIKit; 5 | 6 | //namespace Comet.iOS.Handlers 7 | //{ 8 | // class RadioGroupHandler : AbstractLayoutHandler 9 | // { 10 | // private List RadioButtons = new List(); 11 | 12 | // public RadioGroupHandler(CGRect rect) : base(rect) 13 | // { 14 | // } 15 | 16 | // public RadioGroupHandler() : base() 17 | // { 18 | // } 19 | 20 | // public override void SubviewAdded(UIView uiview) 21 | // { 22 | // base.SubviewAdded(uiview); 23 | 24 | // var radioButton = (CUIRadioButton)uiview; 25 | // radioButton.IsCheckedChanged += HandleIsCheckedChanged; 26 | // RadioButtons.Add(radioButton); 27 | // } 28 | 29 | // public override void WillRemoveSubview(UIView uiview) 30 | // { 31 | // base.WillRemoveSubview(uiview); 32 | 33 | // var radioButton = (CUIRadioButton)uiview; 34 | // radioButton.IsCheckedChanged -= HandleIsCheckedChanged; 35 | // RadioButtons.Remove(radioButton); 36 | // } 37 | 38 | // protected override void Dispose(bool disposing) 39 | // { 40 | // foreach(var button in RadioButtons) 41 | // { 42 | // button.IsCheckedChanged -= HandleIsCheckedChanged; 43 | // } 44 | 45 | // RadioButtons.Clear(); 46 | 47 | // base.Dispose(disposing); 48 | // } 49 | 50 | // private void HandleIsCheckedChanged(object sender, System.EventArgs e) 51 | // { 52 | // var changedButton = (CUIRadioButton)sender; 53 | 54 | // if (changedButton.IsChecked) 55 | // { 56 | // foreach(var button in RadioButtons.Where(_ => _ != changedButton)) 57 | // { 58 | // button.IsChecked = false; 59 | // } 60 | // } 61 | // } 62 | // } 63 | //} -------------------------------------------------------------------------------- /src/Comet/Handlers/ScrollView/ScrollViewHandler.Standard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | using Microsoft.Maui; 4 | namespace Comet.Handlers 5 | { 6 | public partial class ScrollViewHandler: ViewHandler 7 | { 8 | protected override object CreatePlatformView() => throw new NotImplementedException(); 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ScrollView/ScrollViewHandler.Windows.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | using Microsoft.Maui; 4 | using UWPScrollView = Microsoft.UI.Xaml.Controls.ScrollViewer; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class ScrollViewHandler : ViewHandler 9 | { 10 | protected override UWPScrollView CreatePlatformView() => new UWPScrollView(); 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ScrollView/ScrollViewHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Graphics; 4 | using Microsoft.Maui.Handlers; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class ScrollViewHandler 9 | { 10 | public ScrollViewHandler() : base(ViewHandler.ViewMapper) 11 | { 12 | 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ShapeView/ShapeViewHandler.Android.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics.Platform; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class ShapeViewHandler : ViewHandler 9 | { 10 | protected override PlatformGraphicsView CreatePlatformView() => new PlatformGraphicsView(MauiContext.Context); 11 | 12 | 13 | public static void MapShapeProperty(IElementHandler viewHandler, ShapeView virtualView) 14 | { 15 | var nativeView = (PlatformGraphicsView)viewHandler.PlatformView; 16 | nativeView.Drawable = virtualView; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ShapeView/ShapeViewHandler.Standard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | using Microsoft.Maui; 4 | namespace Comet.Handlers 5 | { 6 | public partial class ShapeViewHandler : ViewHandler 7 | { 8 | protected override object CreatePlatformView() => throw new NotImplementedException(); 9 | 10 | public static void MapShapeProperty(IElementHandler viewHandler, ShapeView virtualView) { } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ShapeView/ShapeViewHandler.Windows.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | //using Microsoft.Maui.Graphics.Platform; 4 | using Microsoft.Maui; 5 | using Microsoft.UI.Xaml.Controls; 6 | 7 | namespace Comet.Handlers 8 | { 9 | public partial class ShapeViewHandler : ViewHandler 10 | { 11 | protected override Panel CreatePlatformView() => new LayoutPanel(); 12 | 13 | 14 | public static void MapShapeProperty(IElementHandler viewHandler, ShapeView virtualView) 15 | { 16 | //var nativeView = (PlatformGraphicsView)viewHandler.PlatformView; 17 | //nativeView.Drawable = virtualView; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ShapeView/ShapeViewHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Handlers; 4 | 5 | namespace Comet.Handlers 6 | { 7 | public partial class ShapeViewHandler 8 | { 9 | public static readonly PropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper) 10 | { 11 | [nameof(ShapeView.Shape)] = MapShapeProperty 12 | }; 13 | 14 | 15 | 16 | public ShapeViewHandler() : base(Mapper) 17 | { 18 | } 19 | 20 | public ShapeViewHandler(PropertyMapper mapper) : base(mapper) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Comet/Handlers/ShapeView/ShapeViewHandler.iOS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Handlers; 3 | using Microsoft.Maui.Graphics.Platform; 4 | using Microsoft.Maui; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class ShapeViewHandler : ViewHandler 9 | { 10 | protected override PlatformGraphicsView CreatePlatformView() => new PlatformGraphicsView(); 11 | 12 | 13 | public static void MapShapeProperty(IElementHandler viewHandler, ShapeView virtualView) 14 | { 15 | var nativeView = (PlatformGraphicsView)viewHandler.PlatformView; 16 | nativeView.Drawable = virtualView; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Comet/Handlers/Spacer/SpacerHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Graphics; 4 | using Microsoft.Maui.Handlers; 5 | #if __IOS__ 6 | 7 | using PlatformView = UIKit.UIView; 8 | #elif ANDROID 9 | using PlatformView = Android.Views.View; 10 | #elif WINDOWS 11 | using PlatformView = Microsoft.UI.Xaml.Controls.Panel; 12 | 13 | #else 14 | using PlatformView = System.Object; 15 | #endif 16 | 17 | 18 | namespace Comet.Handlers 19 | { 20 | public partial class SpacerHandler : ViewHandler 21 | { 22 | public static readonly PropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper); 23 | public SpacerHandler() : base(Mapper) 24 | { 25 | 26 | } 27 | 28 | protected override PlatformView CreatePlatformView() => 29 | #if ANDROID 30 | new PlatformView(Context.ApplicationContext); 31 | #elif WINDOWS 32 | new LayoutPanel(); 33 | #else 34 | new PlatformView(); 35 | #endif 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Comet/Handlers/TabView/TabViewHandler.Android.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.Views; 3 | using Android.Widget; 4 | using AView = Android.Views.View; 5 | using Comet.Android.Controls; 6 | using Android.Content; 7 | using Android.Util; 8 | using System.Linq; 9 | using Microsoft.Maui.Handlers; 10 | using Microsoft.Maui; 11 | 12 | namespace Comet.Handlers 13 | { 14 | public partial class TabViewHandler : ViewHandler 15 | { 16 | //private AView _view; 17 | protected override CometTabView CreatePlatformView() => new CometTabView(MauiContext); 18 | 19 | 20 | protected override void ConnectHandler(CometTabView nativeView) 21 | { 22 | base.ConnectHandler(nativeView); 23 | } 24 | public override void SetVirtualView(IView view) { 25 | base.SetVirtualView(view); 26 | 27 | PlatformView?.CreateTabs(this.VirtualView); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Comet/Handlers/TabView/TabViewHandler.Standard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Handlers; 4 | 5 | namespace Comet.Handlers 6 | { 7 | public partial class TabViewHandler : ViewHandler 8 | { 9 | protected override object CreatePlatformView() => throw new NotImplementedException(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Handlers/TabView/TabViewHandler.Windows.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Handlers; 5 | using Microsoft.UI.Xaml; 6 | using Microsoft.UI.Xaml.Controls; 7 | 8 | 9 | namespace Comet.Handlers 10 | { 11 | public partial class TabViewHandler : ViewHandler 12 | { 13 | protected override Panel CreatePlatformView() => PlatformView ?? new LayoutPanel { }; 14 | 15 | 16 | //public override void SetVirtualView(IView view) 17 | //{ 18 | // base.SetVirtualView(view); 19 | 20 | // PlatformView?.Setup(this.VirtualView); 21 | //} 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Comet/Handlers/TabView/TabViewHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Graphics; 4 | using Microsoft.Maui.Handlers; 5 | 6 | namespace Comet.Handlers 7 | { 8 | public partial class TabViewHandler 9 | { 10 | 11 | public TabViewHandler() : base(ViewHandler.ViewMapper) 12 | { 13 | 14 | } 15 | public TabViewHandler(PropertyMapper mapper) : base(mapper) 16 | { 17 | 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Comet/Handlers/TabView/TabViewHandler.iOS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Comet.iOS; 4 | using Microsoft.Maui; 5 | using Microsoft.Maui.Handlers; 6 | 7 | namespace Comet.Handlers 8 | { 9 | public partial class TabViewHandler : ViewHandler 10 | { 11 | //public override bool IgnoreSafeArea => VirtualView?.GetIgnoreSafeArea(true) ?? true; 12 | protected override CUITabView CreatePlatformView() => new CUITabView { Context = MauiContext }; 13 | 14 | 15 | public override void SetVirtualView(IView view) 16 | { 17 | base.SetVirtualView(view); 18 | 19 | PlatformView?.Setup(this.VirtualView); 20 | } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Comet/Handlers/View/CometViewHandler.Android.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Graphics; 4 | using Microsoft.Maui.Handlers; 5 | namespace Comet.Handlers 6 | { 7 | public partial class CometViewHandler 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Handlers/View/CometViewHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Handlers 3 | { 4 | public partial class CometViewHandler 5 | { 6 | public static void AddGesture(IViewHandler viewHandler, IView view, object arg) 7 | { 8 | if (arg is not Gesture g) 9 | return; 10 | viewHandler.AddGesture(g); 11 | } 12 | public static void RemoveGesture(IViewHandler viewHandler, IView view, object arg) 13 | { 14 | if (arg is not Gesture g) 15 | return; 16 | viewHandler.RemoveGesture(g); 17 | } 18 | public static void AddGestures(IViewHandler viewHandler, IView view) 19 | { 20 | if (!(view is IGestureView ig)) 21 | return; 22 | var gestures = ig.Gestures; 23 | if (!(gestures?.Any() ?? false)) 24 | return; 25 | foreach (var g in gestures) 26 | viewHandler.AddGesture(g); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Comet/Handlers/View/CometViewHandler.iOS.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Comet.iOS; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics; 5 | using Microsoft.Maui.Handlers; 6 | using UIKit; 7 | 8 | namespace Comet.Handlers 9 | { 10 | public partial class CometViewHandler : ViewHandler, IPlatformViewHandler 11 | { 12 | public static PropertyMapper CometViewMapper = new () 13 | { 14 | [nameof(ITitledElement.Title)] = MapTitle, 15 | [nameof(IView.Background)] = MapBackgroundColor, 16 | }; 17 | 18 | 19 | public CometViewHandler() : base(CometViewMapper) 20 | { 21 | 22 | } 23 | CometViewController viewController; 24 | UIViewController IPlatformViewHandler.ViewController => viewController ??= new CometViewController { ContainerView = this.PlatformView, MauiContext = MauiContext }; 25 | protected override CometView CreatePlatformView() => new CometView(MauiContext); 26 | public override void SetVirtualView(IView view) 27 | { 28 | base.SetVirtualView(view); 29 | PlatformView.CurrentView = view; 30 | } 31 | 32 | 33 | public static void MapTitle(CometViewHandler handler, View view) 34 | { 35 | var vc = handler?.viewController; 36 | if (vc == null) 37 | return; 38 | vc.Title = view.GetTitle() ?? ""; 39 | } 40 | public static void MapBackgroundColor(CometViewHandler handler, View view) 41 | { 42 | var vc = handler?.viewController; 43 | if (vc == null) 44 | return; 45 | vc.View.UpdateBackground(view); 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Comet/Helpers/BaseExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace Comet 5 | { 6 | public static class BaseExtensions 7 | { 8 | public static string FirstCharToUpper(this string input) 9 | { 10 | if (input != null) 11 | return string.IsNullOrWhiteSpace(input) 12 | ? input[0].ToString().ToUpper() + input.Substring(1) 13 | : input; 14 | 15 | return null; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Comet/Helpers/ControlsExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Comet.Internal; 3 | namespace Comet 4 | { 5 | public static class ControlsExtensions 6 | { 7 | //public static double GetPercent(this Slider slider) 8 | //{ 9 | // var end = slider.Maximum?.CurrentValue ?? 0; 10 | // var current = slider.Value?.CurrentValue ?? 0; 11 | // return current.SafeDivideByZero(end); 12 | //} 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Comet/Helpers/LineBreakModeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | 4 | namespace Comet 5 | { 6 | public static class LineBreakModeExtensions 7 | { 8 | public static LineBreakMode GetLineBreakMode(this T view, LineBreakMode defaultMode) where T : View 9 | { 10 | var mode = view.GetEnvironment(EnvironmentKeys.LineBreakMode.Mode); 11 | return mode ?? defaultMode; 12 | } 13 | 14 | public static T LineBreakMode(this T view, Binding mode) where T : View => 15 | view.SetEnvironment(EnvironmentKeys.LineBreakMode.Mode, mode); 16 | public static T LineBreakMode(this T view, Func mode) where T : View => 17 | view.LineBreakMode((Binding)mode); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Comet/Helpers/ListExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Comet.Internal 6 | { 7 | public static class ListExtensions 8 | { 9 | public static T SafeGetAtIndex(this IReadOnlyList list, int index, Func getItem = null) 10 | { 11 | if (index >= 0 && index < (list?.Count ?? 0)) 12 | return list[index]; 13 | if (getItem != null) 14 | return getItem(index); 15 | return default; 16 | 17 | } 18 | 19 | public static TValue GetOrCreateForKey(this IDictionary dictionary, TKey key) where TValue : new() 20 | { 21 | if (!dictionary.TryGetValue(key, out var result)) 22 | dictionary[key] = result = new TValue(); 23 | return result; 24 | } 25 | 26 | //public static void ForEach(this IEnumerable items, Action action) => 27 | // items.ToList().ForEach(action); 28 | 29 | public static bool TryRemove(this IList list, T item) 30 | { 31 | try 32 | { 33 | list.Remove(item); 34 | return true; 35 | } 36 | catch 37 | { 38 | return false; 39 | } 40 | } 41 | 42 | public static IList InsertAfter(this IList list, T itemToAdd, T previousItem) 43 | { 44 | var index = list.IndexOf(previousItem); 45 | list.Insert(index + 1, itemToAdd); 46 | return list; 47 | } 48 | 49 | public static IList InsertAfter(this IList list, IEnumerable itemsToAdd, T previousItem) 50 | { 51 | var index = list.IndexOf(previousItem) + 1; 52 | foreach (var item in itemsToAdd) 53 | list.Insert(index++, item); 54 | return list; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Comet/Helpers/MathExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet.Internal 3 | { 4 | public static class MathExtensions 5 | { 6 | public static double SafeDivideByZero(this double inDouble, double divisor) => divisor.IsZero() ? 0 : inDouble / divisor; 7 | public static float SafeDivideByZero(this float inDouble, float divisor) => divisor.IsZero() ? 0 : inDouble / divisor; 8 | public static bool IsZero(this double inDouble) => Math.Abs(inDouble) < Double.Epsilon; 9 | public static bool IsZero(this float inFloat) => Math.Abs(inFloat) < float.Epsilon; 10 | public static bool IsNotZero(this float inFloat) => Math.Abs(inFloat) > float.Epsilon; 11 | public static bool IsNotZero(this double inDouble) => Math.Abs(inDouble) > Double.Epsilon; 12 | 13 | public static float Clamp(this float value, float minValue, float max) => Math.Max(Math.Min(max, value), minValue); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Comet/Helpers/MauiExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Microsoft.Maui 5 | { 6 | public static class MauiExtensions 7 | { 8 | public static Size GetDesiredSize(this IViewHandler handler, Size size) => handler.GetDesiredSize(size.Width, size.Height); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Comet/Helpers/RectangleExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet 7 | { 8 | public static class RectangleExtensions 9 | { 10 | public static bool BoundsContains(this Rect rect, Point point) => 11 | point.X >= 0 && point.X <= rect.Width && 12 | point.Y >= 0 && point.Y <= rect.Height; 13 | 14 | public static bool Contains(this Rect rect, Point[] points) 15 | => points.Any(x => rect.Contains(x)); 16 | 17 | public static Rect ApplyPadding(this Rect rect, Thickness thickness) 18 | { 19 | if (thickness == Thickness.Zero) 20 | return rect; 21 | rect.X += thickness.Left; 22 | rect.Y += thickness.Top; 23 | rect.Width -= thickness.HorizontalThickness; 24 | rect.Height -= thickness.VerticalThickness; 25 | 26 | return rect; 27 | } 28 | public static RectF ApplyPadding(this RectF rect, Thickness thickness) 29 | { 30 | if (thickness == Thickness.Zero) 31 | return rect; 32 | rect.X += (float)thickness.Left; 33 | rect.Y += (float)thickness.Top; 34 | rect.Width -= (float)thickness.HorizontalThickness; 35 | rect.Height -= (float)thickness.VerticalThickness; 36 | 37 | return rect; 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Comet/Helpers/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Comet 5 | { 6 | public static class StringExtensions 7 | { 8 | public static string Repeat(this string input, int count) 9 | { 10 | if (!string.IsNullOrEmpty(input)) 11 | { 12 | StringBuilder builder = new StringBuilder(input.Length * count); 13 | 14 | for (int i = 0; i < count; i++) builder.Append(input); 15 | 16 | return builder.ToString(); 17 | } 18 | 19 | return string.Empty; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Comet/Helpers/TabViewExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public static class TabViewExtensions 5 | { 6 | public static T TabIcon(this T view, Binding image) where T : View 7 | => view.SetEnvironment(EnvironmentKeys.TabView.Image, image); 8 | public static T TabIcon(this T view, Func image) where T : View 9 | => view.TabIcon((Binding)image); 10 | 11 | public static T TabText(this T view, Binding text) where T : View 12 | => view.SetEnvironment(EnvironmentKeys.TabView.Title, text); 13 | public static T TabText(this T view, Func text) where T : View 14 | => view.TabText((Binding)text); 15 | 16 | public static T Tab(this T view, Binding text, Binding image) where T : View 17 | => view.TabIcon(image).TabIcon(text); 18 | public static T Tab(this T view, Func text, Func image) where T : View 19 | => view.TabIcon(image).TabIcon(text); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Comet/Helpers/TextExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace Comet 6 | { 7 | public static partial class TextExtensions 8 | { 9 | public static T HorizontalTextAlignment(this T view, Binding alignment, bool cascades = true) where T : View => 10 | view.SetEnvironment(EnvironmentKeys.Text.HorizontalAlignment, alignment, cascades); 11 | public static T HorizontalTextAlignment(this T view, Func alignment, bool cascades = true) where T : View => 12 | view.HorizontalTextAlignment((Binding)alignment, cascades); 13 | public static T VerticalTextAlignment(this T view, Binding alignment, bool cascades = true) where T : View => 14 | view.SetEnvironment(EnvironmentKeys.Text.VerticalAlignment, alignment, cascades); 15 | public static T VerticalTextAlignment(this T view, Func alignment, bool cascades = true) where T : View => 16 | view.VerticalTextAlignment((Binding)alignment, cascades); 17 | 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Comet/Helpers/ThreadHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.Maui.ApplicationModel; 7 | using Microsoft.Maui.Devices; 8 | 9 | namespace Comet 10 | { 11 | public class ThreadHelper 12 | { 13 | public static void SetFireOnMainThread(Action action) => FireOnMainThread = action; 14 | static Action FireOnMainThread = MainThread.BeginInvokeOnMainThread; 15 | public static void RunOnMainThread(Action action) => FireOnMainThread.Invoke(action); 16 | } 17 | } -------------------------------------------------------------------------------- /src/Comet/Helpers/WeakStack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Comet.Helpers 5 | { 6 | public class WeakStack where T : class 7 | { 8 | readonly Stack items = new Stack(); 9 | 10 | public T Peek() => items.Count == 0 ? null : items.Peek()?.Target as T; 11 | 12 | public T Pop() => items.Count == 0 ? null : items.Pop()?.Target as T; 13 | 14 | public void Push(T value) => items.Push(new WeakReference(value)); 15 | 16 | public int Count => items.Count; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Comet/Layout/GridConstraints.cs: -------------------------------------------------------------------------------- 1 | namespace Comet.Layout 2 | { 3 | public class GridConstraints 4 | { 5 | public static GridConstraints Default => new GridConstraints(); 6 | 7 | public GridConstraints( 8 | int row = 0, 9 | int column = 0, 10 | int rowSpan = 1, 11 | int colSpan = 1, 12 | float weightX = 1, 13 | float weightY = 1, 14 | float positionX = 0, 15 | float positionY = 0) 16 | { 17 | Row = row; 18 | Column = column; 19 | RowSpan = rowSpan; 20 | ColumnSpan = colSpan; 21 | WeightX = weightX; 22 | WeightY = weightY; 23 | PositionX = positionX; 24 | PositionY = positionY; 25 | } 26 | 27 | public int Row { get; internal set; } 28 | public int Column { get; internal set; } 29 | public int RowSpan { get; } 30 | public int ColumnSpan { get; } 31 | public float WeightX { get; } 32 | public float WeightY { get; } 33 | public float PositionX { get; } 34 | public float PositionY { get; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Comet/Layout/ZStackLayoutManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics; 5 | using Microsoft.Maui.Layouts; 6 | using Microsoft.Maui.Primitives; 7 | 8 | namespace Comet.Layout 9 | { 10 | public class ZStackLayoutManager : ILayoutManager 11 | { 12 | public ZStackLayoutManager(ILayout layout) => this.layout = layout; 13 | 14 | ILayout layout; 15 | 16 | public Size Measure(double widthConstraint, double heightConstraint) { 17 | 18 | Size measuredSize = new (); 19 | foreach(var c in layout) 20 | { 21 | var s = c.Measure(widthConstraint, heightConstraint); 22 | measuredSize.Height = Math.Max(measuredSize.Height, s.Height); 23 | measuredSize.Width = Math.Max(measuredSize.Width, s.Width); 24 | }; 25 | 26 | return measuredSize; 27 | } 28 | 29 | public Size ArrangeChildren(Rect bounds) 30 | { 31 | var b = bounds; 32 | foreach (var v in layout) 33 | { 34 | if (v is View cv) 35 | cv.LayoutSubviews(b); 36 | else 37 | v.Arrange(b); 38 | } 39 | return bounds.Size; 40 | } 41 | 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Comet/Maui/IMauiContextHolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | 4 | namespace Comet 5 | { 6 | public interface IMauiContextHolder 7 | { 8 | IMauiContext MauiContext {get;set;} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Comet/MulticastAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Comet 4 | { 5 | internal class MulticastAction 6 | { 7 | Action action; 8 | Binding binding; 9 | public MulticastAction(Binding binding, Action action) 10 | { 11 | this.binding = binding; 12 | this.action = action; 13 | } 14 | 15 | public void Invoke(T value) 16 | { 17 | binding.Set(value); 18 | action?.Invoke(value); 19 | } 20 | 21 | public static implicit operator Action(MulticastAction action) => action.Invoke; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Comet/Platform/Android/CometNavigationView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.Content; 3 | using Android.Views; 4 | using Android.Widget; 5 | using Microsoft.Maui; 6 | 7 | namespace Comet.Android.Controls 8 | { 9 | public class CometNavigationView : CustomFrameLayout 10 | { 11 | IMauiContext MauiContext { get; set; } 12 | public CometNavigationView(IMauiContext context) : base(context.Context) 13 | { 14 | MauiContext = context; 15 | } 16 | 17 | public void SetRoot(View view) 18 | { 19 | if (!isAttached) 20 | { 21 | contentView = view; 22 | } 23 | else 24 | (MauiContext.Context).GetFragmentManager() 25 | .BeginTransaction() 26 | .Replace(Id, new CometFragment(view, MauiContext)) 27 | .CommitAllowingStateLoss(); 28 | } 29 | 30 | public void NavigateTo(View view) 31 | { 32 | (MauiContext.Context).GetFragmentManager() 33 | .BeginTransaction() 34 | .SetTransition((int)global::Android.App.FragmentTransit.FragmentFade) 35 | .AddToBackStack(view.Id) 36 | .Replace(Id, new CometFragment(view, MauiContext)) 37 | .CommitAllowingStateLoss(); 38 | } 39 | bool isAttached = false; 40 | View contentView; 41 | protected override void OnAttachedToWindow() 42 | { 43 | base.OnAttachedToWindow(); 44 | isAttached = true; 45 | if(contentView != null) 46 | SetRoot(contentView); 47 | contentView = null; 48 | } 49 | 50 | public void Pop() => 51 | (MauiContext.Context).GetFragmentManager().PopBackStack(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Comet/Platform/Android/CometRecyclerView.cs: -------------------------------------------------------------------------------- 1 | using Android.Content; 2 | using AndroidX.RecyclerView.Widget; 3 | using Microsoft.Maui; 4 | 5 | namespace Comet.Android.Controls 6 | { 7 | public class CometRecyclerView : RecyclerView 8 | { 9 | 10 | //private ListView listView; 11 | readonly CometRecyclerViewAdapter adapter; 12 | public CometRecyclerView(IMauiContext mauiContext) : base(mauiContext.Context) 13 | { 14 | var layoutManager = new LinearLayoutManager(mauiContext.Context); 15 | SetLayoutManager(layoutManager); 16 | SetAdapter(adapter =new CometRecyclerViewAdapter() { MauiContext = mauiContext}); 17 | AddItemDecoration(new DividerItemDecoration(mauiContext.Context, layoutManager.Orientation)); 18 | } 19 | 20 | public IListView ListView 21 | { 22 | get => adapter.ListView; 23 | set => adapter.ListView = value; 24 | } 25 | 26 | public void ReloadData() => adapter.NotifyDataSetChanged(); 27 | } 28 | } -------------------------------------------------------------------------------- /src/Comet/Platform/Android/CometRecyclerViewHolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AndroidX.RecyclerView.Widget; 3 | using Android.Views; 4 | using Android.Widget; 5 | using Microsoft.Maui; 6 | namespace Comet.Android.Controls 7 | { 8 | public class CometRecyclerViewHolder : RecyclerView.ViewHolder 9 | { 10 | private readonly IListView listView; 11 | public IMauiContext MauiContext {get;set;} 12 | public ViewGroup Parent { get; } 13 | public CometView CometView => (CometView)ItemView; 14 | 15 | public CometRecyclerViewHolder( 16 | ViewGroup parent, 17 | IListView listView, IMauiContext mauiContext) : base(new CometView(mauiContext)) 18 | { 19 | MauiContext = MauiContext; 20 | Parent = parent; 21 | this.listView = listView; 22 | 23 | CometView.Click += HandleClick; 24 | } 25 | 26 | private void HandleClick(object sender, EventArgs e) => listView?.OnSelected(0, AdapterPosition); 27 | } 28 | } -------------------------------------------------------------------------------- /src/Comet/Platform/Android/CustomFrameLayout.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Android.Content; 3 | using Android.Runtime; 4 | using Android.Util; 5 | using Android.Views; 6 | using Android.Widget; 7 | using LP = Android.Views.ViewGroup.LayoutParams; 8 | namespace Comet.Android.Controls 9 | { 10 | public class CustomFrameLayout : FrameLayout 11 | { 12 | public CustomFrameLayout(Context context) : base(context) 13 | { 14 | LayoutParameters = new LP(LP.MatchParent, LP.MatchParent); 15 | Id = global::Android.Views.View.GenerateViewId(); 16 | } 17 | 18 | public CustomFrameLayout(Context context, IAttributeSet attrs) : base(context, attrs) 19 | { 20 | } 21 | 22 | public CustomFrameLayout(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) 23 | { 24 | } 25 | 26 | public CustomFrameLayout(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes) 27 | { 28 | } 29 | 30 | protected CustomFrameLayout(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) 31 | { 32 | } 33 | 34 | public override WindowInsets OnApplyWindowInsets(WindowInsets insets) 35 | { 36 | var leftPadding = PaddingLeft; 37 | 38 | var result = base.OnApplyWindowInsets(insets); 39 | 40 | SetPadding(leftPadding, PaddingTop, PaddingRight, PaddingBottom); 41 | 42 | return result; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Comet/Platform/Android/HandlerExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Handlers; 2 | using Comet.Android.Controls; 3 | using AView = Android.Views.View; 4 | using MotionEvent = Android.Views.MotionEvent; 5 | using MotionEventActions = Android.Views.MotionEventActions; 6 | namespace Comet; 7 | 8 | public static partial class HandlerExtensions 9 | { 10 | public static void AddGesture(this IViewHandler handler, Gesture gesture) 11 | { 12 | var gl = handler.GetGestureListener(true); 13 | gl.AddGesture(gesture); 14 | } 15 | 16 | public static void RemoveGesture(this IViewHandler handler, Gesture gesture) 17 | { 18 | var gl = handler.GetGestureListener(false); 19 | gl?.RemoveGesture(gesture); 20 | } 21 | public static CometTouchGestureListener GetGestureListener(this IViewHandler handler, bool createIfNull) 22 | { 23 | var v = handler.VirtualView as View; 24 | if (v == null) 25 | return null; 26 | var gl = v.GetEnvironment>(nameof(CometTouchGestureListener), false)?.Object; 27 | if (gl == null && createIfNull) 28 | v.SetEnvironment(nameof(CometTouchGestureListener), new ObjectWrapper { Object = gl = new CometTouchGestureListener(handler.PlatformView as AView, v) }, false); 29 | return gl; 30 | } 31 | public static bool IsComplete(this MotionEvent e) 32 | { 33 | switch (e.Action) 34 | { 35 | case MotionEventActions.Cancel: 36 | case MotionEventActions.Outside: 37 | case MotionEventActions.PointerUp: 38 | case MotionEventActions.Up: 39 | return true; 40 | default: 41 | return false; 42 | } 43 | } 44 | 45 | internal class ObjectWrapper 46 | { 47 | public T Object { get; set; } 48 | } 49 | 50 | 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/Comet/Platform/Standard/HandlerExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Handlers; 2 | 3 | namespace Comet; 4 | 5 | public static partial class HandlerExtensions 6 | { 7 | public static void AddGesture(this IViewHandler handler, Gesture gesture) 8 | { 9 | 10 | } 11 | 12 | public static void RemoveGesture(this IViewHandler handler, Gesture gesture) 13 | { 14 | 15 | } 16 | 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Comet/Platform/Windows/HandlerExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Handlers; 2 | 3 | namespace Comet; 4 | 5 | public static partial class HandlerExtensions 6 | { 7 | public static void AddGesture(this IViewHandler handler, Gesture gesture) 8 | { 9 | 10 | } 11 | 12 | public static void RemoveGesture(this IViewHandler handler, Gesture gesture) 13 | { 14 | //var nativeView = (UIView)handler.PlatformView; 15 | //if (gesture.PlatformGesture is UIGestureRecognizer g) 16 | // nativeView.RemoveGestureRecognizer(g); 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Comet/Platform/iOS/CUINavigationController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui; 3 | using UIKit; 4 | 5 | namespace Comet.iOS 6 | { 7 | public class CUINavigationController : UINavigationController 8 | { 9 | public static UIColor DefaultBarTintColor { get; private set; } 10 | public static UIColor DefaultTintColor { get; private set; } 11 | public static UIStringAttributes DefaultTitleTextAttributes { get; private set; } 12 | public CUINavigationController() 13 | { 14 | if (DefaultBarTintColor == null) 15 | { 16 | DefaultBarTintColor = NavigationBar.BarTintColor; 17 | DefaultTintColor = NavigationBar.TintColor; 18 | DefaultTitleTextAttributes = NavigationBar.TitleTextAttributes; 19 | } 20 | } 21 | public override UIViewController[] PopToRootViewController(bool animated) 22 | { 23 | return base.PopToRootViewController(animated); 24 | } 25 | public override UIViewController PopViewController(bool animated) 26 | { 27 | var vc = base.PopViewController(animated); 28 | var cometVC = vc as CometViewController; 29 | cometVC?.WasPopped(); 30 | 31 | return vc; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Comet/Platform/iOS/CUIRadioButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UIKit; 3 | 4 | namespace Comet.iOS 5 | { 6 | class CUIRadioButton : UIButton 7 | { 8 | private const float CONTENT_SPACING = 10; 9 | 10 | private static UIImage SelectedImage = UIImage.GetSystemImage("largecircle.fill.circle") 11 | .ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate); 12 | private static UIImage DeselectedImage = UIImage.GetSystemImage("circle") 13 | .ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate); 14 | 15 | public event EventHandler IsCheckedChanged; 16 | 17 | public CUIRadioButton(bool isChecked = false) 18 | { 19 | SetImage(_isChecked ? SelectedImage : DeselectedImage, UIControlState.Normal); 20 | IsChecked = isChecked; 21 | 22 | SetTitleColor(UIColor.Blue, UIControlState.Normal); 23 | 24 | ContentEdgeInsets = new UIEdgeInsets(0, CONTENT_SPACING, 0, CONTENT_SPACING); 25 | TitleEdgeInsets = new UIEdgeInsets(0, CONTENT_SPACING, 0, -CONTENT_SPACING); 26 | 27 | TouchUpInside += (sender, e) => { if (!IsChecked) IsChecked = true; }; 28 | } 29 | 30 | public override void SetTitleColor(UIColor color, UIControlState forState) 31 | { 32 | base.SetTitleColor(color, forState); 33 | 34 | if (forState == UIControlState.Normal) 35 | { 36 | ImageView.TintColor = color; 37 | } 38 | } 39 | 40 | private bool _isChecked = false; 41 | 42 | public bool IsChecked 43 | { 44 | get => _isChecked; 45 | set 46 | { 47 | if (_isChecked != value) 48 | { 49 | _isChecked = value; 50 | SetImage(_isChecked ? SelectedImage : DeselectedImage, UIControlState.Normal); 51 | IsCheckedChanged?.Invoke(this, new EventArgs()); 52 | } 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/Comet/Platform/iOS/CUIScrollView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CoreGraphics; 3 | using Microsoft.Maui; 4 | using Microsoft.Maui.Graphics; 5 | using UIKit; 6 | namespace Comet.iOS 7 | { 8 | public class CUIScrollView : UIScrollView 9 | { 10 | internal Action CrossPlatformArrange { get; set; } 11 | public override void LayoutSubviews() 12 | { 13 | base.LayoutSubviews(); 14 | var bounds = Bounds.ToRectangle(); 15 | CrossPlatformArrange?.Invoke(bounds); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Comet/Platform/iOS/CUITableViewCell.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Foundation; 3 | using Microsoft.Maui; 4 | using UIKit; 5 | 6 | namespace Comet.iOS 7 | { 8 | [Register("CUITableViewCell")] 9 | public class CUITableViewCell : UITableViewCell 10 | { 11 | public static int _instanceCount; 12 | 13 | CometView cometView; 14 | public CUITableViewCell(IntPtr ptr) : base(ptr) 15 | { 16 | ContentView.Tag = _instanceCount++; 17 | BackgroundColor = UIColor.Clear; 18 | } 19 | 20 | public CUITableViewCell(NSString resuseIdentifier) : base(UITableViewCellStyle.Default,resuseIdentifier) 21 | { 22 | ContentView.Tag = _instanceCount++; 23 | BackgroundColor = UIColor.Clear; 24 | } 25 | 26 | public void SetFromContext(IMauiContext context) 27 | { 28 | if (cometView != null) 29 | return; 30 | 31 | ContentView.Tag = _instanceCount++; 32 | cometView = new CometView(ContentView.Bounds, context); 33 | cometView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight; 34 | 35 | ContentView.AutosizesSubviews = true; 36 | ContentView.AddSubview(cometView); 37 | } 38 | 39 | public CUITableViewCell(IMauiContext context, UITableViewCellStyle style, string reuseIdentifier) : base(style, reuseIdentifier) 40 | { 41 | SetFromContext(context); 42 | } 43 | 44 | public void SetView(View view) 45 | { 46 | var previousView = cometView.CurrentView; 47 | cometView.CurrentView = view; 48 | (previousView as View)?.ViewDidDisappear(); 49 | view?.ViewDidAppear(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Comet/Platform/iOS/CUITapGestures.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UIKit; 3 | namespace Comet.iOS 4 | { 5 | public class CUITapGesture : UITapGestureRecognizer 6 | { 7 | public CUITapGesture(TapGesture gesture) : base(() => gesture.Invoke()) 8 | { 9 | gesture.PlatformGesture = this; 10 | } 11 | //TODO SetGesture Tate 12 | public override UIGestureRecognizerState State { get => base.State; set => base.State = value; } 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Comet/Platform/iOS/HandlerExtensions.cs: -------------------------------------------------------------------------------- 1 | using Comet.iOS; 2 | using Microsoft.Maui.Handlers; 3 | using UIKit; 4 | 5 | namespace Comet; 6 | 7 | public static partial class HandlerExtensions 8 | { 9 | public static void AddGesture(this IViewHandler handler, Gesture gesture) 10 | { 11 | var nativeView = (UIView)handler.PlatformView; 12 | nativeView.UserInteractionEnabled = true; 13 | nativeView.AddGestureRecognizer(gesture.ToGestureRecognizer()); 14 | } 15 | 16 | public static void RemoveGesture(this IViewHandler handler, Gesture gesture) 17 | { 18 | var nativeView = (UIView)handler.PlatformView; 19 | if(gesture.PlatformGesture is UIGestureRecognizer g) 20 | nativeView.RemoveGestureRecognizer(g); 21 | } 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Comet/Platform/iOS/iOSExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UIKit; 3 | namespace Comet.iOS 4 | { 5 | public static class iOSExtensions 6 | { 7 | public static UIViewController GetViewController(this UIView view) 8 | { 9 | if (view.NextResponder is UIViewController vc) 10 | return vc; 11 | if (view.NextResponder is UIView uIView) 12 | return uIView.GetViewController(); 13 | return null; 14 | } 15 | 16 | public static UIGestureRecognizer ToGestureRecognizer(this Gesture gesture) 17 | { 18 | if (gesture is TapGesture tapGesture) 19 | { 20 | return new CUITapGesture(tapGesture); 21 | } 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Comet/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | [assembly: InternalsVisibleTo("Reloadify-emit")] -------------------------------------------------------------------------------- /src/Comet/Shadow.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.Maui.Graphics; 4 | 5 | namespace Comet.Graphics 6 | { 7 | public class Shadow : IShadow 8 | { 9 | public Paint Paint { get; private set; } = new SolidPaint(Colors.Black); 10 | public float Opacity { get; private set; } = .5f; 11 | public float Radius { get; private set; } = 10; 12 | public Point Offset { get; private set; } = Point.Zero; 13 | 14 | float IShadow.Radius => Radius; 15 | 16 | float IShadow.Opacity => Opacity; 17 | 18 | Paint IShadow.Paint => Paint; 19 | 20 | Point IShadow.Offset => Offset; 21 | 22 | public Shadow() 23 | { 24 | 25 | } 26 | 27 | protected Shadow(Shadow prototype) 28 | { 29 | Paint = prototype.Paint; 30 | Opacity = prototype.Opacity; 31 | Radius = prototype.Radius; 32 | Offset = prototype.Offset; 33 | } 34 | 35 | public Shadow WithColor(Color color) 36 | { 37 | var shadow = new Shadow(this); 38 | shadow.Paint = new SolidPaint (color); 39 | return shadow; 40 | } 41 | public Shadow WithPaint(Paint paint) 42 | { 43 | var shadow = new Shadow(this); 44 | shadow.Paint = paint; 45 | return shadow; 46 | } 47 | 48 | public Shadow WithOpacity(float opacity) 49 | { 50 | var shadow = new Shadow(this); 51 | shadow.Opacity = opacity; 52 | return shadow; 53 | } 54 | 55 | public Shadow WithRadius(float radius) 56 | { 57 | var shadow = new Shadow(this); 58 | shadow.Radius = radius; 59 | return shadow; 60 | } 61 | 62 | public Shadow WithOffset(Point offset) 63 | { 64 | var shadow = new Shadow(this); 65 | shadow.Offset = offset; 66 | return shadow; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Comet/Shapes/Capsule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Comet.Graphics; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet 7 | { 8 | /// 9 | /// A capsule shape is equivalent to a rounded rectangle where the corner radius is chosen 10 | /// as half the length of the rectangle’s smallest edge. 11 | /// 12 | public class Capsule : Shape 13 | { 14 | public override PathF PathForBounds(Rect rect) 15 | { 16 | var path = new PathF(); 17 | var cornerSize = (float) Math.Min(rect.Width, rect.Height) / 2; 18 | path.AppendRoundedRectangle(rect, cornerSize); 19 | return path; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Comet/Shapes/Circle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Comet.Graphics; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet 7 | { 8 | public class Circle : Shape 9 | { 10 | public override PathF PathForBounds(Rect rect) 11 | { 12 | var size = Math.Min(rect.Width, rect.Height); 13 | var x = rect.X + (rect.Width - size) / 2; 14 | var y = rect.Y + (rect.Height - size) / 2; 15 | var path = new PathF(); 16 | path.AppendEllipse((float)x, (float)y, (float)size, (float)size); 17 | return path; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Comet/Shapes/Ellipse.cs: -------------------------------------------------------------------------------- 1 | using Comet.Graphics; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet 5 | { 6 | public class Ellipse : Shape 7 | { 8 | public override PathF PathForBounds(Rect rect) 9 | { 10 | var path = new PathF(); 11 | path.AppendEllipse(new RectF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height)); 12 | return path; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Comet/Shapes/PathScaling.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public enum PathScaling 5 | { 6 | AspectFit, 7 | AspectFill, 8 | Fill, 9 | None 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Shapes/Pill.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Comet.Graphics; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet 7 | { 8 | public class Pill : Shape 9 | { 10 | public Pill(Orientation orientation) 11 | { 12 | Orientation = orientation; 13 | } 14 | 15 | public Orientation Orientation { get; } 16 | 17 | public override PathF PathForBounds(Rect rect) 18 | { 19 | var cornerRadius = (float)(Orientation == Orientation.Horizontal ? rect.Height : rect.Width) / 2f; 20 | var path = new PathF(); 21 | path.AppendRoundedRectangle(rect, cornerRadius); 22 | return path; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Comet/Shapes/Rectangle.cs: -------------------------------------------------------------------------------- 1 | using Comet.Graphics; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet 5 | { 6 | public class Rectangle : Shape 7 | { 8 | public override PathF PathForBounds(Microsoft.Maui.Graphics.Rect rect) 9 | { 10 | var path = new PathF(); 11 | path.AppendRectangle(rect); 12 | return path; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Comet/Shapes/RoundedRectangle.cs: -------------------------------------------------------------------------------- 1 | using Comet.Graphics; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet 5 | { 6 | public class RoundedRectangle : Shape 7 | { 8 | private readonly float _cornerRadius; 9 | 10 | public RoundedRectangle(float cornerRadius) 11 | { 12 | _cornerRadius = cornerRadius; 13 | } 14 | 15 | public float CornerRadius => _cornerRadius; 16 | 17 | public override PathF PathForBounds(Rect rect) 18 | { 19 | var path = new PathF(); 20 | path.AppendRoundedRectangle(rect, _cornerRadius); 21 | return path; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Comet/Shapes/Shape.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | using Comet.Graphics; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet 7 | { 8 | public abstract class Shape : ContextualObject, IShape, IBorderStroke 9 | { 10 | internal View view; 11 | 12 | Paint IStroke.Stroke => this.GetEnvironment(view, EnvironmentKeys.Shape.StrokeColor); 13 | 14 | double IStroke.StrokeThickness => this.GetEnvironment(view, EnvironmentKeys.Shape.LineWidth); 15 | 16 | LineCap IStroke.StrokeLineCap => this.GetEnvironment(view, nameof(IStroke.StrokeLineCap)) ?? LineCap.Butt; 17 | 18 | LineJoin IStroke.StrokeLineJoin => this.GetEnvironment(view, nameof(IStroke.StrokeLineJoin)) ?? LineJoin.Miter; 19 | 20 | float[] IStroke.StrokeDashPattern => this.GetEnvironment(view, nameof(IStroke.StrokeDashPattern)); 21 | 22 | float IStroke.StrokeDashOffset => this.GetEnvironment(view, nameof(IStroke.StrokeDashOffset)); 23 | 24 | float IStroke.StrokeMiterLimit => this.GetEnvironment(view, nameof(IStroke.StrokeMiterLimit)) ?? 10; 25 | 26 | IShape IBorderStroke.Shape => this; 27 | 28 | protected Shape() 29 | { 30 | 31 | } 32 | 33 | internal override void ContextPropertyChanged(string property, object value, bool cascades) 34 | { 35 | 36 | } 37 | 38 | public abstract PathF PathForBounds(Rect rect); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Comet/Shapes/Squircle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Comet; 4 | 5 | public class Squircle : Shape 6 | { 7 | private readonly float cornerRadius; 8 | 9 | public Squircle(float cornerRadius) 10 | { 11 | this.cornerRadius = cornerRadius; 12 | } 13 | 14 | public float CornerRadius => cornerRadius; 15 | const float SquircleFactor = 1.125f; 16 | const float ControlPointFactor = 46f / 64f; 17 | public override PathF PathForBounds(Microsoft.Maui.Graphics.Rect rect) 18 | { 19 | var x = (float)rect.X; 20 | var y = (float)rect.Y; 21 | var w = (float)rect.Width; 22 | var h = (float)rect.Height; 23 | var path = new PathF(); 24 | var adjustedRadius = cornerRadius * SquircleFactor; 25 | adjustedRadius = Math.Min(adjustedRadius, Math.Min(w, h) / 2); 26 | var controlPointOffset = adjustedRadius * ControlPointFactor; 27 | 28 | var x1 = x + adjustedRadius; 29 | var x3 = x + w; 30 | var x2 = x3 - adjustedRadius; 31 | 32 | var y1 = y + adjustedRadius; 33 | var y3 = y + h; 34 | var y2 = y3 - adjustedRadius; 35 | 36 | path.MoveTo(x1, y); 37 | path.LineTo(x2, y); 38 | path.CurveTo( 39 | x2 + controlPointOffset, y, 40 | x3, y1 - controlPointOffset, 41 | x3, y1); 42 | path.LineTo(x3, y2); 43 | path.CurveTo( 44 | x3, y2 + controlPointOffset, 45 | x2 + controlPointOffset, y3, 46 | x2, y3); 47 | path.LineTo(x1, y3); 48 | path.CurveTo( 49 | x1 - controlPointOffset, y3, 50 | x, y2 + controlPointOffset, 51 | x, y2); 52 | path.LineTo(x, y1); 53 | path.CurveTo( 54 | x, y1 - controlPointOffset, 55 | x1 - controlPointOffset, y, 56 | x1, y); 57 | path.Close(); 58 | return path; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Comet/Styles/ButtonStyle.cs: -------------------------------------------------------------------------------- 1 | using Comet.Graphics; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | using System.Text; 6 | using Microsoft.Maui; 7 | using Microsoft.Maui.Graphics; 8 | 9 | namespace Comet.Styles 10 | { 11 | public class ButtonStyle : ViewStyle 12 | { 13 | public StyleAwareValue TextColor { get; set; } 14 | 15 | public StyleAwareValue TextFont { get; set; } 16 | 17 | public StyleAwareValue Padding { get; set; } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Comet/Styles/ControlState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Comet 3 | { 4 | public enum ControlState 5 | { 6 | Default, 7 | Disabled, 8 | Background, 9 | Pressed, 10 | Hovered 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Comet/Styles/Material/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.Styles.Material 6 | { 7 | public static class Extensions 8 | { 9 | public static T StyleAsOutlined(this T button) where T : Button 10 | { 11 | button.StyleId = MaterialStyle.OutlinedButtonStyleId; 12 | return button; 13 | } 14 | public static T StyleAsContained(this T button) where T : Button 15 | { 16 | button.StyleId = MaterialStyle.ContainedButtonStyleId; 17 | return button; 18 | } 19 | public static T StyleAsText(this T button) where T : Button 20 | { 21 | button.StyleId = MaterialStyle.TextButtonStyleId; 22 | return button; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Comet/Styles/NavbarStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui.Graphics; 6 | 7 | namespace Comet.Styles 8 | { 9 | public class NavbarStyle : ViewStyle 10 | { 11 | public StyleAwareValue TextColor { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Comet/Styles/ProgressBarStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Styles 5 | { 6 | public class ProgressBarStyle : ViewStyle 7 | { 8 | public StyleAwareValue TrackColor { get; set; } 9 | public StyleAwareValue ProgressColor { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Styles/SliderStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Maui.Graphics; 3 | 4 | namespace Comet.Styles 5 | { 6 | public class SliderStyle : ViewStyle 7 | { 8 | public StyleAwareValue TrackColor { get; set; } 9 | public StyleAwareValue ProgressColor { get; set; } 10 | public StyleAwareValue ThumbColor { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Comet/Styles/StyleType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Comet.Styles 6 | { 7 | public class StyleType 8 | { 9 | public string StyleId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Comet/Styles/TextStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using System.Text; 5 | using Microsoft.Maui; 6 | using Microsoft.Maui.Graphics; 7 | 8 | namespace Comet.Styles 9 | { 10 | public class TextStyle 11 | { 12 | public string StyleId { get; set; } 13 | public StyleAwareValue Font { get; set; } 14 | public StyleAwareValue Color { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Comet/Styles/ViewStyle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using Comet.Graphics; 4 | using Microsoft.Maui.Graphics; 5 | 6 | namespace Comet.Styles 7 | { 8 | public class ViewStyle 9 | { 10 | public StyleAwareValue BackgroundColor { get; set; } 11 | 12 | public StyleAwareValue Border { get; set; } 13 | 14 | public StyleAwareValue Shadow { get; set; } 15 | 16 | public StyleAwareValue ClipShape { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Comet/TextStyle.cs: -------------------------------------------------------------------------------- 1 | namespace Comet 2 | { 3 | public enum TextStyle 4 | { 5 | Body, 6 | Callout, 7 | Caption, 8 | Footnote, 9 | Headline, 10 | LargeTitle, 11 | Subheadline, 12 | Title, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Comet/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "msbuild-sdks": { 3 | "MSBuild.Sdk.Extras": "2.0.54" 4 | } 5 | } -------------------------------------------------------------------------------- /templates/comet-templates.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Clancey.Comet.Templates.Multiplatform 5 | Comet Template Pack 6 | 0.3.418-beta 7 | James Clancey 8 | Templates for building Android, iOS, and macOS application with Comet. 9 | https://github.com/Clancey/Comet 10 | https://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm 11 | https://xamarin.com/content/images/nuget/xamarin.png 12 | Copyright 2019 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /templates/single-project/.template.config/template.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/template", 3 | "author": "Microsoft", 4 | "classifications": [ "Comet", "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI" ], 5 | "identity": "Microsoft.Maui.CometApp", 6 | "groupIdentity": "Microsoft.Maui.Comet", 7 | "name": ".NET MAUI Comet App", 8 | "description": "A project for creating a .NET MAUI Comet application for iOS, Android, Mac Catalyst, and WinUI", 9 | "shortName": "comet", 10 | "tags": { 11 | "language": "C#", 12 | "type": "solution" 13 | }, 14 | "sourceName": "CometApp1", 15 | "preferNameDirectory": true, 16 | "guids": [ 17 | "07CD65EF-6238-4365-AF5D-F6D433967F48" 18 | ], 19 | "symbols": { 20 | "applicationId": { 21 | "type": "parameter", 22 | "description": "Overrides the $(ApplicationId) in the project", 23 | "datatype": "string", 24 | "replaces": "com.companyname.CometApp1" 25 | }, 26 | "microsoftExtensionsVersion": { 27 | "type": "parameter", 28 | "dataType": "string", 29 | "replaces": "MICROSOFT_EXTENSIONS_VERSION", 30 | "defaultValue": "6.0.0-preview.4.*" 31 | }, 32 | "mauiVersion": { 33 | "type": "parameter", 34 | "dataType": "string", 35 | "replaces": "MAUI_VERSION", 36 | "defaultValue": "6.0.100-preview.4.*" 37 | }, 38 | "cometVersion": { 39 | "type": "parameter", 40 | "dataType": "string", 41 | "replaces": "COMET_VERSION", 42 | "defaultValue": "0.3.45-beta" 43 | } 44 | }, 45 | "defaultName": "CometApp1" 46 | } 47 | -------------------------------------------------------------------------------- /templates/single-project/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Debug", 6 | "type": "comet", 7 | "request": "launch", 8 | "preLaunchTask": "comet: Build" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /templates/single-project/CometApp1.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31220.234 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CometApp1", "CometApp1\CometApp1.csproj", "{4067340A-BF74-4E4C-97BE-6C932B5FC9D6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {4067340A-BF74-4E4C-97BE-6C932B5FC9D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {4067340A-BF74-4E4C-97BE-6C932B5FC9D6}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {4067340A-BF74-4E4C-97BE-6C932B5FC9D6}.Debug|Any CPU.Deploy.0 = Debug|Any CPU 17 | {4067340A-BF74-4E4C-97BE-6C932B5FC9D6}.Release|Any CPU.ActiveCfg = Release|Any CPU 18 | {4067340A-BF74-4E4C-97BE-6C932B5FC9D6}.Release|Any CPU.Build.0 = Release|Any CPU 19 | {4067340A-BF74-4E4C-97BE-6C932B5FC9D6}.Release|Any CPU.Deploy.0 = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(SolutionProperties) = preSolution 22 | HideSolutionNode = FALSE 23 | EndGlobalSection 24 | GlobalSection(ExtensibilityGlobals) = postSolution 25 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572} 26 | EndGlobalSection 27 | EndGlobal 28 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/App.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Hosting; 2 | 3 | namespace CometApp1; 4 | public class App : CometApp 5 | { 6 | [Body] 7 | View view() => new MainPage(); 8 | 9 | public static MauiApp CreateMauiApp() 10 | { 11 | var builder = MauiApp.CreateBuilder(); 12 | builder.UseCometApp() 13 | .ConfigureFonts(fonts => { 14 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); 15 | fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); 16 | }); 17 | //-:cnd 18 | #if DEBUG 19 | builder.EnableHotReload(); 20 | #endif 21 | //+:cnd 22 | return builder.Build(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | global using Microsoft.Maui; 2 | global using Microsoft.Maui.Graphics; 3 | global using Comet; 4 | global using System; 5 | global using System.Linq; 6 | global using Microsoft.Maui.Primitives; 7 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/MainPage.cs: -------------------------------------------------------------------------------- 1 | namespace CometApp1; 2 | public class MainPage : View 3 | { 4 | 5 | [State] 6 | readonly CometRide comet = new(); 7 | 8 | [Body] 9 | View body() 10 | => new VStack { 11 | new Text(()=> $"({comet.Rides}) rides taken:{comet.CometTrain}") 12 | .Frame(width:300) 13 | .LineBreakMode(LineBreakMode.CharacterWrap), 14 | 15 | new Button("Ride the Comet! ☄️", ()=>{ 16 | comet.Rides++; 17 | }) 18 | .Frame(height:44) 19 | .Margin(8) 20 | .Color(Colors.White) 21 | .Background(Colors.Green) 22 | .RoundedBorder(color:Colors.Blue) 23 | .Shadow(Colors.Grey,4,2,2), 24 | }; 25 | 26 | public class CometRide : BindingObject 27 | { 28 | public int Rides 29 | { 30 | get => GetProperty(); 31 | set => SetProperty(value); 32 | } 33 | 34 | public string CometTrain 35 | { 36 | get 37 | { 38 | return "☄️".Repeat(Rides); 39 | } 40 | } 41 | } 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Android/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Content.PM; 3 | using Android.OS; 4 | 5 | namespace CometApp1; 6 | 7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)] 8 | public class MainActivity : MauiAppCompatActivity 9 | { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Android/MainApplication.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Runtime; 3 | using Microsoft.Maui.Hosting; 4 | 5 | namespace CometApp1; 6 | 7 | [Application] 8 | public class MainApplication : MauiApplication 9 | { 10 | public MainApplication(IntPtr handle, JniHandleOwnership ownership) : base(handle, ownership) 11 | { 12 | } 13 | protected override MauiApp CreateMauiApp() => App.CreateMauiApp(); 14 | } -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Android/Resources/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #512BD4 4 | #2B0B98 5 | #2B0B98 6 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/MacCatalyst/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using Microsoft.Maui.Hosting; 3 | 4 | namespace CometApp1; 5 | 6 | [Register("AppDelegate")] 7 | public class AppDelegate : MauiUIApplicationDelegate 8 | { 9 | protected override MauiApp CreateMauiApp() => App.CreateMauiApp(); 10 | } -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/MacCatalyst/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIDeviceFamily 6 | 7 | 1 8 | 2 9 | 10 | UIRequiredDeviceCapabilities 11 | 12 | arm64 13 | 14 | UISupportedInterfaceOrientations 15 | 16 | UIInterfaceOrientationPortrait 17 | UIInterfaceOrientationLandscapeLeft 18 | UIInterfaceOrientationLandscapeRight 19 | 20 | UISupportedInterfaceOrientations~ipad 21 | 22 | UIInterfaceOrientationPortrait 23 | UIInterfaceOrientationPortraitUpsideDown 24 | UIInterfaceOrientationLandscapeLeft 25 | UIInterfaceOrientationLandscapeRight 26 | 27 | XSAppIconAssets 28 | Assets.xcassets/appicon.appiconset 29 | 30 | 31 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/MacCatalyst/Program.cs: -------------------------------------------------------------------------------- 1 | using ObjCRuntime; 2 | using UIKit; 3 | 4 | namespace CometApp1; 5 | 6 | public class Program 7 | { 8 | // This is the main entry point of the application. 9 | static void Main(string[] args) 10 | { 11 | // if you want to use a different Application Delegate class from "AppDelegate" 12 | // you can specify it here. 13 | UIApplication.Main(args, null, typeof(AppDelegate)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Windows/App.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Windows/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Hosting; 2 | using Microsoft.UI.Xaml; 3 | 4 | // To learn more about WinUI, the WinUI project structure, 5 | // and more about our project templates, see: http://aka.ms/winui-project-info. 6 | 7 | namespace CometApp1.WinUI; 8 | 9 | /// 10 | /// Provides application-specific behavior to supplement the default Application class. 11 | /// 12 | public partial class App : MauiWinUIApplication 13 | { 14 | /// 15 | /// Initializes the singleton application object. This is the first line of authored code 16 | /// executed, and as such is the logical equivalent of main() or WinMain(). 17 | /// 18 | public App() 19 | { 20 | this.InitializeComponent(); 21 | } 22 | 23 | protected override MauiApp CreateMauiApp() => CometApp1.App.CreateMauiApp(); 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Windows/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | 10 | 11 | User Name 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/Windows/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | true/PM 12 | PerMonitorV2, PerMonitor 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/iOS/AppDelegate.cs: -------------------------------------------------------------------------------- 1 | using Foundation; 2 | using Microsoft.Maui.Hosting; 3 | 4 | namespace CometApp1; 5 | 6 | [Register("AppDelegate")] 7 | public class AppDelegate : MauiUIApplicationDelegate 8 | { 9 | protected override MauiApp CreateMauiApp() => App.CreateMauiApp(); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSRequiresIPhoneOS 6 | 7 | UIDeviceFamily 8 | 9 | 1 10 | 2 11 | 12 | UIRequiredDeviceCapabilities 13 | 14 | arm64 15 | 16 | UISupportedInterfaceOrientations 17 | 18 | UIInterfaceOrientationPortrait 19 | UIInterfaceOrientationLandscapeLeft 20 | UIInterfaceOrientationLandscapeRight 21 | 22 | UISupportedInterfaceOrientations~ipad 23 | 24 | UIInterfaceOrientationPortrait 25 | UIInterfaceOrientationPortraitUpsideDown 26 | UIInterfaceOrientationLandscapeLeft 27 | UIInterfaceOrientationLandscapeRight 28 | 29 | XSAppIconAssets 30 | Assets.xcassets/appicon.appiconset 31 | 32 | 33 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Platforms/iOS/Program.cs: -------------------------------------------------------------------------------- 1 | using ObjCRuntime; 2 | using UIKit; 3 | 4 | namespace CometApp1; 5 | 6 | public class Program 7 | { 8 | // This is the main entry point of the application. 9 | static void Main(string[] args) 10 | { 11 | // if you want to use a different Application Delegate class from "AppDelegate" 12 | // you can specify it here. 13 | UIApplication.Main(args, null, typeof(AppDelegate)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Windows Machine": { 4 | "commandName": "MsixPackage", 5 | "nativeDebugging": false 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Resources/Fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/templates/single-project/CometApp1/Resources/Fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Resources/Fonts/OpenSans-Semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/Comet/34b08005f8a55ac6fe26232ea6db54081fa02647/templates/single-project/CometApp1/Resources/Fonts/OpenSans-Semibold.ttf -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Resources/Raw/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "MauiAsset": 3 | 4 | 5 | 6 | These files will be deployed with you package and will be accessible using Essentials: 7 | 8 | async Task LoadMauiAsset() 9 | { 10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt"); 11 | using var reader = new StreamReader(stream); 12 | 13 | var contents = reader.ReadToEnd(); 14 | } 15 | -------------------------------------------------------------------------------- /templates/single-project/CometApp1/Resources/appicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/Comet.Blazor.Tests/Comet.Blazor.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp3.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Animations/AnimationTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using Microsoft.Maui.Animations; 4 | using Microsoft.Maui; 5 | 6 | namespace Comet.Tests 7 | { 8 | public class AnimationTests : TestBase 9 | { 10 | [Fact] 11 | public void DoubleAnimatesOverTime() 12 | { 13 | var animation = new LerpingAnimation 14 | { 15 | StartValue = 0.0, 16 | EndValue = 1.0, 17 | Easing = Easing.Linear 18 | }; 19 | 20 | var progress = .1; 21 | animation.Update (progress); 22 | Assert.Equal(animation.CurrentValue, progress); 23 | 24 | progress = .2; 25 | animation.Update (progress); 26 | Assert.Equal(animation.CurrentValue, progress); 27 | 28 | progress = .33333; 29 | animation.Update (progress); 30 | Assert.Equal(animation.CurrentValue, progress); 31 | 32 | progress = .75; 33 | animation.Update (progress); 34 | Assert.Equal(animation.CurrentValue, progress); 35 | 36 | progress = .99; 37 | animation.Update (progress); 38 | Assert.Equal(animation.CurrentValue, progress); 39 | 40 | progress = 1; 41 | animation.Update (progress); 42 | Assert.Equal(animation.CurrentValue, progress); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/Comet.Tests/AutoNotifyTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Comet; 5 | using Xunit; 6 | 7 | namespace Comet.Tests 8 | { 9 | public partial class StringConcatanator 10 | { 11 | [AutoNotify] 12 | string value1; 13 | 14 | [AutoNotify] 15 | string value2; 16 | 17 | public string Total => $"{Value1}{Value2}"; 18 | } 19 | 20 | public class AutoNotifyTest : TestBase 21 | { 22 | 23 | public class MainPage : View 24 | { 25 | 26 | [State] 27 | public readonly StringConcatanator model = new(); 28 | public Text TotalText { get; set; } 29 | [Body] 30 | View body() 31 | => new VStack 32 | { 33 | (TotalText = new Text(model.Total)) 34 | }; 35 | 36 | 37 | } 38 | 39 | 40 | [Fact] 41 | public void VerifyAutoGeneratesAndUpdates() 42 | { 43 | var view = new MainPage(); 44 | view.SetViewHandlerToGeneric(); 45 | view.model.Value1 = "Foo"; 46 | view.model.Value2 = "Bar"; 47 | 48 | Assert.Equal("FooBar", view.TotalText.Value); 49 | 50 | } 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Comet.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net7.0 5 | false 6 | Release;Debug 7 | 8 | 9 | 10 | true 11 | 12 | 13 | 14 | false 15 | 16 | 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Handlers/ProgressBarHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | 3 | namespace Comet.Tests.Handlers 4 | { 5 | public class ProgressBarHandler : GenericViewHandler 6 | { 7 | public ProgressBarHandler() 8 | { 9 | OnGetIntrinsicSize = HandleOnGetIntrinsicSize; 10 | } 11 | 12 | public Slider VirtualView => (Slider)CurrentView; 13 | 14 | private Size HandleOnGetIntrinsicSize(double widthConstraint, double heightConstraint) => new SizeF(100, 20); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Handlers/SecureFieldHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | 3 | namespace Comet.Tests.Handlers 4 | { 5 | public class SecureFieldHandler : GenericViewHandler 6 | { 7 | public SecureFieldHandler() 8 | { 9 | OnGetIntrinsicSize = HandleOnGetIntrinsicSize; 10 | } 11 | 12 | public SecureField VirtualView => (SecureField)CurrentView; 13 | 14 | private Size HandleOnGetIntrinsicSize(double widthConstraint, double heightConstraint) 15 | { 16 | var length = VirtualView.Text?.CurrentValue?.Length ?? 0; 17 | return new SizeF(10 * length, 12); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Handlers/SliderHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | 3 | namespace Comet.Tests.Handlers 4 | { 5 | public class SliderHandler : GenericViewHandler 6 | { 7 | public SliderHandler() 8 | { 9 | OnGetIntrinsicSize = HandleOnGetIntrinsicSize; 10 | } 11 | 12 | public Slider VirtualView => (Slider)CurrentView; 13 | 14 | private Size HandleOnGetIntrinsicSize(double widthConstraint, double heightConstraint) => new Size(100, 20); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Handlers/TextFieldHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | 3 | namespace Comet.Tests.Handlers 4 | { 5 | public class TextFieldHandler : GenericViewHandler 6 | { 7 | public TextFieldHandler() 8 | { 9 | OnGetIntrinsicSize = HandleOnGetIntrinsicSize; 10 | } 11 | 12 | public TextField VirtualView => (TextField)CurrentView; 13 | 14 | private Size HandleOnGetIntrinsicSize(double widthConstraint, double heightConstraint) 15 | { 16 | var length = VirtualView.Text?.CurrentValue?.Length ?? 0; 17 | return new SizeF(10 * length, 12); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Handlers/TextHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Maui.Graphics; 2 | 3 | namespace Comet.Tests.Handlers 4 | { 5 | public class TextHandler : GenericViewHandler 6 | { 7 | public TextHandler() 8 | { 9 | OnGetIntrinsicSize = HandleOnGetIntrinsicSize; 10 | } 11 | 12 | public Text VirtualView => (Text)CurrentView; 13 | 14 | private Size HandleOnGetIntrinsicSize(double widthConstraint, double heightConstraint) 15 | { 16 | var length = VirtualView.Value?.CurrentValue?.Length ?? 0; 17 | return new SizeF(10 * length, 12); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Comet.Tests/Helpers/ViewExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Comet.Tests.Handlers; 4 | 5 | namespace Comet.Tests 6 | { 7 | public static class ViewExtensions 8 | { 9 | public static View GetReplacedView(this View view) 10 | { 11 | var field = typeof(View).GetField("replacedView", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); 12 | return (View)field.GetValue(view); 13 | } 14 | 15 | public static GenericViewHandler SetViewHandlerToGeneric(this View view) 16 | { 17 | var handler = new GenericViewHandler(); 18 | var v = view.ReplacedView; 19 | view.ViewHandler = handler; 20 | handler.SetVirtualView(view); 21 | return handler; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/Comet.Tests/HotReloadTestsNoParameters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Comet.Internal; 3 | using Microsoft.Maui.HotReload; 4 | using Xunit; 5 | 6 | namespace Comet.Tests 7 | { 8 | public class HotReloadTests : TestBase 9 | { 10 | 11 | public class MyOrgView : View 12 | { 13 | public const string TextValue = "Hello!"; 14 | public MyOrgView() 15 | { 16 | this.Body = () => new Text(TextValue); 17 | } 18 | } 19 | public class MyNewView : View 20 | { 21 | public const string TextValue = "Goodbye!"; 22 | public MyNewView() 23 | { 24 | this.Body = () => new Text(TextValue); 25 | } 26 | } 27 | 28 | public HotReloadTests() 29 | { 30 | MauiHotReloadHelper.IsEnabled = true; 31 | } 32 | 33 | [Fact] 34 | public void HotReloadRegisterReplacedViewReplacesView() 35 | { 36 | var orgView = new MyOrgView(); 37 | var orgText = orgView.GetView() as Text; 38 | Assert.Equal(MyOrgView.TextValue, orgText.Value.CurrentValue); 39 | 40 | MauiHotReloadHelper.RegisterReplacedView(typeof(MyOrgView).FullName, typeof(MyNewView)); 41 | var newText = orgView.GetView() as Text; 42 | 43 | Assert.Equal(MyNewView.TextValue, newText.Value.CurrentValue); 44 | 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Comet.Tests/TestBase.cs: -------------------------------------------------------------------------------- 1 | using Comet.Internal; 2 | using Microsoft.Maui; 3 | using Microsoft.Maui.Graphics; 4 | using Microsoft.Maui.HotReload; 5 | using Xunit; 6 | 7 | [assembly: CollectionBehavior(DisableTestParallelization = true)] 8 | namespace Comet.Tests 9 | { 10 | public class TestBase 11 | { 12 | public TestBase() 13 | { 14 | UI.Init(); 15 | } 16 | 17 | public static void InitializeHandlers(View view) 18 | { 19 | if (view == null) return; 20 | 21 | var handler = view.ViewHandler; 22 | if (handler == null) 23 | { 24 | var v = view.ReplacedView; 25 | handler = UI.Handlers.GetHandler(view.GetType()); 26 | view.ViewHandler = handler; 27 | handler.SetVirtualView(view); 28 | 29 | } 30 | 31 | if (view is AbstractLayout layout) 32 | { 33 | foreach (var subView in layout) 34 | { 35 | InitializeHandlers(subView); 36 | } 37 | } 38 | else if (view is ContentView contentView) 39 | { 40 | InitializeHandlers(contentView.Content); 41 | } 42 | else if (view.BuiltView != null) 43 | { 44 | InitializeHandlers(view.BuiltView); 45 | } 46 | 47 | } 48 | 49 | public static void InitializeHandlers(View view, float width, float height) 50 | { 51 | InitializeHandlers(view); 52 | view.Alignment(Alignment.Fill); 53 | var frame = new Rect(0, 0, width, height); 54 | var iView = (IView)view; 55 | iView.Measure(frame.Width, frame.Height); 56 | iView.Arrange(frame); 57 | } 58 | 59 | public static void ResetComet() 60 | { 61 | var v = new View(); 62 | v.ResetGlobalEnvironment(); 63 | //v.DisposeAllViews(); 64 | UI.Init(true); 65 | MauiHotReloadHelper.Reset(); 66 | v?.Dispose(); 67 | } 68 | } 69 | } 70 | --------------------------------------------------------------------------------