Configurable font support
Use fontconfig to load fonts. Fonts can be added to the `fonts` map in the config, and referenced from individual widgets' configurations for customizability. Fonts default to values "mono" and "sans" if nothing is set.
This commit is contained in:
committed by
Kenny Levinsen
parent
1a62696662
commit
48985c470a
@@ -1,6 +1,9 @@
|
||||
use crate::color::Color;
|
||||
use crate::widget::WaitContext;
|
||||
use crate::widgets::bar_widget::{BarWidget, BarWidgetImpl};
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widgets::bar_widget::{BarWidget, BarWidgetImpl},
|
||||
};
|
||||
|
||||
use alsa::mixer::{Mixer, Selem, SelemChannelId, SelemId};
|
||||
|
||||
@@ -34,15 +37,20 @@ pub struct Alsa {
|
||||
}
|
||||
|
||||
impl Alsa {
|
||||
pub fn new(font_size: f32, length: u32) -> ::std::io::Result<Box<BarWidget>> {
|
||||
pub fn new(font: FontRef, font_size: f32, length: u32) -> ::std::io::Result<Box<BarWidget>> {
|
||||
let mixer = Mixer::new(CARD_NAME, true)
|
||||
.map_err(|err| alsa_error_to_io_error("Failed to create ALSA mixer", &err))?;
|
||||
let mixer = Self { mixer };
|
||||
mixer.get_master_volume()?; // probing
|
||||
Ok(BarWidget::new_simple(font_size, length, Box::new(mixer)))
|
||||
Ok(BarWidget::new_simple(
|
||||
font,
|
||||
font_size,
|
||||
length,
|
||||
Box::new(mixer),
|
||||
))
|
||||
}
|
||||
#[inline]
|
||||
pub fn get_master<'a>(&'a self) -> ::std::io::Result<Selem<'a>> {
|
||||
pub fn get_master(&self) -> ::std::io::Result<Selem> {
|
||||
let master_id = SelemId::new(SELEM_NAME, SELEM_ID);
|
||||
match self.mixer.find_selem(&master_id) {
|
||||
Some(master) => Ok(master),
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use crate::cmd::Cmd;
|
||||
use crate::color::Color;
|
||||
use crate::widget::WaitContext;
|
||||
use crate::widgets::bar_widget::{BarWidget, BarWidgetImpl};
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widgets::bar_widget::{BarWidget, BarWidgetImpl},
|
||||
};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
@@ -484,11 +487,12 @@ pub struct PulseAudio {
|
||||
|
||||
impl PulseAudio {
|
||||
pub fn new(
|
||||
font: FontRef,
|
||||
font_size: f32,
|
||||
length: u32,
|
||||
sender: Sender<Cmd>,
|
||||
) -> Result<Box<BarWidget>, ::std::io::Error> {
|
||||
BarWidget::new(font_size, length, move |dirty| {
|
||||
BarWidget::new(font, font_size, length, move |dirty| {
|
||||
let device = PulseAudioSoundDevice::new(move || {
|
||||
*dirty.lock().unwrap() = true;
|
||||
sender.send(Cmd::Draw).unwrap();
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use crate::color::Color;
|
||||
use crate::widget::WaitContext;
|
||||
use crate::widgets::bar_widget::{BarWidget, BarWidgetImpl};
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widgets::bar_widget::{BarWidget, BarWidgetImpl},
|
||||
};
|
||||
|
||||
use std::fs;
|
||||
use std::fs::OpenOptions;
|
||||
@@ -70,7 +73,12 @@ impl Backlight {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn new(path: &str, font_size: f32, length: u32) -> Result<Box<BarWidget>, Error> {
|
||||
pub fn new<'a>(
|
||||
path: &str,
|
||||
font: FontRef<'a>,
|
||||
font_size: f32,
|
||||
length: u32,
|
||||
) -> Result<Box<BarWidget<'a>>, Error> {
|
||||
let mut dev = Backlight {
|
||||
device_path: Path::new("/sys/class/backlight").to_path_buf().join(path),
|
||||
cur_brightness: 0,
|
||||
@@ -79,7 +87,12 @@ impl Backlight {
|
||||
|
||||
dev.update()?;
|
||||
|
||||
Ok(BarWidget::new_simple(font_size, length, Box::new(dev)))
|
||||
Ok(BarWidget::new_simple(
|
||||
font,
|
||||
font_size,
|
||||
length,
|
||||
Box::new(dev),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-10
@@ -1,6 +1,9 @@
|
||||
use crate::color::Color;
|
||||
use crate::draw::{draw_bar, draw_box, Font, ROBOTO_REGULAR};
|
||||
use crate::widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget};
|
||||
use crate::draw::{draw_bar, draw_box, Font};
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget},
|
||||
};
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
@@ -14,21 +17,22 @@ pub trait BarWidgetImpl {
|
||||
fn toggle(&mut self);
|
||||
}
|
||||
|
||||
pub struct BarWidget {
|
||||
pub struct BarWidget<'a> {
|
||||
bar_impl: Box<dyn BarWidgetImpl + Send>,
|
||||
font: Font,
|
||||
font: Font<'a>,
|
||||
font_size: u32,
|
||||
length: u32,
|
||||
dirty: Arc<Mutex<bool>>,
|
||||
}
|
||||
|
||||
impl BarWidget {
|
||||
impl<'a> BarWidget<'a> {
|
||||
pub fn new_simple(
|
||||
font: FontRef,
|
||||
font_size: f32,
|
||||
length: u32,
|
||||
w: Box<dyn BarWidgetImpl + Send>,
|
||||
) -> Box<BarWidget> {
|
||||
let mut font = Font::new(&ROBOTO_REGULAR, font_size);
|
||||
let mut font = Font::new(font, font_size);
|
||||
font.add_str_to_cache(w.name());
|
||||
|
||||
Box::new(BarWidget {
|
||||
@@ -40,15 +44,20 @@ impl BarWidget {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new<F>(font_size: f32, length: u32, f: F) -> Result<Box<BarWidget>, ::std::io::Error>
|
||||
pub fn new<F>(
|
||||
font: FontRef<'a>,
|
||||
font_size: f32,
|
||||
length: u32,
|
||||
f: F,
|
||||
) -> Result<Box<BarWidget>, ::std::io::Error>
|
||||
where
|
||||
F: FnOnce(Arc<Mutex<bool>>) -> Result<Box<dyn BarWidgetImpl + Send>, ::std::io::Error>,
|
||||
F: Send + 'static + Clone,
|
||||
F: Send + 'a + Clone,
|
||||
{
|
||||
let dirty = Arc::new(Mutex::new(true));
|
||||
let im = f(dirty.clone())?;
|
||||
|
||||
let mut font = Font::new(&ROBOTO_REGULAR, font_size);
|
||||
let mut font = Font::new(font, font_size);
|
||||
font.add_str_to_cache(im.name());
|
||||
|
||||
Ok(Box::new(BarWidget {
|
||||
@@ -61,7 +70,7 @@ impl BarWidget {
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for BarWidget {
|
||||
impl<'a> Widget for BarWidget<'a> {
|
||||
fn wait(&mut self, ctx: &mut WaitContext) {
|
||||
self.bar_impl.wait(ctx);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use crate::cmd::Cmd;
|
||||
use crate::color::Color;
|
||||
use crate::widget::WaitContext;
|
||||
use crate::widgets::bar_widget::{BarWidget, BarWidgetImpl};
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widgets::bar_widget::{BarWidget, BarWidgetImpl},
|
||||
};
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
use std::sync::{Arc, Mutex};
|
||||
@@ -161,11 +164,12 @@ impl UpowerBattery {
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
font: FontRef,
|
||||
font_size: f32,
|
||||
length: u32,
|
||||
sender: Sender<Cmd>,
|
||||
) -> Result<Box<BarWidget>, ::std::io::Error> {
|
||||
BarWidget::new(font_size, length, move |dirty| {
|
||||
BarWidget::new(font, font_size, length, move |dirty| {
|
||||
let d = UpowerBattery::from_device(dirty, sender, "DisplayDevice")?;
|
||||
Ok(Box::new(d))
|
||||
})
|
||||
|
||||
+24
-15
@@ -1,23 +1,26 @@
|
||||
use crate::buffer::Buffer;
|
||||
use crate::color::Color;
|
||||
use crate::draw::{Font, DEJAVUSANS_MONO, ROBOTO_REGULAR};
|
||||
use crate::widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget};
|
||||
use crate::draw::Font;
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget},
|
||||
};
|
||||
|
||||
use chrono::{Datelike, NaiveDate, NaiveDateTime};
|
||||
|
||||
pub struct Calendar {
|
||||
pub struct Calendar<'a> {
|
||||
cur_date: NaiveDate,
|
||||
dirty: bool,
|
||||
offset: f64,
|
||||
sections: u32,
|
||||
font_size: u32,
|
||||
calendar_cache: Font,
|
||||
month_cache: Font,
|
||||
year_cache: Font,
|
||||
day_cache: Font,
|
||||
calendar_cache: Font<'a>,
|
||||
month_cache: Font<'a>,
|
||||
year_cache: Font<'a>,
|
||||
day_cache: Font<'a>,
|
||||
}
|
||||
|
||||
impl Calendar {
|
||||
impl<'a> Calendar<'a> {
|
||||
fn draw_month(
|
||||
&self,
|
||||
buf: &mut Buffer,
|
||||
@@ -152,15 +155,21 @@ impl Calendar {
|
||||
}
|
||||
}
|
||||
|
||||
impl Calendar {
|
||||
pub fn new(time: NaiveDateTime, font_size: f32, sections: u32) -> Box<Calendar> {
|
||||
let mut calendar_cache = Font::new(&DEJAVUSANS_MONO, font_size * 2.0);
|
||||
impl<'a> Calendar<'a> {
|
||||
pub fn new(
|
||||
time: NaiveDateTime,
|
||||
font_primary: FontRef<'a>,
|
||||
font_secondary: FontRef<'a>,
|
||||
font_size: f32,
|
||||
sections: u32,
|
||||
) -> Box<Calendar<'a>> {
|
||||
let mut calendar_cache = Font::new(font_secondary, font_size * 2.0);
|
||||
calendar_cache.add_str_to_cache("0123456789");
|
||||
let mut month_cache = Font::new(&ROBOTO_REGULAR, font_size * 4.0);
|
||||
let mut month_cache = Font::new(font_primary, font_size * 4.0);
|
||||
month_cache.add_str_to_cache("JanuryFebMchApilJgstSmOoNvD");
|
||||
let mut year_cache = Font::new(&DEJAVUSANS_MONO, font_size * 1.5);
|
||||
let mut year_cache = Font::new(font_primary, font_size * 1.5);
|
||||
year_cache.add_str_to_cache("-0123456789");
|
||||
let mut day_cache = Font::new(&DEJAVUSANS_MONO, font_size);
|
||||
let mut day_cache = Font::new(font_primary, font_size);
|
||||
day_cache.add_str_to_cache("MONTUEWDHFRISA");
|
||||
Box::new(Calendar {
|
||||
cur_date: time.date(),
|
||||
@@ -176,7 +185,7 @@ impl Calendar {
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Calendar {
|
||||
impl<'a> Widget for Calendar<'a> {
|
||||
fn wait(&mut self, _: &mut WaitContext) {}
|
||||
fn enter(&mut self) {}
|
||||
fn leave(&mut self) {}
|
||||
|
||||
+11
-8
@@ -1,18 +1,21 @@
|
||||
use crate::color::Color;
|
||||
use crate::draw::{Font, ROBOTO_REGULAR};
|
||||
use crate::widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget};
|
||||
use crate::draw::Font;
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget},
|
||||
};
|
||||
|
||||
use chrono::{Duration, NaiveDateTime, Timelike};
|
||||
|
||||
pub struct Clock {
|
||||
pub struct Clock<'a> {
|
||||
cur_time: NaiveDateTime,
|
||||
clock_cache: Font,
|
||||
clock_cache: Font<'a>,
|
||||
size: f32,
|
||||
}
|
||||
|
||||
impl Clock {
|
||||
pub fn new(time: NaiveDateTime, size: f32) -> Box<Clock> {
|
||||
let mut clock_cache = Font::new(&ROBOTO_REGULAR, size);
|
||||
impl<'a> Clock<'a> {
|
||||
pub fn new(time: NaiveDateTime, font: FontRef, size: f32) -> Box<Clock> {
|
||||
let mut clock_cache = Font::new(font, size);
|
||||
clock_cache.add_str_to_cache("0123456789:");
|
||||
|
||||
Box::new(Clock {
|
||||
@@ -23,7 +26,7 @@ impl Clock {
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Clock {
|
||||
impl<'a> Widget for Clock<'a> {
|
||||
fn wait(&mut self, ctx: &mut WaitContext) {
|
||||
let target = (self.cur_time + Duration::seconds(60))
|
||||
.with_second(0)
|
||||
|
||||
+11
-8
@@ -1,18 +1,21 @@
|
||||
use crate::color::Color;
|
||||
use crate::draw::{Font, ROBOTO_REGULAR};
|
||||
use crate::widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget};
|
||||
use crate::draw::Font;
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget},
|
||||
};
|
||||
|
||||
use chrono::{Datelike, NaiveDateTime};
|
||||
|
||||
pub struct Date {
|
||||
pub struct Date<'a> {
|
||||
cur_time: NaiveDateTime,
|
||||
date_cache: Font,
|
||||
date_cache: Font<'a>,
|
||||
size: f32,
|
||||
}
|
||||
|
||||
impl Date {
|
||||
pub fn new(time: NaiveDateTime, size: f32) -> Box<Date> {
|
||||
let mut date_cache = Font::new(&ROBOTO_REGULAR, size);
|
||||
impl<'a> Date<'a> {
|
||||
pub fn new(time: NaiveDateTime, font: FontRef, size: f32) -> Box<Date> {
|
||||
let mut date_cache = Font::new(font, size);
|
||||
date_cache
|
||||
.add_str_to_cache("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,/ ");
|
||||
|
||||
@@ -24,7 +27,7 @@ impl Date {
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Date {
|
||||
impl<'a> Widget for Date<'a> {
|
||||
fn wait(&mut self, _: &mut WaitContext) {}
|
||||
fn enter(&mut self) {}
|
||||
fn leave(&mut self) {}
|
||||
|
||||
+11
-7
@@ -2,8 +2,11 @@ use crate::buffer::Buffer;
|
||||
use crate::cmd::Cmd;
|
||||
use crate::color::Color;
|
||||
use crate::desktop::{load_desktop_files, Desktop};
|
||||
use crate::draw::{Font, ROBOTO_REGULAR};
|
||||
use crate::widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget};
|
||||
use crate::draw::Font;
|
||||
use crate::{
|
||||
fonts::FontRef,
|
||||
widget::{DrawContext, DrawReport, KeyState, ModifiersState, WaitContext, Widget},
|
||||
};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering;
|
||||
@@ -14,7 +17,7 @@ use std::sync::mpsc::Sender;
|
||||
use fuzzy_matcher::skim::{fuzzy_indices, fuzzy_match};
|
||||
use smithay_client_toolkit::keyboard::keysyms;
|
||||
|
||||
pub struct Launcher {
|
||||
pub struct Launcher<'a> {
|
||||
options: Vec<Desktop>,
|
||||
term_opener: String,
|
||||
app_opener: String,
|
||||
@@ -23,15 +26,16 @@ pub struct Launcher {
|
||||
input: String,
|
||||
result: Option<String>,
|
||||
offset: usize,
|
||||
font: RefCell<Font>,
|
||||
font: RefCell<Font<'a>>,
|
||||
font_size: u32,
|
||||
length: u32,
|
||||
dirty: bool,
|
||||
tx: Sender<Cmd>,
|
||||
}
|
||||
|
||||
impl Launcher {
|
||||
impl<'a> Launcher<'a> {
|
||||
pub fn new(
|
||||
font: FontRef,
|
||||
font_size: f32,
|
||||
length: u32,
|
||||
listener: Sender<Cmd>,
|
||||
@@ -48,7 +52,7 @@ impl Launcher {
|
||||
input: "".to_string(),
|
||||
result: None,
|
||||
offset: 0,
|
||||
font: RefCell::new(Font::new(&ROBOTO_REGULAR, font_size)),
|
||||
font: RefCell::new(Font::new(font, font_size)),
|
||||
font_size: font_size as u32,
|
||||
length,
|
||||
dirty: true,
|
||||
@@ -244,7 +248,7 @@ impl Matcher {
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Launcher {
|
||||
impl<'a> Widget for Launcher<'a> {
|
||||
fn wait(&mut self, _: &mut WaitContext) {}
|
||||
fn enter(&mut self) {}
|
||||
fn leave(&mut self) {
|
||||
|
||||
Reference in New Issue
Block a user