Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,7 @@ resolver = "2"
[patch.crates-io.kas-text]
git = "https://github.com/kas-gui/kas-text.git"
rev = "a087ae3c083fb8e7f73282514b556ecc9083c95a"

[patch.crates-io.impl-tools-lib]
git = "https://github.com/kas-gui/impl-tools.git"
rev = "e0b80cf7f2b868b1ace4ec06601a5ed4cf098686"
22 changes: 1 addition & 21 deletions crates/kas-core/src/core/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,8 @@ use crate::util::IdentifyWidget;
use crate::{Id, Tile};

#[cfg(not(feature = "unsafe_node"))]
#[crate::split_impl(for<'a, T> (&'a mut dyn Widget<Data = T>, &'a T))]
trait NodeT {
fn id_ref(&self) -> &Id;
fn rect(&self) -> Rect;

fn clone_node(&mut self) -> Node<'_>;
fn as_tile(&self) -> &dyn Tile;

fn find_child_index(&self, id: &Id) -> Option<usize>;
fn child_node(&mut self, index: usize) -> Option<Node<'_>>;

fn size_rules(&mut self, cx: &mut SizeCx, axis: AxisInfo) -> SizeRules;
fn set_rect(&mut self, cx: &mut SizeCx, rect: Rect, hints: AlignHints);

fn _configure(&mut self, cx: &mut ConfigCx, id: Id);
fn _update(&mut self, cx: &mut ConfigCx);

fn _send(&mut self, cx: &mut EventCx, id: Id, event: Event) -> IsUsed;
fn _replay(&mut self, cx: &mut EventCx, id: Id);
}
#[cfg(not(feature = "unsafe_node"))]
impl<'a, T> NodeT for (&'a mut dyn Widget<Data = T>, &'a T) {
fn id_ref(&self) -> &Id {
self.0.id_ref()
}
Expand All @@ -52,7 +33,6 @@ impl<'a, T> NodeT for (&'a mut dyn Widget<Data = T>, &'a T) {
fn find_child_index(&self, id: &Id) -> Option<usize> {
self.0.find_child_index(id)
}

fn child_node(&mut self, index: usize) -> Option<Node<'_>> {
self.0.child_node(self.1, index)
}
Expand Down
134 changes: 48 additions & 86 deletions crates/kas-core/src/draw/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,29 +153,40 @@ impl<'a, DS: DrawSharedImpl> DrawIface<'a, DS> {
/// on the graphics backend. Since Rust does not (yet) support trait-object-downcast,
/// accessing these requires reconstruction of the implementing type via
/// [`DrawIface::downcast_from`].
#[crate::split_impl(for<'a, DS: DrawSharedImpl> DrawIface<'a, DS>)]
pub trait Draw {
/// Access shared draw state
fn shared(&mut self) -> &mut dyn DrawShared;
fn shared(&mut self) -> &mut dyn DrawShared {
self.shared
}

/// Request redraw at the next frame time
///
/// Animations should call this each frame until complete.
fn animate(&mut self);
fn animate(&mut self) {
self.draw.animate();
}

/// Request a redraw at a specific time
///
/// This may be used for animations with delays, e.g. flashing. Calling this
/// method only ensures that the *next* draw happens *no later* than `time`,
/// thus the method should be called again in each following frame.
fn animate_at(&mut self, time: Instant);
fn animate_at(&mut self, time: Instant) {
self.draw.animate_at(time);
}

/// Get the current draw pass
fn get_pass(&self) -> PassId;
fn get_pass(&self) -> PassId {
self.pass
}

/// Cast fields to [`Any`] references
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(docsrs, doc(cfg(internal_doc)))]
fn get_fields_as_any_mut(&mut self) -> (&mut dyn Any, &mut dyn Any);
fn get_fields_as_any_mut(&mut self) -> (&mut dyn Any, &mut dyn Any) {
(self.draw, self.shared)
}

/// Add a draw pass
///
Expand All @@ -197,7 +208,9 @@ pub trait Draw {
rect: Rect,
offset: Offset,
class: PassType,
) -> Box<dyn Draw + 'b>;
) -> Box<dyn Draw + 'b> {
Box::new(self.new_pass(rect, offset, class))
}

/// Get drawable rect for a draw `pass`
///
Expand All @@ -206,19 +219,25 @@ pub trait Draw {
///
/// (This is not guaranteed to equal the rect passed to
/// [`DrawIface::new_pass`].)
fn get_clip_rect(&self) -> Rect;
fn get_clip_rect(&self) -> Rect {
self.draw.get_clip_rect(self.pass)
}

/// Draw a rectangle of uniform colour
///
/// Note: where the implementation batches and/or re-orders draw calls,
/// this should be one of the first items drawn such that almost anything
/// else will draw "in front of" a rect.
fn rect(&mut self, rect: Quad, col: Rgba);
fn rect(&mut self, rect: Quad, col: Rgba) {
self.draw.rect(self.pass, rect, col);
}

/// Draw a frame of uniform colour
///
/// The frame is defined by the area inside `outer` and not inside `inner`.
fn frame(&mut self, outer: Quad, inner: Quad, col: Rgba);
fn frame(&mut self, outer: Quad, inner: Quad, col: Rgba) {
self.draw.frame(self.pass, outer, inner, col);
}

/// Draw a line with uniform colour
///
Expand All @@ -230,10 +249,14 @@ pub trait Draw {
///
/// Note that for rectangular, axis-aligned lines, [`DrawImpl::rect`] should be
/// preferred.
fn line(&mut self, p1: Vec2, p2: Vec2, width: f32, col: Rgba);
fn line(&mut self, p1: Vec2, p2: Vec2, width: f32, col: Rgba) {
self.draw.line(self.pass, p1, p2, width, col);
}

/// Draw the image in the given `rect`
fn image(&mut self, id: ImageId, rect: Quad);
fn image(&mut self, id: ImageId, rect: Quad) {
self.shared.draw.draw_image(self.draw, self.pass, id, rect);
}

/// Draw text with a list of color effects
///
Expand All @@ -248,7 +271,11 @@ pub trait Draw {
text: &TextDisplay,
theme: &ColorsLinear,
tokens: &[(u32, format::Colors)],
);
) {
self.shared
.draw
.draw_text(self.draw, self.pass, pos, bounding_box, text, theme, tokens);
}

/// Draw text decorations (e.g. underlines)
///
Expand All @@ -261,81 +288,16 @@ pub trait Draw {
text: &TextDisplay,
theme: &ColorsLinear,
decorations: &[(u32, format::Decoration)],
);
}

impl<'a, DS: DrawSharedImpl> Draw for DrawIface<'a, DS> {
fn shared(&mut self) -> &mut dyn DrawShared {
self.shared
}

fn animate(&mut self) {
self.draw.animate();
}

fn animate_at(&mut self, time: Instant) {
self.draw.animate_at(time);
}

fn get_pass(&self) -> PassId {
self.pass
}

fn get_fields_as_any_mut(&mut self) -> (&mut dyn Any, &mut dyn Any) {
(self.draw, self.shared)
}

fn new_dyn_pass<'b>(
&'b mut self,
rect: Rect,
offset: Offset,
class: PassType,
) -> Box<dyn Draw + 'b> {
Box::new(self.new_pass(rect, offset, class))
}

fn get_clip_rect(&self) -> Rect {
self.draw.get_clip_rect(self.pass)
}

fn rect(&mut self, rect: Quad, col: Rgba) {
self.draw.rect(self.pass, rect, col);
}
fn frame(&mut self, outer: Quad, inner: Quad, col: Rgba) {
self.draw.frame(self.pass, outer, inner, col);
}
fn line(&mut self, p1: Vec2, p2: Vec2, width: f32, col: Rgba) {
self.draw.line(self.pass, p1, p2, width, col);
}

fn image(&mut self, id: ImageId, rect: Quad) {
self.shared.draw.draw_image(self.draw, self.pass, id, rect);
}

fn text(
&mut self,
pos: Vec2,
bb: Quad,
text: &TextDisplay,
theme: &ColorsLinear,
tokens: &[(u32, format::Colors)],
) {
self.shared
.draw
.draw_text(self.draw, self.pass, pos, bb, text, theme, tokens);
}

fn decorate_text(
&mut self,
pos: Vec2,
bb: Quad,
text: &TextDisplay,
theme: &ColorsLinear,
decorations: &[(u32, format::Decoration)],
) {
self.shared
.draw
.decorate_text(self.draw, self.pass, pos, bb, text, theme, decorations);
self.shared.draw.decorate_text(
self.draw,
self.pass,
pos,
bounding_box,
text,
theme,
decorations,
);
}
}

Expand Down
43 changes: 14 additions & 29 deletions crates/kas-core/src/draw/draw_rounded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::geom::{Quad, Vec2};
/// Extended draw interface for [`DrawIface`] providing rounded drawing
///
/// All methods draw some feature.
#[crate::split_impl(for<'a, DS: DrawSharedImpl> DrawIface<'a, DS> where DS::Draw: DrawRoundedImpl)]
pub trait DrawRounded: Draw {
/// Draw a line with rounded ends and uniform colour
///
Expand All @@ -21,7 +22,9 @@ pub trait DrawRounded: Draw {
///
/// Note that for rectangular, axis-aligned lines, [`DrawImpl::rect`] should be
/// preferred.
fn rounded_line(&mut self, p1: Vec2, p2: Vec2, radius: f32, col: Rgba);
fn rounded_line(&mut self, p1: Vec2, p2: Vec2, radius: f32, col: Rgba) {
self.draw.rounded_line(self.pass, p1, p2, radius, col);
}

/// Draw a circle or oval of uniform colour
///
Expand All @@ -30,7 +33,9 @@ pub trait DrawRounded: Draw {
/// The `inner_radius` parameter gives the inner radius relative to the
/// outer radius: a value of `0.0` will result in the whole shape being
/// painted, while `1.0` will result in a zero-width line on the outer edge.
fn circle(&mut self, rect: Quad, inner_radius: f32, col: Rgba);
fn circle(&mut self, rect: Quad, inner_radius: f32, col: Rgba) {
self.draw.circle(self.pass, rect, inner_radius, col);
}

/// Draw a circle or oval with two colours
///
Expand All @@ -41,7 +46,9 @@ pub trait DrawRounded: Draw {
///
/// Note: this is drawn *before* other drawables, allowing it to be used
/// for shadows without masking.
fn circle_2col(&mut self, rect: Quad, col1: Rgba, col2: Rgba);
fn circle_2col(&mut self, rect: Quad, col1: Rgba, col2: Rgba) {
self.draw.circle_2col(self.pass, rect, col1, col2);
}

/// Draw a frame with rounded corners and uniform colour
///
Expand All @@ -54,7 +61,10 @@ pub trait DrawRounded: Draw {
/// painted, while `1.0` will result in a zero-width line on the outer edge.
/// When `inner_radius > 0`, the frame will be visually thinner than the
/// allocated area.
fn rounded_frame(&mut self, outer: Quad, inner: Quad, inner_radius: f32, col: Rgba);
fn rounded_frame(&mut self, outer: Quad, inner: Quad, inner_radius: f32, col: Rgba) {
self.draw
.rounded_frame(self.pass, outer, inner, inner_radius, col);
}

/// Draw a frame with rounded corners with two colours
///
Expand All @@ -63,31 +73,6 @@ pub trait DrawRounded: Draw {
///
/// Note: this is drawn *before* other drawables, allowing it to be used
/// for shadows without masking.
fn rounded_frame_2col(&mut self, outer: Quad, inner: Quad, c1: Rgba, c2: Rgba);
}

impl<'a, DS: DrawSharedImpl> DrawRounded for DrawIface<'a, DS>
where
DS::Draw: DrawRoundedImpl,
{
#[inline]
fn rounded_line(&mut self, p1: Vec2, p2: Vec2, radius: f32, col: Rgba) {
self.draw.rounded_line(self.pass, p1, p2, radius, col);
}
#[inline]
fn circle(&mut self, rect: Quad, inner_radius: f32, col: Rgba) {
self.draw.circle(self.pass, rect, inner_radius, col);
}
#[inline]
fn circle_2col(&mut self, rect: Quad, col1: Rgba, col2: Rgba) {
self.draw.circle_2col(self.pass, rect, col1, col2);
}
#[inline]
fn rounded_frame(&mut self, outer: Quad, inner: Quad, inner_radius: f32, col: Rgba) {
self.draw
.rounded_frame(self.pass, outer, inner, inner_radius, col);
}
#[inline]
fn rounded_frame_2col(&mut self, outer: Quad, inner: Quad, c1: Rgba, c2: Rgba) {
self.draw
.rounded_frame_2col(self.pass, outer, inner, c1, c2);
Expand Down
Loading