Add selectable Pixel clock styling and widget font controls
This commit is contained in:
1 parent
d71fab7102
commit
dcca5fec88
14 files changed
+479
-37
No files matched your search
@@ -0,0 +1,34 @@
|
||||
use std::{process::Command, sync::OnceLock};
|
||||
|
||||
pub fn families() -> &'static [String] {
|
||||
static FAMILIES: OnceLock<Vec<String>> = OnceLock::new();
|
||||
|
||||
FAMILIES.get_or_init(|| {
|
||||
let output = Command::new("fc-list")
|
||||
.args(["--format", "%{family}\\n"])
|
||||
.output()
|
||||
.ok()
|
||||
.filter(|output| output.status.success());
|
||||
let mut families: Vec<String> = output
|
||||
.as_ref()
|
||||
.map(|output| String::from_utf8_lossy(&output.stdout))
|
||||
.unwrap_or_default()
|
||||
.lines()
|
||||
.flat_map(|line| line.split(','))
|
||||
.map(str::trim)
|
||||
.filter(|family| !family.is_empty() && family.len() <= 128)
|
||||
.map(str::to_owned)
|
||||
.collect();
|
||||
|
||||
families.extend([
|
||||
"Comfortaa".into(),
|
||||
"sans-serif".into(),
|
||||
"serif".into(),
|
||||
"monospace".into(),
|
||||
]);
|
||||
families.sort_unstable_by_key(|family| family.to_lowercase());
|
||||
families.dedup();
|
||||
families.insert(0, "Default font".into());
|
||||
families
|
||||
})
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod fonts;
|
||||
mod schema;
|
||||
mod store;
|
||||
mod visuals;
|
||||
@@ -26,6 +27,7 @@ fn main() -> cosmic::iced::Result {
|
||||
None => store::config_path(),
|
||||
};
|
||||
let path = path.canonicalize().unwrap_or(path);
|
||||
fonts::families();
|
||||
let initial = Snapshot::read(&path);
|
||||
let theme = visuals::native_theme(initial.as_ref().ok());
|
||||
|
||||
@@ -45,6 +47,7 @@ enum Message {
|
||||
Page(Page),
|
||||
Search(String),
|
||||
Change(Edit),
|
||||
SelectFont(String, String),
|
||||
Draft(String, String),
|
||||
Commit(Field),
|
||||
Range(Field, f64),
|
||||
@@ -212,6 +215,10 @@ impl cosmic::Application for App {
|
||||
self.sync_notes();
|
||||
return task;
|
||||
}
|
||||
Message::SelectFont(path, family) => {
|
||||
self.inputs.remove(&path);
|
||||
return self.change(set(&path, family));
|
||||
}
|
||||
Message::DragWindow => return self.core.drag(None),
|
||||
Message::ExternalConfig(result) => match result {
|
||||
Ok(snapshot)
|
||||
@@ -1085,6 +1092,41 @@ impl App {
|
||||
let labels = labels.width(Length::Fill);
|
||||
let path = field.path.clone();
|
||||
let control: Element<'static, Message> = match field.kind.clone() {
|
||||
Kind::Font => {
|
||||
let value = self
|
||||
.inputs
|
||||
.get(&path)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| self.draft.string(&path, ""));
|
||||
let families = fonts::families();
|
||||
let selected = if value.is_empty() {
|
||||
Some(0)
|
||||
} else {
|
||||
families.iter().position(|family| family == &value)
|
||||
};
|
||||
let selection_path = path.clone();
|
||||
let commit = field.clone();
|
||||
column([])
|
||||
.spacing(6)
|
||||
.push(
|
||||
widget::dropdown(families, selected, move |index| {
|
||||
let family = if index == 0 { "" } else { &families[index] };
|
||||
Message::SelectFont(selection_path.clone(), family.to_owned())
|
||||
})
|
||||
.width(225),
|
||||
)
|
||||
.push(
|
||||
text_input("Default font", value)
|
||||
.font(self.font)
|
||||
.style(visuals::input_style(palette))
|
||||
.on_input(move |value| Message::Draft(path.clone(), value))
|
||||
.on_submit(move |_| Message::Commit(field.clone()))
|
||||
.on_unfocus(Message::Commit(commit))
|
||||
.width(225)
|
||||
.size(12),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
Kind::Toggle(default) => toggler(self.draft.boolean(&path, default))
|
||||
.size(22)
|
||||
.on_toggle(move |value| Message::Change(set(&path, value)))
|
||||
|
||||
@@ -90,6 +90,7 @@ impl Page {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Kind {
|
||||
Font,
|
||||
Toggle(bool),
|
||||
Range {
|
||||
default: f64,
|
||||
@@ -198,6 +199,13 @@ fn clock_fields() -> Vec<Field> {
|
||||
"Behind windows and click-through.",
|
||||
false,
|
||||
),
|
||||
choice(
|
||||
"desktop_widgets.clock.style",
|
||||
"Clock style",
|
||||
"Pixel stacks heavy, alternating-color digits; Minimal uses plain text.",
|
||||
"pixel",
|
||||
&[("pixel", "Pixel"), ("minimal", "Minimal")],
|
||||
),
|
||||
toggle(
|
||||
"desktop_widgets.clock.bold",
|
||||
"Bold text",
|
||||
@@ -207,7 +215,7 @@ fn clock_fields() -> Vec<Field> {
|
||||
toggle(
|
||||
"desktop_widgets.clock.show_date",
|
||||
"Show date",
|
||||
"A separate line beneath the time.",
|
||||
"A small date above the digits in Pixel; beneath the time in Minimal.",
|
||||
true,
|
||||
),
|
||||
toggle(
|
||||
@@ -222,11 +230,11 @@ fn clock_fields() -> Vec<Field> {
|
||||
"top_left, top_center, top_right, center_left, center, center_right, bottom_left, bottom_center, bottom_right",
|
||||
"top_left",
|
||||
),
|
||||
text(
|
||||
Field::new(
|
||||
"desktop_widgets.clock.font_family",
|
||||
"Font",
|
||||
"Empty follows the desktop font.",
|
||||
"",
|
||||
"Choose an installed family or enter a name. Empty uses the style default.",
|
||||
Kind::Font,
|
||||
),
|
||||
text(
|
||||
"desktop_widgets.clock.time_format",
|
||||
@@ -238,7 +246,7 @@ fn clock_fields() -> Vec<Field> {
|
||||
"desktop_widgets.clock.date_format",
|
||||
"Date format",
|
||||
"%A, %-d %B for weekday and date; %-d %b for a short date.",
|
||||
"%A, %-d %B",
|
||||
"%a, %b %-d",
|
||||
),
|
||||
text(
|
||||
"desktop_widgets.clock.time_zone",
|
||||
@@ -301,7 +309,7 @@ fn clock_fields() -> Vec<Field> {
|
||||
"desktop_widgets.clock.height",
|
||||
"Widget height",
|
||||
"Leave room for both text lines.",
|
||||
160.0,
|
||||
320.0,
|
||||
32.0,
|
||||
800.0,
|
||||
1.0,
|
||||
@@ -312,7 +320,7 @@ fn clock_fields() -> Vec<Field> {
|
||||
"desktop_widgets.clock.time_size",
|
||||
"Time size",
|
||||
"Logical pixels; scales with your output.",
|
||||
72.0,
|
||||
128.0,
|
||||
8.0,
|
||||
240.0,
|
||||
1.0,
|
||||
@@ -411,11 +419,11 @@ pub fn note_fields(index: usize) -> Vec<Field> {
|
||||
"Nine positions, e.g. top_right or center.",
|
||||
"top_right",
|
||||
),
|
||||
text(
|
||||
Field::new(
|
||||
format!("{prefix}.font_family"),
|
||||
"Font",
|
||||
"Empty follows the desktop font.",
|
||||
"",
|
||||
"Choose an installed family or enter a name. Empty follows the desktop font.",
|
||||
Kind::Font,
|
||||
),
|
||||
text(
|
||||
format!("{prefix}.color"),
|
||||
|
||||
@@ -384,6 +384,7 @@ window-rule app-id="mine" floating=#true
|
||||
for field in fields {
|
||||
use crate::schema::Kind;
|
||||
let values: Vec<Value> = match field.kind {
|
||||
Kind::Font => vec!["".into(), "sans-serif".into()],
|
||||
Kind::Toggle(_) => vec![true.into(), false.into()],
|
||||
Kind::Range {
|
||||
min, max, integer, ..
|
||||
|
||||
Reference in new issue
Block a user