644 lines
21 KiB
Markdown
644 lines
21 KiB
Markdown
# CycleGUI API 参考
|
||||
|
|
|
|||
|
|
> **颜色字段统一为 `System.Drawing.Color`**(2026-05 改造):所有公开 API 的 color/colors/_shine/_border_color/team_color/shine_color 字段都是 `Color`,不再有 `uint` 入口。详见 `SKILL.md` `## 颜色契约` 章节。如果你拿到的是引擎 wire-format `uint`(bit0..7=R),用 `Extensions.FromRgba8(uint)` 升回 `Color`;System.Drawing ARGB 布局(`0xAARRGGBB`)则用 `Color.FromArgb(unchecked((int)argb))`。
|
|||
|
|
|
|||
|
|
## PanelBuilder 控件完整签名
|
|||
|
|
|
|||
|
|
维护者核对路径:`D:\MDCS\Source\Core\CycleGUI\CycleGUI\PanelBuilder.Controls.cs`
|
|||
|
|
|
|||
|
|
### 布局
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
void Label(string text)
|
|||
|
|
void Separator()
|
|||
|
|
void SeparatorText(string text)
|
|||
|
|
void SameLine(int spacing = 0)
|
|||
|
|
void CollapsingHeaderStart(string label) // 必须与 End 配对;不可嵌套
|
|||
|
|
void CollapsingHeaderEnd()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> CycleGUI **没有** `BeginChild` / `ChildWindow` / `BeginTabBar` / `BeginTabItem`。容器分区用 `Table(height:)` + `CollapsingHeader`;Tab 切换用 `TabButtons`(见下方"列表与选择")。
|
|||
|
|
|
|||
|
|
### 按钮与切换
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 返回 true 表示被点击
|
|||
|
|
bool Button(string text, string shortcut = "", string hint = "", string distinct = "", bool disabled = false)
|
|||
|
|
|
|||
|
|
// 弹出菜单按钮
|
|||
|
|
void PopMenuButton(string buttonTxt, MenuItem[] menu, Action clickBtn = null)
|
|||
|
|
|
|||
|
|
// 按钮组,返回 true 表示有选择,selecting 为选中索引
|
|||
|
|
bool ButtonGroup(string prompt, string[] buttonText, out int selecting, bool sameLine = false)
|
|||
|
|
|
|||
|
|
// 复选框,返回 true 表示值改变
|
|||
|
|
bool CheckBox(string desc, ref bool chk)
|
|||
|
|
|
|||
|
|
// 开关,返回 true 表示值改变
|
|||
|
|
bool Toggle(string desc, ref bool on)
|
|||
|
|
|
|||
|
|
// 单选按钮,返回 true 表示选择改变
|
|||
|
|
bool RadioButtons(string prompt, string[] items, ref int selected, bool sameLine = false)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 输入
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 文本输入。ret 为当前文本,doneInput 为 true 表示按下回车
|
|||
|
|
(string ret, bool doneInput) TextInput(string prompt, string defaultText = "",
|
|||
|
|
string hintText = "", bool focusOnAppearing = false,
|
|||
|
|
bool hidePrompt = false, bool alwaysReturnString = false)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 数值控件
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
bool DragFloat(string prompt, ref float valf, float step,
|
|||
|
|
float min = float.MinValue, float max = float.MaxValue, bool disableCache = false)
|
|||
|
|
|
|||
|
|
bool SliderInt(string prompt, ref int val, int min, int max, bool disableCache = false)
|
|||
|
|
|
|||
|
|
bool SliderFloat(string prompt, ref float val, float min, float max, bool disableCache = false)
|
|||
|
|
|
|||
|
|
bool DragVector2(string prompt, ref Vector2 vector, float step = 0.01f,
|
|||
|
|
float min = float.MinValue, float max = float.MaxValue)
|
|||
|
|
|
|||
|
|
bool DragMatrix(int m, int n, float[] vals)
|
|||
|
|
|
|||
|
|
bool BezierEditor(string prompt, ref Vector4 controlPoints, ref float startY, ref float endY)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 颜色
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
bool ColorEdit(string label, ref Color color, bool alphaEnabled = true)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 列表与选择
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 返回选中索引,-1 无选择
|
|||
|
|
int ListBox(string prompt, string[] items, int height = 5,
|
|||
|
|
bool persistentSelecting = false, int preselected = -1)
|
|||
|
|
|
|||
|
|
bool DropdownBox(string prompt, string[] items, ref int selected)
|
|||
|
|
|
|||
|
|
// 返回选中标签页索引
|
|||
|
|
int TabButtons(string prompt, string[] items, int forceSelect = -1)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`forceSelect`:希望激活的标签页索引(0-based);`-1` 不强制。API 内建变化检测:仅当该值相对上次变化时才下发 `ImGuiTabItemFlags_SetSelected`,调用方可每帧传入当前目标 Tab,无需自己做 one-shot 门控。用户手动切换 Tab 后,只要 `forceSelect` 不变就不会再被拉回。
|
|||
|
|
|
|||
|
|
### 表格
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
unsafe void Table(string strId, string[] header, int rows,
|
|||
|
|
Action<Row, int> content, int height = 0,
|
|||
|
|
bool enableSearch = false, string title = "",
|
|||
|
|
bool freezeFirstCol = false, int scrollToRow = -1,
|
|||
|
|
Action<int, bool>? onHeaderSort = null)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`height`:可见数据行数;`<=0` 表示不限制高度、显示全部行。`scrollToRow`:希望滚动到可见的数据行索引(0-based);`-1` 不滚动。API 内建变化检测:仅当该值相对上次变化时才下发 `ImGui::SetScrollHereY`,调用方可每帧传入当前选中行,用户之后可自由滚动列表。传入 `-1` 会复位持久态,便于「取消选中后再选同一行」能重新触发滚动。
|
|||
|
|
|
|||
|
|
Row 对象可用方法:`Label`, `ButtonGroup`, `Checkbox`, `SetColor`, `Image`
|
|||
|
|
|
|||
|
|
### 图表
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 实时折线图,返回可选按钮索引
|
|||
|
|
int RealtimePlot(string prompt, float val, bool freeze = false, string[] optionalButtons = null)
|
|||
|
|
|
|||
|
|
// 迷你指标
|
|||
|
|
bool MiniPlot(string name, float value)
|
|||
|
|
bool MiniPlot(string name, string value)
|
|||
|
|
bool MiniPlot<TEnum>(string name, TEnum value) where TEnum : Enum
|
|||
|
|
|
|||
|
|
// 静态折线图
|
|||
|
|
void Plot2D(string prompt, float[] vals, int height = 200)
|
|||
|
|
|
|||
|
|
// ⚠️ 以下为占位/空壳(源码 body 为空,调用无效果,请勿依赖):
|
|||
|
|
// Progress, BulletText, Indent / UnIndent, QuestionMark, ToolTip
|
|||
|
|
// - 需要进度展示:用 RealtimePlot 或 Label 渲染百分比
|
|||
|
|
// - 需要 tooltip:用 Button(hint:) / Table.Row.Label(hint:) 等已实现的入口
|
|||
|
|
void Progress(float val, float max = 1) // 空壳,无效果
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 图像
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
void Image(string prompt, string rgba, int height = -1)
|
|||
|
|
|
|||
|
|
// 图像列表,返回选中索引
|
|||
|
|
int ImageList(string prompt, (string rgba, string top_title, string bottom_title)[] items,
|
|||
|
|
bool persistentSelecting = false, int height_px = 100,
|
|||
|
|
bool hideSeparator = false, int selecting = -1)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 聊天框
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
(bool ret, string sending) ChatBox(string prompt, string[] appending,
|
|||
|
|
int lines = 18, bool input = true)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 文本展示
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
void SelectableText(string prompt, string content, bool copyButton = true)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 文件对话框
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
bool OpenFile(string prompt, string filters, out string dir, string defaultFn = "")
|
|||
|
|
bool SaveFile(string prompt, string filter, out string dir, string defaultFn = "")
|
|||
|
|
bool SelectFolder(string prompt, out string dir)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Web 与链接
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
void OpenWebview(string name, string url, string hint = "")
|
|||
|
|
void DisplayFileLink(string localfilename, string displayName)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 菜单栏
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
void MenuBar(List<MenuItem> menu)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
MenuItem 构造:
|
|||
|
|
```csharp
|
|||
|
|
new MenuItem(string label, Action onClick = null, string shortcut = null,
|
|||
|
|
bool selected = false, bool enabled = true, List<MenuItem> subItems = null)
|
|||
|
|
// label = "-" 表示分隔线
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 面板控制
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
bool Closing() // 返回 true 表示用户点击关闭或终端断开
|
|||
|
|
void DelegateUI() // 执行通过 Panel.dels 注入的委托 UI
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Panel 配置方法
|
|||
|
|
|
|||
|
|
维护者核对路径:`D:\MDCS\Source\Core\CycleGUI\CycleGUI\Panel.cs`
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
Panel ShowTitle(string title) // null 隐藏标题栏
|
|||
|
|
Panel InitSize(int w = 320, int h = 240)
|
|||
|
|
Panel FixSize(int w, int h) // 固定不可调整大小
|
|||
|
|
Panel AutoSize(bool set)
|
|||
|
|
Panel InitPos(bool pin, int left, int top,
|
|||
|
|
float myPivotX = 0, float myPivotY = 0,
|
|||
|
|
float screenPivotX = 0, float screenPivotY = 0)
|
|||
|
|
Panel InitPosRelative(Panel panel, int left, int top,
|
|||
|
|
float relPivotX = 0, float relPivotY = 0,
|
|||
|
|
float myPivotX = 0, float myPivotY = 0)
|
|||
|
|
Panel SetDefaultDocking(Docking docking, bool auxiliary = false)
|
|||
|
|
Panel Modal(bool set)
|
|||
|
|
Panel TopMost(bool set)
|
|||
|
|
Panel AsToolbarPanel(int height = 38, ToolbarAnchor anchor = ToolbarAnchor.RightTop)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
枚举:
|
|||
|
|
- `Panel.Docking`:`Left`, `Top`, `Right`, `Bottom`, `None`, `Full`
|
|||
|
|
- `Panel.ToolbarAnchor`:`RightTop`, `LeftBottom`
|
|||
|
|
|
|||
|
|
实例方法:
|
|||
|
|
```csharp
|
|||
|
|
void Define(CycleGUIHandler handler)
|
|||
|
|
void Repaint(bool dropCurrent = false, int repaintTimeMs = 30)
|
|||
|
|
// dropCurrent=true:丢弃当前帧,立即重绘(编辑后同步 UI 时用)
|
|||
|
|
// repaintTimeMs:持续 Repaint 时的间隔,默认 30ms
|
|||
|
|
// 只在有实时数据的面板持续调用;静态面板不要无条件 Repaint
|
|||
|
|
void BringToFront()
|
|||
|
|
void Exit()
|
|||
|
|
void Freeze() / void UnFreeze()
|
|||
|
|
void SwitchTerminal(Terminal newTerminal)
|
|||
|
|
bool Probe<T>(CycleGUIProber<T> prober, out T val)
|
|||
|
|
void FireAndForget(...)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## HoverMenu
|
|||
|
|
|
|||
|
|
维护者核对路径:`D:\MDCS\Source\Core\CycleGUI\CycleGUI\API\HoverMenu.cs`
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
HoverMenu GUI.DeclareHoverMenu()
|
|||
|
|
|
|||
|
|
enum HoverMenuPlacement {
|
|||
|
|
Cursor = 0,
|
|||
|
|
ObjectScreenAnchor = 1, // 默认;使用 hovered object 的屏幕投影锚点
|
|||
|
|
ObjectBounds = 2, // 预留,v1 不支持
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class HoverMenu : IDisposable {
|
|||
|
|
string Name { get; set; }
|
|||
|
|
string TargetObjectName { get; set; }
|
|||
|
|
HoverMenuPlacement Placement { get; set; } // 默认 ObjectScreenAnchor
|
|||
|
|
int OffsetX { get; set; } // 默认 12
|
|||
|
|
int OffsetY { get; set; } // 默认 12
|
|||
|
|
int CloseDelayMs { get; set; } // 默认 180
|
|||
|
|
PanelBuilder.CycleGUIHandler Build { get; set; }
|
|||
|
|
Terminal Terminal { get; }
|
|||
|
|
void Start()
|
|||
|
|
void StartOnTerminal(Terminal terminal)
|
|||
|
|
void Stop()
|
|||
|
|
void Dispose()
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
实现语义:每个 terminal 一个 manager/native listener,同一时间复用一个 transient panel;C# 侧按 `TargetObjectName` 字典匹配,暂假设一个 object 一个 HoverMenu,重复注册同一 object 会抛异常。native feedback 按 hovered object、object anchor、dragging 去重,不按鼠标移动持续推送。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Workspace Props 完整列表
|
|||
|
|
|
|||
|
|
维护者核对路径:`D:\MDCS\Source\Core\CycleGUI\CycleGUI\API\Workspace.Props.cs`
|
|||
|
|
|
|||
|
|
### 模型
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 加载 GLTF 模型类(不可 Remove)
|
|||
|
|
LoadModel { name, detail: ModelDetail }
|
|||
|
|
|
|||
|
|
// ModelDetail 结构
|
|||
|
|
ModelDetail(byte[] gltfBytes) {
|
|||
|
|
Center = Vector3,
|
|||
|
|
Rotate = Quaternion,
|
|||
|
|
Scale = float,
|
|||
|
|
ColorBias = Vector3,
|
|||
|
|
ColorScale = float,
|
|||
|
|
Brightness = float,
|
|||
|
|
ForceDblFace = bool,
|
|||
|
|
NormalShading = float,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新已加载模型的参数(不重新传 GLTF 数据)
|
|||
|
|
ReloadModel { name, detail: ModelDetail }
|
|||
|
|
|
|||
|
|
// 放置模型实例
|
|||
|
|
PutModelObject { name, clsName, newPosition: Vector3, newQuaternion: Quaternion, baseColor?: Color /* 预留,引擎当前忽略 */ }
|
|||
|
|
|
|||
|
|
// 自定义网格
|
|||
|
|
DefineMesh { clsname, positions: float[] /* 三角面顶点,长度必须是9的倍数 */, color: Color, smooth: bool }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 点云
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
PutPointCloud {
|
|||
|
|
name: string,
|
|||
|
|
xyzSzs: Vector4[], // xyz + size
|
|||
|
|
colors: Color[], // 每点一个 System.Drawing.Color
|
|||
|
|
newPosition: Vector3,
|
|||
|
|
newQuaternion: Quaternion,
|
|||
|
|
handleString: string, // 空=无句柄, 单字符=字符句柄, 多字符=PNG图标
|
|||
|
|
type: int, // 0=普通, 1=SLAM地图
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 线和曲线
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
PutStraightLine {
|
|||
|
|
name, start: Vector3, end: Vector3,
|
|||
|
|
propStart: string, propEnd: string, // 绑定到对象(空则用 start/end)
|
|||
|
|
arrowType: Painter.ArrowType, width: int, color: Color, dashDensity: int,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PutBezierCurve {
|
|||
|
|
name, start: Vector3, end: Vector3,
|
|||
|
|
control1: Vector3, control2: Vector3,
|
|||
|
|
width: int, color: Color,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PutVector { name, from: Vector3, dir: Vector3, color: Color, length: int }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 图像与纹理
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 静态图像
|
|||
|
|
PutImage { name, rgbaName, displayType, displayH, displayW, /* transform fields */ }
|
|||
|
|
|
|||
|
|
// 可更新 RGBA 纹理
|
|||
|
|
PutRGBA { name, width, height, requestRGBA / rgba }
|
|||
|
|
.StartStreaming() -> Action<byte[]> // 返回更新函数
|
|||
|
|
.Invalidate()
|
|||
|
|
.UpdateRGBA(byte[])
|
|||
|
|
|
|||
|
|
// SVG
|
|||
|
|
DeclareSVG { name, svgContent: string }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 对象操作
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 变换对象位置/旋转
|
|||
|
|
TransformObject { name, pos: Vector3, quat: Quaternion, timeMs: int, coord: Coord }
|
|||
|
|
// Coord: Absolute / Relative
|
|||
|
|
|
|||
|
|
// 变换子对象
|
|||
|
|
TransformSubObject { objectNamePattern, subObjectName/subObjectId, translation, rotation, timeMs }
|
|||
|
|
|
|||
|
|
// 对象锚定(moon 跟随 earth)
|
|||
|
|
SetObjectMoonTo { name: "moon", earth: "earth_obj", pos: Vector3, quat: Quaternion }
|
|||
|
|
|
|||
|
|
// 删除对象(通配符)
|
|||
|
|
WorkspaceProp.RemoveNamePattern(string namePattern) // 支持 * 和 ?
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 文本与图标
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
PutHandleIcon { name, ... }
|
|||
|
|
PutTextAlongLine { name, ... }
|
|||
|
|
SpotText { /* fluent builder */ }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 高斯溅射(Gaussian Splatting)
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
PutGaussianSplats {
|
|||
|
|
name, splats: GaussianSplat[],
|
|||
|
|
globalOpacityScale, globalSizeScale, renderMode, ...
|
|||
|
|
}
|
|||
|
|
PutGaussianSplats.FromPLY(path, name, axisPreset)
|
|||
|
|
PutGaussianSplats.FromPointCloud(...)
|
|||
|
|
PutGaussianSplats4D { /* 4D 时序数据 */ }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Workspace UI 操作
|
|||
|
|
|
|||
|
|
维护者核对路径:`D:\MDCS\Source\Core\CycleGUI\CycleGUI\API\Workspace.UIOps.cs`
|
|||
|
|
|
|||
|
|
### 相机
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
SetCamera {
|
|||
|
|
lookAt: Vector3,
|
|||
|
|
azimuth: float, // 默认 -PI/2
|
|||
|
|
altitude: float, // 默认 PI/2
|
|||
|
|
distance: float,
|
|||
|
|
fov: float,
|
|||
|
|
projectionMode: Perspective / Orthographic,
|
|||
|
|
displayMode: Normal / VR / EyeTrackedHolography / EyeTrackedLenticular,
|
|||
|
|
anchor_type: Both / StareOnly / PositionOnly / CopyCamera,
|
|||
|
|
azimuth_range: Vector2, // 限制旋转范围
|
|||
|
|
altitude_range: Vector2,
|
|||
|
|
pan_range: Vector3, // 限制平移范围
|
|||
|
|
mmb_freelook: bool, // 中键自由视角
|
|||
|
|
}
|
|||
|
|
// 提交方式:.IssueToDefault() / .IssueToAllTerminals() / .IssueToTerminal(t)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 外观
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
SetAppearance {
|
|||
|
|
useEDL: bool, // Eye-Dome Lighting
|
|||
|
|
useSSAO: bool, // 环境光遮蔽
|
|||
|
|
useGround: bool, // 地面
|
|||
|
|
useBorder: bool, // 边框
|
|||
|
|
useBloom: bool, // 泛光
|
|||
|
|
drawGroundGrid: bool, // 地面网格
|
|||
|
|
drawGuizmo: bool, // 坐标轴指示器
|
|||
|
|
useDefaultSky: bool, // 默认天空盒
|
|||
|
|
sun_altitude: float, // 太阳高度
|
|||
|
|
hover_shine: Color, // 悬停高亮色
|
|||
|
|
selected_shine: Color, // 选中高亮色
|
|||
|
|
hover_border_color: Color,
|
|||
|
|
selected_border_color: Color,
|
|||
|
|
world_border_color: Color,
|
|||
|
|
voxel_quantize: float, // 体素量化
|
|||
|
|
voxel_opacity: float, // 体素不透明度
|
|||
|
|
clippingPlanes: (Vector3 center, Vector3 direction)[], // 最多4个裁剪面
|
|||
|
|
bring2front_onhovering: bool,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 对象外观
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
SetObjectApperance { namePattern, bring_to_front, shine_color: Color, use_border, transparency }
|
|||
|
|
SetModelObjectProperty { namePattern, baseAnimId, nextAnimId, material_variant, team_color: Color,
|
|||
|
|
base_stopatend, next_stopatend, animate_asap }
|
|||
|
|
SetPropShowHide { namePattern, show: bool } // sticky pattern (2026-05+)
|
|||
|
|
SetPropApplyCrossSection { namePattern, apply: bool } // sticky pattern (2026-05+)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> **Sticky pattern 语义**(适用于 `SetPropShowHide` / `SetPropApplyCrossSection` /
|
|||
|
|
> `SelectObject.SetObjectSelectable` / `SelectObject.SetObjectSubSelectable`):每次调用先按
|
|||
|
|
> pattern 扫一遍 `global_name_map` 立即生效,**同时**把 pattern 字符串记入当前 viewport 的
|
|||
|
|
> `workspace_state.*_patterns`。之后 `Workspace.AddProp` 加入的新对象会被引擎在 `indexier::add`
|
|||
|
|
> 自动按 memo 重匹配并设位/隐藏/纳入 selectables。要取消粘性,用**同一 pattern 字符串**反向调
|
|||
|
|
> 一次(`SetPropShowHide{show=true}` / `SetObjectUnselectable(pattern)` 等)。
|
|||
|
|
>
|
|||
|
|
> **Pattern 是 glob**(`*` / `?`),引擎全栈唯一语义。底层是 `libVRender::wildcardMatch`,
|
|||
|
|
> 2026-05 统一化后已删除 `RegexMatcher::match` / `regexMatch` 全套 regex 路径。详见
|
|||
|
|
> SKILL.md 的 `## namePattern 语法 = glob` 章节,那里有完整的 API 列表 + 历史根因 +
|
|||
|
|
> "真要 regex 怎么办" 指引。
|
|||
|
|
|
|||
|
|
### 交互操作
|
|||
|
|
|
|||
|
|
所有交互操作继承 `WorkspaceUIOperation<T>`,通过 `.Start()` 启动,`.End()` 结束,`.feedback` 回调接收结果。
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 拾取世界坐标
|
|||
|
|
GetPosition {
|
|||
|
|
method: PickMode.GridPlane / Holo3D,
|
|||
|
|
snaps: string[], // 可吸附对象名
|
|||
|
|
}
|
|||
|
|
// feedback: Action<WorldPosition, op>
|
|||
|
|
// WorldPosition { mouse_pos, snapping_object, object_pos, sub_id }
|
|||
|
|
|
|||
|
|
// 拖拽跟随
|
|||
|
|
FollowMouse {
|
|||
|
|
method: FollowingMethod.LineOnGrid / RectOnGrid / PointOnGrid / CircleOnGrid / Line3D / ...,
|
|||
|
|
follower_objects: string[],
|
|||
|
|
start_snapping_objects: string[],
|
|||
|
|
end_snapping_objects: string[],
|
|||
|
|
realtime: bool,
|
|||
|
|
}
|
|||
|
|
// feedback: Action<FollowFeedback, op>
|
|||
|
|
|
|||
|
|
// 对象选择
|
|||
|
|
SelectObject {
|
|||
|
|
fineSelectOnPointClouds: bool,
|
|||
|
|
fineSelectOnHandle: bool,
|
|||
|
|
}
|
|||
|
|
// feedback: Action<(string name, BitArray selector, string firstSub)[], op>
|
|||
|
|
// feedback 返回的是“当前完整选中集”(不是 delta),由引擎处理 Shift+加选 / Alt+减选 / 框选
|
|||
|
|
// 运行时切换模式:selectOp.SetSelectionMode(SelectionMode.Rectangle, paintRadius)
|
|||
|
|
// SelectionMode: Click / Rectangle / Paint
|
|||
|
|
//
|
|||
|
|
// SetObjectSelectable(pattern) / SetObjectSubSelectable(pattern)
|
|||
|
|
// - pattern 是 glob:"*" = 任意子串、"?" = 任意单字符;不是 ECMAScript 正则
|
|||
|
|
// - 立即对已存在对象按 glob 设可选位
|
|||
|
|
// - 并把 pattern 记入 workspace_state.selectable_patterns(sticky,2026-05 起)
|
|||
|
|
// - 之后 AddProp 加入的新对象会被引擎自动匹配 + 设位(indexier::add hook)
|
|||
|
|
// - 取消 sticky:用同一 pattern 调 SetObjectUnselectable / SetObjectSubUnselectable
|
|||
|
|
|
|||
|
|
// Guizmo 操作(移动/旋转 gizmo)
|
|||
|
|
GuizmoAction {
|
|||
|
|
dof: GuizmoDof, // 默认 TranslateXYZ
|
|||
|
|
realtimeResult: bool,
|
|||
|
|
}
|
|||
|
|
// GuizmoDof: None, TranslateX/Y/Z, RotateX/Y/Z, Roll, Pitch, Yaw,
|
|||
|
|
// TranslateXYZ, RotateXYZ, PlanarXY, PlanarXYYaw, All
|
|||
|
|
// feedback: Action<(string name, Vector3 pos, Quaternion rot)[], op>
|
|||
|
|
|
|||
|
|
// 原始鼠标事件
|
|||
|
|
RegisterMouseAction {
|
|||
|
|
listen_MouseDown, listen_MouseUp, listen_MouseMove, listen_Wheel: bool,
|
|||
|
|
}
|
|||
|
|
// feedback: Action<MouseAction, op>
|
|||
|
|
// MouseAction { mouseX, mouseY, workspaceX, workspaceY, mouseLB/RB/MB, wheelDelta }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 工作区行为
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
SetWorkspaceBehaviour {
|
|||
|
|
operation_trigger: Mouse.MouseLB, // 操作触发键
|
|||
|
|
workspace_pan: Mouse.MouseRB, // 平移键
|
|||
|
|
workspace_orbit: Mouse.MouseMB, // 旋转键
|
|||
|
|
}
|
|||
|
|
// Mouse: MouseLB, MouseMB, MouseRB, CtrlMouseLB, CtrlMouseMB, CtrlMouseRB
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 查询操作
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 查询视口相机状态
|
|||
|
|
new QueryViewportState { callback = state => {
|
|||
|
|
// state.CameraPosition, state.LookAt, state.Up
|
|||
|
|
}}.IssueToDefault();
|
|||
|
|
|
|||
|
|
// 捕获渲染画面
|
|||
|
|
new CaptureRenderedViewport { callback = img => {
|
|||
|
|
// img.bytes (RGB), img.width, img.height
|
|||
|
|
}}.IssueToDefault();
|
|||
|
|
|
|||
|
|
// 查询图形信息
|
|||
|
|
new QueryGraphics { callback = state => {
|
|||
|
|
// state.MonitorCount, state.Monitors[], state.FPS
|
|||
|
|
}}.IssueToDefault();
|
|||
|
|
|
|||
|
|
// 聚焦到对象
|
|||
|
|
new FrameToFit { name = "objectName", margin = 1.1f }.IssueToDefault();
|
|||
|
|
|
|||
|
|
// 全屏
|
|||
|
|
new SetFullScreen { fullscreen = true, screen_id = -1 }.IssueToDefault();
|
|||
|
|
|
|||
|
|
// 自定义网格
|
|||
|
|
new SetOperatingGridAppearance {
|
|||
|
|
show = true, pivot = Vector3.Zero,
|
|||
|
|
unitX = Vector3.UnitX, unitY = Vector3.UnitY,
|
|||
|
|
}.IssueToDefault();
|
|||
|
|
|
|||
|
|
// ImGui 样式
|
|||
|
|
new SetImGUIStyle {
|
|||
|
|
windowBg = 0xFF171717, button = 0xFF3D3835,
|
|||
|
|
windowRounding = 6f, frameRounding = 6f,
|
|||
|
|
}.IssueToDefault();
|
|||
|
|
|
|||
|
|
// 主窗口菜单栏
|
|||
|
|
new SetMainMenuBar {
|
|||
|
|
menu = new List<MenuItem> { ... }, show = true
|
|||
|
|
}.IssueToDefault();
|
|||
|
|
|
|||
|
|
// Viewport 专属菜单栏
|
|||
|
|
var viewport = GUI.PromptWorkspaceViewport();
|
|||
|
|
new SetWorkspaceMenuBar {
|
|||
|
|
viewport = viewport,
|
|||
|
|
menu = new List<MenuItem> { ... }, show = true
|
|||
|
|
}.Issue();
|
|||
|
|
|
|||
|
|
// 面板持久菜单栏(从 handler 外部设置,自动注入到每次重绘)
|
|||
|
|
new SetPanelMenuBar {
|
|||
|
|
panel = myPanel,
|
|||
|
|
menu = new List<MenuItem> { ... }
|
|||
|
|
}.Issue();
|
|||
|
|
// 清除:new SetPanelMenuBar { panel = myPanel, menu = null }.Issue();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Painter 完整 API
|
|||
|
|
|
|||
|
|
维护者核对路径:`D:\MDCS\Source\Core\CycleGUI\CycleGUI\Painter.cs`
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 获取/创建命名 Painter(单例)
|
|||
|
|
static Painter GetPainter(string name)
|
|||
|
|
|
|||
|
|
// 清除当前帧数据(双缓冲交换)
|
|||
|
|
void Clear()
|
|||
|
|
|
|||
|
|
// 绘制点(单位:米)
|
|||
|
|
void DrawDot(Color color, Vector3 xyz, float size = 1f)
|
|||
|
|
|
|||
|
|
// 绘制线段
|
|||
|
|
void DrawLine(Color color, Vector3 start, Vector3 end,
|
|||
|
|
float width = 1f, ArrowType arrow = ArrowType.None, int dashScale = 0)
|
|||
|
|
// ArrowType: None, Start, End
|
|||
|
|
|
|||
|
|
// 绘制方向向量(像素长度)
|
|||
|
|
void DrawVector(Vector3 from, Vector3 dir, Color color,
|
|||
|
|
float width = 1f, int pixels = 10)
|
|||
|
|
|
|||
|
|
// 绘制 3D 文本
|
|||
|
|
void DrawText(Color color, Vector3 tCenter, string s)
|
|||
|
|
|
|||
|
|
// 绘制区域体素
|
|||
|
|
void DrawRegion3D(Color color, Vector3 center)
|
|||
|
|
|
|||
|
|
// 绘制填充多边形(2D 点 + 3D 变换)
|
|||
|
|
void DrawPolygonFilled(Vector2[] points2D, Vector3 trans, Quaternion quat,
|
|||
|
|
Color borderColor, Color fillColor, float thickness = 0f)
|
|||
|
|
// thickness=0: 平面多边形; >0: 拉伸立体
|
|||
|
|
|
|||
|
|
// 终端隔离
|
|||
|
|
Painter.terminal = specificTerminal; // null 则广播到所有终端
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## LeastServer(HTTP/WebSocket 服务)
|
|||
|
|
|
|||
|
|
全局类(无命名空间),维护者核对路径:`D:\MDCS\Source\Core\CycleGUI\CycleGUI\Terminals\LeastServer.cs`
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
static void Listener(int port) // 阻塞式启动监听
|
|||
|
|
static void AddGetHandler(string path, Func<string> handler)
|
|||
|
|
static void AddPostTextHandler(string path, Func<string, string> handler)
|
|||
|
|
static void AddPostByteHandler(string path, Func<byte[], byte[]> handler)
|
|||
|
|
static void AddServingFiles(string urlPrefix, string localPath)
|
|||
|
|
static void AddServingResources(string urlPrefix, Assembly, string ns)
|
|||
|
|
static void AddSpecialTreat(string path, Action<...> handler) // WebSocket 升级
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Viewport(面板内嵌 3D 视口)
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
// 创建内嵌 Workspace 视口面板
|
|||
|
|
var viewport = GUI.PromptWorkspaceViewport();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`Viewport` 继承 `Panel`,拥有独立的 `ViewportSubTerminal`,Workspace 状态与主终端隔离。
|
|||
|
|
|