Wuss platypus - #7
Merged
Merged
Conversation
Adds an eleventh launcher task to the interactive wuss test: the two bundled composite demo images (resources/composite/A.png and B.png) composited under a Porter-Duff rule that cycles through all twelve operators, over an alpha checkerboard so transparency reads as transparent rather than white. composite() takes no offset or alpha parameter, so the animation is a per-frame edit on scratch copies: the destination is restored from a pristine B and the source's alpha channel is scaled by a triangle ramp (0 to 255 and back across each rule's turn). Alpha is non-premultiplied, so only the alpha byte is touched. Pacing is a per-idle frame counter, as in ball.c; clicking advances the rule and the wheel adjusts the cycle speed. The bitmap clone/convert helpers are copied from composite-test.c, where they are statics rather than library functions. Widens the launcher window to fit the longer entry name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adjust-clicking a scroll arrow now steps against the direction the arrow points, so a single arrow can be worked both ways without moving the pointer. Toggle-size remains Select-only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ction Reflows the Doxygen parameter blocks in window.h and wuss.h, and renames the README's "Wuss" section to "Windowing".
Select/Menu/Adjust were consecutive enumerated values, so a chord such as Select+Adjust could not be expressed at all. They become flags -- Select 4, Menu 2, Adjust 1, matching the RISC OS button order -- with a wuss_BUTTON_NONE of zero, and every internal comparison switches from equality to a bit test. Where a chord is ambiguous Select wins: a Select+Adjust click on a scroll arrow scrolls the way the arrow points rather than backwards, and on the back icon sends the window to the back. BREAKING CHANGE: wuss_button_t's values have changed, and client code comparing the reported button for equality must now test with '&' or it will fail to match a chord. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Matches the per-area layout of the other docs (databases, datastruct, framebuf, geom, io).
Names the terms the document already leans on: the three coordinate spaces (screen, window-local, virtual content), content area versus visible bounds, furniture and its parts, and the RISC OS button conventions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
doc already caps how large a resize-drag or toggle-size can make a window; the floor was the fixed WUSS_MIN_CONTENT, so a task whose content stops making sense below some size had no way to say so. wuss_window_create gains a min_doc alongside doc, set once at creation. wuss__min_content clamps it up to WUSS_MIN_CONTENT, so a window can never be squeezed too small to grab, and down to doc, so a minimum can never demand a window larger than the document it shows. Pass (0,0) for the built-in floor. BREAKING CHANGE: wuss_window_create takes a min_doc argument between doc and window. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The launcher entry table is now const, so the per-row "running" flag can no longer live in it. Move it into launcher_task as a fixed-size bool array indexed by entry, capped at LAUNCHER_MAX_ENTRIES. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace inline (point_t) { x, y } and (size2d_t) { w, h } compound
literals across the tree with POINT(x, y) / SIZE2D(w, h) helpers defined
alongside their types.
Also folds in a pre-existing null-pointer guard in bmfont_get_info and
minor alignment tidy-ups that were already in the working tree.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Resize-drag recomputed width/height as pointer minus content origin on every move, discarding where within the resize icon the mouse-down click landed. The window's corner snapped to the raw pointer position on the first move, jumping if the click wasn't at the icon's exact corner pixel. Store the pointer's offset from the content box's bottom-right corner at mouse-down (mirroring how a titlebar drag already stores its content-relative offset), and subtract it on each move, so the grabbed point stays under the pointer through the drag. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TWwV3bFEi9z5MZc5wqiJzZ
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add a work-area icon subsystem: static labels and clickable bevelled buttons that Wuss draws inside a window's content area and hit-tests before the content task sees a click. Icon boxes are in virtual document space so they scroll with the content; button clicks and hovers reach the task as wuss_EVENT_ICON, while labels and hidden or disabled icons fall through as wuss_EVENT_MOUSE. Includes the public wuss/icon.h API, per-window icon storage, drawing, mouse routing integration, and an icons test task. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The icons task drew its backdrop grid and x/y axis rulers pinned to the window edge, so Wuss's scroll blit displaced the painted pixels without repainting them, smearing the labels. Anchor all task drawing to document space so it scrolls rigidly with the content, as the blit assumes; add a bmfont-drawn coordinate ruler along the document x=0 and y=0 lines. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Loops wuss_icon_create over a spec array with all-or-nothing rollback: on the first failure any icons already created by the call are destroyed and no handles are written. Converts the icons test task to use it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a BORDER margin around the bitmap, a min-doc resize floor, and a pink background so the border and transparent pixels are visible. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
image_create took the repo root and built the PNG path itself; it now takes the full filename, with path assembly moved to the spawn_image caller in wuss-test.c. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New entry point taking a content size instead of a box: wuss packs the window (furniture included) into the first free screen region via a packer_t it owns, top-left order, tracking occupied area across calls so successive auto-placed windows tile. Cascades from the previous placement when no region fits. The slot is released back to the pool on close, and on the first wuss_window_move / wuss_window_resize (a titlebar drag counts as a move), after which wuss stops tracking the window's position. Adds packer_release() to geom/packer as the inverse of packer_place_*; released areas are not coalesced, which is sufficient for whole-window placement. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Switch every test task from a hardcoded BOX_POS_SIZE origin to wuss_window_create_placed, passing just the content size. Windows now tile from the top-left instead of landing at fixed coordinates. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
packer_place_by now searches for the box plus a configurable gutter strip along its two inner edges, so boxes placed by location never end up flush. The gutter defaults to 0, leaving every existing caller unchanged. The returned position is still the un-inflated box. wuss_window_create_placed sets a fixed WUSS_PLACE_GUTTER and stores the gutter-inflated region in wuss_window::packed so the whole reservation, not just the footprint, is handed back on close/move. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Each wireframe model in the sofa test task now draws a small white square at every projected vertex, on top of the edges. Also adds a Cobra Mk III model alongside the existing ship. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…lines The anti-aliased fixed-point line rasteriser had three undefined behaviours, all reachable with long or off-screen endpoints: - FIX16_ONE * dy_f8 (and grad_f16 * dx) overflowed 32-bit int once a line exceeded ~32k fixed-point units; compute those in long long. - INT_TO_FIX8(iy) left-shifted pixel Y coordinates that can be negative; use a multiply instead. - the yf recurrence left-shifted a possibly-negative fix8 value before shifting back; form the fix16 sum by multiply, then arithmetic-shift down. Adds test_wu_fix8_extreme_coords covering large and off-screen endpoints, and fixes the test draw() helper's own negative left shift. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the launcher's hand-drawn text rows and bespoke mouse hit-testing with wuss_ICON_TYPE_BUTTON icons created via wuss_icon_create_array; wuss now paints and hit-tests them and delivers clicks as wuss_EVENT_ICON. Each click spawns a fresh instance of the row's task, so a row can be clicked any number of times. Drops launcher_redraw/launcher_mouse, the running[] tint array, and the now-unused font and palette parameters. Shutdown calls every entry's destroy() unconditionally (NULL-safe). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reuses WUSS_PLACE_GUTTER to pad the whole screen.
Every launcher task backed its state with a single file-scope static in wuss-test.c, so spawning a task twice made both windows share one state block and only the latest window's animation ran. Each spawn_* now calloc's a fresh per-instance block, passes it to the task's *_create, and frees it again if create fails or opens no window. Each task's wuss_EVENT_CLOSE handler frees its own block (and any owned bitmaps); the checker task, whose two windows share one block, frees it once both have closed. The now-redundant *_destroy functions, the twelve g_*_task statics, the destroy_* wrappers and the launcher_entry_t.destroy column are removed. wuss_idle already walks every window, so tasks now animate independently in as many windows as are open. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New tools/wrap_protos.py rewraps C function prototypes and definitions onto one parameter per line, declarators aligned in a column (the style in screen-copy-rect.c), but only when the one-line form exceeds 80 columns. Conservative guards keep it off call statements, control-flow, macro bodies and comment text. Handles function-pointer and array parameters. Self-check in tools/test_wrap_protos.py. Applied across the tree: 35 files rewrapped. Builds clean (nosdl, sdl, asan); DPTLibTest 24/24. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Draw a 3x3-grid source image into a destination box: corners at natural size, edges and centre tiled. Clipped to the destination and the screen clip, which is restored on return. Inherits pixel-format support and blending from screen_draw_bitmap. Exercised by a new screen test and by the wuss SDL image task, which now tiles resources/wuss/9tile.png behind the loaded PNG. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
screen_draw_ninepatch gains a flags argument; passing screen_NINEPATCH_NO_CENTRE draws only the border and leaves the interior untouched. Existing callers pass 0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A button icon pressed on MOUSE_DOWN stayed pressed if the client's ICON handler opened a window covering the icon's owner: the later MOUSE_UP resolved via wuss__window_at to the new window and never reached the pressed icon. Track the held icon on struct wuss as pressed_icon (mirroring furniture.dragging) and release it on any MOUSE_UP before the window hit-test. Also clear it on pointer-leave in mouse-move, and in wuss_window_close and wuss_icon_delete so it can't dangle. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…piece onto another's vacated ground With an occluder biting a corner out of a window's pre-move footprint, the clean (non-occluded) pieces can overlap in destination: on a downward drag a full-width bottom band slides straight into the destination of the right-side band. The vacated-sliver invalidate only subtracted each piece's own destination, so that shared ground -- which the other piece's blit had already filled with valid pixels -- was invalidated and repainted across the full window width for nothing. Compute each sliver as clean[i] minus every clean piece's destination via wuss__subtract_boxes, not just full_dest[i]. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The resize icon and scrollbar wells shared a restack block, so grabbing a scroll well on Select popped the window to the front. Restrict the raise to FURNITURE_RESIZE. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Two CMake options, WUSS_FURNITURE and WUSS_ICONS (both default ON, so current behaviour is unchanged), drop the respective furniture/*.c and icon/*.c files from the build and #ifdef-guard every core call site, struct field and inline helper that references them. With WUSS_FURNITURE off every window is chromeless: content box == visible box, no furniture drawn, hit-tested or dragged. wuss__scroll_clamp and wuss__scroll_step move to a new core file scroll-step.c so programmatic and wheel scrolling survive. With WUSS_ICONS off the wuss_icon_* API is not compiled and struct wuss/wuss_window lose their icon fields. The icon typedef moves to wuss.h (forward declaration) so wuss_event_t can name it regardless of the option; icon.h's body is wrapped in #ifdef WUSS_ICONS and dropped from PUBLIC_HEADERS when off. Tests stay ON-only: tasks/icons.c, tasks/launcher.c and the SDL interactive driver build only when both options are on. The core wuss_test is split - the existing body is gated on both options, with a compact core-only replacement exercising the chromeless window path (create, move, z-order, doc coordinates, scroll, invalidate, close) for the off configs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add screen_fill_pattern(), an 8x8 two-colour tile fill primitive in framebuf/screen with eight built-in patterns (solid, grey50, stripes, diagonal, dots, grid, crosshatch), phase-locked to a caller-supplied origin so a scrolling fill stays put. Add wuss_ICON_TYPE_PATTERN: a non-interactive icon whose bbox is filled with one of those patterns in fg/bg, aligned to document space. Clicks fall through as wuss_EVENT_MOUSE; disabled swatches fold fg into bg. Cover the primitive in screen-test.c (phase, clipping) and show every pattern in the interactive icons task. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The tile is 8x8 and repeats, so a fill has only eight distinct pixel rows. Expand each to a phase-shifted colour run once up front; the scanline loops then index the run with no per-pixel bit test. The 32bpp path memcpy's whole 8-pixel runs instead of storing pixel by pixel. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Covers screen_fill_pattern(), wuss_ICON_TYPE_PATTERN, the WUSS_FURNITURE/WUSS_ICONS compile-time options and the scrollbar-well raise fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
When dst was narrower or shorter than two patch cells the near and far corner boxes overlapped and each drew its cell full-size across the shared band, so the last one won. Clamp the corner column/row boundaries to the destination midpoint: the near corner keeps the near half, the far corner the far half, and the edge/centre runs between collapse. Also assert log2bpp >= 3 in ninepatch_cell so a sub-8bpp source aborts cleanly instead of hitting a negative shift, and hoist a mid-scope loop var. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
next_cascade had a single wrap check and no loop, so a footprint wider or taller than the screen made the wrap condition permanently true and every oversized auto-placed window landed at (0,0). Pin an over-screen footprint at the top-left and return without advancing the cascade counter, so later normal-sized windows still cascade. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The backdrop and bevel-colour range check plus its free/free/return cleanup were duplicated across the WUSS_FURNITURE and WUSS_ICONS-only branches and had drifted: the two paths defaulted the bevel colours differently for a NULL config. Extract validate_bevel_backdrop() and default both bevels to 0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sform wuss__icon_screen_box was declared, compiled and linked with zero callers, re-deriving the content-to-screen bbox transform that wuss__icon_draw open-codes. Drop it for wuss__icon_box_to_screen(content, scroll, bbox, out), which wuss__icon_draw now routes through, so the transform exists once. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
screen_copy_rect also returns 0 for an off-screen source or destination, and the blit pieces are only occlusion-clipped, so a later piece can fail after earlier pieces have already moved pixels. The frame still self-heals via the union fallback; the comment now says so instead of claiming the blit fails identically on the first piece. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @dpt, your pull request is larger than the review limit of 150,000 diff characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.