Skip to content

Feature/image gallery - #2

Merged
qinware merged 8 commits into
AtomUI:release/6.0from
kusarparlly:feature/image-gallery
Aug 29, 2026
Merged

qinware merged 8 commits into
AtomUI:release/6.0from
kusarparlly:feature/image-gallery

Conversation

@kusarparlly

Copy link
Copy Markdown
Contributor

概述

本 PR 为 AtomUI.Labs 新增实验控件 ImageGalleryAtomUI.Labs.Controls.ImageGallery):一个面向图片集合浏览的沉浸式主图查看器,由主图视口(Viewport)、浮动工具栏(Toolbar)与虚拟化缩略图走廊(Filmstrip)共同组成,而不是把图片排成行列的缩略图网格。

遵循 Labs 多包规范:独立项目、独立 NuGet 包、独立测试项目,AXAML 命名空间 https://atomui.net/labs(推荐前缀 atom.labs)。

  • 新增控件源码、测试、Benchmark、设计/验证文档与 Gallery 展示页,共 102 个文件、约 1.7 万行
  • 运行时依赖仅 AtomUI.CoreAvalonia,不依赖 AtomUI Desktop Controls 与 GalleryBase
  • net10.0 / net8.0 双 TFM,NativeAOT / trimming 友好

动机

图片集合浏览在桌面应用中是高频场景,但通用列表/网格控件无法提供「主图查看 + 缩放平移 + 相邻导航 + 大集合缩略条」的一体化体验。ImageGallery 以 SelectingItemsControl 为根,把选择模型、加载调度、内存预算与资源所有权收敛为一个可托管、可验证的封闭模板控件,同时通过强类型合同和属性级 Appearance 保持必要的开放度。

功能特性

主图视口(Viewport)

  • 显示模式 Fit / ActualSize / Custom,原子缩放范围(ZoomRange="0.05,32"),切换图片自动回到 Fit 并清零旋转与平移
  • 指针锚点缩放、滚轮缩放(Always / ControlModifier / Disabled)、Pinch 连续缩放与双指平移、拖拽平移(含边界与输入状态机)
  • 临时查看旋转(0/90/180/270);主图相邻导航与缩略图走廊共享同一协调路径,支持循环导航开关
  • Empty / Loading / Ready / Error 状态视觉合同;解码清晰度升级(先快速呈现、再无缝升级清晰度);失败仅隔离在当前项,不污染选择与导航

浮动工具栏(Toolbar)

  • 标题、缩放状态与操作入口(放大/缩小/Fit/ActualSize/旋转),支持 ToolbarContent 追加自定义操作区
  • 四边放置;与缩略图走廊同边请求时自动对边规整、相邻边沿边避让,Normal / Compact / Minimal 单调响应式降级

缩略图走廊(Filmstrip)

  • 四边放置、方向与边距规则内建;Add Image 按钮 + Previous/Next + 缩略图条
  • 真实虚拟化与容器回收:10 万项集合下容器数稳定受 Rmax = ceil(2L/P) + 4 约束,与集合规模无关
  • 缩略图内存预算(默认 32 MiB)、解码尺寸分档、加载调度与失败后再次加载准入

集合与选择合同

  • 复用 SelectingItemsControlSelectedIndex / SelectedItem / SelectionChanged 合同,固定单选
  • 强类型项目合同 IImageGalleryItem / ImageGalleryItemKey / Title / MainImageSource / ThumbnailImageSource),不做反射式属性路径猜测
  • 完整集合变化语义:Add / Insert / Remove / RemoveRange / Replace / Move / Reset 全部按稳定 Key 身份保持或恢复选择(含位置回退)

图片源抽象与加载安全

  • IImageGallerySource 统一抽象;内置 FromFile / FromAvaloniaResource / FromHttp / FromStreamCreate 作为自定义解码与释放策略的逃生口
  • 首版保证 PNG、JPEG/JPG、BMP、静态 WebP;EXIF Orientation 在返回前修正;多帧图片不静默退化
  • ImageGalleryLoadLimits 原子安全限制(编码字节 / 像素总数 / 单边尺寸 / 解码内存),危险分配前校验,防止单张超大图拖垮进程
  • 每实例加载调度器、邻项预取(可关)、主图解码缓存预算(默认 128 MiB)

资源所有权与外部消费

  • ImageGalleryImageLease + SharedImageResource 引用计数所有权域:缓存、当前资源槽与外部 Lease 生命周期互不破坏,Dispose 线程安全且幂等
  • MainImageMode = ResourceOnly:视口让渡渲染与输入,宿主应用通过 TryAcquireCurrentImage 取得调用方所有的 Lease,配合 CurrentImageResourceChanged 事件实现外部渲染面(如自绘 Canvas / 渲染引擎)
  • 视觉树附加 / 脱离资源休眠;Gallery Detach 不使仍在外部持有的 Lease 失效

外观、主题与本地化

  • 包内封闭 ControlTheme 与固定模板,内部 Theme / 资源 Key 不公开;属性级 Appearance 开放(Viewport / Toolbar / Button / Filmstrip / ThumbnailItem 五类稀疏覆盖对象、8 个 Appearance 属性)
  • 内置矢量 Glyph 图标,不依赖字体基线;支持高对比度与减少动态效果
  • en_US / zh_CN / zh_TW 强类型语言资源,运行时切换即时生效

@qinware
qinware merged commit 2c47021 into AtomUI:release/6.0 Aug 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants