morph
0.1.0
Asynchronous bridge between GUI thread and business models
Toggle main menu visibility
Loading...
Searching...
No Matches
layout.hpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: Apache-2.0
2
3
#pragma once
4
5
/// @file forms/layout.hpp
6
/// @brief Visual structure (sections, tabs, accordions, column spans) layered
7
/// over an action's flat field list.
8
///
9
/// `morph::forms::schemaJson<A>()` (`forms.hpp`) already lays every field out
10
/// in a single flat list, ordered by `x-order`. This header adds two
11
/// **optional** compile-time declarations an action may expose: `formLayout`,
12
/// a list of `FieldGroup`s that bucket fields into titled sections, tabs, or
13
/// an accordion panel; and `fieldSpans`, a list of `FieldSpan`s that widen
14
/// individual fields in a grid renderer. Both mirror the existing
15
/// `optionalFields` convention (`forms.hpp`) — a `static constexpr` list
16
/// `mergeSchemaExtras` looks for by name, present only when an action opts
17
/// in.
18
///
19
/// Absent either declaration, `schemaJson<A>()`'s output is unchanged: no
20
/// `x-layout`, `x-group`, `x-section`, or `x-colspan` key is emitted, and a
21
/// renderer lays every field out exactly as it does today (flat, `x-order`
22
/// order). See docs/spec/forms/forms.md, "Layout & grouping".
23
24
#include <cstdint>
25
#include <iterator>
26
#include <span>
27
#include <string_view>
28
29
namespace
morph::forms {
30
31
/// @brief The container kind a `FieldGroup` renders as.
32
enum class
GroupKind
: std::uint8_t {
33
Section
,
///< A titled fieldset, stacked vertically (the default).
34
Tab
,
///< A pane of a shared tab bar; consecutive `Tab` groups share one bar.
35
Accordion
///< A collapsible panel.
36
};
37
38
/// @brief Maps a `GroupKind` to the string `mergeSchemaExtras` emits for it
39
/// in `x-layout.groups[].kind`.
40
/// @param kind Group kind to name.
41
/// @return `"section"`, `"tab"`, or `"accordion"`. The `default` branch (all
42
/// three enumerators are already listed explicitly) is an
43
/// out-of-range-value fallback to `"section"`, the renderer's
44
/// documented downgrade for an unsupported kind.
45
[[nodiscard]]
constexpr
std::string_view
groupKindName
(
GroupKind
kind)
noexcept
{
46
switch
(kind) {
47
case
GroupKind::Section
:
48
return
"section"
;
49
case
GroupKind::Tab
:
50
return
"tab"
;
51
case
GroupKind::Accordion
:
52
return
"accordion"
;
53
default
:
54
// Unreachable through any real code path: GroupKind is a closed
55
// enum and every enumerator is already handled explicitly above.
56
// This arm only exists to satisfy the compiler that the function
57
// returns on every enum value, including one manufactured by an
58
// out-of-range `static_cast` -- mirrors ruleKindName's identical
59
// default: arm in forms.hpp.
60
return
"section"
;
61
}
62
}
63
64
/// @brief One named group of fields in an action's `formLayout`.
65
///
66
/// `fields` gives **membership only** — which wire keys belong to this
67
/// group — not intra-group order: the renderer still lays fields out by
68
/// ascending `x-order` within the group. The array position of a `FieldGroup`
69
/// inside `A::formLayout` gives the cross-group order.
70
struct
FieldGroup
{
71
/// @brief Section / tab / panel heading shown to the user.
72
std::string_view
title
;
73
74
/// @brief Container this group renders as. Defaults to `Section`.
75
GroupKind
kind
{
GroupKind::Section
};
76
77
/// @brief Member wire keys belonging to this group (membership only; see
78
/// the struct documentation for intra-group order).
79
std::span<const std::string_view>
fields
;
80
};
81
82
/// @brief A field's declared column span in a grid renderer.
83
struct
FieldSpan
{
84
/// @brief Wire key of the field this span applies to.
85
std::string_view
field
;
86
87
/// @brief Number of grid columns the field should span. `1` (the
88
/// default) is the ordinary single-column width and is never
89
/// emitted as `x-colspan` — only values greater than `1` are.
90
int
colspan
{1};
91
};
92
93
namespace
detail {
94
95
/// @brief Concept: action declares a `static constexpr` iterable
96
/// `formLayout` list of `FieldGroup`.
97
template
<
typename
A>
98
concept
HasFormLayout =
requires
{
99
std::begin(A::formLayout);
100
std::end(A::formLayout);
101
};
102
103
/// @brief Concept: action declares a `static constexpr` iterable
104
/// `fieldSpans` list of `FieldSpan`.
105
template
<
typename
A>
106
concept
HasFieldSpans =
requires
{
107
std::begin(A::fieldSpans);
108
std::end(A::fieldSpans);
109
};
110
111
}
// namespace detail
112
113
}
// namespace morph::forms
morph::forms::GroupKind
GroupKind
The container kind a FieldGroup renders as.
Definition
layout.hpp:32
morph::forms::GroupKind::Accordion
@ Accordion
A collapsible panel.
Definition
layout.hpp:35
morph::forms::GroupKind::Tab
@ Tab
A pane of a shared tab bar; consecutive Tab groups share one bar.
Definition
layout.hpp:34
morph::forms::GroupKind::Section
@ Section
A titled fieldset, stacked vertically (the default).
Definition
layout.hpp:33
morph::forms::groupKindName
constexpr std::string_view groupKindName(GroupKind kind) noexcept
Maps a GroupKind to the string mergeSchemaExtras emits for it in x-layout.groups[]....
Definition
layout.hpp:45
morph::forms::FieldGroup
One named group of fields in an action's formLayout.
Definition
layout.hpp:70
morph::forms::FieldGroup::fields
std::span< const std::string_view > fields
Member wire keys belonging to this group (membership only; see the struct documentation for intra-gro...
Definition
layout.hpp:79
morph::forms::FieldGroup::kind
GroupKind kind
Container this group renders as. Defaults to Section.
Definition
layout.hpp:75
morph::forms::FieldGroup::title
std::string_view title
Section / tab / panel heading shown to the user.
Definition
layout.hpp:72
morph::forms::FieldSpan
A field's declared column span in a grid renderer.
Definition
layout.hpp:83
morph::forms::FieldSpan::colspan
int colspan
Number of grid columns the field should span. 1 (the default) is the ordinary single-column width and...
Definition
layout.hpp:90
morph::forms::FieldSpan::field
std::string_view field
Wire key of the field this span applies to.
Definition
layout.hpp:85
morph::forms::Section
One section of a SectionGroup: a registered action, a display title, and zero or more Bind prefill de...
Definition
sections.hpp:46
morph
forms
layout.hpp
Generated by
1.17.0