-
Notifications
You must be signed in to change notification settings - Fork 154
xilem_masonry
: Create a generic View
trait, and use it to complete the Flex
view
#235
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
Conversation
Marking as draft because the distribution of "responsibilities" between the traits isn't very clear. I still think this pattern is viable, but the implementation is really messy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but that comes at the cost of some how understandable it is.
Yep, took me some time to dive through this...
Pretty clever stuff, neat trick to do this with the SequenceCompatible
trait.
What I think though, is that we should document this thoroughly (at some time, not necessarily in this PR), to avoid scaring off new Contributors with that added complexity. But what I like, is that the added complexity is mostly internal at the core, so I don't think it's necessary to have a deep understanding of all of this to just add simple stuff (widgets etc.), unless a completely new ViewSequence<SpliceElement>
context is necessary (like FlexElement
).
I guess we need the differentiation between the traits MasonryView
and View
because of FlexElement
?
(I can see some use cases with having a "generic" View
though anyway, maybe we somehow are able to marry/merge xilem_web with xilem_masonry with that at some point?)
One thing I'm wondering is, how much compilation time this adds (for reasonbly large view logic functions), because of added associated trait bounds (which seem to be the main culprit for added compilation time).
(Btw. related, but I prefer this, i.e. strong-typed at the expense of complexity as long as it only stays (mostly) inside of xilems implementation over dynamic typing.)
I'm cautiously approving this, but I think it's a good idea to discuss this tomorrow before merging.
}; | ||
let new_child = new_flex_child(params.into(), widget); | ||
*child = new_child; | ||
// TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these TODO
comments, a result of copy paste, or is there really something todo? (and what?)
Btw. I think the two lines below this, could be summed up with
self.ctx.children_changed();
couldn't it?
} | ||
|
||
impl<'a, W: Widget + StoreInWidgetMut> WidgetMut<'a, W> { | ||
pub(crate) fn new(parent_widget_state: &'a mut WidgetState, inner: W::Mut<'a>) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all of this unsafe code is only "safe" because it's only possible to construct this type within masonry isn't it?
Not super comfortable with this, because it's... well unsafe as well as (slightly) complex (not the best combination). Not sure whether all of that could be achieved with just some reference counting.
|
||
pub trait ViewElement { | ||
type Mut<'a>; | ||
type Erased: ViewElement; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to at least add some basic documentation to this trait. E.g. that this is type-erased and not necessarily a deleted element.
) -> R; | ||
} | ||
|
||
impl<SourceElement: ViewElement, SequenceElement: ViewElement> SequenceCompatible<SourceElement> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe put all the bounds into the where
clause (for ease of understanding this)? Or is this intended?
} | ||
} | ||
|
||
pub struct TrivialWrapper<T>(T); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any use of this, is this a remnant from previous experiments?
@@ -113,11 +176,16 @@ pub struct OptionSeqState<InnerState> { | |||
} | |||
|
|||
// TODO(DJMcNab): Add the generation to the id path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this PR, but I don't think that comment is necessary anymore?
use crate::{ | ||
sequence::SequenceCompatible, ChangeFlags, ElementSplice, MasonryView, VecSplice, View, | ||
ViewElement, ViewSequence, | ||
}; | ||
|
||
// TODO: Allow configuring flex properties. I think this actually needs its own view trait? | ||
pub fn flex<VT, Marker>(sequence: VT) -> Flex<VT, Marker> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(not directly related to that PR)
I'm not sure whether we actually should add the type bounds here (generally for these "component" functions).
I think for one it helps a little bit with error messages, and since I think it should only be used inside a View
context, it also shows, what is actually allowed here as sequence. (But well, unfortunately it adds a lot of generic parameters obviously)
@@ -16,6 +19,13 @@ pub fn flex<VT, Marker>(sequence: VT) -> Flex<VT, Marker> { | |||
} | |||
} | |||
|
|||
pub fn flex_item<V>(view: V, params: impl Into<FlexParams>) -> FlexWrapper<V> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More of a UX thing and not entirely relevant to that PR, we could also achieve this via an extension trait. So that this is possible via the builder pattern (maybe also within MasonryView
, to avoid extra traits? (see also e.g. here))
This track of work is continuing in #310 |
…#310) This: 1) Renames the current/old `xilem_core` to `xilem_web_core` and moves it to the `xilem_web/xilem_web_core` folder 2) Creates a new `xilem_core`, which does not use (non-tuple) macros and instead contains a `View` trait which is generic over the `Context` type 3) Ports `xilem` to this `xilem_core`, but with some functionality missing (namely a few of the extra views; I expect these to straightforward to port) 4) Ports the `mason` and `mason_android` examples to this new `xilem`, with less functionality. This continues ideas first explored in #235 The advantages of this new View trait are: 1) Improved support for ad-hoc views, such as views with additional attributes. This will be very useful for layout algorithms, and will also enable native *good* multi-window (and potentially menus?) 2) A lack of macros, to better enable using go-to-definition and other IDE features on the traits Possible disadvantages: 1) There are a few more traits to enable the flexibility 2) It can be less clear what `Self::Element::Mut` is in the `rebuild` function, because of how the resolution works 3) When implementing `View`, you need to specify the context (i.e. `impl<State, Action> View<State, Action, [new] ViewCtx> for Button<State, Action>`. --------- Co-authored-by: Philipp Mildenberger <philipp@mildenberger.me>
…or `Flex` in xilem (#428) Takes ideas from #235 (in particular the masonry side). This implements support for explicit spacers in the `Flex` view and flex parameters for views (see examples `flex` and `mason` for more details). It also adds a way (`AnyFlexChild`) to dynamically switch between spacers and widgets (with optional flex parameters). `masonry::widget::Flex::layout` is also updated to be in sync with current druid. --------- Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
Functionally, this code works, but there's a lot of complexity around the different traits which have been added, which is unfortunate.
That is, the ergonomics are good, but that comes at the cost of some how understandable it is.