209 lines
11 KiB
C
209 lines
11 KiB
C
// dvx_wm.h — Layer 4: Window manager for DVX GUI
|
|
//
|
|
// Manages the window lifecycle, Z-order stack, chrome drawing, hit testing,
|
|
// and interactive operations (drag, resize, scroll). This layer bridges the
|
|
// low-level drawing/compositing layers below with the high-level application
|
|
// API above.
|
|
//
|
|
// Design philosophy: the WM owns window geometry and chrome, but the
|
|
// window's content is owned by the application (via callbacks or the widget
|
|
// system). This separation means the WM can move, resize, and repaint
|
|
// window frames without involving the application at all — only content
|
|
// changes trigger application callbacks.
|
|
//
|
|
// All WM operations that change visible screen state accept a DirtyListT*
|
|
// so they can mark affected regions for compositor repaint. This push-based
|
|
// dirty tracking avoids the need for a full-screen diff each frame.
|
|
#ifndef DVX_WM_H
|
|
#define DVX_WM_H
|
|
|
|
#include "dvxTypes.h"
|
|
|
|
// Zero the window stack. Must be called before any other wm function.
|
|
void wmInit(WindowStackT *stack);
|
|
|
|
// Allocate a new WindowT, initialize its geometry and content buffer, and
|
|
// push it to the top of the Z-order stack. The returned window has default
|
|
// callbacks (all NULL) — the caller should set onPaint/onKey/etc. before
|
|
// the next event loop iteration.
|
|
WindowT *wmCreateWindow(WindowStackT *stack, DisplayT *d, const char *title, int32_t x, int32_t y, int32_t w, int32_t h, bool resizable);
|
|
|
|
// Free the window's content buffer and all attached resources (menu bar,
|
|
// scrollbars, widget tree), then remove it from the stack and dirty the
|
|
// region it occupied.
|
|
void wmDestroyWindow(WindowStackT *stack, WindowT *win);
|
|
|
|
// Move window at stack index idx to the top of the Z-order. Dirties both
|
|
// the old and new top positions so overlapping windows get repainted.
|
|
void wmRaiseWindow(WindowStackT *stack, DirtyListT *dl, int32_t idx);
|
|
|
|
// Transfer keyboard focus to the window at stack index idx. Unfocuses the
|
|
// previously focused window and dirties both title bars (since active/
|
|
// inactive title colors differ).
|
|
void wmSetFocus(WindowStackT *stack, DirtyListT *dl, int32_t idx);
|
|
|
|
// Recompute contentX/Y/W/H from the window's outer frame dimensions,
|
|
// accounting for chrome borders, title bar, menu bar, and scrollbars.
|
|
// Must be called after any change to frame size or chrome configuration
|
|
// (e.g. adding a menu bar or scrollbar).
|
|
void wmUpdateContentRect(WindowT *win);
|
|
|
|
// Reallocate the per-window content backbuffer to match the current
|
|
// contentW/H. Returns 0 on success, -1 if allocation fails. The old
|
|
// buffer contents are lost — the caller should trigger a full repaint
|
|
// via onPaint after a successful realloc.
|
|
int32_t wmReallocContentBuf(WindowT *win, const DisplayT *d);
|
|
|
|
// Allocate and attach a menu bar to a window. Adjusts the content area
|
|
// to make room for the menu bar (CHROME_MENU_HEIGHT pixels). Only one
|
|
// menu bar per window is supported.
|
|
MenuBarT *wmAddMenuBar(WindowT *win);
|
|
|
|
// Append a dropdown menu to the menu bar. Returns the MenuT to populate
|
|
// with items. The label supports & accelerator markers (e.g. "&File").
|
|
MenuT *wmAddMenu(MenuBarT *bar, const char *label);
|
|
|
|
// Append a clickable item to a menu. The id is passed to the window's
|
|
// onMenu callback when the item is selected.
|
|
void wmAddMenuItem(MenuT *menu, const char *label, int32_t id);
|
|
|
|
// Add a checkbox-style item. Check state is toggled on click and
|
|
// rendered with a checkmark glyph.
|
|
void wmAddMenuCheckItem(MenuT *menu, const char *label, int32_t id, bool checked);
|
|
|
|
// Add a radio-style item. Radio groups are defined implicitly by
|
|
// consecutive radio items in the same menu — selecting one unchecks
|
|
// the others in the group.
|
|
void wmAddMenuRadioItem(MenuT *menu, const char *label, int32_t id, bool checked);
|
|
|
|
// Insert a horizontal separator line. Separators are not interactive.
|
|
void wmAddMenuSeparator(MenuT *menu);
|
|
|
|
// Create a cascading submenu attached to the parent menu. Returns the
|
|
// child MenuT to populate, or NULL if MAX_MENU_ITEMS is exhausted.
|
|
// The child MenuT is heap-allocated and freed when the parent window
|
|
// is destroyed.
|
|
MenuT *wmAddSubMenu(MenuT *parentMenu, const char *label);
|
|
|
|
// Attach a vertical scrollbar to the right edge of the window's content
|
|
// area. Shrinks contentW by SCROLLBAR_WIDTH pixels to make room. The
|
|
// scrollbar's value range and page size determine thumb proportions.
|
|
ScrollbarT *wmAddVScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize);
|
|
|
|
// Attach a horizontal scrollbar to the bottom edge. Shrinks contentH
|
|
// by SCROLLBAR_WIDTH pixels.
|
|
ScrollbarT *wmAddHScrollbar(WindowT *win, int32_t min, int32_t max, int32_t pageSize);
|
|
|
|
// Draw the window frame (outer bevel, title bar with text, close/minimize/
|
|
// maximize gadgets, and menu bar if present). clipTo restricts drawing to
|
|
// only the intersection with the given dirty rectangle, avoiding redundant
|
|
// pixel writes outside the damaged region.
|
|
void wmDrawChrome(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo);
|
|
|
|
// Blit the window's content backbuffer into the display backbuffer,
|
|
// clipped to the dirty rect. This is a pure copy (no drawing) — the
|
|
// content was already rendered by the application into contentBuf.
|
|
void wmDrawContent(DisplayT *d, const BlitOpsT *ops, WindowT *win, const RectT *clipTo);
|
|
|
|
// Draw scrollbars (track, arrows, proportional thumb) for a window.
|
|
// Drawn after content so scrollbars overlay the content area edge.
|
|
void wmDrawScrollbars(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, WindowT *win, const RectT *clipTo);
|
|
|
|
// Draw icons for all minimized windows along the bottom of the screen.
|
|
// Each icon shows a scaled-down preview of the window's content (or a
|
|
// default icon) with a beveled border, similar to DESQview/X's icon bar.
|
|
void wmDrawMinimizedIcons(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, const WindowStackT *stack, const RectT *clipTo);
|
|
|
|
// Determine which window and which part of that window is under the given
|
|
// screen coordinates. Iterates the stack front-to-back (highest Z first)
|
|
// so the topmost window wins. Returns the stack index, or -1 if no window
|
|
// was hit (i.e. the desktop). hitPart identifies the chrome region:
|
|
// HIT_CONTENT, HIT_TITLE, HIT_CLOSE, HIT_RESIZE,
|
|
// HIT_MENU, HIT_VSCROLL, HIT_HSCROLL, HIT_MINIMIZE, HIT_MAXIMIZE
|
|
int32_t wmHitTest(const WindowStackT *stack, int32_t mx, int32_t my, int32_t *hitPart);
|
|
|
|
// For a point within a window's border zone, determine which edge(s)
|
|
// are being targeted for resize. Returns a bitmask of RESIZE_xxx flags.
|
|
// Corner hits combine two edges (e.g. RESIZE_LEFT | RESIZE_TOP).
|
|
int32_t wmResizeEdgeHit(const WindowT *win, int32_t mx, int32_t my);
|
|
|
|
// Update window position during an active drag. Called on each mouse move
|
|
// event while dragWindow is active. Dirties both the old and new window
|
|
// positions. The drag offset (mouse position relative to window origin at
|
|
// drag start) is applied so the window tracks the mouse smoothly.
|
|
void wmDragMove(WindowStackT *stack, DirtyListT *dl, int32_t mouseX, int32_t mouseY, int32_t screenW, int32_t screenH);
|
|
|
|
// Update window dimensions during an active resize. Enforces MIN_WINDOW_W/H
|
|
// and optional maxW/maxH constraints. Reallocates the content buffer if the
|
|
// content area size changed, then calls onResize to notify the application.
|
|
// mouseX/mouseY are in/out: on return they hold the clamped position so the
|
|
// caller can warp the hardware cursor to keep it stuck to the window edge.
|
|
void wmResizeMove(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, int32_t *mouseX, int32_t *mouseY);
|
|
|
|
// Begin a window drag operation. Records the mouse offset from the window
|
|
// origin so the window doesn't jump to the cursor position.
|
|
void wmDragBegin(WindowStackT *stack, int32_t idx, int32_t mouseX, int32_t mouseY);
|
|
|
|
// End the current drag operation. Clears dragWindow state.
|
|
void wmDragEnd(WindowStackT *stack);
|
|
|
|
// Begin a window resize operation. Records which edge(s) are being dragged
|
|
// and the initial mouse position for delta computation.
|
|
void wmResizeBegin(WindowStackT *stack, int32_t idx, int32_t edge, int32_t mouseX, int32_t mouseY);
|
|
|
|
// End the current resize operation. Clears resizeWindow state.
|
|
void wmResizeEnd(WindowStackT *stack);
|
|
|
|
// Set window title
|
|
void wmSetTitle(WindowT *win, DirtyListT *dl, const char *title);
|
|
|
|
// Handle an initial click on a scrollbar. Determines what was hit (up/down
|
|
// arrows, page trough area, or thumb) and either adjusts the value
|
|
// immediately (arrows, trough) or begins a thumb drag operation.
|
|
void wmScrollbarClick(WindowStackT *stack, DirtyListT *dl, int32_t idx, int32_t orient, int32_t mx, int32_t my);
|
|
|
|
// Update the scroll value during an active thumb drag. Maps the mouse
|
|
// position along the track to a scroll value proportional to the range.
|
|
void wmScrollbarDrag(WindowStackT *stack, DirtyListT *dl, int32_t mx, int32_t my);
|
|
|
|
// End an active scrollbar thumb drag.
|
|
void wmScrollbarEnd(WindowStackT *stack);
|
|
|
|
// Maximize a window (saves current geometry, expands to screen/max bounds)
|
|
void wmMaximize(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
|
|
|
|
// Minimize a window (hides window, shows icon at bottom of screen)
|
|
void wmMinimize(WindowStackT *stack, DirtyListT *dl, WindowT *win);
|
|
|
|
// Hit-test minimized icons at bottom of screen
|
|
// Returns stack index of the minimized window, or -1
|
|
int32_t wmMinimizedIconHit(const WindowStackT *stack, const DisplayT *d, int32_t mx, int32_t my);
|
|
|
|
// Compute screen position of a minimized icon by ordinal index.
|
|
// Icons wrap into rows from bottom to top when the screen is full.
|
|
void wmMinimizedIconPos(const DisplayT *d, int32_t index, int32_t *x, int32_t *y);
|
|
|
|
// Compute the screen rect covering all minimized icon rows.
|
|
// Used to dirty the icon area when windows are minimized or restored.
|
|
void wmMinimizedIconRect(const WindowStackT *stack, const DisplayT *d, int32_t *y, int32_t *h);
|
|
|
|
// Restore a maximized window to its pre-maximize geometry
|
|
void wmRestore(WindowStackT *stack, DirtyListT *dl, const DisplayT *d, WindowT *win);
|
|
|
|
// Restore a minimized window
|
|
void wmRestoreMinimized(WindowStackT *stack, DirtyListT *dl, WindowT *win);
|
|
|
|
// Load an icon image for a window (converts to display pixel format)
|
|
int32_t wmSetIcon(WindowT *win, const char *path, const DisplayT *d);
|
|
|
|
// Allocate a heap-resident MenuT for use as a context menu (right-click).
|
|
// Unlike menu bar menus (which are embedded in MenuBarT), context menus
|
|
// are standalone allocations because they may be shared across windows or
|
|
// attached/detached dynamically. Free with wmFreeMenu().
|
|
MenuT *wmCreateMenu(void);
|
|
|
|
// Free a standalone menu allocated with wmCreateMenu(). Also frees any
|
|
// heap-allocated submenu children recursively.
|
|
void wmFreeMenu(MenuT *menu);
|
|
|
|
#endif // DVX_WM_H
|