Skip to content
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

Allow custom font #58

Merged
merged 4 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ servers:
# Channels to join upon connecting to the server
channels:
- "##rust"

# Font settings
font:
# Specify the monospaced font family to use
# - Default is Iosevka Term and provided by this application
family: Iosevka Term
# Specify the font size
# - Default is 13
size: 13

# Settings applied by default to new buffers
new_buffer:
Expand Down
8 changes: 8 additions & 0 deletions data/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,19 @@ pub struct Config {
#[serde(default)]
pub palette: Palette,
pub servers: server::Map,
#[serde(default)]
pub font: Font,
/// Default settings when creating a new buffer
#[serde(default)]
pub new_buffer: buffer::Settings,
}

#[derive(Debug, Clone, Default, Deserialize)]
pub struct Font {
pub family: Option<String>,
pub size: Option<u8>,
}

impl Config {
pub fn config_dir() -> PathBuf {
let dir = environment::config_dir().join("halloy");
Expand Down
64 changes: 52 additions & 12 deletions src/font.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,61 @@
use std::sync::OnceLock;

use data::Config;

use iced::font::{self, Error};
use iced::{Command, Font};
use iced::Command;

pub const MONO: Font = Font {
pub static MONO: Font = Font::new(false);
pub static MONO_BOLD: Font = Font::new(true);
pub const ICON: iced::Font = iced::Font {
monospaced: true,
..Font::with_name("Iosevka Term")
..iced::Font::with_name("bootstrap-icons")
};

pub const MONO_BOLD: Font = Font {
monospaced: true,
weight: font::Weight::Bold,
..Font::with_name("Iosevka Term")
};
#[derive(Debug, Clone)]
pub struct Font {
bold: bool,
inner: OnceLock<iced::Font>,
}

pub const ICON: Font = Font {
monospaced: true,
..Font::with_name("bootstrap-icons")
};
impl Font {
const fn new(bold: bool) -> Self {
Self {
bold,
inner: OnceLock::new(),
}
}

fn set(&self, name: String) {
let name = Box::leak(name.into_boxed_str());
let weight = if self.bold {
font::Weight::Bold
} else {
font::Weight::Normal
};

let _ = self.inner.set(iced::Font {
monospaced: true,
weight,
..iced::Font::with_name(name)
});
}
}

impl From<Font> for iced::Font {
fn from(value: Font) -> Self {
value.inner.get().copied().expect("font is set on startup")
}
}

pub fn set(config: Option<&Config>) {
let family = config
.and_then(|config| config.font.family.clone())
.unwrap_or_else(|| String::from("Iosevka Term"));

MONO.set(family.clone());
MONO_BOLD.set(family);
}

pub fn load() -> Command<Result<(), Error>> {
Command::batch(vec![
Expand Down
43 changes: 31 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ pub fn main() -> iced::Result {
data::environment::formatted_version()
);

if let Err(error) = Halloy::run(settings()) {
let config_load = Config::load();

// DANGER ZONE - font must be set using config
// before we do any iced related stuff w/ it
font::set(config_load.as_ref().ok());
Comment on lines +52 to +54
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense!


if let Err(error) = Halloy::run(settings(config_load)) {
log::error!("{}", error.to_string());
Err(error)
} else {
Expand All @@ -72,15 +78,26 @@ fn window_settings() -> iced::window::Settings {
}
}

fn settings() -> iced::Settings<()> {
fn settings(
config_load: Result<Config, config::Error>,
) -> iced::Settings<Result<Config, config::Error>> {
let default_text_size = config_load
.as_ref()
.ok()
.and_then(|config| config.font.size)
.map(f32::from)
.unwrap_or(theme::TEXT_SIZE);

iced::Settings {
default_font: font::MONO,
default_text_size: theme::TEXT_SIZE,
default_font: font::MONO.clone().into(),
default_text_size,
window: iced::window::Settings {
..window_settings()
},
exit_on_close_request: false,
..Default::default()
flags: config_load,
id: None,
antialiasing: false,
}
}

Expand All @@ -92,7 +109,9 @@ struct Halloy {
}

impl Halloy {
pub fn load_from_state() -> (Halloy, Command<Message>) {
pub fn load_from_state(
config_load: Result<Config, config::Error>,
) -> (Halloy, Command<Message>) {
let load_dashboard = |config| match data::Dashboard::load() {
Ok(dashboard) => screen::Dashboard::restore(dashboard),
Err(error) => {
Expand All @@ -104,7 +123,7 @@ impl Halloy {
}
};

let (screen, config, command) = match Config::load() {
let (screen, config, command) = match config_load {
Ok(config) => {
let (screen, command) = load_dashboard(&config);

Expand Down Expand Up @@ -160,10 +179,10 @@ impl Application for Halloy {
type Executor = executor::Default;
type Message = Message;
type Theme = theme::Theme;
type Flags = ();
type Flags = Result<Config, config::Error>;

fn new(_flags: ()) -> (Halloy, Command<Self::Message>) {
let (halloy, command) = Halloy::load_from_state();
fn new(config_load: Self::Flags) -> (Halloy, Command<Self::Message>) {
let (halloy, command) = Halloy::load_from_state(config_load);

(
halloy,
Expand Down Expand Up @@ -199,7 +218,7 @@ impl Application for Halloy {
if let Some(event) = help.update(message) {
match event {
help::Event::RefreshConfiguration => {
let (halloy, command) = Halloy::load_from_state();
let (halloy, command) = Halloy::load_from_state(Config::load());
*self = halloy;

return command;
Expand All @@ -217,7 +236,7 @@ impl Application for Halloy {
if let Some(event) = welcome.update(message) {
match event {
welcome::Event::RefreshConfiguration => {
let (halloy, command) = Halloy::load_from_state();
let (halloy, command) = Halloy::load_from_state(Config::load());
*self = halloy;

return command;
Expand Down
2 changes: 1 addition & 1 deletion src/screen/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl Help {
.spacing(1)
.push(icon::error().size(45))
.push(vertical_space(10))
.push(text("Error reading configuration file").font(font::MONO_BOLD))
.push(text("Error reading configuration file").font(font::MONO_BOLD.clone()))
.push(vertical_space(3))
.push(text(self.error.to_string()).style(theme::Text::Error))
.push(vertical_space(10))
Expand Down
2 changes: 1 addition & 1 deletion src/screen/welcome.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Welcome {
.spacing(1)
.push(image(format!("{}/assets/logo.png", env!("CARGO_MANIFEST_DIR"))).width(150))
.push(vertical_space(10))
.push(text("Welcome to Halloy!").font(font::MONO_BOLD))
.push(text("Welcome to Halloy!").font(font::MONO_BOLD.clone()))
.push(vertical_space(4))
.push(text(
"No configuration file found. Please follow the steps below to proceed",
Expand Down
2 changes: 2 additions & 0 deletions src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use iced::{application, Background, Color};

use crate::widget::selectable_text;

// TODO: If we use non-standard font sizes, we should consider
// Config.font.size since it's user configurable
pub const TEXT_SIZE: f32 = 13.0;
pub const ICON_SIZE: f32 = 12.0;

Expand Down