Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat query writer #601

Merged
merged 2 commits into from
Jun 14, 2024
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ Please only add new entries below the [Unreleased](#unreleased---releasedate) he

## [@Unreleased] - @ReleaseDate

### Features

- **core**: Added support to query a `WriteRef` from a state, enabling users to modify the state after attaching it to a widget. (#601 @M-Adoo)

### Changed

- **core**: Render widgets no longer need to implement the `Query` trait. Data can only be queried if it's a state or wrapped with `Queryable`. (#601 @M-Adoo)

## [0.4.0-alpha.1](https://github.com/RibirX/Ribir/compare/ribir-v0.3.0-beta.2...ribir-v0.4.0-alpha.1) - 2024-06-12

### Changed
Expand Down
4 changes: 2 additions & 2 deletions core/src/builtin_widgets/align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ pub enum VAlign {
}

/// A widget that align its child in x-axis, base on child's width.
#[derive(Query, SingleChild, Default)]
#[derive(SingleChild, Default)]
pub struct HAlignWidget {
pub h_align: HAlign,
}

/// A widget that align its child in y-axis, base on child's height.
#[derive(Query, SingleChild, Default)]
#[derive(SingleChild, Default)]
pub struct VAlignWidget {
pub v_align: VAlign,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl Anchor {
}

/// Widget use to anchor child constraints relative to parent widget.
#[derive(Query, SingleChild, Default)]
#[derive(SingleChild, Default)]
pub struct RelativeAnchor {
pub anchor: Anchor,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/box_decoration.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::prelude::*;

/// The BoxDecoration provides a variety of ways to draw a box.
#[derive(SingleChild, Default, Clone, Query)]
#[derive(SingleChild, Default, Clone)]
pub struct BoxDecoration {
/// The background of the box.
pub background: Option<Brush>,
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub enum ClipType {
Path(Path),
}

#[derive(SingleChild, Query, Clone, Declare)]
#[derive(SingleChild, Clone, Declare)]
pub struct Clip {
#[declare(default)]
pub clip: ClipType,
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/container.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::prelude::*;

/// Widget with fixed size as a container for its child.
#[derive(Declare, Query, SingleChild)]
#[derive(Declare, SingleChild)]
pub struct Container {
pub size: Size,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/fitted_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub enum BoxFit {
}

/// Widget set how its child should be scale to fit its box.
#[derive(Query, SingleChild, Default)]
#[derive(SingleChild, Default)]
pub struct FittedBox {
pub box_fit: BoxFit,
scale_cache: Cell<Transform>,
Expand Down
8 changes: 3 additions & 5 deletions core/src/builtin_widgets/focus_node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{events::focus_mgr::FocusHandle, prelude::*};

#[derive(Query, Default)]
#[derive(Default)]
pub struct RequestFocus {
handle: Option<FocusHandle>,
}
Expand All @@ -22,7 +22,7 @@ impl ComposeChild for RequestFocus {
}
}
.build(ctx!())
.attach_state_data(this, ctx!())
.try_unwrap_state_and_attach(this, ctx!())
}
}
}
Expand Down Expand Up @@ -69,13 +69,11 @@ mod tests {
let id = tree.content_root();
let node = id.get(&tree.arena).unwrap();
let mut cnt = 0;
node.query_type_inside_first(|b: &MixBuiltin| {
node.query_all_iter::<MixBuiltin>().for_each(|b| {
if b.contain_flag(BuiltinFlags::Focus) {
cnt += 1;
}
true
});

assert_eq!(cnt, 1);
}
}
4 changes: 2 additions & 2 deletions core/src/builtin_widgets/focus_scope.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{events::focus_mgr::FocusType, prelude::*};

#[derive(Declare, Query, Clone, Default)]
#[derive(Declare, Clone, Default)]
pub struct FocusScope {
/// If true, the descendants can not be focused.
/// Default value is false, then the hold FocusScope subtree can be focused
Expand All @@ -23,7 +23,7 @@ impl ComposeChild for FocusScope {
on_disposed: move|e| e.window().remove_focus_node(e.id, FocusType::Scope),
}
.build(ctx!())
.attach_state_data(this, ctx!())
.try_unwrap_state_and_attach(this, ctx!())
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/global_anchor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::rc::Rc;

use crate::{prelude::*, ticker::FrameMsg};

#[derive(Query, Default)]
#[derive(Default)]
pub struct GlobalAnchor {
pub global_anchor: Anchor,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/ignore_pointer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::prelude::*;

#[derive(Declare, SingleChild, Query, Clone)]
#[derive(Declare, SingleChild, Clone)]
pub struct IgnorePointer {
#[declare(default = true)]
pub ignore: bool,
Expand Down
4 changes: 0 additions & 4 deletions core/src/builtin_widgets/image_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,3 @@ impl Render for Resource<PixelImage> {
}
}
}

impl Query for Resource<PixelImage> {
crate::widget::impl_query_self_only!();
}
4 changes: 2 additions & 2 deletions core/src/builtin_widgets/keep_alive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::prelude::*;
/// dropped.
///
/// It's useful when you need run a leave animation for a widget.
#[derive(Query, Default)]
#[derive(Default)]
pub struct KeepAlive {
pub keep_alive: bool,
}
Expand All @@ -29,7 +29,7 @@ impl ComposeChild for KeepAlive {
fn compose_child(this: impl StateWriter<Value = Self>, child: Self::Child) -> impl WidgetBuilder {
fn_widget! {
let modifies = this.raw_modifies();
child.attach_state_data(this, ctx!()).dirty_subscribe(modifies, ctx!())
child.try_unwrap_state_and_attach(this, ctx!()).dirty_subscribe(modifies, ctx!())
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions core/src/builtin_widgets/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{
fmt::Debug,
};

use crate::prelude::*;
use crate::{data_widget::Queryable, prelude::*};

/// `Key` help `Ribir` to track if two widget is a same widget in two frames.
/// Abstract all builtin key into a same type.
Expand Down Expand Up @@ -127,15 +127,11 @@ impl<V: 'static + Default + Clone + PartialEq> ComposeChild for KeyWidget<V> {
fn compose_child(this: impl StateWriter<Value = Self>, child: Self::Child) -> impl WidgetBuilder {
fn_widget! {
let data: Box<dyn AnyKey> = Box::new(this);
child.attach_data(data, ctx!()).build(ctx!())
child.attach_data(Queryable(data), ctx!()).build(ctx!())
}
}
}

impl Query for Box<dyn AnyKey> {
crate::widget::impl_query_self_only!();
}

impl<V> KeyWidget<V>
where
V: Clone + PartialEq,
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/margin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub struct EdgeInsets {
}

/// A widget that create space around its child.
#[derive(SingleChild, Default, Query, Clone, PartialEq)]
#[derive(SingleChild, Default, Clone, PartialEq)]
pub struct Margin {
pub margin: EdgeInsets,
}
Expand Down
31 changes: 17 additions & 14 deletions core/src/builtin_widgets/mix_builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{cell::Cell, convert::Infallible};
use rxrust::prelude::*;

use self::focus_mgr::FocusType;
use crate::prelude::*;
use crate::{data_widget::Queryable, prelude::*};

const MULTI_TAP_DURATION: Duration = Duration::from_millis(250);

Expand Down Expand Up @@ -41,7 +41,7 @@ bitflags! {

pub type EventSubject = MutRefItemSubject<'static, Event, Infallible>;

#[derive(Default, Query)]
#[derive(Default)]
pub struct MixBuiltin {
flags: Cell<BuiltinFlags>,
subject: EventSubject,
Expand Down Expand Up @@ -349,28 +349,31 @@ fn life_fn_once_to_fn_mut(
impl ComposeChild for MixBuiltin {
type Child = Widget;
#[inline]
fn compose_child(this: impl StateWriter<Value = Self>, child: Self::Child) -> impl WidgetBuilder {
fn compose_child(
this: impl StateWriter<Value = Self>, mut child: Self::Child,
) -> impl WidgetBuilder {
move |ctx: &BuildCtx| match this.try_into_value() {
Ok(this) => {
let mut this = Some(this);
child
if let Some(m) = child
.id()
.assert_get(&ctx.tree.borrow().arena)
.query_most_outside(|m: &MixBuiltin| {
let this = this.take().unwrap();
if !m.contain_flag(BuiltinFlags::Focus) && this.contain_flag(BuiltinFlags::Focus) {
this.callbacks_for_focus_node();
}
m.merge(this)
});
.query_ref::<MixBuiltin>()
{
let this = unsafe { this.take().unwrap_unchecked() };
if !m.contain_flag(BuiltinFlags::Focus) && this.contain_flag(BuiltinFlags::Focus) {
this.callbacks_for_focus_node();
}
m.merge(this);
}
// We do not use an else branch here, due to the borrow conflict of the `ctx`.
if let Some(this) = this {
if this.contain_flag(BuiltinFlags::Focus) {
this.callbacks_for_focus_node();
}
child.attach_data(this, ctx)
} else {
child
child = child.attach_data(Queryable(this), ctx);
}
child
}
Err(this) => {
if this.read().contain_flag(BuiltinFlags::Focus) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/opacity.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::prelude::*;

#[derive(Query, Clone, SingleChild)]
#[derive(Clone, SingleChild)]
pub struct Opacity {
pub opacity: f32,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/padding.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::prelude::*;

/// A widget that insets its child by the given padding.
#[derive(SingleChild, Query, Clone, Default)]
#[derive(SingleChild, Clone, Default)]
pub struct Padding {
pub padding: EdgeInsets,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/scrollable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ mod tests {
test_assert(Scrollable::Both, 100., 100., 0., 0.);
}

#[derive(SingleChild, Query, Declare, Clone)]
#[derive(SingleChild, Declare, Clone)]
pub struct FixedBox {
pub size: Size,
}
Expand Down
4 changes: 0 additions & 4 deletions core/src/builtin_widgets/svg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,3 @@ impl Render for Svg {
painter.draw_svg(self);
}
}

impl Query for Svg {
crate::widget::impl_query_self_only!();
}
5 changes: 2 additions & 3 deletions core/src/builtin_widgets/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ribir_algo::Sc;
pub use ribir_algo::{CowArc, Resource};
use ribir_macros::Declare;

use crate::{fill_svgs, prelude::*};
use crate::{data_widget::Queryable, fill_svgs, prelude::*};

mod palette;
pub use palette::*;
Expand Down Expand Up @@ -61,7 +61,6 @@ pub struct InheritTheme {
pub font_files: Option<Vec<String>>,
}

#[derive(Query)]
pub enum Theme {
Full(FullTheme),
Inherit(InheritTheme),
Expand Down Expand Up @@ -92,7 +91,7 @@ impl ComposeChild for ThemeWidget {
// node, because the subtree may be hold its id.
//
// A `Void` is cheap for a theme.
let p = Void.build(ctx!()).attach_data(theme, ctx!());
let p = Void.build(ctx!()).attach_data(Queryable(theme), ctx!());
// shadow the context with the theme.
let ctx = BuildCtx::new_with_data(Some(p.id()), ctx!().tree, themes);
let child = child.gen_widget(&ctx);
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/transform_widget.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::prelude::*;

#[derive(SingleChild, Query, Clone, Default)]
#[derive(SingleChild, Clone, Default)]
pub struct TransformWidget {
pub transform: Transform,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/unconstrained_box.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::prelude::*;

#[derive(Declare, Query, SingleChild)]
#[derive(Declare, SingleChild)]
/// A widget that imposes no constraints on its child, allowing it to layout and
/// display as its "natural" size. Its size is equal to its child then clamp by
/// parent.
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl ComposeChild for Visibility {
}
}

#[derive(SingleChild, Query, Declare, Clone)]
#[derive(SingleChild, Declare, Clone)]
struct VisibilityRender {
display: bool,
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/builtin_widgets/void.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::prelude::*;
/// node in `widget!` macro, or hold a place in tree. When it have a child
/// itself will be dropped when build tree, otherwise as a render widget but do
/// nothing.
#[derive(SingleChild, Query, Declare)]
#[derive(SingleChild, Declare)]
pub struct Void;

impl Render for Void {
Expand Down
17 changes: 10 additions & 7 deletions core/src/context/build_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{
};

use ribir_algo::Sc;
use widget_id::RenderQueryable;

use crate::{
prelude::*,
Expand Down Expand Up @@ -73,11 +74,11 @@ impl<'a> BuildCtx<'a> {
}

/// Get the widget back of `id`, panic if not exist.
pub(crate) fn assert_get(&self, id: WidgetId) -> Ref<dyn Render> {
pub(crate) fn assert_get(&self, id: WidgetId) -> Ref<dyn RenderQueryable> {
Ref::map(self.tree.borrow(), |tree| id.assert_get(&tree.arena))
}

pub(crate) fn alloc_widget(&self, widget: Box<dyn Render>) -> WidgetId {
pub(crate) fn alloc_widget(&self, widget: Box<dyn RenderQueryable>) -> WidgetId {
new_node(&mut self.tree.borrow_mut().arena, widget)
}

Expand Down Expand Up @@ -122,11 +123,13 @@ impl<'a> BuildCtx<'a> {

let arena = &self.tree.borrow().arena;
p.ancestors(arena).any(|p| {
p.assert_get(arena)
.query_type_inside_first(|t: &Sc<Theme>| {
themes.push(t.clone());
matches!(t.deref(), Theme::Inherit(_))
});
for t in p.assert_get(arena).query_all_iter::<Sc<Theme>>() {
themes.push(t.clone());
if matches!(&**t, Theme::Full(_)) {
break;
}
}

matches!(themes.last().map(Sc::deref), Some(Theme::Full(_)))
});
themes
Expand Down
Loading
Loading