Implement ZoomIn/ZoomOut/ZoomReset with configurable step
Implements #14. Signed-off-by: Mohammad AlSaleh <CE.Mohammad.AlSaleh@gmail.com>
This commit is contained in:
parent
1e0ce2b7e7
commit
1c8a058e82
3 changed files with 92 additions and 1 deletions
|
|
@ -13,6 +13,7 @@ syntax-dark = Syntax dark
|
||||||
syntax-light = Syntax light
|
syntax-light = Syntax light
|
||||||
default-font = Default font
|
default-font = Default font
|
||||||
default-font-size = Default font size
|
default-font-size = Default font size
|
||||||
|
default-zoom-step = Default zoom step
|
||||||
|
|
||||||
# Context menu
|
# Context menu
|
||||||
copy = Copy
|
copy = Copy
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ pub struct Config {
|
||||||
pub app_theme: AppTheme,
|
pub app_theme: AppTheme,
|
||||||
pub font_name: String,
|
pub font_name: String,
|
||||||
pub font_size: u16,
|
pub font_size: u16,
|
||||||
|
pub font_size_zoom_adj: i8,
|
||||||
|
pub font_size_zoom_step_mul_100: u16,
|
||||||
pub show_headerbar: bool,
|
pub show_headerbar: bool,
|
||||||
pub syntax_theme_dark: String,
|
pub syntax_theme_dark: String,
|
||||||
pub syntax_theme_light: String,
|
pub syntax_theme_light: String,
|
||||||
|
|
@ -42,6 +44,8 @@ impl Default for Config {
|
||||||
app_theme: AppTheme::System,
|
app_theme: AppTheme::System,
|
||||||
font_name: "Fira Mono".to_string(),
|
font_name: "Fira Mono".to_string(),
|
||||||
font_size: 14,
|
font_size: 14,
|
||||||
|
font_size_zoom_adj: 0,
|
||||||
|
font_size_zoom_step_mul_100: 100,
|
||||||
show_headerbar: true,
|
show_headerbar: true,
|
||||||
syntax_theme_dark: "COSMIC Dark".to_string(),
|
syntax_theme_dark: "COSMIC Dark".to_string(),
|
||||||
syntax_theme_light: "COSMIC Light".to_string(),
|
syntax_theme_light: "COSMIC Light".to_string(),
|
||||||
|
|
@ -50,9 +54,16 @@ impl Default for Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
fn font_size_adjusted(&self) -> f32 {
|
||||||
|
let font_size = f32::from(self.font_size).max(1.0);
|
||||||
|
let adj = f32::from(self.font_size_zoom_adj);
|
||||||
|
let adj_step = f32::from(self.font_size_zoom_step_mul_100) / 100.0;
|
||||||
|
(font_size + adj*adj_step).max(1.0)
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate metrics from font size
|
// Calculate metrics from font size
|
||||||
pub fn metrics(&self) -> Metrics {
|
pub fn metrics(&self) -> Metrics {
|
||||||
let font_size = self.font_size.max(1) as f32;
|
let font_size = self.font_size_adjusted();
|
||||||
let line_height = (font_size * 1.4).ceil();
|
let line_height = (font_size * 1.4).ceil();
|
||||||
Metrics::new(font_size, line_height)
|
Metrics::new(font_size, line_height)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
79
src/main.rs
79
src/main.rs
|
|
@ -140,6 +140,10 @@ pub enum Message {
|
||||||
Copy(Option<segmented_button::Entity>),
|
Copy(Option<segmented_button::Entity>),
|
||||||
DefaultFont(usize),
|
DefaultFont(usize),
|
||||||
DefaultFontSize(usize),
|
DefaultFontSize(usize),
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
|
ZoomReset,
|
||||||
|
DefaultZoomStep(usize),
|
||||||
Paste(Option<segmented_button::Entity>),
|
Paste(Option<segmented_button::Entity>),
|
||||||
PasteValue(Option<segmented_button::Entity>, String),
|
PasteValue(Option<segmented_button::Entity>, String),
|
||||||
SelectAll(Option<segmented_button::Entity>),
|
SelectAll(Option<segmented_button::Entity>),
|
||||||
|
|
@ -179,6 +183,8 @@ pub struct App {
|
||||||
font_names: Vec<String>,
|
font_names: Vec<String>,
|
||||||
font_size_names: Vec<String>,
|
font_size_names: Vec<String>,
|
||||||
font_sizes: Vec<u16>,
|
font_sizes: Vec<u16>,
|
||||||
|
zoom_step_names: Vec<String>,
|
||||||
|
zoom_steps: Vec<u16>,
|
||||||
theme_names: Vec<String>,
|
theme_names: Vec<String>,
|
||||||
themes: HashMap<String, TermColors>,
|
themes: HashMap<String, TermColors>,
|
||||||
context_page: ContextPage,
|
context_page: ContextPage,
|
||||||
|
|
@ -251,6 +257,10 @@ impl App {
|
||||||
.font_sizes
|
.font_sizes
|
||||||
.iter()
|
.iter()
|
||||||
.position(|font_size| font_size == &self.config.font_size);
|
.position(|font_size| font_size == &self.config.font_size);
|
||||||
|
let zoom_step_selected = self
|
||||||
|
.zoom_steps
|
||||||
|
.iter()
|
||||||
|
.position(|zoom_step| zoom_step == &self.config.font_size_zoom_step_mul_100);
|
||||||
widget::settings::view_column(vec![widget::settings::view_section(fl!("appearance"))
|
widget::settings::view_column(vec![widget::settings::view_section(fl!("appearance"))
|
||||||
.add(
|
.add(
|
||||||
widget::settings::item::builder(fl!("theme")).control(widget::dropdown(
|
widget::settings::item::builder(fl!("theme")).control(widget::dropdown(
|
||||||
|
|
@ -293,6 +303,13 @@ impl App {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.add(
|
||||||
|
widget::settings::item::builder(fl!("default-zoom-step")).control(
|
||||||
|
widget::dropdown(&self.zoom_step_names, zoom_step_selected, |index| {
|
||||||
|
Message::DefaultZoomStep(index)
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
)
|
||||||
.add(
|
.add(
|
||||||
widget::settings::item::builder(fl!("show-headerbar"))
|
widget::settings::item::builder(fl!("show-headerbar"))
|
||||||
.toggler(self.config.show_headerbar, Message::ShowHeaderBar),
|
.toggler(self.config.show_headerbar, Message::ShowHeaderBar),
|
||||||
|
|
@ -366,6 +383,13 @@ impl Application for App {
|
||||||
font_sizes.push(font_size);
|
font_sizes.push(font_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut zoom_step_names = Vec::new();
|
||||||
|
let mut zoom_steps = Vec::new();
|
||||||
|
for zoom_step in [25, 50, 75, 100, 150, 200] {
|
||||||
|
zoom_step_names.push(format!("{}px", f32::from(zoom_step) / 100.0));
|
||||||
|
zoom_steps.push(zoom_step);
|
||||||
|
}
|
||||||
|
|
||||||
let themes = terminal_theme::terminal_themes();
|
let themes = terminal_theme::terminal_themes();
|
||||||
let mut theme_names: Vec<_> = themes.keys().map(|x| x.clone()).collect();
|
let mut theme_names: Vec<_> = themes.keys().map(|x| x.clone()).collect();
|
||||||
theme_names.sort();
|
theme_names.sort();
|
||||||
|
|
@ -379,6 +403,8 @@ impl Application for App {
|
||||||
font_names,
|
font_names,
|
||||||
font_size_names,
|
font_size_names,
|
||||||
font_sizes,
|
font_sizes,
|
||||||
|
zoom_step_names,
|
||||||
|
zoom_steps,
|
||||||
theme_names,
|
theme_names,
|
||||||
themes,
|
themes,
|
||||||
context_page: ContextPage::Settings,
|
context_page: ContextPage::Settings,
|
||||||
|
|
@ -445,9 +471,32 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::ZoomIn => {
|
||||||
|
self.config.font_size_zoom_adj = self.config.font_size_zoom_adj.saturating_add(1);
|
||||||
|
return self.save_config();
|
||||||
|
},
|
||||||
|
Message::ZoomOut => {
|
||||||
|
self.config.font_size_zoom_adj = self.config.font_size_zoom_adj.saturating_sub(1);
|
||||||
|
return self.save_config();
|
||||||
|
},
|
||||||
|
Message::ZoomReset => {
|
||||||
|
self.config.font_size_zoom_adj = 0;
|
||||||
|
return self.save_config();
|
||||||
|
},
|
||||||
|
Message::DefaultZoomStep(index) => match self.zoom_steps.get(index) {
|
||||||
|
Some(zoom_step) => {
|
||||||
|
self.config.font_size_zoom_step_mul_100 = *zoom_step;
|
||||||
|
self.config.font_size_zoom_adj = 0; // reset zoom
|
||||||
|
return self.save_config();
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
log::warn!("failed to find zoom step with index {}", index);
|
||||||
|
}
|
||||||
|
},
|
||||||
Message::DefaultFontSize(index) => match self.font_sizes.get(index) {
|
Message::DefaultFontSize(index) => match self.font_sizes.get(index) {
|
||||||
Some(font_size) => {
|
Some(font_size) => {
|
||||||
self.config.font_size = *font_size;
|
self.config.font_size = *font_size;
|
||||||
|
self.config.font_size_zoom_adj = 0; // reset zoom
|
||||||
return self.save_config();
|
return self.save_config();
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -779,6 +828,36 @@ impl Application for App {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
|
key_code: KeyCode::Equals,
|
||||||
|
modifiers,
|
||||||
|
}) => {
|
||||||
|
if modifiers == Modifiers::CTRL {
|
||||||
|
Some(Message::ZoomIn)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
|
key_code: KeyCode::Minus,
|
||||||
|
modifiers,
|
||||||
|
}) => {
|
||||||
|
if modifiers == Modifiers::CTRL {
|
||||||
|
Some(Message::ZoomOut)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::Keyboard(KeyEvent::KeyPressed {
|
||||||
|
key_code: KeyCode::Key0,
|
||||||
|
modifiers,
|
||||||
|
}) => {
|
||||||
|
if modifiers == Modifiers::CTRL {
|
||||||
|
Some(Message::ZoomReset)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}),
|
}),
|
||||||
subscription::channel(
|
subscription::channel(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue