#[macro_export]
macro_rules! layout {
($title:expr, $subtitle:expr, $knob_size:expr, { $($body:tt)* }) => {{
let rows = $crate::__layout_rows!( [] $($body)* );
$crate::layout::PluginLayout::build(
$crate::layout::HeaderTitles::pair($title, $subtitle),
rows,
$knob_size,
)
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __layout_rows {
( [ $($rows:expr),* ] ) => {
vec![ $($rows),* ]
};
( [ $($rows:expr),* ] row { $($widgets:tt)* } $($rest:tt)* ) => {
$crate::__layout_rows!(
[ $($rows,)* $crate::layout::KnobRow {
label: None,
knobs: $crate::__layout_widgets!( [] $($widgets)* ),
} ]
$($rest)*
)
};
( [ $($rows:expr),* ] section($label:expr) { $($widgets:tt)* } $($rest:tt)* ) => {
$crate::__layout_rows!(
[ $($rows,)* $crate::layout::KnobRow {
label: Some($label),
knobs: $crate::__layout_widgets!( [] $($widgets)* ),
} ]
$($rest)*
)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __layout_widgets {
( [ $($w:expr),* ] ) => {
vec![ $($w),* ]
};
( [ $($w:expr),* ] knob($id:expr, $label:expr) .span($n:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::knob($id, $label).with_span($n) ] $($rest)* )
};
( [ $($w:expr),* ] slider($id:expr, $label:expr) .span($n:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::slider($id, $label).with_span($n) ] $($rest)* )
};
( [ $($w:expr),* ] toggle($id:expr, $label:expr) .span($n:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::toggle($id, $label).with_span($n) ] $($rest)* )
};
( [ $($w:expr),* ] selector($id:expr, $label:expr) .span($n:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::selector($id, $label).with_span($n) ] $($rest)* )
};
( [ $($w:expr),* ] meter($ids:expr, $label:expr) .span($n:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::meter($ids, $label).with_span($n) ] $($rest)* )
};
( [ $($w:expr),* ] xy_pad($x:expr, $y:expr, $label:expr) .span($n:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::xy_pad($x, $y, $label).with_span($n) ] $($rest)* )
};
( [ $($w:expr),* ] knob($id:expr, $label:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::knob($id, $label) ] $($rest)* )
};
( [ $($w:expr),* ] slider($id:expr, $label:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::slider($id, $label) ] $($rest)* )
};
( [ $($w:expr),* ] toggle($id:expr, $label:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::toggle($id, $label) ] $($rest)* )
};
( [ $($w:expr),* ] selector($id:expr, $label:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::selector($id, $label) ] $($rest)* )
};
( [ $($w:expr),* ] meter($ids:expr, $label:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::meter($ids, $label) ] $($rest)* )
};
( [ $($w:expr),* ] xy_pad($x:expr, $y:expr, $label:expr) $($rest:tt)* ) => {
$crate::__layout_widgets!( [ $($w,)* $crate::layout::KnobDef::xy_pad($x, $y, $label) ] $($rest)* )
};
}
#[macro_export]
macro_rules! grid {
({ $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
}};
(cols: $cols:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cols($cols)
}};
(cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cell_size($cell)
}};
(cols: $cols:expr, cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_grid($cols, $cell)
}};
(title: $title:expr, subtitle: $subtitle:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_titles($crate::layout::HeaderTitles::pair($title, $subtitle))
}};
(title: $title:expr, subtitle: $subtitle:expr, cols: $cols:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cols($cols)
.with_titles($crate::layout::HeaderTitles::pair($title, $subtitle))
}};
(title: $title:expr, subtitle: $subtitle:expr, cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cell_size($cell)
.with_titles($crate::layout::HeaderTitles::pair($title, $subtitle))
}};
(title: $title:expr, subtitle: $subtitle:expr, cols: $cols:expr, cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_grid($cols, $cell)
.with_titles($crate::layout::HeaderTitles::pair($title, $subtitle))
}};
(title: $title:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_title($title)
}};
(title: $title:expr, cols: $cols:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cols($cols)
.with_title($title)
}};
(title: $title:expr, cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cell_size($cell)
.with_title($title)
}};
(title: $title:expr, cols: $cols:expr, cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_grid($cols, $cell)
.with_title($title)
}};
(subtitle: $subtitle:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_subtitle($subtitle)
}};
(subtitle: $subtitle:expr, cols: $cols:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cols($cols)
.with_subtitle($subtitle)
}};
(subtitle: $subtitle:expr, cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_cell_size($cell)
.with_subtitle($subtitle)
}};
(subtitle: $subtitle:expr, cols: $cols:expr, cell: $cell:expr, { $($body:tt)* }) => {{
$crate::layout::GridLayout::build($crate::__grid_sections!($($body)*))
.with_grid($cols, $cell)
.with_subtitle($subtitle)
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __grid_sections {
($($body:tt)*) => {{
let mut _widgets: Vec<$crate::layout::GridWidget> = Vec::new();
let mut _breaks: Vec<(usize, &'static str)> = Vec::new();
$crate::__grid_items!(_widgets, _breaks, $($body)*);
let mut _sections: Vec<$crate::layout::Section> = Vec::new();
let mut _cur_widgets: Vec<$crate::layout::GridWidget> = Vec::new();
let mut _cur_label: Option<&'static str> = None;
for (i, w) in _widgets.into_iter().enumerate() {
if let Some(&(_, label)) = _breaks.iter().find(|(idx, _)| *idx == i) {
if !_cur_widgets.is_empty() || _cur_label.is_some() {
_sections.push($crate::layout::Section {
label: _cur_label,
widgets: std::mem::take(&mut _cur_widgets),
});
}
_cur_label = Some(label);
}
_cur_widgets.push(w);
}
if !_cur_widgets.is_empty() || _cur_label.is_some() {
_sections.push($crate::layout::Section {
label: _cur_label,
widgets: _cur_widgets,
});
}
_sections
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __grid_items {
($w:ident, $b:ident) => {};
($w:ident, $b:ident,) => {};
($w:ident, $b:ident, section($label:expr) $($rest:tt)*) => {
$b.push(($w.len(), $label));
$crate::__grid_items!($w, $b, $($rest)*);
};
($w:ident, $b:ident, knob($id:expr, $label:expr) $($rest:tt)*) => {
$crate::__grid_mods!($w, $b, $crate::layout::GridWidget::knob($id, $label), $($rest)*);
};
($w:ident, $b:ident, slider($id:expr, $label:expr) $($rest:tt)*) => {
$crate::__grid_mods!($w, $b, $crate::layout::GridWidget::slider($id, $label), $($rest)*);
};
($w:ident, $b:ident, toggle($id:expr, $label:expr) $($rest:tt)*) => {
$crate::__grid_mods!($w, $b, $crate::layout::GridWidget::toggle($id, $label), $($rest)*);
};
($w:ident, $b:ident, selector($id:expr, $label:expr) $($rest:tt)*) => {
$crate::__grid_mods!($w, $b, $crate::layout::GridWidget::selector($id, $label), $($rest)*);
};
($w:ident, $b:ident, meter($ids:expr, $label:expr) $($rest:tt)*) => {
$crate::__grid_mods!($w, $b, $crate::layout::GridWidget::meter($ids, $label), $($rest)*);
};
($w:ident, $b:ident, xy_pad($x:expr, $y:expr, $label:expr) $($rest:tt)*) => {
$crate::__grid_mods!($w, $b, $crate::layout::GridWidget::xy_pad($x, $y, $label), $($rest)*);
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __grid_mods {
($w:ident, $b:ident, $widget:expr, .cols($c:expr) .rows($r:expr) $($rest:tt)*) => {
$w.push($widget.cols($c).rows($r));
$crate::__grid_items!($w, $b, $($rest)*);
};
($w:ident, $b:ident, $widget:expr, .rows($r:expr) .cols($c:expr) $($rest:tt)*) => {
$w.push($widget.cols($c).rows($r));
$crate::__grid_items!($w, $b, $($rest)*);
};
($w:ident, $b:ident, $widget:expr, .cols($c:expr) $($rest:tt)*) => {
$w.push($widget.cols($c));
$crate::__grid_items!($w, $b, $($rest)*);
};
($w:ident, $b:ident, $widget:expr, .rows($r:expr) $($rest:tt)*) => {
$w.push($widget.rows($r));
$crate::__grid_items!($w, $b, $($rest)*);
};
($w:ident, $b:ident, $widget:expr, $($rest:tt)*) => {
$w.push($widget);
$crate::__grid_items!($w, $b, $($rest)*);
};
}