From 6dbdc9f483f067bd49e3f10853a1f5c378ef9d15 Mon Sep 17 00:00:00 2001 From: Paris DOUADY Date: Sat, 3 Feb 2024 11:07:00 +0100 Subject: [PATCH] window dragging --- Cargo.lock | 1 - assets_gui/src/main.rs | 2 + engine/Cargo.toml | 3 +- engine/src/framework.rs | 4 +- engine/src/yakui.rs | 2 - goryak/src/window.rs | 108 ++++++++++++++++++++++++++++-------- native_app/src/game_loop.rs | 2 + 7 files changed, 91 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c224a94..7e664f20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -925,7 +925,6 @@ dependencies = [ "egui-winit", "geom", "gltf", - "goryak", "image", "inline_tweak", "itertools", diff --git a/assets_gui/src/main.rs b/assets_gui/src/main.rs index 1f9227fc..fcb236ee 100644 --- a/assets_gui/src/main.rs +++ b/assets_gui/src/main.rs @@ -30,6 +30,8 @@ struct State { impl engine::framework::State for State { fn new(ctx: &mut Context) -> Self { + goryak::set_blur_texture(ctx.yakui.blur_bg_texture); + let gfx = &mut ctx.gfx; gfx.render_params.value_mut().shadow_mapping_resolution = 2048; diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 686caf54..6e91a3b5 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -12,7 +12,6 @@ crate-type = ["dylib"] [dependencies] geom = { path = "../geom" } common = { path = "../common" } -goryak = { path = "../goryak", optional = true } ordered-float = { workspace = true } egui = { workspace = true } oddio = { workspace = true } @@ -42,4 +41,4 @@ yakui-winit = { workspace = true, optional = true } lazy_static = "1.4.0" [features] -yakui = ["dep:yakui", "dep:yakui-wgpu", "dep:yakui-winit", "dep:goryak"] \ No newline at end of file +yakui = ["dep:yakui", "dep:yakui-wgpu", "dep:yakui-winit"] \ No newline at end of file diff --git a/engine/src/framework.rs b/engine/src/framework.rs index e19e38d7..effc7e88 100644 --- a/engine/src/framework.rs +++ b/engine/src/framework.rs @@ -134,13 +134,11 @@ async fn run(el: EventLoop<()>, window: Arc) { }); ctx.gui_time = gui_start.elapsed().as_secs_f32(); ctx.gfx.finish_frame(enc); - sco.present(); - ctx.gfx.window.set_cursor_icon(get_cursor_icon()); - ctx.input.end_frame(); ctx.total_cpu_time = last_update.elapsed().as_secs_f32(); + sco.present(); ctx.gfx.window.request_redraw(); } _ => (), diff --git a/engine/src/yakui.rs b/engine/src/yakui.rs index fa8d39bd..a2187cd5 100644 --- a/engine/src/yakui.rs +++ b/engine/src/yakui.rs @@ -45,8 +45,6 @@ impl YakuiWrapper { wgpu::FilterMode::Linear, ); - goryak::set_blur_texture(texture_id); - Self { blur_bg_texture: texture_id, yakui, diff --git a/goryak/src/window.rs b/goryak/src/window.rs index 790bcb70..d2231008 100644 --- a/goryak/src/window.rs +++ b/goryak/src/window.rs @@ -1,10 +1,12 @@ use std::borrow::Cow; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; +use std::rc::Rc; -use yakui_core::geometry::{Dim2, Vec2}; -use yakui_core::{Alignment, MainAxisSize}; +use yakui_core::geometry::{Constraints, Dim2, Vec2}; +use yakui_core::widget::{LayoutContext, Widget}; +use yakui_core::{context, Alignment, Flow, MainAxisSize}; use yakui_widgets::widgets::{List, Pad}; -use yakui_widgets::{draggable, offset, reflow, row, use_state}; +use yakui_widgets::{draggable, row}; use crate::{blur_bg, divider, on_secondary_container, outline, secondary_container, textc}; @@ -21,29 +23,89 @@ pub struct Window { impl Window { pub fn show(self, children: impl FnOnce()) { - reflow(Alignment::TOP_LEFT, Dim2::ZERO, || { - let off = use_state(|| Vec2::new(300.0, 300.0)); - - offset(off.get(), || { - let r = draggable(|| { - blur_bg(secondary_container().with_alpha(0.7), 5.0, || { - self.pad.show(|| { - let mut l = List::column(); - l.main_axis_size = MainAxisSize::Min; - l.show(|| { - row(|| { - textc(on_secondary_container(), Cow::Borrowed(self.title)); - }); - divider(outline(), 10.0, 1.0); - children(); - }); + let dom = context::dom(); + let response = dom.begin_widget::(()); + + let off = draggable(|| { + blur_bg(secondary_container().with_alpha(0.7), 5.0, || { + self.pad.show(|| { + let mut l = List::column(); + l.main_axis_size = MainAxisSize::Min; + l.show(|| { + row(|| { + textc(on_secondary_container(), Cow::Borrowed(self.title)); }); + divider(outline(), 10.0, 1.0); + children(); }); }); - if let Some(v) = r.dragging { - off.set(v.current); - } }); }); + + response.confirm.set(off.dragging.is_none()); + if let Some(drag) = off.dragging { + response.off.set(drag.current - drag.start); + } + + dom.end_widget::(response.id); + } +} + +#[derive(Default, Debug)] +struct WindowBase { + props: (), + off: Vec2, + resp: Rc, +} + +#[derive(Default, Debug)] +struct WindowResp { + off: Cell, + confirm: Cell, +} + +impl Widget for WindowBase { + type Props<'a> = (); + type Response = Rc; + + fn new() -> Self { + Self::default() + } + + fn update(&mut self, props: Self::Props<'_>) -> Self::Response { + self.props = props; + if self.resp.confirm.get() { + self.off += self.resp.off.get(); + self.resp.off.set(Vec2::ZERO); + } + self.resp.clone() + } + + fn flow(&self) -> Flow { + Flow::Relative { + anchor: Alignment::TOP_LEFT, + offset: Dim2::ZERO, + } + } + + fn layout(&self, mut ctx: LayoutContext<'_>, constraints: Constraints) -> Vec2 { + let node = ctx.dom.get_current(); + if node.children.len() > 1 { + panic!("Window can only have one child"); + } + + let child = *node.children.first().unwrap(); + let size = ctx.calculate_layout(child, constraints); + + let vp = ctx.layout.viewport().size(); + + let mut pos = vp * 0.5 - size * 0.5 + self.off + self.resp.off.get(); + let overflow = (pos + size - vp).max(Vec2::ZERO); + pos = pos - overflow; + pos = pos.max(Vec2::ZERO); + + ctx.layout.set_pos(child, pos); + + Vec2::ZERO } } diff --git a/native_app/src/game_loop.rs b/native_app/src/game_loop.rs index 139f49e2..9f079aec 100644 --- a/native_app/src/game_loop.rs +++ b/native_app/src/game_loop.rs @@ -39,6 +39,8 @@ pub struct State { impl engine::framework::State for State { fn new(ctx: &mut Context) -> Self { + goryak::set_blur_texture(ctx.yakui.blur_bg_texture); + let camera = OrbitCamera::load((ctx.gfx.size.0, ctx.gfx.size.1)); Gui::set_style(ctx.egui.platform.egui_ctx());