snora_widgets/direction.rs
1//! Direction-aware layout helpers.
2//!
3//! These helpers let widget authors write layouts in terms of **logical
4//! start / end** rather than physical left / right. Pass the application's
5//! [`LayoutDirection`] and the helper resolves the order for you.
6//!
7//! # Why these exist
8//!
9//! Without helpers, a widget that wants to be ABDD-compliant has to write
10//! a match on [`LayoutDirection`] every time it builds a `row!`. That
11//! pattern quickly becomes noisy and error-prone — it is easy to forget
12//! one occurrence and ship an RTL bug. These helpers centralise the
13//! decision.
14
15use iced::{
16 Element,
17 widget::{Row, row},
18};
19
20use snora_core::LayoutDirection;
21
22/// A two-slot horizontal row in logical order.
23///
24/// Under [`LayoutDirection::Ltr`], `start` is placed first (left) and
25/// `end` last (right). Under [`LayoutDirection::Rtl`] the order is
26/// reversed. The returned [`Row`] can be customised further with standard
27/// iced builder methods.
28pub fn row_dir<'a, Message>(
29 direction: LayoutDirection,
30 start: impl Into<Element<'a, Message>>,
31 end: impl Into<Element<'a, Message>>,
32) -> Row<'a, Message>
33where
34 Message: 'a,
35{
36 match direction {
37 LayoutDirection::Ltr => row![start.into(), end.into()],
38 LayoutDirection::Rtl => row![end.into(), start.into()],
39 }
40}
41
42/// A three-slot horizontal row in logical order: `start`, `center`, `end`.
43///
44/// `center` is position-stable — it does not flip with direction. Only
45/// `start` and `end` swap. This matches how a typical app header is
46/// organised (title at start, status in the middle, controls at end).
47pub fn row_dir_three<'a, Message>(
48 direction: LayoutDirection,
49 start: impl Into<Element<'a, Message>>,
50 center: impl Into<Element<'a, Message>>,
51 end: impl Into<Element<'a, Message>>,
52) -> Row<'a, Message>
53where
54 Message: 'a,
55{
56 match direction {
57 LayoutDirection::Ltr => row![start.into(), center.into(), end.into()],
58 LayoutDirection::Rtl => row![end.into(), center.into(), start.into()],
59 }
60}