Make recorder widget generic over Theme
This commit is contained in:
parent
87ac14ec48
commit
62795909d8
2 changed files with 49 additions and 57 deletions
|
|
@ -602,45 +602,31 @@ impl<P: Program + 'static> Tester<P> {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let view = match &self.state {
|
||||||
|
State::Empty => Element::from(space()),
|
||||||
|
State::Idle { state } => {
|
||||||
|
program.view(state, window).map(Tick::Program)
|
||||||
|
}
|
||||||
|
State::Recording { emulator } => {
|
||||||
|
recorder(emulator.view(program).map(Tick::Program))
|
||||||
|
.on_record(Tick::Record)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
State::Asserting { state, window, .. } => {
|
||||||
|
recorder(program.view(state, *window).map(Tick::Program))
|
||||||
|
.on_record(Tick::Assert)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
State::Playing { emulator, .. } => {
|
||||||
|
emulator.view(program).map(Tick::Program)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let viewport = container(
|
let viewport = container(
|
||||||
scrollable(
|
scrollable(
|
||||||
container(match &self.state {
|
container(themer(self.theme(program, window), view))
|
||||||
State::Empty => Element::from(space()),
|
.width(self.viewport.width)
|
||||||
State::Idle { state } => {
|
.height(self.viewport.height),
|
||||||
let theme = program.theme(state, window);
|
|
||||||
|
|
||||||
themer(
|
|
||||||
theme,
|
|
||||||
program.view(state, window).map(Tick::Program),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
State::Recording { emulator } => {
|
|
||||||
let theme = emulator.theme(program);
|
|
||||||
let view = emulator.view(program).map(Tick::Program);
|
|
||||||
|
|
||||||
recorder(themer(theme, view))
|
|
||||||
.on_record(Tick::Record)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
State::Asserting { state, window, .. } => {
|
|
||||||
let theme = program.theme(state, *window);
|
|
||||||
let view =
|
|
||||||
program.view(state, *window).map(Tick::Program);
|
|
||||||
|
|
||||||
recorder(themer(theme, view))
|
|
||||||
.on_record(Tick::Assert)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
State::Playing { emulator, .. } => {
|
|
||||||
let theme = emulator.theme(program);
|
|
||||||
let view = emulator.view(program).map(Tick::Program);
|
|
||||||
|
|
||||||
themer(theme, view).into()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.width(self.viewport.width)
|
|
||||||
.height(self.viewport.height),
|
|
||||||
)
|
)
|
||||||
.direction(scrollable::Direction::Both {
|
.direction(scrollable::Direction::Both {
|
||||||
vertical: scrollable::Scrollbar::default(),
|
vertical: scrollable::Scrollbar::default(),
|
||||||
|
|
|
||||||
|
|
@ -2,30 +2,31 @@ use crate::core::layout;
|
||||||
use crate::core::mouse;
|
use crate::core::mouse;
|
||||||
use crate::core::overlay;
|
use crate::core::overlay;
|
||||||
use crate::core::renderer;
|
use crate::core::renderer;
|
||||||
|
use crate::core::theme;
|
||||||
use crate::core::widget;
|
use crate::core::widget;
|
||||||
use crate::core::widget::operation;
|
use crate::core::widget::operation;
|
||||||
use crate::core::widget::tree;
|
use crate::core::widget::tree;
|
||||||
use crate::core::{
|
use crate::core::{
|
||||||
self, Clipboard, Element, Event, Layout, Length, Point, Rectangle, Shell,
|
self, Clipboard, Color, Element, Event, Layout, Length, Point, Rectangle,
|
||||||
Size, Theme, Vector, Widget,
|
Shell, Size, Vector, Widget,
|
||||||
};
|
};
|
||||||
use crate::test::Selector;
|
use crate::test::Selector;
|
||||||
use crate::test::instruction::{Interaction, Mouse, Target};
|
use crate::test::instruction::{Interaction, Mouse, Target};
|
||||||
use crate::test::selector;
|
use crate::test::selector;
|
||||||
|
|
||||||
pub fn recorder<'a, Message, Renderer>(
|
pub fn recorder<'a, Message, Theme, Renderer>(
|
||||||
content: impl Into<Element<'a, Message, Theme, Renderer>>,
|
content: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||||
) -> Recorder<'a, Message, Renderer> {
|
) -> Recorder<'a, Message, Theme, Renderer> {
|
||||||
Recorder::new(content)
|
Recorder::new(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Recorder<'a, Message, Renderer> {
|
pub struct Recorder<'a, Message, Theme, Renderer> {
|
||||||
content: Element<'a, Message, Theme, Renderer>,
|
content: Element<'a, Message, Theme, Renderer>,
|
||||||
on_record: Option<Box<dyn Fn(Interaction) -> Message + 'a>>,
|
on_record: Option<Box<dyn Fn(Interaction) -> Message + 'a>>,
|
||||||
has_overlay: bool,
|
has_overlay: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Recorder<'a, Message, Renderer> {
|
impl<'a, Message, Theme, Renderer> Recorder<'a, Message, Theme, Renderer> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
content: impl Into<Element<'a, Message, Theme, Renderer>>,
|
content: impl Into<Element<'a, Message, Theme, Renderer>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -50,10 +51,11 @@ struct State {
|
||||||
last_hovered_overlay: Option<Rectangle>,
|
last_hovered_overlay: Option<Rectangle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Message, Renderer> Widget<Message, Theme, Renderer>
|
impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer>
|
||||||
for Recorder<'_, Message, Renderer>
|
for Recorder<'_, Message, Theme, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: core::Renderer,
|
Renderer: core::Renderer,
|
||||||
|
Theme: theme::Base,
|
||||||
{
|
{
|
||||||
fn tag(&self) -> tree::Tag {
|
fn tag(&self) -> tree::Tag {
|
||||||
tree::Tag::of::<State>()
|
tree::Tag::of::<State>()
|
||||||
|
|
@ -171,15 +173,13 @@ where
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let palette = theme.palette();
|
|
||||||
|
|
||||||
renderer.with_layer(*viewport, |renderer| {
|
renderer.with_layer(*viewport, |renderer| {
|
||||||
renderer.fill_quad(
|
renderer.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds: *last_hovered,
|
bounds: *last_hovered,
|
||||||
..renderer::Quad::default()
|
..renderer::Quad::default()
|
||||||
},
|
},
|
||||||
palette.primary.scale_alpha(0.7),
|
highlight(theme).scale_alpha(0.7),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -250,29 +250,30 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> From<Recorder<'a, Message, Renderer>>
|
impl<'a, Message, Theme, Renderer> From<Recorder<'a, Message, Theme, Renderer>>
|
||||||
for Element<'a, Message, Theme, Renderer>
|
for Element<'a, Message, Theme, Renderer>
|
||||||
where
|
where
|
||||||
Message: 'a,
|
Message: 'a,
|
||||||
Theme: 'a,
|
Theme: theme::Base + 'a,
|
||||||
Renderer: core::Renderer + 'a,
|
Renderer: core::Renderer + 'a,
|
||||||
{
|
{
|
||||||
fn from(recorder: Recorder<'a, Message, Renderer>) -> Self {
|
fn from(recorder: Recorder<'a, Message, Theme, Renderer>) -> Self {
|
||||||
Element::new(recorder)
|
Element::new(recorder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Overlay<'a, Message, Renderer> {
|
struct Overlay<'a, Message, Theme, Renderer> {
|
||||||
raw: overlay::Element<'a, Message, Theme, Renderer>,
|
raw: overlay::Element<'a, Message, Theme, Renderer>,
|
||||||
bounds: Rectangle,
|
bounds: Rectangle,
|
||||||
last_hovered: &'a mut Option<Rectangle>,
|
last_hovered: &'a mut Option<Rectangle>,
|
||||||
on_record: Option<&'a dyn Fn(Interaction) -> Message>,
|
on_record: Option<&'a dyn Fn(Interaction) -> Message>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> core::Overlay<Message, Theme, Renderer>
|
impl<'a, Message, Theme, Renderer> core::Overlay<Message, Theme, Renderer>
|
||||||
for Overlay<'a, Message, Renderer>
|
for Overlay<'a, Message, Theme, Renderer>
|
||||||
where
|
where
|
||||||
Renderer: core::Renderer + 'a,
|
Renderer: core::Renderer + 'a,
|
||||||
|
Theme: theme::Base + 'a,
|
||||||
{
|
{
|
||||||
fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
|
fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node {
|
||||||
self.raw.as_overlay_mut().layout(renderer, bounds)
|
self.raw.as_overlay_mut().layout(renderer, bounds)
|
||||||
|
|
@ -294,15 +295,13 @@ where
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let palette = theme.palette();
|
|
||||||
|
|
||||||
renderer.with_layer(self.bounds, |renderer| {
|
renderer.with_layer(self.bounds, |renderer| {
|
||||||
renderer.fill_quad(
|
renderer.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds: *last_hovered,
|
bounds: *last_hovered,
|
||||||
..renderer::Quad::default()
|
..renderer::Quad::default()
|
||||||
},
|
},
|
||||||
palette.primary.scale_alpha(0.7),
|
highlight(theme).scale_alpha(0.7),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -496,3 +495,10 @@ fn find_text(
|
||||||
|
|
||||||
Some((content, visible_bounds))
|
Some((content, visible_bounds))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn highlight(theme: &impl theme::Base) -> Color {
|
||||||
|
theme
|
||||||
|
.palette()
|
||||||
|
.map(|palette| palette.primary)
|
||||||
|
.unwrap_or(Color::from_rgb(0.0, 0.0, 1.0))
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue