Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06e97b9f50 | ||
|
|
601ec92181 | ||
|
|
713526b2a8 | ||
|
|
450121b591 | ||
|
|
eab9357f23 | ||
|
|
57f21a0edf |
+33
-1
@@ -2432,6 +2432,35 @@ fn view(state: &AppState) -> Element<'_, AppMessage> {
|
|||||||
.spacing(10)
|
.spacing(10)
|
||||||
.width(iced::Length::Fill);
|
.width(iced::Length::Fill);
|
||||||
|
|
||||||
|
let remove_background: Element<'_, AppMessage> = if state.config.background.is_some() {
|
||||||
|
button(text("Remove background").size(13))
|
||||||
|
.on_press(AppMessage::RemoveBackground)
|
||||||
|
.style(b_style(color_surface, color_blue, color_text, 6.0))
|
||||||
|
.padding(8)
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
iced::widget::Space::new().width(0.0).height(0.0).into()
|
||||||
|
};
|
||||||
|
let background_section = column![
|
||||||
|
row![
|
||||||
|
button(text("Choose image…").size(13))
|
||||||
|
.on_press(AppMessage::PickBackgroundFile)
|
||||||
|
.style(b_style(color_surface, color_blue, color_text, 6.0))
|
||||||
|
.padding(8),
|
||||||
|
remove_background,
|
||||||
|
].spacing(8),
|
||||||
|
text(format!("Background dimming: {:.0}%", state.config.background_dim * 100.0))
|
||||||
|
.size(11)
|
||||||
|
.color(color_subtext),
|
||||||
|
slider(0.0..=1.0, state.config.background_dim, AppMessage::SetBackgroundDim)
|
||||||
|
.step(0.05),
|
||||||
|
text("Set a picture from your computer as the app background. Auto-resized; a dimming overlay keeps text readable. Applies live.")
|
||||||
|
.size(11)
|
||||||
|
.color(color_subtext),
|
||||||
|
]
|
||||||
|
.spacing(10)
|
||||||
|
.width(iced::Length::Fill);
|
||||||
|
|
||||||
// Inline avatar chooser (W4): the monogram fallback plus the bundled
|
// Inline avatar chooser (W4): the monogram fallback plus the bundled
|
||||||
// presets, each a clickable tile. Same SelectAvatar message, applied live
|
// presets, each a clickable tile. Same SelectAvatar message, applied live
|
||||||
// + persisted (and re-announced to the room).
|
// + persisted (and re-announced to the room).
|
||||||
@@ -2780,6 +2809,9 @@ fn view(state: &AppState) -> Element<'_, AppMessage> {
|
|||||||
vertical_space(section_gap),
|
vertical_space(section_gap),
|
||||||
section_header("Theme"),
|
section_header("Theme"),
|
||||||
theme_section,
|
theme_section,
|
||||||
|
vertical_space(section_gap),
|
||||||
|
section_header("Background"),
|
||||||
|
background_section,
|
||||||
]
|
]
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
.width(iced::Length::Fill)
|
.width(iced::Length::Fill)
|
||||||
@@ -3725,7 +3757,7 @@ fn view(state: &AppState) -> Element<'_, AppMessage> {
|
|||||||
.padding(15)
|
.padding(15)
|
||||||
.width(iced::Length::Fill)
|
.width(iced::Length::Fill)
|
||||||
.height(iced::Length::Fill)
|
.height(iced::Length::Fill)
|
||||||
.style(c_style(color_crust, Color::TRANSPARENT, 0.0));
|
.style(c_style(root_bg, Color::TRANSPARENT, 0.0));
|
||||||
|
|
||||||
with_hotkey_info(
|
with_hotkey_info(
|
||||||
with_pixelpass_help(with_layout_picker(room.into(), state), state),
|
with_pixelpass_help(with_layout_picker(room.into(), state), state),
|
||||||
|
|||||||
+64
-4
@@ -60,6 +60,9 @@ pub enum AppTheme {
|
|||||||
GruvboxDark,
|
GruvboxDark,
|
||||||
SolarizedLight,
|
SolarizedLight,
|
||||||
GruvboxLight,
|
GruvboxLight,
|
||||||
|
AyuDark,
|
||||||
|
AyuMirage,
|
||||||
|
AyuLight,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a `Color` from a packed `0xRRGGBB` literal — keeps the palette tables
|
/// Build a `Color` from a packed `0xRRGGBB` literal — keeps the palette tables
|
||||||
@@ -70,7 +73,7 @@ fn hex(c: u32) -> Color {
|
|||||||
|
|
||||||
impl AppTheme {
|
impl AppTheme {
|
||||||
/// Every theme, in picker order.
|
/// Every theme, in picker order.
|
||||||
pub const ALL: [AppTheme; 10] = [
|
pub const ALL: [AppTheme; 13] = [
|
||||||
AppTheme::Mocha,
|
AppTheme::Mocha,
|
||||||
AppTheme::Macchiato,
|
AppTheme::Macchiato,
|
||||||
AppTheme::Frappe,
|
AppTheme::Frappe,
|
||||||
@@ -81,6 +84,9 @@ impl AppTheme {
|
|||||||
AppTheme::GruvboxDark,
|
AppTheme::GruvboxDark,
|
||||||
AppTheme::SolarizedLight,
|
AppTheme::SolarizedLight,
|
||||||
AppTheme::GruvboxLight,
|
AppTheme::GruvboxLight,
|
||||||
|
AppTheme::AyuDark,
|
||||||
|
AppTheme::AyuMirage,
|
||||||
|
AppTheme::AyuLight,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Human-readable name for the picker.
|
/// Human-readable name for the picker.
|
||||||
@@ -96,6 +102,9 @@ impl AppTheme {
|
|||||||
AppTheme::GruvboxDark => "Gruvbox Dark",
|
AppTheme::GruvboxDark => "Gruvbox Dark",
|
||||||
AppTheme::SolarizedLight => "Solarized Light",
|
AppTheme::SolarizedLight => "Solarized Light",
|
||||||
AppTheme::GruvboxLight => "Gruvbox Light",
|
AppTheme::GruvboxLight => "Gruvbox Light",
|
||||||
|
AppTheme::AyuDark => "Ayu Dark",
|
||||||
|
AppTheme::AyuMirage => "Ayu Mirage",
|
||||||
|
AppTheme::AyuLight => "Ayu Light",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +112,10 @@ impl AppTheme {
|
|||||||
pub fn is_dark(self) -> bool {
|
pub fn is_dark(self) -> bool {
|
||||||
!matches!(
|
!matches!(
|
||||||
self,
|
self,
|
||||||
AppTheme::Latte | AppTheme::SolarizedLight | AppTheme::GruvboxLight
|
AppTheme::Latte
|
||||||
|
| AppTheme::SolarizedLight
|
||||||
|
| AppTheme::GruvboxLight
|
||||||
|
| AppTheme::AyuLight
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +132,8 @@ impl AppTheme {
|
|||||||
AppTheme::GruvboxDark => iced::Theme::GruvboxDark,
|
AppTheme::GruvboxDark => iced::Theme::GruvboxDark,
|
||||||
AppTheme::SolarizedLight => iced::Theme::SolarizedLight,
|
AppTheme::SolarizedLight => iced::Theme::SolarizedLight,
|
||||||
AppTheme::GruvboxLight => iced::Theme::GruvboxLight,
|
AppTheme::GruvboxLight => iced::Theme::GruvboxLight,
|
||||||
|
AppTheme::AyuDark | AppTheme::AyuMirage => iced::Theme::TokyoNight,
|
||||||
|
AppTheme::AyuLight => iced::Theme::Light,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,6 +295,52 @@ impl AppTheme {
|
|||||||
green: hex(0x79740e),
|
green: hex(0x79740e),
|
||||||
yellow: hex(0xb57614),
|
yellow: hex(0xb57614),
|
||||||
},
|
},
|
||||||
|
AppTheme::AyuDark => Palette {
|
||||||
|
crust: hex(0x06080a),
|
||||||
|
mantle: hex(0x0b0e14),
|
||||||
|
base: hex(0x0d1017),
|
||||||
|
surface: hex(0x1c222b),
|
||||||
|
overlay: hex(0x565b66),
|
||||||
|
text: hex(0xbfbdb6),
|
||||||
|
subtext: hex(0x9da1a6),
|
||||||
|
blue: hex(0xe6b450),
|
||||||
|
lavender: hex(0x59c2ff),
|
||||||
|
red: hex(0xf07178),
|
||||||
|
maroon: hex(0xff8f40),
|
||||||
|
green: hex(0xaad94c),
|
||||||
|
yellow: hex(0xffb454),
|
||||||
|
},
|
||||||
|
AppTheme::AyuMirage => Palette {
|
||||||
|
crust: hex(0x171b24),
|
||||||
|
mantle: hex(0x1a1f29),
|
||||||
|
base: hex(0x1f2430),
|
||||||
|
surface: hex(0x232834),
|
||||||
|
overlay: hex(0x707a8c),
|
||||||
|
text: hex(0xcccac2),
|
||||||
|
subtext: hex(0xa6abb4),
|
||||||
|
blue: hex(0xffcc66),
|
||||||
|
lavender: hex(0x73d0ff),
|
||||||
|
red: hex(0xf28779),
|
||||||
|
maroon: hex(0xffa759),
|
||||||
|
green: hex(0xd5ff80),
|
||||||
|
yellow: hex(0xffd173),
|
||||||
|
},
|
||||||
|
// Ayu Light's canonical orange is deepened for legibility on white.
|
||||||
|
AppTheme::AyuLight => Palette {
|
||||||
|
crust: hex(0xe6e9ec),
|
||||||
|
mantle: hex(0xf3f4f5),
|
||||||
|
base: hex(0xfcfcfc),
|
||||||
|
surface: hex(0xe8eaed),
|
||||||
|
overlay: hex(0x8a9199),
|
||||||
|
text: hex(0x5c6166),
|
||||||
|
subtext: hex(0x737980),
|
||||||
|
blue: hex(0xc7500e),
|
||||||
|
lavender: hex(0x399ee6),
|
||||||
|
red: hex(0xf07171),
|
||||||
|
maroon: hex(0xfa8d3e),
|
||||||
|
green: hex(0x86b300),
|
||||||
|
yellow: hex(0xff9940),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,11 +431,11 @@ mod tests {
|
|||||||
fn all_themes_distinct_and_labeled() {
|
fn all_themes_distinct_and_labeled() {
|
||||||
// ALL covers exactly the variants once, each with a unique non-empty label
|
// ALL covers exactly the variants once, each with a unique non-empty label
|
||||||
// and a distinct base colour (so swatches don't look identical).
|
// and a distinct base colour (so swatches don't look identical).
|
||||||
assert_eq!(AppTheme::ALL.len(), 10);
|
assert_eq!(AppTheme::ALL.len(), 13);
|
||||||
let mut labels: Vec<&str> = AppTheme::ALL.iter().map(|t| t.label()).collect();
|
let mut labels: Vec<&str> = AppTheme::ALL.iter().map(|t| t.label()).collect();
|
||||||
labels.sort_unstable();
|
labels.sort_unstable();
|
||||||
labels.dedup();
|
labels.dedup();
|
||||||
assert_eq!(labels.len(), 10, "labels must be unique + non-empty");
|
assert_eq!(labels.len(), 13, "labels must be unique + non-empty");
|
||||||
assert!(labels.iter().all(|l| !l.is_empty()));
|
assert!(labels.iter().all(|l| !l.is_empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user