diff --git a/README.md b/README.md
index a4a9675..21f4b11 100644
--- a/README.md
+++ b/README.md
@@ -134,7 +134,16 @@ sudo dnf install libX11-devel libXrandr-devel libXcursor-devel libXi-devel mesa-
- [API Reference](docs/API.md)
- [Contributing Guide](CONTRIBUTING.md)
-## Sample Application
+## Sample Applications
+
+Full sample applications are available in the [maui-linux-samples](https://github.com/open-maui/maui-linux-samples) repository:
+
+| Sample | Description |
+|--------|-------------|
+| **[TodoApp](https://github.com/open-maui/maui-linux-samples/tree/main/TodoApp)** | Task manager with NavigationPage, XAML data binding, CollectionView |
+| **[ShellDemo](https://github.com/open-maui/maui-linux-samples/tree/main/ShellDemo)** | Control showcase with Shell navigation and flyout menu |
+
+## Quick Example
```csharp
using OpenMaui.Platform.Linux;
diff --git a/samples/ShellDemo/App.cs b/samples/ShellDemo/App.cs
deleted file mode 100644
index 2615a41..0000000
--- a/samples/ShellDemo/App.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-// ShellDemo App - Comprehensive Control Demo
-
-using Microsoft.Maui.Controls;
-
-namespace ShellDemo;
-
-///
-/// Main application class with Shell navigation.
-///
-public class App : Application
-{
- public App()
- {
- MainPage = new AppShell();
- }
-}
-
-///
-/// Shell definition with flyout menu - comprehensive control demo.
-///
-public class AppShell : Shell
-{
- public AppShell()
- {
- FlyoutBehavior = FlyoutBehavior.Flyout;
- Title = "OpenMaui Controls Demo";
-
- // Register routes for push navigation (pages not in flyout)
- Routing.RegisterRoute("detail", typeof(DetailPage));
-
- // Home
- Items.Add(CreateFlyoutItem("Home", typeof(HomePage)));
-
- // Buttons Demo
- Items.Add(CreateFlyoutItem("Buttons", typeof(ButtonsPage)));
-
- // Text Input Demo
- Items.Add(CreateFlyoutItem("Text Input", typeof(TextInputPage)));
-
- // Selection Controls Demo
- Items.Add(CreateFlyoutItem("Selection", typeof(SelectionPage)));
-
- // Pickers Demo
- Items.Add(CreateFlyoutItem("Pickers", typeof(PickersPage)));
-
- // Lists Demo
- Items.Add(CreateFlyoutItem("Lists", typeof(ListsPage)));
-
- // Progress Demo
- Items.Add(CreateFlyoutItem("Progress", typeof(ProgressPage)));
-
- // Grids Demo
- Items.Add(CreateFlyoutItem("Grids", typeof(GridsPage)));
-
- // About
- Items.Add(CreateFlyoutItem("About", typeof(AboutPage)));
- }
-
- private FlyoutItem CreateFlyoutItem(string title, Type pageType)
- {
- // Route is required for Shell.GoToAsync navigation to work
- var route = title.Replace(" ", "");
- return new FlyoutItem
- {
- Title = title,
- Route = route,
- Items =
- {
- new ShellContent
- {
- Title = title,
- Route = route,
- ContentTemplate = new DataTemplate(pageType)
- }
- }
- };
- }
-}
diff --git a/samples/ShellDemo/MauiProgram.cs b/samples/ShellDemo/MauiProgram.cs
deleted file mode 100644
index 0ec2a7e..0000000
--- a/samples/ShellDemo/MauiProgram.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// MauiProgram.cs - Shared MAUI app configuration
-// Works across all platforms (iOS, Android, Windows, Linux)
-
-using Microsoft.Maui.Hosting;
-using Microsoft.Maui.Platform.Linux.Hosting;
-
-namespace ShellDemo;
-
-public static class MauiProgram
-{
- public static MauiApp CreateMauiApp()
- {
- var builder = MauiApp.CreateBuilder();
-
- // Configure the app (shared across all platforms)
- builder.UseMauiApp();
-
- // Add Linux platform support
- // On other platforms, this would be iOS/Android/Windows specific
- builder.UseLinux();
-
- return builder.Build();
- }
-}
diff --git a/samples/ShellDemo/Pages/AboutPage.cs b/samples/ShellDemo/Pages/AboutPage.cs
deleted file mode 100644
index e38d027..0000000
--- a/samples/ShellDemo/Pages/AboutPage.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-// AboutPage - Information about OpenMaui Linux
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class AboutPage : ContentPage
-{
- public AboutPage()
- {
- Title = "About";
-
- Content = new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 20,
- Children =
- {
- new Label
- {
- Text = "OpenMaui Linux",
- FontSize = 32,
- FontAttributes = FontAttributes.Bold,
- TextColor = Color.FromArgb("#1A237E"),
- HorizontalOptions = LayoutOptions.Center
- },
- new Label
- {
- Text = "Version 1.0.0",
- FontSize = 16,
- TextColor = Colors.Gray,
- HorizontalOptions = LayoutOptions.Center
- },
- new BoxView { HeightRequest = 1, Color = Colors.LightGray },
- new Label
- {
- Text = "OpenMaui Linux brings .NET MAUI to Linux desktops using SkiaSharp for rendering. " +
- "It provides a native Linux experience while maintaining compatibility with MAUI's cross-platform API.",
- FontSize = 14,
- LineBreakMode = LineBreakMode.WordWrap
- },
- CreateInfoCard("Platform", "Linux (X11/Wayland)"),
- CreateInfoCard("Rendering", "SkiaSharp"),
- CreateInfoCard("Framework", ".NET MAUI"),
- CreateInfoCard("License", "MIT License"),
- new BoxView { HeightRequest = 1, Color = Colors.LightGray },
- new Label
- {
- Text = "Features",
- FontSize = 20,
- FontAttributes = FontAttributes.Bold
- },
- CreateFeatureItem("Full XAML support with styles and resources"),
- CreateFeatureItem("Shell navigation with flyout menus"),
- CreateFeatureItem("All standard MAUI controls"),
- CreateFeatureItem("Data binding and MVVM"),
- CreateFeatureItem("Keyboard and mouse input"),
- CreateFeatureItem("High DPI support"),
- new BoxView { HeightRequest = 1, Color = Colors.LightGray },
- new Label
- {
- Text = "https://github.com/pablotoledo/OpenMaui-Linux",
- FontSize = 12,
- TextColor = Colors.Blue,
- HorizontalOptions = LayoutOptions.Center
- }
- }
- }
- };
- }
-
- private Frame CreateInfoCard(string label, string value)
- {
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Color.FromArgb("#F5F5F5"),
- HasShadow = false,
- Content = new HorizontalStackLayout
- {
- Children =
- {
- new Label
- {
- Text = label + ":",
- FontAttributes = FontAttributes.Bold,
- WidthRequest = 100
- },
- new Label
- {
- Text = value,
- TextColor = Colors.Gray
- }
- }
- }
- };
- }
-
- private View CreateFeatureItem(string text)
- {
- return new HorizontalStackLayout
- {
- Spacing = 10,
- Children =
- {
- new Label { Text = "✓", TextColor = Color.FromArgb("#4CAF50"), FontSize = 16 },
- new Label { Text = text, FontSize = 14 }
- }
- };
- }
-}
diff --git a/samples/ShellDemo/Pages/ButtonsPage.cs b/samples/ShellDemo/Pages/ButtonsPage.cs
deleted file mode 100644
index 695ae97..0000000
--- a/samples/ShellDemo/Pages/ButtonsPage.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-// ButtonsPage - Comprehensive Button Control Demo
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class ButtonsPage : ContentPage
-{
- private readonly Label _eventLog;
- private int _eventCount = 0;
-
- public ButtonsPage()
- {
- Title = "Buttons Demo";
-
- _eventLog = new Label
- {
- Text = "Events will appear here...",
- FontSize = 11,
- TextColor = Colors.Gray,
- LineBreakMode = LineBreakMode.WordWrap
- };
-
- Content = new Grid
- {
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
- new RowDefinition { Height = new GridLength(120) }
- },
- Children =
- {
- CreateMainContent(),
- CreateEventLogPanel()
- }
- };
-
- Grid.SetRow((View)((Grid)Content).Children[0], 0);
- Grid.SetRow((View)((Grid)Content).Children[1], 1);
- }
-
- private View CreateMainContent()
- {
- return new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 20,
- Children =
- {
- new Label { Text = "Button Styles & Events", FontSize = 24, FontAttributes = FontAttributes.Bold },
-
- // Basic Buttons
- CreateSection("Basic Buttons", CreateBasicButtons()),
-
- // Styled Buttons
- CreateSection("Styled Buttons", CreateStyledButtons()),
-
- // Button States
- CreateSection("Button States", CreateButtonStates()),
-
- // Button with Icons (text simulation)
- CreateSection("Button Variations", CreateButtonVariations())
- }
- }
- };
- }
-
- private View CreateBasicButtons()
- {
- var layout = new VerticalStackLayout { Spacing = 10 };
-
- var defaultBtn = new Button { Text = "Default Button" };
- defaultBtn.Clicked += (s, e) => LogEvent("Default Button clicked");
- defaultBtn.Pressed += (s, e) => LogEvent("Default Button pressed");
- defaultBtn.Released += (s, e) => LogEvent("Default Button released");
-
- var textBtn = new Button { Text = "Text Only", BackgroundColor = Colors.Transparent, TextColor = Colors.Blue };
- textBtn.Clicked += (s, e) => LogEvent("Text Button clicked");
-
- layout.Children.Add(defaultBtn);
- layout.Children.Add(textBtn);
-
- return layout;
- }
-
- private View CreateStyledButtons()
- {
- var layout = new HorizontalStackLayout { Spacing = 10 };
-
- var colors = new[]
- {
- ("#2196F3", "Primary"),
- ("#4CAF50", "Success"),
- ("#FF9800", "Warning"),
- ("#F44336", "Danger"),
- ("#9C27B0", "Purple")
- };
-
- foreach (var (color, name) in colors)
- {
- var btn = new Button
- {
- Text = name,
- BackgroundColor = Color.FromArgb(color),
- TextColor = Colors.White,
- CornerRadius = 5
- };
- btn.Clicked += (s, e) => LogEvent($"{name} button clicked");
- layout.Children.Add(btn);
- }
-
- return layout;
- }
-
- private View CreateButtonStates()
- {
- var layout = new VerticalStackLayout { Spacing = 10 };
-
- var enabledBtn = new Button { Text = "Enabled Button", IsEnabled = true };
- enabledBtn.Clicked += (s, e) => LogEvent("Enabled button clicked");
-
- var disabledBtn = new Button { Text = "Disabled Button", IsEnabled = false };
-
- var toggleBtn = new Button { Text = "Toggle Above Button" };
- toggleBtn.Clicked += (s, e) =>
- {
- disabledBtn.IsEnabled = !disabledBtn.IsEnabled;
- disabledBtn.Text = disabledBtn.IsEnabled ? "Now Enabled!" : "Disabled Button";
- LogEvent($"Toggled button to: {(disabledBtn.IsEnabled ? "Enabled" : "Disabled")}");
- };
-
- layout.Children.Add(enabledBtn);
- layout.Children.Add(disabledBtn);
- layout.Children.Add(toggleBtn);
-
- return layout;
- }
-
- private View CreateButtonVariations()
- {
- var layout = new VerticalStackLayout { Spacing = 10 };
-
- var wideBtn = new Button
- {
- Text = "Wide Button",
- HorizontalOptions = LayoutOptions.Fill,
- BackgroundColor = Color.FromArgb("#673AB7"),
- TextColor = Colors.White
- };
- wideBtn.Clicked += (s, e) => LogEvent("Wide button clicked");
-
- var tallBtn = new Button
- {
- Text = "Tall Button",
- HeightRequest = 60,
- BackgroundColor = Color.FromArgb("#009688"),
- TextColor = Colors.White
- };
- tallBtn.Clicked += (s, e) => LogEvent("Tall button clicked");
-
- var roundBtn = new Button
- {
- Text = "Round",
- WidthRequest = 80,
- HeightRequest = 80,
- CornerRadius = 40,
- BackgroundColor = Color.FromArgb("#E91E63"),
- TextColor = Colors.White
- };
- roundBtn.Clicked += (s, e) => LogEvent("Round button clicked");
-
- layout.Children.Add(wideBtn);
- layout.Children.Add(tallBtn);
- layout.Children.Add(new HorizontalStackLayout { Children = { roundBtn } });
-
- return layout;
- }
-
- private Frame CreateSection(string title, View content)
- {
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Colors.White,
- Content = new VerticalStackLayout
- {
- Spacing = 10,
- Children =
- {
- new Label { Text = title, FontSize = 16, FontAttributes = FontAttributes.Bold },
- content
- }
- }
- };
- }
-
- private View CreateEventLogPanel()
- {
- return new Frame
- {
- BackgroundColor = Color.FromArgb("#F5F5F5"),
- Padding = new Thickness(10),
- CornerRadius = 0,
- Content = new VerticalStackLayout
- {
- Children =
- {
- new Label { Text = "Event Log:", FontSize = 12, FontAttributes = FontAttributes.Bold },
- new ScrollView
- {
- HeightRequest = 80,
- Content = _eventLog
- }
- }
- }
- };
- }
-
- private void LogEvent(string message)
- {
- _eventCount++;
- var timestamp = DateTime.Now.ToString("HH:mm:ss");
- _eventLog.Text = $"[{timestamp}] {_eventCount}. {message}\n{_eventLog.Text}";
- }
-}
diff --git a/samples/ShellDemo/Pages/ControlsPage.cs b/samples/ShellDemo/Pages/ControlsPage.cs
deleted file mode 100644
index 6478bdc..0000000
--- a/samples/ShellDemo/Pages/ControlsPage.cs
+++ /dev/null
@@ -1,203 +0,0 @@
-// ControlsPage - Demonstrates various MAUI controls
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class ControlsPage : ContentPage
-{
- public ControlsPage()
- {
- Title = "Controls";
-
- Content = new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 15,
- Children =
- {
- new Label
- {
- Text = "Control Gallery",
- FontSize = 24,
- FontAttributes = FontAttributes.Bold
- },
-
- // Buttons
- CreateSection("Buttons", new View[]
- {
- CreateButtonRow()
- }),
-
- // CheckBox & Switch
- CreateSection("Selection", new View[]
- {
- CreateCheckBoxRow(),
- CreateSwitchRow()
- }),
-
- // Slider
- CreateSection("Slider", new View[]
- {
- CreateSliderRow()
- }),
-
- // Picker
- CreateSection("Picker", new View[]
- {
- CreatePickerRow()
- }),
-
- // Progress
- CreateSection("Progress", new View[]
- {
- CreateProgressRow()
- })
- }
- }
- };
- }
-
- private Frame CreateSection(string title, View[] content)
- {
- var layout = new VerticalStackLayout { Spacing = 10 };
- layout.Children.Add(new Label
- {
- Text = title,
- FontSize = 18,
- FontAttributes = FontAttributes.Bold
- });
-
- foreach (var view in content)
- {
- layout.Children.Add(view);
- }
-
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Colors.White,
- Content = layout
- };
- }
-
- private View CreateButtonRow()
- {
- var resultLabel = new Label { TextColor = Colors.Gray, FontSize = 12 };
-
- var layout = new VerticalStackLayout { Spacing = 10 };
-
- var buttonRow = new HorizontalStackLayout { Spacing = 10 };
-
- var primaryBtn = new Button { Text = "Primary", BackgroundColor = Color.FromArgb("#2196F3"), TextColor = Colors.White };
- primaryBtn.Clicked += (s, e) => resultLabel.Text = "Primary clicked!";
-
- var successBtn = new Button { Text = "Success", BackgroundColor = Color.FromArgb("#4CAF50"), TextColor = Colors.White };
- successBtn.Clicked += (s, e) => resultLabel.Text = "Success clicked!";
-
- var dangerBtn = new Button { Text = "Danger", BackgroundColor = Color.FromArgb("#F44336"), TextColor = Colors.White };
- dangerBtn.Clicked += (s, e) => resultLabel.Text = "Danger clicked!";
-
- buttonRow.Children.Add(primaryBtn);
- buttonRow.Children.Add(successBtn);
- buttonRow.Children.Add(dangerBtn);
-
- layout.Children.Add(buttonRow);
- layout.Children.Add(resultLabel);
-
- return layout;
- }
-
- private View CreateCheckBoxRow()
- {
- var layout = new HorizontalStackLayout { Spacing = 20 };
-
- var cb1 = new CheckBox { IsChecked = true };
- var cb2 = new CheckBox { IsChecked = false };
-
- layout.Children.Add(cb1);
- layout.Children.Add(new Label { Text = "Option 1", VerticalOptions = LayoutOptions.Center });
- layout.Children.Add(cb2);
- layout.Children.Add(new Label { Text = "Option 2", VerticalOptions = LayoutOptions.Center });
-
- return layout;
- }
-
- private View CreateSwitchRow()
- {
- var label = new Label { Text = "Off", VerticalOptions = LayoutOptions.Center };
- var sw = new Switch { IsToggled = false };
- sw.Toggled += (s, e) => label.Text = e.Value ? "On" : "Off";
-
- return new HorizontalStackLayout
- {
- Spacing = 10,
- Children = { sw, label }
- };
- }
-
- private View CreateSliderRow()
- {
- var label = new Label { Text = "Value: 50" };
- var slider = new Slider { Minimum = 0, Maximum = 100, Value = 50 };
- slider.ValueChanged += (s, e) => label.Text = $"Value: {(int)e.NewValue}";
-
- return new VerticalStackLayout
- {
- Spacing = 5,
- Children = { slider, label }
- };
- }
-
- private View CreatePickerRow()
- {
- var label = new Label { Text = "Selected: (none)", TextColor = Colors.Gray };
- var picker = new Picker { Title = "Select a fruit" };
- picker.Items.Add("Apple");
- picker.Items.Add("Banana");
- picker.Items.Add("Cherry");
- picker.Items.Add("Date");
- picker.Items.Add("Elderberry");
-
- picker.SelectedIndexChanged += (s, e) =>
- {
- if (picker.SelectedIndex >= 0)
- label.Text = $"Selected: {picker.Items[picker.SelectedIndex]}";
- };
-
- return new VerticalStackLayout
- {
- Spacing = 5,
- Children = { picker, label }
- };
- }
-
- private View CreateProgressRow()
- {
- var progress = new ProgressBar { Progress = 0.7 };
- var activity = new ActivityIndicator { IsRunning = true };
-
- return new VerticalStackLayout
- {
- Spacing = 10,
- Children =
- {
- progress,
- new Label { Text = "70% Complete", FontSize = 12, TextColor = Colors.Gray },
- new HorizontalStackLayout
- {
- Spacing = 10,
- Children =
- {
- activity,
- new Label { Text = "Loading...", VerticalOptions = LayoutOptions.Center, TextColor = Colors.Gray }
- }
- }
- }
- };
- }
-}
diff --git a/samples/ShellDemo/Pages/DetailPage.cs b/samples/ShellDemo/Pages/DetailPage.cs
deleted file mode 100644
index 438751b..0000000
--- a/samples/ShellDemo/Pages/DetailPage.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-// DetailPage - Demonstrates push/pop navigation
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-using Microsoft.Maui.Platform.Linux.Hosting;
-
-namespace ShellDemo;
-
-///
-/// A detail page that can be pushed onto the navigation stack.
-///
-public class DetailPage : ContentPage
-{
- private readonly string _itemName;
-
- public DetailPage() : this("Detail Item")
- {
- }
-
- public DetailPage(string itemName)
- {
- _itemName = itemName;
- Title = "Detail Page";
-
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(30),
- Spacing = 20,
- VerticalOptions = LayoutOptions.Center,
- Children =
- {
- new Label
- {
- Text = "Pushed Page",
- FontSize = 28,
- FontAttributes = FontAttributes.Bold,
- HorizontalOptions = LayoutOptions.Center,
- TextColor = Color.FromArgb("#9C27B0")
- },
-
- new Label
- {
- Text = $"You navigated to: {_itemName}",
- FontSize = 16,
- HorizontalOptions = LayoutOptions.Center
- },
-
- new Label
- {
- Text = "This page was pushed onto the navigation stack using Shell.Current.GoToAsync()",
- FontSize = 14,
- TextColor = Colors.Gray,
- HorizontalTextAlignment = TextAlignment.Center,
- LineBreakMode = LineBreakMode.WordWrap
- },
-
- new BoxView
- {
- HeightRequest = 2,
- Color = Color.FromArgb("#E0E0E0"),
- Margin = new Thickness(0, 20)
- },
-
- CreateBackButton(),
-
- new Label
- {
- Text = "Use the back button above or the hardware/gesture back to pop this page",
- FontSize = 12,
- TextColor = Colors.Gray,
- HorizontalTextAlignment = TextAlignment.Center,
- Margin = new Thickness(0, 20, 0, 0)
- }
- }
- };
- }
-
- private Button CreateBackButton()
- {
- var backBtn = new Button
- {
- Text = "Go Back (Pop)",
- BackgroundColor = Color.FromArgb("#9C27B0"),
- TextColor = Colors.White,
- HorizontalOptions = LayoutOptions.Center,
- Padding = new Thickness(30, 10)
- };
-
- backBtn.Clicked += (s, e) =>
- {
- // Pop this page off the navigation stack using LinuxViewRenderer
- Console.WriteLine("[DetailPage] Go Back clicked");
- var success = LinuxViewRenderer.PopPage();
- Console.WriteLine($"[DetailPage] PopPage result: {success}");
- };
-
- return backBtn;
- }
-}
-
-///
-/// Query property for passing data to DetailPage.
-///
-[QueryProperty(nameof(ItemName), "item")]
-public class DetailPageWithQuery : DetailPage
-{
- private string _itemName = "Item";
-
- public string ItemName
- {
- get => _itemName;
- set
- {
- _itemName = value;
- // Update the title when the property is set
- Title = $"Detail: {value}";
- }
- }
-
- public DetailPageWithQuery() : base()
- {
- }
-}
diff --git a/samples/ShellDemo/Pages/GridsPage.cs b/samples/ShellDemo/Pages/GridsPage.cs
deleted file mode 100644
index 09cea44..0000000
--- a/samples/ShellDemo/Pages/GridsPage.cs
+++ /dev/null
@@ -1,594 +0,0 @@
-// GridsPage - Demonstrates Grid layouts with various options
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class GridsPage : ContentPage
-{
- public GridsPage()
- {
- Title = "Grids";
-
- Content = new ScrollView
- {
- Orientation = ScrollOrientation.Both,
- Content = new VerticalStackLayout
- {
- Spacing = 25,
- Children =
- {
- CreateSectionHeader("Basic Grid (2x2)"),
- CreateBasicGrid(),
-
- CreateSectionHeader("Column Definitions"),
- CreateColumnDefinitionsDemo(),
-
- CreateSectionHeader("Row Definitions"),
- CreateRowDefinitionsDemo(),
-
- CreateSectionHeader("Auto Rows (Empty vs Content)"),
- CreateAutoRowsDemo(),
-
- CreateSectionHeader("Star Sizing (Proportional)"),
- CreateStarSizingDemo(),
-
- CreateSectionHeader("Row & Column Spacing"),
- CreateSpacingDemo(),
-
- CreateSectionHeader("Row & Column Span"),
- CreateSpanDemo(),
-
- CreateSectionHeader("Mixed Sizing"),
- CreateMixedSizingDemo(),
-
- CreateSectionHeader("Nested Grids"),
- CreateNestedGridDemo(),
-
- new BoxView { HeightRequest = 20 } // Bottom padding
- }
- }
- };
- }
-
- private Label CreateSectionHeader(string text)
- {
- return new Label
- {
- Text = text,
- FontSize = 18,
- FontAttributes = FontAttributes.Bold,
- TextColor = Color.FromArgb("#2196F3"),
- Margin = new Thickness(0, 10, 0, 5)
- };
- }
-
- private View CreateBasicGrid()
- {
- var grid = new Grid
- {
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- },
- BackgroundColor = Color.FromArgb("#F5F5F5")
- };
-
- var cell1 = CreateCell("Row 0, Col 0", "#E3F2FD");
- var cell2 = CreateCell("Row 0, Col 1", "#E8F5E9");
- var cell3 = CreateCell("Row 1, Col 0", "#FFF3E0");
- var cell4 = CreateCell("Row 1, Col 1", "#FCE4EC");
-
- Grid.SetRow(cell1, 0); Grid.SetColumn(cell1, 0);
- Grid.SetRow(cell2, 0); Grid.SetColumn(cell2, 1);
- Grid.SetRow(cell3, 1); Grid.SetColumn(cell3, 0);
- Grid.SetRow(cell4, 1); Grid.SetColumn(cell4, 1);
-
- grid.Children.Add(cell1);
- grid.Children.Add(cell2);
- grid.Children.Add(cell3);
- grid.Children.Add(cell4);
-
- return CreateDemoContainer(grid, "Equal columns using Star sizing");
- }
-
- private View CreateColumnDefinitionsDemo()
- {
- var stack = new VerticalStackLayout { Spacing = 15 };
-
- // Auto width columns
- var autoGrid = new Grid
- {
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Auto },
- new ColumnDefinition { Width = GridLength.Auto },
- new ColumnDefinition { Width = GridLength.Auto }
- },
- BackgroundColor = Color.FromArgb("#F5F5F5")
- };
-
- var a1 = CreateCell("Auto", "#BBDEFB");
- var a2 = CreateCell("Auto Width", "#C8E6C9");
- var a3 = CreateCell("A", "#FFECB3");
- Grid.SetColumn(a1, 0);
- Grid.SetColumn(a2, 1);
- Grid.SetColumn(a3, 2);
- autoGrid.Children.Add(a1);
- autoGrid.Children.Add(a2);
- autoGrid.Children.Add(a3);
-
- stack.Children.Add(new Label { Text = "Auto: Sizes to content", FontSize = 12, TextColor = Colors.Gray });
- stack.Children.Add(autoGrid);
-
- // Absolute width columns
- var absoluteGrid = new Grid
- {
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = new GridLength(50) },
- new ColumnDefinition { Width = new GridLength(100) },
- new ColumnDefinition { Width = new GridLength(150) }
- },
- BackgroundColor = Color.FromArgb("#F5F5F5")
- };
-
- var b1 = CreateCell("50px", "#BBDEFB");
- var b2 = CreateCell("100px", "#C8E6C9");
- var b3 = CreateCell("150px", "#FFECB3");
- Grid.SetColumn(b1, 0);
- Grid.SetColumn(b2, 1);
- Grid.SetColumn(b3, 2);
- absoluteGrid.Children.Add(b1);
- absoluteGrid.Children.Add(b2);
- absoluteGrid.Children.Add(b3);
-
- stack.Children.Add(new Label { Text = "Absolute: Fixed pixel widths (50, 100, 150)", FontSize = 12, TextColor = Colors.Gray, Margin = new Thickness(0, 10, 0, 0) });
- stack.Children.Add(absoluteGrid);
-
- return stack;
- }
-
- private View CreateRowDefinitionsDemo()
- {
- var grid = new Grid
- {
- WidthRequest = 200,
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(30) },
- new RowDefinition { Height = new GridLength(50) },
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = new GridLength(40) }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star }
- },
- BackgroundColor = Color.FromArgb("#F5F5F5")
- };
-
- var r1 = CreateCell("30px height", "#BBDEFB");
- var r2 = CreateCell("50px height", "#C8E6C9");
- var r3 = CreateCell("Auto height\n(fits content)", "#FFECB3");
- var r4 = CreateCell("40px height", "#F8BBD9");
-
- Grid.SetRow(r1, 0);
- Grid.SetRow(r2, 1);
- Grid.SetRow(r3, 2);
- Grid.SetRow(r4, 3);
-
- grid.Children.Add(r1);
- grid.Children.Add(r2);
- grid.Children.Add(r3);
- grid.Children.Add(r4);
-
- return CreateDemoContainer(grid, "Different row heights: 30px, 50px, Auto, 40px");
- }
-
- private View CreateAutoRowsDemo()
- {
- var stack = new VerticalStackLayout { Spacing = 15 };
-
- // Grid with empty Auto row
- var emptyAutoGrid = new Grid
- {
- WidthRequest = 250,
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(40) },
- new RowDefinition { Height = GridLength.Auto }, // Empty - should collapse
- new RowDefinition { Height = new GridLength(40) }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star }
- },
- BackgroundColor = Color.FromArgb("#E0E0E0")
- };
-
- var r1 = CreateCell("Row 0: 40px", "#BBDEFB");
- // Row 1 is Auto with NO content - should be 0 height
- var r3 = CreateCell("Row 2: 40px", "#C8E6C9");
-
- Grid.SetRow(r1, 0);
- Grid.SetRow(r3, 2); // Skip row 1
-
- emptyAutoGrid.Children.Add(r1);
- emptyAutoGrid.Children.Add(r3);
-
- stack.Children.Add(new Label { Text = "Empty Auto row (Row 1) should collapse to 0 height:", FontSize = 12, TextColor = Colors.Gray });
- stack.Children.Add(emptyAutoGrid);
-
- // Grid with Auto row that has content
- var contentAutoGrid = new Grid
- {
- WidthRequest = 250,
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(40) },
- new RowDefinition { Height = GridLength.Auto }, // Has content
- new RowDefinition { Height = new GridLength(40) }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star }
- },
- BackgroundColor = Color.FromArgb("#E0E0E0")
- };
-
- var c1 = CreateCell("Row 0: 40px", "#BBDEFB");
- var c2 = CreateCell("Row 1: Auto (sized to this content)", "#FFECB3");
- var c3 = CreateCell("Row 2: 40px", "#C8E6C9");
-
- Grid.SetRow(c1, 0);
- Grid.SetRow(c2, 1);
- Grid.SetRow(c3, 2);
-
- contentAutoGrid.Children.Add(c1);
- contentAutoGrid.Children.Add(c2);
- contentAutoGrid.Children.Add(c3);
-
- stack.Children.Add(new Label { Text = "Auto row with content sizes to fit:", FontSize = 12, TextColor = Colors.Gray, Margin = new Thickness(0, 10, 0, 0) });
- stack.Children.Add(contentAutoGrid);
-
- return stack;
- }
-
- private View CreateStarSizingDemo()
- {
- var grid = new Grid
- {
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
- new ColumnDefinition { Width = new GridLength(2, GridUnitType.Star) },
- new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }
- },
- BackgroundColor = Color.FromArgb("#F5F5F5")
- };
-
- var s1 = CreateCell("1*", "#BBDEFB");
- var s2 = CreateCell("2* (double)", "#C8E6C9");
- var s3 = CreateCell("1*", "#FFECB3");
-
- Grid.SetColumn(s1, 0);
- Grid.SetColumn(s2, 1);
- Grid.SetColumn(s3, 2);
-
- grid.Children.Add(s1);
- grid.Children.Add(s2);
- grid.Children.Add(s3);
-
- return CreateDemoContainer(grid, "Star proportions: 1* | 2* | 1* = 25% | 50% | 25%");
- }
-
- private View CreateSpacingDemo()
- {
- var stack = new VerticalStackLayout { Spacing = 15 };
-
- // No spacing
- var noSpacing = new Grid
- {
- RowSpacing = 0,
- ColumnSpacing = 0,
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- }
- };
- AddFourCells(noSpacing);
- stack.Children.Add(new Label { Text = "No spacing (RowSpacing=0, ColumnSpacing=0)", FontSize = 12, TextColor = Colors.Gray });
- stack.Children.Add(noSpacing);
-
- // With spacing
- var withSpacing = new Grid
- {
- RowSpacing = 10,
- ColumnSpacing = 10,
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- }
- };
- AddFourCells(withSpacing);
- stack.Children.Add(new Label { Text = "With spacing (RowSpacing=10, ColumnSpacing=10)", FontSize = 12, TextColor = Colors.Gray, Margin = new Thickness(0, 10, 0, 0) });
- stack.Children.Add(withSpacing);
-
- // Different row/column spacing
- var mixedSpacing = new Grid
- {
- RowSpacing = 5,
- ColumnSpacing = 20,
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- }
- };
- AddFourCells(mixedSpacing);
- stack.Children.Add(new Label { Text = "Mixed spacing (RowSpacing=5, ColumnSpacing=20)", FontSize = 12, TextColor = Colors.Gray, Margin = new Thickness(0, 10, 0, 0) });
- stack.Children.Add(mixedSpacing);
-
- return stack;
- }
-
- private View CreateSpanDemo()
- {
- var grid = new Grid
- {
- RowSpacing = 5,
- ColumnSpacing = 5,
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- }
- };
-
- // Spanning header
- var header = CreateCell("ColumnSpan=3 (Header)", "#1976D2", Colors.White);
- Grid.SetRow(header, 0);
- Grid.SetColumn(header, 0);
- Grid.SetColumnSpan(header, 3);
-
- // Left sidebar spanning 2 rows
- var sidebar = CreateCell("RowSpan=2\n(Sidebar)", "#388E3C", Colors.White);
- Grid.SetRow(sidebar, 1);
- Grid.SetColumn(sidebar, 0);
- Grid.SetRowSpan(sidebar, 2);
-
- // Content cells
- var content1 = CreateCell("Content 1", "#E3F2FD");
- Grid.SetRow(content1, 1);
- Grid.SetColumn(content1, 1);
-
- var content2 = CreateCell("Content 2", "#E8F5E9");
- Grid.SetRow(content2, 1);
- Grid.SetColumn(content2, 2);
-
- var content3 = CreateCell("Content 3", "#FFF3E0");
- Grid.SetRow(content3, 2);
- Grid.SetColumn(content3, 1);
-
- var content4 = CreateCell("Content 4", "#FCE4EC");
- Grid.SetRow(content4, 2);
- Grid.SetColumn(content4, 2);
-
- grid.Children.Add(header);
- grid.Children.Add(sidebar);
- grid.Children.Add(content1);
- grid.Children.Add(content2);
- grid.Children.Add(content3);
- grid.Children.Add(content4);
-
- return CreateDemoContainer(grid, "Header spans 3 columns, Sidebar spans 2 rows");
- }
-
- private View CreateMixedSizingDemo()
- {
- var grid = new Grid
- {
- ColumnSpacing = 5,
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = new GridLength(60) }, // Fixed
- new ColumnDefinition { Width = GridLength.Star }, // Fill
- new ColumnDefinition { Width = GridLength.Auto }, // Auto
- new ColumnDefinition { Width = new GridLength(60) } // Fixed
- },
- BackgroundColor = Color.FromArgb("#F5F5F5")
- };
-
- var c1 = CreateCell("60px", "#BBDEFB");
- var c2 = CreateCell("Star (fills remaining)", "#C8E6C9");
- var c3 = CreateCell("Auto", "#FFECB3");
- var c4 = CreateCell("60px", "#F8BBD9");
-
- Grid.SetColumn(c1, 0);
- Grid.SetColumn(c2, 1);
- Grid.SetColumn(c3, 2);
- Grid.SetColumn(c4, 3);
-
- grid.Children.Add(c1);
- grid.Children.Add(c2);
- grid.Children.Add(c3);
- grid.Children.Add(c4);
-
- return CreateDemoContainer(grid, "Mixed: 60px | Star | Auto | 60px");
- }
-
- private View CreateNestedGridDemo()
- {
- var outerGrid = new Grid
- {
- RowSpacing = 10,
- ColumnSpacing = 10,
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- },
- BackgroundColor = Color.FromArgb("#E0E0E0"),
- Padding = new Thickness(10)
- };
-
- // Nested grid 1
- var innerGrid1 = new Grid
- {
- RowSpacing = 2,
- ColumnSpacing = 2,
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- }
- };
- var i1a = CreateCell("A", "#BBDEFB", null, 8);
- var i1b = CreateCell("B", "#90CAF9", null, 8);
- var i1c = CreateCell("C", "#64B5F6", null, 8);
- var i1d = CreateCell("D", "#42A5F5", null, 8);
- Grid.SetRow(i1a, 0); Grid.SetColumn(i1a, 0);
- Grid.SetRow(i1b, 0); Grid.SetColumn(i1b, 1);
- Grid.SetRow(i1c, 1); Grid.SetColumn(i1c, 0);
- Grid.SetRow(i1d, 1); Grid.SetColumn(i1d, 1);
- innerGrid1.Children.Add(i1a);
- innerGrid1.Children.Add(i1b);
- innerGrid1.Children.Add(i1c);
- innerGrid1.Children.Add(i1d);
-
- // Nested grid 2
- var innerGrid2 = new Grid
- {
- RowSpacing = 2,
- ColumnSpacing = 2,
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = GridLength.Star },
- new ColumnDefinition { Width = GridLength.Star }
- }
- };
- var i2a = CreateCell("1", "#C8E6C9", null, 8);
- var i2b = CreateCell("2", "#A5D6A7", null, 8);
- var i2c = CreateCell("3", "#81C784", null, 8);
- var i2d = CreateCell("4", "#66BB6A", null, 8);
- Grid.SetRow(i2a, 0); Grid.SetColumn(i2a, 0);
- Grid.SetRow(i2b, 0); Grid.SetColumn(i2b, 1);
- Grid.SetRow(i2c, 1); Grid.SetColumn(i2c, 0);
- Grid.SetRow(i2d, 1); Grid.SetColumn(i2d, 1);
- innerGrid2.Children.Add(i2a);
- innerGrid2.Children.Add(i2b);
- innerGrid2.Children.Add(i2c);
- innerGrid2.Children.Add(i2d);
-
- Grid.SetRow(innerGrid1, 0); Grid.SetColumn(innerGrid1, 0);
- Grid.SetRow(innerGrid2, 0); Grid.SetColumn(innerGrid2, 1);
-
- var label1 = new Label { Text = "Outer Grid Row 1", HorizontalOptions = LayoutOptions.Center };
- var label2 = new Label { Text = "Spans both columns", HorizontalOptions = LayoutOptions.Center };
- Grid.SetRow(label1, 1); Grid.SetColumn(label1, 0);
- Grid.SetRow(label2, 1); Grid.SetColumn(label2, 1);
-
- outerGrid.Children.Add(innerGrid1);
- outerGrid.Children.Add(innerGrid2);
- outerGrid.Children.Add(label1);
- outerGrid.Children.Add(label2);
-
- return CreateDemoContainer(outerGrid, "Outer grid contains two nested 2x2 grids");
- }
-
- private Border CreateCell(string text, string bgColor, Color? textColor = null, float fontSize = 12)
- {
- return new Border
- {
- BackgroundColor = Color.FromArgb(bgColor),
- Padding = new Thickness(10, 8),
- StrokeThickness = 0,
- Content = new Label
- {
- Text = text,
- FontSize = fontSize,
- TextColor = textColor ?? Colors.Black,
- HorizontalTextAlignment = TextAlignment.Center,
- VerticalTextAlignment = TextAlignment.Center
- }
- };
- }
-
- private void AddFourCells(Grid grid)
- {
- var c1 = CreateCell("0,0", "#BBDEFB");
- var c2 = CreateCell("0,1", "#C8E6C9");
- var c3 = CreateCell("1,0", "#FFECB3");
- var c4 = CreateCell("1,1", "#F8BBD9");
-
- Grid.SetRow(c1, 0); Grid.SetColumn(c1, 0);
- Grid.SetRow(c2, 0); Grid.SetColumn(c2, 1);
- Grid.SetRow(c3, 1); Grid.SetColumn(c3, 0);
- Grid.SetRow(c4, 1); Grid.SetColumn(c4, 1);
-
- grid.Children.Add(c1);
- grid.Children.Add(c2);
- grid.Children.Add(c3);
- grid.Children.Add(c4);
- }
-
- private View CreateDemoContainer(View content, string description)
- {
- return new VerticalStackLayout
- {
- Spacing = 5,
- Children =
- {
- new Label { Text = description, FontSize = 12, TextColor = Colors.Gray },
- content
- }
- };
- }
-}
diff --git a/samples/ShellDemo/Pages/HomePage.cs b/samples/ShellDemo/Pages/HomePage.cs
deleted file mode 100644
index 9a39e63..0000000
--- a/samples/ShellDemo/Pages/HomePage.cs
+++ /dev/null
@@ -1,265 +0,0 @@
-// HomePage - Welcome page for the demo
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-using Microsoft.Maui.Platform.Linux.Hosting;
-
-namespace ShellDemo;
-
-public class HomePage : ContentPage
-{
- public HomePage()
- {
- Title = "Home";
-
- Content = new ScrollView
- {
- Orientation = ScrollOrientation.Both, // Enable horizontal scrolling when window is too narrow
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(30),
- Spacing = 20,
- Children =
- {
- new Label
- {
- Text = "OpenMaui Linux",
- FontSize = 32,
- FontAttributes = FontAttributes.Bold,
- HorizontalOptions = LayoutOptions.Center,
- TextColor = Color.FromArgb("#2196F3")
- },
-
- new Label
- {
- Text = "Controls Demo",
- FontSize = 20,
- HorizontalOptions = LayoutOptions.Center,
- TextColor = Colors.Gray
- },
-
- new BoxView
- {
- HeightRequest = 2,
- Color = Color.FromArgb("#E0E0E0"),
- Margin = new Thickness(0, 10)
- },
-
- new Label
- {
- Text = "Welcome to the comprehensive controls demonstration for OpenMaui Linux. " +
- "This app showcases all the major UI controls available in the framework.",
- FontSize = 14,
- LineBreakMode = LineBreakMode.WordWrap,
- HorizontalTextAlignment = TextAlignment.Center
- },
-
- CreateFeatureSection(),
-
- new Label
- {
- Text = "Use the flyout menu (swipe from left or tap the hamburger icon) to navigate between different control demos.",
- FontSize = 12,
- TextColor = Colors.Gray,
- LineBreakMode = LineBreakMode.WordWrap,
- HorizontalTextAlignment = TextAlignment.Center,
- Margin = new Thickness(0, 20, 0, 0)
- },
-
- CreateQuickLinksSection(),
-
- CreateNavigationDemoSection()
- }
- }
- };
- }
-
- private View CreateFeatureSection()
- {
- var grid = new Grid
- {
- ColumnDefinitions =
- {
- new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
- new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }
- },
- RowDefinitions =
- {
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto },
- new RowDefinition { Height = GridLength.Auto }
- },
- ColumnSpacing = 15,
- RowSpacing = 15,
- Margin = new Thickness(0, 20)
- };
-
- var features = new[]
- {
- ("Buttons", "Various button styles and events"),
- ("Text Input", "Entry, Editor, SearchBar"),
- ("Selection", "CheckBox, Switch, Slider"),
- ("Pickers", "Picker, DatePicker, TimePicker"),
- ("Lists", "CollectionView with selection"),
- ("Progress", "ProgressBar, ActivityIndicator")
- };
-
- for (int i = 0; i < features.Length; i++)
- {
- var (title, desc) = features[i];
- var card = CreateFeatureCard(title, desc);
- Grid.SetRow(card, i / 2);
- Grid.SetColumn(card, i % 2);
- grid.Children.Add(card);
- }
-
- return grid;
- }
-
- private Frame CreateFeatureCard(string title, string description)
- {
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Colors.White,
- HasShadow = true,
- Content = new VerticalStackLayout
- {
- Spacing = 5,
- Children =
- {
- new Label
- {
- Text = title,
- FontSize = 14,
- FontAttributes = FontAttributes.Bold,
- TextColor = Color.FromArgb("#2196F3")
- },
- new Label
- {
- Text = description,
- FontSize = 11,
- TextColor = Colors.Gray,
- LineBreakMode = LineBreakMode.WordWrap
- }
- }
- }
- };
- }
-
- private View CreateQuickLinksSection()
- {
- var layout = new VerticalStackLayout
- {
- Spacing = 10,
- Margin = new Thickness(0, 20, 0, 0)
- };
-
- layout.Children.Add(new Label
- {
- Text = "Quick Actions",
- FontSize = 16,
- FontAttributes = FontAttributes.Bold,
- HorizontalOptions = LayoutOptions.Center
- });
-
- var buttonRow = new HorizontalStackLayout
- {
- Spacing = 10,
- HorizontalOptions = LayoutOptions.Center
- };
-
- var buttonsBtn = new Button
- {
- Text = "Try Buttons",
- BackgroundColor = Color.FromArgb("#2196F3"),
- TextColor = Colors.White
- };
- buttonsBtn.Clicked += (s, e) => LinuxViewRenderer.NavigateToRoute("Buttons");
-
- var listsBtn = new Button
- {
- Text = "Try Lists",
- BackgroundColor = Color.FromArgb("#4CAF50"),
- TextColor = Colors.White
- };
- listsBtn.Clicked += (s, e) => LinuxViewRenderer.NavigateToRoute("Lists");
-
- buttonRow.Children.Add(buttonsBtn);
- buttonRow.Children.Add(listsBtn);
- layout.Children.Add(buttonRow);
-
- return layout;
- }
-
- private View CreateNavigationDemoSection()
- {
- var frame = new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(20),
- BackgroundColor = Color.FromArgb("#F3E5F5"),
- Margin = new Thickness(0, 20, 0, 0),
- Content = new VerticalStackLayout
- {
- Spacing = 15,
- Children =
- {
- new Label
- {
- Text = "Navigation Stack Demo",
- FontSize = 18,
- FontAttributes = FontAttributes.Bold,
- TextColor = Color.FromArgb("#9C27B0"),
- HorizontalOptions = LayoutOptions.Center
- },
-
- new Label
- {
- Text = "Demonstrate push/pop navigation using Shell.GoToAsync()",
- FontSize = 12,
- TextColor = Colors.Gray,
- HorizontalTextAlignment = TextAlignment.Center
- },
-
- CreatePushButton("Push Detail Page", "detail"),
-
- new Label
- {
- Text = "Click the button to push a new page onto the navigation stack. " +
- "Use the back button or 'Go Back' to pop it off.",
- FontSize = 11,
- TextColor = Colors.Gray,
- HorizontalTextAlignment = TextAlignment.Center,
- LineBreakMode = LineBreakMode.WordWrap
- }
- }
- }
- };
-
- return frame;
- }
-
- private Button CreatePushButton(string text, string route)
- {
- var btn = new Button
- {
- Text = text,
- BackgroundColor = Color.FromArgb("#9C27B0"),
- TextColor = Colors.White,
- HorizontalOptions = LayoutOptions.Center,
- Padding = new Thickness(30, 10)
- };
-
- btn.Clicked += (s, e) =>
- {
- Console.WriteLine($"[HomePage] Push button clicked, navigating to {route}");
- // Use LinuxViewRenderer.PushPage for Skia-based navigation
- var success = LinuxViewRenderer.PushPage(new DetailPage());
- Console.WriteLine($"[HomePage] PushPage result: {success}");
- };
-
- return btn;
- }
-}
diff --git a/samples/ShellDemo/Pages/ListsPage.cs b/samples/ShellDemo/Pages/ListsPage.cs
deleted file mode 100644
index 1d93a67..0000000
--- a/samples/ShellDemo/Pages/ListsPage.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-// ListsPage - CollectionView and ListView Demo
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class ListsPage : ContentPage
-{
- private readonly Label _eventLog;
- private int _eventCount = 0;
-
- public ListsPage()
- {
- Title = "Lists";
-
- _eventLog = new Label
- {
- Text = "Events will appear here...",
- FontSize = 11,
- TextColor = Colors.Gray,
- LineBreakMode = LineBreakMode.WordWrap
- };
-
- Content = new Grid
- {
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
- new RowDefinition { Height = new GridLength(120) }
- },
- Children =
- {
- CreateMainContent(),
- CreateEventLogPanel()
- }
- };
-
- Grid.SetRow((View)((Grid)Content).Children[0], 0);
- Grid.SetRow((View)((Grid)Content).Children[1], 1);
- }
-
- private View CreateMainContent()
- {
- return new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 20,
- Children =
- {
- new Label { Text = "List Controls", FontSize = 24, FontAttributes = FontAttributes.Bold },
-
- CreateSection("CollectionView - Fruits", CreateFruitsCollectionView()),
- CreateSection("CollectionView - Colors", CreateColorsCollectionView()),
- CreateSection("CollectionView - Contacts", CreateContactsCollectionView())
- }
- }
- };
- }
-
- private View CreateFruitsCollectionView()
- {
- var layout = new VerticalStackLayout { Spacing = 10 };
-
- var fruits = new List
- {
- "Apple", "Banana", "Cherry", "Date", "Elderberry",
- "Fig", "Grape", "Honeydew", "Kiwi", "Lemon",
- "Mango", "Nectarine", "Orange", "Papaya", "Quince"
- };
-
- var selectedLabel = new Label { Text = "Tap a fruit to select", TextColor = Colors.Gray };
-
- var collectionView = new CollectionView
- {
- ItemsSource = fruits,
- HeightRequest = 200,
- SelectionMode = SelectionMode.Single,
- BackgroundColor = Color.FromArgb("#FAFAFA")
- };
-
- collectionView.SelectionChanged += (s, e) =>
- {
- if (e.CurrentSelection.Count > 0)
- {
- var item = e.CurrentSelection[0]?.ToString();
- selectedLabel.Text = $"Selected: {item}";
- LogEvent($"Fruit selected: {item}");
- }
- };
-
- layout.Children.Add(collectionView);
- layout.Children.Add(selectedLabel);
-
- return layout;
- }
-
- private View CreateColorsCollectionView()
- {
- var layout = new VerticalStackLayout { Spacing = 10 };
-
- var colors = new List
- {
- new("Red", "#F44336"),
- new("Pink", "#E91E63"),
- new("Purple", "#9C27B0"),
- new("Deep Purple", "#673AB7"),
- new("Indigo", "#3F51B5"),
- new("Blue", "#2196F3"),
- new("Cyan", "#00BCD4"),
- new("Teal", "#009688"),
- new("Green", "#4CAF50"),
- new("Light Green", "#8BC34A"),
- new("Lime", "#CDDC39"),
- new("Yellow", "#FFEB3B"),
- new("Amber", "#FFC107"),
- new("Orange", "#FF9800"),
- new("Deep Orange", "#FF5722")
- };
-
- var collectionView = new CollectionView
- {
- ItemsSource = colors,
- HeightRequest = 180,
- SelectionMode = SelectionMode.Single,
- BackgroundColor = Colors.White
- };
-
- collectionView.SelectionChanged += (s, e) =>
- {
- if (e.CurrentSelection.Count > 0 && e.CurrentSelection[0] is ColorItem item)
- {
- LogEvent($"Color selected: {item.Name} ({item.Hex})");
- }
- };
-
- layout.Children.Add(collectionView);
- layout.Children.Add(new Label { Text = "Scroll to see all colors", FontSize = 11, TextColor = Colors.Gray });
-
- return layout;
- }
-
- private View CreateContactsCollectionView()
- {
- var layout = new VerticalStackLayout { Spacing = 10 };
-
- var contacts = new List
- {
- new("Alice Johnson", "alice@example.com", "Engineering"),
- new("Bob Smith", "bob@example.com", "Marketing"),
- new("Carol Williams", "carol@example.com", "Design"),
- new("David Brown", "david@example.com", "Sales"),
- new("Eva Martinez", "eva@example.com", "Engineering"),
- new("Frank Lee", "frank@example.com", "Support"),
- new("Grace Kim", "grace@example.com", "HR"),
- new("Henry Wilson", "henry@example.com", "Finance")
- };
-
- var collectionView = new CollectionView
- {
- ItemsSource = contacts,
- HeightRequest = 200,
- SelectionMode = SelectionMode.Single,
- BackgroundColor = Colors.White
- };
-
- collectionView.SelectionChanged += (s, e) =>
- {
- if (e.CurrentSelection.Count > 0 && e.CurrentSelection[0] is ContactItem contact)
- {
- LogEvent($"Contact: {contact.Name} - {contact.Department}");
- }
- };
-
- layout.Children.Add(collectionView);
-
- // Action buttons
- var buttonRow = new HorizontalStackLayout { Spacing = 10 };
- var addBtn = new Button { Text = "Add Contact", BackgroundColor = Colors.Green, TextColor = Colors.White };
- addBtn.Clicked += (s, e) => LogEvent("Add contact clicked");
- var deleteBtn = new Button { Text = "Delete Selected", BackgroundColor = Colors.Red, TextColor = Colors.White };
- deleteBtn.Clicked += (s, e) => LogEvent("Delete contact clicked");
- buttonRow.Children.Add(addBtn);
- buttonRow.Children.Add(deleteBtn);
- layout.Children.Add(buttonRow);
-
- return layout;
- }
-
- private Frame CreateSection(string title, View content)
- {
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Colors.White,
- Content = new VerticalStackLayout
- {
- Spacing = 10,
- Children =
- {
- new Label { Text = title, FontSize = 16, FontAttributes = FontAttributes.Bold },
- content
- }
- }
- };
- }
-
- private View CreateEventLogPanel()
- {
- return new Frame
- {
- BackgroundColor = Color.FromArgb("#F5F5F5"),
- Padding = new Thickness(10),
- CornerRadius = 0,
- Content = new VerticalStackLayout
- {
- Children =
- {
- new Label { Text = "Event Log:", FontSize = 12, FontAttributes = FontAttributes.Bold },
- new ScrollView
- {
- HeightRequest = 80,
- Content = _eventLog
- }
- }
- }
- };
- }
-
- private void LogEvent(string message)
- {
- _eventCount++;
- var timestamp = DateTime.Now.ToString("HH:mm:ss");
- _eventLog.Text = $"[{timestamp}] {_eventCount}. {message}\n{_eventLog.Text}";
- }
-}
-
-public record ColorItem(string Name, string Hex)
-{
- public override string ToString() => Name;
-}
-
-public record ContactItem(string Name, string Email, string Department)
-{
- public override string ToString() => $"{Name} ({Department})";
-}
diff --git a/samples/ShellDemo/Pages/PickersPage.cs b/samples/ShellDemo/Pages/PickersPage.cs
deleted file mode 100644
index b5ae1d9..0000000
--- a/samples/ShellDemo/Pages/PickersPage.cs
+++ /dev/null
@@ -1,261 +0,0 @@
-// PickersPage - Picker, DatePicker, TimePicker Demo
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class PickersPage : ContentPage
-{
- private readonly Label _eventLog;
- private int _eventCount = 0;
-
- public PickersPage()
- {
- Title = "Pickers";
-
- _eventLog = new Label
- {
- Text = "Events will appear here...",
- FontSize = 11,
- TextColor = Colors.Gray,
- LineBreakMode = LineBreakMode.WordWrap
- };
-
- Content = new Grid
- {
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
- new RowDefinition { Height = new GridLength(120) }
- },
- Children =
- {
- CreateMainContent(),
- CreateEventLogPanel()
- }
- };
-
- Grid.SetRow((View)((Grid)Content).Children[0], 0);
- Grid.SetRow((View)((Grid)Content).Children[1], 1);
- }
-
- private View CreateMainContent()
- {
- return new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 20,
- Children =
- {
- new Label { Text = "Picker Controls", FontSize = 24, FontAttributes = FontAttributes.Bold },
-
- CreateSection("Picker", CreatePickerDemo()),
- CreateSection("DatePicker", CreateDatePickerDemo()),
- CreateSection("TimePicker", CreateTimePickerDemo())
- }
- }
- };
- }
-
- private View CreatePickerDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Basic picker
- var selectedLabel = new Label { Text = "Selected: (none)", TextColor = Colors.Gray };
- var picker1 = new Picker { Title = "Select a fruit" };
- picker1.Items.Add("Apple");
- picker1.Items.Add("Banana");
- picker1.Items.Add("Cherry");
- picker1.Items.Add("Date");
- picker1.Items.Add("Elderberry");
- picker1.Items.Add("Fig");
- picker1.Items.Add("Grape");
- picker1.SelectedIndexChanged += (s, e) =>
- {
- if (picker1.SelectedIndex >= 0)
- {
- var item = picker1.Items[picker1.SelectedIndex];
- selectedLabel.Text = $"Selected: {item}";
- LogEvent($"Fruit selected: {item}");
- }
- };
- layout.Children.Add(picker1);
- layout.Children.Add(selectedLabel);
-
- // Picker with default selection
- layout.Children.Add(new Label { Text = "With Default Selection:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var picker2 = new Picker { Title = "Select a color" };
- picker2.Items.Add("Red");
- picker2.Items.Add("Green");
- picker2.Items.Add("Blue");
- picker2.Items.Add("Yellow");
- picker2.Items.Add("Purple");
- picker2.SelectedIndex = 2; // Blue
- picker2.SelectedIndexChanged += (s, e) =>
- {
- if (picker2.SelectedIndex >= 0)
- LogEvent($"Color selected: {picker2.Items[picker2.SelectedIndex]}");
- };
- layout.Children.Add(picker2);
-
- // Styled picker
- layout.Children.Add(new Label { Text = "Styled Picker:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var picker3 = new Picker
- {
- Title = "Select size",
- TextColor = Colors.DarkBlue,
- TitleColor = Colors.Gray
- };
- picker3.Items.Add("Small");
- picker3.Items.Add("Medium");
- picker3.Items.Add("Large");
- picker3.Items.Add("Extra Large");
- picker3.SelectedIndexChanged += (s, e) =>
- {
- if (picker3.SelectedIndex >= 0)
- LogEvent($"Size selected: {picker3.Items[picker3.SelectedIndex]}");
- };
- layout.Children.Add(picker3);
-
- return layout;
- }
-
- private View CreateDatePickerDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Basic date picker
- var dateLabel = new Label { Text = $"Selected: {DateTime.Today:d}" };
- var datePicker1 = new DatePicker { Date = DateTime.Today };
- datePicker1.DateSelected += (s, e) =>
- {
- dateLabel.Text = $"Selected: {e.NewDate:d}";
- LogEvent($"Date selected: {e.NewDate:d}");
- };
- layout.Children.Add(datePicker1);
- layout.Children.Add(dateLabel);
-
- // Date picker with range
- layout.Children.Add(new Label { Text = "With Date Range (this month only):", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var startOfMonth = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
- var endOfMonth = startOfMonth.AddMonths(1).AddDays(-1);
- var datePicker2 = new DatePicker
- {
- MinimumDate = startOfMonth,
- MaximumDate = endOfMonth,
- Date = DateTime.Today
- };
- datePicker2.DateSelected += (s, e) => LogEvent($"Date (limited): {e.NewDate:d}");
- layout.Children.Add(datePicker2);
-
- // Styled date picker
- layout.Children.Add(new Label { Text = "Styled DatePicker:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var datePicker3 = new DatePicker
- {
- Date = DateTime.Today.AddDays(7),
- TextColor = Colors.DarkGreen
- };
- datePicker3.DateSelected += (s, e) => LogEvent($"Styled date: {e.NewDate:d}");
- layout.Children.Add(datePicker3);
-
- return layout;
- }
-
- private View CreateTimePickerDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Basic time picker
- var timeLabel = new Label { Text = $"Selected: {DateTime.Now:t}" };
- var timePicker1 = new TimePicker { Time = DateTime.Now.TimeOfDay };
- timePicker1.PropertyChanged += (s, e) =>
- {
- if (e.PropertyName == nameof(TimePicker.Time))
- {
- var time = timePicker1.Time;
- timeLabel.Text = $"Selected: {time:hh\\:mm}";
- LogEvent($"Time selected: {time:hh\\:mm}");
- }
- };
- layout.Children.Add(timePicker1);
- layout.Children.Add(timeLabel);
-
- // Styled time picker
- layout.Children.Add(new Label { Text = "Styled TimePicker:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var timePicker2 = new TimePicker
- {
- Time = new TimeSpan(14, 30, 0),
- TextColor = Colors.DarkBlue
- };
- timePicker2.PropertyChanged += (s, e) =>
- {
- if (e.PropertyName == nameof(TimePicker.Time))
- LogEvent($"Styled time: {timePicker2.Time:hh\\:mm}");
- };
- layout.Children.Add(timePicker2);
-
- // Morning alarm example
- layout.Children.Add(new Label { Text = "Alarm Time:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var alarmRow = new HorizontalStackLayout { Spacing = 10 };
- var alarmPicker = new TimePicker { Time = new TimeSpan(7, 0, 0) };
- var alarmBtn = new Button { Text = "Set Alarm", BackgroundColor = Colors.Orange, TextColor = Colors.White };
- alarmBtn.Clicked += (s, e) => LogEvent($"Alarm set for {alarmPicker.Time:hh\\:mm}");
- alarmRow.Children.Add(alarmPicker);
- alarmRow.Children.Add(alarmBtn);
- layout.Children.Add(alarmRow);
-
- return layout;
- }
-
- private Frame CreateSection(string title, View content)
- {
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Colors.White,
- Content = new VerticalStackLayout
- {
- Spacing = 10,
- Children =
- {
- new Label { Text = title, FontSize = 16, FontAttributes = FontAttributes.Bold },
- content
- }
- }
- };
- }
-
- private View CreateEventLogPanel()
- {
- return new Frame
- {
- BackgroundColor = Color.FromArgb("#F5F5F5"),
- Padding = new Thickness(10),
- CornerRadius = 0,
- Content = new VerticalStackLayout
- {
- Children =
- {
- new Label { Text = "Event Log:", FontSize = 12, FontAttributes = FontAttributes.Bold },
- new ScrollView
- {
- HeightRequest = 80,
- Content = _eventLog
- }
- }
- }
- };
- }
-
- private void LogEvent(string message)
- {
- _eventCount++;
- var timestamp = DateTime.Now.ToString("HH:mm:ss");
- _eventLog.Text = $"[{timestamp}] {_eventCount}. {message}\n{_eventLog.Text}";
- }
-}
diff --git a/samples/ShellDemo/Pages/ProgressPage.cs b/samples/ShellDemo/Pages/ProgressPage.cs
deleted file mode 100644
index 87e4828..0000000
--- a/samples/ShellDemo/Pages/ProgressPage.cs
+++ /dev/null
@@ -1,261 +0,0 @@
-// ProgressPage - ProgressBar and ActivityIndicator Demo
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class ProgressPage : ContentPage
-{
- private readonly Label _eventLog;
- private int _eventCount = 0;
- private ProgressBar? _animatedProgress;
- private bool _isAnimating = false;
-
- public ProgressPage()
- {
- Title = "Progress";
-
- _eventLog = new Label
- {
- Text = "Events will appear here...",
- FontSize = 11,
- TextColor = Colors.Gray,
- LineBreakMode = LineBreakMode.WordWrap
- };
-
- Content = new Grid
- {
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
- new RowDefinition { Height = new GridLength(120) }
- },
- Children =
- {
- CreateMainContent(),
- CreateEventLogPanel()
- }
- };
-
- Grid.SetRow((View)((Grid)Content).Children[0], 0);
- Grid.SetRow((View)((Grid)Content).Children[1], 1);
- }
-
- private View CreateMainContent()
- {
- return new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 20,
- Children =
- {
- new Label { Text = "Progress Indicators", FontSize = 24, FontAttributes = FontAttributes.Bold },
-
- CreateSection("ProgressBar", CreateProgressBarDemo()),
- CreateSection("ActivityIndicator", CreateActivityIndicatorDemo()),
- CreateSection("Interactive Demo", CreateInteractiveDemo())
- }
- }
- };
- }
-
- private View CreateProgressBarDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Various progress values
- var values = new[] { 0.0, 0.25, 0.5, 0.75, 1.0 };
- foreach (var value in values)
- {
- var row = new HorizontalStackLayout { Spacing = 10 };
- var progress = new ProgressBar { Progress = value, WidthRequest = 200 };
- var label = new Label { Text = $"{value * 100:0}%", VerticalOptions = LayoutOptions.Center, WidthRequest = 50 };
- row.Children.Add(progress);
- row.Children.Add(label);
- layout.Children.Add(row);
- }
-
- // Colored progress bars
- layout.Children.Add(new Label { Text = "Colored Progress Bars:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
-
- var colors = new[] { Colors.Red, Colors.Green, Colors.Blue, Colors.Orange, Colors.Purple };
- foreach (var color in colors)
- {
- var progress = new ProgressBar { Progress = 0.7, ProgressColor = color };
- layout.Children.Add(progress);
- }
-
- return layout;
- }
-
- private View CreateActivityIndicatorDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Running indicator
- var runningRow = new HorizontalStackLayout { Spacing = 15 };
- var runningIndicator = new ActivityIndicator { IsRunning = true };
- runningRow.Children.Add(runningIndicator);
- runningRow.Children.Add(new Label { Text = "Loading...", VerticalOptions = LayoutOptions.Center });
- layout.Children.Add(runningRow);
-
- // Toggle indicator
- var toggleRow = new HorizontalStackLayout { Spacing = 15 };
- var toggleIndicator = new ActivityIndicator { IsRunning = false };
- var toggleBtn = new Button { Text = "Start/Stop" };
- toggleBtn.Clicked += (s, e) =>
- {
- toggleIndicator.IsRunning = !toggleIndicator.IsRunning;
- LogEvent($"ActivityIndicator: {(toggleIndicator.IsRunning ? "Started" : "Stopped")}");
- };
- toggleRow.Children.Add(toggleIndicator);
- toggleRow.Children.Add(toggleBtn);
- layout.Children.Add(toggleRow);
-
- // Colored indicators
- layout.Children.Add(new Label { Text = "Colored Indicators:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var colorRow = new HorizontalStackLayout { Spacing = 20 };
- var indicatorColors = new[] { Colors.Red, Colors.Green, Colors.Blue, Colors.Orange };
- foreach (var color in indicatorColors)
- {
- var indicator = new ActivityIndicator { IsRunning = true, Color = color };
- colorRow.Children.Add(indicator);
- }
- layout.Children.Add(colorRow);
-
- return layout;
- }
-
- private View CreateInteractiveDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Slider-controlled progress
- var progressLabel = new Label { Text = "Progress: 50%" };
- _animatedProgress = new ProgressBar { Progress = 0.5 };
-
- var slider = new Slider { Minimum = 0, Maximum = 100, Value = 50 };
- slider.ValueChanged += (s, e) =>
- {
- var value = e.NewValue / 100.0;
- _animatedProgress.Progress = value;
- progressLabel.Text = $"Progress: {e.NewValue:0}%";
- };
-
- layout.Children.Add(_animatedProgress);
- layout.Children.Add(slider);
- layout.Children.Add(progressLabel);
-
- // Animated progress buttons
- var buttonRow = new HorizontalStackLayout { Spacing = 10, Margin = new Thickness(0, 10, 0, 0) };
-
- var resetBtn = new Button { Text = "Reset", BackgroundColor = Colors.Gray, TextColor = Colors.White };
- resetBtn.Clicked += async (s, e) =>
- {
- _animatedProgress.Progress = 0;
- slider.Value = 0;
- LogEvent("Progress reset to 0%");
- };
-
- var animateBtn = new Button { Text = "Animate to 100%", BackgroundColor = Colors.Blue, TextColor = Colors.White };
- animateBtn.Clicked += async (s, e) =>
- {
- if (_isAnimating) return;
- _isAnimating = true;
- LogEvent("Animation started");
-
- for (int i = (int)(slider.Value); i <= 100; i += 5)
- {
- _animatedProgress.Progress = i / 100.0;
- slider.Value = i;
- await Task.Delay(100);
- }
-
- _isAnimating = false;
- LogEvent("Animation completed");
- };
-
- var simulateBtn = new Button { Text = "Simulate Download", BackgroundColor = Colors.Green, TextColor = Colors.White };
- simulateBtn.Clicked += async (s, e) =>
- {
- if (_isAnimating) return;
- _isAnimating = true;
- LogEvent("Download simulation started");
-
- _animatedProgress.Progress = 0;
- slider.Value = 0;
-
- var random = new Random();
- double progress = 0;
- while (progress < 1.0)
- {
- progress += random.NextDouble() * 0.1;
- if (progress > 1.0) progress = 1.0;
- _animatedProgress.Progress = progress;
- slider.Value = progress * 100;
- await Task.Delay(200 + random.Next(300));
- }
-
- _isAnimating = false;
- LogEvent("Download simulation completed");
- };
-
- buttonRow.Children.Add(resetBtn);
- buttonRow.Children.Add(animateBtn);
- buttonRow.Children.Add(simulateBtn);
- layout.Children.Add(buttonRow);
-
- return layout;
- }
-
- private Frame CreateSection(string title, View content)
- {
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Colors.White,
- Content = new VerticalStackLayout
- {
- Spacing = 10,
- Children =
- {
- new Label { Text = title, FontSize = 16, FontAttributes = FontAttributes.Bold },
- content
- }
- }
- };
- }
-
- private View CreateEventLogPanel()
- {
- return new Frame
- {
- BackgroundColor = Color.FromArgb("#F5F5F5"),
- Padding = new Thickness(10),
- CornerRadius = 0,
- Content = new VerticalStackLayout
- {
- Children =
- {
- new Label { Text = "Event Log:", FontSize = 12, FontAttributes = FontAttributes.Bold },
- new ScrollView
- {
- HeightRequest = 80,
- Content = _eventLog
- }
- }
- }
- };
- }
-
- private void LogEvent(string message)
- {
- _eventCount++;
- var timestamp = DateTime.Now.ToString("HH:mm:ss");
- _eventLog.Text = $"[{timestamp}] {_eventCount}. {message}\n{_eventLog.Text}";
- }
-}
diff --git a/samples/ShellDemo/Pages/SelectionPage.cs b/samples/ShellDemo/Pages/SelectionPage.cs
deleted file mode 100644
index e247af6..0000000
--- a/samples/ShellDemo/Pages/SelectionPage.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-// SelectionPage - CheckBox, Switch, Slider Demo
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class SelectionPage : ContentPage
-{
- private readonly Label _eventLog;
- private int _eventCount = 0;
-
- public SelectionPage()
- {
- Title = "Selection Controls";
-
- _eventLog = new Label
- {
- Text = "Events will appear here...",
- FontSize = 11,
- TextColor = Colors.Gray,
- LineBreakMode = LineBreakMode.WordWrap
- };
-
- Content = new Grid
- {
- RowDefinitions =
- {
- new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
- new RowDefinition { Height = new GridLength(120) }
- },
- Children =
- {
- CreateMainContent(),
- CreateEventLogPanel()
- }
- };
-
- Grid.SetRow((View)((Grid)Content).Children[0], 0);
- Grid.SetRow((View)((Grid)Content).Children[1], 1);
- }
-
- private View CreateMainContent()
- {
- return new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 20,
- Children =
- {
- new Label { Text = "Selection Controls", FontSize = 24, FontAttributes = FontAttributes.Bold },
-
- CreateSection("CheckBox", CreateCheckBoxDemo()),
- CreateSection("Switch", CreateSwitchDemo()),
- CreateSection("Slider", CreateSliderDemo())
- }
- }
- };
- }
-
- private View CreateCheckBoxDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Basic checkboxes
- var basicRow = new HorizontalStackLayout { Spacing = 20 };
-
- var cb1 = new CheckBox { IsChecked = false };
- cb1.CheckedChanged += (s, e) => LogEvent($"Checkbox 1: {(e.Value ? "Checked" : "Unchecked")}");
- basicRow.Children.Add(cb1);
- basicRow.Children.Add(new Label { Text = "Option 1", VerticalOptions = LayoutOptions.Center });
-
- var cb2 = new CheckBox { IsChecked = true };
- cb2.CheckedChanged += (s, e) => LogEvent($"Checkbox 2: {(e.Value ? "Checked" : "Unchecked")}");
- basicRow.Children.Add(cb2);
- basicRow.Children.Add(new Label { Text = "Option 2 (default checked)", VerticalOptions = LayoutOptions.Center });
-
- layout.Children.Add(basicRow);
-
- // Colored checkboxes
- var colorRow = new HorizontalStackLayout { Spacing = 20 };
- var colors = new[] { Colors.Red, Colors.Green, Colors.Blue, Colors.Purple };
- foreach (var color in colors)
- {
- var cb = new CheckBox { Color = color, IsChecked = true };
- cb.CheckedChanged += (s, e) => LogEvent($"{color} checkbox: {(e.Value ? "Checked" : "Unchecked")}");
- colorRow.Children.Add(cb);
- }
- layout.Children.Add(new Label { Text = "Colored Checkboxes:", FontSize = 12 });
- layout.Children.Add(colorRow);
-
- // Disabled checkbox
- var disabledRow = new HorizontalStackLayout { Spacing = 10 };
- var disabledCb = new CheckBox { IsChecked = true, IsEnabled = false };
- disabledRow.Children.Add(disabledCb);
- disabledRow.Children.Add(new Label { Text = "Disabled (checked)", VerticalOptions = LayoutOptions.Center, TextColor = Colors.Gray });
- layout.Children.Add(disabledRow);
-
- return layout;
- }
-
- private View CreateSwitchDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Basic switch
- var basicRow = new HorizontalStackLayout { Spacing = 15 };
- var statusLabel = new Label { Text = "Off", VerticalOptions = LayoutOptions.Center, WidthRequest = 50 };
- var sw1 = new Switch { IsToggled = false };
- sw1.Toggled += (s, e) =>
- {
- statusLabel.Text = e.Value ? "On" : "Off";
- LogEvent($"Switch toggled: {(e.Value ? "ON" : "OFF")}");
- };
- basicRow.Children.Add(sw1);
- basicRow.Children.Add(statusLabel);
- layout.Children.Add(basicRow);
-
- // Colored switches
- var colorRow = new HorizontalStackLayout { Spacing = 20 };
- var switchColors = new[] { Colors.Green, Colors.Orange, Colors.Purple };
- foreach (var color in switchColors)
- {
- var sw = new Switch { IsToggled = true, OnColor = color };
- sw.Toggled += (s, e) => LogEvent($"{color} switch: {(e.Value ? "ON" : "OFF")}");
- colorRow.Children.Add(sw);
- }
- layout.Children.Add(new Label { Text = "Colored Switches:", FontSize = 12 });
- layout.Children.Add(colorRow);
-
- // Disabled switch
- var disabledRow = new HorizontalStackLayout { Spacing = 10 };
- var disabledSw = new Switch { IsToggled = true, IsEnabled = false };
- disabledRow.Children.Add(disabledSw);
- disabledRow.Children.Add(new Label { Text = "Disabled (on)", VerticalOptions = LayoutOptions.Center, TextColor = Colors.Gray });
- layout.Children.Add(disabledRow);
-
- return layout;
- }
-
- private View CreateSliderDemo()
- {
- var layout = new VerticalStackLayout { Spacing = 15 };
-
- // Basic slider
- var valueLabel = new Label { Text = "Value: 50" };
- var slider1 = new Slider { Minimum = 0, Maximum = 100, Value = 50 };
- slider1.ValueChanged += (s, e) =>
- {
- valueLabel.Text = $"Value: {(int)e.NewValue}";
- LogEvent($"Slider value: {(int)e.NewValue}");
- };
- layout.Children.Add(slider1);
- layout.Children.Add(valueLabel);
-
- // Slider with custom range
- layout.Children.Add(new Label { Text = "Temperature (0-40°C):", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var tempLabel = new Label { Text = "20°C" };
- var tempSlider = new Slider { Minimum = 0, Maximum = 40, Value = 20 };
- tempSlider.ValueChanged += (s, e) =>
- {
- tempLabel.Text = $"{(int)e.NewValue}°C";
- LogEvent($"Temperature: {(int)e.NewValue}°C");
- };
- layout.Children.Add(tempSlider);
- layout.Children.Add(tempLabel);
-
- // Colored slider
- layout.Children.Add(new Label { Text = "Colored Slider:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var colorSlider = new Slider
- {
- Minimum = 0,
- Maximum = 100,
- Value = 75,
- MinimumTrackColor = Colors.Green,
- MaximumTrackColor = Colors.LightGray,
- ThumbColor = Colors.DarkGreen
- };
- colorSlider.ValueChanged += (s, e) => LogEvent($"Colored slider: {(int)e.NewValue}");
- layout.Children.Add(colorSlider);
-
- // Disabled slider
- layout.Children.Add(new Label { Text = "Disabled Slider:", FontSize = 12, Margin = new Thickness(0, 10, 0, 0) });
- var disabledSlider = new Slider { Minimum = 0, Maximum = 100, Value = 30, IsEnabled = false };
- layout.Children.Add(disabledSlider);
-
- return layout;
- }
-
- private Frame CreateSection(string title, View content)
- {
- return new Frame
- {
- CornerRadius = 8,
- Padding = new Thickness(15),
- BackgroundColor = Colors.White,
- Content = new VerticalStackLayout
- {
- Spacing = 10,
- Children =
- {
- new Label { Text = title, FontSize = 16, FontAttributes = FontAttributes.Bold },
- content
- }
- }
- };
- }
-
- private View CreateEventLogPanel()
- {
- return new Frame
- {
- BackgroundColor = Color.FromArgb("#F5F5F5"),
- Padding = new Thickness(10),
- CornerRadius = 0,
- Content = new VerticalStackLayout
- {
- Children =
- {
- new Label { Text = "Event Log:", FontSize = 12, FontAttributes = FontAttributes.Bold },
- new ScrollView
- {
- HeightRequest = 80,
- Content = _eventLog
- }
- }
- }
- };
- }
-
- private void LogEvent(string message)
- {
- _eventCount++;
- var timestamp = DateTime.Now.ToString("HH:mm:ss");
- _eventLog.Text = $"[{timestamp}] {_eventCount}. {message}\n{_eventLog.Text}";
- }
-}
diff --git a/samples/ShellDemo/Pages/TextInputPage.cs b/samples/ShellDemo/Pages/TextInputPage.cs
deleted file mode 100644
index 95c4e28..0000000
--- a/samples/ShellDemo/Pages/TextInputPage.cs
+++ /dev/null
@@ -1,166 +0,0 @@
-// TextInputPage - Demonstrates text input controls
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace ShellDemo;
-
-public class TextInputPage : ContentPage
-{
- private Label _entryOutput;
- private Label _searchOutput;
- private Label _editorOutput;
-
- public TextInputPage()
- {
- Title = "Text Input";
-
- _entryOutput = new Label { TextColor = Colors.Gray, FontSize = 12 };
- _searchOutput = new Label { TextColor = Colors.Gray, FontSize = 12 };
- _editorOutput = new Label { TextColor = Colors.Gray, FontSize = 12 };
-
- Content = new ScrollView
- {
- Content = new VerticalStackLayout
- {
- Padding = new Thickness(20),
- Spacing = 15,
- Children =
- {
- new Label
- {
- Text = "Text Input Controls",
- FontSize = 24,
- FontAttributes = FontAttributes.Bold
- },
- new Label
- {
- Text = "Click on any field and start typing. All keyboard input is handled by the framework.",
- FontSize = 14,
- TextColor = Colors.Gray
- },
-
- // Entry Section
- new BoxView { HeightRequest = 1, Color = Colors.LightGray },
- new Label { Text = "Entry (Single Line)", FontSize = 18, FontAttributes = FontAttributes.Bold },
- CreateEntry("Enter your name...", e => _entryOutput.Text = $"You typed: {e.Text}"),
- _entryOutput,
-
- CreateEntry("Enter your email...", null, Keyboard.Email),
- new Label { Text = "Email keyboard type", FontSize = 12, TextColor = Colors.Gray },
-
- CreatePasswordEntry("Enter password..."),
- new Label { Text = "Password field (text hidden)", FontSize = 12, TextColor = Colors.Gray },
-
- // SearchBar Section
- new BoxView { HeightRequest = 1, Color = Colors.LightGray },
- new Label { Text = "SearchBar", FontSize = 18, FontAttributes = FontAttributes.Bold },
- CreateSearchBar(),
- _searchOutput,
-
- // Editor Section
- new BoxView { HeightRequest = 1, Color = Colors.LightGray },
- new Label { Text = "Editor (Multi-line)", FontSize = 18, FontAttributes = FontAttributes.Bold },
- CreateEditor(),
- _editorOutput,
-
- // Instructions
- new BoxView { HeightRequest = 1, Color = Colors.LightGray },
- new Frame
- {
- BackgroundColor = Color.FromArgb("#E3F2FD"),
- CornerRadius = 8,
- Padding = new Thickness(15),
- Content = new VerticalStackLayout
- {
- Spacing = 5,
- Children =
- {
- new Label
- {
- Text = "Keyboard Shortcuts",
- FontAttributes = FontAttributes.Bold
- },
- new Label { Text = "Ctrl+A: Select all" },
- new Label { Text = "Ctrl+C: Copy" },
- new Label { Text = "Ctrl+V: Paste" },
- new Label { Text = "Ctrl+X: Cut" },
- new Label { Text = "Home/End: Move to start/end" },
- new Label { Text = "Shift+Arrow: Select text" }
- }
- }
- }
- }
- }
- };
- }
-
- private Entry CreateEntry(string placeholder, Action? onTextChanged, Keyboard? keyboard = null)
- {
- var entry = new Entry
- {
- Placeholder = placeholder,
- FontSize = 14
- };
-
- if (keyboard != null)
- {
- entry.Keyboard = keyboard;
- }
-
- if (onTextChanged != null)
- {
- entry.TextChanged += (s, e) => onTextChanged(entry);
- }
-
- return entry;
- }
-
- private Entry CreatePasswordEntry(string placeholder)
- {
- return new Entry
- {
- Placeholder = placeholder,
- FontSize = 14,
- IsPassword = true
- };
- }
-
- private SearchBar CreateSearchBar()
- {
- var searchBar = new SearchBar
- {
- Placeholder = "Search for items..."
- };
-
- searchBar.TextChanged += (s, e) =>
- {
- _searchOutput.Text = $"Searching: {e.NewTextValue}";
- };
-
- searchBar.SearchButtonPressed += (s, e) =>
- {
- _searchOutput.Text = $"Search submitted: {searchBar.Text}";
- };
-
- return searchBar;
- }
-
- private Editor CreateEditor()
- {
- var editor = new Editor
- {
- Placeholder = "Enter multiple lines of text here...\nPress Enter to create new lines.",
- HeightRequest = 120,
- FontSize = 14
- };
-
- editor.TextChanged += (s, e) =>
- {
- var lineCount = string.IsNullOrEmpty(e.NewTextValue) ? 0 : e.NewTextValue.Split('\n').Length;
- _editorOutput.Text = $"Lines: {lineCount}, Characters: {e.NewTextValue?.Length ?? 0}";
- };
-
- return editor;
- }
-}
diff --git a/samples/ShellDemo/Platforms/Linux/Program.cs b/samples/ShellDemo/Platforms/Linux/Program.cs
deleted file mode 100644
index 4330c0f..0000000
--- a/samples/ShellDemo/Platforms/Linux/Program.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Platforms/Linux/Program.cs - Linux platform entry point
-// Same pattern as Android's MainActivity or iOS's AppDelegate
-
-using Microsoft.Maui.Platform.Linux;
-using Microsoft.Maui.Platform.Linux.Hosting;
-
-namespace ShellDemo;
-
-class Program
-{
- static void Main(string[] args)
- {
- // Create the shared MAUI app
- var app = MauiProgram.CreateMauiApp();
-
- // Run on Linux platform
- LinuxApplication.Run(app, args);
- }
-}
diff --git a/samples/ShellDemo/README.md b/samples/ShellDemo/README.md
deleted file mode 100644
index b734932..0000000
--- a/samples/ShellDemo/README.md
+++ /dev/null
@@ -1,157 +0,0 @@
-# ShellDemo Sample
-
-A comprehensive control showcase application demonstrating all OpenMaui Linux controls with Shell navigation and flyout menu.
-
-## Features
-
-- **Shell Navigation** - Flyout menu with multiple pages
-- **Route-Based Navigation** - Push navigation with registered routes
-- **All Core Controls** - Button, Entry, Editor, CheckBox, Switch, Slider, Picker, etc.
-- **CollectionView** - Lists with selection and data binding
-- **Progress Indicators** - ProgressBar and ActivityIndicator with animations
-- **Grid Layouts** - Complex multi-column/row layouts
-- **Event Logging** - Real-time event feedback panel
-
-## Pages
-
-| Page | Controls Demonstrated |
-|------|----------------------|
-| **Home** | Welcome screen, navigation overview |
-| **Buttons** | Button styles, colors, states, click/press/release events |
-| **Text Input** | Entry, Editor, SearchBar, password fields, keyboard types |
-| **Selection** | CheckBox, Switch, Slider with colors and states |
-| **Pickers** | Picker, DatePicker, TimePicker with styling |
-| **Lists** | CollectionView with selection, custom items |
-| **Progress** | ProgressBar, ActivityIndicator, animated demos |
-| **Grids** | Grid layouts with row/column definitions |
-| **About** | App information |
-
-## Architecture
-
-```
-ShellDemo/
-├── App.cs # AppShell definition with flyout
-├── Program.cs # Linux platform bootstrap
-├── MauiProgram.cs # MAUI app builder
-└── Pages/
- ├── HomePage.cs # Welcome page
- ├── ButtonsPage.cs # Button demonstrations
- ├── TextInputPage.cs # Entry, Editor, SearchBar
- ├── SelectionPage.cs # CheckBox, Switch, Slider
- ├── PickersPage.cs # Picker, DatePicker, TimePicker
- ├── ListsPage.cs # CollectionView demos
- ├── ProgressPage.cs # ProgressBar, ActivityIndicator
- ├── GridsPage.cs # Grid layout demos
- ├── DetailPage.cs # Push navigation target
- └── AboutPage.cs # About information
-```
-
-## Shell Configuration
-
-```csharp
-public class AppShell : Shell
-{
- public AppShell()
- {
- FlyoutBehavior = FlyoutBehavior.Flyout;
- Title = "OpenMaui Controls Demo";
-
- // Register routes for push navigation
- Routing.RegisterRoute("detail", typeof(DetailPage));
-
- // Add flyout items
- Items.Add(CreateFlyoutItem("Home", typeof(HomePage)));
- Items.Add(CreateFlyoutItem("Buttons", typeof(ButtonsPage)));
- // ...more items
- }
-}
-```
-
-## Control Demonstrations
-
-### Buttons Page
-- Default, styled, and transparent buttons
-- Color variations (Primary, Success, Warning, Danger)
-- Enabled/disabled state toggling
-- Wide, tall, and round button shapes
-- Pressed, clicked, released event handling
-
-### Text Input Page
-- Entry with placeholder and text change events
-- Password entry with hidden text
-- Email keyboard type
-- SearchBar with search button
-- Multi-line Editor
-- Keyboard shortcuts guide
-
-### Selection Page
-- CheckBox with colors and disabled state
-- Switch with OnColor customization
-- Slider with min/max range and track colors
-
-### Pickers Page
-- Picker with items and selection events
-- DatePicker with date range limits
-- TimePicker with time selection
-- Styled pickers with custom colors
-
-### Lists Page
-- CollectionView with string items
-- CollectionView with custom data types (ColorItem, ContactItem)
-- Selection handling and event feedback
-
-### Progress Page
-- ProgressBar at various percentages
-- Colored progress bars
-- ActivityIndicator running/stopped states
-- Colored activity indicators
-- Interactive slider-controlled progress
-- Animated progress simulation
-
-## Building and Running
-
-```bash
-# From the maui-linux-push directory
-cd samples/ShellDemo
-dotnet publish -c Release -r linux-arm64
-
-# Run on Linux
-./bin/Release/net9.0/linux-arm64/publish/ShellDemo
-```
-
-## Event Logging
-
-Each page features an event log panel that displays control interactions in real-time:
-
-```
-[14:32:15] 3. Button clicked: Primary
-[14:32:12] 2. Slider value: 75
-[14:32:08] 1. CheckBox: Checked
-```
-
-## Controls Reference
-
-| Control | Properties Demonstrated |
-|---------|------------------------|
-| Button | Text, BackgroundColor, TextColor, CornerRadius, IsEnabled, WidthRequest, HeightRequest |
-| Entry | Placeholder, Text, IsPassword, Keyboard, FontSize |
-| Editor | Placeholder, Text, HeightRequest |
-| SearchBar | Placeholder, Text, SearchButtonPressed |
-| CheckBox | IsChecked, Color, IsEnabled |
-| Switch | IsToggled, OnColor, IsEnabled |
-| Slider | Minimum, Maximum, Value, MinimumTrackColor, MaximumTrackColor, ThumbColor |
-| Picker | Title, Items, SelectedIndex, TextColor, TitleColor |
-| DatePicker | Date, MinimumDate, MaximumDate, TextColor |
-| TimePicker | Time, TextColor |
-| CollectionView | ItemsSource, SelectionMode, SelectionChanged, HeightRequest |
-| ProgressBar | Progress, ProgressColor |
-| ActivityIndicator | IsRunning, Color |
-| Label | Text, FontSize, FontAttributes, TextColor |
-| Frame | CornerRadius, Padding, BackgroundColor |
-| Grid | RowDefinitions, ColumnDefinitions, RowSpacing, ColumnSpacing |
-| StackLayout | Spacing, Padding, Orientation |
-| ScrollView | Content scrolling |
-
-## License
-
-MIT License - See repository root for details.
diff --git a/samples/ShellDemo/ShellDemo.csproj b/samples/ShellDemo/ShellDemo.csproj
deleted file mode 100644
index 1c0d871..0000000
--- a/samples/ShellDemo/ShellDemo.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- Exe
- net9.0
- enable
- enable
- true
-
-
-
-
-
-
-
diff --git a/samples/TodoApp/App.cs b/samples/TodoApp/App.cs
deleted file mode 100644
index 7ffbb8d..0000000
--- a/samples/TodoApp/App.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// TodoApp - Main Application with NavigationPage
-
-using Microsoft.Maui.Controls;
-
-namespace TodoApp;
-
-public class App : Application
-{
- public static NavigationPage? NavigationPage { get; private set; }
-
- public App()
- {
- NavigationPage = new NavigationPage(new TodoListPage())
- {
- Title = "OpenMaui Todo App",
- BarBackgroundColor = Color.FromArgb("#2196F3"),
- BarTextColor = Colors.White
- };
- MainPage = NavigationPage;
- }
-}
diff --git a/samples/TodoApp/MauiProgram.cs b/samples/TodoApp/MauiProgram.cs
deleted file mode 100644
index 94b7677..0000000
--- a/samples/TodoApp/MauiProgram.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// MauiProgram.cs - MAUI app configuration
-
-using Microsoft.Maui.Hosting;
-using Microsoft.Maui.Platform.Linux.Hosting;
-
-namespace TodoApp;
-
-public static class MauiProgram
-{
- public static MauiApp CreateMauiApp()
- {
- var builder = MauiApp.CreateBuilder();
-
- // Configure the app
- builder.UseMauiApp();
-
- // Add Linux platform support with all handlers
- builder.UseLinux();
-
- return builder.Build();
- }
-}
diff --git a/samples/TodoApp/NewTodoPage.xaml b/samples/TodoApp/NewTodoPage.xaml
deleted file mode 100644
index 7f4f1a4..0000000
--- a/samples/TodoApp/NewTodoPage.xaml
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
- #5C6BC0
- #26A69A
- #212121
- #757575
- #FFFFFF
- #E8EAF6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/TodoApp/NewTodoPage.xaml.cs b/samples/TodoApp/NewTodoPage.xaml.cs
deleted file mode 100644
index ed1c90b..0000000
--- a/samples/TodoApp/NewTodoPage.xaml.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// NewTodoPage - Create a new todo item
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-
-namespace TodoApp;
-
-public partial class NewTodoPage : ContentPage
-{
- private readonly TodoService _service = TodoService.Instance;
-
- public NewTodoPage()
- {
- InitializeComponent();
- }
-
- private async void OnSaveClicked(object? sender, EventArgs e)
- {
- var title = TitleEntry.Text?.Trim();
-
- if (string.IsNullOrEmpty(title))
- {
- TitleEntry.Placeholder = "Title is required!";
- TitleEntry.PlaceholderColor = Colors.Red;
- return;
- }
-
- _service.AddTodo(title, NotesEditor.Text ?? "");
- await Navigation.PopAsync();
- }
-}
diff --git a/samples/TodoApp/Program.cs b/samples/TodoApp/Program.cs
deleted file mode 100644
index 1602090..0000000
--- a/samples/TodoApp/Program.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Program.cs - Linux platform entry point
-
-using Microsoft.Maui.Platform.Linux;
-
-namespace TodoApp;
-
-class Program
-{
- static void Main(string[] args)
- {
- // Redirect console output to a log file for debugging
- var logPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "todoapp.log");
- using var logWriter = new StreamWriter(logPath, append: false) { AutoFlush = true };
- var multiWriter = new MultiTextWriter(Console.Out, logWriter);
- Console.SetOut(multiWriter);
- Console.SetError(multiWriter);
-
- // Global exception handler
- AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
- {
- var ex = e.ExceptionObject as Exception;
- Console.WriteLine($"[FATAL] Unhandled exception: {ex?.GetType().Name}: {ex?.Message}");
- Console.WriteLine($"[FATAL] Stack trace: {ex?.StackTrace}");
- if (ex?.InnerException != null)
- {
- Console.WriteLine($"[FATAL] Inner exception: {ex.InnerException.GetType().Name}: {ex.InnerException.Message}");
- Console.WriteLine($"[FATAL] Inner stack trace: {ex.InnerException.StackTrace}");
- }
- };
-
- TaskScheduler.UnobservedTaskException += (sender, e) =>
- {
- Console.WriteLine($"[FATAL] Unobserved task exception: {e.Exception?.GetType().Name}: {e.Exception?.Message}");
- Console.WriteLine($"[FATAL] Stack trace: {e.Exception?.StackTrace}");
- e.SetObserved(); // Prevent crash
- };
-
- Console.WriteLine($"[Program] Starting TodoApp at {DateTime.Now}");
- Console.WriteLine($"[Program] Log file: {logPath}");
-
- try
- {
- // Create the MAUI app with all handlers registered
- var app = MauiProgram.CreateMauiApp();
-
- // Run on Linux platform
- LinuxApplication.Run(app, args);
- }
- catch (Exception ex)
- {
- Console.WriteLine($"[FATAL] Exception in Main: {ex.GetType().Name}: {ex.Message}");
- Console.WriteLine($"[FATAL] Stack trace: {ex.StackTrace}");
- throw;
- }
- }
-}
-
-// Helper to write to both console and file
-class MultiTextWriter : TextWriter
-{
- private readonly TextWriter[] _writers;
- public MultiTextWriter(params TextWriter[] writers) => _writers = writers;
- public override System.Text.Encoding Encoding => System.Text.Encoding.UTF8;
- public override void Write(char value) { foreach (var w in _writers) w.Write(value); }
- public override void WriteLine(string? value) { foreach (var w in _writers) w.WriteLine(value); }
- public override void Flush() { foreach (var w in _writers) w.Flush(); }
-}
diff --git a/samples/TodoApp/README.md b/samples/TodoApp/README.md
deleted file mode 100644
index 67c5f85..0000000
--- a/samples/TodoApp/README.md
+++ /dev/null
@@ -1,111 +0,0 @@
-# TodoApp Sample
-
-A complete task management application demonstrating OpenMaui Linux capabilities with real-world XAML patterns.
-
-## Features
-
-- **NavigationPage** - Full page navigation with back button support
-- **CollectionView** - Scrollable list with data binding and selection
-- **XAML Data Binding** - Value converters for dynamic styling
-- **DisplayAlert Dialogs** - Confirmation dialogs for delete actions
-- **Grid Layouts** - Complex layouts with star sizing for expanding content
-- **Entry & Editor** - Single and multi-line text input
-- **Border with RoundRectangle** - Modern card-style UI
-- **ToolbarItems** - Navigation bar actions
-
-## Screenshots
-
-The app consists of three pages:
-
-1. **TodoListPage** - Shows all tasks with completion status indicators
-2. **NewTodoPage** - Create a new task with title and notes
-3. **TodoDetailPage** - View/edit task details, mark complete, or delete
-
-## Architecture
-
-```
-TodoApp/
-├── App.cs # Application entry with NavigationPage
-├── Program.cs # Linux platform bootstrap
-├── MauiProgram.cs # MAUI app builder
-├── TodoItem.cs # Data model
-├── TodoService.cs # In-memory data store
-├── TodoListPage.xaml(.cs) # Main list view
-├── NewTodoPage.xaml(.cs) # Create task page
-└── TodoDetailPage.xaml(.cs) # Task detail/edit page
-```
-
-## XAML Highlights
-
-### Value Converters
-The app uses custom converters for dynamic styling based on completion status:
-- `CompletedToColorConverter` - Gray text for completed items
-- `CompletedToTextDecorationsConverter` - Strikethrough for completed items
-- `CompletedToOpacityConverter` - Fade completed items
-- `AlternatingRowColorConverter` - Alternating background colors
-
-### ResourceDictionary
-```xml
-
- #5C6BC0
- #26A69A
- #212121
-
-```
-
-### CollectionView with DataTemplate
-```xml
-
-
-
-
-
-
-
-
-
-```
-
-### Grid with Star Rows (Expanding Editor)
-```xml
-
-
-
-
-
-
-
-```
-
-## Building and Running
-
-```bash
-# From the maui-linux-push directory
-cd samples/TodoApp
-dotnet publish -c Release -r linux-arm64
-
-# Run on Linux
-./bin/Release/net9.0/linux-arm64/publish/TodoApp
-```
-
-## Controls Demonstrated
-
-| Control | Usage |
-|---------|-------|
-| NavigationPage | App navigation container |
-| ContentPage | Individual screens |
-| CollectionView | Task list with selection |
-| Grid | Page layouts |
-| VerticalStackLayout | Vertical grouping |
-| HorizontalStackLayout | Horizontal grouping |
-| Label | Text display |
-| Entry | Single-line input |
-| Editor | Multi-line input |
-| Button | Toolbar actions |
-| Border | Card styling with rounded corners |
-| CheckBox | Completion toggle |
-| BoxView | Visual separators |
-
-## License
-
-MIT License - See repository root for details.
diff --git a/samples/TodoApp/TodoApp.csproj b/samples/TodoApp/TodoApp.csproj
deleted file mode 100644
index 1c0d871..0000000
--- a/samples/TodoApp/TodoApp.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- Exe
- net9.0
- enable
- enable
- true
-
-
-
-
-
-
-
diff --git a/samples/TodoApp/TodoDetailPage.xaml b/samples/TodoApp/TodoDetailPage.xaml
deleted file mode 100644
index ea8037a..0000000
--- a/samples/TodoApp/TodoDetailPage.xaml
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
- #5C6BC0
- #26A69A
- #EF5350
- #212121
- #757575
- #FFFFFF
- #E8EAF6
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/TodoApp/TodoDetailPage.xaml.cs b/samples/TodoApp/TodoDetailPage.xaml.cs
deleted file mode 100644
index d0d1df5..0000000
--- a/samples/TodoApp/TodoDetailPage.xaml.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-// TodoDetailPage - View and edit a todo item
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-using Microsoft.Maui.Platform;
-
-namespace TodoApp;
-
-public partial class TodoDetailPage : ContentPage
-{
- private readonly TodoItem _todo;
- private readonly TodoService _service = TodoService.Instance;
-
- // Colors for status label
- private static readonly Color AccentColor = Color.FromArgb("#26A69A");
- private static readonly Color TextPrimary = Color.FromArgb("#212121");
-
- public TodoDetailPage(TodoItem todo)
- {
- try
- {
- Console.WriteLine($"[TodoDetailPage] Constructor starting for: {todo.Title}");
- InitializeComponent();
- Console.WriteLine($"[TodoDetailPage] InitializeComponent complete");
-
- _todo = todo;
-
- // Populate fields
- Console.WriteLine($"[TodoDetailPage] Setting TitleEntry.Text");
- TitleEntry.Text = _todo.Title;
- Console.WriteLine($"[TodoDetailPage] Setting NotesEditor.Text");
- NotesEditor.Text = _todo.Notes;
- Console.WriteLine($"[TodoDetailPage] Setting CompletedCheckBox.IsChecked");
- CompletedCheckBox.IsChecked = _todo.IsCompleted;
- Console.WriteLine($"[TodoDetailPage] Calling UpdateStatusLabel");
- UpdateStatusLabel(_todo.IsCompleted);
- Console.WriteLine($"[TodoDetailPage] Setting CreatedLabel.Text");
- CreatedLabel.Text = $"Created {_todo.CreatedAt:MMMM d, yyyy} at {_todo.CreatedAt:h:mm tt}";
- Console.WriteLine($"[TodoDetailPage] Constructor complete");
- }
- catch (Exception ex)
- {
- Console.WriteLine($"[TodoDetailPage] EXCEPTION in constructor: {ex.GetType().Name}: {ex.Message}");
- Console.WriteLine($"[TodoDetailPage] Stack trace: {ex.StackTrace}");
- throw;
- }
- }
-
- private void OnCompletedChanged(object? sender, Microsoft.Maui.Controls.CheckedChangedEventArgs e)
- {
- Console.WriteLine($"[TodoDetailPage] OnCompletedChanged: {e.Value}");
- UpdateStatusLabel(e.Value);
- }
-
- private void UpdateStatusLabel(bool isCompleted)
- {
- if (StatusLabel == null)
- {
- Console.WriteLine($"[TodoDetailPage] UpdateStatusLabel: StatusLabel is null, skipping");
- return;
- }
- Console.WriteLine($"[TodoDetailPage] UpdateStatusLabel: setting to {(isCompleted ? "Completed" : "In Progress")}");
- StatusLabel.Text = isCompleted ? "Completed" : "In Progress";
- StatusLabel.TextColor = isCompleted ? AccentColor : TextPrimary;
- }
-
- private async void OnSaveClicked(object? sender, EventArgs e)
- {
- _todo.Title = TitleEntry.Text ?? "";
- _todo.Notes = NotesEditor.Text ?? "";
- _todo.IsCompleted = CompletedCheckBox.IsChecked;
-
- await Navigation.PopAsync();
- }
-
- private async void OnDeleteClicked(object? sender, EventArgs e)
- {
- // Show confirmation dialog
- var confirmed = await LinuxDialogService.ShowAlertAsync(
- "Delete Task",
- $"Are you sure you want to delete \"{_todo.Title}\"? This action cannot be undone.",
- "Delete",
- "Cancel");
-
- if (confirmed)
- {
- _service.DeleteTodo(_todo);
- await Navigation.PopAsync();
- }
- }
-}
diff --git a/samples/TodoApp/TodoItem.cs b/samples/TodoApp/TodoItem.cs
deleted file mode 100644
index e7ab47c..0000000
--- a/samples/TodoApp/TodoItem.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-// TodoItem - Data model for a todo item
-
-using System.ComponentModel;
-
-namespace TodoApp;
-
-public class TodoItem : INotifyPropertyChanged
-{
- private string _title = "";
- private string _notes = "";
- private bool _isCompleted;
- private DateTime _dueDate;
-
- public int Id { get; set; }
-
- ///
- /// Index in the collection for alternating row colors.
- ///
- public int Index { get; set; }
-
- public string Title
- {
- get => _title;
- set
- {
- if (_title != value)
- {
- _title = value;
- OnPropertyChanged(nameof(Title));
- }
- }
- }
-
- public string Notes
- {
- get => _notes;
- set
- {
- if (_notes != value)
- {
- _notes = value;
- OnPropertyChanged(nameof(Notes));
- }
- }
- }
-
- public bool IsCompleted
- {
- get => _isCompleted;
- set
- {
- if (_isCompleted != value)
- {
- _isCompleted = value;
- OnPropertyChanged(nameof(IsCompleted));
- }
- }
- }
-
- public DateTime DueDate
- {
- get => _dueDate;
- set
- {
- if (_dueDate != value)
- {
- _dueDate = value;
- OnPropertyChanged(nameof(DueDate));
- }
- }
- }
-
- public DateTime CreatedAt { get; set; } = DateTime.Now;
-
- public event PropertyChangedEventHandler? PropertyChanged;
-
- protected void OnPropertyChanged(string propertyName)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
-}
diff --git a/samples/TodoApp/TodoListPage.xaml b/samples/TodoApp/TodoListPage.xaml
deleted file mode 100644
index 9299260..0000000
--- a/samples/TodoApp/TodoListPage.xaml
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
- #5C6BC0
- #3949AB
- #26A69A
- #212121
- #757575
- #FFFFFF
- #E0E0E0
- #9E9E9E
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/samples/TodoApp/TodoListPage.xaml.cs b/samples/TodoApp/TodoListPage.xaml.cs
deleted file mode 100644
index 204541b..0000000
--- a/samples/TodoApp/TodoListPage.xaml.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-// TodoListPage - Main page for viewing todos with XAML support
-
-using Microsoft.Maui.Controls;
-using Microsoft.Maui.Graphics;
-using System.Globalization;
-
-namespace TodoApp;
-
-public partial class TodoListPage : ContentPage
-{
- private readonly TodoService _service = TodoService.Instance;
-
- public TodoListPage()
- {
- Console.WriteLine("[TodoListPage] Constructor starting");
- InitializeComponent();
-
- TodoCollectionView.ItemsSource = _service.Todos;
- UpdateStats();
-
- Console.WriteLine("[TodoListPage] Constructor finished");
- }
-
- protected override void OnAppearing()
- {
- Console.WriteLine("[TodoListPage] OnAppearing called - refreshing CollectionView");
- base.OnAppearing();
-
- // Refresh indexes for alternating row colors
- _service.RefreshIndexes();
-
- // Refresh the collection view
- TodoCollectionView.ItemsSource = null;
- TodoCollectionView.ItemsSource = _service.Todos;
- Console.WriteLine($"[TodoListPage] ItemsSource set with {_service.Todos.Count} items");
- UpdateStats();
- }
-
- private async void OnAddClicked(object sender, EventArgs e)
- {
- await Navigation.PushAsync(new NewTodoPage());
- }
-
- private async void OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
- {
- try
- {
- Console.WriteLine($"[TodoListPage] OnSelectionChanged: {e.CurrentSelection.Count} items selected");
- if (e.CurrentSelection.FirstOrDefault() is TodoItem todo)
- {
- Console.WriteLine($"[TodoListPage] Navigating to TodoDetailPage for: {todo.Title}");
- TodoCollectionView.SelectedItem = null; // Deselect
- var detailPage = new TodoDetailPage(todo);
- Console.WriteLine($"[TodoListPage] Created TodoDetailPage, pushing...");
- await Navigation.PushAsync(detailPage);
- Console.WriteLine($"[TodoListPage] Navigation complete");
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine($"[TodoListPage] EXCEPTION in OnSelectionChanged: {ex.GetType().Name}: {ex.Message}");
- Console.WriteLine($"[TodoListPage] Stack trace: {ex.StackTrace}");
- }
- }
-
- private void UpdateStats()
- {
- var completed = _service.CompletedCount;
- var total = _service.TotalCount;
-
- if (total == 0)
- {
- StatsLabel.Text = "";
- }
- else
- {
- StatsLabel.Text = $"{completed} of {total} completed";
- }
- }
-}
-
-///
-/// Converter for alternating row background colors.
-///
-public class AlternatingRowColorConverter : IValueConverter
-{
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- if (value is int index)
- {
- return index % 2 == 0 ? Colors.White : Color.FromArgb("#F5F5F5");
- }
- return Colors.White;
- }
-
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
-}
-
-///
-/// Converter for completed task text color and indicator color.
-///
-public class CompletedToColorConverter : IValueConverter
-{
- // Define colors
- private static readonly Color PrimaryColor = Color.FromArgb("#5C6BC0");
- private static readonly Color AccentColor = Color.FromArgb("#26A69A");
- private static readonly Color CompletedColor = Color.FromArgb("#9E9E9E");
- private static readonly Color TextPrimary = Color.FromArgb("#212121");
- private static readonly Color TextSecondary = Color.FromArgb("#757575");
-
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- bool isCompleted = value is bool b && b;
- string param = parameter as string ?? "";
-
- // Indicator bar color
- if (param == "indicator")
- {
- return isCompleted ? CompletedColor : AccentColor;
- }
-
- // Text colors
- if (isCompleted)
- {
- return CompletedColor;
- }
- else
- {
- return param == "notes" ? TextSecondary : TextPrimary;
- }
- }
-
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
-}
-
-///
-/// Converter for completed task text decorations (strikethrough).
-///
-public class CompletedToTextDecorationsConverter : IValueConverter
-{
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- bool isCompleted = value is bool b && b;
- return isCompleted ? TextDecorations.Strikethrough : TextDecorations.None;
- }
-
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
-}
-
-///
-/// Converter for completed task opacity (slightly faded when complete).
-///
-public class CompletedToOpacityConverter : IValueConverter
-{
- public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- bool isCompleted = value is bool b && b;
- return isCompleted ? 0.7 : 1.0;
- }
-
- public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
- {
- throw new NotImplementedException();
- }
-}
diff --git a/samples/TodoApp/TodoService.cs b/samples/TodoApp/TodoService.cs
deleted file mode 100644
index f03844b..0000000
--- a/samples/TodoApp/TodoService.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// TodoService - Manages todo items
-
-using System.Collections.ObjectModel;
-
-namespace TodoApp;
-
-public class TodoService
-{
- private static TodoService? _instance;
- public static TodoService Instance => _instance ??= new TodoService();
-
- private int _nextId = 1;
-
- public ObservableCollection Todos { get; } = new();
-
- private TodoService()
- {
- // Add sample todos with varying lengths to test MaxLines=2 with ellipsis
- AddTodo("Learn OpenMaui Linux", "Explore the SkiaSharp-based rendering engine for .NET MAUI on Linux desktop. This is a very long description that should wrap to multiple lines and demonstrate the ellipsis truncation feature when MaxLines is set to 2.");
- AddTodo("Build amazing apps", "Create cross-platform applications that run on Windows, macOS, iOS, Android, and Linux! With OpenMaui, you can write once and deploy everywhere.");
- AddTodo("Share with the community", "Contribute to the open-source project and help others build great Linux apps. Join our growing community of developers who are passionate about bringing .NET MAUI to Linux.");
- }
-
- public TodoItem AddTodo(string title, string notes = "")
- {
- var todo = new TodoItem
- {
- Id = _nextId++,
- Index = Todos.Count, // Set index for alternating row colors
- Title = title,
- Notes = notes,
- DueDate = DateTime.Today.AddDays(7)
- };
- Todos.Add(todo);
- return todo;
- }
-
- ///
- /// Refreshes the Index property on all items for alternating row colors.
- ///
- public void RefreshIndexes()
- {
- for (int i = 0; i < Todos.Count; i++)
- {
- Todos[i].Index = i;
- }
- }
-
- public TodoItem? GetTodo(int id)
- {
- return Todos.FirstOrDefault(t => t.Id == id);
- }
-
- public void DeleteTodo(TodoItem todo)
- {
- Todos.Remove(todo);
- }
-
- public int CompletedCount => Todos.Count(t => t.IsCompleted);
- public int TotalCount => Todos.Count;
-}