| 279 |
279 |
|
//! sit with whatever holds the regions, the same split [`Selector`] already made
|
| 280 |
280 |
|
//! against `Node::Select`.
|
| 281 |
281 |
|
//!
|
|
282 |
+ |
//! 0.27.0 adds [`Region::Group`], which closes a gap this crate had carried
|
|
283 |
+ |
//! since 0.2.0 without noticing: [`Heading::Section`] is documented as naming a
|
|
284 |
+ |
//! block within the screen, and there was no block. A section heading is a leaf
|
|
285 |
+ |
//! beside the things it names, so the description could say a section had
|
|
286 |
+ |
//! *started* and never that one had ended.
|
|
287 |
+ |
//!
|
|
288 |
+ |
//! Found by asking how a screen distinguishes groups of settings by colour, and
|
|
289 |
+ |
//! the answer turned out to be two findings rather than one. This is the first
|
|
290 |
+ |
//! and it is the precondition: there is nothing to tint until there is a
|
|
291 |
+ |
//! container. The second — every renderer already resolves `category.one`
|
|
292 |
+ |
//! through `category.six` and no description can reach any of them — is filed
|
|
293 |
+ |
//! and not shipped here.
|
|
294 |
+ |
//!
|
|
295 |
+ |
//! What the colour question settled anyway, because it shapes this member: the
|
|
296 |
+ |
//! group carries no colour and no ordinal. A renderer distinguishing sibling
|
|
297 |
+ |
//! groups derives the assignment from their order, which is
|
|
298 |
+ |
//! [`Region::Columns`]' reasoning about counts applied to colour — the children
|
|
299 |
+ |
//! say, and a value here would be a second source for something the description
|
|
300 |
+ |
//! already states by containing them.
|
|
301 |
+ |
//!
|
| 282 |
302 |
|
//! # Reach, focus and the focus ring
|
| 283 |
303 |
|
//!
|
| 284 |
304 |
|
//! Three terms, and no others, for what 0.19.0 moved out of the description.
|
| 1933 |
1953 |
|
Sidebar,
|
| 1934 |
1954 |
|
/// A region of content with its own scroll.
|
| 1935 |
1955 |
|
Pane,
|
|
1956 |
+ |
/// Things that belong together, and nothing else.
|
|
1957 |
+ |
///
|
|
1958 |
+ |
/// The block [`Heading::Section`] has been naming since 0.2.0 without the
|
|
1959 |
+ |
/// vocabulary being able to contain it. A section heading is a leaf sitting
|
|
1960 |
+ |
/// *beside* the things it names, so nothing said where a section started or
|
|
1961 |
+ |
/// ended and a renderer learned one had ended only because the next heading
|
|
1962 |
+ |
/// arrived.
|
|
1963 |
+ |
///
|
|
1964 |
+ |
/// # The measurement
|
|
1965 |
+ |
///
|
|
1966 |
+ |
/// 41 [`Heading::Section`] sites across the ten screens described through
|
|
1967 |
+ |
/// the router, not one of them contained. audiofiles' settings screen is the
|
|
1968 |
+ |
/// clearest: one pane holding a heading, a field, a heading, two toggles, a
|
|
1969 |
+ |
/// heading, a toggle and a heading, which is four sections and no
|
|
1970 |
+ |
/// containers. Under the hand-written CSS the ports are replacing the same
|
|
1971 |
+ |
/// block is spelled `.settings-section` in goingson, `.form-section` and
|
|
1972 |
+ |
/// `.content-section` in the MNW server, `.help-section` in Balanced
|
|
1973 |
+ |
/// Breakfast: three apps, four names, one shape.
|
|
1974 |
+ |
///
|
|
1975 |
+ |
/// # Why the existing members were the wrong answer
|
|
1976 |
+ |
///
|
|
1977 |
+ |
/// [`Pane`](Self::Pane) is what apps reached for, and it is 28 of the 45
|
|
1978 |
+ |
/// regions in the described screens. It claims a scroll of its own and
|
|
1979 |
+ |
/// [`Depth::Well`], so four settings groups inside a pane are four wells
|
|
1980 |
+ |
/// inside a well and four scroll contexts. Neither claim is true of a group.
|
|
1981 |
+ |
///
|
|
1982 |
+ |
/// [`Widget`](Self::Widget) is wrong from the other side. Its own docs say a
|
|
1983 |
+ |
/// widget is never how a primitive gets added by the back door, and a run of
|
|
1984 |
+ |
/// related controls under a heading is furniture any app would have, which
|
|
1985 |
+ |
/// is the generic-against-bespoke bar a primitive has to clear.
|
|
1986 |
+ |
///
|
|
1987 |
+ |
/// # What it does not carry
|
|
1988 |
+ |
///
|
|
1989 |
+ |
/// **A heading.** A group usually has one and it is an ordinary node in the
|
|
1990 |
+ |
/// body, the way it already was. A group of related toggles with no heading
|
|
1991 |
+ |
/// is a real thing and a mandatory slot would forbid it.
|
|
1992 |
+ |
///
|
|
1993 |
+ |
/// **A depth.** [`Depth::Flat`], on [`Bespoke`](Self::Bespoke)'s reasoning:
|
|
1994 |
+ |
/// it inherits, and an app that wants its group in a well puts it in a
|
|
1995 |
+ |
/// [`Pane`](Self::Pane), which composes rather than adding a knob here.
|
|
1996 |
+ |
///
|
|
1997 |
+ |
/// **A colour.** Distinguishing sibling groups by colour is the thing this
|
|
1998 |
+ |
/// member was asked for and it is deliberately not stated here. The
|
|
1999 |
+ |
/// description says these things belong together; which of the theme's
|
|
2000 |
+ |
/// categorical colours a renderer reaches for, and whether it reaches for
|
|
2001 |
+ |
/// one at all, is derived from sibling order at the renderer. A terminal
|
|
2002 |
+ |
/// that tints nothing and separates with a rule is honouring this.
|
|
2003 |
+ |
Group,
|
| 1936 |
2004 |
|
/// Two panes side by side, where the left chooses what the right shows.
|
| 1937 |
2005 |
|
Split,
|
| 1938 |
2006 |
|
/// Peer regions across, all of them equals.
|
| 2056 |
2124 |
|
pub const fn depth(self) -> Depth {
|
| 2057 |
2125 |
|
match self {
|
| 2058 |
2126 |
|
Self::Band | Self::Sidebar | Self::Split | Self::TabGroup => Depth::Flat,
|
|
2127 |
+ |
// Flat, and it inherits. A group says its contents belong together
|
|
2128 |
+ |
// and says nothing about the surface they sit on, so a group in a
|
|
2129 |
+ |
// pane is in a well and a group on the page is on the page. An app
|
|
2130 |
+ |
// wanting one lifted puts it in a `Pane`.
|
|
2131 |
+ |
Self::Group => Depth::Flat,
|
| 2059 |
2132 |
|
// Flat, and it is the container rather than the columns. Each
|
| 2060 |
2133 |
|
// column is its own region and brings its own depth; a well here
|
| 2061 |
2134 |
|
// would put a second edge around a row of wells.
|
| 2111 |
2184 |
|
Self::Band
|
| 2112 |
2185 |
|
| Self::Sidebar
|
| 2113 |
2186 |
|
| Self::Pane
|
|
2187 |
+ |
| Self::Group
|
| 2114 |
2188 |
|
| Self::Split
|
| 2115 |
2189 |
|
| Self::Columns
|
| 2116 |
2190 |
|
| Self::TabGroup
|
| 3707 |
3781 |
|
for r in [
|
| 3708 |
3782 |
|
Region::Band,
|
| 3709 |
3783 |
|
Region::Sidebar,
|
|
3784 |
+ |
Region::Group,
|
| 3710 |
3785 |
|
Region::Split,
|
| 3711 |
3786 |
|
Region::TabGroup,
|
| 3712 |
3787 |
|
] {
|
| 3723 |
3798 |
|
Region::Band,
|
| 3724 |
3799 |
|
Region::Sidebar,
|
| 3725 |
3800 |
|
Region::Pane,
|
|
3801 |
+ |
Region::Group,
|
| 3726 |
3802 |
|
Region::Split,
|
| 3727 |
3803 |
|
Region::TabGroup,
|
| 3728 |
3804 |
|
Region::Modal,
|
| 3795 |
3871 |
|
assert_eq!(Image::new("a").fit(Fit::Cover).fit, Fit::Cover);
|
| 3796 |
3872 |
|
}
|
| 3797 |
3873 |
|
|
|
3874 |
+ |
#[test]
|
|
3875 |
+ |
fn a_group_contains_a_section_without_claiming_to_be_a_pane() {
|
|
3876 |
+ |
// The whole of why this is a member rather than a `Pane`. A pane is
|
|
3877 |
+ |
// looked into and scrolls; a group is neither, and four groups inside a
|
|
3878 |
+ |
// settings pane described as panes are four wells inside a well.
|
|
3879 |
+ |
assert_eq!(Region::Pane.depth(), Depth::Well);
|
|
3880 |
+ |
assert_eq!(Region::Group.depth(), Depth::Flat);
|
|
3881 |
+ |
assert_ne!(Region::Group, Region::Pane);
|
|
3882 |
+ |
|
|
3883 |
+ |
// Described, and it carries no name: a group is a primitive every
|
|
3884 |
+ |
// renderer draws from scratch, which is what separates it from the two
|
|
3885 |
+ |
// members that do carry one.
|
|
3886 |
+ |
assert!(Region::Group.described());
|
|
3887 |
+ |
assert_eq!(Region::Group.name(), None);
|
|
3888 |
+ |
}
|
|
3889 |
+ |
|
|
3890 |
+ |
#[test]
|
|
3891 |
+ |
fn a_section_heading_names_a_block_that_now_exists() {
|
|
3892 |
+ |
// `Heading::Section` has said "names a block within the screen" since
|
|
3893 |
+ |
// 0.2.0 and there was no block. The pairing is the point, and it is the
|
|
3894 |
+ |
// reason a group carries no heading of its own: the heading is an
|
|
3895 |
+ |
// ordinary node in the body, and a group without one is legal.
|
|
3896 |
+ |
assert!(Heading::Section.separated());
|
|
3897 |
+ |
assert_eq!(Region::Group.depth(), Depth::Flat);
|
|
3898 |
+ |
}
|
|
3899 |
+ |
|
| 3798 |
3900 |
|
#[test]
|
| 3799 |
3901 |
|
fn a_widget_inherits_its_depth_the_way_a_bespoke_does() {
|
| 3800 |
3902 |
|
// Stronger than the bespoke case: a widget is drawn by whichever
|
| 3818 |
3920 |
|
Region::Band,
|
| 3819 |
3921 |
|
Region::Sidebar,
|
| 3820 |
3922 |
|
Region::Pane,
|
|
3923 |
+ |
Region::Group,
|
| 3821 |
3924 |
|
Region::Split,
|
| 3822 |
3925 |
|
Region::TabGroup,
|
| 3823 |
3926 |
|
Region::Modal,
|