mirror of
https://github.com/danbulant/cushy
synced 2026-06-18 14:01:10 +00:00
Added animation recording + event wiring
Not great, but it technically exists.
This commit is contained in:
parent
2e2d45d281
commit
bc52be440f
18 changed files with 807 additions and 330 deletions
3
.github/workflows/rust.yml
vendored
3
.github/workflows/rust.yml
vendored
|
|
@ -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
15
Cargo.lock
generated
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
38
examples/offscreen-apng.rs
Normal file
38
examples/offscreen-apng.rs
Normal 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();
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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<'_>,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -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<'_>,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
985
src/window.rs
985
src/window.rs
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue