diff --git a/API 文档.md b/API 文档.md new file mode 100644 index 0000000..ed017cb --- /dev/null +++ b/API 文档.md @@ -0,0 +1,685 @@ +# 中文 API 文档 + +[English API Documentation](English API Documentation.md) + +下面是 **StellarX GUI 框架** 各主要类和函数的 API 文档。每个类的用途、接口、参数和返回值等详细信息如下: + +### Control 类 (抽象基类) + +**描述:** `Control` 是所有控件的抽象基类,定义了通用的属性和接口,包括位置、尺寸、重绘标记等。它提供了绘图状态保存与恢复机制,确保控件绘制不影响全局状态。`Control` 本身不能直接实例化。 + +- **主要属性:** + - `x, y`:控件左上角坐标。 + - `width, height`:控件宽度和高度。 + - `dirty`:是否需要重绘的标志。 + - `show`:控件是否可见。 + - `rouRectangleSize`:`StellarX::RouRectangle` 结构,保存圆角矩形控件圆角的宽高半径。 + - **注意:** `Control` 会在内部维护当前绘图状态(字体、颜色、线型等)的备份指针,用于绘制前保存状态、绘制后恢复。 +- **主要接口方法:** + - `virtual void draw() = 0;` + **描述:** 纯虚函数,绘制控件内容。具体控件类需实现自己的绘制逻辑。 + - `virtual bool handleEvent(const ExMessage& msg) = 0;` + **描述:** 纯虚函数,处理事件消息(如鼠标、键盘事件)。返回值表示事件是否被该控件消费(`true` 则不再向其他控件传播)。 + - `void saveBackground(int x, int y, int w, int h);` + **描述:** 保存控件区域 `(x, y, w, h)` 的背景图像快照,以便需要时恢复背景。常用于控件需要暂时覆盖背景(如弹出框)。 + - `void restBackground();` + **描述:** 恢复最近保存的背景快照,将之前保存的背景图像绘制回控件原位置。典型用于控件隐藏或重绘前清除旧内容。 + - `void discardBackground();` + **描述:** 丢弃当前保存的背景快照并释放相关资源。当窗口重绘或尺寸变化导致背景失效时调用,避免错误使用旧快照。 + - *属性访问和设置:* + - `int getX() const, getY() const, getWidth() const, getHeight() const` 等:获取控件位置和尺寸各属性。 + - `int getRight() const, getBottom() const`:获取控件右边界和下边界坐标(`x + width`,`y + height`)。 + - `void setX(int nx), setY(int ny), setWidth(int w), setHeight(int h)`:设置控件位置或尺寸,对应属性改变后自动将控件标记为需要重绘 (`dirty = true`)。 + - `void setDirty(bool d)`:手动设置控件的重绘标志。 + - `void setShow(bool visible)`:设置控件可见性。如果设为 `false`,则控件将不绘制自身内容。 + - `bool isVisible() const`:返回控件当前可见状态(`show` 标志)。**注意:** 控件被标记为隐藏时,其 `draw()` 通常不会被调用。 + - *其他:* + - `virtual bool model() const = 0;` + **描述:** 纯虚函数,用于检查控件是否为“模态”。仅对话框控件需要实现(模态对话框返回 `true`),其他非对话框控件可忽略(返回 `false`)。窗口事件循环根据此函数区分模态对话框与普通控件的事件处理优先级。 + - `void saveStyle(), restoreStyle();` *(受保护方法)* + **描述:** 保存当前全局绘图样式(字体、颜色、线型等)并恢复。控件在 `draw()` 中应先调用 `saveStyle()` 备份当前样式,绘制完毕后调用 `restoreStyle()` 以免影响其他绘制操作。 + +### Window 类 (应用主窗口) + +**描述:** `Window` 类表示应用程序的主窗口,负责窗口的创建、消息循环、控件管理和整体渲染。一个应用通常创建一个 Window 实例作为 GUI 的根容器。 + +- **构造函数:** + - `Window(int width, int height, int mode, COLORREF bkColor = ..., std::string headline = "窗口")` + 创建一个指定宽、高的主窗口。`mode` 参数指定图形模式(如是否双缓冲,EasyX 使用 NULL 或 `INIT_RENDERMANUAL` 等模式),`bkColor` 是窗口背景色,`headline` 是窗口标题文本。构造时不会立即显示窗口,需调用 `draw()`。 +- **主要方法:** + - `void draw();` + **描述:** 初始化并显示窗口,创建绘图界面。将使用设定的模式创建绘图窗口(调用 EasyX 的 `initgraph`),并应用窗口标题和背景色。然后绘制已添加的控件。通常在创建 Window 后立即调用一次。 + - `void draw(std::string pImgFile);` + **描述:** 与无参版本类似,但使用指定路径的图像文件作为窗口背景图。该方法会加载图像并按照窗口尺寸绘制为背景,然后再绘制子控件。 + - `void runEventLoop();` + **描述:** 进入窗口消息处理循环。该循环持续获取用户输入事件 (`peekmessage`) 并将其分发给子控件或对话框处理: + - 优先将事件传递给所有已打开的非模态对话框(`Dialog`,`model() == false` 且 `isVisible() == true`)。一旦某个对话框的 `handleEvent` 返回 `true`(事件被消费),停止继续传递。 + - 若事件未被对话框消费,再按添加顺序将事件传递给普通控件列表中的各控件的 `handleEvent`(通常 Container 控件会向其子控件继续传播)。 + - 处理完事件后,如果有对话框正在显示(或刚关闭),或者 `dialogClose` 标志为真,则强制重绘一帧界面:包括所有普通控件和对话框,以确保界面更新。 + - 循环每帧暂停 10 毫秒,防止 CPU 占用过高。 + - **注意:** 该函数在调用后不会返回,直到窗口接收到关闭消息 (`WM_CLOSE`),此时函数内部会跳出循环结束。 + - `void setBkImage(IMAGE* img)` / `void setBkImage(std::string filePath);` + **描述:** 更改窗口背景图像。可以直接传入一个已加载的 `IMAGE` 指针,或提供图像文件路径让函数内部加载。调用此函数会触发窗口重绘当前所有控件和对话框以应用新的背景。 + - `void setBkcolor(COLORREF c);` + **描述:** 设置窗口背景颜色,并立即用该颜色清除屏幕背景(不销毁已有背景图,仅覆盖绘制)。 + - `void setHeadline(std::string title);` + **描述:** 设置窗口标题文本。窗口创建后可随时更改标题;如果窗口已显示,则通过 WinAPI `SetWindowText` 立即更新窗口标题栏。 + - `void addControl(std::unique_ptr control);` + **描述:** 向窗口添加一个普通控件。Window 维护一个控件列表,`draw()` 和 `runEventLoop()` 会据此绘制及派发事件。此方法接收智能指针,调用后 Window 接管控件的生命周期。 + - `void addDialog(std::unique_ptr dialog);` + **描述:** 向窗口添加一个对话框控件(一般为 `Dialog` 类型)。对话框与普通控件分开管理,其事件和绘制有独立逻辑。 + - `bool hasNonModalDialogWithCaption(const std::string& caption) const;` + **描述:** 检查当前是否已有**非模态**对话框,其标题(caption)与给定字符串匹配。如果存在返回 `true`。通常用于避免重复打开相同对话框。 + **重载版本:** `bool hasNonModalDialogWithCaption(const std::string& caption, const std::string& text) const;` + 除了标题,还同时比较对话框内容文本,以更严格地判断重复。`MessageBox::showAsync` 内部使用此方法防止弹出重复的提示框。 + - *信息获取方法:* + - `HWND getHwnd() const;` 获取底层窗口句柄(EasyX 初始化返回的 HWND)。 + - `int getWidth() const, getHeight() const;` 获取窗口宽度和高度。 + - `std::string getHeadline() const;` 获取当前窗口标题。 + - `COLORREF getBkcolor() const;` 获取窗口背景色。 + - `IMAGE* getBkImage() const;` 获取当前窗口背景图像对象指针(如果有)。 + - `std::vector>& getControls();` 引用返回窗口维护的控件列表(可以对其遍历,但一般不手动修改)。 + +### Canvas 类 (容器控件) + +**描述:** `Canvas` 是一种可包含子控件的画布容器,用于将其他控件分组、统一背景和边框样式,以及实现复杂布局。Canvas 自身也是一个控件,继承自 `Control`。 + +- **特性:** + - 支持四种矩形形状背景(普通矩形/圆角矩形,各有无边框和有边框版本),可通过 `setShape` 设置。 + - 可自定义容器背景颜色 (`canvasBkColor`)、边框颜色 (`canvasBorderColor`)、边框线型 (`canvasLineStyle`)、填充模式 (`canvasFillMode`,纯色/图案/无填充) 等。 + - Canvas 能自动管理子控件的生命周期(使用 `addControl` 添加的子控件在 Canvas 销毁时自动释放)。 + - Canvas 会在绘制时遍历并绘制所有添加的子控件,并在处理事件时优先将事件传递给子控件列表中最后添加的控件(Z 顺序)。 +- **重要数据成员:** + - `std::vector> controls;` 子控件列表。 + - `StellarX::ControlShape shape;` 容器背景形状(默认矩形)。 + - `StellarX::FillMode canvasFillMode;` 背景填充模式(默认实色填充)。 + - `StellarX::LineStyle canvasLineStyle;` 边框线型(默认实线)。 + - `int canvaslinewidth;` 边框线宽像素值。 + - `COLORREF canvasBorderColor, canvasBkColor;` 容器边框颜色与背景色。 + - `StellarX::LayoutKind Kind;` (预留)布局管理类型,当前未深入实现,可用于标识布局策略(如绝对布局、水平/垂直布局等)。 + - **注意:** Canvas 重载了 `isVisible()` 始终返回 false,因为 Canvas 通常不作为独立可见单元(事件循环中不直接处理 Canvas,而由其子控件处理事件)。但这不影响 Canvas 作为容器的绘制和子控件事件派发。 +- **主要方法:** + - `Canvas(); Canvas(int x, int y, int w, int h);` + **描述:** 构造一个 Canvas 容器,可以指定位置 `(x,y)` 及初始尺寸。 + - `void addControl(std::unique_ptr control);` + **描述:** 添加子控件到 Canvas。被添加控件将成为 Canvas 内容的一部分,其坐标相对于 Canvas 左上角(Canvas 并不主动调整子控件位置,需在添加前设置好子控件位置)。添加后 Canvas 会将自身标记为需要重绘。 + - `void setShape(StellarX::ControlShape shape);` + **描述:** 设置 Canvas 背景形状。支持 `RECTANGLE`、`B_RECTANGLE`(无边框矩形)、`ROUND_RECTANGLE`(圆角矩形)、`B_ROUND_RECTANGLE`(无边框圆角矩形)。如果传入圆形或椭圆形(CIRCLE/ELLIPSE等),Canvas 不支持,将自动按矩形处理。 + - `void setCanvasFillMode(StellarX::FillMode mode);` + **描述:** 设置背景填充模式,如纯色 (`Solid`)、无填充 (`Null`)、预定义图案填充 (`Hatched`) 或自定义图案/图像填充 (`Pattern/DibPattern`),需结合 `setfillstyle` 使用。默认为纯色。 + - `void setBorderColor(COLORREF color);` / `void setCanvasBkColor(COLORREF color);` / `void setCanvasLineStyle(StellarX::LineStyle style);` / `void setLinewidth(int width);` + **描述:** 分别设置容器边框颜色、背景色、边框线型和线宽。这些改变都会使 Canvas 需要重绘。 + - `void draw() override;` + **描述:** 绘制 Canvas 背景和其所有子控件。Canvas 绘制步骤: + 1. 根据设定的背景颜色/填充模式和形状绘制容器背景(例如填充矩形或圆角矩形区域)。 + 2. 遍历子控件列表,调用每个子控件的 `draw()` 方法绘制它们。绘制前对每个子控件先设置其 `dirty = true`,确保子控件按需重绘。 + 3. 恢复绘图样式,标记自身为已绘制(`dirty = false`)。 + *实现细节:* Canvas 使用 `saveStyle()/restoreStyle()` 保护全局绘图状态,并依赖 EasyX 的填充/绘制函数根据 `shape` 绘制矩形或圆角矩形背景。 + - `bool handleEvent(const ExMessage& msg) override;` + **描述:** 将事件按照子控件的添加顺序逆序传递(后添加的子控件先处理)。对 `controls` 列表从末尾向前调用每个子控件的 `handleEvent`,若某子控件返回 `true`(表示事件已被处理),则停止传递并返回 `true`;若所有子控件都未消费事件,则返回 `false` 表示未处理。 + *用途:* 使得堆叠在顶层的子控件(通常列表后面的)有更高优先权处理事件,例如多个重叠控件的情形。 + - `void clearAllControls();` *(protected 方法)* + **描述:** 清除并移除所有子控件。会释放智能指针列表中所有控件对象。一般在容器销毁或重置时使用。普通情况下不直接调用,由容器析构自动完成。 + +### Label 类 (静态文本标签) + +**描述:** `Label` 用于显示一段静态文本,可设置文字颜色、背景透明/不透明及样式等。Label 不处理用户输入事件(纯展示)。 + +- **构造函数:** + - `Label(); Label(int x, int y, std::string text = "标签", COLORREF textColor = BLACK, COLORREF bkColor = WHITE);` + **描述:** 创建一个 Label 控件。可指定初始位置 `(x,y)`、显示文本内容和文本颜色、背景色等。默认文本为“标签”,默认文字黑色、背景白色。 +- **主要属性:** + - `std::string text;` 显示的文字内容。 + - `COLORREF textColor;` 文本颜色。 + - `COLORREF textBkColor;` 文本背景色(在背景不透明时生效)。 + - `bool textBkDisap;` 是否背景透明显示文本。若为 `true`,Label 绘制文字时使用透明背景模式。 + - `StellarX::ControlText textStyle;` 文字样式结构,包括字体、高度、粗细等属性(继承自 Control 默认值,例如 `字体:微软雅黑`)。 + - **注意:** Label 大小 (`width, height`) 初始为 0,通常 Label 大小根据文本自动适应,无需手动设置宽高。Label 绘制时会截取背景图像以覆盖文字区域刷新。 +- **主要方法:** + - `void setTextdisap(bool transparent);` + **描述:** 设置文本背景是否透明显示。传入 `true` 则文字背景透明,显示时不遮挡底下背景;`false` 则文字背景为 `textBkColor` 实色矩形。 + - `void setTextColor(COLORREF color);` / `void setTextBkColor(COLORREF color);` + **描述:** 设置文字颜色或背景色。更改后会标记 Label 需要重绘。 + - `void setText(std::string text);` + **描述:** 更改显示的文本内容,并标记需要重绘。支持中文字符串。 + - `void draw() override;` + **描述:** 绘制文本标签。根据 `textBkDisap` 决定调用 EasyX 的 `setbkmode(TRANSPARENT)` 或 `OPAQUE`,并设置背景色 `setbkcolor(textBkColor)`。然后设置文本颜色和样式,调用 `outtextxy(x, y, text)` 输出文字。为防止文字重绘留痕迹,`Label::draw` 会先保存文字区域背景 (`saveBackground`),绘制完成后再恢复样式。首次绘制后将 `dirty` 置为 false。 + - `bool handleEvent(...) override;` + **描述:** Label 不处理任何事件,始终返回 false。 + - `void hide();` + **描述:** 将 Label 内容隐藏。其实现是调用 `restBackground()` 恢复先前保存的背景,然后 `discardBackground()` 释放快照,并将 `dirty` 设为 false。这通常在 Label 用作 Tooltip 提示框时,由宿主控件调用,用于移除提示文本的显示而不重绘整个界面。 +- **使用场景:** Label 常用于界面中的静态说明文字、标题、状态栏信息等。通过配合 `textStyle` 可以修改字体、大小、是否加粗等。默认情况下 Label 背景不透明白底,如需与窗口背景融合可调用 `setTextdisap(true)` 使背景透明。 + +### Button 类 (按钮控件) + +**描述:** `Button` 提供普通按钮和切换按钮(两态)的功能,可响应点击和悬停事件。支持设置各种样式(形状、颜色)和点击回调,是交互的主要控件之一。 + +- **工作模式:** 由 `StellarX::ButtonMode` 枚举定义: + + - `NORMAL` 普通按钮:每次点击都会触发一次动作,按钮本身不保持按下状态。 + - `TOGGLE` 切换按钮:每次点击切换自身状态(选中/未选中),并触发不同的回调。 + - `DISABLED` 禁用按钮:不响应用户点击,显示为灰色且文字带删除线。 + - 可通过 `setButtonMode(ButtonMode mode)` 改变按钮模式。 + +- **外观形状:** 由 `StellarX::ControlShape` 定义: + + - 支持矩形 (`RECTANGLE`/`B_RECTANGLE`)、圆角矩形 (`ROUND_RECTANGLE`/`B_ROUND_RECTANGLE`)、圆形 (`CIRCLE`/`B_CIRCLE`)、椭圆 (`ELLIPSE`/`B_ELLIPSE`) 八种形状(B_ 前缀表示无边框填充)。通过 `setButtonShape(ControlShape shape)` 设置按钮形状。 + - 注意:在切换 `ControlShape` 时,某些尺寸下圆形/椭圆以控件的 `width` 和 `height` 计算,圆形半径取较小的半径,椭圆按照矩形外接框绘制。 + +- **主要可配置属性:** + + - 颜色:`buttonTrueColor`(被点击时颜色),`buttonFalseColor`(常态颜色),`buttonHoverColor`(鼠标悬停颜色),`buttonBorderColor`(边框颜色)。 + - 填充:`buttonFillMode`(填充模式,实色/图案/图像等),`buttonFillIma`(图案填充样式,如果 `FillMode == Hatched`),`buttonFileIMAGE`(指向自定义填充图像的指针,如果 `FillMode == DibPattern`)。 + - 文本:按钮显示的文字 `text` 及其样式 `textStyle`(字体、字号、颜色等)。另外提供 `cutText` 字符串用于文本过长时显示裁剪的内容。 + - Tooltip:`tipEnabled`(是否启用悬停提示),`tipTextClick`(NORMAL模式提示文本),`tipTextOn/Off`(TOGGLE模式下两种状态的提示文本),`tipFollowCursor`(提示框是否跟随鼠标移动),`tipDelayMs`(提示延迟毫秒),`tipOffsetX/Y`(提示框相对位置偏移),`tipLabel`(内部使用的 Label 控件呈现提示文本)。 + - 圆角大小:通过继承自 `Control` 的 `rouRectangleSize` 成员控制圆角矩形圆角的半径大小。提供 `setRoundRectangleWidth(int)` 和 `setRoundRectangleHeight(int)` 接口修改。 + +- **主要方法:** + + - `void setOnClickListener(function&& callback);` + **描述:** 设置按钮普通点击时的回调函数。当按钮模式为 NORMAL,在每次鼠标释放点击时调用该回调;当模式为 TOGGLE,则仅在每次点击状态发生变化时调用(取决于 toggle 逻辑)。 + + - `void setOnToggleOnListener(...)` / `void setOnToggleOffListener(...);` + **描述:** 设置按钮在 TOGGLE 模式下由未选中变为选中、以及由选中变为未选中时分别触发的回调函数。当按钮模式为 NORMAL 或 DISABLED 时,这两个回调不会被调用。 + + - `void setButtonText(const char* text)` / `void setButtonText(std::string text);` + **描述:** 更改按钮上的显示文本。支持 C 风格字符串或 `std::string`。更改文本后会重新计算文本宽高,并标记按钮需要重绘。 + + - `void setButtonBorder(COLORREF border)` / `void setButtonFalseColor(COLORREF color)` + **描述:** 设置按钮边框颜色、常态下背景填充颜色。 + + - `void setFillMode(FillMode mode)` / `void setFillPattern(FillStyle pattern)` / `void setFillImage(const std::string& path)` + **描述:** 设置按钮背景填充方式: + + - `setFillMode` 改变填充模式(纯色、图案、位图等)。 + - 若填充模式为图案 (`Pattern`),需调用 `setFillPattern` 设置具体的图案样式 (`StellarX::FillStyle`)。 + - 若填充模式为位图 (`DibPattern`),可调用 `setFillImage` 加载指定路径的图像并用作填充(会自动调整图像大小与按钮一致)。 + + - `void setButtonClick(bool click);` + **描述:** 外部设置按钮的“点击状态”。对于 TOGGLE 模式,`setButtonClick(true)` 会将按钮设为选中状态并触发 onToggleOn 回调,`false` 则触发 onToggleOff 回调。对于 NORMAL 模式,传入 true 将临时触发一次 onClick 回调(随后状态立即复位为未点击)。无论哪种模式,调用都会引起按钮重绘。**注意:** DISABLED 模式调用此函数没有效果。 + + - `bool isClicked() const;` + **描述:** 返回按钮当前是否处于按下状态(仅对 TOGGLE 模式有意义,表示按钮选中状态)。 + + - 其他状态获取方法如 `getButtonText()`, `getButtonMode()`, `getButtonShape()`, `getFillMode()`, `getFillPattern()`, `getFillImage()`, `getButtonBorder()`, `getButtonTextColor()`, `getButtonTextStyle()`, `getButtonWidth()`, `getButtonHeight()` 一一提供,返回对应属性值。 + + - `void draw() override;` + **描述:** 绘制按钮外观。根据按钮当前状态选择填充颜色:若禁用则用 `DISABLEDCOLOUR` 灰色并给文字加删除线效果,否则 `click` 状态优先,其次 `hover` 状态,最后默认未点击颜色。然后设置透明背景、边框颜色和文本样式,计算文字应绘制的位置并绘制文字。 + 如果按钮文本长度超出按钮宽度,`draw()` 会自动调用 `cutButtonText()` 对文本进行裁剪,并用省略号表示超出部分,以确保文字在按钮内完整显示。绘制结束后恢复样式并将 `dirty` 置为 false。 + + - `bool handleEvent(const ExMessage& msg) override;` + **描述:** 处理与按钮相关的鼠标事件,包括鼠标按下、弹起、移动等: + + - 检测鼠标是否悬停在按钮区域内(根据按钮形状调用内部 `isMouseInCircle/Ellipse` 辅助函数)。 + - 处理 `WM_LBUTTONDOWN`(鼠标按下):若按钮未禁用且鼠标位于按钮上,在 NORMAL 模式下将按钮标记为点击状态(按下),在 TOGGLE 模式下不改变状态(等待弹起时处理)。 + - 处理 `WM_LBUTTONUP`(鼠标弹起):若鼠标在按钮上且按钮可点击: + - NORMAL 模式:如果之前已记录按下,则认为一次有效点击,调用 `onClickCallback`,然后清除点击状态。 + - TOGGLE 模式:切换按钮状态 `click = !click`。根据切换后的状态调用 `onToggleOnCallback` 或 `onToggleOffCallback`。 + - 每次有效点击后,都会通过 `flushmessage(EX_MOUSE|EX_KEY)` 清空输入消息队列,防止此次点击产生的消息(例如弹起)重复被处理。 + - 处理鼠标移出(在 `WM_MOUSEMOVE` 中检测):如果 NORMAL 模式下拖出按钮区域则取消按下状态,任何模式下 hover 状态变化都将使按钮重绘。 + - Tooltip 提示:如果启用了 `tipEnabled`,`handleEvent` 内会管理 `tipLabel` 的显示: + - 当鼠标首次移入按钮区域,启动一个定时(根据 `tipDelayMs`)。 + - 当鼠标离开或按钮点击后,立即隐藏提示(调用 `hideTooltip()`)。 + - 当鼠标在按钮上停留超过延迟且按钮仍显示,则设置 `tipVisible = true` 并初始化 `tipLabel` 的文本和位置准备显示提示。`tipFollowCursor` 决定提示框锚定鼠标位置还是按钮下方。 + - `refreshTooltipTextForState()` 用于当按钮为 TOGGLE 模式且未自定义提示文本时,选择显示 `tipTextOn` 或 `tipTextOff`。 + - 每帧事件处理后,如提示应显示,则调用 `tipLabel.draw()` 绘制提示文本。 + - 函数最后,如果按钮 `hover` 状态或 `click` 状态有变化,则将自身标记为 `dirty` 并立即调用 `draw()` 重绘自身,实现交互的即时反馈。 + + `handleEvent` 返回值为 `true` 当且仅当按钮按下鼠标弹起事件被处理时,表示该点击事件已被消费,其它控件不应再处理。 + +- **使用说明:** + 开发者通常通过设置按钮的各种监听器来处理点击事件。例如: + + ``` + auto btn = std::make_unique