Skip to content

Commit

Permalink
Merge pull request #10 from linebender/mut_fragment
Browse files Browse the repository at this point in the history
Pass mutable scene builder reference to paint
  • Loading branch information
raphlinus authored Nov 26, 2022
2 parents c07f0ab + 68f5a6b commit 44369fb
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 46 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ use std::time::Duration;
use glazier::kurbo::Size;
use glazier::{IdleHandle, IdleToken, WindowHandle};
use parley::FontContext;
use piet_scene::{SceneBuilder, SceneFragment};
use tokio::runtime::Runtime;

use crate::event::{AsyncWake, EventResult};
use crate::id::IdPath;
use crate::widget::{CxState, EventCx, LayoutCx, PaintCx, Pod, Rendered, UpdateCx, WidgetState};
use crate::widget::{CxState, EventCx, LayoutCx, PaintCx, Pod, UpdateCx, WidgetState};
use crate::{
event::Event,
id::Id,
Expand Down Expand Up @@ -170,7 +171,7 @@ where
self.size = size;
}

pub fn paint(&mut self) -> Rendered {
pub fn paint(&mut self) {
loop {
self.send_events();
// TODO: be more lazy re-rendering
Expand Down Expand Up @@ -198,7 +199,8 @@ where
continue;
}
let mut paint_cx = PaintCx::new(&mut cx_state, &mut self.root_state);
return root_pod.paint(&mut paint_cx);
root_pod.paint(&mut paint_cx);
break;
}
}

Expand Down Expand Up @@ -273,6 +275,12 @@ where
}
}

impl<T, V: View<T>> App<T, V> {
pub fn fragment(&self) -> &SceneFragment {
self.root_pod.as_ref().unwrap().fragment()
}
}

impl<T, V: View<T>, F: FnMut(&mut T) -> V> AppTask<T, V, F>
where
V::Element: Widget + 'static,
Expand Down
12 changes: 7 additions & 5 deletions src/app_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ where
fn prepare_paint(&mut self) {}

fn paint(&mut self, _: &Region) {
let rendered = self.app.paint();
self.render(rendered.0);
self.app.paint();
self.render();
self.schedule_render();
}

// TODO: temporary hack
fn idle(&mut self, _: IdleToken) {
let rendered = self.app.paint();
self.render(rendered.0);
self.app.paint();
self.render();
self.schedule_render();
}

Expand Down Expand Up @@ -160,6 +160,7 @@ where
impl<T, V: View<T>> MainState<T, V>
where
V::Element: Widget,
T: Send,
{
fn new(app: App<T, V>) -> Self {
let state = MainState {
Expand All @@ -186,7 +187,8 @@ where
self.handle.invalidate();
}

fn render(&mut self, fragment: SceneFragment) {
fn render(&mut self) {
let fragment = self.app.fragment();
if self.pgpu_state.is_none() {
let handle = &self.handle;
let scale = handle.get_scale().unwrap();
Expand Down
9 changes: 4 additions & 5 deletions src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use std::any::Any;
use std::ops::{Deref, DerefMut};

use glazier::kurbo::{Rect, Size};
use piet_scene::SceneBuilder;

use self::contexts::LifeCycleCx;
pub use self::contexts::{AlignCx, CxState, EventCx, LayoutCx, PaintCx, PreparePaintCx, UpdateCx};
Expand Down Expand Up @@ -79,11 +80,9 @@ pub trait Widget {
#[allow(unused)]
fn prepare_paint(&mut self, cx: &mut LayoutCx, visible: Rect) {}

fn paint(&mut self, cx: &mut PaintCx) -> Rendered;
fn paint(&mut self, cx: &mut PaintCx, builder: &mut SceneBuilder);
}

pub struct Rendered(pub(crate) piet_scene::SceneFragment);

pub trait AnyWidget: Widget {
fn as_any(&self) -> &dyn Any;

Expand Down Expand Up @@ -135,8 +134,8 @@ impl Widget for Box<dyn AnyWidget> {
self.deref_mut().prepare_paint(cx, visible)
}

fn paint(&mut self, cx: &mut PaintCx) -> Rendered {
self.deref_mut().paint(cx)
fn paint(&mut self, cx: &mut PaintCx, builder: &mut SceneBuilder) {
self.deref_mut().paint(cx, builder);
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/widget/align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
// limitations under the License.

use glazier::kurbo::{Point, Size};
use piet_scene::SceneBuilder;

use super::{
contexts::LifeCycleCx, AlignCx, AnyWidget, EventCx, LifeCycle, Rendered, Widget, WidgetState,
};
use super::{contexts::LifeCycleCx, AlignCx, AnyWidget, EventCx, LifeCycle, Widget, WidgetState};

#[derive(Clone, Copy, PartialEq)]
pub enum AlignmentMerge {
Expand Down Expand Up @@ -276,7 +275,7 @@ impl<F: Fn(AlignmentProxy) -> f64 + 'static> Widget for AlignmentGuide<F> {
}
}

fn paint(&mut self, cx: &mut super::PaintCx) -> Rendered {
self.child.paint(cx)
fn paint(&mut self, cx: &mut super::PaintCx, builder: &mut SceneBuilder) {
self.child.paint(cx, builder);
}
}
18 changes: 5 additions & 13 deletions src/widget/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::{
align::{FirstBaseline, LastBaseline, SingleAlignment},
contexts::LifeCycleCx,
piet_scene_helpers::{self, UnitPoint},
AlignCx, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, Rendered, UpdateCx, Widget,
AlignCx, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, UpdateCx, Widget,
};

pub struct Button {
Expand Down Expand Up @@ -122,7 +122,7 @@ impl Widget for Button {
*/
}

fn paint(&mut self, cx: &mut PaintCx) -> Rendered {
fn paint(&mut self, cx: &mut PaintCx, builder: &mut SceneBuilder) {
let is_hot = cx.is_hot();
let is_active = cx.is_active();
let button_border_width = 2.0;
Expand Down Expand Up @@ -156,16 +156,9 @@ impl Widget for Button {
)
};
*/
let mut fragment = SceneFragment::default();
let mut builder = SceneBuilder::for_fragment(&mut fragment);
piet_scene_helpers::stroke(
&mut builder,
&rounded_rect,
border_color,
button_border_width,
);
piet_scene_helpers::stroke(builder, &rounded_rect, border_color, button_border_width);
piet_scene_helpers::fill_lin_gradient(
&mut builder,
builder,
&rounded_rect,
bg_stops,
UnitPoint::TOP,
Expand All @@ -176,8 +169,7 @@ impl Widget for Button {
let size = Size::new(layout.width() as f64, layout.height() as f64);
let offset = (cx.size().to_vec2() - size.to_vec2()) * 0.5;
let transform = Affine::translate(offset);
crate::text::render_text(&mut builder, transform, &layout);
crate::text::render_text(builder, transform, &layout);
}
Rendered(fragment)
}
}
24 changes: 18 additions & 6 deletions src/widget/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
//! widget system, particularly its core.rs.
use bitflags::bitflags;
use glazier::kurbo::{Affine, Point, Rect, Size};
use glazier::kurbo::{Point, Rect, Size};
use piet_scene::{SceneBuilder, SceneFragment};

use crate::Widget;

Expand All @@ -29,7 +30,7 @@ use super::{
},
contexts::LifeCycleCx,
AlignCx, AnyWidget, CxState, EventCx, LayoutCx, LifeCycle, PaintCx, PreparePaintCx, RawEvent,
Rendered, UpdateCx,
UpdateCx,
};

bitflags! {
Expand All @@ -52,6 +53,7 @@ bitflags! {
pub struct Pod {
pub(crate) state: WidgetState,
pub(crate) widget: Box<dyn AnyWidget>,
fragment: SceneFragment,
}

#[derive(Default, Debug)]
Expand Down Expand Up @@ -116,6 +118,7 @@ impl Pod {
flags: PodFlags::INIT_FLAGS,
..Default::default()
},
fragment: SceneFragment::default(),
widget,
}
}
Expand Down Expand Up @@ -295,24 +298,25 @@ impl Pod {
self.widget.align(&mut child_cx, alignment);
}

pub fn paint_raw(&mut self, cx: &mut PaintCx) {
pub fn paint_raw(&mut self, cx: &mut PaintCx, builder: &mut SceneBuilder) {
let mut inner_cx = PaintCx {
cx_state: cx.cx_state,
widget_state: &mut self.state,
};
self.widget.paint(&mut inner_cx);
self.widget.paint(&mut inner_cx, builder);
}

pub fn prepare_paint(&mut self, cx: &mut PreparePaintCx, visible: Rect) {
self.widget.prepare_paint(cx, visible);
}

pub fn paint(&mut self, cx: &mut PaintCx) -> Rendered {
pub fn paint(&mut self, cx: &mut PaintCx) {
let mut inner_cx = PaintCx {
cx_state: cx.cx_state,
widget_state: &mut self.state,
};
self.widget.paint(&mut inner_cx)
let mut builder = SceneBuilder::for_fragment(&mut self.fragment);
self.widget.paint(&mut inner_cx, &mut builder);
}

pub fn height_flexibility(&self) -> f64 {
Expand Down Expand Up @@ -350,4 +354,12 @@ impl Pod {
}
false
}

/// Get the rendered scene fragment for the widget.
///
/// This is only valid after a `paint` call, but the fragment can be retained
/// (skipping further paint calls) if the appearance does not change.
pub fn fragment(&self) -> &SceneFragment {
&self.fragment
}
}
9 changes: 3 additions & 6 deletions src/widget/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::text::ParleyBrush;
use super::{
align::{FirstBaseline, LastBaseline, SingleAlignment, VertAlignment},
contexts::LifeCycleCx,
AlignCx, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, Rendered, UpdateCx, Widget,
AlignCx, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, UpdateCx, Widget,
};

pub struct TextWidget {
Expand Down Expand Up @@ -77,13 +77,10 @@ impl Widget for TextWidget {

fn align(&self, cx: &mut AlignCx, alignment: SingleAlignment) {}

fn paint(&mut self, cx: &mut PaintCx) -> Rendered {
let mut fragment = SceneFragment::default();
let mut builder = SceneBuilder::for_fragment(&mut fragment);
fn paint(&mut self, cx: &mut PaintCx, builder: &mut SceneBuilder) {
if let Some(layout) = &self.layout {
let transform = Affine::translate((40.0, 40.0));
crate::text::render_text(&mut builder, transform, &layout);
crate::text::render_text(builder, transform, &layout);
}
Rendered(fragment)
}
}

0 comments on commit 44369fb

Please sign in to comment.