Skip to content

v0.3.0

Choose a tag to compare

@roblillack roblillack released this 07 Jun 12:58
· 13 commits to main since this release

Fixed

  • The filer example no longer confuses scrolling with dragging a file out.
    The drag-out gesture armed on a press anywhere inside the list bounds — which
    include the scrollbar pinned to the right edge — so grabbing the thumb both
    scrolled and armed a drag, and the drag won on the next move (yanking a file
    out instead of scrolling). It now yields the scrollbar strip via the new
    List::scrollbar_hit. Relatedly, ScrollBar and Slider now end an
    in-progress thumb drag on PointerLeave: with no OS pointer grab, a drag
    interrupted by the pointer leaving the window (as an outbound drag-and-drop
    does by revoking pointer focus) left a stale drag flag set, so the thumb
    chased the cursor when it returned. (#35)
  • TextEditor is no longer pathologically slow to repaint with large or
    long-lined documents. Each frame rebuilt every visible row's caret-offset
    table by re-measuring every prefix of the line (O(n²)) and re-rasterized every
    glyph from scratch — including ones scrolled off the right edge — and the
    runtime repaints the whole tree on every scroll notch and resize step. The
    font now caches rasterized glyphs (in a bounded LRU) and per-glyph advances,
    the caret table is built in one O(n) pass over those advances, and
    Font::draw_phys stops at the clip's right edge. Output is snapshot-identical;
    the worst case is ~100× faster. (#34)
  • include_svg! now maps every contour through its abs_transform (the full
    ancestor chain, viewBox→viewport origin offset and scale included), while still
    framing the baked image by the SVG's declared viewport (the box resvg renders
    into). This fixes SVGs that previously baked mis-scaled or off-frame — a viewBox
    with a non-zero origin or an <svg> whose width/height differ from the viewBox
    — without disturbing artwork that is deliberately padded inside its viewBox
    (the scrollbar, dropdown, dialog, and checkbox marks). (#27, #31)
  • Firing a menu item by its keyboard mnemonic no longer leaks the letter into
    whatever the item opens. Picking File → Open with Alt+F, O previously typed an
    "o" into the dialog's freshly focused File name field; the menu now swallows
    the keystroke through its release. (#30)

Added

  • FileDialog: a modern, single-pane Open / Save file picker (built on Modal)
    with the current path along the top, one combined list of folders and files,
    a "File name" field, and a "File types" filter dropdown — the flat layout
    modern KDE / Windows pickers use. Section labels carry Alt+L / Alt+N / Alt+T
    accelerators. Glob-based FileFilters drive the filter. The notepad example
    now uses it for File → Open and File → Save As. (#26)
  • Window-chrome screenshots: MockBackend::render_framed wraps a rendered
    client area in Canoe's default desktop style — a teal background, a soft drop
    shadow, a navy active title bar, and a window frame. Choose the frame via
    WindowChrome::resizable / fixed / dialog (WindowFrame), which mirror
    Canoe's three window paints and differ in their window controls and border;
    with_desktop_background / with_margin tweak the backdrop. Windows are
    always drawn active. See the new chrome example. (#33)
  • include_svg! now honors clip-path: clip regions are intersected with the
    drawn geometry at build time (via i_overlay), so clipped artwork bakes
    correctly instead of being dropped. i_overlay is a compile-time-only
    dependency of saudade-macros and never reaches a shipped binary. (#27)
  • include_svg! takes an optional crop argument —
    include_svg!("logo.svg", crop) — that frames the baked image by the tight
    bounding box of the drawn geometry instead of the SVG's declared viewport,
    dropping any padding so the mark fills its target rect. The default is still
    viewport framing (matching resvg). (#31)
  • include_svg! now approximates linear and radial gradient paint instead of
    dropping it: each gradient bakes into a stack of flat-color bands (strips for
    linear, nested disks for radial) clipped to the painted shape. Gradient fills
    and strokes are no longer reported as unsupported. (#27)
  • File drag-and-drop: drop files from the OS onto a window. New Event::DragEnter
    / DragMove / DragLeave / Drop events carry a DragData of file paths,
    and a drop target opts in by calling EventCtx::accept_drop() while handling
    DragEnter / DragMove. Works on macOS, Windows, X11, and Wayland. See the
    dnd example. (#23)
  • Dragging files out of a window (drag source), Wayland only:
    EventCtx::start_drag() begins an OS text/uri-list drag from a widget's
    press-and-drag gesture, with an icon that follows the cursor and shows a green
    checkmark over a target that accepts the drop or a red cross elsewhere. The
    winit backends (macOS, Windows, X11) expose no API to initiate a drag, so it
    is a no-op there. See the filer example. (#23)
  • Dropdown popups now scroll: a list longer than 12 rows caps the popup height
    and grows a vertical scrollbar — mouse wheel, draggable thumb, Page Up/Down,
    and scroll-the-selection-into-view all work — so a long list (e.g. the full
    set of keyboard layouts) stays usable instead of opening a popup taller than
    the screen. (#28)
  • ScrollBar::end_drag() to abandon an in-progress thumb drag, for hosts that
    can be torn down mid-drag (such as a dropdown popup that closes on focus
    loss). (#28)
  • ListItem::with_svg_icon: list rows can now show a compile-time-baked
    SvgImage (from include_svg!), drawn crisply at any DPI, alongside the
    existing raster ListIcon. (#32)
  • EventCtx::swallow_key_until_release(): a handler that fully acts on a key
    press can ask the runtime to discard the rest of it — the trailing Char,
    autorepeat, and the release. (#30)
  • Painter::light_button() (a lighter chrome frame: square outline, single
    top/left highlight, 2px bottom/right shadow) and Painter::fill_checker() (a
    two-tone DPI-aware checkerboard fill). (#29)

Changed

  • The folder / file / up-arrow icons in the file dialog and the filer example
    are now real SVG assets (assets/icons/*.svg) baked via include_svg! and
    shared between the two, instead of hand-coded pixel buffers. (#32)
  • ScrollBar chrome now matches Win 3.1 more closely: the arrow buttons and
    thumb use the lighter light_button frame (square outline, one highlight line
    instead of two), the track gains a thin black outline that collapses into the
    button/thumb frames where they meet, the arrow glyphs sit centered on the
    button face with the classic margin instead of filling it edge to edge, and
    the empty track shows the classic black-on-gray "newsprint"
    checkerboard instead of a flat gray fill. (#29)
  • Adjacent ScrollBar outlines no longer double up into a 2px band where they
    meet — each shared edge collapses to a single 1px line: a thumb slid flush
    against an arrow button shares that button's edge, and a scrollbar embedded in
    a List or TextEditor shares its outer edge with the field's border. (#29)