Skip to content

Commit

Permalink
Implement more standalone blueprints
Browse files Browse the repository at this point in the history
  • Loading branch information
gyscos committed Aug 5, 2024
1 parent f23444d commit d9a34e3
Show file tree
Hide file tree
Showing 16 changed files with 152 additions and 7 deletions.
41 changes: 41 additions & 0 deletions cursive-core/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ pub struct Context {
blueprints: Arc<Blueprints>,
}

impl std::fmt::Debug for Context {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let vars: Vec<_> = self.variables.keys().collect();
let blueprints: Vec<_> = self.blueprints.keys().collect();
let wrappers: Vec<_> = self.blueprints.wrapper_keys().collect();

write!(f, "Variables: {vars:?}, ")?;
write!(f, "Blueprints: {blueprints:?}, ")?;
write!(f, "Wrappers: {wrappers:?}")?;

Ok(())
}
}

struct Blueprints {
blueprints: HashMap<String, BoxedBuilder>,
wrappers: HashMap<String, BoxedWrapperBuilder>,
Expand Down Expand Up @@ -175,6 +189,24 @@ impl<T> ResolveOnce<T> {
}

impl Blueprints {
fn wrapper_keys(&self) -> impl Iterator<Item = &String> {
self.wrappers
.keys()
.chain(self.parent.iter().flat_map(|parent| {
let parent: Box<dyn Iterator<Item = &String>> = Box::new(parent.wrapper_keys());
parent
}))
}

fn keys(&self) -> impl Iterator<Item = &String> {
self.blueprints
.keys()
.chain(self.parent.iter().flat_map(|parent| {
let parent: Box<dyn Iterator<Item = &String>> = Box::new(parent.keys());
parent
}))
}

fn build(&self, name: &str, config: &Config, context: &Context) -> Result<BoxedView, Error> {
if let Some(blueprint) = self.blueprints.get(name) {
(blueprint)(config, context)
Expand Down Expand Up @@ -826,6 +858,15 @@ fn parse_var(value: &Config) -> Option<&str> {
}

impl Variables {
fn keys(&self) -> impl Iterator<Item = &String> {
self.variables
.keys()
.chain(self.parent.iter().flat_map(|parent| {
let parent: Box<dyn Iterator<Item = &String>> = Box::new(parent.keys());
parent
}))
}

/// Store a new variable for interpolation.
///
/// Can be a callback, a usize, ...
Expand Down
11 changes: 11 additions & 0 deletions cursive-core/src/builder/resolvable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,17 @@ impl Resolvable for crate::style::ColorStyle {
}
}

impl Resolvable for crate::view::ScrollStrategy {
fn from_config(config: &Config, context: &Context) -> Result<Self, Error>
where
Self: Sized,
{
resolve_from_str(config, context, |_| {
"Expected one of keep_row, stick_to_top, stick_to_bottom"
})
}
}

impl Resolvable for crate::view::Offset {
fn from_config(config: &Config, context: &Context) -> Result<Self, Error> {
if let Some("center" | "Center") = config.as_str() {
Expand Down
12 changes: 12 additions & 0 deletions cursive-core/src/view/scroll/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ impl Default for ScrollStrategy {
}
}

impl std::str::FromStr for ScrollStrategy {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"KeepRow" | "keep_row" => Self::KeepRow,
"StickToTop" | "stick_to_top" => Self::StickToTop,
"StickToBottom" | "stick_to_bottom" => Self::StickToBottom,
_ => return Err(()),
})
}
}

/// Performs `View::on_event` on a `scroll::Scroller`.
///
/// Example:
Expand Down
9 changes: 9 additions & 0 deletions cursive-core/src/views/focus_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ impl<T: View> ViewWrapper for FocusTracker<T> {
}
}

#[crate::blueprint(FocusTracker::new(view))]
struct Blueprint {
view: crate::views::BoxedView,

on_focus: Option<_>,

on_focus_lost: Option<_>,
}

crate::manual_blueprint!(with focus_tracker, |config, context| {
let on_focus = context.resolve(&config["on_focus"])?;
let on_focus_lost = context.resolve(&config["on_focus_lost"])?;
Expand Down
6 changes: 6 additions & 0 deletions cursive-core/src/views/gradient_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ where
}
}

#[crate::blueprint(GradientView::new(view, gradient))]
struct Blueprint {
view: crate::views::BoxedView,
gradient: crate::style::gradient::Dynterpolator,
}

crate::manual_blueprint!(with gradient, |config, context| {
let gradient: crate::style::gradient::Dynterpolator = context.resolve(config)?;
Ok(move |view| GradientView::new(view, gradient))
Expand Down
6 changes: 6 additions & 0 deletions cursive-core/src/views/hideable_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ impl<V: View> ViewWrapper for HideableView<V> {
}
}

#[crate::blueprint(HideableView::new(view))]
struct Blueprint {
view: crate::views::BoxedView,
visible: Option<bool>,
}

crate::manual_blueprint!(with hideable, |config, context| {
let visible: Option<bool> = context.resolve(&config["visible"])?;

Expand Down
5 changes: 5 additions & 0 deletions cursive-core/src/views/last_size_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ impl<T: View> ViewWrapper for LastSizeView<T> {
}
}

#[crate::blueprint(LastSizeView::new(view))]
struct Blueprint {
view: crate::views::BoxedView,
}

crate::manual_blueprint!(with last_size, |_, _| Ok(LastSizeView::new));
6 changes: 6 additions & 0 deletions cursive-core/src/views/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ impl<T: View> ViewWrapper for Layer<T> {
}
}

#[crate::blueprint(Layer::new(view))]
struct Blueprint {
view: crate::views::BoxedView,
color: Option<ColorStyle>,
}

crate::manual_blueprint!(with layer, |config, context| {
let color = match config {
crate::builder::Config::Null => None,
Expand Down
7 changes: 7 additions & 0 deletions cursive-core/src/views/on_layout_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ impl<V: View> ViewWrapper for OnLayoutView<V> {
}
}

#[crate::blueprint(OnLayoutView::wrap(view))]
struct Blueprint {
view: crate::views::BoxedView,

on_layout: Option<_>,
}

crate::manual_blueprint!(with on_layout, |config, context| {
let callback = context.resolve(config)?;
Ok(move |view| {
Expand Down
4 changes: 2 additions & 2 deletions cursive-core/src/views/padded_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ impl<V: View> ViewWrapper for PaddedView<V> {
}
}

#[crate::blueprint(PaddedView::new(margins, child))]
#[crate::blueprint(PaddedView::new(margins, view))]
struct Blueprint {
margins: Margins,
child: crate::views::BoxedView,
view: crate::views::BoxedView,
}

crate::manual_blueprint!(with padding, |config, context| {
Expand Down
4 changes: 2 additions & 2 deletions cursive-core/src/views/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ impl<V: View> ViewWrapper for Panel<V> {
}
}

#[crate::blueprint(Panel::new(child))]
#[crate::blueprint(Panel::new(view))]
struct Blueprint {
child: crate::views::BoxedView,
view: crate::views::BoxedView,

title: Option<StyledString>,
title_position: Option<HAlign>,
Expand Down
7 changes: 7 additions & 0 deletions cursive-core/src/views/resized_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,13 @@ mod tests {
}
}

#[crate::blueprint(ResizedView::new(SizeConstraint::Free, SizeConstraint::Free, view))]
struct Blueprint {
view: crate::views::BoxedView,
width: Option<SizeConstraint>,
height: Option<SizeConstraint>,
}

crate::manual_blueprint!(with full_screen, |_config, _context| {
Ok(crate::views::ResizedView::with_full_screen)
});
Expand Down
25 changes: 22 additions & 3 deletions cursive-core/src/views/scroll_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ impl<V> ScrollView<V> {
on_scroll: Arc::new(|_, _| EventResult::Ignored),
}
}

}
impl<V: 'static> ScrollView<V> {
/// Returns the viewport in the inner content.
pub fn content_viewport(&self) -> Rect {
self.core.content_viewport()
Expand Down Expand Up @@ -221,6 +222,7 @@ impl<V> ScrollView<V> {
///
/// If you just need to run a callback on `&mut Cursive`, consider
/// `set_on_scroll`.
#[crate::callback_helpers]
pub fn set_on_scroll_inner<F>(&mut self, on_scroll: F)
where
F: FnMut(&mut Self, Rect) -> EventResult + 'static + Send + Sync,
Expand All @@ -229,6 +231,7 @@ impl<V> ScrollView<V> {
}

/// Sets a callback to be run whenever scrolling happens.
#[crate::callback_helpers]
pub fn set_on_scroll<F>(&mut self, on_scroll: F)
where
F: FnMut(&mut Cursive, Rect) + 'static + Send + Sync,
Expand Down Expand Up @@ -264,19 +267,19 @@ impl<V> ScrollView<V> {
}

/// Sets a callback to be run whenever the scroll offset changes.
#[crate::callback_helpers]
pub fn set_on_scroll_change_inner<F>(&mut self, on_scroll: F)
where
F: FnMut(&mut Self, Rect) -> EventResult + 'static + Send + Sync,
V: 'static,
{
self.set_on_scroll_inner(Self::skip_unchanged(on_scroll, || EventResult::Ignored));
}

/// Sets a callback to be run whenever the scroll offset changes.
#[crate::callback_helpers]
pub fn set_on_scroll_change<F>(&mut self, on_scroll: F)
where
F: FnMut(&mut Cursive, Rect) + 'static + Send + Sync,
V: 'static,
{
self.set_on_scroll(Self::skip_unchanged(on_scroll, || ()));
}
Expand Down Expand Up @@ -422,6 +425,22 @@ where
}
}

#[crate::blueprint(ScrollView::new(view))]
struct Blueprint {
view: crate::views::BoxedView,

scroll_x: Option<bool>,
scroll_y: Option<bool>,
scroll_strategy: Option<ScrollStrategy>,
show_scrollbars: Option<bool>,

on_scroll: Option<_>,
on_scroll_inner: Option<_>,

on_scroll_change: Option<_>,
on_scroll_change_inner: Option<_>,
}

// ```yaml
// - TextView
// content: $content
Expand Down
5 changes: 5 additions & 0 deletions cursive-core/src/views/shadow_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,9 @@ impl<T: View> ViewWrapper for ShadowView<T> {
}
}

#[crate::blueprint(ShadowView::new(view))]
struct Blueprint {
view: crate::views::BoxedView,
}

crate::manual_blueprint!(with shadow, |_, _| Ok(ShadowView::new));
6 changes: 6 additions & 0 deletions cursive-core/src/views/themed_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ impl<T: View> ViewWrapper for ThemedView<T> {
}
}

#[crate::blueprint(ThemedView::new(theme, view))]
struct Blueprint {
view: crate::views::BoxedView,
theme: crate::theme::Theme,
}

crate::manual_blueprint!(with theme, |config, context| {
let theme = context.resolve(config)?;
Ok(move |view| ThemedView::new(theme, view))
Expand Down
5 changes: 5 additions & 0 deletions cursive-core/src/views/tracked_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ impl<T: View> ViewWrapper for TrackedView<T> {
}
}

#[crate::blueprint(TrackedView::new(view))]
struct Blueprint {
view: crate::views::BoxedView,
}

crate::manual_blueprint!(with tracked, |_, _| Ok(TrackedView::new));

0 comments on commit d9a34e3

Please sign in to comment.