Krypton Ribbon right-to-left layout
Overview
Issue #2382 adds Office-style logical RTL packing to Krypton.Ribbon. KryptonRibbon inherits VisualSimple (not VisualSimpleBase), so it exposes its own bool RightToLeftLayout matching WinForms Form / VisualSimpleBase. That value is copied from the parent KryptonForm. VisualPopup has the same flag so docker-based overflow, app-menu, and minimized-group popups pack correctly. Do not confuse the property with the Toolkit RightToLeftLayout enum (LeftToRight / RightToLeft) used by toast data.
Logical RTL means sequential chrome packs from the reading-order start edge. Glyphs and Arabic/Hebrew text stay readable. Do not use Graphics.ScaleTransform or WS_EX_LAYOUTRTL for the ribbon body.
Consumer API
RightToLeft = RightToLeft.Yes;
RightToLeftLayout = true; // on the KryptonForm; the ribbon syncs
Both flags are required for packing. Setting only RightToLeft changes text direction (AccurateText / content rendering), not item order.
Do not reverse public RibbonTabs, Groups, or QATButtons collections. Collection order stays LTR in the object model; the first item is drawn on the start edge (right when RTL).
Architecture
KryptonForm RightToLeft + RightToLeftLayout
→ KryptonRibbon.SyncRightToLeftLayoutFromParent
→ ViewLayoutDocker.CalculateDock (Left ↔ Right)
→ sequential Layout methods via RibbonRtlLayout
→ draw / hit-test the laid-out rectangles
Gate every packing decision on ViewLayoutContext.IsRightToLeftLayout or CommonHelper.IsRightToLeftLayout (both flags). RibbonRtlLayout wraps start-X, item rect, remainder, Left/Right key remap, and popup ApplyTo.
WinForms does not inherit RightToLeftLayout. Without the form sync, caption chrome can flip while the ribbon body stays LTR.
Layout layers
- Plumbing —
KryptonRibboncopiesRightToLeftLayoutfrom the parentKryptonForm, hooksRightToLeftChanged/RightToLeftLayoutChanged, andPerformNeedPaint(true). An explicit ribbonRightToLeftLayoutremains valid when the parent is not aKryptonForm. - Docker chrome — Tabs area (Office 2007 orb / File tab docked Left), QAT mini overflow (Right), group dialog launcher (Right), and caption injection pick up RTL from
ViewLayoutDocker.CalculateDock. The orb’s window-edge gap usesStartBorderWidth. Caption QAT minibar overlap extends toward the orb on the start edge (ViewDrawRibbonQATBorder). Context-title icon filler uses an RTL remainder so the form icon stays on the start edge.ViewLayoutRibbonScrollPorttreats near as start and far as end. - Sequential packing — Tabs, groups, QAT contents, group content/cluster/lines/triple, gallery items, and row-center start at
ClientRectangle.Rightand subtract width when RTL. - Popups — App menu, QAT overflow, minimized groups, and
KryptonGallerycallRibbonRtlLayout.ApplyTo. - Keyboard — Controllers remap Left/Right through
RibbonRtlLayout.HorizontalKeyso existing switch arms follow visual start/end.GetViewForFirstRibbonTabstays collection-order (first = visual start). Do not also remap inProcessDialogKey(double-flip).
Drawing
Prefer Near / Far alignment. RenderStandardContent / AccurateText already honor RightToLeft. Do not globally mirror bitmaps. Adjust tab chrome paths only if a selected-tab overlap looks wrong after reverse packing.
Hosted editors inherit RightToLeft from the ribbon; their Bounds come from the RTL layout rectangles.
Out of scope
- Do not add
KryptonUseRTLLayout(dialog dual-form switch). - Do not reverse public collections.
- Design-time selection flaps may stay physical-left (not user-facing).