mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-27 04:09:37 +08:00
feat(Browser): add palette showcase with tab fallbacks
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
using AtomUIGallery.ShowCases.AboutUs;
|
||||
using AtomUIGallery.ShowCases.Palette;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Imaging;
|
||||
@@ -11,6 +13,10 @@ namespace AtomUIGallery.Browser;
|
||||
|
||||
internal sealed class BrowserGalleryView : UserControl, IScreen
|
||||
{
|
||||
private readonly Border _aboutUsNavigationItem;
|
||||
private readonly Border _paletteNavigationItem;
|
||||
private readonly ContentControl _contentHost;
|
||||
|
||||
public RoutingState Router { get; } = new();
|
||||
|
||||
public BrowserGalleryView()
|
||||
@@ -46,6 +52,9 @@ internal sealed class BrowserGalleryView : UserControl, IScreen
|
||||
};
|
||||
Grid.SetColumnSpan(header, 2);
|
||||
|
||||
_aboutUsNavigationItem = CreateNavigationItem("AboutUs", () => ShowAboutUs());
|
||||
_paletteNavigationItem = CreateNavigationItem("Palette", () => ShowPalette());
|
||||
|
||||
var navigation = new Border
|
||||
{
|
||||
BorderBrush = new SolidColorBrush(Color.Parse("#E5E7EB")),
|
||||
@@ -64,23 +73,16 @@ internal sealed class BrowserGalleryView : UserControl, IScreen
|
||||
FontWeight = FontWeight.SemiBold,
|
||||
Foreground = new SolidColorBrush(Color.Parse("#374151"))
|
||||
},
|
||||
new TextBlock
|
||||
{
|
||||
Text = "AboutUs",
|
||||
FontSize = 14,
|
||||
Foreground = new SolidColorBrush(Color.Parse("#111827"))
|
||||
}
|
||||
_aboutUsNavigationItem,
|
||||
_paletteNavigationItem
|
||||
}
|
||||
}
|
||||
};
|
||||
Grid.SetRow(navigation, 1);
|
||||
|
||||
var aboutUsPage = new AboutUsPage
|
||||
{
|
||||
DataContext = new AboutUsViewModel(this)
|
||||
};
|
||||
Grid.SetColumn(aboutUsPage, 1);
|
||||
Grid.SetRow(aboutUsPage, 1);
|
||||
_contentHost = new ContentControl();
|
||||
Grid.SetColumn(_contentHost, 1);
|
||||
Grid.SetRow(_contentHost, 1);
|
||||
|
||||
Content = new Grid
|
||||
{
|
||||
@@ -91,9 +93,11 @@ internal sealed class BrowserGalleryView : UserControl, IScreen
|
||||
{
|
||||
header,
|
||||
navigation,
|
||||
aboutUsPage
|
||||
_contentHost
|
||||
}
|
||||
};
|
||||
|
||||
ShowAboutUs();
|
||||
}
|
||||
|
||||
private static Bitmap LoadGalleryLogo()
|
||||
@@ -101,4 +105,58 @@ internal sealed class BrowserGalleryView : UserControl, IScreen
|
||||
using var stream = AssetLoader.Open(new Uri("avares://AtomUIGallery.Browser/Assets/gallery-logo.png"));
|
||||
return new Bitmap(stream);
|
||||
}
|
||||
|
||||
private Border CreateNavigationItem(string text, Action navigate)
|
||||
{
|
||||
var item = new Border
|
||||
{
|
||||
CornerRadius = new CornerRadius(4),
|
||||
Padding = new Thickness(8, 6),
|
||||
Cursor = new Cursor(StandardCursorType.Hand),
|
||||
Child = new TextBlock
|
||||
{
|
||||
Text = text,
|
||||
FontSize = 14,
|
||||
Foreground = new SolidColorBrush(Color.Parse("#111827"))
|
||||
}
|
||||
};
|
||||
item.PointerPressed += (_, _) => navigate();
|
||||
return item;
|
||||
}
|
||||
|
||||
private void ShowAboutUs()
|
||||
{
|
||||
_contentHost.Content = new AboutUsPage
|
||||
{
|
||||
DataContext = new AboutUsViewModel(this)
|
||||
};
|
||||
UpdateNavigationSelection(_aboutUsNavigationItem);
|
||||
}
|
||||
|
||||
private void ShowPalette()
|
||||
{
|
||||
_contentHost.Content = new PaletteShowCase
|
||||
{
|
||||
DataContext = new PaletteViewModel(this)
|
||||
};
|
||||
UpdateNavigationSelection(_paletteNavigationItem);
|
||||
}
|
||||
|
||||
private void UpdateNavigationSelection(Border selectedItem)
|
||||
{
|
||||
ApplyNavigationItemState(_aboutUsNavigationItem, selectedItem == _aboutUsNavigationItem);
|
||||
ApplyNavigationItemState(_paletteNavigationItem, selectedItem == _paletteNavigationItem);
|
||||
}
|
||||
|
||||
private static void ApplyNavigationItemState(Border item, bool isSelected)
|
||||
{
|
||||
item.Background = isSelected
|
||||
? new SolidColorBrush(Color.Parse("#F3F4F6"))
|
||||
: Brushes.Transparent;
|
||||
|
||||
if (item.Child is TextBlock textBlock)
|
||||
{
|
||||
textBlock.FontWeight = isSelected ? FontWeight.SemiBold : FontWeight.Normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# AtomUI Gallery Browser 改造问题记录
|
||||
|
||||
本文档记录 2026-06-07 进行 `AtomUIGallery.Browser` 初步改造时遇到的问题、根因和处理结论。当前目标是先让 Browser Gallery 以薄封装方式复用共享 `AtomUIGallery` 的 `AboutUsPage`,并允许 Browser 项目引用 `AtomUI.Desktop.Controls`,由控件库内部自动降级。
|
||||
本文档记录 2026-06-07 进行 `AtomUIGallery.Browser` 初步改造时遇到的问题、根因和处理结论。当前目标是让 Browser Gallery 以薄封装方式复用共享 `AtomUIGallery` 的 ShowCase,并允许 Browser 项目引用 `AtomUI.Desktop.Controls`,由控件库内部自动降级。
|
||||
|
||||
## 本轮目标
|
||||
|
||||
- 新增 Browser Gallery 项目并跑通空壳应用。
|
||||
- Browser 启动阶段使用 AtomUI 红色 SVG logo。
|
||||
- Browser Gallery 不复制 `AboutUsPage`,只做一层薄的宿主封装。
|
||||
- Browser Gallery 不复制 `AboutUsPage` / `PaletteShowCase`,只做一层薄的宿主封装。
|
||||
- Browser 可以引用 `AtomUI.Desktop.Controls`,用户侧继续调用 `UseDesktopControls()`,控件库内部按平台自动降级。
|
||||
- 不改变公开 API,不影响 Desktop Gallery 原有行为。
|
||||
|
||||
@@ -53,13 +53,18 @@ this.UseAtomUI(builder =>
|
||||
});
|
||||
```
|
||||
|
||||
`BrowserGalleryView` 只负责 Browser 单视图宿主和导航外壳,内容直接创建共享页面:
|
||||
`BrowserGalleryView` 只负责 Browser 单视图宿主、导航外壳和当前 ShowCase 切换,内容直接创建共享页面:
|
||||
|
||||
```csharp
|
||||
var aboutUsPage = new AboutUsPage
|
||||
{
|
||||
DataContext = new AboutUsViewModel(this)
|
||||
};
|
||||
|
||||
var paletteShowCase = new PaletteShowCase
|
||||
{
|
||||
DataContext = new PaletteViewModel(this)
|
||||
};
|
||||
```
|
||||
|
||||
### Common 控件降级
|
||||
@@ -101,12 +106,13 @@ themeManagerBuilder.AddControlThemesProvider(RuntimePlatform.Features.SupportsNa
|
||||
: new BrowserDesktopControlThemesProvider());
|
||||
```
|
||||
|
||||
Browser desktop provider 当前只承载 `AboutUsPage` 需要的最小集合:
|
||||
Browser desktop provider 当前只承载 `AboutUsPage` 和 `PaletteShowCase` 需要的最小集合:
|
||||
|
||||
```text
|
||||
Buttons/Themes/HyperLinkButtonTheme.axaml
|
||||
Buttons/Themes/BrowserButtonThemes.axaml
|
||||
GroupBox/Themes/GroupBoxTheme.axaml
|
||||
ScrollViewer/Themes/ScrollViewerThemes.axaml
|
||||
TabControl/Themes/TabControlThemes.axaml
|
||||
```
|
||||
|
||||
Browser token 当前只注册:
|
||||
@@ -114,7 +120,9 @@ Browser token 当前只注册:
|
||||
```text
|
||||
ButtonToken
|
||||
GroupBoxToken
|
||||
MenuToken
|
||||
ScrollViewerToken
|
||||
TabControlToken
|
||||
```
|
||||
|
||||
Desktop 下仍然使用完整 `ControlTokenTypePool` 和 `DesktopControlThemesProvider`,并继续注册原有 initialized handler。Browser 下跳过该 handler,避免注册 Window/Tooltip/媒体断点等 native window 相关逻辑。
|
||||
@@ -146,7 +154,7 @@ dotnet build controlgallery/AtomUIGallery.Desktop/AtomUIGallery.Desktop.csproj -
|
||||
|
||||
- Browser Debug build 通过。
|
||||
- Desktop Gallery Debug build 通过。
|
||||
- Browser 实跑 `AboutUsPage` 渲染成功,无 `.splash-error`。
|
||||
- Browser 实跑 `AboutUsPage` / `PaletteShowCase` 渲染成功,无 `.splash-error`。
|
||||
|
||||
Browser 运行验证时不要只依赖 DOM 文本,因为 Avalonia Browser 页面内容主要在 canvas 中绘制;需要结合 splash error 和截图。
|
||||
|
||||
@@ -162,6 +170,6 @@ Browser 运行验证时不要只依赖 DOM 文本,因为 Avalonia Browser 页
|
||||
## 待继续处理
|
||||
|
||||
- `UseDesktopColorPicker()` 和 `UseDesktopDataGrid()` 尚未接入 Browser 降级路径。
|
||||
- Browser Gallery 当前只接入 `AboutUsPage`,完整 Workspace / AppView / AppShell 还未实现。
|
||||
- Browser Gallery 当前只接入 `AboutUsPage` 和 `PaletteShowCase`,完整 Workspace / AppView / AppShell 还未实现。
|
||||
- `BrowserDesktopControlThemesProvider` 的范围后续应随着 ShowCase 迁移逐步扩大,并保持最小可用集合。
|
||||
- `EmbeddableControlRootTheme` 在 Browser 下的精确不兼容点后续可以进一步拆解;当前先通过 Browser provider 排除该资源,保证启动路径稳定。
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
x:Class="AtomUI.Desktop.Controls.BrowserDesktopControlThemesProvider"
|
||||
Id="AtomUI.Desktop.Controls">
|
||||
<atom:ControlThemesProvider.ControlThemes>
|
||||
<ResourceInclude Source="Buttons/Themes/HyperLinkButtonTheme.axaml" />
|
||||
<ResourceInclude Source="Buttons/Themes/BrowserButtonThemes.axaml" />
|
||||
<ResourceInclude Source="GroupBox/Themes/GroupBoxTheme.axaml" />
|
||||
<ResourceInclude Source="ScrollViewer/Themes/ScrollViewerThemes.axaml" />
|
||||
<ResourceInclude Source="TabControl/Themes/TabControlThemes.axaml" />
|
||||
</atom:ControlThemesProvider.ControlThemes>
|
||||
</atom:ControlThemesProvider>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:atom="https://atomui.net"
|
||||
x:ClassModifier="internal">
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceInclude Source="HyperLinkButtonTheme.axaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<atom:IconButtonTheme x:Key="{x:Type atom:IconButton}" TargetType="atom:IconButton" />
|
||||
</ResourceDictionary>
|
||||
@@ -60,7 +60,9 @@ public static class ThemeManagerBuilderExtensions
|
||||
{
|
||||
typeof(ButtonToken),
|
||||
typeof(GroupBoxToken),
|
||||
typeof(ScrollViewerToken)
|
||||
typeof(MenuToken),
|
||||
typeof(ScrollViewerToken),
|
||||
typeof(TabControlToken)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user