settings_ui: Add font ligature settings controls (#15301)

This PR adds settings controls for changing whether ligatures are
enabled for the UI and buffer fonts.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-07-26 17:06:14 -04:00 committed by GitHub
parent 769ae8b101
commit 27f97ba762
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 158 additions and 6 deletions

View file

@ -1,4 +1,6 @@
use gpui::{AppContext, FontWeight};
use std::sync::Arc;
use gpui::{AppContext, FontFeatures, FontWeight};
use project::project_settings::{InlineBlameSettings, ProjectSettings};
use settings::{EditableSettingControl, Settings};
use theme::{FontFamilyCache, ThemeSettings};
@ -28,7 +30,8 @@ impl RenderOnce for EditorSettingsControls {
.child(BufferFontFamilyControl)
.child(BufferFontWeightControl),
)
.child(BufferFontSizeControl),
.child(BufferFontSizeControl)
.child(BufferFontLigaturesControl),
)
.child(SettingsGroup::new("Editor").child(InlineGitBlameControl))
}
@ -190,6 +193,76 @@ impl RenderOnce for BufferFontWeightControl {
}
}
#[derive(IntoElement)]
struct BufferFontLigaturesControl;
impl EditableSettingControl for BufferFontLigaturesControl {
type Value = bool;
type Settings = ThemeSettings;
fn name(&self) -> SharedString {
"Buffer Font Ligatures".into()
}
fn read(cx: &AppContext) -> Self::Value {
let settings = ThemeSettings::get_global(cx);
settings
.buffer_font
.features
.is_calt_enabled()
.unwrap_or(true)
}
fn apply(
settings: &mut <Self::Settings as Settings>::FileContent,
value: Self::Value,
_cx: &AppContext,
) {
let value = if value { 1 } else { 0 };
let mut features = settings
.buffer_font_features
.as_ref()
.map(|features| {
features
.tag_value_list()
.into_iter()
.cloned()
.collect::<Vec<_>>()
})
.unwrap_or_default();
if let Some(calt_index) = features.iter().position(|(tag, _)| tag == "calt") {
features[calt_index].1 = value;
} else {
features.push(("calt".into(), value));
}
settings.buffer_font_features = Some(FontFeatures(Arc::new(features)));
}
}
impl RenderOnce for BufferFontLigaturesControl {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let value = Self::read(cx);
CheckboxWithLabel::new(
"buffer-font-ligatures",
Label::new(self.name()),
value.into(),
|selection, cx| {
Self::write(
match selection {
Selection::Selected => true,
Selection::Unselected | Selection::Indeterminate => false,
},
cx,
);
},
)
}
}
#[derive(IntoElement)]
struct InlineGitBlameControl;

View file

@ -12,6 +12,16 @@ impl FontFeatures {
pub fn tag_value_list(&self) -> &[(String, u32)] {
&self.0.as_slice()
}
/// Returns whether the `calt` feature is enabled.
///
/// Returns `None` if the feature is not present.
pub fn is_calt_enabled(&self) -> Option<bool> {
self.0
.iter()
.find(|(feature, _)| feature == "calt")
.map(|(_, value)| *value == 1)
}
}
impl std::fmt::Debug for FontFeatures {

View file

@ -1,9 +1,11 @@
use gpui::{AppContext, FontWeight};
use std::sync::Arc;
use gpui::{AppContext, FontFeatures, FontWeight};
use settings::{EditableSettingControl, Settings};
use theme::{FontFamilyCache, SystemAppearance, ThemeMode, ThemeRegistry, ThemeSettings};
use ui::{
prelude::*, ContextMenu, DropdownMenu, NumericStepper, SettingsContainer, SettingsGroup,
ToggleButton,
prelude::*, CheckboxWithLabel, ContextMenu, DropdownMenu, NumericStepper, SettingsContainer,
SettingsGroup, ToggleButton,
};
#[derive(IntoElement)]
@ -36,7 +38,8 @@ impl RenderOnce for AppearanceSettingsControls {
.child(UiFontFamilyControl)
.child(UiFontWeightControl),
)
.child(UiFontSizeControl),
.child(UiFontSizeControl)
.child(UiFontLigaturesControl),
)
}
}
@ -320,3 +323,69 @@ impl RenderOnce for UiFontWeightControl {
))
}
}
#[derive(IntoElement)]
struct UiFontLigaturesControl;
impl EditableSettingControl for UiFontLigaturesControl {
type Value = bool;
type Settings = ThemeSettings;
fn name(&self) -> SharedString {
"UI Font Ligatures".into()
}
fn read(cx: &AppContext) -> Self::Value {
let settings = ThemeSettings::get_global(cx);
settings.ui_font.features.is_calt_enabled().unwrap_or(true)
}
fn apply(
settings: &mut <Self::Settings as Settings>::FileContent,
value: Self::Value,
_cx: &AppContext,
) {
let value = if value { 1 } else { 0 };
let mut features = settings
.ui_font_features
.as_ref()
.map(|features| {
features
.tag_value_list()
.into_iter()
.cloned()
.collect::<Vec<_>>()
})
.unwrap_or_default();
if let Some(calt_index) = features.iter().position(|(tag, _)| tag == "calt") {
features[calt_index].1 = value;
} else {
features.push(("calt".into(), value));
}
settings.ui_font_features = Some(FontFeatures(Arc::new(features)));
}
}
impl RenderOnce for UiFontLigaturesControl {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let value = Self::read(cx);
CheckboxWithLabel::new(
"ui-font-ligatures",
Label::new(self.name()),
value.into(),
|selection, cx| {
Self::write(
match selection {
Selection::Selected => true,
Selection::Unselected | Selection::Indeterminate => false,
},
cx,
);
},
)
}
}