From 438aef2e5db8d2d0c01ffdeba2167da5b87888ae Mon Sep 17 00:00:00 2001 From: Kangho Hur Date: Fri, 15 Apr 2022 17:43:01 +0900 Subject: [PATCH] Adds Tizen backend (#2360) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Tizen] Add Resizetizer Tizen Implementation * Treat nullablity for buidling net6 project * Bump to latest and fix build error * Fix Tizen Handlers * Fix font and SingleProject to locate manifest * Update tizen manifest path * Bump to latest - Adds the GraphicsViewHandler and ShapeViewHandler - Apply one stop shop UseMauiControls (#1157) - Implements new APIs for each IView - and so on * Bump to latest - Including register images and set Compat Service Provider (#1306), and so on * [SingleProject] Update intermediate asset path * Bump to latest - Apply to start adding in APIs for adding legacy renderers via assembly scanning (#1333) - Update to IMauiContext (#1357) - and so on * Remove duplicate type for legacy compat renderers * Fix Color Extension * Adds Microsoft.Maui.Tizen.sln * Rebase to upstream latest main * InitialzationOption for MauiApp * Bump to latest - Apply to patch related to Animation (#1436) - Apply to register Microsoft.Maui.Graphics Platforms (#1441) - and so on. * Enable to DisplayResolutionUnit * Implement Clip * Implement ModalNavigationService * Update build targets for single project * Remove comment * Remove image resource on Tizen project * Remove space * Bump to latest - Added GestureManager.Tizen.cs (#1489) - Set handler to shimmed handler so it doesn't get reshimmed (#1483) - Turn XamlC on by default (#1422) - and so on * Fix SwitchHandler * Fix compatibility issue (#41) * Fix compatibility issue * Fix Compatibility Resource path * Fix Transformations (#42) * Fix the compat LayoutRenderer (#43) * Bump to latest - Modal Navigation Manager (#1563) - Implement the basic WindowHandler (#1468) - Don't extract native defaults, meaning users can no longer reset a color back to a platform theme (#1485) - Implement Alerts (Alert, Prompt and ActionSheet) (#1328) - And so on. * Fix Layout margin issue (#44) * [SingleProject] Fix Issues (#50) * Fix RefreshView related issue (#51) * Fix RefreshView related issue * Fix StreamImageSourceService.Tizen * Bumt to latest - Effects (#1574) - Improve Window and AnimationManager (#1653) - and so on * Add Microsoft.Maui.Graphics.Skia as PackageReference * Update Compatibility projects (*.csproj) for Tizen * Add AlertManager on Tizen (#57) * Add AlertManager on Tizen * Add null check and remove whitespace * Remove watch profile code * Change subscriber object * Add Essentials.Samples.Tizen (#24) * Add Essentials.Samples.Tizen * Add guard for null exception * Fix Essentials.Samples for Tizen * Fix csproj for net6 * Remove Forms.Init * Fix build error (#60) * Update referenced Tizen.UIExtensions version (#61) * Add BlazorWebView skeleton code (#62) * Bump to latest (#71) - Window lifecycle (#1754) - Move New Navigation Handler to Core and make it internal (#1800) - Scrollview handler (#1669) - ScrollView Resize + Window Handler Resize (#1676) - Font AutoScalingEnabled (#1774) - Rename Font Properties (#1755) - Update layout system to ensure native measure/arrange are called for all controls, even from Page subclasses (#1819) - IContainer as IList (#1724) - Implement Layout padding for new StackLayouts and GridLayout (#1749) - Delete all the TabIndex, TabStop, Focusable things! (#1777) - Introduce SetSemanticFocus API via SemanticExtensions (#1829) - Improve Window and AnimationManager (#1653) - And so on * Remove IPage on Tizen (#72) - Merge IFrameworkElement and IView and Remove IPage (#1875) * Remove obsolete methods from Controls (#73) - [Controls] Remove obsolete methods from Controls (#1644) * Fix issue related rebase (#74) * Add Blazor webview (#67) * Add Blazor webview * Replace space to tab * remove space * Fix AlertManager prompt layout issue (#76) * Fix entry cursor error (#68) * Fix entry cursor error * Update code referring to android extension * Remove duplicate code & Add exception cases * Code fixes for consistency * Fix nullable issue (#77) * Fix Image loading (#78) * Fix nested layout issue (#79) Co-authored-by: 허강호/Common Platform Lab(SR)/Principal Engineer/삼성전자 * Fix issues caused by bump up (#75) * Fix issues caused by bump up * Update Tizen file provider * Update file provider with proper path * Replace StackLayout from Compatibility.StackLayout (#82) * Fix unmatched partial method (#84) * Bump to latest * Fix GetDesiredSize (#87) * Fix GetDesiredSize * update for readability * Fix ScrollView content absolute position (#89) * Fixes incorrect parameter type for ILayoutManager.ArrangeChildren (Rectangle -> Size). (#91) * Make the HandlerToRendererShim simple * Revert "Fixes incorrect parameter type for ILayoutManager.ArrangeChildren (Rectangle -> Size). (#91)" (#97) This reverts commit c54ac836ef961d647989a34fa83208b9883142ef. * Add GestureManager (#96) * Add GestureManager * Fix DragGestureHandler * Fix GestureManager * Check nullable enable * Fix Label LineBreakMode using workaround (#98) * Refactor the LayoutHandler (#99) * Fix layout measure issue (#100) * Bump to latest * Fix LayoutHandler Update issue (#103) * Fix LayoutHandler Update issue * Implement InvalidateMeasure propagation * Update MapBackground * Fix default font size issue (#113) * Add InitializationOptions (#107) * Add InitializationOptions * Set UseSkiaSharp true as default * Apply DP as default * Fix SKClipperView to have proper size (#115) * Fix Essentials sample (#108) * Fix Essentials sample for Tizen * Remove UseSkiaSharp flag * Remove MaterialComponents * Fix Tizen flag * Remove CustomRenderer * Add ShellHandler (#64) * Add ShellHandler * Move ShellView into Platform/Tizen * Update ShellView * Move the code for embedded tizen resources to csproj * Add UIExtenstions for shell * fix ViewHandlerOfT dispose (#120) * MAUI workload for Tizen (#66) * Fix build and runtime error after bumping to latest code * Fix HandlerToRendererShim dispose (#127) * Add ShellSearchView (#121) * Add ShellSearchView * Fix the layout issue in ShellSearchResultList * Enable nullable * Fix maximum height of ShellSearchResultList * Fix scaling issue on Clip (#130) * Fix Shell build error on net6 project (#133) * Fix DisplayResolutionUnit sync issue (#134) * Fix build error (#137) * Replace SkiaGraphicsView with local patch (#135) This commit will be revert when upstream code is updated * Fix GraphicsView scaling issue (#136) * Support Min/Max Height/Width on IView and applying MauiApp/MauiAppBuilder pattern - Support Min/Max Height/Width on IView (#2265) - Updating .NET MAUI to use MauiApp/MauiAppBuilder pattern and use MS.Extensions.DependencyInjection (#2137) * Fix Tizen Templates (#144) * Fix webview break caused by updated dependency (#143) * Update the Tizen.UIExtension.ElmSharp version (#145) * Fix Essentials (#146) * Fix Essentials sample for tizen * Add SemanticScreenReader for Tizen * Fix Startup * Reomve internal UIExtensions compoments for Shell (#147) * Implement PlaceholderColor property in SearchBarHandlers - Implement PlaceholderColor property in SearchBarHandlers (#1512) * Adds missing implementation after bumping to latest main * Fix Control.Samples.Singleproject Main correctly (#150) * [Tizen] Add support for JS root components in BlazorWebView (#151) * [Tizen] Adds BoxView Handler * [Tizen] Update project templates to work with safe characters - Update project templates to work with safe characters (#2368) * [Tizen] Implement ProgressColor property in ProgressBarHandlers - Implement ProgressColor property in ProgressBarHandlers (#600) * [Tizen] Fix project template's tizne-manifest.xml correctly * [Tizen] Handle ContentViews and templated content in new layout system * [Tizen] WebView Handlers * [Tizen] Use Color.IsDefault in Compat renderers * Fix Essentials DeviceDisplay (#156) * Fix Essentials.DeviceDisplay * Fix DeviceDisplay * [Tizen] Fix build error on net6 * Fix Layout remove issue (#164) * Fix Layout remove issue * Fix layout remove on Dispose * Bump to latest (rc1) - ImageButtonHandler and Handler Re-usability (#2352) - Remove IBoxView (#2619) - Add SupportedOSPlatformVersion (#2565) - Merge all the .NET 6 projects/solutions (#2505) - Shadow Support (#570) - Add IndicatorView handler(#2038) * [Tizen] Initial Border control * [Tizen] Apply graphics related code review feedback * [Tizen] Remove Device.OpenUri impl and Device.Flags/SetFlags * [Tizen] Fix Display Prompt Alerts * [Tizen] Fix WebView Handler * [Tizen] Fix ShapeViewHandler * [Tizen] Port H/V TextAlignment to Editor/Picker Handler * [Tizen] Add TVShellView (#183) * [Tizen] Add TVShellView * [Tizen] Update TVShellView * [Tizen] Update NativeView for Shell * [Tizen] Update ShellView * [Tizen] Change default FlyoutBackgroundColor for TV * [Tizen] Enable nullable * Refactor WrapperView to draw drawable features (#186) * Refactor WrapperView to draw drawable features * Update class names and devide files * Override NeesContainer to remove duplicated code * Update class names * [Tizen] Adds ApplicationHandler * Remove dispose action on ImageSourceServiceResult (#192) * Fix Background issue of Frame (#193) * Fix UpdateBackground (#194) * Fix UpdateBackground * Add ContentView Background mapper * Fix Editor/Entry/Label/Layout Background * Add IWrapperViewCanvas.Content * Add PageHandler Background mapper * Restore WrapperView * Remove unnecessary namespace * [Tizen] Fix build error on PageHandler * [Tizen] Fix ButtonHandler events * [Tizen] Use new dispatcher instance in Tizen's BlazorWebView * [Tizen] Fix DpiPath correctly * [Tizen] Fix Compatibility and Controls.Sample build error * [Tizen] Initial CollectionViewHandler * [Tizen] Apply ITextButton related changes * [Tizen] Add Shadows (#233) * [Tizen] Add Shadows * [Tizen] Apply review comments * [Tizen] Move updating shape in proper position * [Tizen] Update BackgroundDrawable * [Tizen] Apply review comments * [Tizen] Add BorderDrawable (#224) * Move to platform specific * Fix border handler for Tizen * Rename ToDrawable method * Fix border content layout * Fix BorderView * Apply rebase * [Tizen] Fix entry cursor issue (#222) * Fix entry cursor issue * Fix UpdateSelectionLength method * [Tizen] Remove TVNavigationDrawer TVNavigationView (#223) * [Tizen] Remove TVNavigationDrawer TVNavigationView * [Elmsharp] Update Tizen.UIExtensions version * [Tizen] Remove Forms DeviceInfo and use Essentials * [Tizen] Initial Multi Window support * [Tizen] Fix MauiContext * [Tizen] Refactor Border by defining MauiDrawable (#248) * [Tizen] Refactor Border by defining MauiDrawable * [Tizen] Apply review comments * [Tizen] Remove unnecessary type casting * [Tizen] Move getting path logic to drawable * [Tizen] Obsolete AndExpand & Remove IsolatedStorage * Fix layout measure issue (#254) * Fix layout measure issue * Update src/Compatibility/Core/src/Tizen/Platform.cs Co-authored-by: 허강호/Common Platform Lab(SR)/Principal Engineer/삼성전자 Co-authored-by: 허강호/Common Platform Lab(SR)/Principal Engineer/삼성전자 * Fix tizen solution (.sln) correctly * [Tizen] Add VerticalTextAlignment * [Tizen] Move IDispatcher logic out of IPlatformServices * [Tizen] Fix Scoping of MauiContext * Fix NavigationPage navigating issue (#263) * [Tizen] Add ImageButton handler (#261) * [Tizen] Add ImageButton handler * Add comment * Fix Compatibility build error (#265) * Fix catch exception for sample (#262) * Fix catch exception for control sample * Fix exception type for Tizen * Add bracket * [Tizen] Use CoreApplication as native app type * Fix ScrollView (#269) * [Tizen] Add Collectionview adaptor (#271) * [Tizen] Add CollectionView Adaptors * Remove unnecessary override * Fix ConvertToScaledDP * Fix flag * Fix item selected event * Apply review comments * Move to extension for CollectionView * [Tizen] Remove legacy Log and use ILogger * [Tizen] Applying upstream changes * [Tizen] Add ContainerView to Layout if it's present * [Tizen] Initial Reloadyfy support * [Tizen] Initial IVisualDiagnosticOveraly support * [Tizen] Setup first set of Automation Properties * [Tizen] Move types in the Platform folder into the Platform namespaces * Fix CollectionView layout issue (#288) * Fix CollectionView layout issue * Remove unnecessary code * [Tizen] ZIndex proof-of-concept * Fix ScrollView ContentSize and Padding margin (#291) * Fix ScrollView ContentSize and Padding margin * Fix MapRequestScrollTo * Update src/Core/src/Handlers/ScrollView/ScrollViewHandler.Tizen.cs Co-authored-by: 허강호/Common Platform Lab(SR)/Principal Engineer/삼성전자 * Update src/Core/src/Handlers/ScrollView/ScrollViewHandler.Tizen.cs Co-authored-by: 허강호/Common Platform Lab(SR)/Principal Engineer/삼성전자 * Remove MapContentSize Co-authored-by: 허강호/Common Platform Lab(SR)/Principal Engineer/삼성전자 * Implements WindowOverlay and VisualDiagnosticsOverlay (#294) * Implements WindowOverlay and VisualDiagnosticsOverlay * Apply code review * [Tizen] Fix Image Handler * Remove GetDesiredSize (#295) * [Tizen] Fix ButtonHandler * Fix UpdateSemantics (#299) * Fix UpdateSemantics * Fix Semantics mapping * Apply comment * [Tizen] Organize and centralize HandlerExtensions * Refactor WrapperView and Fix Issue (#302) * Refactor WrapperView * Use Thickness type for Shadow margin * Update variable name * Update class name to GraphicsExtensions * Fix essentials sample for Tizen (#305) * [Tizen] Fix NativeView casting issue * [Tizen] Update the UIExtensions package version * [Templates] Update Tizen Template (#311) * [Tizen] Initial Flyout handler * Fix BlazorWebview binary resource issue (#317) * [Tizen] Handle query strings in Blazor static assets by trimming them out * Refactor MauiContext (#330) * [Tizen] Adds PaintExtensions * [Tizen] Update compat's Platform * [Tizen] Fix controls build error * [Tizen] Adds RadioButton Handler * [Tizen] Implement CursorPosition in IEditor/ITextInput Handlers * [Tizen] Initial SwipeView Handler * [Tizen] Remove GetNative * [Tizen] Update Microsoft.NET.Sdk.Maui/WorkloadManifest * [Tizen] Add FormattedText property support to Label in Controls * [Tizen] Bump to latest * [Tizen] Use legacy compat renderers temporarily * [Tizen] Use BorderView * [SingleProject] Update splash updator (#353) * [singleproject] update splash updator * [singleproject] update icon updator * [singleproject] Fix default icon path * [Tizen] Fix BlazorWebView build error (#355) * [Tizen] Fix BlazorWebView build error * [Tizen] Update tizen handler * [Tizen] Implement IPlatformApplication.Current * [Tizen] Implements missing WebViewHandler APIs * [Tizen] Refactor AppInfo/PhoneDialer into interface * [Tizen] Fix INativeViewHandler to return more expected NativeView * [Tizen] Remove legacy TFMs * [Tizen] Refactor DeviceInfo and Flashlight to use an interface * [Tizen] Remove `IPlatformInvalidate` and `Device.Invalidate() * [Tizen] Refactored Geocoding to an interface * [Tizen] Adds Microsoft.Maui.Graphics.Skia as package reference * [Tizen] Refactored Map, SMS, Contacts to an interface * [Tizen] Bump to latest * [Tizen] Fix Essential sample build error * [Tizen] Fix Workload build error * Add Platform code on Controls.Sample.Sandbox for tizen (#382) * Fix processing MauiAssets (#383) Co-authored-by: Jay Cho * [Tizen] Refactor Essential's implementations * [Tizen] Renaming public APIs Native -> Platform * [Tizen] Update template & sample's tizen-manifest.xml * Fix DotNet.csproj to build tizen (#372) * [Tizen] Update ImageHandler and ImageButtonHandler * [Tizen] Add handling for TextTransform for SearchBar/Editor/Entry * [Tizen] Interfaced Handler for Label, Page, NavigationView, Picker, ProgressBar, SwipeView * [Tizen] Initial MenuBar * [Tizen] Moved GetPlatformSize logic into a new service * [Tizen] Interfaced handler for Switch, TimePicker, WebView, Slider, SearchBar, RefreshView, RadioButton * [Tizen] Fix build error after rebasing * [Tizen] Use StringComparison.Ordinal everywhere * [Tizen] Move TabbedPageHandler to TabbedViewHandler * [Tizen] Add more APIs to IDispatcher * [Tizen] Remove Application.Properties implementation * [Tizen] Backport p14 changes * [Tizen] Implement InputTransparent * [Tizen] Loaded/Unloaded events and propagate Window * [Tizen] Fix Path shapes rendering issues * [Tizen] Fix CI build error on ImageButtonHandler * [Tizen] Optimize ConfigureFonts and Logging during startup * [Tizen] Make sure StrokeDashArray property invalidate the Shape * [Tizen] Implement FillRule property in Polygon/PolylineHandler * [Tizen] Add install tizen to provision.yml * [Tizen] Simplify OnPlatformExtension * [Tizen] Use interface on mappers of shapes * [Tizen] Install tizen workload on dotnet-local-workloads * [Tizen] Move package version into Versions.props * [Tizen] Move 'UseMauiApp' call into "Controls" * [Tizen] update template description of localized string files * [Tizen] Update the package reference of Microsoft.Maui.Dependencies * [Tizen] Add IWindow.DisplayDensity * [Tizen] Initial VisualDiagnostic Image APIs * [Tizen] Mark all the Device [Obsolete] * [Tizen] Mark renderers and related base classes as obsolete * [Tizen] Platform behavior implementation * [Tizen] Clean unnecessary resource files * [Tizen] Graphics events * [Tizen] Modernize Essentials Namepsaces * [Tizen] Fix Compat's control gallery build error * Fix ClipperView background color issue (#447) * Fix typo (#450) * [Tizen] Initial support for configuring the underlying Web view settings * [Tizen] BlazorWebView public API tracking * [Tizen] use latest tizen workload as default * [Tizen] specify sdk version to avoid ci build error * [Tizen] Keep the text wrapping/truncation and max lines stuff in Controls * [Tizen] Remove downcasts in BlazorWebView * [Tizen] BlazorWebView API review changes: Shared sources * [Tizen] add tizen TFM optional * [Tizen] adding informative comments for template * [Tizen] Set IncludeTizenTargetFrameworks correctly * [Tizen] install maui-tizen Co-authored-by: JoonghyunCho Co-authored-by: Seungkeun Lee Co-authored-by: 김성수/Common Platform Lab(SR)/Staff Engineer/삼성전자 Co-authored-by: 박인서/Common Platform Lab(SR)/Associate/삼성전자 Co-authored-by: 민성현/Common Platform Lab(SR)/Staff Engineer/삼성전자 Co-authored-by: Jay Cho --- ...osoft.Maui.Controls.MultiTargeting.targets | 15 + ...icrosoft.Maui.Controls.SingleProject.props | 6 + ...rosoft.Maui.Controls.SingleProject.targets | 16 +- .nuspec/Microsoft.Maui.Resizetizer.targets | 71 +- Directory.Build.props | 6 + Directory.Build.targets | 4 + eng/Microsoft.Extensions.targets | 4 + eng/Versions.props | 3 + eng/pipelines/common/provision.yml | 8 + .../net6.0-tizen/PublicAPI.Shipped.txt | 1 + .../net6.0-tizen/PublicAPI.Unshipped.txt | 63 ++ .../Maui/Tizen/BlazorWebViewHandler.Tizen.cs | 192 ++++++ .../Maui/Tizen/TizenMauiAssetFileProvider.cs | 74 ++ .../src/Maui/Tizen/TizenWebViewManager.cs | 69 ++ .../src/Maui/Tizen/WebViewContainer.cs | 42 ++ .../src/Maui/Tizen/WebViewExtensions.cs | 79 +++ .../BlazorWebViewInitializedEventArgs.cs | 7 + .../BlazorWebViewInitializingEventArgs.cs | 2 + .../ControlGallery/src/Core/Startup.cs | 7 + .../BorderEffect.cs | 9 +- .../Compatibility.ControlGallery.Tizen.csproj | 38 ++ .../src/Tizen/ControlGallery.Tizen.cs | 32 + .../src/Tizen/DisposeLabelRenderer.cs | 22 + .../src/Tizen/DisposePageRenderer.cs | 22 + .../PlatformSpecificCoreGalleryFactory.cs | 9 +- .../RegistrarValidationService.cs | 11 +- .../src/Tizen/SampleNativeControl.cs | 27 + .../res/FlowerBuds.jpg | Bin .../res/Fruits.jpg | Bin .../res/Icon-Small.png | Bin .../res/Icon.png | Bin .../res/Intranet-icon.png | Bin .../res/Legumes.jpg | Bin .../res/Vegetables.jpg | Bin .../res/about.png | Bin .../res/bank.png | Bin .../res/bell.png | Bin .../res/blog.png | Bin .../res/books.png | Bin .../res/booksflyout.png | Bin .../res/calculator.png | Bin .../res/card.png | Bin .../res/caret_r.png | Bin .../res/coffee.png | Bin .../res/cover1.jpg | Bin .../res/cover1small.jpg | Bin .../res/crimson.jpg | Bin .../res/crimsonsmall.jpg | Bin .../res/facebook.png | Bin .../res/favorite.png | Bin .../res/film.png | Bin .../res/filmflyout.png | Bin .../res/games.png | Bin .../res/gamesflyout.png | Bin .../res/googleplus.png | Bin .../res/grid.png | Bin .../res/headphone.png | Bin .../res/headphoneflyout.png | Bin .../res/hm.png | Bin .../res/hm_full.jpg | Bin .../res/home.png | Bin .../res/homeflyout.png | Bin .../res/ic_pause.png | Bin .../res/ic_play.png | Bin .../res/ic_share.png | Bin .../res/ic_stop.png | Bin .../res/instagram.png | Bin .../res/invalidimage.jpg | 0 .../res/jet.png | Bin .../res/lists.png | Bin .../res/loop.png | Bin .../res/menuIcon.png | Bin .../res/messages.png | Bin .../res/newspaper.png | Bin .../res/newspaperflyout.png | Bin .../res/notifications.png | Bin .../res/oasis.jpg | Bin .../res/oasissmall.jpg | Bin .../res/person.png | Bin .../res/photo.jpg | Bin .../res/profile.png | Bin .../res/ratchet.png | Bin .../res/ratchet_full.jpg | Bin .../res/refresh.png | Bin .../res/reply.png | Bin .../res/retweet.png | Bin .../res/scott.png | Bin .../res/scott159.png | Bin .../res/search.png | Bin .../res/seth.png | Bin .../res/slideout.png | Bin .../res/star.png | Bin .../res/tdl.png | Bin .../res/tdl_full.jpg | Bin .../res/test.jpg | Bin .../res/toolbar_close.png | Bin .../res/tweet.png | Bin .../res/twitter.png | Bin .../res/twitternav.png | Bin .../res/xamarinlogo.png | Bin .../res/xamarinstore.jpg | Bin .../Compatibility.ControlGallery.Tizen.png} | Bin .../tizen-manifest.xml | 8 +- .../ControlGallery.Tizen.cs | 31 - .../DisposeLabelRenderer.cs | 20 - .../DisposePageRenderer.cs | 20 - .../SampleNativeControl.cs | 24 - .../Xamarin.Forms.ControlGallery.Tizen.csproj | 23 - .../src/AppHostBuilderExtensions.Tizen.cs | 55 ++ .../Core/src/AppHostBuilderExtensions.cs | 38 ++ .../Core/src/Compatibility.csproj | 6 +- src/Compatibility/Core/src/Forms.cs | 2 +- .../src/MauiHandlersCollectionExtensions.cs | 2 +- .../Core/src/RendererToHandlerShim.Tizen.cs | 62 ++ .../Core/src/RendererToHandlerShim.cs | 7 + .../Core/src/Tizen/Cells/CellRenderer.cs | 5 +- .../Core/src/Tizen/Cells/EntryCellRenderer.cs | 8 +- .../Core/src/Tizen/Cells/ImageCellRenderer.cs | 1 + .../src/Tizen/Cells/SwitchCellRenderer.cs | 2 + .../Core/src/Tizen/Cells/TextCellRenderer.cs | 1 + .../Core/src/Tizen/Cells/ViewCellRenderer.cs | 3 +- .../Core/src/Tizen/Compatibility.Tizen.csproj | 36 - .../Core/src/Tizen/Deserializer.cs | 103 --- .../Core/src/Tizen/DisplayResolutionUnit.cs | 31 + .../Core/src/Tizen/DragGestureHandler.cs | 6 +- .../Core/src/Tizen/DropGestureHandler.cs | 3 +- .../Core/src/Tizen/EmbeddedFontLoader.cs | 46 +- .../Core/src/Tizen/ExportCellAttribute.cs | 12 - .../Core/src/Tizen/ExportHandlerAttribute.cs | 12 - .../ExportImageSourceHandlerAttribute.cs | 12 - .../Core/src/Tizen/ExportRendererAttribute.cs | 36 - .../Extensions/AccessibilityExtensions.cs | 1 + .../src/Tizen/Extensions/BrushExtensions.cs | 7 +- .../src/Tizen/Extensions/ColorExtensions.cs | 9 +- .../DensityIndependentPixelExtensions.cs | 8 +- .../src/Tizen/Extensions/FontExtensions.cs | 63 -- .../Tizen/Extensions/GeometryExtensions.cs | 12 +- .../Tizen/Extensions/KeyboardExtensions.cs | 3 +- .../Extensions/NativeBindingExtensions.cs | 2 +- .../src/Tizen/Extensions/PageExtensions.cs | 2 + .../PlatformConfigurationExtensions.cs | 2 +- .../Extensions/TextAlignmentExtensions.cs | 6 +- .../Tizen/Extensions/TransformExtensions.cs | 2 +- src/Compatibility/Core/src/Tizen/Forms.cs | 319 ++++----- .../Core/src/Tizen/FormsApplication.cs | 55 +- .../Core/src/Tizen/GestureDetector.cs | 2 + .../Core/src/Tizen/GestureHandler.cs | 1 + .../Core/src/Tizen/HandlerToRendererShim.cs | 196 ++++++ .../Core/src/Tizen/IMEApplication.cs | 1 + .../Core/src/Tizen/LightweightPlatform.cs | 4 +- .../Core/src/Tizen/Log/XamarinLogListener.cs | 20 - .../Core/src/Tizen/Native/BorderRectangle.cs | 2 +- .../Core/src/Tizen/Native/Button.cs | 2 +- .../Native/CollectionView/CollectionView.cs | 7 +- .../Native/CollectionView/EmptyItemAdaptor.cs | 20 +- .../CollectionView/GridLayoutManager.cs | 7 +- .../Native/CollectionView/IndicatorView.cs | 2 + .../CollectionView/ItemTemplateAdaptor.cs | 20 +- .../CollectionView/LinearLayoutManager.cs | 5 +- .../src/Tizen/Native/DateTimePickerDialog.cs | 1 + .../Core/src/Tizen/Native/Dialog.cs | 7 +- .../Core/src/Tizen/Native/EditfieldEntry.cs | 1 + .../Core/src/Tizen/Native/Entry.cs | 6 +- .../Core/src/Tizen/Native/FlyoutPage.cs | 12 +- .../Core/src/Tizen/Native/ListView.cs | 5 +- .../Core/src/Tizen/Native/Span.cs | 10 +- .../Core/src/Tizen/Native/TableView.cs | 3 +- .../Core/src/Tizen/Native/TitleViewPage.cs | 3 +- .../Tizen/Native/Watch/FormsWatchLayout.cs | 5 +- .../src/Tizen/Native/Watch/WatchButton.cs | 2 +- .../Native/Watch/WatchDateTimePickerDialog.cs | 2 +- .../src/Tizen/Native/Watch/WatchListView.cs | 1 + .../src/Tizen/Native/Watch/WatchTableView.cs | 3 +- .../Core/src/Tizen/NativeBindingService.cs | 6 +- .../src/Tizen/NativeValueConverterService.cs | 4 +- .../Core/src/Tizen/NativeViewWrapper.cs | 2 + .../Core/src/Tizen/PanGestureHandler.cs | 1 + .../Core/src/Tizen/PinchGestureHandler.cs | 5 +- src/Compatibility/Core/src/Tizen/Platform.cs | 84 ++- .../Core/src/Tizen/PlatformEffect.cs | 11 - .../Core/src/Tizen/PopupManager.cs | 24 +- .../Core/src/Tizen/PreloadedWindow.cs | 3 +- .../Core/src/Tizen/Properties/AssemblyInfo.cs | 83 +-- .../Renderers/ActivityIndicatorRenderer.cs | 6 +- .../src/Tizen/Renderers/BoxViewRenderer.cs | 14 +- .../src/Tizen/Renderers/ButtonRenderer.cs | 27 +- .../Tizen/Renderers/CarouselPageRenderer.cs | 10 +- .../Tizen/Renderers/CarouselViewRenderer.cs | 4 +- .../src/Tizen/Renderers/CheckBoxRenderer.cs | 8 +- .../src/Tizen/Renderers/CustomFocusManager.cs | 108 +-- .../src/Tizen/Renderers/DatePickerRenderer.cs | 23 +- .../src/Tizen/Renderers/DefaultRenderer.cs | 11 +- .../src/Tizen/Renderers/EditorRenderer.cs | 29 +- .../Core/src/Tizen/Renderers/EntryRenderer.cs | 48 +- .../src/Tizen/Renderers/FastLayoutRenderer.cs | 2 + .../src/Tizen/Renderers/FlyoutContainer.cs | 3 +- .../src/Tizen/Renderers/FlyoutPageRenderer.cs | 5 +- .../Core/src/Tizen/Renderers/FrameRenderer.cs | 6 +- .../src/Tizen/Renderers/ILayoutRenderer.cs | 1 + .../Tizen/Renderers/IVisualElementRenderer.cs | 3 + .../Tizen/Renderers/ImageButtonRenderer.cs | 8 +- .../Core/src/Tizen/Renderers/ImageRenderer.cs | 13 +- .../Tizen/Renderers/IndicatorViewRenderer.cs | 3 + .../src/Tizen/Renderers/ItemsViewRenderer.cs | 7 +- .../Core/src/Tizen/Renderers/LabelRenderer.cs | 18 +- .../src/Tizen/Renderers/LayoutRenderer.cs | 4 +- .../src/Tizen/Renderers/ListViewRenderer.cs | 7 +- .../Tizen/Renderers/MasterDetailContainer.cs | 140 ---- .../Renderers/MasterDetailPageRenderer.cs | 160 ----- .../Renderers/NativeViewWrapperRenderer.cs | 3 + .../Tizen/Renderers/NavigationPageRenderer.cs | 16 +- .../Core/src/Tizen/Renderers/PageRenderer.cs | 9 +- .../src/Tizen/Renderers/PickerRenderer.cs | 36 +- .../Tizen/Renderers/ProgressBarRenderer.cs | 10 +- .../Tizen/Renderers/RadioButtonRenderer.cs | 6 +- .../Tizen/Renderers/RefreshViewRenderer.cs | 43 +- .../src/Tizen/Renderers/ScrollViewRenderer.cs | 18 +- .../src/Tizen/Renderers/SearchBarRenderer.cs | 20 +- .../src/Tizen/Renderers/SliderRenderer.cs | 8 +- .../src/Tizen/Renderers/StepperRenderer.cs | 3 + .../Renderers/StructuredItemsViewRenderer.cs | 2 + .../src/Tizen/Renderers/SwipeViewRenderer.cs | 45 +- .../src/Tizen/Renderers/SwitchRenderer.cs | 20 +- .../src/Tizen/Renderers/TabbedPageRenderer.cs | 39 +- .../src/Tizen/Renderers/TableViewRenderer.cs | 3 + .../src/Tizen/Renderers/TimePickerRenderer.cs | 23 +- .../Core/src/Tizen/Renderers/ViewRenderer.cs | 4 +- .../Tizen/Renderers/VisualElementRenderer.cs | 114 ++-- .../src/Tizen/Renderers/WebViewRenderer.cs | 39 +- .../Core/src/Tizen/Resource/arrow_left.png | Bin 490 -> 0 bytes .../src/Tizen/Resource/dots_horizontal.png | Bin 419 -> 0 bytes .../Core/src/Tizen/Resource/menu.png | Bin 417 -> 0 bytes .../Core/src/Tizen/Resource/refresh_48dp.png | Bin 876 -> 0 bytes .../Core/src/Tizen/Resource/wc_visual_cue.png | Bin 433 -> 0 bytes .../Core/src/Tizen/Shapes/EllipseRenderer.cs | 4 +- .../Core/src/Tizen/Shapes/LineRenderer.cs | 4 +- .../Core/src/Tizen/Shapes/PathRenderer.cs | 4 +- .../Core/src/Tizen/Shapes/PolygonRenderer.cs | 4 +- .../Core/src/Tizen/Shapes/PolylineRenderer.cs | 4 +- .../src/Tizen/Shapes/RectangleRenderer.cs | 4 +- .../Core/src/Tizen/Shapes/ShapeRenderer.cs | 5 +- .../Core/src/Tizen/Shell/IShellTabs.cs | 3 +- .../Core/src/Tizen/Shell/NavigationDrawer.cs | 1 + .../Core/src/Tizen/Shell/NavigationView.cs | 9 +- .../src/Tizen/Shell/SearchHandlerRenderer.cs | 22 +- .../Core/src/Tizen/Shell/SearchResultList.cs | 1 + .../Core/src/Tizen/Shell/ShellItemRenderer.cs | 16 +- .../Core/src/Tizen/Shell/ShellMoreToolbar.cs | 3 +- .../Core/src/Tizen/Shell/ShellNavBar.cs | 8 +- .../Core/src/Tizen/Shell/ShellRenderer.cs | 7 +- .../src/Tizen/Shell/ShellSectionRenderer.cs | 16 +- .../Core/src/Tizen/Shell/ShellSectionStack.cs | 18 +- .../Core/src/Tizen/Shell/ShellTabs.cs | 3 +- .../Core/src/Tizen/Shell/SimpleViewStack.cs | 4 +- .../Shell/TV/FlyoutItemTemplateAdaptor.cs | 3 +- .../Shell/TV/FlyoutItemTemplateSelector.cs | 13 +- .../src/Tizen/Shell/TV/TVNavigationDrawer.cs | 1 + .../src/Tizen/Shell/TV/TVNavigationView.cs | 3 +- .../src/Tizen/Shell/TV/TVShellItemRenderer.cs | 1 + .../src/Tizen/Shell/TV/TVShellRenderer.cs | 1 + .../Tizen/Shell/TV/TVShellSectionRenderer.cs | 1 + .../src/Tizen/Shell/TV/TVShellSectionStack.cs | 1 + .../src/Tizen/Shell/Watch/NavigationDrawer.cs | 1 + .../src/Tizen/Shell/Watch/NavigationView.cs | 1 + .../Tizen/Shell/Watch/ShellContentRenderer.cs | 1 + .../Tizen/Shell/Watch/ShellItemRenderer.cs | 1 + .../src/Tizen/Shell/Watch/ShellRenderer.cs | 6 +- .../Tizen/Shell/Watch/ShellRendererFactory.cs | 1 + .../Shell/Watch/ShellSectionItemsRenderer.cs | 2 + .../Watch/ShellSectionNavigationRenderer.cs | 9 +- .../src/Tizen/SkiaSharp/BoxViewRenderer.cs | 14 +- .../src/Tizen/SkiaSharp/CanvasViewRenderer.cs | 4 +- .../Core/src/Tizen/SkiaSharp/FrameRenderer.cs | 8 +- .../Core/src/Tizen/SkiaSharp/ImageRenderer.cs | 12 +- .../Core/src/Tizen/SkiaSharp/SKClipperView.cs | 2 + .../Core/src/Tizen/StaticRegistrar.cs | 19 +- .../Core/src/Tizen/SwipeGestureHandler.cs | 1 + .../Core/src/Tizen/TapGestureHandler.cs | 1 + .../Core/src/Tizen/ThemeConstants.cs | 20 +- .../Core/src/Tizen/ThemeManager.cs | 51 +- .../src/Tizen/TizenIsolatedStorageFile.cs | 127 ---- .../Core/src/Tizen/TizenPlatformServices.cs | 118 ---- .../Tizen/VisualElementChangedEventArgs.cs | 17 - .../src/Tizen/Compatibility.Maps.Tizen.csproj | 18 +- src/Compatibility/Maps/src/Tizen/FormsMaps.cs | 7 +- .../Maps/src/Tizen/GeocoderBackend.cs | 1 + .../Maps/src/Tizen/MapRenderer.cs | 7 +- .../Maps/src/Tizen/Properties/AssemblyInfo.cs | 5 +- .../Platforms/Tizen/Main.cs | 17 + .../Platforms/Tizen/tizen-manifest.xml | 29 + .../Platforms/Tizen/Main.cs | 17 + .../Platforms/Tizen/tizen-manifest.xml | 27 + .../Controls.Sample.Tizen.csproj | 17 + .../samples/Controls.Sample.Tizen/Main.cs | 21 + .../res/dokdo_regular.ttf | Bin 0 -> 2149420 bytes .../Controls.Sample.Tizen/shared/res/icon.png | Bin 0 -> 2413 bytes .../Controls.Sample.Tizen/tizen-manifest.xml | 27 + .../BordelessEntry/BordelessEntryHandler.cs | 4 + .../FocusEffect/FocusPlatformEffect.cs | 19 + .../SkiaGraphicsViewHandler.cs | 2 + .../SkiaSharpHandlers/SkiaShapeViewHandler.cs | 2 + .../samples/Controls.Sample/Startup.cs | 21 +- .../Tizen/FontNamedSizeService.cs | 6 +- .../Compatibility/Tizen/PlatformInvalidate.cs | 19 + .../Tizen/PlatformSizeService.cs | 20 + .../Compatibility}/Tizen/ResourcesProvider.cs | 9 +- .../Core/HandlerImpl/Button/Button.Tizen.cs | 18 + .../Core/HandlerImpl/Editor/Editor.Tizen.cs | 10 + .../Core/HandlerImpl/Element/Element.Tizen.cs | 19 + .../src/Core/HandlerImpl/Entry/Entry.Tizen.cs | 10 + .../src/Core/HandlerImpl/Label/Label.Tizen.cs | 57 ++ .../Core/HandlerImpl/Layout/Layout.Tizen.cs | 11 + .../NavigationPage/NavigationPage.Impl.cs | 2 +- .../HandlerImpl/SearchBar/SearchBar.Tizen.cs | 10 + .../src/Core/HandlerImpl/Shape/Shape.Tizen.cs | 17 + .../TabbedPage/TabbedPage.Tizen.cs | 40 ++ .../VisualElement/VisualElement.Platform.cs | 2 + .../Core/HandlerImpl/Window/Window.Tizen.cs | 12 + .../Items/CarouselViewHandler.Tizen.cs | 18 + .../Items/CollectionViewHandler.Tizen.cs | 6 + .../Items/GroupableItemsViewHandler.Tizen.cs | 9 + .../Handlers/Items/ItemsViewHandler.Tizen.cs | 60 ++ .../ReorderableItemsViewHandler.Tizen.cs | 12 + .../Items/SelectableItemsViewHandler.Tizen.cs | 25 + .../Items/StructuredItemsViewHandler.Tizen.cs | 27 + .../Handlers/Items/Tizen/EmptyItemAdaptor.cs | 105 +++ .../Items/Tizen/ItemDefaultTemplateAdaptor.cs | 42 ++ .../Items/Tizen/ItemTemplateAdaptor.cs | 307 +++++++++ .../Handlers/Shapes/Line/LineHandler.Tizen.cs | 27 + .../Handlers/Shapes/Path/PathHandler.Tizen.cs | 17 + .../Shapes/Polygon/PolygonHandler.Tizen.cs | 52 ++ .../Shapes/Polyline/PolylineHandler.Tizen.cs | 52 ++ .../Rectangle/RectangleHandler.Tizen.cs | 17 + .../RoundRectangleHandler.Tizen.cs | 12 + .../Core/Handlers/Shell/ShellHandler.Tizen.cs | 37 + .../Core/Interactivity/PlatformBehavior.cs | 2 + .../AlertManager/AlertManager.Tizen.cs | 331 +++++++++ .../GestureManager/GestureManager.Tizen.cs | 137 ++++ .../ModalNavigationManager.Tizen.cs | 59 ++ .../PlatformConfigurationExtensions.cs | 2 + .../src/Core/Platform/PlatformEffect.cs | 2 + .../Core/Platform/Tizen/DragGestureHandler.cs | 243 +++++++ .../Core/Platform/Tizen/DropGestureHandler.cs | 126 ++++ .../Tizen/Extensions/ButtonExtensions.cs | 13 + .../Extensions/CollectionViewExtensions.cs | 129 ++++ .../Tizen/Extensions/DragDropExtensions.cs | 114 ++++ .../Tizen/Extensions/FontExtensions.cs | 10 + .../Tizen/Extensions/SearchBarExtensions.cs | 21 + .../Tizen/Extensions/ShellExtensions.cs | 17 + .../Tizen/Extensions/TextExtensions.cs | 23 + .../Core/Platform/Tizen/GestureDetector.cs | 637 ++++++++++++++++++ .../src/Core/Platform/Tizen/GestureHandler.cs | 55 ++ .../Core/Platform/Tizen/IGestureController.cs | 15 + .../Core/Platform/Tizen/PanGestureHandler.cs | 43 ++ .../Platform/Tizen/PinchGestureHandler.cs | 58 ++ .../Tizen/Shell/ShellFlyoutItemAdaptor.cs | 185 +++++ .../Platform/Tizen/Shell/ShellItemView.cs | 475 +++++++++++++ .../Platform/Tizen/Shell/ShellMoreTabs.cs | 97 +++ .../Core/Platform/Tizen/Shell/ShellNavBar.cs | 400 +++++++++++ .../Tizen/Shell/ShellSearchResultList.cs | 99 +++ .../Platform/Tizen/Shell/ShellSearchView.cs | 372 ++++++++++ .../Tizen/Shell/ShellSectionHandler.cs | 389 +++++++++++ .../Platform/Tizen/Shell/ShellSectionStack.cs | 305 +++++++++ .../Core/Platform/Tizen/Shell/ShellView.cs | 427 ++++++++++++ .../Platform/Tizen/Shell/SimpleViewStack.cs | 93 +++ .../Tizen/Shell/TVShellItemAdaptor.cs | 358 ++++++++++ .../Platform/Tizen/Shell/TVShellItemView.cs | 18 + .../Tizen/Shell/TVShellSectionHandler.cs | 285 ++++++++ .../Tizen/Shell/TVShellSectionStack.cs | 16 + .../Core/Platform/Tizen/Shell/TVShellView.cs | 43 ++ .../Platform/Tizen/Shell/ThemeConstants.cs | 43 ++ .../Core/Platform/Tizen/Shell/ThemeManager.cs | 130 ++++ .../Platform/Tizen/SwipeGestureHandler.cs | 29 + .../Core/Platform/Tizen/TapGestureHandler.cs | 46 ++ .../src/Core/Properties/AssemblyInfo.cs | 2 + .../Xaml/Hosting/AppHostBuilderExtensions.cs | 10 +- .../src/Xaml/SimplifyOnPlatformVisitor.cs | 6 + src/Core/src/ActivationState.cs | 24 + .../src/Animations/PlatformTicker.Tizen.cs | 42 ++ src/Core/src/Core.csproj | 3 + src/Core/src/Dispatching/Dispatcher.Tizen.cs | 108 +++ .../src/Fonts/EmbeddedFontLoader.Tizen.cs | 55 ++ src/Core/src/Fonts/FontManager.Tizen.cs | 107 +++ src/Core/src/Fonts/FontRegistrar.Tizen.cs | 26 + src/Core/src/Fonts/IFontManager.Tizen.cs | 9 + src/Core/src/Graphics/MauiDrawable.Tizen.cs | 89 +++ .../src/Graphics/PaintExtensions.Tizen.cs | 82 +++ .../ActivityIndicatorHandler.Tizen.cs | 28 + .../ActivityIndicatorHandler.cs | 4 +- .../IActivityIndicatorHandler.cs | 4 +- .../Application/ApplicationHandler.Tizen.cs | 25 + .../Application/ApplicationHandler.cs | 2 + .../Handlers/Border/BorderHandler.Tizen.cs | 71 ++ src/Core/src/Handlers/Border/BorderHandler.cs | 2 + .../src/Handlers/Border/IBorderHandler.cs | 2 + .../Handlers/Button/ButtonHandler.Tizen.cs | 95 +++ src/Core/src/Handlers/Button/ButtonHandler.cs | 4 +- .../src/Handlers/Button/IButtonHandler.cs | 6 +- .../CheckBox/CheckBoxHandler.Tizen.cs | 41 ++ .../src/Handlers/CheckBox/CheckBoxHandler.cs | 2 + .../src/Handlers/CheckBox/ICheckboxHandler.cs | 2 + .../ContentView/ContentViewHandler.Tizen.cs | 77 +++ .../ContentView/ContentViewHandler.cs | 7 +- .../ContentView/IContentViewHandler.cs | 4 +- .../DatePicker/DatePickerHandler.Tizen.cs | 136 ++++ .../Handlers/DatePicker/DatePickerHandler.cs | 4 +- .../Handlers/DatePicker/IDatePickerHandler.cs | 4 +- .../Handlers/Editor/EditorHandler.Tizen.cs | 170 +++++ src/Core/src/Handlers/Editor/EditorHandler.cs | 4 +- .../src/Handlers/Editor/IEditorHandler.cs | 4 +- .../src/Handlers/ElementHandlerExtensions.cs | 2 + .../src/Handlers/Entry/EntryHandler.Tizen.cs | 221 ++++++ src/Core/src/Handlers/Entry/EntryHandler.cs | 6 +- src/Core/src/Handlers/Entry/IEntryHandler.cs | 4 +- .../FlyoutView/FlyoutViewHandler.Tizen.cs | 14 + .../GraphicsView/GraphicsViewHandler.Tizen.cs | 28 + .../GraphicsView/GraphicsViewHandler.cs | 2 +- .../GraphicsView/IGraphicsViewHandler.cs | 2 +- src/Core/src/Handlers/IViewHandler.Tizen.cs | 19 + src/Core/src/Handlers/Image/IImageHandler.cs | 4 +- .../src/Handlers/Image/ImageHandler.Tizen.cs | 58 ++ src/Core/src/Handlers/Image/ImageHandler.cs | 8 +- .../ImageButton/IImageButtonHandler.cs | 4 +- .../ImageButton/ImageButtonHandler.Tizen.cs | 65 ++ .../ImageButton/ImageButtonHandler.cs | 10 +- .../IndicatorView/IIndicatorViewHandler.cs | 4 +- .../IndicatorViewHandler.Tizen.cs | 60 ++ .../IndicatorView/IndicatorViewHandler.cs | 4 +- src/Core/src/Handlers/Label/ILabelHandler.cs | 4 +- .../src/Handlers/Label/LabelHandler.Tizen.cs | 78 +++ src/Core/src/Handlers/Label/LabelHandler.cs | 6 +- .../src/Handlers/Layout/ILayoutHandler.cs | 4 +- .../Handlers/Layout/LayoutHandler.Tizen.cs | 176 +++++ src/Core/src/Handlers/Layout/LayoutHandler.cs | 6 + .../src/Handlers/MenuBar/IMenuBarHandler.cs | 4 +- .../Handlers/MenuBar/MenuBarHandler.Tizen.cs | 30 + .../src/Handlers/MenuBar/MenuBarHandler.cs | 4 +- .../MenuBarItem/IMenuBarItemHandler.cs | 4 +- .../MenuBarItem/MenuBarItemHandler.Tizen.cs | 30 + .../MenuBarItem/MenuBarItemHandler.cs | 4 +- .../MenuFlyoutItem/IMenuFlyoutItemHandler.cs | 4 +- .../MenuFlyoutItem/MenuFlyoutItemHandler.cs | 4 +- .../IMenuFlyoutSubItemHandler.cs | 4 +- .../MenuFlyoutSubItemHandler.Tizen.cs | 30 + .../MenuFlyoutSubItemHandler.cs | 4 +- .../NavigationPage/INavigationViewHandler.cs | 4 +- .../NavigationViewHandler.Tizen.cs | 341 ++++++++++ .../NavigationPage/NavigationViewHandler.cs | 4 +- .../src/Handlers/Page/PageHandler.Tizen.cs | 29 + src/Core/src/Handlers/Page/PageHandler.cs | 3 + .../src/Handlers/Picker/IPickerHandler.cs | 4 +- .../Handlers/Picker/PickerHandler.Tizen.cs | 199 ++++++ src/Core/src/Handlers/Picker/PickerHandler.cs | 4 +- .../ProgressBar/ProgressBarHandler.Tizen.cs | 33 + .../RadioButton/IRadioButtonHandler.cs | 4 +- .../RadioButton/RadioButtonHandler.Tizen.cs | 63 ++ .../RadioButton/RadioButtonHandler.cs | 4 +- .../RefreshView/IRefreshViewHandler.cs | 4 +- .../RefreshView/RefreshViewHandler.Tizen.cs | 31 + .../RefreshView/RefreshViewHandler.cs | 4 +- .../Handlers/ScrollView/IScrollViewHandler.cs | 4 +- .../ScrollView/ScrollViewHandler.Tizen.cs | 153 +++++ .../Handlers/ScrollView/ScrollViewHandler.cs | 4 +- .../Handlers/SearchBar/ISearchBarHandler.cs | 5 +- .../SearchBar/SearchBarHandler.Tizen.cs | 149 ++++ .../Handlers/SearchBar/SearchBarHandler.cs | 4 +- .../Handlers/ShapeView/IShapeViewHandler.cs | 4 +- .../ShapeView/ShapeViewHandler.Tizen.cs | 76 +++ .../Handlers/ShapeView/ShapeViewHandler.cs | 4 +- .../src/Handlers/Slider/ISliderHandler.cs | 4 +- .../Handlers/Slider/SliderHandler.Tizen.cs | 90 +++ src/Core/src/Handlers/Slider/SliderHandler.cs | 4 +- .../Handlers/Stepper/StepperHandler.Tizen.cs | 48 ++ .../ISwipeItemMenuItemHandler.cs | 4 +- .../SwipeItemMenuItemHandler.Tizen.cs | 33 + .../SwipeItemMenuItemHandler.cs | 4 +- .../SwipeItemView/ISwipeItemViewHandler.cs | 4 +- .../SwipeItemViewHandler.Tizen.cs | 73 ++ .../SwipeItemView/SwipeItemViewHandler.cs | 4 +- .../Handlers/SwipeView/ISwipeViewHandler.cs | 6 +- .../SwipeView/SwipeViewHandler.Tizen.cs | 61 ++ .../Handlers/SwipeView/SwipeViewHandler.cs | 6 +- .../src/Handlers/Switch/ISwitchHandler.cs | 4 +- .../Handlers/Switch/SwitchHandler.Tizen.cs | 48 ++ src/Core/src/Handlers/Switch/SwitchHandler.cs | 4 +- .../Handlers/TabbedView/TabbedViewHandler.cs | 4 +- .../Handlers/TimePicker/ITimePickerHandler.cs | 4 +- .../TimePicker/TimePickerHandler.Tizen.cs | 131 ++++ .../Handlers/TimePicker/TimePickerHandler.cs | 4 +- .../src/Handlers/Toolbar/IToolbarHandler.cs | 4 +- .../Handlers/Toolbar/ToolbarHandler.Tizen.cs | 16 + .../src/Handlers/Toolbar/ToolbarHandler.cs | 4 +- .../src/Handlers/View/ViewHandler.Tizen.cs | 130 ++++ src/Core/src/Handlers/View/ViewHandler.cs | 2 + .../src/Handlers/View/ViewHandlerOfT.Tizen.cs | 202 ++++++ src/Core/src/Handlers/View/ViewHandlerOfT.cs | 6 +- .../src/Handlers/WebView/IWebViewHandler.cs | 4 +- .../Handlers/WebView/WebViewHandler.Tizen.cs | 80 +++ .../src/Handlers/WebView/WebViewHandler.cs | 4 +- .../src/Handlers/Window/IWindowHandler.cs | 4 +- .../Handlers/Window/WindowHandler.Tizen.cs | 32 + src/Core/src/Handlers/Window/WindowHandler.cs | 2 + .../EssentialsMauiAppBuilderExtensions.cs | 6 +- .../AppHostBuilderExtensions.Tizen.cs | 37 + src/Core/src/IMauiContext.cs | 2 +- .../FileImageSourceService.Tizen.cs | 88 +++ .../FontImageSourceService.Tizen.cs | 40 ++ .../src/ImageSources/IImageSourceService.cs | 5 + .../src/ImageSources/ImageSourceExtensions.cs | 7 +- .../src/ImageSources/ImageSourceService.cs | 5 + .../ImageSources/ImageSourceServiceResult.cs | 4 +- .../StreamImageSourceService.Tizen.cs | 41 ++ .../UriImageSourceService.Tizen.cs | 38 ++ .../Tizen/ITizenLifecycleBuilder.cs | 6 + .../LifecycleEvents/Tizen/TizenLifecycle.cs | 25 + .../Tizen/TizenLifecycleBuilderExtensions.cs | 19 + .../Tizen/TizenLifecycleExtensions.cs | 32 + src/Core/src/MauiContextExtensions.cs | 3 + src/Core/src/Platform/ElementExtensions.cs | 7 +- .../src/Platform/ImageSourcePartLoader.cs | 13 +- .../Tizen/ActivityIndicatorExtensions.cs | 18 + .../src/Platform/Tizen/AspectExtensions.cs | 16 + src/Core/src/Platform/Tizen/BorderView.cs | 29 + .../src/Platform/Tizen/ButtonExtensions.cs | 17 + .../src/Platform/Tizen/CheckBoxExtensions.cs | 22 + .../src/Platform/Tizen/ColorExtensions.cs | 39 ++ src/Core/src/Platform/Tizen/ContainerView.cs | 74 ++ src/Core/src/Platform/Tizen/ContentCanvas.cs | 49 ++ .../src/Platform/Tizen/CoreAppExtensions.cs | 98 +++ src/Core/src/Platform/Tizen/DPExtensions.cs | 122 ++++ .../Platform/Tizen/DatePickerExtensions.cs | 17 + .../src/Platform/Tizen/EditorExtensions.cs | 12 + .../src/Platform/Tizen/ElementExtensions.cs | 10 + .../src/Platform/Tizen/EntryExtensions.cs | 215 ++++++ .../Platform/Tizen/FlowDirectionExtensions.cs | 13 + .../src/Platform/Tizen/GraphicsExtensions.cs | 19 + .../Platform/Tizen/GraphicsViewExtensions.cs | 12 + .../Platform/Tizen/IWrapperViewDrawables.cs | 13 + .../src/Platform/Tizen/ImageExtensions.cs | 22 + .../Tizen/ImageSourcePartExtensions.cs | 63 ++ .../src/Platform/Tizen/KeyboardExtensions.cs | 76 +++ .../src/Platform/Tizen/LabelExtensions.cs | 88 +++ src/Core/src/Platform/Tizen/LayoutCanvas.cs | 49 ++ .../Platform/Tizen/LayoutCanvasExtensions.cs | 10 + .../src/Platform/Tizen/MauiApplication.cs | 117 ++++ src/Core/src/Platform/Tizen/MauiBoxView.cs | 12 + .../Platform/Tizen/MauiContextExtensions.cs | 18 + .../src/Platform/Tizen/MauiImageButton.cs | 65 ++ .../Tizen/MauiIndicatorViewExtensions.cs | 20 + .../src/Platform/Tizen/MauiRadioButton.cs | 145 ++++ src/Core/src/Platform/Tizen/MauiShapeView.cs | 12 + src/Core/src/Platform/Tizen/MauiWebView.cs | 41 ++ src/Core/src/Platform/Tizen/ModalStack.cs | 101 +++ .../src/Platform/Tizen/PickerExtensions.cs | 24 + .../Tizen/PlatformTouchGraphicsView.cs | 68 ++ .../Platform/Tizen/ProgressBarExtensions.cs | 17 + .../Platform/Tizen/RadioButtonExtensions.cs | 15 + .../Platform/Tizen/ScrollViewExtensions.cs | 55 ++ .../src/Platform/Tizen/SearchBarExtensions.cs | 12 + .../src/Platform/Tizen/ShapeViewExtensions.cs | 17 + .../src/Platform/Tizen/SliderExtensions.cs | 76 +++ .../src/Platform/Tizen/StepperExtensions.cs | 56 ++ .../src/Platform/Tizen/StrokeExtensions.cs | 100 +++ .../src/Platform/Tizen/SwitchExtensions.cs | 33 + .../Platform/Tizen/TimePickerExtensions.cs | 24 + .../Tizen/TransformationExtensions.cs | 140 ++++ src/Core/src/Platform/Tizen/ViewExtensions.cs | 275 ++++++++ .../src/Platform/Tizen/WebViewExtensions.cs | 57 ++ .../src/Platform/Tizen/WindowExtensions.cs | 114 ++++ src/Core/src/Platform/Tizen/WrapperView.cs | 310 +++++++++ .../Platform/Tizen/WrapperViewDrawables.cs | 65 ++ src/Core/src/Platform/ViewExtensions.cs | 3 + src/Core/src/Properties/AssemblyInfo.cs | 2 + src/Core/src/SemanticExtensions.cs | 8 +- src/Core/src/ViewExtensions.cs | 5 +- .../VisualDiagnosticsOverlay.Tizen.cs | 55 ++ src/Core/src/WindowExtensions.cs | 2 + .../src/WindowOverlay/WindowOverlay.Tizen.cs | 77 +++ src/Core/src/WindowOverlay/WindowOverlay.cs | 2 + src/DotNet/Dependencies/Workloads.csproj | 1 + src/DotNet/DotNet.csproj | 4 +- src/Essentials/samples/Samples/App.xaml.cs | 2 +- .../samples/Samples/Essentials.Sample.csproj | 4 + .../Platforms/Tizen/CustomViewCellRenderer.cs | 20 - .../Samples/Platforms/Tizen/Program.cs | 19 +- .../Platforms/Tizen/tizen-manifest.xml | 4 +- src/Essentials/samples/Samples/Startup.cs | 8 +- .../samples/Samples/View/HomePage.xaml | 2 +- .../src/Accelerometer/Accelerometer.tizen.cs | 5 +- src/Essentials/src/AppInfo/AppInfo.tizen.cs | 7 +- .../src/Barometer/Barometer.tizen.cs | 7 +- src/Essentials/src/Battery/Battery.tizen.cs | 1 + src/Essentials/src/Browser/Browser.tizen.cs | 2 +- src/Essentials/src/Compass/Compass.tizen.cs | 3 +- .../src/Connectivity/Connectivity.tizen.cs | 3 +- src/Essentials/src/Contacts/Contacts.tizen.cs | 6 +- .../src/DeviceDisplay/DeviceDisplay.shared.cs | 2 +- .../src/DeviceDisplay/DeviceDisplay.tizen.cs | 95 ++- .../src/DeviceInfo/DeviceInfo.tizen.cs | 30 +- src/Essentials/src/Email/Email.tizen.cs | 21 +- src/Essentials/src/Essentials.csproj | 7 +- .../src/FilePicker/FilePicker.tizen.cs | 14 +- .../src/FileSystem/FileSystem.tizen.cs | 1 + .../src/Flashlight/Flashlight.tizen.cs | 25 +- .../src/Geocoding/Geocoding.tizen.cs | 9 +- .../src/Geolocation/Geolocation.tizen.cs | 6 +- .../src/Gyroscope/Gyroscope.tizen.cs | 5 +- .../HapticFeedback/HapticFeedback.tizen.cs | 1 + src/Essentials/src/Launcher/Launcher.tizen.cs | 3 +- .../src/Magnetometer/Magnetometer.tizen.cs | 3 +- src/Essentials/src/Map/Map.tizen.cs | 1 + .../src/MediaPicker/MediaPicker.tizen.cs | 2 + .../OrientationSensor.tizen.cs | 3 +- .../src/PhoneDialer/PhoneDialer.tizen.cs | 3 +- .../src/Platform/Platform.shared.cs | 17 + .../src/Platform/PlatformUtils.tizen.cs | 54 +- ...> Screenshot.netstandard.watchos.macos.cs} | 0 .../src/Screenshot/Screenshot.shared.cs | 8 + .../src/Screenshot/Screenshot.tizen.cs | 40 ++ .../src/SecureStorage/SecureStorage.tizen.cs | 1 + ...nReader.netstandard.tvos.watchos.macos.cs} | 0 .../SemanticScreenReader.tizen.cs | 10 + src/Essentials/src/Sms/Sms.tizen.cs | 3 +- .../src/TextToSpeech/TextToSpeech.tizen.cs | 12 +- .../src/Vibration/Vibration.tizen.cs | 1 + src/SingleProject/Resizetizer/src/DpiPath.cs | 38 ++ .../Resizetizer/src/ResizetizeImages.cs | 11 + .../src/TizenIconManifestUpdater.cs | 87 +++ .../src/TizenResourceXmlGenerator.cs | 87 +++ .../Resizetizer/src/TizenSplashUpdater.cs | 193 ++++++ .../localize/templatestrings.cs.json | 2 +- .../localize/templatestrings.de.json | 2 +- .../localize/templatestrings.en.json | 2 +- .../localize/templatestrings.es.json | 2 +- .../localize/templatestrings.fr.json | 2 +- .../localize/templatestrings.it.json | 2 +- .../localize/templatestrings.ja.json | 2 +- .../localize/templatestrings.json | 2 +- .../localize/templatestrings.ko.json | 2 +- .../localize/templatestrings.pl.json | 2 +- .../localize/templatestrings.pt-BR.json | 2 +- .../localize/templatestrings.ru.json | 2 +- .../localize/templatestrings.tr.json | 2 +- .../localize/templatestrings.zh-Hans.json | 2 +- .../localize/templatestrings.zh-Hant.json | 2 +- .../.template.config/template.in.json | 4 +- .../templates/maui-blazor/MauiApp.1.csproj | 3 + .../maui-blazor/Platforms/Tizen/Main.cs | 16 + .../Platforms/Tizen/tizen-manifest.xml | 15 + .../.template.config/template.json | 2 +- .../.template.config/template.json | 2 +- .../.template.config/template.json | 2 +- .../.template.config/template.json | 2 +- .../.template.config/template.in.json | 2 +- .../src/templates/maui-lib/MauiLib1.csproj | 3 + .../Platforms/Tizen/PlatformClass1.cs | 9 + .../localize/templatestrings.cs.json | 2 +- .../localize/templatestrings.de.json | 2 +- .../localize/templatestrings.en.json | 2 +- .../localize/templatestrings.es.json | 2 +- .../localize/templatestrings.fr.json | 2 +- .../localize/templatestrings.it.json | 2 +- .../localize/templatestrings.ja.json | 2 +- .../localize/templatestrings.json | 2 +- .../localize/templatestrings.ko.json | 2 +- .../localize/templatestrings.pl.json | 2 +- .../localize/templatestrings.pt-BR.json | 2 +- .../localize/templatestrings.ru.json | 2 +- .../localize/templatestrings.tr.json | 2 +- .../localize/templatestrings.zh-Hans.json | 2 +- .../localize/templatestrings.zh-Hant.json | 2 +- .../.template.config/template.in.json | 4 +- .../templates/maui-mobile/MauiApp.1.csproj | 3 + .../maui-mobile/Platforms/Tizen/Main.cs | 16 + .../Platforms/Tizen/tizen-manifest.xml | 15 + .../Microsoft.Maui.Dependencies.csproj | 4 + .../Sdk/BundledVersions.in.targets | 2 +- .../WorkloadManifest.in.json | 41 +- src/Workload/README.md | 1 + src/Workload/Shared/Frameworks.targets | 9 +- 680 files changed, 18088 insertions(+), 2380 deletions(-) create mode 100644 src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Shipped.txt create mode 100644 src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Unshipped.txt create mode 100644 src/BlazorWebView/src/Maui/Tizen/BlazorWebViewHandler.Tizen.cs create mode 100644 src/BlazorWebView/src/Maui/Tizen/TizenMauiAssetFileProvider.cs create mode 100644 src/BlazorWebView/src/Maui/Tizen/TizenWebViewManager.cs create mode 100644 src/BlazorWebView/src/Maui/Tizen/WebViewContainer.cs create mode 100644 src/BlazorWebView/src/Maui/Tizen/WebViewExtensions.cs rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/BorderEffect.cs (69%) create mode 100644 src/Compatibility/ControlGallery/src/Tizen/Compatibility.ControlGallery.Tizen.csproj create mode 100644 src/Compatibility/ControlGallery/src/Tizen/ControlGallery.Tizen.cs create mode 100644 src/Compatibility/ControlGallery/src/Tizen/DisposeLabelRenderer.cs create mode 100644 src/Compatibility/ControlGallery/src/Tizen/DisposePageRenderer.cs rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/PlatformSpecificCoreGalleryFactory.cs (57%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/RegistrarValidationService.cs (65%) create mode 100644 src/Compatibility/ControlGallery/src/Tizen/SampleNativeControl.cs rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/FlowerBuds.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/Fruits.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/Icon-Small.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/Icon.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/Intranet-icon.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/Legumes.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/Vegetables.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/about.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/bank.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/bell.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/blog.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/books.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/booksflyout.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/calculator.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/card.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/caret_r.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/coffee.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/cover1.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/cover1small.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/crimson.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/crimsonsmall.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/facebook.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/favorite.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/film.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/filmflyout.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/games.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/gamesflyout.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/googleplus.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/grid.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/headphone.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/headphoneflyout.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/hm.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/hm_full.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/home.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/homeflyout.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/ic_pause.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/ic_play.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/ic_share.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/ic_stop.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/instagram.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/invalidimage.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/jet.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/lists.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/loop.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/menuIcon.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/messages.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/newspaper.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/newspaperflyout.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/notifications.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/oasis.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/oasissmall.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/person.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/photo.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/profile.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/ratchet.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/ratchet_full.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/refresh.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/reply.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/retweet.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/scott.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/scott159.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/search.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/seth.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/slideout.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/star.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/tdl.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/tdl_full.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/test.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/toolbar_close.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/tweet.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/twitter.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/twitternav.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/xamarinlogo.png (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/res/xamarinstore.jpg (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen/shared/res/Xamarin.Forms.ControlGallery.Tizen.png => Tizen/shared/res/Compatibility.ControlGallery.Tizen.png} (100%) rename src/Compatibility/ControlGallery/src/{Xamarin.Forms.ControlGallery.Tizen => Tizen}/tizen-manifest.xml (53%) delete mode 100644 src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/ControlGallery.Tizen.cs delete mode 100644 src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposeLabelRenderer.cs delete mode 100644 src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposePageRenderer.cs delete mode 100644 src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/SampleNativeControl.cs delete mode 100644 src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/Xamarin.Forms.ControlGallery.Tizen.csproj create mode 100644 src/Compatibility/Core/src/AppHostBuilderExtensions.Tizen.cs create mode 100644 src/Compatibility/Core/src/RendererToHandlerShim.Tizen.cs delete mode 100644 src/Compatibility/Core/src/Tizen/Compatibility.Tizen.csproj delete mode 100644 src/Compatibility/Core/src/Tizen/Deserializer.cs delete mode 100644 src/Compatibility/Core/src/Tizen/ExportCellAttribute.cs delete mode 100644 src/Compatibility/Core/src/Tizen/ExportHandlerAttribute.cs delete mode 100644 src/Compatibility/Core/src/Tizen/ExportImageSourceHandlerAttribute.cs delete mode 100644 src/Compatibility/Core/src/Tizen/ExportRendererAttribute.cs delete mode 100644 src/Compatibility/Core/src/Tizen/Extensions/FontExtensions.cs create mode 100644 src/Compatibility/Core/src/Tizen/HandlerToRendererShim.cs delete mode 100644 src/Compatibility/Core/src/Tizen/Log/XamarinLogListener.cs delete mode 100644 src/Compatibility/Core/src/Tizen/PlatformEffect.cs delete mode 100644 src/Compatibility/Core/src/Tizen/Renderers/MasterDetailContainer.cs delete mode 100644 src/Compatibility/Core/src/Tizen/Renderers/MasterDetailPageRenderer.cs delete mode 100644 src/Compatibility/Core/src/Tizen/Resource/arrow_left.png delete mode 100644 src/Compatibility/Core/src/Tizen/Resource/dots_horizontal.png delete mode 100644 src/Compatibility/Core/src/Tizen/Resource/menu.png delete mode 100644 src/Compatibility/Core/src/Tizen/Resource/refresh_48dp.png delete mode 100644 src/Compatibility/Core/src/Tizen/Resource/wc_visual_cue.png delete mode 100644 src/Compatibility/Core/src/Tizen/TizenIsolatedStorageFile.cs delete mode 100644 src/Compatibility/Core/src/Tizen/TizenPlatformServices.cs delete mode 100644 src/Compatibility/Core/src/Tizen/VisualElementChangedEventArgs.cs create mode 100644 src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/Main.cs create mode 100644 src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/tizen-manifest.xml create mode 100644 src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/Main.cs create mode 100644 src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/tizen-manifest.xml create mode 100644 src/Controls/samples/Controls.Sample.Tizen/Controls.Sample.Tizen.csproj create mode 100644 src/Controls/samples/Controls.Sample.Tizen/Main.cs create mode 100644 src/Controls/samples/Controls.Sample.Tizen/res/dokdo_regular.ttf create mode 100644 src/Controls/samples/Controls.Sample.Tizen/shared/res/icon.png create mode 100644 src/Controls/samples/Controls.Sample.Tizen/tizen-manifest.xml rename src/{Compatibility/Core/src => Controls/src/Core/Compatibility}/Tizen/FontNamedSizeService.cs (89%) create mode 100644 src/Controls/src/Core/Compatibility/Tizen/PlatformInvalidate.cs create mode 100644 src/Controls/src/Core/Compatibility/Tizen/PlatformSizeService.cs rename src/{Compatibility/Core/src => Controls/src/Core/Compatibility}/Tizen/ResourcesProvider.cs (91%) create mode 100644 src/Controls/src/Core/HandlerImpl/Button/Button.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/Editor/Editor.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/Element/Element.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/Entry/Entry.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/Label/Label.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/Layout/Layout.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/SearchBar/SearchBar.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/Shape/Shape.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/TabbedPage/TabbedPage.Tizen.cs create mode 100644 src/Controls/src/Core/HandlerImpl/Window/Window.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/CollectionViewHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/GroupableItemsViewHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/ReorderableItemsViewHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/SelectableItemsViewHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/StructuredItemsViewHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Items/Tizen/EmptyItemAdaptor.cs create mode 100644 src/Controls/src/Core/Handlers/Items/Tizen/ItemDefaultTemplateAdaptor.cs create mode 100644 src/Controls/src/Core/Handlers/Items/Tizen/ItemTemplateAdaptor.cs create mode 100644 src/Controls/src/Core/Handlers/Shapes/Line/LineHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Shapes/Path/PathHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Shapes/Rectangle/RectangleHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Shapes/RoundRectangle/RoundRectangleHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Handlers/Shell/ShellHandler.Tizen.cs create mode 100644 src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs create mode 100644 src/Controls/src/Core/Platform/GestureManager/GestureManager.Tizen.cs create mode 100644 src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Tizen.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/DragGestureHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/DropGestureHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/ButtonExtensions.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/CollectionViewExtensions.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/DragDropExtensions.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/FontExtensions.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/SearchBarExtensions.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/ShellExtensions.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/GestureDetector.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/GestureHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/IGestureController.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/PanGestureHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/PinchGestureHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellFlyoutItemAdaptor.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellItemView.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellMoreTabs.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellNavBar.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchResultList.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchView.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionStack.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ShellView.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/SimpleViewStack.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemAdaptor.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemView.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionStack.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/TVShellView.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ThemeConstants.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/Shell/ThemeManager.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/SwipeGestureHandler.cs create mode 100644 src/Controls/src/Core/Platform/Tizen/TapGestureHandler.cs create mode 100644 src/Core/src/Animations/PlatformTicker.Tizen.cs create mode 100644 src/Core/src/Dispatching/Dispatcher.Tizen.cs create mode 100644 src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs create mode 100644 src/Core/src/Fonts/FontManager.Tizen.cs create mode 100644 src/Core/src/Fonts/FontRegistrar.Tizen.cs create mode 100644 src/Core/src/Fonts/IFontManager.Tizen.cs create mode 100644 src/Core/src/Graphics/MauiDrawable.Tizen.cs create mode 100644 src/Core/src/Graphics/PaintExtensions.Tizen.cs create mode 100644 src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Application/ApplicationHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Border/BorderHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Button/ButtonHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/CheckBox/CheckBoxHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/ContentView/ContentViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/DatePicker/DatePickerHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Editor/EditorHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Entry/EntryHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/IViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Image/ImageHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/ImageButton/ImageButtonHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Label/LabelHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Layout/LayoutHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/MenuBar/MenuBarHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/NavigationPage/NavigationViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Page/PageHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Picker/PickerHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/ProgressBar/ProgressBarHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/RadioButton/RadioButtonHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/RefreshView/RefreshViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/ScrollView/ScrollViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/SearchBar/SearchBarHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/ShapeView/ShapeViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Slider/SliderHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Stepper/StepperHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/SwipeView/SwipeViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Switch/SwitchHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/TimePicker/TimePickerHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Toolbar/ToolbarHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/View/ViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/View/ViewHandlerOfT.Tizen.cs create mode 100644 src/Core/src/Handlers/WebView/WebViewHandler.Tizen.cs create mode 100644 src/Core/src/Handlers/Window/WindowHandler.Tizen.cs create mode 100644 src/Core/src/Hosting/LifecycleEvents/AppHostBuilderExtensions.Tizen.cs create mode 100644 src/Core/src/ImageSources/FileImageSourceService/FileImageSourceService.Tizen.cs create mode 100644 src/Core/src/ImageSources/FontImageSourceService/FontImageSourceService.Tizen.cs create mode 100644 src/Core/src/ImageSources/StreamImageSourceService/StreamImageSourceService.Tizen.cs create mode 100644 src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.Tizen.cs create mode 100644 src/Core/src/LifecycleEvents/Tizen/ITizenLifecycleBuilder.cs create mode 100644 src/Core/src/LifecycleEvents/Tizen/TizenLifecycle.cs create mode 100644 src/Core/src/LifecycleEvents/Tizen/TizenLifecycleBuilderExtensions.cs create mode 100644 src/Core/src/LifecycleEvents/Tizen/TizenLifecycleExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ActivityIndicatorExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/AspectExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/BorderView.cs create mode 100644 src/Core/src/Platform/Tizen/ButtonExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/CheckBoxExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ColorExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ContainerView.cs create mode 100644 src/Core/src/Platform/Tizen/ContentCanvas.cs create mode 100644 src/Core/src/Platform/Tizen/CoreAppExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/DPExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/DatePickerExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/EditorExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ElementExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/EntryExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/FlowDirectionExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/GraphicsExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/GraphicsViewExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/IWrapperViewDrawables.cs create mode 100644 src/Core/src/Platform/Tizen/ImageExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ImageSourcePartExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/KeyboardExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/LabelExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/LayoutCanvas.cs create mode 100644 src/Core/src/Platform/Tizen/LayoutCanvasExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/MauiApplication.cs create mode 100644 src/Core/src/Platform/Tizen/MauiBoxView.cs create mode 100644 src/Core/src/Platform/Tizen/MauiContextExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/MauiImageButton.cs create mode 100644 src/Core/src/Platform/Tizen/MauiIndicatorViewExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/MauiRadioButton.cs create mode 100644 src/Core/src/Platform/Tizen/MauiShapeView.cs create mode 100644 src/Core/src/Platform/Tizen/MauiWebView.cs create mode 100644 src/Core/src/Platform/Tizen/ModalStack.cs create mode 100644 src/Core/src/Platform/Tizen/PickerExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/PlatformTouchGraphicsView.cs create mode 100644 src/Core/src/Platform/Tizen/ProgressBarExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/RadioButtonExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ScrollViewExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/SearchBarExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ShapeViewExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/SliderExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/StepperExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/StrokeExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/SwitchExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/TimePickerExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/TransformationExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/ViewExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/WebViewExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/WindowExtensions.cs create mode 100644 src/Core/src/Platform/Tizen/WrapperView.cs create mode 100644 src/Core/src/Platform/Tizen/WrapperViewDrawables.cs create mode 100644 src/Core/src/VisualDiagnostics/VisualDiagnosticsOverlay.Tizen.cs create mode 100644 src/Core/src/WindowOverlay/WindowOverlay.Tizen.cs delete mode 100644 src/Essentials/samples/Samples/Platforms/Tizen/CustomViewCellRenderer.cs rename src/Essentials/src/Screenshot/{Screenshot.netstandard.tizen.watchos.macos.cs => Screenshot.netstandard.watchos.macos.cs} (100%) create mode 100644 src/Essentials/src/Screenshot/Screenshot.tizen.cs rename src/Essentials/src/SemanticScreenReader/{SemanticScreenReader.netstandard.tvos.watchos.macos.tizen.cs => SemanticScreenReader.netstandard.tvos.watchos.macos.cs} (100%) create mode 100644 src/Essentials/src/SemanticScreenReader/SemanticScreenReader.tizen.cs create mode 100644 src/SingleProject/Resizetizer/src/TizenIconManifestUpdater.cs create mode 100644 src/SingleProject/Resizetizer/src/TizenResourceXmlGenerator.cs create mode 100644 src/SingleProject/Resizetizer/src/TizenSplashUpdater.cs create mode 100644 src/Templates/src/templates/maui-blazor/Platforms/Tizen/Main.cs create mode 100644 src/Templates/src/templates/maui-blazor/Platforms/Tizen/tizen-manifest.xml create mode 100644 src/Templates/src/templates/maui-lib/Platforms/Tizen/PlatformClass1.cs create mode 100644 src/Templates/src/templates/maui-mobile/Platforms/Tizen/Main.cs create mode 100644 src/Templates/src/templates/maui-mobile/Platforms/Tizen/tizen-manifest.xml diff --git a/.nuspec/Microsoft.Maui.Controls.MultiTargeting.targets b/.nuspec/Microsoft.Maui.Controls.MultiTargeting.targets index b077c57f7e..a9b30bac85 100644 --- a/.nuspec/Microsoft.Maui.Controls.MultiTargeting.targets +++ b/.nuspec/Microsoft.Maui.Controls.MultiTargeting.targets @@ -59,6 +59,12 @@ + + + + + + @@ -99,6 +105,11 @@ $(DefineConstants);MACCATALYST;IOS + + + $(DefineConstants);TIZEN + + @@ -120,4 +131,8 @@ + + + + diff --git a/.nuspec/Microsoft.Maui.Controls.SingleProject.props b/.nuspec/Microsoft.Maui.Controls.SingleProject.props index 52df01095c..2e565e39a9 100644 --- a/.nuspec/Microsoft.Maui.Controls.SingleProject.props +++ b/.nuspec/Microsoft.Maui.Controls.SingleProject.props @@ -16,4 +16,10 @@ <_MauiUsingDefaultRuntimeIdentifier>true + + + + + + diff --git a/.nuspec/Microsoft.Maui.Controls.SingleProject.targets b/.nuspec/Microsoft.Maui.Controls.SingleProject.targets index 9f2e22d371..484bfb0e70 100644 --- a/.nuspec/Microsoft.Maui.Controls.SingleProject.targets +++ b/.nuspec/Microsoft.Maui.Controls.SingleProject.targets @@ -22,6 +22,10 @@ false $(PlatformsProjectFolder)Windows\ $([MSBuild]::EnsureTrailingSlash('$(WindowsProjectFolder)')) + + false + $(PlatformsProjectFolder)Tizen\ + $([MSBuild]::EnsureTrailingSlash('$(TizenProjectFolder)')) @@ -29,6 +33,7 @@ + @@ -57,6 +62,12 @@ <_SingleProjectWindowsExcludes>$(WindowsProjectFolder)/**/.*/** + + $(TizenProjectFolder)tizen-manifest.xml + $(TizenProjectFolder)res + $(TizenProjectFolder)shared + + <_MauiXamlToRemove @@ -127,4 +141,4 @@ - \ No newline at end of file + diff --git a/.nuspec/Microsoft.Maui.Resizetizer.targets b/.nuspec/Microsoft.Maui.Resizetizer.targets index 6759cc6719..79c5eaf17a 100644 --- a/.nuspec/Microsoft.Maui.Resizetizer.targets +++ b/.nuspec/Microsoft.Maui.Resizetizer.targets @@ -33,6 +33,10 @@ AssemblyFile="$(_ResizetizerTaskAssemblyName)" TaskName="Microsoft.Maui.Resizetizer.GenerateSplashStoryboard" /> + + @@ -76,6 +80,7 @@ <_ResizetizerPlatformIsmacOS Condition="'$(_ResizetizerPlatformIdentifier)' == 'macos'">True <_ResizetizerPlatformIstvOS Condition="'$(_ResizetizerPlatformIdentifier)' == 'tvos'">True <_ResizetizerPlatformIsWindows Condition="$(_ResizetizerPlatformIdentifier.Contains('windows')) == 'True'">True + <_ResizetizerPlatformIsTizen Condition="'$(_ResizetizerPlatformIdentifier)' == 'tizen'">True False @@ -90,9 +95,10 @@ <_ResizetizerIsiOSApp Condition="( '$(_ResizetizerPlatformIsiOS)' == 'True' OR '$(_ResizetizerPlatformIsMacCatalyst)' == 'True' ) And ('$(OutputType)' == 'Exe' Or '$(IsAppExtension)' == 'True')">True <_ResizetizerIsWPFApp Condition="'$(IsApplication)' == 'True' And '$(NuGetRuntimeIdentifier)' == 'win' And '$(_ResizetizerPlatformIsWindows)' == 'True'">True <_ResizetizerIsWindowsAppSdk Condition="('$(ProjectReunionWinUI)'=='True' Or '$(WindowsAppSDKWinUI)'=='True') And '$(_ResizetizerPlatformIsWindows)' == 'True' And ('$(OutputType)' == 'WinExe' Or '$(OutputType)' == 'Exe')">True + <_ResizetizerIsTizenApp Condition="'$(_ResizetizerPlatformIsTizen)' == 'True'">True - + <_ResizetizerIsCompatibleApp>True @@ -190,10 +196,29 @@ + + + tizen + + + $(ResizetizeBeforeTargets); + PrepareResources; + + + + $(ResizetizeAfterTargets); + ResizetizeCollectItems; + + + + $(ProcessMauiFontsAfterTargets); + ResizetizeCollectItems; + + + - @@ -295,6 +320,12 @@ + + <_MauiAssetItemMetadata>TizenTpkFileName + + + + + @@ -348,7 +380,7 @@ <_MauiSplashAssets Include="$(_MauiIntermediateSplashScreen)**\*" /> @@ -358,6 +390,11 @@ + + + + + @@ -437,6 +474,11 @@ + + + + + @@ -479,6 +521,13 @@ Images="@(MauiImage->Distinct())"> + + + @@ -548,6 +597,20 @@ + + + $([System.IO.Path]::GetFullPath('$(_MauiIntermediateImages)')) + + + + + + + $([MSBuild]::MakeRelative($(ResizetizerIntermediateOutputAbsolutePath), $([System.IO.Path]::GetFullPath('%(_ResizetizerCollectedImages.RelativeDir)')))) + + + + @@ -602,4 +665,4 @@ - \ No newline at end of file + diff --git a/Directory.Build.props b/Directory.Build.props index 55301d5489..42d747e774 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,8 +12,12 @@ <_MauiTargetPlatformIsmacOS Condition="'$(_MauiTargetPlatformIdentifier)' == 'macos'">True <_MauiTargetPlatformIstvOS Condition="'$(_MauiTargetPlatformIdentifier)' == 'tvos'">True <_MauiTargetPlatformIsWindows Condition="$(_MauiTargetPlatformIdentifier.Contains('windows')) == 'True'">True + <_MauiTargetPlatformIsTizen Condition="'$(_MauiTargetPlatformIdentifier)' == 'tizen'">True true + true @@ -34,6 +38,7 @@ 30.0 10.0.19041 10.0.20348 + 6.5 @@ -41,6 +46,7 @@ net$(_MauiDotNetVersion)-ios;net$(_MauiDotNetVersion)-maccatalyst;net$(_MauiDotNetVersion)-android net$(_MauiDotNetVersion)-windows$(WindowsTargetFrameworkVersion);net$(_MauiDotNetVersion)-windows$(Windows2TargetFrameworkVersion) $(MauiPlatforms);$(WindowsMauiPlatforms) + $(MauiPlatforms);net$(_MauiDotNetVersion)-tizen net$(_MauiDotNetVersion)-ios;net$(_MauiDotNetVersion)-android diff --git a/Directory.Build.targets b/Directory.Build.targets index e1c4eda5c7..dc0e3527e7 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -33,6 +33,10 @@ 21.0 21.0 + + 6.5 + 6.5 + 6.0.4 $(MicrosoftNETWorkloadEmscriptenManifest60300PackageVersion) @@ -49,6 +50,7 @@ 1.0.0-prerelease.22211.4 1.0.0-prerelease.22211.4 1.0.0-prerelease.22211.4 + 0.6.0-pre1 @@ -60,5 +62,6 @@ $(DotNetVersionBand) $(DotNetVersionBand) $(DotNetVersionBand) + $(DotNetVersionBand) diff --git a/eng/pipelines/common/provision.yml b/eng/pipelines/common/provision.yml index 6fc8f5948b..937ae99787 100644 --- a/eng/pipelines/common/provision.yml +++ b/eng/pipelines/common/provision.yml @@ -107,6 +107,14 @@ steps: displayName: 'Setup MSBuild Paths' condition: eq(variables['provisioningVS'], 'true') + - pwsh: | + [xml] $fileXml = Get-Content "eng\Versions.props" + $DotNetVersionBand = $fileXml.SelectSingleNode("Project/PropertyGroup/DotNetVersionBand").InnerText + echo "Installing .NET $DotNetVersion" + Invoke-WebRequest 'https://raw.githubusercontent.com/Samsung/Tizen.NET/main/workload/scripts/workload-install.ps1' -OutFile 'workload-install.ps1' + .\workload-install.ps1 -t $DotNetVersion + displayName: 'Install Tizen' + # Prepare Both - pwsh: ./build.ps1 --target provision displayName: 'Cake Provision' diff --git a/src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Shipped.txt b/src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..ab058de62d --- /dev/null +++ b/src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Unshipped.txt b/src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..21bd2d4a2a --- /dev/null +++ b/src/BlazorWebView/src/Maui/PublicAPI/net6.0-tizen/PublicAPI.Unshipped.txt @@ -0,0 +1,63 @@ +#nullable enable +Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializedEventArgs +Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializedEventArgs.BlazorWebViewInitializedEventArgs() -> void +Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializingEventArgs +Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializingEventArgs.BlazorWebViewInitializingEventArgs() -> void +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.BlazorWebView() -> void +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.BlazorWebViewInitialized -> System.EventHandler? +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.BlazorWebViewInitializing -> System.EventHandler? +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.HostPage.get -> string? +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.HostPage.set -> void +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.RootComponents.get -> Microsoft.AspNetCore.Components.WebView.Maui.RootComponentsCollection! +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.UrlLoading -> System.EventHandler? +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.BlazorWebViewHandler() -> void +Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.BlazorWebViewHandler(Microsoft.Maui.PropertyMapper? mapper) -> void +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.BlazorWebViewInitialized(Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializedEventArgs! args) -> void +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.BlazorWebViewInitializing(Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializingEventArgs! args) -> void +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.CreateFileProvider(string! contentRootDir) -> Microsoft.Extensions.FileProviders.IFileProvider! +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.HostPage.get -> string? +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.JSComponents.get -> Microsoft.AspNetCore.Components.Web.JSComponentConfigurationStore! +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.RootComponents.get -> Microsoft.AspNetCore.Components.WebView.Maui.RootComponentsCollection! +Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView.UrlLoading(Microsoft.AspNetCore.Components.WebView.UrlLoadingEventArgs! args) -> void +Microsoft.AspNetCore.Components.WebView.Maui.IMauiBlazorWebViewBuilder +Microsoft.AspNetCore.Components.WebView.Maui.IMauiBlazorWebViewBuilder.Services.get -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent.ComponentType.get -> System.Type? +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent.ComponentType.set -> void +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent.Parameters.get -> System.Collections.Generic.IDictionary? +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent.Parameters.set -> void +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent.RootComponent() -> void +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent.Selector.get -> string? +Microsoft.AspNetCore.Components.WebView.Maui.RootComponent.Selector.set -> void +Microsoft.AspNetCore.Components.WebView.Maui.RootComponentsCollection +Microsoft.AspNetCore.Components.WebView.Maui.RootComponentsCollection.JSComponents.get -> Microsoft.AspNetCore.Components.Web.JSComponentConfigurationStore! +Microsoft.AspNetCore.Components.WebView.Maui.RootComponentsCollection.RootComponentsCollection(Microsoft.AspNetCore.Components.Web.JSComponentConfigurationStore! jsComponents) -> void +Microsoft.AspNetCore.Components.WebView.Maui.TizenWebViewManager +Microsoft.AspNetCore.Components.WebView.Maui.TizenWebViewManager.TizenWebViewManager(Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler! blazorMauiWebViewHandler, Tizen.WebView.WebView! webview, System.IServiceProvider! provider, Microsoft.AspNetCore.Components.Dispatcher! dispatcher, Microsoft.Extensions.FileProviders.IFileProvider! fileProvider, Microsoft.AspNetCore.Components.Web.JSComponentConfigurationStore! jsComponents, string! contentRootRelativeToAppRoot, string! hostPageRelativePath) -> void +override Microsoft.AspNetCore.Components.WebView.Maui.TizenWebViewManager.NavigateCore(System.Uri! absoluteUri) -> void +override Microsoft.AspNetCore.Components.WebView.Maui.TizenWebViewManager.SendMessage(string! message) -> void +Microsoft.AspNetCore.Components.WebView.Maui.WebViewContainer +Microsoft.AspNetCore.Components.WebView.Maui.WebViewContainer.WebViewContainer(ElmSharp.EvasObject! parent) -> void +Microsoft.AspNetCore.Components.WebView.Maui.WebViewContainer.WebView.get -> Tizen.WebView.WebView! +Microsoft.AspNetCore.Components.WebView.UrlLoadingEventArgs +Microsoft.AspNetCore.Components.WebView.UrlLoadingEventArgs.Url.get -> System.Uri! +Microsoft.AspNetCore.Components.WebView.UrlLoadingEventArgs.UrlLoadingStrategy.get -> Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy +Microsoft.AspNetCore.Components.WebView.UrlLoadingEventArgs.UrlLoadingStrategy.set -> void +Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy +Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy.CancelLoad = 2 -> Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy +Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy.OpenExternally = 0 -> Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy +Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy.OpenInWebView = 1 -> Microsoft.AspNetCore.Components.WebView.UrlLoadingStrategy +Microsoft.Extensions.DependencyInjection.BlazorWebViewServiceCollectionExtensions +override Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.CreatePlatformView() -> Microsoft.AspNetCore.Components.WebView.Maui.WebViewContainer! +override Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.ConnectHandler(Microsoft.AspNetCore.Components.WebView.Maui.WebViewContainer! platformView) -> void +override Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.DisconnectHandler(Microsoft.AspNetCore.Components.WebView.Maui.WebViewContainer! platformView) -> void +static Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.MapHostPage(Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler! handler, Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView! webView) -> void +static Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.MapRootComponents(Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler! handler, Microsoft.AspNetCore.Components.WebView.Maui.IBlazorWebView! webView) -> void +static Microsoft.Extensions.DependencyInjection.BlazorWebViewServiceCollectionExtensions.AddBlazorWebViewDeveloperTools(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.BlazorWebViewServiceCollectionExtensions.AddMauiBlazorWebView(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.AspNetCore.Components.WebView.Maui.IMauiBlazorWebViewBuilder! +static Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebViewHandler.BlazorWebViewMapper -> Microsoft.Maui.PropertyMapper! +virtual Microsoft.AspNetCore.Components.WebView.Maui.BlazorWebView.CreateFileProvider(string! contentRootDir) -> Microsoft.Extensions.FileProviders.IFileProvider! +~Microsoft.AspNetCore.Components.WebView.BlazorWebViewInitializedEventArgs.WebView.get -> Tizen.WebView.WebView diff --git a/src/BlazorWebView/src/Maui/Tizen/BlazorWebViewHandler.Tizen.cs b/src/BlazorWebView/src/Maui/Tizen/BlazorWebViewHandler.Tizen.cs new file mode 100644 index 0000000000..8e5f94930a --- /dev/null +++ b/src/BlazorWebView/src/Maui/Tizen/BlazorWebViewHandler.Tizen.cs @@ -0,0 +1,192 @@ +using System; +using System.IO; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; +using Microsoft.Maui; +using Microsoft.Maui.Dispatching; +using Microsoft.Maui.Handlers; +using Tizen.WebView; +using TChromium = Tizen.WebView.Chromium; +using TWebView = Tizen.WebView.WebView; + +namespace Microsoft.AspNetCore.Components.WebView.Maui +{ + /// + /// The Tizen for . + /// + public partial class BlazorWebViewHandler : ViewHandler + { + private const string AppOrigin = "http://0.0.0.0/"; + private const string BlazorInitScript = @" + window.__receiveMessageCallbacks = []; + window.__dispatchMessageCallback = function(message) { + window.__receiveMessageCallbacks.forEach(function(callback) { callback(message); }); + }; + window.external = { + sendMessage: function(message) { + window.BlazorHandler.postMessage(message); + }, + receiveMessage: function(callback) { + window.__receiveMessageCallbacks.push(callback); + } + }; + + Blazor.start(); + + (function () { + window.onpageshow = function(event) { + if (event.persisted) { + window.location.reload(); + } + }; + })(); + "; + + private TizenWebViewManager? _webviewManager; + private WebViewExtensions.InterceptRequestCallback? _interceptRequestCallback; + + private TWebView NativeWebView => PlatformView.WebView; + + private bool RequiredStartupPropertiesSet => + //_webview != null && + HostPage != null && + Services != null; + + /// + protected override WebViewContainer CreatePlatformView() + { + TChromium.Initialize(); + MauiApplication.Current.Terminated += (s, e) => TChromium.Shutdown(); + + return new WebViewContainer(NativeParent!); + } + + /// + protected override void ConnectHandler(WebViewContainer platformView) + { + _interceptRequestCallback = OnRequestInterceptCallback; + NativeWebView.LoadFinished += OnLoadFinished; + NativeWebView.AddJavaScriptMessageHandler("BlazorHandler", PostMessageFromJS); + NativeWebView.SetInterceptRequestCallback(_interceptRequestCallback); + NativeWebView.GetSettings().JavaScriptEnabled = true; + } + + /// + protected override void DisconnectHandler(WebViewContainer platformView) + { + NativeWebView.LoadFinished -= OnLoadFinished; + base.DisconnectHandler(platformView); + } + + private void PostMessageFromJS(JavaScriptMessage message) + { + if (message is null) + { + throw new ArgumentNullException(nameof(message)); + } + + if (message.Name.Equals("BlazorHandler", StringComparison.Ordinal)) + { + _webviewManager!.MessageReceivedInternal(new Uri(NativeWebView.Url), message.GetBodyAsString()); + } + } + + private void StartWebViewCoreIfPossible() + { + if (!RequiredStartupPropertiesSet || + _webviewManager != null) + { + return; + } + if (PlatformView == null) + { + throw new InvalidOperationException($"Can't start {nameof(BlazorWebView)} without platform web view instance."); + } + + // We assume the host page is always in the root of the content directory, because it's + // unclear there's any other use case. We can add more options later if so. + var contentRootDir = Path.GetDirectoryName(HostPage!) ?? string.Empty; + var hostPageRelativePath = Path.GetRelativePath(contentRootDir, HostPage!); + + var fileProvider = VirtualView.CreateFileProvider(contentRootDir); + + _webviewManager = new TizenWebViewManager( + this, + NativeWebView, + Services!, + new MauiDispatcher(Services!.GetRequiredService()), + fileProvider, + VirtualView.JSComponents, + contentRootDir, + hostPageRelativePath); + + StaticContentHotReloadManager.AttachToWebViewManagerIfEnabled(_webviewManager); + + VirtualView.BlazorWebViewInitializing(new BlazorWebViewInitializingEventArgs()); + VirtualView.BlazorWebViewInitialized(new BlazorWebViewInitializedEventArgs + { + WebView = NativeWebView, + }); + + if (RootComponents != null) + { + foreach (var rootComponent in RootComponents) + { + // Since the page isn't loaded yet, this will always complete synchronously + _ = rootComponent.AddToWebViewManagerAsync(_webviewManager); + } + } + _webviewManager.Navigate("/"); + } + + private void OnRequestInterceptCallback(IntPtr context, IntPtr request, IntPtr userdata) + { + if (request == IntPtr.Zero) + { + return; + } + + var url = NativeWebView.GetInterceptRequestUrl(request); + + if (url.StartsWith(AppOrigin)) + { + var allowFallbackOnHostPage = url.EndsWith("/"); + url = QueryStringHelper.RemovePossibleQueryString(url); + if (_webviewManager!.TryGetResponseContentInternal(url, allowFallbackOnHostPage, out var statusCode, out var statusMessage, out var content, out var headers)) + { + var header = $"HTTP/1.0 200 OK\r\n"; + foreach (var item in headers) + { + header += $"{item.Key}:{item.Value}\r\n"; + } + header += "\r\n"; + + using (MemoryStream memstream = new MemoryStream()) + { + content.CopyTo(memstream); + var body = memstream.ToArray(); + NativeWebView.SetInterceptRequestResponse(request, header, body, (uint)body.Length); + } + return; + } + } + + NativeWebView.IgnoreInterceptRequest(request); + } + + private void OnLoadFinished(object? sender, EventArgs e) + { + NativeWebView.SetFocus(true); + var url = NativeWebView.Url; + + if (url == AppOrigin) + NativeWebView.Eval(BlazorInitScript); + } + + internal IFileProvider CreateFileProvider(string contentRootDir) + { + return new TizenMauiAssetFileProvider(contentRootDir); + } + + } +} diff --git a/src/BlazorWebView/src/Maui/Tizen/TizenMauiAssetFileProvider.cs b/src/BlazorWebView/src/Maui/Tizen/TizenMauiAssetFileProvider.cs new file mode 100644 index 0000000000..dd5824fa32 --- /dev/null +++ b/src/BlazorWebView/src/Maui/Tizen/TizenMauiAssetFileProvider.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Primitives; +using Tizen.Applications; + +namespace Microsoft.AspNetCore.Components.WebView.Maui +{ + /// + /// A minimal implementation of an IFileProvider to be used by the BlazorWebView and WebViewManager types. + /// + internal sealed class TizenMauiAssetFileProvider : IFileProvider + { + private readonly string _resDir; + + public TizenMauiAssetFileProvider(string contentRootDir) + { + _resDir = Path.Combine(Application.Current.DirectoryInfo.Resource, contentRootDir); + } + + public IDirectoryContents GetDirectoryContents(string subpath) + => new TizenMauiAssetDirectoryContents(Path.Combine(_resDir, subpath)); + + public IFileInfo GetFileInfo(string subpath) + => new TizenMauiAssetFileInfo(Path.Combine(_resDir, subpath)); + + public IChangeToken? Watch(string filter) + => null; + + private sealed class TizenMauiAssetFileInfo : IFileInfo + { + private readonly string _filePath; + + public TizenMauiAssetFileInfo(string filePath) + { + _filePath = filePath; + + Name = Path.GetFileName(_filePath); + + var fileInfo = new FileInfo(_filePath); + Exists = fileInfo.Exists; + Length = Exists ? fileInfo.Length : -1; + } + + public bool Exists { get; } + public long Length { get; } + public string PhysicalPath { get; } = null!; + public string Name { get; } + public DateTimeOffset LastModified { get; } = DateTimeOffset.FromUnixTimeSeconds(0); + public bool IsDirectory => false; + + public Stream CreateReadStream() + => File.OpenRead(_filePath); + } + + // This is never used by BlazorWebView or WebViewManager + private sealed class TizenMauiAssetDirectoryContents : IDirectoryContents + { + public TizenMauiAssetDirectoryContents(string filePath) + { + } + + public bool Exists => false; + + public IEnumerator GetEnumerator() + => throw new NotImplementedException(); + + IEnumerator IEnumerable.GetEnumerator() + => throw new NotImplementedException(); + } + } +} diff --git a/src/BlazorWebView/src/Maui/Tizen/TizenWebViewManager.cs b/src/BlazorWebView/src/Maui/Tizen/TizenWebViewManager.cs new file mode 100644 index 0000000000..967fe158ca --- /dev/null +++ b/src/BlazorWebView/src/Maui/Tizen/TizenWebViewManager.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.Extensions.FileProviders; +using TWebView = Tizen.WebView.WebView; + +namespace Microsoft.AspNetCore.Components.WebView.Maui +{ + /// + /// An implementation of that uses the Tizen WebView browser control + /// to render web content. + /// + public class TizenWebViewManager : WebViewManager + { + private const string AppOrigin = "http://0.0.0.0/"; + + private readonly BlazorWebViewHandler _blazorMauiWebViewHandler; + private readonly TWebView _webview; + private readonly string _contentRootRelativeToAppRoot; + + /// + /// Initializes a new instance of + /// + /// The . + /// A wrapper to access platform-specific WebView APIs. + /// The for the application. + /// A instance instance that can marshal calls to the required thread or sync context. + /// Provides static content to the webview. + /// Describes configuration for adding, removing, and updating root components from JavaScript code. + /// Path to the directory containing application content files. + /// Path to the host page within the fileProvider. + public TizenWebViewManager(BlazorWebViewHandler blazorMauiWebViewHandler, TWebView webview, IServiceProvider provider, Dispatcher dispatcher, IFileProvider fileProvider, JSComponentConfigurationStore jsComponents, string contentRootRelativeToAppRoot, string hostPageRelativePath) + : base(provider, dispatcher, new Uri(AppOrigin), fileProvider, jsComponents, hostPageRelativePath) + { + _blazorMauiWebViewHandler = blazorMauiWebViewHandler ?? throw new ArgumentNullException(nameof(blazorMauiWebViewHandler)); + _webview = webview ?? throw new ArgumentNullException(nameof(webview)); + _contentRootRelativeToAppRoot = contentRootRelativeToAppRoot; + + } + + internal bool TryGetResponseContentInternal(string uri, bool allowFallbackOnHostPage, out int statusCode, out string statusMessage, out Stream content, out IDictionary headers) + { + var defaultResult = TryGetResponseContent(uri, allowFallbackOnHostPage, out statusCode, out statusMessage, out content, out headers); + var hotReloadedResult = StaticContentHotReloadManager.TryReplaceResponseContent(_contentRootRelativeToAppRoot, uri, ref statusCode, ref content, headers); + return defaultResult || hotReloadedResult; + } + + + /// + protected override void NavigateCore(Uri absoluteUri) + { + _webview.LoadUrl(absoluteUri.ToString()); + } + + /// + protected override void SendMessage(string message) + { + var messageJSStringLiteral = JavaScriptEncoder.Default.Encode(message); + _webview.Eval($"__dispatchMessageCallback(\"{messageJSStringLiteral}\")"); + } + + internal void MessageReceivedInternal(Uri uri, string message) + { + MessageReceived(uri, message); + } + } +} diff --git a/src/BlazorWebView/src/Maui/Tizen/WebViewContainer.cs b/src/BlazorWebView/src/Maui/Tizen/WebViewContainer.cs new file mode 100644 index 0000000000..52b3a3423f --- /dev/null +++ b/src/BlazorWebView/src/Maui/Tizen/WebViewContainer.cs @@ -0,0 +1,42 @@ +using System; +using Tizen.UIExtensions.ElmSharp; +using ElmSharp; +using TWebView = Tizen.WebView.WebView; + +namespace Microsoft.AspNetCore.Components.WebView.Maui +{ + /// + /// A Tizen WebView browser control container. + /// + public class WebViewContainer : WidgetLayout + { + + /// + /// A Tizen WebView. + /// + public TWebView WebView { get; } + + /// + /// Initializes a new instance of + /// + /// The . + public WebViewContainer(EvasObject parent) : base(parent) + { + WebView = new TWebView(parent); + SetContent(WebView); + AllowFocus(true); + Focused += OnFocused; + Unfocused += OnUnfocused; + } + + void OnFocused(object? sender, EventArgs e) + { + WebView.SetFocus(true); + } + + void OnUnfocused(object? sender, EventArgs e) + { + WebView.SetFocus(false); + } + } +} diff --git a/src/BlazorWebView/src/Maui/Tizen/WebViewExtensions.cs b/src/BlazorWebView/src/Maui/Tizen/WebViewExtensions.cs new file mode 100644 index 0000000000..4150989f10 --- /dev/null +++ b/src/BlazorWebView/src/Maui/Tizen/WebViewExtensions.cs @@ -0,0 +1,79 @@ +using System; +using System.Runtime.InteropServices; +using TWebView = Tizen.WebView.WebView; + +namespace Microsoft.AspNetCore.Components.WebView.Maui +{ + /// + /// WebViewExtension + /// + internal static class WebViewExtensions + { + public const string ChromiumEwk = "libchromium-ewk.so"; + + public static void SetInterceptRequestCallback(this TWebView webView, InterceptRequestCallback callback) + { + var context = webView.GetContext(); + var handleField = context.GetType().GetField("_handle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + var contextHandle = (IntPtr?)handleField?.GetValue(context); + if (contextHandle != null) + ewk_context_intercept_request_callback_set(contextHandle.Value, callback, IntPtr.Zero); + } + + public static void SetInspectorStart(this TWebView webView, uint port) + { + var context = webView.GetContext(); + var handleField = context.GetType().GetField("_handle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + var contextHandle = (IntPtr?)handleField?.GetValue(context); + if (contextHandle != null) + ewk_context_inspector_server_start(contextHandle.Value, port); + } + + public static bool SetInterceptRequestResponse(this TWebView webView, IntPtr request, string header, byte[] body, uint length) + { + return ewk_intercept_request_response_set(request, header, body, length); + } + + public static bool IgnoreInterceptRequest(this TWebView webView, IntPtr request) + { + return ewk_intercept_request_ignore(request); + } + + public static string GetInterceptRequestUrl(this TWebView webView, IntPtr request) + { + return Marshal.PtrToStringAnsi(_ewk_intercept_request_url_get(request)) ?? string.Empty; + } + + [DllImport(ChromiumEwk)] + internal static extern IntPtr ewk_view_context_get(IntPtr obj); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void InterceptRequestCallback(IntPtr context, IntPtr request, IntPtr userData); + + [DllImport(ChromiumEwk)] + internal static extern void ewk_context_intercept_request_callback_set(IntPtr context, InterceptRequestCallback callback, IntPtr userData); + + [DllImport(ChromiumEwk, EntryPoint = "ewk_intercept_request_url_get")] + internal static extern IntPtr _ewk_intercept_request_url_get(IntPtr request); + + [DllImport(ChromiumEwk, EntryPoint = "ewk_intercept_request_http_method_get")] + internal static extern IntPtr _ewk_intercept_request_http_method_get(IntPtr request); + + internal static string ewk_intercept_request_http_method_get(IntPtr request) + { + return Marshal.PtrToStringAnsi(_ewk_intercept_request_http_method_get(request)) ?? string.Empty; + } + + [DllImport(ChromiumEwk)] + public static extern uint ewk_context_inspector_server_start(IntPtr context, uint port); + + [DllImport(ChromiumEwk)] + internal static extern bool ewk_intercept_request_ignore(IntPtr request); + + [DllImport(ChromiumEwk)] + internal static extern bool ewk_intercept_request_response_set(IntPtr request, string header, string body, uint length); + + [DllImport(ChromiumEwk)] + internal static extern bool ewk_intercept_request_response_set(IntPtr request, string header, byte[] body, uint length); + } +} diff --git a/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializedEventArgs.cs b/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializedEventArgs.cs index e8d124cac0..a7de76a6af 100644 --- a/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializedEventArgs.cs +++ b/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializedEventArgs.cs @@ -13,6 +13,8 @@ using WebView2Control = Microsoft.UI.Xaml.Controls.WebView2; using AWebView = Android.Webkit.WebView; #elif IOS || MACCATALYST using WebKit; +#elif TIZEN +using TWebView = Tizen.WebView.WebView; #endif namespace Microsoft.AspNetCore.Components.WebView @@ -39,6 +41,11 @@ namespace Microsoft.AspNetCore.Components.WebView /// the default values to allow further configuring additional options. /// public WKWebView WebView { get; internal set; } +#elif TIZEN + /// + /// Gets the instance that was initialized. + /// + public TWebView WebView { get; internal set; } #endif } } diff --git a/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializingEventArgs.cs b/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializingEventArgs.cs index dc11d075e8..f14ccd6564 100644 --- a/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializingEventArgs.cs +++ b/src/BlazorWebView/src/SharedSource/BlazorWebViewInitializingEventArgs.cs @@ -12,6 +12,8 @@ using WebView2Control = Microsoft.UI.Xaml.Controls.WebView2; using AWebView = Android.Webkit.WebView; #elif IOS || MACCATALYST using WebKit; +#elif TIZEN +using TWebView = Tizen.WebView.WebView; #endif namespace Microsoft.AspNetCore.Components.WebView diff --git a/src/Compatibility/ControlGallery/src/Core/Startup.cs b/src/Compatibility/ControlGallery/src/Core/Startup.cs index 2c0044972a..ffd97ef433 100644 --- a/src/Compatibility/ControlGallery/src/Core/Startup.cs +++ b/src/Compatibility/ControlGallery/src/Core/Startup.cs @@ -4,6 +4,7 @@ using Microsoft.Maui; using Microsoft.Maui.Controls.Compatibility; using Microsoft.Maui.Controls.Compatibility.Hosting; using Microsoft.Maui.Controls.Hosting; +using Microsoft.Maui.Devices; using Microsoft.Maui.Hosting; namespace Microsoft.Maui.Controls.Compatibility.ControlGallery @@ -41,6 +42,12 @@ namespace Microsoft.Maui.Controls.Compatibility.ControlGallery effects.AddCompatibilityEffects(AppDomain.CurrentDomain.GetAssemblies()); }); + if (DeviceInfo.Platform == DevicePlatform.Tizen) + { + //Some controls still need to use legacy renderers on Tizen. + builder.UseMauiCompatibility(); + } + DependencyService.Register(AppDomain.CurrentDomain.GetAssemblies()); return builder; diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/BorderEffect.cs b/src/Compatibility/ControlGallery/src/Tizen/BorderEffect.cs similarity index 69% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/BorderEffect.cs rename to src/Compatibility/ControlGallery/src/Tizen/BorderEffect.cs index 786ad812e7..66d95efcbd 100644 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/BorderEffect.cs +++ b/src/Compatibility/ControlGallery/src/Tizen/BorderEffect.cs @@ -1,12 +1,13 @@ using System.ComponentModel; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using Microsoft.Maui.Controls.Platform; using ElmSharp; -using Xamarin.Forms; -using Xamarin.Forms.ControlGallery.Tizen; -using Xamarin.Forms.Platform.Tizen; using EColor = ElmSharp.Color; [assembly: ExportEffect(typeof(BorderEffect), "BorderEffect")] -namespace Xamarin.Forms.ControlGallery.Tizen +namespace Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen { public class BorderEffect : PlatformEffect { diff --git a/src/Compatibility/ControlGallery/src/Tizen/Compatibility.ControlGallery.Tizen.csproj b/src/Compatibility/ControlGallery/src/Tizen/Compatibility.ControlGallery.Tizen.csproj new file mode 100644 index 0000000000..41ea8acb66 --- /dev/null +++ b/src/Compatibility/ControlGallery/src/Tizen/Compatibility.ControlGallery.Tizen.csproj @@ -0,0 +1,38 @@ + + + + $(_MauiDotNetTfm)-tizen + Exe + Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen + Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen + false + disable + + + 0612 + + + + + + + + + + + + + + + + + + + diff --git a/src/Compatibility/ControlGallery/src/Tizen/ControlGallery.Tizen.cs b/src/Compatibility/ControlGallery/src/Tizen/ControlGallery.Tizen.cs new file mode 100644 index 0000000000..c8c6b95594 --- /dev/null +++ b/src/Compatibility/ControlGallery/src/Tizen/ControlGallery.Tizen.cs @@ -0,0 +1,32 @@ +using ElmSharp; +using Tizen.Applications; +using Tizen.NET.MaterialComponents; +using Microsoft.Maui.Controls.Compatibility.ControlGallery; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Issues; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Handlers; +using Microsoft.Maui.Hosting; +using Microsoft.Maui.Platform; + +namespace Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen +{ + class MainApplication : MauiApplication + { + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + protected override void OnCreate() + { + base.OnCreate(); + MaterialComponents.Init(DirectoryInfo.Resource); + } + + static void Main(string[] args) + { + var app = new MainApplication(); + FormsMaps.Init("HERE", "write-your-API-key-here"); + //FormsMaterial.Init(); + app.Run(args); + } + } +} diff --git a/src/Compatibility/ControlGallery/src/Tizen/DisposeLabelRenderer.cs b/src/Compatibility/ControlGallery/src/Tizen/DisposeLabelRenderer.cs new file mode 100644 index 0000000000..a56b2ce2a2 --- /dev/null +++ b/src/Compatibility/ControlGallery/src/Tizen/DisposeLabelRenderer.cs @@ -0,0 +1,22 @@ +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Maui.Controls.Compatibility.ControlGallery; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; + +[assembly: ExportRenderer(typeof(DisposeLabel), typeof(DisposeLabelRenderer))] +namespace Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen +{ +#pragma warning disable CS0618 // Type or member is obsolete + public class DisposeLabelRenderer : LabelRenderer +#pragma warning disable CS0618 // Type or member is obsolete + { + protected override void Dispose(bool disposing) + { + if (disposing) + { + ((DisposeLabel)Element).SendRendererDisposed(); + } + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/src/Compatibility/ControlGallery/src/Tizen/DisposePageRenderer.cs b/src/Compatibility/ControlGallery/src/Tizen/DisposePageRenderer.cs new file mode 100644 index 0000000000..9067c3f1e6 --- /dev/null +++ b/src/Compatibility/ControlGallery/src/Tizen/DisposePageRenderer.cs @@ -0,0 +1,22 @@ +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Maui.Controls.Compatibility.ControlGallery; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; + +[assembly: ExportRenderer(typeof(DisposePage), typeof(DisposePageRenderer))] +namespace Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen +{ +#pragma warning disable CS0618 // Type or member is obsolete + public class DisposePageRenderer : PageRenderer +#pragma warning disable CS0618 // Type or member is obsolete + { + protected override void Dispose(bool disposing) + { + if (disposing) + { + ((DisposePage)Element).SendRendererDisposed(); + } + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/PlatformSpecificCoreGalleryFactory.cs b/src/Compatibility/ControlGallery/src/Tizen/PlatformSpecificCoreGalleryFactory.cs similarity index 57% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/PlatformSpecificCoreGalleryFactory.cs rename to src/Compatibility/ControlGallery/src/Tizen/PlatformSpecificCoreGalleryFactory.cs index 04d6275344..12a0d7aadd 100644 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/PlatformSpecificCoreGalleryFactory.cs +++ b/src/Compatibility/ControlGallery/src/Tizen/PlatformSpecificCoreGalleryFactory.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; -using Xamarin.Forms; -using Xamarin.Forms.ControlGallery.Tizen; -using Xamarin.Forms.Controls; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen; +using Microsoft.Maui.Controls.Internals; [assembly: Dependency(typeof(PlatformSpecificCoreGalleryFactory))] -namespace Xamarin.Forms.ControlGallery.Tizen +namespace Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen { public class PlatformSpecificCoreGalleryFactory : IPlatformSpecificCoreGalleryFactory { diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/RegistrarValidationService.cs b/src/Compatibility/ControlGallery/src/Tizen/RegistrarValidationService.cs similarity index 65% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/RegistrarValidationService.cs rename to src/Compatibility/ControlGallery/src/Tizen/RegistrarValidationService.cs index 57ae24f7e0..1d029d5eec 100644 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/RegistrarValidationService.cs +++ b/src/Compatibility/ControlGallery/src/Tizen/RegistrarValidationService.cs @@ -1,10 +1,11 @@ -using Xamarin.Forms; -using Xamarin.Forms.ControlGallery.Tizen; -using Xamarin.Forms.Controls; -using Xamarin.Forms.Platform.Tizen; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using Microsoft.Maui.Controls.Internals; [assembly: Dependency(typeof(RegistrarValidationService))] -namespace Xamarin.Forms.ControlGallery.Tizen +namespace Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen { public class RegistrarValidationService : IRegistrarValidationService { diff --git a/src/Compatibility/ControlGallery/src/Tizen/SampleNativeControl.cs b/src/Compatibility/ControlGallery/src/Tizen/SampleNativeControl.cs new file mode 100644 index 0000000000..e2c11508fa --- /dev/null +++ b/src/Compatibility/ControlGallery/src/Tizen/SampleNativeControl.cs @@ -0,0 +1,27 @@ +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen; +using Microsoft.Maui.Controls.Compatibility.ControlGallery.Issues.Helpers; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Platform; +using ELabel = ElmSharp.Label; + +[assembly: Dependency(typeof(SampleNativeControl))] +namespace Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen +{ + public class SampleNativeControl : ISampleNativeControl + { + public View View + { + get + { + var label = new ELabel(CoreAppExtensions.MainWindow) + { + Text = "Sample Native Control" + }; + return label.ToView(); + } + } + } +} \ No newline at end of file diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/FlowerBuds.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/FlowerBuds.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/FlowerBuds.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/FlowerBuds.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Fruits.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/Fruits.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Fruits.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/Fruits.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Icon-Small.png b/src/Compatibility/ControlGallery/src/Tizen/res/Icon-Small.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Icon-Small.png rename to src/Compatibility/ControlGallery/src/Tizen/res/Icon-Small.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Icon.png b/src/Compatibility/ControlGallery/src/Tizen/res/Icon.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Icon.png rename to src/Compatibility/ControlGallery/src/Tizen/res/Icon.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Intranet-icon.png b/src/Compatibility/ControlGallery/src/Tizen/res/Intranet-icon.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Intranet-icon.png rename to src/Compatibility/ControlGallery/src/Tizen/res/Intranet-icon.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Legumes.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/Legumes.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Legumes.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/Legumes.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Vegetables.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/Vegetables.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/Vegetables.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/Vegetables.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/about.png b/src/Compatibility/ControlGallery/src/Tizen/res/about.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/about.png rename to src/Compatibility/ControlGallery/src/Tizen/res/about.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/bank.png b/src/Compatibility/ControlGallery/src/Tizen/res/bank.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/bank.png rename to src/Compatibility/ControlGallery/src/Tizen/res/bank.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/bell.png b/src/Compatibility/ControlGallery/src/Tizen/res/bell.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/bell.png rename to src/Compatibility/ControlGallery/src/Tizen/res/bell.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/blog.png b/src/Compatibility/ControlGallery/src/Tizen/res/blog.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/blog.png rename to src/Compatibility/ControlGallery/src/Tizen/res/blog.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/books.png b/src/Compatibility/ControlGallery/src/Tizen/res/books.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/books.png rename to src/Compatibility/ControlGallery/src/Tizen/res/books.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/booksflyout.png b/src/Compatibility/ControlGallery/src/Tizen/res/booksflyout.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/booksflyout.png rename to src/Compatibility/ControlGallery/src/Tizen/res/booksflyout.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/calculator.png b/src/Compatibility/ControlGallery/src/Tizen/res/calculator.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/calculator.png rename to src/Compatibility/ControlGallery/src/Tizen/res/calculator.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/card.png b/src/Compatibility/ControlGallery/src/Tizen/res/card.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/card.png rename to src/Compatibility/ControlGallery/src/Tizen/res/card.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/caret_r.png b/src/Compatibility/ControlGallery/src/Tizen/res/caret_r.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/caret_r.png rename to src/Compatibility/ControlGallery/src/Tizen/res/caret_r.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/coffee.png b/src/Compatibility/ControlGallery/src/Tizen/res/coffee.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/coffee.png rename to src/Compatibility/ControlGallery/src/Tizen/res/coffee.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/cover1.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/cover1.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/cover1.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/cover1.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/cover1small.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/cover1small.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/cover1small.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/cover1small.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/crimson.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/crimson.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/crimson.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/crimson.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/crimsonsmall.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/crimsonsmall.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/crimsonsmall.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/crimsonsmall.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/facebook.png b/src/Compatibility/ControlGallery/src/Tizen/res/facebook.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/facebook.png rename to src/Compatibility/ControlGallery/src/Tizen/res/facebook.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/favorite.png b/src/Compatibility/ControlGallery/src/Tizen/res/favorite.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/favorite.png rename to src/Compatibility/ControlGallery/src/Tizen/res/favorite.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/film.png b/src/Compatibility/ControlGallery/src/Tizen/res/film.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/film.png rename to src/Compatibility/ControlGallery/src/Tizen/res/film.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/filmflyout.png b/src/Compatibility/ControlGallery/src/Tizen/res/filmflyout.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/filmflyout.png rename to src/Compatibility/ControlGallery/src/Tizen/res/filmflyout.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/games.png b/src/Compatibility/ControlGallery/src/Tizen/res/games.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/games.png rename to src/Compatibility/ControlGallery/src/Tizen/res/games.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/gamesflyout.png b/src/Compatibility/ControlGallery/src/Tizen/res/gamesflyout.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/gamesflyout.png rename to src/Compatibility/ControlGallery/src/Tizen/res/gamesflyout.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/googleplus.png b/src/Compatibility/ControlGallery/src/Tizen/res/googleplus.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/googleplus.png rename to src/Compatibility/ControlGallery/src/Tizen/res/googleplus.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/grid.png b/src/Compatibility/ControlGallery/src/Tizen/res/grid.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/grid.png rename to src/Compatibility/ControlGallery/src/Tizen/res/grid.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/headphone.png b/src/Compatibility/ControlGallery/src/Tizen/res/headphone.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/headphone.png rename to src/Compatibility/ControlGallery/src/Tizen/res/headphone.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/headphoneflyout.png b/src/Compatibility/ControlGallery/src/Tizen/res/headphoneflyout.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/headphoneflyout.png rename to src/Compatibility/ControlGallery/src/Tizen/res/headphoneflyout.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/hm.png b/src/Compatibility/ControlGallery/src/Tizen/res/hm.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/hm.png rename to src/Compatibility/ControlGallery/src/Tizen/res/hm.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/hm_full.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/hm_full.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/hm_full.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/hm_full.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/home.png b/src/Compatibility/ControlGallery/src/Tizen/res/home.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/home.png rename to src/Compatibility/ControlGallery/src/Tizen/res/home.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/homeflyout.png b/src/Compatibility/ControlGallery/src/Tizen/res/homeflyout.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/homeflyout.png rename to src/Compatibility/ControlGallery/src/Tizen/res/homeflyout.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_pause.png b/src/Compatibility/ControlGallery/src/Tizen/res/ic_pause.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_pause.png rename to src/Compatibility/ControlGallery/src/Tizen/res/ic_pause.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_play.png b/src/Compatibility/ControlGallery/src/Tizen/res/ic_play.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_play.png rename to src/Compatibility/ControlGallery/src/Tizen/res/ic_play.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_share.png b/src/Compatibility/ControlGallery/src/Tizen/res/ic_share.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_share.png rename to src/Compatibility/ControlGallery/src/Tizen/res/ic_share.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_stop.png b/src/Compatibility/ControlGallery/src/Tizen/res/ic_stop.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ic_stop.png rename to src/Compatibility/ControlGallery/src/Tizen/res/ic_stop.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/instagram.png b/src/Compatibility/ControlGallery/src/Tizen/res/instagram.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/instagram.png rename to src/Compatibility/ControlGallery/src/Tizen/res/instagram.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/invalidimage.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/invalidimage.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/invalidimage.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/invalidimage.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/jet.png b/src/Compatibility/ControlGallery/src/Tizen/res/jet.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/jet.png rename to src/Compatibility/ControlGallery/src/Tizen/res/jet.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/lists.png b/src/Compatibility/ControlGallery/src/Tizen/res/lists.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/lists.png rename to src/Compatibility/ControlGallery/src/Tizen/res/lists.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/loop.png b/src/Compatibility/ControlGallery/src/Tizen/res/loop.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/loop.png rename to src/Compatibility/ControlGallery/src/Tizen/res/loop.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/menuIcon.png b/src/Compatibility/ControlGallery/src/Tizen/res/menuIcon.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/menuIcon.png rename to src/Compatibility/ControlGallery/src/Tizen/res/menuIcon.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/messages.png b/src/Compatibility/ControlGallery/src/Tizen/res/messages.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/messages.png rename to src/Compatibility/ControlGallery/src/Tizen/res/messages.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/newspaper.png b/src/Compatibility/ControlGallery/src/Tizen/res/newspaper.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/newspaper.png rename to src/Compatibility/ControlGallery/src/Tizen/res/newspaper.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/newspaperflyout.png b/src/Compatibility/ControlGallery/src/Tizen/res/newspaperflyout.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/newspaperflyout.png rename to src/Compatibility/ControlGallery/src/Tizen/res/newspaperflyout.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/notifications.png b/src/Compatibility/ControlGallery/src/Tizen/res/notifications.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/notifications.png rename to src/Compatibility/ControlGallery/src/Tizen/res/notifications.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/oasis.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/oasis.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/oasis.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/oasis.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/oasissmall.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/oasissmall.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/oasissmall.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/oasissmall.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/person.png b/src/Compatibility/ControlGallery/src/Tizen/res/person.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/person.png rename to src/Compatibility/ControlGallery/src/Tizen/res/person.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/photo.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/photo.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/photo.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/photo.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/profile.png b/src/Compatibility/ControlGallery/src/Tizen/res/profile.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/profile.png rename to src/Compatibility/ControlGallery/src/Tizen/res/profile.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ratchet.png b/src/Compatibility/ControlGallery/src/Tizen/res/ratchet.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ratchet.png rename to src/Compatibility/ControlGallery/src/Tizen/res/ratchet.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ratchet_full.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/ratchet_full.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/ratchet_full.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/ratchet_full.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/refresh.png b/src/Compatibility/ControlGallery/src/Tizen/res/refresh.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/refresh.png rename to src/Compatibility/ControlGallery/src/Tizen/res/refresh.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/reply.png b/src/Compatibility/ControlGallery/src/Tizen/res/reply.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/reply.png rename to src/Compatibility/ControlGallery/src/Tizen/res/reply.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/retweet.png b/src/Compatibility/ControlGallery/src/Tizen/res/retweet.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/retweet.png rename to src/Compatibility/ControlGallery/src/Tizen/res/retweet.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/scott.png b/src/Compatibility/ControlGallery/src/Tizen/res/scott.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/scott.png rename to src/Compatibility/ControlGallery/src/Tizen/res/scott.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/scott159.png b/src/Compatibility/ControlGallery/src/Tizen/res/scott159.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/scott159.png rename to src/Compatibility/ControlGallery/src/Tizen/res/scott159.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/search.png b/src/Compatibility/ControlGallery/src/Tizen/res/search.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/search.png rename to src/Compatibility/ControlGallery/src/Tizen/res/search.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/seth.png b/src/Compatibility/ControlGallery/src/Tizen/res/seth.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/seth.png rename to src/Compatibility/ControlGallery/src/Tizen/res/seth.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/slideout.png b/src/Compatibility/ControlGallery/src/Tizen/res/slideout.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/slideout.png rename to src/Compatibility/ControlGallery/src/Tizen/res/slideout.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/star.png b/src/Compatibility/ControlGallery/src/Tizen/res/star.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/star.png rename to src/Compatibility/ControlGallery/src/Tizen/res/star.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/tdl.png b/src/Compatibility/ControlGallery/src/Tizen/res/tdl.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/tdl.png rename to src/Compatibility/ControlGallery/src/Tizen/res/tdl.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/tdl_full.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/tdl_full.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/tdl_full.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/tdl_full.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/test.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/test.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/test.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/test.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/toolbar_close.png b/src/Compatibility/ControlGallery/src/Tizen/res/toolbar_close.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/toolbar_close.png rename to src/Compatibility/ControlGallery/src/Tizen/res/toolbar_close.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/tweet.png b/src/Compatibility/ControlGallery/src/Tizen/res/tweet.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/tweet.png rename to src/Compatibility/ControlGallery/src/Tizen/res/tweet.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/twitter.png b/src/Compatibility/ControlGallery/src/Tizen/res/twitter.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/twitter.png rename to src/Compatibility/ControlGallery/src/Tizen/res/twitter.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/twitternav.png b/src/Compatibility/ControlGallery/src/Tizen/res/twitternav.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/twitternav.png rename to src/Compatibility/ControlGallery/src/Tizen/res/twitternav.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/xamarinlogo.png b/src/Compatibility/ControlGallery/src/Tizen/res/xamarinlogo.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/xamarinlogo.png rename to src/Compatibility/ControlGallery/src/Tizen/res/xamarinlogo.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/xamarinstore.jpg b/src/Compatibility/ControlGallery/src/Tizen/res/xamarinstore.jpg similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/res/xamarinstore.jpg rename to src/Compatibility/ControlGallery/src/Tizen/res/xamarinstore.jpg diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/shared/res/Xamarin.Forms.ControlGallery.Tizen.png b/src/Compatibility/ControlGallery/src/Tizen/shared/res/Compatibility.ControlGallery.Tizen.png similarity index 100% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/shared/res/Xamarin.Forms.ControlGallery.Tizen.png rename to src/Compatibility/ControlGallery/src/Tizen/shared/res/Compatibility.ControlGallery.Tizen.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/tizen-manifest.xml b/src/Compatibility/ControlGallery/src/Tizen/tizen-manifest.xml similarity index 53% rename from src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/tizen-manifest.xml rename to src/Compatibility/ControlGallery/src/Tizen/tizen-manifest.xml index 6305605b28..e655844d17 100644 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/tizen-manifest.xml +++ b/src/Compatibility/ControlGallery/src/Tizen/tizen-manifest.xml @@ -1,9 +1,9 @@  - + - - - Xamarin.Forms.ControlGallery.Tizen.png + + + Compatibility.ControlGallery.Tizen.png diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/ControlGallery.Tizen.cs b/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/ControlGallery.Tizen.cs deleted file mode 100644 index 5d29a47908..0000000000 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/ControlGallery.Tizen.cs +++ /dev/null @@ -1,31 +0,0 @@ -using ElmSharp; -using Tizen.Applications; -using Tizen.NET.MaterialComponents; -using Xamarin.Forms; -using Xamarin.Forms.Controls; -using Xamarin.Forms.Platform.Tizen; - -namespace Xamarin.Forms.ControlGallery.Tizen -{ - class MainApplication : FormsApplication - { - internal static EvasObject NativeParent { get; private set; } - protected override void OnCreate() - { - base.OnCreate(); - MaterialComponents.Init(DirectoryInfo.Resource); - NativeParent = MainWindow; - LoadApplication(new App()); - } - - static void Main(string[] args) - { - var app = new MainApplication(); - FormsMaps.Init("HERE", "write-your-API-key-here"); - Forms.SetFlags("CollectionView_Experimental", "Shell_Experimental"); - Forms.Init(app); - FormsMaterial.Init(); - app.Run(args); - } - } -} diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposeLabelRenderer.cs b/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposeLabelRenderer.cs deleted file mode 100644 index 27005a6701..0000000000 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposeLabelRenderer.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Xamarin.Forms; -using Xamarin.Forms.ControlGallery.Tizen; -using Xamarin.Forms.Controls; -using Xamarin.Forms.Platform.Tizen; - -[assembly: ExportRenderer(typeof(DisposeLabel), typeof(DisposeLabelRenderer))] -namespace Xamarin.Forms.ControlGallery.Tizen -{ - public class DisposeLabelRenderer : LabelRenderer - { - protected override void Dispose(bool disposing) - { - if (disposing) - { - ((DisposeLabel)Element).SendRendererDisposed(); - } - base.Dispose(disposing); - } - } -} \ No newline at end of file diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposePageRenderer.cs b/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposePageRenderer.cs deleted file mode 100644 index 942e3b9480..0000000000 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/DisposePageRenderer.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Xamarin.Forms; -using Xamarin.Forms.ControlGallery.Tizen; -using Xamarin.Forms.Controls; -using Xamarin.Forms.Platform.Tizen; - -[assembly: ExportRenderer(typeof(DisposePage), typeof(DisposePageRenderer))] -namespace Xamarin.Forms.ControlGallery.Tizen -{ - public class DisposePageRenderer : PageRenderer - { - protected override void Dispose(bool disposing) - { - if (disposing) - { - ((DisposePage)Element).SendRendererDisposed(); - } - base.Dispose(disposing); - } - } -} \ No newline at end of file diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/SampleNativeControl.cs b/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/SampleNativeControl.cs deleted file mode 100644 index 2d56a96fb8..0000000000 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/SampleNativeControl.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Xamarin.Forms; -using Xamarin.Forms.ControlGallery.Tizen; -using Xamarin.Forms.Controls.Issues.Helpers; -using Xamarin.Forms.Platform.Tizen; -using ELabel = ElmSharp.Label; - -[assembly: Dependency(typeof(SampleNativeControl))] -namespace Xamarin.Forms.ControlGallery.Tizen -{ - public class SampleNativeControl : ISampleNativeControl - { - public View View - { - get - { - var label = new ELabel(MainApplication.NativeParent) - { - Text = "Sample Native Control" - }; - return label.ToView(); - } - } - } -} \ No newline at end of file diff --git a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/Xamarin.Forms.ControlGallery.Tizen.csproj b/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/Xamarin.Forms.ControlGallery.Tizen.csproj deleted file mode 100644 index 2896ae684d..0000000000 --- a/src/Compatibility/ControlGallery/src/Xamarin.Forms.ControlGallery.Tizen/Xamarin.Forms.ControlGallery.Tizen.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - Exe - tizen40 - - - - - - - - - - - - - - - - - - diff --git a/src/Compatibility/Core/src/AppHostBuilderExtensions.Tizen.cs b/src/Compatibility/Core/src/AppHostBuilderExtensions.Tizen.cs new file mode 100644 index 0000000000..3142d9fcf9 --- /dev/null +++ b/src/Compatibility/Core/src/AppHostBuilderExtensions.Tizen.cs @@ -0,0 +1,55 @@ +using Microsoft.Maui.Hosting; +using Microsoft.Maui.LifecycleEvents; +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Extensions.DependencyInjection; +using TDeviceInfo = Tizen.UIExtensions.Common.DeviceInfo; + +namespace Microsoft.Maui.Controls.Compatibility.Hosting +{ + public static partial class AppHostBuilderExtensions + { + internal static MauiAppBuilder ConfigureCompatibilityLifecycleEvents(this MauiAppBuilder builder) => + builder.ConfigureLifecycleEvents(events => events.AddTizen(OnConfigureLifeCycle)); + + static void OnConfigureLifeCycle(ITizenLifecycleBuilder tizen) + { + tizen.OnPreCreate((app) => + { + // This is the initial Init to set up any system services registered by + // Forms.Init(). This happens before any UI has appeared. + // This creates a dummy MauiContext. + + var services = MauiApplication.Current.Services; + MauiContext mauiContext = new MauiContext(services); + ActivationState state = new ActivationState(mauiContext); + +#pragma warning disable CS0612 // Type or member is obsolete + var options = services.GetService(); + if (options == null) + { + options = new InitializationOptions(MauiApplication.Current) + { + DisplayResolutionUnit = TDeviceInfo.DisplayResolutionUnit.ToCompatibility(TDeviceInfo.ViewPortWidth) + }; + } + else + { + options.Context = options.Context ?? MauiApplication.Current; + TDeviceInfo.DisplayResolutionUnit = options.DisplayResolutionUnit.ToDeviceInfo(); + } + options.Flags |= InitializationFlags.SkipRenderers; + Forms.Init(state, options); +#pragma warning disable CS0612 // Type or member is obsolete + }) + .OnMauiContextCreated((mauiContext) => + { + // This is the final Init that sets up the real context from the application. + + var state = new ActivationState(mauiContext!); +#pragma warning disable CS0612 // Type or member is obsolete + Forms.Init(state); +#pragma warning disable CS0612 // Type or member is obsolete + }); + } + } +} diff --git a/src/Compatibility/Core/src/AppHostBuilderExtensions.cs b/src/Compatibility/Core/src/AppHostBuilderExtensions.cs index b221d8e0b1..6efb4d6f88 100644 --- a/src/Compatibility/Core/src/AppHostBuilderExtensions.cs +++ b/src/Compatibility/Core/src/AppHostBuilderExtensions.cs @@ -33,6 +33,23 @@ using Microsoft.Maui.Controls.Compatibility.Platform.iOS; using WebViewRenderer = Microsoft.Maui.Controls.Compatibility.Platform.iOS.WkWebViewRenderer; using RadioButtonRenderer = Microsoft.Maui.Controls.Compatibility.Platform.iOS.Platform.DefaultRenderer; using DefaultRenderer = Microsoft.Maui.Controls.Compatibility.Platform.iOS.Platform.DefaultRenderer; +#elif TIZEN +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using Microsoft.Maui.Graphics.Skia; +using BoxRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.BoxViewRenderer; +using CollectionViewRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.StructuredItemsViewRenderer; +using OpenGLViewRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.DefaultRenderer; +using StreamImagesourceHandler = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.StreamImageSourceHandler; +using ImageLoaderSourceHandler = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.UriImageSourceHandler; +using DefaultRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.DefaultRenderer; +using FrameRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.FrameRenderer; +using ImageRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.ImageRenderer; +using EllipseRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.EllipseRenderer; +using LineRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.LineRenderer; +using PathRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.PathRenderer; +using PolygonRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.PolygonRenderer; +using PolylineRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.PolylineRenderer; +using RectangleRenderer = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp.RectangleRenderer; #endif namespace Microsoft.Maui.Controls.Compatibility.Hosting @@ -89,11 +106,32 @@ namespace Microsoft.Maui.Controls.Compatibility.Hosting #pragma warning restore CS0618 // Type or member is obsolete #pragma warning restore CS0612 // Type or member is obsolete +#if TIZEN +#pragma warning disable CS0618 // Type or member is obsolete +#pragma warning disable CS0612 // Type or member is obsolete + handlers.TryAddCompatibilityRenderer(typeof(ContentView), typeof(LayoutRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(TabbedPage), typeof(TabbedPageRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(NavigationPage), typeof(NavigationPageRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(FlyoutPage), typeof(FlyoutPageRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(ListView), typeof(ListViewRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(Cell), typeof(CellRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(ImageCell), typeof(ImageCellRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(EntryCell), typeof(EntryCellRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(TextCell), typeof(TextCellRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(ViewCell), typeof(ViewCellRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(SwitchCell), typeof(SwitchCellRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(TableView), typeof(TableViewRenderer)); + handlers.TryAddCompatibilityRenderer(typeof(Frame), typeof(FrameRenderer)); +#pragma warning disable CS0612 // Type or member is obsolete +#pragma warning disable CS0618 // Type or member is obsolete +#endif // Shimmed renderers go directly to the registrar to load Image Handlers Internals.Registrar.Registered.Register(typeof(FileImageSource), typeof(FileImageSourceHandler)); Internals.Registrar.Registered.Register(typeof(StreamImageSource), typeof(StreamImagesourceHandler)); Internals.Registrar.Registered.Register(typeof(UriImageSource), typeof(ImageLoaderSourceHandler)); +#if !TIZEN Internals.Registrar.Registered.Register(typeof(FontImageSource), typeof(FontImageSourceHandler)); +#endif Internals.Registrar.Registered.Register(typeof(Microsoft.Maui.EmbeddedFont), typeof(Microsoft.Maui.EmbeddedFontLoader)); #endif diff --git a/src/Compatibility/Core/src/Compatibility.csproj b/src/Compatibility/Core/src/Compatibility.csproj index 5a4a4beec9..635e411fb1 100644 --- a/src/Compatibility/Core/src/Compatibility.csproj +++ b/src/Compatibility/Core/src/Compatibility.csproj @@ -7,6 +7,7 @@ Android\ iOS\ Windows\ + Tizen\ false true @@ -21,19 +22,15 @@ - - - - @@ -48,6 +45,7 @@ + diff --git a/src/Compatibility/Core/src/Forms.cs b/src/Compatibility/Core/src/Forms.cs index 3e288ebd19..9b4c24ec1a 100644 --- a/src/Compatibility/Core/src/Forms.cs +++ b/src/Compatibility/Core/src/Forms.cs @@ -1,4 +1,4 @@ -#if !(__ANDROID__ || __IOS__ || WINDOWS) +#if !(__ANDROID__ || __IOS__ || WINDOWS || TIZEN) using System; using System.Collections.Generic; using System.Text; diff --git a/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs b/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs index e89ea8313c..9c6fad5d85 100644 --- a/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs +++ b/src/Compatibility/Core/src/MauiHandlersCollectionExtensions.cs @@ -126,4 +126,4 @@ namespace Microsoft.Maui.Controls.Compatibility.Hosting return effectsBuilder; } } -} \ No newline at end of file +} diff --git a/src/Compatibility/Core/src/RendererToHandlerShim.Tizen.cs b/src/Compatibility/Core/src/RendererToHandlerShim.Tizen.cs new file mode 100644 index 0000000000..dab4452aaa --- /dev/null +++ b/src/Compatibility/Core/src/RendererToHandlerShim.Tizen.cs @@ -0,0 +1,62 @@ +#pragma warning disable CS0612 // Type or member is obsolete +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +#pragma warning disable CS0612 // Type or member is obsolete +using Microsoft.Maui.Graphics; +using Rect = Microsoft.Maui.Graphics.Rect; +using ERect = ElmSharp.Rect; +using PlatformView = ElmSharp.EvasObject; + +namespace Microsoft.Maui.Controls.Compatibility +{ + public partial class RendererToHandlerShim : IPlatformViewHandler + { + protected override PlatformView CreatePlatformView() + { + return VisualElementRenderer.NativeView; + } + + IVisualElementRenderer CreateRenderer(IView view) + { + return Internals.Registrar.Registered.GetHandlerForObject(view) ?? new DefaultRenderer(); + } + + public override Size GetDesiredSize(double widthConstraint, double heightConstraint) + { + if (VisualElementRenderer == null) + return Size.Zero; + + // TODO. It is workaroud code, Controls.VisualElement.MeasureOverride implementation is wrong. it does not apply Height/WidthRequest + return VisualElementRenderer.Element.Measure(widthConstraint, heightConstraint).Request; + } + + public override void UpdateValue(string property) + { + base.UpdateValue(property); + if (property == "Frame") + { + PlatformArrange(VisualElementRenderer.Element.Bounds); + } + } + + public override void PlatformArrange(Rect frame) + { + base.PlatformArrange(frame); + VisualElementRenderer.UpdateLayout(); + } + + public override ERect GetPlatformContentGeometry() + { + return VisualElementRenderer?.GetNativeContentGeometry() ?? new ERect(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + VisualElementRenderer?.Dispose(); + VisualElementRenderer = null; + } + base.Dispose(disposing); + } + } +} diff --git a/src/Compatibility/Core/src/RendererToHandlerShim.cs b/src/Compatibility/Core/src/RendererToHandlerShim.cs index 39cd804c61..11d9c74384 100644 --- a/src/Compatibility/Core/src/RendererToHandlerShim.cs +++ b/src/Compatibility/Core/src/RendererToHandlerShim.cs @@ -18,6 +18,13 @@ using static Microsoft.Maui.Controls.Compatibility.Platform.iOS.Platform; using PlatformView = UIKit.UIView; using Microsoft.Maui.Controls.Compatibility.Platform.iOS; using ViewHandler = Microsoft.Maui.Handlers.ViewHandler; +#elif TIZEN +#pragma warning disable CS0612 // Type or member is obsolete +using static Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Platform; +#pragma warning disable CS0612 // Type or member is obsolete +using PlatformView = ElmSharp.EvasObject; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using ViewHandler = Microsoft.Maui.Handlers.ViewHandler; #elif NETSTANDARD using PlatformView = System.Object; using ViewHandler = Microsoft.Maui.Handlers.ViewHandler; diff --git a/src/Compatibility/Core/src/Tizen/Cells/CellRenderer.cs b/src/Compatibility/Core/src/Tizen/Cells/CellRenderer.cs index 9d3b1b8260..9ef5ce2075 100644 --- a/src/Compatibility/Core/src/Tizen/Cells/CellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Cells/CellRenderer.cs @@ -3,6 +3,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public abstract class CellRenderer : IRegisterable { const string HeightProperty = "Height"; @@ -100,9 +101,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { var nativeSpan = new Native.Span(); nativeSpan.Text = span.Text; - nativeSpan.ForegroundColor = span.TextColor.ToPlatform(); + nativeSpan.ForegroundColor = span.TextColor.ToNative(); nativeSpan.FontAttributes = span.FontAttributes; - nativeSpan.BackgroundColor = span.BackgroundColor.ToPlatform(); + nativeSpan.BackgroundColor = span.BackgroundColor.ToNative(); nativeSpan.FontSize = span.FontSize; nativeSpan.FontFamily = span.FontFamily; return nativeSpan; diff --git a/src/Compatibility/Core/src/Tizen/Cells/EntryCellRenderer.cs b/src/Compatibility/Core/src/Tizen/Cells/EntryCellRenderer.cs index 62f4ecd19e..55ab30338c 100644 --- a/src/Compatibility/Core/src/Tizen/Cells/EntryCellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Cells/EntryCellRenderer.cs @@ -2,9 +2,11 @@ using System; using System.Collections.Generic; using System.Globalization; using ElmSharp; +using XStackLayout = Microsoft.Maui.Controls.StackLayout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class EntryCellRenderer : ViewCellRenderer { readonly Dictionary _cacheCandidate = new Dictionary(); @@ -33,7 +35,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var entry = new Entry() { - HorizontalOptions = LayoutOptions.FillAndExpand, + HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Center, FontSize = -1, }; @@ -42,7 +44,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen entry.SetBinding(InputView.KeyboardProperty, new Binding(EntryCell.KeyboardProperty.PropertyName)); entry.SetBinding(Entry.HorizontalTextAlignmentProperty, new Binding(EntryCell.HorizontalTextAlignmentProperty.PropertyName)); - var layout = new StackLayout() + var layout = new XStackLayout() { Orientation = StackOrientation.Horizontal, Children = { @@ -95,7 +97,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - return ((Color)value).IsDefault ? ThemeConstants.EntryCell.ColorClass.DefaultLabelColor : value; + return (value == null || ((Color)value).IsDefault) ? ThemeConstants.EntryCell.ColorClass.DefaultLabelColor : value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) diff --git a/src/Compatibility/Core/src/Tizen/Cells/ImageCellRenderer.cs b/src/Compatibility/Core/src/Tizen/Cells/ImageCellRenderer.cs index 57b36327eb..d11c12561d 100644 --- a/src/Compatibility/Core/src/Tizen/Cells/ImageCellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Cells/ImageCellRenderer.cs @@ -3,6 +3,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ImageCellRenderer : TextCellRenderer { public ImageCellRenderer() : this(ThemeManager.GetImageCellRendererStyle()) diff --git a/src/Compatibility/Core/src/Tizen/Cells/SwitchCellRenderer.cs b/src/Compatibility/Core/src/Tizen/Cells/SwitchCellRenderer.cs index 53ac419f17..ff1475b201 100644 --- a/src/Compatibility/Core/src/Tizen/Cells/SwitchCellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Cells/SwitchCellRenderer.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; +using Microsoft.Maui.Devices; using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class SwitchCellRenderer : CellRenderer { readonly Dictionary _cacheCandidate = new Dictionary(); diff --git a/src/Compatibility/Core/src/Tizen/Cells/TextCellRenderer.cs b/src/Compatibility/Core/src/Tizen/Cells/TextCellRenderer.cs index 1e44d9a699..4c89702d5e 100644 --- a/src/Compatibility/Core/src/Tizen/Cells/TextCellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Cells/TextCellRenderer.cs @@ -3,6 +3,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class TextCellRenderer : CellRenderer { bool _groupMode = false; diff --git a/src/Compatibility/Core/src/Tizen/Cells/ViewCellRenderer.cs b/src/Compatibility/Core/src/Tizen/Cells/ViewCellRenderer.cs index 6acda7e5de..7351d27fe6 100644 --- a/src/Compatibility/Core/src/Tizen/Cells/ViewCellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Cells/ViewCellRenderer.cs @@ -3,6 +3,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ViewCellRenderer : CellRenderer { readonly Dictionary _cacheCandidate = new Dictionary(); @@ -98,7 +99,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { if (element is Button || element is Switch) { - var nativeView = Platform.GetRenderer(element).NativeView ?? null; + var nativeView = Platform.GetRenderer(element)?.NativeView ?? null; if (nativeView != null) { nativeView.PropagateEvents = false; diff --git a/src/Compatibility/Core/src/Tizen/Compatibility.Tizen.csproj b/src/Compatibility/Core/src/Tizen/Compatibility.Tizen.csproj deleted file mode 100644 index 8a2e33b20d..0000000000 --- a/src/Compatibility/Core/src/Tizen/Compatibility.Tizen.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - Tizen Backend for Xamarin.Forms - - - tizen40 - Tizen - v4.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Compatibility/Core/src/Tizen/Deserializer.cs b/src/Compatibility/Core/src/Tizen/Deserializer.cs deleted file mode 100644 index a8e7a690ab..0000000000 --- a/src/Compatibility/Core/src/Tizen/Deserializer.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO.IsolatedStorage; -using System.Runtime.Serialization; -using System.Threading.Tasks; -using System.Xml; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ - internal class Deserializer : Internals.IDeserializer - { - const string PropertyStoreFile = "PropertyStore.forms"; - - public Task> DeserializePropertiesAsync() => Task.Factory.StartNew(DeserializeProperties); - - [RequiresUnreferencedCode(TrimmerConstants.SerializerTrimmerWarning)] - IDictionary DeserializeProperties() - { - // Deserialize property dictionary to local storage - // Make sure to use Internal - using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!store.FileExists(PropertyStoreFile)) - return null; - - using (IsolatedStorageFileStream stream = store.OpenFile(PropertyStoreFile, System.IO.FileMode.Open, System.IO.FileAccess.Read)) - using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max)) - { - if (stream.Length == 0) - return null; - - try - { - var dcs = new DataContractSerializer(typeof(Dictionary)); - return (IDictionary)dcs.ReadObject(reader); - } - catch (Exception e) - { - Debug.WriteLine("Could not deserialize properties: " + e.Message); - Internals.Log.Warning("Microsoft.Maui.Controls.Compatibility PropertyStore", $"Exception while reading Application properties: {e}"); - } - } - } - - return null; - } - - [RequiresUnreferencedCode(TrimmerConstants.SerializerTrimmerWarning)] - public Task SerializePropertiesAsync(IDictionary properties) - { - properties = new Dictionary(properties); - - // No need to write 0 properties if no file exists - if (properties.Count <= 0) - return Task.CompletedTask; - - return Task.Factory.StartNew(SerializeProperties, properties); - } - - [RequiresUnreferencedCode(TrimmerConstants.SerializerTrimmerWarning)] - void SerializeProperties(object properties) - { - using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) - { - // No need to write 0 properties if no file exists - if (properties.Count == 0 && !store.FileExists(PropertyStoreFile)) - { - return; - } - using (IsolatedStorageFileStream stream = store.OpenFile(PropertyStoreFile + ".tmp", System.IO.FileMode.OpenOrCreate)) - using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(stream)) - { - try - { - var dcs = new DataContractSerializer(typeof(Dictionary)); - dcs.WriteObject(writer, properties); - writer.Flush(); - } - catch (Exception e) - { - Debug.WriteLine("Could not serialize properties: " + e.Message); - Internals.Log.Warning("Microsoft.Maui.Controls.Compatibility PropertyStore", $"Exception while writing Application properties: {e}"); - return; - } - } - - try - { - if (store.FileExists(PropertyStoreFile)) - store.DeleteFile(PropertyStoreFile); - store.MoveFile(PropertyStoreFile + ".tmp", PropertyStoreFile); - } - catch (Exception e) - { - Debug.WriteLine("Could not move new serialized property file over old: " + e.Message); - Internals.Log.Warning("Microsoft.Maui.Controls.Compatibility PropertyStore", $"Exception while writing Application properties: {e}"); - } - } - } - } -} \ No newline at end of file diff --git a/src/Compatibility/Core/src/Tizen/DisplayResolutionUnit.cs b/src/Compatibility/Core/src/Tizen/DisplayResolutionUnit.cs index fdd1138ffc..dd8925343d 100644 --- a/src/Compatibility/Core/src/Tizen/DisplayResolutionUnit.cs +++ b/src/Compatibility/Core/src/Tizen/DisplayResolutionUnit.cs @@ -1,4 +1,5 @@ using System; +using TDisplayResolutionUnit = Tizen.UIExtensions.Common.DisplayResolutionUnit; namespace Microsoft.Maui.Controls.Compatibility { @@ -50,4 +51,34 @@ namespace Microsoft.Maui.Controls.Compatibility public double ViewportWidth { get; private set; } = -1; } + + public static class DisplayResolutionUnitConverter + { + public static DisplayResolutionUnit ToCompatibility(this TDisplayResolutionUnit unit, double width = 0) => unit switch + { + TDisplayResolutionUnit.DP => DisplayResolutionUnit.DP(), + TDisplayResolutionUnit.DeviceScaledDP => DisplayResolutionUnit.DP(true), + TDisplayResolutionUnit.Pixel => DisplayResolutionUnit.Pixel(), + TDisplayResolutionUnit.DeviceScaledPixel => DisplayResolutionUnit.Pixel(true), + TDisplayResolutionUnit.VP => DisplayResolutionUnit.VP(width), + _ => DisplayResolutionUnit.DP(), + }; + + public static TDisplayResolutionUnit ToDeviceInfo(this DisplayResolutionUnit unit) + { + if (unit.UseDP) + { + return unit.UseDeviceScale ? TDisplayResolutionUnit.DeviceScaledDP : TDisplayResolutionUnit.DP; + } + else if (unit.UseVP) + { + Tizen.UIExtensions.Common.DeviceInfo.ViewPortWidth = unit.ViewportWidth; + return TDisplayResolutionUnit.VP; + } + else + { + return unit.UseDeviceScale ? TDisplayResolutionUnit.DeviceScaledPixel : TDisplayResolutionUnit.Pixel; + } + } + } } diff --git a/src/Compatibility/Core/src/Tizen/DragGestureHandler.cs b/src/Compatibility/Core/src/Tizen/DragGestureHandler.cs index 3608360e0e..dc1e4001ad 100644 --- a/src/Compatibility/Core/src/Tizen/DragGestureHandler.cs +++ b/src/Compatibility/Core/src/Tizen/DragGestureHandler.cs @@ -7,6 +7,7 @@ using EGestureType = ElmSharp.GestureLayer.GestureType; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class DragGestureHandler : GestureHandler { bool _isApi4; @@ -84,7 +85,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (Renderer == null) return; - var arg = dragGestureRecognizer.SendDragStarting(Renderer.Element); + if (Renderer.Element is not View view) + return; + + var arg = dragGestureRecognizer.SendDragStarting(view); if (arg.Cancel) return; diff --git a/src/Compatibility/Core/src/Tizen/DropGestureHandler.cs b/src/Compatibility/Core/src/Tizen/DropGestureHandler.cs index f9c03d5650..13b73ae158 100644 --- a/src/Compatibility/Core/src/Tizen/DropGestureHandler.cs +++ b/src/Compatibility/Core/src/Tizen/DropGestureHandler.cs @@ -6,6 +6,7 @@ using EGestureType = ElmSharp.GestureLayer.GestureType; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class DropGestureHandler : GestureHandler { bool _isApi4; @@ -103,7 +104,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (currentStateData.DataPackage == null || currentStateData.AcceptedOperation == DataPackageOperation.None) return false; - Device.BeginInvokeOnMainThread(async () => + Application.Current?.Dispatcher.Dispatch(async () => { if (Recognizer is DropGestureRecognizer dropRecognizer && dropRecognizer.AllowDrop) await dropRecognizer.SendDrop(new DropEventArgs(currentStateData.DataPackage.View)); diff --git a/src/Compatibility/Core/src/Tizen/EmbeddedFontLoader.cs b/src/Compatibility/Core/src/Tizen/EmbeddedFontLoader.cs index 00d57405c5..09d16a7cba 100644 --- a/src/Compatibility/Core/src/Tizen/EmbeddedFontLoader.cs +++ b/src/Compatibility/Core/src/Tizen/EmbeddedFontLoader.cs @@ -1,49 +1,7 @@ -using System; -using System.IO; -using ElmSharp; -using Tizen.Common; -using IOPath = System.IO.Path; -using TApplication = Tizen.Applications.Application; - namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { - public class EmbeddedFontLoader : IEmbeddedFontLoader, IRegisterable + public class CompatibilityEmbeddedFontLoader : EmbeddedFontLoader, IRegisterable { - const string _fontCacheFolderName = "fonts"; - - public DirectoryInfo FontCacheDirectory { get; private set; } - - public EmbeddedFontLoader() - { - FontCacheDirectory = Directory.CreateDirectory(IOPath.Combine(TApplication.Current.DirectoryInfo.Data, _fontCacheFolderName)); - Utility.AppendGlobalFontPath(FontCacheDirectory.FullName); - } - - public (bool success, string filePath) LoadFont(EmbeddedFont font) - { - var filePath = IOPath.Combine(FontCacheDirectory.FullName, font.FontName); - if (File.Exists(filePath)) - return (true, filePath); - try - { - using (var fileStream = File.Create(filePath)) - { - font.ResourceStream.CopyTo(fileStream); - } - - if (DotnetUtil.TizenAPIVersion > 5) - { - FontExtensions.FontReinit(); - } - - return (true, filePath); - } - catch (Exception ex) - { - Log.Error(ex.Message); - File.Delete(filePath); - } - return (false, null); - } + //Provide compatibilityEmveddedFontLoader (implements IRegisterable) for static registar } } \ No newline at end of file diff --git a/src/Compatibility/Core/src/Tizen/ExportCellAttribute.cs b/src/Compatibility/Core/src/Tizen/ExportCellAttribute.cs deleted file mode 100644 index fd6844112e..0000000000 --- a/src/Compatibility/Core/src/Tizen/ExportCellAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Microsoft.Maui.Controls.Compatibility -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - public sealed class ExportCellAttribute : HandlerAttribute - { - public ExportCellAttribute(Type handler, Type target) : base(handler, target) - { - } - } -} diff --git a/src/Compatibility/Core/src/Tizen/ExportHandlerAttribute.cs b/src/Compatibility/Core/src/Tizen/ExportHandlerAttribute.cs deleted file mode 100644 index 17a126abb3..0000000000 --- a/src/Compatibility/Core/src/Tizen/ExportHandlerAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Microsoft.Maui.Controls.Compatibility -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - public sealed class ExportHandlerAttribute : HandlerAttribute - { - public ExportHandlerAttribute(Type handler, Type target) : base(handler, target) - { - } - } -} diff --git a/src/Compatibility/Core/src/Tizen/ExportImageSourceHandlerAttribute.cs b/src/Compatibility/Core/src/Tizen/ExportImageSourceHandlerAttribute.cs deleted file mode 100644 index fb680b156e..0000000000 --- a/src/Compatibility/Core/src/Tizen/ExportImageSourceHandlerAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Microsoft.Maui.Controls.Compatibility -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - public sealed class ExportImageSourceHandlerAttribute : HandlerAttribute - { - public ExportImageSourceHandlerAttribute(Type handler, Type target) : base(handler, target) - { - } - } -} diff --git a/src/Compatibility/Core/src/Tizen/ExportRendererAttribute.cs b/src/Compatibility/Core/src/Tizen/ExportRendererAttribute.cs deleted file mode 100644 index f07feb8da8..0000000000 --- a/src/Compatibility/Core/src/Tizen/ExportRendererAttribute.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; - -namespace Microsoft.Maui.Controls.Compatibility -{ - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - public sealed class ExportRendererAttribute : HandlerAttribute - { - TargetIdiom Target { get; set; } - - public ExportRendererAttribute(Type handler, Type target) : this(handler, target, null) - { - } - - public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisuals) : base(handler, target, supportedVisuals) - { - } - - public ExportRendererAttribute(Type handler, Type target, TargetIdiom targetIdiom) : this(handler, target, null, targetIdiom) - { - } - - public ExportRendererAttribute(Type handler, Type target, Type[] supportedVisuals, TargetIdiom targetIdiom) : base(handler, target, supportedVisuals) - { - Target = targetIdiom; - } - - public override bool ShouldRegister() - { - if (Target == TargetIdiom.Unsupported) - return true; - - return (Target == Device.Idiom); - } - } -} diff --git a/src/Compatibility/Core/src/Tizen/Extensions/AccessibilityExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/AccessibilityExtensions.cs index e1e025ff2d..31d5923c59 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/AccessibilityExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/AccessibilityExtensions.cs @@ -2,6 +2,7 @@ using ElmSharp.Accessible; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete] public static class AccessibilityExtensions { public static string SetAccessibilityName(this IAccessibleObject Control, Element Element, string _defaultAccessibilityName = null) diff --git a/src/Compatibility/Core/src/Tizen/Extensions/BrushExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/BrushExtensions.cs index 17f2980eaf..4d641e206c 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/BrushExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/BrushExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using SkiaSharp; using SkiaSharp.Views.Tizen; +using Microsoft.Maui.Graphics; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { @@ -82,7 +83,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public static SKColor ToSolidColor(this SolidColorBrush solidColorBrush) { - return solidColorBrush.Color != Color.Default ? solidColorBrush.Color.ToPlatform().ToSKColor() : SKColor.Empty; + return solidColorBrush.Color.IsDefault() ? SKColor.Empty : solidColorBrush.Color.ToNative().ToSKColor(); } static SKShader CreateLinearGradient(LinearGradientBrush linearGradientBrush, SKRect pathBounds) @@ -90,7 +91,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var startPoint = new SKPoint(pathBounds.Left + (float)linearGradientBrush.StartPoint.X * pathBounds.Width, pathBounds.Top + (float)linearGradientBrush.StartPoint.Y * pathBounds.Height); var endPoint = new SKPoint(pathBounds.Left + (float)linearGradientBrush.EndPoint.X * pathBounds.Width, pathBounds.Top + (float)linearGradientBrush.EndPoint.Y * pathBounds.Height); var orderedGradientStops = linearGradientBrush.GradientStops.OrderBy(x => x.Offset).ToList(); - var gradientColors = orderedGradientStops.Select(x => x.Color.ToPlatform().ToSKColor()).ToArray(); + var gradientColors = orderedGradientStops.Select(x => x.Color.ToNative().ToSKColor()).ToArray(); var gradientColorPos = orderedGradientStops.Select(x => x.Offset).ToArray(); return SKShader.CreateLinearGradient(startPoint, endPoint, gradientColors, gradientColorPos, SKShaderTileMode.Clamp); } @@ -100,7 +101,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var center = new SKPoint((float)radialGradientBrush.Center.X * pathBounds.Width + pathBounds.Left, (float)radialGradientBrush.Center.Y * pathBounds.Height + pathBounds.Top); var radius = (float)radialGradientBrush.Radius * Math.Max(pathBounds.Height, pathBounds.Width); var orderedGradientStops = radialGradientBrush.GradientStops.OrderBy(x => x.Offset).ToList(); - var gradientColors = orderedGradientStops.Select(x => x.Color.ToPlatform().ToSKColor()).ToArray(); + var gradientColors = orderedGradientStops.Select(x => x.Color.ToNative().ToSKColor()).ToArray(); var gradientColorPos = orderedGradientStops.Select(x => x.Offset).ToArray(); return SKShader.CreateRadialGradient(center, radius, gradientColors, gradientColorPos, SKShaderTileMode.Clamp); } diff --git a/src/Compatibility/Core/src/Tizen/Extensions/ColorExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/ColorExtensions.cs index 0a5e12f52a..0f86966258 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/ColorExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/ColorExtensions.cs @@ -1,3 +1,4 @@ +using Microsoft.Maui.Graphics; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen @@ -11,25 +12,25 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// The Microsoft.Maui.Controls.Compatibility.Color instance which will be converted to a ElmSharp.Color public static EColor ToNative(this Color c) { - if (c.IsDefault) + if (c == null) { // Trying to convert the default color, this may result in black color. return EColor.Default; } else { - return new EColor((int)(255.0 * c.R), (int)(255.0 * c.G), (int)(255.0 * c.B), (int)(255.0 * c.A)); + return new EColor((int)(255.0 * c.Red), (int)(255.0 * c.Green), (int)(255.0 * c.Blue), (int)(255.0 * c.Alpha)); } } public static Color WithAlpha(this Color color, double alpha) { - return new Color(color.R, color.G, color.B, (int)(255 * alpha)); + return new Color(color.Red, color.Green, color.Blue, (int)(255 * alpha)); } public static Color WithPremultiplied(this Color color, double alpha) { - return new Color((int)(color.R * alpha), (int)(color.G * alpha), (int)(color.B * alpha), color.A); + return new Color((int)(color.Red * alpha), (int)(color.Green * alpha), (int)(color.Blue * alpha), color.Alpha); } /// diff --git a/src/Compatibility/Core/src/Tizen/Extensions/DensityIndependentPixelExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/DensityIndependentPixelExtensions.cs index 2d293ce5e3..fb54025692 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/DensityIndependentPixelExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/DensityIndependentPixelExtensions.cs @@ -1,3 +1,5 @@ +using Microsoft.Maui.Graphics; +using Rect = Microsoft.Maui.Graphics.Rect; using ERect = ElmSharp.Rect; using ESize = ElmSharp.Size; @@ -8,12 +10,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// public static class DensityIndependentPixelExtensions { - public static Rectangle ToDP(this ERect rect) + public static Rect ToDP(this ERect rect) { - return new Rectangle(Forms.ConvertToScaledDP(rect.X), Forms.ConvertToScaledDP(rect.Y), Forms.ConvertToScaledDP(rect.Width), Forms.ConvertToScaledDP(rect.Height)); + return new Rect(Forms.ConvertToScaledDP(rect.X), Forms.ConvertToScaledDP(rect.Y), Forms.ConvertToScaledDP(rect.Width), Forms.ConvertToScaledDP(rect.Height)); } - public static ERect ToPixel(this Rectangle rect) + public static ERect ToPixel(this Rect rect) { return new ERect(Forms.ConvertToScaledPixel(rect.X), Forms.ConvertToScaledPixel(rect.Y), Forms.ConvertToScaledPixel(rect.Width), Forms.ConvertToScaledPixel(rect.Height)); } diff --git a/src/Compatibility/Core/src/Tizen/Extensions/FontExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/FontExtensions.cs deleted file mode 100644 index 74d485f18d..0000000000 --- a/src/Compatibility/Core/src/Tizen/Extensions/FontExtensions.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Runtime.InteropServices; -using Microsoft.Maui.Controls.Compatibility.Core; -using Microsoft.Maui.Controls.Compatibility.Internals; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ - public static class FontExtensions - { - public static string ToNativeFontFamily(this string self) - { - if (string.IsNullOrEmpty(self)) - return null; - - var cleansedFont = CleanseFontName(self); - int index = cleansedFont.LastIndexOf('-'); - if (index != -1) - { - string font = cleansedFont.Substring(0, index); - string style = cleansedFont.Substring(index + 1); - return $"{font}:style={style}"; - } - else - { - return cleansedFont; - } - } - - static string CleanseFontName(string fontName) - { - //First check Alias - var (hasFontAlias, fontPostScriptName) = FontRegistrar.HasFont(fontName); - if (hasFontAlias) - return fontPostScriptName; - var fontFile = FontFile.FromString(fontName); - - if (!string.IsNullOrWhiteSpace(fontFile.Extension)) - { - var (hasFont, _) = FontRegistrar.HasFont(fontFile.FileNameWithExtension()); - if (hasFont) - return fontFile.PostScriptName; - } - else - { - foreach (var ext in FontFile.Extensions) - { - var formated = fontFile.FileNameWithExtension(ext); - var (hasFont, filePath) = FontRegistrar.HasFont(formated); - if (hasFont) - return fontFile.PostScriptName; - } - } - return fontFile.PostScriptName; - } - - public static void FontReinit() - { - evas_font_reinit(); - } - - [DllImport("libelementary.so.1")] - static extern void evas_font_reinit(); - } -} diff --git a/src/Compatibility/Core/src/Tizen/Extensions/GeometryExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/GeometryExtensions.cs index c9319e18cd..ceb0487636 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/GeometryExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/GeometryExtensions.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using SkiaSharp; -using Microsoft.Maui.Controls.Compatibility.Shapes; -using FormsRectangle = Microsoft.Maui.Controls.Compatibility.Rectangle; +using Microsoft.Maui.Controls.Shapes; +using Rect = Microsoft.Maui.Graphics.Rect; +using Point = Microsoft.Maui.Graphics.Point; + namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { @@ -9,7 +11,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { public static SKPath ToSKPath(this Geometry geometry) { +#pragma warning disable IL2026 return geometry == null ? MakePath(geometry) : MakePath((dynamic)geometry); +#pragma warning disable IL2026 } static SKPath MakePath(Geometry geometry) @@ -34,7 +38,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen static SKPath MakePath(RectangleGeometry rectangleGeometry) { var path = new SKPath(); - FormsRectangle rect = rectangleGeometry.Rect; + Rect rect = rectangleGeometry.Rect; path.AddRect(new SKRect( Forms.ConvertToScaledPixel(rect.Left), @@ -66,7 +70,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen foreach (Geometry child in geometryGroup.Children) { +#pragma warning disable IL2026 SKPath childPath = MakePath((dynamic)child); +#pragma warning disable IL2026 path.AddPath(childPath); } diff --git a/src/Compatibility/Core/src/Tizen/Extensions/KeyboardExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/KeyboardExtensions.cs index 25ca64110e..d07cbba0ed 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/KeyboardExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/KeyboardExtensions.cs @@ -1,5 +1,4 @@ using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; using EEntry = ElmSharp.Entry; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen @@ -66,7 +65,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public static void UpdateKeyboard(this Native.IEntry control, Keyboard keyboard, bool isSpellCheckEnabled, bool isTextPredictionEnabled) { - control.Keyboard = keyboard.ToPlatform(); + control.Keyboard = keyboard.ToNative(); if (keyboard is CustomKeyboard customKeyboard) { (control as EEntry).AutoCapital = customKeyboard.Flags.ToAutoCapital(); diff --git a/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs index 4fca4515e3..a833dd5bf9 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/NativeBindingExtensions.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; using EObject = ElmSharp.EvasObject; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen diff --git a/src/Compatibility/Core/src/Tizen/Extensions/PageExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/PageExtensions.cs index d0c6c756d3..6d777e438e 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/PageExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/PageExtensions.cs @@ -3,6 +3,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility { + [Obsolete] public static class PageExtensions { public static EvasObject CreateEvasObject(this Page page, EvasObject parent, bool hasAlpha = false) @@ -33,6 +34,7 @@ namespace Microsoft.Maui.Controls.Compatibility namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public static class PageExtensions { public static EvasObject CreateEvasObject(this ContentPage page, EvasObject parent, bool hasAlpha = false) diff --git a/src/Compatibility/Core/src/Tizen/Extensions/PlatformConfigurationExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/PlatformConfigurationExtensions.cs index 2f674573c8..088e7f4e27 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/PlatformConfigurationExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/PlatformConfigurationExtensions.cs @@ -1,4 +1,4 @@ -using CurrentPlatform = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.Tizen; +using CurrentPlatform = Microsoft.Maui.Controls.PlatformConfiguration.Tizen; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { diff --git a/src/Compatibility/Core/src/Tizen/Extensions/TextAlignmentExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/TextAlignmentExtensions.cs index 276d0fc574..7abde6d2c2 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/TextAlignmentExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/TextAlignmentExtensions.cs @@ -1,3 +1,5 @@ +using Microsoft.Extensions.Logging; + namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { public static class TextAlignmentExtensions @@ -16,9 +18,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen return Native.TextAlignment.End; default: - Log.Warn("Warning: unrecognized HorizontalTextAlignment value {0}. " + + Application.Current?.FindMauiContext()?.CreateLogger()?.LogWarning("Warning: unrecognized HorizontalTextAlignment value {0}. " + "Expected: {Start|Center|End}.", alignment); - Log.Debug("Falling back to platform's default settings."); + Application.Current?.FindMauiContext()?.CreateLogger()?.LogDebug("Falling back to platform's default settings."); return Native.TextAlignment.Auto; } } diff --git a/src/Compatibility/Core/src/Tizen/Extensions/TransformExtensions.cs b/src/Compatibility/Core/src/Tizen/Extensions/TransformExtensions.cs index 7649bc12c4..63805730a7 100644 --- a/src/Compatibility/Core/src/Tizen/Extensions/TransformExtensions.cs +++ b/src/Compatibility/Core/src/Tizen/Extensions/TransformExtensions.cs @@ -1,5 +1,5 @@ using SkiaSharp; -using Microsoft.Maui.Controls.Compatibility.Shapes; +using Microsoft.Maui.Controls.Shapes; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { diff --git a/src/Compatibility/Core/src/Tizen/Forms.cs b/src/Compatibility/Core/src/Tizen/Forms.cs index cd214025da..529d8c97c5 100644 --- a/src/Compatibility/Core/src/Tizen/Forms.cs +++ b/src/Compatibility/Core/src/Tizen/Forms.cs @@ -7,12 +7,14 @@ using System.Reflection; using ElmSharp; using ElmSharp.Wearable; using Tizen.Applications; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; -using Microsoft.Maui.Controls.Compatibility.Shapes; -using DeviceOrientation = Microsoft.Maui.Controls.Compatibility.Internals.DeviceOrientation; +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Devices; using ELayout = ElmSharp.Layout; using TSystemInfo = Tizen.System.Information; +using Size = Microsoft.Maui.Graphics.Size; +using Color = Microsoft.Maui.Graphics.Color; namespace Microsoft.Maui.Controls.Compatibility { @@ -29,11 +31,12 @@ namespace Microsoft.Maui.Controls.Compatibility Lightweight, } + [Obsolete] public class InitializationOptions { public CoreApplication Context { get; set; } public bool UseDeviceIndependentPixel { get; set; } - public bool UseSkiaSharp { get; set; } + public bool UseSkiaSharp { get; set; } = true; public HandlerAttribute[] Handlers { get; set; } public Dictionary> CustomHandlers { get; set; } // for static registers public Assembly[] Assemblies { get; set; } @@ -51,6 +54,9 @@ namespace Microsoft.Maui.Controls.Compatibility public string Name; public ExportEffectAttribute[] Effects; } + public InitializationOptions() + { + } public InitializationOptions(CoreApplication application) { @@ -80,7 +86,11 @@ namespace Microsoft.Maui.Controls.Compatibility } } +#pragma warning disable CS0618 // Type or member is obsolete +#pragma warning disable CS0612 // Type or member is obsolete public static class Forms +#pragma warning disable CS0612 // Type or member is obsolete +#pragma warning disable CS0618 // Type or member is obsolete { static Lazy s_profile = new Lazy(() => { @@ -137,92 +147,41 @@ namespace Microsoft.Maui.Controls.Compatibility return ThemeManager.GetBaseScale(s_deviceType.Value); }); - class TizenDeviceInfo : DeviceInfo + static Lazy s_scalingFactor = new Lazy(() => { - readonly Size pixelScreenSize; + int width = 0; + int height = 0; - readonly Size scaledScreenSize; + TSystemInfo.TryGetValue("http://tizen.org/feature/screen.width", out width); + TSystemInfo.TryGetValue("http://tizen.org/feature/screen.height", out height); - readonly double scalingFactor; - - readonly string profile; - - public override Size PixelScreenSize + var scalingFactor = 1.0; // scaling is disabled, we're using pixels as Xamarin's geometry units + if (DisplayResolutionUnit.UseVP && DisplayResolutionUnit.ViewportWidth > 0) { - get - { - return this.pixelScreenSize; - } + scalingFactor = width / DisplayResolutionUnit.ViewportWidth; } - - public override Size ScaledScreenSize + else { - get + if (DisplayResolutionUnit.UseDP) { - return this.scaledScreenSize; + scalingFactor = s_dpi.Value / 160.0; } - } - public Size PhysicalScreenSize { get; } - - public override double ScalingFactor - { - get + if (DisplayResolutionUnit.UseDeviceScale) { - return this.scalingFactor; - } - } - - public string Profile - { - get - { - return this.profile; - } - } - - public TizenDeviceInfo() - { - int width = 0; - int height = 0; - - TSystemInfo.TryGetValue("http://tizen.org/feature/screen.width", out width); - TSystemInfo.TryGetValue("http://tizen.org/feature/screen.height", out height); - - var physicalScale = s_dpi.Value / 160.0; - PhysicalScreenSize = new Size(width / physicalScale, height / physicalScale); - - scalingFactor = 1.0; // scaling is disabled, we're using pixels as Xamarin's geometry units - if (DisplayResolutionUnit.UseVP && DisplayResolutionUnit.ViewportWidth > 0) - { - scalingFactor = width / DisplayResolutionUnit.ViewportWidth; - } - else - { - if (DisplayResolutionUnit.UseDP) + var portraitSize = Math.Min(PhysicalScreenSize.Width, PhysicalScreenSize.Height); + if (portraitSize > 2000) { - scalingFactor = s_dpi.Value / 160.0; + scalingFactor *= 4; } - - if (DisplayResolutionUnit.UseDeviceScale) + else if (portraitSize > 1000) { - var portraitSize = Math.Min(PhysicalScreenSize.Width, PhysicalScreenSize.Height); - if (portraitSize > 2000) - { - scalingFactor *= 4; - } - else if (portraitSize > 1000) - { - scalingFactor *= 2.5; - } + scalingFactor *= 2.5; } } - - pixelScreenSize = new Size(width, height); - scaledScreenSize = new Size(width / scalingFactor, height / scalingFactor); - profile = s_profile.Value; } - } + return scalingFactor; + }); static StaticRegistrarStrategy s_staticRegistrarStrategy = StaticRegistrarStrategy.None; @@ -232,6 +191,12 @@ namespace Microsoft.Maui.Controls.Compatibility public static event EventHandler ViewInitialized; + public static IMauiContext MauiContext + { + get; + internal set; + } + public static CoreApplication Context { get; @@ -262,8 +227,6 @@ namespace Microsoft.Maui.Controls.Compatibility private set; } - public static DeviceOrientation NaturalOrientation { get; } = GetDeviceOrientation(); - public static StaticRegistrarStrategy StaticRegistrarStrategy => s_staticRegistrarStrategy; public static PlatformType PlatformType => s_platformType; @@ -274,11 +237,11 @@ namespace Microsoft.Maui.Controls.Compatibility public static bool UseFastLayout { get; private set; } - public static DisplayResolutionUnit DisplayResolutionUnit { get; private set; } + public static DisplayResolutionUnit DisplayResolutionUnit { get; private set; } = DisplayResolutionUnit.Pixel(); public static int ScreenDPI => s_dpi.Value; - public static Size PhysicalScreenSize => (Device.info as TizenDeviceInfo).PhysicalScreenSize; + public static Size PhysicalScreenSize => DeviceDisplay.MainDisplayInfo.GetScaledScreenSize(); internal static TizenTitleBarVisibility TitleBarVisibility { @@ -286,23 +249,6 @@ namespace Microsoft.Maui.Controls.Compatibility private set; } - static DeviceOrientation GetDeviceOrientation() - { - int width = 0; - int height = 0; - TSystemInfo.TryGetValue("http://tizen.org/feature/screen.width", out width); - TSystemInfo.TryGetValue("http://tizen.org/feature/screen.height", out height); - - if (height >= width) - { - return DeviceOrientation.Portrait; - } - else - { - return DeviceOrientation.Landscape; - } - } - internal static void SendViewInitialized(this VisualElement self, EvasObject nativeView) { EventHandler viewInitialized = Forms.ViewInitialized; @@ -316,6 +262,8 @@ namespace Microsoft.Maui.Controls.Compatibility } } + public static bool IsInitializedRenderers { get; private set; } + public static void SetTitleBarVisibility(TizenTitleBarVisibility visibility) { TitleBarVisibility = visibility; @@ -384,41 +332,32 @@ namespace Microsoft.Maui.Controls.Compatibility } } - public static void Init(CoreApplication application) - { - Init(application, false); - } + [Obsolete] + public static void Init(IActivationState activationState) => Init(activationState.Context); - public static void Init(CoreApplication application, bool useDeviceIndependentPixel) - { - DisplayResolutionUnit = DisplayResolutionUnit.FromInit(useDeviceIndependentPixel); - SetupInit(application); - } + [Obsolete] + public static void Init(IActivationState activationState, InitializationOptions options) => Init(activationState.Context, options); - public static void Init(CoreApplication application, DisplayResolutionUnit unit) + [Obsolete] + public static void Init(IMauiContext context, InitializationOptions options = null) { - DisplayResolutionUnit = unit ?? DisplayResolutionUnit.Pixel(); - SetupInit(application); - } - - public static void Init(InitializationOptions options) - { - if (options == null) + if (options != null && options.DisplayResolutionUnit != null) { - throw new ArgumentException("Must be set options", nameof(options)); + DisplayResolutionUnit = options.DisplayResolutionUnit; } - - DisplayResolutionUnit = options.DisplayResolutionUnit ?? DisplayResolutionUnit.FromInit(options.UseDeviceIndependentPixel); - SetupInit(options.Context, options); + SetupInit(context, options); } - static void SetupInit(CoreApplication application, InitializationOptions options = null) + [Obsolete] + static void SetupInit(IMauiContext context, InitializationOptions options = null) { - Context = application; + MauiContext = context; + Context = options?.Context ?? MauiApplication.Current; + NativeParent = context.GetNativeParent(); + Registrar.RegisterRendererToHandlerShim(RendererToHandlerShim.CreateShim); if (!IsInitialized) { - Internals.Log.Listeners.Add(new XamarinLogListener()); if (System.Threading.SynchronizationContext.Current == null) { TizenSynchronizationContext.Initialize(); @@ -429,73 +368,51 @@ namespace Microsoft.Maui.Controls.Compatibility Utility.AppendGlobalFontPath(@"/usr/share/fonts"); } - Device.PlatformServices = new TizenPlatformServices(); - if (Device.info != null) + Device.DefaultRendererAssembly = typeof(Forms).Assembly; + + if (options?.Flags.HasFlag(InitializationFlags.SkipRenderers) != true) + RegisterCompatRenderers(options); + + if (options != null) { - ((TizenDeviceInfo)Device.info).Dispose(); - Device.info = null; + s_platformType = options.PlatformType; + s_useMessagingCenter = options.UseMessagingCenter; + UseSkiaSharp = options.UseSkiaSharp; + UseFastLayout = options.UseFastLayout; } - Device.Info = new Forms.TizenDeviceInfo(); + Application.AccentColor = GetAccentColor(); + ExpressionSearch.Default = new TizenExpressionSearch(); - if (!Forms.IsInitialized) + if (Context is WatchApplication) + s_platformType = PlatformType.Lightweight; + + IsInitialized = true; + } + + [Obsolete] + internal static void RegisterCompatRenderers(InitializationOptions maybeOptions = null) + { + if (!IsInitializedRenderers) { - if (options != null) + IsInitializedRenderers = true; + if (maybeOptions != null) { - s_platformType = options.PlatformType; - s_useMessagingCenter = options.UseMessagingCenter; - UseSkiaSharp = options.UseSkiaSharp; - UseFastLayout = options.UseFastLayout; + var options = maybeOptions; + var handlers = options.Handlers; + var flags = options.Flags; + var effectScopes = options.EffectScopes; + + //TODO: ExportCell? + //TODO: ExportFont // renderers - if (options.Handlers != null) + if (handlers != null) { - Registrar.RegisterRenderers(options.Handlers); - } - else - { - // static registrar - if (options.StaticRegistarStrategy != StaticRegistrarStrategy.None) - { - s_staticRegistrarStrategy = options.StaticRegistarStrategy; - StaticRegistrar.RegisterHandlers(options.CustomHandlers); - - if (options.StaticRegistarStrategy == StaticRegistrarStrategy.All) - { - Registrar.RegisterAll(new Type[] - { - typeof(ExportRendererAttribute), - typeof(ExportImageSourceHandlerAttribute), - typeof(ExportCellAttribute), - typeof(ExportHandlerAttribute), - typeof(ExportFontAttribute) - }); - - if (UseSkiaSharp) - RegisterSkiaSharpRenderers(); - } - } - else - { - Registrar.RegisterAll(new Type[] - { - typeof(ExportRendererAttribute), - typeof(ExportImageSourceHandlerAttribute), - typeof(ExportCellAttribute), - typeof(ExportHandlerAttribute), - typeof(ExportFontAttribute) - }); - - if (UseSkiaSharp) - RegisterSkiaSharpRenderers(); - - if (UseFastLayout) - Registrar.Registered.Register(typeof(Layout), typeof(FastLayoutRenderer)); - } + Registrar.RegisterRenderers(handlers); } // effects - var effectScopes = options.EffectScopes; if (effectScopes != null) { for (var i = 0; i < effectScopes.Length; i++) @@ -506,28 +423,19 @@ namespace Microsoft.Maui.Controls.Compatibility } // css - Registrar.RegisterStylesheets(options.Flags); + Registrar.RegisterStylesheets(flags); } else { - Registrar.RegisterAll(new Type[] - { + // Only need to do this once + Registrar.RegisterAll(new[] { typeof(ExportRendererAttribute), - typeof(ExportImageSourceHandlerAttribute), typeof(ExportCellAttribute), - typeof(ExportHandlerAttribute), + typeof(ExportImageSourceHandlerAttribute), typeof(ExportFontAttribute) }); } } - - Color.SetAccent(GetAccentColor(profile)); - ExpressionSearch.Default = new TizenExpressionSearch(); - - if (application is WatchApplication) - s_platformType = PlatformType.Lightweight; - - IsInitialized = true; } static void RegisterSkiaSharpRenderers() @@ -545,26 +453,23 @@ namespace Microsoft.Maui.Controls.Compatibility Registrar.Registered.Register(typeof(Shapes.Rectangle), typeof(Platform.Tizen.SkiaSharp.RectangleRenderer)); } - static Color GetAccentColor(string profile) + static Color GetAccentColor() { // On Windows Phone, this is the complementary color chosen by the user. // Good Windows Phone applications use this as part of their styling to provide a native look and feel. // On iOS and Android this instance is set to a contrasting color that is visible on the default // background but is not the same as the default text color. - switch (profile) - { - case "mobile": - // [Tizen_3.0]Basic_Interaction_GUI_[REF].xlsx Theme 001 (Default) 1st HSB: 188 70 80 - return Color.FromRgba(61, 185, 204, 255); - case "tv": - return Color.FromRgba(15, 15, 15, 230); - case "wearable": - // Theme A (Default) 1st HSB: 207 75 16 - return Color.FromRgba(10, 27, 41, 255); - default: - return Color.Black; - } + if (DeviceInfo.Idiom == DeviceIdiom.Phone) + // [Tizen_3.0]Basic_Interaction_GUI_[REF].xlsx Theme 001 (Default) 1st HSB: 188 70 80 + return Color.FromRgba(61, 185, 204, 255); + else if (DeviceInfo.Idiom == DeviceIdiom.TV) + return Color.FromRgba(15, 15, 15, 230); + else if (DeviceInfo.Idiom == DeviceIdiom.Watch) + // Theme A (Default) 1st HSB: 207 75 16 + return Color.FromRgba(10, 27, 41, 255); + else + return Color.FromRgb(0, 0, 0); } /// @@ -591,7 +496,7 @@ namespace Microsoft.Maui.Controls.Compatibility /// public static int ConvertToScaledPixel(double dp) { - return (int)Math.Round(dp * Device.Info.ScalingFactor); + return (int)Math.Round(dp * s_scalingFactor.Value); } /// @@ -604,7 +509,9 @@ namespace Microsoft.Maui.Controls.Compatibility /// public static double ConvertToScaledDP(int pixel) { - return pixel / Device.Info.ScalingFactor; + if (pixel == int.MaxValue) + return double.PositiveInfinity; + return pixel / s_scalingFactor.Value; } /// @@ -617,7 +524,9 @@ namespace Microsoft.Maui.Controls.Compatibility /// public static double ConvertToScaledDP(double pixel) { - return pixel / Device.Info.ScalingFactor; + if (pixel == double.PositiveInfinity) + return double.PositiveInfinity; + return pixel / s_scalingFactor.Value; } /// @@ -660,7 +569,7 @@ namespace Microsoft.Maui.Controls.Compatibility { Elementary.Initialize(); Elementary.ThemeOverlay(); - var window = new PreloadedWindow(); + var window = new Microsoft.Maui.Controls.Compatibility.Platform.Tizen.PreloadedWindow(); TSystemInfo.TryGetValue("http://tizen.org/feature/screen.width", out int width); TSystemInfo.TryGetValue("http://tizen.org/feature/screen.height", out int height); } diff --git a/src/Compatibility/Core/src/Tizen/FormsApplication.cs b/src/Compatibility/Core/src/Tizen/FormsApplication.cs index 593437afae..330de47c62 100644 --- a/src/Compatibility/Core/src/Tizen/FormsApplication.cs +++ b/src/Compatibility/Core/src/Tizen/FormsApplication.cs @@ -7,20 +7,23 @@ using ElmSharp; using ElmSharp.Wearable; using Tizen.Applications; using Tizen.Common; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; -using DeviceOrientation = Microsoft.Maui.Controls.Compatibility.Internals.DeviceOrientation; +using Microsoft.Maui.Devices; +using EWindow = ElmSharp.Window; using ELayout = ElmSharp.Layout; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Application; +using EDisplayRotation = ElmSharp.DisplayRotation; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Application; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class FormsApplication : CoreUIApplication { ITizenPlatform _platform; Application _application; - Window _window; + EWindow _window; bool _useBezelInteration; protected FormsApplication() @@ -31,7 +34,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// Gets the main window or null if it's not set. /// /// The main window or null. - public Window MainWindow + public EWindow MainWindow { get { @@ -67,20 +70,20 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Environment.SetEnvironmentVariable("XDG_DATA_HOME", Current.DirectoryInfo.Data); } - var type = typeof(Window); + var type = typeof(EWindow); // Use reflection to avoid breaking compatibility. ElmSharp.Window.CreateWindow() is has been added since API6. var methodInfo = type.GetMethod("CreateWindow", BindingFlags.NonPublic | BindingFlags.Static); - Window window = null; + EWindow window = null; if (methodInfo != null) { - window = (Window)methodInfo.Invoke(null, new object[] { "FormsWindow" }); + window = (EWindow)methodInfo.Invoke(null, new object[] { "FormsWindow" }); BaseLayout = (ELayout)window.GetType().GetProperty("BaseLayout")?.GetValue(window); BaseCircleSurface = (CircleSurface)window.GetType().GetProperty("BaseCircleSurface")?.GetValue(window); Forms.CircleSurface = BaseCircleSurface; } else // in case of Xamarin Preload { - window = PreloadedWindow.GetInstance() ?? new Window("FormsWindow"); + window = PreloadedWindow.GetInstance() ?? new EWindow("FormsWindow"); if (window is PreloadedWindow precreated) { BaseLayout = precreated.BaseLayout; @@ -128,7 +131,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (null == MainWindow) { - throw new InvalidOperationException("MainWindow is not prepared. This method should be called in OnCreated()."); + throw new InvalidOperationException("MainEWindow is not prepared. This method should be called in OnCreated()."); } if (null == application) @@ -192,7 +195,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void InitializeWindow() { - Debug.Assert(MainWindow != null, "Window cannot be null"); + Debug.Assert(MainWindow != null, "EWindow cannot be null"); MainWindow.Active(); MainWindow.Show(); @@ -217,20 +220,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen conformant.SetContent(BaseLayout); } - MainWindow.AvailableRotations = DisplayRotation.Degree_0 | DisplayRotation.Degree_90 | DisplayRotation.Degree_180 | DisplayRotation.Degree_270; + MainWindow.AvailableRotations = EDisplayRotation.Degree_0 | EDisplayRotation.Degree_90 | EDisplayRotation.Degree_180 | EDisplayRotation.Degree_270; MainWindow.Deleted += (s, e) => { Exit(); }; - Device.Info.CurrentOrientation = MainWindow.GetDeviceOrientation(); - - MainWindow.RotationChanged += (sender, e) => - { - Device.Info.CurrentOrientation = MainWindow.GetDeviceOrientation(); - }; - MainWindow.BackButtonPressed += (sender, e) => { if (_platform != null) @@ -275,25 +271,4 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen base.Exit(); } } - static class WindowExtension - { - public static DeviceOrientation GetDeviceOrientation(this Window window) - { - DeviceOrientation orientation = DeviceOrientation.Other; - var isPortraitDevice = Forms.NaturalOrientation.IsPortrait(); - switch (window.Rotation) - { - case 0: - case 180: - orientation = isPortraitDevice ? DeviceOrientation.Portrait : DeviceOrientation.Landscape; - break; - - case 90: - case 270: - orientation = isPortraitDevice ? DeviceOrientation.Landscape : DeviceOrientation.Portrait; - break; - } - return orientation; - } - } } diff --git a/src/Compatibility/Core/src/Tizen/GestureDetector.cs b/src/Compatibility/Core/src/Tizen/GestureDetector.cs index 6e41259bac..a5c7fca263 100644 --- a/src/Compatibility/Core/src/Tizen/GestureDetector.cs +++ b/src/Compatibility/Core/src/Tizen/GestureDetector.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Maui.Devices; using ElmSharp; using EGestureType = ElmSharp.GestureLayer.GestureType; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] internal class GestureDetector { readonly IDictionary> _handlerCache; diff --git a/src/Compatibility/Core/src/Tizen/GestureHandler.cs b/src/Compatibility/Core/src/Tizen/GestureHandler.cs index 763523013d..0df0a99280 100644 --- a/src/Compatibility/Core/src/Tizen/GestureHandler.cs +++ b/src/Compatibility/Core/src/Tizen/GestureHandler.cs @@ -4,6 +4,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public abstract class GestureHandler : IGestureController, INotifyPropertyChanged, IRegisterable { public IGestureRecognizer Recognizer { get; private set; } diff --git a/src/Compatibility/Core/src/Tizen/HandlerToRendererShim.cs b/src/Compatibility/Core/src/Tizen/HandlerToRendererShim.cs new file mode 100644 index 0000000000..22489b74cd --- /dev/null +++ b/src/Compatibility/Core/src/Tizen/HandlerToRendererShim.cs @@ -0,0 +1,196 @@ +using System; +using System.ComponentModel; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Handlers; +using Rect = Microsoft.Maui.Graphics.Rect; +using ERect = ElmSharp.Rect; +using EvasObject = ElmSharp.EvasObject; + +namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen +{ +#pragma warning disable CS0612 // Type or member is obsolete + public class HandlerToRendererShim : IVisualElementRenderer +#pragma warning disable CS0612 // Type or member is obsolete + { + bool _disposed; + + public HandlerToRendererShim(IPlatformViewHandler vh) + { + Compatibility.Hosting.MauiAppBuilderExtensions.CheckForCompatibility(); + ViewHandler = vh; + } + + IPlatformViewHandler ViewHandler { get; } + + public VisualElement Element { get; private set; } + + public EvasObject NativeView => ViewHandler.ContainerView ?? ViewHandler.PlatformView; + + public event EventHandler ElementChanged; + public event EventHandler ElementPropertyChanged; + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + Platform.SetRenderer(Element, null); + ViewHandler.Dispose(); + } + } + + public void SetElement(VisualElement element) + { + var oldElement = Element; + + if (oldElement != null) + { + oldElement.PropertyChanged -= OnElementPropertyChanged; + oldElement.BatchCommitted -= OnBatchCommitted; + } + + if (element != null) + { + element.PropertyChanged += OnElementPropertyChanged; + element.BatchCommitted += OnBatchCommitted; + } + + Element = element; + ((IView)element).Handler = ViewHandler; + Platform.SetRenderer(element, this); + + if (ViewHandler.VirtualView != element) + ViewHandler.SetVirtualView((IView)element); + + if (element.RealParent is IView view && view.Handler is IPlatformViewHandler nvh) + { + ViewHandler.SetParent(nvh); + } + else + { + ViewHandler.SetParent(new MockParentHandler(element.RealParent as VisualElement)); + } + + NativeView.Deleted += OnNativeDeleted; + ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(oldElement, Element)); + } + + void OnBatchCommitted(object sender, EventArg e) + { + ViewHandler?.PlatformArrange(Element.Bounds); + } + + void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + { + ElementPropertyChanged?.Invoke(this, new PropertyChangedEventArgs(e.PropertyName)); + } + + void OnNativeDeleted(object sender, EventArgs e) + { + Dispose(); + } + + public SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) + { + return ViewHandler.GetDesiredSize(widthConstraint, heightConstraint); + } + + public void SetElementSize(Size size) + { + Layout.LayoutChildIntoBoundingRegion(Element, new Rect(Element.X, Element.Y, size.Width, size.Height)); + } + + public void UpdateLayout() + { + ViewHandler.PlatformArrange(Element.Bounds); + } + + public ERect GetNativeContentGeometry() + { + return NativeView.Geometry; + } + + class MockParentHandler : IPlatformViewHandler + { + + public MockParentHandler(VisualElement parent) + { + RealParent = parent; + } + + VisualElement RealParent { get; } + IVisualElementRenderer Renderer => RealParent != null ? Platform.GetRenderer(RealParent) : null; + public EvasObject PlatformView => Renderer.NativeView; + + public EvasObject ContainerView => PlatformView; + + public IPlatformViewHandler Parent => null; + + public IView VirtualView => Renderer.Element as IView; + + public IMauiContext MauiContext => null; + + object IElementHandler.PlatformView => PlatformView; + + object IViewHandler.ContainerView => PlatformView; + + bool IViewHandler.HasContainer { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + Maui.IElement IElementHandler.VirtualView => throw new NotImplementedException(); + + public void DisconnectHandler() { } + + public void Dispose() + { + } + + public Size GetDesiredSize(double widthConstraint, double heightConstraint) + { + throw new NotImplementedException(); + } + + public ERect GetPlatformContentGeometry() + { + return Renderer?.GetNativeContentGeometry() ?? new ERect(0, 0, 0, 0); + } + + public void PlatformArrange(Rect frame) + { + throw new NotImplementedException(); + } + + public void SetMauiContext(IMauiContext mauiContext) + { + throw new NotImplementedException(); + } + + public void SetParent(IPlatformViewHandler parent) + { + throw new NotImplementedException(); + } + + public void SetVirtualView(IView view) + { + throw new NotImplementedException(); + } + + public void UpdateValue(string property) + { + throw new NotImplementedException(); + } + + public void SetVirtualView(Maui.IElement view) + { + throw new NotImplementedException(); + } + + public void Invoke(string command, object args) + { + throw new NotImplementedException(); + } + } + + } +} diff --git a/src/Compatibility/Core/src/Tizen/IMEApplication.cs b/src/Compatibility/Core/src/Tizen/IMEApplication.cs index d874fa78b3..96c07ef780 100644 --- a/src/Compatibility/Core/src/Tizen/IMEApplication.cs +++ b/src/Compatibility/Core/src/Tizen/IMEApplication.cs @@ -4,6 +4,7 @@ using Tizen.Uix.InputMethod; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class IMEApplication : FormsApplication { public EditorWindow EditorWindow diff --git a/src/Compatibility/Core/src/Tizen/LightweightPlatform.cs b/src/Compatibility/Core/src/Tizen/LightweightPlatform.cs index 357ae26b64..71e4046944 100644 --- a/src/Compatibility/Core/src/Tizen/LightweightPlatform.cs +++ b/src/Compatibility/Core/src/Tizen/LightweightPlatform.cs @@ -3,11 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Devices; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class LightweightPlatform : ITizenPlatform, INavigation, IDisposable { NavigationModel _navModel = new NavigationModel(); diff --git a/src/Compatibility/Core/src/Tizen/Log/XamarinLogListener.cs b/src/Compatibility/Core/src/Tizen/Log/XamarinLogListener.cs deleted file mode 100644 index 5105ecf5ca..0000000000 --- a/src/Compatibility/Core/src/Tizen/Log/XamarinLogListener.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.Maui.Controls.Compatibility.Internals; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ - internal class XamarinLogListener : LogListener - { - public XamarinLogListener() - { - } - - #region implemented abstract members of LogListener - - public override void Warning(string category, string message) - { - Log.Warn("[{0}] {1}", category, message); - } - - #endregion - } -} diff --git a/src/Compatibility/Core/src/Tizen/Native/BorderRectangle.cs b/src/Compatibility/Core/src/Tizen/Native/BorderRectangle.cs index 13836a28d5..db0dcdb2c3 100644 --- a/src/Compatibility/Core/src/Tizen/Native/BorderRectangle.cs +++ b/src/Compatibility/Core/src/Tizen/Native/BorderRectangle.cs @@ -35,7 +35,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native radius[2] = Math.Min(bottomLeft, maxR); radius[3] = Math.Min(bottomRight, maxR); - Point first = new Point(-1, -1); + Graphics.Point first = new Graphics.Point(-1, -1); for (int i = 0; i <= radius[0]; i++) { int x = i; diff --git a/src/Compatibility/Core/src/Tizen/Native/Button.cs b/src/Compatibility/Core/src/Tizen/Native/Button.cs index 3e70f482dc..f53ecefb66 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Button.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Button.cs @@ -3,7 +3,7 @@ using ElmSharp; using EButton = ElmSharp.Button; using EColor = ElmSharp.Color; using ESize = ElmSharp.Size; -using TSButtonStyle = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.ButtonStyle; +using TSButtonStyle = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.ButtonStyle; #if __MATERIAL__ using Tizen.NET.MaterialComponents; diff --git a/src/Compatibility/Core/src/Tizen/Native/CollectionView/CollectionView.cs b/src/Compatibility/Core/src/Tizen/Native/CollectionView/CollectionView.cs index ac6bbf9f85..46dbbefb1d 100644 --- a/src/Compatibility/Core/src/Tizen/Native/CollectionView/CollectionView.cs +++ b/src/Compatibility/Core/src/Tizen/Native/CollectionView/CollectionView.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; +using Microsoft.Maui.Devices; using ElmSharp; using ElmSharp.Wearable; using EBox = ElmSharp.Box; @@ -332,7 +333,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native if (holder.State == ViewHolderState.Focused && FocusedItemScrollPosition != ScrollToPosition.MakeVisible) { - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { if (holder.State == ViewHolderState.Focused && _viewHolderIndexTable.TryGetValue(holder, out int itemIndex)) { @@ -613,7 +614,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native Scroller.HorizontalStepSize = _layoutManager.GetScrollBlockSize(); Scroller.VerticalStepSize = _layoutManager.GetScrollBlockSize(); UpdateSnapPointsType(SnapPointsType); - Device.BeginInvokeOnMainThread(SendScrolledEvent); + Application.Current.Dispatcher.Dispatch(SendScrolledEvent); } } @@ -625,7 +626,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native if (!_requestLayoutItems) { _requestLayoutItems = true; - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { _requestLayoutItems = false; if (_adaptor != null && _layoutManager != null) diff --git a/src/Compatibility/Core/src/Tizen/Native/CollectionView/EmptyItemAdaptor.cs b/src/Compatibility/Core/src/Tizen/Native/CollectionView/EmptyItemAdaptor.cs index f0c8113df6..f194c7e3a6 100644 --- a/src/Compatibility/Core/src/Tizen/Native/CollectionView/EmptyItemAdaptor.cs +++ b/src/Compatibility/Core/src/Tizen/Native/CollectionView/EmptyItemAdaptor.cs @@ -2,10 +2,12 @@ using System.Collections; using System.Collections.Generic; using ElmSharp; using ESize = ElmSharp.Size; -using XLabel = Microsoft.Maui.Controls.Compatibility.Label; +using XLabel = Microsoft.Maui.Controls.Label; +using XStackLayout = Microsoft.Maui.Controls.StackLayout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { + [System.Obsolete] public class EmptyItemAdaptor : ItemTemplateAdaptor, IEmptyAdaptor { static DataTemplate s_defaultEmptyTemplate = new DataTemplate(typeof(EmptyView)); @@ -56,7 +58,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native var header = CreateHeaderView(); var footer = CreateFooterView(); - var layout = new StackLayout(); + var layout = new XStackLayout(); if (header != null) { @@ -79,20 +81,20 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native native.Unrealize(); } - class EmptyView : StackLayout + class EmptyView : XStackLayout { public EmptyView() { - HorizontalOptions = LayoutOptions.FillAndExpand; - VerticalOptions = LayoutOptions.FillAndExpand; + HorizontalOptions = LayoutOptions.Fill; + VerticalOptions = LayoutOptions.Fill; Children.Add( new XLabel { Text = "No items found", - VerticalOptions = LayoutOptions.CenterAndExpand, - HorizontalOptions = LayoutOptions.CenterAndExpand, - HorizontalTextAlignment = Microsoft.Maui.Controls.Compatibility.TextAlignment.Center, - VerticalTextAlignment = Microsoft.Maui.Controls.Compatibility.TextAlignment.Center, + VerticalOptions = LayoutOptions.Center, + HorizontalOptions = LayoutOptions.Center, + HorizontalTextAlignment = Maui.TextAlignment.Center, + VerticalTextAlignment = Maui.TextAlignment.Center, } ); } diff --git a/src/Compatibility/Core/src/Tizen/Native/CollectionView/GridLayoutManager.cs b/src/Compatibility/Core/src/Tizen/Native/CollectionView/GridLayoutManager.cs index 28b3699108..595b532a45 100644 --- a/src/Compatibility/Core/src/Tizen/Native/CollectionView/GridLayoutManager.cs +++ b/src/Compatibility/Core/src/Tizen/Native/CollectionView/GridLayoutManager.cs @@ -111,8 +111,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native int ItemSpacing => IsHorizontal ? HorizontalItemSpacing : VerticalItemSpacing; - int ItemWidthConstraint => IsHorizontal ? _allocatedSize.Width * 100 : ColumnSize; - int ItemHeightConstraint => IsHorizontal ? ColumnSize : _allocatedSize.Height * 100; + // It is a rule, if you want to fit with a content natural size, constraint should be infinity + int ItemWidthConstraint => IsHorizontal ? int.MaxValue : ColumnSize; + int ItemHeightConstraint => IsHorizontal ? ColumnSize : int.MaxValue; int ColumnSize { @@ -404,7 +405,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native public int GetVisibleItemIndex(int x, int y) { int index = 0; - if (x < 0 || y < 0) + if (x < 0 || y < 0 || _accumulatedItemSizes == null) return index; if (_scrollCanvasSize.Width < x || _scrollCanvasSize.Height < y) return CollectionView.Count - 1; diff --git a/src/Compatibility/Core/src/Tizen/Native/CollectionView/IndicatorView.cs b/src/Compatibility/Core/src/Tizen/Native/CollectionView/IndicatorView.cs index 7680b996c9..593c4a6984 100644 --- a/src/Compatibility/Core/src/Tizen/Native/CollectionView/IndicatorView.cs +++ b/src/Compatibility/Core/src/Tizen/Native/CollectionView/IndicatorView.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using Microsoft.Maui.Devices; using ElmSharp; +using Index = ElmSharp.Index; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { diff --git a/src/Compatibility/Core/src/Tizen/Native/CollectionView/ItemTemplateAdaptor.cs b/src/Compatibility/Core/src/Tizen/Native/CollectionView/ItemTemplateAdaptor.cs index 7444dbcd09..9c0e8ea7df 100644 --- a/src/Compatibility/Core/src/Tizen/Native/CollectionView/ItemTemplateAdaptor.cs +++ b/src/Compatibility/Core/src/Tizen/Native/CollectionView/ItemTemplateAdaptor.cs @@ -4,10 +4,13 @@ using System.Collections.Generic; using System.Globalization; using ElmSharp; using ESize = ElmSharp.Size; -using XLabel = Microsoft.Maui.Controls.Compatibility.Label; +using XLabel = Microsoft.Maui.Controls.Label; +using XColor = Microsoft.Maui.Graphics.Color; +using XStackLayout = Microsoft.Maui.Controls.StackLayout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { + [Obsolete] public class ItemDefaultTemplateAdaptor : ItemTemplateAdaptor { class ToTextConverter : IValueConverter @@ -26,13 +29,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { var label = new XLabel { - TextColor = Color.Black, + TextColor = XColor.FromRgb(0,0,0), }; label.SetBinding(XLabel.TextProperty, new Binding(".", converter: new ToTextConverter())); - return new StackLayout + return new XStackLayout { - BackgroundColor = Color.White, + BackgroundColor = XColor.FromRgb(255, 255, 255), Padding = 30, Children = { @@ -43,6 +46,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native } } + [Obsolete] public class ItemTemplateAdaptor : ItemAdaptor { Dictionary _nativeFormsTable = new Dictionary(); @@ -182,7 +186,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { if (_dataBindedViewTable.TryGetValue(this[index], out View createdView) && createdView != null) { - return createdView.Measure(Forms.ConvertToScaledDP(widthConstraint), Forms.ConvertToScaledDP(heightConstraint), MeasureFlags.IncludeMargins).Request.ToPixel(); + return createdView.Measure(Forms.ConvertToScaledDP(widthConstraint), Forms.ConvertToScaledDP(heightConstraint), MeasureFlags.IncludeMargins).Request.ToEFLPixel(); } View view = null; @@ -200,18 +204,18 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native if (Count > index) view.BindingContext = this[index]; var request = view.Measure(Forms.ConvertToScaledDP(widthConstraint), Forms.ConvertToScaledDP(heightConstraint), MeasureFlags.IncludeMargins).Request; - return request.ToPixel(); + return request.ToEFLPixel(); } } public override ESize MeasureHeader(int widthConstraint, int heightConstraint) { - return _headerCache?.Measure(Forms.ConvertToScaledDP(widthConstraint), Forms.ConvertToScaledDP(heightConstraint)).Request.ToPixel() ?? new ESize(0, 0); + return _headerCache?.Measure(Forms.ConvertToScaledDP(widthConstraint), Forms.ConvertToScaledDP(heightConstraint)).Request.ToEFLPixel() ?? new ESize(0, 0); } public override ESize MeasureFooter(int widthConstraint, int heightConstraint) { - return _footerCache?.Measure(Forms.ConvertToScaledDP(widthConstraint), Forms.ConvertToScaledDP(heightConstraint)).Request.ToPixel() ?? new ESize(0, 0); + return _footerCache?.Measure(Forms.ConvertToScaledDP(widthConstraint), Forms.ConvertToScaledDP(heightConstraint)).Request.ToEFLPixel() ?? new ESize(0, 0); } public override void UpdateViewState(EvasObject view, ViewHolderState state) diff --git a/src/Compatibility/Core/src/Tizen/Native/CollectionView/LinearLayoutManager.cs b/src/Compatibility/Core/src/Tizen/Native/CollectionView/LinearLayoutManager.cs index 414cf3b8ea..d5e32d2b9b 100644 --- a/src/Compatibility/Core/src/Tizen/Native/CollectionView/LinearLayoutManager.cs +++ b/src/Compatibility/Core/src/Tizen/Native/CollectionView/LinearLayoutManager.cs @@ -100,8 +100,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native } } - int ItemWidthConstraint => IsHorizontal ? _allocatedSize.Width * 100 : _allocatedSize.Width; - int ItemHeightConstraint => IsHorizontal ? _allocatedSize.Height : _allocatedSize.Height * 100; + // It is a rule, if you want to fit with a content natural size, constraint should be infinity + int ItemWidthConstraint => IsHorizontal ? int.MaxValue : _allocatedSize.Width; + int ItemHeightConstraint => IsHorizontal ? _allocatedSize.Height : int.MaxValue; int FooterSize => IsHorizontal ? _footerSize.Width : _footerSize.Height; int HeaderSize => IsHorizontal ? _headerSize.Width : _headerSize.Height; diff --git a/src/Compatibility/Core/src/Tizen/Native/DateTimePickerDialog.cs b/src/Compatibility/Core/src/Tizen/Native/DateTimePickerDialog.cs index 11ddcb5c1a..03234ecf48 100644 --- a/src/Compatibility/Core/src/Tizen/Native/DateTimePickerDialog.cs +++ b/src/Compatibility/Core/src/Tizen/Native/DateTimePickerDialog.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Maui.Devices; using ElmSharp; using EButton = ElmSharp.Button; diff --git a/src/Compatibility/Core/src/Tizen/Native/Dialog.cs b/src/Compatibility/Core/src/Tizen/Native/Dialog.cs index 3bad6f74af..10c4f292cf 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Dialog.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Dialog.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Maui.Devices; using ElmSharp; using EButton = ElmSharp.Button; using EColor = ElmSharp.Color; @@ -56,7 +57,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native /// /// Occurs whenever the dialog is first displayed. /// - public event EventHandler Shown; + public event EventHandler DialogShown; /// /// Gets or sets the title of the dialog @@ -194,7 +195,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native public new void Show() { base.Show(); - Shown?.Invoke(this, EventArgs.Empty); + DialogShown?.Invoke(this, EventArgs.Empty); } /// @@ -301,7 +302,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native // Adds a handler for the Shown event. // In effect, registers this instance to be affected by the hardware back key presses. - Shown += (s, e) => + DialogShown += (s, e) => { OnShown(); }; diff --git a/src/Compatibility/Core/src/Tizen/Native/EditfieldEntry.cs b/src/Compatibility/Core/src/Tizen/Native/EditfieldEntry.cs index a2d20154e6..b66ab8f583 100644 --- a/src/Compatibility/Core/src/Tizen/Native/EditfieldEntry.cs +++ b/src/Compatibility/Core/src/Tizen/Native/EditfieldEntry.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Maui.Devices; using ElmSharp; using EColor = ElmSharp.Color; using ELayout = ElmSharp.Layout; diff --git a/src/Compatibility/Core/src/Tizen/Native/Entry.cs b/src/Compatibility/Core/src/Tizen/Native/Entry.cs index 4a914642ab..27579173d3 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Entry.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Entry.cs @@ -105,11 +105,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native var old = _span.Text; _span.Text = value; ApplyTextAndStyle(); - Device.StartTimer(TimeSpan.FromTicks(1), () => - { - OnTextChanged(old, value); - return false; - }); + Application.Current.Dispatcher.DispatchDelayed(TimeSpan.FromTicks(1), () => OnTextChanged(old, value)); } } } diff --git a/src/Compatibility/Core/src/Tizen/Native/FlyoutPage.cs b/src/Compatibility/Core/src/Tizen/Native/FlyoutPage.cs index bcd12ec388..ce3841aac8 100644 --- a/src/Compatibility/Core/src/Tizen/Native/FlyoutPage.cs +++ b/src/Compatibility/Core/src/Tizen/Native/FlyoutPage.cs @@ -1,6 +1,7 @@ using System; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Devices; +using Microsoft.Maui.Controls.Internals; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { @@ -127,12 +128,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native // in case of the screen rotation we may need to update the choice between split // and popover behaviors and reconfigure the layout - Device.Info.PropertyChanged += (s, e) => + DeviceDisplay.MainDisplayInfoChanged += (s, e) => { - if (e.PropertyName == nameof(Device.Info.CurrentOrientation)) - { - UpdateFlyoutLayoutBehavior(); - } + UpdateFlyoutLayoutBehavior(); }; } @@ -352,7 +350,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native // Screen orientation affects those 2 behaviors if (behavior == FlyoutLayoutBehavior.SplitOnLandscape || behavior == FlyoutLayoutBehavior.SplitOnPortrait) { - var orientation = Device.Info.CurrentOrientation; + var orientation = DeviceDisplay.MainDisplayInfo.Orientation; if ((orientation.IsLandscape() && behavior == FlyoutLayoutBehavior.SplitOnLandscape) || (orientation.IsPortrait() && behavior == FlyoutLayoutBehavior.SplitOnPortrait)) { diff --git a/src/Compatibility/Core/src/Tizen/Native/ListView.cs b/src/Compatibility/Core/src/Tizen/Native/ListView.cs index 7e75e82bd3..e504d3711b 100644 --- a/src/Compatibility/Core/src/Tizen/Native/ListView.cs +++ b/src/Compatibility/Core/src/Tizen/Native/ListView.cs @@ -3,7 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.ComponentModel; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; using EColor = ElmSharp.Color; using ERect = ElmSharp.Rect; using EScroller = ElmSharp.Scroller; @@ -25,6 +25,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native /// Whenever element disappears from visible space its content is destroyed for time being. /// This is carried out by so called Cell Handlers. /// + [Obsolete] public class ListView : GenList { /// @@ -293,7 +294,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { GenListItem item = GetItemContext(cell)?.Item as GenListItem; if (item != null) - this.ScrollTo(item, position.ToPlatform(), animated); + this.ScrollTo(item, position.ToNative(), animated); } /// diff --git a/src/Compatibility/Core/src/Tizen/Native/Span.cs b/src/Compatibility/Core/src/Tizen/Native/Span.cs index 8ce1b31ed4..2b663171c9 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Span.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Span.cs @@ -1,7 +1,7 @@ using System; using System.Text; using EColor = ElmSharp.Color; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { @@ -257,10 +257,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native string ConvertTags(string text) { - return text.Replace("&", "&") - .Replace("<", "<") - .Replace(">", ">") - .Replace(Environment.NewLine, "
"); + return text.Replace("&", "&", StringComparison.Ordinal) + .Replace("<", "<", StringComparison.Ordinal) + .Replace(">", ">", StringComparison.Ordinal) + .Replace(Environment.NewLine, "
", StringComparison.Ordinal); } public string GetStyle() diff --git a/src/Compatibility/Core/src/Tizen/Native/TableView.cs b/src/Compatibility/Core/src/Tizen/Native/TableView.cs index 21162287e3..3b9621bf0b 100644 --- a/src/Compatibility/Core/src/Tizen/Native/TableView.cs +++ b/src/Compatibility/Core/src/Tizen/Native/TableView.cs @@ -5,6 +5,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native /// /// Extends the ListView class to provide TableView class implementation. /// + [System.Obsolete] public class TableView : ListView, ITableView { @@ -44,7 +45,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native /// /// Sets the section title. /// - void AddSectionTitle(string title, Color textColor) + void AddSectionTitle(string title, Graphics.Color textColor) { Cell cell = new SectionCell() { diff --git a/src/Compatibility/Core/src/Tizen/Native/TitleViewPage.cs b/src/Compatibility/Core/src/Tizen/Native/TitleViewPage.cs index 460befafd3..3697632d90 100644 --- a/src/Compatibility/Core/src/Tizen/Native/TitleViewPage.cs +++ b/src/Compatibility/Core/src/Tizen/Native/TitleViewPage.cs @@ -3,13 +3,14 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native { + [Obsolete] public class TitleViewPage : Native.Box { Native.Page _page = null; View _titleView = null; bool _hasNavigationBar = true; - public TitleViewPage(EvasObject parent, Microsoft.Maui.Controls.Compatibility.Page page, View titleView) : base(parent) + public TitleViewPage(EvasObject parent, Microsoft.Maui.Controls.Page page, View titleView) : base(parent) { _page = Platform.GetOrCreateRenderer(page).NativeView as Native.Page; _titleView = titleView; diff --git a/src/Compatibility/Core/src/Tizen/Native/Watch/FormsWatchLayout.cs b/src/Compatibility/Core/src/Tizen/Native/Watch/FormsWatchLayout.cs index 1ec60ad485..9d2e9972cc 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Watch/FormsWatchLayout.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Watch/FormsWatchLayout.cs @@ -1,3 +1,4 @@ +using Microsoft.Maui.Devices; using ElmSharp; using EColor = ElmSharp.Color; @@ -7,8 +8,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch { public FormsWatchLayout(EvasObject parent) : base(parent) { - if (Device.Idiom != TargetIdiom.Watch) - Log.Error($"{0} is only supported on TargetIdiom.Watch : {1}", this, Device.Idiom); + if (DeviceInfo.Idiom != DeviceIdiom.Watch) + Log.Error($"{0} is only supported on TargetIdiom.Watch : {1}", this, DeviceInfo.Idiom); } } diff --git a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchButton.cs b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchButton.cs index 70ecd2137e..6bde527a75 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchButton.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchButton.cs @@ -1,6 +1,6 @@ using System; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific; +using Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific; using ESize = ElmSharp.Size; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch diff --git a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchDateTimePickerDialog.cs b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchDateTimePickerDialog.cs index ea7e4e6cdc..891b0a6129 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchDateTimePickerDialog.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchDateTimePickerDialog.cs @@ -3,7 +3,7 @@ using ElmSharp; using ElmSharp.Wearable; using EButton = ElmSharp.Button; using ELayout = ElmSharp.Layout; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Application; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Application; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch { diff --git a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchListView.cs b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchListView.cs index 72dc5ff9ee..c0a365e0a7 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchListView.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchListView.cs @@ -5,6 +5,7 @@ using ElmSharp.Wearable; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch { + [Obsolete] public class WatchListView : Native.ListView, IRotaryActionWidget, IRotaryInteraction { CircleGenList _circleGenList; diff --git a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchTableView.cs b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchTableView.cs index 63b8e626ca..65ff1e120f 100644 --- a/src/Compatibility/Core/src/Tizen/Native/Watch/WatchTableView.cs +++ b/src/Compatibility/Core/src/Tizen/Native/Watch/WatchTableView.cs @@ -3,6 +3,7 @@ using ElmSharp.Wearable; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch { + [System.Obsolete] public class WatchTableView : WatchListView, ITableView { static readonly SectionCellRenderer _sectionCellRenderer = new SectionCellRenderer(); @@ -34,7 +35,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch return base.GetCellRenderer(cell, isGroup); } - void AddSectionTitle(string title, Color textColor) + void AddSectionTitle(string title, Graphics.Color textColor) { Cell cell = new SectionCell() { diff --git a/src/Compatibility/Core/src/Tizen/NativeBindingService.cs b/src/Compatibility/Core/src/Tizen/NativeBindingService.cs index adfc61627c..a4d7cc87b1 100644 --- a/src/Compatibility/Core/src/Tizen/NativeBindingService.cs +++ b/src/Compatibility/Core/src/Tizen/NativeBindingService.cs @@ -1,6 +1,5 @@ using System.Diagnostics.CodeAnalysis; -using Microsoft.Maui.Controls.Compatibility.Internals; -using Microsoft.Maui.Controls.Compatibility.Xaml.Internals; +using Microsoft.Maui.Controls.Xaml.Internals; using EObject = ElmSharp.EvasObject; @@ -11,6 +10,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen [UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = TrimmerConstants.NativeBindingService)] public bool TrySetBinding(object target, string propertyName, BindingBase binding) { + Hosting.MauiAppBuilderExtensions.CheckForCompatibility(); var view = target as EObject; if (view == null) return false; @@ -22,6 +22,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public bool TrySetBinding(object target, BindableProperty property, BindingBase binding) { + Hosting.MauiAppBuilderExtensions.CheckForCompatibility(); var view = target as EObject; if (view == null) return false; @@ -31,6 +32,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public bool TrySetValue(object target, BindableProperty property, object value) { + Hosting.MauiAppBuilderExtensions.CheckForCompatibility(); var view = target as EObject; if (view == null) return false; diff --git a/src/Compatibility/Core/src/Tizen/NativeValueConverterService.cs b/src/Compatibility/Core/src/Tizen/NativeValueConverterService.cs index 7b22f3bf55..274b9cf5a5 100644 --- a/src/Compatibility/Core/src/Tizen/NativeValueConverterService.cs +++ b/src/Compatibility/Core/src/Tizen/NativeValueConverterService.cs @@ -1,6 +1,5 @@ using System; -using Microsoft.Maui.Controls.Compatibility.Internals; -using Microsoft.Maui.Controls.Compatibility.Xaml.Internals; +using Microsoft.Maui.Controls.Xaml.Internals; using EObject = ElmSharp.EvasObject; @@ -10,6 +9,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { public bool ConvertTo(object value, Type toType, out object nativeValue) { + Hosting.MauiAppBuilderExtensions.CheckForCompatibility(); nativeValue = null; if ((value is EObject) && toType.IsAssignableFrom(typeof(View))) { diff --git a/src/Compatibility/Core/src/Tizen/NativeViewWrapper.cs b/src/Compatibility/Core/src/Tizen/NativeViewWrapper.cs index 32a4251aa6..3aee745950 100644 --- a/src/Compatibility/Core/src/Tizen/NativeViewWrapper.cs +++ b/src/Compatibility/Core/src/Tizen/NativeViewWrapper.cs @@ -5,7 +5,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { public delegate ESize? MeasureDelegate(NativeViewWrapperRenderer renderer, int availableWidth, int availableHeight); +#pragma warning disable CS0618 // Type or member is obsolete public class NativeViewWrapper : View +#pragma warning disable CS0618 // Type or member is obsolete { public NativeViewWrapper(EvasObject obj, MeasureDelegate measureDelegate = null) { diff --git a/src/Compatibility/Core/src/Tizen/PanGestureHandler.cs b/src/Compatibility/Core/src/Tizen/PanGestureHandler.cs index c6c90f60f4..8a3213fa1f 100644 --- a/src/Compatibility/Core/src/Tizen/PanGestureHandler.cs +++ b/src/Compatibility/Core/src/Tizen/PanGestureHandler.cs @@ -4,6 +4,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class PanGestureHandler : GestureHandler { int _currentPanGestureId; diff --git a/src/Compatibility/Core/src/Tizen/PinchGestureHandler.cs b/src/Compatibility/Core/src/Tizen/PinchGestureHandler.cs index 3e7cbf8bc4..a5888f2935 100644 --- a/src/Compatibility/Core/src/Tizen/PinchGestureHandler.cs +++ b/src/Compatibility/Core/src/Tizen/PinchGestureHandler.cs @@ -4,9 +4,10 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class PinchGestureHandler : GestureHandler { - Point _currentScalePoint; + Graphics.Point _currentScalePoint; int _previousPinchRadius; double _originalPinchScale; @@ -26,7 +27,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { var geometry = Platform.GetRenderer(sender).NativeView.Geometry; var zoomData = (GestureLayer.ZoomData)data; - _currentScalePoint = new Point((zoomData.X - geometry.X) / (double)geometry.Width, (zoomData.Y - geometry.Y) / (double)geometry.Height); + _currentScalePoint = new Graphics.Point((zoomData.X - geometry.X) / (double)geometry.Width, (zoomData.Y - geometry.Y) / (double)geometry.Height); _originalPinchScale = sender.Scale; _previousPinchRadius = zoomData.Radius; (Recognizer as IPinchGestureController)?.SendPinchStarted(sender, _currentScalePoint); diff --git a/src/Compatibility/Core/src/Tizen/Platform.cs b/src/Compatibility/Core/src/Tizen/Platform.cs index c89281a4e9..0ef8670bf9 100644 --- a/src/Compatibility/Core/src/Tizen/Platform.cs +++ b/src/Compatibility/Core/src/Tizen/Platform.cs @@ -5,20 +5,28 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Handlers; -[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Material")] +[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Material")] namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public static class Platform { internal static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(IVisualElementRenderer), typeof(Platform), default(IVisualElementRenderer), propertyChanged: (bindable, oldvalue, newvalue) => { - var ve = bindable as VisualElement; - if (ve != null && newvalue == null) - ve.IsPlatformEnabled = false; + var view = bindable as VisualElement; + if (view != null) + view.IsPlatformEnabled = newvalue != null; + + if (bindable is IView mauiView) + { + if (mauiView.Handler == null && newvalue is IVisualElementRenderer ver) + mauiView.Handler = new RendererToHandlerShim(ver); + } }); public static IVisualElementRenderer GetRenderer(BindableObject bindable) @@ -43,14 +51,58 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen internal static IVisualElementRenderer CreateRenderer(VisualElement element) { - IVisualElementRenderer renderer = Forms.GetHandlerForObject(element) ?? new DefaultRenderer(); + IVisualElementRenderer renderer = null; + + if (renderer == null) + { + IViewHandler handler = null; + + //TODO: Handle this with AppBuilderHost + try + { + handler = Forms.MauiContext.Handlers.GetHandler(element.GetType()) as IViewHandler; + handler.SetMauiContext(Forms.MauiContext); + } + catch + { + // TODO define better catch response or define if this is needed? + } + + if (handler == null) + { + renderer = Forms.GetHandlerForObject(element) ?? new DefaultRenderer(); + } + // This means the only thing registered is the RendererToHandlerShim + // Which is only used when you are running a .NET MAUI app + // This indicates that the user hasn't registered a specific handler for this given type + else if (handler is RendererToHandlerShim shim) + { + renderer = shim.VisualElementRenderer; + + if (renderer == null) + { + renderer = Forms.GetHandlerForObject(element) ?? new DefaultRenderer(); + } + } + else if (handler is IVisualElementRenderer ver) + renderer = ver; + else if (handler is IPlatformViewHandler vh) + { + if (element.Parent is IView view && view.Handler is IPlatformViewHandler nvh) + { + vh.SetParent(nvh); + } + renderer = new HandlerToRendererShim(vh); + element.Handler = handler; + } + } renderer.SetElement(element); return renderer; } internal static ITizenPlatform CreatePlatform(EvasObject parent) { - if (Forms.PlatformType == PlatformType.Lightweight || Forms.Flags.Contains(Flags.LightweightPlatformExperimental)) + if (Forms.PlatformType == PlatformType.Lightweight) { return new LightweightPlatform(parent); } @@ -63,10 +115,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen widthConstraint = widthConstraint <= -1 ? double.PositiveInfinity : widthConstraint; heightConstraint = heightConstraint <= -1 ? double.PositiveInfinity : heightConstraint; - double width = !double.IsPositiveInfinity(widthConstraint) ? widthConstraint : Int32.MaxValue; - double height = !double.IsPositiveInfinity(heightConstraint) ? heightConstraint : Int32.MaxValue; + var renderView = GetRenderer(view); + if (renderView == null || renderView.NativeView == null) + { + return (view is IView iView) ? new SizeRequest(iView.Handler.GetDesiredSize(widthConstraint, heightConstraint)) : new SizeRequest(Graphics.Size.Zero); + } - return Platform.GetRenderer(view).GetDesiredSize(width, height); + return renderView.GetDesiredSize(widthConstraint, heightConstraint); } } @@ -87,6 +142,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public EvasObject RootNativeView { get; private set; } } + [Obsolete] public class DefaultPlatform : BindableObject, ITizenPlatform, INavigation { NavigationModel _navModel = new NavigationModel(); @@ -179,11 +235,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen ((Application)Page.RealParent).NavigationProxy.Inner = this; - Device.StartTimer(TimeSpan.Zero, () => - { - CurrentPageController?.SendAppearing(); - return false; - }); + Application.Current.Dispatcher.DispatchDelayed(TimeSpan.Zero, () => CurrentPageController?.SendAppearing()); } public bool SendBackButtonPressed() @@ -281,7 +333,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen async Task INavigation.PushModalAsync(Page modal, bool animated) { var previousPage = CurrentPageController; - Device.BeginInvokeOnMainThread(() => previousPage?.SendDisappearing()); + Application.Current.Dispatcher.Dispatch(() => previousPage?.SendDisappearing()); _navModel.PushModal(modal); diff --git a/src/Compatibility/Core/src/Tizen/PlatformEffect.cs b/src/Compatibility/Core/src/Tizen/PlatformEffect.cs deleted file mode 100644 index d5875e1577..0000000000 --- a/src/Compatibility/Core/src/Tizen/PlatformEffect.cs +++ /dev/null @@ -1,11 +0,0 @@ -using ElmSharp; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ - /// - /// Base class for platform-specific effect classes. - /// - public abstract class PlatformEffect : PlatformEffect - { - } -} diff --git a/src/Compatibility/Core/src/Tizen/PopupManager.cs b/src/Compatibility/Core/src/Tizen/PopupManager.cs index 131a49fc19..c830f19774 100644 --- a/src/Compatibility/Core/src/Tizen/PopupManager.cs +++ b/src/Compatibility/Core/src/Tizen/PopupManager.cs @@ -1,14 +1,18 @@ using System; using System.Collections.Generic; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; -using Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific; +using Microsoft.Maui.Devices; using EButton = ElmSharp.Button; using EColor = ElmSharp.Color; using EProgressBar = ElmSharp.ProgressBar; +using Color = Microsoft.Maui.Graphics.Color; +using XStackLayout = Microsoft.Maui.Controls.StackLayout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class PopupManager : IDisposable { ITizenPlatform _platform; @@ -23,7 +27,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen MessagingCenter.Subscribe(this, Page.AlertSignalName, OnAlertRequest); MessagingCenter.Subscribe(this, Page.ActionSheetSignalName, OnActionSheetRequest); MessagingCenter.Subscribe(this, Page.PromptSignalName, OnPromptRequested); - } + } public void Dispose() { @@ -93,7 +97,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var alert = Native.Dialog.CreateDialog(Forms.NativeParent, (arguments.Accept != null)); alert.Title = arguments.Title; - var message = arguments.Message?.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace(Environment.NewLine, "
"); + var message = arguments.Message?.Replace("&", "&", StringComparison.Ordinal).Replace("<", "<", StringComparison.Ordinal).Replace(">", ">", StringComparison.Ordinal).Replace(Environment.NewLine, "
", StringComparison.Ordinal); alert.Message = message; var cancel = new EButton(alert) { Text = arguments.Cancel }; @@ -211,9 +215,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var entry = new Entry { MinimumWidthRequest = 200, - HorizontalOptions = LayoutOptions.FillAndExpand, + HorizontalOptions = LayoutOptions.Fill, BackgroundColor = Color.FromRgb(250, 250, 250), - TextColor = Color.Black, + TextColor = Color.FromRgb(0, 0, 0), Keyboard = args.Keyboard, }; @@ -226,7 +230,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen entry.MaxLength = args.MaxLength; } - var layout = new StackLayout + var layout = new XStackLayout { Spacing = 10, Children = @@ -234,11 +238,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen new Label { LineBreakMode = LineBreakMode.CharacterWrap, - TextColor = DeviceInfo.Idiom == DeviceIdiom.Watch ? Color.White : Color.Accent, + TextColor = DeviceInfo.Idiom == DeviceIdiom.Watch ? Color.FromRgb(255,255,255) : Application.AccentColor, Text = args.Message, - HorizontalOptions = LayoutOptions.FillAndExpand, + HorizontalOptions = LayoutOptions.Fill, HorizontalTextAlignment = TextAlignment.Center, +#pragma warning disable CS0612 // Type or member is obsolete FontSize = Device.GetNamedSize(NamedSize.Subtitle, typeof(Label)), +#pragma warning disable CS0612 // Type or member is obsolete }, entry, } diff --git a/src/Compatibility/Core/src/Tizen/PreloadedWindow.cs b/src/Compatibility/Core/src/Tizen/PreloadedWindow.cs index b92adb9aea..baa8aadf2f 100644 --- a/src/Compatibility/Core/src/Tizen/PreloadedWindow.cs +++ b/src/Compatibility/Core/src/Tizen/PreloadedWindow.cs @@ -1,10 +1,11 @@ using ElmSharp; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; using ELayout = ElmSharp.Layout; +using EWindow = ElmSharp.Window; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { - public class PreloadedWindow : Window + public class PreloadedWindow : EWindow { static PreloadedWindow s_precreated; diff --git a/src/Compatibility/Core/src/Tizen/Properties/AssemblyInfo.cs b/src/Compatibility/Core/src/Tizen/Properties/AssemblyInfo.cs index 408ab48f44..54f1710e1f 100644 --- a/src/Compatibility/Core/src/Tizen/Properties/AssemblyInfo.cs +++ b/src/Compatibility/Core/src/Tizen/Properties/AssemblyInfo.cs @@ -1,79 +1,6 @@ -using Microsoft.Maui.Controls.Compatibility; -using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; -using Microsoft.Maui.Controls.Compatibility.Shapes; +using System.Runtime.CompilerServices; +using Microsoft.Maui.Controls.Internals; -[assembly: Dependency(typeof(ResourcesProvider))] -[assembly: Dependency(typeof(Deserializer))] -[assembly: Dependency(typeof(NativeBindingService))] -[assembly: Dependency(typeof(NativeValueConverterService))] - -[assembly: ExportRenderer(typeof(Layout), typeof(LayoutRenderer))] -[assembly: ExportRenderer(typeof(ScrollView), typeof(ScrollViewRenderer))] -[assembly: ExportRenderer(typeof(CarouselPage), typeof(CarouselPageRenderer))] -[assembly: ExportRenderer(typeof(Page), typeof(PageRenderer))] -[assembly: ExportRenderer(typeof(NavigationPage), typeof(NavigationPageRenderer))] -#pragma warning disable CS0618 // Type or member is obsolete -[assembly: ExportRenderer(typeof(MasterDetailPage), typeof(MasterDetailPageRenderer))] -#pragma warning restore CS0618 // Type or member is obsolete -[assembly: ExportRenderer(typeof(FlyoutPage), typeof(FlyoutPageRenderer))] -[assembly: ExportRenderer(typeof(TabbedPage), typeof(TabbedPageRenderer))] -[assembly: ExportRenderer(typeof(Shell), typeof(ShellRenderer))] - -[assembly: ExportRenderer(typeof(Label), typeof(LabelRenderer))] -[assembly: ExportRenderer(typeof(Button), typeof(ButtonRenderer))] -[assembly: ExportRenderer(typeof(Image), typeof(ImageRenderer))] -[assembly: ExportRenderer(typeof(Slider), typeof(SliderRenderer))] -[assembly: ExportRenderer(typeof(Picker), typeof(PickerRenderer))] -[assembly: ExportRenderer(typeof(Frame), typeof(FrameRenderer))] -[assembly: ExportRenderer(typeof(Stepper), typeof(StepperRenderer))] -[assembly: ExportRenderer(typeof(DatePicker), typeof(DatePickerRenderer))] -[assembly: ExportRenderer(typeof(TimePicker), typeof(TimePickerRenderer))] -[assembly: ExportRenderer(typeof(ProgressBar), typeof(ProgressBarRenderer))] -[assembly: ExportRenderer(typeof(Switch), typeof(SwitchRenderer))] -[assembly: ExportRenderer(typeof(CheckBox), typeof(CheckBoxRenderer))] -[assembly: ExportRenderer(typeof(ListView), typeof(ListViewRenderer))] -[assembly: ExportRenderer(typeof(BoxView), typeof(BoxViewRenderer))] -[assembly: ExportRenderer(typeof(ActivityIndicator), typeof(ActivityIndicatorRenderer))] -[assembly: ExportRenderer(typeof(IndicatorView), typeof(IndicatorViewRenderer))] -[assembly: ExportRenderer(typeof(SearchBar), typeof(SearchBarRenderer))] -[assembly: ExportRenderer(typeof(Entry), typeof(EntryRenderer))] -[assembly: ExportRenderer(typeof(Editor), typeof(EditorRenderer))] -[assembly: ExportRenderer(typeof(TableView), typeof(TableViewRenderer))] -[assembly: ExportRenderer(typeof(NativeViewWrapper), typeof(NativeViewWrapperRenderer))] -[assembly: ExportRenderer(typeof(WebView), typeof(WebViewRenderer))] -[assembly: ExportRenderer(typeof(ImageButton), typeof(ImageButtonRenderer))] -[assembly: ExportRenderer(typeof(StructuredItemsView), typeof(StructuredItemsViewRenderer))] -[assembly: ExportRenderer(typeof(CarouselView), typeof(CarouselViewRenderer))] -[assembly: ExportRenderer(typeof(SwipeView), typeof(SwipeViewRenderer))] -[assembly: ExportRenderer(typeof(RefreshView), typeof(RefreshViewRenderer))] -[assembly: ExportRenderer(typeof(IndicatorView), typeof(IndicatorViewRenderer))] -[assembly: ExportRenderer(typeof(RadioButton), typeof(RadioButtonRenderer))] - -[assembly: ExportImageSourceHandler(typeof(FileImageSource), typeof(FileImageSourceHandler))] -[assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImageSourceHandler))] -[assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(UriImageSourceHandler))] - -[assembly: ExportCell(typeof(TextCell), typeof(TextCellRenderer))] -[assembly: ExportCell(typeof(ImageCell), typeof(ImageCellRenderer))] -[assembly: ExportCell(typeof(SwitchCell), typeof(SwitchCellRenderer))] -[assembly: ExportCell(typeof(EntryCell), typeof(EntryCellRenderer))] -[assembly: ExportCell(typeof(ViewCell), typeof(ViewCellRenderer))] - -[assembly: ExportRenderer(typeof(EmbeddedFont), typeof(EmbeddedFontLoader))] - -[assembly: ExportHandler(typeof(TapGestureRecognizer), typeof(TapGestureHandler))] -[assembly: ExportHandler(typeof(PinchGestureRecognizer), typeof(PinchGestureHandler))] -[assembly: ExportHandler(typeof(PanGestureRecognizer), typeof(PanGestureHandler))] -[assembly: ExportHandler(typeof(SwipeGestureRecognizer), typeof(SwipeGestureHandler))] -[assembly: ExportHandler(typeof(DragGestureRecognizer), typeof(DragGestureHandler))] -[assembly: ExportHandler(typeof(DropGestureRecognizer), typeof(DropGestureHandler))] - -[assembly: ExportRenderer(typeof(Shell), typeof(Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch.ShellRenderer), TargetIdiom.Watch)] -[assembly: ExportRenderer(typeof(Shell), typeof(Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV.TVShellRenderer), TargetIdiom.TV)] - -[assembly: ExportRenderer(typeof(Ellipse), typeof(EllipseRenderer))] -[assembly: ExportRenderer(typeof(Line), typeof(LineRenderer))] -[assembly: ExportRenderer(typeof(Path), typeof(PathRenderer))] -[assembly: ExportRenderer(typeof(Polygon), typeof(PolygonRenderer))] -[assembly: ExportRenderer(typeof(Polyline), typeof(PolylineRenderer))] -[assembly: ExportRenderer(typeof(Microsoft.Maui.Controls.Compatibility.Shapes.Rectangle), typeof(RectangleRenderer))] +[assembly: Preserve] +[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Platform")] +[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Material")] \ No newline at end of file diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ActivityIndicatorRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ActivityIndicatorRenderer.cs index 4234edf67f..42f7488c34 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ActivityIndicatorRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ActivityIndicatorRenderer.cs @@ -1,8 +1,10 @@ +using Microsoft.Maui.Controls.Platform; using EColor = ElmSharp.Color; using EProgressBar = ElmSharp.ProgressBar; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ActivityIndicatorRenderer : ViewRenderer { static readonly EColor s_defaultColor = ThemeConstants.ProgressBar.ColorClass.Default; @@ -28,10 +30,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateColor(bool initialize) { - if (initialize && Element.Color.IsDefault) + if (initialize && Element.Color.IsDefault()) return; - Control.Color = (Element.Color == Color.Default) ? s_defaultColor : Element.Color.ToPlatform(); + Control.Color = (Element.Color.IsDefault()) ? s_defaultColor : Element.Color.ToNative(); } void UpdateIsRunning() diff --git a/src/Compatibility/Core/src/Tizen/Renderers/BoxViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/BoxViewRenderer.cs index 63c5d3126c..9823e21fb1 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/BoxViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/BoxViewRenderer.cs @@ -1,9 +1,11 @@ using System.ComponentModel; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class BoxViewRenderer : ViewRenderer { public BoxViewRenderer() @@ -33,10 +35,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected override void UpdateBackgroundColor(bool initialize) { - if (initialize && Element.BackgroundColor.IsDefault) + if (initialize && Element.BackgroundColor.IsDefault()) return; - if (Element.Color.IsDefault) + if (Element.Color.IsDefault()) { UpdateColor(); } @@ -71,9 +73,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateColor() { - if (Element.Color.IsDefault) + if (Element.Color.IsDefault()) { - if (Element.BackgroundColor.IsDefault) + if (Element.BackgroundColor.IsDefault()) { // Set to default color. (Transparent) Control.Color = EColor.Transparent; @@ -81,13 +83,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen else { // Use BackgroundColor only if color is default and background color is not default. - Control.Color = Element.BackgroundColor.MultiplyAlpha(Element.Opacity).ToPlatform(); + Control.Color = Element.BackgroundColor.MultiplyAlpha((float)Element.Opacity).ToNative(); } } else { // Color has higer priority than BackgroundColor. - Control.Color = Element.Color.MultiplyAlpha(Element.Opacity).ToPlatform(); + Control.Color = Element.Color.MultiplyAlpha((float)Element.Opacity).ToNative(); } } } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ButtonRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ButtonRenderer.cs index f51d3766d1..8933fb8cfb 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ButtonRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ButtonRenderer.cs @@ -1,10 +1,15 @@ using System; +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; +using Microsoft.Maui.Devices; +using NIButton = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.IButton; using EButton = ElmSharp.Button; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.VisualElement; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.VisualElement; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ButtonRenderer : ViewRenderer { public ButtonRenderer() @@ -61,8 +66,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var style = Specific.GetStyle(Element); if (!string.IsNullOrEmpty(style)) { - (Control as IButton)?.UpdateStyle(style); - ((IVisualElementController)Element).NativeSizeChanged(); + (Control as NIButton)?.UpdateStyle(style); + ((IVisualElementController)Element).PlatformSizeChanged(); UpdateBackgroundColor(false); } } @@ -98,12 +103,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateText() { - (Control as IButton).Text = Element.Text ?? ""; + (Control as NIButton).Text = Element.Text ?? ""; } void UpdateFontSize() { - if (Control is IButton ib) + if (Control is NIButton ib) { ib.FontSize = Element.FontSize; } @@ -111,7 +116,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontAttributes() { - if (Control is IButton ib) + if (Control is NIButton ib) { ib.FontAttributes = Element.FontAttributes; } @@ -119,23 +124,23 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontFamily() { - if (Control is IButton ib) + if (Control is NIButton ib) { - ib.FontFamily = Element.FontFamily.ToNativeFontFamily(); + ib.FontFamily = Element.FontFamily.ToNativeFontFamily(Element.RequireFontManager()); } } void UpdateTextColor() { - if (Control is IButton ib) + if (Control is NIButton ib) { - ib.TextColor = Element.TextColor.ToPlatform(); + ib.TextColor = Element.TextColor.ToPlatformEFL(); } } void UpdateBitmap() { - if (Control is IButton ib) + if (Control is NIButton ib) { if (Element.ImageSource != null) { diff --git a/src/Compatibility/Core/src/Tizen/Renderers/CarouselPageRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/CarouselPageRenderer.cs index 69602c6a13..e072950006 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/CarouselPageRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/CarouselPageRenderer.cs @@ -2,17 +2,21 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using ElmSharp; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Devices; using EBox = ElmSharp.Box; using ELayout = ElmSharp.Layout; using ERect = ElmSharp.Rect; using ESize = ElmSharp.Size; +using Index = ElmSharp.Index; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] /// /// Renderer of a CarouselPage widget. /// - public class CarouselPageRenderer : VisualElementRenderer + internal class CarouselPageRenderer : VisualElementRenderer { const int ItemMaxCount = 20; const int OddMiddleItem = 10; @@ -137,7 +141,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { _scroller.Geometry = _outterLayout.Geometry; var newGeometry = _outterLayout.Geometry; - if (Device.Idiom != TargetIdiom.Watch) + if (DeviceInfo.Idiom != DeviceIdiom.Watch) newGeometry.Y += (int)(newGeometry.Height * 0.9); newGeometry.Height = (int)(newGeometry.Height * 0.1); _index.Geometry = newGeometry; @@ -171,8 +175,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void OnCurrentPageChanged(object sender, EventArgs e) { - CustomFocusManager.StartReorderTabIndex(); - Element.UpdateFocusTreePolicy(); if (IsChangedByScroll()) diff --git a/src/Compatibility/Core/src/Tizen/Renderers/CarouselViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/CarouselViewRenderer.cs index 2fd6c864c4..0d616c8d16 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/CarouselViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/CarouselViewRenderer.cs @@ -2,10 +2,12 @@ using System; using System.Collections.Generic; using System.ComponentModel; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class CarouselViewRenderer : ItemsViewRenderer { List _oldViews = new List(); @@ -41,7 +43,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _animationStart = new SmartEvent(Control.Scroll, Control.Scroll.RealHandle, ThemeConstants.Scroller.Signals.StartScrollAnimation); _animationStart.On += OnScrollStart; } - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { UpdatePositionFromElement(false); UpdateCurrentItemFromElement(false); diff --git a/src/Compatibility/Core/src/Tizen/Renderers/CheckBoxRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/CheckBoxRenderer.cs index fc60d0cd79..73cbeae02b 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/CheckBoxRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/CheckBoxRenderer.cs @@ -1,9 +1,11 @@ using System; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class CheckBoxRenderer : ViewRenderer { public CheckBoxRenderer() @@ -46,16 +48,16 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateOnColor(bool initialize) { - if (initialize && Element.Color.IsDefault) + if (initialize && Element.Color.IsDefault()) return; - if (Element.Color.IsDefault) + if (Element.Color.IsDefault()) { Control.DeleteOnColors(); } else { - Control.SetOnColors(Element.Color.ToPlatform()); + Control.SetOnColors(Element.Color.ToNative()); } } } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/CustomFocusManager.cs b/src/Compatibility/Core/src/Tizen/Renderers/CustomFocusManager.cs index 2668fde47b..fb6e0c4d08 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/CustomFocusManager.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/CustomFocusManager.cs @@ -7,23 +7,18 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] class CustomFocusManager : IDisposable { - static bool s_reorderTriggered; - static readonly ObservableCollection s_tabIndexList = new ObservableCollection(); - VisualElement _nextUp; VisualElement _nextDown; VisualElement _nextLeft; VisualElement _nextRight; VisualElement _nextForward; VisualElement _nextBackward; - int _tabIndex = -1; - bool _isTabStop = true; static CustomFocusManager() { - s_tabIndexList.CollectionChanged += TabIndexCollectionChanged; } public CustomFocusManager(VisualElement element, Widget nativeView) @@ -40,52 +35,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen VisualElement Element { get; } Widget NativeView { get; } - public int TabIndex - { - get - { - return _tabIndex; - } - set - { - if (IsTabStop) - { - if (_tabIndex > -1) - { - s_tabIndexList.Remove(this); - } - if (value > -1) - { - s_tabIndexList.Add(this); - } - } - _tabIndex = value; - } - } - - public bool IsTabStop - { - get - { - return _isTabStop; - } - set - { - if (TabIndex > -1) - { - if (_isTabStop) - { - s_tabIndexList.Remove(this); - } - if (value) - { - s_tabIndexList.Add(this); - } - } - _isTabStop = value; - } - } - public VisualElement NextUp { get => _nextUp; @@ -152,23 +101,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen GC.SuppressFinalize(this); } - public static void StartReorderTabIndex() - { - if (Device.IsInvokeRequired) - { - Device.BeginInvokeOnMainThread(() => - { - StartReorderTabIndex(); - }); - return; - } - if (!s_reorderTriggered) - { - s_reorderTriggered = true; - Device.BeginInvokeOnMainThread(ReorderTabIndex); - } - } - protected virtual void Dispose(bool disposing) { if (disposing) @@ -198,10 +130,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen NextBackward.PropertyChanged -= OnNextViewPropertyChanged; } } - if (s_tabIndexList.Contains(this)) - { - s_tabIndexList.Remove(this); - } } void SetUpFocus(VisualElement next, FocusDirection direction) @@ -251,36 +179,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen return FocusDirection.Next; } - static void ReorderTabIndex() - { - s_reorderTriggered = false; - var list = s_tabIndexList.Where((t) => t.IsTabStop && ElementIsVisible(t)).OrderBy(x => x.Element.TabIndex); - CustomFocusManager first = null; - CustomFocusManager last = null; - foreach (var item in list) - { - if (first == null) - first = item; - - if (last != null) - { - item.NextBackward = last.Element; - last.NextForward = item.Element; - } - last = item; - } - if (first != null && last != null) - { - first.NextBackward = last.Element; - last.NextForward = first.Element; - } - } - - static void TabIndexCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - StartReorderTabIndex(); - } - static bool PageIsVisible(Page page) { if (page == null) @@ -305,9 +203,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { return false; } -#pragma warning disable CS0618 // Type or member is obsolete - if (parentPage is MasterDetailPage mdPage && mdPage.Master == parent && !mdPage.IsPresented) -#pragma warning restore CS0618 // Type or member is obsolete + if (parentPage is FlyoutPage flyoutPage && flyoutPage.Flyout == parent && !flyoutPage.IsPresented) { return false; } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/DatePickerRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/DatePickerRenderer.cs index bf011cb5e3..ae6ea1aec0 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/DatePickerRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/DatePickerRenderer.cs @@ -1,11 +1,16 @@ using System; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; +using Microsoft.Maui.Devices; +using Microsoft.Maui.Graphics; +using NIEntery = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.IEntry; using EEntry = ElmSharp.Entry; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Application; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Application; using WatchDateTimePickerDialog = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch.WatchDateTimePickerDialog; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class DatePickerRenderer : ViewRenderer { //TODO need to add internationalization support @@ -42,7 +47,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen entry.SetVerticalTextAlignment(0.5); SetNativeControl(entry); - if (entry is IEntry ie) + if (entry is NIEntery ie) { ie.TextBlockFocused += OnTextBlockFocused; ie.EntryLayoutFocused += OnFocused; @@ -91,7 +96,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { if (Control != null) { - if (Control is IEntry ie) + if (Control is NIEntery ie) { ie.TextBlockFocused -= OnTextBlockFocused; ie.EntryLayoutFocused -= OnFocused; @@ -121,7 +126,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen dialog.MinimumDateTime = Element.MinimumDate; // You need to call Show() after ui thread occupation because of EFL problem. // Otherwise, the content of the popup will not receive focus. - Device.BeginInvokeOnMainThread(() => dialog.Show()); + Application.Current.Dispatcher.Dispatch(() => dialog.Show()); } } @@ -138,9 +143,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateTextColor() { - if (Control is IEntry ie) + if (Control is NIEntery ie) { - ie.TextColor = Element.TextColor.ToPlatform(); + ie.TextColor = Element.TextColor.ToPlatformEFL(); } } @@ -167,7 +172,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontSize() { - if (Control is IEntry ie) + if (Control is NIEntery ie) { ie.FontSize = Element.FontSize; } @@ -175,7 +180,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontFamily() { - if (Control is IEntry ie) + if (Control is NIEntery ie) { ie.FontFamily = Element.FontFamily; } @@ -183,7 +188,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontAttributes() { - if (Control is IEntry ie) + if (Control is NIEntery ie) { ie.FontAttributes = Element.FontAttributes; } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/DefaultRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/DefaultRenderer.cs index 210de2214b..bb6ef92f5d 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/DefaultRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/DefaultRenderer.cs @@ -1,9 +1,9 @@ -using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Shapes; +using Microsoft.Maui.Controls.Platform; using ELayout = ElmSharp.Layout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete] public sealed class DefaultRenderer : VisualElementRenderer { protected override void OnElementChanged(ElementChangedEventArgs e) @@ -17,18 +17,25 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class EllipseRenderer : ShapeRenderer { } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class LineRenderer : ShapeRenderer { } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PathRenderer : ShapeRenderer { } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PolygonRenderer : ShapeRenderer { } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PolylineRenderer : ShapeRenderer { } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class RectangleRenderer : ShapeRenderer { } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShapeRenderer : VisualElementRenderer { protected override void OnElementChanged(ElementChangedEventArgs e) diff --git a/src/Compatibility/Core/src/Tizen/Renderers/EditorRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/EditorRenderer.cs index 464e3d67f7..74946edd72 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/EditorRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/EditorRenderer.cs @@ -1,9 +1,14 @@ using System; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; +using Microsoft.Maui.Devices; +using Microsoft.Maui.Graphics; using EEntry = ElmSharp.Entry; +using NIEntry = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.IEntry; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class EditorRenderer : ViewRenderer { public EditorRenderer() @@ -30,7 +35,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen entry.Unfocused += OnEntryUnfocused; entry.Unfocused += OnCompleted; entry.PrependMarkUpFilter(MaxLengthFilter); - if (entry is IEntry ie) + if (entry is NIEntry ie) { ie.TextChanged += OnTextChanged; ie.EntryLayoutFocused += OnFocused; @@ -61,7 +66,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Control.BackButtonPressed -= OnCompleted; Control.Unfocused -= OnEntryUnfocused; Control.Focused -= OnEntryFocused; - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.TextChanged -= OnTextChanged; ie.EntryLayoutFocused -= OnFocused; @@ -79,9 +84,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateTextColor() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.TextColor = Element.TextColor.ToPlatform(); + ie.TextColor = Element.TextColor.ToPlatformEFL(); } } @@ -127,7 +132,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontSize() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontSize = Element.FontSize; } @@ -135,15 +140,15 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontFamily() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.FontFamily = Element.FontFamily.ToNativeFontFamily(); + ie.FontFamily = Element.FontFamily.ToNativeFontFamily(Element.RequireFontManager()); } } void UpdateFontAttributes() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontAttributes = Element.FontAttributes; } @@ -154,7 +159,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (initialize && Element.Keyboard == Keyboard.Default) return; - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.UpdateKeyboard(Element.Keyboard, Element.IsSpellCheckEnabled, true); } @@ -173,7 +178,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdatePlaceholder() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.Placeholder = Element.Placeholder; } @@ -181,9 +186,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdatePlaceholderColor() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.PlaceholderColor = Element.PlaceholderColor.ToPlatform(); + ie.PlaceholderColor = Element.PlaceholderColor.ToPlatformEFL(); } } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/EntryRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/EntryRenderer.cs index 12aa5a1770..08c9b39dce 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/EntryRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/EntryRenderer.cs @@ -1,11 +1,14 @@ using System; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using EEntry = ElmSharp.Entry; -using IEntry = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.IEntry; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Entry; +using NIEntry = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.IEntry; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Entry; +using Size = Microsoft.Maui.Graphics.Size; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class EntryRenderer : ViewRenderer { SmartEvent _selectionCleared; @@ -49,7 +52,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _selectionCleared = new SmartEvent(entry, entry.RealHandle, ThemeConstants.Entry.Signals.SelectionCleared); _selectionCleared.On += OnSelectionCleared; - if (entry is IEntry ie) + if (entry is NIEntry ie) { ie.TextChanged += OnTextChanged; ie.EntryLayoutFocused += OnFocused; @@ -59,7 +62,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen SetNativeControl(entry); // An initial CursorPosition is set after layouting to avoid timing issue when the EditField entry is initialized. - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { UpdateSelectionLength(false); }); @@ -85,7 +88,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Control.Activated -= OnCompleted; Control.CursorChanged -= OnCursorChanged; - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.TextChanged -= OnTextChanged; ie.EntryLayoutFocused -= OnFocused; @@ -119,14 +122,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void OnCompleted(object sender, EventArgs e) { - if (Element.ReturnType == ReturnType.Next) - { - FocusSearch(true)?.SetFocus(true); - } - else - { - Control.SetFocus(false); - } + Control.SetFocus(false); ((IEntryController)Element).SendCompleted(); } @@ -146,15 +142,15 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateTextColor() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.TextColor = Element.TextColor.ToPlatform(); + ie.TextColor = Element.TextColor.ToPlatformEFL(); } } void UpdateFontSize() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontSize = Element.FontSize; } @@ -162,15 +158,15 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontFamily() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.FontFamily = Element.FontFamily.ToNativeFontFamily(); + ie.FontFamily = Element.FontFamily.ToNativeFontFamily(Element.RequireFontManager()); } } void UpdateFontAttributes() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontAttributes = Element.FontAttributes; } @@ -178,9 +174,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateHorizontalTextAlignment() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToPlatform(); + ie.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToNative(); } } @@ -195,7 +191,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (initialize && Element.Keyboard == Keyboard.Default) return; - (Control as IEntry)?.UpdateKeyboard(Element.Keyboard, Element.IsSpellCheckEnabled, Element.IsTextPredictionEnabled); + (Control as NIEntry)?.UpdateKeyboard(Element.Keyboard, Element.IsSpellCheckEnabled, Element.IsTextPredictionEnabled); } void UpdateIsSpellCheckEnabled() @@ -205,7 +201,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdatePlaceholder() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.Placeholder = Element.Placeholder; } @@ -213,15 +209,15 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdatePlaceholderColor() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.PlaceholderColor = Element.PlaceholderColor.ToPlatform(); + ie.PlaceholderColor = Element.PlaceholderColor.ToPlatformEFL(); } } void UpdateFontWeight() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontWeight = Specific.GetFontWeight(Element); } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/FastLayoutRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/FastLayoutRenderer.cs index 25ae0ff4bb..5d57c87b13 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/FastLayoutRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/FastLayoutRenderer.cs @@ -1,9 +1,11 @@ using System; using System.ComponentModel; using SkiaSharp.Views.Tizen; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class FastLayoutRenderer : ViewRenderer, SkiaSharp.IBackgroundCanvas, ILayoutRenderer { bool _layoutUpdatedRegistered = false; diff --git a/src/Compatibility/Core/src/Tizen/Renderers/FlyoutContainer.cs b/src/Compatibility/Core/src/Tizen/Renderers/FlyoutContainer.cs index d06655d1fc..1ea13ab43d 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/FlyoutContainer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/FlyoutContainer.cs @@ -2,6 +2,7 @@ using System; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Renderers { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class FlyoutContainer : ElmSharp.Box, IDisposable { readonly FlyoutPage _parent; @@ -51,7 +52,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Renderers if (_hasAppearedToParent) { - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { if (!_disposed && _hasAppearedToParent) PageController?.SendAppearing(); diff --git a/src/Compatibility/Core/src/Tizen/Renderers/FlyoutPageRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/FlyoutPageRenderer.cs index 2c75df587c..bf63fd79ed 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/FlyoutPageRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/FlyoutPageRenderer.cs @@ -1,8 +1,10 @@ using System; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Renderers; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class FlyoutPageRenderer : VisualElementRenderer { Native.FlyoutPage _flyoutPage; @@ -140,9 +142,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateIsPresented() { - // To update TabIndex order - CustomFocusManager.StartReorderTabIndex(); - _flyoutPage.IsPresented = Element.IsPresented; } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/FrameRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/FrameRenderer.cs index 8630e373fc..bf9b8f3eca 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/FrameRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/FrameRenderer.cs @@ -1,8 +1,10 @@ +using Microsoft.Maui.Controls.Platform; using EColor = ElmSharp.Color; using EPolygon = ElmSharp.Polygon; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class FrameRenderer : LayoutRenderer { const int _thickness = 2; @@ -104,10 +106,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateColor() { - if ((Element as Frame).BorderColor.IsDefault) + if ((Element as Frame).BorderColor.IsDefault()) _frame.Color = s_DefaultColor; else - _frame.Color = (Element as Frame).BorderColor.ToPlatform(); + _frame.Color = (Element as Frame).BorderColor.ToNative(); } void UpdateShadowVisibility() diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ILayoutRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ILayoutRenderer.cs index 9e587bcbb1..c11d922afe 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ILayoutRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ILayoutRenderer.cs @@ -1,5 +1,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public interface ILayoutRenderer { void RegisterOnLayoutUpdated(); diff --git a/src/Compatibility/Core/src/Tizen/Renderers/IVisualElementRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/IVisualElementRenderer.cs index e2e2de0809..df238d13ed 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/IVisualElementRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/IVisualElementRenderer.cs @@ -1,5 +1,6 @@ using System; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using ERect = ElmSharp.Rect; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen @@ -27,6 +28,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen get; } + event EventHandler ElementChanged; + /// /// Sets the VisualElement associated with this renderer. /// diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ImageButtonRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ImageButtonRenderer.cs index 4c135e2ff3..28bf84ee0c 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ImageButtonRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ImageButtonRenderer.cs @@ -1,10 +1,12 @@ using System; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using EButton = ElmSharp.Button; using ERect = ElmSharp.Rect; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ImageButtonRenderer : ViewRenderer { public ImageButtonRenderer() @@ -64,7 +66,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected override void UpdateBackgroundColor(bool initialize) { - _round.Color = Element.BackgroundColor.ToPlatform(); + _round.Color = Element.BackgroundColor.ToNative(); } protected override void Dispose(bool disposing) @@ -138,7 +140,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (!IsDisposed && success) { - (Element as IVisualElementController)?.NativeSizeChanged(); + (Element as IVisualElementController)?.PlatformSizeChanged(); UpdateAfterLoading(); } } @@ -184,7 +186,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateBorderColor() { - _border.Color = Element.BorderColor.ToPlatform(); + _border.Color = Element.BorderColor.ToNative(); } void UpdateAspect() diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ImageRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ImageRenderer.cs index 0706c464da..63c9c977d3 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ImageRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ImageRenderer.cs @@ -1,12 +1,13 @@ using System.ComponentModel; using System.Threading; using System.Threading.Tasks; +using Microsoft.Maui.Controls.Platform; using EImage = ElmSharp.Image; - -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Image; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Image; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ImageRenderer : ViewRenderer { public ImageRenderer() @@ -42,7 +43,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (!IsDisposed && success) { - ((IVisualElementController)Element).NativeSizeChanged(); + ((IVisualElementController)Element).PlatformSizeChanged(); UpdateAfterLoading(initialize); } } @@ -62,7 +63,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (!IsDisposed && success) { - ((IVisualElementController)Element).NativeSizeChanged(); + ((IVisualElementController)Element).PlatformSizeChanged(); UpdateAfterLoading(initialize); } } @@ -102,10 +103,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateBlendColor(bool initialize) { - if (initialize && Specific.GetBlendColor(Element).IsDefault) + if (initialize && Specific.GetBlendColor(Element) == null) return; - Control.Color = Specific.GetBlendColor(Element).ToPlatform(); + Control.Color = Specific.GetBlendColor(Element).ToPlatformEFL(); } } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/IndicatorViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/IndicatorViewRenderer.cs index e908a84ba6..b7f8b5f8b5 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/IndicatorViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/IndicatorViewRenderer.cs @@ -1,5 +1,8 @@ +using Microsoft.Maui.Controls.Platform; + namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class IndicatorViewRenderer : ViewRenderer { public IndicatorViewRenderer() diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ItemsViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ItemsViewRenderer.cs index 6ce1ea1624..4b7bb631f8 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ItemsViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ItemsViewRenderer.cs @@ -1,12 +1,13 @@ using System.Collections.Specialized; using System.Linq; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; - -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.ItemsView; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.ItemsView; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public abstract class ItemsViewRenderer : ViewRenderer where TItemsView : ItemsView where TNative : Native.CollectionView @@ -86,7 +87,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void OnLayoutPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { - if (e.PropertyName == nameof(Microsoft.Maui.Controls.Compatibility.ItemsLayout.SnapPointsType)) + if (e.PropertyName == nameof(Microsoft.Maui.Controls.ItemsLayout.SnapPointsType)) { Control.SnapPointsType = (sender as ItemsLayout)?.SnapPointsType ?? SnapPointsType.None; } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/LabelRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/LabelRenderer.cs index 8e47cef0e5..0387c4dcd0 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/LabelRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/LabelRenderer.cs @@ -1,8 +1,11 @@ +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Label; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Label; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class LabelRenderer : ViewRenderer { @@ -52,8 +55,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen nativeSpan.FontAttributes = span.FontAttributes; nativeSpan.FontFamily = span.FontFamily; nativeSpan.FontSize = span.FontSize; - nativeSpan.ForegroundColor = span.TextColor.ToPlatform(); - nativeSpan.BackgroundColor = span.BackgroundColor.ToPlatform(); + nativeSpan.ForegroundColor = span.TextColor.ToPlatformEFL(); + nativeSpan.BackgroundColor = span.BackgroundColor.ToPlatformEFL(); nativeSpan.Underline = (textDecorations & TextDecorations.Underline) != 0; nativeSpan.Strikethrough = (textDecorations & TextDecorations.Strikethrough) != 0; nativeSpan.LineHeight = span.LineHeight; @@ -78,6 +81,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Control.FormattedText = ConvertFormattedText(Element.FormattedText); } + [PortHandler] void UpdateText() { Control.Text = Element.Text ?? ""; @@ -85,17 +89,17 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateTextColor() { - Control.TextColor = Element.TextColor.ToPlatform(); + Control.TextColor = Element.TextColor.ToPlatformEFL(); } void UpdateHorizontalTextAlignment() { - Control.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToPlatform(); + Control.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToNative(); } void UpdateVerticalTextAlignment() { - Control.VerticalTextAlignment = Element.VerticalTextAlignment.ToPlatform(); + Control.VerticalTextAlignment = Element.VerticalTextAlignment.ToNative(); } void UpdateFontProperties() @@ -104,7 +108,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Control.FontSize = Element.FontSize; Control.FontAttributes = Element.FontAttributes; - Control.FontFamily = Element.FontFamily.ToNativeFontFamily(); + Control.FontFamily = Element.FontFamily.ToNativeFontFamily(Element.RequireFontManager()); Control.BatchCommit(); } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/LayoutRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/LayoutRenderer.cs index e8b4dcb19a..37e2fce15a 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/LayoutRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/LayoutRenderer.cs @@ -1,9 +1,11 @@ using System; using System.ComponentModel; using SkiaSharp.Views.Tizen; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] /// /// Renderer of a Layout. /// @@ -67,7 +69,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _layoutUpdatedRegistered = false; } - if (Forms.UseSkiaSharp) + if (Forms.UseSkiaSharp && Control != null) { Control.LayoutUpdated -= OnBackgroundLayoutUpdated; diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ListViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ListViewRenderer.cs index 69d29a71a7..e0220fff33 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ListViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ListViewRenderer.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Specialized; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Devices; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] /// /// Renderer class for Xamarin ListView class. This provides necessary logic translating /// Xamarin API to Tizen Native API. This is a derivate of a ViewRenderer base class. @@ -394,7 +397,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateSeparator() { - Control.BottomLineColor = Element.SeparatorVisibility == SeparatorVisibility.Default ? Element.SeparatorColor.ToPlatform() : EColor.Transparent; + Control.BottomLineColor = Element.SeparatorVisibility == SeparatorVisibility.Default ? Element.SeparatorColor.ToPlatformEFL() : EColor.Transparent; } } } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/MasterDetailContainer.cs b/src/Compatibility/Core/src/Tizen/Renderers/MasterDetailContainer.cs deleted file mode 100644 index 24228c62ef..0000000000 --- a/src/Compatibility/Core/src/Tizen/Renderers/MasterDetailContainer.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Renderers -{ - [Obsolete("MasterDetailContainer is obsolete as of version 5.0.0. Please use FlyoutContainer instead.")] - public class MasterDetailContainer : ElmSharp.Box, IDisposable - { -#pragma warning disable CS0618 // Type or member is obsolete - readonly MasterDetailPage _parent; -#pragma warning restore CS0618 // Type or member is obsolete - readonly bool _isMaster; - - VisualElement _childView; - bool _disposed; - bool _hasAppearedToParent; - - IPageController PageController => ChildView as IPageController; - - IMasterDetailPageController MasterDetailPageController => _parent as IMasterDetailPageController; - -#pragma warning disable CS0618 // Type or member is obsolete - public MasterDetailContainer(MasterDetailPage parentElement, bool isMaster) : base(Forms.NativeParent) -#pragma warning restore CS0618 // Type or member is obsolete - { - _parent = parentElement; - _isMaster = isMaster; - - SetLayoutCallback(OnLayoutUpdated); - Show(); - } - - ~MasterDetailContainer() - { - Dispose(false); - } - - public VisualElement ChildView - { - get { return _childView; } - set - { - if (_childView == value) - return; - - if (_childView != null) - { - RemoveChildView(); - } - - _childView = value; - - if (_childView == null) - return; - - AddChildView(_childView); - - if (_hasAppearedToParent) - { - Device.BeginInvokeOnMainThread(() => - { - if (!_disposed && _hasAppearedToParent) - PageController?.SendAppearing(); - }); - } - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected void RemoveChildView() - { - IVisualElementRenderer childRenderer = Platform.GetRenderer(_childView); - if (childRenderer != null) - { - UnPack(childRenderer.NativeView); - childRenderer.Dispose(); - } - } - - protected void AddChildView(VisualElement childView) - { - IVisualElementRenderer renderer = Platform.GetOrCreateRenderer(childView); - this.PackEnd(renderer.NativeView); - } - - protected virtual void Dispose(bool disposing) - { - if (_disposed) - return; - - if (disposing) - { - if (_childView != null) - { - RemoveChildView(); - } - SetLayoutCallback(null); - } - _disposed = true; - } - - void OnLayoutUpdated() - { - if (_childView != null) - { - if (_isMaster) - MasterDetailPageController.MasterBounds = this.Geometry.ToDP(); - else - MasterDetailPageController.DetailBounds = this.Geometry.ToDP(); - - IVisualElementRenderer renderer = Platform.GetRenderer(_childView); - renderer.NativeView.Geometry = this.Geometry; - } - } - - public void SendAppearing() - { - if (_hasAppearedToParent) - return; - - _hasAppearedToParent = true; - - PageController?.SendAppearing(); - } - - public void SendDisappearing() - { - if (!_hasAppearedToParent) - return; - - _hasAppearedToParent = false; - - PageController?.SendDisappearing(); - } - } -} \ No newline at end of file diff --git a/src/Compatibility/Core/src/Tizen/Renderers/MasterDetailPageRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/MasterDetailPageRenderer.cs deleted file mode 100644 index db2708f7fc..0000000000 --- a/src/Compatibility/Core/src/Tizen/Renderers/MasterDetailPageRenderer.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Renderers; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ -#pragma warning disable CS0618 // Type or member is obsolete - [Obsolete("MasterDetailPage is obsolete as of version 5.0.0. Please use FlyoutPage instead.")] - public class MasterDetailPageRenderer : VisualElementRenderer - { - Native.FlyoutPage _mdpage; - MasterDetailContainer _masterContainer = null; - MasterDetailContainer _detailContainer = null; - - /// - /// Default constructor. - /// - public MasterDetailPageRenderer() - { - RegisterPropertyHandler(nameof(Element.Master), UpdateMasterPage); - RegisterPropertyHandler(nameof(Element.Detail), UpdateDetailPage); - RegisterPropertyHandler(MasterDetailPage.IsPresentedProperty, - UpdateIsPresented); - RegisterPropertyHandler(MasterDetailPage.MasterBehaviorProperty, - UpdateMasterBehavior); - RegisterPropertyHandler(MasterDetailPage.IsGestureEnabledProperty, - UpdateIsGestureEnabled); - } - - protected override void OnElementChanged(ElementChangedEventArgs e) - { - if (_mdpage == null) - { - _mdpage = new Native.FlyoutPage(Forms.NativeParent) - { - IsPresented = e.NewElement.IsPresented, - Flyout = _masterContainer = new MasterDetailContainer(Element, true), - Detail = _detailContainer = new MasterDetailContainer(Element, false), - }; - - _mdpage.IsPresentedChanged += (sender, ev) => - { - Element.IsPresented = ev.IsPresent; - }; - _mdpage.UpdateIsPresentChangeable += (sender, ev) => - { - (Element as IMasterDetailPageController).CanChangeIsPresented = ev.CanChange; - }; - SetNativeView(_mdpage); - } - - if (e.OldElement != null) - { - (e.OldElement as IMasterDetailPageController).BackButtonPressed -= OnBackButtonPressed; - e.OldElement.Appearing -= OnMasterDetailAppearing; - e.OldElement.Disappearing -= OnMasterDetailDisappearing; - } - - if (e.NewElement != null) - { - (e.NewElement as IMasterDetailPageController).BackButtonPressed += OnBackButtonPressed; - e.NewElement.Appearing += OnMasterDetailAppearing; - e.NewElement.Disappearing += OnMasterDetailDisappearing; - } - - UpdateMasterBehavior(); - base.OnElementChanged(e); - } - - void OnMasterDetailDisappearing(object sender, EventArgs e) - { - _masterContainer?.SendDisappearing(); - _detailContainer?.SendDisappearing(); - } - - void OnMasterDetailAppearing(object sender, EventArgs e) - { - _masterContainer?.SendAppearing(); - _detailContainer?.SendAppearing(); - } - - protected override void OnElementReady() - { - base.OnElementReady(); - UpdateMasterPage(false); - UpdateDetailPage(false); - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (_masterContainer != null) - { - _masterContainer.Dispose(); - _masterContainer = null; - } - - if (_detailContainer != null) - { - _detailContainer.Dispose(); - _detailContainer = null; - } - - if (Element != null) - { - Element.Appearing -= OnMasterDetailAppearing; - Element.Disappearing -= OnMasterDetailDisappearing; - } - } - - base.Dispose(disposing); - } - - protected void UpdateMasterPageRatio(double popoverRatio, double splitRatio) - { - _mdpage.PopoverRatio = popoverRatio; - _mdpage.SplitRatio = splitRatio; - } - - void OnBackButtonPressed(object sender, BackButtonPressedEventArgs e) - { - if ((Element != null) && Element.IsPresented && !_mdpage.IsSplit) - { - Element.IsPresented = false; - e.Handled = true; - } - } - - void UpdateMasterBehavior() - { - _mdpage.FlyoutLayoutBehavior = (FlyoutLayoutBehavior)Element.MasterBehavior; - } - - void UpdateMasterPage(bool isInit) - { - if (!isInit) - _masterContainer.ChildView = Element.Master; - } - - void UpdateDetailPage(bool isInit) - { - if (!isInit) - _detailContainer.ChildView = Element.Detail; - } - - void UpdateIsPresented() - { - // To update TabIndex order - CustomFocusManager.StartReorderTabIndex(); - - _mdpage.IsPresented = Element.IsPresented; - } - - void UpdateIsGestureEnabled() - { - _mdpage.IsGestureEnabled = Element.IsGestureEnabled; - } - } -#pragma warning restore CS0618 // Type or member is obsolete -} diff --git a/src/Compatibility/Core/src/Tizen/Renderers/NativeViewWrapperRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/NativeViewWrapperRenderer.cs index 7132649ce0..ef868692bb 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/NativeViewWrapperRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/NativeViewWrapperRenderer.cs @@ -1,9 +1,12 @@ using ElmSharp; +using Microsoft.Maui.Controls.Platform; using ESize = ElmSharp.Size; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { +#pragma warning disable CS0618 // Type or member is obsolete public class NativeViewWrapperRenderer : ViewRenderer +#pragma warning disable CS0618 // Type or member is obsolete { protected override void OnElementChanged(ElementChangedEventArgs e) { diff --git a/src/Compatibility/Core/src/Tizen/Renderers/NavigationPageRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/NavigationPageRenderer.cs index 721100fe7c..1c765c06ff 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/NavigationPageRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/NavigationPageRenderer.cs @@ -3,16 +3,18 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; -using Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific; using EButton = ElmSharp.Button; using EToolbar = ElmSharp.Toolbar; using EToolbarItem = ElmSharp.ToolbarItem; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.NavigationPage; -using SpecificPage = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Page; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.NavigationPage; +using SpecificPage = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Page; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class NavigationPageRenderer : VisualElementRenderer { enum ToolbarButtonPosition @@ -117,7 +119,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (e.PropertyName == NavigationPage.CurrentPageProperty.PropertyName) { - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { (_previousPage as IPageController)?.SendDisappearing(); _previousPage = Element.CurrentPage; @@ -228,14 +230,14 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { Text = Title, HorizontalTextAlignment = Native.TextAlignment.Center, - ForegroundColor = Element.BarTextColor.ToPlatform() + ForegroundColor = Element.BarTextColor.ToPlatformEFL() }; return span.GetMarkupText(); } void UpdateBarBackgroundColor(NaviItem item) { - item.TitleBarBackgroundColor = Element.BarBackgroundColor.ToPlatform(); + item.TitleBarBackgroundColor = Element.BarBackgroundColor.ToPlatformEFL(); } void UpdateNavigationBar(Page page, NaviItem item = null) diff --git a/src/Compatibility/Core/src/Tizen/Renderers/PageRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/PageRenderer.cs index b76dca7378..fc15cad337 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/PageRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/PageRenderer.cs @@ -2,7 +2,9 @@ using System; using System.Collections.Specialized; using ElmSharp.Wearable; using SkiaSharp.Views.Tizen; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch; +using Microsoft.Maui.Devices; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen @@ -10,6 +12,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// /// Renderer of ContentPage. /// + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PageRenderer : VisualElementRenderer, SkiaSharp.IBackgroundCanvas { Native.Page _page; @@ -102,14 +105,14 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected override void UpdateBackgroundColor(bool initialize) { - if (initialize && Element.BackgroundColor.IsDefault) + if (initialize && Element.BackgroundColor.IsDefault()) return; // base.UpdateBackgroundColor() is not called on purpose, we don't want the regular background setting - if (Element.BackgroundColor.IsDefault || Element.BackgroundColor.A == 0) + if (Element.BackgroundColor.IsDefault() || Element.BackgroundColor.Alpha == 0) _page.Color = EColor.Transparent; else - _page.Color = Element.BackgroundColor.ToPlatform(); + _page.Color = Element.BackgroundColor.ToNative(); } protected override void UpdateLayout() diff --git a/src/Compatibility/Core/src/Tizen/Renderers/PickerRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/PickerRenderer.cs index 06668f7ef8..3f6fa06615 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/PickerRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/PickerRenderer.cs @@ -1,12 +1,16 @@ using System; using System.Collections.Generic; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch; +using Microsoft.Maui.Devices; using EEntry = ElmSharp.Entry; +using NIEntry = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.IEntry; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PickerRenderer : ViewRenderer { List _list; @@ -31,7 +35,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { if (Control != null) { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.TextBlockFocused -= OnTextBlockFocused; ie.EntryLayoutFocused -= OnFocused; @@ -54,7 +58,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { var entry = CreateNativeControl(); entry.SetVerticalTextAlignment(0.5); - if (entry is IEntry ie) + if (entry is NIEntry ie) { ie.TextBlockFocused += OnTextBlockFocused; ie.EntryLayoutFocused += OnFocused; @@ -90,23 +94,23 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateTitleColor() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.PlaceholderColor = Element.TitleColor.ToPlatform(); + ie.PlaceholderColor = Element.TitleColor.ToPlatformEFL(); } } protected virtual void UpdateTextColor() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.TextColor = Element.TextColor.ToPlatform(); + ie.TextColor = Element.TextColor.ToPlatformEFL(); } } void UpdateFontSize() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontSize = Element.FontSize; } @@ -114,7 +118,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontFamily() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontFamily = Element.FontFamily; } @@ -122,7 +126,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontAttributes() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontAttributes = Element.FontAttributes; } @@ -130,7 +134,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateTitle() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.Placeholder = Element.Title; } @@ -138,15 +142,15 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateHorizontalTextAlignment() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToPlatform(); + ie.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToNative(); } } void OnLayoutFocused(object sender, EventArgs e) { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontSize = ie.FontSize * 1.5; } @@ -154,7 +158,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void OnLayoutUnfocused(object sender, EventArgs e) { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontSize = ie.FontSize / 1.5; } @@ -178,7 +182,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _dialog.AlignmentX = -1; _dialog.AlignmentY = -1; _dialog.Title = Element.Title; - _dialog.TitleColor = Element.TitleColor.ToPlatform(); + _dialog.TitleColor = Element.TitleColor.ToPlatformEFL(); _dialog.Dismissed += OnDialogDismissed; _dialog.BackButtonPressed += (object senders, EventArgs es) => { @@ -197,7 +201,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen // You need to call Show() after ui thread occupation because of EFL problem. // Otherwise, the content of the popup will not receive focus. - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { _dialog.Show(); _list.Show(); diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ProgressBarRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ProgressBarRenderer.cs index a20e61e8c9..486b165926 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ProgressBarRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ProgressBarRenderer.cs @@ -1,11 +1,13 @@ using System.ComponentModel; +using Microsoft.Maui.Controls.Platform; using EColor = ElmSharp.Color; using EProgressBar = ElmSharp.ProgressBar; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.ProgressBar; -using SpecificVE = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.VisualElement; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.ProgressBar; +using SpecificVE = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.VisualElement; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ProgressBarRenderer : ViewRenderer { static readonly EColor s_defaultColor = ThemeConstants.ProgressBar.ColorClass.Default; @@ -70,10 +72,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateProgressColor(bool initialize) { - if (initialize && Element.ProgressColor.IsDefault) + if (initialize && Element.ProgressColor.IsDefault()) return; - Control.Color = Element.ProgressColor == Color.Default ? s_defaultColor : Element.ProgressColor.ToPlatform(); + Control.Color = Element.ProgressColor.IsDefault() ? s_defaultColor : Element.ProgressColor.ToPlatformEFL(); } void UpdateProgress() diff --git a/src/Compatibility/Core/src/Tizen/Renderers/RadioButtonRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/RadioButtonRenderer.cs index dab5c0fec1..4b26a7c684 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/RadioButtonRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/RadioButtonRenderer.cs @@ -1,10 +1,12 @@ using System; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using ESize = ElmSharp.Size; using TSpan = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Span; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class RadioButtonRenderer : ViewRenderer { readonly TSpan _span = new TSpan(); @@ -41,7 +43,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen base.Dispose(disposing); } - protected override Size MinimumSize() + protected override Graphics.Size MinimumSize() { return Measure(Control.MinimumWidth, Control.MinimumHeight).ToDP(); } @@ -78,7 +80,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateTextColor(bool isInitialized) { - _span.ForegroundColor = Element.TextColor.ToPlatform(); + _span.ForegroundColor = Element.TextColor.ToNative(); if (!isInitialized) ApplyTextAndStyle(); } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/RefreshViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/RefreshViewRenderer.cs index 7b609d5a06..dd28917aa1 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/RefreshViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/RefreshViewRenderer.cs @@ -1,13 +1,21 @@ using System; using System.Reflection; using System.Threading.Tasks; -using ElmSharp; +using Microsoft.Maui.Layouts; +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Controls.Platform; +using Rect = Microsoft.Maui.Graphics.Rect; using ERect = ElmSharp.Rect; +using EvasObject = ElmSharp.EvasObject; +using GestureLayer = ElmSharp.GestureLayer; +using Scroller = ElmSharp.Scroller; using TWebView = Tizen.WebView.WebView; +using XStackLayout = Microsoft.Maui.Controls.StackLayout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { - class RefreshIcon : ContentView + [Obsolete] + class RefreshIcon : AbsoluteLayout { public const int IconSize = ThemeConstants.RefreshView.Resources.IconSize; static readonly Color DefaultColor = ThemeConstants.RefreshView.ColorClass.DefaultColor; @@ -20,25 +28,19 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { HeightRequest = IconSize; WidthRequest = IconSize; - var layout = new AbsoluteLayout() - { - HeightRequest = IconSize, - WidthRequest = IconSize, - }; - layout.Children.Add(new BoxView + Children.Add(new BoxView { - Color = Color.White, + Color = Color.FromRgb(200, 200, 200), CornerRadius = new CornerRadius(IconSize), - }, new Rectangle(0.5, 0.5, IconSize, IconSize), AbsoluteLayoutFlags.PositionProportional); + }, new Rect(0.5, 0.5, IconSize, IconSize), AbsoluteLayoutFlags.PositionProportional); _icon = new Image { Source = ImageSource.FromResource(IconPath, typeof(ShellItemRenderer).Assembly), }; - layout.Children.Add(_icon, new Rectangle(0.5, 0.5, IconSize - 8, IconSize - 8), AbsoluteLayoutFlags.PositionProportional); - Content = layout; + Children.Add(_icon, new Rect(0.5, 0.5, IconSize - 8, IconSize - 8), AbsoluteLayoutFlags.PositionProportional); IconColor = DefaultColor; } @@ -51,7 +53,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } set { - PlatformConfiguration.TizenSpecific.Image.SetBlendColor(_icon, value == Color.Default ? DefaultColor : value); + PlatformConfiguration.TizenSpecific.Image.SetBlendColor(_icon, value == null ? DefaultColor : value); } } @@ -88,14 +90,15 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } } - class RefreshLayout : StackLayout + [Obsolete] + class RefreshLayout : XStackLayout { static readonly int MaximumDistance = 100; public RefreshLayout() { HeightRequest = 200; - HorizontalOptions = LayoutOptions.FillAndExpand; + HorizontalOptions = LayoutOptions.Fill; RefreshIcon = new RefreshIcon { @@ -105,6 +108,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Opacity = 0.5, }; Children.Add(RefreshIcon); + Children.Add(new BoxView + { + HeightRequest = 200 + }); } RefreshIcon RefreshIcon { get; set; } @@ -161,9 +168,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Loading, } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class RefreshViewRenderer : LayoutRenderer { - GestureLayer _gestureLayer; + ElmSharp.GestureLayer _gestureLayer; RefreshLayout _refreshLayout; IVisualElementRenderer _refreshLayoutRenderer; @@ -198,6 +206,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateRefreshLayout() { _refreshLayout = new RefreshLayout(); + _refreshLayout.Parent = Element; _refreshLayout.RefreshIconColor = RefreshView.RefreshColor; _refreshLayoutRenderer = Platform.GetOrCreateRenderer(_refreshLayout); (_refreshLayoutRenderer as ILayoutRenderer).RegisterOnLayoutUpdated(); @@ -274,7 +283,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen int GetScrollYOnGenList(IntPtr handle) { +#pragma warning disable IL2026 var interop = typeof(EvasObject).Assembly.GetType("Interop"); +#pragma warning disable IL2026 var elementary = interop?.GetNestedType("Elementary", BindingFlags.NonPublic | BindingFlags.Static) ?? null; if (elementary != null) diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ScrollViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ScrollViewRenderer.cs index 922d635b1c..b0ff4ff10b 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ScrollViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ScrollViewRenderer.cs @@ -1,15 +1,18 @@ using System; using System.ComponentModel; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; +using Microsoft.Maui.Devices; using EContainer = ElmSharp.Container; using ERect = ElmSharp.Rect; using NBox = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Box; using NScroller = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Scroller; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.ScrollView; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.ScrollView; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ScrollViewRenderer : ViewRenderer { EContainer _scrollCanvas; @@ -145,6 +148,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void OnContentLayoutUpdated(object sender, Native.LayoutEventArgs e) { + // It is workaround, + // in some case, before set a size of ScrollView, if content of content was filled with sized items, + // after size of ScrollView was updated, a content position was moved to somewhere. + if (Element.Content != null) + { + Platform.GetRenderer(Element.Content)?.NativeView?.Move(e.Geometry.X, e.Geometry.Y); + } UpdateContentSize(); } @@ -176,7 +186,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _scrollCanvas.MinimumHeight = Forms.ConvertToScaledPixel(Element.ContentSize.Height + Element.Padding.VerticalThickness); // elm-scroller updates the CurrentRegion after render - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { if (Control != null) { @@ -198,12 +208,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var y = e.ScrollY; if (e.Mode == ScrollToMode.Element) { - Point itemPosition = (Element as IScrollViewController).GetScrollPositionForElement(e.Element as VisualElement, e.Position); + Graphics.Point itemPosition = (Element as IScrollViewController).GetScrollPositionForElement(e.Element as VisualElement, e.Position); x = itemPosition.X; y = itemPosition.Y; } - ERect region = new Rectangle(x, y, Element.Width, Element.Height).ToPixel(); + ERect region = new Graphics.Rect(x, y, Element.Width, Element.Height).ToEFLPixel(); await Control.ScrollToAsync(region, e.ShouldAnimate); Element.SendScrollFinished(); } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/SearchBarRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/SearchBarRenderer.cs index 0959612dce..0416c05755 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/SearchBarRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/SearchBarRenderer.cs @@ -1,8 +1,10 @@ using System; +using Microsoft.Maui.Controls.Platform; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class SearchBarRenderer : ViewRenderer { @@ -64,7 +66,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen base.OnElementChanged(e); } - protected override Size MinimumSize() + protected override Graphics.Size MinimumSize() { return Control.Measure(Control.MinimumWidth, Control.MinimumHeight).ToDP(); } @@ -75,10 +77,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// void CancelButtonColorPropertyHandler(bool initialize) { - if (initialize && Element.CancelButtonColor.IsDefault) + if (initialize && Element.CancelButtonColor.IsDefault()) return; - Control.SetClearButtonColor(Element.CancelButtonColor.ToPlatform()); + Control.SetClearButtonColor(Element.CancelButtonColor.ToNative()); } /// @@ -97,7 +99,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// void FontFamilyPropertyHandler() { - Control.FontFamily = Element.FontFamily.ToNativeFontFamily(); + Control.FontFamily = Element.FontFamily.ToNativeFontFamily(Element.RequireFontManager()); } /// @@ -116,7 +118,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// void HorizontalTextAlignmentPropertyHandler() { - Control.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToPlatform(); + Control.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToNative(); } /// @@ -126,10 +128,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// void PlaceholderColorPropertyHandler(bool initialize) { - if (initialize && Element.TextColor.IsDefault) + if (initialize && Element.TextColor.IsDefault()) return; - Control.PlaceholderColor = Element.PlaceholderColor.ToPlatform(); + Control.PlaceholderColor = Element.PlaceholderColor.ToNative(); } /// @@ -168,10 +170,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// void TextColorPropertyHandler(bool initialize) { - if (initialize && Element.TextColor.IsDefault) + if (initialize && Element.TextColor.IsDefault()) return; - Control.TextColor = Element.TextColor.ToPlatform(); + Control.TextColor = Element.TextColor.ToNative(); } /// diff --git a/src/Compatibility/Core/src/Tizen/Renderers/SliderRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/SliderRenderer.cs index 290855dd0c..8536bc3138 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/SliderRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/SliderRenderer.cs @@ -1,11 +1,13 @@ using System; using System.ComponentModel; +using Microsoft.Maui.Controls.Platform; using EColor = ElmSharp.Color; using ESize = ElmSharp.Size; using ESlider = ElmSharp.Slider; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class SliderRenderer : ViewRenderer { EColor _defaultMinColor; @@ -117,18 +119,18 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateMinimumTrackColor() { - var color = Element.MinimumTrackColor.IsDefault ? _defaultMinColor : Element.MinimumTrackColor.ToPlatform(); + var color = Element.MinimumTrackColor.IsDefault() ? _defaultMinColor : Element.MinimumTrackColor.ToNative(); Control.SetBarColor(color); } protected virtual void UpdateMaximumTrackColor() { - Control.SetBackgroundColor(Element.MaximumTrackColor.IsDefault ? _defaultMaxColor : Element.MaximumTrackColor.ToPlatform()); + Control.SetBackgroundColor(Element.MaximumTrackColor.IsDefault() ? _defaultMaxColor : Element.MaximumTrackColor.ToNative()); } protected virtual void UpdateThumbColor() { - var color = Element.ThumbColor.IsDefault ? _defaultThumbColor : Element.ThumbColor.ToPlatform(); + var color = Element.ThumbColor.IsDefault() ? _defaultThumbColor : Element.ThumbColor.ToNative(); Control.SetHandlerColor(color); } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/StepperRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/StepperRenderer.cs index fcf565161d..5f0fed9929 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/StepperRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/StepperRenderer.cs @@ -1,9 +1,12 @@ using System; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch; +using Microsoft.Maui.Devices; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class StepperRenderer : ViewRenderer { diff --git a/src/Compatibility/Core/src/Tizen/Renderers/StructuredItemsViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/StructuredItemsViewRenderer.cs index 6a57d9f9b8..fd6e09193b 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/StructuredItemsViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/StructuredItemsViewRenderer.cs @@ -1,7 +1,9 @@ +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class StructuredItemsViewRenderer : ItemsViewRenderer { public StructuredItemsViewRenderer() diff --git a/src/Compatibility/Core/src/Tizen/Renderers/SwipeViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/SwipeViewRenderer.cs index 5ffa087724..b891670b07 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/SwipeViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/SwipeViewRenderer.cs @@ -1,8 +1,10 @@ using System; using System.Threading.Tasks; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Platform; using ERect = ElmSharp.Rect; +using XStackLayout = Microsoft.Maui.Controls.StackLayout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { @@ -12,6 +14,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Closed } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class SwipeViewRenderer : LayoutRenderer { static readonly double SwipeItemWidth = Forms.ConvertToScaledDP(100); @@ -81,7 +84,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { if (SwipeDirection == 0) { - var direction = SwipeDirectionHelper.GetSwipeDirection(new Point(moment.X1, moment.Y1), new Point(moment.X2, moment.Y2)); + var direction = SwipeDirectionHelper.GetSwipeDirection(new Graphics.Point(moment.X1, moment.Y1), new Graphics.Point(moment.X2, moment.Y2)); if (HasRightItems && direction == SwipeDirection.Left) { @@ -243,7 +246,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateItems() { CurrentItems = GetSwipedItems(); - var itemsLayout = new StackLayout + var itemsLayout = new XStackLayout { Spacing = 0, Orientation = IsHorizontalSwipe ? StackOrientation.Horizontal : StackOrientation.Vertical, @@ -271,7 +274,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen tap.CommandParameter = item.CommandParameter; tap.Tapped += (s, e) => { - if (item is SwipeItem swipeItem) + if (item is ISwipeItem swipeItem) swipeItem.OnInvoked(); if (item is SwipeItemView customSwipeItem) @@ -279,7 +282,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (CurrentItems.SwipeBehaviorOnInvoked != SwipeBehaviorOnInvoked.RemainOpen) { - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { _ = SwipeCloseAsync(); }); @@ -290,12 +293,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (IsHorizontalSwipe) { itemView.HorizontalOptions = LayoutOptions.Start; - itemView.VerticalOptions = LayoutOptions.FillAndExpand; + itemView.VerticalOptions = LayoutOptions.Fill; } else { itemView.VerticalOptions = LayoutOptions.Start; - itemView.HorizontalOptions = LayoutOptions.FillAndExpand; + itemView.HorizontalOptions = LayoutOptions.Fill; } itemsLayout.Children.Add(itemView); } @@ -344,10 +347,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen static View CreateItemView(SwipeItemView item) { - return new StackLayout + return new XStackLayout { - VerticalOptions = LayoutOptions.FillAndExpand, - HorizontalOptions = LayoutOptions.FillAndExpand, + VerticalOptions = LayoutOptions.Fill, + HorizontalOptions = LayoutOptions.Fill, Children = { item.Content @@ -365,34 +368,38 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { Text = item.Text, HorizontalTextAlignment = TextAlignment.Center, +#pragma warning disable CS0612 // Type or member is obsolete FontSize = Device.GetNamedSize(NamedSize.Default, typeof(Label)), +#pragma warning disable CS0612 // Type or member is obsolete }; if (horizontal) { - image.VerticalOptions = LayoutOptions.FillAndExpand; + image.VerticalOptions = LayoutOptions.Fill; image.HorizontalOptions = LayoutOptions.Start; - label.VerticalOptions = LayoutOptions.CenterAndExpand; - label.HorizontalOptions = LayoutOptions.CenterAndExpand; + label.VerticalOptions = LayoutOptions.Center; + label.HorizontalOptions = LayoutOptions.Center; label.VerticalTextAlignment = TextAlignment.Center; +#pragma warning disable CS0612 // Type or member is obsolete label.FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)); +#pragma warning disable CS0612 // Type or member is obsolete } else { - image.VerticalOptions = LayoutOptions.FillAndExpand; - image.HorizontalOptions = LayoutOptions.FillAndExpand; + image.VerticalOptions = LayoutOptions.Fill; + image.HorizontalOptions = LayoutOptions.Fill; - label.VerticalOptions = LayoutOptions.EndAndExpand; - label.HorizontalOptions = LayoutOptions.CenterAndExpand; + label.VerticalOptions = LayoutOptions.End; + label.HorizontalOptions = LayoutOptions.Center; label.VerticalTextAlignment = TextAlignment.End; } - var layout = new StackLayout + var layout = new XStackLayout { Padding = 5, BackgroundColor = item.BackgroundColor, - VerticalOptions = LayoutOptions.FillAndExpand, + VerticalOptions = LayoutOptions.Fill, Orientation = horizontal ? StackOrientation.Horizontal : StackOrientation.Vertical, Children = { diff --git a/src/Compatibility/Core/src/Tizen/Renderers/SwitchRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/SwitchRenderer.cs index 1932c6d88d..38973d228e 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/SwitchRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/SwitchRenderer.cs @@ -1,12 +1,14 @@ using System; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific; using EColor = ElmSharp.Color; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.VisualElement; -using SpecificSwitch = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Switch; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.VisualElement; +using SpecificSwitch = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Switch; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class SwitchRenderer : ViewRenderer { public SwitchRenderer() @@ -61,7 +63,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Control.Style = SwitchStyle.Toggle; break; } - ((IVisualElementController)Element).NativeSizeChanged(); + ((IVisualElementController)Element).PlatformSizeChanged(); UpdateBackgroundColor(false); UpdateOnColor(false); UpdateColor(); @@ -70,24 +72,24 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateColor() { var color = SpecificSwitch.GetColor(Element); - if (color != Color.Default) + if (color != null) { - Control.Color = color.ToPlatform(); + Control.Color = color.ToPlatformEFL(); } } protected void UpdateOnColor(bool initialize) { - if (initialize && Element.OnColor.IsDefault) + if (initialize && Element.OnColor.IsDefault()) return; - if (Element.OnColor.IsDefault) + if (Element.OnColor.IsDefault()) { Control.DeleteOnColors(); } else { - Control.SetOnColors(Element.OnColor.ToPlatform()); + Control.SetOnColors(Element.OnColor.ToPlatformEFL()); } } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/TabbedPageRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/TabbedPageRenderer.cs index 1ad9198615..8e0711ecfd 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/TabbedPageRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/TabbedPageRenderer.cs @@ -3,20 +3,24 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific; +using Microsoft.Maui.Devices; using EColor = ElmSharp.Color; using ERect = ElmSharp.Rect; +using EToolbar = ElmSharp.Toolbar; using EToolbarItem = ElmSharp.ToolbarItem; using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class TabbedPageRenderer : VisualElementRenderer { Box _outterLayout; Box _innerBox; Scroller _scroller; - Toolbar _toolbar; + EToolbar _toolbar; Dictionary _itemToItemPage = new Dictionary(); List _toolbarItemList = new List(); bool _isResettingToolbarItems = false; @@ -51,7 +55,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _outterLayout.Show(); //Create toolbar that is placed inside the _outterLayout - _toolbar = new Toolbar(Forms.NativeParent) + _toolbar = new EToolbar(Forms.NativeParent) { AlignmentX = -1, WeightX = 1, @@ -155,7 +159,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (!string.IsNullOrEmpty(style)) { _toolbar.Style = style; - ((IVisualElementController)Element).NativeSizeChanged(); + ((IVisualElementController)Element).PlatformSizeChanged(); UpdateBackgroundColor(false); UpdateBarBackgroundColor(false); UpdateSelectedTabColor(false); @@ -210,10 +214,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateBarBackgroundColor(bool initialize) { - if (initialize && Element.BarBackgroundColor.IsDefault) + if (initialize && Element.BarBackgroundColor.IsDefault()) return; - EColor bgColor = Element.BarBackgroundColor.ToPlatform(); + EColor bgColor = Element.BarBackgroundColor.ToPlatformEFL(); _toolbar.BackgroundColor = bgColor; foreach (EToolbarItem item in _itemToItemPage.Keys) { @@ -223,34 +227,34 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateBarTextColor(bool initialize) { - if (initialize && Element.BarTextColor.IsDefault) + if (initialize && Element.BarTextColor.IsDefault()) return; foreach (EToolbarItem item in _itemToItemPage.Keys) { - ApplyBarItemColors(item, BarItemColorType.Text, Element.BarTextColor.ToPlatform()); + ApplyBarItemColors(item, BarItemColorType.Text, Element.BarTextColor.ToPlatformEFL()); } } void UpdateSelectedTabColor(bool initialize) { - if (initialize && Element.SelectedTabColor.IsDefault) + if (initialize && Element.SelectedTabColor.IsDefault()) return; foreach (EToolbarItem item in _itemToItemPage.Keys) { - ApplyBarItemColors(item, BarItemColorType.SelectedTab, Element.SelectedTabColor.ToPlatform()); + ApplyBarItemColors(item, BarItemColorType.SelectedTab, Element.SelectedTabColor.ToPlatformEFL()); } } void UpdateUnselectedTabColor(bool initialize) { - if (initialize && Element.UnselectedTabColor.IsDefault) + if (initialize && Element.UnselectedTabColor.IsDefault()) return; foreach (EToolbarItem item in _itemToItemPage.Keys) { - ApplyBarItemColors(item, BarItemColorType.UnselectedTab, Element.UnselectedTabColor.ToPlatform()); + ApplyBarItemColors(item, BarItemColorType.UnselectedTab, Element.UnselectedTabColor.ToPlatformEFL()); } } @@ -322,10 +326,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _toolbarItemList.Insert(index, toolbarItem); _itemToItemPage.Add(toolbarItem, newItem); - ApplyBarItemColors(toolbarItem, BarItemColorType.Background, Element.BarBackgroundColor.ToPlatform()); - ApplyBarItemColors(toolbarItem, BarItemColorType.Text, Element.BarTextColor.ToPlatform()); - ApplyBarItemColors(toolbarItem, BarItemColorType.SelectedTab, Element.SelectedTabColor.ToPlatform()); - ApplyBarItemColors(toolbarItem, BarItemColorType.UnselectedTab, Element.UnselectedTabColor.ToPlatform()); + ApplyBarItemColors(toolbarItem, BarItemColorType.Background, Element.BarBackgroundColor.ToPlatformEFL()); + ApplyBarItemColors(toolbarItem, BarItemColorType.Text, Element.BarTextColor.ToPlatformEFL()); + ApplyBarItemColors(toolbarItem, BarItemColorType.SelectedTab, Element.SelectedTabColor.ToPlatformEFL()); + ApplyBarItemColors(toolbarItem, BarItemColorType.UnselectedTab, Element.UnselectedTabColor.ToPlatformEFL()); var childContent = Platform.GetOrCreateRenderer(newItem).NativeView; _innerBox.PackEnd(childContent); @@ -416,9 +420,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void OnCurrentPageChanged() { - // To update TabIndex order - CustomFocusManager.StartReorderTabIndex(); - if (_isUpdateByScroller || _isUpdateByToolbar || !_isInitialized) return; diff --git a/src/Compatibility/Core/src/Tizen/Renderers/TableViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/TableViewRenderer.cs index 6da95e76ff..b849441efd 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/TableViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/TableViewRenderer.cs @@ -1,9 +1,12 @@ using System; using ElmSharp; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; +using Microsoft.Maui.Devices; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class TableViewRenderer : ViewRenderer { internal static BindableProperty PresentationProperty = BindableProperty.Create("Presentation", typeof(View), typeof(TableSectionBase), null, BindingMode.OneWay, null, null, null, null, null as BindableProperty.CreateDefaultValueDelegate); diff --git a/src/Compatibility/Core/src/Tizen/Renderers/TimePickerRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/TimePickerRenderer.cs index e4d0b8c167..b9e91f3898 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/TimePickerRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/TimePickerRenderer.cs @@ -1,12 +1,17 @@ using System; using System.Globalization; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; +using Microsoft.Maui.Devices; +using Microsoft.Maui.Graphics; using EEntry = ElmSharp.Entry; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Application; +using NIEntry = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.IEntry; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Application; using WatchDateTimePickerDialog = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.Watch.WatchDateTimePickerDialog; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class TimePickerRenderer : ViewRenderer { //TODO need to add internationalization support @@ -47,7 +52,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen entry.SetVerticalTextAlignment(0.5); SetNativeControl(entry); - if (entry is IEntry ie) + if (entry is NIEntry ie) { ie.TextBlockFocused += OnTextBlockFocused; ie.EntryLayoutFocused += OnFocused; @@ -85,7 +90,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { if (Control != null) { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.TextBlockFocused -= OnTextBlockFocused; ie.EntryLayoutFocused -= OnFocused; @@ -128,7 +133,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen // You need to call Show() after ui thread occupation because of EFL problem. // Otherwise, the content of the popup will not receive focus. - Device.BeginInvokeOnMainThread(() => dialog.Show()); + Application.Current.Dispatcher.Dispatch(() => dialog.Show()); } } @@ -144,9 +149,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } protected virtual void UpdateTextColor() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { - ie.TextColor = Element.TextColor.ToPlatform(); + ie.TextColor = Element.TextColor.ToPlatformEFL(); } } @@ -158,7 +163,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontSize() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontSize = Element.FontSize; } @@ -166,7 +171,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontFamily() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontFamily = Element.FontFamily; } @@ -174,7 +179,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFontAttributes() { - if (Control is IEntry ie) + if (Control is NIEntry ie) { ie.FontAttributes = Element.FontAttributes; } diff --git a/src/Compatibility/Core/src/Tizen/Renderers/ViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/ViewRenderer.cs index 736b7fa4a8..23385e9449 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/ViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/ViewRenderer.cs @@ -5,10 +5,12 @@ using System.Diagnostics; using System.Linq; using ElmSharp; using ElmSharp.Wearable; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Application; +using Microsoft.Maui.Controls.Platform; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Application; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete("Use Microsoft.Maui.Controls.Handlers.Compatibility.ViewRenderer instead")] /// /// Base class for view renderers. /// diff --git a/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs index 12eb446d6e..2ad6d99ff3 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/VisualElementRenderer.cs @@ -4,19 +4,25 @@ using System.ComponentModel; using System.Linq; using ElmSharp; using ElmSharp.Accessible; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; +using Tizen.UIExtensions.ElmSharp; +using Size = Microsoft.Maui.Graphics.Size; +using Rect = Microsoft.Maui.Graphics.Rect; +using Point = Microsoft.Maui.Graphics.Point; using EFocusDirection = ElmSharp.FocusDirection; using ERect = ElmSharp.Rect; using ESize = ElmSharp.Size; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.VisualElement; -using XFocusDirection = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.FocusDirection; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.VisualElement; +using XFocusDirection = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.FocusDirection; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { /// /// Base class for rendering of a Xamarin element. /// + [Obsolete("Use Microsoft.Maui.Controls.Handlers.Compatibility.VisualElementRenderer instead")] public abstract class VisualElementRenderer : IVisualElementRenderer, IEffectControlProvider where TElement : VisualElement { readonly List> _elementChangedHandlers = new List>(); @@ -70,8 +76,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen RegisterPropertyHandler(VisualElement.RotationYProperty, UpdateTransformation); RegisterPropertyHandler(VisualElement.TranslationXProperty, UpdateTransformation); RegisterPropertyHandler(VisualElement.TranslationYProperty, UpdateTransformation); - RegisterPropertyHandler(VisualElement.TabIndexProperty, UpdateTabIndex); - RegisterPropertyHandler(VisualElement.IsTabStopProperty, UpdateIsTabStop); RegisterPropertyHandler(AutomationProperties.NameProperty, SetAccessibilityName); RegisterPropertyHandler(AutomationProperties.HelpTextProperty, SetAccessibilityDescription); @@ -89,7 +93,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Dispose(false); } - event EventHandler ElementChanged + event EventHandler IVisualElementRenderer.ElementChanged { add { @@ -120,6 +124,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public EvasObject NativeView { get; private set; } + public event EventHandler> ElementChanged; + protected bool IsDisposed => _flags.HasFlag(VisualElementRendererFlags.Disposed); /// @@ -295,7 +301,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } // Reset Element geometry, to re-calculate when Renderer was re-attached - Element.Layout(new Rectangle(0, 0, -1, -1)); + Element.Layout(new Rect(0, 0, -1, -1)); Element = default(TElement); } @@ -338,6 +344,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } } + var args = new VisualElementChangedEventArgs(e.OldElement, e.NewElement); + for (var i = 0; i < _elementChangedHandlers.Count; i++) + _elementChangedHandlers[i](this, args); + + ElementChanged?.Invoke(this, e); + if (null != e.NewElement) { e.NewElement.PropertyChanged += OnElementPropertyChanged; @@ -496,29 +508,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } } - protected Widget FocusSearch(bool forwardDirection) - { - VisualElement element = Element as VisualElement; - int maxAttempts = 0; - var tabIndexes = element?.GetTabIndexesOnParentPage(out maxAttempts); - if (tabIndexes == null) - return null; - - int tabIndex = Element.TabIndex; - int attempt = 0; - - do - { - element = element.FindNextElement(forwardDirection, tabIndexes, ref tabIndex) as VisualElement; - var renderer = Platform.GetRenderer(element); - if (renderer?.NativeView is Widget widget && widget.IsFocusAllowed) - { - return widget; - } - } while (!(element.IsFocused || ++attempt >= maxAttempts)); - return null; - } - internal virtual void SendVisualElementInitialized(VisualElement element, EvasObject nativeView) { element.SendViewInitialized(nativeView); @@ -526,7 +515,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateNativeGeometry() { - var updatedGeometry = new Rectangle(ComputeAbsolutePoint(Element), new Size(Element.Width, Element.Height)).ToPixel(); + var updatedGeometry = new Rect(ComputeAbsolutePoint(Element), new Size(Element.Width, Element.Height)).ToEFLPixel(); if (NativeView.Geometry != updatedGeometry) { @@ -644,12 +633,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateBackgroundColor(bool initialize) { - if (initialize && Element.BackgroundColor.IsDefault) + if (initialize && Element.BackgroundColor.IsDefault()) return; if (NativeView is Widget) { - (NativeView as Widget).BackgroundColor = Element.BackgroundColor.ToPlatform(); + (NativeView as Widget).BackgroundColor = Element.BackgroundColor.ToPlatformEFL(); } else { @@ -702,15 +691,23 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen static double ComputeAbsoluteX(VisualElement e) { var parentX = 0.0; - if (e.RealParent is VisualElement ve) + if (e.RealParent is VisualElement parent) { if (CompressedLayout.GetIsHeadless(e.RealParent)) { - parentX = ComputeAbsoluteX(ve); + parentX = ComputeAbsoluteX(parent); } else { - parentX = Forms.ConvertToScaledDP(Platform.GetRenderer(e.RealParent).GetNativeContentGeometry().X); + if (parent.Handler is IPlatformViewHandler nativeHandler) + { + + parentX = nativeHandler.GetPlatformContentGeometry().X.ToScaledDP(); + } + else + { + parentX = Forms.ConvertToScaledDP(Platform.GetRenderer(e.RealParent).GetNativeContentGeometry().X); + } } } return e.X + parentX; @@ -719,15 +716,22 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen static double ComputeAbsoluteY(VisualElement e) { var parentY = 0.0; - if (e.RealParent is VisualElement ve) + if (e.RealParent is VisualElement parent) { if (CompressedLayout.GetIsHeadless(e.RealParent)) { - parentY = ComputeAbsoluteY(ve); + parentY = ComputeAbsoluteY(parent); } else { - parentY = Forms.ConvertToScaledDP(Platform.GetRenderer(e.RealParent).GetNativeContentGeometry().Y); + if (parent.Handler is IPlatformViewHandler nativeHandler) + { + parentY = nativeHandler.GetPlatformContentGeometry().Y.ToScaledDP(); + } + else + { + parentY = Forms.ConvertToScaledDP(Platform.GetRenderer(e.RealParent).GetNativeContentGeometry().Y); + } } } return e.Y + parentY; @@ -787,7 +791,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void AddHeadlessChild(VisualElement element, IContainable parent) { - foreach (var child in element.LogicalChildren) + foreach (var child in (element as IVisualTreeElement).GetVisualChildren()) { if (child is VisualElement visualChild) { @@ -875,8 +879,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen /// The effect to register. void OnRegisterEffect(PlatformEffect effect) { - effect.SetContainer(Element.Parent == null ? null : Platform.GetRenderer(Element.Parent)?.NativeView); - effect.SetControl(NativeView); + effect.Container = Element.Parent == null ? null : Platform.GetRenderer(Element.Parent)?.NativeView; + effect.Control = NativeView; } void OnMoved(object sender, EventArgs e) @@ -1185,32 +1189,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } } - void UpdateTabIndex() - { - if (!Forms.Flags.Contains(Flags.DisableTabIndex)) - { - if (Element is View && NativeView is Widget widget && widget.IsFocusAllowed) - { - _customFocusManager.Value.TabIndex = Element.TabIndex; - } - } - } - - void UpdateIsTabStop(bool init) - { - if (init && Element.IsTabStop) - { - return; - } - if (!Forms.Flags.Contains(Flags.DisableTabIndex)) - { - if (Element is View && NativeView is Widget widget && widget.IsFocusAllowed) - { - _customFocusManager.Value.IsTabStop = Element.IsTabStop; - } - } - } - EFocusDirection ConvertToNativeFocusDirection(string direction) { if (direction == XFocusDirection.Back) diff --git a/src/Compatibility/Core/src/Tizen/Renderers/WebViewRenderer.cs b/src/Compatibility/Core/src/Tizen/Renderers/WebViewRenderer.cs index c6d1750f2b..97dd1345c2 100644 --- a/src/Compatibility/Core/src/Tizen/Renderers/WebViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Renderers/WebViewRenderer.cs @@ -1,13 +1,15 @@ using System; using System.ComponentModel; using System.Threading.Tasks; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; using TChromium = Tizen.WebView.Chromium; using TWebView = Tizen.WebView.WebView; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class WebViewRenderer : ViewRenderer, IWebViewDelegate { bool _isUpdating; @@ -44,11 +46,11 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (Element != null) { - Element.EvalRequested -= OnEvalRequested; - Element.EvaluateJavaScriptRequested -= OnEvaluateJavaScriptRequested; - Element.GoBackRequested -= OnGoBackRequested; - Element.GoForwardRequested -= OnGoForwardRequested; - Element.ReloadRequested -= OnReloadRequested; + ((IWebViewController)Element).EvalRequested -= OnEvalRequested; + ((IWebViewController)Element).EvaluateJavaScriptRequested -= OnEvaluateJavaScriptRequested; + ((IWebViewController)Element).GoBackRequested -= OnGoBackRequested; + ((IWebViewController)Element).GoForwardRequested -= OnGoForwardRequested; + ((IWebViewController)Element).ReloadRequested -= OnReloadRequested; } } base.Dispose(disposing); @@ -68,19 +70,19 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (e.OldElement != null) { - e.OldElement.EvalRequested -= OnEvalRequested; - e.OldElement.GoBackRequested -= OnGoBackRequested; - e.OldElement.GoForwardRequested -= OnGoForwardRequested; - e.OldElement.ReloadRequested -= OnReloadRequested; + ((IWebViewController)e.OldElement).EvalRequested -= OnEvalRequested; + ((IWebViewController)e.OldElement).GoBackRequested -= OnGoBackRequested; + ((IWebViewController)e.OldElement).GoForwardRequested -= OnGoForwardRequested; + ((IWebViewController)e.OldElement).ReloadRequested -= OnReloadRequested; } if (e.NewElement != null) { - e.NewElement.EvalRequested += OnEvalRequested; - e.NewElement.EvaluateJavaScriptRequested += OnEvaluateJavaScriptRequested; - e.NewElement.GoForwardRequested += OnGoForwardRequested; - e.NewElement.GoBackRequested += OnGoBackRequested; - e.NewElement.ReloadRequested += OnReloadRequested; + ((IWebViewController)e.NewElement).EvalRequested += OnEvalRequested; + ((IWebViewController)e.NewElement).EvaluateJavaScriptRequested += OnEvaluateJavaScriptRequested; + ((IWebViewController)e.NewElement).GoForwardRequested += OnGoForwardRequested; + ((IWebViewController)e.NewElement).GoBackRequested += OnGoBackRequested; + ((IWebViewController)e.NewElement).ReloadRequested += OnReloadRequested; Load(); } base.OnElementChanged(e); @@ -107,7 +109,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (!string.IsNullOrEmpty(url)) { var args = new WebNavigatingEventArgs(_eventState, new UrlWebViewSource { Url = url }, url); - Element.SendNavigating(args); + ElementController.SendNavigating(args); if (args.Cancel) { @@ -180,15 +182,16 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void SendNavigated(UrlWebViewSource source, WebNavigationEvent evnt, WebNavigationResult result) { _isUpdating = true; - ((IElementController)Element).SetValueFromRenderer(WebView.SourceProperty, source); + ElementController.SetValueFromRenderer(WebView.SourceProperty, source); _isUpdating = false; - Element.SendNavigated(new WebNavigatedEventArgs(evnt, source, source.Url, result)); + ElementController.SendNavigated(new WebNavigatedEventArgs(evnt, source, source.Url, result)); UpdateCanGoBackForward(); _eventState = WebNavigationEvent.NewPage; } + [PortHandler] void UpdateCanGoBackForward() { ElementController.CanGoBack = NativeWebView.CanGoBack(); diff --git a/src/Compatibility/Core/src/Tizen/Resource/arrow_left.png b/src/Compatibility/Core/src/Tizen/Resource/arrow_left.png deleted file mode 100644 index 923dfeb34fef7636cd416788a5e63a0e782c54b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 490 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+eS5K)hhiu0R{01Y44~ zy9wy$!fk$L9koEv$x0Bg+K*nlM7srr@!*8$K^D#O~w0$ghaeB$4mmL1u zN=VndfR%Ua@l1g#AZBg%d{)IqvO18)$c9z>fY|)pqQz=^8N{xpsHQv z%kvz39g0e`{Wh?wRqfd{wXPslUi_7!$tjJ+ObZ^>9NIVI%9>E0)F8vU<~hYP&*>kV z_bY3$OEu8hswJ)wB`Jv|saDBFsX&Us$iUE2*T7iU$Rfnh$ja2f%Gg}nz`)ADK-@hP z6dVW*x%nxXX_dG&q)EMP0BX|k1|%Oc%$NbBSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+eS5K)hhiu0R{01Y44~ zy9wy$!fk$L9koEv$x0Bg+Kt_tEi(^Q{;kTCzxf%=vTrMU|+8nJAKfQsj&e~cXmcv2Erg#_GFs<>6xUFz`3Ul>!lrT4@f-?e^I zZ`)~H4$XMEWAD_R;m2m25{PcDoikCz^VbE&TR(+f`^(mWoTFOe8c~vxSdwa$T$Bo= z7>o=IEp-iyb&V`S42`TzO{@$Iv<(b^WN6D7Z4?c;`6-!cmAEyi+$@<6)Sv;fp|~vF zDk-rzRkyS#lOZiLC)G+{U%w=`KtDGzJu^95*V54?(BCLOE4y2A9Z(O0r>mdKI;Vst E0GM@v1^@s6 diff --git a/src/Compatibility/Core/src/Tizen/Resource/menu.png b/src/Compatibility/Core/src/Tizen/Resource/menu.png deleted file mode 100644 index 6dcfc0575a1d6c10f34cf6df4933ce31b21ccf02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 417 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbBSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+eS5K)hhiu0R{01Y44~ zy9wy$!fk$L9koEv$x0Bg+Kt__Mi(^Q{;kVZUxf&D%S{~kfk#J9^|Jm7P z*M&HpZnXS+UnrO^DKLeB;e1Z`^Od##zLheb)@M1>RhO{aL(B80uF|d24g7qfp6*GS z+gqnqe_Pyk>$bOAO4`HqKkC-(6JS_S%+#a$)V%xH<2;~kswJ)wB`Jv|saDBFsX&Us z$iUE2*T7iU$Rfnh$ja2%%Gglbz`)ADVE%&JAnzkI>Kms6W9c%CLbv5?y>lcGmG9$4EYK8l7-o zfCt%5&_vEG;B#z+(*j(;8iLx8AqB)q^mJB$I7Sgvo_Hw)l4$Izz#9ZrRX8lwofIIG zCD_^#FNH*Pa8uw1Y!k_pLZUo4DL^JGF>T}`7xA?Ue1`2;H}SO!jKnmD6gTlz3UCRw zFQiZ?0WJ&tiD?a4uHx$y7=o$1yZ8zPIEw9Yf{UXY!kL?Z7LK-VDZRA2x#4XqssD3u`z2@SsjSMDYdr$jq zuozo=;+1xtyI`B9{@Kp!S{ocTY7%s>Xd{jhA#5?lQ<9(-5(X}04MAoRtzpSy4Ug_$K~_E{6E{sPH_nr4P%TNoSet-uh_@lezJv#6owRZ z*n=eQrv~fDNqdq+fzG(iO?$^}QaPE6xs{J;%Q|9dOrp3!0@ct~o;Y!dr&)=X4ZJSy zaXLNGFpTr%&>)TvSWjWh=XI@1$Nk{zDt;tQ6zGf|k0w86@q@-HtNY<^m_<46C;o6A zzrS_w`2BEZvk`#pOrse;@i?c663_EI&+|Ob^Sm9?3(oMoN8C*S0000VM%xNb!1@J z*w6hZkrl}2EbxddW??NMQuI!IEm{={W z*VeIw15H)*ba4#v@P2#M*NfRvpzUE`jFhRAt9cc>ZDW%{M~8yq@eA4<_YSqrXmBd~ zH^*U5i+5n>f*qxa68HVpolE^yTW+#k3G#989r6krBDY-7e?Ftx{B==x?VAUZX74M0SDsls`)2EQ_r~a+ zGY>=x-)(40y|YSSX{Xj6+v2>7Hx4Q1?6Nq_B>DD+YPLH{%LfM|K{x*(15SP5a2jgC&a{>o=T;IrNOV{l~wXa+9j~7evm^ zX4!jCX>&)o#`lQk>*hV78T_vIr>U~o9z3+-F^_1lcDB&1)rna<|JNVhU)P}WlWB*o WRE1^#Dj{I_F?hQAxvX { protected override void OnElementChanged(ElementChangedEventArgs e) diff --git a/src/Compatibility/Core/src/Tizen/Shapes/LineRenderer.cs b/src/Compatibility/Core/src/Tizen/Shapes/LineRenderer.cs index c1bbd1f064..c7c4213610 100644 --- a/src/Compatibility/Core/src/Tizen/Shapes/LineRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shapes/LineRenderer.cs @@ -1,8 +1,10 @@ using SkiaSharp; -using Microsoft.Maui.Controls.Compatibility.Shapes; +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class LineRenderer : ShapeRenderer { public LineRenderer() : base() diff --git a/src/Compatibility/Core/src/Tizen/Shapes/PathRenderer.cs b/src/Compatibility/Core/src/Tizen/Shapes/PathRenderer.cs index 03b79a8f01..5655a460e5 100644 --- a/src/Compatibility/Core/src/Tizen/Shapes/PathRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shapes/PathRenderer.cs @@ -1,8 +1,10 @@ using SkiaSharp; -using Path = Microsoft.Maui.Controls.Compatibility.Shapes.Path; +using Microsoft.Maui.Controls.Platform; +using Path = Microsoft.Maui.Controls.Shapes.Path; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PathRenderer : ShapeRenderer { public PathRenderer() : base() diff --git a/src/Compatibility/Core/src/Tizen/Shapes/PolygonRenderer.cs b/src/Compatibility/Core/src/Tizen/Shapes/PolygonRenderer.cs index 5eafb47b29..b9e140fdd4 100644 --- a/src/Compatibility/Core/src/Tizen/Shapes/PolygonRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shapes/PolygonRenderer.cs @@ -1,9 +1,11 @@ using System.Collections.Specialized; using SkiaSharp; -using Microsoft.Maui.Controls.Compatibility.Shapes; +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PolygonRenderer : ShapeRenderer { public PolygonRenderer() : base() diff --git a/src/Compatibility/Core/src/Tizen/Shapes/PolylineRenderer.cs b/src/Compatibility/Core/src/Tizen/Shapes/PolylineRenderer.cs index a498f74c8f..46766f2302 100644 --- a/src/Compatibility/Core/src/Tizen/Shapes/PolylineRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shapes/PolylineRenderer.cs @@ -1,9 +1,11 @@ using System.ComponentModel; using SkiaSharp; -using Microsoft.Maui.Controls.Compatibility.Shapes; +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class PolylineRenderer : ShapeRenderer { public PolylineRenderer() : base() diff --git a/src/Compatibility/Core/src/Tizen/Shapes/RectangleRenderer.cs b/src/Compatibility/Core/src/Tizen/Shapes/RectangleRenderer.cs index a7492df9e7..5fc3973d87 100644 --- a/src/Compatibility/Core/src/Tizen/Shapes/RectangleRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shapes/RectangleRenderer.cs @@ -1,9 +1,11 @@ using SkiaSharp; -using FormsRectangle = Microsoft.Maui.Controls.Compatibility.Shapes.Rectangle; +using Microsoft.Maui.Controls.Platform; +using FormsRectangle = Microsoft.Maui.Controls.Shapes.Rectangle; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class RectangleRenderer : ShapeRenderer { public RectangleRenderer() : base() diff --git a/src/Compatibility/Core/src/Tizen/Shapes/ShapeRenderer.cs b/src/Compatibility/Core/src/Tizen/Shapes/ShapeRenderer.cs index f34c3cf56d..50f74f6ccf 100644 --- a/src/Compatibility/Core/src/Tizen/Shapes/ShapeRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shapes/ShapeRenderer.cs @@ -1,10 +1,11 @@ using System.Linq; using SkiaSharp; -using Microsoft.Maui.Controls.Compatibility.Shapes; -using Shape = Microsoft.Maui.Controls.Compatibility.Shapes.Shape; +using Microsoft.Maui.Controls.Shapes; +using Shape = Microsoft.Maui.Controls.Shapes.Shape; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShapeRenderer : ViewRenderer where TShape : Shape where TNativeShape : ShapeView diff --git a/src/Compatibility/Core/src/Tizen/Shell/IShellTabs.cs b/src/Compatibility/Core/src/Tizen/Shell/IShellTabs.cs index 7cd54531fd..a8f195df61 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/IShellTabs.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/IShellTabs.cs @@ -2,6 +2,7 @@ using System; using ElmSharp; using EColor = ElmSharp.Color; using EToolbarItem = ElmSharp.ToolbarItem; +using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { @@ -15,7 +16,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen EToolbarItem SelectedItem { get; } - event EventHandler Selected; + event EventHandler Selected; EToolbarItem Append(string label, string icon); EToolbarItem Append(string label); diff --git a/src/Compatibility/Core/src/Tizen/Shell/NavigationDrawer.cs b/src/Compatibility/Core/src/Tizen/Shell/NavigationDrawer.cs index 57d5ab5a69..5963f308c6 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/NavigationDrawer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/NavigationDrawer.cs @@ -7,6 +7,7 @@ using ERect = ElmSharp.Rect; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class NavigationDrawer : EBox, INavigationDrawer, IAnimatable { EvasObject _navigationView; diff --git a/src/Compatibility/Core/src/Tizen/Shell/NavigationView.cs b/src/Compatibility/Core/src/Tizen/Shell/NavigationView.cs index a0b4d129dc..8690c53616 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/NavigationView.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/NavigationView.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; using EColor = ElmSharp.Color; using EImage = ElmSharp.Image; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class NavigationView : Background, INavigationView { static EColor s_defaultBackgroundColor = EColor.White; @@ -311,7 +312,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { FontSize = this.GetFlyoutItemFontSize(), VerticalTextAlignment = TextAlignment.Center, - TextColor = Microsoft.Maui.Controls.Compatibility.Color.Black.MultiplyAlpha(0.87), + TextColor = Graphics.Color.FromRgb(0,0,0).MultiplyAlpha(0.87f), Margin = new Thickness(this.GetFlyoutMargin(), 0, 0, 0), }; label.SetBinding(Label.TextProperty, new Binding(textBinding)); @@ -333,7 +334,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen selectedState.Setters.Add(new Setter { Property = VisualElement.BackgroundColorProperty, - Value = new Color(0.95) + Value = new Graphics.Color(0.95f) }); commonGroup.States.Add(selectedState); @@ -467,7 +468,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } else { - Device.BeginInvokeOnMainThread(OnLayout); + Application.Current.Dispatcher.Dispatch(OnLayout); } } diff --git a/src/Compatibility/Core/src/Tizen/Shell/SearchHandlerRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/SearchHandlerRenderer.cs index 3465bc6ea1..a252fa2fbd 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/SearchHandlerRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/SearchHandlerRenderer.cs @@ -6,6 +6,7 @@ using NSearchBar = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.S namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class SearchHandlerRenderer : IDisposable { bool disposedValue; @@ -152,7 +153,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { var data = (e.Item.Data as View).BindingContext; SearchHandlerController.ItemSelected(data); - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { DeinitializeSearchResultList(); }); @@ -222,18 +223,18 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateBackgroundColor() { - var color = Element.BackgroundColor.ToPlatform(); + var color = Element.BackgroundColor.ToNative(); Control.BackgroundColor = color == EColor.Default ? EColor.White : color; } void UpdateTextColor() { - Control.TextColor = Element.TextColor.ToPlatform(); + Control.TextColor = Element.TextColor.ToNative(); } void UpdateHorizontalTextAlignment() { - Control.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToPlatform(); + Control.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToNative(); } void OnFocusChangedRequested(object sender, VisualElement.FocusRequestArgs e) @@ -244,7 +245,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateKeyboard() { - Control.Keyboard = Element.Keyboard.ToPlatform(); + Control.Keyboard = Element.Keyboard.ToNative(); } void UpdatePlaceholder() @@ -253,7 +254,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } void UpdatePlaceholderColor() { - Control.PlaceholderColor = Element.PlaceholderColor.ToPlatform(); + Control.PlaceholderColor = Element.PlaceholderColor.ToNative(); } void OnFocused(object sender, EventArgs e) @@ -269,14 +270,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { _searchResultList.Hide(); } - Device.BeginInvokeOnMainThread(() => - { - Device.StartTimer(TimeSpan.FromMilliseconds(100), () => - { - DeinitializeSearchResultList(); - return false; - }); - }); + Application.Current.Dispatcher.DispatchDelayed(TimeSpan.FromMilliseconds(100), () => DeinitializeSearchResultList()); } } diff --git a/src/Compatibility/Core/src/Tizen/Shell/SearchResultList.cs b/src/Compatibility/Core/src/Tizen/Shell/SearchResultList.cs index dfcc3d748a..8f7c70c60b 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/SearchResultList.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/SearchResultList.cs @@ -4,6 +4,7 @@ using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete] public class SearchResultList : GenList { GenItemClass _defaultClass = null; diff --git a/src/Compatibility/Core/src/Tizen/Shell/ShellItemRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/ShellItemRenderer.cs index fcca304173..95f38abd0e 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/ShellItemRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/ShellItemRenderer.cs @@ -9,9 +9,11 @@ using EBox = ElmSharp.Box; using EColor = ElmSharp.Color; using EImage = ElmSharp.Image; using EToolbarItem = ElmSharp.ToolbarItem; +using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellItemRenderer : IAppearanceObserver, IDisposable { // The source of icon resources is https://materialdesignicons.com/ @@ -32,8 +34,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen List _tabsItems = new List(); bool _disposed = false; - EColor _tabBarBackgroudColor = ShellRenderer.DefaultBackgroundColor.ToPlatform(); - EColor _tabBarTitleColor = ShellRenderer.DefaultTitleColor.ToPlatform(); + EColor _tabBarBackgroudColor = ShellRenderer.DefaultBackgroundColor.ToNative(); + EColor _tabBarTitleColor = ShellRenderer.DefaultTitleColor.ToNative(); public ShellItemRenderer(ShellItem item) { @@ -282,10 +284,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance) { - var tabBarBackgroudColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarBackgroundColor ?? Color.Default; - var tabBarTitleColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarTitleColor ?? Color.Default; - TabBarBackgroundColor = tabBarBackgroudColor.IsDefault ? ShellRenderer.DefaultBackgroundColor.ToPlatform() : tabBarBackgroudColor.ToPlatform(); - TabBarTitleColor = tabBarTitleColor.IsDefault ? ShellRenderer.DefaultTitleColor.ToPlatform() : tabBarTitleColor.ToPlatform(); + var tabBarBackgroudColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarBackgroundColor; + var tabBarTitleColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarTitleColor; + TabBarBackgroundColor = tabBarBackgroudColor.IsDefault() ? ShellRenderer.DefaultBackgroundColor.ToNative() : tabBarBackgroudColor.ToNative(); + TabBarTitleColor = tabBarTitleColor.IsDefault() ? ShellRenderer.DefaultTitleColor.ToNative() : tabBarTitleColor.ToNative(); } void UpdateTabsBackgroudColor(EColor color) @@ -388,7 +390,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _contentHolder.PackEnd(_currentStack); } - void OnTabsSelected(object sender, ToolbarItemEventArgs e) + void OnTabsSelected(object sender, EToolbarItemEventArgs e) { if (_tabs.SelectedItem == null) return; diff --git a/src/Compatibility/Core/src/Tizen/Shell/ShellMoreToolbar.cs b/src/Compatibility/Core/src/Tizen/Shell/ShellMoreToolbar.cs index 47b15be3cd..edee7e2b55 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/ShellMoreToolbar.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/ShellMoreToolbar.cs @@ -5,6 +5,7 @@ using EImage = ElmSharp.Image; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class ShellMoreToolbar : GenList { GenItemClass _defaultClass = null; @@ -15,7 +16,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen SetWeight(1, 1); Homogeneous = true; SelectionMode = GenItemSelectionMode.Always; - BackgroundColor = ShellRenderer.DefaultBackgroundColor.ToPlatform(); + BackgroundColor = ShellRenderer.DefaultBackgroundColor.ToNative(); _defaultClass = new GenItemClass(ThemeConstants.GenItemClass.Styles.Full) { GetContentHandler = GetContent, diff --git a/src/Compatibility/Core/src/Tizen/Shell/ShellNavBar.cs b/src/Compatibility/Core/src/Tizen/Shell/ShellNavBar.cs index 30f1546ae9..3cceea6169 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/ShellNavBar.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/ShellNavBar.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using Microsoft.Maui.Devices; using ElmSharp; using EBox = ElmSharp.Box; using EButton = ElmSharp.Button; @@ -8,6 +9,7 @@ using EImage = ElmSharp.Image; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class ShellNavBar : EBox, IFlyoutBehaviorObserver, IDisposable { EImage _menuIcon = null; @@ -22,9 +24,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen FlyoutBehavior _flyoutBehavior = FlyoutBehavior.Flyout; - EColor _backgroudColor = ShellRenderer.DefaultBackgroundColor.ToPlatform(); - EColor _foregroudColor = ShellRenderer.DefaultForegroundColor.ToPlatform(); - EColor _titleColor = ShellRenderer.DefaultTitleColor.ToPlatform(); + EColor _backgroudColor = ShellRenderer.DefaultBackgroundColor.ToNative(); + EColor _foregroudColor = ShellRenderer.DefaultForegroundColor.ToNative(); + EColor _titleColor = ShellRenderer.DefaultTitleColor.ToNative(); // The source of icon resources is https://materialdesignicons.com/ const string _menuIconRes = ThemeConstants.Shell.Resources.MenuIcon; diff --git a/src/Compatibility/Core/src/Tizen/Shell/ShellRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/ShellRenderer.cs index 729bb4356b..3237ad9464 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/ShellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/ShellRenderer.cs @@ -1,7 +1,10 @@ using System; +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellRenderer : VisualElementRenderer, IFlyoutController { INavigationDrawer _drawer; @@ -119,7 +122,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void UpdateFlyoutBackgroundColor() { - _navigationView.BackgroundColor = Element.FlyoutBackgroundColor.ToPlatform(); + _navigationView.BackgroundColor = Element.FlyoutBackgroundColor.ToPlatformEFL(); } void UpdateFlyoutBackgroundImageAspect() @@ -135,7 +138,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen protected virtual void UpdateFlyoutIsPresented() { // It is workaround of Panel.IsOpen bug, Panel.IsOpen property is not working when layouting was triggered - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { _drawer.IsOpen = Element.FlyoutIsPresented; }); diff --git a/src/Compatibility/Core/src/Tizen/Shell/ShellSectionRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/ShellSectionRenderer.cs index b04a0877ab..3cc160c230 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/ShellSectionRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/ShellSectionRenderer.cs @@ -6,6 +6,7 @@ using ElmSharp; using EBox = ElmSharp.Box; using EColor = ElmSharp.Color; using EToolbarItem = ElmSharp.ToolbarItem; +using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { @@ -14,6 +15,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen EvasObject NativeView { get; } } + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellSectionRenderer : IAppearanceObserver, IShellSectionRenderer { EBox _mainLayout = null; @@ -27,8 +29,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Dictionary _itemToContent = new Dictionary(); List _tabsItems = new List(); - EColor _backgroundColor = ShellRenderer.DefaultBackgroundColor.ToPlatform(); - EColor _foregroundColor = ShellRenderer.DefaultForegroundColor.ToPlatform(); + EColor _backgroundColor = ShellRenderer.DefaultBackgroundColor.ToNative(); + EColor _foregroundColor = ShellRenderer.DefaultForegroundColor.ToNative(); bool _disposed = false; @@ -127,10 +129,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance) { - var backgroundColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarBackgroundColor ?? Color.Default; - var foregroundColor = appearance?.ForegroundColor ?? Color.Default; - ToolbarBackgroundColor = backgroundColor.IsDefault ? ShellRenderer.DefaultBackgroundColor.ToPlatform() : backgroundColor.ToPlatform(); - ToolbarForegroundColor = foregroundColor.IsDefault ? ShellRenderer.DefaultForegroundColor.ToPlatform() : foregroundColor.ToPlatform(); + var backgroundColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarBackgroundColor; + var foregroundColor = appearance?.ForegroundColor; + ToolbarBackgroundColor = backgroundColor.IsDefault() ? ShellRenderer.DefaultBackgroundColor.ToNative() : backgroundColor.ToNative(); + ToolbarForegroundColor = foregroundColor.IsDefault() ? ShellRenderer.DefaultForegroundColor.ToNative() : foregroundColor.ToNative(); } void UpdateDisplayedPage(Page page) @@ -296,7 +298,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen UpdateTabsItem(); } - void OnTabsSelected(object sender, ToolbarItemEventArgs e) + void OnTabsSelected(object sender, EToolbarItemEventArgs e) { if (_tabs.SelectedItem == null) { diff --git a/src/Compatibility/Core/src/Tizen/Shell/ShellSectionStack.cs b/src/Compatibility/Core/src/Tizen/Shell/ShellSectionStack.cs index bce506b0da..ecd126a3ec 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/ShellSectionStack.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/ShellSectionStack.cs @@ -1,11 +1,13 @@ using System; using System.ComponentModel; using System.Threading.Tasks; +using Microsoft.Maui.Devices; using ElmSharp; using EBox = ElmSharp.Box; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class ShellSectionStack : EBox, IAppearanceObserver, IDisposable { ShellNavBar _navBar = null; @@ -110,7 +112,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen _shellSectionRenderer.NativeView.Show(); _viewStack.Push(_shellSectionRenderer.NativeView); - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { (_shellSectionRenderer.NativeView as Widget)?.SetFocus(true); }); @@ -137,13 +139,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen if (_navBar == null) return; - var titleColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarTitleColor ?? Microsoft.Maui.Controls.Compatibility.Color.Default; - var backgroundColor = appearance?.BackgroundColor ?? Microsoft.Maui.Controls.Compatibility.Color.Default; - var foregroundColor = appearance?.ForegroundColor ?? Microsoft.Maui.Controls.Compatibility.Color.Default; + var titleColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarTitleColor; + var backgroundColor = appearance?.BackgroundColor; + var foregroundColor = appearance?.ForegroundColor; - _navBar.TitleColor = titleColor.IsDefault ? ShellRenderer.DefaultTitleColor.ToPlatform() : titleColor.ToPlatform(); - _navBar.BackgroundColor = backgroundColor.IsDefault ? ShellRenderer.DefaultBackgroundColor.ToPlatform() : backgroundColor.ToPlatform(); - _navBar.ForegroundColor = foregroundColor.IsDefault ? ShellRenderer.DefaultForegroundColor.ToPlatform() : foregroundColor.ToPlatform(); + _navBar.TitleColor = titleColor.IsDefault() ? ShellRenderer.DefaultTitleColor.ToPlatformEFL() : titleColor.ToPlatformEFL(); + _navBar.BackgroundColor = backgroundColor.IsDefault() ? ShellRenderer.DefaultBackgroundColor.ToPlatformEFL() : backgroundColor.ToPlatformEFL(); + _navBar.ForegroundColor = foregroundColor.IsDefault() ? ShellRenderer.DefaultForegroundColor.ToPlatformEFL() : foregroundColor.ToPlatformEFL(); } @@ -221,7 +223,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen var renderer = Platform.GetOrCreateRenderer(request.Page); _viewStack.Push(renderer.NativeView); request.Task = Task.FromResult(true); - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { (renderer.NativeView as Widget)?.SetFocus(true); }); diff --git a/src/Compatibility/Core/src/Tizen/Shell/ShellTabs.cs b/src/Compatibility/Core/src/Tizen/Shell/ShellTabs.cs index a1230ca5e8..7626804c9b 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/ShellTabs.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/ShellTabs.cs @@ -1,8 +1,9 @@ using ElmSharp; +using EToolbar = ElmSharp.Toolbar; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { - public class ShellTabs : Toolbar, IShellTabs + public class ShellTabs : EToolbar, IShellTabs { ShellTabsType _type; diff --git a/src/Compatibility/Core/src/Tizen/Shell/SimpleViewStack.cs b/src/Compatibility/Core/src/Tizen/Shell/SimpleViewStack.cs index c7f2a1c779..1245231cb1 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/SimpleViewStack.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/SimpleViewStack.cs @@ -36,7 +36,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen UpdateTopView(); // if Pop was called by removed page, // Unrealize cause deletation of NativeCallback, it could be a cause of crash - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { tobeRemoved.Unrealize(); }); @@ -65,7 +65,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen InternalStack.Remove(view); UnPack(view); UpdateTopView(); - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { view?.Unrealize(); }); diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateAdaptor.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateAdaptor.cs index e36306c54c..a6f7cc5c14 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateAdaptor.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateAdaptor.cs @@ -1,8 +1,9 @@ using System.Collections; -using Xamarin.Forms.Platform.Tizen.Native; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV { + [System.Obsolete] public class FlyoutItemTemplateAdaptor : ItemTemplateAdaptor { public FlyoutItemTemplateAdaptor(Element itemsView, IEnumerable items, DataTemplate template, bool hasHeader) diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateSelector.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateSelector.cs index 76e2b2a587..ede79b5c20 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateSelector.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/FlyoutItemTemplateSelector.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using Microsoft.Maui.Graphics; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV { @@ -138,25 +139,25 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - if (value is Color c && c == Color.Transparent) + if (value is Color c && c == KnownColor.Transparent) { - return Color.White; + return Color.FromRgb(255, 255, 255); } else { - return Color.Black; + return Color.FromRgb(0, 0, 0); } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { - if (value is Color c && c == Color.White) + if (value is Color c && c.Equals(Color.FromRgb(255, 255, 255))) { - return Color.Transparent; + return KnownColor.Transparent; } else { - return Color.Black; + return Color.FromRgb(0, 0, 0); } } } diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationDrawer.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationDrawer.cs index 1231c11dda..68bc76c832 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationDrawer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationDrawer.cs @@ -6,6 +6,7 @@ using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV { + [Obsolete] public class TVNavigationDrawer : EBox, INavigationDrawer, IAnimatable, IFlyoutBehaviorObserver { EBox _drawerBox; diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationView.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationView.cs index c16335246a..80cdd7bd07 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationView.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/TVNavigationView.cs @@ -10,6 +10,7 @@ using NCollectionView = Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Nat namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class TVNavigationView : Background, INavigationView { static EColor s_defaultBackgroundColor = EColor.Black; @@ -349,7 +350,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen void OnHeaderSizeChanged(object sender, EventArgs e) { - Device.BeginInvokeOnMainThread(OnLayout); + Application.Current.Dispatcher.Dispatch(OnLayout); } void OnLayout() diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellItemRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellItemRenderer.cs index 613f5295f1..2ab47af829 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellItemRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellItemRenderer.cs @@ -2,6 +2,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class TVShellItemRenderer : ShellItemRenderer { public TVShellItemRenderer(ShellItem item) : base(item) diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellRenderer.cs index 0225a2a71e..a94c5343d5 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellRenderer.cs @@ -2,6 +2,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class TVShellRenderer : ShellRenderer { protected override INavigationDrawer CreateNavigationDrawer() diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionRenderer.cs index e1d544d38f..ff1838fa4b 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionRenderer.cs @@ -7,6 +7,7 @@ using EBox = ElmSharp.Box; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class TVShellSectionRenderer : IShellSectionRenderer, IDisposable { EBox _mainLayout = null; diff --git a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionStack.cs b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionStack.cs index 7ba2652b73..784244db91 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionStack.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/TV/TVShellSectionStack.cs @@ -2,6 +2,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.TV { + [System.Obsolete] public class TVShellSectionStack : ShellSectionStack { diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationDrawer.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationDrawer.cs index 7ffb5f322a..8e0ee78412 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationDrawer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationDrawer.cs @@ -12,6 +12,7 @@ using EWidget = ElmSharp.Widget; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [Obsolete] public class NavigationDrawer : ELayout, IAnimatable { static readonly int TouchWidth = ThemeConstants.Shell.Resources.Watch.DefaultDrawerTouchWidth; diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationView.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationView.cs index 4928ec11de..efba6fe375 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationView.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/NavigationView.cs @@ -10,6 +10,7 @@ using ELayout = ElmSharp.Layout; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [Obsolete] public class NavigationView : ELayout { readonly int _defaultIconSize = ThemeConstants.Shell.Resources.Watch.DefaultNavigationViewIconSize; diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellContentRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellContentRenderer.cs index 07b8ae5c43..a6ccb674aa 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellContentRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellContentRenderer.cs @@ -2,6 +2,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellContentRenderer : IShellItemRenderer { public ShellContentRenderer(ShellContent content) diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellItemRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellItemRenderer.cs index 9de2756b3d..11db455ffb 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellItemRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellItemRenderer.cs @@ -4,6 +4,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellItemRenderer : IShellItemRenderer { Box _mainLayout; diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRenderer.cs index f855615a69..b54cba9647 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRenderer.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; using ElmSharp; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellRenderer : VisualElementRenderer { NavigationDrawer _drawer; @@ -185,12 +187,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch void UpdateFlyoutBackgroundColor(bool init) { - if (init && Element.FlyoutBackgroundColor.IsDefault) + if (init && Element.FlyoutBackgroundColor.IsDefault()) return; if (_navigationView != null) { - _navigationView.BackgroundColor = Element.FlyoutBackgroundColor.ToPlatform(); + _navigationView.BackgroundColor = Element.FlyoutBackgroundColor.ToNative(); } } diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRendererFactory.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRendererFactory.cs index 44bd11e5b2..820c90d03c 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRendererFactory.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellRendererFactory.cs @@ -1,5 +1,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [System.Obsolete] public class ShellRendererFactory { static ShellRendererFactory _instance; diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionItemsRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionItemsRenderer.cs index cbccbfecd4..21d3fb523c 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionItemsRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionItemsRenderer.cs @@ -5,9 +5,11 @@ using System.ComponentModel; using ElmSharp; using ElmSharp.Wearable; using ERect = ElmSharp.Rect; +using Index = ElmSharp.Index; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellSectionItemsRenderer : IShellItemRenderer { const int ItemMaxCount = 20; diff --git a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionNavigationRenderer.cs b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionNavigationRenderer.cs index c0e5341fbc..6cd67841ac 100644 --- a/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionNavigationRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/Shell/Watch/ShellSectionNavigationRenderer.cs @@ -1,12 +1,11 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; +using Microsoft.Maui.Controls.Internals; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ShellSectionNavigationRenderer : IShellItemRenderer { SimpleViewStack _viewStack; @@ -48,7 +47,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch _rootPageRenderer = ShellRendererFactory.Default.CreateItemRenderer(ShellSection); _viewStack.Push(_rootPageRenderer.NativeView); - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { (_rootPageRenderer.NativeView as Widget)?.SetFocus(true); }); @@ -72,7 +71,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Watch var renderer = Platform.GetOrCreateRenderer(request.Page); _viewStack.Push(renderer.NativeView); request.Task = Task.FromResult(true); - Device.BeginInvokeOnMainThread(() => + Application.Current.Dispatcher.Dispatch(() => { (renderer.NativeView as Widget)?.SetFocus(true); }); diff --git a/src/Compatibility/Core/src/Tizen/SkiaSharp/BoxViewRenderer.cs b/src/Compatibility/Core/src/Tizen/SkiaSharp/BoxViewRenderer.cs index f9d79b9f4f..afcc8f2167 100644 --- a/src/Compatibility/Core/src/Tizen/SkiaSharp/BoxViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/SkiaSharp/BoxViewRenderer.cs @@ -1,8 +1,10 @@ +using Microsoft.Maui.Controls.Platform; using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; using EColor = ElmSharp.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class BoxViewRenderer : CanvasViewRenderer { public BoxViewRenderer() @@ -23,10 +25,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp protected override void UpdateBackgroundColor(bool initialize) { - if (initialize && Element.BackgroundColor.IsDefault) + if (initialize && Element.BackgroundColor.IsDefault()) return; - if (Element.Color.IsDefault) + if (Element.Color.IsDefault()) { UpdateColor(); } @@ -62,9 +64,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp void UpdateColor() { - if (Element.Color.IsDefault) + if (Element.Color.IsDefault()) { - if (Element.BackgroundColor.IsDefault) + if (Element.BackgroundColor.IsDefault()) { // Set to default color. (Transparent) RealControl.Color = EColor.Transparent; @@ -72,13 +74,13 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp else { // Use BackgroundColor only if color is default and background color is not default. - RealControl.Color = Element.BackgroundColor.MultiplyAlpha(Element.Opacity).ToPlatform(); + RealControl.Color = Element.BackgroundColor.MultiplyAlpha((float)Element.Opacity).ToNative(); } } else { // Color has higer priority than BackgroundColor. - RealControl.Color = Element.Color.MultiplyAlpha(Element.Opacity).ToPlatform(); + RealControl.Color = Element.Color.MultiplyAlpha((float)Element.Opacity).ToNative(); } } } diff --git a/src/Compatibility/Core/src/Tizen/SkiaSharp/CanvasViewRenderer.cs b/src/Compatibility/Core/src/Tizen/SkiaSharp/CanvasViewRenderer.cs index 91e1c2137c..ff079661bd 100644 --- a/src/Compatibility/Core/src/Tizen/SkiaSharp/CanvasViewRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/SkiaSharp/CanvasViewRenderer.cs @@ -3,10 +3,12 @@ using System.Diagnostics; using ElmSharp; using SkiaSharp; using SkiaSharp.Views.Tizen; -using Microsoft.Maui.Controls.Compatibility.Shapes; +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public abstract class CanvasViewRenderer : ViewRenderer, IBackgroundCanvas, IClipperCanvas, ICanvasRenderer where TView : View where TNativeView : EvasObject diff --git a/src/Compatibility/Core/src/Tizen/SkiaSharp/FrameRenderer.cs b/src/Compatibility/Core/src/Tizen/SkiaSharp/FrameRenderer.cs index aa4a03b659..1f13ba5a90 100644 --- a/src/Compatibility/Core/src/Tizen/SkiaSharp/FrameRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/SkiaSharp/FrameRenderer.cs @@ -1,8 +1,10 @@ using SkiaSharp; using SkiaSharp.Views.Tizen; +using Microsoft.Maui.Controls.Platform; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class FrameRenderer : LayoutRenderer { static float s_borderWidth = 1.0f; @@ -32,7 +34,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp protected override void UpdateBackgroundColor(bool initialize) { - if (initialize && Element.BackgroundColor.IsDefault) + if (initialize && Element.BackgroundColor.IsDefault()) return; else BackgroundCanvas.Invalidate(); @@ -50,8 +52,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp var canvas = e.Surface.Canvas; var bound = e.Info.Rect; canvas.Clear(); - var bgColor = Element.BackgroundColor == Color.Default ? s_defaultColor : SKColor.Parse(Element.BackgroundColor.ToHex()); - var borderColor = Element.BorderColor == Color.Default ? s_defaultColor : SKColor.Parse(Element.BorderColor.ToHex()); + var bgColor = Element.BackgroundColor.IsDefault() ? s_defaultColor : SKColor.Parse(Element.BackgroundColor.ToHex()); + var borderColor = Element.BorderColor.IsDefault() ? s_defaultColor : SKColor.Parse(Element.BorderColor.ToHex()); var roundRect = CreateRoundRect(bound); using (var paint = new SKPaint diff --git a/src/Compatibility/Core/src/Tizen/SkiaSharp/ImageRenderer.cs b/src/Compatibility/Core/src/Tizen/SkiaSharp/ImageRenderer.cs index 088f4335c9..b38057ea0f 100644 --- a/src/Compatibility/Core/src/Tizen/SkiaSharp/ImageRenderer.cs +++ b/src/Compatibility/Core/src/Tizen/SkiaSharp/ImageRenderer.cs @@ -1,8 +1,10 @@ +using Microsoft.Maui.Controls.Platform; using ESize = ElmSharp.Size; -using Specific = Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific.Image; +using Specific = Microsoft.Maui.Controls.PlatformConfiguration.TizenSpecific.Image; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { + [System.Obsolete(Compatibility.Hosting.MauiAppBuilderExtensions.UseMapperInstead)] public class ImageRenderer : CanvasViewRenderer { public ImageRenderer() @@ -42,7 +44,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp bool success = await RealControl.LoadFromImageSourceAsync(source); if (!IsDisposed && success) { - ((IVisualElementController)Element).NativeSizeChanged(); + ((IVisualElementController)Element).PlatformSizeChanged(); UpdateAfterLoading(initialize); } } @@ -61,7 +63,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp bool success = RealControl.LoadFromFile(Specific.GetFile(Element)); if (!IsDisposed && success) { - ((IVisualElementController)Element).NativeSizeChanged(); + ((IVisualElementController)Element).PlatformSizeChanged(); UpdateAfterLoading(initialize); } } @@ -101,10 +103,10 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp void UpdateBlendColor(bool initialize) { - if (initialize && Specific.GetBlendColor(Element).IsDefault) + if (initialize && Specific.GetBlendColor(Element) == null) return; - RealControl.Color = Specific.GetBlendColor(Element).ToPlatform(); + RealControl.Color = Specific.GetBlendColor(Element).ToPlatformEFL(); } } } diff --git a/src/Compatibility/Core/src/Tizen/SkiaSharp/SKClipperView.cs b/src/Compatibility/Core/src/Tizen/SkiaSharp/SKClipperView.cs index 40d64d0d93..f664466e45 100644 --- a/src/Compatibility/Core/src/Tizen/SkiaSharp/SKClipperView.cs +++ b/src/Compatibility/Core/src/Tizen/SkiaSharp/SKClipperView.cs @@ -25,7 +25,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen.SkiaSharp { if (target != null && clipper.ClippingRequired) { +#pragma warning disable CS0612 // Type or member is obsolete var nativeView = Platform.GetOrCreateRenderer(target)?.NativeView; +#pragma warning disable CS0612 // Type or member is obsolete var realHandle = elm_object_part_content_get(clipper, "elm.swallow.content"); nativeView?.SetClip(null); // To restore original image diff --git a/src/Compatibility/Core/src/Tizen/StaticRegistrar.cs b/src/Compatibility/Core/src/Tizen/StaticRegistrar.cs index e3874f195d..53480c9687 100644 --- a/src/Compatibility/Core/src/Tizen/StaticRegistrar.cs +++ b/src/Compatibility/Core/src/Tizen/StaticRegistrar.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; using System.Reflection; -using Microsoft.Maui.Controls.Compatibility.Internals; -using Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native; -using Microsoft.Maui.Controls.Compatibility.PlatformConfiguration.TizenSpecific; -using Microsoft.Maui.Controls.Compatibility.Shapes; -using Microsoft.Maui.Controls.Compatibility.Xaml.Internals; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Controls.Xaml.Internals; +using Microsoft.Maui.Devices; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class StaticRegistrar where TRegistrable : class { readonly Dictionary> _handlers = new Dictionary>(); @@ -58,6 +58,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen } } + [Obsolete] public static class StaticRegistrar { public static StaticRegistrar Registered { get; internal set; } @@ -82,9 +83,6 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Registered.Register(typeof(CarouselPage), () => new CarouselPageRenderer()); Registered.Register(typeof(Page), () => new PageRenderer()); Registered.Register(typeof(NavigationPage), () => new NavigationPageRenderer()); -#pragma warning disable CS0618 // Type or member is obsolete - Registered.Register(typeof(MasterDetailPage), () => new MasterDetailPageRenderer()); -#pragma warning restore CS0618 // Type or member is obsolete Registered.Register(typeof(FlyoutPage), () => new FlyoutPageRenderer()); Registered.Register(typeof(TabbedPage), () => new TabbedPageRenderer()); Registered.Register(typeof(Label), () => new LabelRenderer()); @@ -142,11 +140,12 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen Registered.Register(typeof(ViewCell), () => new ViewCellRenderer()); //Font Loaders - Registered.Register(typeof(EmbeddedFont), () => new EmbeddedFontLoader()); + Registered.Register(typeof(EmbeddedFont), () => new CompatibilityEmbeddedFontLoader()); //Dependencies +#pragma warning disable CS0612 // Type or member is obsolete DependencyService.Register(); - DependencyService.Register(); +#pragma warning disable CS0612 // Type or member is obsolete DependencyService.Register(); DependencyService.Register(); diff --git a/src/Compatibility/Core/src/Tizen/SwipeGestureHandler.cs b/src/Compatibility/Core/src/Tizen/SwipeGestureHandler.cs index b9116928bf..e34d3b6f72 100644 --- a/src/Compatibility/Core/src/Tizen/SwipeGestureHandler.cs +++ b/src/Compatibility/Core/src/Tizen/SwipeGestureHandler.cs @@ -2,6 +2,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [System.Obsolete] public class SwipeGestureHandler : GestureHandler { public SwipeGestureHandler(IGestureRecognizer recognizer) : base(recognizer) diff --git a/src/Compatibility/Core/src/Tizen/TapGestureHandler.cs b/src/Compatibility/Core/src/Tizen/TapGestureHandler.cs index 66eaf78c98..5d23d8370c 100644 --- a/src/Compatibility/Core/src/Tizen/TapGestureHandler.cs +++ b/src/Compatibility/Core/src/Tizen/TapGestureHandler.cs @@ -4,6 +4,7 @@ using ElmSharp; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public class TapGestureHandler : GestureHandler { public TapGestureHandler(IGestureRecognizer recognizer) : base(recognizer) diff --git a/src/Compatibility/Core/src/Tizen/ThemeConstants.cs b/src/Compatibility/Core/src/Tizen/ThemeConstants.cs index 4bfe44f30c..95b1cd1591 100644 --- a/src/Compatibility/Core/src/Tizen/ThemeConstants.cs +++ b/src/Compatibility/Core/src/Tizen/ThemeConstants.cs @@ -1,5 +1,7 @@ +using Microsoft.Maui.Devices; using Tizen.Common; using EColor = ElmSharp.Color; +using Color = Microsoft.Maui.Graphics.Color; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { @@ -516,7 +518,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public class Resources { public const int IconSize = 48; - public const string IconPath = "Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Resource.refresh_48dp.png"; + public const string IconPath = "Microsoft.Maui.Controls.Compatibility.Tizen.Resources.refresh_48dp.png"; } public class ColorClass @@ -565,16 +567,16 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public class Resources { // The source of icon resources is https://materialdesignicons.com/ - public const string MenuIcon = "Resource.menu.png"; - public const string BackIcon = "Resource.arrow_left.png"; - public const string DotsIcon = "Resource.dots_horizontal.png"; + public const string MenuIcon = "Resources.menu.png"; + public const string BackIcon = "Resources.arrow_left.png"; + public const string DotsIcon = "Resources.dots_horizontal.png"; public class Watch { public const int DefaultNavigationViewIconSize = 60; public const int DefaultDrawerTouchWidth = 50; public const int DefaultDrawerIconSize = 40; - public const string DefaultDrawerIcon = "Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Resource.wc_visual_cue.png"; + public const string DefaultDrawerIcon = "Microsoft.Maui.Controls.Compatibility.Tizen.Resources.wc_visual_cue.png"; } public class TV @@ -588,8 +590,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public class ColorClass { public static readonly Color DefaultBackgroundColor = Color.FromRgb(33, 150, 243); - public static readonly Color DefaultForegroundColor = Color.White; - public static readonly Color DefaultTitleColor = Color.White; + public static readonly Color DefaultForegroundColor = Color.FromRgb(255, 255, 255); + public static readonly Color DefaultTitleColor = Color.FromRgb(0, 0, 0); public static readonly EColor DefaultNavigationViewBackgroundColor = EColor.White; public static readonly EColor DefaultDrawerDimBackgroundColor = new EColor(0, 0, 0, 82); @@ -618,8 +620,8 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { public class Resources { - public const string PlayImagePath = "Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Resource.img_button_play.png"; - public const string PauseImagePath = "Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Resource.img_button_pause.png"; + public const string PlayImagePath = "Microsoft.Maui.Controls.Compatibility.Tizen.Resources.img_button_play.png"; + public const string PauseImagePath = "Microsoft.Maui.Controls.Compatibility.Tizen.Resources.img_button_pause.png"; } public class ColorClass diff --git a/src/Compatibility/Core/src/Tizen/ThemeManager.cs b/src/Compatibility/Core/src/Tizen/ThemeManager.cs index 51c755a47c..ae51278f36 100644 --- a/src/Compatibility/Core/src/Tizen/ThemeManager.cs +++ b/src/Compatibility/Core/src/Tizen/ThemeManager.cs @@ -1,8 +1,10 @@ using System; +using Microsoft.Maui.Devices; using ElmSharp; using ElmSharp.Wearable; -using Microsoft.Maui.Controls.Compatibility.Platform.TV; +#pragma warning disable CS0612 // Type or member is obsolete using static Microsoft.Maui.Controls.Compatibility.Platform.Tizen.Native.TableView; +#pragma warning disable CS0612 // Type or member is obsolete using EButton = ElmSharp.Button; using EColor = ElmSharp.Color; using EEntry = ElmSharp.Entry; @@ -11,10 +13,13 @@ using ELayout = ElmSharp.Layout; using EProgressBar = ElmSharp.ProgressBar; using ESize = ElmSharp.Size; using ESlider = ElmSharp.Slider; +using EToolbar = ElmSharp.Toolbar; using EToolbarItem = ElmSharp.ToolbarItem; +using Index = ElmSharp.Index; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] public static class ThemeManager { #region Layout @@ -216,9 +221,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public static EButton SetWatchPopupRightStyle(this EButton button) { - if (Device.Idiom != TargetIdiom.Watch) + if (DeviceInfo.Idiom != DeviceIdiom.Watch) { - Log.Error($"ToWatchPopupRightStyleButton is only supported on TargetIdiom.Watch : {0}", Device.Idiom); + Log.Error($"ToWatchPopupRightStyleButton is only supported on DeviceIdiom.Watch : {0}", DeviceInfo.Idiom); return button; } button.Style = ThemeConstants.Button.Styles.Watch.PopupRight; @@ -227,9 +232,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public static EButton SetWatchPopupLeftStyle(this EButton button) { - if (Device.Idiom != TargetIdiom.Watch) + if (DeviceInfo.Idiom != DeviceIdiom.Watch) { - Log.Error($"WatchPopupLeftStyleButton is only supported on TargetIdiom.Watch : {0}", Device.Idiom); + Log.Error($"WatchPopupLeftStyleButton is only supported on DeviceIdiom.Watch : {0}", DeviceInfo.Idiom); return button; } button.Style = ThemeConstants.Button.Styles.Watch.PopupLeft; @@ -238,9 +243,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public static EButton SetWatchTextStyle(this EButton button) { - if (Device.Idiom != TargetIdiom.Watch) + if (DeviceInfo.Idiom != DeviceIdiom.Watch) { - Log.Error($"ToWatchPopupRightStyleButton is only supported on TargetIdiom.Watch : {0}", Device.Idiom); + Log.Error($"ToWatchPopupRightStyleButton is only supported on DeviceIdiom.Watch : {0}", DeviceInfo.Idiom); return button; } button.Style = ThemeConstants.Button.Styles.Watch.Text; @@ -291,9 +296,9 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen #region Popup public static Popup SetWatchCircleStyle(this Popup popup) { - if (Device.Idiom != TargetIdiom.Watch) + if (DeviceInfo.Idiom != DeviceIdiom.Watch) { - Log.Error($"WatchCircleStylePopup is only supported on TargetIdiom.Watch : {0}", Device.Idiom); + Log.Error($"WatchCircleStylePopup is only supported on DeviceIdiom.Watch : {0}", DeviceInfo.Idiom); return popup; } popup.Style = ThemeConstants.Popup.Styles.Watch.Circle; @@ -419,7 +424,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen for (int i = 0; i < ret.Length; i++) { - ret[i] = check.ClassName.ToLower().Replace("elm_", "") + "/" + ret[i]; + ret[i] = check.ClassName.ToLower().Replace("elm_", "", StringComparison.Ordinal) + "/" + ret[i]; } return ret; } @@ -473,17 +478,17 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen #endregion #region Toolbar - public static Toolbar SetNavigationBarStyle(this Toolbar toolbar) + public static EToolbar SetNavigationBarStyle(this EToolbar toolbar) { toolbar.Style = ThemeConstants.Toolbar.Styles.NavigationBar; return toolbar; } - public static Toolbar SetTVTabBarWithTitleStyle(this Toolbar toolbar) + public static EToolbar SetTVTabBarWithTitleStyle(this EToolbar toolbar) { - if (Device.Idiom != TargetIdiom.TV) + if (DeviceInfo.Idiom != DeviceIdiom.TV) { - Log.Error($"TabBarWithTitleStyle is only supported on TargetIdiom.TV : {0}", Device.Idiom); + Log.Error($"TabBarWithTitleStyle is only supported on DeviceIdiom.TV : {0}", DeviceInfo.Idiom); return toolbar; } toolbar.Style = ThemeConstants.Toolbar.Styles.TV.TabbarWithTitle; @@ -636,7 +641,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen public static void SendSignalToItem(this Cell cell, GenListItem item) { // This is only required for TV profile. - if (Device.Idiom != TargetIdiom.TV) + if (DeviceInfo.Idiom != DeviceIdiom.TV) return; if (cell is ImageCell) @@ -960,24 +965,24 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen return s_navigationViewFlyoutItemFontSize = CalculateDoubleScaledSizeInLargeScreen(25); } - public static Color GetTvFlyoutItemDefaultColor(this INavigationView nav) + public static Graphics.Color GetTvFlyoutItemDefaultColor(this INavigationView nav) { - return Color.Transparent; + return new Graphics.Color(0f); } - public static Color GetTvFlyoutItemFocusedColor(this INavigationView nav) + public static Graphics.Color GetTvFlyoutItemFocusedColor(this INavigationView nav) { - return new Color(0.95); + return new Graphics.Color(0.95f); } - public static Color GetTvFlyoutItemTextDefaultColor(this INavigationView nav) + public static Graphics.Color GetTvFlyoutItemTextDefaultColor(this INavigationView nav) { - return Color.White; + return Graphics.Color.FromRgb(255, 255, 255); } - public static Color GetTvFlyoutItemTextFocusedColor(this INavigationView nav) + public static Graphics.Color GetTvFlyoutItemTextFocusedColor(this INavigationView nav) { - return Color.Black; + return Graphics.Color.FromRgb(0, 0, 0); } #endregion diff --git a/src/Compatibility/Core/src/Tizen/TizenIsolatedStorageFile.cs b/src/Compatibility/Core/src/Tizen/TizenIsolatedStorageFile.cs deleted file mode 100644 index 7ecb5d5985..0000000000 --- a/src/Compatibility/Core/src/Tizen/TizenIsolatedStorageFile.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.IO; -using System.Threading.Tasks; -using Microsoft.Maui.Controls.Compatibility.Internals; -using IOPath = System.IO.Path; -using TApplication = Tizen.Applications.Application; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ - internal class TizenIsolatedStorageFile : IIsolatedStorageFile - { - readonly string _rootPath; - - internal TizenIsolatedStorageFile() - { - _rootPath = TApplication.Current.DirectoryInfo.Data; - } - - public void CreateDirectory(string path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - Directory.CreateDirectory(IOPath.Combine(_rootPath, path)); - } - - public Task CreateDirectoryAsync(string path) - { - CreateDirectory(path); - return Task.FromResult(true); - } - - public void MoveFile(string source, string dest) - { - if (source == null) - throw new ArgumentNullException(nameof(source)); - if (dest == null) - throw new ArgumentNullException(nameof(dest)); - - File.Move(IOPath.Combine(_rootPath, source), IOPath.Combine(_rootPath, dest)); - } - - public void DeleteFile(string path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Trim().Length == 0) - throw new ArgumentException("An empty path is not valid."); - - File.Delete(IOPath.Combine(_rootPath, path)); - } - - public bool DirectoryExists(string path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - return Directory.Exists(IOPath.Combine(_rootPath, path)); - } - - public Task GetDirectoryExistsAsync(string path) - { - return Task.FromResult(DirectoryExists(path)); - } - - public bool FileExists(string path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - return File.Exists(IOPath.Combine(_rootPath, path)); - } - - public Task GetFileExistsAsync(string path) - { - return Task.FromResult(FileExists(path)); - } - - public DateTimeOffset GetLastWriteTime(string path) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Trim().Length == 0) - throw new ArgumentException("An empty path is not valid."); - - string fullPath = IOPath.Combine(_rootPath, path); - if (File.Exists(fullPath)) - return File.GetLastWriteTime(fullPath); - - return Directory.GetLastWriteTime(fullPath); - } - - public Task GetLastWriteTimeAsync(string path) - { - return Task.FromResult(GetLastWriteTime(path)); - } - - public Stream OpenFile(string path, FileMode mode) - { - return OpenFile(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite)); - } - - public Stream OpenFile(string path, FileMode mode, FileAccess access) - { - return OpenFile(path, mode, access, FileShare.Read); - } - - public Stream OpenFile(string path, FileMode mode, FileAccess access, FileShare share) - { - if (path == null) - throw new ArgumentNullException(nameof(path)); - if (path.Trim().Length == 0) - throw new ArgumentException("An empty path is not valid."); - - string fullPath = IOPath.Combine(_rootPath, path); - return new FileStream(fullPath, mode, access, share); - } - - public Task OpenFileAsync(string path, FileMode mode, FileAccess access) - { - return Task.FromResult(OpenFile(path, mode, access)); - } - - public Task OpenFileAsync(string path, FileMode mode, FileAccess access, FileShare share) - { - return Task.FromResult(OpenFile(path, mode, access, share)); - } - - } -} diff --git a/src/Compatibility/Core/src/Tizen/TizenPlatformServices.cs b/src/Compatibility/Core/src/Tizen/TizenPlatformServices.cs deleted file mode 100644 index 208c8fa63f..0000000000 --- a/src/Compatibility/Core/src/Tizen/TizenPlatformServices.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Reflection; -using System.Security.Cryptography; -using System.Threading; -using System.Threading.Tasks; -using ElmSharp; -using Microsoft.Maui.Controls.Compatibility.Internals; -using TAppControl = Tizen.Applications.AppControl; - -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ - internal class TizenPlatformServices : IPlatformServices - { - static SynchronizationContext s_context; - - public TizenPlatformServices() - { - s_context = SynchronizationContext.Current; - } - - public class TizenTicker : Ticker - { - readonly Timer _timer; - - public TizenTicker() - { - _timer = new Timer((object o) => HandleElapsed(o), this, Timeout.Infinite, Timeout.Infinite); - } - - protected override void EnableTimer() - { - _timer.Change(16, 16); - } - - protected override void DisableTimer() - { - _timer.Change(-1, -1); - } - - void HandleElapsed(object state) - { - s_context.Post((o) => SendSignals(-1), null); - } - } - #region IPlatformServices implementation - - public void BeginInvokeOnMainThread(Action action) - { - s_context.Post((o) => action(), null); - } - - public Ticker CreateTicker() - { - return new TizenTicker(); - } - - public void StartTimer(TimeSpan interval, Func callback) - { - Timer timer = null; - bool invoking = false; - TimerCallback onTimeout = o => - { - if (!invoking) - { - invoking = true; - BeginInvokeOnMainThread(() => - { - if (!callback()) - { - timer.Dispose(); - } - invoking = false; - } - ); - } - }; - timer = new Timer(onTimeout, null, Timeout.Infinite, Timeout.Infinite); - // set interval separarately to prevent calling onTimeout before `timer' is assigned - timer.Change(interval, interval); - } - - public async Task GetStreamAsync(Uri uri, CancellationToken cancellationToken) - { - using (var client = new HttpClient()) - using (HttpResponseMessage response = await client.GetAsync(uri, cancellationToken)) - return await response.Content.ReadAsStreamAsync(); - } - - public IIsolatedStorageFile GetUserStoreForApplication() - { - return new TizenIsolatedStorageFile(); - } - - public void QuitApplication() - { - Forms.Context.Exit(); - } - - public bool IsInvokeRequired => !EcoreMainloop.IsMainThread; - - #endregion - - public SizeRequest GetNativeSize(VisualElement view, double widthConstraint, double heightConstraint) - { - return Platform.GetNativeSize(view, widthConstraint, heightConstraint); - } - - public AppTheme RequestedTheme => AppTheme.Unspecified; - - static MD5 CreateChecksum() - { - return MD5.Create(); - } - } -} \ No newline at end of file diff --git a/src/Compatibility/Core/src/Tizen/VisualElementChangedEventArgs.cs b/src/Compatibility/Core/src/Tizen/VisualElementChangedEventArgs.cs deleted file mode 100644 index 229309021c..0000000000 --- a/src/Compatibility/Core/src/Tizen/VisualElementChangedEventArgs.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen -{ - /// - /// Represents the arguments passed to every VisualElement change event. - /// - public class VisualElementChangedEventArgs : ElementChangedEventArgs - { - /// - /// Initializes a new instance of the class. - /// - /// Old element. - /// New element. - public VisualElementChangedEventArgs(VisualElement oldElement, VisualElement newElement) : base(oldElement, newElement) - { - } - } -} diff --git a/src/Compatibility/Maps/src/Tizen/Compatibility.Maps.Tizen.csproj b/src/Compatibility/Maps/src/Tizen/Compatibility.Maps.Tizen.csproj index 36da7799b3..86f48042c3 100644 --- a/src/Compatibility/Maps/src/Tizen/Compatibility.Maps.Tizen.csproj +++ b/src/Compatibility/Maps/src/Tizen/Compatibility.Maps.Tizen.csproj @@ -1,17 +1,17 @@ - tizen40 - Tizen - v4.0 + $(_MauiDotNetTfm)-tizen + Microsoft.Maui.Controls.Compatibility.Maps.Tizen + Microsoft.Maui.Controls.Compatibility.Maps.Tizen + false + disable - - - - - - + + + + diff --git a/src/Compatibility/Maps/src/Tizen/FormsMaps.cs b/src/Compatibility/Maps/src/Tizen/FormsMaps.cs index 96e22d17e5..5ab23bb4a9 100644 --- a/src/Compatibility/Maps/src/Tizen/FormsMaps.cs +++ b/src/Compatibility/Maps/src/Tizen/FormsMaps.cs @@ -1,9 +1,9 @@ using System; using System.Diagnostics; using System.Threading.Tasks; -using Tizen.Maps; using Microsoft.Maui.Controls.Compatibility.Maps.Tizen; -using Microsoft.Maui.Controls.Platform.Tizen; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using Tizen.Maps; namespace Microsoft.Maui.Controls { @@ -28,13 +28,14 @@ namespace Microsoft.Maui.Controls return; _mapService = new MapService(provider, authenticationToken); - +#pragma warning disable CS0612 // Type or member is obsolete FormsApplication.RequestingUserConsentFunc = new Func(() => { TaskCompletionSource userConsentWaiter = new TaskCompletionSource(); UserConsentAction(userConsentWaiter); return userConsentWaiter.Task; }); +#pragma warning disable CS0612 // Type or member is obsolete } static async void UserConsentAction(TaskCompletionSource tcs) diff --git a/src/Compatibility/Maps/src/Tizen/GeocoderBackend.cs b/src/Compatibility/Maps/src/Tizen/GeocoderBackend.cs index 3ec3ef394e..ec9f93515c 100644 --- a/src/Compatibility/Maps/src/Tizen/GeocoderBackend.cs +++ b/src/Compatibility/Maps/src/Tizen/GeocoderBackend.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.Maui.Controls.Maps; namespace Microsoft.Maui.Controls.Compatibility.Maps.Tizen { diff --git a/src/Compatibility/Maps/src/Tizen/MapRenderer.cs b/src/Compatibility/Maps/src/Tizen/MapRenderer.cs index bc3f6a7f20..cf85f72afc 100644 --- a/src/Compatibility/Maps/src/Tizen/MapRenderer.cs +++ b/src/Compatibility/Maps/src/Tizen/MapRenderer.cs @@ -4,14 +4,19 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; +using Microsoft.Maui.Controls.Maps; +using Microsoft.Maui.Controls.Platform; using Tizen.Location; using Tizen.Maps; -using Microsoft.Maui.Controls.Platform.Tizen; +using Pin = Microsoft.Maui.Controls.Maps.Pin; using TPin = Tizen.Maps.Pin; namespace Microsoft.Maui.Controls.Compatibility.Maps.Tizen { +#pragma warning disable CS0618 // Type or member is obsolete public class MapRenderer : ViewRenderer +#pragma warning disable CS0618 // Type or member is obsolete { const string MoveMessageName = "MapMoveToRegion"; const int BaseZoomLevel = 2; diff --git a/src/Compatibility/Maps/src/Tizen/Properties/AssemblyInfo.cs b/src/Compatibility/Maps/src/Tizen/Properties/AssemblyInfo.cs index 61fbc3f25a..16531064d6 100644 --- a/src/Compatibility/Maps/src/Tizen/Properties/AssemblyInfo.cs +++ b/src/Compatibility/Maps/src/Tizen/Properties/AssemblyInfo.cs @@ -1,5 +1,6 @@ -using Microsoft.Maui.Controls; -using Microsoft.Maui.Controls.Compatibility.Maps; +using Microsoft.Maui.Controls.Compatibility; using Microsoft.Maui.Controls.Compatibility.Maps.Tizen; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Controls.Maps; [assembly: ExportRenderer(typeof(Map), typeof(MapRenderer))] \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/Main.cs b/src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/Main.cs new file mode 100644 index 0000000000..fc21470992 --- /dev/null +++ b/src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/Main.cs @@ -0,0 +1,17 @@ +using System; +using Microsoft.Maui; +using Microsoft.Maui.Hosting; + +namespace Maui.Controls.Sample.Tizen +{ + class Program : MauiApplication + { + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } + } +} diff --git a/src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/tizen-manifest.xml b/src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/tizen-manifest.xml new file mode 100644 index 0000000000..f46ad9bf73 --- /dev/null +++ b/src/Controls/samples/Controls.Sample.Sandbox/Platforms/Tizen/tizen-manifest.xml @@ -0,0 +1,29 @@ + + + + + xhdpi/appicon.xhigh.png + xhdpi/appicon.xhigh.png + hdpi/appicon.high.png + + + + + + + + + + + + + + + + + + + + http://tizen.org/privilege/internet + + \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/Main.cs b/src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/Main.cs new file mode 100644 index 0000000000..5fc566fbb1 --- /dev/null +++ b/src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/Main.cs @@ -0,0 +1,17 @@ +using System; +using Microsoft.Maui; +using Microsoft.Maui.Hosting; + +namespace Maui.Controls.Sample.SingleProject +{ + class Program : MauiApplication + { + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } + } +} diff --git a/src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/tizen-manifest.xml b/src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/tizen-manifest.xml new file mode 100644 index 0000000000..0cae846153 --- /dev/null +++ b/src/Controls/samples/Controls.Sample.SingleProject/Platforms/Tizen/tizen-manifest.xml @@ -0,0 +1,27 @@ + + + + + + appicon.xhigh.png + + + + + + + + + + + + + + + + + + + http://tizen.org/privilege/internet + + diff --git a/src/Controls/samples/Controls.Sample.Tizen/Controls.Sample.Tizen.csproj b/src/Controls/samples/Controls.Sample.Tizen/Controls.Sample.Tizen.csproj new file mode 100644 index 0000000000..4fd7ad8f82 --- /dev/null +++ b/src/Controls/samples/Controls.Sample.Tizen/Controls.Sample.Tizen.csproj @@ -0,0 +1,17 @@ + + + + Exe + tizen40 + Maui.Controls.Sample.Tizen + Maui.Controls.Sample.Tizen + + + + + + + + + + diff --git a/src/Controls/samples/Controls.Sample.Tizen/Main.cs b/src/Controls/samples/Controls.Sample.Tizen/Main.cs new file mode 100644 index 0000000000..5ac254c7f6 --- /dev/null +++ b/src/Controls/samples/Controls.Sample.Tizen/Main.cs @@ -0,0 +1,21 @@ +using Microsoft.Maui; +using Microsoft.Maui.Hosting; + +namespace Maui.Controls.Sample.Tizen +{ + class Program : MauiApplication + { + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + protected override void OnCreate() + { + base.OnCreate(); + } + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } + } +} diff --git a/src/Controls/samples/Controls.Sample.Tizen/res/dokdo_regular.ttf b/src/Controls/samples/Controls.Sample.Tizen/res/dokdo_regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..051a88fe379a0cc807ceefeb61510cf316002120 GIT binary patch literal 2149420 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 LsVKhyYE$J^czuq>NFZy^SnGh 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%0DB-`6tlY$#f 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%0AC2^a~-hlIdI;;q|Kwc{yDv%HUWX_5GM54EQr=i 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

W2NQ^2MuiNpX=>G?rlF0<`2P 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 z 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℞mEH8?EsTKYLg)Tit|y*}hHfQbS|X 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

    li+nt5$MYT+BQHS~ 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�wP1Q{_LXuDTG*Z>p7)b^ryH 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 literal 0 HcmV?d00001 diff --git a/src/Controls/samples/Controls.Sample.Tizen/shared/res/icon.png b/src/Controls/samples/Controls.Sample.Tizen/shared/res/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8f56909cddfa86f1387074bf43003f36d6e67be1 GIT binary patch literal 2413 zcmV-z36l1SP)p}(2Rxc)0-Wh zPz3vmm7#NyIfb0yJsg?*5GSVI%x06tn*`vD#o;mJ+k3dbY*-$U8jEw|8d7Ty7(7{M z2?5^gTb%6;7qo)(`V?{C^O6B8As$GQZ?i94&}#idAQHmOY47p2nQdDKpoFg)F!}5* z1dkTN_>DAhf8lb3TSsTH?G|z&93`TBmS?vhc=4oil6(iElplhz7?Z70geiDp3pJhq zUo2Q&3H+3rdGN}cjqt{n9bwD5joZLJ^Jz#fa7Ze_3Gs@la;X?w&^oWTII@IL=i2%NcOHd%)xIge|?jz0h*z98}LAfTHV)^}_4nSH_wME~+6KI3|u?B>WKA)ZI3my4tGjqYu;Kt340fR@u zd7fRhPPRI6SnQz5ow86SlsJuyM%zd-phc+7a^N!`o(_LGbR;6+1v&B6DKM5eW%mg* zs?Jn#TCL8$FTe|eMmn>tR~sMN|QlRckj&CbTc9?V!#otMm6llrQ#e z`+~)O_T)$4%-Qn+$#}c76FP3)hVJfeMUdUyZrTs~<2doV)^EOr${7n3b3vC|zTcM% z1iP?7=&~!5IEKi|dLX5s3SN8bod8hRZ`_2XFRq7KPp^PAuWyEKw_6f?m&*ljzq6C} z!~W+k{3pN=+jf0G*OBH`cXJcUk}j{Jjtd|8#I?^{2;W}#Uec-?8h-<+ zg;kJVJQWW7^_Zjrpa1{6SH~HGfl5VAjGFaQVtr#rS@2&tBq%YU&B9tQVArR;`TUY4qKjjlZT| zlbgpy@@USodYO%l1#NEmQG(f5N*Sgwnz*J_P64#W(c}LJT1C+Pvlp$TV{C*X2r-V{ zm_BDYZLc6n>hB#X`QpS$>M5z6S!=R>9T%7UfL8%cYVm_i9{Yoo0$A3tY`Wd<5U7C% z4jev4cU81>!=~*tBzF9kc!neCz|LAEn;S~<&AAJ7jsR|yS9vWVIaljd zU_x4clAHpiQ|sWXQ>|eUw8kCpQ;XyHWvd(L-ht0+-`*A$@w?o9l@dlN1>*FXj86f^ z9LJd1OHv9LOP%oHC;LNQ6!W0`k-2ni)nm`V#Y>lA-g7U}|FIp}Yp8Q!-XUr9SAbB8 zwpg_>(W}7yBq5ZN7(*Zw>d@2E1Dm(+p<}Yjro%^{9;EFUg2v>EBA7>tiQEuvPWg7Fec)l|QhVjM)zHsitL!xgV7nr=OIr zH`{M0kvR+DF`ped9>XaNYr55OP^hA^OU@$uU#NrnMN+HHL9t$yU4@oE}F0tq-?6>#N2T7=0 z>%Vysa<}5u4T^L+DYN7-)}4Mw0U-~@r&<xzUJepI zHi*?{WB3g5J63YXvk@bH9IG=~PX{|vI-gt$=fArcQShC_i_@Q4u6U%>5}G^YqFC%_{WgD6$Q3E;8rKcsY)1@M}f>X9#=^#*iALQmN8o zwHeQ=Gl~wAI(;31@H;s80Qw8HKH#p3V{k0afpg)UA=UXvc!OVL1d$jb6CW7!U`4FX zxGFK-vL|U$ag#QCa;rASdXZ4yb`*TZwxmg=P1pzf;utbk%g-@_pYyK#W&#(!j|YN@ zr&Fm$8ly-3q~QM1W6MzR8Qbt3-zSD2qq++}_6YO{f?ycuP(F4A@8Itre#FbYe47gU f;7KY{KPUJv@z%Xey2sv&00000NkvXXu0mjfaG + + + + + appicon.xhigh.png + + + + + + + + + + + + + + + + + http://tizen.org/privilege/internet + + + + \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryHandler.cs b/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryHandler.cs index 66b818b1eb..6cf29c51de 100644 --- a/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryHandler.cs +++ b/src/Controls/samples/Controls.Sample/Controls/BordelessEntry/BordelessEntryHandler.cs @@ -34,6 +34,10 @@ namespace Maui.Controls.Sample.Controls public static void MapBorder(BordelessEntryHandler handler, BordelessEntry borderlessEntry) { } +#elif TIZEN + public static void MapBorder(BordelessEntryHandler handler, BordelessEntry borderlessEntry) + { + } #else public static void MapBorder(BordelessEntryHandler handler, BordelessEntry borderlessEntry) { diff --git a/src/Controls/samples/Controls.Sample/Controls/FocusEffect/FocusPlatformEffect.cs b/src/Controls/samples/Controls.Sample/Controls/FocusEffect/FocusPlatformEffect.cs index 8883f67e4f..5af77c22fb 100644 --- a/src/Controls/samples/Controls.Sample/Controls/FocusEffect/FocusPlatformEffect.cs +++ b/src/Controls/samples/Controls.Sample/Controls/FocusEffect/FocusPlatformEffect.cs @@ -15,6 +15,8 @@ namespace Maui.Controls.Sample.Controls Android.Graphics.Color backgroundColor; #elif __IOS__ UIKit.UIColor backgroundColor; +#elif TIZEN + ElmSharp.Color backgroundColor; #endif public FocusPlatformEffect() @@ -33,6 +35,8 @@ namespace Maui.Controls.Sample.Controls Control.SetBackgroundColor(backgroundColor); #elif __IOS__ Control.BackgroundColor = backgroundColor = UIKit.UIColor.FromRGB(204, 153, 255); +#elif TIZEN + (Control as ElmSharp.Widget).BackgroundColor = backgroundColor = ElmSharp.Color.FromRgb(204, 153, 255); #endif } catch (Exception ex) @@ -75,6 +79,21 @@ namespace Maui.Controls.Sample.Controls Control.BackgroundColor = backgroundColor; } } +#elif TIZEN + if (args.PropertyName == "IsFocused") + { + if (Control is ElmSharp.Widget widget) + { + if (widget.BackgroundColor == backgroundColor) + { + widget.BackgroundColor = ElmSharp.Color.White; + } + else + { + widget.BackgroundColor = backgroundColor; + } + } + } #endif } catch (Exception ex) diff --git a/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaGraphicsViewHandler.cs b/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaGraphicsViewHandler.cs index ae2feabdfe..1dca399d22 100644 --- a/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaGraphicsViewHandler.cs +++ b/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaGraphicsViewHandler.cs @@ -27,6 +27,8 @@ namespace Maui.Controls.Sample.Controls { #if __ANDROID__ return new SkiaGraphicsView(Context); +#elif TIZEN + return new SkiaGraphicsView(NativeParent); #else return new SkiaGraphicsView(); #endif diff --git a/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaShapeViewHandler.cs b/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaShapeViewHandler.cs index b42c950a56..934bede1c9 100644 --- a/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaShapeViewHandler.cs +++ b/src/Controls/samples/Controls.Sample/Controls/SkiaSharpHandlers/SkiaShapeViewHandler.cs @@ -36,6 +36,8 @@ namespace Maui.Controls.Sample.Controls { #if __ANDROID__ return new SkiaGraphicsView(Context); +#elif TIZEN + return new SkiaGraphicsView(NativeParent); #else return new SkiaGraphicsView(); #endif diff --git a/src/Controls/samples/Controls.Sample/Startup.cs b/src/Controls/samples/Controls.Sample/Startup.cs index 51a0be4071..cff2edeb56 100644 --- a/src/Controls/samples/Controls.Sample/Startup.cs +++ b/src/Controls/samples/Controls.Sample/Startup.cs @@ -39,6 +39,9 @@ namespace Maui.Controls.Sample var appBuilder = MauiApp.CreateBuilder(); appBuilder.UseMauiApp(); +#if TIZEN + appBuilder.UseMauiCompatibility(); +#endif var services = appBuilder.Services; if (UseMauiGraphicsSkia) @@ -72,7 +75,10 @@ namespace Maui.Controls.Sample //#elif WINDOWS // handlers.AddCompatibilityRenderer(typeof(CustomButton), // typeof(Microsoft.Maui.Controls.Compatibility.Platform.UWP.ButtonRenderer)); -//#endif +// #elif TIZEN +// handlers.AddCompatibilityRenderer(typeof(CustomButton), +// typeof(Microsoft.Maui.Controls.Compatibility.Platform.Tizen.ButtonRenderer)); +// #endif //#pragma warning restore CS0618 // Type or member is obsolete // }); @@ -228,6 +234,19 @@ namespace Maui.Controls.Sample .OnClosed((a, b) => LogEvent(nameof(WindowsLifecycle.OnClosed))) .OnLaunched((a, b) => LogEvent(nameof(WindowsLifecycle.OnLaunched))) .OnVisibilityChanged((a, b) => LogEvent(nameof(WindowsLifecycle.OnVisibilityChanged)))); +#elif TIZEN + events.AddTizen(tizen => tizen + .OnAppControlReceived((a, b) => LogEvent(nameof(TizenLifecycle.OnAppControlReceived))) + .OnCreate((a) => LogEvent(nameof(TizenLifecycle.OnCreate))) + .OnDeviceOrientationChanged((a, b) => LogEvent(nameof(TizenLifecycle.OnDeviceOrientationChanged))) + .OnLocaleChanged((a, b) => LogEvent(nameof(TizenLifecycle.OnLocaleChanged))) + .OnLowBattery((a, b) => LogEvent(nameof(TizenLifecycle.OnLowBattery))) + .OnLowMemory((a, b) => LogEvent(nameof(TizenLifecycle.OnLowMemory))) + .OnPause((a) => LogEvent(nameof(TizenLifecycle.OnPause))) + .OnPreCreate((a) => LogEvent(nameof(TizenLifecycle.OnPreCreate))) + .OnRegionFormatChanged((a, b) => LogEvent(nameof(TizenLifecycle.OnRegionFormatChanged))) + .OnResume((a) => LogEvent(nameof(TizenLifecycle.OnResume))) + .OnTerminate((a) => LogEvent(nameof(TizenLifecycle.OnTerminate)))); #endif static bool LogEvent(string eventName, string type = null) diff --git a/src/Compatibility/Core/src/Tizen/FontNamedSizeService.cs b/src/Controls/src/Core/Compatibility/Tizen/FontNamedSizeService.cs similarity index 89% rename from src/Compatibility/Core/src/Tizen/FontNamedSizeService.cs rename to src/Controls/src/Core/Compatibility/Tizen/FontNamedSizeService.cs index b1fa20fe34..b182ce2c06 100644 --- a/src/Compatibility/Core/src/Tizen/FontNamedSizeService.cs +++ b/src/Controls/src/Core/Compatibility/Tizen/FontNamedSizeService.cs @@ -1,10 +1,14 @@ using System; using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Devices; +#pragma warning disable CS0612 // Type or member is obsolete [assembly: Microsoft.Maui.Controls.Dependency(typeof(Microsoft.Maui.Controls.Compatibility.Platform.Tizen.FontNamedSizeService))] +#pragma warning disable CS0612 // Type or member is obsolete namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] class FontNamedSizeService : IFontNamedSizeService { public double GetNamedSize(NamedSize size, Type targetElementType, bool useOldSizes) @@ -44,7 +48,7 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen default: throw new ArgumentOutOfRangeException(nameof(size)); } - return Forms.ConvertToDPFont(pt); + return DPExtensions.ConvertToDPFont(pt); } } } \ No newline at end of file diff --git a/src/Controls/src/Core/Compatibility/Tizen/PlatformInvalidate.cs b/src/Controls/src/Core/Compatibility/Tizen/PlatformInvalidate.cs new file mode 100644 index 0000000000..773a913d2e --- /dev/null +++ b/src/Controls/src/Core/Compatibility/Tizen/PlatformInvalidate.cs @@ -0,0 +1,19 @@ +using Microsoft.Maui.Controls.Internals; + +[assembly: Microsoft.Maui.Controls.Dependency(typeof(Microsoft.Maui.Controls.Compatibility.Platform.Tizen.PlatformInvalidate))] + +namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen +{ + class PlatformInvalidate : IPlatformInvalidate + { + public void Invalidate(VisualElement visualElement) + { + if (visualElement.Handler?.PlatformView == null) + { + return; + } + + visualElement.ToPlatform().MarkChanged(); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Compatibility/Tizen/PlatformSizeService.cs b/src/Controls/src/Core/Compatibility/Tizen/PlatformSizeService.cs new file mode 100644 index 0000000000..62298693fb --- /dev/null +++ b/src/Controls/src/Core/Compatibility/Tizen/PlatformSizeService.cs @@ -0,0 +1,20 @@ +using Microsoft.Maui.Controls.Internals; + +[assembly: Microsoft.Maui.Controls.Dependency(typeof(Microsoft.Maui.Controls.Compatibility.Platform.Tizen.PlatformSizeService))] + +namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen +{ + class PlatformSizeService : IPlatformSizeService + { + public SizeRequest GetPlatformSize(VisualElement view, double widthConstraint, double heightConstraint) + { + if (widthConstraint > 0 && heightConstraint > 0) + { + return view.Handler?.GetDesiredSize(widthConstraint, heightConstraint) ?? + new SizeRequest(); + } + + return new SizeRequest(); + } + } +} \ No newline at end of file diff --git a/src/Compatibility/Core/src/Tizen/ResourcesProvider.cs b/src/Controls/src/Core/Compatibility/Tizen/ResourcesProvider.cs similarity index 91% rename from src/Compatibility/Core/src/Tizen/ResourcesProvider.cs rename to src/Controls/src/Core/Compatibility/Tizen/ResourcesProvider.cs index 31bf6af6ec..1a48a80ff0 100644 --- a/src/Compatibility/Core/src/Tizen/ResourcesProvider.cs +++ b/src/Controls/src/Core/Compatibility/Tizen/ResourcesProvider.cs @@ -1,7 +1,10 @@ -using Microsoft.Maui.Controls.Compatibility.Internals; +using System; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Graphics; namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen { + [Obsolete] internal class ResourcesProvider : ISystemResourcesProvider { ResourceDictionary _dictionary; @@ -56,14 +59,14 @@ namespace Microsoft.Maui.Controls.Compatibility.Platform.Tizen return style; } - Style GetStyle(int? fontSize = null, Color? textColor = null) + Style GetStyle(int? fontSize = null, Color textColor = null) { Style style = new Style(typeof(Label)); if (fontSize.HasValue) { style.Setters.Add(new Setter { Property = Label.FontSizeProperty, Value = fontSize }); } - if (textColor.HasValue) + if (textColor != null) { style.Setters.Add(new Setter { Property = Label.TextColorProperty, Value = textColor }); } diff --git a/src/Controls/src/Core/HandlerImpl/Button/Button.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Button/Button.Tizen.cs new file mode 100644 index 0000000000..b5eab66e32 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Button/Button.Tizen.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Maui.Controls.Platform; + +namespace Microsoft.Maui.Controls +{ + public partial class Button + { + public static void MapText(ButtonHandler handler, Button button) + { + handler.PlatformView?.UpdateText(button); + } + + [MissingMapper] + public static void MapLineBreakMode(IButtonHandler handler, Button button) {} + } +} diff --git a/src/Controls/src/Core/HandlerImpl/Editor/Editor.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Editor/Editor.Tizen.cs new file mode 100644 index 0000000000..c7c657b378 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Editor/Editor.Tizen.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Maui.Controls +{ + public partial class Editor + { + public static void MapText(EditorHandler handler, Editor editor) + { + Platform.TextExtensions.UpdateText(handler.PlatformView, editor); + } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/Element/Element.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Element/Element.Tizen.cs new file mode 100644 index 0000000000..1155fee413 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Element/Element.Tizen.cs @@ -0,0 +1,19 @@ +#nullable enable + +using Microsoft.Maui.Controls.Platform; + +namespace Microsoft.Maui.Controls +{ + public partial class Element + { + public static void MapAutomationPropertiesIsInAccessibleTree(IElementHandler handler, Element element) + { + //TODO : Need to impl + } + + public static void MapAutomationPropertiesExcludedWithChildren(IElementHandler handler, Element element) + { + //TODO : Need to impl + } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/Entry/Entry.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Entry/Entry.Tizen.cs new file mode 100644 index 0000000000..7b1ed44178 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Entry/Entry.Tizen.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Maui.Controls +{ + public partial class Entry + { + public static void MapText(EntryHandler handler, Entry entry) + { + Platform.TextExtensions.UpdateText(handler.PlatformView, entry); + } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/Label/Label.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Label/Label.Tizen.cs new file mode 100644 index 0000000000..37c0f6347a --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Label/Label.Tizen.cs @@ -0,0 +1,57 @@ +using Microsoft.Maui; +using Microsoft.Maui.Handlers; +using Microsoft.Maui.Controls.Platform; + +namespace Microsoft.Maui.Controls +{ + public partial class Label + { + public static void MapTextType(LabelHandler handler, Label label) + { + handler.PlatformView?.UpdateText(label); + } + + public static void MapText(LabelHandler handler, Label label) + { + handler.PlatformView?.UpdateText(label); + } + + public static void MapTextDecorations(LabelHandler handler, Label label) + { + if (label?.TextType == TextType.Html) + { + return; + } + + LabelHandler.MapTextDecorations(handler, label); + } + + public static void MapFont(LabelHandler handler, Label label) + { + if (label?.TextType == TextType.Html) + { + return; + } + + LabelHandler.MapFont(handler, label); + } + + public static void MapTextColor(LabelHandler handler, Label label) + { + if (label?.TextType == TextType.Html) + { + return; + } + + LabelHandler.MapTextColor(handler, label); + } + + public static void MapLineBreakMode(ILabelHandler handler, Label label) + { + handler.PlatformView?.UpdateLineBreakMode(label); + } + + [MissingMapper] + public static void MapMaxLines(ILabelHandler handler, Label label) { } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/Layout/Layout.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Layout/Layout.Tizen.cs new file mode 100644 index 0000000000..18df92e580 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Layout/Layout.Tizen.cs @@ -0,0 +1,11 @@ +namespace Microsoft.Maui.Controls +{ + public partial class Layout + { + public static void MapInputTransparent(LayoutHandler handler, Layout layout) + { + handler.PlatformView?.UpdateInputTransparent(handler, layout); + layout.UpdateDescendantInputTransparent(); + } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/NavigationPage/NavigationPage.Impl.cs b/src/Controls/src/Core/HandlerImpl/NavigationPage/NavigationPage.Impl.cs index aa369445a8..d5cfb498b6 100644 --- a/src/Controls/src/Core/HandlerImpl/NavigationPage/NavigationPage.Impl.cs +++ b/src/Controls/src/Core/HandlerImpl/NavigationPage/NavigationPage.Impl.cs @@ -285,7 +285,7 @@ namespace Microsoft.Maui.Controls p.Toolbar = null; } - if (InternalChildren.Count > 0) + if (Navigation is MauiNavigationImpl && InternalChildren.Count > 0) { var navStack = Navigation.NavigationStack; var visiblePage = Navigation.NavigationStack[NavigationStack.Count - 1]; diff --git a/src/Controls/src/Core/HandlerImpl/SearchBar/SearchBar.Tizen.cs b/src/Controls/src/Core/HandlerImpl/SearchBar/SearchBar.Tizen.cs new file mode 100644 index 0000000000..ce19b366a5 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/SearchBar/SearchBar.Tizen.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Maui.Controls +{ + public partial class SearchBar + { + public static void MapText(SearchBarHandler handler, SearchBar searchBar) + { + Platform.TextExtensions.UpdateText(handler.PlatformView, searchBar); + } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/Shape/Shape.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Shape/Shape.Tizen.cs new file mode 100644 index 0000000000..770c08010c --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Shape/Shape.Tizen.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Handlers; + +namespace Microsoft.Maui.Controls.Shapes +{ + public partial class Shape + { + public static void MapStrokeDashArray(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/TabbedPage/TabbedPage.Tizen.cs b/src/Controls/src/Core/HandlerImpl/TabbedPage/TabbedPage.Tizen.cs new file mode 100644 index 0000000000..2f8b57ca02 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/TabbedPage/TabbedPage.Tizen.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Maui.Handlers; + +namespace Microsoft.Maui.Controls +{ + public partial class TabbedPage + { + internal static void MapBarBackground(ITabbedViewHandler handler, TabbedPage view) + { + } + internal static void MapBarBackgroundColor(ITabbedViewHandler handler, TabbedPage view) + { + } + internal static void MapBarTextColor(ITabbedViewHandler handler, TabbedPage view) + { + } + internal static void MapUnselectedTabColor(ITabbedViewHandler handler, TabbedPage view) + { + } + internal static void MapSelectedTabColor(ITabbedViewHandler handler, TabbedPage view) + { + } + + internal static void MapItemsSource(ITabbedViewHandler handler, TabbedPage view) + { + } + internal static void MapItemTemplate(ITabbedViewHandler handler, TabbedPage view) + { + } + internal static void MapSelectedItem(ITabbedViewHandler handler, TabbedPage view) + { + } + internal static void MapCurrentPage(ITabbedViewHandler handler, TabbedPage view) + { + + } + } +} diff --git a/src/Controls/src/Core/HandlerImpl/VisualElement/VisualElement.Platform.cs b/src/Controls/src/Core/HandlerImpl/VisualElement/VisualElement.Platform.cs index 540247b82e..88058852a1 100644 --- a/src/Controls/src/Core/HandlerImpl/VisualElement/VisualElement.Platform.cs +++ b/src/Controls/src/Core/HandlerImpl/VisualElement/VisualElement.Platform.cs @@ -8,6 +8,8 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; #endif namespace Microsoft.Maui.Controls diff --git a/src/Controls/src/Core/HandlerImpl/Window/Window.Tizen.cs b/src/Controls/src/Core/HandlerImpl/Window/Window.Tizen.cs new file mode 100644 index 0000000000..8c27288b79 --- /dev/null +++ b/src/Controls/src/Core/HandlerImpl/Window/Window.Tizen.cs @@ -0,0 +1,12 @@ +#nullable enable +using System; +using EWindow = ElmSharp.Window; + +namespace Microsoft.Maui.Controls +{ + public partial class Window + { + internal EWindow NativeWindow => + (Handler?.PlatformView as EWindow) ?? throw new InvalidOperationException("Window should have a ElmSharp.Window set."); + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Tizen.cs new file mode 100644 index 0000000000..73542dc5b8 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/CarouselViewHandler.Tizen.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Maui.Handlers; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public partial class CarouselViewHandler : ItemsViewHandler + { + //TODO : Need to impl + public static void MapCurrentItem(CarouselViewHandler handler, CarouselView carouselView) { } + public static void MapPosition(CarouselViewHandler handler, CarouselView carouselView) { } + public static void MapIsBounceEnabled(CarouselViewHandler handler, CarouselView carouselView) { } + public static void MapIsSwipeEnabled(CarouselViewHandler handler, CarouselView carouselView) { } + public static void MapPeekAreaInsets(CarouselViewHandler handler, CarouselView carouselView) { } + public static void MapLoop(CarouselViewHandler handler, CarouselView carouselView) { } + } +} diff --git a/src/Controls/src/Core/Handlers/Items/CollectionViewHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Items/CollectionViewHandler.Tizen.cs new file mode 100644 index 0000000000..1dd9e7e8c8 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/CollectionViewHandler.Tizen.cs @@ -0,0 +1,6 @@ +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public partial class CollectionViewHandler : ReorderableItemsViewHandler + { + } +} diff --git a/src/Controls/src/Core/Handlers/Items/GroupableItemsViewHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Items/GroupableItemsViewHandler.Tizen.cs new file mode 100644 index 0000000000..ccbc69c5dd --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/GroupableItemsViewHandler.Tizen.cs @@ -0,0 +1,9 @@ +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public partial class GroupableItemsViewHandler : SelectableItemsViewHandler where TItemsView : GroupableItemsView + { + public static void MapIsGrouped(GroupableItemsViewHandler handler, GroupableItemsView itemsView) + { + } + } +} diff --git a/src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Tizen.cs new file mode 100644 index 0000000000..6809198715 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/ItemsViewHandler.Tizen.cs @@ -0,0 +1,60 @@ +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Handlers; +using TCollectionView = Tizen.UIExtensions.ElmSharp.CollectionView; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public abstract partial class ItemsViewHandler : ViewHandler where TItemsView : ItemsView + { + protected ItemsViewHandler(PropertyMapper mapper, CommandMapper commandMapper = null) : base(mapper, commandMapper) + { + } + + protected override TCollectionView CreatePlatformView() + { + return new TCollectionView(NativeParent); + } + + public static void MapItemsSource(ItemsViewHandler handler, ItemsView itemsView) + { + handler.PlatformView.UpdateItemsSource(itemsView); + } + + public static void MapHorizontalScrollBarVisibility(ItemsViewHandler handler, ItemsView itemsView) + { + handler.PlatformView.HorizontalScrollBarVisiblePolicy = itemsView.HorizontalScrollBarVisibility.ToPlatform(); + } + + public static void MapVerticalScrollBarVisibility(ItemsViewHandler handler, ItemsView itemsView) + { + handler.PlatformView.VerticalScrollBarVisiblePolicy = itemsView.VerticalScrollBarVisibility.ToPlatform(); + } + + public static void MapItemTemplate(ItemsViewHandler handler, ItemsView itemsView) + { + handler.PlatformView.UpdateAdaptor(itemsView); + } + + public static void MapEmptyView(ItemsViewHandler handler, ItemsView itemsView) + { + handler.PlatformView.UpdateAdaptor(itemsView); + } + + public static void MapEmptyViewTemplate(ItemsViewHandler handler, ItemsView itemsView) + { + handler.PlatformView.UpdateAdaptor(itemsView); + } + + public static void MapFlowDirection(ItemsViewHandler handler, ItemsView itemsView) + { + } + public static void MapIsVisible(ItemsViewHandler handler, ItemsView itemsView) + { + handler.PlatformView.UpdateVisibility(itemsView); + } + public static void MapItemsUpdatingScrollMode(ItemsViewHandler handler, ItemsView itemsView) + { + } + } +} diff --git a/src/Controls/src/Core/Handlers/Items/ReorderableItemsViewHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Items/ReorderableItemsViewHandler.Tizen.cs new file mode 100644 index 0000000000..a1ae82bece --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/ReorderableItemsViewHandler.Tizen.cs @@ -0,0 +1,12 @@ +using System; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public partial class ReorderableItemsViewHandler : GroupableItemsViewHandler where TItemsView : ReorderableItemsView + { + public static void MapCanReorderItems(ReorderableItemsViewHandler handler, ReorderableItemsView itemsView) + { + //TODO : Need to impl + } + } +} diff --git a/src/Controls/src/Core/Handlers/Items/SelectableItemsViewHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Items/SelectableItemsViewHandler.Tizen.cs new file mode 100644 index 0000000000..acd21c8465 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/SelectableItemsViewHandler.Tizen.cs @@ -0,0 +1,25 @@ +using Microsoft.Maui.Controls.Platform; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public partial class SelectableItemsViewHandler : StructuredItemsViewHandler where TItemsView : SelectableItemsView + { + public static void MapSelectedItem(SelectableItemsViewHandler handler, SelectableItemsView itemsView) + { + if (itemsView.SelectionMode != SelectionMode.None && itemsView.SelectedItem != null) + { + var index = handler.PlatformView.Adaptor.GetItemIndex(itemsView.SelectedItem); + handler.PlatformView.SelectedItemIndex = index; + } + } + + public static void MapSelectedItems(SelectableItemsViewHandler handler, SelectableItemsView itemsView) + { + } + + public static void MapSelectionMode(SelectableItemsViewHandler handler, SelectableItemsView itemsView) + { + handler.PlatformView.SelectionMode = itemsView.SelectionMode.ToPlatform(); + } + } +} diff --git a/src/Controls/src/Core/Handlers/Items/StructuredItemsViewHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Items/StructuredItemsViewHandler.Tizen.cs new file mode 100644 index 0000000000..3e124d71e6 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/StructuredItemsViewHandler.Tizen.cs @@ -0,0 +1,27 @@ +using Microsoft.Maui.Controls.Platform; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public partial class StructuredItemsViewHandler : ItemsViewHandler where TItemsView : StructuredItemsView + { + public static void MapHeaderTemplate(StructuredItemsViewHandler handler, StructuredItemsView itemsView) + { + handler.PlatformView.UpdateAdaptor(itemsView); + } + + public static void MapFooterTemplate(StructuredItemsViewHandler handler, StructuredItemsView itemsView) + { + handler.PlatformView.UpdateAdaptor(itemsView); + } + + public static void MapItemsLayout(StructuredItemsViewHandler handler, StructuredItemsView itemsView) + { + handler.PlatformView.UpdateItemsLayout(itemsView); + } + + public static void MapItemSizingStrategy(StructuredItemsViewHandler handler, StructuredItemsView itemsView) + { + handler.PlatformView.UpdateItemsLayout(itemsView); + } + } +} diff --git a/src/Controls/src/Core/Handlers/Items/Tizen/EmptyItemAdaptor.cs b/src/Controls/src/Core/Handlers/Items/Tizen/EmptyItemAdaptor.cs new file mode 100644 index 0000000000..ca3a4c9a67 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/Tizen/EmptyItemAdaptor.cs @@ -0,0 +1,105 @@ +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public class EmptyItemAdaptor : ItemTemplateAdaptor, IEmptyAdaptor + { + static DataTemplate s_defaultEmptyTemplate = new DataTemplate(typeof(EmptyView)); + + IMauiContext _context; + + public EmptyItemAdaptor(ItemsView itemsView) : this(itemsView, itemsView.ItemsSource, itemsView.ItemTemplate) { } + + public EmptyItemAdaptor(ItemsView itemsView, IEnumerable items, DataTemplate template) : base(itemsView, items, template) + { + _context = itemsView.Handler!.MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + } + + public static EmptyItemAdaptor Create(ItemsView itemsView) + { + DataTemplate? template = null; + if (itemsView.EmptyView is View emptyView) + { + template = new DataTemplate(() => + { + return emptyView; + }); + } + else + { + template = itemsView.EmptyViewTemplate ?? s_defaultEmptyTemplate; + } + var empty = new List + { + itemsView.EmptyView ?? new object() + }; + return new EmptyItemAdaptor(itemsView, empty, template); + } + + public override Size MeasureItem(int widthConstraint, int heightConstraint) + { + return new Size(widthConstraint, heightConstraint); + } + + public override EvasObject CreateNativeView(int index, EvasObject parent) + { + View? emptyView = null; + if (ItemTemplate is DataTemplateSelector selector) + { + emptyView = selector.SelectTemplate(this[index], Element).CreateContent() as View; + } + else + { + emptyView = ItemTemplate.CreateContent() as View; + } + + var header = CreateHeaderView(); + var footer = CreateFooterView(); + var layout = new StackLayout(); + + if (header != null) + { + layout.Children.Add(header); + } + layout.Children.Add(emptyView); + if (footer != null) + { + layout.Children.Add(footer); + } + + layout.Parent = Element; + + return layout.ToPlatform(_context); + } + + public override void RemoveNativeView(EvasObject native) + { + native.Unrealize(); + } + + class EmptyView : StackLayout + { + public EmptyView() + { + HorizontalOptions = LayoutOptions.Fill; + VerticalOptions = LayoutOptions.Fill; + Children.Add( + new Label + { + Text = "No items found", + VerticalOptions = LayoutOptions.Center, + HorizontalOptions = LayoutOptions.Center, + HorizontalTextAlignment = TextAlignment.Center, + VerticalTextAlignment = TextAlignment.Center, + } + ); + } + } + } +} diff --git a/src/Controls/src/Core/Handlers/Items/Tizen/ItemDefaultTemplateAdaptor.cs b/src/Controls/src/Core/Handlers/Items/Tizen/ItemDefaultTemplateAdaptor.cs new file mode 100644 index 0000000000..cc572273b3 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/Tizen/ItemDefaultTemplateAdaptor.cs @@ -0,0 +1,42 @@ +#nullable enable + +using System; +using System.Globalization; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public class ItemDefaultTemplateAdaptor : ItemTemplateAdaptor + { + class ToTextConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value?.ToString() ?? string.Empty; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); + } + + public ItemDefaultTemplateAdaptor(ItemsView itemsView) : base(itemsView) + { + ItemTemplate = new DataTemplate(() => + { + var label = new Label + { + TextColor = Graphics.Colors.Black, + }; + label.SetBinding(Label.TextProperty, new Binding(".", converter: new ToTextConverter())); + + return new StackLayout + { + BackgroundColor = Graphics.Colors.White, + Padding = 30, + Children = + { + label + } + }; + }); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Items/Tizen/ItemTemplateAdaptor.cs b/src/Controls/src/Core/Handlers/Items/Tizen/ItemTemplateAdaptor.cs new file mode 100644 index 0000000000..5265f15a53 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Items/Tizen/ItemTemplateAdaptor.cs @@ -0,0 +1,307 @@ +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; +using DPExtensions = Microsoft.Maui.Platform.DPExtensions; + +namespace Microsoft.Maui.Controls.Handlers.Items +{ + public class ItemTemplateAdaptor : ItemAdaptor + { + Dictionary _nativeTable = new Dictionary(); + Dictionary _dataBindedViewTable = new Dictionary(); + protected View? _headerCache; + protected View? _footerCache; + IMauiContext _context; + + public ItemTemplateAdaptor(ItemsView itemsView) : this(itemsView, itemsView.ItemsSource, itemsView.ItemTemplate) { } + + protected ItemTemplateAdaptor(ItemsView itemsView, IEnumerable items, DataTemplate template) : base(items) + { + ItemTemplate = template; + Element = itemsView; + IsSelectable = itemsView is SelectableItemsView; + _context = itemsView.Handler!.MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + } + + protected DataTemplate ItemTemplate { get; set; } + + protected Element Element { get; set; } + + protected virtual bool IsSelectable { get; } + + + public View GetTemplatedView(EvasObject evasObject) + { + return _nativeTable[evasObject]; + } + + public View? GetTemplatedView(int index) + { + var item = this[index]; + if (item != null && Count > index && _dataBindedViewTable.TryGetValue(item, out View? view)) + { + return view; + } + return null; + } + + public override object GetViewCategory(int index) + { + if (ItemTemplate is DataTemplateSelector selector) + { + return selector.SelectTemplate(this[index], Element); + } + return base.GetViewCategory(index); + } + + public override EvasObject? CreateNativeView(EvasObject parent) + { + return CreateNativeView(0, parent); + } + + public override EvasObject? CreateNativeView(int index, EvasObject parent) + { + View? view = null; + if (ItemTemplate is DataTemplateSelector selector) + { + view = selector.SelectTemplate(this[index], Element).CreateContent() as View; + } + else + { + view = ItemTemplate.CreateContent() as View; + } + + if (view != null) + { + var native = view.ToPlatform(_context); + view.Parent = Element; + _nativeTable[native] = view; + return native; + } + return null; + } + + public override EvasObject? GetFooterView(EvasObject parent) + { + _footerCache = CreateFooterView(); + if (_footerCache != null) + { + _footerCache.Parent = Element; + return _footerCache.ToPlatform(_context); + } + return null; + } + + public override EvasObject? GetHeaderView(EvasObject parent) + { + _headerCache = CreateHeaderView(); + if (_headerCache != null) + { + _headerCache.Parent = Element; + return _headerCache.ToPlatform(_context); + } + return null; + } + + public override Size MeasureFooter(int widthConstraint, int heightConstraint) + { + return _footerCache?.Measure(DPExtensions.ConvertToScaledDP(widthConstraint), DPExtensions.ConvertToScaledDP(heightConstraint)).Request.ToEFLPixel() ?? new Size(0, 0); + } + + public override Size MeasureHeader(int widthConstraint, int heightConstraint) + { + return _headerCache?.Measure(DPExtensions.ConvertToScaledDP(widthConstraint), DPExtensions.ConvertToScaledDP(heightConstraint)).Request.ToEFLPixel() ?? new Size(0, 0); + } + + public override Size MeasureItem(int widthConstraint, int heightConstraint) + { + return MeasureItem(0, widthConstraint, heightConstraint); + } + + public override Size MeasureItem(int index, int widthConstraint, int heightConstraint) + { + if (widthConstraint > heightConstraint) + { + widthConstraint = int.MaxValue; + } + if (heightConstraint > widthConstraint) + { + heightConstraint = int.MaxValue; + } + + var item = this[index]; + if (item != null && _dataBindedViewTable.TryGetValue(item, out View? createdView) && createdView != null) + { + return createdView.Measure(DPExtensions.ConvertToScaledDP(widthConstraint), DPExtensions.ConvertToScaledDP(heightConstraint), MeasureFlags.IncludeMargins).Request.ToEFLPixel(); + } + + View? view = null; + if (ItemTemplate is DataTemplateSelector selector) + { + view = selector.SelectTemplate(this[index], Element).CreateContent() as View; + } + else + { + view = ItemTemplate.CreateContent() as View; + } + + if (view != null) + { + view.Parent = Element; + if (Count > index) + view.BindingContext = this[index]; + var request = view.Measure(DPExtensions.ConvertToScaledDP(widthConstraint), DPExtensions.ConvertToScaledDP(heightConstraint), MeasureFlags.IncludeMargins).Request; + return request.ToEFLPixel(); + } + return new Size(0, 0); + } + + public override void RemoveNativeView(EvasObject native) + { + UnBinding(native); + if (_nativeTable.TryGetValue(native, out View? view)) + { + native.Unrealize(); + _nativeTable.Remove(native); + } + } + + public override void SetBinding(EvasObject native, int index) + { + if (_nativeTable.TryGetValue(native, out View? view)) + { + ResetBindedView(view); + var item = this[index]; + if (item != null) + { + view.BindingContext = item; + _dataBindedViewTable[item] = view; + } + view.MeasureInvalidated += OnItemMeasureInvalidated; + AddLogicalChild(view); + } + } + + public override void UnBinding(EvasObject native) + { + if (_nativeTable.TryGetValue(native, out View? view)) + { + view.MeasureInvalidated -= OnItemMeasureInvalidated; + ResetBindedView(view); + } + } + + public void SendItemSelected(object selectedItem) + { + if (Element is SelectableItemsView selectable) + { + selectable.SelectedItem = selectedItem; + } + } + + protected virtual View? CreateHeaderView() + { + if (Element is StructuredItemsView structuredItemsView) + { + if (structuredItemsView.Header != null) + { + View? header = null; + if (structuredItemsView.Header is View view) + { + header = view; + } + else if (structuredItemsView.HeaderTemplate != null) + { + header = structuredItemsView.HeaderTemplate.CreateContent() as View; + if (header != null) + header.BindingContext = structuredItemsView.Header; + } + else if (structuredItemsView.Header is String str) + { + header = new Label { Text = str, }; + } + return header; + } + } + return null; + } + + protected virtual View? CreateFooterView() + { + if (Element is StructuredItemsView structuredItemsView) + { + if (structuredItemsView.Footer != null) + { + View? footer = null; + if (structuredItemsView.Footer is View view) + { + footer = view; + } + else if (structuredItemsView.FooterTemplate != null) + { + footer = structuredItemsView.FooterTemplate.CreateContent() as View; + if (footer != null) + footer.BindingContext = structuredItemsView.Footer; + } + else if (structuredItemsView.Footer is String str) + { + footer = new Label { Text = str, }; + } + return footer; + } + } + return null; + } + + void ResetBindedView(View view) + { + if (view.BindingContext != null && _dataBindedViewTable.ContainsKey(view.BindingContext)) + { + _dataBindedViewTable[view.BindingContext] = null; + RemoveLogicalChild(view); + view.BindingContext = null; + } + } + + void OnItemMeasureInvalidated(object? sender, EventArgs e) + { + var data = (sender as View)?.BindingContext ?? null; + if (data != null) + { + int index = GetItemIndex(data); + if (index != -1) + { + CollectionView?.ItemMeasureInvalidated(index); + } + } + } + + void AddLogicalChild(Element element) + { + if (Element is ItemsView iv) + { + iv.AddLogicalChild(element); + } + else + { + element.Parent = Element; + } + } + + void RemoveLogicalChild(Element element) + { + if (Element is ItemsView iv) + { + iv.RemoveLogicalChild(element); + } + else + { + element.Parent = null; + } + } + } +} diff --git a/src/Controls/src/Core/Handlers/Shapes/Line/LineHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Shapes/Line/LineHandler.Tizen.cs new file mode 100644 index 0000000000..1494179e4b --- /dev/null +++ b/src/Controls/src/Core/Handlers/Shapes/Line/LineHandler.Tizen.cs @@ -0,0 +1,27 @@ +using Microsoft.Maui.Controls.Shapes; + +namespace Microsoft.Maui.Controls.Handlers +{ + public partial class LineHandler + { + public static void MapX1(IShapeViewHandler handler, Line line) + { + handler.PlatformView?.InvalidateShape(line); + } + + public static void MapY1(IShapeViewHandler handler, Line line) + { + handler.PlatformView?.InvalidateShape(line); + } + + public static void MapX2(IShapeViewHandler handler, Line line) + { + handler.PlatformView?.InvalidateShape(line); + } + + public static void MapY2(IShapeViewHandler handler, Line line) + { + handler.PlatformView?.InvalidateShape(line); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Shapes/Path/PathHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Shapes/Path/PathHandler.Tizen.cs new file mode 100644 index 0000000000..f4ef45d6d5 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Shapes/Path/PathHandler.Tizen.cs @@ -0,0 +1,17 @@ +using Microsoft.Maui.Controls.Shapes; + +namespace Microsoft.Maui.Controls.Handlers +{ + public partial class PathHandler + { + public static void MapData(IShapeViewHandler handler, Path path) + { + handler.PlatformView?.InvalidateShape(path); + } + + public static void MapRenderTransform(IShapeViewHandler handler, Path path) + { + handler.PlatformView?.InvalidateShape(path); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.Tizen.cs new file mode 100644 index 0000000000..51635c23a1 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Shapes/Polygon/PolygonHandler.Tizen.cs @@ -0,0 +1,52 @@ +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Controls.Handlers +{ + public partial class PolygonHandler + { + protected override void ConnectHandler(MauiShapeView nativeView) + { + if (VirtualView is Polygon polygon) + polygon.Points.CollectionChanged += OnPointsCollectionChanged; + + base.ConnectHandler(nativeView); + } + + protected override void DisconnectHandler(MauiShapeView nativeView) + { + if (VirtualView is Polygon polygon) + polygon.Points.CollectionChanged -= OnPointsCollectionChanged; + + base.DisconnectHandler(nativeView); + } + + public static void MapShape(IShapeViewHandler handler, Polygon polygon) + { + handler.PlatformView?.UpdateShape(polygon); + } + + public static void MapPoints(IShapeViewHandler handler, Polygon polygon) + { + handler.PlatformView?.InvalidateShape(polygon); + } + + public static void MapFillRule(IShapeViewHandler handler, Polygon polygon) + { + IDrawable drawable = handler.PlatformView?.Drawable; + + if (drawable == null) + return; + + if (drawable is ShapeDrawable shapeDrawable) + shapeDrawable.WindingMode = polygon.FillRule == FillRule.EvenOdd ? Graphics.WindingMode.EvenOdd : Graphics.WindingMode.NonZero; + + handler.PlatformView?.InvalidateShape(polygon); + } + + void OnPointsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + PlatformView?.InvalidateShape(VirtualView); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.Tizen.cs new file mode 100644 index 0000000000..69fa54c1a0 --- /dev/null +++ b/src/Controls/src/Core/Handlers/Shapes/Polyline/PolylineHandler.Tizen.cs @@ -0,0 +1,52 @@ +using Microsoft.Maui.Controls.Shapes; +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Controls.Handlers +{ + public partial class PolylineHandler + { + protected override void ConnectHandler(MauiShapeView nativeView) + { + if (VirtualView is Polyline polyline) + polyline.Points.CollectionChanged += OnPointsCollectionChanged; + + base.ConnectHandler(nativeView); + } + + protected override void DisconnectHandler(MauiShapeView nativeView) + { + if (VirtualView is Polyline polyline) + polyline.Points.CollectionChanged -= OnPointsCollectionChanged; + + base.DisconnectHandler(nativeView); + } + + public static void MapShape(IShapeViewHandler handler, Polyline polyline) + { + handler.PlatformView?.UpdateShape(polyline); + } + + public static void MapPoints(IShapeViewHandler handler, Polyline polyline) + { + handler.PlatformView?.InvalidateShape(polyline); + } + + public static void MapFillRule(IShapeViewHandler handler, Polyline polyline) + { + IDrawable drawable = handler.PlatformView?.Drawable; + + if (drawable == null) + return; + + if (drawable is ShapeDrawable shapeDrawable) + shapeDrawable.WindingMode = polyline.FillRule == FillRule.EvenOdd ? Graphics.WindingMode.EvenOdd : Graphics.WindingMode.NonZero; + + handler.PlatformView?.InvalidateShape(polyline); + } + + void OnPointsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + PlatformView?.InvalidateShape(VirtualView); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Shapes/Rectangle/RectangleHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Shapes/Rectangle/RectangleHandler.Tizen.cs new file mode 100644 index 0000000000..ced3c8e08a --- /dev/null +++ b/src/Controls/src/Core/Handlers/Shapes/Rectangle/RectangleHandler.Tizen.cs @@ -0,0 +1,17 @@ +using Microsoft.Maui.Controls.Shapes; + +namespace Microsoft.Maui.Controls.Handlers +{ + public partial class RectangleHandler + { + public static void MapRadiusX(IShapeViewHandler handler, Rectangle rectangle) + { + handler.PlatformView?.InvalidateShape(rectangle); + } + + public static void MapRadiusY(IShapeViewHandler handler, Rectangle rectangle) + { + handler.PlatformView?.InvalidateShape(rectangle); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Shapes/RoundRectangle/RoundRectangleHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Shapes/RoundRectangle/RoundRectangleHandler.Tizen.cs new file mode 100644 index 0000000000..56c443511c --- /dev/null +++ b/src/Controls/src/Core/Handlers/Shapes/RoundRectangle/RoundRectangleHandler.Tizen.cs @@ -0,0 +1,12 @@ +using Microsoft.Maui.Controls.Shapes; + +namespace Microsoft.Maui.Controls.Handlers +{ + public partial class RoundRectangleHandler + { + public static void MapCornerRadius(IShapeViewHandler handler, RoundRectangle roundRectangle) + { + handler.PlatformView?.InvalidateShape(roundRectangle); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Handlers/Shell/ShellHandler.Tizen.cs b/src/Controls/src/Core/Handlers/Shell/ShellHandler.Tizen.cs new file mode 100644 index 0000000000..de1e02121a --- /dev/null +++ b/src/Controls/src/Core/Handlers/Shell/ShellHandler.Tizen.cs @@ -0,0 +1,37 @@ +using Microsoft.Maui.Controls.Platform; +using Microsoft.Maui.Handlers; +using Tizen.UIExtensions.Common; + +namespace Microsoft.Maui.Controls.Handlers +{ + public partial class ShellHandler : ViewHandler + { + public static PropertyMapper Mapper = + new PropertyMapper(ElementMapper); + + public static CommandMapper CommandMapper = + new CommandMapper(ElementCommandMapper); + + public ShellHandler() : base(Mapper, CommandMapper) + { + } + + public override void SetVirtualView(IView view) + { + base.SetVirtualView(view); + PlatformView?.SetElement((Shell)view, MauiContext); + } + + protected override ShellView CreatePlatformView() + { + if (DeviceInfo.GetDeviceType() == DeviceType.TV) + { + return new TVShellView(NativeParent); + } + else + { + return new ShellView(NativeParent); + } + } + } +} diff --git a/src/Controls/src/Core/Interactivity/PlatformBehavior.cs b/src/Controls/src/Core/Interactivity/PlatformBehavior.cs index eb3f46f7c8..e7ae465102 100644 --- a/src/Controls/src/Core/Interactivity/PlatformBehavior.cs +++ b/src/Controls/src/Core/Interactivity/PlatformBehavior.cs @@ -8,6 +8,8 @@ using PlatformView = AppKit.NSView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; #elif NET6_0 || NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs new file mode 100644 index 0000000000..0862df7d90 --- /dev/null +++ b/src/Controls/src/Core/Platform/AlertManager/AlertManager.Tizen.cs @@ -0,0 +1,331 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ElmSharp; +using Microsoft.Maui.Controls.Internals; +using Tizen.UIExtensions.ElmSharp; +using EBox = ElmSharp.Box; +using EButton = ElmSharp.Button; +using EColor = ElmSharp.Color; +using EProgressBar = ElmSharp.ProgressBar; +using EWindow = ElmSharp.Window; +using GColor = Microsoft.Maui.Graphics.Color; +using TButton = Tizen.UIExtensions.ElmSharp.Button; +using TColor = Tizen.UIExtensions.Common.Color; + +namespace Microsoft.Maui.Controls.Platform +{ + internal partial class AlertManager + { + readonly List Subscriptions = new List(); + + internal void Subscribe(Window window) + { + IMauiContext mauiContext = window?.MauiContext; + EWindow nativeWindow = mauiContext.GetNativeWindow(); + + if (mauiContext == null || nativeWindow == null) + return; + + if (Subscriptions.Any(s => s.Window == nativeWindow)) + { + return; + } + + Subscriptions.Add(new AlertRequestHelper(nativeWindow, mauiContext)); + } + + internal void Unsubscribe(Window window) + { + IMauiContext mauiContext = window?.MauiContext; + EWindow nativeWindow = mauiContext.GetNativeWindow(); + + var toRemove = Subscriptions.Where(s => s.Window == nativeWindow).ToList(); + + foreach (AlertRequestHelper alertRequestHelper in toRemove) + { + alertRequestHelper.Dispose(); + Subscriptions.Remove(alertRequestHelper); + } + } + } + + internal sealed class AlertRequestHelper : IDisposable + { + int _busyCount; + Dialog _pageBusyDialog; + readonly HashSet _alerts = new HashSet(); + + internal AlertRequestHelper(EWindow window, IMauiContext mauiContext) + { + Window = window; + MauiContext = mauiContext; + + MessagingCenter.Subscribe(Window, Page.BusySetSignalName, OnBusySetRequest); + MessagingCenter.Subscribe(Window, Page.AlertSignalName, OnAlertRequest); + MessagingCenter.Subscribe(Window, Page.ActionSheetSignalName, OnActionSheetRequest); + MessagingCenter.Subscribe(Window, Page.PromptSignalName, OnPromptRequested); + } + + public EWindow Window { get; } + public IMauiContext MauiContext { get; } + + public void Dispose() + { + MessagingCenter.Unsubscribe(Window, Page.AlertSignalName); + MessagingCenter.Unsubscribe(Window, Page.BusySetSignalName); + MessagingCenter.Unsubscribe(Window, Page.ActionSheetSignalName); + MessagingCenter.Unsubscribe(Window, Page.PromptSignalName); + } + + void OnBusySetRequest(Page sender, bool enabled) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + { + return; + } + _busyCount = Math.Max(0, enabled ? _busyCount + 1 : _busyCount - 1); + + if (null == _pageBusyDialog) + { + _pageBusyDialog = new Dialog(MauiContext.GetNativeParent()) + { + Orientation = PopupOrientation.Center, + BackgroundColor = EColor.Transparent + }; + + _pageBusyDialog.SetTitleBackgroundColor(EColor.Transparent); + _pageBusyDialog.SetContentBackgroundColor(EColor.Transparent); + + var activity = new EProgressBar(_pageBusyDialog) { IsPulseMode = true }.SetLargeStyle(); + activity.PlayPulse(); + activity.Show(); + + _pageBusyDialog.Content = activity; + } + + if (_busyCount > 0) + { + _pageBusyDialog.Show(); + } + else + { + _pageBusyDialog.Dismiss(); + _pageBusyDialog.Unrealize(); + _pageBusyDialog = null; + } + } + + void OnAlertRequest(Page sender, AlertArguments arguments) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + return; + + var alert = Dialog.CreateDialog(MauiContext.GetNativeParent(), (arguments.Accept != null)); + + alert.Title = arguments.Title; + var message = arguments.Message?.Replace("&", "&", StringComparison.Ordinal).Replace("<", "<", StringComparison.Ordinal).Replace(">", ">", StringComparison.Ordinal).Replace(Environment.NewLine, "
      ", StringComparison.Ordinal); + alert.Message = message; + + var cancel = new EButton(alert) { Text = arguments.Cancel }; + alert.NegativeButton = cancel; + cancel.Clicked += (s, evt) => + { + arguments.SetResult(false); + alert.Dismiss(); + }; + + if (arguments.Accept != null) + { + var ok = new EButton(alert) { Text = arguments.Accept }; + alert.NeutralButton = ok; + ok.Clicked += (s, evt) => + { + arguments.SetResult(true); + alert.Dismiss(); + }; + } + + alert.BackButtonPressed += (s, evt) => + { + arguments.SetResult(false); + alert.Dismiss(); + }; + + alert.Show(); + _alerts.Add(alert); + alert.Dismissed += (s, e) => _alerts.Remove(alert); + } + + void OnActionSheetRequest(Page sender, ActionSheetArguments arguments) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + return; + + var alert = Dialog.CreateDialog(MauiContext.GetNativeParent()); + + alert.Title = arguments.Title; + var box = new EBox(alert); + + if (null != arguments.Destruction) + { + var destruction = new TButton(alert) + { + Text = arguments.Destruction, + AlignmentX = -1 + }; + //TextColor should be set after applying style + destruction.TextColor = TColor.Red; + + destruction.Clicked += (s, evt) => + { + arguments.SetResult(arguments.Destruction); + alert.Dismiss(); + }; + destruction.Show(); + box.PackEnd(destruction); + } + + foreach (string buttonName in arguments.Buttons) + { + var button = new TButton(alert) + { + Text = buttonName, + AlignmentX = -1 + }; + + button.Clicked += (s, evt) => + { + arguments.SetResult(buttonName); + alert.Dismiss(); + }; + button.Show(); + box.PackEnd(button); + } + + box.Show(); + alert.Content = box; + + if (null != arguments.Cancel) + { + var cancel = new TButton(alert) { Text = arguments.Cancel }; + alert.NegativeButton = cancel; + cancel.Clicked += (s, evt) => + { + alert.Dismiss(); + }; + } + + alert.BackButtonPressed += (s, evt) => + { + alert.Dismiss(); + }; + + alert.Show(); + + _alerts.Add(alert); + alert.Dismissed += (s, e) => _alerts.Remove(alert); + } + + void OnPromptRequested(Page sender, PromptArguments args) + { + // Verify that the page making the request is child of this platform + if (!PageIsInThisContext(sender)) + return; + + var prompt = Dialog.CreateDialog(MauiContext.GetNativeParent(), (args.Accept != null)); + prompt.Title = args.Title; + + var entry = new Entry + { + MinimumWidthRequest = 200, + HorizontalOptions = LayoutOptions.Fill, + BackgroundColor = GColor.FromRgb(250, 250, 250), + TextColor = GColor.FromRgb(0, 0, 0), + Keyboard = args.Keyboard, + }; + + if (!string.IsNullOrEmpty(args.Placeholder)) + { + entry.Placeholder = args.Placeholder; + } + + if (args.MaxLength > 0) + { + entry.MaxLength = args.MaxLength; + } + + var layout = new VerticalStackLayout + { + Spacing = 10, + }; + layout.Add(new Label + { + LineBreakMode = LineBreakMode.CharacterWrap, + TextColor = Application.AccentColor, + Text = args.Message, + HorizontalOptions = LayoutOptions.Fill, + HorizontalTextAlignment = TextAlignment.Center, +#pragma warning disable CS0612 // Type or member is obsolete + FontSize = Device.GetNamedSize(NamedSize.Subtitle, typeof(Label)), +#pragma warning disable CS0612 // Type or member is obsolete + }); + layout.Add(entry); + layout.Parent = sender; + var nativeView = layout.ToPlatform(MauiContext); + + var width = sender.Width <= -1 ? double.PositiveInfinity : sender.Width; + var height = sender.Height <= -1 ? double.PositiveInfinity : sender.Height; + var request = layout.CrossPlatformMeasure(width, height); + + nativeView.MinimumHeight = request.Height.ToScaledPixel(); + nativeView.MinimumWidth = request.Width.ToScaledPixel(); + + prompt.Content = nativeView; + + var cancel = new EButton(prompt) { Text = args.Cancel }; + prompt.NegativeButton = cancel; + cancel.Clicked += (s, evt) => + { + args.SetResult(null); + prompt.Dismiss(); + }; + + if (args.Accept != null) + { + var ok = new EButton(prompt) { Text = args.Accept }; + prompt.NeutralButton = ok; + ok.Clicked += (s, evt) => + { + args.SetResult(entry.Text); + prompt.Dismiss(); + }; + } + + entry.Completed += (s, e) => + { + args.SetResult(entry.Text); + prompt.Dismiss(); + }; + + prompt.BackButtonPressed += (s, evt) => + { + prompt.Dismiss(); + }; + + prompt.Show(); + + _alerts.Add(prompt); + prompt.Dismissed += (s, e) => _alerts.Remove(prompt); + } + + bool PageIsInThisContext(IView sender) + { + var context = sender.Handler?.MauiContext ?? null; + return context?.GetNativeWindow() == Window; + } + } +} diff --git a/src/Controls/src/Core/Platform/GestureManager/GestureManager.Tizen.cs b/src/Controls/src/Core/Platform/GestureManager/GestureManager.Tizen.cs new file mode 100644 index 0000000000..f231e5a477 --- /dev/null +++ b/src/Controls/src/Core/Platform/GestureManager/GestureManager.Tizen.cs @@ -0,0 +1,137 @@ +#nullable enable + +using System; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Linq; + +namespace Microsoft.Maui.Controls.Platform +{ + class GestureManager : IDisposable + { + IViewHandler? _handler; + GestureDetector? _gestureDetector; + bool _disposed = false; + + protected virtual VisualElement? Element => _handler?.VirtualView as VisualElement; + + public GestureManager(IViewHandler handler) + { + _handler = handler; + _gestureDetector = null; + SetupElement(null, Element); + } + + void SetupElement(VisualElement? oldElement, VisualElement? newElement) + { + if (oldElement != null) + { + if (oldElement is View ov && + ov.GestureRecognizers is INotifyCollectionChanged incc) + { + incc.CollectionChanged -= OnGestureRecognizerCollectionChanged; + _gestureDetector?.Clear(); + } + oldElement.PropertyChanged -= OnElementPropertyChanged; + } + + if (newElement != null) + { + if (newElement is View ov && + ov.GestureRecognizers is INotifyCollectionChanged incc) + { + incc.CollectionChanged += OnGestureRecognizerCollectionChanged; + if (ov.GestureRecognizers.Count > 0) + { + _gestureDetector = new GestureDetector(_handler); + _gestureDetector.AddGestures(ov.GestureRecognizers); + } + } + newElement.PropertyChanged += OnElementPropertyChanged; + } + + UpdateInputTransparent(); + UpdateIsEnabled(); + } + + void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == VisualElement.InputTransparentProperty.PropertyName) + UpdateInputTransparent(); + else if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName) + UpdateIsEnabled(); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + _disposed = true; + + if (disposing) + { + SetupElement(Element, null); + if (_gestureDetector != null) + { + _gestureDetector.Dispose(); + _gestureDetector = null; + } + _handler = null; + } + } + + void UpdateInputTransparent() + { + if (Element != null && _gestureDetector != null) + { + _gestureDetector.InputTransparent = Element.InputTransparent; + } + } + + void UpdateIsEnabled() + { + if (Element != null && _gestureDetector != null) + { + _gestureDetector.IsEnabled = Element.IsEnabled; + } + } + + void OnGestureRecognizerCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + if (_gestureDetector == null) + { + _gestureDetector = new GestureDetector(_handler); + } + + // Gestures will be registered/unregistered according to changes in the GestureRecognizers list + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + _gestureDetector.AddGestures(e.NewItems?.OfType()); + break; + + case NotifyCollectionChangedAction.Replace: + _gestureDetector.RemoveGestures(e.OldItems?.OfType()); + _gestureDetector.AddGestures(e.NewItems?.OfType()); + break; + + case NotifyCollectionChangedAction.Remove: + _gestureDetector.RemoveGestures(e.OldItems?.OfType()); + break; + + case NotifyCollectionChangedAction.Reset: + _gestureDetector.Clear(); + break; + } + } + } +} diff --git a/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Tizen.cs b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Tizen.cs new file mode 100644 index 0000000000..1f9c89a024 --- /dev/null +++ b/src/Controls/src/Core/Platform/ModalNavigationManager/ModalNavigationManager.Tizen.cs @@ -0,0 +1,59 @@ +#nullable enable + +using System.Threading.Tasks; +using Microsoft.Maui; + +namespace Microsoft.Maui.Controls.Platform +{ + internal partial class ModalNavigationManager + { + ModalStack _modalStack => MauiContext.GetModalStack(); + IPageController CurrentPageController => _navModel.CurrentPage; + + partial void OnPageAttachedHandler() + { + MauiContext.GetNativeWindow().SetBackButtonPressedHandler(OnBackButtonPressed); + } + + public Task PopModalAsync(bool animated) + { + Page modal = _navModel.PopModal(); + ((IPageController)modal).SendDisappearing(); + var source = new TaskCompletionSource(); + + var modalRenderer = modal.Handler as IPlatformViewHandler; + if (modalRenderer != null) + { + // TODO. Need to implement animated + _modalStack.Pop(); + source.TrySetResult(modal); + CurrentPageController?.SendAppearing(); + } + return source.Task; + } + + public Task PushModalAsync(Page modal, bool animated) + { + CurrentPageController?.SendDisappearing(); + _navModel.PushModal(modal); + + var nativeView = modal.ToPlatform(MauiContext); + + _modalStack.Push(nativeView); + + // Verify that the modal is still on the stack + if (_navModel.CurrentPage == modal) + ((IPageController)modal).SendAppearing(); + + return Task.CompletedTask; + } + + bool OnBackButtonPressed() + { + Page root = _navModel.LastRoot; + bool handled = root?.SendBackButtonPressed() ?? false; + + return handled; + } + } +} diff --git a/src/Controls/src/Core/Platform/PlatformConfigurationExtensions.cs b/src/Controls/src/Core/Platform/PlatformConfigurationExtensions.cs index eec66985e2..f09c4341dd 100644 --- a/src/Controls/src/Core/Platform/PlatformConfigurationExtensions.cs +++ b/src/Controls/src/Core/Platform/PlatformConfigurationExtensions.cs @@ -4,6 +4,8 @@ using CurrentPlatform = Microsoft.Maui.Controls.PlatformConfiguration.iOS; using CurrentPlatform = Microsoft.Maui.Controls.PlatformConfiguration.Android; #elif WINDOWS using CurrentPlatform = Microsoft.Maui.Controls.PlatformConfiguration.Windows; +#elif TIZEN +using CurrentPlatform = Microsoft.Maui.Controls.PlatformConfiguration.Tizen; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Controls/src/Core/Platform/PlatformEffect.cs b/src/Controls/src/Core/Platform/PlatformEffect.cs index 7d00c80daa..ca81a67794 100644 --- a/src/Controls/src/Core/Platform/PlatformEffect.cs +++ b/src/Controls/src/Core/Platform/PlatformEffect.cs @@ -5,6 +5,8 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Controls/src/Core/Platform/Tizen/DragGestureHandler.cs b/src/Controls/src/Core/Platform/Tizen/DragGestureHandler.cs new file mode 100644 index 0000000000..50fef189fe --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/DragGestureHandler.cs @@ -0,0 +1,243 @@ +using System; +using System.Threading.Tasks; +using ElmSharp; +using Microsoft.Maui.Controls.Internals; +using Tizen.UIExtensions.ElmSharp; +using EGestureType = ElmSharp.GestureLayer.GestureType; +using TImage = Tizen.UIExtensions.ElmSharp.Image; +using TLabel = Tizen.UIExtensions.ElmSharp.Label; + +namespace Microsoft.Maui.Controls.Platform +{ + public class DragGestureHandler : GestureHandler + { + DragDropExtensions.Interop.DragIconCreateCallback _iconCallback; + DragDropExtensions.Interop.DragStateCallback _dragDoneCallback; + + static bool s_isDragging; + static CustomDragStateData s_currentDragStateData; + + protected virtual IView Element => Handler?.VirtualView as IView; + + public DragGestureHandler(IGestureRecognizer recognizer, IViewHandler handler) : base(recognizer) + { + _iconCallback = OnIconCallback; + _dragDoneCallback = OnDragDoneCallback; + Handler = handler; + } + + public override EGestureType Type => EGestureType.LongTap; + + public IViewHandler Handler { get; } + + public static CustomDragStateData CurrentStateData + { + get + { + return s_currentDragStateData; + } + } + + EvasObject PlatformView + { + get + { + return Handler.PlatformView as EvasObject; + } + } + + public void ResetCurrentStateData() + { + s_currentDragStateData = null; + } + + protected override void OnStarted(View sender, object data) + { + } + + protected override void OnMoved(View sender, object data) + { + //Workaround to prevent an error occuring by multiple StartDrag calling in Tizen 6.5 + if (!s_isDragging) + { + ResetCurrentStateData(); + StartDrag(); + } + } + + protected override void OnCompleted(View sender, object data) + { + } + + protected override void OnCanceled(View sender, object data) + { + } + + void StartDrag() + { + if (Recognizer is DragGestureRecognizer dragGestureRecognizer && dragGestureRecognizer.CanDrag) + { + if (Handler == null) + return; + + var arg = dragGestureRecognizer.SendDragStarting(Element); + + if (arg.Cancel) + return; + + s_currentDragStateData = new CustomDragStateData(); + s_currentDragStateData.DataPackage = arg.Data; + + var target = DragDropExtensions.DragDropContentType.Text; + var strData = string.IsNullOrEmpty(arg.Data.Text) ? " " : arg.Data.Text; + + s_isDragging = true; + + DragDropExtensions.StartDrag(PlatformView, + target, + strData, + DragDropExtensions.DragDropActionType.Move, + _iconCallback, + null, + null, + _dragDoneCallback); + } + } + + IntPtr OnIconCallback(IntPtr data, IntPtr window, ref int xoff, ref int yoff) + { + EvasObject icon = null; + EvasObject parent = new CustomWindow(PlatformView, window); + + if (s_currentDragStateData.DataPackage.Image != null) + { + icon = GetImageIconAsync(parent).Result; + } + else if (PlatformView is ShapeView) + { + icon = GetShapeView(parent); + } + else + { + icon = GetDefaultIcon(parent); + } + var bound = PlatformView.Geometry; + bound.X = 0; + bound.Y = 0; + icon.Geometry = bound; + + if (icon is TLabel) + { + icon.Resized += (s, e) => + { + var map = new EvasMap(4); + map.PopulatePoints(icon.Geometry, 0); + map.Zoom(0.5, 0.5, 0, 0); + icon.IsMapEnabled = true; + icon.EvasMap = map; + }; + } + else + { + var map = new EvasMap(4); + map.PopulatePoints(icon.Geometry, 0); + map.Zoom(0.5, 0.5, 0, 0); + icon.IsMapEnabled = true; + icon.EvasMap = map; + } + + + return icon; + } + + EvasObject GetDefaultIcon(EvasObject parent) + { + if (!string.IsNullOrEmpty(s_currentDragStateData.DataPackage.Text)) + { + var label = new TLabel(parent); + label.Text = s_currentDragStateData.DataPackage.Text; + + if (Element is IFontElement fe) + label.FontSize = fe.FontSize; + + return label; + } + else + { + var box = new ElmSharp.Rectangle(parent); + box.Color = new ElmSharp.Color(128, 128, 128, 128); + return box; + } + } + + async Task GetImageIconAsync(EvasObject parent) + { + var image = new TImage(parent); + var mImage = s_currentDragStateData.DataPackage.Image; + var services = Handler.MauiContext?.Services; + var provider = services.GetService(typeof(IImageSourceServiceProvider)) as IImageSourceServiceProvider; + var service = provider?.GetImageSourceService(mImage); + var result = await service.GetImageAsync(mImage, image); + if (result == null) + return null; + return image; + } + + EvasObject GetShapeView(EvasObject parent) + { + var copiedImg = new EvasImage(parent) + { + IsFilled = true + }; + + if (PlatformView is ShapeView shapeView) + { + var canvas = shapeView.SKCanvasView; + var realHandle = DragDropExtensions.Interop.elm_object_part_content_get(canvas, "elm.swallow.content"); + + DragDropExtensions.Interop.evas_object_image_size_get(realHandle, out int w, out int h); + DragDropExtensions.Interop.evas_object_image_size_set(copiedImg, w, h); + + var imgData = DragDropExtensions.Interop.evas_object_image_data_get(realHandle, false); + DragDropExtensions.Interop.evas_object_image_data_set(copiedImg, imgData); + } + + return copiedImg; + } + + void OnDragDoneCallback(IntPtr data, IntPtr obj) + { + s_isDragging = false; + if (Recognizer is DragGestureRecognizer dragGestureRecognizer && dragGestureRecognizer.CanDrag) + { + dragGestureRecognizer.SendDropCompleted(new DropCompletedEventArgs()); + } + } + + public class CustomWindow : EvasObject + { + IntPtr _handle; + + public CustomWindow(EvasObject parent, IntPtr handle) : base() + { + _handle = handle; + Realize(parent); + } + + public CustomWindow(EvasObject handle) : base(handle) + { + } + + protected override IntPtr CreateHandle(EvasObject parent) + { + return _handle; + } + } + + public class CustomDragStateData + { + public DataPackage DataPackage { get; set; } + public DataPackageOperation AcceptedOperation { get; set; } = DataPackageOperation.Copy; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/DropGestureHandler.cs b/src/Controls/src/Core/Platform/Tizen/DropGestureHandler.cs new file mode 100644 index 0000000000..a25c4ec482 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/DropGestureHandler.cs @@ -0,0 +1,126 @@ +using System; +using System.Linq; +using ElmSharp; +using Tizen.Common; +using Tizen.UIExtensions.ElmSharp; +using EGestureType = ElmSharp.GestureLayer.GestureType; + +namespace Microsoft.Maui.Controls.Platform +{ + public class DropGestureHandler : GestureHandler + { + DragDropExtensions.Interop.DragStateCallback _dragEnterCallback; + DragDropExtensions.Interop.DragStateCallback _dragLeaveCallback; + DragDropExtensions.Interop.DropCallback _dropCallback; + + public override EGestureType Type => default(EGestureType); + + public DropGestureHandler(IGestureRecognizer recognizer, IViewHandler handler) : base(recognizer) + { + _dragEnterCallback = OnEnterCallback; + _dragLeaveCallback = OnLeaveCallback; + _dropCallback = OnDropCallback; + Handler = handler; + } + + public IViewHandler Handler { get; } + + EvasObject PlatformView + { + get + { + var native = Handler.PlatformView as EvasObject; + if (native is Canvas canvas) + { + var child = canvas.Children.LastOrDefault(); + + if (child != null) + { + if (child.PassEvents) + child.PassEvents = false; + + return child; + } + } + return native; + } + } + + + public void AddDropGesture() + { + if (Handler == null) + return; + + var target = DragDropExtensions.DragDropContentType.Targets; + + DragDropExtensions.AddDropTarget(PlatformView, + target, + _dragEnterCallback, + _dragLeaveCallback, null, + _dropCallback); + } + + void OnEnterCallback(IntPtr data, IntPtr obj) + { + var currentStateData = DragGestureHandler.CurrentStateData; + if (currentStateData == null) + return; + + var arg = new DragEventArgs(currentStateData.DataPackage); + + if (Recognizer is DropGestureRecognizer dropRecognizer && dropRecognizer.AllowDrop) + dropRecognizer.SendDragOver(arg); + + DragGestureHandler.CurrentStateData.AcceptedOperation = arg.AcceptedOperation; + } + + void OnLeaveCallback(IntPtr data, IntPtr obj) + { + var currentStateData = DragGestureHandler.CurrentStateData; + if (currentStateData == null) + return; + + var arg = new DragEventArgs(currentStateData.DataPackage); + + if (Recognizer is DropGestureRecognizer dropRecognizer && dropRecognizer.AllowDrop) + dropRecognizer.SendDragLeave(arg); + + DragGestureHandler.CurrentStateData.AcceptedOperation = arg.AcceptedOperation; + } + + bool OnDropCallback(IntPtr data, IntPtr obj, IntPtr selectionData) + { + var currentStateData = DragGestureHandler.CurrentStateData; + + if (currentStateData.DataPackage == null || currentStateData.AcceptedOperation == DataPackageOperation.None) + return false; + + Application.Current?.Dispatcher.Dispatch(async () => + { + if (Recognizer is DropGestureRecognizer dropRecognizer && dropRecognizer.AllowDrop) + await dropRecognizer.SendDrop(new DropEventArgs(currentStateData.DataPackage.View)); + }); + + return true; + } + + #region GestureHandler + protected override void OnStarted(View sender, object data) + { + } + + protected override void OnMoved(View sender, object data) + { + } + + protected override void OnCompleted(View sender, object data) + { + } + + protected override void OnCanceled(View sender, object data) + { + } + #endregion + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/ButtonExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/ButtonExtensions.cs new file mode 100644 index 0000000000..60448c71b3 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/ButtonExtensions.cs @@ -0,0 +1,13 @@ +using static Microsoft.Maui.Controls.Button; +using EButton = ElmSharp.Button; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class ButtonExtensions + { + public static void UpdateContentLayout(this EButton platformButton, Button button) + { + //TODO : Need to impl + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/CollectionViewExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/CollectionViewExtensions.cs new file mode 100644 index 0000000000..0740026247 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/CollectionViewExtensions.cs @@ -0,0 +1,129 @@ +using System.Collections.Specialized; +using System.Linq; +using Microsoft.Maui.Controls.Handlers.Items; +using Tizen.UIExtensions.ElmSharp; +using TCollectionView = Tizen.UIExtensions.ElmSharp.CollectionView; +using TCollectionViewSelectionMode = Tizen.UIExtensions.ElmSharp.CollectionViewSelectionMode; +using TItemSizingStrategy = Tizen.UIExtensions.ElmSharp.ItemSizingStrategy; +using TSelectedItemChangedEventArgs = Tizen.UIExtensions.ElmSharp.SelectedItemChangedEventArgs; +using TSnapPointsType = Tizen.UIExtensions.ElmSharp.SnapPointsType; +using DPExtensions = Tizen.UIExtensions.ElmSharp.DPExtensions; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class CollectionViewExtensions + { + static INotifyCollectionChanged _observableSource; + + public static void UpdateItemsSource(this TCollectionView platformView, ItemsView view) + { + if (view.ItemsSource is INotifyCollectionChanged collectionChanged) + { + if (_observableSource != null) + { + _observableSource.CollectionChanged -= OnCollectionChanged; + } + _observableSource = collectionChanged; + _observableSource.CollectionChanged += OnCollectionChanged; + } + UpdateAdaptor(platformView, view); + + void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (view.ItemsSource == null || !view.ItemsSource.Cast().Any()) + { + platformView.Adaptor = EmptyItemAdaptor.Create(view); + } + else + { + if (platformView.Adaptor is EmptyItemAdaptor) + { + platformView.UpdateAdaptor(view); + } + } + } + } + + public static void UpdateItemsLayout(this TCollectionView platformView, StructuredItemsView view) + { + if (view.ItemsLayout != null) + { + var itemSizingStrategy = view.ItemSizingStrategy.ToPlatform(); + if (view.ItemsLayout is GridItemsLayout grid) + { + var orientation = grid.Orientation == ItemsLayoutOrientation.Horizontal; + var verticalItemSpacing = DPExtensions.ConvertToScaledPixel(grid.VerticalItemSpacing); + var horizontalItemSpacing = DPExtensions.ConvertToScaledPixel(grid.HorizontalItemSpacing); + platformView.LayoutManager = new GridLayoutManager(orientation, grid.Span, itemSizingStrategy, verticalItemSpacing, horizontalItemSpacing); + } + else if (view.ItemsLayout is LinearItemsLayout linear) + { + var orientation = linear.Orientation == ItemsLayoutOrientation.Horizontal; + var itemSpacing = DPExtensions.ConvertToScaledPixel(linear.ItemSpacing); + platformView.LayoutManager = new LinearLayoutManager(orientation, itemSizingStrategy, itemSpacing); + } + else + { + platformView.LayoutManager = new LinearLayoutManager(false); + } + platformView.SnapPointsType = (view.ItemsLayout as ItemsLayout).SnapPointsType.ToPlatform(); + platformView.SelectionMode = (view as SelectableItemsView).SelectionMode.ToPlatform(); + } + } + + public static void UpdateAdaptor(this TCollectionView platformView, ItemsView view) + { + if (view.ItemsSource == null || !view.ItemsSource.Cast().Any()) + { + platformView.Adaptor = EmptyItemAdaptor.Create(view); + } + else if (view.ItemTemplate == null) + { + platformView.Adaptor = new ItemDefaultTemplateAdaptor(view); + } + else + { + platformView.Adaptor = new ItemTemplateAdaptor(view); + } + platformView.Adaptor.ItemSelected += OnItemSelected; + } + + static void OnItemSelected(object sender, TSelectedItemChangedEventArgs e) + { + (sender as ItemTemplateAdaptor)?.SendItemSelected(e.SelectedItem); + } + + public static TItemSizingStrategy ToPlatform(this ItemSizingStrategy itemSizingStrategy) + { + if (itemSizingStrategy == ItemSizingStrategy.MeasureAllItems) + return TItemSizingStrategy.MeasureAllItems; + return TItemSizingStrategy.MeasureFirstItem; + } + + public static TSnapPointsType ToPlatform(this SnapPointsType snapPointsType) + { + switch (snapPointsType) + { + case SnapPointsType.Mandatory: + return TSnapPointsType.Mandatory; + case SnapPointsType.MandatorySingle: + return TSnapPointsType.MandatorySingle; + default: + return TSnapPointsType.None; + } + } + + public static TCollectionViewSelectionMode ToPlatform(this SelectionMode selectionMode) + { + switch (selectionMode) + { + case SelectionMode.Multiple: + return TCollectionViewSelectionMode.Multiple; + case SelectionMode.Single: + return TCollectionViewSelectionMode.Single; + default: + return TCollectionViewSelectionMode.None; + } + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/DragDropExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/DragDropExtensions.cs new file mode 100644 index 0000000000..1d3f8108f1 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/DragDropExtensions.cs @@ -0,0 +1,114 @@ +using System; +using System.Runtime.InteropServices; +using ElmSharp; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class DragDropExtensions + { + public static void AddDropTarget(EvasObject obj, DragDropContentType contentType, + Interop.DragStateCallback enterCallback, + Interop.DragStateCallback leaveCallback, + Interop.DragPositionCallback positionCallback, + Interop.DropCallback dropCallback) + { + Interop.elm_drop_target_add(obj.RealHandle, contentType, + enterCallback, IntPtr.Zero, + leaveCallback, IntPtr.Zero, + positionCallback, IntPtr.Zero, + dropCallback, IntPtr.Zero); + } + + public static void StartDrag(EvasObject obj, DragDropContentType contentType, + string data, DragDropActionType actionType, + Interop.DragIconCreateCallback iconCallback, + Interop.DragPositionCallback positionCallback, + Interop.DragAcceptCallback acceptCallback, + Interop.DragStateCallback statCallback) + { + var strData = Marshal.StringToHGlobalAnsi(data); + Interop.elm_drag_start(obj.RealHandle, contentType, strData, actionType, + iconCallback, IntPtr.Zero, + positionCallback, IntPtr.Zero, + acceptCallback, IntPtr.Zero, + statCallback, IntPtr.Zero); + } + + public enum DragDropContentType + { + Targets = -1, + None = 0, + Text = 1, + MarkUp = 2, + Image = 4, + VCard = 8, + Html = 16 + } + + public enum DragDropActionType + { + Unknown = 0, + Copy, + Move, + Private, + Ask, + List, + Link, + Description + } + + public class Interop + { + public const string LibElementary = "libelementary.so.1"; + public const string LibEvas = "libevas.so.1"; + + + public delegate IntPtr DragIconCreateCallback(IntPtr data, IntPtr window, ref int xoff, ref int yoff); + public delegate void DragPositionCallback(IntPtr data, IntPtr obj, int x, int y, int actionType); + public delegate void DragAcceptCallback(IntPtr data, IntPtr obj, bool accept); + public delegate void DragStateCallback(IntPtr data, IntPtr obj); + public delegate bool DropCallback(IntPtr data, IntPtr obj, IntPtr selectionData); + + [DllImport(LibElementary)] + internal static extern void elm_drop_target_add(IntPtr obj, + DragDropContentType type, + DragStateCallback enterCallback, + IntPtr enterData, + DragStateCallback leaveCallback, + IntPtr leaveData, + DragPositionCallback positionCallback, + IntPtr positionData, + DropCallback dropcallback, + IntPtr dropData); + + [DllImport(LibElementary)] + internal static extern void elm_drag_start(IntPtr obj, + DragDropContentType contentType, + IntPtr data, + DragDropActionType actionType, + DragIconCreateCallback iconCreateCallback, + IntPtr iconCreateData, + DragPositionCallback dragPositionCallback, + IntPtr dragPositonData, + DragAcceptCallback dragAcceptCallback, + IntPtr dragAcceptData, + DragStateCallback dragStateCallback, + IntPtr dragStateData); + + [DllImport(LibElementary)] + internal static extern IntPtr elm_object_part_content_get(IntPtr obj, string part); + + [DllImport(LibEvas)] + internal static extern IntPtr evas_object_image_data_get(IntPtr obj, bool forWriting); + + [DllImport(LibEvas)] + internal static extern void evas_object_image_data_set(IntPtr obj, IntPtr data); + + [DllImport(LibEvas)] + internal static extern void evas_object_image_size_get(IntPtr obj, out int w, out int h); + + [DllImport(LibEvas)] + internal static extern void evas_object_image_size_set(IntPtr obj, int w, int h); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/FontExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/FontExtensions.cs new file mode 100644 index 0000000000..bb363a06d7 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/FontExtensions.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Maui.Controls.Platform +{ + public static class FontExtensions + { + public static string ToNativeFontFamily(this string self, IFontManager fontManager) + { + return fontManager.GetFontFamily(self); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/SearchBarExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/SearchBarExtensions.cs new file mode 100644 index 0000000000..8238de824c --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/SearchBarExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.Maui.Controls; +using TFontAttributes = Tizen.UIExtensions.Common.FontAttributes; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class SearchBarExtensions + { + + public static TFontAttributes ToPlatform(this FontAttributes fontAttribute) + { + TFontAttributes attributes = TFontAttributes.None; + if (fontAttribute == FontAttributes.Italic) + attributes = attributes | TFontAttributes.Italic; + + if (fontAttribute == FontAttributes.Bold) + attributes = attributes | TFontAttributes.Bold; + + return attributes; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/ShellExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/ShellExtensions.cs new file mode 100644 index 0000000000..fc30d0f8f2 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/ShellExtensions.cs @@ -0,0 +1,17 @@ +using Tizen.UIExtensions.Common; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class ShellExtensions + { + public static DrawerBehavior ToPlatform(this FlyoutBehavior behavior) + { + if (behavior == FlyoutBehavior.Disabled) + return DrawerBehavior.Disabled; + else if (behavior == FlyoutBehavior.Locked) + return DrawerBehavior.Locked; + else + return DrawerBehavior.Drawer; + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs b/src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs new file mode 100644 index 0000000000..8dada6bad8 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Extensions/TextExtensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Maui.Platform; +using Microsoft.Maui.Controls.Internals; +using TEntry = Tizen.UIExtensions.ElmSharp.Entry; +using TLabel = Tizen.UIExtensions.ElmSharp.Label; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class TextExtensions + { + public static void UpdateText(this TEntry entry, InputView inputView) + { + entry.Text = TextTransformUtilites.GetTransformedText(entry.Text, inputView.TextTransform); + } + + public static void UpdateLineBreakMode(this TLabel platformLabel, Label label) + { + platformLabel.LineBreakMode = label.LineBreakMode.ToPlatform(); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/GestureDetector.cs b/src/Controls/src/Core/Platform/Tizen/GestureDetector.cs new file mode 100644 index 0000000000..6576dce5f6 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/GestureDetector.cs @@ -0,0 +1,637 @@ +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using ElmSharp; +using Microsoft.Maui.Devices; +using Microsoft.Maui.Controls.Internals; +using EGestureType = ElmSharp.GestureLayer.GestureType; + +namespace Microsoft.Maui.Controls.Platform +{ + class GestureDetector : IDisposable + { + readonly IDictionary> _handlerCache; + + IViewHandler? _handler; + GestureLayer? _gestureLayer; + double _doubleTapTime = 0; + double _longTapTime = 0; + bool _inputTransparent = false; + bool _isEnabled; + + protected virtual VisualElement? Element => _handler?.VirtualView as VisualElement; + + View? View => Element as View; + + protected virtual EvasObject? Control => _handler?.PlatformView as EvasObject; + + public bool IsEnabled + { + get + { + return _isEnabled; + } + set + { + _isEnabled = value; + UpdateGestureLayerEnabled(); + } + } + + public bool InputTransparent + { + get + { + return _inputTransparent; + } + set + { + _inputTransparent = value; + UpdateGestureLayerEnabled(); + } + } + + public GestureDetector(IViewHandler? handler) + { + _handlerCache = new Dictionary>(); + _handler = handler; + _isEnabled = View?.IsEnabled ?? false; + _inputTransparent = View?.InputTransparent ?? false; + } + + public void Dispose() + { + Clear(); + _handler = null; + } + + public void Clear() + { + // this will clear all callbacks in ElmSharp GestureLayer + _gestureLayer?.Unrealize(); + _gestureLayer = null; + foreach (var handlers in _handlerCache.Values) + { + foreach (var handler in handlers) + { + handler.PropertyChanged -= OnGestureRecognizerPropertyChanged; + } + } + _handlerCache?.Clear(); + + if (DeviceInfo.Idiom == DeviceIdiom.TV) + { + if (Control != null) + Control.KeyDown -= OnKeyDown; + } + } + + public void AddGestures(IEnumerable? recognizers) + { + if (_gestureLayer == null) + { + CreateGestureLayer(); + } + if (recognizers == null) + return; + foreach (var item in recognizers) + { + AddGesture(item); + } + } + + public void RemoveGestures(IEnumerable? recognizers) + { + if (recognizers == null) + return; + foreach (var item in recognizers) + RemoveGesture(item); + } + + void CreateGestureLayer() + { + _gestureLayer = new GestureLayer(Control); + _gestureLayer.Attach(Control); + _gestureLayer.Deleted += (s, e) => + { + _gestureLayer = null; + Clear(); + }; + UpdateGestureLayerEnabled(); + + if (DeviceInfo.Idiom == DeviceIdiom.TV) + { + if (Control != null) + Control.KeyDown += OnKeyDown; + } + } + + void UpdateGestureLayerEnabled() + { + if (_gestureLayer != null) + { + _gestureLayer.IsEnabled = !_inputTransparent && _isEnabled; + } + } + + void AddGesture(IGestureRecognizer recognizer) + { + var handler = CreateHandler(recognizer); + if (handler == null) + return; + + var gestureType = handler.Type; + var timeout = handler.Timeout; + var cache = _handlerCache; + if (!cache.ContainsKey(gestureType)) + { + cache[gestureType] = new List(); + } + + handler.PropertyChanged += OnGestureRecognizerPropertyChanged; + cache[gestureType].Add(handler); + if (cache[gestureType].Count == 1) + { + switch (gestureType) + { + case EGestureType.Tap: + case EGestureType.TripleTap: + AddTapGesture(gestureType); + break; + + case EGestureType.DoubleTap: + AddDoubleTapGesture(gestureType, timeout); + break; + + case EGestureType.LongTap: + AddLongTapGesture(gestureType, timeout); + break; + + case EGestureType.Line: + AddLineGesture(gestureType); + break; + + case EGestureType.Flick: + AddFlickGesture(gestureType, timeout); + break; + + case EGestureType.Rotate: + AddRotateGesture(gestureType); + break; + + case EGestureType.Momentum: + AddMomentumGesture(gestureType); + break; + + case EGestureType.Zoom: + AddPinchGesture(gestureType); + break; + + default: + break; + } + } + + if (handler is DropGestureHandler dropGestureHandler) + { + dropGestureHandler.AddDropGesture(); + } + } + + void RemoveGesture(IGestureRecognizer recognizer) + { + var cache = _handlerCache; + var handler = LookupHandler(recognizer); + if (handler == null) return; + + var gestureType = cache.FirstOrDefault(x => x.Value.Contains(handler)).Key; + + handler.PropertyChanged -= OnGestureRecognizerPropertyChanged; + cache[gestureType].Remove(handler); + + if (cache[gestureType].Count == 0) + { + switch (gestureType) + { + case EGestureType.Tap: + case EGestureType.DoubleTap: + case EGestureType.TripleTap: + case EGestureType.LongTap: + RemoveTapGesture(gestureType); + break; + + case EGestureType.Line: + RemoveLineGesture(); + break; + + case EGestureType.Flick: + RemoveFlickGesture(); + break; + + case EGestureType.Rotate: + RemoveRotateGesture(); + break; + + case EGestureType.Momentum: + RemoveMomentumGesture(); + break; + + case EGestureType.Zoom: + RemovePinchGesture(); + break; + + default: + break; + } + } + } + + void AddLineGesture(EGestureType type) + { + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.Start, (data) => { OnGestureStarted(type, data); }); + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.Move, (data) => { OnGestureMoved(type, data); }); + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.End, (data) => { OnGestureCompleted(type, data); }); + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void AddPinchGesture(EGestureType type) + { + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.Start, (data) => { OnGestureStarted(type, data); }); + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.Move, (data) => { OnGestureMoved(type, data); }); + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.End, (data) => { OnGestureCompleted(type, data); }); + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void AddTapGesture(EGestureType type) + { + _gestureLayer?.SetTapCallback(type, GestureLayer.GestureState.Start, (data) => { OnGestureStarted(type, data); }); + _gestureLayer?.SetTapCallback(type, GestureLayer.GestureState.End, (data) => { OnGestureCompleted(type, data); }); + _gestureLayer?.SetTapCallback(type, GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void AddDoubleTapGesture(EGestureType type, double timeout) + { + if (_gestureLayer == null) + return; + if (timeout > 0) + _gestureLayer.DoubleTapTimeout = timeout; + + _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.Start, (data) => { OnDoubleTapStarted(type, data); }); + _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.End, (data) => { OnDoubleTapCompleted(type, data); }); + _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void AddLongTapGesture(EGestureType type, double timeout) + { + if (_gestureLayer == null) + return; + if (timeout > 0) + _gestureLayer.LongTapTimeout = timeout; + + _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.Start, (data) => { OnLongTapStarted(type, data); }); + _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.Move, (data) => { OnLongTapMoved(type, data); }); + _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.End, (data) => { OnLongTapCompleted(type, data); }); + _gestureLayer.SetTapCallback(type, GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void AddFlickGesture(EGestureType type, double timeout) + { + if (_gestureLayer == null) + return; + if (timeout > 0) + _gestureLayer.FlickTimeLimit = (int)(timeout * 1000); + + // Task to correct wrong coordinates information when applying EvasMap(Xamarin ex: Translation, Scale, Rotate property) + // Always change to the absolute coordinates of the pointer. + int startX = 0; + int startY = 0; + _gestureLayer.SetFlickCallback(GestureLayer.GestureState.Start, (data) => + { + startX = _gestureLayer.EvasCanvas.Pointer.X; + startY = _gestureLayer.EvasCanvas.Pointer.Y; + data.X1 = startX; + data.Y1 = startY; + OnGestureStarted(type, data); + }); + _gestureLayer.SetFlickCallback(GestureLayer.GestureState.Move, (data) => + { + data.X1 = startX; + data.Y1 = startY; + data.X2 = _gestureLayer.EvasCanvas.Pointer.X; + data.Y2 = _gestureLayer.EvasCanvas.Pointer.Y; + OnGestureMoved(type, data); + }); + _gestureLayer.SetFlickCallback(GestureLayer.GestureState.End, (data) => + { + data.X1 = startX; + data.Y1 = startY; + data.X2 = _gestureLayer.EvasCanvas.Pointer.X; + data.Y2 = _gestureLayer.EvasCanvas.Pointer.Y; + OnGestureCompleted(type, data); + }); + _gestureLayer.SetFlickCallback(GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void AddRotateGesture(EGestureType type) + { + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.Start, (data) => { OnGestureStarted(type, data); }); + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.Move, (data) => { OnGestureMoved(type, data); }); + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.End, (data) => { OnGestureCompleted(type, data); }); + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void AddMomentumGesture(EGestureType type) + { + // Task to correct wrong coordinates information when applying EvasMap(Xamarin ex: Translation, Scale, Rotate property) + // Always change to the absolute coordinates of the pointer. + int startX = 0; + int startY = 0; + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.Start, (data) => + { + startX = _gestureLayer.EvasCanvas.Pointer.X; + startY = _gestureLayer.EvasCanvas.Pointer.Y; + OnGestureStarted(type, data); + }); + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.Move, (data) => + { + data.X1 = startX; + data.Y1 = startY; + data.X2 = _gestureLayer.EvasCanvas.Pointer.X; + data.Y2 = _gestureLayer.EvasCanvas.Pointer.Y; + OnGestureMoved(type, data); + }); + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.End, (data) => { OnGestureCompleted(type, data); }); + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.Abort, (data) => { OnGestureCanceled(type, data); }); + } + + void RemoveLineGesture() + { + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.Start, null); + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.Move, null); + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.End, null); + _gestureLayer?.SetLineCallback(GestureLayer.GestureState.Abort, null); + } + + void RemovePinchGesture() + { + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.Start, null); + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.Move, null); + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.End, null); + _gestureLayer?.SetZoomCallback(GestureLayer.GestureState.Abort, null); + } + + void RemoveTapGesture(EGestureType type) + { + _gestureLayer?.SetTapCallback(type, GestureLayer.GestureState.Start, null); + _gestureLayer?.SetTapCallback(type, GestureLayer.GestureState.End, null); + _gestureLayer?.SetTapCallback(type, GestureLayer.GestureState.Abort, null); + } + + void RemoveFlickGesture() + { + _gestureLayer?.SetFlickCallback(GestureLayer.GestureState.Start, null); + _gestureLayer?.SetFlickCallback(GestureLayer.GestureState.Move, null); + _gestureLayer?.SetFlickCallback(GestureLayer.GestureState.End, null); + _gestureLayer?.SetFlickCallback(GestureLayer.GestureState.Abort, null); + } + + void RemoveRotateGesture() + { + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.Start, null); + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.Move, null); + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.End, null); + _gestureLayer?.SetRotateCallback(GestureLayer.GestureState.Abort, null); + } + + void RemoveMomentumGesture() + { + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.Start, null); + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.Move, null); + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.End, null); + _gestureLayer?.SetMomentumCallback(GestureLayer.GestureState.Abort, null); + } + + #region GestureCallback + + void OnGestureStarted(EGestureType type, object data) + { + var cache = _handlerCache; + if (cache.ContainsKey(type)) + { + foreach (var handler in cache[type]) + { + (handler as IGestureController)?.SendStarted(View, data); + } + } + } + + void OnGestureMoved(EGestureType type, object data) + { + var cache = _handlerCache; + if (cache.ContainsKey(type)) + { + foreach (var handler in cache[type]) + { + (handler as IGestureController)?.SendMoved(View, data); + } + } + } + + void OnGestureCompleted(EGestureType type, object data) + { + var cache = _handlerCache; + if (cache.ContainsKey(type)) + { + foreach (var handler in cache[type]) + { + (handler as IGestureController)?.SendCompleted(View, data); + } + } + } + + void OnGestureCanceled(EGestureType type, object data) + { + var cache = _handlerCache; + if (cache.ContainsKey(type)) + { + foreach (var handler in cache[type]) + { + (handler as IGestureController)?.SendCanceled(View, data); + } + } + } + + void OnDoubleTapStarted(EGestureType type, object data) + { + _doubleTapTime = ((GestureLayer.TapData)data).Timestamp; + OnGestureStarted(type, data); + } + + void OnDoubleTapCompleted(EGestureType type, object data) + { + _doubleTapTime = ((GestureLayer.TapData)data).Timestamp - _doubleTapTime; + var cache = _handlerCache; + + if (cache.ContainsKey(type)) + { + foreach (var handler in cache[type]) + { + if ((handler.Timeout * 1000) >= _longTapTime) + (handler as IGestureController)?.SendCompleted(View, data); + else + (handler as IGestureController)?.SendCanceled(View, data); + } + } + } + + void OnLongTapStarted(EGestureType type, object data) + { + _longTapTime = ((GestureLayer.TapData)data).Timestamp; + OnGestureStarted(type, data); + } + + void OnLongTapMoved(EGestureType type, object data) + { + OnGestureMoved(type, data); + } + + void OnLongTapCompleted(EGestureType type, object data) + { + _longTapTime = ((GestureLayer.TapData)data).Timestamp - _longTapTime; + var cache = _handlerCache; + + if (cache.ContainsKey(type)) + { + foreach (var handler in cache[type]) + { + if ((handler.Timeout * 1000) <= _longTapTime) + (handler as IGestureController)?.SendCompleted(View, data); + else + (handler as IGestureController)?.SendCanceled(View, data); + } + } + } + + #endregion GestureCallback + + GestureHandler CreateHandler(IGestureRecognizer recognizer) + { + if (recognizer is TapGestureRecognizer) + { + return new TapGestureHandler(recognizer); + } + else if (recognizer is PinchGestureRecognizer) + { + return new PinchGestureHandler(recognizer, _handler); + } + else if (recognizer is PanGestureRecognizer) + { + return new PanGestureHandler(recognizer); + } + else if (recognizer is SwipeGestureRecognizer) + { + return new SwipeGestureHandler(recognizer); + } + else if (recognizer is DragGestureRecognizer) + { + return new DragGestureHandler(recognizer, _handler); + } + else if (recognizer is DropGestureRecognizer) + { + return new DropGestureHandler(recognizer, _handler); + } + return Registrar.Registered.GetHandlerForObject(recognizer, recognizer); + } + + GestureHandler? LookupHandler(IGestureRecognizer recognizer) + { + var cache = _handlerCache; + + foreach (var handlers in cache.Values) + { + foreach (var handler in handlers) + { + if (handler.Recognizer == recognizer) + return handler; + } + } + return null; + } + + void UpdateTapGesture(GestureHandler handler) + { + if (handler == null) + return; + RemoveGesture(handler.Recognizer); + AddGesture(handler.Recognizer); + + if (_gestureLayer == null) + return; + if (handler.Timeout > _gestureLayer.DoubleTapTimeout) + _gestureLayer.DoubleTapTimeout = handler.Timeout; + } + + void UpdateLongTapGesture(GestureHandler handler) + { + if (_gestureLayer == null) + return; + if (handler.Timeout > 0 && handler.Timeout < _gestureLayer.LongTapTimeout) + _gestureLayer.LongTapTimeout = handler.Timeout; + } + + void UpdateFlickGesture(GestureHandler handler) + { + if (_gestureLayer == null) + return; + if (handler.Timeout > _gestureLayer.FlickTimeLimit) + _gestureLayer.FlickTimeLimit = (int)(handler.Timeout * 1000); + } + + void OnGestureRecognizerPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) + { + var handler = sender as GestureHandler; + if (handler != null) + { + switch (handler.Type) + { + case EGestureType.Tap: + case EGestureType.DoubleTap: + case EGestureType.TripleTap: + UpdateTapGesture(handler); + break; + + case EGestureType.LongTap: + UpdateLongTapGesture(handler); + break; + + case EGestureType.Flick: + UpdateFlickGesture(handler); + break; + + default: + break; + } + } + } + + void OnKeyDown(object? sender, EvasKeyEventArgs e) + { + if (_gestureLayer == null) + return; + if (e.KeyName == "Return" && _gestureLayer.IsEnabled) + { + var cache = _handlerCache; + if (cache.ContainsKey(EGestureType.Tap)) + { + foreach (var handler in cache[EGestureType.Tap]) + { + (handler as IGestureController)?.SendStarted(View, null); + (handler as IGestureController)?.SendCompleted(View, null); + } + } + } + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/GestureHandler.cs b/src/Controls/src/Core/Platform/Tizen/GestureHandler.cs new file mode 100644 index 0000000000..623357bc30 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/GestureHandler.cs @@ -0,0 +1,55 @@ +using System.ComponentModel; +using ElmSharp; + +namespace Microsoft.Maui.Controls.Platform +{ + public abstract class GestureHandler : IGestureController, INotifyPropertyChanged, IRegisterable + { + public IGestureRecognizer Recognizer { get; private set; } + + public abstract GestureLayer.GestureType Type { get; } + + public virtual double Timeout { get; } + + protected GestureHandler(IGestureRecognizer recognizer) + { + Recognizer = recognizer; + Recognizer.PropertyChanged += OnRecognizerPropertyChanged; + } + + public event PropertyChangedEventHandler PropertyChanged; + + protected abstract void OnStarted(View sender, object data); + + protected abstract void OnMoved(View sender, object data); + + protected abstract void OnCompleted(View sender, object data); + + protected abstract void OnCanceled(View sender, object data); + + void IGestureController.SendStarted(View sender, object data) + { + OnStarted(sender, data); + } + + void IGestureController.SendCompleted(View sender, object data) + { + OnCompleted(sender, data); + } + + void IGestureController.SendMoved(View sender, object data) + { + OnMoved(sender, data); + } + + void IGestureController.SendCanceled(View sender, object data) + { + OnCanceled(sender, data); + } + + protected virtual void OnRecognizerPropertyChanged(object sender, PropertyChangedEventArgs e) + { + PropertyChanged?.Invoke(this, e); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Platform/Tizen/IGestureController.cs b/src/Controls/src/Core/Platform/Tizen/IGestureController.cs new file mode 100644 index 0000000000..a3fda1bb1e --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/IGestureController.cs @@ -0,0 +1,15 @@ +using System; + +namespace Microsoft.Maui.Controls.Platform +{ + public interface IGestureController + { + void SendStarted(View sender, object data); + + void SendMoved(View sender, object data); + + void SendCompleted(View sender, object data); + + void SendCanceled(View sender, object data); + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Platform/Tizen/PanGestureHandler.cs b/src/Controls/src/Core/Platform/Tizen/PanGestureHandler.cs new file mode 100644 index 0000000000..4a18bda041 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/PanGestureHandler.cs @@ -0,0 +1,43 @@ +using ElmSharp; + +namespace Microsoft.Maui.Controls.Platform +{ + public class PanGestureHandler : GestureHandler + { + int _currentPanGestureId; + + public PanGestureHandler(IGestureRecognizer recognizer) : base(recognizer) + { + } + + public override GestureLayer.GestureType Type + { + get + { + return GestureLayer.GestureType.Momentum; + } + } + + protected override void OnStarted(View sender, object data) + { + _currentPanGestureId++; + (Recognizer as IPanGestureController)?.SendPanStarted(sender, _currentPanGestureId); + } + + protected override void OnMoved(View sender, object data) + { + var lineData = (GestureLayer.MomentumData)data; + (Recognizer as IPanGestureController)?.SendPan(sender, DPExtensions.ConvertToScaledDP(lineData.X2 - lineData.X1), DPExtensions.ConvertToScaledDP(lineData.Y2 - lineData.Y1), _currentPanGestureId); + } + + protected override void OnCompleted(View sender, object data) + { + (Recognizer as IPanGestureController)?.SendPanCompleted(sender, _currentPanGestureId); + } + + protected override void OnCanceled(View sender, object data) + { + (Recognizer as IPanGestureController)?.SendPanCanceled(sender, _currentPanGestureId); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Platform/Tizen/PinchGestureHandler.cs b/src/Controls/src/Core/Platform/Tizen/PinchGestureHandler.cs new file mode 100644 index 0000000000..22242d4dca --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/PinchGestureHandler.cs @@ -0,0 +1,58 @@ +using ElmSharp; + +namespace Microsoft.Maui.Controls.Platform +{ + public class PinchGestureHandler : GestureHandler + { + Graphics.Point _currentScalePoint; + int _previousPinchRadius; + double _originalPinchScale; + IViewHandler _handler; + + public PinchGestureHandler(IGestureRecognizer recognizer, IViewHandler handler) : base(recognizer) + { + _handler = handler; + } + + public override GestureLayer.GestureType Type + { + get + { + return GestureLayer.GestureType.Zoom; + } + } + + protected override void OnStarted(View sender, object data) + { + var geometry = (_handler.PlatformView as EvasObject).Geometry; + var zoomData = (GestureLayer.ZoomData)data; + _currentScalePoint = new Graphics.Point((zoomData.X - geometry.X) / (double)geometry.Width, (zoomData.Y - geometry.Y) / (double)geometry.Height); + _originalPinchScale = sender.Scale; + _previousPinchRadius = zoomData.Radius; + (Recognizer as IPinchGestureController)?.SendPinchStarted(sender, _currentScalePoint); + } + + protected override void OnMoved(View sender, object data) + { + var zoomData = (GestureLayer.ZoomData)data; + if (_previousPinchRadius <= 0) + _previousPinchRadius = 1; + // functionality limitation: _currentScalePoint is not updated + (Recognizer as IPinchGestureController)?.SendPinch(sender, + 1 + _originalPinchScale * (zoomData.Radius - _previousPinchRadius) / _previousPinchRadius, + _currentScalePoint + ); + _previousPinchRadius = zoomData.Radius; + } + + protected override void OnCompleted(View sender, object data) + { + (Recognizer as IPinchGestureController)?.SendPinchEnded(sender); + } + + protected override void OnCanceled(View sender, object data) + { + (Recognizer as IPinchGestureController)?.SendPinchCanceled(sender); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellFlyoutItemAdaptor.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellFlyoutItemAdaptor.cs new file mode 100644 index 0000000000..e58088272d --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellFlyoutItemAdaptor.cs @@ -0,0 +1,185 @@ +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using ElmSharp; +using Microsoft.Maui.Controls.Internals; +using Tizen.UIExtensions.ElmSharp; +using DPExtensions = Tizen.UIExtensions.ElmSharp.DPExtensions; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellFlyoutItemAdaptor : ItemAdaptor + { + Dictionary _nativeFormsTable = new Dictionary(); + Dictionary _dataBindedViewTable = new Dictionary(); + + Shell _shell; + View? _headerCache; + IMauiContext _context; + + protected Shell Shell => _shell; + + public bool HasHeader { get; set; } + + protected virtual DataTemplate? DefaultItemTemplate => null; + + protected virtual DataTemplate? DefaultMenuItemTemplate => null; + + public ShellFlyoutItemAdaptor(Shell shell, IMauiContext context, IEnumerable items, bool hasHeader) : base(items) + { + _shell = shell; + _context = context; + HasHeader = hasHeader; + } + + public override EvasObject? CreateNativeView(EvasObject parent) + { + return CreateNativeView(0, parent); + } + + DataTemplate? GetDataTemplate(int index) + { + var item = this[index]; + if (item != null && item is BindableObject bo) + { + DataTemplate? dataTemplate = (Shell as IShellController)?.GetFlyoutItemDataTemplate(bo); + if (item is IMenuItemController) + { + if (DefaultMenuItemTemplate != null && Shell.MenuItemTemplate == dataTemplate) + dataTemplate = DefaultMenuItemTemplate; + } + else + { + if (DefaultItemTemplate != null && Shell.ItemTemplate == dataTemplate) + dataTemplate = DefaultItemTemplate; + } + + var template = dataTemplate.SelectDataTemplate(item, Shell); + + return template; + } + + return null; + } + + public override EvasObject? CreateNativeView(int index, EvasObject parent) + { + + var template = GetDataTemplate(index); + + if (template != null) + { + var content = (View)template.CreateContent(); + var native = content.ToPlatform(_context); + + _nativeFormsTable[native] = content; + return native; + } + + return null; + } + + public override EvasObject? GetFooterView(EvasObject parent) + { + return null; + } + + public override EvasObject? GetHeaderView(EvasObject parent) + { + if (!HasHeader) + return null; + + _headerCache = ((IShellController)Shell).FlyoutHeader; + + if (_headerCache != null) + { + var native = _headerCache.ToPlatform(_context); + return native; + } + + return null; + } + + public override Size MeasureFooter(int widthConstraint, int heightConstraint) + { + return new Size(0, 0); + } + + public override Size MeasureHeader(int widthConstraint, int heightConstraint) + { + return _headerCache?.Measure(DPExtensions.ConvertToScaledDP(widthConstraint), DPExtensions.ConvertToScaledDP(heightConstraint)).Request.ToEFLPixel() ?? new Size(0, 0); + } + + public override Size MeasureItem(int widthConstraint, int heightConstraint) + { + return MeasureItem(0, widthConstraint, heightConstraint); + } + + public override Size MeasureItem(int index, int widthConstraint, int heightConstraint) + { + var item = this[index]; + if (item != null && _dataBindedViewTable.TryGetValue(item, out View? createdView) && createdView != null) + { + return createdView.Measure(DPExtensions.ConvertToScaledDP(widthConstraint), DPExtensions.ConvertToScaledDP(heightConstraint), MeasureFlags.IncludeMargins).Request.ToEFLPixel(); + } + + return new Size(0, 0); + } + + public override void RemoveNativeView(EvasObject native) + { + native?.Unrealize(); + } + + public override void SetBinding(EvasObject native, int index) + { + if (_nativeFormsTable.TryGetValue(native, out View? view)) + { + ResetBindedView(view); + var item = this[index]; + if (item != null) + { + view.BindingContext = item; + _dataBindedViewTable[item] = view; + } + + view.MeasureInvalidated += OnItemMeasureInvalidated; + Shell.AddLogicalChild(view); + } + } + + public override void UnBinding(EvasObject native) + { + if (_nativeFormsTable.TryGetValue(native, out View? view)) + { + view.MeasureInvalidated -= OnItemMeasureInvalidated; + ResetBindedView(view); + } + } + + void ResetBindedView(View view) + { + if (view.BindingContext != null && _dataBindedViewTable.ContainsKey(view.BindingContext)) + { + _dataBindedViewTable[view.BindingContext] = null; + Shell.RemoveLogicalChild(view); + view.BindingContext = null; + } + } + + void OnItemMeasureInvalidated(object? sender, EventArgs e) + { + var data = (sender as View)?.BindingContext ?? null; + if (data != null) + { + int index = GetItemIndex(data); + if (index != -1) + { + CollectionView?.ItemMeasureInvalidated(index); + } + } + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellItemView.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellItemView.cs new file mode 100644 index 0000000000..6c689ee44b --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellItemView.cs @@ -0,0 +1,475 @@ +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Reflection; +using ElmSharp; +using Microsoft.Extensions.DependencyInjection; +using Tizen.UIExtensions.ElmSharp; +using EBox = ElmSharp.Box; +using EColor = ElmSharp.Color; +using EToolbarItem = ElmSharp.ToolbarItem; +using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; +using TImage = Tizen.UIExtensions.ElmSharp.Image; +using TThemeConstants = Tizen.UIExtensions.ElmSharp.ThemeConstants; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellItemView : IAppearanceObserver, IDisposable + { + Tabs? _tabs = null; + EBox _mainLayout; + EBox _contentHolder; + Panel? _moreItemsDrawer = null; + ShellMoreTabs? _moreItemsList = null; + EToolbarItem? _moreTabItem = null; + ShellSectionStack? _currentStack = null; + + Dictionary _sectionsTable = new Dictionary(); + Dictionary _tabItemsTable = new Dictionary(); + Dictionary _shellSectionStackCache = new Dictionary(); + List _tabsItems = new List(); + + bool _disposed = false; + Color _tabBarBackgroudColor = ShellView.DefaultBackgroundColor; + Color _tabBarTitleColor = ShellView.DefaultTitleColor; + + const string _dotsIcon = TThemeConstants.Shell.Resources.DotsIcon; + + public ShellItemView(ShellItem item, IMauiContext context) + { + ShellItem = item; + MauiContext = context; + + //Initialize(); + _mainLayout = new EBox(NativeParent); + _mainLayout.SetLayoutCallback(OnLayout); + _mainLayout.Show(); + _contentHolder = new EBox(NativeParent); + _contentHolder.Show(); + _mainLayout.PackEnd(_contentHolder); + + ShellItem.PropertyChanged += OnShellItemPropertyChanged; + if (ShellItem.Items is INotifyCollectionChanged notifyCollectionChanged) + { + notifyCollectionChanged.CollectionChanged += OnShellItemsCollectionChanged; + } + ShellController.AddAppearanceObserver(this, ShellItem); + + UpdateTabsItems(); + UpdateCurrentItem(ShellItem.CurrentItem); + } + + ~ShellItemView() + { + Dispose(false); + } + + protected IMauiContext MauiContext { get; private set; } + + protected EvasObject? NativeParent + { + get => MauiContext.GetNativeParent(); + } + + public EvasObject NativeView + { + get + { + return _mainLayout; + } + } + + public EColor TabBarBackgroundColor + { + get + { + return _tabBarBackgroudColor; + } + set + { + _tabBarBackgroudColor = value; + UpdateTabsBackgroudColor(_tabBarBackgroudColor); + } + } + + public EColor TabBarTitleColor + { + get => _tabBarTitleColor; + set + { + _tabBarTitleColor = value; + UpdateTabBarTitleColor(value); + } + } + + ShellItem ShellItem { get; } + IShellController ShellController => Shell.Current; + bool HasMoreItems => _moreItemsDrawer != null; + bool HasTabs => _tabs != null; + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + ShellController.RemoveAppearanceObserver(this); + if (ShellItem != null) + { + ShellItem.PropertyChanged -= OnShellItemPropertyChanged; + if (ShellItem.Items is INotifyCollectionChanged notifyCollectionChanged) + { + notifyCollectionChanged.CollectionChanged -= OnShellItemsCollectionChanged; + } + + foreach (var stack in _shellSectionStackCache.Values) + { + stack.Dispose(); + } + + DestroyMoreItems(); + DeinitializeTabs(); + + _sectionsTable.Clear(); + _tabItemsTable.Clear(); + _shellSectionStackCache.Clear(); + _tabsItems.Clear(); + } + NativeView.Unrealize(); + } + _disposed = true; + } + + protected virtual void UpdateTabsItems() + { + ResetTabs(); + if (ShellItem.Items.Count > 1) + { + InitializeTabs(); + foreach (ShellSection section in ShellItem.Items) + { + AddTabsItem(section); + } + } + else + { + DeinitializeTabs(); + } + } + + protected virtual ShellSectionStack CreateShellSectionStack(ShellSection section) + { + return new ShellSectionStack(section, MauiContext); + } + + bool _disableMoreItemOpen; + + void UpdateCurrentItem(ShellSection section) + { + UpdateCurrentShellSection(section); + + if (_tabs != null) + { + if (_tabItemsTable.ContainsKey(section)) + { + _tabItemsTable[section].IsSelected = true; + } + else if (_moreItemsDrawer != null) + { + _disableMoreItemOpen = true; + + if (_moreTabItem != null) + _moreTabItem.IsSelected = true; + + _disableMoreItemOpen = false; + } + + if (_moreItemsDrawer != null) + { + _moreItemsDrawer.IsOpen = false; + } + } + } + + void UpdateCurrentItemFromUI(ShellSection? section) + { + if (section != null && ShellItem.CurrentItem != section) + { + ShellItem.SetValueFromRenderer(ShellItem.CurrentItemProperty, section); + } + if (_moreItemsDrawer != null) + { + _moreItemsDrawer.IsOpen = false; + } + } + + void InitializeTabs() + { + if (_tabs != null) + return; + + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + _tabs = new Tabs(NativeParent); + _tabs.Show(); + _tabs.BackgroundColor = _tabBarBackgroudColor; + _tabs.Scrollable = TabsType.Fixed; + _tabs.Selected += OnTabsSelected; + _mainLayout.PackEnd(_tabs); + } + + void DeinitializeTabs() + { + if (_tabs == null) + return; + + _mainLayout.UnPack(_tabs); + _tabs.Selected -= OnTabsSelected; + _tabs.Unrealize(); + _tabs = null; + } + + void CreateMoreItems() + { + if (_moreItemsDrawer != null) + return; + + _moreItemsList = new ShellMoreTabs(NativeParent); + _moreItemsList.Show(); + _moreItemsList.ItemSelected += OnMoreItemSelected; + + _moreItemsDrawer = new Panel(NativeParent); + _moreItemsDrawer.Show(); + + _moreItemsDrawer.SetScrollable(true); + _moreItemsDrawer.SetScrollableArea(1.0); + _moreItemsDrawer.Direction = PanelDirection.Bottom; + _moreItemsDrawer.IsOpen = false; + _moreItemsDrawer.SetContent(_moreItemsList, true); + _mainLayout.PackEnd(_moreItemsDrawer); + } + + void DestroyMoreItems() + { + if (_moreItemsDrawer == null) + return; + + _mainLayout.UnPack(_moreItemsDrawer); + + _moreItemsList?.Unrealize(); + _moreItemsDrawer?.Unrealize(); + + _moreItemsList = null; + _moreItemsDrawer = null; + } + + void OnMoreItemSelected(object? sender, GenListItemEventArgs e) + { + ShellSection? section = e.Item.Data as ShellSection; + UpdateCurrentItemFromUI(section); + } + + void OnShellItemPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(ShellItem.CurrentItem)) + { + UpdateCurrentItem(ShellItem.CurrentItem); + } + } + + void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance) + { + var tabBarBackgroudColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarBackgroundColor; + var tabBarTitleColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarTitleColor; + + TabBarBackgroundColor = tabBarBackgroudColor.IsDefault() ? ShellView.DefaultBackgroundColor : (tabBarBackgroudColor?.ToPlatformEFL()).GetValueOrDefault(); + TabBarTitleColor = tabBarTitleColor.IsDefault() ? ShellView.DefaultTitleColor : (tabBarTitleColor?.ToPlatformEFL()).GetValueOrDefault(); + } + + void UpdateTabsBackgroudColor(EColor color) + { + foreach (EToolbarItem item in _tabsItems) + { + item.SetBackgroundColor(color); + } + } + + void UpdateTabBarTitleColor(EColor color) + { + foreach (EToolbarItem item in _tabsItems) + { + item.SetTextColor(color); + } + } + + void ResetTabs() + { + if (!HasTabs) + return; + + foreach (var item in _tabsItems) + { + item.Delete(); + } + _tabsItems.Clear(); + DestroyMoreItems(); + _moreTabItem = null; + } + + void OnShellItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + UpdateTabsItems(); + } + + void AddTabsItem(ShellSection section) + { + if (_tabsItems.Count < 5) + { + var item = AppendTabsItem(section.Title, section.Icon); + if (item != null) + { + _sectionsTable.Add(item, section); + _tabItemsTable.Add(section, item); + _tabsItems.Add(item); + } + } + else if (_moreItemsDrawer == null) + { + CreateMoreItems(); + + var last = _tabsItems.Last(); + var lastSection = _sectionsTable[last]; + + _tabsItems.Remove(last); + _sectionsTable.Remove(last); + _tabItemsTable.Remove(lastSection); + last.Delete(); + + //The source of icon resources is https://materialdesignicons.com/ + var assembly = typeof(ShellItemView).GetTypeInfo().Assembly; + var assemblyName = assembly.GetName().Name; + _moreTabItem = AppendTabsItem("More", ImageSource.FromResource(assemblyName + "." + _dotsIcon, assembly)); + if (_moreTabItem != null) + _tabsItems.Add(_moreTabItem); + + _moreItemsList?.AddItem(lastSection); + _moreItemsList?.AddItem(section); + } + else + { + _moreItemsList?.AddItem(section); + } + } + + void UpdateCurrentShellSection(ShellSection section) + { + if (_currentStack != null) + { + _currentStack.Hide(); + _contentHolder.UnPack(_currentStack); + } + _currentStack = null; + + if (section == null) + { + return; + } + + ShellSectionStack native; + if (_shellSectionStackCache.ContainsKey(section)) + { + native = _shellSectionStackCache[section]; + } + else + { + native = CreateShellSectionStack(section); + _shellSectionStackCache[section] = native; + } + _currentStack = native; + _currentStack.Show(); + _contentHolder.PackEnd(_currentStack); + } + + void OnTabsSelected(object? sender, EToolbarItemEventArgs e) + { + if (_tabs?.SelectedItem == null) + return; + + if (_moreItemsDrawer != null && e.Item == _moreTabItem) + { + if (!_disableMoreItemOpen) + { + _moreItemsDrawer.IsOpen = !_moreItemsDrawer.IsOpen; + } + } + else + { + UpdateCurrentItemFromUI(_sectionsTable[_tabs.SelectedItem]); + } + } + + void OnLayout() + { + if (NativeView.Geometry.Height == 0 || NativeView.Geometry.Width == 0) + return; + + int tabsHeight = 0; + var bound = _mainLayout.Geometry; + if (_tabs != null) + { + tabsHeight = _tabs.MinimumHeight; + var tabsBound = bound; + tabsBound.Y += (bound.Height - tabsHeight); + tabsBound.Height = tabsHeight; + _tabs.Geometry = tabsBound; + if (_moreItemsDrawer != null && _moreItemsList != null) + { + int moreItemListHeight = _moreItemsList.HeightRequest; + moreItemListHeight = Math.Min(moreItemListHeight, bound.Height - tabsHeight); + var moreItemDrawerBound = bound; + moreItemDrawerBound.Y += (bound.Height - tabsHeight - moreItemListHeight); + moreItemDrawerBound.Height = moreItemListHeight; + _moreItemsDrawer.Geometry = moreItemDrawerBound; + } + } + bound.Height -= tabsHeight; + _contentHolder.Geometry = bound; + } + + EToolbarItem? AppendTabsItem(string text, ImageSource iconSource) + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + var item = _tabs?.Append(text); + if (item != null) + { + if (iconSource != null) + { + TImage image = new TImage(NativeParent); + var provider = MauiContext.Services.GetRequiredService(); + var service = provider.GetRequiredImageSourceService(iconSource); + + _ = service.GetImageAsync(iconSource, image); + + item.SetIconPart(image); + } + + item.SetBackgroundColor(_tabBarBackgroudColor); + item.SetUnderlineColor(EColor.Transparent); + item.SetTextColor(_tabBarTitleColor); + return item; + } + return null; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellMoreTabs.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellMoreTabs.cs new file mode 100644 index 0000000000..408cf90399 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellMoreTabs.cs @@ -0,0 +1,97 @@ +using ElmSharp; +using EBox = ElmSharp.Box; +using EImage = ElmSharp.Image; +using TImage = Tizen.UIExtensions.ElmSharp.Image; +using TLabel = Tizen.UIExtensions.ElmSharp.Label; +using TThemeConstants = Tizen.UIExtensions.ElmSharp.ThemeConstants; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellMoreTabs : GenList + { + GenItemClass _defaultClass = null; + + public ShellMoreTabs(EvasObject parent) : base(parent) + { + SetAlignment(-1, -1); + SetWeight(1, 1); + NativeParent = parent; + + Homogeneous = true; + SelectionMode = GenItemSelectionMode.Always; + BackgroundColor = ShellView.DefaultBackgroundColor; + _defaultClass = new GenItemClass(TThemeConstants.GenItemClass.Styles.Full) + { + GetContentHandler = GetContent, + }; + } + + protected EvasObject NativeParent { get; private set; } + + public void AddItem(ShellSection section) + { + Append(_defaultClass, section); + } + + public int HeightRequest + { + get + { + var cellHeight = this.GetDefaultIconSize() * 2 + this.GetDefaultIconSize(); + return DPExtensions.ConvertToScaledPixel(cellHeight) * Count; + } + } + + EvasObject GetContent(object data, string part) + { + ShellSection section = data as ShellSection; + + var box = new EBox(NativeParent); + box.Show(); + + EImage icon = null; + if (section.Icon != null) + { + icon = new TImage(NativeParent); + icon.Show(); + box.PackEnd(icon); + } + + var title = new TLabel(NativeParent) + { + Text = section.Title, + FontSize = DPExtensions.ConvertToEflFontPoint(14), + HorizontalTextAlignment = Tizen.UIExtensions.Common.TextAlignment.Start, + VerticalTextAlignment = Tizen.UIExtensions.Common.TextAlignment.Center, + }; + title.Show(); + box.PackEnd(title); + int iconPadding = DPExtensions.ConvertToScaledPixel(this.GetDefaultIconPadding()); + int iconSize = DPExtensions.ConvertToScaledPixel(this.GetDefaultIconSize()); + int cellHeight = iconPadding * 2 + iconSize; + box.SetLayoutCallback(() => + { + var bound = box.Geometry; + int leftMargin = iconPadding; + + if (icon != null) + { + var iconBound = bound; + iconBound.X += iconPadding; + iconBound.Y += iconPadding; + iconBound.Width = iconSize; + iconBound.Height = iconSize; + icon.Geometry = iconBound; + leftMargin = (2 * iconPadding + iconSize); + } + + bound.X += leftMargin; + bound.Width -= leftMargin; + title.Geometry = bound; + }); + + box.MinimumHeight = cellHeight; + return box; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellNavBar.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellNavBar.cs new file mode 100644 index 0000000000..a06b5b445f --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellNavBar.cs @@ -0,0 +1,400 @@ +#nullable enable + +using System; +using System.Reflection; +using ElmSharp; +using Microsoft.Maui.Devices; +using Microsoft.Extensions.DependencyInjection; +using Tizen.UIExtensions.ElmSharp; +using EBox = ElmSharp.Box; +using EColor = ElmSharp.Color; +using TButton = Tizen.UIExtensions.ElmSharp.Button; +using TImage = Tizen.UIExtensions.ElmSharp.Image; +using TLabel = Tizen.UIExtensions.ElmSharp.Label; +using TThemeConstants = Tizen.UIExtensions.ElmSharp.ThemeConstants; +using TDPExtensions = Tizen.UIExtensions.ElmSharp.DPExtensions; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellNavBar : EBox, IFlyoutBehaviorObserver, IDisposable + { + TImage? _menuIcon; + TButton _menuButton; + TLabel _title; + ShellSearchView? _searchView = null; + EvasObject? _nativeTitleView = null; + + SearchHandler? _searchHandler = null; + View? _titleView = null; + Page? _page = null; + + FlyoutBehavior _flyoutBehavior = FlyoutBehavior.Flyout; + + EColor _backgroudColor = ShellView.DefaultBackgroundColor; + EColor _foregroudColor = ShellView.DefaultForegroundColor; + EColor _titleColor = ShellView.DefaultTitleColor; + + // The source of icon resources is https://materialdesignicons.com/ + const string _menuIconRes = TThemeConstants.Shell.Resources.MenuIcon; + const string _backIconRes = TThemeConstants.Shell.Resources.BackIcon; + + bool _hasBackButton = false; + private bool disposedValue; + bool _isTV = DeviceInfo.Idiom == DeviceIdiom.TV; + + public ShellNavBar(IMauiContext context) : base(context?.GetNativeParent()) + { + MauiContext = context; + + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + SetLayoutCallback(OnLayout); + + _menuButton = new TButton(NativeParent); + _menuButton.Clicked += OnMenuClicked; + + _menuIcon = new TImage(NativeParent); + UpdateMenuIcon(); + + _title = new TLabel(NativeParent) + { + FontSize = this.GetDefaultTitleFontSize(), + VerticalTextAlignment = (global::Tizen.UIExtensions.Common.TextAlignment)TextAlignment.Center, + TextColor = _titleColor.ToCommon(), + FontAttributes = Tizen.UIExtensions.Common.FontAttributes.Bold, + }; + _title.Show(); + + BackgroundColor = _backgroudColor; + _menuButton.BackgroundColor = _backgroudColor; + PackEnd(_menuButton); + PackEnd(_title); + } + + ~ShellNavBar() + { + Dispose(false); + } + + protected IMauiContext? MauiContext { get; private set; } + + protected EvasObject? NativeParent + { + get => MauiContext?.GetNativeParent(); + } + + public IShellController ShellController => Shell.Current; + + public bool HasBackButton + { + get + { + return _hasBackButton; + } + set + { + _hasBackButton = value; + UpdateMenuIcon(); + } + } + + public FlyoutBehavior FlyoutBehavior + { + get => _flyoutBehavior; + set + { + if (_flyoutBehavior != value) + { + _flyoutBehavior = value; + UpdateMenuIcon(); + } + } + } + + public SearchHandler? SearchHandler + { + get + { + return _searchHandler; + } + set + { + _searchHandler = value; + UpdateSearchHandler(_searchHandler); + UpdateChildren(); + } + } + + public View? TitleView + { + get + { + return _titleView; + } + set + { + _titleView = value; + UpdateTitleView(_titleView); + UpdateChildren(); + } + } + + public string Title + { + get + { + return _title.Text; + } + set + { + _title.Text = value; + } + } + + public override EColor BackgroundColor + { + get + { + return _backgroudColor; + } + set + { + _backgroudColor = value; + _menuButton.BackgroundColor = _backgroudColor; + base.BackgroundColor = _backgroudColor; + } + } + + public EColor ForegroundColor + { + get + { + return _foregroudColor; + } + set + { + _foregroudColor = value; + } + } + + public EColor TitleColor + { + get + { + return _titleColor; + } + set + { + _titleColor = value; + _title.TextColor = value.ToCommon(); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void SetPage(Page page) + { + _page = page; + Title = page.Title; + SearchHandler = Shell.GetSearchHandler(page); + TitleView = Shell.GetTitleView(page); + UpdateMenuIcon(); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + Unrealize(); + } + disposedValue = true; + } + } + + async void UpdateMenuIcon() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + ImageSource? source = null; + if (HasBackButton) + { + if (_isTV) + { + _menuButton.Style = TThemeConstants.Button.Styles.Default; + _menuButton.Text = TThemeConstants.Shell.Resources.TV.BackIconCode; + _menuIcon = null; + } + else + { + var assembly = typeof(ShellNavBar).GetTypeInfo().Assembly; + var assemblyName = assembly.GetName().Name; + source = ImageSource.FromResource(assemblyName + "." + _backIconRes, assembly); + } + } + else if (_flyoutBehavior != FlyoutBehavior.Flyout) + { + _menuButton.Hide(); + } + else if (ShellController.FlyoutIcon != null) + { + if (_isTV) + { + _menuButton.Style = TThemeConstants.Button.Styles.Circle; + _menuIcon = new TImage(NativeParent); + } + source = Shell.Current.FlyoutIcon; + } + else + { + if (_isTV) + { + _menuButton.Style = TThemeConstants.Button.Styles.Default; + _menuButton.Text = TThemeConstants.Shell.Resources.TV.MenuIconCode; + _menuIcon = null; + } + else + { + var assembly = typeof(ShellNavBar).GetTypeInfo().Assembly; + var assemblyName = assembly.GetName().Name; + source = ImageSource.FromResource(assemblyName + "." + _menuIconRes, assembly); + + } + } + + if (source != null && _menuIcon != null) + { + _menuIcon.Show(); + var provider = MauiContext?.Services.GetRequiredService(); + var service = provider?.GetRequiredImageSourceService(source); + if (service != null) + { + await service.GetImageAsync(source, _menuIcon); + } + } + _menuButton.SetIconPart(_menuIcon); + _menuButton.Show(); + } + + void OnMenuClicked(object? sender, EventArgs e) + { + var backButtonHandler = Shell.GetBackButtonBehavior(_page); + if (backButtonHandler?.Command != null) + { + backButtonHandler.Command.Execute(backButtonHandler.CommandParameter); + } + else if (_hasBackButton) + { + Shell.Current.CurrentItem.Navigation.PopAsync(); + } + else if (_flyoutBehavior == FlyoutBehavior.Flyout) + { + Shell.Current.FlyoutIsPresented = !Shell.Current.FlyoutIsPresented; + } + } + + void UpdateTitleView(View? titleView) + { + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + _nativeTitleView?.Unrealize(); + _nativeTitleView = null; + + if (titleView != null) + { + var _nativeTitleView = titleView.ToPlatform(MauiContext); + _nativeTitleView.Show(); + PackEnd(_nativeTitleView); + } + } + + void UpdateSearchHandler(SearchHandler? handler) + { + if (_searchView != null) + { + UnPack(_searchView.PlatformView); + _searchView.Dispose(); + _searchView = null; + } + + if (handler != null) + { + _searchView = new ShellSearchView(handler, MauiContext); + _searchView.PlatformView?.Show(); + PackEnd(_searchView.PlatformView); + } + } + + void UpdateChildren() + { + if (_searchHandler != null) + { + _searchView?.PlatformView?.Show(); + _title?.Hide(); + _nativeTitleView?.Hide(); + } + else if (_titleView != null) + { + _nativeTitleView?.Show(); + _title?.Hide(); + _searchView?.PlatformView?.Hide(); + } + else + { + _title.Show(); + _nativeTitleView?.Hide(); + _searchView?.PlatformView?.Hide(); + } + } + + void OnLayout() + { + if (Geometry.Width == 0 || Geometry.Height == 0) + return; + + int menuSize = TDPExtensions.ConvertToScaledPixel(this.GetDefaultMenuSize()); + int menuMargin = TDPExtensions.ConvertToScaledPixel(this.GetDefaultMargin()); + int titleHMargin = TDPExtensions.ConvertToScaledPixel(this.GetDefaultMargin()); + int titleVMargin = TDPExtensions.ConvertToScaledPixel(this.GetDefaultTitleVMargin()); + + var bound = Geometry; + + var menuBound = bound; + menuBound.X += menuMargin; + menuBound.Y += (menuBound.Height - menuSize) / 2; + menuBound.Width = menuSize; + menuBound.Height = menuSize; + + _menuButton.Geometry = menuBound; + + var contentBound = Geometry; + contentBound.X = menuBound.Right + titleHMargin; + contentBound.Y += titleVMargin; + contentBound.Width -= (menuBound.Width + menuMargin + titleHMargin * 2); + contentBound.Height -= titleVMargin * 2; + + if (_searchView != null && _searchView.PlatformView != null) + { + _searchView.PlatformView.Geometry = contentBound; + } + else if (_titleView != null && _nativeTitleView != null) + { + _nativeTitleView.Geometry = contentBound; + } + else + { + _title.Geometry = contentBound; + } + } + + void IFlyoutBehaviorObserver.OnFlyoutBehaviorChanged(FlyoutBehavior behavior) + { + FlyoutBehavior = behavior; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchResultList.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchResultList.cs new file mode 100644 index 0000000000..97ca3331ba --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchResultList.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using ElmSharp; +using EColor = ElmSharp.Color; +using TThemeConstants = Tizen.UIExtensions.ElmSharp.ThemeConstants; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellSearchResultList : GenList + { + GenItemClass _defaultClass = null; + IReadOnlyList _itemsSource; + + public ShellSearchResultList(IMauiContext context) : base(context?.GetNativeParent()) + { + MauiContext = context; + + SetAlignment(-1, -1); + SetWeight(1, 1); + AllowFocus(true); + + Homogeneous = true; + SelectionMode = GenItemSelectionMode.Always; + BackgroundColor = EColor.White; + + _defaultClass = new GenItemClass(TThemeConstants.GenItemClass.Styles.Full) + { + GetContentHandler = GetContent, + }; + } + + public int Height { get; private set; } + + public IReadOnlyList ItemsSource + { + get => _itemsSource; + set + { + Clear(); + Height = 0; + + _itemsSource = value; + foreach (var item in _itemsSource) + { + Append(item); + } + } + } + + protected IMauiContext MauiContext { get; private set; } + + protected EvasObject NativeParent + { + get => MauiContext.GetNativeParent(); + } + + public void UpdateLayout() + { + if (FirstItem != null && Height == 0) + { + var view = FirstItem.Data as View; + var native = view.ToPlatform(MauiContext); + var measured = view.Measure(DPExtensions.ConvertToScaledDP(Geometry.Width), double.PositiveInfinity); + Height = DPExtensions.ConvertToScaledPixel(measured.Request.Height); + } + + var bound = Geometry; + bound.Height = Math.Min(Height * _itemsSource.Count, bound.Width); + Geometry = bound; + + UpdateRealizedItems(); + } + + public DataTemplate ItemTemplate { get; set; } + + EvasObject GetContent(object data, string part) + { + var view = data as View; + var native = view.ToPlatform(MauiContext); + + if (Height == 0) + { + var measured = view.Measure(DPExtensions.ConvertToScaledDP(Geometry.Width), double.PositiveInfinity); + Height = DPExtensions.ConvertToScaledPixel(measured.Request.Height); + } + + native.MinimumHeight = Height; + return native; + } + + void Append(object data) + { + var view = ItemTemplate.CreateContent() as View; + view.Parent = Shell.Current; + view.BindingContext = data; + Append(_defaultClass, view); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchView.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchView.cs new file mode 100644 index 0000000000..bd7024c064 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSearchView.cs @@ -0,0 +1,372 @@ +#nullable enable + +using System; +using System.ComponentModel; +using ElmSharp; +using EColor = ElmSharp.Color; +using TSearchBar = Tizen.UIExtensions.ElmSharp.SearchBar; +using TTextChangedEventArgs = Tizen.UIExtensions.Common.TextChangedEventArgs; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellSearchView : IDisposable + { + bool disposedValue; + ShellSearchResultList? _searchResultList; + + public ShellSearchView(SearchHandler searchHandler, IMauiContext? context) + { + Element = searchHandler; + MauiContext = context; + + Element.FocusChangeRequested += OnFocusChangedRequested; + Element.PropertyChanged += OnElementPropertyChanged; + (Element as ISearchHandlerController).ListProxyChanged += OnSearchResultListChanged; + + if (NativeParent != null) + { + Control = new TSearchBar(NativeParent) + { + IsSingleLine = true, + }; + Control.Show(); + Control.SetInputPanelReturnKeyType(InputPanelReturnKeyType.Search); + Control.TextChanged += OnTextChanged; + Control.Activated += OnActivated; + Control.Focused += OnFocused; + Control.Unfocused += OnFocused; + } + + UpdateKeyboard(); + UpdatePlaceholder(); + UpdatePlaceholderColor(); + UpdateHorizontalTextAlignment(); + UpdateTextColor(); + UpdateFontAttributes(); + UpdateFontFamily(); + UpdateFontSize(); + UpdateBackgroundColor(); + UpdateQuery(); + UpdateIsSearchEnabled(); + UpdateSearchResult(); + } + + public SearchHandler Element { get; } + + public EvasObject? PlatformView => Control; + + protected IMauiContext? MauiContext { get; private set; } + + protected EvasObject? NativeParent + { + get => MauiContext?.GetNativeParent(); + } + + ISearchHandlerController SearchHandlerController => Element; + + TSearchBar? Control { get; } + + ~ShellSearchView() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + Element.FocusChangeRequested -= OnFocusChangedRequested; + Element.PropertyChanged -= OnElementPropertyChanged; + (Element as ISearchHandlerController).ListProxyChanged -= OnSearchResultListChanged; + + if (Control != null) + { + Control.TextChanged -= OnTextChanged; + Control.Activated -= OnActivated; + Control.Focused -= OnFocused; + Control.Unfocused -= OnFocused; + Control.Unrealize(); + } + } + disposedValue = true; + } + } + + void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(Element.Keyboard)) + { + UpdateKeyboard(); + } + else if (e.PropertyName == nameof(Element.Placeholder)) + { + UpdatePlaceholder(); + } + else if (e.PropertyName == nameof(Element.PlaceholderColor)) + { + UpdatePlaceholderColor(); + } + else if (e.PropertyName == nameof(Element.HorizontalTextAlignment)) + { + UpdateHorizontalTextAlignment(); + } + else if (e.PropertyName == nameof(Element.TextColor)) + { + UpdateTextColor(); + } + else if (e.PropertyName == nameof(Element.FontAttributes)) + { + UpdateFontAttributes(); + } + else if (e.PropertyName == nameof(Element.FontFamily)) + { + UpdateFontFamily(); + } + else if (e.PropertyName == nameof(Element.FontSize)) + { + UpdateFontSize(); + } + else if (e.PropertyName == nameof(Element.BackgroundColor)) + { + UpdateBackgroundColor(); + } + else if (e.PropertyName == nameof(Element.Query)) + { + UpdateQuery(); + } + else if (e.PropertyName == nameof(Element.IsSearchEnabled)) + { + UpdateIsSearchEnabled(); + } + else if (e.PropertyName == nameof(Element.ShowsResults)) + { + UpdateSearchResult(); + } + } + + void OnSearchResultListChanged(object? sender, ListProxyChangedEventArgs e) + { + UpdateSearchResult(); + } + + void InitializeSearchResultList() + { + if (_searchResultList != null) + { + return; + } + _searchResultList = new ShellSearchResultList(MauiContext); + _searchResultList.Show(); + _searchResultList.ItemSelected += OnResultItemSelected; + } + + void OnResultItemSelected(object? sender, GenListItemEventArgs e) + { + var data = (e.Item.Data as View)?.BindingContext; + + if (data != null) + { + SearchHandlerController.ItemSelected(data); + Application.Current?.Dispatcher.Dispatch(() => + { + DeinitializeSearchResultList(); + }); + } + } + + void DeinitializeSearchResultList() + { + if (_searchResultList == null) + { + return; + } + + _searchResultList.ItemSelected -= OnResultItemSelected; + _searchResultList.Unrealize(); + _searchResultList = null; + } + + void UpdateSearchResult() + { + if (SearchHandlerController == null) + return; + + if (!Element.ShowsResults) + { + DeinitializeSearchResultList(); + return; + } + + if (Control != null && + Control.IsFocused && SearchHandlerController.ListProxy != null && + SearchHandlerController.ListProxy.Count > 0 && + Element.ItemTemplate != null) + { + InitializeSearchResultList(); + if (_searchResultList != null) + { + _searchResultList.ItemTemplate = Element.ItemTemplate; + _searchResultList.ItemsSource = SearchHandlerController.ListProxy; + UpdateSearchResultLayout(); + } + } + else + { + DeinitializeSearchResultList(); + } + } + + void UpdateIsSearchEnabled() + { + if (Control == null) + return; + + Control.IsEnabled = Element.IsSearchEnabled; + } + + void UpdateQuery() + { + if (Control == null) + return; + + Control.Text = (Element.Query != null) ? Element.Query : ""; + } + + void UpdateFontAttributes() + { + if (Control == null) + return; + + Control.FontAttributes = Element.FontAttributes.ToPlatform(); + } + + void UpdateFontFamily() + { + if (Control == null) + return; + + Control.FontFamily = Element.FontFamily; + } + + void UpdateFontSize() + { + if (Control == null) + return; + + Control.FontSize = Element.FontSize; + } + + void UpdateBackgroundColor() + { + if (Control == null) + return; + + var color = Element.BackgroundColor.ToPlatformEFL(); + Control.BackgroundColor = color == EColor.Default ? EColor.White : color; + } + + void UpdateTextColor() + { + if (Control == null) + return; + + Control.TextColor = Element.TextColor.ToPlatform(); + } + + void UpdateHorizontalTextAlignment() + { + if (Control == null) + return; + + Control.HorizontalTextAlignment = Element.HorizontalTextAlignment.ToPlatform(); + } + + void OnFocusChangedRequested(object? sender, VisualElement.FocusRequestArgs e) + { + if (Control == null) + return; + + Control.SetFocus(e.Focus); + e.Result = true; + } + + void UpdateKeyboard() + { + if (Control == null) + return; + + Control.Keyboard = Element.Keyboard.ToPlatform(); + } + + void UpdatePlaceholder() + { + if (Control == null) + return; + + Control.Placeholder = Element.Placeholder; + } + void UpdatePlaceholderColor() + { + if (Control == null) + return; + + Control.PlaceholderColor = Element.PlaceholderColor.ToPlatform(); + } + + void OnFocused(object? sender, EventArgs e) + { + if (Control == null) + return; + + Element.SetIsFocused(Control.IsFocused); + if (Control.IsFocused) + { + UpdateSearchResult(); + } + else + { + if (_searchResultList != null) + { + _searchResultList.Hide(); + } + Application.Current?.Dispatcher.DispatchDelayed(TimeSpan.FromMilliseconds(100), () => + { + DeinitializeSearchResultList(); + }); + } + } + + void OnActivated(object? sender, EventArgs e) + { + if (Control == null) + return; + + Control.HideInputPanel(); + (Element as ISearchHandlerController).QueryConfirmed(); + } + + void OnTextChanged(object? sender, TTextChangedEventArgs e) + { + Element.SetValueCore(SearchHandler.QueryProperty, (sender as TSearchBar)?.Text); + } + + void UpdateSearchResultLayout() + { + if (_searchResultList != null && PlatformView != null) + { + var bound = PlatformView.Geometry; + bound.Y += PlatformView.Geometry.Height; + _searchResultList.Geometry = bound; + _searchResultList.UpdateLayout(); + } + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionHandler.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionHandler.cs new file mode 100644 index 0000000000..791dc80af9 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionHandler.cs @@ -0,0 +1,389 @@ +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; +using EBox = ElmSharp.Box; +using EColor = ElmSharp.Color; +using EToolbarItem = ElmSharp.ToolbarItem; +using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; + +namespace Microsoft.Maui.Controls.Platform +{ + public interface IShellSectionHandler : IDisposable + { + EvasObject PlatformView { get; } + } + + public class ShellSectionHandler : IAppearanceObserver, IShellSectionHandler + { + EBox _mainLayout; + EBox _contentArea; + Tabs? _tabs = null; + EvasObject? _currentContent = null; + Page? _displayedPage; + + Dictionary _contentCache = new Dictionary(); + Dictionary _contentToTabsItem = new Dictionary(); + Dictionary _itemToContent = new Dictionary(); + List _tabsItems = new List(); + + EColor _backgroundColor = ShellView.DefaultBackgroundColor; + EColor _foregroundColor = ShellView.DefaultForegroundColor; + + bool _disposed = false; + + public ShellSectionHandler(ShellSection section, IMauiContext context) + { + ShellSection = section; + MauiContext = context; + ShellSection.PropertyChanged += OnSectionPropertyChanged; + if (ShellSection.Items is INotifyCollectionChanged collection) + { + collection.CollectionChanged += OnShellSectionCollectionChanged; + } + + _mainLayout = new EBox(NativeParent); + _mainLayout.SetLayoutCallback(OnLayout); + + _contentArea = new EBox(NativeParent); + _contentArea.Show(); + _mainLayout.PackEnd(_contentArea); + + UpdateTabsItem(); + UpdateCurrentItem(ShellSection.CurrentItem); + + ((IShellController)Shell.Current).AddAppearanceObserver(this, ShellSection); + (ShellSection as IShellSectionController).AddDisplayedPageObserver(this, UpdateDisplayedPage); + } + + bool HasTabs => _tabs != null; + + bool _tabBarIsVisible = true; + + protected IMauiContext MauiContext { get; private set; } + + protected EvasObject? NativeParent + { + get => MauiContext.GetNativeParent(); + } + + protected virtual bool TabBarIsVisible + { + get => _tabBarIsVisible; + set + { + if (_tabBarIsVisible != value) + { + _tabBarIsVisible = value; + _mainLayout.MarkChanged(); + + if (value) + { + _tabs?.Show(); + } + else + { + _tabs?.Hide(); + } + } + } + } + + public ShellSection ShellSection { get; } + + public EvasObject PlatformView + { + get + { + return _mainLayout; + } + } + + public EColor ToolbarBackgroundColor + { + get + { + return _backgroundColor; + } + set + { + _backgroundColor = value; + UpdateToolbarBackgroudColor(_backgroundColor); + } + } + + public EColor ToolbarForegroundColor + { + get + { + return _foregroundColor; + } + set + { + _foregroundColor = value; + UpdateToolbarForegroundColor(_foregroundColor); + } + } + + ~ShellSectionHandler() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance) + { + var backgroundColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarBackgroundColor; + var foregroundColor = appearance?.ForegroundColor; + + ToolbarBackgroundColor = backgroundColor.IsDefault() ? ShellView.DefaultBackgroundColor : (backgroundColor?.ToPlatformEFL()).GetValueOrDefault(); + ToolbarForegroundColor = foregroundColor.IsDefault() ? ShellView.DefaultForegroundColor : (foregroundColor?.ToPlatformEFL()).GetValueOrDefault(); + } + + void UpdateDisplayedPage(Page page) + { + if (_displayedPage != null) + { + _displayedPage.PropertyChanged -= OnDisplayedPagePropertyChanged; + } + + if (page == null) + { + TabBarIsVisible = true; + return; + } + _displayedPage = page; + _displayedPage.PropertyChanged += OnDisplayedPagePropertyChanged; + TabBarIsVisible = Shell.GetTabBarIsVisible(page); + } + + void OnDisplayedPagePropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == Shell.TabBarIsVisibleProperty.PropertyName) + { + TabBarIsVisible = Shell.GetTabBarIsVisible(_displayedPage); + } + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + ((IShellController)Shell.Current).RemoveAppearanceObserver(this); + if (ShellSection != null) + { + (ShellSection as IShellSectionController).RemoveDisplayedPageObserver(this); + ShellSection.PropertyChanged -= OnSectionPropertyChanged; + DeinitializeTabs(); + + foreach (var native in _contentCache.Values) + { + native.Unrealize(); + } + _contentCache.Clear(); + _contentToTabsItem.Clear(); + _itemToContent.Clear(); + } + PlatformView.Unrealize(); + } + _disposed = true; + } + + void InitializeTabs() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + if (_tabs != null) + { + return; + } + _tabs = new Tabs(NativeParent); + _tabs.Show(); + _tabs.BackgroundColor = _backgroundColor; + _tabs.Scrollable = TabsType.Fixed; + _tabs.Selected += OnTabsSelected; + _mainLayout.PackEnd(_tabs); + } + + void ClearTabsItem() + { + if (!HasTabs) + return; + + foreach (var item in _tabsItems) + { + item.Delete(); + } + _tabsItems.Clear(); + _contentToTabsItem.Clear(); + _itemToContent.Clear(); + } + + void DeinitializeTabs() + { + if (_tabs == null) + { + return; + } + ClearTabsItem(); + _tabs.Unrealize(); + _tabs = null; + } + + void OnSectionPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "CurrentItem") + { + UpdateCurrentItem(ShellSection.CurrentItem); + } + } + + void UpdateCurrentItem(ShellContent content) + { + UpdateCurrentShellContent(content); + if (_contentToTabsItem.ContainsKey(content)) + { + _contentToTabsItem[content].IsSelected = true; + } + } + + void UpdateToolbarBackgroudColor(EColor color) + { + foreach (EToolbarItem item in _tabsItems) + { + item.SetBackgroundColor(color); + } + } + + void UpdateToolbarForegroundColor(EColor color) + { + foreach (EToolbarItem item in _tabsItems) + { + item.SetUnderlineColor(color); + } + } + + void UpdateTabsItem() + { + if (ShellSection.Items.Count <= 1) + { + DeinitializeTabs(); + return; + } + + InitializeTabs(); + ClearTabsItem(); + foreach (ShellContent content in ShellSection.Items) + { + InsertTabsItem(content); + } + + if(_tabs !=null) + _tabs.Scrollable = ShellSection.Items.Count > 3 ? TabsType.Scrollable : TabsType.Fixed; + } + + EToolbarItem? InsertTabsItem(ShellContent content) + { + EToolbarItem? item = _tabs?.Append(content.Title, null); + item?.SetBackgroundColor(_backgroundColor); + item?.SetUnderlineColor(_foregroundColor); + + if (item != null) + { + _tabsItems.Add(item); + _itemToContent[item] = content; + _contentToTabsItem[content] = item; + } + + return item; + } + + void OnShellSectionCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + UpdateTabsItem(); + } + + void OnTabsSelected(object? sender, EToolbarItemEventArgs e) + { + if (_tabs?.SelectedItem == null) + { + return; + } + + ShellContent content = _itemToContent[_tabs.SelectedItem]; + if (ShellSection.CurrentItem != content) + { + ShellSection.SetValueFromRenderer(ShellSection.CurrentItemProperty, content); + } + } + + void UpdateCurrentShellContent(ShellContent content) + { + if (_currentContent != null) + { + _currentContent.Hide(); + _contentArea.UnPack(_currentContent); + _currentContent = null; + } + + if (content == null) + { + return; + } + + if (!_contentCache.ContainsKey(content)) + { + var native = CreateShellContent(content); + native.SetAlignment(-1, -1); + native.SetWeight(1, 1); + _contentCache[content] = native; + } + _currentContent = _contentCache[content]; + _currentContent.Show(); + _contentArea.PackEnd(_currentContent); + } + + EvasObject CreateShellContent(ShellContent content) + { + Page xpage = ((IShellContentController)content).GetOrCreateContent(); + return xpage.ToPlatform(MauiContext); + } + + void OnLayout() + { + if (PlatformView.Geometry.Width == 0 || PlatformView.Geometry.Height == 0) + return; + var bound = PlatformView.Geometry; + + int tabsHeight; + if (_tabs != null && TabBarIsVisible) + { + var tabsBound = bound; + tabsHeight = _tabs.MinimumHeight; + tabsBound.Height = tabsHeight; + _tabs.Geometry = tabsBound; + } + else + { + tabsHeight = 0; + } + + var contentBound = bound; + contentBound.Y += tabsHeight; + contentBound.Height -= tabsHeight; + _contentArea.Geometry = contentBound; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionStack.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionStack.cs new file mode 100644 index 0000000000..44fa03f08b --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellSectionStack.cs @@ -0,0 +1,305 @@ +#nullable enable + +using System; +using System.ComponentModel; +using System.Threading.Tasks; +using Microsoft.Maui.Devices; +using ElmSharp; +using EBox = ElmSharp.Box; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellSectionStack : EBox, IAppearanceObserver, IDisposable + { + ShellNavBar? _navBar = null; + Page? _currentPage = null; + SimpleViewStack _viewStack; + IShellSectionHandler? _shellSectionHandler; + + bool _disposed = false; + bool _navBarIsVisible = true; + + public ShellSectionStack(ShellSection section, IMauiContext context) : base(context.GetNativeParent()) + { + ShellSection = section; + MauiContext = context; + + SetAlignment(-1, -1); + SetWeight(1, 1); + SetLayoutCallback(OnLayout); + + _viewStack = new SimpleViewStack(NativeParent); + if (DeviceInfo.Idiom == DeviceIdiom.Phone) + { + _viewStack.BackgroundColor = ElmSharp.Color.White; + } + _viewStack.Show(); + PackEnd(_viewStack); + + InitializeComponent(); + } + + protected IMauiContext? MauiContext { get; private set; } + + protected EvasObject? NativeParent + { + get => MauiContext?.GetNativeParent(); + } + + public virtual bool NavBarIsVisible + { + get + { + return _navBarIsVisible; + } + set + { + _navBarIsVisible = value; + OnLayout(); + } + } + + ShellSection ShellSection { get; } + + ~ShellSectionStack() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + (Shell.Current as IShellController).RemoveAppearanceObserver(this); + (Shell.Current as IShellController).RemoveFlyoutBehaviorObserver(_navBar); + if (ShellSection != null) + { + IShellSectionController controller = ShellSection; + controller.NavigationRequested -= OnNavigationRequested; + controller.RemoveDisplayedPageObserver(this); + } + if (_currentPage != null) + { + _currentPage.PropertyChanged -= OnPagePropertyChanged; + } + if (_navBar != null) + { + _navBar.Dispose(); + _navBar = null; + } + Unrealize(); + } + _disposed = true; + } + + protected virtual IShellSectionHandler CreateShellSectionView(ShellSection section) + { + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + return new ShellSectionHandler(section, MauiContext); + } + + void InitializeComponent() + { + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + _navBar = new ShellNavBar(MauiContext); + _navBar.Show(); + PackEnd(_navBar); + + IShellSectionController controller = ShellSection; + controller.NavigationRequested += OnNavigationRequested; + controller.AddDisplayedPageObserver(this, UpdateDisplayedPage); + ((IShellController)Shell.Current).AddAppearanceObserver(this, ShellSection); + ((IShellController)Shell.Current).AddFlyoutBehaviorObserver(_navBar); + + _shellSectionHandler = CreateShellSectionView(ShellSection); + _shellSectionHandler.PlatformView.Show(); + _viewStack.Push(_shellSectionHandler.PlatformView); + + Application.Current?.Dispatcher.Dispatch(() => + { + (_shellSectionHandler.PlatformView as Widget)?.SetFocus(true); + }); + } + + void UpdateDisplayedPage(Page page) + { + // this callback is raised when DisplayPage was updated and it is raised ahead of push NavigationRequesed event + if (_currentPage != null) + { + _currentPage.PropertyChanged -= OnPagePropertyChanged; + } + if (page == null) + return; + + _currentPage = page; + _currentPage.PropertyChanged += OnPagePropertyChanged; + NavBarIsVisible = Shell.GetNavBarIsVisible(page); + _navBar?.SetPage(page); + } + + void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance) + { + if (_navBar == null) + return; + + var titleColor = (appearance as IShellAppearanceElement)?.EffectiveTabBarTitleColor; + var backgroundColor = appearance?.BackgroundColor; + var foregroundColor = appearance?.ForegroundColor; + + _navBar.TitleColor = titleColor.IsDefault() ? ShellView.DefaultTitleColor : (titleColor?.ToPlatformEFL()).GetValueOrDefault(); + _navBar.BackgroundColor = backgroundColor.IsDefault() ? ShellView.DefaultBackgroundColor : (backgroundColor?.ToPlatformEFL()).GetValueOrDefault(); + _navBar.ForegroundColor = foregroundColor.IsDefault() ? ShellView.DefaultForegroundColor : (foregroundColor?.ToPlatformEFL()).GetValueOrDefault(); + } + + + protected virtual void OnPagePropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == Page.TitleProperty.PropertyName) + { + if (_navBar != null) + _navBar.Title = (sender as Page)?.Title ?? ""; + } + else if (e.PropertyName == Shell.NavBarIsVisibleProperty.PropertyName) + { + NavBarIsVisible = Shell.GetNavBarIsVisible(sender as Page); + } + else if (e.PropertyName == Shell.TitleViewProperty.PropertyName) + { + if (_navBar != null) + _navBar.TitleView = Shell.GetTitleView(sender as Page); + } + } + + void OnNavigationRequested(object? sender, Internals.NavigationRequestedEventArgs e) + { + if (e.RequestType == Internals.NavigationRequestType.Push) + { + PushRequest(sender, e); + } + else if (e.RequestType == Internals.NavigationRequestType.Insert) + { + InsertRequest(sender, e); + } + else if (e.RequestType == Internals.NavigationRequestType.Pop) + { + PopRequest(sender, e); + } + else if (e.RequestType == Internals.NavigationRequestType.PopToRoot) + { + PopToRootRequest(sender, e); + } + else if (e.RequestType == Internals.NavigationRequestType.Remove) + { + RemoveRequest(sender, e); + } + UpdateHasBackButton(); + } + + void RemoveRequest(object? sender, Internals.NavigationRequestedEventArgs request) + { + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + var nativePage = request.Page.ToPlatform(MauiContext); + if (nativePage == null) + { + request.Task = Task.FromException(new ArgumentException("Can't found page on stack", nameof(request.Page))); + return; + } + _viewStack.Remove(nativePage); + request.Task = Task.FromResult(true); + } + + void PopRequest(object? sender, Internals.NavigationRequestedEventArgs request) + { + _viewStack.Pop(); + request.Task = Task.FromResult(true); + } + + void PopToRootRequest(object? sender, Internals.NavigationRequestedEventArgs request) + { + _viewStack.PopToRoot(); + request.Task = Task.FromResult(true); + } + + void PushRequest(object? sender, Internals.NavigationRequestedEventArgs request) + { + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + var nativePage = request.Page.ToPlatform(MauiContext); + _viewStack.Push(nativePage); + request.Task = Task.FromResult(true); + Application.Current?.Dispatcher.Dispatch(() => + { + (nativePage as Widget)?.SetFocus(true); + }); + } + + void InsertRequest(object? sender, Internals.NavigationRequestedEventArgs request) + { + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + var before = request.BeforePage.ToPlatform(MauiContext); + if (before == null) + { + request.Task = Task.FromException(new ArgumentException("Can't found page on stack", nameof(request.BeforePage))); + return; + } + var page = request.Page.ToPlatform(MauiContext); + _viewStack.Insert(before, page); + request.Task = Task.FromResult(true); + } + + void UpdateHasBackButton() + { + if (_navBar == null) + return; + + if (_viewStack.Stack.Count > 1) + _navBar.HasBackButton = true; + else + _navBar.HasBackButton = false; + } + + void OnLayout() + { + if (Geometry.Width == 0 || Geometry.Height == 0) + return; + + var bound = Geometry; + int navBarHeight; + if (NavBarIsVisible) + { + var navBound = bound; + navBarHeight = DPExtensions.ConvertToScaledPixel(_navBar.GetDefaultNavBarHeight()); + navBound.Height = navBarHeight; + + if (_navBar != null) + { + _navBar.Show(); + _navBar.Geometry = navBound; + _navBar.RaiseTop(); + } + } + else + { + navBarHeight = 0; + _navBar?.Hide(); + } + + bound.Y += navBarHeight; + bound.Height -= navBarHeight; + _viewStack.Geometry = bound; + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ShellView.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ShellView.cs new file mode 100644 index 0000000000..bde90036b6 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ShellView.cs @@ -0,0 +1,427 @@ +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using ElmSharp; +using Microsoft.Extensions.DependencyInjection; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using EBox = ElmSharp.Box; +using EColor = ElmSharp.Color; +using ITNavigationView = Tizen.UIExtensions.ElmSharp.INavigationView; +using TCollectionView = Tizen.UIExtensions.ElmSharp.CollectionView; +using TImage = Tizen.UIExtensions.ElmSharp.Image; +using TNavigationView = Tizen.UIExtensions.ElmSharp.NavigationView; +using TSelectedItemChangedEventArgs = Tizen.UIExtensions.ElmSharp.SelectedItemChangedEventArgs; +using TThemeConstants = Tizen.UIExtensions.ElmSharp.ThemeConstants; +using TDPExtensions = Tizen.UIExtensions.ElmSharp.DPExtensions; + +namespace Microsoft.Maui.Controls.Platform +{ + public class ShellView : EBox, IFlyoutBehaviorObserver + { + public static readonly EColor DefaultBackgroundColor = TThemeConstants.Shell.ColorClass.DefaultBackgroundColor; + public static readonly EColor DefaultForegroundColor = TThemeConstants.Shell.ColorClass.DefaultForegroundColor; + public static readonly EColor DefaultTitleColor = TThemeConstants.Shell.ColorClass.DefaultTitleColor; + + INavigationDrawer _navigationDrawer; + ITNavigationView _navigationView; + FlyoutHeaderBehavior _headerBehavior; + + List>? _cachedGroups; + + View? _headerView; + View? _footerView; + TCollectionView _itemsView; + + Element? _lastSelected; + ShellItemView? _currentShellItem; + + public ShellView(EvasObject parent) : base(parent) + { + NativeParent = parent; + _navigationDrawer = CreateNavigationDrawer(); + _navigationView = CreateNavigationView(); + _navigationView.LayoutUpdated += OnNavigationViewLayoutUpdated; + _navigationView.Content = _itemsView = CreateItemsView(); + + _navigationDrawer.NavigationView = _navigationView.TargetView; + _navigationDrawer.Toggled += OnDrawerToggled; + + _navigationDrawer.TargetView.SetAlignment(-1.0, -1.0); + _navigationDrawer.TargetView.SetWeight(1.0, 1.0); + _navigationDrawer.TargetView.Show(); + PackEnd(_navigationDrawer.TargetView); + } + + public IMauiContext? MauiContext { get; private set; } + + protected EvasObject? NativeParent { get; private set; } + + protected Shell? Element { get; private set; } + + protected TCollectionView ItemsView => _itemsView; + + protected ITNavigationView NavigationView => _navigationView; + + protected bool HeaderOnMenu => _headerBehavior == FlyoutHeaderBehavior.Scroll || _headerBehavior == FlyoutHeaderBehavior.CollapseOnScroll; + + public virtual void SetElement(Shell shell, IMauiContext context) + { + Element = shell; + Element.PropertyChanged += OnElementPropertyChanged; + MauiContext = context; + + ((IShellController)Element).StructureChanged += OnShellStructureChanged; + _lastSelected = null; + + UpdateFlyoutIsPresented(); + UpdateFlyoutBackgroundColor(); + UpdateFlyoutBackgroundImage(); + UpdateCurrentItem(); + UpdateFlyoutHeader(); + UpdateFooter(); + } + + protected virtual ShellItemView CreateShellItemView(ShellItem item) + { + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + return new ShellItemView(item, MauiContext); + } + + protected virtual INavigationDrawer CreateNavigationDrawer() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + return new NavigationDrawer(NativeParent); + } + + protected virtual ITNavigationView CreateNavigationView() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + return new TNavigationView(NativeParent); + } + + protected virtual TCollectionView CreateItemsView() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + return new TCollectionView(NativeParent) + { + AlignmentX = -1, + AlignmentY = -1, + WeightX = 1, + WeightY = 1, + SelectionMode = CollectionViewSelectionMode.Single, + HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible, + VerticalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible, + LayoutManager = new LinearLayoutManager(false, Tizen.UIExtensions.ElmSharp.ItemSizingStrategy.MeasureFirstItem) + }; + } + + protected virtual ItemAdaptor GetItemAdaptor(IEnumerable items) + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + return new ShellFlyoutItemAdaptor(Element, MauiContext, items, HeaderOnMenu); + } + + protected virtual void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == Shell.CurrentItemProperty.PropertyName) + { + UpdateCurrentItem(); + } + else if (e.PropertyName == Shell.FlyoutIsPresentedProperty.PropertyName) + { + UpdateFlyoutIsPresented(); + } + else if (e.PropertyName == Shell.FlyoutBackgroundColorProperty.PropertyName) + { + UpdateFlyoutBackgroundColor(); + } + else if (e.PropertyName == Shell.FlyoutBackgroundImageProperty.PropertyName) + { + UpdateFlyoutBackgroundImage(); + } + else if (e.PropertyName == Shell.FlyoutBackgroundImageProperty.PropertyName) + { + UpdateFlyoutBackgroundImageAspect(); + } + else if (e.PropertyName == Shell.FlyoutHeaderProperty.PropertyName) + { + UpdateFlyoutHeader(); + } + else if (e.PropertyName == Shell.FlyoutHeaderTemplateProperty.PropertyName) + { + UpdateFlyoutHeader(); + } + else if (e.PropertyName == Shell.FlyoutHeaderBehaviorProperty.PropertyName) + { + UpdateFlyoutHeader(); + } + else if (e.PropertyName == Shell.FlyoutFooterProperty.PropertyName) + { + UpdateFooter(); + } + } + + protected virtual void UpdateFlyoutIsPresented() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + // It is workaround of Panel.IsOpen bug, Panel.IsOpen property is not working when layouting was triggered + Application.Current?.Dispatcher.Dispatch(() => + { + _navigationDrawer.IsOpen = Element.FlyoutIsPresented; + }); + } + + protected void OnDrawerToggled(object? sender, EventArgs e) + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + Element.SetValueFromRenderer(Shell.FlyoutIsPresentedProperty, _navigationDrawer.IsOpen); + } + + protected virtual void UpdateFlyoutBehavior() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + _navigationDrawer.DrawerBehavior = Element.FlyoutBehavior.ToPlatform(); + } + + protected virtual void BuildMenu() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + var groups = ((IShellController)Element).GenerateFlyoutGrouping(); + + if (!IsItemChanged(groups) && !HeaderOnMenu) + return; + + _cachedGroups = groups; + + var items = new List(); + + foreach (var group in groups) + { + bool isFirst = true; + foreach (var item in group) + { + items.Add(item); + + // TODO: implements separator + if (isFirst) + isFirst = false; + } + } + + ItemsView.Adaptor = GetItemAdaptor(items); + ItemsView.Adaptor.ItemSelected += OnItemSelected; + } + + protected virtual void UpdateFlyoutHeader() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + if (_headerView != null) + { + _headerView.MeasureInvalidated -= OnHeaderSizeChanged; + _headerView = null; + } + + _headerView = (Element as IShellController).FlyoutHeader; + _headerBehavior = Element.FlyoutHeaderBehavior; + + BuildMenu(); + + if (_headerView != null) + { + if (HeaderOnMenu) + { + _navigationView.Header = null; + } + else + { + _navigationView.Header = _headerView.ToPlatform(MauiContext); + _headerView.MeasureInvalidated += OnHeaderSizeChanged; + } + } + else + { + _navigationView.Header = null; + } + } + + protected virtual void UpdateFooter() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + if (_footerView != null) + { + _footerView.MeasureInvalidated -= OnFooterSizeChanged; + _footerView = null; + } + + _footerView = (Element as IShellController).FlyoutFooter; + + if (_footerView != null) + { + _navigationView.Footer = _footerView.ToPlatform(MauiContext); + _footerView.MeasureInvalidated += OnFooterSizeChanged; + } + else + { + _navigationView.Footer = null; + } + } + + void OnShellStructureChanged(object? sender, EventArgs e) + { + BuildMenu(); + } + + void OnItemSelected(object? sender, TSelectedItemChangedEventArgs e) + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + _lastSelected = e.SelectedItem as Element; + ((IShellController)Element).OnFlyoutItemSelected(_lastSelected); + } + + bool IsItemChanged(List> groups) + { + if (_cachedGroups == null) + return true; + + if (_cachedGroups.Count != groups.Count) + return true; + + for (int i = 0; i < groups.Count; i++) + { + if (_cachedGroups[i].Count != groups[i].Count) + return true; + + for (int j = 0; j < groups[i].Count; j++) + { + if (_cachedGroups[i][j] != groups[i][j]) + return true; + } + } + + _cachedGroups = groups; + return false; + } + + void UpdateCurrentItem() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + _currentShellItem?.Dispose(); + if (Element.CurrentItem != null) + { + _currentShellItem = CreateShellItemView(Element.CurrentItem); + _navigationDrawer.Main = _currentShellItem.NativeView; + } + else + { + _navigationDrawer.Main = null; + } + } + + void UpdateFlyoutBackgroundColor() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + _navigationView.BackgroundColor = Element.FlyoutBackgroundColor.ToPlatformEFL(); + } + + async void UpdateFlyoutBackgroundImage() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + if (Element.FlyoutBackgroundImage != null) + { + var image = new TImage(NativeParent); + var imageSource = Element.FlyoutBackgroundImage; + var provider = MauiContext.Services.GetRequiredService(); + var service = provider.GetRequiredImageSourceService(imageSource); + image.Aspect = Element.FlyoutBackgroundImageAspect.ToPlatform(); + _navigationView.BackgroundImage = image; + + await service.GetImageAsync(imageSource, image); + } + else + { + _navigationView.BackgroundImage = null; + } + } + + void UpdateFlyoutBackgroundImageAspect() + { + _ = Element ?? throw new InvalidOperationException($"{nameof(Element)} should have been set by base class."); + + if (_navigationView.BackgroundImage is TImage image) + { + image.Aspect = Element.FlyoutBackgroundImageAspect.ToPlatform(); + } + } + + void OnNavigationViewLayoutUpdated(object? sender, LayoutEventArgs args) + { + UpdateHeaderLayout(args.Geometry.Width, args.Geometry.Height); + UpdateFooterLayout(args.Geometry.Width, args.Geometry.Height); + } + + void OnHeaderSizeChanged(object? sender, EventArgs e) + { + var bound = (_navigationView as EvasObject)?.Geometry; + Application.Current?.Dispatcher.Dispatch(()=> { + UpdateHeaderLayout((bound?.Width).GetValueOrDefault(), (bound?.Height).GetValueOrDefault()); + }); + } + + void OnFooterSizeChanged(object? sender, EventArgs e) + { + var bound = (_navigationView as EvasObject)?.Geometry; + Application.Current?.Dispatcher.Dispatch(() => { + UpdateFooterLayout((bound?.Width).GetValueOrDefault(), (bound?.Height).GetValueOrDefault()); + }); + } + + void UpdateHeaderLayout(double widthConstraint, double heightConstraint) + { + if ((!HeaderOnMenu) && (_headerView != null)) + { + var requestSize = _headerView.Measure(widthConstraint, heightConstraint); + if(_navigationView.Header != null) + _navigationView.Header.MinimumHeight = TDPExtensions.ConvertToScaledPixel(requestSize.Request.Height); + } + } + + void UpdateFooterLayout(double widthConstraint, double heightConstraint) + { + if (_footerView != null) + { + var requestSize = _footerView.Measure(widthConstraint, heightConstraint); + if (_navigationView.Footer != null) + _navigationView.Footer.MinimumHeight = TDPExtensions.ConvertToScaledPixel(requestSize.Request.Height); + } + } + + void IFlyoutBehaviorObserver.OnFlyoutBehaviorChanged(FlyoutBehavior behavior) + { + UpdateFlyoutBehavior(); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/SimpleViewStack.cs b/src/Controls/src/Core/Platform/Tizen/Shell/SimpleViewStack.cs new file mode 100644 index 0000000000..3114f02108 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/SimpleViewStack.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using System.Linq; +using ElmSharp; +using EBox = ElmSharp.Box; + +namespace Microsoft.Maui.Controls.Platform +{ + public class SimpleViewStack : EBox + { + EvasObject _lastTop; + + public SimpleViewStack(EvasObject parent) : base(parent) + { + InternalStack = new List(); + SetLayoutCallback(OnLayout); + } + + List InternalStack { get; set; } + + public IReadOnlyList Stack => InternalStack; + + public void Push(EvasObject view) + { + InternalStack.Add(view); + PackEnd(view); + UpdateTopView(); + } + + public void Pop() + { + if (_lastTop != null) + { + var tobeRemoved = _lastTop; + InternalStack.Remove(tobeRemoved); + UnPack(tobeRemoved); + UpdateTopView(); + // if Pop was called by removed page, + // Unrealize cause deletation of NativeCallback, it could be a cause of crash + Application.Current?.Dispatcher.Dispatch(() => + { + tobeRemoved.Unrealize(); + }); + } + } + + public void PopToRoot() + { + while (InternalStack.Count > 1) + { + Pop(); + } + } + + public void Insert(EvasObject before, EvasObject view) + { + view.Hide(); + var idx = InternalStack.IndexOf(before); + InternalStack.Insert(idx, view); + PackEnd(view); + UpdateTopView(); + } + + public void Remove(EvasObject view) + { + InternalStack.Remove(view); + UnPack(view); + UpdateTopView(); + Application.Current?.Dispatcher.Dispatch(() => + { + view?.Unrealize(); + }); + } + + void UpdateTopView() + { + if (_lastTop != InternalStack.LastOrDefault()) + { + _lastTop?.Hide(); + _lastTop = InternalStack.LastOrDefault(); + _lastTop.Show(); + (_lastTop as Widget)?.SetFocus(true); + } + } + + void OnLayout() + { + foreach (var view in Stack) + { + view.Geometry = Geometry; + } + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemAdaptor.cs b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemAdaptor.cs new file mode 100644 index 0000000000..dcaa6d41e8 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemAdaptor.cs @@ -0,0 +1,358 @@ +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using ElmSharp; +using Microsoft.Maui.Controls.Internals; +using Tizen.UIExtensions.ElmSharp; +using ITNavigtaionView = Tizen.UIExtensions.ElmSharp.INavigationView; +using TViewHolderState = Tizen.UIExtensions.ElmSharp.ViewHolderState; +using DPExtensions = Tizen.UIExtensions.ElmSharp.DPExtensions; + +namespace Microsoft.Maui.Controls.Platform +{ + public class TVShellItemAdaptor : ItemAdaptor + { + Dictionary _nativeFormsTable = new Dictionary(); + Dictionary _dataBindedViewTable = new Dictionary(); + + Element _element; + IMauiContext _context; + ITNavigtaionView? _navigationView; + + protected virtual bool IsSelectable { get; } + + public DataTemplate DefaultTemplate { get; private set; } + + public TVShellItemAdaptor(Element element, ITNavigtaionView? nv, IMauiContext context, IEnumerable items, bool isCollapsed) : base(items) + { + _element = element; + _context = context; + _navigationView = nv; + IsSelectable = true; + DefaultTemplate = CreateDafaultTemplate(nv, isCollapsed); + } + + public override EvasObject? CreateNativeView(EvasObject parent) + { + return CreateNativeView(0, parent); + } + + public override EvasObject? CreateNativeView(int index, EvasObject parent) + { + View? view = GetTemplatedView(index); + if (view != null) + { + var native = view.ToPlatform(_context); + _nativeFormsTable[native] = view; + return native; + } + + return null; + } + + public override EvasObject? GetFooterView(EvasObject parent) + { + return null; + } + + public override EvasObject? GetHeaderView(EvasObject parent) + { + return null; + } + + public override Size MeasureFooter(int widthConstraint, int heightConstraint) + { + return new Size(0, 0); + } + + public override Size MeasureHeader(int widthConstraint, int heightConstraint) + { + return new Size(0, 0); + } + + public override Size MeasureItem(int widthConstraint, int heightConstraint) + { + return MeasureItem(0, widthConstraint, heightConstraint); + } + + public override Size MeasureItem(int index, int widthConstraint, int heightConstraint) + { + View? view = GetTemplatedView(index); + if (view != null) + { + var native = view.ToPlatform(_context); + view.Parent = _element; + + if (Count > index) + view.BindingContext = this[index]; + + var size = view.Measure(DPExtensions.ConvertToScaledDP(widthConstraint), DPExtensions.ConvertToScaledDP(heightConstraint), MeasureFlags.IncludeMargins).Request; + native.Unrealize(); + + return size.ToEFLPixel(); + } + + return new Size(0, 0); + } + + public override void RemoveNativeView(EvasObject native) + { + native?.Unrealize(); + } + + public override void SetBinding(EvasObject native, int index) + { + if (_nativeFormsTable.TryGetValue(native, out View? view)) + { + ResetBindedView(view); + var item = this[index]; + view.BindingContext = item; + if (item != null) + _dataBindedViewTable[item] = view; + + view.MeasureInvalidated += OnItemMeasureInvalidated; + view.Parent = _element; + } + } + + public override void UnBinding(EvasObject native) + { + if (_nativeFormsTable.TryGetValue(native, out View? view)) + { + view.MeasureInvalidated -= OnItemMeasureInvalidated; + ResetBindedView(view); + } + } + + public override void UpdateViewState(EvasObject native, TViewHolderState state) + { + base.UpdateViewState(native, state); + if (_nativeFormsTable.TryGetValue(native, out View? view)) + { + switch (state) + { + case TViewHolderState.Focused: + VisualStateManager.GoToState(view, VisualStateManager.CommonStates.Focused); + view.SetValue(VisualElement.IsFocusedPropertyKey, true); + break; + case TViewHolderState.Normal: + VisualStateManager.GoToState(view, VisualStateManager.CommonStates.Normal); + view.SetValue(VisualElement.IsFocusedPropertyKey, false); + break; + case TViewHolderState.Selected: + if (IsSelectable) + VisualStateManager.GoToState(view, VisualStateManager.CommonStates.Selected); + break; + } + } + } + + DataTemplate CreateDafaultTemplate(ITNavigtaionView? nv, bool isCollapsed) + { + return new DataTemplate(() => + { + var grid = new Grid + { + HeightRequest = nv.GetTvFlyoutItemHeight(), + WidthRequest = nv.GetTvFlyoutItemWidth(), + BackgroundColor = Graphics.Colors.Transparent + }; + + ColumnDefinitionCollection columnDefinitions = new ColumnDefinitionCollection(); + columnDefinitions.Add(new ColumnDefinition { Width = nv.GetTvFlyoutIconColumnSize() }); + columnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star }); + grid.ColumnDefinitions = columnDefinitions; + + var image = new Image + { + VerticalOptions = LayoutOptions.Center, + HorizontalOptions = LayoutOptions.Center, + HeightRequest = nv.GetTvFlyoutIconSize(), + WidthRequest = nv.GetTvFlyoutIconSize(), + Margin = new Thickness(nv.GetTvFlyoutMargin(), 0, 0, 0), + }; + image.SetBinding(Image.SourceProperty, new Binding("FlyoutIcon")); + grid.Add(image); + grid.SetColumn(image, 0); + + var label = new Label + { + FontSize = nv.GetTvFlyoutItemFontSize(), + VerticalTextAlignment = TextAlignment.Center, + Margin = new Thickness(nv.GetTvFlyoutMargin(), 0, 0, 0), + }; + + label.SetBinding(Label.TextProperty, new Binding("Title")); + label.SetBinding(Label.TextColorProperty, new Binding("BackgroundColor", converter: new TextColorConverter(), source: grid)); + + if (isCollapsed) + { + label.Opacity = 0; + label.SetBinding(Label.OpacityProperty, new Binding("Width", converter: new OpacityConverter(label.Opacity), source: label)); + } + + grid.Add(label); + grid.SetColumn(label, 1); + + var groups = new VisualStateGroupList(); + + var commonGroup = new VisualStateGroup(); + commonGroup.Name = "CommonStates"; + groups.Add(commonGroup); + + var normalState = new VisualState(); + normalState.Name = "Normal"; + normalState.Setters.Add(new Setter + { + Property = VisualElement.BackgroundColorProperty, + Value = nv.GetTvFlyoutItemColor(), + }); + + var focusedState = new VisualState(); + focusedState.Name = "Focused"; + focusedState.Setters.Add(new Setter + { + Property = VisualElement.BackgroundColorProperty, + Value = nv.GetTvFlyoutItemFocusedColor() + }); + + var selectedState = new VisualState(); + selectedState.Name = "Selected"; + selectedState.Setters.Add(new Setter + { + Property = VisualElement.BackgroundColorProperty, + Value = nv.GetTvFlyoutItemColor() + }); + + commonGroup.States.Add(normalState); + commonGroup.States.Add(focusedState); + commonGroup.States.Add(selectedState); + + VisualStateManager.SetVisualStateGroups(grid, groups); + return grid; + }); + } + + View? GetTemplatedView(int index) + { + var dataTemplate = DefaultTemplate; + var item = this[index]; + if (item is BindableObject bo) + { + dataTemplate = (_element as IShellController)?.GetFlyoutItemDataTemplate(bo); + if (dataTemplate != null) + { + if (item is IMenuItemController) + { + if (_element is Shell shell && shell.MenuItemTemplate != dataTemplate) + dataTemplate = DefaultTemplate; + } + else + { + if (_element is Shell shell && shell.ItemTemplate != dataTemplate) + dataTemplate = DefaultTemplate; + } + } + else + { + dataTemplate = DefaultTemplate; + } + } + + var view = dataTemplate.SelectDataTemplate(this[index], _element).CreateContent() as View; + return view; + } + + void ResetBindedView(View view) + { + if (view.BindingContext != null && _dataBindedViewTable.ContainsKey(view.BindingContext)) + { + _dataBindedViewTable[view.BindingContext] = null; + view.Parent = null; + view.BindingContext = null; + } + } + + void OnItemMeasureInvalidated(object? sender, EventArgs e) + { + var data = (sender as View)?.BindingContext ?? null; + if (data != null) + { + int index = GetItemIndex(data); + if (index != -1) + { + CollectionView?.ItemMeasureInvalidated(index); + } + } + } + + class TextColorConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Graphics.Color c && c == Graphics.Colors.Transparent) + { + return Graphics.Colors.White; + } + else + { + return Graphics.Colors.Black; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Graphics.Color c && c == Graphics.Colors.White) + { + return Graphics.Colors.Transparent; + } + else + { + return Graphics.Colors.Black; + } + } + } + + class OpacityConverter : IValueConverter + { + double _opacity; + double _itemWidth = -1; + + public OpacityConverter(double opacity) + { + _opacity = opacity; + } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + var width = (double)value; + + if (_itemWidth == -1) + { + _itemWidth = width; + return _opacity; + } + + _itemWidth = (_itemWidth < width) ? width : _itemWidth; + return ((width / _itemWidth) > 1) ? 1 : (width / _itemWidth); + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + var width = (double)value; + + if (_itemWidth == -1) + { + _itemWidth = width; + return _opacity; + } + + _itemWidth = (_itemWidth < width) ? width : _itemWidth; + return width * _itemWidth; + } + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemView.cs b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemView.cs new file mode 100644 index 0000000000..4662d3232e --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellItemView.cs @@ -0,0 +1,18 @@ +namespace Microsoft.Maui.Controls.Platform +{ + public class TVShellItemView : ShellItemView + { + public TVShellItemView(ShellItem item, IMauiContext context) : base(item, context) + { + } + + protected override ShellSectionStack CreateShellSectionStack(ShellSection section) + { + return new TVShellSectionStack(section, MauiContext); + } + + protected override void UpdateTabsItems() + { + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionHandler.cs b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionHandler.cs new file mode 100644 index 0000000000..8ea8f90330 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionHandler.cs @@ -0,0 +1,285 @@ +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; +using ElmSharp; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using EBox = ElmSharp.Box; +using TCollectionView = Tizen.UIExtensions.ElmSharp.CollectionView; +using TNavigationView = Tizen.UIExtensions.ElmSharp.NavigationView; +using ITCollectionViewController = Tizen.UIExtensions.ElmSharp.ICollectionViewController; +using TSelectedItemChangedEventArgs = Tizen.UIExtensions.ElmSharp.SelectedItemChangedEventArgs; + + +namespace Microsoft.Maui.Controls.Platform +{ + public class TVShellSectionHandler : IShellSectionHandler, IDisposable + { + EBox _mainLayout; + EBox _contentArea; + EvasObject? _currentContent = null; + + TNavigationView? _navigationView; + TCollectionView? _itemsView; + + IList? _cachedItems; + Dictionary _contentCache = new Dictionary(); + + bool _disposed = false; + + bool _drawerIsVisible => (ShellSection != null) ? (ShellSection.Items.Count > 1) : false; + + public TVShellSectionHandler(ShellSection section, IMauiContext context) + { + ShellSection = section; + MauiContext = context; + ShellSection.PropertyChanged += OnSectionPropertyChanged; + if (ShellSection.Items is INotifyCollectionChanged collection) + { + collection.CollectionChanged += OnShellSectionCollectionChanged; + } + + _mainLayout = new EBox(NativeParent); + _mainLayout.SetLayoutCallback(OnLayout); + + _contentArea = new EBox(NativeParent); + _contentArea.Show(); + _mainLayout.PackEnd(_contentArea); + + UpdateSectionItems(); + UpdateCurrentItem(ShellSection.CurrentItem); + } + + public ShellSection ShellSection { get; } + + public EvasObject PlatformView + { + get + { + return _mainLayout; + } + } + + protected IMauiContext MauiContext { get; private set; } + + protected TCollectionView? ItemsView => _itemsView; + + protected EvasObject? NativeParent + { + get => MauiContext.GetNativeParent(); + } + + ~TVShellSectionHandler() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (_disposed) + return; + + if (disposing) + { + if (ShellSection != null) + { + ShellSection.PropertyChanged -= OnSectionPropertyChanged; + } + + PlatformView.Unrealize(); + } + _disposed = true; + } + + protected virtual TCollectionView CreateItemsView() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + return new TCollectionView(NativeParent) + { + AlignmentX = -1, + AlignmentY = -1, + WeightX = 1, + WeightY = 1, + SelectionMode = CollectionViewSelectionMode.Single, + HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible, + VerticalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible, + LayoutManager = new LinearLayoutManager(false) + }; + } + + void OnNavigationViewSelectedItemChanged(object sender, ItemSelectedEventArgs e) + { + if (e.SelectedItem == null) + return; + + var content = e.SelectedItem; + if (ShellSection.CurrentItem != content) + { + ShellSection.SetValueFromRenderer(ShellSection.CurrentItemProperty, content); + } + } + + void OnSectionPropertyChanged(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == ShellSection.CurrentItemProperty.PropertyName) + { + UpdateCurrentItem(ShellSection.CurrentItem); + } + } + + void UpdateSectionItems() + { + if (!_drawerIsVisible) + { + return; + } + + if (_navigationView == null && NativeParent != null) + { + _navigationView = new TVNavigationView(NativeParent); + _navigationView.SetAlignment(-1, -1); + _navigationView.SetWeight(1, 1); + _navigationView.Show(); + _mainLayout.PackStart(_navigationView); + + _navigationView.LayoutUpdated += (s, e) => + { + var drawerBound = e.Geometry; + var drawerWidth = GetDrawerWidth(); + }; + + _navigationView.Content = _itemsView = CreateItemsView(); + } + + BuildMenu(); + } + + bool IsItemChanged(IList items) + { + if (_cachedItems == null) + return true; + + if (_cachedItems.Count != items.Count) + return true; + + for (int i = 0; i < items.Count; i++) + { + if (_cachedItems[i] != items[i]) + return true; + } + + _cachedItems = items; + return false; + } + + void BuildMenu() + { + var items = ShellSection.Items; + + if (!IsItemChanged(items)) + return; + + _cachedItems = items; + + if (ItemsView != null) + { + ItemsView.Adaptor = new TVShellItemAdaptor(ShellSection, _navigationView, MauiContext, items, false); + ItemsView.Adaptor.ItemSelected += OnItemSelected; + } + } + + void UpdateCurrentItem(ShellContent content) + { + if (_currentContent != null) + { + _currentContent.Hide(); + _contentArea.UnPack(_currentContent); + _currentContent = null; + } + + if (content == null) + { + return; + } + + if (!_contentCache.ContainsKey(content)) + { + var native = CreateShellContent(content); + native.SetAlignment(-1, -1); + native.SetWeight(1, 1); + _contentCache[content] = native; + } + _currentContent = _contentCache[content]; + _currentContent.Show(); + _contentArea.PackEnd(_currentContent); + } + + EvasObject CreateShellContent(ShellContent content) + { + Page xpage = ((IShellContentController)content).GetOrCreateContent(); + return xpage.ToPlatform(MauiContext); + } + + void OnLayout() + { + if (PlatformView.Geometry.Width == 0 || PlatformView.Geometry.Height == 0) + return; + + var bound = PlatformView.Geometry; + var drawerWidth = 0; + + if (_drawerIsVisible && _navigationView != null) + { + var drawerBound = bound; + drawerWidth = GetDrawerWidth(); + drawerBound.Width = drawerWidth; + + _navigationView.Geometry = drawerBound; + } + + var contentBound = bound; + + contentBound.X += drawerWidth; + contentBound.Width -= drawerWidth; + _contentArea.Geometry = contentBound; + } + + int GetDrawerWidth() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + + int width = 0; + if (ItemsView is ITCollectionViewController controller) + width = controller.GetItemSize((NativeParent.Geometry.Width / 2), NativeParent.Geometry.Height).Width; + + return width; + } + + void OnItemSelected(object? sender, TSelectedItemChangedEventArgs e) + { + if (e.SelectedItem == null) + return; + + var content = e.SelectedItem; + if (ShellSection.CurrentItem != content) + { + ShellSection.SetValueFromRenderer(ShellSection.CurrentItemProperty, content); + } + } + + void OnShellSectionCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + UpdateSectionItems(); + } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionStack.cs b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionStack.cs new file mode 100644 index 0000000000..6b60ac79db --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellSectionStack.cs @@ -0,0 +1,16 @@ +namespace Microsoft.Maui.Controls.Platform +{ + public class TVShellSectionStack : ShellSectionStack + { + public TVShellSectionStack(ShellSection section, IMauiContext context) : base(section, context) + { + } + + public override bool NavBarIsVisible => false; + + protected override IShellSectionHandler CreateShellSectionView(ShellSection section) + { + return new TVShellSectionHandler(section, MauiContext); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/TVShellView.cs b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellView.cs new file mode 100644 index 0000000000..9ebaada57e --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/TVShellView.cs @@ -0,0 +1,43 @@ +using System.Collections; +using ElmSharp; +using Microsoft.Maui.Graphics; +using Tizen.UIExtensions.ElmSharp; +using ITNavigationView = Tizen.UIExtensions.ElmSharp.INavigationView; + +namespace Microsoft.Maui.Controls.Platform +{ + public class TVShellView : ShellView + { + public TVShellView(EvasObject parent) : base(parent) + { + } + + public override void SetElement(Shell shell, IMauiContext context) + { + base.SetElement(shell, context); + + // Workaround to set to use a default color for TV different from the mobile + shell.SetAppThemeColor(Shell.FlyoutBackgroundColorProperty, Colors.Black, Colors.Black); + } + + protected override INavigationDrawer CreateNavigationDrawer() + { + return new TVNavigationDrawer(NativeParent); + } + + protected override ITNavigationView CreateNavigationView() + { + return new TVNavigationView(NativeParent); + } + + protected override ShellItemView CreateShellItemView(ShellItem item) + { + return new TVShellItemView(item, MauiContext); + } + + protected override ItemAdaptor GetItemAdaptor(IEnumerable items) + { + return new TVShellItemAdaptor(Element, NavigationView, MauiContext, items, !Element.FlyoutIsPresented); + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ThemeConstants.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ThemeConstants.cs new file mode 100644 index 0000000000..a4f602b6fb --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ThemeConstants.cs @@ -0,0 +1,43 @@ +namespace Microsoft.Maui.Controls.Platform +{ + public class ThemeConstants + { + public class Shell + { + public class Resources + { + public const int DefaultMargin = 10; + public const int DefaultNavBarHeight = 70; + public const int DefaultMenuSize = 40; + + public const int DefaultTitleFontSize = 23; + public const int DefaultTitleMargin = 23; + + public const int DefaultIconSize = 30; + public const int DefaultIconPadding = 15; + + public const int DefaultFlyoutItemHeight = 60; + public const int DefaultFlyoutItemWidth = 250; + + public class TV + { + public const int DefaultMenuSize = 70; + + public const int DefaultFlyoutIconColumnSize = 40; + public const int DefaultFlyoutIconSize = 25; + + public const int DefaultFlyoutItemfontSize = 25; + } + } + + public class ColorClass + { + public class TV + { + public static readonly Graphics.Color DefaultFlyoutItemColor = Graphics.Colors.Transparent; + public static readonly Graphics.Color DefaultFlyoutItemFocusedColor = new Graphics.Color(0.95f); + } + } + } + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/Shell/ThemeManager.cs b/src/Controls/src/Core/Platform/Tizen/Shell/ThemeManager.cs new file mode 100644 index 0000000000..a7886b4d83 --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/Shell/ThemeManager.cs @@ -0,0 +1,130 @@ +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using ITNavigtaionView = Tizen.UIExtensions.ElmSharp.INavigationView; + +namespace Microsoft.Maui.Controls.Platform +{ + public static class ThemeManager + { + #region ShellMoreTabs + static double s_shellMoreToolBarIconPadding = -1; + public static double GetDefaultIconPadding(this ShellMoreTabs self) + { + if (s_shellMoreToolBarIconPadding > 0) + return s_shellMoreToolBarIconPadding; + return s_shellMoreToolBarIconPadding = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultIconPadding); + } + + static double s_shellMoreToolBarIconSize = -1; + public static double GetDefaultIconSize(this ShellMoreTabs self) + { + if (s_shellMoreToolBarIconSize > 0) + return s_shellMoreToolBarIconSize; + return s_shellMoreToolBarIconSize = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultIconSize); + } + #endregion + + #region ShellNavBar + static double s_shellNavBarDefaultHeight = -1; + public static double GetDefaultNavBarHeight(this ShellNavBar navBar) + { + if (s_shellNavBarDefaultHeight > 0) + return s_shellNavBarDefaultHeight; + return s_shellNavBarDefaultHeight = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultNavBarHeight); + } + + static double s_shellNavBarDefaultMenuSize = -1; + public static double GetDefaultMenuSize(this ShellNavBar navBar) + { + if (s_shellNavBarDefaultMenuSize > 0) + return s_shellNavBarDefaultMenuSize; + return s_shellNavBarDefaultMenuSize = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen( + Microsoft.Maui.Devices.DeviceInfo.Idiom == Microsoft.Maui.Devices.DeviceIdiom.TV ? ThemeConstants.Shell.Resources.TV.DefaultMenuSize : ThemeConstants.Shell.Resources.DefaultMenuSize); + } + + static double s_shellNavBarDefaultMargin = -1; + public static double GetDefaultMargin(this ShellNavBar navBar) + { + if (s_shellNavBarDefaultMargin > 0) + return s_shellNavBarDefaultMargin; + return s_shellNavBarDefaultMargin = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultMargin); + } + + static double s_shellNavBarTitleVDefaultMargin = -1; + public static double GetDefaultTitleVMargin(this ShellNavBar navBar) + { + if (s_shellNavBarTitleVDefaultMargin > 0) + return s_shellNavBarTitleVDefaultMargin; + return s_shellNavBarTitleVDefaultMargin = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultTitleMargin); + } + + static double s_shellNavBarTitleFontSize = -1; + public static double GetDefaultTitleFontSize(this ShellNavBar navBar) + { + if (s_shellNavBarTitleFontSize > 0) + return s_shellNavBarTitleFontSize; + return s_shellNavBarTitleFontSize = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultTitleFontSize); + } + #endregion + + #region TVShell + static double s_navigationViewFlyoutItemHeight = -1; + public static double GetTvFlyoutItemHeight(this ITNavigtaionView nav) + { + if (s_navigationViewFlyoutItemHeight > 0) + return s_navigationViewFlyoutItemHeight; + return s_navigationViewFlyoutItemHeight = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultFlyoutItemHeight); + } + + static double s_navigationViewFlyoutItemWidth = -1; + public static double GetTvFlyoutItemWidth(this ITNavigtaionView nav) + { + if (s_navigationViewFlyoutItemWidth > 0) + return s_navigationViewFlyoutItemWidth; + return s_navigationViewFlyoutItemWidth = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultFlyoutItemWidth); + } + + static double s_navigationViewFlyoutIconColumnSize = -1; + public static double GetTvFlyoutIconColumnSize(this ITNavigtaionView nav) + { + if (s_navigationViewFlyoutIconColumnSize > 0) + return s_navigationViewFlyoutIconColumnSize; + return s_navigationViewFlyoutIconColumnSize = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.TV.DefaultFlyoutIconColumnSize); + } + + static double s_navigationViewFlyoutIconSize = -1; + public static double GetTvFlyoutIconSize(this ITNavigtaionView nav) + { + if (s_navigationViewFlyoutIconSize > 0) + return s_navigationViewFlyoutIconSize; + return s_navigationViewFlyoutIconSize = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.TV.DefaultFlyoutIconSize); + } + + static double s_navigationViewFlyoutMargin = -1; + public static double GetTvFlyoutMargin(this ITNavigtaionView nav) + { + if (s_navigationViewFlyoutMargin > 0) + return s_navigationViewFlyoutMargin; + return s_navigationViewFlyoutMargin = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.DefaultMargin); + } + + static double s_navigationViewFlyoutItemFontSize = -1; + public static double GetTvFlyoutItemFontSize(this ITNavigtaionView nav) + { + if (s_navigationViewFlyoutItemFontSize > 0) + return s_navigationViewFlyoutItemFontSize; + return s_navigationViewFlyoutItemFontSize = DeviceInfo.CalculateDoubleScaledSizeInLargeScreen(ThemeConstants.Shell.Resources.TV.DefaultFlyoutItemfontSize); + } + + public static Graphics.Color GetTvFlyoutItemColor(this ITNavigtaionView nav) + { + return ThemeConstants.Shell.ColorClass.TV.DefaultFlyoutItemColor; + } + + public static Graphics.Color GetTvFlyoutItemFocusedColor(this ITNavigtaionView nav) + { + return ThemeConstants.Shell.ColorClass.TV.DefaultFlyoutItemFocusedColor; + } + #endregion + } +} diff --git a/src/Controls/src/Core/Platform/Tizen/SwipeGestureHandler.cs b/src/Controls/src/Core/Platform/Tizen/SwipeGestureHandler.cs new file mode 100644 index 0000000000..be7f26059e --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/SwipeGestureHandler.cs @@ -0,0 +1,29 @@ +using ElmSharp; + +namespace Microsoft.Maui.Controls.Platform +{ + public class SwipeGestureHandler : GestureHandler + { + public SwipeGestureHandler(IGestureRecognizer recognizer) : base(recognizer) + { + } + + public override GestureLayer.GestureType Type => GestureLayer.GestureType.Flick; + + protected override void OnStarted(View sender, object data) { } + + protected override void OnMoved(View sender, object data) { } + + protected override void OnCompleted(View sender, object data) + { + if (Recognizer is SwipeGestureRecognizer swipeGesture) + { + var lineData = (GestureLayer.LineData)data; + (swipeGesture as ISwipeGestureController)?.SendSwipe(sender, DPExtensions.ConvertToScaledDP(lineData.X2 - lineData.X1), DPExtensions.ConvertToScaledDP(lineData.Y2 - lineData.Y1)); + (swipeGesture as ISwipeGestureController)?.DetectSwipe(sender, swipeGesture.Direction); + } + } + + protected override void OnCanceled(View sender, object data) { } + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Platform/Tizen/TapGestureHandler.cs b/src/Controls/src/Core/Platform/Tizen/TapGestureHandler.cs new file mode 100644 index 0000000000..21ee68ea1e --- /dev/null +++ b/src/Controls/src/Core/Platform/Tizen/TapGestureHandler.cs @@ -0,0 +1,46 @@ +using ElmSharp; + +namespace Microsoft.Maui.Controls.Platform +{ + public class TapGestureHandler : GestureHandler + { + public TapGestureHandler(IGestureRecognizer recognizer) : base(recognizer) + { + } + + public override GestureLayer.GestureType Type + { + get + { + var recognizer = Recognizer as TapGestureRecognizer; + if (recognizer != null) + { + int numberOfTaps = recognizer.NumberOfTapsRequired; + + if (numberOfTaps > 2) + return GestureLayer.GestureType.TripleTap; + else if (numberOfTaps > 1) + return GestureLayer.GestureType.DoubleTap; + } + return GestureLayer.GestureType.Tap; + } + } + + protected override void OnStarted(View sender, object data) + { + } + + protected override void OnMoved(View sender, object data) + { + } + + protected override void OnCompleted(View sender, object data) + { + (Recognizer as TapGestureRecognizer)?.SendTapped(sender); + } + + protected override void OnCanceled(View sender, object data) + { + } + } +} diff --git a/src/Controls/src/Core/Properties/AssemblyInfo.cs b/src/Controls/src/Core/Properties/AssemblyInfo.cs index 484a31f47a..1595f94401 100644 --- a/src/Controls/src/Core/Properties/AssemblyInfo.cs +++ b/src/Controls/src/Core/Properties/AssemblyInfo.cs @@ -10,6 +10,7 @@ using Compatibility = Microsoft.Maui.Controls.Compatibility; [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Android")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.iOS")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Windows")] +[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Tizen")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Core.Design")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Core.UnitTests")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Android.UnitTests")] @@ -20,6 +21,7 @@ using Compatibility = Microsoft.Maui.Controls.Compatibility; [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Maps.iOS")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Maps.iOS.Classic")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Maps.Android")] +[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Maps.Tizen")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Xaml.UnitTests")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.UITests")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.FlexLayout.UnitTests")] diff --git a/src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs b/src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs index eb09e8c8cb..d27af8969e 100644 --- a/src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs +++ b/src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs @@ -21,6 +21,8 @@ using Microsoft.Maui.Controls.Compatibility.Platform.UWP; #elif IOS || MACCATALYST using Microsoft.Maui.Controls.Compatibility.Platform.iOS; using Microsoft.Maui.Controls.Handlers.Compatibility; +#elif TIZEN +using Microsoft.Maui.Controls.Compatibility.Platform.Tizen; #endif namespace Microsoft.Maui.Controls.Hosting @@ -111,9 +113,13 @@ namespace Microsoft.Maui.Controls.Hosting handlersCollection.AddHandler(typeof(FlyoutPage), typeof(Handlers.Compatibility.PhoneFlyoutPageRenderer)); #endif -#if ANDROID || IOS || MACCATALYST +#if ANDROID || IOS || MACCATALYST || TIZEN handlersCollection.AddHandler(); +#if ANDROID || IOS || MACCATALYST handlersCollection.AddHandler(); +#else + handlersCollection.AddHandler(); +#endif #endif #if WINDOWS || ANDROID handlersCollection.AddHandler(); @@ -133,7 +139,7 @@ namespace Microsoft.Maui.Controls.Hosting static MauiAppBuilder SetupDefaults(this MauiAppBuilder builder) { -#if WINDOWS || ANDROID || IOS || MACCATALYST +#if WINDOWS || ANDROID || IOS || MACCATALYST || TIZEN // initialize compatibility DependencyService DependencyService.SetToInitialized(); DependencyService.Register(); diff --git a/src/Controls/src/Xaml/SimplifyOnPlatformVisitor.cs b/src/Controls/src/Xaml/SimplifyOnPlatformVisitor.cs index 08ffe825be..2c545e7ddc 100644 --- a/src/Controls/src/Xaml/SimplifyOnPlatformVisitor.cs +++ b/src/Controls/src/Xaml/SimplifyOnPlatformVisitor.cs @@ -60,6 +60,12 @@ namespace Microsoft.Maui.Controls.Xaml if (TargetFramework.Contains("-maccatalyst", StringComparison.Ordinal)) #endif target = nameof(OnPlatformExtension.MacCatalyst); +#if NETSTANDARD2_0 + if (TargetFramework.Contains("-tizen")) +#else + if (TargetFramework.Contains("-tizen", StringComparison.Ordinal)) +#endif + target = nameof(OnPlatformExtension.Tizen); if (target is null) return; diff --git a/src/Core/src/ActivationState.cs b/src/Core/src/ActivationState.cs index 6f313d4f87..7475226bf3 100644 --- a/src/Core/src/ActivationState.cs +++ b/src/Core/src/ActivationState.cs @@ -22,6 +22,12 @@ namespace Microsoft.Maui { LaunchActivatedEventArgs = launchActivatedEventArgs; } +#elif TIZEN + public ActivationState(IMauiContext context, Tizen.Applications.Bundle? savedInstance) + : this(context, GetPersistedState(savedInstance)) + { + SavedInstance = savedInstance; + } #endif public ActivationState(IMauiContext context) @@ -44,6 +50,8 @@ namespace Microsoft.Maui public Android.OS.Bundle? SavedInstance { get; } #elif WINDOWS public UI.Xaml.LaunchActivatedEventArgs? LaunchActivatedEventArgs { get; } +#elif TIZEN + public Tizen.Applications.Bundle? SavedInstance { get; } #endif #if __ANDROID__ @@ -83,6 +91,22 @@ namespace Microsoft.Maui return state; } +#elif TIZEN + static IPersistedState GetPersistedState(Tizen.Applications.Bundle? state) + { + var dict = new PersistedState(); + + var keyset = state?.Keys; + if (keyset != null) + { + foreach (var k in keyset) + { + dict[k] = state?.GetItem(k); + } + } + + return dict; + } #endif } } \ No newline at end of file diff --git a/src/Core/src/Animations/PlatformTicker.Tizen.cs b/src/Core/src/Animations/PlatformTicker.Tizen.cs new file mode 100644 index 0000000000..f88c87a439 --- /dev/null +++ b/src/Core/src/Animations/PlatformTicker.Tizen.cs @@ -0,0 +1,42 @@ +using System.Threading; +using Tizen.Applications; + +namespace Microsoft.Maui.Animations +{ + public class PlatformTicker : Ticker + { + readonly Timer _timer; + readonly SynchronizationContext? _context; + bool _isRunning; + + public override bool IsRunning => _isRunning; + + public PlatformTicker() + { + if (SynchronizationContext.Current == null) + { + TizenSynchronizationContext.Initialize(); + } + + _context = SynchronizationContext.Current; + _timer = new Timer((object? o) => HandleElapsed(o), this, Timeout.Infinite, Timeout.Infinite); + } + + public override void Start() + { + _timer.Change(16, 16); + _isRunning = true; + } + + public override void Stop() + { + _timer.Change(-1, -1); + _isRunning = false; + } + + void HandleElapsed(object? state) + { + _context?.Post((o) => Fire?.Invoke(), null); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Core.csproj b/src/Core/src/Core.csproj index 80ef4c3e45..66f78946eb 100644 --- a/src/Core/src/Core.csproj +++ b/src/Core/src/Core.csproj @@ -18,6 +18,9 @@ + + + diff --git a/src/Core/src/Dispatching/Dispatcher.Tizen.cs b/src/Core/src/Dispatching/Dispatcher.Tizen.cs new file mode 100644 index 0000000000..4711b8cc6a --- /dev/null +++ b/src/Core/src/Dispatching/Dispatcher.Tizen.cs @@ -0,0 +1,108 @@ +using System; +using System.Threading; + +namespace Microsoft.Maui.Dispatching +{ + public partial class Dispatcher : IDispatcher + { + readonly SynchronizationContext _context; + + internal Dispatcher(SynchronizationContext context) + { + _context = context; + } + + bool IsDispatchRequiredImplementation() => + _context != SynchronizationContext.Current; + + bool DispatchImplementation(Action action) + { + _context.Post((o) => action(), null); + return true; + } + + bool DispatchDelayedImplementation(TimeSpan delay, Action action) + { + Timer? timer = null; + TimerCallback onTimeout = o => + { + _context.Post((o) => action(), null); + timer?.Dispose(); + }; + timer = new Timer(onTimeout, null, Timeout.Infinite, Timeout.Infinite); + timer?.Change(delay, delay); + return true; + } + + IDispatcherTimer CreateTimerImplementation() + { + return new DispatcherTimer(_context); + } + } + + partial class DispatcherTimer : IDispatcherTimer + { + readonly SynchronizationContext _context; + readonly Timer _timer; + + public DispatcherTimer(SynchronizationContext context) + { + _context = context; + _timer = new Timer((object? state) => _context.Post(OnTimerTick, null), null, Timeout.Infinite, Timeout.Infinite); + } + + public TimeSpan Interval { get; set; } + + public bool IsRepeating { get; set; } + + public bool IsRunning { get; private set; } + + public event EventHandler? Tick; + + public void Start() + { + if (IsRunning) + return; + + IsRunning = true; + // set interval separarately to prevent calling callback before `timer' is assigned + _timer.Change(Interval, Interval); + } + + public void Stop() + { + if (!IsRunning) + return; + + IsRunning = false; + + _timer.Change(Timeout.Infinite, Timeout.Infinite); + } + + + void OnTimerTick(object? state) + { + if (!IsRunning) + return; + + Tick?.Invoke(this, EventArgs.Empty); + + if (!IsRepeating) + { + _timer.Change(Timeout.Infinite, Timeout.Infinite); + } + } + } + + public partial class DispatcherProvider + { + static IDispatcher? GetForCurrentThreadImplementation() + { + var context = SynchronizationContext.Current; + if (context == null) + return null; + + return new Dispatcher(context); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs b/src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs new file mode 100644 index 0000000000..10b13494cf --- /dev/null +++ b/src/Core/src/Fonts/EmbeddedFontLoader.Tizen.cs @@ -0,0 +1,55 @@ +using System; +using System.Diagnostics; +using System.IO; +using ElmSharp; +using Tizen.Common; +using IOPath = System.IO.Path; +using TApplication = Tizen.Applications.Application; + +namespace Microsoft.Maui +{ + public partial class EmbeddedFontLoader : IEmbeddedFontLoader + { + const string _fontCacheFolderName = "fonts"; + + public DirectoryInfo? FontCacheDirectory { get; private set; } + + public string? LoadFont(EmbeddedFont font) + { + if (FontCacheDirectory == null) + { + FontCacheDirectory = Directory.CreateDirectory(IOPath.Combine(TApplication.Current.DirectoryInfo.Data, _fontCacheFolderName)); + Utility.AppendGlobalFontPath(FontCacheDirectory.FullName); + } + + var filePath = IOPath.Combine(FontCacheDirectory.FullName, font.FontName!); + var name = IOPath.GetFileNameWithoutExtension(filePath); + if (File.Exists(filePath)) + return name; + try + { + using (var fileStream = File.Create(filePath)) + { + if (font.ResourceStream == null) + throw new InvalidOperationException("ResourceStream was null."); + + font.ResourceStream.CopyTo(fileStream); + } + +#if __TIZEN__ + if (DotnetUtil.TizenAPIVersion > 5) + { + Utility.FontReinit(); + } +#endif + return name; + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + File.Delete(filePath); + } + return null; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Fonts/FontManager.Tizen.cs b/src/Core/src/Fonts/FontManager.Tizen.cs new file mode 100644 index 0000000000..83b070ac57 --- /dev/null +++ b/src/Core/src/Fonts/FontManager.Tizen.cs @@ -0,0 +1,107 @@ +using System; +using System.IO; +using System.Collections.Concurrent; + +namespace Microsoft.Maui +{ + public class FontManager : IFontManager + { + readonly ConcurrentDictionary<(string? family, float size, FontSlant slant), string> _fonts = new(); + + readonly IFontRegistrar _fontRegistrar; + readonly IServiceProvider? _serviceProvider; + + public double DefaultFontSize => 14; // 14sp + + public FontManager(IFontRegistrar fontRegistrar, IServiceProvider? serviceProvider = null) + { + _fontRegistrar = fontRegistrar; + _serviceProvider = serviceProvider; + } + + + public string GetFont(Font font) + { + var size = (float)font.Size; + + return GetFont(font.Family, size, font.Slant, GetNativeFontFamily); + } + + public string GetFontFamily(string? fontFamliy) + { + if (string.IsNullOrEmpty(fontFamliy)) + return ""; + + var cleansedFont = CleanseFontName(fontFamliy??string.Empty); + if (cleansedFont == null) + return ""; + + int index = cleansedFont.LastIndexOf('-'); + if (index != -1) + { + string font = cleansedFont.Substring(0, index); + string style = cleansedFont.Substring(index + 1); + return $"{font}:style={style}"; + } + else + { + return cleansedFont; + } + } + + string GetFont(string? family, float size, FontSlant slant, Func<(string?, float, FontSlant), string> factory) + { + return _fonts.GetOrAdd((family, size, slant), factory); + } + + string GetNativeFontFamily((string? family, float size, FontSlant slant) fontKey) + { + if (string.IsNullOrEmpty(fontKey.family)) + return ""; + + var cleansedFont = CleanseFontName(fontKey.family??string.Empty); + + if (cleansedFont == null) + return ""; + + int index = cleansedFont.LastIndexOf('-'); + if (index != -1) + { + string font = cleansedFont.Substring(0, index); + string style = cleansedFont.Substring(index + 1); + return $"{font}:style={style}"; + } + else + { + return cleansedFont; + } + } + + string? CleanseFontName(string fontName) + { + // First check Alias + if (_fontRegistrar.GetFont(fontName) is string fontPostScriptName) + return fontPostScriptName; + + var fontFile = FontFile.FromString(fontName); + + if (!string.IsNullOrWhiteSpace(fontFile.Extension)) + { + if (_fontRegistrar.GetFont(fontFile.FileNameWithExtension()) is string filePath) + return filePath ?? fontFile.PostScriptName; + } + else + { + foreach (var ext in FontFile.Extensions) + { + + var formatted = fontFile.FileNameWithExtension(ext); + if (_fontRegistrar.GetFont(formatted) is string filePath) + return filePath; + } + } + + return fontFile.PostScriptName; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Fonts/FontRegistrar.Tizen.cs b/src/Core/src/Fonts/FontRegistrar.Tizen.cs new file mode 100644 index 0000000000..8915d20e89 --- /dev/null +++ b/src/Core/src/Fonts/FontRegistrar.Tizen.cs @@ -0,0 +1,26 @@ +#nullable enable +using System.IO; + +namespace Microsoft.Maui +{ + public partial class FontRegistrar : IFontRegistrar + { + string? LoadNativeAppFont(string font, string filename, string? alias) + { + using var stream = GetNativeFontStream(filename, alias); + + return LoadEmbeddedFont(font, filename, alias, stream); + } + + Stream GetNativeFontStream(string filename, string? alias) + { + // TODO: check other folders as well + var resDirPath = Tizen.Applications.Application.Current.DirectoryInfo.Resource; + var fontPath = Path.Combine(resDirPath, "fonts", filename); + if (File.Exists(fontPath)) + return File.OpenRead(fontPath); + + throw new FileNotFoundException($"Native font with the name {filename} was not found."); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Fonts/IFontManager.Tizen.cs b/src/Core/src/Fonts/IFontManager.Tizen.cs new file mode 100644 index 0000000000..c6ee0c3974 --- /dev/null +++ b/src/Core/src/Fonts/IFontManager.Tizen.cs @@ -0,0 +1,9 @@ +namespace Microsoft.Maui +{ + public partial interface IFontManager + { + string GetFont(Font font); + + string GetFontFamily(string? font); + } +} \ No newline at end of file diff --git a/src/Core/src/Graphics/MauiDrawable.Tizen.cs b/src/Core/src/Graphics/MauiDrawable.Tizen.cs new file mode 100644 index 0000000000..a99614a25d --- /dev/null +++ b/src/Core/src/Graphics/MauiDrawable.Tizen.cs @@ -0,0 +1,89 @@ +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui +{ + public class MauiDrawable : IDrawable + { + public IShadow? Shadow { get; set; } + + public Paint? Background { get; set; } + + public IBorderStroke? Border { get; set; } + + public Thickness ShadowThickness { get; set; } + + public IShape? Shape { get; set; } + + public IShape? Clip { get; set; } + + PathF GetBoundaryPath(Rect bounds) + { + if (Clip != null) + { + return Clip.PathForBounds(bounds); + } + + if (Shape != null) + { + return Shape.PathForBounds(bounds); + } + + var path = new PathF(); + path.AppendRectangle(bounds); + return path; + } + + public void Draw(ICanvas canvas, RectF dirtyRect) + { + canvas.SaveState(); + canvas.Translate((float)ShadowThickness.Left, (float)ShadowThickness.Top); + RectF drawBounds = new Rect(0, 0, dirtyRect.Width - ShadowThickness.HorizontalThickness, dirtyRect.Height - ShadowThickness.VerticalThickness); + var drawablePath = GetBoundaryPath(drawBounds); + + if (Shadow != null) + { + canvas.SaveState(); + Color color = Shadow.Paint.ToColor() != null ? Shadow.Paint.ToColor()!.MultiplyAlpha(Shadow.Opacity) : Colors.Black.MultiplyAlpha(Shadow.Opacity); + canvas.FillColor = color; + canvas.SetShadow( + new SizeF((float)Shadow.Offset.X, (float)Shadow.Offset.Y), + (int)Shadow.Radius, + color); + canvas.FillPath(drawablePath); + canvas.RestoreState(); + + canvas.SaveState(); + canvas.StrokeColor = Colors.Transparent; + canvas.DrawPath(drawablePath); + canvas.ClipPath(drawablePath, WindingMode.EvenOdd); + canvas.RestoreState(); + } + + if (Background != null) + { + canvas.SaveState(); + canvas.SetFillPaint(Background, drawBounds); + canvas.FillPath(drawablePath); + canvas.RestoreState(); + } + + if (Border != null) + { + canvas.SaveState(); + var borderPath = Border.Shape?.PathForBounds(drawBounds); + if (borderPath != null) + { + canvas.MiterLimit = Border.StrokeMiterLimit; + canvas.StrokeColor = Border.Stroke.ToColor(); + canvas.StrokeDashPattern = Border.StrokeDashPattern; + canvas.StrokeLineCap = Border.StrokeLineCap; + canvas.StrokeLineJoin = Border.StrokeLineJoin; + canvas.StrokeSize = (float)Border.StrokeThickness; + canvas.DrawPath(borderPath); + } + canvas.RestoreState(); + } + canvas.RestoreState(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Graphics/PaintExtensions.Tizen.cs b/src/Core/src/Graphics/PaintExtensions.Tizen.cs new file mode 100644 index 0000000000..f683d214fe --- /dev/null +++ b/src/Core/src/Graphics/PaintExtensions.Tizen.cs @@ -0,0 +1,82 @@ +using TColor = Tizen.UIExtensions.Common.Color; + +namespace Microsoft.Maui.Graphics +{ + public static partial class PaintExtensions + { + public static TColor ToPlatform(this Paint paint) + { + var color = paint.ToColor(); + return color != null ? color.ToPlatform() : TColor.Default; + } + + public static MauiDrawable? ToDrawable(this Paint paint) + { + if (paint is SolidPaint solidPaint) + return solidPaint.CreateDrawable(); + + if (paint is LinearGradientPaint linearGradientPaint) + return linearGradientPaint.CreateDrawable(); + + if (paint is RadialGradientPaint radialGradientPaint) + return radialGradientPaint.CreateDrawable(); + + if (paint is ImagePaint imagePaint) + return imagePaint.CreateDrawable(); + + if (paint is PatternPaint patternPaint) + return patternPaint.CreateDrawable(); + + return null; + } + + public static MauiDrawable? CreateDrawable(this SolidPaint solidPaint) + { + return new MauiDrawable + { + Background = solidPaint + }; + } + + public static MauiDrawable? CreateDrawable(this LinearGradientPaint linearGradientPaint) + { + if (!linearGradientPaint.IsValid()) + return null; + + return new MauiDrawable + { + Background = linearGradientPaint + }; + } + + public static MauiDrawable? CreateDrawable(this RadialGradientPaint radialGradientPaint) + { + if (!radialGradientPaint.IsValid()) + return null; + + return new MauiDrawable + { + Background = radialGradientPaint + }; + } + + public static MauiDrawable? CreateDrawable(this ImagePaint imagePaint) + { + return new MauiDrawable + { + Background = imagePaint + }; + } + + public static MauiDrawable? CreateDrawable(this PatternPaint patternPaint) + { + return new MauiDrawable + { + Background = patternPaint + }; + } + + static bool IsValid(this GradientPaint? gradienPaint) => + gradienPaint?.GradientStops?.Length > 0; + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.Tizen.cs b/src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.Tizen.cs new file mode 100644 index 0000000000..ab1eced9f8 --- /dev/null +++ b/src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.Tizen.cs @@ -0,0 +1,28 @@ +using Tizen.UIExtensions.ElmSharp; +using EColor = ElmSharp.Color; +using EProgressBar = ElmSharp.ProgressBar; + +namespace Microsoft.Maui.Handlers +{ + public partial class ActivityIndicatorHandler : ViewHandler + { + protected virtual EColor DefaultColor => ThemeConstants.ProgressBar.ColorClass.Default; + + protected override EProgressBar CreatePlatformView() + { + var progressBar = new EProgressBar(NativeParent) { IsPulseMode = true }.SetSmallStyle(); + progressBar.Color = DefaultColor; + return progressBar; + } + + public static void MapIsRunning(IActivityIndicatorHandler handler, IActivityIndicator activityIndicator) + { + handler.PlatformView?.UpdateIsRunning(activityIndicator); + } + + public static void MapColor(IActivityIndicatorHandler handler, IActivityIndicator activityIndicator) + { + handler.PlatformView?.UpdateColor(activityIndicator); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.cs b/src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.cs index 70d8198c86..5922ecfc0e 100644 --- a/src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.cs +++ b/src/Core/src/Handlers/ActivityIndicator/ActivityIndicatorHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiActivityIndicator; using PlatformView = Android.Widget.ProgressBar; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ProgressRing; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.ProgressBar; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ActivityIndicator/IActivityIndicatorHandler.cs b/src/Core/src/Handlers/ActivityIndicator/IActivityIndicatorHandler.cs index 58d2bce514..f0bc878d76 100644 --- a/src/Core/src/Handlers/ActivityIndicator/IActivityIndicatorHandler.cs +++ b/src/Core/src/Handlers/ActivityIndicator/IActivityIndicatorHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiActivityIndicator; using PlatformView = Android.Widget.ProgressBar; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ProgressRing; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.ProgressBar; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Application/ApplicationHandler.Tizen.cs b/src/Core/src/Handlers/Application/ApplicationHandler.Tizen.cs new file mode 100644 index 0000000000..b8c0d621c0 --- /dev/null +++ b/src/Core/src/Handlers/Application/ApplicationHandler.Tizen.cs @@ -0,0 +1,25 @@ +using Tizen.Applications; + +namespace Microsoft.Maui.Handlers +{ + public partial class ApplicationHandler : ElementHandler + { + public static void MapTerminate(ApplicationHandler handler, IApplication application, object? args) + { + handler.PlatformView.Exit(); + } + + public static void MapOpenWindow(ApplicationHandler handler, IApplication application, object? args) + { + handler.PlatformView?.RequestNewWindow(application, args as OpenWindowRequest); + } + + public static void MapCloseWindow(ApplicationHandler handler, IApplication application, object? args) + { + if (args is IWindow window) + { + //TODO : Need to implementation + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Application/ApplicationHandler.cs b/src/Core/src/Handlers/Application/ApplicationHandler.cs index d357e78d65..73ea47c328 100644 --- a/src/Core/src/Handlers/Application/ApplicationHandler.cs +++ b/src/Core/src/Handlers/Application/ApplicationHandler.cs @@ -7,6 +7,8 @@ using PlatformView = UIKit.IUIApplicationDelegate; using PlatformView = Android.App.Application; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Application; +#elif TIZEN +using PlatformView = Tizen.Applications.CoreApplication; #endif namespace Microsoft.Maui.Handlers diff --git a/src/Core/src/Handlers/Border/BorderHandler.Tizen.cs b/src/Core/src/Handlers/Border/BorderHandler.Tizen.cs new file mode 100644 index 0000000000..c258a0dd3a --- /dev/null +++ b/src/Core/src/Handlers/Border/BorderHandler.Tizen.cs @@ -0,0 +1,71 @@ +using System; + +namespace Microsoft.Maui.Handlers +{ + public partial class BorderHandler : ViewHandler + { + IPlatformViewHandler? _contentHandler; + + protected override BorderView CreatePlatformView() + { + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} must be set to create a Page"); + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} cannot be null"); + + var view = new BorderView(NativeParent, VirtualView) + { + CrossPlatformMeasure = VirtualView.CrossPlatformMeasure, + CrossPlatformArrange = VirtualView.CrossPlatformArrange + }; + view.Show(); + return view; + } + + protected override void SetupContainer() + { + base.SetupContainer(); + PlatformView.ContainerView = ContainerView; + } + + public override Graphics.Size GetDesiredSize(double widthConstraint, double heightConstraint) + { + return VirtualView.CrossPlatformMeasure(widthConstraint, heightConstraint); + } + + public override void SetVirtualView(IView view) + { + base.SetVirtualView(view); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + + PlatformView.CrossPlatformMeasure = VirtualView.CrossPlatformMeasure; + PlatformView.CrossPlatformArrange = VirtualView.CrossPlatformArrange; + } + + public static void MapContent(IBorderHandler handler, IBorderView border) + { + if (handler is BorderHandler borderHandler) + borderHandler.UpdateContent(); + } + + void UpdateContent() + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + PlatformView.Children.Clear(); + _contentHandler?.Dispose(); + _contentHandler = null; + + if (VirtualView.PresentedContent is IView view) + { + PlatformView.Children.Add(view.ToPlatform(MauiContext)); + if (view.Handler is IPlatformViewHandler thandler) + { + thandler?.SetParent(this); + _contentHandler = thandler; + } + } + } + } +} diff --git a/src/Core/src/Handlers/Border/BorderHandler.cs b/src/Core/src/Handlers/Border/BorderHandler.cs index 4299a9b7f1..cc37c2ed25 100644 --- a/src/Core/src/Handlers/Border/BorderHandler.cs +++ b/src/Core/src/Handlers/Border/BorderHandler.cs @@ -5,6 +5,8 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.ContentPanel; +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.BorderView; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Border/IBorderHandler.cs b/src/Core/src/Handlers/Border/IBorderHandler.cs index 4583eb91c1..d6360fe83c 100644 --- a/src/Core/src/Handlers/Border/IBorderHandler.cs +++ b/src/Core/src/Handlers/Border/IBorderHandler.cs @@ -5,6 +5,8 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.ContentPanel; +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.BorderView; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Button/ButtonHandler.Tizen.cs b/src/Core/src/Handlers/Button/ButtonHandler.Tizen.cs new file mode 100644 index 0000000000..4301ae2c30 --- /dev/null +++ b/src/Core/src/Handlers/Button/ButtonHandler.Tizen.cs @@ -0,0 +1,95 @@ +using System; +using System.Threading.Tasks; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class ButtonHandler : ViewHandler + { + protected override Button CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + return new Button(NativeParent); + } + + protected override void ConnectHandler(Button platformView) + { + platformView.Released += OnButtonReleased; + platformView.Clicked += OnButtonClicked; + platformView.Pressed += OnButtonPressed; + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(Button platformView) + { + platformView.Released -= OnButtonReleased; + platformView.Clicked -= OnButtonClicked; + platformView.Pressed -= OnButtonPressed; + base.DisconnectHandler(platformView); + } + + public static void MapText(IButtonHandler handler, IText button) + { + handler.PlatformView?.UpdateText(button); + } + + public static void MapTextColor(IButtonHandler handler, ITextStyle button) + { + handler.PlatformView?.UpdateTextColor(button); + } + + public static void MapImageSource(IButtonHandler handler, IImage image) => + MapImageSourceAsync(handler, image).FireAndForget(handler); + + public static Task MapImageSourceAsync(IButtonHandler handler, IImage image) + { + if (image.Source == null) + { + return Task.CompletedTask; + } + return handler.ImageSourceLoader.UpdateImageSourceAsync(); + } + + [MissingMapper] + public static void MapCharacterSpacing(IButtonHandler handler, ITextStyle button) { } + + [MissingMapper] + public static void MapFont(IButtonHandler handler, ITextStyle button) { } + + [MissingMapper] + public static void MapPadding(IButtonHandler handler, IButton button) { } + + [MissingMapper] + public static void MapStrokeColor(IButtonHandler handler, IButtonStroke buttonStroke) { } + + [MissingMapper] + public static void MapStrokeThickness(IButtonHandler handler, IButtonStroke buttonStroke) { } + + [MissingMapper] + public static void MapCornerRadius(IButtonHandler handler, IButtonStroke buttonStroke) { } + + [MissingMapper] + public static void MapLineBreakMode(IButtonHandler handler, IButton button) { } + + void OnButtonClicked(object? sender, EventArgs e) + { + VirtualView?.Clicked(); + } + + void OnButtonReleased(object? sender, EventArgs e) + { + VirtualView?.Released(); + } + + void OnButtonPressed(object? sender, EventArgs e) + { + VirtualView?.Pressed(); + } + + void OnSetImageSource(Image? image) + { + PlatformView.Image = image; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Button/ButtonHandler.cs b/src/Core/src/Handlers/Button/ButtonHandler.cs index aa81a3b303..06e6a8c5d8 100644 --- a/src/Core/src/Handlers/Button/ButtonHandler.cs +++ b/src/Core/src/Handlers/Button/ButtonHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIButton; using PlatformView = Google.Android.Material.Button.MaterialButton; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Button; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Button; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Button/IButtonHandler.cs b/src/Core/src/Handlers/Button/IButtonHandler.cs index 7c097ad3ac..94e7159156 100644 --- a/src/Core/src/Handlers/Button/IButtonHandler.cs +++ b/src/Core/src/Handlers/Button/IButtonHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIButton; using PlatformView = Google.Android.Material.Button.MaterialButton; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Button; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Button; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif @@ -16,4 +18,4 @@ namespace Microsoft.Maui.Handlers new PlatformView PlatformView { get; } ImageSourcePartLoader ImageSourceLoader { get; } } -} \ No newline at end of file +} diff --git a/src/Core/src/Handlers/CheckBox/CheckBoxHandler.Tizen.cs b/src/Core/src/Handlers/CheckBox/CheckBoxHandler.Tizen.cs new file mode 100644 index 0000000000..15b50c0f24 --- /dev/null +++ b/src/Core/src/Handlers/CheckBox/CheckBoxHandler.Tizen.cs @@ -0,0 +1,41 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class CheckBoxHandler : ViewHandler + { + protected override Check CreatePlatformView() => new Check(NativeParent); + + protected override void ConnectHandler(Check platformView) + { + base.ConnectHandler(platformView); + platformView.StateChanged += OnStateChanged; + } + + protected override void DisconnectHandler(Check platformView) + { + base.DisconnectHandler(platformView); + platformView.StateChanged -= OnStateChanged; + } + + public static void MapIsChecked(ICheckBoxHandler handler, ICheckBox check) + { + handler.PlatformView?.UpdateIsChecked(check); + } + + public static void MapForeground(ICheckBoxHandler handler, ICheckBox check) + { + handler.PlatformView?.UpdateForeground(check); + } + + void OnStateChanged(object? sender, EventArgs e) + { + if (VirtualView == null) + return; + + if (PlatformView != null) + VirtualView.IsChecked = PlatformView.IsChecked; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/CheckBox/CheckBoxHandler.cs b/src/Core/src/Handlers/CheckBox/CheckBoxHandler.cs index a6bbab0931..668efe6c32 100644 --- a/src/Core/src/Handlers/CheckBox/CheckBoxHandler.cs +++ b/src/Core/src/Handlers/CheckBox/CheckBoxHandler.cs @@ -5,6 +5,8 @@ using PlatformView = Microsoft.Maui.Platform.MauiCheckBox; using PlatformView = AndroidX.AppCompat.Widget.AppCompatCheckBox; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.CheckBox; +#elif TIZEN +using PlatformView = ElmSharp.Check; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/CheckBox/ICheckboxHandler.cs b/src/Core/src/Handlers/CheckBox/ICheckboxHandler.cs index 57fed104b9..0248931ace 100644 --- a/src/Core/src/Handlers/CheckBox/ICheckboxHandler.cs +++ b/src/Core/src/Handlers/CheckBox/ICheckboxHandler.cs @@ -5,6 +5,8 @@ using PlatformView = Microsoft.Maui.Platform.MauiCheckBox; using PlatformView = AndroidX.AppCompat.Widget.AppCompatCheckBox; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.CheckBox; +#elif TIZEN +using PlatformView = ElmSharp.Check; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ContentView/ContentViewHandler.Tizen.cs b/src/Core/src/Handlers/ContentView/ContentViewHandler.Tizen.cs new file mode 100644 index 0000000000..88182d8492 --- /dev/null +++ b/src/Core/src/Handlers/ContentView/ContentViewHandler.Tizen.cs @@ -0,0 +1,77 @@ +using System; +using PlatformView = ElmSharp.EvasObject; +using EColor = ElmSharp.Color; +using Tizen.UIExtensions.Common; + +namespace Microsoft.Maui.Handlers +{ + public partial class ContentViewHandler : ViewHandler + { + IPlatformViewHandler? _contentHandler; + + protected override ContentCanvas CreatePlatformView() + { + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} must be set to create a Page"); + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} cannot be null"); + + var view = new ContentCanvas(NativeParent, VirtualView) + { + CrossPlatformMeasure = VirtualView.CrossPlatformMeasure, + CrossPlatformArrange = VirtualView.CrossPlatformArrange + }; + + view.Show(); + return view; + } + + public override Graphics.Size GetDesiredSize(double widthConstraint, double heightConstraint) + { + return VirtualView.CrossPlatformMeasure(widthConstraint, heightConstraint); + } + + public override void SetVirtualView(IView view) + { + base.SetVirtualView(view); + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + + PlatformView.CrossPlatformMeasure = VirtualView.CrossPlatformMeasure; + PlatformView.CrossPlatformArrange = VirtualView.CrossPlatformArrange; + } + + public static void MapBackground(IContentViewHandler handler, IContentView view) + { + handler.UpdateValue(nameof(handler.ContainerView)); + handler.ToPlatform()?.UpdateBackground(view); + } + + public static void MapContent(IContentViewHandler handler, IContentView page) + { + if (handler is ContentViewHandler contentViewHandler) + { + contentViewHandler.UpdateContent(); + } + } + + void UpdateContent() + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + PlatformView.Children.Clear(); + _contentHandler?.Dispose(); + _contentHandler = null; + + if (VirtualView.PresentedContent is IView view) + { + PlatformView.Children.Add(view.ToPlatform(MauiContext)); + if (view.Handler is IPlatformViewHandler thandler) + { + thandler?.SetParent(this); + _contentHandler = thandler; + } + } + } + } +} diff --git a/src/Core/src/Handlers/ContentView/ContentViewHandler.cs b/src/Core/src/Handlers/ContentView/ContentViewHandler.cs index ad54f36acd..f01dd14f83 100644 --- a/src/Core/src/Handlers/ContentView/ContentViewHandler.cs +++ b/src/Core/src/Handlers/ContentView/ContentViewHandler.cs @@ -5,7 +5,9 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.ContentPanel; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.ContentCanvas; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif @@ -16,6 +18,9 @@ namespace Microsoft.Maui.Handlers public static IPropertyMapper Mapper = new PropertyMapper(ViewMapper) { [nameof(IContentView.Content)] = MapContent, +#if TIZEN + [nameof(IContentView.Background)] = MapBackground, +#endif }; public static CommandMapper CommandMapper = new(ViewCommandMapper) diff --git a/src/Core/src/Handlers/ContentView/IContentViewHandler.cs b/src/Core/src/Handlers/ContentView/IContentViewHandler.cs index a8dc3cd346..b4f4b2eb45 100644 --- a/src/Core/src/Handlers/ContentView/IContentViewHandler.cs +++ b/src/Core/src/Handlers/ContentView/IContentViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.ContentPanel; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.ContentCanvas; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/DatePicker/DatePickerHandler.Tizen.cs b/src/Core/src/Handlers/DatePicker/DatePickerHandler.Tizen.cs new file mode 100644 index 0000000000..f08f407da7 --- /dev/null +++ b/src/Core/src/Handlers/DatePicker/DatePickerHandler.Tizen.cs @@ -0,0 +1,136 @@ +using System; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using TEntry = Tizen.UIExtensions.ElmSharp.Entry; +using TTextAlignment = Tizen.UIExtensions.Common.TextAlignment; +using EcoreMainloop = ElmSharp.EcoreMainloop; + +namespace Microsoft.Maui.Handlers +{ + public partial class DatePickerHandler : ViewHandler + { + const string DialogTitle = "Choose Date"; + Lazy? _lazyDialog; + + protected override TEntry CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + var entry = new EditfieldEntry(NativeParent) + { + IsSingleLine = true, + HorizontalTextAlignment = TTextAlignment.Center, + InputPanelShowByOnDemand = true, + IsEditable = false + }; + entry.SetVerticalTextAlignment(0.5); + return entry; + } + + protected override void ConnectHandler(TEntry platformView) + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + platformView.TextBlockFocused += OnTextBlockFocused; + platformView.EntryLayoutFocused += OnFocused; + platformView.EntryLayoutUnfocused += OnUnfocused; + + _lazyDialog = new Lazy(() => + { + var dialog = new DateTimePickerDialog(NativeParent) + { + Title = DialogTitle + }; + dialog.DateTimeChanged += OnDateTimeChanged; + dialog.PickerOpened += OnPickerOpened; + dialog.PickerClosed += OnPickerClosed; + return dialog; + }); + + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(TEntry platformView) + { + if (_lazyDialog != null && _lazyDialog.IsValueCreated) + { + _lazyDialog.Value.DateTimeChanged -= OnDateTimeChanged; + _lazyDialog.Value.PickerOpened -= OnPickerOpened; + _lazyDialog.Value.PickerClosed -= OnPickerClosed; + _lazyDialog.Value.Unrealize(); + _lazyDialog = null; + } + + platformView.TextBlockFocused -= OnTextBlockFocused; + platformView.EntryLayoutFocused -= OnFocused; + platformView.EntryLayoutUnfocused -= OnUnfocused; + + base.DisconnectHandler(platformView); + } + + public static void MapFormat(IDatePickerHandler handler, IDatePicker datePicker) + { + handler.PlatformView?.UpdateFormat(datePicker); + } + + public static void MapDate(IDatePickerHandler handler, IDatePicker datePicker) + { + handler.PlatformView?.UpdateDate(datePicker); + } + + public static void MapFont(IDatePickerHandler handler, IDatePicker datePicker) + { + var fontManager = handler.GetRequiredService(); + handler.PlatformView?.UpdateFont(datePicker, fontManager); + } + + public static void MapTextColor(IDatePickerHandler handler, IDatePicker datePicker) + { + handler.PlatformView?.UpdateTextColor(datePicker); + } + + [MissingMapper] + public static void MapMinimumDate(IDatePickerHandler handler, IDatePicker datePicker) { } + + [MissingMapper] + public static void MapMaximumDate(IDatePickerHandler handler, IDatePicker datePicker) { } + + [MissingMapper] + public static void MapCharacterSpacing(IDatePickerHandler handler, IDatePicker datePicker) { } + + protected virtual void OnDateTimeChanged(object? sender, DateChangedEventArgs dcea) + { + if (VirtualView == null || PlatformView == null) + return; + + VirtualView.Date = dcea.NewDate.Date; + } + + void OnTextBlockFocused(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null || _lazyDialog == null) + return; + + // For EFL Entry, the event will occur even if it is currently disabled. + // If the problem is resolved, no conditional statement is required. + if (VirtualView.IsEnabled) + { + var dialog = _lazyDialog.Value; + dialog.DateTime = VirtualView.Date; + dialog.MaximumDateTime = VirtualView.MaximumDate; + dialog.MinimumDateTime = VirtualView.MinimumDate; + // You need to call Show() after ui thread occupation because of EFL problem. + // Otherwise, the content of the popup will not receive focus. + EcoreMainloop.Post(() => dialog.Show()); + } + } + + protected virtual void OnPickerOpened(object? sender, EventArgs args) + { + } + + protected virtual void OnPickerClosed(object? sender, EventArgs args) + { + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/DatePicker/DatePickerHandler.cs b/src/Core/src/Handlers/DatePicker/DatePickerHandler.cs index fbabeb8cc5..840ae24b7b 100644 --- a/src/Core/src/Handlers/DatePicker/DatePickerHandler.cs +++ b/src/Core/src/Handlers/DatePicker/DatePickerHandler.cs @@ -6,7 +6,9 @@ using PlatformView = UIKit.UIDatePicker; using PlatformView = Microsoft.Maui.Platform.MauiDatePicker; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.CalendarDatePicker; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/DatePicker/IDatePickerHandler.cs b/src/Core/src/Handlers/DatePicker/IDatePickerHandler.cs index f90ab7af18..f4c684e4d9 100644 --- a/src/Core/src/Handlers/DatePicker/IDatePickerHandler.cs +++ b/src/Core/src/Handlers/DatePicker/IDatePickerHandler.cs @@ -6,7 +6,9 @@ using PlatformView = UIKit.UIDatePicker; using PlatformView = Microsoft.Maui.Platform.MauiDatePicker; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.CalendarDatePicker; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Editor/EditorHandler.Tizen.cs b/src/Core/src/Handlers/Editor/EditorHandler.Tizen.cs new file mode 100644 index 0000000000..1a0ce4ba3c --- /dev/null +++ b/src/Core/src/Handlers/Editor/EditorHandler.Tizen.cs @@ -0,0 +1,170 @@ +using System; +using Tizen.UIExtensions.ElmSharp; +using EEntry = ElmSharp.Entry; + +namespace Microsoft.Maui.Handlers +{ + public partial class EditorHandler : ViewHandler + { + protected override Entry CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + return new EditfieldEntry(NativeParent, EditFieldEntryLayout.Styles.MulitLine) + { + IsSingleLine = false + }; + } + + protected override void ConnectHandler(Entry platformView) + { + platformView.Focused += OnEntryFocused; + platformView.Unfocused += OnEntryUnfocused; + platformView.Unfocused += OnCompleted; + platformView.PrependMarkUpFilter(MaxLengthFilter); + platformView.TextChanged += OnTextChanged; + } + + protected override void DisconnectHandler(Entry platformView) + { + platformView.BackButtonPressed -= OnCompleted; + platformView.Unfocused -= OnEntryUnfocused; + platformView.Focused -= OnEntryFocused; + platformView.TextChanged -= OnTextChanged; + } + + public static void MapBackground(IEditorHandler handler, IEditor editor) + { + handler.UpdateValue(nameof(handler.ContainerView)); + handler.ToPlatform()?.UpdateBackground(editor); + } + + public static void MapText(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateText(editor); + + // Any text update requires that we update any attributed string formatting + MapFormatting(handler, editor); + } + + public static void MapTextColor(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateTextColor(editor); + } + + public static void MapPlaceholder(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdatePlaceholder(editor); + } + + public static void MapPlaceholderColor(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdatePlaceholderColor(editor); + } + + public static void MapMaxLength(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateMaxLength(editor); + } + + public static void MapIsReadOnly(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateIsReadOnly(editor); + } + + public static void MapIsTextPredictionEnabled(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateIsTextPredictionEnabled(editor); + } + + public static void MapFont(IEditorHandler handler, IEditor editor) + { + var fontManager = handler.GetRequiredService(); + + handler.PlatformView?.UpdateFont(editor, fontManager); + } + + public static void MapFormatting(IEditorHandler handler, IEditor editor) + { + // Update all of the attributed text formatting properties + handler.PlatformView?.UpdateMaxLength(editor); + } + + public static void MapKeyboard(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateKeyboard(editor); + } + + public static void MapHorizontalTextAlignment(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateHorizontalTextAlignment(editor); + } + + public static void MapVerticalTextAlignment(IEditorHandler handler, IEditor editor) + { + handler.PlatformView?.UpdateVerticalTextAlignment(editor); + } + + public static void MapCursorPosition(IEditorHandler handler, ITextInput editor) + { + handler.PlatformView?.UpdateSelectionLength(editor); + } + + public static void MapSelectionLength(IEditorHandler handler, ITextInput editor) + { + handler.PlatformView?.UpdateSelectionLength(editor); + } + + [MissingMapper] + public static void MapCharacterSpacing(IEditorHandler handler, IEditor editor) { } + + string? MaxLengthFilter(EEntry entry, string s) + { + if (VirtualView == null || PlatformView == null) + return null; + + if (entry.Text.Length < VirtualView.MaxLength) + return s; + + return null; + } + + void OnTextChanged(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null) + return; + + VirtualView.Text = PlatformView.Text; + } + + + + void OnEntryFocused(object? sender, EventArgs e) + { + if (PlatformView == null) + return; + + // BackButtonPressed is only passed to the object that is at the highest Z-Order, and it does not propagate to lower objects. + // If you want to make Editor input completed by using BackButtonPressed, you should subscribe BackButtonPressed event only when Editor gets focused. + PlatformView.BackButtonPressed += OnCompleted; + } + + void OnEntryUnfocused(object? sender, EventArgs e) + { + if (PlatformView == null) + return; + + // BackButtonPressed is only passed to the object that is at the highest Z-Order, and it does not propagate to lower objects. + // When the object is unfocesed BackButtonPressed event has to be released to stop using it. + PlatformView.BackButtonPressed -= OnCompleted; + } + + void OnCompleted(object? sender, EventArgs e) + { + if (PlatformView == null) + return; + + PlatformView.SetFocus(false); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Editor/EditorHandler.cs b/src/Core/src/Handlers/Editor/EditorHandler.cs index 856dd88cc3..a82bc9d82c 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.cs @@ -5,7 +5,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiTextView; using PlatformView = AndroidX.AppCompat.Widget.AppCompatEditText; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TextBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Editor/IEditorHandler.cs b/src/Core/src/Handlers/Editor/IEditorHandler.cs index b2d7304117..a6d52b42b4 100644 --- a/src/Core/src/Handlers/Editor/IEditorHandler.cs +++ b/src/Core/src/Handlers/Editor/IEditorHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiTextView; using PlatformView = AndroidX.AppCompat.Widget.AppCompatEditText; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TextBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ElementHandlerExtensions.cs b/src/Core/src/Handlers/ElementHandlerExtensions.cs index 99b908f11c..1926db58f0 100644 --- a/src/Core/src/Handlers/ElementHandlerExtensions.cs +++ b/src/Core/src/Handlers/ElementHandlerExtensions.cs @@ -4,6 +4,8 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Entry/EntryHandler.Tizen.cs b/src/Core/src/Handlers/Entry/EntryHandler.Tizen.cs new file mode 100644 index 0000000000..720fd581ce --- /dev/null +++ b/src/Core/src/Handlers/Entry/EntryHandler.Tizen.cs @@ -0,0 +1,221 @@ +using System; +using Tizen.UIExtensions.ElmSharp; +using EEntry = ElmSharp.Entry; + +namespace Microsoft.Maui.Handlers +{ + public partial class EntryHandler : ViewHandler + { + + protected override Entry CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + return new EditfieldEntry(NativeParent) + { + IsSingleLine = true + }; + } + + protected override void ConnectHandler(Entry platformView) + { + platformView.Activated += OnCompleted; + platformView.CursorPositionChanged += OnCursorChanged; + + // In order to know when the selection is cleared, SelectionCleared event has been used. + // Because CursorChanged event is still invoked with the selected text when an user clears selection. It is an known issue in EFL. + platformView.SelectionCleared += OnSelectionCleared; + + platformView.TextChanged += OnTextChanged; + platformView.EntryLayoutFocused += OnFocused; + platformView.EntryLayoutUnfocused += OnUnfocused; + platformView.PrependMarkUpFilter(MaxLengthFilter); + + + // TODO: Fix me later + // An initial CursorPosition is set after layouting to avoid timing issue when the EditField entry is initialized. + //if (VirtualView != null) + //{ + // MainThread.BeginInvokeOnMainThread(() => + // { + // platformView.UpdateSelectionLength(VirtualView); + // }); + //} + } + + protected override void DisconnectHandler(Entry platformView) + { + platformView.Activated -= OnCompleted; + platformView.CursorPositionChanged -= OnCursorChanged; + platformView.TextChanged -= OnTextChanged; + platformView.EntryLayoutFocused -= OnFocused; + platformView.EntryLayoutUnfocused -= OnUnfocused; + } + + public static void MapBackground(IEntryHandler handler, IEntry entry) + { + handler.UpdateValue(nameof(handler.ContainerView)); + handler.ToPlatform()?.UpdateBackground(entry); + } + + public static void MapText(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateText(entry); + + // Any text update requires that we update any attributed string formatting + MapFormatting(handler, entry); + } + + public static void MapTextColor(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateTextColor(entry); + } + + public static void MapPlaceholder(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdatePlaceholder(entry); + } + + public static void MapPlaceholderColor(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdatePlaceholderColor(entry); + } + + public static void MapIsPassword(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateIsPassword(entry); + } + + public static void MapHorizontalTextAlignment(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateHorizontalTextAlignment(entry); + } + + public static void MapVerticalTextAlignment(IEntryHandler handler, IEntry entry) + { + handler?.PlatformView?.UpdateVerticalTextAlignment(entry); + } + + public static void MapMaxLength(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateMaxLength(entry); + } + + public static void MapIsReadOnly(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateIsReadOnly(entry); + } + + public static void MapIsTextPredictionEnabled(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateIsTextPredictionEnabled(entry); + } + + public static void MapKeyboard(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateKeyboard(entry); + } + + public static void MapReturnType(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateReturnType(entry); + } + + public static void MapFont(IEntryHandler handler, IEntry entry) + { + var fontManager = handler.GetRequiredService(); + + handler.PlatformView?.UpdateFont(entry, fontManager); + } + + public static void MapClearButtonVisibility(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateClearButtonVisibility(entry); + } + + public static void MapFormatting(IEntryHandler handler, IEntry entry) + { + // Update all of the attributed text formatting properties + // Setting any of those may have removed text alignment settings, + // so we need to make sure those are applied, too + handler.PlatformView?.UpdateMaxLength(entry); + handler.PlatformView?.UpdateHorizontalTextAlignment(entry); + } + + public static void MapSelectionLength(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateSelectionLength(entry); + } + + public static void MapCursorPosition(IEntryHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateSelectionLength(entry); + } + + public static void MapKeyboard(EditorHandler handler, IEntry entry) + { + handler.PlatformView?.UpdateKeyboard(entry); + } + + [MissingMapper] + public static void MapCharacterSpacing(IEntryHandler handler, IEntry entry) { } + + string? MaxLengthFilter(EEntry entry, string s) + { + if (VirtualView == null || PlatformView == null) + return null; + + if (entry.Text.Length < VirtualView.MaxLength) + return s; + + return null; + } + + void OnTextChanged(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null) + return; + + VirtualView.Text = PlatformView.Text; + } + + void OnCursorChanged(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null) + return; + + var position = PlatformView.CursorPosition; + + PlatformView.GetSelectRegion(out int start, out int end); + + if (start > -1) + { + position = (start < end) ? start : end; + var selectionLength = Math.Abs(end - start); + VirtualView.SelectionLength = selectionLength; + } + + VirtualView.CursorPosition = position; + } + + void OnSelectionCleared(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null) + return; + + if (PlatformView.IsFocused) + { + VirtualView.SelectionLength = 0; + VirtualView.CursorPosition = PlatformView.CursorPosition; + } + } + + void OnCompleted(object? sender, EventArgs e) + { + if (PlatformView == null) + return; + + PlatformView.SetFocus(false); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Entry/EntryHandler.cs b/src/Core/src/Handlers/Entry/EntryHandler.cs index 35e92ea624..6b5180a255 100644 --- a/src/Core/src/Handlers/Entry/EntryHandler.cs +++ b/src/Core/src/Handlers/Entry/EntryHandler.cs @@ -5,7 +5,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiTextField; using PlatformView = AndroidX.AppCompat.Widget.AppCompatEditText; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TextBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif @@ -60,4 +62,4 @@ namespace Microsoft.Maui.Handlers PlatformView IEntryHandler.PlatformView => PlatformView; } -} \ No newline at end of file +} diff --git a/src/Core/src/Handlers/Entry/IEntryHandler.cs b/src/Core/src/Handlers/Entry/IEntryHandler.cs index e4390388a8..66ed5f171d 100644 --- a/src/Core/src/Handlers/Entry/IEntryHandler.cs +++ b/src/Core/src/Handlers/Entry/IEntryHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiTextField; using PlatformView = AndroidX.AppCompat.Widget.AppCompatEditText; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TextBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Tizen.cs b/src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Tizen.cs new file mode 100644 index 0000000000..c5ab0d85e6 --- /dev/null +++ b/src/Core/src/Handlers/FlyoutView/FlyoutViewHandler.Tizen.cs @@ -0,0 +1,14 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class FlyoutViewHandler : ViewHandler + { + protected override EvasObject CreatePlatformView() + { + //TODO : Need to impl + throw new NotImplementedException(); + } + } +} diff --git a/src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.Tizen.cs b/src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.Tizen.cs new file mode 100644 index 0000000000..f699ed7d87 --- /dev/null +++ b/src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.Tizen.cs @@ -0,0 +1,28 @@ +using Microsoft.Maui.Platform; + +namespace Microsoft.Maui.Handlers +{ + public partial class GraphicsViewHandler : ViewHandler + { + protected override PlatformTouchGraphicsView CreatePlatformView() + { + return new PlatformTouchGraphicsView(NativeParent); + } + + public static void MapDrawable(IGraphicsViewHandler handler, IGraphicsView graphicsView) + { + handler.PlatformView?.UpdateDrawable(graphicsView); + } + + public static void MapFlowDirection(IGraphicsViewHandler handler, IGraphicsView graphicsView) + { + handler.PlatformView?.UpdateFlowDirection(graphicsView); + handler.PlatformView?.Invalidate(); + } + + public static void MapInvalidate(IGraphicsViewHandler handler, IGraphicsView graphicsView, object? arg) + { + handler.PlatformView?.Invalidate(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.cs b/src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.cs index b9c98eb5c2..926b5ad758 100644 --- a/src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.cs +++ b/src/Core/src/Handlers/GraphicsView/GraphicsViewHandler.cs @@ -1,5 +1,5 @@ #nullable enable -#if __IOS__ || MACCATALYST || MONOANDROID || WINDOWS +#if __IOS__ || MACCATALYST || MONOANDROID || WINDOWS || TIZEN #define PLATFORM using PlatformView = Microsoft.Maui.Platform.PlatformTouchGraphicsView; #else diff --git a/src/Core/src/Handlers/GraphicsView/IGraphicsViewHandler.cs b/src/Core/src/Handlers/GraphicsView/IGraphicsViewHandler.cs index 61239029ce..88a52002e7 100644 --- a/src/Core/src/Handlers/GraphicsView/IGraphicsViewHandler.cs +++ b/src/Core/src/Handlers/GraphicsView/IGraphicsViewHandler.cs @@ -1,4 +1,4 @@ -#if __IOS__ || MACCATALYST || MONOANDROID || WINDOWS +#if __IOS__ || MACCATALYST || MONOANDROID || WINDOWS || TIZEN using PlatformView = Microsoft.Maui.Platform.PlatformTouchGraphicsView; #else using PlatformView = System.Object; diff --git a/src/Core/src/Handlers/IViewHandler.Tizen.cs b/src/Core/src/Handlers/IViewHandler.Tizen.cs new file mode 100644 index 0000000000..8cb46442b7 --- /dev/null +++ b/src/Core/src/Handlers/IViewHandler.Tizen.cs @@ -0,0 +1,19 @@ +using System; +using EvasObject = ElmSharp.EvasObject; +using ERect = ElmSharp.Rect; + +namespace Microsoft.Maui +{ + public interface IPlatformViewHandler : IViewHandler, IDisposable + { + new EvasObject? PlatformView { get; } + + new EvasObject? ContainerView { get; } + + void SetParent(IPlatformViewHandler parent); + + IPlatformViewHandler? Parent { get; } + + ERect GetPlatformContentGeometry(); + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Image/IImageHandler.cs b/src/Core/src/Handlers/Image/IImageHandler.cs index fae4c2a528..fbaddcd8a6 100644 --- a/src/Core/src/Handlers/Image/IImageHandler.cs +++ b/src/Core/src/Handlers/Image/IImageHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIImageView; using PlatformView = Android.Widget.ImageView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Image; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Image; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Image/ImageHandler.Tizen.cs b/src/Core/src/Handlers/Image/ImageHandler.Tizen.cs new file mode 100644 index 0000000000..d2bdeb28a1 --- /dev/null +++ b/src/Core/src/Handlers/Image/ImageHandler.Tizen.cs @@ -0,0 +1,58 @@ +#nullable enable +using System; +using System.Threading.Tasks; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class ImageHandler : ViewHandler + { + protected override Image CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + return new Image(NativeParent); + } + + protected override void DisconnectHandler(Image platformView) + { + base.DisconnectHandler(platformView); + SourceLoader.Reset(); + } + + public override bool NeedsContainer => + VirtualView?.Background != null || + VirtualView?.Clip != null || + base.NeedsContainer; + + public static void MapBackground(IImageHandler handler, IImage image) + { + handler.UpdateValue(nameof(IViewHandler.ContainerView)); + handler.ToPlatform()?.UpdateBackground(image); + } + + public static void MapAspect(IImageHandler handler, IImage image) => + handler.PlatformView?.UpdateAspect(image); + + public static void MapIsAnimationPlaying(IImageHandler handler, IImage image) => + handler.PlatformView?.UpdateIsAnimationPlaying(image); + + public static void MapSource(IImageHandler handler, IImage image) => + MapSourceAsync(handler, image).FireAndForget(handler); + + public static Task MapSourceAsync(IImageHandler handler, IImage image) + { + if (handler.PlatformView == null) + return Task.CompletedTask; + + handler.PlatformView.Clear(); + return handler.SourceLoader.UpdateImageSourceAsync(); + } + + void OnSetImageSource(Image? obj) + { + //Empty on purpose + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Image/ImageHandler.cs b/src/Core/src/Handlers/Image/ImageHandler.cs index e48a9fdbe0..f33d6b7285 100644 --- a/src/Core/src/Handlers/Image/ImageHandler.cs +++ b/src/Core/src/Handlers/Image/ImageHandler.cs @@ -6,7 +6,9 @@ using PlatformView = UIKit.UIImageView; using PlatformView = Android.Widget.ImageView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Image; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Image; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif @@ -16,7 +18,7 @@ namespace Microsoft.Maui.Handlers { public static IPropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper) { -#if __ANDROID__ || WINDOWS +#if __ANDROID__ || WINDOWS || TIZEN [nameof(IImage.Background)] = MapBackground, #endif [nameof(IImage.Aspect)] = MapAspect, @@ -46,4 +48,4 @@ namespace Microsoft.Maui.Handlers PlatformView IImageHandler.PlatformView => PlatformView; } -} \ No newline at end of file +} diff --git a/src/Core/src/Handlers/ImageButton/IImageButtonHandler.cs b/src/Core/src/Handlers/ImageButton/IImageButtonHandler.cs index 52eb04d345..881022f741 100644 --- a/src/Core/src/Handlers/ImageButton/IImageButtonHandler.cs +++ b/src/Core/src/Handlers/ImageButton/IImageButtonHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIButton; using PlatformView = Google.Android.Material.ImageView.ShapeableImageView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Button; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.MauiImageButton; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Tizen.cs b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Tizen.cs new file mode 100644 index 0000000000..ab600d8d0d --- /dev/null +++ b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Tizen.cs @@ -0,0 +1,65 @@ +using System; +using TImage = Tizen.UIExtensions.ElmSharp.Image; + +namespace Microsoft.Maui.Handlers +{ + public partial class ImageButtonHandler : ViewHandler + { + protected override MauiImageButton CreatePlatformView() + { + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} must be set to create a ImageButton"); + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} cannot be null"); + + var view = new MauiImageButton(NativeParent); + return view; + } + + protected override void ConnectHandler(MauiImageButton platformView) + { + platformView.Clicked += OnClicked; + platformView.Pressed += OnPressed; + platformView.Released += OnReleased; + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(MauiImageButton platformView) + { + platformView.Clicked -= OnClicked; + platformView.Pressed -= OnPressed; + platformView.Released -= OnReleased; + base.DisconnectHandler(platformView); + } + + [MissingMapper] + public static void MapStrokeColor(IImageButtonHandler handler, IButtonStroke buttonStroke) { } + + [MissingMapper] + public static void MapStrokeThickness(IImageButtonHandler handler, IButtonStroke buttonStroke) { } + + [MissingMapper] + public static void MapCornerRadius(IImageButtonHandler handler, IButtonStroke buttonStroke) { } + + [MissingMapper] + public static void MapPadding(IImageButtonHandler handler, IImageButton imageButton) { } + + private void OnReleased(object? sender, EventArgs e) + { + VirtualView?.Released(); + } + + private void OnPressed(object? sender, EventArgs e) + { + VirtualView?.Pressed(); + } + + private void OnClicked(object? sender, EventArgs e) + { + VirtualView?.Clicked(); + } + + void OnSetImageSource(TImage? img) + { + //Empty on purpose + } + } +} diff --git a/src/Core/src/Handlers/ImageButton/ImageButtonHandler.cs b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.cs index bf90c5e0ed..25532e407d 100644 --- a/src/Core/src/Handlers/ImageButton/ImageButtonHandler.cs +++ b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.cs @@ -11,7 +11,11 @@ using System; using PlatformImage = Microsoft.UI.Xaml.Media.ImageSource; using PlatformImageView = Microsoft.UI.Xaml.Controls.Image; using PlatformView = Microsoft.UI.Xaml.Controls.Button; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformImage = Tizen.UIExtensions.ElmSharp.Image; +using PlatformImageView = Tizen.UIExtensions.ElmSharp.Image; +using PlatformView = Microsoft.Maui.Platform.MauiImageButton; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformImage = System.Object; using PlatformImageView = System.Object; using PlatformView = System.Object; @@ -55,7 +59,7 @@ namespace Microsoft.Maui.Handlers IImage IImageHandler.VirtualView => VirtualView; PlatformImageView IImageHandler.PlatformView => -#if __IOS__ +#if __IOS__ || TIZEN PlatformView.ImageView; #elif WINDOWS PlatformView.GetContent() ?? throw new InvalidOperationException("ImageButton did not contain an Image element."); @@ -67,4 +71,4 @@ namespace Microsoft.Maui.Handlers ImageSourcePartLoader IImageHandler.SourceLoader => SourceLoader; } -} \ No newline at end of file +} diff --git a/src/Core/src/Handlers/IndicatorView/IIndicatorViewHandler.cs b/src/Core/src/Handlers/IndicatorView/IIndicatorViewHandler.cs index b4b3236f9d..6cffb37e66 100644 --- a/src/Core/src/Handlers/IndicatorView/IIndicatorViewHandler.cs +++ b/src/Core/src/Handlers/IndicatorView/IIndicatorViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiPageControl; using PlatformView = Microsoft.Maui.Platform.MauiPageControl; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.MauiPageControl; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.IndicatorView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.Tizen.cs b/src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.Tizen.cs new file mode 100644 index 0000000000..fe77754eca --- /dev/null +++ b/src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.Tizen.cs @@ -0,0 +1,60 @@ +using System; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class IndicatorViewHandler : ViewHandler + { + protected override IndicatorView CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + return new IndicatorView(NativeParent); + } + + protected override void ConnectHandler(IndicatorView platformView) + { + base.ConnectHandler(platformView); + PlatformView.SelectedPosition += OnSelectedPosition; + } + + protected override void DisconnectHandler(IndicatorView platformView) + { + base.DisconnectHandler(platformView); + PlatformView.SelectedPosition -= OnSelectedPosition; + } + + public static void MapCount(IIndicatorViewHandler handler, IIndicatorView indicator) + { + handler.PlatformView.UpdateIndicatorCount(indicator); + } + + public static void MapPosition(IIndicatorViewHandler handler, IIndicatorView indicator) + { + handler.PlatformView.UpdatePosition(indicator); + } + + //TODO : Need to impl + [MissingMapper] + public static void MapHideSingle(IIndicatorViewHandler handler, IIndicatorView indicator) { } + + [MissingMapper] + public static void MapMaximumVisible(IIndicatorViewHandler handler, IIndicatorView indicator) { } + + [MissingMapper] + public static void MapIndicatorSize(IIndicatorViewHandler handler, IIndicatorView indicator) { } + + [MissingMapper] + public static void MapIndicatorColor(IIndicatorViewHandler handler, IIndicatorView indicator) { } + + [MissingMapper] + public static void MapSelectedIndicatorColor(IIndicatorViewHandler handler, IIndicatorView indicator) { } + + [MissingMapper] + public static void MapIndicatorShape(IIndicatorViewHandler handler, IIndicatorView indicator) { } + + void OnSelectedPosition(object? sender, SelectedPositionChangedEventArgs e) + { + VirtualView.Position = e.SelectedPosition; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.cs b/src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.cs index 79e458cae7..b525a717ac 100644 --- a/src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.cs +++ b/src/Core/src/Handlers/IndicatorView/IndicatorViewHandler.cs @@ -5,7 +5,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiPageControl; using PlatformView = Microsoft.Maui.Platform.MauiPageControl; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.MauiPageControl; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.IndicatorView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Label/ILabelHandler.cs b/src/Core/src/Handlers/Label/ILabelHandler.cs index 3aa57b5af6..e801efec38 100644 --- a/src/Core/src/Handlers/Label/ILabelHandler.cs +++ b/src/Core/src/Handlers/Label/ILabelHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiLabel; using PlatformView = AndroidX.AppCompat.Widget.AppCompatTextView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TextBlock; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Label; +#elif NETSTANDARD || (NET6_0 && !IOS && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Label/LabelHandler.Tizen.cs b/src/Core/src/Handlers/Label/LabelHandler.Tizen.cs new file mode 100644 index 0000000000..276b3b52a6 --- /dev/null +++ b/src/Core/src/Handlers/Label/LabelHandler.Tizen.cs @@ -0,0 +1,78 @@ +using System; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class LabelHandler : ViewHandler + { + protected override Label CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + var label = new Label(NativeParent) + { + // Fix me : it is workaround code, LineBreakMode is not working when Label was measured but we set LineBreakMode as WordWrap at initialize time, it works + LineBreakMode = Tizen.UIExtensions.Common.LineBreakMode.WordWrap + }; + return label; + } + + public static void MapBackground(ILabelHandler handler, ILabel label) + { + handler.UpdateValue(nameof(handler.ContainerView)); + handler.ToPlatform()?.UpdateBackground(label); + } + + public static void MapText(ILabelHandler handler, ILabel label) + { + handler.PlatformView?.UpdateText(label); + + // Any text update requires that we update any attributed string formatting + MapFormatting(handler, label); + } + + public static void MapTextColor(ILabelHandler handler, ILabel label) + { + handler.PlatformView?.UpdateTextColor(label); + } + + public static void MapHorizontalTextAlignment(ILabelHandler handler, ILabel label) + { + handler.PlatformView?.UpdateHorizontalTextAlignment(label); + } + + public static void MapVerticalTextAlignment(ILabelHandler handler, ILabel label) + { + handler.PlatformView?.UpdateVerticalTextAlignment(label); + } + + public static void MapTextDecorations(ILabelHandler handler, ILabel label) + { + handler.PlatformView?.UpdateTextDecorations(label); + } + + public static void MapFont(ILabelHandler handler, ILabel label) + { + var fontManager = handler.GetRequiredService(); + handler.PlatformView?.UpdateFont(label, fontManager); + } + + public static void MapFormatting(ILabelHandler handler, ILabel label) + { + // Update all of the attributed text formatting properties + // Setting any of those may have removed text alignment settings, + // so we need to make sure those are applied, too + handler.PlatformView?.UpdateHorizontalTextAlignment(label); + handler.PlatformView?.UpdateTextDecorations(label); + } + + [MissingMapper] + public static void MapCharacterSpacing(ILabelHandler handler, ILabel label) {} + + [MissingMapper] + public static void MapLineHeight(ILabelHandler handler, ILabel label) {} + + [MissingMapper] + public static void MapPadding(ILabelHandler handler, ILabel label) {} + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Label/LabelHandler.cs b/src/Core/src/Handlers/Label/LabelHandler.cs index d59dafa21a..e1ee2b8e94 100644 --- a/src/Core/src/Handlers/Label/LabelHandler.cs +++ b/src/Core/src/Handlers/Label/LabelHandler.cs @@ -5,7 +5,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiLabel; using PlatformView = AndroidX.AppCompat.Widget.AppCompatTextView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TextBlock; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Label; +#elif NETSTANDARD || (NET6_0 && !IOS && !TIZEN) using PlatformView = System.Object; #endif @@ -15,7 +17,7 @@ namespace Microsoft.Maui.Handlers { public static IPropertyMapper Mapper = new PropertyMapper(ViewHandler.ViewMapper) { -#if __IOS__ +#if __IOS__ || TIZEN [nameof(ILabel.Background)] = MapBackground, [nameof(ILabel.Opacity)] = MapOpacity, #elif WINDOWS diff --git a/src/Core/src/Handlers/Layout/ILayoutHandler.cs b/src/Core/src/Handlers/Layout/ILayoutHandler.cs index a58e29d9bc..bf43bc63d2 100644 --- a/src/Core/src/Handlers/Layout/ILayoutHandler.cs +++ b/src/Core/src/Handlers/Layout/ILayoutHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.LayoutView; using PlatformView = Microsoft.Maui.Platform.LayoutViewGroup; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.LayoutPanel; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.LayoutCanvas; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Layout/LayoutHandler.Tizen.cs b/src/Core/src/Handlers/Layout/LayoutHandler.Tizen.cs new file mode 100644 index 0000000000..d43c36aa9b --- /dev/null +++ b/src/Core/src/Handlers/Layout/LayoutHandler.Tizen.cs @@ -0,0 +1,176 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class LayoutHandler : ViewHandler + { + public override bool NeedsContainer => + VirtualView?.Background != null || + VirtualView?.Clip != null || + base.NeedsContainer; + + protected override LayoutCanvas CreatePlatformView() + { + if (VirtualView == null) + { + throw new InvalidOperationException($"{nameof(VirtualView)} must be set to create a Canvas"); + } + + if (NativeParent == null) + { + throw new InvalidOperationException($"{nameof(NativeParent)} cannot be null"); + } + + var view = new LayoutCanvas(NativeParent, VirtualView) + { + CrossPlatformMeasure = VirtualView.CrossPlatformMeasure, + CrossPlatformArrange = VirtualView.CrossPlatformArrange + }; + + view.Show(); + return view; + } + + public override Graphics.Size GetDesiredSize(double widthConstraint, double heightConstraint) + { + return VirtualView.CrossPlatformMeasure(widthConstraint, heightConstraint); + } + + public override void SetVirtualView(IView view) + { + base.SetVirtualView(view); + + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + PlatformView.CrossPlatformMeasure = VirtualView.CrossPlatformMeasure; + PlatformView.CrossPlatformArrange = VirtualView.CrossPlatformArrange; + + PlatformView.Children.Clear(); + + foreach (var child in VirtualView.OrderByZIndex()) + { + PlatformView.Children.Add(child.ToPlatform(MauiContext)); + if (child.Handler is IPlatformViewHandler thandler) + { + thandler?.SetParent(this); + } + } + } + + public void Add(IView child) + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + var targetIndex = VirtualView.GetLayoutHandlerIndex(child); + PlatformView.Children.Insert(targetIndex, child.ToPlatform(MauiContext)); + if (child.Handler is IPlatformViewHandler childHandler) + { + childHandler?.SetParent(this); + } + } + + public void Remove(IView child) + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + + if (child.Handler is IPlatformViewHandler thandler && child?.ToPlatform() is EvasObject childView) + { + PlatformView.Children.Remove(childView); + thandler.Dispose(); + } + } + + public void Clear() + { + if (PlatformView == null) + return; + + foreach (var child in PlatformView.Children) + { + child.Unrealize(); + } + PlatformView.Children.Clear(); + } + + public void Insert(int index, IView child) + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + var targetIndex = VirtualView.GetLayoutHandlerIndex(child); + PlatformView.Children.Insert(targetIndex, child.ToPlatform(MauiContext)); + if (child.Handler is IPlatformViewHandler childHandler) + { + childHandler?.SetParent(this); + } + } + + public void Update(int index, IView child) + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + var toBeRemoved = PlatformView.Children[index]; + PlatformView.Children.RemoveAt(index); + toBeRemoved.Unrealize(); + + var targetIndex = VirtualView.GetLayoutHandlerIndex(child); + PlatformView.Children.Insert(targetIndex, child.ToPlatform(MauiContext)); + if (child.Handler is IPlatformViewHandler childHandler) + { + childHandler?.SetParent(this); + } + } + + public void UpdateZIndex(IView child) + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + EnsureZIndexOrder(child); + } + + void EnsureZIndexOrder(IView child) + { + if (PlatformView.Children.Count == 0) + { + return; + } + + var nativeChildView = child.ToPlatform(MauiContext!); + var currentIndex = PlatformView.Children.IndexOf(nativeChildView); + + if (currentIndex == -1) + { + return; + } + + var targetIndex = VirtualView.GetLayoutHandlerIndex(child); + if (targetIndex > currentIndex) + { + child.ToPlatform(MauiContext!).RaiseTop(); + for (int i = targetIndex+1; i < PlatformView.Children.Count; i++) + { + PlatformView.Children[i].RaiseTop(); + } + } + else + { + child.ToPlatform(MauiContext!).Lower(); + for (int i = targetIndex-1; i >= 0; i--) + { + PlatformView.Children[i].Lower(); + } + } + } + } +} diff --git a/src/Core/src/Handlers/Layout/LayoutHandler.cs b/src/Core/src/Handlers/Layout/LayoutHandler.cs index e17e7b4892..a7463ad42c 100644 --- a/src/Core/src/Handlers/Layout/LayoutHandler.cs +++ b/src/Core/src/Handlers/Layout/LayoutHandler.cs @@ -5,6 +5,8 @@ using PlatformView = Microsoft.Maui.Platform.LayoutView; using PlatformView = Microsoft.Maui.Platform.LayoutViewGroup; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.LayoutPanel; +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.LayoutCanvas; #elif NETSTANDARD using PlatformView = System.Object; #endif @@ -48,6 +50,10 @@ namespace Microsoft.Maui.Handlers public static void MapBackground(ILayoutHandler handler, ILayout layout) { +#if TIZEN + handler.UpdateValue(nameof(handler.ContainerView)); + handler.ToPlatform()?.UpdateBackground(layout); +#endif ((PlatformView?)handler.PlatformView)?.UpdateBackground(layout); } diff --git a/src/Core/src/Handlers/MenuBar/IMenuBarHandler.cs b/src/Core/src/Handlers/MenuBar/IMenuBarHandler.cs index 7db5e0ccfd..22c7c99bbd 100644 --- a/src/Core/src/Handlers/MenuBar/IMenuBarHandler.cs +++ b/src/Core/src/Handlers/MenuBar/IMenuBarHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.IUIMenuBuilder; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuBar; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/MenuBar/MenuBarHandler.Tizen.cs b/src/Core/src/Handlers/MenuBar/MenuBarHandler.Tizen.cs new file mode 100644 index 0000000000..958cd367f2 --- /dev/null +++ b/src/Core/src/Handlers/MenuBar/MenuBarHandler.Tizen.cs @@ -0,0 +1,30 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class MenuBarHandler : ElementHandler, IMenuBarHandler + { + // TODO : Need to implement + protected override EvasObject CreatePlatformElement() + { + throw new NotImplementedException(); + } + + public void Add(IMenuBarItem view) + { + } + + public void Remove(IMenuBarItem view) + { + } + + public void Clear() + { + } + + public void Insert(int index, IMenuBarItem view) + { + } + } +} diff --git a/src/Core/src/Handlers/MenuBar/MenuBarHandler.cs b/src/Core/src/Handlers/MenuBar/MenuBarHandler.cs index 1165fc84a5..f5badf32ac 100644 --- a/src/Core/src/Handlers/MenuBar/MenuBarHandler.cs +++ b/src/Core/src/Handlers/MenuBar/MenuBarHandler.cs @@ -7,7 +7,9 @@ using PlatformView = UIKit.IUIMenuBuilder; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuBar; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/MenuBarItem/IMenuBarItemHandler.cs b/src/Core/src/Handlers/MenuBarItem/IMenuBarItemHandler.cs index 63e3e1ef18..42a47d99fb 100644 --- a/src/Core/src/Handlers/MenuBarItem/IMenuBarItemHandler.cs +++ b/src/Core/src/Handlers/MenuBarItem/IMenuBarItemHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIMenu; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuBarItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.Tizen.cs b/src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.Tizen.cs new file mode 100644 index 0000000000..6ae7b2e33c --- /dev/null +++ b/src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.Tizen.cs @@ -0,0 +1,30 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class MenuBarItemHandler : ElementHandler, IMenuBarItemHandler + { + // TODO : Need to implement + protected override EvasObject CreatePlatformElement() + { + throw new NotImplementedException(); + } + + public void Add(IMenuElement view) + { + } + + public void Remove(IMenuElement view) + { + } + + public void Clear() + { + } + + public void Insert(int index, IMenuElement view) + { + } + } +} diff --git a/src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.cs b/src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.cs index 90f47944dd..574671a695 100644 --- a/src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.cs +++ b/src/Core/src/Handlers/MenuBarItem/MenuBarItemHandler.cs @@ -7,7 +7,9 @@ using PlatformView = UIKit.UIMenu; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuBarItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/MenuFlyoutItem/IMenuFlyoutItemHandler.cs b/src/Core/src/Handlers/MenuFlyoutItem/IMenuFlyoutItemHandler.cs index 1a807e2734..00efe52954 100644 --- a/src/Core/src/Handlers/MenuFlyoutItem/IMenuFlyoutItemHandler.cs +++ b/src/Core/src/Handlers/MenuFlyoutItem/IMenuFlyoutItemHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIMenuElement; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuFlyoutItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/MenuFlyoutItem/MenuFlyoutItemHandler.cs b/src/Core/src/Handlers/MenuFlyoutItem/MenuFlyoutItemHandler.cs index 9f870262aa..7b889eebd8 100644 --- a/src/Core/src/Handlers/MenuFlyoutItem/MenuFlyoutItemHandler.cs +++ b/src/Core/src/Handlers/MenuFlyoutItem/MenuFlyoutItemHandler.cs @@ -7,7 +7,9 @@ using PlatformView = UIKit.UIMenuElement; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuFlyoutItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/MenuFlyoutSubItem/IMenuFlyoutSubItemHandler.cs b/src/Core/src/Handlers/MenuFlyoutSubItem/IMenuFlyoutSubItemHandler.cs index 4bf0139cd3..7dfb3c45c9 100644 --- a/src/Core/src/Handlers/MenuFlyoutSubItem/IMenuFlyoutSubItemHandler.cs +++ b/src/Core/src/Handlers/MenuFlyoutSubItem/IMenuFlyoutSubItemHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIMenu; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuFlyoutSubItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.Tizen.cs b/src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.Tizen.cs new file mode 100644 index 0000000000..c026c2cd65 --- /dev/null +++ b/src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.Tizen.cs @@ -0,0 +1,30 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class MenuFlyoutSubItemHandler + { + // TODO : Need to implement + protected override EvasObject CreatePlatformElement() + { + throw new NotImplementedException(); + } + + public void Add(IMenuElement view) + { + } + + public void Remove(IMenuElement view) + { + } + + public void Clear() + { + } + + public void Insert(int index, IMenuElement view) + { + } + } +} diff --git a/src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.cs b/src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.cs index 49874dbac7..31a90d74fd 100644 --- a/src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.cs +++ b/src/Core/src/Handlers/MenuFlyoutSubItem/MenuFlyoutSubItemHandler.cs @@ -7,7 +7,9 @@ using PlatformView = UIKit.UIMenu; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.MenuFlyoutSubItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/NavigationPage/INavigationViewHandler.cs b/src/Core/src/Handlers/NavigationPage/INavigationViewHandler.cs index 661564de59..368d795672 100644 --- a/src/Core/src/Handlers/NavigationPage/INavigationViewHandler.cs +++ b/src/Core/src/Handlers/NavigationPage/INavigationViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Frame; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.Naviframe; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/NavigationPage/NavigationViewHandler.Tizen.cs b/src/Core/src/Handlers/NavigationPage/NavigationViewHandler.Tizen.cs new file mode 100644 index 0000000000..54fd8981be --- /dev/null +++ b/src/Core/src/Handlers/NavigationPage/NavigationViewHandler.Tizen.cs @@ -0,0 +1,341 @@ +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using ElmSharp; +using Microsoft.Maui.Handlers; +using Tizen.UIExtensions.ElmSharp; +using TButton = Tizen.UIExtensions.ElmSharp.Button; +using TSpan = Tizen.UIExtensions.Common.Span; +using TTextAlignment = Tizen.UIExtensions.Common.TextAlignment; + +namespace Microsoft.Maui.Handlers +{ + public partial class NavigationViewHandler : + ViewHandler, IPlatformViewHandler + { + readonly List _naviItemContentPartList = new List(); + TaskCompletionSource? _currentTaskSource = null; + IDictionary? _naviItemMap; + + IView? PreviousPage => NavigationStack.Count > 1 ? NavigationStack[NavigationStack.Count - 2] : null; + NaviItem? CurrentNaviItem => PlatformView.NavigationStack.Count > 0 ? PlatformView.NavigationStack.Last() : null; + NaviItem? PreviousNaviItem => PlatformView.NavigationStack.Count > 1 ? PlatformView.NavigationStack[PlatformView.NavigationStack.Count - 2] : null; + + public INavigationView NavigationView => ((INavigationView)VirtualView); + + public IReadOnlyList NavigationStack { get; private set; } = new List(); + + protected override Naviframe CreatePlatformView() + { + return new Naviframe(NativeParent) + { + PreserveContentOnPop = true, + DefaultBackButtonEnabled = false, + }; + } + + public static void RequestNavigation(INavigationViewHandler arg1, IStackNavigationView arg2, object? arg3) + { + if (arg1 is NavigationViewHandler platformHandler && arg3 is NavigationRequest navigationRequest) + { + platformHandler.NavigationStack = navigationRequest.NavigationStack; + } + //if (arg3 is NavigationRequest args) + // arg1.OnPushRequested(args); + } + + //private static void PushAsyncTo(NavigationViewHandler arg1, INavigationView arg2, object? arg3) + //{ + // if (arg3 is MauiNavigationRequestedEventArgs args) + // arg1.OnPushRequested(args); + //} + + //private static void PopAsyncTo(NavigationViewHandler arg1, INavigationView arg2, object? arg3) + //{ + // if (arg3 is MauiNavigationRequestedEventArgs args) + // arg1.OnPopRequested(args); + //} + + //void OnPushRequested(MauiNavigationRequestedEventArgs e) + //{ + // _ = _naviItemMap ?? throw new InvalidOperationException($"{nameof(_naviItemMap)} cannot be null."); + + // if (e.Animated || PlatformView.NavigationStack.Count == 0) + // { + // _naviItemMap[e.Page] = PlatformView.Push(CreateNavItem(e.Page), SpanTitle(e.Page)); + // _currentTaskSource = new TaskCompletionSource(); + // e.Task = _currentTaskSource.Task; + + // // There is no TransitionFinished (AnimationFinished) event after the first Push + // if (PlatformView.NavigationStack.Count == 1) + // CompleteCurrentNavigationTask(); + // } + // else + // { + // _naviItemMap[e.Page] = PlatformView.InsertAfter(PlatformView.NavigationStack.Last(), CreateNavItem(e.Page), SpanTitle(e.Page)); + // } + // //UpdateHasNavigationBar(nre.Page); + //} + + //void OnPopRequested(MauiNavigationRequestedEventArgs e) + //{ + // _ = _naviItemMap ?? throw new InvalidOperationException($"{nameof(_naviItemMap)} cannot be null."); + + // if (VirtualView.NavigationStack.Count == PlatformView.NavigationStack.Count) + // { + // //e.Page?.SendDisappearing(); + // //UpdateNavigationBar(PreviousPage, PreviousNaviItem); + + // if (e.Animated) + // { + // PlatformView.Pop(); + + // _currentTaskSource = new TaskCompletionSource(); + // e.Task = _currentTaskSource.Task; + + // // There is no TransitionFinished (AnimationFinished) event after Pop the last page + // if (PlatformView.NavigationStack.Count == 0) + // CompleteCurrentNavigationTask(); + // } + // else + // { + // CurrentNaviItem?.Delete(); + // } + + // if (_naviItemMap.ContainsKey(e.Page)) + // _naviItemMap.Remove(e.Page); + // } + //} + + protected override void ConnectHandler(Naviframe platformView) + { + base.ConnectHandler(platformView); + platformView.AnimationFinished += OnAnimationFinished; + _naviItemMap = new Dictionary(); + + if (VirtualView == null) + return; + + //VirtualView.PushRequested += OnPushRequested; + //VirtualView.PopRequested += OnPopRequested; + //VirtualView.InternalChildren.CollectionChanged += OnPageCollectionChanged; + + foreach (var page in NavigationStack) + { + _naviItemMap[page] = PlatformView.Push(CreateNavItem(page), SpanTitle(page)); + //page.PropertyChanged += NavigationBarPropertyChangedHandler; + + //UpdateHasNavigationBar(page); + } + } + + protected override void DisconnectHandler(Naviframe platformView) + { + base.DisconnectHandler(platformView); + platformView.AnimationFinished -= OnAnimationFinished; + + //VirtualView.PushRequested -= OnPushRequested; + //VirtualView.PopRequested -= OnPopRequested; + //VirtualView.InternalChildren.CollectionChanged -= OnPageCollectionChanged; + } + + //public static void MapPadding(NavigationViewHandler handler, INavigationView view) { } + + //public static void MapBarTextColor(NavigationViewHandler handler, INavigationView view) + //{ + // //handler.UpdateTitle(view.CurrentPage); + //} + + public static void MapBarBackground(INavigationViewHandler handler, INavigationView view) { } + + public static void MapTitleIcon(INavigationViewHandler handler, INavigationView view) { } + + public static void MapTitleView(INavigationViewHandler handler, INavigationView view) { } + + //void NavigationBarPropertyChangedHandler(object sender, System.ComponentModel.PropertyChangedEventArgs e) + //{ + // // this handler is invoked only for child pages (contained on a navigation stack) + // if (e.PropertyName == INavigationView.HasNavigationBarProperty.PropertyName) + // UpdateHasNavigationBar(sender as Page); + // else if (e.PropertyName == NavigationPage.HasBackButtonProperty.PropertyName || + // e.PropertyName == NavigationPage.BackButtonTitleProperty.PropertyName) + // UpdateHasBackButton(sender as Page); + // else if (e.PropertyName == Page.TitleProperty.PropertyName) + // UpdateTitle(sender as Page); + //} + + //void OnPageCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + //{ + // if (e.OldItems != null) + // foreach (Page page in e.OldItems) + // page.PropertyChanged -= NavigationBarPropertyChangedHandler; + // if (e.NewItems != null) + // foreach (Page page in e.NewItems) + // page.PropertyChanged += NavigationBarPropertyChangedHandler; + //} + + //void OnPushRequested(object sender, NavigationRequestedEventArgs nre) + //{ + // if (nre.Animated || PlatformView.NavigationStack.Count == 0) + // { + // _naviItemMap[nre.Page] = PlatformView.Push(CreateNavItem(nre.Page), SpanTitle(nre.Page.Title)); + // _currentTaskSource = new TaskCompletionSource(); + // nre.Task = _currentTaskSource.Task; + + // // There is no TransitionFinished (AnimationFinished) event after the first Push + // if (PlatformView.NavigationStack.Count == 1) + // CompleteCurrentNavigationTask(); + // } + // else + // { + // _naviItemMap[nre.Page] = PlatformView.InsertAfter(PlatformView.NavigationStack.Last(), CreateNavItem(nre.Page), SpanTitle(nre.Page.Title)); + // } + // UpdateHasNavigationBar(nre.Page); + //} + + //void OnPopRequested(object sender, NavigationRequestedEventArgs nre) + //{ + // if (VirtualView.InternalChildren.Count == PlatformView.NavigationStack.Count) + // { + // nre.Page?.SendDisappearing(); + // UpdateNavigationBar(PreviousPage, PreviousNaviItem); + + // if (nre.Animated) + // { + // PlatformView.Pop(); + + // _currentTaskSource = new TaskCompletionSource(); + // nre.Task = _currentTaskSource.Task; + + // // There is no TransitionFinished (AnimationFinished) event after Pop the last page + // if (PlatformView.NavigationStack.Count == 0) + // CompleteCurrentNavigationTask(); + // } + // else + // { + // CurrentNaviItem?.Delete(); + // } + + // if (_naviItemMap.ContainsKey(nre.Page)) + // _naviItemMap.Remove(nre.Page); + // } + //} + + void OnAnimationFinished(object? sender, EventArgs e) + { + CompleteCurrentNavigationTask(); + } + + void CompleteCurrentNavigationTask() + { + if (_currentTaskSource != null) + { + var tmp = _currentTaskSource; + _currentTaskSource = null; + tmp.SetResult(true); + } + } + + //void UpdateHasNavigationBar(IView page) + //{ + // NaviItem item = GetNaviItemForPage(page); + // item.SetTabBarStyle(); + // item.TitleBarVisible = (bool)page.GetValue(NavigationPage.HasNavigationBarProperty); + // UpdateBarBackgroundColor(item); + //} + + //void UpdateNavigationBar(Page page, NaviItem item = null) + //{ + // if (item == null) + // item = GetNaviItemForPage(page); + + // UpdateTitle(page, item); + // UpdateBarBackgroundColor(item); + //} + + //void UpdateHasBackButton(Page page, NaviItem item = null) + //{ + // if (item == null) + // item = GetNaviItemForPage(page); + + // TButton button = null; + + // if ((bool)page.GetValue(NavigationPage.HasBackButtonProperty) && PlatformView.NavigationStack.Count > 1) + // { + // button = CreateNavigationButton((string)page.GetValue(NavigationPage.BackButtonTitleProperty)); + // } + // item.SetBackButton(button); + //} + + void UpdateTitle(IView page, NaviItem? item = null) + { + if (item == null) + item = GetNaviItemForPage(page); + + item?.SetTitle(SpanTitle(page)); + } + + string SpanTitle(IView view) + { + if (view is not ITitledElement page) + return string.Empty; + else + { + var span = new TSpan + { + Text = page.Title??string.Empty, + HorizontalTextAlignment = TTextAlignment.Center, + //ForegroundColor = VirtualView.BarTextColor.ToNative() + }; + return span.GetMarkupText(); + } + } + + //void UpdateBarBackgroundColor(NaviItem item) + //{ + // item.TitleBarBackgroundColor = VirtualView.BarBackgroundColor.ToNativeEFL(); + //} + + //TButton CreateNavigationButton(string text) + //{ + // var button = new TButton(NativeParent) + // { + // Text = text + // }; + // button.SetNavigationBackStyle(); + // button.Clicked += (sender, e) => + // { + // if (!VirtualView.SendBackButtonPressed()) + // Tizen.Applications.Application.Current.Exit(); + // }; + // _naviItemContentPartList.Add(button); + // button.Deleted += NaviItemPartContentDeletedHandler; + // return button; + //} + + //void NaviItemPartContentDeletedHandler(object sender, EventArgs e) + //{ + // _naviItemContentPartList.Remove(sender as Widget); + //} + + NaviItem? GetNaviItemForPage(IView page) + { + _ = _naviItemMap ?? throw new InvalidOperationException($"{nameof(_naviItemMap)} cannot be null."); + + NaviItem? item; + if (_naviItemMap.TryGetValue(page, out item)) + { + return item; + } + return null; + } + + EvasObject CreateNavItem(IView page) + { + return page.ToPlatform(MauiContext!); + } + } +} diff --git a/src/Core/src/Handlers/NavigationPage/NavigationViewHandler.cs b/src/Core/src/Handlers/NavigationPage/NavigationViewHandler.cs index 8955c05f05..338aab2669 100644 --- a/src/Core/src/Handlers/NavigationPage/NavigationViewHandler.cs +++ b/src/Core/src/Handlers/NavigationPage/NavigationViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Frame; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.Naviframe; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Page/PageHandler.Tizen.cs b/src/Core/src/Handlers/Page/PageHandler.Tizen.cs new file mode 100644 index 0000000000..457e54dbec --- /dev/null +++ b/src/Core/src/Handlers/Page/PageHandler.Tizen.cs @@ -0,0 +1,29 @@ +using Tizen.UIExtensions.Common; +using EColor = ElmSharp.Color; + +namespace Microsoft.Maui.Handlers +{ + public partial class PageHandler : ContentViewHandler + { + public static void MapBackground(IPageHandler handler, IContentView page) + { + handler.UpdateValue(nameof(handler.ContainerView)); + if (page.Background != null && handler.PlatformView.BackgroundColor != EColor.Transparent) + { + handler.PlatformView.BackgroundColor = EColor.Transparent; + } + handler.ToPlatform()?.UpdateBackground(page); + } + + [MissingMapper] + public static void MapTitle(IPageHandler handler, IContentView page) { } + + protected override ContentCanvas CreatePlatformView() + { + var view = base.CreatePlatformView(); + view.BackgroundColor = (DeviceInfo.GetDeviceType() == DeviceType.TV) ? EColor.Transparent : EColor.White; + + return view; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Page/PageHandler.cs b/src/Core/src/Handlers/Page/PageHandler.cs index 48eb693a9a..086e456e67 100644 --- a/src/Core/src/Handlers/Page/PageHandler.cs +++ b/src/Core/src/Handlers/Page/PageHandler.cs @@ -5,6 +5,9 @@ namespace Microsoft.Maui.Handlers { public static new IPropertyMapper Mapper = new PropertyMapper(ContentViewHandler.Mapper) { +#if TIZEN + [nameof(IContentView.Background)] = MapBackground, +#endif [nameof(ITitledElement.Title)] = MapTitle }; diff --git a/src/Core/src/Handlers/Picker/IPickerHandler.cs b/src/Core/src/Handlers/Picker/IPickerHandler.cs index 07f0a82d44..ca71249e62 100644 --- a/src/Core/src/Handlers/Picker/IPickerHandler.cs +++ b/src/Core/src/Handlers/Picker/IPickerHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiPicker; using PlatformView = Microsoft.Maui.Platform.MauiPicker; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ComboBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Picker/PickerHandler.Tizen.cs b/src/Core/src/Handlers/Picker/PickerHandler.Tizen.cs new file mode 100644 index 0000000000..ad15e086e5 --- /dev/null +++ b/src/Core/src/Handlers/Picker/PickerHandler.Tizen.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using Tizen.UIExtensions.ElmSharp; +using TEntry = Tizen.UIExtensions.ElmSharp.Entry; +using TTextAlignment = Tizen.UIExtensions.Common.TextAlignment; +using DeviceInfo = Tizen.UIExtensions.Common.DeviceInfo; +using EcoreMainloop = ElmSharp.EcoreMainloop; +using List = ElmSharp.List; +using ListItem = ElmSharp.ListItem; + +namespace Microsoft.Maui.Handlers +{ + public partial class PickerHandler : ViewHandler + { + List? _list; + Dialog? _dialog; + Dictionary _itemToItemNumber = new Dictionary(); + + protected override TEntry CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + return new EditfieldEntry(NativeParent) + { + IsSingleLine = true, + InputPanelShowByOnDemand = true, + IsEditable = false, + HorizontalTextAlignment = TTextAlignment.Center + }; + } + + protected override void ConnectHandler(TEntry platformView) + { + platformView.SetVerticalTextAlignment(0.5); + + platformView.TextBlockFocused += OnTextBlockFocused; + platformView.EntryLayoutFocused += OnFocused; + platformView.EntryLayoutUnfocused += OnUnfocused; + + if (DeviceInfo.IsTV) + { + platformView.EntryLayoutFocused += OnLayoutFocused; + platformView.EntryLayoutUnfocused += OnLayoutUnfocused; + } + + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(TEntry platformView) + { + platformView.TextBlockFocused -= OnTextBlockFocused; + platformView.EntryLayoutFocused -= OnFocused; + platformView.EntryLayoutUnfocused -= OnUnfocused; + if (DeviceInfo.IsTV) + { + platformView.EntryLayoutFocused -= OnLayoutFocused; + platformView.EntryLayoutUnfocused -= OnLayoutUnfocused; + } + CleanView(); + base.DisconnectHandler(platformView); + } + + static void Reload(IPickerHandler handler) + { + if (handler.VirtualView == null || handler.PlatformView == null) + return; + + handler.PlatformView.UpdatePicker(handler.VirtualView); + } + + public static void MapReload(IPickerHandler handler, IPicker picker, object? args) => Reload(handler); + + public static void MapTitleColor(IPickerHandler handler, IPicker picker) + { + handler.PlatformView?.UpdateTitleColor(picker); + } + + public static void MapFont(IPickerHandler handler, IPicker picker) + { + var fontManager = handler.GetRequiredService(); + handler.PlatformView?.UpdateFont(picker, fontManager); + } + + public static void MapHorizontalTextAlignment(IPickerHandler handler, IPicker picker) + { + handler.PlatformView?.UpdateHorizontalTextAlignment(picker); + } + + public static void MapVerticalTextAlignment(IPickerHandler handler, IPicker picker) + { + handler.PlatformView?.UpdateHorizontalTextAlignment(picker); + } + + public static void MapTextColor(IPickerHandler handler, IPicker picker) + { + handler.PlatformView?.UpdateTextColor(picker); + } + + public static void MapTitle(IPickerHandler handler, IPicker picker) + { + handler.PlatformView?.UpdateTitle(picker); + } + + public static void MapSelectedIndex(IPickerHandler handler, IPicker picker) + { + handler.PlatformView?.UpdateSelectedIndex(picker); + } + + [MissingMapper] + public static void MapCharacterSpacing(IPickerHandler handler, IPicker picker) { } + + void OnLayoutFocused(object? sender, EventArgs e) + { + if (PlatformView == null) + return; + + PlatformView.FontSize = PlatformView.FontSize * 1.5; + } + + void OnLayoutUnfocused(object? sender, EventArgs e) + { + if (PlatformView == null) + return; + + PlatformView.FontSize = PlatformView.FontSize / 1.5; + } + + void OnTextBlockFocused(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null || NativeParent == null) + return; + + // For EFL Entry, the event will occur even if it is currently disabled. + // If the problem is resolved, no conditional statement is required. + if (VirtualView.IsEnabled) + { + int i = 0; + _dialog = new Dialog(NativeParent) + { + AlignmentX = -1, + AlignmentY = -1, + Title = VirtualView.Title, + }; + _dialog.Dismissed += OnDialogDismissed; + _dialog.BackButtonPressed += (object? senders, EventArgs es) => + { + _dialog.Dismiss(); + }; + + _list = new List(_dialog); + foreach (var s in VirtualView.GetItemsAsArray()) + { + ListItem item = _list.Append(s); + _itemToItemNumber[item] = i; + i++; + } + _list.ItemSelected += OnItemSelected; + _dialog.Content = _list; + + // You need to call Show() after ui thread occupation because of EFL problem. + // Otherwise, the content of the popup will not receive focus. + EcoreMainloop.Post(() => + { + _dialog.Show(); + _list.Show(); + }); + } + } + + void OnItemSelected(object? senderObject, EventArgs ev) + { + if (VirtualView == null || PlatformView == null || _dialog == null) + return; + + VirtualView.SelectedIndex = _itemToItemNumber[(senderObject as List)!.SelectedItem]; + _dialog.Dismiss(); + } + + void OnDialogDismissed(object? sender, EventArgs e) + { + CleanView(); + } + + void CleanView() + { + if (null != _list) + { + _list.Unrealize(); + _itemToItemNumber.Clear(); + _list = null; + } + if (null != _dialog) + { + _dialog.Unrealize(); + _dialog = null; + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Picker/PickerHandler.cs b/src/Core/src/Handlers/Picker/PickerHandler.cs index 5c455c7d28..ed86856ea3 100644 --- a/src/Core/src/Handlers/Picker/PickerHandler.cs +++ b/src/Core/src/Handlers/Picker/PickerHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiPicker; using PlatformView = Microsoft.Maui.Platform.MauiPicker; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ComboBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ProgressBar/ProgressBarHandler.Tizen.cs b/src/Core/src/Handlers/ProgressBar/ProgressBarHandler.Tizen.cs new file mode 100644 index 0000000000..fb41e29b85 --- /dev/null +++ b/src/Core/src/Handlers/ProgressBar/ProgressBarHandler.Tizen.cs @@ -0,0 +1,33 @@ +using Tizen.UIExtensions.ElmSharp; +using EColor = ElmSharp.Color; +using EProgressBar = ElmSharp.ProgressBar; + +namespace Microsoft.Maui.Handlers +{ + public partial class ProgressBarHandler : ViewHandler + { + protected virtual EColor DefaultColor => ThemeConstants.ProgressBar.ColorClass.Default; + + protected override EProgressBar CreatePlatformView() + { + var progressBar = new EProgressBar(NativeParent); + progressBar.Color = DefaultColor; + return progressBar; + } + + void SetupDefaults(EProgressBar platformView) + { + platformView.Color = ThemeConstants.ProgressBar.ColorClass.Default; + } + + public static void MapProgress(ProgressBarHandler handler, IProgress progress) + { + handler.PlatformView?.UpdateProgress(progress); + } + + public static void MapProgressColor(ProgressBarHandler handler, IProgress progress) + { + handler.PlatformView?.UpdateProgressColor(progress); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/RadioButton/IRadioButtonHandler.cs b/src/Core/src/Handlers/RadioButton/IRadioButtonHandler.cs index 2be7357184..52aba450f4 100644 --- a/src/Core/src/Handlers/RadioButton/IRadioButtonHandler.cs +++ b/src/Core/src/Handlers/RadioButton/IRadioButtonHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.RadioButton; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.MauiRadioButton; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/RadioButton/RadioButtonHandler.Tizen.cs b/src/Core/src/Handlers/RadioButton/RadioButtonHandler.Tizen.cs new file mode 100644 index 0000000000..67062c6269 --- /dev/null +++ b/src/Core/src/Handlers/RadioButton/RadioButtonHandler.Tizen.cs @@ -0,0 +1,63 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class RadioButtonHandler : ViewHandler + { + protected override MauiRadioButton CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + return new MauiRadioButton(NativeParent) + { + StateValue = 1 + }; + } + + protected override void ConnectHandler(MauiRadioButton platformView) + { + PlatformView.ValueChanged += OnValueChanged; + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(MauiRadioButton platformView) + { + PlatformView.ValueChanged -= OnValueChanged; + base.DisconnectHandler(platformView); + } + + public static void MapIsChecked(IRadioButtonHandler handler, IRadioButton radioButton) + { + handler.PlatformView?.UpdateIsChecked(radioButton); + } + + [MissingMapper] + public static void MapContent(IRadioButtonHandler handler, IRadioButton radioButton) { } + + public static void MapTextColor(IRadioButtonHandler handler, ITextStyle textStyle) + { + handler.PlatformView?.UpdateTextColor(textStyle); + } + + [MissingMapper] + public static void MapCharacterSpacing(IRadioButtonHandler handler, ITextStyle textStyle) { } + + [MissingMapper] + public static void MapFont(IRadioButtonHandler handler, ITextStyle textStyle) { } + + [MissingMapper] + public static void MapStrokeColor(IRadioButtonHandler handler, IRadioButton radioButton) { } + + [MissingMapper] + public static void MapStrokeThickness(IRadioButtonHandler handler, IRadioButton radioButton) { } + + [MissingMapper] + public static void MapCornerRadius(IRadioButtonHandler handler, IRadioButton radioButton) { } + + void OnValueChanged(object? sender, EventArgs e) + { + VirtualView.IsChecked = PlatformView.GroupValue == 1 ? true : false; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/RadioButton/RadioButtonHandler.cs b/src/Core/src/Handlers/RadioButton/RadioButtonHandler.cs index edef90e0f3..d01bd2b95f 100644 --- a/src/Core/src/Handlers/RadioButton/RadioButtonHandler.cs +++ b/src/Core/src/Handlers/RadioButton/RadioButtonHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.RadioButton; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.MauiRadioButton; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/RefreshView/IRefreshViewHandler.cs b/src/Core/src/Handlers/RefreshView/IRefreshViewHandler.cs index 891e11e6cc..a03db2b98a 100644 --- a/src/Core/src/Handlers/RefreshView/IRefreshViewHandler.cs +++ b/src/Core/src/Handlers/RefreshView/IRefreshViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiRefreshView; using PlatformView = Microsoft.Maui.Platform.MauiSwipeRefreshLayout; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.RefreshContainer; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Tizen.cs b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Tizen.cs new file mode 100644 index 0000000000..48106b8ff4 --- /dev/null +++ b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.Tizen.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Maui.Graphics; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + // TODO : Need to implement + public partial class RefreshViewHandler : ViewHandler + { + protected override EvasObject CreatePlatformView() => throw new NotImplementedException(); + + public static void MapIsRefreshing(IRefreshViewHandler handler, IRefreshView refreshView) + { + } + + public static void MapContent(IRefreshViewHandler handler, IRefreshView refreshView) + { + } + + public static void MapRefreshColor(IRefreshViewHandler handler, IRefreshView refreshView) + { + } + + public static void MapRefreshViewBackground(IRefreshViewHandler handler, IView view) + { + } + + } +} diff --git a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.cs b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.cs index 7668970848..665363ce21 100644 --- a/src/Core/src/Handlers/RefreshView/RefreshViewHandler.cs +++ b/src/Core/src/Handlers/RefreshView/RefreshViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiRefreshView; using PlatformView = Microsoft.Maui.Platform.MauiSwipeRefreshLayout; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.RefreshContainer; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ScrollView/IScrollViewHandler.cs b/src/Core/src/Handlers/ScrollView/IScrollViewHandler.cs index d7b00ef4f8..babc3dfa45 100644 --- a/src/Core/src/Handlers/ScrollView/IScrollViewHandler.cs +++ b/src/Core/src/Handlers/ScrollView/IScrollViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIScrollView; using PlatformView = Microsoft.Maui.Platform.MauiScrollView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ScrollViewer; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.ScrollView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ScrollView/ScrollViewHandler.Tizen.cs b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.Tizen.cs new file mode 100644 index 0000000000..754e8c8d99 --- /dev/null +++ b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.Tizen.cs @@ -0,0 +1,153 @@ +using System; +using Microsoft.Maui.Graphics; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using EContainer = ElmSharp.Container; +using EcoreMainloop = ElmSharp.EcoreMainloop; + +namespace Microsoft.Maui.Handlers +{ + public partial class ScrollViewHandler : ViewHandler + { + EContainer? _scrollCanvas; + + Box? Canvas => (Box?)_scrollCanvas; + + protected override ScrollView CreatePlatformView() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} cannot be null"); + var scrollView = new ScrollView(NativeParent); + _scrollCanvas = new Box(scrollView); + scrollView.SetContent(_scrollCanvas); + return scrollView; + } + + protected override void ConnectHandler(ScrollView platformView) + { + base.ConnectHandler(platformView); + _ = Canvas ?? throw new InvalidOperationException($"{nameof(Canvas)} cannot be null"); + + platformView.Scrolled += OnScrolled; + Canvas.LayoutUpdated += OnContentLayoutUpdated; + } + + public override ElmSharp.Rect GetPlatformContentGeometry() + { + return Canvas?.Geometry ?? PlatformView.Geometry; + } + + protected override void DisconnectHandler(ScrollView platformView) + { + base.DisconnectHandler(platformView); + _ = Canvas ?? throw new InvalidOperationException($"{nameof(Canvas)} cannot be null"); + + platformView.Scrolled -= OnScrolled; + Canvas.LayoutUpdated -= OnContentLayoutUpdated; + } + + public override Graphics.Size GetDesiredSize(double widthConstraint, double heightConstraint) + { + return VirtualView.CrossPlatformMeasure(widthConstraint, heightConstraint); + } + + void ScrollAnimationEnded(object? sender, EventArgs e) + { + VirtualView.ScrollFinished(); + } + + void OnScrolled(object? sender, EventArgs e) + { + var region = PlatformView.CurrentRegion.ToDP(); + VirtualView.HorizontalOffset = region.X; + VirtualView.VerticalOffset = region.Y; + } + + void OnContentLayoutUpdated(object? sender, LayoutEventArgs e) + { + // It is workaround, + // in some case, before set a size of ScrollView, if content was filled with sized items, + // after size of ScrollView was updated, a content position was moved to somewhere. + if (VirtualView != null && VirtualView.PresentedContent != null) + { + var frame = VirtualView.PresentedContent.Frame; + VirtualView.PresentedContent.ToPlatform(MauiContext!)?.Move((int)e.Geometry.X + frame.X.ToScaledPixel(), (int)e.Geometry.Y + frame.Y.ToScaledPixel()); + } + + UpdateContentSize(); + } + + void UpdateContentSize() + { + _ = Canvas ?? throw new InvalidOperationException($"{nameof(Canvas)} cannot be null"); + + if (VirtualView == null || VirtualView.PresentedContent == null) + return; + + Canvas.MinimumWidth = (VirtualView.PresentedContent.Margin.HorizontalThickness + VirtualView.PresentedContent.Frame.Width + VirtualView.Padding.HorizontalThickness).ToScaledPixel(); + Canvas.MinimumHeight = (VirtualView.PresentedContent.Margin.VerticalThickness + VirtualView.PresentedContent.Frame.Height + VirtualView.Padding.VerticalThickness).ToScaledPixel(); + + // elm-scroller updates the CurrentRegion after render + EcoreMainloop.Post(() => + { + if (PlatformView != null) + { + OnScrolled(PlatformView, EventArgs.Empty); + } + }); + } + + public static void MapContent(IScrollViewHandler handler, IScrollView scrollView) + { + if (handler.MauiContext == null || scrollView.PresentedContent == null || handler is not ScrollViewHandler sHandler || sHandler.Canvas == null) + { + return; + } + + sHandler.Canvas.UnPackAll(); + sHandler.Canvas.PackEnd(scrollView.PresentedContent.ToPlatform(handler.MauiContext)); + if (scrollView.PresentedContent.Handler is IPlatformViewHandler thandler) + { + thandler?.SetParent(sHandler); + } + sHandler.UpdateContentSize(); + } + + public static void MapHorizontalScrollBarVisibility(IScrollViewHandler handler, IScrollView scrollView) + { + handler.PlatformView?.UpdateHorizontalScrollBarVisibility(scrollView.HorizontalScrollBarVisibility); + } + + public static void MapVerticalScrollBarVisibility(IScrollViewHandler handler, IScrollView scrollView) + { + handler.PlatformView?.UpdateVerticalScrollBarVisibility(scrollView.VerticalScrollBarVisibility); + } + + public static void MapOrientation(IScrollViewHandler handler, IScrollView scrollView) + { + handler.PlatformView?.UpdateOrientation(scrollView.Orientation); + } + + public static void MapRequestScrollTo(IScrollViewHandler handler, IScrollView scrollView, object? args) + { + if (args is ScrollToRequest request) + { + var x = request.HoriztonalOffset; + var y = request.VerticalOffset; + + var region = new ElmSharp.Rect + { + X = x.ToScaledPixel(), + Y = y.ToScaledPixel(), + Width = handler.PlatformView!.Geometry.Width, + Height = handler.PlatformView!.Geometry.Height + }; + handler.PlatformView.ScrollTo(region, !request.Instant); + + if (request.Instant) + { + scrollView.ScrollFinished(); + } + } + } + } +} diff --git a/src/Core/src/Handlers/ScrollView/ScrollViewHandler.cs b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.cs index 2c715b6c34..25acbe9628 100644 --- a/src/Core/src/Handlers/ScrollView/ScrollViewHandler.cs +++ b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.cs @@ -6,7 +6,9 @@ using PlatformView = UIKit.UIScrollView; using PlatformView = Microsoft.Maui.Platform.MauiScrollView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ScrollViewer; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.ScrollView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/SearchBar/ISearchBarHandler.cs b/src/Core/src/Handlers/SearchBar/ISearchBarHandler.cs index 0af23fc562..dbefd33d5c 100644 --- a/src/Core/src/Handlers/SearchBar/ISearchBarHandler.cs +++ b/src/Core/src/Handlers/SearchBar/ISearchBarHandler.cs @@ -8,7 +8,10 @@ using QueryEditor = Android.Widget.EditText; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.AutoSuggestBox; using QueryEditor = Microsoft.UI.Xaml.Controls.AutoSuggestBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.SearchBar; +using QueryEditor = Tizen.UIExtensions.ElmSharp.EditfieldEntry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; using QueryEditor = System.Object; #endif diff --git a/src/Core/src/Handlers/SearchBar/SearchBarHandler.Tizen.cs b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Tizen.cs new file mode 100644 index 0000000000..e44891b2d6 --- /dev/null +++ b/src/Core/src/Handlers/SearchBar/SearchBarHandler.Tizen.cs @@ -0,0 +1,149 @@ +using System; +using Tizen.UIExtensions.ElmSharp; +using EEntry = ElmSharp.Entry; +using InputPanelReturnKeyType = ElmSharp.InputPanelReturnKeyType; + +namespace Microsoft.Maui.Handlers +{ + public partial class SearchBarHandler : ViewHandler + { + EditfieldEntry? _editor; + + public EditfieldEntry? QueryEditor => _editor; + + protected override SearchBar CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + var searchBar = new SearchBar(NativeParent) + { + IsSingleLine = true + }; + searchBar.SetInputPanelReturnKeyType(InputPanelReturnKeyType.Search); + + _editor = searchBar; + return searchBar; + } + + protected override void ConnectHandler(SearchBar platformView) + { + platformView.Activated += OnActivated; + platformView.TextChanged += OnTextChanged; + platformView.PrependMarkUpFilter(MaxLengthFilter); + platformView.EntryLayoutFocused += OnFocused; + platformView.EntryLayoutUnfocused += OnUnfocused; + + } + + protected override void DisconnectHandler(SearchBar platformView) + { + platformView.Activated -= OnActivated; + platformView.TextChanged -= OnTextChanged; + platformView.EntryLayoutFocused -= OnFocused; + platformView.EntryLayoutUnfocused -= OnUnfocused; + } + + public static void MapText(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateText(searchBar); + + // Any text update requires that we update any attributed string formatting + MapFormatting(handler, searchBar); + } + public static void MapPlaceholder(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdatePlaceholder(searchBar); + } + + public static void MapPlaceholderColor(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdatePlaceholderColor(searchBar); + } + + public static void MapFont(ISearchBarHandler handler, ISearchBar searchBar) + { + var fontManager = handler.GetRequiredService(); + + handler.PlatformView?.UpdateFont(searchBar, fontManager); + } + + public static void MapHorizontalTextAlignment(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateHorizontalTextAlignment(searchBar); + } + + public static void MapVerticalTextAlignment(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateVerticalTextAlignment(searchBar); + } + + public static void MapTextColor(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateTextColor(searchBar); + } + + public static void MapMaxLength(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateMaxLength(searchBar); + } + + public static void MapIsReadOnly(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateIsReadOnly(searchBar); + } + + public static void MapIsTextPredictionEnabled(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateIsTextPredictionEnabled(searchBar); + } + + public static void MapKeyboard(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateKeyboard(searchBar); + } + + public static void MapFormatting(ISearchBarHandler handler, ISearchBar searchBar) + { + // Update all of the attributed text formatting properties + // Setting any of those may have removed text alignment settings, + // so we need to make sure those are applied, too + handler.PlatformView?.UpdateMaxLength(searchBar); + handler.PlatformView?.UpdateHorizontalTextAlignment(searchBar); + } + + public static void MapCancelButtonColor(ISearchBarHandler handler, ISearchBar searchBar) + { + handler.PlatformView?.UpdateCancelButtonColor(searchBar); + } + + [MissingMapper] + public static void MapCharacterSpacing(ISearchBarHandler handler, ISearchBar searchBar) { } + + string? MaxLengthFilter(EEntry searchBar, string s) + { + if (VirtualView == null || PlatformView == null) + return null; + + if (searchBar.Text.Length < VirtualView.MaxLength) + return s; + + return null; + } + + void OnTextChanged(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null) + return; + + VirtualView.Text = PlatformView.Text; + } + + void OnActivated(object? sender, EventArgs e) + { + if (PlatformView == null) + return; + + PlatformView.HideInputPanel(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs b/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs index 4b82bf00db..8a192a8b80 100644 --- a/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs +++ b/src/Core/src/Handlers/SearchBar/SearchBarHandler.cs @@ -5,7 +5,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiSearchBar; using PlatformView = AndroidX.AppCompat.Widget.SearchView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.AutoSuggestBox; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.SearchBar; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ShapeView/IShapeViewHandler.cs b/src/Core/src/Handlers/ShapeView/IShapeViewHandler.cs index 814fc0cc5d..91e328fefe 100644 --- a/src/Core/src/Handlers/ShapeView/IShapeViewHandler.cs +++ b/src/Core/src/Handlers/ShapeView/IShapeViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiShapeView; using PlatformView = Microsoft.Maui.Platform.MauiShapeView; #elif WINDOWS using PlatformView = Microsoft.Maui.Graphics.Win2D.W2DGraphicsView; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.MauiShapeView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/ShapeView/ShapeViewHandler.Tizen.cs b/src/Core/src/Handlers/ShapeView/ShapeViewHandler.Tizen.cs new file mode 100644 index 0000000000..528167a5b6 --- /dev/null +++ b/src/Core/src/Handlers/ShapeView/ShapeViewHandler.Tizen.cs @@ -0,0 +1,76 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class ShapeViewHandler : ViewHandler + { + protected virtual double MinimumSize => 40d; + + protected override MauiShapeView CreatePlatformView() + { + return new MauiShapeView(NativeParent!) + { + MinimumWidth = MinimumSize.ToScaledPixel(), + MinimumHeight = MinimumSize.ToScaledPixel() + }; + } + + protected override void SetupContainer() + { + base.SetupContainer(); + ContainerView?.UpdateShape(VirtualView.Shape); + } + + public static void MapShape(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.UpdateShape(shapeView); + if (handler.ContainerView is WrapperView wrapperView) + wrapperView.UpdateShape(shapeView.Shape); + } + + public static void MapAspect(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapFill(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapStroke(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapStrokeThickness(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapStrokeDashPattern(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapStrokeDashOffset(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapStrokeLineCap(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapStrokeLineJoin(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + + public static void MapStrokeMiterLimit(IShapeViewHandler handler, IShapeView shapeView) + { + handler.PlatformView?.InvalidateShape(shapeView); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/ShapeView/ShapeViewHandler.cs b/src/Core/src/Handlers/ShapeView/ShapeViewHandler.cs index e53c785757..423bbbb094 100644 --- a/src/Core/src/Handlers/ShapeView/ShapeViewHandler.cs +++ b/src/Core/src/Handlers/ShapeView/ShapeViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiShapeView; using PlatformView = Microsoft.Maui.Platform.MauiShapeView; #elif WINDOWS using PlatformView = Microsoft.Maui.Graphics.Win2D.W2DGraphicsView; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.MauiShapeView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Slider/ISliderHandler.cs b/src/Core/src/Handlers/Slider/ISliderHandler.cs index 8106dc4dac..77bc21bae4 100644 --- a/src/Core/src/Handlers/Slider/ISliderHandler.cs +++ b/src/Core/src/Handlers/Slider/ISliderHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UISlider; using PlatformView = Android.Widget.SeekBar; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Slider; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.Slider; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Slider/SliderHandler.Tizen.cs b/src/Core/src/Handlers/Slider/SliderHandler.Tizen.cs new file mode 100644 index 0000000000..254294ce62 --- /dev/null +++ b/src/Core/src/Handlers/Slider/SliderHandler.Tizen.cs @@ -0,0 +1,90 @@ +using System; +using Tizen.UIExtensions.ElmSharp; +using EColor = ElmSharp.Color; +using ESlider = ElmSharp.Slider; + +namespace Microsoft.Maui.Handlers +{ + public partial class SliderHandler : ViewHandler + { + static EColor? DefaultMinTrackColor; + static EColor? DefaultMaxTrackColor; + static EColor? DefaultThumbColor; + + protected override ESlider CreatePlatformView() => new ESlider(NativeParent); + + protected override void ConnectHandler(ESlider platformView) + { + platformView!.ValueChanged += OnControlValueChanged; + platformView!.DragStarted += OnDragStarted; + platformView!.DragStopped += OnDragStopped; + } + + protected override void DisconnectHandler(ESlider platformView) + { + platformView!.ValueChanged -= OnControlValueChanged; + platformView!.DragStarted -= OnDragStarted; + platformView!.DragStopped -= OnDragStopped; + } + + void SetupDefaults(ESlider platformView) + { + DefaultMinTrackColor = platformView.GetBarColor(); + DefaultMaxTrackColor = platformView.GetBackgroundColor(); + DefaultThumbColor = platformView.GetHandlerColor(); + } + + public static void MapMinimum(ISliderHandler handler, ISlider slider) + { + handler.PlatformView?.UpdateMinimum(slider); + } + + public static void MapMaximum(ISliderHandler handler, ISlider slider) + { + handler.PlatformView?.UpdateMaximum(slider); + } + + + public static void MapValue(ISliderHandler handler, ISlider slider) + { + handler.PlatformView?.UpdateValue(slider); + } + + public static void MapMinimumTrackColor(ISliderHandler handler, ISlider slider) + { + handler.PlatformView?.UpdateMinimumTrackColor(slider, DefaultMinTrackColor); + } + + public static void MapMaximumTrackColor(ISliderHandler handler, ISlider slider) + { + handler.PlatformView?.UpdateMaximumTrackColor(slider, DefaultMaxTrackColor); + } + + public static void MapThumbColor(ISliderHandler handler, ISlider slider) + { + + handler.PlatformView?.UpdateThumbColor(slider, DefaultThumbColor); + } + + [MissingMapper] + public static void MapThumbImageSource(ISliderHandler handler, ISlider slider) { } + + void OnControlValueChanged(object? sender, EventArgs eventArgs) + { + if (PlatformView == null || VirtualView == null) + return; + + VirtualView.Value = PlatformView.Value; + } + + void OnDragStarted(object? sender, EventArgs e) + { + VirtualView?.DragStarted(); + } + + void OnDragStopped(object? sender, EventArgs e) + { + VirtualView?.DragCompleted(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Slider/SliderHandler.cs b/src/Core/src/Handlers/Slider/SliderHandler.cs index d9bea82969..44dfb79097 100644 --- a/src/Core/src/Handlers/Slider/SliderHandler.cs +++ b/src/Core/src/Handlers/Slider/SliderHandler.cs @@ -5,7 +5,9 @@ using PlatformView = UIKit.UISlider; using PlatformView = Android.Widget.SeekBar; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.Slider; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.Slider; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Stepper/StepperHandler.Tizen.cs b/src/Core/src/Handlers/Stepper/StepperHandler.Tizen.cs new file mode 100644 index 0000000000..05f18aed77 --- /dev/null +++ b/src/Core/src/Handlers/Stepper/StepperHandler.Tizen.cs @@ -0,0 +1,48 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class StepperHandler : ViewHandler + { + protected override Spinner CreatePlatformView() => new Spinner(NativeParent) { IsEditable = false }; + + protected override void ConnectHandler(Spinner platformView) + { + platformView!.ValueChanged += OnValueChanged; + } + + protected override void DisconnectHandler(Spinner platformView) + { + platformView!.ValueChanged -= OnValueChanged; + } + + public static void MapMinimum(StepperHandler handler, IStepper stepper) + { + handler.PlatformView?.UpdateMinimum(stepper); + } + + public static void MapMaximum(StepperHandler handler, IStepper stepper) + { + handler.PlatformView?.UpdateMaximum(stepper); + } + + public static void MapIncrement(StepperHandler handler, IStepper stepper) + { + handler.PlatformView?.UpdateIncrement(stepper); + } + + public static void MapValue(StepperHandler handler, IStepper stepper) + { + handler.PlatformView?.UpdateValue(stepper); + } + + void OnValueChanged(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null) + return; + + VirtualView.Value = PlatformView.Value; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/SwipeItemMenuItem/ISwipeItemMenuItemHandler.cs b/src/Core/src/Handlers/SwipeItemMenuItem/ISwipeItemMenuItemHandler.cs index 3a5141371a..9c5cee02e6 100644 --- a/src/Core/src/Handlers/SwipeItemMenuItem/ISwipeItemMenuItemHandler.cs +++ b/src/Core/src/Handlers/SwipeItemMenuItem/ISwipeItemMenuItemHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIButton; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.SwipeItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Tizen.cs b/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Tizen.cs new file mode 100644 index 0000000000..e5a57db528 --- /dev/null +++ b/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Tizen.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + //TODO : Need to implement + public partial class SwipeItemMenuItemHandler : ElementHandler + { + protected override EvasObject CreatePlatformElement() + { + throw new NotImplementedException(); + } + + public static void MapTextColor(ISwipeItemMenuItemHandler handler, ITextStyle view) { } + + public static void MapCharacterSpacing(ISwipeItemMenuItemHandler handler, ITextStyle view) { } + + public static void MapFont(ISwipeItemMenuItemHandler handler, ITextStyle view) { } + + public static void MapText(ISwipeItemMenuItemHandler handler, ISwipeItemMenuItem view) { } + + public static void MapBackground(ISwipeItemMenuItemHandler handler, ISwipeItemMenuItem view) { } + + public static void MapVisibility(ISwipeItemMenuItemHandler handler, ISwipeItemMenuItem view) { } + + void OnSetImageSource(EvasObject? obj) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.cs b/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.cs index 371a3d8c1d..f029e52191 100644 --- a/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.cs +++ b/src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIButton; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.SwipeItem; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/SwipeItemView/ISwipeItemViewHandler.cs b/src/Core/src/Handlers/SwipeItemView/ISwipeItemViewHandler.cs index 210985589d..950b0f48a6 100644 --- a/src/Core/src/Handlers/SwipeItemView/ISwipeItemViewHandler.cs +++ b/src/Core/src/Handlers/SwipeItemView/ISwipeItemViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.ContentCanvas; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.Tizen.cs b/src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.Tizen.cs new file mode 100644 index 0000000000..a02c369b2e --- /dev/null +++ b/src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.Tizen.cs @@ -0,0 +1,73 @@ +using System; +using PlatformView = Microsoft.Maui.Platform.ContentCanvas; + +namespace Microsoft.Maui.Handlers +{ + public partial class SwipeItemViewHandler : ViewHandler, ISwipeItemViewHandler + { + IPlatformViewHandler? _contentHandler; + + protected override ContentCanvas CreatePlatformView() + { + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} must be set to create a Page"); + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} cannot be null"); + + var view = new ContentCanvas(NativeParent, VirtualView) + { + CrossPlatformMeasure = VirtualView.CrossPlatformMeasure, + CrossPlatformArrange = VirtualView.CrossPlatformArrange + }; + + view.Show(); + return view; + } + + public override void SetVirtualView(IView view) + { + base.SetVirtualView(view); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + + PlatformView.CrossPlatformMeasure = VirtualView.CrossPlatformMeasure; + PlatformView.CrossPlatformArrange = VirtualView.CrossPlatformArrange; + } + + void UpdateContent() + { + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + // Cleanup the old view when reused + PlatformView.Children.Clear(); + _contentHandler?.Dispose(); + _contentHandler = null; + + if (VirtualView.PresentedContent is IView view) + { + PlatformView.Children.Add(view.ToPlatform(MauiContext)); + if (view.Handler is IPlatformViewHandler thandler) + { + thandler?.SetParent(this); + _contentHandler = thandler; + } + } + } + + public static void MapContent(ISwipeItemViewHandler handler, ISwipeItemView page) + { + if (handler is SwipeItemViewHandler platformHandler) + platformHandler.UpdateContent(); + } + + public static void MapVisibility(ISwipeItemViewHandler handler, ISwipeItemView view) + { + //TODO : need to update + //var swipeView = handler.PlatformView.GetParentOfType(); + //if (swipeView != null) + // swipeView.UpdateIsVisibleSwipeItem(view); + + //handler.PlatformView.UpdateVisibility(view.Visibility); + } + } +} diff --git a/src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.cs b/src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.cs index a79138dffa..7809d57261 100644 --- a/src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.cs +++ b/src/Core/src/Handlers/SwipeItemView/SwipeItemViewHandler.cs @@ -5,7 +5,9 @@ using PlatformView = Microsoft.Maui.Platform.ContentView; using PlatformView = Microsoft.Maui.Platform.ContentViewGroup; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.ContentCanvas; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/SwipeView/ISwipeViewHandler.cs b/src/Core/src/Handlers/SwipeView/ISwipeViewHandler.cs index a562934331..66f2b80199 100644 --- a/src/Core/src/Handlers/SwipeView/ISwipeViewHandler.cs +++ b/src/Core/src/Handlers/SwipeView/ISwipeViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiSwipeView; using PlatformView = Microsoft.Maui.Platform.MauiSwipeView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.SwipeControl; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif @@ -15,4 +17,4 @@ namespace Microsoft.Maui.Handlers new ISwipeView VirtualView { get; } new PlatformView PlatformView { get; } } -} \ No newline at end of file +} diff --git a/src/Core/src/Handlers/SwipeView/SwipeViewHandler.Tizen.cs b/src/Core/src/Handlers/SwipeView/SwipeViewHandler.Tizen.cs new file mode 100644 index 0000000000..c5914049c5 --- /dev/null +++ b/src/Core/src/Handlers/SwipeView/SwipeViewHandler.Tizen.cs @@ -0,0 +1,61 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class SwipeViewHandler : ViewHandler + { + // TODO : Need to implement + protected override EvasObject CreatePlatformView() + { + throw new NotImplementedException(); + } + + public override void SetVirtualView(IView view) + { + base.SetVirtualView(view); + _ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + _ = PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + } + + public static void MapContent(ISwipeViewHandler handler, ISwipeView view) + { + _ = handler.PlatformView ?? throw new InvalidOperationException($"{nameof(PlatformView)} should have been set by base class."); + _ = handler.MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + _ = handler.VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class."); + } + + public static void MapSwipeTransitionMode(ISwipeViewHandler handler, ISwipeView swipeView) + { + } + + public static void MapRequestOpen(ISwipeViewHandler handler, ISwipeView swipeView, object? args) + { + if (args is not SwipeViewOpenRequest request) + { + return; + } + } + + public static void MapRequestClose(ISwipeViewHandler handler, ISwipeView swipeView, object? args) + { + if (args is not SwipeViewCloseRequest request) + { + return; + } + } + + public static void MapLeftItems(ISwipeViewHandler handler, ISwipeView view) + { + } + public static void MapTopItems(ISwipeViewHandler handler, ISwipeView view) + { + } + public static void MapRightItems(ISwipeViewHandler handler, ISwipeView view) + { + } + public static void MapBottomItems(ISwipeViewHandler handler, ISwipeView view) + { + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/SwipeView/SwipeViewHandler.cs b/src/Core/src/Handlers/SwipeView/SwipeViewHandler.cs index e0f41a232d..4f58823e10 100644 --- a/src/Core/src/Handlers/SwipeView/SwipeViewHandler.cs +++ b/src/Core/src/Handlers/SwipeView/SwipeViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = Microsoft.Maui.Platform.MauiSwipeView; using PlatformView = Microsoft.Maui.Platform.MauiSwipeView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.SwipeControl; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif @@ -53,4 +55,4 @@ namespace Microsoft.Maui.Handlers PlatformView ISwipeViewHandler.PlatformView => PlatformView; } -} \ No newline at end of file +} diff --git a/src/Core/src/Handlers/Switch/ISwitchHandler.cs b/src/Core/src/Handlers/Switch/ISwitchHandler.cs index e9b549772b..452a9a6092 100644 --- a/src/Core/src/Handlers/Switch/ISwitchHandler.cs +++ b/src/Core/src/Handlers/Switch/ISwitchHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UISwitch; using PlatformView = AndroidX.AppCompat.Widget.SwitchCompat; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ToggleSwitch; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.Check; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Switch/SwitchHandler.Tizen.cs b/src/Core/src/Handlers/Switch/SwitchHandler.Tizen.cs new file mode 100644 index 0000000000..a41c763732 --- /dev/null +++ b/src/Core/src/Handlers/Switch/SwitchHandler.Tizen.cs @@ -0,0 +1,48 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class SwitchHandler : ViewHandler + { + protected override Check CreatePlatformView() => new Check(NativeParent) + { + Style = "toggle" + }; + + protected override void ConnectHandler(Check nativeView) + { + base.ConnectHandler(nativeView); + nativeView!.StateChanged += OnStateChanged; + } + + protected override void DisconnectHandler(Check nativeView) + { + base.DisconnectHandler(nativeView); + nativeView!.StateChanged -= OnStateChanged; + } + + public static void MapIsOn(ISwitchHandler handler, ISwitch view) + { + handler.PlatformView?.UpdateIsOn(view); + } + + public static void MapTrackColor(ISwitchHandler handler, ISwitch view) + { + handler.PlatformView?.UpdateTrackColor(view); + } + + public static void MapThumbColor(ISwitchHandler handler, ISwitch view) + { + handler.PlatformView?.UpdateThumbColor(view); + } + + void OnStateChanged(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null) + return; + + VirtualView.IsOn = PlatformView.IsChecked; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Switch/SwitchHandler.cs b/src/Core/src/Handlers/Switch/SwitchHandler.cs index d03bac9f40..5c36e2ee1a 100644 --- a/src/Core/src/Handlers/Switch/SwitchHandler.cs +++ b/src/Core/src/Handlers/Switch/SwitchHandler.cs @@ -5,7 +5,9 @@ using PlatformView = UIKit.UISwitch; using PlatformView = AndroidX.AppCompat.Widget.SwitchCompat; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.ToggleSwitch; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.Check; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/TabbedView/TabbedViewHandler.cs b/src/Core/src/Handlers/TabbedView/TabbedViewHandler.cs index fe4c17f3b2..61a1582160 100644 --- a/src/Core/src/Handlers/TabbedView/TabbedViewHandler.cs +++ b/src/Core/src/Handlers/TabbedView/TabbedViewHandler.cs @@ -7,7 +7,9 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/TimePicker/ITimePickerHandler.cs b/src/Core/src/Handlers/TimePicker/ITimePickerHandler.cs index dfc5b840ed..2cb1e4e6b4 100644 --- a/src/Core/src/Handlers/TimePicker/ITimePickerHandler.cs +++ b/src/Core/src/Handlers/TimePicker/ITimePickerHandler.cs @@ -6,7 +6,9 @@ using PlatformView = UIKit.UIDatePicker; using PlatformView = Microsoft.Maui.Platform.MauiTimePicker; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TimePicker; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/TimePicker/TimePickerHandler.Tizen.cs b/src/Core/src/Handlers/TimePicker/TimePickerHandler.Tizen.cs new file mode 100644 index 0000000000..1ef8288daa --- /dev/null +++ b/src/Core/src/Handlers/TimePicker/TimePickerHandler.Tizen.cs @@ -0,0 +1,131 @@ +using System; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using TEntry = Tizen.UIExtensions.ElmSharp.Entry; +using TTextAlignment = Tizen.UIExtensions.Common.TextAlignment; +using EcoreMainloop = ElmSharp.EcoreMainloop; + +namespace Microsoft.Maui.Handlers +{ + public partial class TimePickerHandler : ViewHandler + { + const string DialogTitle = "Choose Time"; + Lazy? _lazyDialog; + + protected override TEntry CreatePlatformView() + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + var entry = new EditfieldEntry(NativeParent) + { + IsSingleLine = true, + HorizontalTextAlignment = TTextAlignment.Center, + InputPanelShowByOnDemand = true, + IsEditable = false + }; + entry.SetVerticalTextAlignment(0.5); + return entry; + } + + protected override void ConnectHandler(TEntry platformView) + { + _ = NativeParent ?? throw new ArgumentNullException(nameof(NativeParent)); + + platformView.TextBlockFocused += OnTextBlockFocused; + platformView.EntryLayoutFocused += OnFocused; + platformView.EntryLayoutUnfocused += OnUnfocused; + + _lazyDialog = new Lazy(() => + { + var dialog = new DateTimePickerDialog(NativeParent) + { + Mode = DateTimePickerMode.Time, + Title = DialogTitle + }; + dialog.DateTimeChanged += OnDateTimeChanged; + dialog.PickerOpened += OnPickerOpened; + dialog.PickerClosed += OnPickerClosed; + return dialog; + }); + + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(TEntry platformView) + { + if (_lazyDialog != null && _lazyDialog.IsValueCreated) + { + _lazyDialog.Value.DateTimeChanged -= OnDateTimeChanged; + _lazyDialog.Value.PickerOpened -= OnPickerOpened; + _lazyDialog.Value.PickerClosed -= OnPickerClosed; + _lazyDialog.Value.Unrealize(); + _lazyDialog = null; + } + + platformView.TextBlockFocused -= OnTextBlockFocused; + platformView.EntryLayoutFocused -= OnFocused; + platformView.EntryLayoutUnfocused -= OnUnfocused; + + base.DisconnectHandler(platformView); + } + + public static void MapFormat(ITimePickerHandler handler, ITimePicker timePicker) + { + handler.PlatformView?.UpdateFormat(timePicker); + } + + public static void MapTime(ITimePickerHandler handler, ITimePicker timePicker) + { + handler.PlatformView?.UpdateTime(timePicker); + } + + public static void MapFont(ITimePickerHandler handler, ITimePicker timePicker) + { + var fontManager = handler.GetRequiredService(); + handler.PlatformView?.UpdateFont(timePicker, fontManager); + } + + public static void MapTextColor(ITimePickerHandler handler, ITimePicker timePicker) + { + handler.PlatformView?.UpdateTextColor(timePicker); + } + + [MissingMapper] + public static void MapCharacterSpacing(ITimePickerHandler handler, ITimePicker timePicker) { } + + protected virtual void OnDateTimeChanged(object? sender, DateChangedEventArgs dcea) + { + if (VirtualView == null || PlatformView == null) + return; + + VirtualView.Time = dcea.NewDate.TimeOfDay; + } + + void OnTextBlockFocused(object? sender, EventArgs e) + { + if (VirtualView == null || PlatformView == null || _lazyDialog == null) + return; + + // For EFL Entry, the event will occur even if it is currently disabled. + // If the problem is resolved, no conditional statement is required. + if (VirtualView.IsEnabled) + { + var dialog = _lazyDialog.Value; + dialog.DateTime -= dialog.DateTime.TimeOfDay; + dialog.DateTime += VirtualView.Time; + + // You need to call Show() after ui thread occupation because of EFL problem. + // Otherwise, the content of the popup will not receive focus. + EcoreMainloop.Post(() => dialog.Show()); + } + } + + protected virtual void OnPickerOpened(object? sender, EventArgs args) + { + } + + protected virtual void OnPickerClosed(object? sender, EventArgs args) + { + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/TimePicker/TimePickerHandler.cs b/src/Core/src/Handlers/TimePicker/TimePickerHandler.cs index 84fbd67ade..8d7c558098 100644 --- a/src/Core/src/Handlers/TimePicker/TimePickerHandler.cs +++ b/src/Core/src/Handlers/TimePicker/TimePickerHandler.cs @@ -6,7 +6,9 @@ using PlatformView = UIKit.UIDatePicker; using PlatformView = Microsoft.Maui.Platform.MauiTimePicker; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.TimePicker; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Entry; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Toolbar/IToolbarHandler.cs b/src/Core/src/Handlers/Toolbar/IToolbarHandler.cs index 280bffd7b8..8e61d7a480 100644 --- a/src/Core/src/Handlers/Toolbar/IToolbarHandler.cs +++ b/src/Core/src/Handlers/Toolbar/IToolbarHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UINavigationBar; using PlatformView = Google.Android.Material.AppBar.MaterialToolbar; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.MauiToolbar; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView =ElmSharp.Toolbar; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Toolbar/ToolbarHandler.Tizen.cs b/src/Core/src/Handlers/Toolbar/ToolbarHandler.Tizen.cs new file mode 100644 index 0000000000..3603642efa --- /dev/null +++ b/src/Core/src/Handlers/Toolbar/ToolbarHandler.Tizen.cs @@ -0,0 +1,16 @@ +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class ToolbarHandler : ElementHandler + { + protected override Toolbar CreatePlatformElement() + { + throw new System.NotImplementedException(); + } + + public static void MapTitle(IToolbarHandler arg1, IToolbar arg2) + { + } + } +} diff --git a/src/Core/src/Handlers/Toolbar/ToolbarHandler.cs b/src/Core/src/Handlers/Toolbar/ToolbarHandler.cs index 93de9b2fde..1cc4a0f3e6 100644 --- a/src/Core/src/Handlers/Toolbar/ToolbarHandler.cs +++ b/src/Core/src/Handlers/Toolbar/ToolbarHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UINavigationBar; using PlatformView = Google.Android.Material.AppBar.MaterialToolbar; #elif WINDOWS using PlatformView = Microsoft.Maui.Platform.MauiToolbar; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView =ElmSharp.Toolbar; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/View/ViewHandler.Tizen.cs b/src/Core/src/Handlers/View/ViewHandler.Tizen.cs new file mode 100644 index 0000000000..7032b427d4 --- /dev/null +++ b/src/Core/src/Handlers/View/ViewHandler.Tizen.cs @@ -0,0 +1,130 @@ +using System; +using ElmSharp; +using PlatformView = ElmSharp.EvasObject; + +namespace Microsoft.Maui.Handlers +{ + public partial class ViewHandler + { + static partial void MappingFrame(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapTranslationX(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapTranslationY(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapScale(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapScaleX(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapScaleY(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapRotation(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapRotationX(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapRotationY(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapAnchorX(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + public static void MapAnchorY(IViewHandler handler, IView view) + { + UpdateTransformation(handler, view); + } + + internal static void UpdateTransformation(IViewHandler handler, IView view) + { + handler.ToPlatform()?.UpdateTransformation(view); + } + + protected virtual void OnPlatformViewDeleted() + { + } + + protected virtual void OnFocused() + { + } + + protected virtual void OnUnfocused() + { + } + + protected void OnFocused(object? sender, EventArgs e) + { + OnFocused(); + } + + protected void OnUnfocused(object? sender, EventArgs e) + { + OnUnfocused(); + } + + partial void ConnectingHandler(PlatformView? platformView) + { + if (platformView == null) + return; + + + platformView.Deleted += OnPlatformViewDeleted; + + if (platformView is Widget widget) + { + widget.Focused += OnFocused; + widget.Unfocused += OnUnfocused; + } + } + + partial void DisconnectingHandler(PlatformView platformView) + { + if (platformView == null) + return; + + platformView.Deleted -= OnPlatformViewDeleted; + } + + public virtual bool NeedsContainer + { + get + { + if(VirtualView is IBorderView border) + return border?.Shape != null || border?.Stroke != null; + + return false; + } + } + + void OnPlatformViewDeleted(object? sender, EventArgs e) + { + OnPlatformViewDeleted(); + } + } +} diff --git a/src/Core/src/Handlers/View/ViewHandler.cs b/src/Core/src/Handlers/View/ViewHandler.cs index 12e0ab82fc..92ada0d938 100644 --- a/src/Core/src/Handlers/View/ViewHandler.cs +++ b/src/Core/src/Handlers/View/ViewHandler.cs @@ -7,6 +7,8 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/View/ViewHandlerOfT.Tizen.cs b/src/Core/src/Handlers/View/ViewHandlerOfT.Tizen.cs new file mode 100644 index 0000000000..06e5383c59 --- /dev/null +++ b/src/Core/src/Handlers/View/ViewHandlerOfT.Tizen.cs @@ -0,0 +1,202 @@ +using System; +using ElmSharp; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using ERect = ElmSharp.Rect; +using ESize = ElmSharp.Size; +using Point = Microsoft.Maui.Graphics.Point; +using Rect = Microsoft.Maui.Graphics.Rect; +using Size = Microsoft.Maui.Graphics.Size; + +namespace Microsoft.Maui.Handlers +{ + public abstract partial class ViewHandler : IPlatformViewHandler + { + bool _disposedValue; + + EvasObject? IPlatformViewHandler.PlatformView => this.ToPlatform(); + EvasObject? IPlatformViewHandler.ContainerView => ContainerView; + + public new WrapperView? ContainerView + { + get => (WrapperView?)base.ContainerView; + protected set => base.ContainerView = value; + } + + public void SetParent(IPlatformViewHandler parent) => Parent = parent; + + public IPlatformViewHandler? Parent { get; private set; } + + public EvasObject? NativeParent => MauiContext?.GetNativeParent(); + + ~ViewHandler() + { + Dispose(disposing: false); + } + + public override bool NeedsContainer => + VirtualView?.Background != null || + VirtualView?.Clip != null || + VirtualView?.Shadow != null || + base.NeedsContainer; + + public override void PlatformArrange(Rect frame) + { + if (NativeParent == null) + return; + + var platformView = this.ToPlatform(); + + if (platformView == null) + return; + + if (frame.Width < 0 || frame.Height < 0) + { + // This is just some initial Forms value nonsense, nothing is actually laying out yet + return; + } + + platformView.UpdateBounds(new Rect(ComputeAbsolutePoint(frame), new Size(frame.Width, frame.Height)).ToPixel()); + } + + public override Size GetDesiredSize(double widthConstraint, double heightConstraint) + { + var platformView = base.PlatformView; + + if (platformView == null || VirtualView == null || NativeParent == null) + { + return VirtualView == null || double.IsNaN(VirtualView.Width) || double.IsNaN(VirtualView.Height) ? Size.Zero : new Size(VirtualView.Width, VirtualView.Height); + } + + int availableWidth = widthConstraint.ToScaledPixel(); + int availableHeight = heightConstraint.ToScaledPixel(); + + if (availableWidth < 0) + availableWidth = int.MaxValue; + if (availableHeight < 0) + availableHeight = int.MaxValue; + + var explicitWidth = VirtualView.Width; + var explicitHeight = VirtualView.Height; + var hasExplicitWidth = explicitWidth >= 0; + var hasExplicitHeight = explicitHeight >= 0; + + Size measured; + if (platformView is IMeasurable platformViewMeasurable) + { + measured = platformViewMeasurable.Measure(availableWidth, availableHeight).ToDP(); + } + else + { + measured = Measure(availableWidth, availableHeight); + } + + return new Size(hasExplicitWidth ? explicitWidth : measured.Width, + hasExplicitHeight ? explicitHeight : measured.Height); + } + + public virtual ERect GetPlatformContentGeometry() + { + var platformView = this.ToPlatform(); + + if (platformView == null) + { + return new ERect(); + } + return platformView.Geometry; + } + + protected virtual Size Measure(double availableWidth, double availableHeight) + { + var platformView = this.ToPlatform(); + + if (platformView == null) + { + return new Size(0, 0); + } + return new ESize(platformView.MinimumWidth, platformView.MinimumHeight).ToDP(); + } + + protected virtual double ComputeAbsoluteX(Rect frame) + { + if (Parent != null) + { + return frame.X + Parent.GetPlatformContentGeometry().X.ToScaledDP(); + } + else + { + return frame.X; + } + } + + protected virtual double ComputeAbsoluteY(Rect frame) + { + if (Parent != null) + { + return frame.Y + Parent.GetPlatformContentGeometry().Y.ToScaledDP(); + } + else + { + return frame.Y; + } + } + + protected virtual Point ComputeAbsolutePoint(Rect frame) + { + return new Point(ComputeAbsoluteX(frame), ComputeAbsoluteY(frame)); + } + + protected override void SetupContainer() + { + var parent = Parent?.PlatformView as IContainable; + parent?.Children.Remove(PlatformView!); + + ContainerView ??= new WrapperView(NativeParent!); + ContainerView.Show(); + ContainerView.Content = PlatformView; + + parent?.Children?.Add(ContainerView); + } + + protected override void RemoveContainer() + { + var parent = Parent?.PlatformView as IContainable; + parent?.Children.Remove(ContainerView!); + + ContainerView!.Content = null; + ContainerView?.Unrealize(); + ContainerView = null; + + parent?.Children.Add(PlatformView!); + } + + protected override void OnPlatformViewDeleted() + { + Dispose(); + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + var platformView = base.PlatformView; + (this as IElementHandler)?.DisconnectHandler(); + platformView?.Unrealize(); + ContainerView?.Unrealize(); + } + + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + _disposedValue = true; + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Core/src/Handlers/View/ViewHandlerOfT.cs b/src/Core/src/Handlers/View/ViewHandlerOfT.cs index 4f58c487f9..26c1b90ab9 100644 --- a/src/Core/src/Handlers/View/ViewHandlerOfT.cs +++ b/src/Core/src/Handlers/View/ViewHandlerOfT.cs @@ -5,7 +5,9 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif @@ -13,7 +15,7 @@ namespace Microsoft.Maui.Handlers { public abstract partial class ViewHandler : ViewHandler, IViewHandler where TVirtualView : class, IView -#if !NETSTANDARD || IOS || ANDROID || WINDOWS +#if !NETSTANDARD || IOS || ANDROID || WINDOWS || TIZEN where TPlatformView : PlatformView #else where TPlatformView : class diff --git a/src/Core/src/Handlers/WebView/IWebViewHandler.cs b/src/Core/src/Handlers/WebView/IWebViewHandler.cs index 478a0d4523..a1c83577b1 100644 --- a/src/Core/src/Handlers/WebView/IWebViewHandler.cs +++ b/src/Core/src/Handlers/WebView/IWebViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = WebKit.WKWebView; using PlatformView = Android.Webkit.WebView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.WebView2; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.MauiWebView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/WebView/WebViewHandler.Tizen.cs b/src/Core/src/Handlers/WebView/WebViewHandler.Tizen.cs new file mode 100644 index 0000000000..0fad49fc97 --- /dev/null +++ b/src/Core/src/Handlers/WebView/WebViewHandler.Tizen.cs @@ -0,0 +1,80 @@ +using System; +using Tizen.UIExtensions.ElmSharp; +using TChromium = Tizen.WebView.Chromium; +using TWebView = Tizen.WebView.WebView; + +namespace Microsoft.Maui.Handlers +{ + public partial class WebViewHandler : ViewHandler + { + protected virtual double MinimumSize => 44d; + + TWebView PlatformWebView => PlatformView.WebView; + + public static void MapSource(IWebViewHandler handler, IWebView webView) + { + IWebViewDelegate? webViewDelegate = handler.PlatformView as IWebViewDelegate; + handler.PlatformView?.UpdateSource(webView, webViewDelegate); + } + + public static void MapGoBack(IWebViewHandler handler, IWebView webView, object? arg) + { + handler.PlatformView?.UpdateGoBack(webView); + } + + public static void MapGoForward(IWebViewHandler handler, IWebView webView, object? arg) + { + handler.PlatformView?.UpdateGoForward(webView); + } + + public static void MapReload(IWebViewHandler handler, IWebView webView, object? arg) + { + handler.PlatformView?.UpdateReload(webView); + } + + public static void MapEval(IWebViewHandler handler, IWebView webView, object? arg) + { + if (arg is not string script) + return; + + handler.PlatformView?.Eval(webView, script); + } + + public static void MapEvaluateJavaScriptAsync(IWebViewHandler handler, IWebView webView, object? arg) + { + if (arg is not string script) + return; + + handler.PlatformView?.Eval(webView, script); + } + + protected override MauiWebView CreatePlatformView() + { + _ = NativeParent ?? throw new InvalidOperationException($"{nameof(NativeParent)} should have been set by base class."); + return new MauiWebView(NativeParent) + { + MinimumHeight = MinimumSize.ToScaledPixel(), + MinimumWidth = MinimumSize.ToScaledPixel() + }; + } + + protected override void ConnectHandler(MauiWebView platformView) + { + TChromium.Initialize(); + MauiApplication.Current.Terminated += (sender, arg) => TChromium.Shutdown(); + PlatformWebView.LoadFinished += OnLoadFinished; + } + + protected override void DisconnectHandler(MauiWebView platformView) + { + PlatformWebView.StopLoading(); + PlatformWebView.LoadFinished -= OnLoadFinished; + base.DisconnectHandler(platformView); + } + + void OnLoadFinished(object? sender, EventArgs e) + { + PlatformWebView.SetFocus(true); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/WebView/WebViewHandler.cs b/src/Core/src/Handlers/WebView/WebViewHandler.cs index 03abec556b..b21dd79a26 100644 --- a/src/Core/src/Handlers/WebView/WebViewHandler.cs +++ b/src/Core/src/Handlers/WebView/WebViewHandler.cs @@ -4,7 +4,9 @@ using PlatformView = WebKit.WKWebView; using PlatformView = Android.Webkit.WebView; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Controls.WebView2; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Microsoft.Maui.Platform.MauiWebView; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Window/IWindowHandler.cs b/src/Core/src/Handlers/Window/IWindowHandler.cs index 0a26f19dd4..762a0c9d69 100644 --- a/src/Core/src/Handlers/Window/IWindowHandler.cs +++ b/src/Core/src/Handlers/Window/IWindowHandler.cs @@ -4,7 +4,9 @@ using PlatformView = UIKit.UIWindow; using PlatformView = Android.App.Activity; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Window; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.Window; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/Handlers/Window/WindowHandler.Tizen.cs b/src/Core/src/Handlers/Window/WindowHandler.Tizen.cs new file mode 100644 index 0000000000..7c381ea88a --- /dev/null +++ b/src/Core/src/Handlers/Window/WindowHandler.Tizen.cs @@ -0,0 +1,32 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Handlers +{ + public partial class WindowHandler : ElementHandler + { + public static void MapTitle(IWindowHandler handler, IWindow window) { } + + public static void MapContent(IWindowHandler handler, IWindow window) + { + _ = handler.MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class."); + + var nativeContent = window.Content.ToContainerView(handler.MauiContext); + + nativeContent.SetAlignment(-1, -1); + nativeContent.SetWeight(1, 1); + nativeContent.Show(); + handler.MauiContext.GetModalStack().Reset(); + handler.MauiContext.GetModalStack().Push(nativeContent); + + if (window.VisualDiagnosticsOverlay != null) + window.VisualDiagnosticsOverlay.Initialize(); + } + + public static void MapRequestDisplayDensity(IWindowHandler handler, IWindow window, object? args) + { + if (args is DisplayDensityRequest request) + request.SetResult(handler.PlatformView.GetDisplayDensity()); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Handlers/Window/WindowHandler.cs b/src/Core/src/Handlers/Window/WindowHandler.cs index a77f2dcef5..6781f370c8 100644 --- a/src/Core/src/Handlers/Window/WindowHandler.cs +++ b/src/Core/src/Handlers/Window/WindowHandler.cs @@ -6,6 +6,8 @@ using PlatformView = UIKit.UIWindow; using PlatformView = Android.App.Activity; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Window; +#elif TIZEN +using PlatformView = ElmSharp.Window; #endif namespace Microsoft.Maui.Handlers diff --git a/src/Core/src/Hosting/EssentialsMauiAppBuilderExtensions.cs b/src/Core/src/Hosting/EssentialsMauiAppBuilderExtensions.cs index f79dcec33b..d6814ea51f 100644 --- a/src/Core/src/Hosting/EssentialsMauiAppBuilderExtensions.cs +++ b/src/Core/src/Hosting/EssentialsMauiAppBuilderExtensions.cs @@ -74,6 +74,8 @@ namespace Microsoft.Maui.Hosting { ApplicationModel.Platform.OnLaunched(args); })); +#elif TIZEN + #endif }); @@ -134,12 +136,14 @@ namespace Microsoft.Maui.Hosting ApplicationModel.Platform.MapServiceToken = _essentialsBuilder.MapServiceToken; #endif +#if !TIZEN AppActions.OnAppAction += HandleOnAppAction; if (_essentialsBuilder.AppActions is not null) { SetAppActions(services, _essentialsBuilder.AppActions); } +#endif if (_essentialsBuilder.TrackVersions) VersionTracking.Track(); @@ -203,4 +207,4 @@ namespace Microsoft.Maui.Hosting } } } -} \ No newline at end of file +} diff --git a/src/Core/src/Hosting/LifecycleEvents/AppHostBuilderExtensions.Tizen.cs b/src/Core/src/Hosting/LifecycleEvents/AppHostBuilderExtensions.Tizen.cs new file mode 100644 index 0000000000..42c2ba653d --- /dev/null +++ b/src/Core/src/Hosting/LifecycleEvents/AppHostBuilderExtensions.Tizen.cs @@ -0,0 +1,37 @@ +using System; +using Microsoft.Maui.Hosting; +using Microsoft.Maui.LifecycleEvents; + +namespace Microsoft.Maui.LifecycleEvents +{ + public static partial class AppHostBuilderExtensions + { + internal static MauiAppBuilder ConfigureCrossPlatformLifecycleEvents(this MauiAppBuilder builder) => + builder.ConfigureLifecycleEvents(events => events.AddTizen(OnConfigureLifeCycle)); + + static void OnConfigureLifeCycle(ITizenLifecycleBuilder tizen) + { + tizen + .OnCreate((app) => + { + // OnCreate is only ever called once when the app is initally created + app.GetWindow().Created(); + }) + .OnResume(app => + { + app.GetWindow().Resumed(); + app.GetWindow().Activated(); + + }) + .OnPause(app => + { + app.GetWindow().Deactivated(); + app.GetWindow().Stopped(); + }) + .OnTerminate(app => + { + app.GetWindow().Destroying(); + }); + } + } +} diff --git a/src/Core/src/IMauiContext.cs b/src/Core/src/IMauiContext.cs index 28f3b12ad7..cf899f3188 100644 --- a/src/Core/src/IMauiContext.cs +++ b/src/Core/src/IMauiContext.cs @@ -12,4 +12,4 @@ namespace Microsoft.Maui Android.Content.Context? Context { get; } #endif } -} +} \ No newline at end of file diff --git a/src/Core/src/ImageSources/FileImageSourceService/FileImageSourceService.Tizen.cs b/src/Core/src/ImageSources/FileImageSourceService/FileImageSourceService.Tizen.cs new file mode 100644 index 0000000000..3d14433c3c --- /dev/null +++ b/src/Core/src/ImageSources/FileImageSourceService/FileImageSourceService.Tizen.cs @@ -0,0 +1,88 @@ +#nullable enable +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Tizen.UIExtensions.ElmSharp; +using AppFW = Tizen.Applications; + +namespace Microsoft.Maui +{ + public partial class FileImageSourceService + { + public override Task?> GetImageAsync(IImageSource imageSource, Image image, CancellationToken cancellationToken = default) => + GetImageAsync((IFileImageSource)imageSource, image, cancellationToken); + + public async Task?> GetImageAsync(IFileImageSource imageSource, Image image, CancellationToken cancellationToken = default) + { + if (imageSource.IsEmpty) + return null; + + var filename = imageSource.File; + try + { + if (!string.IsNullOrEmpty(filename)) + { + var isLoadComplated = await image.LoadAsync(GetPath(filename), cancellationToken); + + if (!isLoadComplated) + { + //If it fails, call the Load function to remove the previous image. + image.Load(string.Empty); + throw new InvalidOperationException("Unable to load image file."); + } + + var result = new ImageSourceServiceResult(image); + return result; + } + else + { + throw new InvalidOperationException("Unable to load image file."); + } + } + catch (Exception ex) + { + Logger?.LogWarning(ex, "Unable to load image file '{File}'.", filename); + throw; + } + } + + static string GetPath(string res) + { + if (Path.IsPathRooted(res)) + { + return res; + } + + foreach (AppFW.ResourceManager.Category category in Enum.GetValues(typeof(AppFW.ResourceManager.Category))) + { + foreach (var file in new[] { res, res + ".jpg", res + ".png", res + ".gif" }) + { + var path = AppFW.ResourceManager.TryGetPath(category, file); + + if (path != null) + { + return path; + } + } + } + + AppFW.Application app = AppFW.Application.Current; + if (app != null) + { + string resPath = app.DirectoryInfo.Resource + res; + + foreach (var file in new []{ resPath, resPath + ".jpg", resPath + ".png", resPath + ".gif" }) + { + if (File.Exists(file)) + { + return resPath; + } + } + } + + return res; + } + } +} \ No newline at end of file diff --git a/src/Core/src/ImageSources/FontImageSourceService/FontImageSourceService.Tizen.cs b/src/Core/src/ImageSources/FontImageSourceService/FontImageSourceService.Tizen.cs new file mode 100644 index 0000000000..e725701113 --- /dev/null +++ b/src/Core/src/ImageSources/FontImageSourceService/FontImageSourceService.Tizen.cs @@ -0,0 +1,40 @@ +#nullable enable +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui +{ + public partial class FontImageSourceService + { + public override Task?> GetImageAsync(IImageSource imageSource, Image image, CancellationToken cancellationToken = default) => + GetImageAsync((IFontImageSource)imageSource, image, cancellationToken); + + public async Task?> GetImageAsync(IFontImageSource imageSource, Image image, CancellationToken cancellationToken = default) + { + if (imageSource.IsEmpty) + return null; + + try + { + //TODO : Fix me correctly later. + var isLoadComplated = await image.LoadAsync(string.Empty, cancellationToken); + + if (!isLoadComplated) + { + throw new InvalidOperationException("Unable to load image file."); + } + + var result = new ImageSourceServiceResult(image); + return result; + } + catch (Exception ex) + { + Logger?.LogWarning(ex, "Unable to generate font image '{Glyph}'.", imageSource.Glyph); + throw; + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/ImageSources/IImageSourceService.cs b/src/Core/src/ImageSources/IImageSourceService.cs index 51fff6161b..51a4fc4fb4 100644 --- a/src/Core/src/ImageSources/IImageSourceService.cs +++ b/src/Core/src/ImageSources/IImageSourceService.cs @@ -21,6 +21,11 @@ namespace Microsoft.Maui IImageSource imageSource, float scale = 1, CancellationToken cancellationToken = default); +#elif TIZEN || __TIZEN__ + Task?> GetImageAsync( + IImageSource imageSource, + Tizen.UIExtensions.ElmSharp.Image image, + CancellationToken cancellationToken = default); #elif WINDOWS Task?> GetImageSourceAsync( IImageSource imageSource, diff --git a/src/Core/src/ImageSources/ImageSourceExtensions.cs b/src/Core/src/ImageSources/ImageSourceExtensions.cs index da67d1ecd6..adcf6d5129 100644 --- a/src/Core/src/ImageSources/ImageSourceExtensions.cs +++ b/src/Core/src/ImageSources/ImageSourceExtensions.cs @@ -10,7 +10,9 @@ using PlatformImage = UIKit.UIImage; using PlatformImage = Android.Graphics.Drawables.Drawable; #elif WINDOWS using PlatformImage = Microsoft.UI.Xaml.Media.ImageSource; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformImage = Tizen.UIExtensions.ElmSharp.Image; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformImage = System.Object; #endif @@ -52,6 +54,9 @@ namespace Microsoft.Maui return imageSourceService.GetDrawableAsync(imageSource, mauiContext.Context!); #elif WINDOWS return imageSourceService.GetImageSourceAsync(imageSource); +#elif TIZEN + var platformImage = new PlatformImage(mauiContext.GetNativeParent()); + return imageSourceService.GetImageAsync(imageSource, platformImage); #else throw new NotImplementedException(); #endif diff --git a/src/Core/src/ImageSources/ImageSourceService.cs b/src/Core/src/ImageSources/ImageSourceService.cs index e37edb6ef8..c79d0fe768 100644 --- a/src/Core/src/ImageSources/ImageSourceService.cs +++ b/src/Core/src/ImageSources/ImageSourceService.cs @@ -47,6 +47,11 @@ namespace Microsoft.Maui IImageSource imageSource, float scale = 1, CancellationToken cancellationToken = default); +#elif TIZEN || __TIZEN__ + public abstract Task?> GetImageAsync( + IImageSource imageSource, + Tizen.UIExtensions.ElmSharp.Image image, + CancellationToken cancellationToken = default); #elif WINDOWS public abstract Task?> GetImageSourceAsync( IImageSource imageSource, diff --git a/src/Core/src/ImageSources/ImageSourceServiceResult.cs b/src/Core/src/ImageSources/ImageSourceServiceResult.cs index fd54df50ed..f85a6ec541 100644 --- a/src/Core/src/ImageSources/ImageSourceServiceResult.cs +++ b/src/Core/src/ImageSources/ImageSourceServiceResult.cs @@ -6,7 +6,9 @@ using PlatformView = UIKit.UIImage; using PlatformView = Android.Graphics.Drawables.Drawable; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Media.ImageSource; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = Tizen.UIExtensions.ElmSharp.Image; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; #endif diff --git a/src/Core/src/ImageSources/StreamImageSourceService/StreamImageSourceService.Tizen.cs b/src/Core/src/ImageSources/StreamImageSourceService/StreamImageSourceService.Tizen.cs new file mode 100644 index 0000000000..d6d9844ca2 --- /dev/null +++ b/src/Core/src/ImageSources/StreamImageSourceService/StreamImageSourceService.Tizen.cs @@ -0,0 +1,41 @@ +#nullable enable +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui +{ + public partial class StreamImageSourceService + { + public override Task?> GetImageAsync(IImageSource imageSource, Image image, CancellationToken cancellationToken = default) => + GetImageAsync((IStreamImageSource)imageSource, image, cancellationToken); + + public async Task?> GetImageAsync(IStreamImageSource imageSource, Image image, CancellationToken cancellationToken = default) + { + if (imageSource.IsEmpty) + return null; + + try + { + var stream = await imageSource.GetStreamAsync(cancellationToken); + + if (stream == null) + throw new InvalidOperationException("Unable to load image stream."); + + var isLoadComplated = await image.LoadAsync(stream, cancellationToken); + + if (!isLoadComplated) + throw new InvalidOperationException("Unable to decode image from stream."); + + return new ImageSourceServiceResult(image); + } + catch (Exception ex) + { + Logger?.LogWarning(ex, "Unable to load image stream."); + throw; + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.Tizen.cs b/src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.Tizen.cs new file mode 100644 index 0000000000..d28fa31bd2 --- /dev/null +++ b/src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.Tizen.cs @@ -0,0 +1,38 @@ +#nullable enable +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui +{ + public partial class UriImageSourceService + { + public override Task?> GetImageAsync(IImageSource imageSource, Image image, CancellationToken cancellationToken = default) => + GetImageAsync((IUriImageSource)imageSource, image, cancellationToken); + + public async Task?> GetImageAsync(IUriImageSource imageSource, Image image, CancellationToken cancellationToken = default) + { + if (imageSource.IsEmpty) + return null; + + var uri = imageSource.Uri; + + try + { + var isLoadComplated = await image.LoadAsync(uri, cancellationToken); + + if (!isLoadComplated) + throw new InvalidOperationException($"Unable to load image URI '{uri}'."); + + return new ImageSourceServiceResult(image); + } + catch (Exception ex) + { + Logger?.LogWarning(ex, "Unable to load image URI '{Uri}'.", uri); + throw; + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/LifecycleEvents/Tizen/ITizenLifecycleBuilder.cs b/src/Core/src/LifecycleEvents/Tizen/ITizenLifecycleBuilder.cs new file mode 100644 index 0000000000..aaef20de99 --- /dev/null +++ b/src/Core/src/LifecycleEvents/Tizen/ITizenLifecycleBuilder.cs @@ -0,0 +1,6 @@ +namespace Microsoft.Maui.LifecycleEvents +{ + public interface ITizenLifecycleBuilder : ILifecycleBuilder + { + } +} \ No newline at end of file diff --git a/src/Core/src/LifecycleEvents/Tizen/TizenLifecycle.cs b/src/Core/src/LifecycleEvents/Tizen/TizenLifecycle.cs new file mode 100644 index 0000000000..37e70e7ac9 --- /dev/null +++ b/src/Core/src/LifecycleEvents/Tizen/TizenLifecycle.cs @@ -0,0 +1,25 @@ +using Tizen.Applications; + +namespace Microsoft.Maui.LifecycleEvents +{ + public static class TizenLifecycle + { + // Events called by CoreUIApplication overrides + public delegate void OnPause(CoreApplication application); + public delegate void OnPreCreate(CoreApplication application); + public delegate void OnResume(CoreApplication application); + + // Events called by CoreApplication overrides + public delegate void OnAppControlReceived(CoreApplication application, AppControlReceivedEventArgs e); + public delegate void OnCreate(CoreApplication application); + public delegate void OnDeviceOrientationChanged(CoreApplication application, DeviceOrientationEventArgs e); + public delegate void OnLocaleChanged(CoreApplication application, LocaleChangedEventArgs e); + public delegate void OnLowBattery(CoreApplication application, LowBatteryEventArgs e); + public delegate void OnLowMemory(CoreApplication application, LowMemoryEventArgs e); + public delegate void OnRegionFormatChanged(CoreApplication application, RegionFormatChangedEventArgs e); + public delegate void OnTerminate(CoreApplication application); + + // Internal events + internal delegate void OnMauiContextCreated(IMauiContext mauiContext); + } +} \ No newline at end of file diff --git a/src/Core/src/LifecycleEvents/Tizen/TizenLifecycleBuilderExtensions.cs b/src/Core/src/LifecycleEvents/Tizen/TizenLifecycleBuilderExtensions.cs new file mode 100644 index 0000000000..c1b5de9a15 --- /dev/null +++ b/src/Core/src/LifecycleEvents/Tizen/TizenLifecycleBuilderExtensions.cs @@ -0,0 +1,19 @@ +namespace Microsoft.Maui.LifecycleEvents +{ + public static class TizenLifecycleBuilderExtensions + { + public static ITizenLifecycleBuilder OnPause(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnPause del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnPreCreate(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnPreCreate del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnResume(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnResume del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnAppControlReceived(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnAppControlReceived del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnCreate(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnCreate del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnDeviceOrientationChanged(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnDeviceOrientationChanged del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnLocaleChanged(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnLocaleChanged del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnLowBattery(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnLowBattery del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnLowMemory(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnLowMemory del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnRegionFormatChanged(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnRegionFormatChanged del) => lifecycle.OnEvent(del); + public static ITizenLifecycleBuilder OnTerminate(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnTerminate del) => lifecycle.OnEvent(del); + + internal static ITizenLifecycleBuilder OnMauiContextCreated(this ITizenLifecycleBuilder lifecycle, TizenLifecycle.OnMauiContextCreated del) => lifecycle.OnEvent(del); + } +} \ No newline at end of file diff --git a/src/Core/src/LifecycleEvents/Tizen/TizenLifecycleExtensions.cs b/src/Core/src/LifecycleEvents/Tizen/TizenLifecycleExtensions.cs new file mode 100644 index 0000000000..b1328b2782 --- /dev/null +++ b/src/Core/src/LifecycleEvents/Tizen/TizenLifecycleExtensions.cs @@ -0,0 +1,32 @@ +using System; + +namespace Microsoft.Maui.LifecycleEvents +{ + public static class TizenLifecycleExtensions + { + public static ILifecycleBuilder AddTizen(this ILifecycleBuilder builder, Action configureDelegate) + { + var lifecycle = new LifecycleBuilder(builder); + + configureDelegate?.Invoke(lifecycle); + + return builder; + } + + class LifecycleBuilder : ITizenLifecycleBuilder + { + readonly ILifecycleBuilder _builder; + + public LifecycleBuilder(ILifecycleBuilder builder) + { + _builder = builder; + } + + public void AddEvent(string eventName, TDelegate action) + where TDelegate : Delegate + { + _builder.AddEvent(eventName, action); + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/MauiContextExtensions.cs b/src/Core/src/MauiContextExtensions.cs index 46d3f326da..5532ec4177 100644 --- a/src/Core/src/MauiContextExtensions.cs +++ b/src/Core/src/MauiContextExtensions.cs @@ -14,6 +14,9 @@ using NativeWindow = UIKit.UIWindow; #elif __ANDROID__ using NativeApplication = Android.App.Application; using NativeWindow = Android.App.Activity; +#elif TIZEN +using NativeApplication = Tizen.Applications.CoreApplication; +using NativeWindow = ElmSharp.Window; #else using NativeApplication = System.Object; using NativeWindow = System.Object; diff --git a/src/Core/src/Platform/ElementExtensions.cs b/src/Core/src/Platform/ElementExtensions.cs index 3f2efe33c6..a0bda15d13 100644 --- a/src/Core/src/Platform/ElementExtensions.cs +++ b/src/Core/src/Platform/ElementExtensions.cs @@ -15,7 +15,12 @@ using PlatformView = Microsoft.UI.Xaml.FrameworkElement; using BasePlatformType = WinRT.IWinRTObject; using PlatformWindow = Microsoft.UI.Xaml.Window; using PlatformApplication = Microsoft.UI.Xaml.Application; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +using BasePlatformType = System.Object; +using PlatformWindow = ElmSharp.Window; +using PlatformApplication = Tizen.Applications.CoreUIApplication; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformView = System.Object; using BasePlatformType = System.Object; using IPlatformViewHandler = Microsoft.Maui.IViewHandler; diff --git a/src/Core/src/Platform/ImageSourcePartLoader.cs b/src/Core/src/Platform/ImageSourcePartLoader.cs index 8cb4c404ce..98359ed696 100644 --- a/src/Core/src/Platform/ImageSourcePartLoader.cs +++ b/src/Core/src/Platform/ImageSourcePartLoader.cs @@ -11,9 +11,12 @@ using PlatformView = Android.Views.View; #elif WINDOWS using PlatformImage = Microsoft.UI.Xaml.Media.ImageSource; using PlatformView = Microsoft.UI.Xaml.FrameworkElement; -#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID) -using PlatformView = System.Object; +#elif TIZEN +using PlatformImage = Tizen.UIExtensions.ElmSharp.Image; +using PlatformView = ElmSharp.EvasObject; +#elif NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using PlatformImage = System.Object; +using PlatformView = System.Object; #endif namespace Microsoft.Maui.Platform @@ -60,6 +63,12 @@ namespace Microsoft.Maui.Platform var result = await imageSource.UpdateSourceAsync(PlatformView, ImageSourceServiceProvider, SetImage!, token) .ConfigureAwait(false); + SourceManager.CompleteLoad(result); +#elif TIZEN + PlatformImage image = (PlatformView as PlatformImage)??new PlatformImage(PlatformView); + var result = await imageSource.UpdateSourceAsync(image, ImageSourceServiceProvider, SetImage!, token) + .ConfigureAwait(false); + SourceManager.CompleteLoad(result); #else await Task.CompletedTask; diff --git a/src/Core/src/Platform/Tizen/ActivityIndicatorExtensions.cs b/src/Core/src/Platform/Tizen/ActivityIndicatorExtensions.cs new file mode 100644 index 0000000000..2bffe4750a --- /dev/null +++ b/src/Core/src/Platform/Tizen/ActivityIndicatorExtensions.cs @@ -0,0 +1,18 @@ +using ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class ActivityIndicatorExtensions + { + public static void UpdateIsRunning(this ProgressBar activityIndicatorView, IActivityIndicator activityIndicator) + { + if (activityIndicator.IsRunning) + activityIndicatorView.PlayPulse(); + else + activityIndicatorView.StopPulse(); + } + + public static void UpdateColor(this ProgressBar activityIndicatorView, IActivityIndicator activityIndicator) + => activityIndicatorView.Color = activityIndicator.Color.ToPlatformEFL(); + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/AspectExtensions.cs b/src/Core/src/Platform/Tizen/AspectExtensions.cs new file mode 100644 index 0000000000..0036fda1ec --- /dev/null +++ b/src/Core/src/Platform/Tizen/AspectExtensions.cs @@ -0,0 +1,16 @@ +using TAspect = Tizen.UIExtensions.Common.Aspect; + +namespace Microsoft.Maui.Platform +{ + public static class AspectExtensions + { + public static TAspect ToPlatform(this Aspect aspect) => + aspect switch + { + Aspect.AspectFit => TAspect.AspectFit, + Aspect.AspectFill => TAspect.AspectFill, + Aspect.Fill => TAspect.Fill, + _ => TAspect.AspectFit, + }; + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/BorderView.cs b/src/Core/src/Platform/Tizen/BorderView.cs new file mode 100644 index 0000000000..62a35d25bd --- /dev/null +++ b/src/Core/src/Platform/Tizen/BorderView.cs @@ -0,0 +1,29 @@ +using ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public class BorderView : ContentCanvas + { + WrapperView? _wrapperView; + IBorderView _borderView; + + public BorderView(EvasObject parent, IBorderView view) : base(parent, view) + { + _borderView = view; + } + + public WrapperView? ContainerView + { + get + { + return _wrapperView; + } + set + { + _wrapperView = value; + _wrapperView?.UpdateBorder(_borderView); + _wrapperView?.UpdateBackground(_borderView.Background); + } + } + } +} diff --git a/src/Core/src/Platform/Tizen/ButtonExtensions.cs b/src/Core/src/Platform/Tizen/ButtonExtensions.cs new file mode 100644 index 0000000000..209cfc50ed --- /dev/null +++ b/src/Core/src/Platform/Tizen/ButtonExtensions.cs @@ -0,0 +1,17 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class ButtonExtensions + { + public static void UpdateTextColor(this Button platformButton, ITextStyle button) + { + platformButton.TextColor = button.TextColor.ToPlatform(); + } + + public static void UpdateText(this Button platformButton, IText button) + { + platformButton.Text = button.Text ?? ""; + } + } +} diff --git a/src/Core/src/Platform/Tizen/CheckBoxExtensions.cs b/src/Core/src/Platform/Tizen/CheckBoxExtensions.cs new file mode 100644 index 0000000000..34f9ecdf59 --- /dev/null +++ b/src/Core/src/Platform/Tizen/CheckBoxExtensions.cs @@ -0,0 +1,22 @@ +using ElmSharp; +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Platform +{ + public static class CheckBoxExtensions + { + public static void UpdateIsChecked(this Check platformCheck, ICheckBox check) + { + platformCheck.IsChecked = check.IsChecked; + } + + public static void UpdateForeground(this Check platformCheck, ICheckBox check) + { + // For the moment, we're only supporting solid color Paint + if (check.Foreground is SolidPaint solid) + { + platformCheck.Color = solid.Color.ToPlatformEFL(); + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/ColorExtensions.cs b/src/Core/src/Platform/Tizen/ColorExtensions.cs new file mode 100644 index 0000000000..74f5e2f970 --- /dev/null +++ b/src/Core/src/Platform/Tizen/ColorExtensions.cs @@ -0,0 +1,39 @@ +using Microsoft.Maui.Graphics; +using TLog = Tizen.UIExtensions.Common.Log; +using TColor = Tizen.UIExtensions.Common.Color; +using EColor = ElmSharp.Color; + +namespace Microsoft.Maui.Platform +{ + public static class ColorExtensions + { + public static TColor ToPlatform(this Color c) + { + return c == null ? TColor.Default : new TColor(c.Red, c.Green, c.Blue, c.Alpha); + } + + public static EColor ToPlatformEFL(this Color c) + { + return c == null ? EColor.Default : new EColor((int)(255.0 * c.Red), (int)(255.0 * c.Green), (int)(255.0 * c.Blue), (int)(255.0 * c.Alpha)); + } + + public static Color WithAlpha(this Color color, double alpha) + { + return new Color(color.Red, color.Green, color.Blue, (int)(255 * alpha)); + } + + public static Color WithPremultiplied(this Color color, double alpha) + { + return new Color((int)(color.Red * alpha), (int)(color.Green * alpha), (int)(color.Blue * alpha), color.Alpha); + } + + internal static string ToHex(this TColor c) + { + if (c.IsDefault) + { + TLog.Warn("Trying to convert the default color to hexagonal notation, it does not works as expected."); + } + return string.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", c.R, c.G, c.B, c.A); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/ContainerView.cs b/src/Core/src/Platform/Tizen/ContainerView.cs new file mode 100644 index 0000000000..f2986b46c0 --- /dev/null +++ b/src/Core/src/Platform/Tizen/ContainerView.cs @@ -0,0 +1,74 @@ +using System; +using Microsoft.Maui.HotReload; +using ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public class ContainerView : Box, IReloadHandler + { + readonly IMauiContext? _context; + + EvasObject? _mainView; + IElement? _view; + + public ContainerView(IMauiContext context) : this(context.GetNativeParent(), context) + { + } + + public ContainerView(EvasObject parent, IMauiContext context) : base(parent) + { + _context = context; + } + + public EvasObject? MainView + { + get => _mainView; + set + { + if (_mainView != null) + { + UnPack(_mainView); + } + + _mainView = value; + + if (_mainView != null) + { + _mainView.SetAlignment(-1, -1); + _mainView.SetWeight(1, 1); + PackEnd(_mainView); + } + } + } + + public IElement? CurrentView + { + get => _view; + set => SetView(value); + } + + void SetView(IElement? view, bool forceRefresh = false) + { + if (view == _view && !forceRefresh) + return; + + _view = view; + + if (_view is IHotReloadableView ihr) + { + ihr.ReloadHandler = this; + MauiHotReloadHelper.AddActiveView(ihr); + } + + MainView = null; + + if (_view != null) + { + _ = _context ?? throw new ArgumentNullException(nameof(_context)); + MainView = _view.ToPlatform(_context); + } + } + + public void Reload() => SetView(CurrentView, true); + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/ContentCanvas.cs b/src/Core/src/Platform/Tizen/ContentCanvas.cs new file mode 100644 index 0000000000..c47a45d99b --- /dev/null +++ b/src/Core/src/Platform/Tizen/ContentCanvas.cs @@ -0,0 +1,49 @@ +using System; +using ElmSharp; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using Rect = Microsoft.Maui.Graphics.Rect; +using Size = Microsoft.Maui.Graphics.Size; +using TSize = Tizen.UIExtensions.Common.Size; + +namespace Microsoft.Maui.Platform +{ + public class ContentCanvas : Canvas, IMeasurable + { + IView _virtualView; + Size _measureCache; + + public ContentCanvas(EvasObject parent, IView view) : base(parent) + { + _virtualView = view; + LayoutUpdated += OnLayoutUpdated; + } + + public TSize Measure(double availableWidth, double availableHeight) + { + return CrossPlatformMeasure?.Invoke(availableWidth.ToScaledDP(), availableHeight.ToScaledDP()).ToPixel() ?? new TSize(0, 0); + } + + internal Func? CrossPlatformMeasure { get; set; } + internal Func? CrossPlatformArrange { get; set; } + + protected void OnLayoutUpdated(object? sender, LayoutEventArgs e) + { + var platformGeometry = Geometry.ToDP(); + + var measured = CrossPlatformMeasure!(platformGeometry.Width, platformGeometry.Height); + if (measured != _measureCache && _virtualView?.Parent is IView parentView) + { + parentView?.InvalidateMeasure(); + } + _measureCache = measured; + + if (platformGeometry.Width > 0 && platformGeometry.Height > 0) + { + platformGeometry.X = 0; + platformGeometry.Y = 0; + CrossPlatformArrange!(platformGeometry); + } + } + } +} diff --git a/src/Core/src/Platform/Tizen/CoreAppExtensions.cs b/src/Core/src/Platform/Tizen/CoreAppExtensions.cs new file mode 100644 index 0000000000..027e69ca6f --- /dev/null +++ b/src/Core/src/Platform/Tizen/CoreAppExtensions.cs @@ -0,0 +1,98 @@ +using System; +using System.Reflection; +using ElmSharp; +using Microsoft.Maui.LifecycleEvents; +using Tizen.Applications; +using EWindow = ElmSharp.Window; + +namespace Microsoft.Maui.Platform +{ + internal static class CoreAppExtensions + { + public static Window? MainWindow { get; set; } + + public static IWindow GetWindow(this CoreApplication application) + { + foreach (var window in MauiApplication.Current.Application.Windows) + { + if (window?.Handler?.PlatformView is EWindow win && win == MainWindow) + return window; + } + + throw new InvalidOperationException("Window Not Found"); + } + + public static void RequestNewWindow(this CoreApplication platformApplication, IApplication application, OpenWindowRequest? args) + { + if (application.Handler?.MauiContext is not IMauiContext applicationContext) + return; + + var state = args?.State; + var bundle = state.ToBundle(); + + //TODO : Need to implementation + } + + public static void CreateNativeWindow(this CoreApplication platformApplication, IApplication application) + { + if (application.Handler?.MauiContext is not IMauiContext applicationContext) + return; + + var tizenWindow = GetDefaultWindow(); + if (tizenWindow == null) + throw new InvalidOperationException($"The {nameof(tizenWindow)} instance was not found."); + + var mauiContext = applicationContext.MakeWindowScope(tizenWindow, out var windowScope); + + tizenWindow.SetWindowCloseRequestHandler(() => platformApplication.Exit()); + + applicationContext.Services.InvokeLifecycleEvents(del => del(mauiContext)); + + var activationState = new ActivationState(mauiContext); + var window = application.CreateWindow(activationState); + + tizenWindow.SetWindowHandler(window, mauiContext); + } + + public static Bundle ToBundle(this IPersistedState? state) + { + var userInfo = new Bundle(); + + var keyset = userInfo.Keys; + if (keyset != null) + { + foreach (var k in keyset) + { + userInfo?.GetItem(k); + } + } + + if (state is not null) + { + foreach (var pair in state) + { + userInfo.AddItem(pair.Key, pair.Value); + } + } + + return userInfo; + } + + public static EWindow GetDefaultWindow() + { + if (MainWindow != null) + return MainWindow; + + return MainWindow = GetPreloadedWindow() ?? new EWindow("MauiDefaultWindow"); + } + + static EWindow? GetPreloadedWindow() + { + var type = typeof(EWindow); + // Use reflection to avoid breaking compatibility. ElmSharp.Window.CreateWindow() is has been added since API6. + var methodInfo = type.GetMethod("CreateWindow", BindingFlags.NonPublic | BindingFlags.Static); + + return (EWindow?)methodInfo?.Invoke(null, new object[] { "FormsWindow" }); + } + } +} diff --git a/src/Core/src/Platform/Tizen/DPExtensions.cs b/src/Core/src/Platform/Tizen/DPExtensions.cs new file mode 100644 index 0000000000..5bb53ef49c --- /dev/null +++ b/src/Core/src/Platform/Tizen/DPExtensions.cs @@ -0,0 +1,122 @@ +using System; +using Microsoft.Maui.Graphics; +using ERect = ElmSharp.Rect; +using ESize = ElmSharp.Size; +using TRect = Tizen.UIExtensions.Common.Rect; +using TSize = Tizen.UIExtensions.Common.Size; +using DeviceInfo = Tizen.UIExtensions.Common.DeviceInfo; +using Point = Microsoft.Maui.Graphics.Point; +using EPoint = ElmSharp.Point; + +namespace Microsoft.Maui.Platform +{ + public static class DPExtensions + { + public static Rect ToDP(this ERect rect) + { + return new Rect(ConvertToScaledDP(rect.X), ConvertToScaledDP(rect.Y), ConvertToScaledDP(rect.Width), ConvertToScaledDP(rect.Height)); + } + + public static ERect ToEFLPixel(this Rect rect) + { + return new ERect(ConvertToScaledPixel(rect.X), ConvertToScaledPixel(rect.Y), ConvertToScaledPixel(rect.Width), ConvertToScaledPixel(rect.Height)); + } + + public static Size ToDP(this ESize size) + { + return new Size(ConvertToScaledDP(size.Width), ConvertToScaledDP(size.Height)); + } + + public static ESize ToEFLPixel(this Size size) + { + return new ESize(ConvertToScaledPixel(size.Width), ConvertToScaledPixel(size.Height)); + } + + public static Rect ToDP(this TRect rect) + { + return new Rect(ConvertToScaledDP(rect.X), ConvertToScaledDP(rect.Y), ConvertToScaledDP(rect.Width), ConvertToScaledDP(rect.Height)); + } + + public static TRect ToPixel(this Rect rect) + { + return new TRect(ConvertToScaledPixel(rect.X), ConvertToScaledPixel(rect.Y), ConvertToScaledPixel(rect.Width), ConvertToScaledPixel(rect.Height)); + } + + public static Size ToDP(this TSize size) + { + return new Size(ConvertToScaledDP(size.Width), ConvertToScaledDP(size.Height)); + } + + public static TSize ToPixel(this Size size) + { + return new TSize(ConvertToScaledPixel(size.Width), ConvertToScaledPixel(size.Height)); + } + + public static int ToPixel(this double dp) + { + return (int)Math.Round(dp * DeviceInfo.DPI / 160.0); + } + + public static float ToScaledDP(this float pixel) + { + return pixel / (float)DeviceInfo.ScalingFactor; + } + + public static double ToScaledDP(this double pixel) + { + return pixel / DeviceInfo.ScalingFactor; + } + + public static int ToEflFontPoint(this double sp) + { + return (int)Math.Round(ConvertToScaledPixel(sp) * DeviceInfo.ElmScale); + } + + public static double ToDPFont(this int eflPt) + { + return ConvertToScaledDP(eflPt / DeviceInfo.ElmScale); + } + + public static int ConvertToPixel(double dp) + { + return (int)Math.Round(dp * DeviceInfo.DPI / 160.0); + } + + public static int ConvertToScaledPixel(double dp) + { + return (int)Math.Round(dp * DeviceInfo.ScalingFactor); + } + + public static double ConvertToScaledDP(int pixel) + { + if (pixel == int.MaxValue) + return double.PositiveInfinity; + return pixel / DeviceInfo.ScalingFactor; + } + + public static double ConvertToScaledDP(double pixel) + { + return pixel / DeviceInfo.ScalingFactor; + } + + public static int ConvertToEflFontPoint(double sp) + { + return (int)Math.Round(ConvertToScaledPixel(sp) * DeviceInfo.ElmScale); + } + + public static double ConvertToDPFont(int eflPt) + { + return ConvertToScaledDP(eflPt / DeviceInfo.ElmScale); + } + + public static Point ToPoint(this EPoint point) + { + return new Point(DPExtensions.ConvertToScaledDP(point.X), DPExtensions.ConvertToScaledDP(point.Y)); + } + + public static PointF ToPointF(this EPoint point) + { + return new PointF((float)DPExtensions.ConvertToScaledDP(point.X), (float)DPExtensions.ConvertToScaledDP(point.Y)); + } + } +} diff --git a/src/Core/src/Platform/Tizen/DatePickerExtensions.cs b/src/Core/src/Platform/Tizen/DatePickerExtensions.cs new file mode 100644 index 0000000000..ac4efb0252 --- /dev/null +++ b/src/Core/src/Platform/Tizen/DatePickerExtensions.cs @@ -0,0 +1,17 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class DatePickerExtensions + { + public static void UpdateFormat(this Entry platformDatePicker, IDatePicker datePicker) + { + UpdateDate(platformDatePicker, datePicker); + } + + public static void UpdateDate(this Entry platformDatePicker, IDatePicker datePicker) + { + platformDatePicker.Text = datePicker.Date.ToString(datePicker.Format); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/EditorExtensions.cs b/src/Core/src/Platform/Tizen/EditorExtensions.cs new file mode 100644 index 0000000000..b9726aceb8 --- /dev/null +++ b/src/Core/src/Platform/Tizen/EditorExtensions.cs @@ -0,0 +1,12 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class EditorExtensions + { + public static void UpdatePlaceholderColor(this Entry platformEntry, IEditor editor) + { + platformEntry.PlaceholderColor = editor.PlaceholderColor.ToPlatform(); + } + } +} diff --git a/src/Core/src/Platform/Tizen/ElementExtensions.cs b/src/Core/src/Platform/Tizen/ElementExtensions.cs new file mode 100644 index 0000000000..6c876fc7ba --- /dev/null +++ b/src/Core/src/Platform/Tizen/ElementExtensions.cs @@ -0,0 +1,10 @@ +using ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static partial class ElementExtensions + { + public static EvasObject ToContainerView(this IElement view, IMauiContext context) => + new ContainerView(context) { CurrentView = view }; + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/EntryExtensions.cs b/src/Core/src/Platform/Tizen/EntryExtensions.cs new file mode 100644 index 0000000000..93f68f5d74 --- /dev/null +++ b/src/Core/src/Platform/Tizen/EntryExtensions.cs @@ -0,0 +1,215 @@ +using System; +using System.Runtime.InteropServices; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using InputPanelReturnKeyType = ElmSharp.InputPanelReturnKeyType; +using TTextAlignment = Tizen.UIExtensions.Common.TextAlignment; + +namespace Microsoft.Maui.Platform +{ + public static class EntryExtensions + { + public static void UpdateText(this Entry platformEntry, IText entry) + { + platformEntry.Text = entry.Text ?? ""; + } + + public static void UpdateTextColor(this Entry platformEntry, ITextStyle entry) + { + platformEntry.TextColor = entry.TextColor.ToPlatform(); + } + + public static void UpdateHorizontalTextAlignment(this Entry platformEntry, ITextAlignment entry) + { + platformEntry.HorizontalTextAlignment = entry.HorizontalTextAlignment.ToPlatform(); + } + + public static void UpdateVerticalTextAlignment(this Entry platformEntry, ITextAlignment entry) + { + platformEntry.SetVerticalTextAlignment(entry.VerticalTextAlignment.ToPlatformDouble()); + platformEntry.SetVerticalPlaceHolderTextAlignment(entry.VerticalTextAlignment.ToPlatformDouble()); + } + + public static void UpdateIsPassword(this Entry platformEntry, IEntry entry) + { + platformEntry.IsPassword = entry.IsPassword; + } + + public static void UpdateReturnType(this Entry platformEntry, IEntry entry) + { + platformEntry.SetInputPanelReturnKeyType(entry.ReturnType.ToInputPanelReturnKeyType()); + } + + public static void UpdateClearButtonVisibility(this Entry platformEntry, IEntry entry) + { + if (entry.ClearButtonVisibility == ClearButtonVisibility.WhileEditing) + { + if (platformEntry is EditfieldEntry editfieldEntry) + { + editfieldEntry.EnableClearButton = true; + } + } + else + { + if (platformEntry is EditfieldEntry editfieldEntry) + { + editfieldEntry.EnableClearButton = false; + } + } + } + + public static void UpdateFont(this Entry platformEntry, ITextStyle textStyle, IFontManager fontManager) + { + platformEntry.BatchBegin(); + platformEntry.FontSize = textStyle.Font.Size > 0 ? textStyle.Font.Size : 25.ToDPFont(); + platformEntry.FontAttributes = textStyle.Font.GetFontAttributes(); + platformEntry.FontFamily = fontManager.GetFontFamily(textStyle.Font.Family) ?? ""; + platformEntry.BatchCommit(); + } + + public static void UpdatePlaceholder(this Entry platformEntry, ITextInput entry) + { + platformEntry.Placeholder = entry.Placeholder ?? string.Empty; + } + + public static void UpdatePlaceholderColor(this Entry platformEntry, ITextInput entry) + { + platformEntry.PlaceholderColor = entry.PlaceholderColor.ToPlatform(); + } + + public static void UpdateIsReadOnly(this Entry platformEntry, ITextInput entry) + { + platformEntry.IsEditable = !entry.IsReadOnly; + } + + public static void UpdateIsTextPredictionEnabled(this Entry platformEntry, ITextInput entry) + { + platformEntry.InputHint = entry.Keyboard.ToInputHints(true, entry.IsTextPredictionEnabled); + } + + public static void UpdateKeyboard(this Entry platformEntry, ITextInput entry) + { + platformEntry.UpdateKeyboard(entry.Keyboard, true, entry.IsTextPredictionEnabled); + } + + public static void UpdateMaxLength(this Entry platformEntry, ITextInput entry) + { + if (entry.MaxLength > 0 && platformEntry.Text.Length > entry.MaxLength) + platformEntry.Text = platformEntry.Text.Substring(0, entry.MaxLength); + } + + /* Updates both the IEntry.CursorPosition and IEntry.SelectionLength properties. */ + [PortHandler] + public static void UpdateSelectionLength(this Entry platformEntry, ITextInput entry) + { + if (platformEntry.IsUpdatingCursorPosition) + return; + + int start = GetSelectionStart(platformEntry, entry); + int end = GetSelectionEnd(platformEntry, entry, start); + + if (start < end) + { + platformEntry.SetSelectionRegion(start, end); + } + else + { + platformEntry.CursorPosition = entry.CursorPosition; + } + } + + static int GetSelectionStart(Entry platformEntry, ITextInput entry) + { + int start = platformEntry.Text?.Length ?? 0; + int cursorPosition = entry.CursorPosition; + + if (!string.IsNullOrEmpty(platformEntry.Text)) + start = Math.Min(start, cursorPosition); + + if (start != cursorPosition) + entry.CursorPosition = start; + + return start; + } + + static int GetSelectionEnd(Entry platformEntry, ITextInput entry, int start) + { + int end = Math.Max(start, Math.Min(platformEntry.Text?.Length ?? 0, start + entry.SelectionLength)); + int selectionLength = end - start; + if (selectionLength != entry.SelectionLength) + entry.SelectionLength = selectionLength; + return end; + } + + public static InputPanelReturnKeyType ToInputPanelReturnKeyType(this ReturnType returnType) + { + switch (returnType) + { + case ReturnType.Go: + return InputPanelReturnKeyType.Go; + case ReturnType.Next: + return InputPanelReturnKeyType.Next; + case ReturnType.Send: + return InputPanelReturnKeyType.Send; + case ReturnType.Search: + return InputPanelReturnKeyType.Search; + case ReturnType.Done: + return InputPanelReturnKeyType.Done; + case ReturnType.Default: + return InputPanelReturnKeyType.Default; + default: + throw new System.NotImplementedException($"ReturnType {returnType} not supported"); + } + } + + public static TTextAlignment ToPlatform(this TextAlignment alignment) + { + switch (alignment) + { + case TextAlignment.Center: + return TTextAlignment.Center; + + case TextAlignment.Start: + return TTextAlignment.Start; + + case TextAlignment.End: + return TTextAlignment.End; + + default: + Log.Warn("Warning: unrecognized HorizontalTextAlignment value {0}. " + + "Expected: {Start|Center|End}.", alignment); + Log.Debug("Falling back to platform's default settings."); + return TTextAlignment.Auto; + } + } + + public static double ToPlatformDouble(this TextAlignment alignment) + { + switch (alignment) + { + case TextAlignment.Center: + return 0.5d; + + case TextAlignment.Start: + return 0; + + case TextAlignment.End: + return 1d; + + default: + Log.Warn("Warning: unrecognized HorizontalTextAlignment value {0}. " + + "Expected: {Start|Center|End}.", alignment); + Log.Debug("Falling back to platform's default settings."); + return 0.5d; + } + } + + public static void GetSelectRegion(this Entry entry, out int start, out int end) + { + elm_entry_select_region_get(entry.RealHandle, out start, out end); + } + + [DllImport("libelementary.so.1")] + static extern void elm_entry_select_region_get(IntPtr obj, out int start, out int end); + } +} diff --git a/src/Core/src/Platform/Tizen/FlowDirectionExtensions.cs b/src/Core/src/Platform/Tizen/FlowDirectionExtensions.cs new file mode 100644 index 0000000000..39b4f27bbc --- /dev/null +++ b/src/Core/src/Platform/Tizen/FlowDirectionExtensions.cs @@ -0,0 +1,13 @@ +using System; +using ElmSharp; + +namespace Microsoft.Maui.Platform +{ + internal static class FlowDirectionExtensions + { + internal static void UpdateFlowDirection(this EvasObject platformView, IView view) + { + // TODO: Need to impl + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/GraphicsExtensions.cs b/src/Core/src/Platform/Tizen/GraphicsExtensions.cs new file mode 100644 index 0000000000..fd943a2f9f --- /dev/null +++ b/src/Core/src/Platform/Tizen/GraphicsExtensions.cs @@ -0,0 +1,19 @@ +using System; +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Platform +{ + internal static class GraphicsExtensions + { + public static Rect ExpandTo(this Rect geometry, Thickness shadowMargin) + { + var canvasGeometry = new Rect( + geometry.X - shadowMargin.Left, + geometry.Y - shadowMargin.Top, + geometry.Width + shadowMargin.HorizontalThickness, + geometry.Height + shadowMargin.VerticalThickness); + + return canvasGeometry; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/GraphicsViewExtensions.cs b/src/Core/src/Platform/Tizen/GraphicsViewExtensions.cs new file mode 100644 index 0000000000..b6ee57a02f --- /dev/null +++ b/src/Core/src/Platform/Tizen/GraphicsViewExtensions.cs @@ -0,0 +1,12 @@ +using Microsoft.Maui.Graphics.Skia.Views; + +namespace Microsoft.Maui.Platform +{ + public static class GraphicsViewExtensions + { + public static void UpdateDrawable(this SkiaGraphicsView platformGraphicsView, IGraphicsView graphicsView) + { + platformGraphicsView.Drawable = graphicsView.Drawable; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/IWrapperViewDrawables.cs b/src/Core/src/Platform/Tizen/IWrapperViewDrawables.cs new file mode 100644 index 0000000000..8265a81363 --- /dev/null +++ b/src/Core/src/Platform/Tizen/IWrapperViewDrawables.cs @@ -0,0 +1,13 @@ +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Platform +{ + public interface IWrapperViewDrawables : IDrawable + { + IDrawable? ShadowDrawable { get; set; } + + IDrawable? BackgroundDrawable { get; set; } + + IDrawable? BorderDrawable { get; set; } + } +} diff --git a/src/Core/src/Platform/Tizen/ImageExtensions.cs b/src/Core/src/Platform/Tizen/ImageExtensions.cs new file mode 100644 index 0000000000..607b99cdc0 --- /dev/null +++ b/src/Core/src/Platform/Tizen/ImageExtensions.cs @@ -0,0 +1,22 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class ImageExtensions + { + public static void Clear(this Image platformImage) + { + } + + public static void UpdateAspect(this Image platformImage, IImage image) + { + platformImage.Aspect = image.Aspect.ToPlatform(); + } + + public static void UpdateIsAnimationPlaying(this Image platformImage, IImageSourcePart image) + { + platformImage.IsAnimated = image.IsAnimationPlaying; + platformImage.IsAnimationPlaying = image.IsAnimationPlaying; + } + } +} diff --git a/src/Core/src/Platform/Tizen/ImageSourcePartExtensions.cs b/src/Core/src/Platform/Tizen/ImageSourcePartExtensions.cs new file mode 100644 index 0000000000..61be6a98dd --- /dev/null +++ b/src/Core/src/Platform/Tizen/ImageSourcePartExtensions.cs @@ -0,0 +1,63 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class ImageSourcePartExtensions + { + public static async Task?> UpdateSourceAsync(this IImageSourcePart image, Image destinationContext, IImageSourceServiceProvider services, Action setImage, CancellationToken cancellationToken = default) + { + image.UpdateIsLoading(false); + + var imageSource = image.Source; + if (imageSource == null) + return null; + + var events = image as IImageSourcePartEvents; + + events?.LoadingStarted(); + image.UpdateIsLoading(true); + + try + { + var service = services.GetRequiredImageSourceService(imageSource); + var result = await service.GetImageAsync(imageSource, destinationContext, cancellationToken); + var tImage = result?.Value; + + var applied = !cancellationToken.IsCancellationRequested && tImage != null && imageSource == image.Source; + + // only set the image if we are still on the same one + if (applied) + { + setImage.Invoke(tImage); + destinationContext.UpdateIsAnimationPlaying(image); + } + + events?.LoadingCompleted(applied); + + return result; + } + catch (OperationCanceledException) + { + // no-op + events?.LoadingCompleted(false); + } + catch (Exception ex) + { + events?.LoadingFailed(ex); + } + finally + { + // only mark as finished if we are still working on the same image + if (imageSource == image.Source) + { + image.UpdateIsLoading(false); + } + } + + return null; + } + } +} diff --git a/src/Core/src/Platform/Tizen/KeyboardExtensions.cs b/src/Core/src/Platform/Tizen/KeyboardExtensions.cs new file mode 100644 index 0000000000..2377eeac84 --- /dev/null +++ b/src/Core/src/Platform/Tizen/KeyboardExtensions.cs @@ -0,0 +1,76 @@ +using ElmSharp; +using TKeyboard = Tizen.UIExtensions.Common.Keyboard; +using TEntry = Tizen.UIExtensions.ElmSharp.Entry; + +namespace Microsoft.Maui.Platform +{ + public static class KeyboardExtensions + { + public static TKeyboard ToPlatform(this Keyboard keyboard) + { + if (keyboard == Keyboard.Numeric) + { + return TKeyboard.Numeric; + } + else if (keyboard == Keyboard.Telephone) + { + return TKeyboard.PhoneNumber; + } + else if (keyboard == Keyboard.Email) + { + return TKeyboard.Email; + } + else if (keyboard == Keyboard.Url) + { + return TKeyboard.Url; + } + else + { + return TKeyboard.Normal; + } + } + + public static AutoCapital ToAutoCapital(this KeyboardFlags keyboardFlags) + { + if (keyboardFlags.HasFlag(KeyboardFlags.CapitalizeSentence)) + { + return AutoCapital.Sentence; + } + else if (keyboardFlags.HasFlag(KeyboardFlags.CapitalizeWord)) + { + return AutoCapital.Word; + } + else if (keyboardFlags.HasFlag(KeyboardFlags.CapitalizeCharacter)) + { + return AutoCapital.All; + } + else + { + return AutoCapital.None; + } + } + + public static InputHints ToInputHints(this Keyboard keyboard, bool isSpellCheckEnabled, bool isTextPredictionEnabled) + { + if (keyboard is CustomKeyboard customKeyboard) + { + return customKeyboard.Flags.HasFlag(KeyboardFlags.Suggestions) || customKeyboard.Flags.HasFlag(KeyboardFlags.Spellcheck) ? InputHints.AutoComplete : InputHints.None; + } + return isSpellCheckEnabled && isTextPredictionEnabled ? InputHints.AutoComplete : InputHints.None; + } + + public static void UpdateKeyboard(this TEntry control, Keyboard keyboard, bool isSpellCheckEnabled, bool isTextPredictionEnabled) + { + control.Keyboard = keyboard.ToPlatform(); + if (keyboard is CustomKeyboard customKeyboard) + { + control.AutoCapital = customKeyboard.Flags.ToAutoCapital(); + } + else + { + control.AutoCapital = AutoCapital.None; + } + control.InputHint = keyboard.ToInputHints(isSpellCheckEnabled, isTextPredictionEnabled); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/LabelExtensions.cs b/src/Core/src/Platform/Tizen/LabelExtensions.cs new file mode 100644 index 0000000000..37946a2423 --- /dev/null +++ b/src/Core/src/Platform/Tizen/LabelExtensions.cs @@ -0,0 +1,88 @@ +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using TLineBreakMode = Tizen.UIExtensions.Common.LineBreakMode; +using TTextDecorationse = Tizen.UIExtensions.Common.TextDecorations; + +namespace Microsoft.Maui.Platform +{ + public static class LabelExtensions + { + public static void UpdateText(this Label platformLabel, ILabel label) + { + platformLabel.Text = label.Text ?? ""; + } + + public static void UpdateTextColor(this Label platformLabel, ILabel label) + { + platformLabel.TextColor = label.TextColor.ToPlatform(); + } + + public static void UpdateFont(this Label platformLabel, ILabel label, IFontManager fontManager) + { + platformLabel.BatchBegin(); + platformLabel.FontSize = label.Font.Size > 0 ? label.Font.Size : 25.ToDPFont(); + platformLabel.FontAttributes = label.Font.GetFontAttributes(); + platformLabel.FontFamily = fontManager.GetFontFamily(label.Font.Family)??""; + platformLabel.BatchCommit(); + } + + public static void UpdateHorizontalTextAlignment(this Label platformLabel, ILabel label) + { + platformLabel.HorizontalTextAlignment = label.HorizontalTextAlignment.ToPlatform(); + } + + public static void UpdateVerticalTextAlignment(this Label platformLabel, ILabel label) + { + platformLabel.VerticalTextAlignment = label.VerticalTextAlignment.ToPlatform(); + } + + public static void UpdateTextDecorations(this Label platformLabel, ILabel label) + { + platformLabel.TextDecorations = label.TextDecorations.ToPlatform(); + } + + public static FontAttributes GetFontAttributes(this Font font) + { + FontAttributes attributes = font.Weight == FontWeight.Bold ? FontAttributes.Bold : FontAttributes.None; + if (font.Slant != FontSlant.Default) + { + if (attributes == FontAttributes.None) + attributes = FontAttributes.Italic; + else + attributes = attributes | FontAttributes.Italic; + } + return attributes; + } + + public static TLineBreakMode ToPlatform(this LineBreakMode mode) + { + switch (mode) + { + case LineBreakMode.CharacterWrap: + return TLineBreakMode.CharacterWrap; + case LineBreakMode.HeadTruncation: + return TLineBreakMode.HeadTruncation; + case LineBreakMode.MiddleTruncation: + return TLineBreakMode.MiddleTruncation; + case LineBreakMode.NoWrap: + return TLineBreakMode.NoWrap; + case LineBreakMode.TailTruncation: + return TLineBreakMode.TailTruncation; + case LineBreakMode.WordWrap: + default: + return TLineBreakMode.WordWrap; + } + } + + public static TTextDecorationse ToPlatform(this TextDecorations td) + { + if (td == TextDecorations.Strikethrough) + return TTextDecorationse.Strikethrough; + else if (td == TextDecorations.Underline) + return TTextDecorationse.Underline; + else + return TTextDecorationse.None; + } + + } +} diff --git a/src/Core/src/Platform/Tizen/LayoutCanvas.cs b/src/Core/src/Platform/Tizen/LayoutCanvas.cs new file mode 100644 index 0000000000..7aa89aa8eb --- /dev/null +++ b/src/Core/src/Platform/Tizen/LayoutCanvas.cs @@ -0,0 +1,49 @@ +using System; +using ElmSharp; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using Rect = Microsoft.Maui.Graphics.Rect; +using Size = Microsoft.Maui.Graphics.Size; +using TSize = Tizen.UIExtensions.Common.Size; + +namespace Microsoft.Maui.Platform +{ + public class LayoutCanvas : Canvas, IMeasurable + { + IView _virtualView; + Size _measureCache; + + public LayoutCanvas(EvasObject parent, IView view) : base(parent) + { + _virtualView = view; + LayoutUpdated += OnLayoutUpdated; + } + + public TSize Measure(double availableWidth, double availableHeight) + { + return CrossPlatformMeasure?.Invoke(availableWidth.ToScaledDP(), availableHeight.ToScaledDP()).ToPixel() ?? new TSize(0, 0); + } + + internal Func? CrossPlatformMeasure { get; set; } + internal Func? CrossPlatformArrange { get; set; } + + protected void OnLayoutUpdated(object? sender, LayoutEventArgs e) + { + var platformGeometry = Geometry.ToDP(); + + var measured = CrossPlatformMeasure!(platformGeometry.Width, platformGeometry.Height); + if (measured != _measureCache && _virtualView?.Parent is IView parentView) + { + parentView?.InvalidateMeasure(); + } + _measureCache = measured; + + if (platformGeometry.Width > 0 && platformGeometry.Height > 0) + { + platformGeometry.X = 0; + platformGeometry.Y = 0; + CrossPlatformArrange!(platformGeometry); + } + } + } +} diff --git a/src/Core/src/Platform/Tizen/LayoutCanvasExtensions.cs b/src/Core/src/Platform/Tizen/LayoutCanvasExtensions.cs new file mode 100644 index 0000000000..f9c8d3dba1 --- /dev/null +++ b/src/Core/src/Platform/Tizen/LayoutCanvasExtensions.cs @@ -0,0 +1,10 @@ +namespace Microsoft.Maui.Platform +{ + public static class LayoutCanvasExtensions + { + public static void UpdateClipsToBounds(this LayoutCanvas layoutCanvas, ILayout layout) + { + //TODO: Need to impl + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/MauiApplication.cs b/src/Core/src/Platform/Tizen/MauiApplication.cs new file mode 100644 index 0000000000..044ac49a0c --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiApplication.cs @@ -0,0 +1,117 @@ +using System; +using ElmSharp; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Maui.Hosting; +using Microsoft.Maui.LifecycleEvents; +using Tizen.Applications; + +namespace Microsoft.Maui +{ + public abstract class MauiApplication : CoreUIApplication, IPlatformApplication + { + IMauiContext _applicationContext = null!; + + protected MauiApplication() + { + Current = this; + IPlatformApplication.Current = this; + } + + protected abstract MauiApp CreateMauiApp(); + + protected override void OnPreCreate() + { + base.OnPreCreate(); + + Elementary.Initialize(); + Elementary.ThemeOverlay(); + + var mauiApp = CreateMauiApp(); + + var rootContext = new MauiContext(mauiApp.Services); + + var platformWindow = CoreAppExtensions.GetDefaultWindow(); + platformWindow.Initialize(); + rootContext.AddWeakSpecific(platformWindow); + + _applicationContext = rootContext.MakeApplicationScope(this); + + Services = _applicationContext.Services; + + Current.Services?.InvokeLifecycleEvents(del => del(this)); + } + + protected override void OnCreate() + { + base.OnCreate(); + + Application = Services.GetRequiredService(); + + this.SetApplicationHandler(Application, _applicationContext); + + this.CreateNativeWindow(Application); + + Current.Services?.InvokeLifecycleEvents(del => del(this)); + } + + protected override void OnAppControlReceived(AppControlReceivedEventArgs e) + { + base.OnAppControlReceived(e); + Current.Services?.InvokeLifecycleEvents(del => del(this, e)); + } + + protected override void OnDeviceOrientationChanged(DeviceOrientationEventArgs e) + { + base.OnDeviceOrientationChanged(e); + Current.Services?.InvokeLifecycleEvents(del => del(this, e)); + } + + protected override void OnLocaleChanged(LocaleChangedEventArgs e) + { + base.OnLocaleChanged(e); + Current.Services?.InvokeLifecycleEvents(del => del(this, e)); + } + + protected override void OnLowBattery(LowBatteryEventArgs e) + { + base.OnLowBattery(e); + Current.Services?.InvokeLifecycleEvents(del => del(this, e)); + } + + protected override void OnLowMemory(LowMemoryEventArgs e) + { + base.OnLowMemory(e); + Current.Services?.InvokeLifecycleEvents(del => del(this, e)); + } + + protected override void OnPause() + { + base.OnPause(); + Current.Services?.InvokeLifecycleEvents(del => del(this)); + } + + protected override void OnRegionFormatChanged(RegionFormatChangedEventArgs e) + { + base.OnRegionFormatChanged(e); + Current.Services?.InvokeLifecycleEvents(del => del(this, e)); + } + + protected override void OnResume() + { + base.OnResume(); + Current.Services?.InvokeLifecycleEvents(del => del(this)); + } + + protected override void OnTerminate() + { + base.OnTerminate(); + Current.Services?.InvokeLifecycleEvents(del => del(this)); + } + + public static new MauiApplication Current { get; private set; } = null!; + + public IServiceProvider Services { get; protected set; } = null!; + + public IApplication Application { get; protected set; } = null!; + } +} diff --git a/src/Core/src/Platform/Tizen/MauiBoxView.cs b/src/Core/src/Platform/Tizen/MauiBoxView.cs new file mode 100644 index 0000000000..628c31233d --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiBoxView.cs @@ -0,0 +1,12 @@ +using ElmSharp; +using Microsoft.Maui.Graphics.Skia.Views; + +namespace Microsoft.Maui.Platform +{ + public class MauiBoxView : SkiaGraphicsView + { + public MauiBoxView(EvasObject parent) : base(parent) + { + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/MauiContextExtensions.cs b/src/Core/src/Platform/Tizen/MauiContextExtensions.cs new file mode 100644 index 0000000000..b8d9cc9aaa --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiContextExtensions.cs @@ -0,0 +1,18 @@ +using ElmSharp; +using Microsoft.Extensions.DependencyInjection; +using ELayout = ElmSharp.Layout; + +namespace Microsoft.Maui.Platform +{ + internal static partial class MauiContextExtensions + { + public static Window GetNativeWindow(this IMauiContext mauiContext) => + mauiContext.Services.GetRequiredService(); + + public static ELayout GetNativeParent(this IMauiContext mauiContext) => + mauiContext.GetNativeWindow().GetBaseLayout(); + + public static ModalStack GetModalStack(this IMauiContext mauiContext) => + mauiContext.GetNativeWindow().GetModalStack(); + } +} diff --git a/src/Core/src/Platform/Tizen/MauiImageButton.cs b/src/Core/src/Platform/Tizen/MauiImageButton.cs new file mode 100644 index 0000000000..c34f6a68e4 --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiImageButton.cs @@ -0,0 +1,65 @@ +using System; +using ElmSharp; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using TButton = Tizen.UIExtensions.ElmSharp.Button; +using TImage = Tizen.UIExtensions.ElmSharp.Image; + +namespace Microsoft.Maui.Platform +{ + public class MauiImageButton : Canvas + { + TImage _image; + TButton _button; + + public MauiImageButton(EvasObject parent) : base(parent) + { + _image = new TImage(parent); + _button = new TButton(parent); + + _button.Clicked += OnClicked; + _button.Pressed += OnPressed; + _button.Released += OnReleased; + _button.SetTransparentStyle(); + + Children.Add(_image); + _image.RaiseTop(); + + Children.Add(_button); + _button.SetTransparentStyle(); + _button.RaiseTop(); + + LayoutUpdated += OnLayout; + } + + public TImage ImageView + { + get => _image; + } + + public event EventHandler? Clicked; + public event EventHandler? Pressed; + public event EventHandler? Released; + + void OnReleased(object? sender, EventArgs e) + { + Released?.Invoke(this, EventArgs.Empty); + } + + void OnPressed(object? sender, EventArgs e) + { + Pressed?.Invoke(this, EventArgs.Empty); + } + + void OnClicked(object? sender, EventArgs e) + { + Clicked?.Invoke(this, EventArgs.Empty); + } + + void OnLayout(object? sender, LayoutEventArgs e) + { + _button.Geometry = Geometry; + _image.Geometry = Geometry; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/MauiIndicatorViewExtensions.cs b/src/Core/src/Platform/Tizen/MauiIndicatorViewExtensions.cs new file mode 100644 index 0000000000..0b1b1c05ae --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiIndicatorViewExtensions.cs @@ -0,0 +1,20 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class MauiIndicatorViewExtensions + { + public static void UpdateIndicatorCount(this IndicatorView platformView, IIndicatorView indicator) + { + platformView.ClearIndex(); + platformView.AppendIndex(indicator.Count); + platformView.Update(0); + platformView.UpdatePosition(indicator); + } + + public static void UpdatePosition(this IndicatorView platformView, IIndicatorView indicator) + { + platformView.UpdateSelectedIndex(indicator.Position); + } + } +} diff --git a/src/Core/src/Platform/Tizen/MauiRadioButton.cs b/src/Core/src/Platform/Tizen/MauiRadioButton.cs new file mode 100644 index 0000000000..c1ee2dd443 --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiRadioButton.cs @@ -0,0 +1,145 @@ +using System; +using ElmSharp; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using TSize = Tizen.UIExtensions.Common.Size; +using TColor = Tizen.UIExtensions.Common.Color; + +namespace Microsoft.Maui.Platform +{ + public class MauiRadioButton : Radio, IMeasurable, IBatchable + { + public MauiRadioButton(EvasObject parent) : base(parent) + { + } + + readonly Span _span = new Span(); + + public override string Text + { + get + { + return _span.Text; + } + + set + { + if (value != _span.Text) + { + _span.Text = value; + ApplyTextAndStyle(); + } + } + } + + public TColor TextColor + { + get + { + return _span.ForegroundColor; + } + + set + { + if (!_span.ForegroundColor.Equals(value)) + { + _span.ForegroundColor = value; + ApplyTextAndStyle(); + } + } + } + + public string FontFamily + { + get + { + return _span.FontFamily; + } + + set + { + if (value != _span.FontFamily) + { + _span.FontFamily = value; + ApplyTextAndStyle(); + } + } + } + + public FontAttributes FontAttributes + { + get + { + return _span.FontAttributes; + } + + set + { + if (value != _span.FontAttributes) + { + _span.FontAttributes = value; + ApplyTextAndStyle(); + } + } + } + + public double FontSize + { + get + { + return _span.FontSize; + } + + set + { + if (value != _span.FontSize) + { + _span.FontSize = value; + ApplyTextAndStyle(); + } + } + } + + public virtual TSize Measure(double availableWidth, double availableHeight) + { + Resize(availableWidth.ToScaledPixel(), Geometry.Height); + var formattedSize = this.GetTextBlockFormattedSize(); + Resize(Geometry.Width, Geometry.Height); + return new TSize + { + Width = MinimumWidth + formattedSize.Width, + Height = Math.Max(MinimumHeight, formattedSize.Height) + }; + } + + void IBatchable.OnBatchCommitted() + { + ApplyTextAndStyle(); + } + + void ApplyTextAndStyle() + { + if (!this.IsBatched()) + { + SetInternalTextAndStyle(_span.GetDecoratedText(), _span.GetStyle()); + } + } + + void SetInternalTextAndStyle(string formattedText, string textStyle) + { + bool isVisible = true; + if (string.IsNullOrEmpty(formattedText)) + { + base.Text = null; + this.SetTextBlockStyle(""); + this.SendTextVisibleSignal(false); + } + else + { + base.Text = formattedText; + this.SetTextBlockStyle(textStyle); + this.SendTextVisibleSignal(isVisible); + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/MauiShapeView.cs b/src/Core/src/Platform/Tizen/MauiShapeView.cs new file mode 100644 index 0000000000..6baeb99bcc --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiShapeView.cs @@ -0,0 +1,12 @@ +using ElmSharp; +using Microsoft.Maui.Graphics.Skia.Views; + +namespace Microsoft.Maui.Platform +{ + public class MauiShapeView : SkiaGraphicsView + { + public MauiShapeView(EvasObject parent) : base(parent) + { + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/MauiWebView.cs b/src/Core/src/Platform/Tizen/MauiWebView.cs new file mode 100644 index 0000000000..e099eac33f --- /dev/null +++ b/src/Core/src/Platform/Tizen/MauiWebView.cs @@ -0,0 +1,41 @@ +using System; +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; +using TWebView = Tizen.WebView.WebView; + +namespace Microsoft.Maui.Platform +{ + public class MauiWebView : WidgetLayout, IWebViewDelegate + { + public TWebView WebView { get; } + + public MauiWebView(EvasObject parent) : base(parent) + { + WebView = new TWebView(parent); + SetContent(WebView); + AllowFocus(true); + Focused += OnFocused; + Unfocused += OnUnfocused; + } + + void IWebViewDelegate.LoadHtml(string? html, string? baseUrl) + { + WebView.LoadHtml(baseUrl ?? string.Empty, html ?? string.Empty); + } + + void IWebViewDelegate.LoadUrl(string? url) + { + WebView.LoadUrl(url ?? string.Empty); + } + + void OnFocused(object? sender, EventArgs e) + { + WebView.SetFocus(true); + } + + void OnUnfocused(object? sender, EventArgs e) + { + WebView.SetFocus(false); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/ModalStack.cs b/src/Core/src/Platform/Tizen/ModalStack.cs new file mode 100644 index 0000000000..e6da597eff --- /dev/null +++ b/src/Core/src/Platform/Tizen/ModalStack.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Linq; +using ElmSharp; +using EBox = ElmSharp.Box; + +namespace Microsoft.Maui.Platform +{ + public class ModalStack : EBox + { + EvasObject? _lastTop; + + public ModalStack(EvasObject parent) : base(parent) + { + InternalStack = new List(); + SetLayoutCallback(OnLayout); + } + + List InternalStack { get; set; } + + public IReadOnlyList Stack => InternalStack; + + public void Push(EvasObject view) + { + InternalStack.Add(view); + PackEnd(view); + UpdateTopView(); + } + + public void Pop() + { + if (_lastTop != null) + { + var tobeRemoved = _lastTop; + InternalStack.Remove(tobeRemoved); + UnPack(tobeRemoved); + UpdateTopView(); + // if Pop was called by removed page, + // Unrealize cause deletation of NativeCallback, it could be a cause of crash + EcoreMainloop.Post(() => + { + tobeRemoved.Unrealize(); + }); + } + } + + public void PopToRoot() + { + while (InternalStack.Count > 1) + { + Pop(); + } + } + + public void Insert(EvasObject before, EvasObject view) + { + view.Hide(); + var idx = InternalStack.IndexOf(before); + InternalStack.Insert(idx, view); + PackEnd(view); + UpdateTopView(); + } + + public void Remove(EvasObject view) + { + InternalStack.Remove(view); + UnPack(view); + UpdateTopView(); + EcoreMainloop.Post(() => + { + view?.Unrealize(); + }); + } + + public void Reset() + { + while (InternalStack.Count > 0) + { + Pop(); + } + } + + void UpdateTopView() + { + if (_lastTop != InternalStack.LastOrDefault()) + { + _lastTop?.Hide(); + _lastTop = InternalStack.LastOrDefault(); + _lastTop?.Show(); + (_lastTop as Widget)?.SetFocus(true); + } + } + + void OnLayout() + { + foreach (var view in Stack) + { + view.Geometry = Geometry; + } + } + } +} diff --git a/src/Core/src/Platform/Tizen/PickerExtensions.cs b/src/Core/src/Platform/Tizen/PickerExtensions.cs new file mode 100644 index 0000000000..20d6c3a060 --- /dev/null +++ b/src/Core/src/Platform/Tizen/PickerExtensions.cs @@ -0,0 +1,24 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class PickerExtensions + { + public static void UpdateTitle(this Entry platformPicker, IPicker picker) => + UpdatePicker(platformPicker, picker); + + public static void UpdateTitleColor(this Entry platformPicker, IPicker picker) => + platformPicker.PlaceholderColor = picker.TitleColor.ToPlatform(); + + public static void UpdateSelectedIndex(this Entry platformPicker, IPicker picker) => + UpdatePicker(platformPicker, picker); + + internal static void UpdatePicker(this Entry platformPicker, IPicker picker) + { + if (picker.SelectedIndex == -1 || picker.SelectedIndex >= picker.GetCount()) + platformPicker.Text = string.Empty; + else + platformPicker.Text = picker.GetItem(picker.SelectedIndex); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/PlatformTouchGraphicsView.cs b/src/Core/src/Platform/Tizen/PlatformTouchGraphicsView.cs new file mode 100644 index 0000000000..6ef97a39fe --- /dev/null +++ b/src/Core/src/Platform/Tizen/PlatformTouchGraphicsView.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ElmSharp; +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Graphics.Skia.Views; + +namespace Microsoft.Maui.Platform +{ + public class PlatformTouchGraphicsView : SkiaGraphicsView + { + IGraphicsView? _graphicsView; + GestureLayer? _gestureLayer; + + public PlatformTouchGraphicsView(EvasObject? parent, IDrawable? drawable = null) : base(parent, drawable) + { + _ = parent ?? throw new ArgumentNullException(nameof(parent)); + } + + public void Connect(IGraphicsView graphicsView) + { + _graphicsView = graphicsView; + _gestureLayer = new GestureLayer(this); + _gestureLayer.Attach(this); + + _gestureLayer.SetTapCallback(GestureLayer.GestureType.Tap, GestureLayer.GestureState.Start, (_) => { OnGestureStarted(); }); + + _gestureLayer.SetTapCallback(GestureLayer.GestureType.Tap, GestureLayer.GestureState.End, (_) => { OnGestureEnded(true); }); + + _gestureLayer.SetLineCallback(GestureLayer.GestureState.Start, (_) => { OnGestureStarted(); }); + + _gestureLayer.SetLineCallback(GestureLayer.GestureState.Move, (_) => { + _graphicsView?.DragInteraction(new[] { _gestureLayer.EvasCanvas.Pointer.ToPointF() }); + }); + + _gestureLayer.SetLineCallback(GestureLayer.GestureState.End, (_) => { + OnGestureEnded(Geometry.ToDP().Contains(_gestureLayer.EvasCanvas.Pointer.ToPoint())); + }); + + _gestureLayer.SetLineCallback(GestureLayer.GestureState.Abort, (_) => { + _graphicsView?.CancelInteraction(); + }); + } + + public void Disconnect() + { + _gestureLayer?.Unrealize(); + _gestureLayer = null; + _graphicsView = null; + } + + void OnGestureStarted() + { + if (_graphicsView is null || _gestureLayer is null) + return; + + _graphicsView.StartInteraction(new[] { _gestureLayer.EvasCanvas.Pointer.ToPointF() }); + } + + void OnGestureEnded(bool isInsideBounds) + { + if (_graphicsView is null || _gestureLayer is null) + return; + + _graphicsView.EndInteraction(new[] { _gestureLayer.EvasCanvas.Pointer.ToPointF() }, isInsideBounds); + } + } +} diff --git a/src/Core/src/Platform/Tizen/ProgressBarExtensions.cs b/src/Core/src/Platform/Tizen/ProgressBarExtensions.cs new file mode 100644 index 0000000000..89ce8489bb --- /dev/null +++ b/src/Core/src/Platform/Tizen/ProgressBarExtensions.cs @@ -0,0 +1,17 @@ +using ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class ProgressBarExtensions + { + public static void UpdateProgress(this ProgressBar platformProgressBar, IProgress progress) + { + platformProgressBar.Value = progress.Progress; + } + + public static void UpdateProgressColor(this ProgressBar platformProgressBar, IProgress progress) + { + platformProgressBar.Color = progress.ProgressColor.ToPlatformEFL(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/RadioButtonExtensions.cs b/src/Core/src/Platform/Tizen/RadioButtonExtensions.cs new file mode 100644 index 0000000000..0c59e2de2b --- /dev/null +++ b/src/Core/src/Platform/Tizen/RadioButtonExtensions.cs @@ -0,0 +1,15 @@ +namespace Microsoft.Maui +{ + public static class RadioButtonExtensions + { + public static void UpdateIsChecked(this MauiRadioButton platformRadioButton, IRadioButton radioButton) + { + platformRadioButton.GroupValue = radioButton.IsChecked ? 1 : 0; + } + + public static void UpdateTextColor(this MauiRadioButton platformRadioButton, ITextStyle radioButton) + { + platformRadioButton.TextColor = radioButton.TextColor.ToPlatform(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/ScrollViewExtensions.cs b/src/Core/src/Platform/Tizen/ScrollViewExtensions.cs new file mode 100644 index 0000000000..6183c14009 --- /dev/null +++ b/src/Core/src/Platform/Tizen/ScrollViewExtensions.cs @@ -0,0 +1,55 @@ +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class ScrollViewExtensions + { + public static void UpdateVerticalScrollBarVisibility(this ScrollView scrollView, ScrollBarVisibility scrollBarVisibility) + { + scrollView.VerticalScrollBarVisiblePolicy = scrollBarVisibility.ToPlatform(); + } + + public static void UpdateHorizontalScrollBarVisibility(this ScrollView scrollView, ScrollBarVisibility scrollBarVisibility) + { + scrollView.HorizontalScrollBarVisiblePolicy = scrollBarVisibility.ToPlatform(); + } + + public static void UpdateOrientation(this ScrollView scrollView, ScrollOrientation scrollOrientation) + { + switch (scrollOrientation) + { + case ScrollOrientation.Horizontal: + scrollView.ScrollBlock = ScrollBlock.Vertical; + scrollView.HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Auto; + scrollView.VerticalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible; + break; + case ScrollOrientation.Vertical: + scrollView.ScrollBlock = ScrollBlock.Horizontal; + scrollView.HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible; + scrollView.VerticalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Auto; + break; + default: + scrollView.ScrollBlock = ScrollBlock.None; + scrollView.HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Auto; + scrollView.VerticalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Auto; + break; + } + } + + public static ScrollBarVisiblePolicy ToPlatform(this ScrollBarVisibility visibility) + { + switch (visibility) + { + case ScrollBarVisibility.Default: + return ScrollBarVisiblePolicy.Auto; + case ScrollBarVisibility.Always: + return ScrollBarVisiblePolicy.Visible; + case ScrollBarVisibility.Never: + return ScrollBarVisiblePolicy.Invisible; + default: + return ScrollBarVisiblePolicy.Auto; + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/SearchBarExtensions.cs b/src/Core/src/Platform/Tizen/SearchBarExtensions.cs new file mode 100644 index 0000000000..d2ec1b46df --- /dev/null +++ b/src/Core/src/Platform/Tizen/SearchBarExtensions.cs @@ -0,0 +1,12 @@ +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class SearchBarExtensions + { + public static void UpdateCancelButtonColor(this SearchBar platformView, ISearchBar searchBar) + { + platformView.SetClearButtonColor(searchBar.CancelButtonColor.ToPlatformEFL()); + } + } +} diff --git a/src/Core/src/Platform/Tizen/ShapeViewExtensions.cs b/src/Core/src/Platform/Tizen/ShapeViewExtensions.cs new file mode 100644 index 0000000000..e8dca6fe0c --- /dev/null +++ b/src/Core/src/Platform/Tizen/ShapeViewExtensions.cs @@ -0,0 +1,17 @@ +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Platform +{ + public static class ShapeViewExtensions + { + public static void UpdateShape(this MauiShapeView platformView, IShapeView shapeView) + { + platformView.Drawable = new ShapeDrawable(shapeView); + } + + public static void InvalidateShape(this MauiShapeView platformView, IShapeView shapeView) + { + platformView.Invalidate(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/SliderExtensions.cs b/src/Core/src/Platform/Tizen/SliderExtensions.cs new file mode 100644 index 0000000000..7996c43558 --- /dev/null +++ b/src/Core/src/Platform/Tizen/SliderExtensions.cs @@ -0,0 +1,76 @@ +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; +using EColor = ElmSharp.Color; + +namespace Microsoft.Maui.Platform +{ + public static class SliderExtensions + { + public static void UpdateMinimum(this Slider platformSlider, ISlider slider) + { + platformSlider.Minimum = slider.Minimum; + } + + public static void UpdateMaximum(this Slider platformSlider, ISlider slider) + { + platformSlider.Maximum = slider.Maximum; + } + + public static void UpdateValue(this Slider platformSlider, ISlider slider) + { + platformSlider.Value = slider.Value; + } + + public static void UpdateMinimumTrackColor(this Slider platformSlider, ISlider slider) + { + UpdateMinimumTrackColor(platformSlider, slider, null); + } + + public static void UpdateMinimumTrackColor(this Slider platformSlider, ISlider slider, EColor? defaultMinTrackColor) + { + if (slider.MinimumTrackColor == null) + { + if (defaultMinTrackColor != null) + platformSlider.SetBarColor(defaultMinTrackColor.Value); + } + else + platformSlider.SetBarColor(slider.MinimumTrackColor.ToPlatformEFL()); + } + + public static void UpdateMaximumTrackColor(this Slider platformSlider, ISlider slider) + { + UpdateMaximumTrackColor(platformSlider, slider, null); + } + + public static void UpdateMaximumTrackColor(this Slider platformSlider, ISlider slider, EColor? defaultMaxTrackColor) + { + if (slider.MaximumTrackColor == null) + { + if (defaultMaxTrackColor != null) + platformSlider.SetBackgroundColor(defaultMaxTrackColor.Value); + } + else + { + platformSlider.SetBackgroundColor(slider.MaximumTrackColor.ToPlatformEFL()); + } + } + + public static void UpdateThumbColor(this Slider platformSlider, ISlider slider) + { + UpdateThumbColor(platformSlider, slider, null); + } + + public static void UpdateThumbColor(this Slider platformSlider, ISlider slider, EColor? defaultThumbColor) + { + if (slider.ThumbColor == null) + { + if (defaultThumbColor != null) + platformSlider.SetHandlerColor(defaultThumbColor.Value); + } + else + { + platformSlider.SetHandlerColor(slider.ThumbColor.ToPlatformEFL()); + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/StepperExtensions.cs b/src/Core/src/Platform/Tizen/StepperExtensions.cs new file mode 100644 index 0000000000..8a0d17b2db --- /dev/null +++ b/src/Core/src/Platform/Tizen/StepperExtensions.cs @@ -0,0 +1,56 @@ +using ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class StepperExtensions + { + public static void UpdateMinimum(this Spinner nativeStepper, IStepper stepper) + { + nativeStepper.Minimum = stepper.Minimum; + } + + public static void UpdateMaximum(this Spinner nativeStepper, IStepper stepper) + { + nativeStepper.Maximum = stepper.Maximum; + } + + public static void UpdateIncrement(this Spinner nativeStepper, IStepper stepper) + { + var increment = stepper.Interval; + + if (increment > 0) + { + nativeStepper.LabelFormat = string.Format("%.{0}f", GetRequiredPrecision(increment)); + nativeStepper.Step = stepper.Interval; + } + } + + public static void UpdateValue(this Spinner nativeStepper, IStepper stepper) + { + if (nativeStepper.Value != stepper.Value) + nativeStepper.Value = stepper.Value; + } + + static int GetRequiredPrecision(double step) + { + // Determines how many decimal places are there in current Stepper's value. + // The 15 pound characters below correspond to the maximum precision of Double type. + var decimalValue = decimal.Parse(step.ToString("0.###############")); + + // GetBits() method returns an array of four 32-bit integer values. + // The third (0-indexing) element of an array contains the following information: + // bits 00-15: unused, required to be 0 + // bits 16-23: an exponent between 0 and 28 indicating the power of 10 to divide the integer number passed as a parameter. + // Conversely this is the number of decimal digits in the number as well. + // bits 24-30: unused, required to be 0 + // bit 31: indicates the sign. 0 means positive number, 1 is for negative numbers. + // + // The precision information needs to be extracted from bits 16-23 of third element of an array + // returned by GetBits() call. Right-shifting by 16 bits followed by zeroing anything else results + // in a nice conversion of this data to integer variable. + var precision = (decimal.GetBits(decimalValue)[3] >> 16) & 0x000000FF; + + return precision; + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/StrokeExtensions.cs b/src/Core/src/Platform/Tizen/StrokeExtensions.cs new file mode 100644 index 0000000000..02de4b0067 --- /dev/null +++ b/src/Core/src/Platform/Tizen/StrokeExtensions.cs @@ -0,0 +1,100 @@ +using ElmSharp; +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Platform +{ + public static class StrokeExtensions + { + public static void UpdateStrokeShape(this EvasObject platformView, IBorderStroke border) + { + var borderShape = border.Shape; + var canvas = platformView as BorderView; + if (canvas == null && borderShape == null) + return; + + platformView.UpdateMauiDrawable(border); + } + + public static void UpdateStroke(this EvasObject platformView, IBorderStroke border) + { + var stroke = border.Stroke; + var canvas = platformView as BorderView; + if (canvas == null && stroke.IsNullOrEmpty()) + return; + + platformView.UpdateMauiDrawable(border); + } + + public static void UpdateStrokeThickness(this EvasObject platformView, IBorderStroke border) + { + var canvas = platformView as BorderView; + bool hasBorder = border.Shape != null && border.Stroke != null; + if (canvas == null && !hasBorder) + return; + + platformView.UpdateMauiDrawable(border); + } + + public static void UpdateStrokeDashPattern(this EvasObject platformView, IBorderStroke border) + { + var strokeDashPattern = border.StrokeDashPattern; + var canvas = platformView as BorderView; + bool hasBorder = border.Shape != null && border.Stroke != null; + if (canvas == null && !hasBorder && (strokeDashPattern == null || strokeDashPattern.Length == 0)) + return; + + platformView.UpdateMauiDrawable(border); + } + + public static void UpdateStrokeDashOffset(this EvasObject platformView, IBorderStroke border) + { + var canvas = platformView as BorderView; + bool hasBorder = border.Shape != null && border.Stroke != null; + if (canvas == null && !hasBorder) + return; + + platformView.UpdateMauiDrawable(border); + } + + public static void UpdateStrokeMiterLimit(this EvasObject platformView, IBorderStroke border) + { + var canvas = platformView as BorderView; + bool hasBorder = border.Shape != null && border.Stroke != null; + if (canvas == null && !hasBorder) + return; + + platformView.UpdateMauiDrawable(border); + } + + public static void UpdateStrokeLineCap(this EvasObject platformView, IBorderStroke border) + { + var canvas = platformView as BorderView; + bool hasBorder = border.Shape != null && border.Stroke != null; + if (canvas == null && !hasBorder) + return; + platformView.UpdateMauiDrawable(border); + } + + public static void UpdateStrokeLineJoin(this EvasObject platformView, IBorderStroke border) + { + var canvas = platformView as BorderView; + bool hasBorder = border.Shape != null && border.Stroke != null; + if (canvas == null && !hasBorder) + return; + + platformView.UpdateMauiDrawable(border); + } + + internal static void UpdateMauiDrawable(this EvasObject platformView, IBorderStroke border) + { + bool hasBorder = border.Shape != null && border.Stroke != null; + if (!hasBorder) + return; + + if (platformView is BorderView borderView) + { + borderView.ContainerView?.UpdateBorder(border); + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/SwitchExtensions.cs b/src/Core/src/Platform/Tizen/SwitchExtensions.cs new file mode 100644 index 0000000000..1eb9659a59 --- /dev/null +++ b/src/Core/src/Platform/Tizen/SwitchExtensions.cs @@ -0,0 +1,33 @@ +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class SwitchExtensions + { + public static void UpdateIsOn(this Check platformCheck, ISwitch view) + { + platformCheck.IsChecked = view.IsOn; + } + + public static void UpdateTrackColor(this Check platformCheck, ISwitch view) + { + if (view.ThumbColor != null) + { + platformCheck.Color = view.TrackColor.ToPlatformEFL(); + } + } + + public static void UpdateThumbColor(this Check platformCheck, ISwitch view) + { + if (view.ThumbColor == null) + { + platformCheck.DeleteOnColors(); + } + else + { + platformCheck.SetOnColors(view.ThumbColor.ToPlatformEFL()); + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/TimePickerExtensions.cs b/src/Core/src/Platform/Tizen/TimePickerExtensions.cs new file mode 100644 index 0000000000..21cff819a8 --- /dev/null +++ b/src/Core/src/Platform/Tizen/TimePickerExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Globalization; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class TimePickerExtensions + { + static readonly string s_defaultFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern; + static TimeSpan Time = DateTime.Now.TimeOfDay; + + public static void UpdateFormat(this Entry platformTimePicker, ITimePicker timePicker) + { + UpdateTime(platformTimePicker, timePicker); + } + + public static void UpdateTime(this Entry platformTimePicker, ITimePicker timePicker) + { + // Xamarin using DateTime formatting (https://developer.xamarin.com/api/property/Xamarin.Forms.TimePicker.Format/) + platformTimePicker.Text = new DateTime(Time.Ticks).ToString(timePicker.Format ?? s_defaultFormat); + } + + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/TransformationExtensions.cs b/src/Core/src/Platform/Tizen/TransformationExtensions.cs new file mode 100644 index 0000000000..22f6251c7e --- /dev/null +++ b/src/Core/src/Platform/Tizen/TransformationExtensions.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using ElmSharp; +using Tizen.UIExtensions.ElmSharp; + +namespace Microsoft.Maui.Platform +{ + public static class TransformationExtensions + { + static Dictionary s_movedHandlers = new Dictionary(); + + public static void UpdateTransformation(this EvasObject platformView, IView? view) + { + if (view == null) + return; + + // prepare the EFL effect structure + Rect geometry = platformView.Geometry; + EvasMap map = new EvasMap(4); + map.PopulatePoints(geometry, 0); + + bool changed = false; + view.ApplyScale(map, geometry, ref changed); + view.ApplyRotation(platformView, map, geometry, ref changed); + view.ApplyTranslation(map, geometry, ref changed); + + platformView.IsMapEnabled = changed; + + if (changed) + { + platformView.EvasMap = map; + if (!s_movedHandlers.ContainsKey(platformView)) + { + // not registered moved handler + s_movedHandlers[platformView] = () => platformView.UpdateTransformation(view); + platformView.Moved += OnMoved; + } + } + else + { + if (s_movedHandlers.ContainsKey(platformView)) + { + // need to unregister moved handler + platformView.Moved -= OnMoved; + s_movedHandlers.Remove(platformView); + } + } + } + + static void OnMoved(object? sender, EventArgs e) + { + if (sender is EvasObject platformView) + { + s_movedHandlers[platformView].Invoke(); + } + } + + internal static void ApplyScale(this IView view, EvasMap map, Rect geometry, ref bool changed) + { + var scale = view.Scale; + var scaleX = view.ScaleX * scale; + var scaleY = view.ScaleY * scale; + + // apply scale factor + if (scaleX != 1.0 || scaleY != 1.0) + { + map.Zoom(scaleX, scaleY, + geometry.X + (int)(geometry.Width * view.AnchorX), + geometry.Y + (int)(geometry.Height * view.AnchorY)); + changed = true; + } + } + + internal static void ApplyRotation(this IView view, EvasObject platformView, EvasMap map, Rect geometry, ref bool changed) + { + var rotationX = view.RotationX; + var rotationY = view.RotationY; + var rotationZ = view.Rotation; + var anchorX = view.AnchorX; + var anchorY = view.AnchorY; + + // apply rotations + if (rotationX != 0 || rotationY != 0 || rotationZ != 0) + { + map.Rotate3D(rotationX, rotationY, rotationZ, (int)(geometry.X + geometry.Width * anchorX), + (int)(geometry.Y + geometry.Height * anchorY), 0); + // the last argument is focal length, it determine the strength of distortion. We compared it with the Android implementation + map.Perspective3D(geometry.X + geometry.Width / 2, geometry.Y + geometry.Height / 2, 0, (int)(1.3 * Math.Max(geometry.Height, geometry.Width))); + // Need to unset clip because perspective 3d rotation is going beyond the container bound + platformView.SetClip(null); + changed = true; + } + } + + internal static void ApplyTranslation(this IView view, EvasMap map, Rect geometry, ref bool changed) + { + var shiftX = view.TranslationX.ToScaledPixel(); + var shiftY = view.TranslationY.ToScaledPixel(); + + // apply translation, i.e. move/shift the object a little + if (shiftX != 0 || shiftY != 0) + { + if (changed) + { + // special care is taken to apply the translation last + Point3D p; + for (int i = 0; i < 4; i++) + { + p = map.GetPointCoordinate(i); + p.X += shiftX; + p.Y += shiftY; + map.SetPointCoordinate(i, p); + } + } + else + { + // in case when we only need translation, then construct the map in a simpler way + geometry.X += shiftX; + geometry.Y += shiftY; + map.PopulatePoints(geometry, 0); + + changed = true; + } + } + } + + public static void Perspective3D(this EvasMap map, int px, int py, int z0, int foc) + { + var mapType = typeof(EvasMap); + var propInfo = mapType.GetProperty("Handle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + IntPtr? handle = (IntPtr?)propInfo?.GetValue(map); + if (handle != null) + evas_map_util_3d_perspective(handle.Value, px, py, z0, foc); + } + + [DllImport("libevas.so.1")] + static extern void evas_map_util_3d_perspective(IntPtr map, int px, int py, int z0, int foc); + } +} diff --git a/src/Core/src/Platform/Tizen/ViewExtensions.cs b/src/Core/src/Platform/Tizen/ViewExtensions.cs new file mode 100644 index 0000000000..dfa133c55c --- /dev/null +++ b/src/Core/src/Platform/Tizen/ViewExtensions.cs @@ -0,0 +1,275 @@ +using System; +using System.Diagnostics; +using System.Numerics; +using System.Threading.Tasks; +using Microsoft.Maui.Graphics; +using ElmSharp; +using ElmSharp.Accessible; +using Tizen.UIExtensions.ElmSharp; +using static Microsoft.Maui.Primitives.Dimension; +using Rect = Microsoft.Maui.Graphics.Rect; + +namespace Microsoft.Maui.Platform +{ + public static partial class ViewExtensions + { + public static void UpdateIsEnabled(this EvasObject platformView, IView view) + { + if (!(platformView is Widget widget)) + return; + + widget.IsEnabled = view.IsEnabled; + } + + public static void Focus(this EvasObject platformView, FocusRequest request) + { + // TODO: Implement Focus on Tizen (ref #4588) + } + + public static void Unfocus(this EvasObject platformView, IView view) + { + // TODO: Implement Unfocus on Tizen (ref #4588) + } + + public static void UpdateVisibility(this EvasObject platformView, IView view) + { + if (view.Visibility.ToPlatformVisibility()) + { + platformView.Show(); + } + else + { + platformView.Hide(); + } + } + + public static bool ToPlatformVisibility(this Visibility visibility) + { + return visibility switch + { + Visibility.Hidden => false, + Visibility.Collapsed => false, + _ => true, + }; + } + + public static void UpdateBackground(this EvasObject platformView, IView view) + { + var paint = view.Background; + + if (platformView is WrapperView wrapperView) + { + wrapperView.UpdateBackground(paint); + } + else if (platformView is BorderView borderView) + { + borderView.ContainerView?.UpdateBackground(paint); + } + else if (paint is not null) + { + platformView.UpdateBackgroundColor(paint.ToPlatform()); + } + } + + public static void UpdateBorder(this EvasObject platformView, IView view) + { + var border = (view as IBorder)?.Border; + + if (platformView is WrapperView wrapperView) + wrapperView.Border = border; + } + + public static void UpdateOpacity(this EvasObject platformView, IView view) + { + if (platformView is Widget widget) + { + widget.Opacity = (int)(view.Opacity * 255.0); + } + } + + public static void UpdateClip(this EvasObject platformView, IView view) + { + if (platformView is WrapperView wrapper) + wrapper.Clip = view.Clip; + } + + public static void UpdateShadow(this EvasObject platformView, IView view) + { + if (platformView is WrapperView wrapper) + wrapper.Shadow = view.Shadow; + } + + public static void UpdateAutomationId(this EvasObject platformView, IView view) + { + { + //TODO: EvasObject.AutomationId is supported from tizen60. + //platformView.AutomationId = view.AutomationId; + } + } + + public static void UpdateSemantics(this EvasObject platformView, IView view) + { + var semantics = view.Semantics; + var accessibleObject = platformView as IAccessibleObject; + + if (semantics == null || accessibleObject == null) + return; + + accessibleObject.Name = semantics.Description; + accessibleObject.Description = semantics.Hint; + } + + public static void InvalidateMeasure(this EvasObject platformView, IView view) + { + platformView.MarkChanged(); + } + + public static void UpdateWidth(this EvasObject platformView, IView view) + { + UpdateSize(platformView, view); + } + + public static void UpdateHeight(this EvasObject platformView, IView view) + { + UpdateSize(platformView, view); + } + + public static void UpdateMinimumWidth(this EvasObject platformView, IView view) + { + UpdateSize(platformView, view); + } + + public static void UpdateMinimumHeight(this EvasObject platformView, IView view) + { + UpdateSize(platformView, view); + } + + public static void UpdateMaximumWidth(this EvasObject platformView, IView view) + { + UpdateSize(platformView, view); + } + + public static void UpdateMaximumHeight(this EvasObject platformView, IView view) + { + UpdateSize(platformView, view); + } + + public static void UpdateInputTransparent(this EvasObject platformView, IViewHandler handler, IView view) + { + platformView.PassEvents = view.InputTransparent; + } + + public static void UpdateSize(EvasObject platformView, IView view) + { + if (!IsExplicitSet(view.Width) || !IsExplicitSet(view.Height)) + { + // Ignore the initial setting of the value; the initial layout will take care of it + return; + } + + // Updating the frame (assuming it's an actual change) will kick off a layout update + // Handling of the default (-1) width/height will be taken care of by GetDesiredSize + platformView.Resize(view.Width.ToScaledPixel(), view.Height.ToScaledPixel()); + } + + internal static Rect GetPlatformViewBounds(this IView view) + { + var platformView = view?.ToPlatform(); + if (platformView == null) + { + return new Rect(); + } + + return platformView.GetPlatformViewBounds(); + } + + internal static Rect GetPlatformViewBounds(this EvasObject platformView) + { + if (platformView == null) + return new Rect(); + + return platformView.Geometry.ToDP(); + } + + internal static Matrix4x4 GetViewTransform(this IView view) + { + var platformView = view?.ToPlatform(); + if (platformView == null) + return new Matrix4x4(); + return platformView.GetViewTransform(); + } + + internal static Matrix4x4 GetViewTransform(this EvasObject platformView) + => new Matrix4x4(); + + internal static Rect GetBoundingBox(this IView view) + => view.ToPlatform().GetBoundingBox(); + + internal static Rect GetBoundingBox(this EvasObject? platformView) + { + if (platformView == null) + return new Rect(); + + return platformView.Geometry.ToDP(); + } + + internal static EvasObject? GetParent(this EvasObject? view) + { + return view?.Parent; + } + + // TODO : Should consider a better way to determine that the view has been loaded/unloaded. + internal static bool IsLoaded(this EvasObject view) => + view.IsRealized; + + internal static IDisposable OnLoaded(this EvasObject view, Action action) + { + if (view.IsLoaded()) + { + action(); + return new ActionDisposable(() => { }); + } + + EventHandler? renderPostEventHandler = null; + ActionDisposable disposable = new ActionDisposable(() => + { + if (renderPostEventHandler != null) + view.RenderPost -= renderPostEventHandler; + }); + + renderPostEventHandler = (_, __) => + { + disposable.Dispose(); + action(); + }; + + view.RenderPost += renderPostEventHandler; + return disposable; + } + + internal static IDisposable OnUnloaded(this EvasObject view, Action action) + { + if (!view.IsLoaded()) + { + action(); + return new ActionDisposable(() => { }); + } + + EventHandler? deletedEventHandler = null; + ActionDisposable disposable = new ActionDisposable(() => + { + if (deletedEventHandler != null) + view.Deleted -= deletedEventHandler; + }); + + deletedEventHandler = (_, __) => + { + disposable.Dispose(); + action(); + }; + + view.Deleted += deletedEventHandler; + return disposable; + } + } +} diff --git a/src/Core/src/Platform/Tizen/WebViewExtensions.cs b/src/Core/src/Platform/Tizen/WebViewExtensions.cs new file mode 100644 index 0000000000..02bafd7ed8 --- /dev/null +++ b/src/Core/src/Platform/Tizen/WebViewExtensions.cs @@ -0,0 +1,57 @@ + +namespace Microsoft.Maui.Platform +{ + public static class WebViewExtensions + { + public static void UpdateSource(this MauiWebView platformWebView, IWebView webView) + { + platformWebView.UpdateSource(webView, null); + } + + public static void UpdateSource(this MauiWebView platformWebView, IWebView webView, IWebViewDelegate? webViewDelegate) + { + if (webViewDelegate != null) + webView.Source?.Load(webViewDelegate); + } + + public static void UpdateGoBack(this MauiWebView platformWebView, IWebView webView) + { + if (platformWebView == null) + return; + + if (platformWebView.WebView.CanGoBack()) + platformWebView.WebView.GoBack(); + + platformWebView.UpdateCanGoBackForward(webView); + } + + public static void UpdateGoForward(this MauiWebView platformWebView, IWebView webView) + { + if (platformWebView == null) + return; + + if (platformWebView.WebView.CanGoForward()) + platformWebView.WebView.GoForward(); + + platformWebView.UpdateCanGoBackForward(webView); + } + + public static void UpdateReload(this MauiWebView platformWebView, IWebView webView) + { + // TODO: Sync Cookies + + platformWebView?.WebView.Reload(); + } + + internal static void UpdateCanGoBackForward(this MauiWebView platformWebView, IWebView webView) + { + webView.CanGoBack = platformWebView.WebView.CanGoBack(); + webView.CanGoForward = platformWebView.WebView.CanGoForward(); + } + + public static void Eval(this MauiWebView platformWebView, IWebView webView, string script) + { + platformWebView.WebView.Eval(script); + } + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/WindowExtensions.cs b/src/Core/src/Platform/Tizen/WindowExtensions.cs new file mode 100644 index 0000000000..b21b0972d5 --- /dev/null +++ b/src/Core/src/Platform/Tizen/WindowExtensions.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using ElmSharp; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using ELayout = ElmSharp.Layout; + +namespace Microsoft.Maui.Platform +{ + public static partial class WindowExtensions + { + static Dictionary> s_windowBackButtonPressedHandler = new Dictionary>(); + static Dictionary s_windowCloseRequestHandler = new Dictionary(); + static Dictionary s_windowBaseLayout = new Dictionary(); + static Dictionary s_windowModalStack = new Dictionary(); + + public static void Initialize(this Window platformWindow) + { + var baseLayout = (ELayout?)platformWindow.GetType().GetProperty("BaseLayout")?.GetValue(platformWindow); + + if (baseLayout == null) + { + var conformant = new Conformant(platformWindow); + conformant.Show(); + + var layout = new ApplicationLayout(conformant); + layout.Show(); + + baseLayout = layout; + conformant.SetContent(baseLayout); + } + platformWindow.SetBaseLayout(baseLayout); + var modalStack = new ModalStack(baseLayout) + { + AlignmentX = -1, + AlignmentY = -1, + WeightX = 1, + WeightY = 1, + }; + modalStack.Show(); + baseLayout.SetContent(modalStack); + platformWindow.SetModalStack(modalStack); + + platformWindow.Active(); + platformWindow.Show(); + platformWindow.AvailableRotations = DisplayRotation.Degree_0 | DisplayRotation.Degree_90 | DisplayRotation.Degree_180 | DisplayRotation.Degree_270; + + platformWindow.RotationChanged += (sender, e) => + { + // TODO : should update later + }; + + platformWindow.BackButtonPressed += (s, e) => OnBackButtonPressed(platformWindow); + } + + public static void SetOverlay(this Window window, EvasObject content) + { + content?.SetAlignment(-1, -1); + content?.SetWeight(1, 1); + content?.Show(); + window.AddResizeObject(content); + } + + public static void SetWindowCloseRequestHandler(this Window window, Action handler) + { + s_windowCloseRequestHandler[window] = handler; + } + + public static void SetBackButtonPressedHandler(this Window window, Func handler) + { + s_windowBackButtonPressedHandler[window] = handler; + } + + public static ELayout GetBaseLayout(this Window window) + { + return s_windowBaseLayout[window]; + } + + public static void SetBaseLayout(this Window window, ELayout layout) + { + s_windowBaseLayout[window] = layout; + } + + public static ModalStack GetModalStack(this Window window) + { + return s_windowModalStack[window]; + } + + public static void SetModalStack(this Window window, ModalStack modalStack) + { + s_windowModalStack[window] = modalStack; + } + + public static float GetDisplayDensity(this Window window) + { + return (float)DeviceInfo.ScalingFactor; + } + + static void OnBackButtonPressed(Window window) + { + if (s_windowBackButtonPressedHandler.ContainsKey(window)) + { + if (s_windowBackButtonPressedHandler[window].Invoke()) + return; + } + + if (s_windowCloseRequestHandler.ContainsKey(window)) + s_windowCloseRequestHandler[window].Invoke(); + } + + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Tizen/WrapperView.cs b/src/Core/src/Platform/Tizen/WrapperView.cs new file mode 100644 index 0000000000..bbd979f9ad --- /dev/null +++ b/src/Core/src/Platform/Tizen/WrapperView.cs @@ -0,0 +1,310 @@ +using System; +using System.Runtime.InteropServices; +using ElmSharp; +using Microsoft.Maui.Graphics; +using Microsoft.Maui.Graphics.Skia; +using Microsoft.Maui.Graphics.Skia.Views; +using SkiaSharp.Views.Tizen; +using Tizen.UIExtensions.Common; +using Tizen.UIExtensions.ElmSharp; +using Rect = Microsoft.Maui.Graphics.Rect; + +namespace Microsoft.Maui.Platform +{ + public partial class WrapperView : Canvas + { + Lazy _drawableCanvas; + Lazy _clipperView; + EvasObject? _content; + + public WrapperView(EvasObject parent) : base(parent) + { + _drawableCanvas = new Lazy(() => + { + var view = new SkiaGraphicsView(parent) + { + IgnorePixelScaling = true, + Drawable = new MauiDrawable(), + PassEvents = true + }; + view.Show(); + Children.Add(view); + view.Lower(); + Content?.RaiseTop(); + return view; + }); + + _clipperView = new Lazy(() => + { + var clipper = new SKClipperView(parent) + { + PassEvents = true + }; + clipper.DrawClip += OnClipPaint; + clipper.Show(); + clipper.DeviceScalingFactor = (float)DeviceInfo.ScalingFactor; + Children.Add(clipper); + clipper.Lower(); + Content?.RaiseTop(); + return clipper; + }); + + LayoutUpdated += OnLayout; + } + + public void UpdateBackground(Paint? paint) + { + UpdateDrawableCanvas(paint); + } + + public void UpdateShape(IShape? shape) + { + UpdateDrawableCanvas(shape); + } + + public void UpdateBorder(IBorderStroke border) + { + ((MauiDrawable)_drawableCanvas.Value.Drawable).Border = border; + UpdateShape(border.Shape); + } + + partial void ShadowChanged() + { + if (!_drawableCanvas.IsValueCreated && Shadow is null) + return; + + ((MauiDrawable)_drawableCanvas.Value.Drawable).Shadow = Shadow; + + if (Shadow != null) + { + _drawableCanvas.Value.SetClip(null); + } + UpdateDrawableCanvas(true); + } + + partial void ClipChanged() + { + if (_drawableCanvas.IsValueCreated || Clip is not null) + { + ((MauiDrawable)_drawableCanvas.Value.Drawable).Clip = Clip; + UpdateDrawableCanvas(false); + } + + if (_clipperView.IsValueCreated || Clip is not null) + _clipperView.Value.Invalidate(); + } + + void UpdateDrawableCanvas(Paint? paint) + { + if (_drawableCanvas.IsValueCreated || paint is not null) + { + ((MauiDrawable)_drawableCanvas.Value.Drawable).Background = paint; + _drawableCanvas.Value.Invalidate(); + } + } + + void UpdateDrawableCanvas(IShape? shape) + { + if (_drawableCanvas.IsValueCreated || shape is not null) + { + ((MauiDrawable)_drawableCanvas.Value.Drawable).Shape = shape; + _drawableCanvas.Value.Invalidate(); + } + } + + void UpdateDrawableCanvas(bool isShadowUpdated) + { + if (isShadowUpdated) + { + UpdateDrawableCanvasGeometry(); + } + _drawableCanvas.Value.Invalidate(); + } + + void OnClipPaint(object? sender, DrawClipEventArgs e) + { + var canvas = e.Canvas; + var width = e.DirtyRect.Width; + var height = e.DirtyRect.Height; + + canvas.FillColor = Colors.Transparent; + canvas.FillRectangle(e.DirtyRect); + + canvas.FillColor = Colors.White; + var clipPath = Clip?.PathForBounds(new Rect(0, 0, width, height)) ?? null; + if (clipPath == null) + { + return; + } + canvas.FillPath(clipPath); + Content?.SetClipperCanvas(_clipperView.Value); + if (_drawableCanvas.IsValueCreated) + { + _drawableCanvas.Value.SetClipperCanvas(_clipperView.Value); + } + } + + void OnLayout(object? sender, LayoutEventArgs e) + { + if (Content != null) + { + Content.Geometry = Geometry; + } + + if (_drawableCanvas.IsValueCreated) + { + UpdateDrawableCanvas(true); + } + + if (_clipperView.IsValueCreated) + { + _clipperView.Value.Geometry = Geometry; + _clipperView.Value.Invalidate(); + if (Shadow != null) + { + _drawableCanvas.Value.SetClip(null); + } + } + } + + public EvasObject? Content + { + get => _content; + set + { + if (_content != value) + { + if (_content != null) + { + Children.Remove(_content); + _content = null; + } + _content = value; + if (_content != null) + { + Children.Add(_content); + _content.RaiseTop(); + } + } + } + } + + void UpdateDrawableCanvasGeometry() + { + if (_drawableCanvas.IsValueCreated) + { + var shadowMargin = GetShadowMargin(Shadow); + _drawableCanvas.Value.UpdateBounds(Geometry.ToDP().ExpandTo(shadowMargin).ToPixel()); + ((MauiDrawable)_drawableCanvas.Value.Drawable).ShadowThickness = shadowMargin; + } + } + + Thickness GetShadowMargin(IShadow? shadow) + { + double left = 0; + double top = 0; + double right = 0; + double bottom = 0; + + var offsetX = shadow == null ? 0 : shadow.Offset.X; + var offsetY = shadow == null ? 0 : shadow.Offset.Y; + var blurRadius = shadow == null ? 0 : ((double)shadow.Radius); + var spreadSize = blurRadius * 3; + var spreadLeft = offsetX - spreadSize; + var spreadRight = offsetX + spreadSize; + var spreadTop = offsetY - spreadSize; + var spreadBottom = offsetY + spreadSize; + if (left > spreadLeft) + left = spreadLeft; + if (top > spreadTop) + top = spreadTop; + if (right < spreadRight) + right = spreadRight; + if (bottom < spreadBottom) + bottom = spreadBottom; + + return new Thickness(Math.Abs(left), Math.Abs(top), Math.Abs(right), Math.Abs(bottom)); + } + } + + public class DrawClipEventArgs : EventArgs + { + public DrawClipEventArgs(ICanvas canvas, RectF dirtyRect) + { + Canvas = canvas; + DirtyRect = dirtyRect; + } + + public ICanvas Canvas { get; set; } + + public RectF DirtyRect { get; set; } + } + + public class SKClipperView : SKCanvasView + { + private SkiaCanvas _canvas; + private ScalingCanvas _scalingCanvas; + + public SKClipperView(EvasObject parent) : base(parent) + { + _canvas = new SkiaCanvas(); + _scalingCanvas = new ScalingCanvas(_canvas); + PaintSurface += OnPaintSurface; + } + + public float DeviceScalingFactor { get; set; } + public bool ClippingRequired { get; set; } + public event EventHandler? DrawClip; + + public new void Invalidate() + { + ClippingRequired = true; + OnDrawFrame(); + ClippingRequired = false; + } + + protected virtual void OnPaintSurface(object? sender, SKPaintSurfaceEventArgs e) + { + var skiaCanvas = e.Surface.Canvas; + skiaCanvas.Clear(); + + _canvas.Canvas = skiaCanvas; + _scalingCanvas.ResetState(); + + float width = e.Info.Width; + float height = e.Info.Height; + if (DeviceScalingFactor > 0) + { + width = width / DeviceScalingFactor; + height = height / DeviceScalingFactor; + } + + _scalingCanvas.SaveState(); + + if (DeviceScalingFactor > 0) + _scalingCanvas.Scale(DeviceScalingFactor, DeviceScalingFactor); + DrawClip?.Invoke(this, new DrawClipEventArgs(_scalingCanvas, new RectF(0, 0, width, height))); + _scalingCanvas.RestoreState(); + } + } + + public static class ClipperExtension + { + public static void SetClipperCanvas(this EvasObject target, SKClipperView clipper) + { + if (target != null && clipper.ClippingRequired) + { + var realHandle = elm_object_part_content_get(clipper, "elm.swallow.content"); + + target.SetClip(null); // To restore original image + evas_object_clip_set(target, realHandle); + } + } + + [DllImport("libevas.so.1")] + internal static extern void evas_object_clip_set(IntPtr obj, IntPtr clip); + + [DllImport("libelementary.so.1")] + internal static extern IntPtr elm_object_part_content_get(IntPtr obj, string part); + } +} diff --git a/src/Core/src/Platform/Tizen/WrapperViewDrawables.cs b/src/Core/src/Platform/Tizen/WrapperViewDrawables.cs new file mode 100644 index 0000000000..5a5e19200c --- /dev/null +++ b/src/Core/src/Platform/Tizen/WrapperViewDrawables.cs @@ -0,0 +1,65 @@ +using System; +using Microsoft.Maui.Graphics; + +namespace Microsoft.Maui.Platform +{ + public class WrapperViewDrawables : IWrapperViewDrawables + { + public event EventHandler? Invalidated; + + IDrawable? _shadowDrawable; + IDrawable? _backgroundDrawable; + IDrawable? _borderDrawable; + + public IDrawable? ShadowDrawable + { + get + { + return _shadowDrawable; + } + set + { + _shadowDrawable = value; + SendInvalidated(); + } + } + + public IDrawable? BackgroundDrawable + { + get + { + return _backgroundDrawable; + } + set + { + _backgroundDrawable = value; + SendInvalidated(); + } + } + + public IDrawable? BorderDrawable + { + get + { + return _borderDrawable; + } + set + { + _borderDrawable = value; + SendInvalidated(); + } + } + + public void Draw(ICanvas canvas, RectF dirtyRect) + { + _shadowDrawable?.Draw(canvas, dirtyRect); + _backgroundDrawable?.Draw(canvas, dirtyRect); + _borderDrawable?.Draw(canvas, dirtyRect); + } + + public void SendInvalidated() + { + Invalidated?.Invoke(this, EventArgs.Empty); + } + } +} diff --git a/src/Core/src/Platform/ViewExtensions.cs b/src/Core/src/Platform/ViewExtensions.cs index b78a073cad..53408473dd 100644 --- a/src/Core/src/Platform/ViewExtensions.cs +++ b/src/Core/src/Platform/ViewExtensions.cs @@ -17,6 +17,9 @@ using ParentView = Android.Views.IViewParent; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; using ParentView = Microsoft.UI.Xaml.DependencyObject; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +using ParentView = ElmSharp.EvasObject; #else using PlatformView = System.Object; using ParentView = System.Object; diff --git a/src/Core/src/Properties/AssemblyInfo.cs b/src/Core/src/Properties/AssemblyInfo.cs index 7fb9f923b2..26da9521f6 100644 --- a/src/Core/src/Properties/AssemblyInfo.cs +++ b/src/Core/src/Properties/AssemblyInfo.cs @@ -7,8 +7,10 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Maps.Android")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.iOS")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Windows")] +[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.Tizen")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.ControlGallery")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.ControlGallery.Android")] +[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Compatibility.ControlGallery.Tizen")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Xaml")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Xaml.UnitTests")] [assembly: InternalsVisibleTo("Microsoft.Maui.Controls.HotReload.Forms")] diff --git a/src/Core/src/SemanticExtensions.cs b/src/Core/src/SemanticExtensions.cs index 311f83a05f..e66534e5b5 100644 --- a/src/Core/src/SemanticExtensions.cs +++ b/src/Core/src/SemanticExtensions.cs @@ -9,6 +9,10 @@ using Android.Views.Accessibility; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +#elif TIZEN +using ElmSharp; +using ElmSharp.Accessible; +using PlatformView = ElmSharp.EvasObject; #elif NETSTANDARD using PlatformView = System.Object; #endif @@ -26,7 +30,9 @@ namespace Microsoft.Maui platformView.SendAccessibilityEvent(EventTypes.ViewHoverEnter); #elif __IOS__ || MACCATALYST UIAccessibility.PostNotification(UIAccessibilityPostNotification.LayoutChanged, platformView); +#elif TIZEN + (platformView as IAccessibleObject)?.Highlight(); #endif } } -} \ No newline at end of file +} diff --git a/src/Core/src/ViewExtensions.cs b/src/Core/src/ViewExtensions.cs index 8655de37b8..8e40698967 100644 --- a/src/Core/src/ViewExtensions.cs +++ b/src/Core/src/ViewExtensions.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Microsoft.Maui.Media; using System.IO; -#if NETSTANDARD || (NET6_0 && !IOS && !ANDROID) +#if NETSTANDARD || (NET6_0 && !IOS && !ANDROID && !TIZEN) using IPlatformViewHandler = Microsoft.Maui.IViewHandler; #endif #if IOS || MACCATALYST @@ -14,6 +14,9 @@ using ParentView = Android.Views.IViewParent; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; using ParentView = Microsoft.UI.Xaml.DependencyObject; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; +using ParentView = ElmSharp.EvasObject; #else using PlatformView = System.Object; using ParentView = System.Object; diff --git a/src/Core/src/VisualDiagnostics/VisualDiagnosticsOverlay.Tizen.cs b/src/Core/src/VisualDiagnostics/VisualDiagnosticsOverlay.Tizen.cs new file mode 100644 index 0000000000..47afc488be --- /dev/null +++ b/src/Core/src/VisualDiagnostics/VisualDiagnosticsOverlay.Tizen.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using ElmSharp; + +namespace Microsoft.Maui +{ + /// + /// Visual Diagnostics Overlay. + /// + public partial class VisualDiagnosticsOverlay + { + readonly Dictionary _scrollViews = new(); + + public void AddScrollableElementHandler(IScrollView scrollBar) + { + var nativeScroll = scrollBar.ToPlatform(); + if (nativeScroll != null) + { + _scrollViews.Add(scrollBar, nativeScroll); + if (nativeScroll is Scroller scroller) + { + scroller.Scrolled += OnScrolled; + } + } + } + + public override void HandleUIChange() + { + base.HandleUIChange(); + + if (WindowElements.Count > 0) + RemoveAdorners(); + + Invalidate(); + } + + /// + public void RemoveScrollableElementHandler() + { + foreach (var scroll in _scrollViews.Values) + { + if (scroll is Scroller scroller) + { + scroller.Scrolled -= OnScrolled; + } + } + _scrollViews.Clear(); + } + + void OnScrolled(object? sender, EventArgs e) + { + Invalidate(); + } + } +} \ No newline at end of file diff --git a/src/Core/src/WindowExtensions.cs b/src/Core/src/WindowExtensions.cs index 5502c210e4..82d6300d79 100644 --- a/src/Core/src/WindowExtensions.cs +++ b/src/Core/src/WindowExtensions.cs @@ -7,6 +7,8 @@ using PlatformView = UIKit.UIWindow; using PlatformView = Android.App.Activity; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.Window; +#elif TIZEN +using PlatformView = ElmSharp.Window; #endif namespace Microsoft.Maui diff --git a/src/Core/src/WindowOverlay/WindowOverlay.Tizen.cs b/src/Core/src/WindowOverlay/WindowOverlay.Tizen.cs new file mode 100644 index 0000000000..e22b038c00 --- /dev/null +++ b/src/Core/src/WindowOverlay/WindowOverlay.Tizen.cs @@ -0,0 +1,77 @@ +using ElmSharp; +using Microsoft.Maui.Graphics.Skia.Views; +using Point = Microsoft.Maui.Graphics.Point; + +namespace Microsoft.Maui +{ + public partial class WindowOverlay + { + SkiaGraphicsView? _graphicsView; + GestureLayer? _touchLayer; + + public virtual bool Initialize() + { + if (IsPlatformViewInitialized) + return true; + + if (Window == null) + return false; + + var platformWindow = Window.Content?.ToPlatform() as Window; + if (platformWindow == null) + return false; + + var handler = Window.Handler as WindowHandler; + if (handler?.MauiContext == null) + return false; + + _graphicsView = new SkiaGraphicsView(platformWindow); + _graphicsView.Drawable = this; + _graphicsView.RepeatEvents = !DisableUITouchEventPassthrough; + + _touchLayer = new GestureLayer(platformWindow); + _touchLayer.Attach(_graphicsView); + _touchLayer.SetTapCallback(GestureLayer.GestureType.Tap, GestureLayer.GestureState.Start, (data) => + { + var x = _touchLayer.EvasCanvas.Pointer.X; + var y = _touchLayer.EvasCanvas.Pointer.Y; + OnTappedInternal(new Point(DPExtensions.ConvertToScaledDP(x), DPExtensions.ConvertToScaledDP(y))); + }); + + platformWindow.SetOverlay(_graphicsView); + IsPlatformViewInitialized = true; + return IsPlatformViewInitialized; + } + + public void Invalidate() + { + _graphicsView?.Invalidate(); + } + + void DeinitializePlatformDependencies() + { + if (Window == null) + return; + + var platformWindow = Window?.Content?.ToPlatform(); + if (platformWindow == null) + return; + + var handler = Window?.Handler as WindowHandler; + if (handler?.MauiContext == null) + return; + + _graphicsView?.Unrealize(); + _graphicsView = null; + IsPlatformViewInitialized = false; + } + + partial void OnDisableUITouchEventPassthroughSet() + { + if (_graphicsView != null) + { + _graphicsView.RepeatEvents = !DisableUITouchEventPassthrough; + } + } + } +} \ No newline at end of file diff --git a/src/Core/src/WindowOverlay/WindowOverlay.cs b/src/Core/src/WindowOverlay/WindowOverlay.cs index 6ace5c31ad..03d6524a19 100644 --- a/src/Core/src/WindowOverlay/WindowOverlay.cs +++ b/src/Core/src/WindowOverlay/WindowOverlay.cs @@ -9,6 +9,8 @@ using PlatformView = UIKit.UIView; using PlatformView = Android.Views.View; #elif WINDOWS using PlatformView = Microsoft.UI.Xaml.FrameworkElement; +#elif TIZEN +using PlatformView = ElmSharp.EvasObject; #elif NETSTANDARD using PlatformView = System.Object; #endif diff --git a/src/DotNet/Dependencies/Workloads.csproj b/src/DotNet/Dependencies/Workloads.csproj index 310f70e787..5d1e5e0c78 100644 --- a/src/DotNet/Dependencies/Workloads.csproj +++ b/src/DotNet/Dependencies/Workloads.csproj @@ -10,5 +10,6 @@ + \ No newline at end of file diff --git a/src/DotNet/DotNet.csproj b/src/DotNet/DotNet.csproj index b496dad564..2ccc823eeb 100644 --- a/src/DotNet/DotNet.csproj +++ b/src/DotNet/DotNet.csproj @@ -75,7 +75,7 @@ - + @@ -118,6 +118,7 @@ <_WorkloadIds Include="macos" /> <_WorkloadIds Include="ios" /> <_WorkloadIds Include="tvos" /> + <_WorkloadIds Include="tizen" /> <_WorkloadFiles Include="$(_WorkloadManifestDir)microsoft.net.*/*/data/WorkloadManifest.*" /> + <_WorkloadFiles Include="$(_WorkloadManifestDir)samsung.net.sdk.*/*/data/WorkloadManifest.*" /> 1 + + + + diff --git a/src/Essentials/samples/Samples/Platforms/Tizen/CustomViewCellRenderer.cs b/src/Essentials/samples/Samples/Platforms/Tizen/CustomViewCellRenderer.cs deleted file mode 100644 index ddca32c29d..0000000000 --- a/src/Essentials/samples/Samples/Platforms/Tizen/CustomViewCellRenderer.cs +++ /dev/null @@ -1,20 +0,0 @@ -using ElmSharp; -using Microsoft.Maui; -using Microsoft.Maui.Controls; -using Samples.Tizen; -using Xamarin.Forms.Platform.Tizen; - -[assembly: ExportCell(typeof(ViewCell), typeof(CustomViewCellRenderer))] - -namespace Samples.Tizen -{ - public sealed class CustomViewCellRenderer : ViewCellRenderer - { - protected override EvasObject OnGetContent(Cell cell, string part) - { - var view = base.OnGetContent(cell, part); - view.PropagateEvents = true; - return view; - } - } -} diff --git a/src/Essentials/samples/Samples/Platforms/Tizen/Program.cs b/src/Essentials/samples/Samples/Platforms/Tizen/Program.cs index cc8575ab4c..4602bc64c8 100644 --- a/src/Essentials/samples/Samples/Platforms/Tizen/Program.cs +++ b/src/Essentials/samples/Samples/Platforms/Tizen/Program.cs @@ -1,28 +1,15 @@ using Microsoft.Maui; -using Microsoft.Maui.Controls; -using Tizen.NET.MaterialComponents; -using Xamarin.Forms.Platform.Tizen; +using Microsoft.Maui.Hosting; namespace Samples.Tizen { - class Program : FormsApplication + class Program : MauiApplication { - static App formsApp; - - protected override void OnCreate() - { - base.OnCreate(); - - MaterialComponents.Init(DirectoryInfo.Resource); - Microsoft.Maui.Essentials.Platform.Init(MainWindow); - LoadApplication(formsApp ??= new App()); - } + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); static void Main(string[] args) { var app = new Program(); - Forms.Init(app); - Microsoft.Maui.Essentials.Platform.MapServiceToken = "MAP_SERVICE_KEY"; app.Run(args); } } diff --git a/src/Essentials/samples/Samples/Platforms/Tizen/tizen-manifest.xml b/src/Essentials/samples/Samples/Platforms/Tizen/tizen-manifest.xml index 934859bc5f..c84a6dcf56 100644 --- a/src/Essentials/samples/Samples/Platforms/Tizen/tizen-manifest.xml +++ b/src/Essentials/samples/Samples/Platforms/Tizen/tizen-manifest.xml @@ -1,7 +1,7 @@  - + - + Samples.Tizen.png diff --git a/src/Essentials/samples/Samples/Startup.cs b/src/Essentials/samples/Samples/Startup.cs index 995d029691..b85505ad73 100644 --- a/src/Essentials/samples/Samples/Startup.cs +++ b/src/Essentials/samples/Samples/Startup.cs @@ -1,4 +1,7 @@ -using Microsoft.Maui; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Maui; +using Microsoft.Maui.Controls.Compatibility; +using Microsoft.Maui.Controls.Compatibility.Hosting; using Microsoft.Maui.Controls.Hosting; using Microsoft.Maui.Hosting; using Microsoft.Maui.LifecycleEvents; @@ -13,6 +16,9 @@ namespace Samples builder .UseMauiApp() +#if TIZEN + .UseMauiCompatibility() +#endif .ConfigureEssentials(essentials => { essentials.UseVersionTracking(); diff --git a/src/Essentials/samples/Samples/View/HomePage.xaml b/src/Essentials/samples/Samples/View/HomePage.xaml index 31a76b69b1..1e6c1097b8 100644 --- a/src/Essentials/samples/Samples/View/HomePage.xaml +++ b/src/Essentials/samples/Samples/View/HomePage.xaml @@ -50,4 +50,4 @@ - \ No newline at end of file + diff --git a/src/Essentials/src/Accelerometer/Accelerometer.tizen.cs b/src/Essentials/src/Accelerometer/Accelerometer.tizen.cs index d0054512a9..7ec85b8498 100644 --- a/src/Essentials/src/Accelerometer/Accelerometer.tizen.cs +++ b/src/Essentials/src/Accelerometer/Accelerometer.tizen.cs @@ -1,3 +1,4 @@ +using Microsoft.Maui.ApplicationModel; using Tizen.Sensor; using TizenAccelerometer = Tizen.Sensor.Accelerometer; @@ -6,9 +7,9 @@ namespace Microsoft.Maui.Devices.Sensors partial class AccelerometerImplementation { internal static TizenAccelerometer DefaultSensor => - (TizenAccelerometer)Platform.GetDefaultSensor(SensorType.Accelerometer); + (TizenAccelerometer)PlatformUtils.GetDefaultSensor(SensorType.Accelerometer); - internal static bool IsSupported => + public bool IsSupported => TizenAccelerometer.IsSupported; void PlatformStart(SensorSpeed sensorSpeed) diff --git a/src/Essentials/src/AppInfo/AppInfo.tizen.cs b/src/Essentials/src/AppInfo/AppInfo.tizen.cs index c0d8f05952..321e0ed0cc 100644 --- a/src/Essentials/src/AppInfo/AppInfo.tizen.cs +++ b/src/Essentials/src/AppInfo/AppInfo.tizen.cs @@ -3,7 +3,7 @@ using Tizen.Applications; namespace Microsoft.Maui.ApplicationModel { - class AppInfoImplementation + class AppInfoImplementation : IAppInfo { public string PackageName => Application.Current.ApplicationInfo.PackageId; @@ -19,7 +19,7 @@ namespace Microsoft.Maui.ApplicationModel public string BuildString => Version.Build.ToString(CultureInfo.InvariantCulture); - public void PlatformShowSettingsUI() + public void ShowSettingsUI() { Permissions.EnsureDeclared(); AppControl.SendLaunchRequest(new AppControl() { Operation = AppControlOperations.Setting }); @@ -29,5 +29,8 @@ namespace Microsoft.Maui.ApplicationModel => AppTheme.Unspecified; public AppPackagingModel PackagingModel => AppPackagingModel.Packaged; + + public LayoutDirection RequestedLayoutDirection + => LayoutDirection.LeftToRight; } } diff --git a/src/Essentials/src/Barometer/Barometer.tizen.cs b/src/Essentials/src/Barometer/Barometer.tizen.cs index fd4f95478a..3add4eb3c4 100644 --- a/src/Essentials/src/Barometer/Barometer.tizen.cs +++ b/src/Essentials/src/Barometer/Barometer.tizen.cs @@ -1,16 +1,17 @@ using System; +using Microsoft.Maui.ApplicationModel; using Tizen.Sensor; using TizenBarometerSensor = Tizen.Sensor.PressureSensor; namespace Microsoft.Maui.Devices.Sensors { - class BarometerImplementation : IBarometer + partial class BarometerImplementation : IBarometer { public bool IsSupported => TizenBarometerSensor.IsSupported; TizenBarometerSensor DefaultSensor - => (TizenBarometerSensor)Platform.GetDefaultSensor(SensorType.Barometer); + => (TizenBarometerSensor)PlatformUtils.GetDefaultSensor(SensorType.Barometer); TizenBarometerSensor sensor = null; @@ -23,7 +24,7 @@ namespace Microsoft.Maui.Devices.Sensors } void DataUpdated(object sender, PressureSensorDataUpdatedEventArgs e) - => RaiseDataChanged(new BarometerData(e.Pressure)); + => RaiseReadingChanged(new BarometerData(e.Pressure)); void PlatformStop() { diff --git a/src/Essentials/src/Battery/Battery.tizen.cs b/src/Essentials/src/Battery/Battery.tizen.cs index 8631755f54..6aee8be5fa 100755 --- a/src/Essentials/src/Battery/Battery.tizen.cs +++ b/src/Essentials/src/Battery/Battery.tizen.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Maui.ApplicationModel; using TizenBattery = Tizen.System.Battery; namespace Microsoft.Maui.Devices diff --git a/src/Essentials/src/Browser/Browser.tizen.cs b/src/Essentials/src/Browser/Browser.tizen.cs index ae06dc054b..df8d64b450 100755 --- a/src/Essentials/src/Browser/Browser.tizen.cs +++ b/src/Essentials/src/Browser/Browser.tizen.cs @@ -8,7 +8,7 @@ namespace Microsoft.Maui.ApplicationModel { partial class BrowserImplementation : IBrowser { - public Task PlatformOpenAsync(Uri uri, BrowserLaunchOptions launchMode) + public Task OpenAsync(Uri uri, BrowserLaunchOptions launchMode) { if (uri == null) throw new ArgumentNullException(nameof(uri)); diff --git a/src/Essentials/src/Compass/Compass.tizen.cs b/src/Essentials/src/Compass/Compass.tizen.cs index 97f081d4b1..dd38854755 100644 --- a/src/Essentials/src/Compass/Compass.tizen.cs +++ b/src/Essentials/src/Compass/Compass.tizen.cs @@ -1,3 +1,4 @@ +using Microsoft.Maui.ApplicationModel; using Tizen.Sensor; using TizenCompass = Tizen.Sensor.OrientationSensor; @@ -6,7 +7,7 @@ namespace Microsoft.Maui.Devices.Sensors partial class CompassImplementation : ICompass { static TizenCompass DefaultSensor => - (TizenCompass)Platform.GetDefaultSensor(SensorType.Compass); + (TizenCompass)PlatformUtils.GetDefaultSensor(SensorType.Compass); bool PlatformIsSupported => TizenCompass.IsSupported; diff --git a/src/Essentials/src/Connectivity/Connectivity.tizen.cs b/src/Essentials/src/Connectivity/Connectivity.tizen.cs index 259f6faa80..3994748400 100644 --- a/src/Essentials/src/Connectivity/Connectivity.tizen.cs +++ b/src/Essentials/src/Connectivity/Connectivity.tizen.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Microsoft.Maui.ApplicationModel; using Tizen.Network.Connection; namespace Microsoft.Maui.Networking @@ -37,7 +38,7 @@ namespace Microsoft.Maui.Networking break; } } - Connectivity.OnConnectivityChanged(); + OnConnectivityChanged(); } public NetworkAccess NetworkAccess diff --git a/src/Essentials/src/Contacts/Contacts.tizen.cs b/src/Essentials/src/Contacts/Contacts.tizen.cs index 699c28ee8d..bf33e366ca 100644 --- a/src/Essentials/src/Contacts/Contacts.tizen.cs +++ b/src/Essentials/src/Contacts/Contacts.tizen.cs @@ -11,11 +11,11 @@ using TizenNumber = Tizen.Pims.Contacts.ContactsViews.Number; namespace Microsoft.Maui.ApplicationModel.Communication { - static partial class Contacts + class ContactsImplementation:IContacts { static ContactsManager manager = new ContactsManager(); - static async Task PlatformPickContactAsync() + public async Task PickContactAsync() { Permissions.EnsureDeclared(); Permissions.EnsureDeclared(); @@ -50,7 +50,7 @@ namespace Microsoft.Maui.ApplicationModel.Communication return await tcs.Task; } - static Task> PlatformGetAllAsync(CancellationToken cancellationToken) + public Task> GetAllAsync(CancellationToken cancellationToken) { var contactsList = manager.Database.GetAll(TizenContact.Uri, 0, 0); diff --git a/src/Essentials/src/DeviceDisplay/DeviceDisplay.shared.cs b/src/Essentials/src/DeviceDisplay/DeviceDisplay.shared.cs index 30b104457c..ffaa16bbb4 100644 --- a/src/Essentials/src/DeviceDisplay/DeviceDisplay.shared.cs +++ b/src/Essentials/src/DeviceDisplay/DeviceDisplay.shared.cs @@ -45,7 +45,7 @@ namespace Microsoft.Maui.Devices #if WINDOWS internal const float BaseLogicalDpi = 96.0f; -#elif ANDROID +#elif ANDROID || TIZEN internal const float BaseLogicalDpi = 160.0f; #endif diff --git a/src/Essentials/src/DeviceDisplay/DeviceDisplay.tizen.cs b/src/Essentials/src/DeviceDisplay/DeviceDisplay.tizen.cs index 4dec01f1d5..cda04e217a 100644 --- a/src/Essentials/src/DeviceDisplay/DeviceDisplay.tizen.cs +++ b/src/Essentials/src/DeviceDisplay/DeviceDisplay.tizen.cs @@ -1,6 +1,7 @@ -#nullable enable using System; using System.Runtime.InteropServices; +using Microsoft.Maui.ApplicationModel; +using Tizen.Applications; namespace Microsoft.Maui.Devices { @@ -12,6 +13,13 @@ namespace Microsoft.Maui.Devices [DllImport("libcapi-system-device.so.0", EntryPoint = "device_power_release_lock")] static extern void ReleaseKeepScreenOn(int type = 1); + static CoreUIApplication CoreUIApplication => Application.Current as CoreUIApplication; + static int displayWidth = PlatformUtils.GetFeatureInfo("screen.width"); + static int displayHeight = PlatformUtils.GetFeatureInfo("screen.height"); + static int displayDpi = DeviceInfo.Idiom == DeviceIdiom.TV ? 72 : PlatformUtils.GetFeatureInfo("screen.dpi"); + DisplayOrientation displayOrientation; + DisplayRotation displayRotation = DisplayRotation.Rotation0; + bool keepScreenOn = false; protected override bool GetKeepScreenOn() => keepScreenOn; @@ -27,50 +35,69 @@ namespace Microsoft.Maui.Devices protected override DisplayInfo GetMainDisplayInfo() { - var display = Platform.MainWindow; return new DisplayInfo( - width: display.ScreenSize.Width, - height: display.ScreenSize.Height, - density: display.ScreenDpi.X / (DeviceInfo.Idiom == DeviceIdiom.TV ? 72.0 : 160.0), - orientation: GetOrientation(), - rotation: GetRotation()); - } - - static DisplayOrientation GetOrientation() - { - return Platform.MainWindow.Rotation switch - { - 0 => DisplayOrientation.Portrait, - 90 => DisplayOrientation.Landscape, - 180 => DisplayOrientation.Portrait, - 270 => DisplayOrientation.Landscape, - _ => DisplayOrientation.Unknown, - }; - } - - static DisplayRotation GetRotation() - { - return Platform.MainWindow.Rotation switch - { - 0 => DisplayRotation.Rotation0, - 90 => DisplayRotation.Rotation90, - 180 => DisplayRotation.Rotation180, - 270 => DisplayRotation.Rotation270, - _ => DisplayRotation.Unknown, - }; + width: displayWidth, + height: displayHeight, + density: displayDpi / DeviceDisplay.BaseLogicalDpi, + orientation: GetNaturalDisplayOrientation(), + rotation: displayRotation + ); } protected override void StartScreenMetricsListeners() { - Platform.MainWindow.RotationChanged += OnRotationChanged; + if (CoreUIApplication != null) + { + CoreUIApplication.DeviceOrientationChanged += OnRotationChanged; + } } protected override void StopScreenMetricsListeners() { - Platform.MainWindow.RotationChanged -= OnRotationChanged; + if (CoreUIApplication != null) + { + CoreUIApplication.DeviceOrientationChanged -= OnRotationChanged; + } } - void OnRotationChanged(object s, EventArgs e) => + DisplayOrientation GetNaturalDisplayOrientation() + { + if (displayHeight >= displayWidth) + { + return DisplayOrientation.Portrait; + } + else + { + return DisplayOrientation.Landscape; + } + } + + void OnRotationChanged(object s, DeviceOrientationEventArgs e) + { + switch (e.DeviceOrientation) + { + case DeviceOrientation.Orientation_0: + displayRotation = DisplayRotation.Rotation0; + displayOrientation = GetNaturalDisplayOrientation(); + break; + case DeviceOrientation.Orientation_90: + displayRotation = DisplayRotation.Rotation90; + displayOrientation = GetNaturalDisplayOrientation() == DisplayOrientation.Portrait ? DisplayOrientation.Landscape : DisplayOrientation.Portrait; + break; + case DeviceOrientation.Orientation_180: + displayRotation = DisplayRotation.Rotation180; + displayOrientation = GetNaturalDisplayOrientation(); + break; + case DeviceOrientation.Orientation_270: + displayRotation = DisplayRotation.Rotation270; + displayOrientation = GetNaturalDisplayOrientation() == DisplayOrientation.Portrait ? DisplayOrientation.Landscape : DisplayOrientation.Portrait; + break; + default: + displayRotation = DisplayRotation.Unknown; + displayOrientation = DisplayOrientation.Unknown; + break; + } OnMainDisplayInfoChanged(); + } } } diff --git a/src/Essentials/src/DeviceInfo/DeviceInfo.tizen.cs b/src/Essentials/src/DeviceInfo/DeviceInfo.tizen.cs index 79e9e8eb8d..d96c927e6d 100644 --- a/src/Essentials/src/DeviceInfo/DeviceInfo.tizen.cs +++ b/src/Essentials/src/DeviceInfo/DeviceInfo.tizen.cs @@ -1,29 +1,27 @@ +using System; +using Microsoft.Maui.ApplicationModel; + namespace Microsoft.Maui.Devices { class DeviceInfoImplementation : IDeviceInfo { - public string Model - => Platform.GetSystemInfo("model_name"); + public string Model => PlatformUtils.GetSystemInfo("model_name"); - public string Manufacturer - => Platform.GetSystemInfo("manufacturer"); + public string Manufacturer => PlatformUtils.GetSystemInfo("manufacturer"); - public string Name - => Platform.GetSystemInfo("device_name"); + public string Name => PlatformUtils.GetSystemInfo("device_name"); - public string VersionString - => Platform.GetFeatureInfo("platform.version"); + public string VersionString => PlatformUtils.GetFeatureInfo("platform.version"); public Version Version => Utils.ParseVersion(VersionString); - public DevicePlatform Platform - => DevicePlatform.Tizen; + public DevicePlatform Platform => DevicePlatform.Tizen; public DeviceIdiom Idiom { get { - var profile = Plat.GetFeatureInfo("profile")?.ToUpperInvariant(); + var profile = PlatformUtils.GetFeatureInfo("profile")?.ToUpperInvariant(); if (profile == null) return DeviceIdiom.Unknown; @@ -43,13 +41,13 @@ namespace Microsoft.Maui.Devices { get { - var arch = Platform.GetFeatureInfo("platform.core.cpu.arch"); - var armv7 = Platform.GetFeatureInfo("platform.core.cpu.arch.armv7"); - var x86 = Platform.GetFeatureInfo("platform.core.cpu.arch.x86"); + var arch = PlatformUtils.GetFeatureInfo("platform.core.cpu.arch"); + var armv7 = PlatformUtils.GetFeatureInfo("platform.core.cpu.arch.armv7"); + var x86 = PlatformUtils.GetFeatureInfo("platform.core.cpu.arch.x86"); - if (arch != null && arch.Equals("armv7") && armv7 && !x86) + if (arch != null && arch.Equals("armv7", StringComparison.Ordinal) && armv7 && !x86) return DeviceType.Physical; - else if (arch != null && arch.Equals("x86") && !armv7 && x86) + else if (arch != null && arch.Equals("x86", StringComparison.Ordinal) && !armv7 && x86) return DeviceType.Virtual; else return DeviceType.Unknown; diff --git a/src/Essentials/src/Email/Email.tizen.cs b/src/Essentials/src/Email/Email.tizen.cs index a28815452f..0b0bb9763d 100644 --- a/src/Essentials/src/Email/Email.tizen.cs +++ b/src/Essentials/src/Email/Email.tizen.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Threading.Tasks; +using Microsoft.Maui.ApplicationModel; using Tizen.Applications; namespace Microsoft.Maui.ApplicationModel.Communication @@ -7,7 +8,7 @@ namespace Microsoft.Maui.ApplicationModel.Communication partial class EmailImplementation : IEmail { public bool IsComposeSupported - => Platform.GetFeatureInfo("email"); + => PlatformUtils.GetFeatureInfo("email"); Task PlatformComposeAsync(EmailMessage message) { @@ -19,20 +20,32 @@ namespace Microsoft.Maui.ApplicationModel.Communication Uri = "mailto:", }; - if (message.Bcc.Count > 0) + if (message.Bcc?.Count > 0) appControl.ExtraData.Add(AppControlData.Bcc, message.Bcc); if (!string.IsNullOrEmpty(message.Body)) appControl.ExtraData.Add(AppControlData.Text, message.Body); - if (message.Cc.Count > 0) + if (message.Cc?.Count > 0) appControl.ExtraData.Add(AppControlData.Cc, message.Cc); if (!string.IsNullOrEmpty(message.Subject)) appControl.ExtraData.Add(AppControlData.Subject, message.Subject); - if (message.To.Count > 0) + if (message.To?.Count > 0) appControl.ExtraData.Add(AppControlData.To, message.To); AppControl.SendLaunchRequest(appControl); return Task.CompletedTask; } + + public Task ComposeAsync(string subject, string body, params string[] to) + => ComposeAsync( + new EmailMessage + { + Subject = subject, + Body = body, + To = to.ToList() + }); + + public Task ComposeAsync() + => ComposeAsync(null); } } diff --git a/src/Essentials/src/Essentials.csproj b/src/Essentials/src/Essentials.csproj index 3855a2ceef..95f21dc367 100644 --- a/src/Essentials/src/Essentials.csproj +++ b/src/Essentials/src/Essentials.csproj @@ -1,4 +1,4 @@ - + netstandard2.1;netstandard2.0;$(_MauiDotNetTfm);$(MauiPlatforms) Microsoft.Maui.Essentials @@ -61,11 +61,10 @@ --> - + + Exe MauiApp._1 true @@ -26,6 +28,7 @@ 21.0 10.0.17763.0 10.0.17763.0 + 6.5 diff --git a/src/Templates/src/templates/maui-blazor/Platforms/Tizen/Main.cs b/src/Templates/src/templates/maui-blazor/Platforms/Tizen/Main.cs new file mode 100644 index 0000000000..98ac2ef82a --- /dev/null +++ b/src/Templates/src/templates/maui-blazor/Platforms/Tizen/Main.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.Maui; +using Microsoft.Maui.Hosting; + +namespace MauiApp._1; + +class Program : MauiApplication +{ + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } +} diff --git a/src/Templates/src/templates/maui-blazor/Platforms/Tizen/tizen-manifest.xml b/src/Templates/src/templates/maui-blazor/Platforms/Tizen/tizen-manifest.xml new file mode 100644 index 0000000000..58f91fae47 --- /dev/null +++ b/src/Templates/src/templates/maui-blazor/Platforms/Tizen/tizen-manifest.xml @@ -0,0 +1,15 @@ + + + + + + appicon.xhigh.png + + + + + http://tizen.org/privilege/internet + + + + \ No newline at end of file diff --git a/src/Templates/src/templates/maui-contentpage-csharp/.template.config/template.json b/src/Templates/src/templates/maui-contentpage-csharp/.template.config/template.json index 34147264cf..0485fe0294 100644 --- a/src/Templates/src/templates/maui-contentpage-csharp/.template.config/template.json +++ b/src/Templates/src/templates/maui-contentpage-csharp/.template.config/template.json @@ -1,7 +1,7 @@ { "$schema": "http://json.schemastore.org/template", "author": "Microsoft", - "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Xaml", "Code" ], + "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Tizen", "Xaml", "Code" ], "identity": "Microsoft.Maui.CSharpContentPage", "name": ".NET MAUI ContentPage (C#) (Preview)", "shortName": "maui-page-csharp", diff --git a/src/Templates/src/templates/maui-contentpage-xaml/.template.config/template.json b/src/Templates/src/templates/maui-contentpage-xaml/.template.config/template.json index 24dec31fb1..1948845df2 100644 --- a/src/Templates/src/templates/maui-contentpage-xaml/.template.config/template.json +++ b/src/Templates/src/templates/maui-contentpage-xaml/.template.config/template.json @@ -1,7 +1,7 @@ { "$schema": "http://json.schemastore.org/template", "author": "Microsoft", - "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Xaml", "Code" ], + "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Tizen", "Xaml", "Code" ], "identity": "Microsoft.Maui.XamlContentPage", "name": ".NET MAUI ContentPage (XAML) (Preview)", "shortName": "maui-page-xaml", diff --git a/src/Templates/src/templates/maui-contentview-csharp/.template.config/template.json b/src/Templates/src/templates/maui-contentview-csharp/.template.config/template.json index cdc31e23d9..e5182f7059 100644 --- a/src/Templates/src/templates/maui-contentview-csharp/.template.config/template.json +++ b/src/Templates/src/templates/maui-contentview-csharp/.template.config/template.json @@ -1,7 +1,7 @@ { "$schema": "http://json.schemastore.org/template", "author": "Microsoft", - "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Xaml", "Code" ], + "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Tizen", "Xaml", "Code" ], "identity": "Microsoft.Maui.CSharpContentView", "name": ".NET MAUI ContentView (C#) (Preview)", "shortName": "maui-view-csharp", diff --git a/src/Templates/src/templates/maui-contentview-xaml/.template.config/template.json b/src/Templates/src/templates/maui-contentview-xaml/.template.config/template.json index eddd0216d0..54cbeff5ec 100644 --- a/src/Templates/src/templates/maui-contentview-xaml/.template.config/template.json +++ b/src/Templates/src/templates/maui-contentview-xaml/.template.config/template.json @@ -1,7 +1,7 @@ { "$schema": "http://json.schemastore.org/template", "author": "Microsoft", - "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Xaml", "Code" ], + "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "WinUI", "Tizen", "Xaml", "Code" ], "identity": "Microsoft.Maui.XamlContentView", "name": ".NET MAUI ContentView (XAML) (Preview)", "shortName": "maui-view-xaml", diff --git a/src/Templates/src/templates/maui-lib/.template.config/template.in.json b/src/Templates/src/templates/maui-lib/.template.config/template.in.json index 927891f2ab..3490542ff6 100644 --- a/src/Templates/src/templates/maui-lib/.template.config/template.in.json +++ b/src/Templates/src/templates/maui-lib/.template.config/template.in.json @@ -1,7 +1,7 @@ { "$schema": "http://json.schemastore.org/template", "author": "Microsoft", - "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "Windows" ], + "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "Windows", "Tizen" ], "identity": "Microsoft.Maui.MauiLib", "groupIdentity": "Microsoft.Maui.Library", "name": ".NET MAUI Class Library (Preview)", diff --git a/src/Templates/src/templates/maui-lib/MauiLib1.csproj b/src/Templates/src/templates/maui-lib/MauiLib1.csproj index dfeee41120..a4739cbbd6 100644 --- a/src/Templates/src/templates/maui-lib/MauiLib1.csproj +++ b/src/Templates/src/templates/maui-lib/MauiLib1.csproj @@ -3,6 +3,8 @@ DOTNET_TFM;DOTNET_TFM-android;DOTNET_TFM-ios;DOTNET_TFM-maccatalyst $(TargetFrameworks);DOTNET_TFM-windows10.0.19041.0 + + MauiLib1 true true @@ -13,6 +15,7 @@ 21.0 10.0.17763.0 10.0.17763.0 + 6.5 diff --git a/src/Templates/src/templates/maui-lib/Platforms/Tizen/PlatformClass1.cs b/src/Templates/src/templates/maui-lib/Platforms/Tizen/PlatformClass1.cs new file mode 100644 index 0000000000..82cb63571e --- /dev/null +++ b/src/Templates/src/templates/maui-lib/Platforms/Tizen/PlatformClass1.cs @@ -0,0 +1,9 @@ +using System; + +namespace MauiLib1 +{ + // All the code in this file is only included on Tizen. + public class PlatformClass1 + { + } +} \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.cs.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.cs.json index 58202df9ae..63d3e7cbf7 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.cs.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.cs.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": "Aplikace .NET MAUI (Preview)", - "description": "Projekt pro vytvoření .NET MAUI aplikace pro iOS, Android, Mac Catalyst a WinUI", + "description": "Projekt pro vytvoření .NET MAUI aplikace pro iOS, Android, Mac Catalyst, Tizen a WinUI", "postActions/openInEditor/description": "Otevře soubor MainPage.xaml v editoru.", "symbols/applicationId/description": "Přepíše v projektu $(ApplicationId)." } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.de.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.de.json index 907e2fb5a4..488dd64f67 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.de.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.de.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI-App (Vorschau)", - "description": "Ein Projekt zum Erstellen einer .NET MAUI-Anwendung für iOS, Android, Mac Catalyst und WinUI", + "description": "Ein Projekt zum Erstellen einer .NET MAUI-Anwendung für iOS, Android, Mac Catalyst, Tizen und WinUI", "postActions/openInEditor/description": "Öffnet \"MainPage.xaml\" im Editor.", "symbols/applicationId/description": "Überschreibt $(ApplicationId) im Projekt" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.en.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.en.json index a829721cbd..ece9732b6a 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.en.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.en.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI App (Preview)", - "description": "A project for creating a .NET MAUI application for iOS, Android, Mac Catalyst, and WinUI", + "description": "A project for creating a .NET MAUI application for iOS, Android, Mac Catalyst, Tizen and WinUI", "postActions/openInEditor/description": "Opens MainPage.xaml in the editor.", "symbols/applicationId/description": "Overrides the $(ApplicationId) in the project" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.es.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.es.json index f21b031826..4dbd42091a 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.es.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.es.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": "Aplicación .NET MAUI (versión preliminar)", - "description": "Un proyecto para crear una aplicación .NET MAUI para iOS, Android, Mac Catalyst y WinUI", + "description": "Un proyecto para crear una aplicación .NET MAUI para iOS, Android, Mac Catalyst, Tizen y WinUI", "postActions/openInEditor/description": "Abre MainPage.xaml en el editor.", "symbols/applicationId/description": "Reemplaza $(ApplicationId) en el proyecto" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.fr.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.fr.json index 4138581b1a..ca7f0e392c 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.fr.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.fr.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": "Application .NET MAUI (préversion)", - "description": "Projet de création d’une application .NET MAUI pour iOS, Android, Mac Catalyst et WinUI", + "description": "Projet de création d’une application .NET MAUI pour iOS, Android, Mac Catalyst, Tizen et WinUI", "postActions/openInEditor/description": "Ouvre MainPage.xaml dans l’éditeur.", "symbols/applicationId/description": "Remplace $(ApplicationId) dans le projet" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.it.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.it.json index c7c7a04794..feb4743fa9 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.it.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.it.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": "App .NET MAUI (Anteprima)", - "description": "Progetto per la creazione di un'applicazione .NET MAUI per iOS, Android, Mac Catalyst e WinUI", + "description": "Progetto per la creazione di un'applicazione .NET MAUI per iOS, Android, Mac Catalyst, Tizen e WinUI", "postActions/openInEditor/description": "Apre MainPage.xaml nell'editor.", "symbols/applicationId/description": "Esegue l'override di $(ApplicationId) nel progetto" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ja.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ja.json index decab63ba1..034e56658c 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ja.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ja.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI アプリ (プレビュー)", - "description": "iOS、Android、Mac Catalyst、および WinUI 用の .NET MAUI アプリケーションを作成するためのプロジェクト", + "description": "iOS、Android、Mac Catalyst、Tizen、および WinUI 用の .NET MAUI アプリケーションを作成するためのプロジェクト", "postActions/openInEditor/description": "エディターで MainPage.xaml を開きます。", "symbols/applicationId/description": "プロジェクト内の $(ApplicationId) をオーバーライドします" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.json index a829721cbd..b3db9ef8dc 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI App (Preview)", - "description": "A project for creating a .NET MAUI application for iOS, Android, Mac Catalyst, and WinUI", + "description": "A project for creating a .NET MAUI application for iOS, Android, Mac Catalyst, Tizen, and WinUI", "postActions/openInEditor/description": "Opens MainPage.xaml in the editor.", "symbols/applicationId/description": "Overrides the $(ApplicationId) in the project" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ko.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ko.json index aa6e8bcbf4..35d530a6ed 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ko.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ko.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI 앱(미리 보기)", - "description": "iOS, Android, Mac Catalyst 및 WinUI용 .NET MAUI 애플리케이션을 만들기 위한 프로젝트", + "description": "iOS, Android, Mac Catalyst, Tizen 및 WinUI용 .NET MAUI 애플리케이션을 만들기 위한 프로젝트", "postActions/openInEditor/description": "편집기에서 MainPage.xaml을 엽니다.", "symbols/applicationId/description": "프로젝트에서 $(ApplicationId) 재정의" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pl.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pl.json index 674a4fc8dc..dd7e2c0d8e 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pl.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pl.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": "Aplikacja platformy .NET MAUI (wersja zapoznawcza)", - "description": "Projekt służący do tworzenia aplikacji .NET MAUI dla systemów iOS, Android, Mac Catalyst i WinUI", + "description": "Projekt służący do tworzenia aplikacji .NET MAUI dla systemów iOS, Android, Mac Catalyst, Tizen i WinUI", "postActions/openInEditor/description": "Otwiera plik MainPage.xaml w edytorze.", "symbols/applicationId/description": "Zastępuje $(ApplicationId) w projekcie" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pt-BR.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pt-BR.json index 610b7cf7fa..ae522526f9 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pt-BR.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.pt-BR.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": "Aplicativo .NET MAUI (Versão Prévia)", - "description": "Um projeto para a criação de um aplicativo .NET MAUI para iOS, Android, Mac Catalyst e WinUI", + "description": "Um projeto para a criação de um aplicativo .NET MAUI para iOS, Android, Mac Catalyst, Tizen e WinUI", "postActions/openInEditor/description": "Abre MainPage.xaml no editor.", "symbols/applicationId/description": "Substitui $(ApplicationId) no projeto" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ru.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ru.json index 3a80e5fc82..c8faa9320c 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ru.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.ru.json @@ -1,7 +1,7 @@ { "author": "Майкрософт", "name": "Приложение .NET MAUI (предварительная версия)", - "description": "Проект по созданию приложения .NET MAUI для iOS, Android, Mac Catalyst и WinUI", + "description": "Проект по созданию приложения .NET MAUI для iOS, Android, Mac Catalyst, Tizen и WinUI", "postActions/openInEditor/description": "Открывает MainPage.xaml в редакторе.", "symbols/applicationId/description": "Переопределяет $(ApplicationId) в проекте" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.tr.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.tr.json index de728e8d33..92f06027fd 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.tr.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.tr.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI Uygulaması (Önizleme)", - "description": "iOS, Android, Mac Catalyst .NET MAUI ve WinUI için yeni bir uygulama oluşturmaya yönelik proje", + "description": "iOS, Android, Mac Catalyst, Tizen .NET MAUI ve WinUI için yeni bir uygulama oluşturmaya yönelik proje", "postActions/openInEditor/description": "Düzenleyicide MainPage.xaml dosyasını açar.", "symbols/applicationId/description": "Projedeki $(ApplicationId) uygulamasın geçersiz kılar" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hans.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hans.json index 4a3a79b21c..6d0d050e54 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hans.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hans.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI应用(预览)", - "description": "用于创建适用于 iOS、Android、Mac Catalyst 和 WinUI 的 .NET MAUI 应用程序的项目", + "description": "用于创建适用于 iOS、Android、Mac Catalyst、Tizen 和 WinUI 的 .NET MAUI 应用程序的项目", "postActions/openInEditor/description": "在编辑器中打开 MainPage.xaml。", "symbols/applicationId/description": "替代项目中的 $(ApplicationId)" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hant.json b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hant.json index f79a962155..a6a77a1066 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hant.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/localize/templatestrings.zh-Hant.json @@ -1,7 +1,7 @@ { "author": "Microsoft", "name": ".NET MAUI 應用程式 (預覽)", - "description": "此專案可用於建立適用於 iOS、Android、Mac Catalyst 和 WinUI 的 .NET MAUI 應用程式", + "description": "此專案可用於建立適用於 iOS、Android、Mac Catalyst、Tizen 和 WinUI 的 .NET MAUI 應用程式", "postActions/openInEditor/description": "在編輯器中開啟 MainPage.xaml。", "symbols/applicationId/description": "覆寫專案中的 $(ApplicationId)" } \ No newline at end of file diff --git a/src/Templates/src/templates/maui-mobile/.template.config/template.in.json b/src/Templates/src/templates/maui-mobile/.template.config/template.in.json index 62084950aa..ac3fce8e01 100644 --- a/src/Templates/src/templates/maui-mobile/.template.config/template.in.json +++ b/src/Templates/src/templates/maui-mobile/.template.config/template.in.json @@ -1,11 +1,11 @@ { "$schema": "http://json.schemastore.org/template", "author": "Microsoft", - "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "Windows" ], + "classifications": [ "MAUI", "Android", "iOS", "macOS", "Mac Catalyst", "Windows", "Tizen" ], "identity": "Microsoft.Maui.MauiApp", "groupIdentity": "Microsoft.Maui.App", "name": ".NET MAUI App (Preview)", - "description": "A project for creating a .NET MAUI application for iOS, Android, Mac Catalyst, and WinUI", + "description": "A project for creating a .NET MAUI application for iOS, Android, Mac Catalyst, WinUI and Tizen", "shortName": "maui", "tags": { "language": "C#", diff --git a/src/Templates/src/templates/maui-mobile/MauiApp.1.csproj b/src/Templates/src/templates/maui-mobile/MauiApp.1.csproj index 8968d42fea..7f1b8c112a 100644 --- a/src/Templates/src/templates/maui-mobile/MauiApp.1.csproj +++ b/src/Templates/src/templates/maui-mobile/MauiApp.1.csproj @@ -3,6 +3,8 @@ DOTNET_TFM-android;DOTNET_TFM-ios;DOTNET_TFM-maccatalyst $(TargetFrameworks);DOTNET_TFM-windows10.0.19041.0 + + Exe MauiApp._1 true @@ -25,6 +27,7 @@ 21.0 10.0.17763.0 10.0.17763.0 + 6.5 diff --git a/src/Templates/src/templates/maui-mobile/Platforms/Tizen/Main.cs b/src/Templates/src/templates/maui-mobile/Platforms/Tizen/Main.cs new file mode 100644 index 0000000000..98ac2ef82a --- /dev/null +++ b/src/Templates/src/templates/maui-mobile/Platforms/Tizen/Main.cs @@ -0,0 +1,16 @@ +using System; +using Microsoft.Maui; +using Microsoft.Maui.Hosting; + +namespace MauiApp._1; + +class Program : MauiApplication +{ + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } +} diff --git a/src/Templates/src/templates/maui-mobile/Platforms/Tizen/tizen-manifest.xml b/src/Templates/src/templates/maui-mobile/Platforms/Tizen/tizen-manifest.xml new file mode 100644 index 0000000000..58f91fae47 --- /dev/null +++ b/src/Templates/src/templates/maui-mobile/Platforms/Tizen/tizen-manifest.xml @@ -0,0 +1,15 @@ + + + + + + appicon.xhigh.png + + + + + http://tizen.org/privilege/internet + + + + \ No newline at end of file diff --git a/src/Workload/Microsoft.Maui.Dependencies/Microsoft.Maui.Dependencies.csproj b/src/Workload/Microsoft.Maui.Dependencies/Microsoft.Maui.Dependencies.csproj index 2f88e55e47..2bdb652b09 100644 --- a/src/Workload/Microsoft.Maui.Dependencies/Microsoft.Maui.Dependencies.csproj +++ b/src/Workload/Microsoft.Maui.Dependencies/Microsoft.Maui.Dependencies.csproj @@ -33,5 +33,9 @@ + + + + diff --git a/src/Workload/Microsoft.Maui.Sdk/Sdk/BundledVersions.in.targets b/src/Workload/Microsoft.Maui.Sdk/Sdk/BundledVersions.in.targets index 492b227b23..d26a80d5b3 100644 --- a/src/Workload/Microsoft.Maui.Sdk/Sdk/BundledVersions.in.targets +++ b/src/Workload/Microsoft.Maui.Sdk/Sdk/BundledVersions.in.targets @@ -14,7 +14,7 @@ - <_MauiRuntimeIdentifiers Include="android;ios;maccatalyst;win" /> + <_MauiRuntimeIdentifiers Include="android;ios;maccatalyst;win;tizen" /> + <_TargetPlatform + Condition=" '$(MauiPlatformName)' == 'tizen' " + Include="net$(_MauiDotNetVersion)-tizen$(TizenTargetFrameworkVersion)" + FullTfm="%(Identity)" + Tfm="net$(_MauiDotNetVersion)-tizen" + Profile="Tizen" + /> - <_Platforms Include="any;android;maccatalyst;ios" /> + <_Platforms Include="any;android;maccatalyst;ios;tizen" /> <_Platforms Include="win" Condition="'$(IncludeWindowsTargetFrameworks)' == 'true'" />