Skip to content

Add a "gallery"-type example for Xilem's Label View #864

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

Open
wants to merge 36 commits into
base: main
Choose a base branch
from

Conversation

eugenesvk
Copy link
Contributor

@eugenesvk eugenesvk commented Feb 11, 2025

There are existing issues re. the general state of docs with Xilem
#392
#851

so this PR is a suggestion on covering one area I missed when reading the docs: being able to have

  • a condensed overview of
  • all available options and, more importantly,
  • their visual style
  • in an interactive manner (ideally at runtime, which this PR partially addresses for alignment)

So this is an example of a simple gallery-type app that covers Xilem's Label View (but not Masonry Label Widget) where you can simply vertically scroll to see all the available options and even some notes on interaction issues: e.g., the fact that a label with a Start alignment starts in the middle because its parent vertical flex has a Center alignment by default for its horizontal axis. Now, you could find this explanation deep down in Masonry tests, but that would require a lot of digging around (and Masonry screenshots wouldn't show it).

After identifying an issue this example also shows a suggested fix by using .flex, though if I do the override, I lose the portal's vertical scrolling, which might be a 🐞bug or just a missing understanding on my part of how these portal/flex/.flex elements interact, in which case it would be nice to change to a better example and to have a shorter alignment section that didn't have to note these issues.

Xilem Label View

Now, there are a few missing pieces, but think this might be still be a good initial fix:

As far as I understand mostly blocked by missing functionality support in the framework:

  • add rust code generating each element in a tooltip
  • add the same code in a context menu as a "copy" command
    • is this something the debugging F11/F12 tools could do?
  • add URL support for doc links

But also just not yet implemented:

  • add non-desktop platforms
  • add to a CI build so you can simply download a binary and use it as a reference without having to build everything yourself
    • have both debug/release builds so that you can use F11/F12 inspectors?
      • is a release build useful for basic examples?

(these are also added in the Todos comment section in the example itself)

@DJMcNab
Copy link
Member

DJMcNab commented Feb 11, 2025

My initial feedback here is that Label is that we shouldn't be encouraging developers to reach for label in most cases.
The label is designed solely to be used as a child of other non-interactive widgets (such as the extant button and checkbox). This is because it doesn't allow the user to select within the text, and therefore doesn't allow copy-and-paste from the text, which makes it annoying. Note that this isn't a position that I've carefully reasoned about (e.g., what about on Android where the idiomatic way to select such (short) text is to use the OCR built-in to the app selector).

I also want to check (as a self-calibration exercise only), was this code LLM assisted?

@eugenesvk
Copy link
Contributor Author

eugenesvk commented Feb 11, 2025

The galleries aren't meant to encourage anything, they're purely documenting what's available. Similar to the regular docs, but in a better format so that you don't have to click on an argument, then an enum, then read its variants and still have a vague idea as to how it would look in practice.

Feel free to add a disclaimer at the top guiding to better options and pointing out the limitations!

such as the extant button

That's actually precisely the use case that led me to create this example as a reference for myself when trying to learn about how to add labels to a button! It's just that the button in this case is more complex than typical one and has several labels so that, for example, you could have these great self-documenting buttons that show their shortcuts

button9

(no LLM involved. Have you tried it yourself, does any LLM give good info on Xilem/Masonry? Would it be able to uncover and explain the label|flex alignment interaction?)

@DJMcNab
Copy link
Member

DJMcNab commented Feb 11, 2025

That makes sense to me. I think there's something in the naming of label which needs to change, probably. I would agree that we should probably have a paragraph at the start of this, explaining why Label exists and how to use it (which should be copied into Label's docs).

That does look pretty cool. Is that saying that the confirm action happens if you press enter or alt-k?

I'm not sure about the flex issue. I know that our layout story is still... in flux at the moment.

I don't know when I'll find time to review this.

(no LLM involved. Have you tried it yourself, does any LLM give good info on Xilem/Masonry?)

No, I've not tried it myself. I'd hope that they don't, to be honest, because we're still at a stage of refining our APIs.
The reason I asked that is because of the weird formatting of the Rust code, which struck me as sufficiently unusual that I had alarm bells going off.

The formatting definitely needs to be changed to follow the Rust style guide. The reason that this isn't happening is the eternally vexing rustfmt issue, rust-lang/rustfmt#3863. We have a few workarounds in the past, e.g. linebender/vello#499

@eugenesvk
Copy link
Contributor Author

eugenesvk commented Feb 11, 2025

Is that saying that the confirm action happens if you press enter or alt-k?

Yes, though just K, this is just an experimental replacement for the "&Accelerators", which are bad because of their inconsistent position, requiring users to scan, and poor highlight (especially consider a tiny underscore for a thin letter i̲ - try to find it vs the first O̲
i_under
)

weird formatting of the Rust code

Which LLMs have you seen that are able to do this? That would be at least something of use from them...

I find the default "fmt"'s style an unaligned mess, and don't use it myself, so this is a result of whatever the cargo tool managed to do...
(Due to the very high verbosity of Xilem's code and 4 spaces this has the downside of being too wide, but then a simple dynamic word-wrap editor shortuct can easily bring all the zigzags back!)

Like what's the point of this zigzaggy mess where you can't easily compare the grid position coordinates

flex((
  lc("1/4").alignment(TextAlignment::Start).grid_pos(0, 0),
  lc("2/4").alignment(TextAlignment::Middle).gird_pos(0, 1),
  lc("3/4").alignment(TextAlignment::End).grid_pos(0, 2),
  lc("4/4").alignment(TextAlignment::Justified).grid_pos(0, 3),
))

when tables have been invented a long time ago, so you could have a proper tabular alignment, allowing you to skip identical syntax like () and also identical words, focusing only on the difference, which would be 0,1,2,3

flex((
  lc("1/4").alignment(TextAlignment::Start    ).grid_pos(0,0),
  lc("2/4").alignment(TextAlignment::Middle   ).gird_pos(0,1),
  lc("3/4").alignment(TextAlignment::End      ).grid_pos(0,2),
  lc("4/4").alignment(TextAlignment::Justified).grid_pos(0,3),
))

Though at any rate, the CI should just commit the formatting changes on PRs, that's what robots do well, no need to involve people manually running commands that fit this project's style

Copy link
Member

@DJMcNab DJMcNab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be nice to get something like this in. It's great to see an exploration of the full range of options here.

This is still blocked on the formatting. I think the 2024 style edition might have resolved this not being formatted, but I've not checked it.

Comment on lines +47 to +119
fn lc(text: impl Into<ArcStr>) -> Label {
//colored label
label(text).brush(LABEL_COLOR)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name lc here is actually really interesting.
The "tailwind" style of micro components, requires that you name the components. Which has
Because lc is to me clearly not a good name, but I don't know what a good name for this would be; the component is so minimal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the minimal name here is so that all the props fit in a single screen width, which with the waste of 4 spaces per indent level and 3 indents in some cases is a challenge

So the only important part in
lc("4/4 alignment Justified" ).alignment(TextAlignment::Justified ).grid_pos(0,3), is alignment/grid info, so whether it's l or lc doesn't really matter, but it fits in 100 chars

.brush(l_c) //impl Into<peniko:Brush> brush sets text color, but gradients and images are also supported Solid(color::AlphaColor<Srgb>) Gradient(Gradient) Image(Image),
.line_break_mode(LineBreaking::Overflow) //WordWrap Clip Overflow
,
title_prose(format!("§{i} .alignment")),{i+=1;},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should break this out into multiple expressions, if we're incrementing the counter inside the expression.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't understand this, meanwhile just changed the order so that unused_assignments allowance isn't needed anymore

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well like i+=1 is not a meaningful view; it only happens to work here because it has type (), which is the empty tuples, and nested tuples are allowed. We shouldn't have assignment expressions inside view writing code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the proposed change to fix it without having to manually track index increments.
The narrow issue of empty tuples could be fixed via {i+=1;title_prose(format!("§ {i} .alignment"))} which results in a single valid view result

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah - when I said expressions above, I meant "statements". Sorry for the confusion

@eugenesvk
Copy link
Contributor Author

eugenesvk commented Apr 18, 2025

I don't get it, but locally on Windows cargo fmt --all reverts the changes suggested by the failing CI's fmt. Must've been due to the edition changes

Copy link
Member

@DJMcNab DJMcNab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still blocked on applying the Rust style guide.

I know that rustfmt breaks with big expressions; that is another reason to suggest breaking it up into multiple expressions (perhaps a component per section)?

Comment on lines 204 to 209
button("Δ1/6", |da:&mut AppState|{da.realign("l1i1");}),
button("Δ2/6", |da:&mut AppState|{da.realign("l1i2");}),
button("Δ3/6", |da:&mut AppState|{da.realign("l1i3");}),
button("Δ4/6", |da:&mut AppState|{da.realign("l1i4");}),
button("Δ5/6", |da:&mut AppState|{da.realign("l1i5");}),
button("Δ6/6", |da:&mut AppState|{da.realign("l1i6");}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not all that clear what these buttons are useful for?

Even so, with having them, I think they could probably also be changed into an enumarted loop over a sub-array of the state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For playing with various styling in real time. While currently for some styles all the variants are already included, so buttons are of limited use when you want to see e.g. the whole "table" of labels aligned the same way, that's not true for all styles - Cross-alignment doesn't list all the combos. Neither would font families (though those don't have dynamic buttons/pickers at the moment) and colors/sizes

@eugenesvk eugenesvk force-pushed the fr-example-layout branch from 310e02a to 3bb8789 Compare May 12, 2025 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants