2025-12-19 09:30:16 +00:00
|
|
|
// Licensed to the .NET Foundation under one or more agreements.
|
|
|
|
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|
|
|
|
|
|
|
|
|
using SkiaSharp;
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.Maui.Platform;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Shell provides a common navigation experience for MAUI applications.
|
|
|
|
|
/// Supports flyout menu, tabs, and URI-based navigation.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class SkiaShell : SkiaLayoutView
|
|
|
|
|
{
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
#region BindableProperties
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for FlyoutIsPresented.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty FlyoutIsPresentedProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(FlyoutIsPresented),
|
|
|
|
|
typeof(bool),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
false,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.OneWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).OnFlyoutIsPresentedChanged((bool)n));
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for FlyoutBehavior.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty FlyoutBehaviorProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(FlyoutBehavior),
|
|
|
|
|
typeof(ShellFlyoutBehavior),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
ShellFlyoutBehavior.Flyout,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for FlyoutWidth.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty FlyoutWidthProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(FlyoutWidth),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
280f,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
coerceValue: (b, v) => Math.Max(100f, (float)v),
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for FlyoutBackgroundColor.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty FlyoutBackgroundColorProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(FlyoutBackgroundColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
SKColors.White,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for FlyoutTextColor.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty FlyoutTextColorProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(FlyoutTextColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
new SKColor(33, 33, 33),
|
|
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for NavBarBackgroundColor.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty NavBarBackgroundColorProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(NavBarBackgroundColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
new SKColor(33, 150, 243),
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for NavBarTextColor.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty NavBarTextColorProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(NavBarTextColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
SKColors.White,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for NavBarHeight.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty NavBarHeightProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(NavBarHeight),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
56f,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).InvalidateMeasure());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for TabBarHeight.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty TabBarHeightProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(TabBarHeight),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
56f,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).InvalidateMeasure());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for NavBarIsVisible.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty NavBarIsVisibleProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(NavBarIsVisible),
|
|
|
|
|
typeof(bool),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
true,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).InvalidateMeasure());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for TabBarIsVisible.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty TabBarIsVisibleProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(TabBarIsVisible),
|
|
|
|
|
typeof(bool),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
false,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).InvalidateMeasure());
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for ContentPadding.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty ContentPaddingProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(ContentPadding),
|
|
|
|
|
typeof(float),
|
|
|
|
|
typeof(SkiaShell),
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
0f,
|
|
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).InvalidateMeasure());
|
|
|
|
|
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for ContentBackgroundColor.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty ContentBackgroundColorProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(ContentBackgroundColor),
|
|
|
|
|
typeof(SKColor),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
new SKColor(250, 250, 250),
|
|
|
|
|
BindingMode.TwoWay,
|
|
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Bindable property for Title.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static readonly BindableProperty TitleProperty =
|
|
|
|
|
BindableProperty.Create(
|
|
|
|
|
nameof(Title),
|
|
|
|
|
typeof(string),
|
|
|
|
|
typeof(SkiaShell),
|
|
|
|
|
string.Empty,
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
BindingMode.TwoWay,
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
propertyChanged: (b, o, n) => ((SkiaShell)b).Invalidate());
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
private readonly List<ShellSection> _sections = new();
|
|
|
|
|
private SkiaView? _currentContent;
|
|
|
|
|
private float _flyoutAnimationProgress = 0f;
|
|
|
|
|
private int _selectedSectionIndex = 0;
|
|
|
|
|
private int _selectedItemIndex = 0;
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
// Navigation stack for push/pop navigation
|
|
|
|
|
private readonly Stack<(SkiaView Content, string Title)> _navigationStack = new();
|
|
|
|
|
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
private float _flyoutScrollOffset;
|
|
|
|
|
private readonly Dictionary<string, Func<SkiaView?>> _registeredRoutes = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
private readonly Dictionary<string, string> _routeTitles = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
private void OnFlyoutIsPresentedChanged(bool newValue)
|
|
|
|
|
{
|
|
|
|
|
_flyoutAnimationProgress = newValue ? 1f : 0f;
|
|
|
|
|
FlyoutIsPresentedChanged?.Invoke(this, EventArgs.Empty);
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets whether the flyout is presented.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool FlyoutIsPresented
|
|
|
|
|
{
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
get => (bool)GetValue(FlyoutIsPresentedProperty);
|
|
|
|
|
set => SetValue(FlyoutIsPresentedProperty, value);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the flyout behavior.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public ShellFlyoutBehavior FlyoutBehavior
|
|
|
|
|
{
|
|
|
|
|
get => (ShellFlyoutBehavior)GetValue(FlyoutBehaviorProperty);
|
|
|
|
|
set => SetValue(FlyoutBehaviorProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the flyout width.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public float FlyoutWidth
|
|
|
|
|
{
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
get => (float)GetValue(FlyoutWidthProperty);
|
|
|
|
|
set => SetValue(FlyoutWidthProperty, value);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Background color of the flyout.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public SKColor FlyoutBackgroundColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(FlyoutBackgroundColorProperty);
|
|
|
|
|
set => SetValue(FlyoutBackgroundColorProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Text color in the flyout.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public SKColor FlyoutTextColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(FlyoutTextColorProperty);
|
|
|
|
|
set => SetValue(FlyoutTextColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Optional header view in the flyout.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public SkiaView? FlyoutHeaderView { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Height of the flyout header.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public float FlyoutHeaderHeight { get; set; } = 140f;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Optional footer text in the flyout.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string? FlyoutFooterText { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Height of the flyout footer.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public float FlyoutFooterHeight { get; set; } = 40f;
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Background color of the navigation bar.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public SKColor NavBarBackgroundColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(NavBarBackgroundColorProperty);
|
|
|
|
|
set => SetValue(NavBarBackgroundColorProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Text color of the navigation bar title.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public SKColor NavBarTextColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(NavBarTextColorProperty);
|
|
|
|
|
set => SetValue(NavBarTextColorProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Height of the navigation bar.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public float NavBarHeight
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(NavBarHeightProperty);
|
|
|
|
|
set => SetValue(NavBarHeightProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Height of the tab bar (when using bottom tabs).
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public float TabBarHeight
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(TabBarHeightProperty);
|
|
|
|
|
set => SetValue(TabBarHeightProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets whether the navigation bar is visible.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public bool NavBarIsVisible
|
|
|
|
|
{
|
|
|
|
|
get => (bool)GetValue(NavBarIsVisibleProperty);
|
|
|
|
|
set => SetValue(NavBarIsVisibleProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets whether the tab bar is visible.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public bool TabBarIsVisible
|
|
|
|
|
{
|
|
|
|
|
get => (bool)GetValue(TabBarIsVisibleProperty);
|
|
|
|
|
set => SetValue(TabBarIsVisibleProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets or sets the padding applied to page content.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public float ContentPadding
|
|
|
|
|
{
|
|
|
|
|
get => (float)GetValue(ContentPaddingProperty);
|
|
|
|
|
set => SetValue(ContentPaddingProperty, value);
|
|
|
|
|
}
|
2025-12-21 13:26:56 -05:00
|
|
|
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Background color of the content area.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public SKColor ContentBackgroundColor
|
|
|
|
|
{
|
|
|
|
|
get => (SKColor)GetValue(ContentBackgroundColorProperty);
|
|
|
|
|
set => SetValue(ContentBackgroundColorProperty, value);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Current title displayed in the navigation bar.
|
|
|
|
|
/// </summary>
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
public string Title
|
|
|
|
|
{
|
|
|
|
|
get => (string)GetValue(TitleProperty);
|
|
|
|
|
set => SetValue(TitleProperty, value);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The sections in this shell.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IReadOnlyList<ShellSection> Sections => _sections;
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the currently selected section index.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int CurrentSectionIndex => _selectedSectionIndex;
|
|
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Reference to the MAUI Shell this view represents.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Shell? MauiShell { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Callback to render content from a ShellContent.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Func<Microsoft.Maui.Controls.ShellContent, SkiaView?>? ContentRenderer { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Callback to refresh shell colors.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Action<SkiaShell, Shell>? ColorRefresher { get; set; }
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Event raised when FlyoutIsPresented changes.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler? FlyoutIsPresentedChanged;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Event raised when navigation occurs.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<ShellNavigationEventArgs>? Navigated;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds a section to the shell.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void AddSection(ShellSection section)
|
|
|
|
|
{
|
|
|
|
|
_sections.Add(section);
|
|
|
|
|
|
|
|
|
|
if (_sections.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
NavigateToSection(0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Removes a section from the shell.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void RemoveSection(ShellSection section)
|
|
|
|
|
{
|
|
|
|
|
_sections.Remove(section);
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Navigates to a specific section and item.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void NavigateToSection(int sectionIndex, int itemIndex = 0)
|
|
|
|
|
{
|
|
|
|
|
if (sectionIndex < 0 || sectionIndex >= _sections.Count) return;
|
|
|
|
|
|
|
|
|
|
var section = _sections[sectionIndex];
|
|
|
|
|
if (itemIndex < 0 || itemIndex >= section.Items.Count) return;
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
// Clear navigation stack when navigating to a new section
|
|
|
|
|
_navigationStack.Clear();
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
_selectedSectionIndex = sectionIndex;
|
|
|
|
|
_selectedItemIndex = itemIndex;
|
|
|
|
|
|
|
|
|
|
var item = section.Items[itemIndex];
|
|
|
|
|
SetCurrentContent(item.Content);
|
|
|
|
|
Title = item.Title;
|
|
|
|
|
|
|
|
|
|
Navigated?.Invoke(this, new ShellNavigationEventArgs(section, item));
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Refreshes the shell theme and re-renders all pages.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void RefreshTheme()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("[SkiaShell] RefreshTheme called - refreshing all pages");
|
|
|
|
|
if (MauiShell != null && ColorRefresher != null)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("[SkiaShell] Refreshing shell colors");
|
|
|
|
|
ColorRefresher(this, MauiShell);
|
|
|
|
|
}
|
|
|
|
|
if (ContentRenderer != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var section in _sections)
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in section.Items)
|
|
|
|
|
{
|
|
|
|
|
if (item.MauiShellContent != null)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("[SkiaShell] Re-rendering: " + item.Title);
|
|
|
|
|
var skiaView = ContentRenderer(item.MauiShellContent);
|
|
|
|
|
if (skiaView != null)
|
|
|
|
|
{
|
|
|
|
|
item.Content = skiaView;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (_selectedSectionIndex >= 0 && _selectedSectionIndex < _sections.Count)
|
|
|
|
|
{
|
|
|
|
|
var section = _sections[_selectedSectionIndex];
|
|
|
|
|
if (_selectedItemIndex >= 0 && _selectedItemIndex < section.Items.Count)
|
|
|
|
|
{
|
|
|
|
|
var item = section.Items[_selectedItemIndex];
|
|
|
|
|
SetCurrentContent(item.Content);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InvalidateMeasure();
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
/// <summary>
|
|
|
|
|
/// Navigates using a URI route.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void GoToAsync(string route)
|
|
|
|
|
{
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
GoToAsync(route, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Navigates using a URI route with parameters.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void GoToAsync(string route, IDictionary<string, object>? parameters)
|
|
|
|
|
{
|
2025-12-19 09:30:16 +00:00
|
|
|
if (string.IsNullOrEmpty(route)) return;
|
|
|
|
|
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
string routePath = route;
|
|
|
|
|
Dictionary<string, string> queryParams = new Dictionary<string, string>();
|
|
|
|
|
int queryIndex = route.IndexOf('?');
|
|
|
|
|
if (queryIndex >= 0)
|
|
|
|
|
{
|
|
|
|
|
routePath = route.Substring(0, queryIndex);
|
|
|
|
|
queryParams = ParseQueryString(route.Substring(queryIndex + 1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dictionary<string, object> allParams = new Dictionary<string, object>();
|
|
|
|
|
foreach (var kvp in queryParams)
|
|
|
|
|
{
|
|
|
|
|
allParams[kvp.Key] = kvp.Value;
|
|
|
|
|
}
|
|
|
|
|
if (parameters != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var kvp in parameters)
|
|
|
|
|
{
|
|
|
|
|
allParams[kvp.Key] = kvp.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parts = routePath.TrimStart('/').Split('/');
|
2025-12-19 09:30:16 +00:00
|
|
|
if (parts.Length == 0) return;
|
|
|
|
|
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
// Check registered routes first
|
|
|
|
|
if (_registeredRoutes.TryGetValue(routePath.TrimStart('/'), out Func<SkiaView?>? factory))
|
|
|
|
|
{
|
|
|
|
|
var view = factory();
|
|
|
|
|
if (view != null)
|
|
|
|
|
{
|
|
|
|
|
ApplyQueryParameters(view, allParams);
|
|
|
|
|
PushAsync(view, GetRouteTitle(routePath.TrimStart('/')));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
// Find matching section
|
|
|
|
|
for (int i = 0; i < _sections.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var section = _sections[i];
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
if (!section.Route.Equals(parts[0], StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (parts.Length > 1)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
// Find matching item
|
|
|
|
|
for (int j = 0; j < section.Items.Count; j++)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
if (section.Items[j].Route.Equals(parts[1], StringComparison.OrdinalIgnoreCase))
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
NavigateToSection(i, j);
|
|
|
|
|
if (section.Items[j].Content != null && allParams.Count > 0)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
ApplyQueryParameters(section.Items[j].Content!, allParams);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
return;
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
}
|
|
|
|
|
NavigateToSection(i);
|
|
|
|
|
if (section.Items.Count > 0 && section.Items[0].Content != null && allParams.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
ApplyQueryParameters(section.Items[0].Content!, allParams);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Dictionary<string, string> ParseQueryString(string queryString)
|
|
|
|
|
{
|
|
|
|
|
var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
if (string.IsNullOrEmpty(queryString)) return result;
|
|
|
|
|
|
|
|
|
|
var pairs = queryString.Split('&', StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
foreach (var pair in pairs)
|
|
|
|
|
{
|
|
|
|
|
var parts = pair.Split('=', 2);
|
|
|
|
|
if (parts.Length == 2)
|
|
|
|
|
{
|
|
|
|
|
result[Uri.UnescapeDataString(parts[0])] = Uri.UnescapeDataString(parts[1]);
|
|
|
|
|
}
|
|
|
|
|
else if (parts.Length == 1)
|
|
|
|
|
{
|
|
|
|
|
result[Uri.UnescapeDataString(parts[0])] = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void ApplyQueryParameters(SkiaView content, IDictionary<string, object> parameters)
|
|
|
|
|
{
|
|
|
|
|
if (parameters.Count == 0) return;
|
|
|
|
|
|
|
|
|
|
if (content is ISkiaQueryAttributable attributable)
|
|
|
|
|
{
|
|
|
|
|
attributable.ApplyQueryAttributes(parameters);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var type = content.GetType();
|
|
|
|
|
foreach (var param in parameters)
|
|
|
|
|
{
|
|
|
|
|
var prop = type.GetProperty(param.Key, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
|
|
|
|
|
if (prop != null && prop.CanWrite)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var value = Convert.ChangeType(param.Value, prop.PropertyType);
|
|
|
|
|
prop.SetValue(content, value);
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Registers a route with a content factory.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void RegisterRoute(string route, Func<SkiaView?> contentFactory, string? title = null)
|
|
|
|
|
{
|
|
|
|
|
var key = route.TrimStart('/');
|
|
|
|
|
_registeredRoutes[key] = contentFactory;
|
|
|
|
|
if (!string.IsNullOrEmpty(title))
|
|
|
|
|
{
|
|
|
|
|
_routeTitles[key] = title;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Unregisters a route.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void UnregisterRoute(string route)
|
|
|
|
|
{
|
|
|
|
|
var key = route.TrimStart('/');
|
|
|
|
|
_registeredRoutes.Remove(key);
|
|
|
|
|
_routeTitles.Remove(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetRouteTitle(string route)
|
|
|
|
|
{
|
|
|
|
|
if (_routeTitles.TryGetValue(route, out string? title))
|
|
|
|
|
{
|
|
|
|
|
return title;
|
|
|
|
|
}
|
|
|
|
|
return route.Split('/').LastOrDefault() ?? route;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
/// <summary>
|
|
|
|
|
/// Gets whether there are pages on the navigation stack.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool CanGoBack => _navigationStack.Count > 0;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the current navigation stack depth.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int NavigationStackDepth => _navigationStack.Count;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Pushes a new page onto the navigation stack.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void PushAsync(SkiaView page, string title)
|
|
|
|
|
{
|
|
|
|
|
// Save current content to stack
|
|
|
|
|
if (_currentContent != null)
|
|
|
|
|
{
|
|
|
|
|
_navigationStack.Push((_currentContent, Title));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set new content
|
|
|
|
|
SetCurrentContent(page);
|
|
|
|
|
Title = title;
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Pops the current page from the navigation stack.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool PopAsync()
|
|
|
|
|
{
|
|
|
|
|
if (_navigationStack.Count == 0) return false;
|
|
|
|
|
|
|
|
|
|
var (previousContent, previousTitle) = _navigationStack.Pop();
|
|
|
|
|
SetCurrentContent(previousContent);
|
|
|
|
|
Title = previousTitle;
|
|
|
|
|
Invalidate();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Pops all pages from the navigation stack, returning to the root.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void PopToRootAsync()
|
|
|
|
|
{
|
|
|
|
|
if (_navigationStack.Count == 0) return;
|
|
|
|
|
|
|
|
|
|
// Get the root content
|
|
|
|
|
(SkiaView Content, string Title) root = default;
|
|
|
|
|
while (_navigationStack.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
root = _navigationStack.Pop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetCurrentContent(root.Content);
|
|
|
|
|
Title = root.Title;
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 09:30:16 +00:00
|
|
|
private void SetCurrentContent(SkiaView? content)
|
|
|
|
|
{
|
|
|
|
|
if (_currentContent != null)
|
|
|
|
|
{
|
|
|
|
|
RemoveChild(_currentContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_currentContent = content;
|
|
|
|
|
|
|
|
|
|
if (_currentContent != null)
|
|
|
|
|
{
|
|
|
|
|
AddChild(_currentContent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override SKSize MeasureOverride(SKSize availableSize)
|
|
|
|
|
{
|
2025-12-27 11:20:27 -05:00
|
|
|
// Measure current content with padding accounted for (consistent with ArrangeOverride)
|
2025-12-19 09:30:16 +00:00
|
|
|
if (_currentContent != null)
|
|
|
|
|
{
|
|
|
|
|
float contentTop = NavBarIsVisible ? NavBarHeight : 0;
|
|
|
|
|
float contentBottom = TabBarIsVisible ? TabBarHeight : 0;
|
|
|
|
|
var contentSize = new SKSize(
|
2025-12-27 11:20:27 -05:00
|
|
|
availableSize.Width - (float)Padding.Left - (float)Padding.Right,
|
|
|
|
|
availableSize.Height - contentTop - contentBottom - (float)Padding.Top - (float)Padding.Bottom);
|
2025-12-19 09:30:16 +00:00
|
|
|
_currentContent.Measure(contentSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return availableSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override SKRect ArrangeOverride(SKRect bounds)
|
|
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
Console.WriteLine($"[SkiaShell] ArrangeOverride - bounds={bounds}");
|
|
|
|
|
|
|
|
|
|
// Arrange current content with padding
|
2025-12-19 09:30:16 +00:00
|
|
|
if (_currentContent != null)
|
|
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
float contentTop = bounds.Top + (NavBarIsVisible ? NavBarHeight : 0) + ContentPadding;
|
|
|
|
|
float contentBottom = bounds.Bottom - (TabBarIsVisible ? TabBarHeight : 0) - ContentPadding;
|
2025-12-19 09:30:16 +00:00
|
|
|
var contentBounds = new SKRect(
|
2025-12-21 13:26:56 -05:00
|
|
|
bounds.Left + ContentPadding,
|
2025-12-19 09:30:16 +00:00
|
|
|
contentTop,
|
2025-12-21 13:26:56 -05:00
|
|
|
bounds.Right - ContentPadding,
|
2025-12-19 09:30:16 +00:00
|
|
|
contentBottom);
|
2025-12-21 13:26:56 -05:00
|
|
|
Console.WriteLine($"[SkiaShell] Arranging content with bounds={contentBounds}, padding={ContentPadding}");
|
2025-12-19 09:30:16 +00:00
|
|
|
_currentContent.Arrange(contentBounds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bounds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnDraw(SKCanvas canvas, SKRect bounds)
|
|
|
|
|
{
|
|
|
|
|
canvas.Save();
|
|
|
|
|
canvas.ClipRect(bounds);
|
|
|
|
|
|
|
|
|
|
// Draw content
|
|
|
|
|
_currentContent?.Draw(canvas);
|
|
|
|
|
|
|
|
|
|
// Draw navigation bar
|
|
|
|
|
if (NavBarIsVisible)
|
|
|
|
|
{
|
|
|
|
|
DrawNavBar(canvas, bounds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw tab bar
|
|
|
|
|
if (TabBarIsVisible)
|
|
|
|
|
{
|
|
|
|
|
DrawTabBar(canvas, bounds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw flyout overlay and panel
|
|
|
|
|
if (_flyoutAnimationProgress > 0)
|
|
|
|
|
{
|
|
|
|
|
DrawFlyout(canvas, bounds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
canvas.Restore();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawNavBar(SKCanvas canvas, SKRect bounds)
|
|
|
|
|
{
|
|
|
|
|
var navBarBounds = new SKRect(
|
|
|
|
|
bounds.Left,
|
|
|
|
|
bounds.Top,
|
|
|
|
|
bounds.Right,
|
|
|
|
|
bounds.Top + NavBarHeight);
|
|
|
|
|
|
|
|
|
|
// Draw background
|
|
|
|
|
using var bgPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = NavBarBackgroundColor,
|
|
|
|
|
Style = SKPaintStyle.Fill,
|
|
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
|
|
|
|
canvas.DrawRect(navBarBounds, bgPaint);
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
// Draw nav icon (back arrow if can go back, else hamburger menu if flyout enabled)
|
|
|
|
|
using var iconPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = NavBarTextColor,
|
|
|
|
|
Style = SKPaintStyle.Stroke,
|
|
|
|
|
StrokeWidth = 2,
|
|
|
|
|
StrokeCap = SKStrokeCap.Round,
|
|
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
float iconLeft = navBarBounds.Left + 16;
|
|
|
|
|
float iconCenter = navBarBounds.MidY;
|
|
|
|
|
|
|
|
|
|
if (CanGoBack)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
// Draw iOS-style back chevron "<"
|
|
|
|
|
using var chevronPaint = new SKPaint
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
|
|
|
|
Color = NavBarTextColor,
|
|
|
|
|
Style = SKPaintStyle.Stroke,
|
2025-12-21 13:26:56 -05:00
|
|
|
StrokeWidth = 2.5f,
|
|
|
|
|
StrokeCap = SKStrokeCap.Round,
|
|
|
|
|
StrokeJoin = SKStrokeJoin.Round,
|
2025-12-19 09:30:16 +00:00
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
// Clean chevron pointing left
|
|
|
|
|
float chevronX = iconLeft + 6;
|
|
|
|
|
float chevronSize = 10;
|
|
|
|
|
canvas.DrawLine(chevronX + chevronSize, iconCenter - chevronSize, chevronX, iconCenter, chevronPaint);
|
|
|
|
|
canvas.DrawLine(chevronX, iconCenter, chevronX + chevronSize, iconCenter + chevronSize, chevronPaint);
|
|
|
|
|
}
|
|
|
|
|
else if (FlyoutBehavior == ShellFlyoutBehavior.Flyout)
|
|
|
|
|
{
|
|
|
|
|
// Draw hamburger menu icon
|
2025-12-19 09:30:16 +00:00
|
|
|
canvas.DrawLine(iconLeft, iconCenter - 8, iconLeft + 18, iconCenter - 8, iconPaint);
|
|
|
|
|
canvas.DrawLine(iconLeft, iconCenter, iconLeft + 18, iconCenter, iconPaint);
|
|
|
|
|
canvas.DrawLine(iconLeft, iconCenter + 8, iconLeft + 18, iconCenter + 8, iconPaint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw title
|
|
|
|
|
using var titlePaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = NavBarTextColor,
|
|
|
|
|
TextSize = 20f,
|
|
|
|
|
IsAntialias = true,
|
|
|
|
|
FakeBoldText = true
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
float titleX = (CanGoBack || FlyoutBehavior == ShellFlyoutBehavior.Flyout) ? navBarBounds.Left + 56 : navBarBounds.Left + 16;
|
2025-12-19 09:30:16 +00:00
|
|
|
float titleY = navBarBounds.MidY + 6;
|
|
|
|
|
canvas.DrawText(Title, titleX, titleY, titlePaint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawTabBar(SKCanvas canvas, SKRect bounds)
|
|
|
|
|
{
|
|
|
|
|
if (_selectedSectionIndex < 0 || _selectedSectionIndex >= _sections.Count) return;
|
|
|
|
|
|
|
|
|
|
var section = _sections[_selectedSectionIndex];
|
|
|
|
|
if (section.Items.Count <= 1) return;
|
|
|
|
|
|
|
|
|
|
var tabBarBounds = new SKRect(
|
|
|
|
|
bounds.Left,
|
|
|
|
|
bounds.Bottom - TabBarHeight,
|
|
|
|
|
bounds.Right,
|
|
|
|
|
bounds.Bottom);
|
|
|
|
|
|
|
|
|
|
// Draw background
|
|
|
|
|
using var bgPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = SKColors.White,
|
|
|
|
|
Style = SKPaintStyle.Fill,
|
|
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
|
|
|
|
canvas.DrawRect(tabBarBounds, bgPaint);
|
|
|
|
|
|
|
|
|
|
// Draw top border
|
|
|
|
|
using var borderPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = new SKColor(224, 224, 224),
|
|
|
|
|
Style = SKPaintStyle.Stroke,
|
|
|
|
|
StrokeWidth = 1
|
|
|
|
|
};
|
|
|
|
|
canvas.DrawLine(tabBarBounds.Left, tabBarBounds.Top, tabBarBounds.Right, tabBarBounds.Top, borderPaint);
|
|
|
|
|
|
|
|
|
|
// Draw tabs
|
|
|
|
|
float tabWidth = tabBarBounds.Width / section.Items.Count;
|
|
|
|
|
|
|
|
|
|
using var textPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
TextSize = 12f,
|
|
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < section.Items.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var item = section.Items[i];
|
|
|
|
|
bool isSelected = i == _selectedItemIndex;
|
|
|
|
|
|
|
|
|
|
textPaint.Color = isSelected ? NavBarBackgroundColor : new SKColor(117, 117, 117);
|
|
|
|
|
|
|
|
|
|
var textBounds = new SKRect();
|
|
|
|
|
textPaint.MeasureText(item.Title, ref textBounds);
|
|
|
|
|
|
|
|
|
|
float textX = tabBarBounds.Left + i * tabWidth + tabWidth / 2 - textBounds.MidX;
|
|
|
|
|
float textY = tabBarBounds.MidY - textBounds.MidY;
|
|
|
|
|
|
|
|
|
|
canvas.DrawText(item.Title, textX, textY, textPaint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawFlyout(SKCanvas canvas, SKRect bounds)
|
|
|
|
|
{
|
|
|
|
|
// Draw scrim
|
|
|
|
|
using var scrimPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = new SKColor(0, 0, 0, (byte)(100 * _flyoutAnimationProgress)),
|
|
|
|
|
Style = SKPaintStyle.Fill
|
|
|
|
|
};
|
|
|
|
|
canvas.DrawRect(bounds, scrimPaint);
|
|
|
|
|
|
|
|
|
|
// Draw flyout panel
|
|
|
|
|
float flyoutX = bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
|
|
|
|
var flyoutBounds = new SKRect(
|
|
|
|
|
flyoutX,
|
|
|
|
|
bounds.Top,
|
|
|
|
|
flyoutX + FlyoutWidth,
|
|
|
|
|
bounds.Bottom);
|
|
|
|
|
|
|
|
|
|
using var flyoutPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = FlyoutBackgroundColor,
|
|
|
|
|
Style = SKPaintStyle.Fill,
|
|
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
|
|
|
|
canvas.DrawRect(flyoutBounds, flyoutPaint);
|
|
|
|
|
|
|
|
|
|
// Draw flyout items
|
|
|
|
|
float itemY = flyoutBounds.Top + 80;
|
|
|
|
|
float itemHeight = 48f;
|
|
|
|
|
|
|
|
|
|
using var itemTextPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
TextSize = 14f,
|
|
|
|
|
IsAntialias = true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < _sections.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var section = _sections[i];
|
|
|
|
|
bool isSelected = i == _selectedSectionIndex;
|
|
|
|
|
|
|
|
|
|
// Draw selection background
|
|
|
|
|
if (isSelected)
|
|
|
|
|
{
|
|
|
|
|
using var selectionPaint = new SKPaint
|
|
|
|
|
{
|
|
|
|
|
Color = new SKColor(33, 150, 243, 30),
|
|
|
|
|
Style = SKPaintStyle.Fill
|
|
|
|
|
};
|
2025-12-21 13:26:56 -05:00
|
|
|
var selectionRect = new SKRect(flyoutBounds.Left, itemY, flyoutBounds.Right, itemY + itemHeight);
|
|
|
|
|
canvas.DrawRect(selectionRect, selectionPaint);
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
itemTextPaint.Color = isSelected ? NavBarBackgroundColor : new SKColor(33, 33, 33);
|
|
|
|
|
canvas.DrawText(section.Title, flyoutBounds.Left + 16, itemY + 30, itemTextPaint);
|
|
|
|
|
|
|
|
|
|
itemY += itemHeight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override SkiaView? HitTest(float x, float y)
|
|
|
|
|
{
|
|
|
|
|
if (!IsVisible || !Bounds.Contains(x, y)) return null;
|
|
|
|
|
|
|
|
|
|
// Check flyout area
|
|
|
|
|
if (_flyoutAnimationProgress > 0)
|
|
|
|
|
{
|
|
|
|
|
float flyoutX = Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
|
|
|
|
var flyoutBounds = new SKRect(flyoutX, Bounds.Top, flyoutX + FlyoutWidth, Bounds.Bottom);
|
|
|
|
|
|
|
|
|
|
if (flyoutBounds.Contains(x, y))
|
|
|
|
|
{
|
|
|
|
|
return this; // Flyout handles its own hits
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Tap on scrim closes flyout
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
if (FlyoutIsPresented)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check nav bar
|
|
|
|
|
if (NavBarIsVisible && y < Bounds.Top + NavBarHeight)
|
|
|
|
|
{
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check tab bar
|
|
|
|
|
if (TabBarIsVisible && y > Bounds.Bottom - TabBarHeight)
|
|
|
|
|
{
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check content
|
|
|
|
|
if (_currentContent != null)
|
|
|
|
|
{
|
|
|
|
|
var hit = _currentContent.HitTest(x, y);
|
|
|
|
|
if (hit != null) return hit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnPointerPressed(PointerEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!IsEnabled) return;
|
|
|
|
|
|
|
|
|
|
// Check flyout tap
|
|
|
|
|
if (_flyoutAnimationProgress > 0)
|
|
|
|
|
{
|
|
|
|
|
float flyoutX = Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
|
|
|
|
var flyoutBounds = new SKRect(flyoutX, Bounds.Top, flyoutX + FlyoutWidth, Bounds.Bottom);
|
|
|
|
|
|
|
|
|
|
if (flyoutBounds.Contains(e.X, e.Y))
|
|
|
|
|
{
|
|
|
|
|
// Check which section was tapped
|
|
|
|
|
float itemY = flyoutBounds.Top + 80;
|
|
|
|
|
float itemHeight = 48f;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < _sections.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (e.Y >= itemY && e.Y < itemY + itemHeight)
|
|
|
|
|
{
|
|
|
|
|
NavigateToSection(i, 0);
|
|
|
|
|
FlyoutIsPresented = false;
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
itemY += itemHeight;
|
|
|
|
|
}
|
|
|
|
|
}
|
RC1: Full XAML support with BindableProperty, VSM, and data binding
Phase 1 - BindableProperty Foundation:
- SkiaLayoutView: Convert Spacing, Padding, ClipToBounds to BindableProperty
- SkiaStackLayout: Convert Orientation to BindableProperty
- SkiaGrid: Convert RowSpacing, ColumnSpacing to BindableProperty
- SkiaCollectionView: Convert all 12 properties to BindableProperty
- SkiaShell: Convert all 12 properties to BindableProperty
Phase 2 - Visual State Manager:
- Add VSM integration to SkiaImageButton pointer handlers
- Support Normal, PointerOver, Pressed, Disabled states
Phase 3-4 - XAML/Data Binding:
- Type converters for SKColor, SKRect, SKSize, SKPoint
- BindingContext propagation through visual tree
- Full handler registration for all MAUI controls
Documentation:
- README: Add styling/binding examples, update roadmap
- Add RC1-ROADMAP.md with implementation details
Version: 1.0.0-rc.1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 09:26:04 -05:00
|
|
|
else if (FlyoutIsPresented)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
|
|
|
|
// Tap on scrim
|
|
|
|
|
FlyoutIsPresented = false;
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-21 13:26:56 -05:00
|
|
|
// Check nav bar icon tap (back button or hamburger menu)
|
|
|
|
|
if (NavBarIsVisible && e.Y < Bounds.Top + NavBarHeight && e.X < 56)
|
2025-12-19 09:30:16 +00:00
|
|
|
{
|
2025-12-21 13:26:56 -05:00
|
|
|
if (CanGoBack)
|
|
|
|
|
{
|
|
|
|
|
// Back button pressed
|
|
|
|
|
PopAsync();
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (FlyoutBehavior == ShellFlyoutBehavior.Flyout)
|
|
|
|
|
{
|
|
|
|
|
// Hamburger menu pressed
|
|
|
|
|
FlyoutIsPresented = !FlyoutIsPresented;
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check tab bar tap
|
|
|
|
|
if (TabBarIsVisible && e.Y > Bounds.Bottom - TabBarHeight)
|
|
|
|
|
{
|
|
|
|
|
if (_selectedSectionIndex >= 0 && _selectedSectionIndex < _sections.Count)
|
|
|
|
|
{
|
|
|
|
|
var section = _sections[_selectedSectionIndex];
|
|
|
|
|
float tabWidth = Bounds.Width / section.Items.Count;
|
|
|
|
|
int tappedIndex = (int)((e.X - Bounds.Left) / tabWidth);
|
|
|
|
|
tappedIndex = Math.Clamp(tappedIndex, 0, section.Items.Count - 1);
|
|
|
|
|
|
|
|
|
|
if (tappedIndex != _selectedItemIndex)
|
|
|
|
|
{
|
|
|
|
|
NavigateToSection(_selectedSectionIndex, tappedIndex);
|
|
|
|
|
}
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
base.OnPointerPressed(e);
|
|
|
|
|
}
|
Fix Views: SkiaEntry, SkiaEditor, SkiaShell, SkiaWebView
- SkiaEntry.cs: TextProperty BindingMode.OneWay (was TwoWay)
- SkiaEditor.cs: All BindingModes corrected (Text=OneWay, others=TwoWay)
- SkiaShell.cs: Added FlyoutTextColor, ContentBackgroundColor properties,
route registration system, query parameter support, OnScroll handler
- SkiaWebView.cs: Full rewrite with X11 embedding, GTK window positioning,
hardware acceleration settings, load-changed callbacks, position tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 14:27:33 -05:00
|
|
|
|
|
|
|
|
public override void OnScroll(ScrollEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (FlyoutIsPresented && _flyoutAnimationProgress > 0)
|
|
|
|
|
{
|
|
|
|
|
float flyoutX = Bounds.Left - FlyoutWidth + (FlyoutWidth * _flyoutAnimationProgress);
|
|
|
|
|
var flyoutBounds = new SKRect(flyoutX, Bounds.Top, flyoutX + FlyoutWidth, Bounds.Bottom);
|
|
|
|
|
|
|
|
|
|
if (flyoutBounds.Contains(e.X, e.Y))
|
|
|
|
|
{
|
|
|
|
|
float headerHeight = FlyoutHeaderView != null ? FlyoutHeaderHeight : 0f;
|
|
|
|
|
float footerHeight = !string.IsNullOrEmpty(FlyoutFooterText) ? FlyoutFooterHeight : 0f;
|
|
|
|
|
float itemHeight = 48f;
|
|
|
|
|
float totalItemsHeight = _sections.Count * itemHeight;
|
|
|
|
|
float viewableHeight = flyoutBounds.Height - headerHeight - footerHeight;
|
|
|
|
|
float maxScroll = Math.Max(0f, totalItemsHeight - viewableHeight);
|
|
|
|
|
|
|
|
|
|
_flyoutScrollOffset -= e.DeltaY * 30f;
|
|
|
|
|
_flyoutScrollOffset = Math.Max(0f, Math.Min(_flyoutScrollOffset, maxScroll));
|
|
|
|
|
Invalidate();
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
base.OnScroll(e);
|
|
|
|
|
}
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Shell flyout behavior options.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public enum ShellFlyoutBehavior
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// No flyout menu.
|
|
|
|
|
/// </summary>
|
|
|
|
|
Disabled,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Flyout slides over content.
|
|
|
|
|
/// </summary>
|
|
|
|
|
Flyout,
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Flyout is always visible (side-by-side layout).
|
|
|
|
|
/// </summary>
|
|
|
|
|
Locked
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents a section in the shell (typically shown in flyout).
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ShellSection
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The route identifier for this section.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Route { get; set; } = string.Empty;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The display title.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Title { get; set; } = string.Empty;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Optional icon path.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string? IconPath { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Items in this section.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<ShellContent> Items { get; } = new();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents content within a shell section.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ShellContent
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The route identifier for this content.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Route { get; set; } = string.Empty;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The display title.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Title { get; set; } = string.Empty;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Optional icon path.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string? IconPath { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The content view.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public SkiaView? Content { get; set; }
|
Major production merge: GTK support, context menus, and dispatcher fixes
Core Infrastructure:
- Add Dispatching folder with LinuxDispatcher, LinuxDispatcherProvider, LinuxDispatcherTimer
- Add Native folder with P/Invoke wrappers (GTK, GLib, GDK, Cairo, WebKit)
- Add GTK host window system with GtkHostWindow and GtkSkiaSurfaceWidget
- Update LinuxApplication with GTK mode, theme handling, and icon support
- Fix duplicate LinuxDispatcher in LinuxMauiContext
Handlers:
- Add GtkWebViewManager and GtkWebViewPlatformView for GTK WebView
- Add FlexLayoutHandler and GestureManager
- Update multiple handlers with ToViewHandler fix and missing mappers
- Add MauiHandlerExtensions with ToViewHandler extension method
Views:
- Add SkiaContextMenu with hover, keyboard, and dark theme support
- Add LinuxDialogService with context menu management
- Add SkiaFlexLayout for flex container support
- Update SkiaShell with RefreshTheme, MauiShell, ContentRenderer
- Update SkiaWebView with SetMainWindow, ProcessGtkEvents
- Update SkiaImage with LoadFromBitmap method
Services:
- Add AppInfoService, ConnectivityService, DeviceDisplayService, DeviceInfoService
- Add GtkHostService, GtkContextMenuService, MauiIconGenerator
Window:
- Add CursorType enum and GtkHostWindow
- Update X11Window with SetIcon, SetCursor methods
Build: SUCCESS (0 errors)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 11:19:58 -05:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Reference to the MAUI ShellContent this represents.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Microsoft.Maui.Controls.ShellContent? MauiShellContent { get; set; }
|
2025-12-19 09:30:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Event args for shell navigation events.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ShellNavigationEventArgs : EventArgs
|
|
|
|
|
{
|
|
|
|
|
public ShellSection Section { get; }
|
|
|
|
|
public ShellContent Content { get; }
|
|
|
|
|
|
|
|
|
|
public ShellNavigationEventArgs(ShellSection section, ShellContent content)
|
|
|
|
|
{
|
|
|
|
|
Section = section;
|
|
|
|
|
Content = content;
|
|
|
|
|
}
|
|
|
|
|
}
|