diff --git a/API Documentation.en.md b/API Documentation.en.md index 535f274..a9a8735 100644 --- a/API Documentation.en.md +++ b/API Documentation.en.md @@ -1,872 +1,2028 @@ -# English API Documentation +# API Documentation -[API文档](API 文档.md) +[中文 API ](API 文档.md) -Below is the API documentation for the **StellarX GUI framework** classes and functions, in English. It covers the usage, parameters, and behavior of each primary component: +Below is the API documentation for the main classes and functions of the **StellarX GUI Framework**. Detailed information such as the purpose, interface, parameters, and return values for each class are as follows: -### Control Class (Abstract Base Class) +## Control Class (Abstract Base Class) -**Description:** `Control` is the abstract base class for all GUI controls. It defines common properties and interfaces such as position, size, and dirty (redraw) flags. It also implements saving and restoring of drawing state to ensure that drawing a control does not affect global graphics state. `Control` itself is not instantiated directly. +**Description:** `Control` is the abstract base class for all controls, defining common properties and interfaces, including basic functionalities like position, size, and dirty flag. It provides drawing state save and restore mechanisms to ensure that a control's drawing operations do not affect the global drawing state. It also declares a series of pure virtual functions (such as `draw()` and `handleEvent()`) to be implemented by subclasses and prohibits copying (supports move semantics) to prevent accidental copying overhead. Generally, `Control` is not instantiated directly but serves as the parent class for other specific controls. -- **Key Properties:** - - `x, y`: Coordinates of the control's top-left corner. - - `width, height`: Dimensions of the control. - - `dirty`: A flag indicating whether the control needs to be redrawn. - - `show`: Visibility flag (whether the control is visible). - - `rouRectangleSize`: A `StellarX::RouRectangle` struct that stores the ellipse width and height for rounded rectangle corners (used by controls with round-rect shape). - - **Note:** `Control` internally maintains pointers (`currentFont`, etc.) to backup current drawing state (font, colors, line style) so that it can restore the state after custom drawing. -- **Main Interface Methods:** - - `virtual void draw() = 0;` - **Description:** Pure virtual function to draw the control. Each derived control class must implement its own drawing logic. - - `virtual bool handleEvent(const ExMessage& msg) = 0;` - **Description:** Pure virtual function to handle an input event message (mouse or keyboard). Returns true if the event is consumed by this control (meaning it should not propagate further). - - `void saveBackground(int x, int y, int w, int h);` - **Description:** Saves a background snapshot of the specified area `(x, y, w, h)` (in screen coordinates) where the control is drawn. Used to restore background when needed (e.g., hiding a popup). - - `void restBackground();` - **Description:** Restores the last saved background image by putting it back to the saved position. Typically used when a control is hidden or needs to erase its drawing. - - `void discardBackground();` - **Description:** Discards the currently saved background snapshot and frees its resources. Should be called when the saved background is no longer valid (e.g., after window resize) to avoid using stale snapshots. - - *Property Accessors and Mutators:* - - `int getX() const, getY() const, getWidth() const, getHeight() const`: Get the control's position and size. - - `int getRight() const, getBottom() const`: Get the coordinate of the control's right boundary (`x + width`) and bottom boundary (`y + height`). - - `void setX(int nx), setY(int ny), setWidth(int w), setHeight(int h)`: Set the control's position or size. Setting these will mark the control as dirty (need redraw). - - `void setDirty(bool d)`: Manually mark the control as needing redraw or not. - - `void setShow(bool visible)`: Set the control's visibility (`show` flag). If set to false, the control will not draw itself. - - `bool isVisible() const`: Returns the current visibility state of the control (`show` flag). **Note:** If a control is hidden, its `draw()` is typically not called. - - *Other Methods:* - - `virtual bool model() const = 0;` - **Description:** Pure virtual function to check if the control is "modal". Only dialog controls need to implement this (modal dialogs return true), other controls can ignore (return false). The window event loop uses this to prioritize modal dialog events. - - `void saveStyle(); void restoreStyle();` *(protected)* - **Description:** Saves the current global drawing style (font, colors, line style, etc.) and restores it. Controls should call `saveStyle()` at the beginning of `draw()` to backup global settings, and `restoreStyle()` at the end of `draw()` to not pollute the global state for other drawings. +**Features:** -### Window Class (Application Main Window) - -**Description:** The `Window` class represents the main application window. It manages the window creation, message loop, and acts as the root container for all controls and dialogs. Typically, an application creates one Window instance as the main GUI container. - -- **Constructors:** - - `Window(int width, int height, int mode, COLORREF bkColor = ..., std::string headline = "窗口")` - **Description:** Creates a Window with specified width and height. `mode` is the graphics mode (such as double-buffering or manual flush flags in EasyX, use NULL for default). `bkColor` is the window background color, and `headline` is the window title text. Construction does not immediately display the window; you need to call `draw()` to open it. -- **Main Methods:** - - `void draw();` - **Description:** Initializes and opens the graphics window. It uses the specified mode to create the drawing window (calls EasyX `initgraph`), sets up the window's title and background color, and then draws all added controls. Usually called once right after creating the Window object. - - `void draw(std::string pImgFile);` - **Description:** Similar to the above, but uses an image file as the window background. This loads the image and draws it scaled to the window size, then draws all child controls on top. - - `void runEventLoop();` - **Description:** Enters the main event processing loop for the window. This loop continuously retrieves user input events (`peekmessage`) and dispatches them to child controls or dialogs: - - Dialogs (non-modal ones) get first priority: for each event, it iterates over `dialogs` and if a dialog is visible (`isVisible() == true`) and not modal (`model() == false`), it calls that dialog's `handleEvent`. If any dialog consumes the event (returns true), it stops further propagation. - - If no dialog consumed the event, it then iterates through `controls` (regular controls) in order and calls each control's `handleEvent` until one returns true (meaning the event was handled). - - After handling an event (or if none present), it checks if any dialog is open or was just closed (`dialogClose` flag). If so, it forces a redraw of the entire interface to keep things updated: - - It synthesizes a `WM_MOUSEMOVE` message to update hover states (ensuring controls properly update their highlight states), then calls `draw()` on all controls and dialogs, and flushes the drawing. - - It resets `dialogClose` to false after the redraw. - - Sleeps for 10 ms at each loop iteration to prevent high CPU usage. - - The loop continues until a `WM_CLOSE` message is received (e.g., user closes the window), at which point it sets `running` false and breaks out. - - `void setBkImage(IMAGE* img);` / `void setBkImage(std::string filePath);` - **Description:** Changes the window's background image. You can pass an already loaded `IMAGE*`, or specify a file path to load. After setting, it immediately repaints the window (drawing all controls and dialogs) with the new background. - - `void setBkcolor(COLORREF c);` - **Description:** Sets the window background color and immediately clears the screen with that color (this does not remove an existing background image if one was set; it just overlays the color). - - `void setHeadline(std::string title);` - **Description:** Sets the window title text. If the window is already open, it updates the title bar via `SetWindowText` immediately. - - `void addControl(std::unique_ptr control);` - **Description:** Adds a regular control to the window. The Window maintains a list of such controls; `draw()` and `runEventLoop()` use this list for rendering and event dispatch. Ownership is transferred (control is managed by Window after adding). - - `void addDialog(std::unique_ptr dialog);` - **Description:** Adds a dialog control to the window (usually an instance of `Dialog`). Dialogs are managed separately from normal controls, with their own event and drawing handling. - - `bool hasNonModalDialogWithCaption(const std::string& caption) const;` - **Description:** Checks if there is a currently open **non-modal** dialog with the given title caption. Returns true if found. Typically used to avoid opening duplicate dialogs with the same purpose. - - **Overloaded variant:** `bool hasNonModalDialogWithCaption(const std::string& caption, const std::string& text) const;` - Additionally compares the dialog's message text. This provides a stricter duplicate check (same caption **and** same content). It is used internally by `MessageBox::showAsync` to prevent popping up the same notification multiple times. - - *Information Getters:* - - `HWND getHwnd() const;` Returns the underlying window handle (HWND from EasyX). - - `int getWidth() const, getHeight() const;` Returns the window's dimensions. - - `std::string getHeadline() const;` Returns the current window title string. - - `COLORREF getBkcolor() const;` Returns the background color. - - `IMAGE* getBkImage() const;` Returns the current background image pointer (if any). - - `std::vector>& getControls();` Returns a reference to the list of child controls (for iteration or debugging; generally you don't modify this directly). - -### Canvas Class (Container Control) - -**Description:** `Canvas` is a container control that can hold child controls, grouping them with a unified background and border style, and enabling composite layouts. Canvas itself is a control (derives from `Control`), and typically used for panels or dialog surfaces. - -- **Features:** - - Supports four rectangular background shapes (normal rectangle or rounded rectangle, each with border or borderless version). Set via `setShape`. - - Customizable background color (`canvasBkColor`), border color (`canvasBorderColor`), border line style (`canvasLineStyle`), and fill mode (`canvasFillMode`, e.g., solid color, hatched pattern, no fill). - - Automatically manages the lifecycle of child controls (added via `addControl`, and destroyed when Canvas is destroyed). - - When drawing, Canvas will draw its background and then iterate through its child controls to draw them. For event handling, it propagates events to children (with last-added getting first chance). -- **Important Members:** - - `std::vector> controls;` The list of child controls. - - `StellarX::ControlShape shape;` Background shape of the container (default is RECTANGLE). - - `StellarX::FillMode canvasFillMode;` Background fill mode (default Solid color). - - `StellarX::LineStyle canvasLineStyle;` Border line style (default Solid line). - - `int canvaslinewidth;` Border line width in pixels. - - `COLORREF canvasBorderColor, canvasBkColor;` Border and background colors of the container. - - `StellarX::LayoutKind Kind;` (Reserved) Layout management type (Absolute/HBox/VBox/Grid). Not fully implemented but can be used to indicate layout strategy. - - **Note:** Canvas overrides `isVisible()` to always return false because a Canvas itself is not considered a standalone visible entity for event loop prioritization (the event loop doesn't handle Canvas directly, only its children). This doesn't affect drawing or child event dispatch. -- **Main Methods:** - - `Canvas(); Canvas(int x, int y, int width, int height);` - **Description:** Constructors to create a Canvas container at position `(x,y)` with given size. - - `void addControl(std::unique_ptr control);` - **Description:** Adds a child control to the canvas. The child control's coordinates are relative to the canvas (Canvas does not reposition children automatically; you should set the child's position accordingly before adding). After adding, the Canvas is marked dirty so it will redraw with the new content. - - `void setShape(StellarX::ControlShape shape);` - **Description:** Sets the canvas background shape. Supports `RECTANGLE`, `B_RECTANGLE` (borderless rectangle), `ROUND_RECTANGLE` (rounded corners with border), `B_ROUND_RECTANGLE` (rounded without border). If a circular/ellipse shape is passed, Canvas does not support it (it will treat it as RECTANGLE internally). - - `void setCanvasFillMode(StellarX::FillMode mode);` - **Description:** Sets the background fill mode, e.g., Solid, Null (no fill), Hatched pattern, or pattern/bitmap fill. This influences how the background is drawn (using EasyX `setfillstyle`). Default is solid fill. - - `void setBorderColor(COLORREF color);` / `void setCanvasBkColor(COLORREF color);` / `void setCanvasLineStyle(StellarX::LineStyle style);` / `void setLinewidth(int width);` - **Description:** Set the container's border color, background color, border line style, and line width, respectively. Changing any of these will mark the Canvas dirty (to be redrawn). - - `void draw() override;` - **Description:** Draws the canvas background and all its child controls. Steps: - 1. If not dirty, returns immediately (no redraw needed). - 2. Saves current style and sets line color, fill color, fill style, and line style based on canvas properties. - 3. Draws the background shape: e.g., calls `fillrectangle` or `fillroundrect` depending on `shape`. If an unsupported shape (Circle/Ellipse) was set, it defaults to rectangle. - 4. Iterates over `controls` and calls each child's `setDirty(true)` then `draw()`, ensuring each child is redrawn on this canvas. - 5. Restores the style and marks itself clean (`dirty = false`). - *Note:* Canvas uses `saveStyle()`/`restoreStyle()` to preserve global drawing state, and uses EasyX drawing functions to fill the background according to its shape. - - `bool handleEvent(const ExMessage& msg) override;` - **Description:** Propagates the event to its children in reverse order (so the last added child gets the event first). It iterates `controls` from end to start and calls each child's `handleEvent(msg)`. If any child returns true (meaning it consumed the event), Canvas stops and returns true. If none consumed it, returns false. - *Use case:* This ensures that in overlapping or layered controls, the topmost (last added) gets first crack at the event, implementing a basic Z-order. - - `void clearAllControls();` *(protected)* - **Description:** Clears all child controls from the canvas, deleting them. This releases all smart pointers in the `controls` list. Typically used in destructor or when resetting the UI. In normal use, you don't call this directly (the Canvas destructor will automatically free children). - -### Label Class (Static Text Label) - -**Description:** `Label` displays a static text string on the UI. It supports transparent background and custom text style, but does not handle user input (no interactive events). It is lightweight and intended for captions, status messages, etc. - -- **Constructors:** - - - `Label(); Label(int x, int y, std::string text = "标签", COLORREF textColor = BLACK, COLORREF bkColor = WHITE);` - **Description:** Creates a Label control at `(x,y)`. You can specify initial text, text color, and background color. The default text is "标签" (label in Chinese), default text color is black, background is white. - -- **Key Properties:** - - - `std::string text;` The text content displayed. - - `COLORREF textColor;` The text color. - - `COLORREF textBkColor;` The background color behind the text when not transparent. - - `bool textBkDisap;` Flag indicating if the background is transparent. If true, the label is drawn with a transparent background (so whatever is behind it shows through); if false, it draws an opaque rectangle behind the text using `textBkColor`. - - `StellarX::ControlText textStyle;` The text style struct (includes font face, size, weight, etc. as well as text color). - - **Note:** Label's width and height are initially 0; usually a Label's size is determined by its text content automatically when drawn. You normally don't need to set width/height for labels. - -- **Main Methods:** - - - `void setTextdisap(bool transparent);` - **Description:** Sets whether the label's background is transparent. If true, when drawing, the text is rendered with `TRANSPARENT` background mode (not overwriting the background behind it). If false, the text is drawn on an opaque background colored `textBkColor`. - - `void setTextColor(COLORREF color);` / `void setTextBkColor(COLORREF color);` - **Description:** Sets the text color and background color, respectively. After setting, the label is marked dirty for redraw. - - `void setText(std::string text);` - **Description:** Changes the label's displayed text content. Marks the label dirty (so it will redraw with the new text). - - `void draw() override;` - **Description:** Draws the label's text (and background if not transparent). It: - - Calls `saveStyle()`. - - If `textBkDisap` is true, calls `setbkmode(TRANSPARENT)`; otherwise `setbkmode(OPAQUE)` and sets `bkcolor` to `textBkColor`. - - Sets the text color via `settextcolor(textColor)` and font via `settextstyle` based on `textStyle`. - - Saves the area behind where the text will be drawn using `saveBackground` (so it can restore it later if needed). - - Writes the text at `(x,y)` using `outtextxy`. - - Restores the drawing style and marks `dirty = false`. - This approach ensures that if the label text is redrawn, the background behind it is handled properly. - - `bool handleEvent(...) override;` - **Description:** Label does not handle any events; it always returns false (meaning it never consumes events). - - `void hide();` - **Description:** Hides the label. Specifically, it uses `restBackground()` to put back the saved background (erasing the text from the screen) and then `discardBackground()` to free the snapshot, and sets `dirty = false`. This is typically used when a Label is serving as a transient tooltip or overlay and needs to be removed without causing a full screen redraw. - -- **Usage Scenarios:** - Label is used for static text like descriptions, titles, or status information. You can adjust `textStyle` to change the font and size (by default, the font might be "微软雅黑" with height 0 meaning default height). For example: - - ``` - Label *status = new Label(10, 10, "Ready", RGB(0,128,0)); - status->textStyle.nHeight = 20; // set font size if needed - ``` - - If you want the label to blend into a custom background, you can do: - - ``` - status->setTextdisap(true); - ``` - - to make the background transparent. - -### Button Class (Button Control) - -**Description:** `Button` provides a clickable button control, supporting both standard push-button behavior and toggle (on/off) behavior. It handles click and hover events, and allows setting various styles (shape, colors). Buttons are one of the primary interactive controls. - -- **Operating Modes:** Determined by `StellarX::ButtonMode`: - - - `NORMAL` – Standard push-button. Each click triggers an action but does not maintain a pressed state. - - `TOGGLE` – Toggle button. Each click changes the button's state (pressed vs not pressed) and triggers different callbacks for each state. - - `DISABLED` – Disabled button. It does not respond to user clicks and typically displays in a grayed-out style with strikeout text. - - The mode can be changed via `setButtonMode(ButtonMode mode)`. - -- **Appearance Shape:** Determined by `StellarX::ControlShape`: - - - Supports rectangle (`RECTANGLE`/`B_RECTANGLE`), rounded rectangle (`ROUND_RECTANGLE`/`B_ROUND_RECTANGLE`), circle (`CIRCLE`/`B_CIRCLE`), and ellipse (`ELLIPSE`/`B_ELLIPSE`) – eight shape options in total (`B_` prefix indicates borderless). Use `setButtonShape(ControlShape shape)` to set. - - Note: When switching shapes, ensure the button's width/height are appropriate (for circle/ellipse shapes, the drawing will use width and height differently; circle uses min(width,height)/2 as radius, ellipse uses width,height as bounding box). - - The button's border will be drawn for shapes without the `B_` prefix; borderless shapes omit the border. - -- **Key Configurable Properties:** - - - **Colors:** - - `buttonTrueColor` – color when button is in pressed state (for toggle or momentary press in normal mode). - - `buttonFalseColor` – color when button is not pressed (normal default state). - - `buttonHoverColor` – color when mouse is hovering over the button. - - `buttonBorderColor` – border outline color. - - **Fill:** - - `buttonFillMode` – fill mode for the button background (solid, hatched pattern, custom pattern, custom image). - - `buttonFillIma` – pattern style for hatched fills (if `FillMode == Hatched`). - - `buttonFileIMAGE` – pointer to an `IMAGE` for custom image fill (if `FillMode == DibPattern`). - - **Text:** - - `text` – the text label displayed on the button. - - `textStyle` – text style (font face, size, weight, etc., including text color). - - Additionally, `cutText` is used internally if the text is too long to fit; the button can automatically truncate and add "..." or a Chinese ellipsis to fit. - - **Tooltip (hover hint):** - - `tipEnabled` – whether a tooltip is enabled on hover. - - `tipTextClick` – tooltip text for the NORMAL mode (single-state). - - `tipTextOn` / `tipTextOff` – tooltip texts for toggle mode when the button is ON or OFF. - - `tipFollowCursor` – if true, tooltip appears near the cursor; if false, tooltip appears at a fixed offset below the button. - - `tipDelayMs` – delay in milliseconds before tooltip appears when hovering. - - `tipOffsetX, tipOffsetY` – offset of tooltip position relative to cursor or button (depending on `tipFollowCursor`). - - `tipLabel` – an internal `Label` object used to display the tooltip text. - - **Rounded Corner Size:** In round-rectangle shapes, the corner radii come from the inherited `rouRectangleSize` (`ROUND_RECTANGLEwidth` and `height`). Set via `setRoundRectangleWidth(int)` and `setRoundRectangleHeight(int)`. - -- **Main Methods:** - - - `void setOnClickListener(const std::function&& callback);` - **Description:** Sets the callback function to be invoked when the button is clicked in NORMAL mode. For a toggle button, this callback is called every time the button is clicked (but typically you might use toggle-specific callbacks instead). The callback is executed when the user releases the mouse button over the button. - - `void setOnToggleOnListener(const std::function&& callback);` - **Description:** Sets the callback for when a toggle button is switched to the "on/pressed" state. - - `void setOnToggleOffListener(const std::function&& callback);` - **Description:** Sets the callback for when a toggle button is switched to the "off/released" state. - - `void setButtonText(const char* text)` / `void setButtonText(std::string text);` - **Description:** Changes the button's label text. Accepts a C-string or an std::string. After changing, it recalculates the text width/height (for centering and truncation logic) and marks the button dirty to redraw. - - `void setButtonBorder(COLORREF border);` / `void setButtonFalseColor(COLORREF color);` - **Description:** Sets the border color and the default (false) state fill color, respectively. - - `void setFillMode(FillMode mode);` / `void setFillPattern(FillStyle pattern);` / `void setFillImage(const std::string& path);` - **Description:** Configures the background fill of the button: - - `setFillMode` changes the fill mode (solid, hatched pattern, custom bitmap, etc). - - If setting to a hatched pattern fill, call `setFillPattern` to choose the hatch style (`StellarX::FillStyle`). - - If setting to a custom image fill, call `setFillImage` with the image file path; it will load the image (resizing to button size) and store it in `buttonFileIMAGE`. - - `void setButtonClick(bool click);` - **Description:** Programmatically sets the button's "clicked" state. - - For NORMAL mode: setting true will simulate a click – it triggers the onClick callback (if any) and then immediately resets to false (not pressed). - - For TOGGLE mode: setting true or false will force the button into that state and trigger the corresponding onToggle callback if provided. - - In any case, it marks the button dirty and redraws it (ensuring visual state update). - - **Note:** If the button is disabled, this method has no effect. - - `bool isClicked() const;` - **Description:** Returns whether the button is currently in the pressed state. This is primarily meaningful for toggle buttons (true if toggled on, false if off). For a normal button, this is typically false except during the brief moment of click handling. - - Other getters such as `getButtonText()`, `getButtonMode()`, `getButtonShape()`, `getFillMode()`, `getFillPattern()`, `getFillImage()`, `getButtonBorder()`, `getButtonTextColor()`, `getButtonTextStyle()`, `getButtonWidth()`, `getButtonHeight()` provide read access to the button's corresponding properties. - - `void draw() override;` - **Description:** Draws the button's background and text according to its current state and properties: - - Chooses the fill color based on state: if disabled, uses `DISABLEDCOLOUR` (gray) and applies a strike-out to the text; otherwise, if `click` is true (pressed or toggled on) uses `buttonTrueColor`, else if `hover` is true uses `buttonHoverColor`, otherwise `buttonFalseColor`. - - Sets transparent background mode for text, sets border color and text style (color, font). - - If `needCutText` is true, calls `cutButtonText()` to possibly truncate the text with ellipsis if it doesn't fit in the button width. - - Recalculates `text_width` and `text_height` if the text content or style changed (to ensure text is centered correctly). - - Sets the fill style for background (using `buttonFillMode`, pattern or image as needed). - - Draws the shape: - - For rectangle shapes: uses `fillrectangle` or `solidrectangle`. - - For round-rectangle: uses `fillroundrect` or `solidroundrect` with `rouRectangleSize` radii. - - For circle: uses `fillcircle` or `solidcircle` with radius = min(width,height)/2. - - For ellipse: uses `fillellipse` or `solidellipse` with bounding box corners. - - Draws the text: - - It calculates the position to center the text/cutText horizontally and vertically within the button. - - If `isUseCutText` is true (meaning the original text was truncated), it draws `cutText` (with "..." or Chinese ellipsis). - - Otherwise, draws the full `text`. - - Restores style and marks dirty false after drawing. - - `bool handleEvent(const ExMessage& msg) override;` - **Description:** Handles mouse events for the button: - - If the button is hidden (`show == false`), returns false immediately. - - Tracks the previous `hover` and `click` states to detect changes. - - If the message is `WM_MOUSEMOVE`, updates `lastMouseX/Y` for tooltip positioning. - - Determines `hover` state by checking if the mouse `(msg.x, msg.y)` is within the button's shape (calls `isMouseInCircle` or `isMouseInEllipse` for those shapes, otherwise simple rectangle bounds check). - - Handling `WM_LBUTTONDOWN`: if button is enabled and mouse is over it: - - In NORMAL mode: set `click = true` (button appears pressed), mark dirty, and mark event consumed. - - In TOGGLE mode: do nothing on down (toggle action is deferred to release). - - Handling `WM_LBUTTONUP`: if button is enabled and mouse is currently over it: - - In NORMAL mode: if it was pressed (`click` was true), trigger the onClick callback (if set), then set `click = false` (release it). Mark dirty, consume event, and hide tooltip (if any). Also flush the message queue of any pending mouse/keyboard events using `flushmessage` to prevent processing a duplicate click message. - - In TOGGLE mode: flip the `click` state (`click = !click`). If it becomes true, trigger onToggleOn callback; if false, trigger onToggleOff callback. Mark dirty, consume event, update tooltip text via `refreshTooltipTextForState()`, hide tooltip, and flush message queue similarly. - - Handling `WM_MOUSEMOVE`: - - If moving outside (not hover anymore) while in NORMAL mode and the button was pressed (`click == true`), then user is dragging out: set `click = false` (cancel the press) and mark dirty (so it returns to unpressed visual). - - If hover state changed (entered or exited), mark dirty. - - Tooltip management: - - If tooltip enabled (`tipEnabled`): - - If just hovered (hover true and oldHover false): record the timestamp via `tipHoverTick` and set `tipVisible = false` (starting hover timer). - - If just exited (hover false and oldHover true): immediately call `hideTooltip()` (which hides the tooltip label if it was visible). - - If still hovering and tooltip not yet visible: - - Check if current time minus `tipHoverTick` >= `tipDelayMs`; if so: - - Set `tipVisible = true`. - - Determine tooltip position: if `tipFollowCursor` is true, `tipX = lastMouseX + tipOffsetX`, `tipY = lastMouseY + tipOffsetY`. If false, perhaps `tipX = lastMouseX` (or button center) and `tipY = y + height` (so it appears below the button). - - Set the tooltip text: if `tipUserOverride` is true (meaning user explicitly set tooltip text via `setTooltipText` or `setTooltipTextsForToggle`), then: - - For NORMAL mode: always use `tipTextClick` (explicitly set text or maybe button text by default). - - For TOGGLE mode: use `click ? tipTextOn : tipTextOff`. - - If `tipUserOverride` is false (no explicit text provided): - - If mode is TOGGLE: default behavior might be to use `tipTextOn/Off` (which could be set to default values like "On"/"Off" or left empty). - - If mode is NORMAL: possibly do nothing (the code currently only sets text in else for toggle, leaving normal with no dynamic text unless overridden). - - Position the internal `tipLabel` at (tipX, tipY), mark it dirty. - - After updating tooltip state, - - If `hover` or `click` state changed compared to old states, mark the button dirty so it will redraw to reflect highlight or press/unpress. - - If the button is dirty, call `draw()` immediately for real-time feedback. - - If tooltip is enabled and now visible (`tipVisible`), call `tipLabel.draw()` to draw the tooltip label. - - Return true if the event was handled (for example, a click or certain modal conditions), else false. - - (In summary, the event is considered consumed if a click occurred or if the modal logic swallowed it. Hover alone doesn’t consume the event.) - -- **Usage Notes:** - Typically, you create a Button and set its callback like: - - ``` - auto btn = std::make_unique