Added animation recording + event wiring

Not great, but it technically exists.
This commit is contained in:
Jonathan Johnson 2024-01-03 17:45:11 -08:00
parent 2e2d45d281
commit bc52be440f
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
18 changed files with 807 additions and 330 deletions

View file

@ -41,5 +41,8 @@ jobs:
cargo build --all-features --all-targets
- name: Run all features unit tests
# for msrv, we only check build compatibility, as it's possible bugs are
# fixed purely by updating the rust version.
if: matrix.version == 'stable'
run: |
cargo test --all-features --all-targets

15
Cargo.lock generated
View file

@ -582,6 +582,7 @@ dependencies = [
"kempt",
"kludgine",
"palette",
"png",
"pollster",
"rand",
"tracing",
@ -1179,7 +1180,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "kludgine"
version = "0.7.0"
source = "git+https://github.com/khonsulabs/kludgine#9999ff4a323a6dec1deebb9a0a1825d561559478"
source = "git+https://github.com/khonsulabs/kludgine#6b0d5fa0477daaf79f75a6f7dad819377a45e645"
dependencies = [
"ahash",
"alot",
@ -1858,9 +1859,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.74"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db"
checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708"
dependencies = [
"unicode-ident",
]
@ -2331,9 +2332,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.46"
version = "2.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e"
checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb"
dependencies = [
"proc-macro2",
"quote",
@ -3233,9 +3234,9 @@ dependencies = [
[[package]]
name = "winnow"
version = "0.5.31"
version = "0.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c"
checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6"
dependencies = [
"memchr",
]

View file

@ -40,6 +40,7 @@ arboard = "3.2.1"
zeroize = "1.6.1"
unicode-segmentation = "1.10.1"
pollster = "0.3.0"
png = "0.17.10"
# [patch.crates-io]

View file

@ -4,6 +4,7 @@
use cushy::value::{Destination, Dynamic, Source};
use cushy::widget::{MakeWidget, MakeWidgetWithTag, Widget, WidgetInstance, WidgetTag, HANDLED};
use cushy::widgets::Custom;
use cushy::window::DeviceId;
use cushy::Run;
use figures::units::{Lp, UPx};
use figures::{ScreenScale, Size};
@ -116,7 +117,7 @@ impl Widget for Toggle {
fn mouse_down(
&mut self,
_location: figures::Point<figures::units::Px>,
_device_id: kludgine::app::winit::event::DeviceId,
_device_id: DeviceId,
_button: kludgine::app::winit::event::MouseButton,
_context: &mut cushy::context::EventContext<'_>,
) -> cushy::widget::EventHandling {

View file

@ -0,0 +1,38 @@
use std::time::Duration;
use cushy::animation::easings::EaseInOutSine;
use cushy::widget::MakeWidget;
use figures::units::Px;
use figures::{Point, Size};
fn ui() -> impl MakeWidget {
"Hello World".into_button().centered()
}
fn main() {
// The default recorder generated solid, rgb images.
let mut recorder = ui()
.build_recorder()
.size(Size::new(320, 240))
.finish()
.unwrap();
let initial_point = Point::new(Px::new(140), Px::new(150));
recorder.set_cursor_position(initial_point);
recorder.refresh().unwrap();
let mut animation = recorder.record_animated_png(60);
animation
.animate_cursor_to(
Point::new(Px::new(160), Px::new(120)),
Duration::from_millis(250),
EaseInOutSine,
)
.unwrap();
animation.wait_for(Duration::from_millis(500)).unwrap();
animation
.animate_cursor_to(initial_point, Duration::from_millis(250), EaseInOutSine)
.unwrap();
animation.wait_for(Duration::from_millis(500)).unwrap();
animation
.write_to("examples/offscreen-animated.png")
.unwrap();
}

View file

@ -15,8 +15,8 @@ fn main() {
image::save_buffer_with_format(
"examples/offscreen.png",
recorder.bytes(),
recorder.size().width.get(),
recorder.size().height.get(),
recorder.window.size().width.get(),
recorder.window.size().height.get(),
image::ColorType::Rgb8,
image::ImageFormat::Png,
)
@ -32,8 +32,8 @@ fn main() {
image::save_buffer_with_format(
"examples/offscreen-transparent.png",
recorder.bytes(),
recorder.size().width.get(),
recorder.size().height.get(),
recorder.window.size().width.get(),
recorder.window.size().height.get(),
image::ColorType::Rgba8,
image::ImageFormat::Png,
)

View file

@ -49,7 +49,7 @@ use std::time::{Duration, Instant};
use alot::{LotId, Lots};
use figures::units::{Lp, Px, UPx};
use figures::{Angle, Ranged, UnscaledUnit, Zero};
use figures::{Angle, Point, Ranged, Rect, Size, UnscaledUnit, Zero};
use intentional::Cast;
use kempt::Set;
use kludgine::Color;
@ -929,6 +929,42 @@ impl_unscaled_lerp!(Px);
impl_unscaled_lerp!(Lp);
impl_unscaled_lerp!(UPx);
impl<Unit> LinearInterpolate for Point<Unit>
where
Unit: LinearInterpolate,
{
fn lerp(&self, target: &Self, percent: f32) -> Self {
Self::new(
self.x.lerp(&target.x, percent),
self.y.lerp(&target.y, percent),
)
}
}
impl<Unit> LinearInterpolate for Size<Unit>
where
Unit: LinearInterpolate,
{
fn lerp(&self, target: &Self, percent: f32) -> Self {
Self::new(
self.width.lerp(&target.width, percent),
self.height.lerp(&target.height, percent),
)
}
}
impl<Unit> LinearInterpolate for Rect<Unit>
where
Unit: LinearInterpolate,
{
fn lerp(&self, target: &Self, percent: f32) -> Self {
Self::new(
self.origin.lerp(&target.origin, percent),
self.size.lerp(&target.size, percent),
)
}
}
#[test]
fn integer_lerps() {
#[track_caller]

View file

@ -4,9 +4,7 @@ use std::ops::{Deref, DerefMut};
use figures::units::{Lp, Px, UPx};
use figures::{IntoSigned, Point, Px2D, Rect, Round, ScreenScale, Size, Zero};
use kludgine::app::winit::event::{
DeviceId, Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase,
};
use kludgine::app::winit::event::{Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::window::CursorIcon;
use kludgine::shapes::{Shape, StrokeOptions};
use kludgine::{Color, Kludgine, KludgineId};
@ -21,7 +19,7 @@ use crate::styles::{ComponentDefinition, Styles, Theme, ThemePair};
use crate::tree::Tree;
use crate::value::{IntoValue, Source, Value};
use crate::widget::{EventHandling, MountedWidget, RootBehavior, WidgetId, WidgetInstance};
use crate::window::{CursorState, PlatformWindow, ThemeMode};
use crate::window::{CursorState, DeviceId, PlatformWindow, ThemeMode};
use crate::ConstraintLimit;
/// A context to an event function.

View file

@ -12,9 +12,7 @@ use alot::LotId;
use figures::units::{Px, UPx};
use figures::{IntoSigned, IntoUnsigned, Point, Rect, Size};
use intentional::Assert;
use kludgine::app::winit::event::{
DeviceId, Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase,
};
use kludgine::app::winit::event::{Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::window::CursorIcon;
use kludgine::Color;
@ -47,7 +45,7 @@ use crate::widgets::{
};
use crate::window::sealed::WindowCommand;
use crate::window::{
Rgb8, RunningWindow, ThemeMode, VirtualRecorderBuilder, VirtualWindowBuilder, Window,
DeviceId, Rgb8, RunningWindow, ThemeMode, VirtualRecorderBuilder, VirtualWindowBuilder, Window,
WindowBehavior, WindowHandle, WindowLocal,
};
use crate::ConstraintLimit;

View file

@ -3,7 +3,7 @@ use std::time::Duration;
use figures::units::{Lp, Px, UPx};
use figures::{IntoSigned, Point, Rect, Round, ScreenScale, Size};
use kludgine::app::winit::event::{DeviceId, MouseButton};
use kludgine::app::winit::event::MouseButton;
use kludgine::app::winit::window::CursorIcon;
use kludgine::shapes::{Shape, StrokeOptions};
use kludgine::Color;
@ -21,7 +21,7 @@ use crate::styles::components::{
use crate::styles::{ColorExt, Styles};
use crate::value::{Destination, Dynamic, IntoValue, Source, Value};
use crate::widget::{Callback, EventHandling, MakeWidget, Widget, WidgetRef, HANDLED};
use crate::window::WindowLocal;
use crate::window::{DeviceId, WindowLocal};
use crate::FitMeasuredSize;
/// A clickable button.

View file

@ -4,7 +4,7 @@ use std::ops::Range;
use figures::units::{Lp, Px};
use figures::{FloatConversion, Point, Rect, Round, ScreenScale, Zero};
use intentional::Cast;
use kludgine::app::winit::event::{DeviceId, MouseButton};
use kludgine::app::winit::event::MouseButton;
use kludgine::shapes::{self, FillOptions, PathBuilder, Shape, StrokeOptions};
use kludgine::{Color, DrawableExt, Origin};
@ -14,6 +14,7 @@ use crate::styles::components::{HighlightColor, OutlineColor, TextColor};
use crate::styles::{ColorExt, ColorSource};
use crate::value::{Destination, Dynamic, IntoValue, Source, Value};
use crate::widget::{EventHandling, Widget, HANDLED};
use crate::window::DeviceId;
/// A widget that selects a [`ColorSource`].
#[derive(Debug)]

View file

@ -2,9 +2,7 @@ use std::fmt::Debug;
use figures::units::Px;
use figures::{Point, Size};
use kludgine::app::winit::event::{
DeviceId, Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase,
};
use kludgine::app::winit::event::{Ime, KeyEvent, MouseButton, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::window::CursorIcon;
use kludgine::Color;
@ -13,6 +11,7 @@ use crate::styles::VisualOrder;
use crate::value::{IntoValue, Value};
use crate::widget::{EventHandling, MakeWidget, WidgetRef, WrappedLayout, WrapperWidget, IGNORED};
use crate::widgets::Space;
use crate::window::DeviceId;
use crate::ConstraintLimit;
/// A callback-based custom widget.

View file

@ -18,6 +18,7 @@ use crate::widget::{
EventHandling, MakeWidget, MakeWidgetWithTag, Widget, WidgetInstance, WidgetRef, WidgetTag,
HANDLED, IGNORED,
};
use crate::window::DeviceId;
use crate::ConstraintLimit;
/// A widget that hides and shows another widget.
@ -316,7 +317,7 @@ impl Widget for DiscloseIndicator {
fn mouse_down(
&mut self,
location: Point<Px>,
_device_id: kludgine::app::winit::event::DeviceId,
_device_id: DeviceId,
_button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_>,
) -> EventHandling {
@ -333,7 +334,7 @@ impl Widget for DiscloseIndicator {
fn mouse_up(
&mut self,
_location: Option<Point<Px>>,
_device_id: kludgine::app::winit::event::DeviceId,
_device_id: DeviceId,
_button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_>,
) {

View file

@ -973,7 +973,7 @@ where
fn mouse_down(
&mut self,
location: Point<Px>,
_device_id: kludgine::app::winit::event::DeviceId,
_device_id: crate::window::DeviceId,
_button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_>,
) -> EventHandling {
@ -997,7 +997,7 @@ where
fn mouse_drag(
&mut self,
location: Point<Px>,
_device_id: kludgine::app::winit::event::DeviceId,
_device_id: crate::window::DeviceId,
_button: kludgine::app::winit::event::MouseButton,
context: &mut EventContext<'_>,
) {
@ -1012,7 +1012,7 @@ where
fn mouse_up(
&mut self,
_location: Option<Point<Px>>,
_device_id: kludgine::app::winit::event::DeviceId,
_device_id: crate::window::DeviceId,
_button: kludgine::app::winit::event::MouseButton,
_context: &mut EventContext<'_>,
) {
@ -1188,7 +1188,7 @@ where
fn keyboard_input(
&mut self,
_device_id: kludgine::app::winit::event::DeviceId,
_device_id: crate::window::DeviceId,
input: kludgine::app::winit::event::KeyEvent,
_is_synthetic: bool,
context: &mut EventContext<'_>,

View file

@ -4,7 +4,7 @@ use std::time::{Duration, Instant};
use figures::units::{Lp, Px, UPx};
use figures::{FloatConversion, IntoSigned, IntoUnsigned, Point, Rect, ScreenScale, Size, Zero};
use intentional::Cast;
use kludgine::app::winit::event::{DeviceId, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::event::{MouseScrollDelta, TouchPhase};
use kludgine::app::winit::window::CursorIcon;
use kludgine::shapes::Shape;
use kludgine::Color;
@ -15,6 +15,7 @@ use crate::styles::components::{EasingIn, EasingOut, LineHeight};
use crate::styles::Dimension;
use crate::value::{Destination, Dynamic, Source};
use crate::widget::{EventHandling, MakeWidget, Widget, WidgetRef, HANDLED, IGNORED};
use crate::window::DeviceId;
use crate::ConstraintLimit;
/// A widget that supports scrolling its contents.

View file

@ -6,7 +6,7 @@ use std::ops::RangeInclusive;
use figures::units::{Lp, Px, UPx};
use figures::{FloatConversion, IntoSigned, Point, Ranged, Rect, Round, ScreenScale, Size};
use intentional::{Assert, Cast as _};
use kludgine::app::winit::event::{DeviceId, MouseButton, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::event::{MouseButton, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::keyboard::{Key, NamedKey};
use kludgine::app::winit::window::CursorIcon;
use kludgine::shapes::{Shape, StrokeOptions};
@ -21,6 +21,7 @@ use crate::styles::components::{
use crate::styles::{Dimension, HorizontalOrder, VerticalOrder, VisualOrder};
use crate::value::{Destination, Dynamic, IntoDynamic, IntoValue, Source, Value};
use crate::widget::{EventHandling, Widget, HANDLED, IGNORED};
use crate::window::DeviceId;
use crate::ConstraintLimit;
/// A widget that allows sliding between two values.

View file

@ -3,7 +3,7 @@ use std::fmt::Debug;
use figures::units::{Px, UPx};
use figures::{Point, Size};
use intentional::Cast;
use kludgine::app::winit::event::{DeviceId, ElementState, KeyEvent, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::event::{ElementState, KeyEvent, MouseScrollDelta, TouchPhase};
use kludgine::app::winit::window::CursorIcon;
use kludgine::tilemap;
use kludgine::tilemap::TileMapFocus;
@ -12,6 +12,7 @@ use crate::context::{EventContext, GraphicsContext, LayoutContext, Trackable};
use crate::tick::Tick;
use crate::value::{Dynamic, IntoValue, Value};
use crate::widget::{EventHandling, Widget, HANDLED, IGNORED};
use crate::window::DeviceId;
use crate::ConstraintLimit;
/// A layered tile-based 2d game surface.

File diff suppressed because it is too large Load diff