-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Superfluous alignment functions #286
Comments
Yes, I believe these methods need to be redesigned and unified somehow. Some thoughts:
Overall, I think layouting needs some rethinking in general. |
I'd like to consider separating alignment from any of the visual widgets, and relegating it to the layout widgets only. This would mean I think this shouldn't be too hard with On the other hand, I'm not sure how |
You can look at the flutter. pub struct Alignment(pub f32, pub f32); // (x, y)
impl Alignment {
const TOP_LEFT: Self = Self(-1.0, -1.0);
const TOP_CENTER: Self = Self(-1.0, 0.0);
const TOP_RIGHT: Self = Self(-1.0, 1.0);
const CENTER_LEFT: Self = Self(0.0, -1.0);
const CENTER: Self = Self(0.0, 0.0);
const CENTER_RIGHT: Self = Self(0.0, 1.0);
const BOTTOM_LEFT: Self = Self(1.0, -1.0);
const BOTTOM_CENTER: Self = Self(1.0, 0.0);
const BOTTOM_RIGHT: Self = Self(1.0, 1.0);
// ....
}
// Possible usage:
let element = Container::new(inner).align(Alignment::CENTER_LEFT);
let element = Container::align(Alignment::CENTER_LEFT, inner);
// You can add a special widget for alignment only:
let element = Align::new(Alignment::CENTER_LEFT, inner); |
I like the idea of just using Flutter has some good insights, some bloody confusing stuff as well though. |
Here are some notes I have gathered about alignment from daily use: I understand the convenience of However, this means for me, that the I am also looking for cleanest way to approach alignment, so here are some (expected) examples to look at: Using This is hard to understand. container(column()
.align_x(Align::Start)
.align_y(Align::End)
.push(text("Making the example a bit busier..."))
.push(horizontal_rule(1))
) Using This is much more readable than the first example. container(column()
.align_x(Align::Left)
.align_y(Align::Bottom)
.push(text("Making the example a bit busier..."))
.push(horizontal_rule(1))
) Using custom methods for each alignment container(column()
.left()
.middle()
.push(text("Making the example a bit busier..."))
.push(horizontal_rule(1))
) left()
center()
right()
top()
middle() // the best I can think of
bottom() Some other potential APIs: left_x(), center_x(), right_x()
top_y(), center_y(), bottom_y()
// I actually prefer this to using `left` and `right`
start_x(), center_x(), end_x()
start_y(), center_y(), end_y() If I had a preference, I would actually stop using I am sharing this because I originally thought having distinct methods for So I wound up agreeing with @krooq. I do think aligning horizontal and vertical in the same method as described by @lain-dono is unnecessary as I find most things don't require a specified alignment at all. |
@asvln align_size_within_range(size, range, -1.0) // align start (left or top)
align_size_within_range(size, range, 0.0) // align center
align_size_within_range(size, range, -1.0) // align end (right or bottom)
fn align_size_within_range(size: f32, range: Range<f32>, align: f32) -> Range<f32> {
let half_delta = (range.end - range.start - size) * 0.5;
let start = range.start + align.mul_add(half_delta, half_delta);
start..start + size
}
/// Find the position that corresponds to the alignment
fn align(range: Range<f32>, align: f32) -> f32 {
let half = (range.end - range.start) * 0.5;
range.start + align.mul_add(half, half)
} Note: f32::mul_add is just With this math you can get an api like this: struct Align(f32);
impl From<f32> for Align {
fn from(align: f32) -> Self {
Self(align)
}
}
impl Align {
const START: Self = Self(-1.0);
const END: Self = Self(1.0);
// ...
}
type HorizontalAlign = Align;
impl HorizontalAlign { // Yes, it's legal. And it also gives you convenient documentation.
const LEFT: Self = Self(-1.0);
const RIGHT: Self = Self(1.0);
// ...
}
type VerticalAlign = Align; // Personally, I think AlignY is the best name. But who cares.
impl VerticalAlign {
const TOP: Self = Self(-1.0);
const BOTTOM: Self = Self(1.0);
// ...
}
fn align(self, x: impl Into<Align>, y: impl Into<Align>);
fn align_x(self, x: impl Into<Align>);
fn align_y(self, y: impl Into<Align>);
// All options below work simultaneously
container(column()
.align(0.0, 0.0)
.push(text("Making the example a bit busier..."))
.push(horizontal_rule(1))
)
container(column()
.align_x(Align::START)
.align_y(Align::END)
.push(text("Making the example a bit busier..."))
.push(horizontal_rule(1))
)
container(column()
.align_x(HorizontalAlign::LEFT)
.align_y(VerticalAlign::BOTTOM)
.push(text("Making the example a bit busier..."))
.push(horizontal_rule(1))
)
container(column()
.align(Align::LEFT, Align::BOTTOM)
.push(text("Making the example a bit busier..."))
.push(horizontal_rule(1))
) Keep in mind, if you want to support bi-direction, you should use start/end instead of left/right. |
The current api exposes multiple ways for alignment to be expressed:
Container::center_x
is equivalent toContainer::align_x(Center)
HorizonalAlignment
,VerticalAlignement
, andAlign
all express the same concept.These introduce more names and relationships for users to learn about in the api, and I think reducing them would be positive. could we remove them?
The text was updated successfully, but these errors were encountered: