Repository navigation
craft-ui: extend direction with body/window/popup/dialog helpers, sizing-pass LTR, direction-aware grids, geometry and paint submodules - #507
Draft
ahmedhosnypro wants to merge 1 commit into
Conversation
Promote the app-proven, app-agnostic helpers from PhotoCraft's i18n/rtl-layout direction.rs into crates/ui/src/direction, keeping craft-ui's Context-temp HasDirection model as the single source of truth (signatures take &impl HasDirection instead of the app's thread-local): - body/window/popup/dialog scopes: body_layout, trailing_min, popup_body, dialog_row, dialog_content, window_body, sizing_pass_ltr - direction-blind forms and grids: settings_row, settings_grid, form_grid, two_col_grid, ltr_grid, scroll_grid, grid_cells, row_width, hscroll_row, ltr/ltr_vertical, body_label - window helpers: clamp_window_min_size, float_window_x, horizontal_nav_keys (thin tuple over Step for raw-key machines) - hand-painted geometry family in direction/geometry.rs (start_x_w, after_x, start_rect, start_cell, advance, start_span, name_span, start_edge, row_end_edge, end_span, split_end, start_align2, end_align2, start_side, glyph_x, text anchors, end_corner_anchor); start_x/end_x gain a width parameter (0.0 = bare edge) - painters in direction/paint.rs: elided_galley, paint_label_span, paint_elided, popup_area_near, popup_anchor_reading_end, text_direction() - direction_scope: per-Context/thread force guard alongside apply (precedence FORCED > env > context), since apply cannot force one frame - mirror-exactly-once rule documented: flag + body_layout + explicit row/trailing pin each flip a row once; two on one row double-flip Regression twins ported into direction/tests.rs; existing 10 tests kept. crates.io-egui no-op SetRightToLeft fallback in apply preserved. Also: - font-manager: adapt the two start_x/end_x call sites to the new width parameter - docking/render/preview.rs: simplify a boolean expression flagged by clippy 1.95 nonminimal_bool at the base commit (De Morgan-identical) Gate (rust 1.95.0): cargo check --workspace, clippy -p craft-ui -p craft-font-manager --all-targets -- -D warnings, cargo test -p craft-ui / -p craft-font-manager, cargo fmt --check, and wasm32 check of craft-ui all green. Source: plan/rtl/01-direction-core-spec.md (branch plan/rtl-core, 0149e7e); battle-tested reference photocraft i18n/rtl-layout 9a446cfea. Refs: craft-libs#198, emilk/egui#8577, #8698.
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
This was referenced Nov 2, 2026
Draft
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.
Summary
Adds a large set of RTL direction helpers to
craft-ui'scrates/ui/src/directionmodule and splits the hand-painted part of it into two new submodules,geometry.rsandpaint.rs. Apps built on craft-ui can mirror their whole chrome for right-to-left languages (Arabic, Hebrew, Persian, Urdu): dialog, window, popup and settings bodies lay out in reading order, resizable windows measure a direction-independent minimum size, forms and grids emit label/editor pairs in reading order, and hand-painted rows, labels and popups place themselves from reading edges instead of left/right. Existing LTR layouts are byte-identical.Motivation
egui has no whole-context interface direction: panels, popups, grids and hand-painted positions all name left and right explicitly, and the
right_to_leftstyle flag alone does not mirror nested rows of a plaintop_down(Align::Min)body,egui::Gridcell order, or painted shapes. Every app would otherwise re-derive the same mirroring rules; this lands them once in the shared library. Refs #198 (language support across the craft apps, track 6 "RTL interface", item D1: row and trailing layouts, popup alignment, direction-aware arrow keys in craft-uidirection).Changes
crates/ui/src/direction/mod.rs(+421 lines):body_layout(vertical +Align::Maxin RTL, so nestedui.horizontalrows mirror; egui's default in LTR),trailing_min,dialog_row,dialog_content,window_body,popup_body, andsizing_pass_ltr— the sizing pass of a resizable host measures left-to-right (force guard + cleared flag +top_down(Align::Min)), so the enforced window minimum is direction-independent instead of ballooning to the offered width.settings_row,settings_grid,form_grid,two_col_grid(shared body),ltr,ltr_vertical,ltr_grid,scroll_grid,grid_cells,row_width,hscroll_row(mirrors a centred row's region about the scroll viewport so the reading-end is not cropped),full_row,full_trailing,trailing_row,body_label(pins paragraph base direction and aligns the galley to the reading-start edge so mixed Arabic/Latin lines keep their phrase order),text_direction.clamp_window_min_size(clamps a resizable window's rect to exactlyminwhile keeping the anchored edge fixed, so shrink drags are honoured),float_window_x(first-show x of a cascading panel from the canvas's reading-end edge),horizontal_nav_keys(thin tuple over the existingStepfor raw-key machines:(ArrowRight, ArrowLeft)LTR, swapped RTL).direction_scope: a#[must_use]per-thread force guard with correct nesting and!Sendby construction;Context::directionreads it first, then the stored context direction, so a single frame or widget can be forced even whereapplycannot.body_layoutand an explicitrow/trailingpin each flip a row once — never combine two on the same row.start_x/end_xgain a width/offset parameter (content offset from the edge);forwarddoc updated.crates/ui/src/direction/geometry.rs(new, 169 lines): hand-painted geometry from reading edges —start_x_w,after_x,start_rect,start_cell,advance,start_span,end_span,name_span,start_edge,row_end_edge,split_end,start_align2,end_align2,start_side,glyph_x,start_text_anchor,end_text_anchor,end_corner_anchor(screen-cornerAreaanchors),float_window_x,clamp_window_min_size.crates/ui/src/direction/paint.rs(new, 133 lines): direction-aware painting —elided_galley(binary search over whole-character cuts; an RTL string keeps its start and takes "…" at its logical end),PaintText,paint_label_span,paint_elided,popup_area_near(anAreahanging off an anchor's reading-end edge),popup_anchor_reading_end(aPopupAnchortranslated past the reading end).crates/ui/src/direction/tests.rs: updated for the widenedstart_x/end_xsignature and a newstyle_flaghelper (split fromstyle_rtlso the chrome-mirror test inspects a plainStyle); all 10 existing direction tests stay green.crates/font-manager/src/panel/browse.rs,crates/font-manager/src/panel/details.rs(start_x(ui, rect, 0.0));crates/ui/src/docking/render/preview.rsfolds a boolean guard into one!expression (no behaviour change).craft-i18n; no new dependencies; the no-opSetRightToLefttrait fallback for the crates.io egui build is preserved, so craft-ui still builds against stock egui.Testing
On rust 1.95 (the workspace
rust-version), all exit 0:cargo fmt --all -- --checkcargo check --workspacecargo clippy --workspace --all-targets -- -D warningscargo test -p craft-ui -p craft-font-manager— all passed (craft-ui 457 lib tests including the 10 direction tests, craft-font-manager suites, 7 doctests)cargo check -p craft-ui --target wasm32-unknown-unknownChanged tests:
positions_and_popups_mirrorcovers the newstart_x/end_xoffsets; thestyle_flag/style_rtlsplit lets the chrome test build against both the patched and the crates.io egui API surface.Checklist
cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warnings(nounwrap/expect/panic, nounsafe)cargo test -p craft-ui -p craft-font-managercargo check -p craft-ui --target wasm32-unknown-unknown