launcher: fix account skin arm-type segmented control overflow and caption layout

In the glass theme account settings (skin_panel), long translated option
labels such as French 'Bras classiques' protruded outside the segmented
control pill due to an inherited ml(40px) margin and cross-axis stretching.
Additionally, the multi-sentence caption wrapped into a 10-line block inside
the narrow column, clipping off the bottom on 1080p displays.

- Remove the ml(40px) margin in glass theme mode.
- Set items_start() on the control column so segments size to natural width.
- Adjust segments option padding to 12px with flex_none and justify_center.
- Reorganize skin_panel so the caption spans full width across the bottom.
- Adjust Microsoft card width to 360px and reduce vertical padding in glass_who_plays.

Co-Authored-By: Antigravity <[email protected]>
This commit is contained in:
AxxioandAntigravity committed 2026-11-06 00:10:36 +01:00
1 parent 3c7bb44aa1
commit 576c5942f1
3 files changed
+60 -38

No files matched your search

+5 -5
View File
@@ -20,8 +20,8 @@ impl Launcher {
div()
.flex()
.gap(px(8.))
.child(left.flex_1().min_w_0().p(px(24.)))
.child(right.flex_none().w(px(400.)))
.child(left.flex_1().min_w_0().p(px(20.)))
.child(right.flex_none().w(px(360.)))
}
/// The player now, the offline names and the field to add one.
@@ -178,20 +178,20 @@ impl Launcher {
.child(header)
.child(
ui::text(13., FontWeight::MEDIUM, 0.6)
.mt(px(32.))
.mt(px(20.))
.child(tr("Offline names")),
)
.child(chips)
.child(
ui::text(13., FontWeight::NORMAL, 0.5)
.mt(px(12.))
.mt(px(10.))
.line_height(px(19.5))
.child(tr(
"3 to 16 letters, numbers or underscores. Switch names from the top bar \
too. Online servers don't take offline names.",
)),
)
.children(self.skin_panel(cx).map(|p| p.mt(px(16.))))
.children(self.skin_panel(cx).map(|p| p.mt(px(12.))))
}
/// An offline name's chip: its head and name, a tick on the one playing; white at 14 % for
+3 -1
View File
@@ -937,9 +937,11 @@ pub fn segments<T: Copy + PartialEq + 'static>(
let d = div()
.id(SharedString::from(format!("{id}-{label}")))
.flex()
.flex_none()
.items_center()
.justify_center()
.h(px(32.))
.px(px(14.))
.px(px(12.))
.rounded(px(radius::CONTROL))
.cursor_pointer()
.font_family(horizon_theme::glass::FONT)
+52 -32
View File
@@ -144,6 +144,7 @@ impl Launcher {
let frame = |w: f32, h: f32, image: Preview, empty: &'static str| {
div()
.flex()
.flex_none()
.items_center()
.justify_center()
.w(px(w + 24.))
@@ -191,19 +192,21 @@ impl Launcher {
},
))
};
let mut skin_buttons =
div()
.flex()
.gap(px(6.))
.child(pick("skin-choose", "Choose a skin…", false, cx));
let mut skin_buttons = div().flex().flex_wrap().gap(px(6.)).child(pick(
"skin-choose",
"Choose a skin…",
false,
cx,
));
if look.skin {
skin_buttons = skin_buttons.child(drop("skin-remove", "Default skin", false, cx));
}
let mut cape_buttons =
div()
.flex()
.gap(px(6.))
.child(pick("cape-choose", "Choose a cape…", true, cx));
let mut cape_buttons = div().flex().flex_wrap().gap(px(6.)).child(pick(
"cape-choose",
"Choose a cape…",
true,
cx,
));
if look.cape {
cape_buttons = cape_buttons.child(drop("cape-remove", "No cape", true, cx));
}
@@ -211,33 +214,50 @@ impl Launcher {
Some(
plate(&t)
.flex()
.gap(px(20.))
.flex_col()
.gap(px(12.))
.px(px(16.))
.py(px(14.))
.ml(px(40.))
.child(frame(16. * TEXEL, 32. * TEXEL, skin, "Default"))
.child(frame(10. * TEXEL, 16. * TEXEL, cape, "No cape"))
.py(px(12.))
.when(!t.glass, |d| d.ml(px(40.)))
.child(
div()
.flex()
.flex_col()
.flex_1()
.min_w_0()
.gap(px(12.))
.child(caps(trf("{name}'s skin", &[("name", &name)])).text_color(t.muted))
.child(skin_buttons)
.child(model)
.child(cape_buttons)
.children(note.map(|n| match n {
Ok(said) => text(theme::CAPTION).text_color(t.muted).child(said),
Err(e) => text(theme::CAPTION).text_color(t.danger).child(e),
}))
.child(text(theme::CAPTION).text_color(t.muted).child(tr(
.gap(px(16.))
.child(frame(16. * TEXEL, 32. * TEXEL, skin, "Default"))
.child(frame(10. * TEXEL, 16. * TEXEL, cape, "No cape"))
.child(
div()
.flex()
.flex_col()
.items_start()
.flex_1()
.min_w_0()
.gap(px(10.))
.child(
caps(trf("{name}'s skin", &[("name", &name)]))
.text_color(t.muted),
)
.child(skin_buttons)
.child(model)
.child(cape_buttons)
.children(note.map(|n| match n {
Ok(said) => {
text(theme::CAPTION).text_color(t.muted).child(said)
}
Err(e) => text(theme::CAPTION).text_color(t.danger).child(e),
})),
),
)
.child(
text(theme::CAPTION)
.text_color(t.muted)
.line_height(px(16.))
.child(tr(
"A 64×64 (or 64×32) skin PNG and a 64×32 cape PNG, kept by the \
launcher and given to the game when this name plays. The game \
draws the default skins for now; it uses these once it can. A \
Microsoft account's skin and cape: coming soon.",
))),
launcher and given to the game when this name plays. The game \
draws the default skins for now; it uses these once it can. A \
Microsoft account's skin and cape: coming soon.",
)),
),
)
}