Include builtin cosmic dark and light theme in color schemes list, fixes #206
This commit is contained in:
parent
69468765b7
commit
c0d1ab1fb8
4 changed files with 180 additions and 123 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
|
@ -1208,13 +1208,14 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-text"
|
name = "cosmic-text"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
source = "git+https://github.com/pop-os/cosmic-text.git#5e82de11cf5c977ee82a5d631c05382f4acc7314"
|
source = "git+https://github.com/pop-os/cosmic-text.git#89503b254fb6a2014d3712568054b32925ea9008"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"fontdb",
|
"fontdb",
|
||||||
"libm",
|
"libm",
|
||||||
"log",
|
"log",
|
||||||
"rangemap",
|
"rangemap",
|
||||||
|
"rayon",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustybuzz",
|
"rustybuzz",
|
||||||
"self_cell 1.0.4",
|
"self_cell 1.0.4",
|
||||||
|
|
|
||||||
231
src/main.rs
231
src/main.rs
|
|
@ -272,9 +272,9 @@ pub enum Message {
|
||||||
AppTheme(AppTheme),
|
AppTheme(AppTheme),
|
||||||
ColorSchemeCollapse,
|
ColorSchemeCollapse,
|
||||||
ColorSchemeDelete(ColorSchemeKind, ColorSchemeId),
|
ColorSchemeDelete(ColorSchemeKind, ColorSchemeId),
|
||||||
ColorSchemeExpand(ColorSchemeKind, ColorSchemeId),
|
ColorSchemeExpand(ColorSchemeKind, Option<ColorSchemeId>),
|
||||||
ColorSchemeExport(ColorSchemeKind, ColorSchemeId),
|
ColorSchemeExport(ColorSchemeKind, Option<ColorSchemeId>),
|
||||||
ColorSchemeExportResult(ColorSchemeKind, ColorSchemeId, DialogResult),
|
ColorSchemeExportResult(ColorSchemeKind, Option<ColorSchemeId>, DialogResult),
|
||||||
ColorSchemeImport(ColorSchemeKind),
|
ColorSchemeImport(ColorSchemeKind),
|
||||||
ColorSchemeImportResult(ColorSchemeKind, DialogResult),
|
ColorSchemeImportResult(ColorSchemeKind, DialogResult),
|
||||||
ColorSchemeRename(ColorSchemeKind, ColorSchemeId, String),
|
ColorSchemeRename(ColorSchemeKind, ColorSchemeId, String),
|
||||||
|
|
@ -401,7 +401,7 @@ pub struct App {
|
||||||
startup_options: Option<tty::Options>,
|
startup_options: Option<tty::Options>,
|
||||||
term_config: term::Config,
|
term_config: term::Config,
|
||||||
color_scheme_errors: Vec<String>,
|
color_scheme_errors: Vec<String>,
|
||||||
color_scheme_expanded: Option<(ColorSchemeKind, ColorSchemeId)>,
|
color_scheme_expanded: Option<(ColorSchemeKind, Option<ColorSchemeId>)>,
|
||||||
color_scheme_renaming: Option<(ColorSchemeKind, ColorSchemeId, String)>,
|
color_scheme_renaming: Option<(ColorSchemeKind, ColorSchemeId, String)>,
|
||||||
color_scheme_rename_id: widget::Id,
|
color_scheme_rename_id: widget::Id,
|
||||||
color_scheme_tab_model: widget::segmented_button::SingleSelectModel,
|
color_scheme_tab_model: widget::segmented_button::SingleSelectModel,
|
||||||
|
|
@ -696,65 +696,67 @@ impl App {
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if !self.config.color_schemes(color_scheme_kind).is_empty() {
|
let mut section = widget::settings::view_section("");
|
||||||
let mut section = widget::settings::view_section("");
|
let builtin_name = format!("COSMIC {:?}", color_scheme_kind);
|
||||||
for (color_scheme_name, color_scheme_id) in
|
let color_scheme_names = self.config.color_scheme_names(color_scheme_kind);
|
||||||
self.config.color_scheme_names(color_scheme_kind)
|
for (color_scheme_name, color_scheme_id_opt) in std::iter::once((builtin_name, None)).chain(
|
||||||
{
|
color_scheme_names
|
||||||
let expanded =
|
.into_iter()
|
||||||
self.color_scheme_expanded == Some((color_scheme_kind, color_scheme_id));
|
.map(|(name, id)| (name, Some(id))),
|
||||||
let renaming = match &self.color_scheme_renaming {
|
) {
|
||||||
Some((kind, id, value))
|
let expanded =
|
||||||
if kind == &color_scheme_kind && id == &color_scheme_id =>
|
self.color_scheme_expanded == Some((color_scheme_kind, color_scheme_id_opt));
|
||||||
{
|
let renaming = match &self.color_scheme_renaming {
|
||||||
Some(value)
|
Some((kind, id, value))
|
||||||
}
|
if kind == &color_scheme_kind && Some(id) == color_scheme_id_opt.as_ref() =>
|
||||||
_ => None,
|
{
|
||||||
};
|
Some(value)
|
||||||
|
|
||||||
let button = if expanded {
|
|
||||||
widget::button(icon_cache_get("view-more-symbolic", 16))
|
|
||||||
.on_press(Message::ColorSchemeCollapse)
|
|
||||||
} else {
|
|
||||||
widget::button(icon_cache_get("view-more-symbolic", 16)).on_press(
|
|
||||||
Message::ColorSchemeExpand(color_scheme_kind, color_scheme_id),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.style(style::Button::Icon);
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
let mut popover = widget::popover(button);
|
let button = if expanded {
|
||||||
if expanded {
|
widget::button(icon_cache_get("view-more-symbolic", 16))
|
||||||
let menu = menu::color_scheme_menu(
|
.on_press(Message::ColorSchemeCollapse)
|
||||||
color_scheme_kind,
|
} else {
|
||||||
color_scheme_id,
|
widget::button(icon_cache_get("view-more-symbolic", 16)).on_press(
|
||||||
&color_scheme_name,
|
Message::ColorSchemeExpand(color_scheme_kind, color_scheme_id_opt),
|
||||||
);
|
)
|
||||||
popover = popover
|
|
||||||
.popup(menu)
|
|
||||||
.position(widget::popover::Position::Bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
let item = match renaming {
|
|
||||||
Some(value) => widget::settings::item_row(vec![
|
|
||||||
widget::text_input("", value)
|
|
||||||
.id(self.color_scheme_rename_id.clone())
|
|
||||||
.on_input(move |value| {
|
|
||||||
Message::ColorSchemeRename(
|
|
||||||
color_scheme_kind,
|
|
||||||
color_scheme_id,
|
|
||||||
value,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.on_submit(Message::ColorSchemeRenameSubmit)
|
|
||||||
.into(),
|
|
||||||
popover.into(),
|
|
||||||
]),
|
|
||||||
None => widget::settings::item::builder(color_scheme_name).control(popover),
|
|
||||||
};
|
|
||||||
section = section.add(item);
|
|
||||||
}
|
}
|
||||||
sections.push(section.into());
|
.style(style::Button::Icon);
|
||||||
|
|
||||||
|
let mut popover = widget::popover(button);
|
||||||
|
if expanded {
|
||||||
|
let menu = menu::color_scheme_menu(
|
||||||
|
color_scheme_kind,
|
||||||
|
color_scheme_id_opt,
|
||||||
|
&color_scheme_name,
|
||||||
|
);
|
||||||
|
popover = popover
|
||||||
|
.popup(menu)
|
||||||
|
.position(widget::popover::Position::Bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = match renaming {
|
||||||
|
Some(value) => widget::settings::item_row(vec![
|
||||||
|
widget::text_input("", value)
|
||||||
|
.id(self.color_scheme_rename_id.clone())
|
||||||
|
.on_input(move |value| {
|
||||||
|
Message::ColorSchemeRename(
|
||||||
|
color_scheme_kind,
|
||||||
|
color_scheme_id_opt.expect("trying to rename builtin color scheme"),
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.on_submit(Message::ColorSchemeRenameSubmit)
|
||||||
|
.into(),
|
||||||
|
popover.into(),
|
||||||
|
]),
|
||||||
|
None => widget::settings::item::builder(color_scheme_name).control(popover),
|
||||||
|
};
|
||||||
|
section = section.add(item);
|
||||||
}
|
}
|
||||||
|
sections.push(section.into());
|
||||||
|
|
||||||
sections.push(
|
sections.push(
|
||||||
widget::row::with_children(vec![
|
widget::row::with_children(vec![
|
||||||
|
|
@ -1520,24 +1522,27 @@ impl Application for App {
|
||||||
.remove(&color_scheme_id);
|
.remove(&color_scheme_id);
|
||||||
return self.save_color_schemes(color_scheme_kind);
|
return self.save_color_schemes(color_scheme_kind);
|
||||||
}
|
}
|
||||||
Message::ColorSchemeExport(color_scheme_kind, color_scheme_id) => {
|
Message::ColorSchemeExport(color_scheme_kind, color_scheme_id_opt) => {
|
||||||
self.color_scheme_expanded = None;
|
self.color_scheme_expanded = None;
|
||||||
if let Some(color_scheme) = self
|
if let Some(color_scheme_name) = match color_scheme_id_opt {
|
||||||
.config
|
Some(color_scheme_id) => self
|
||||||
.color_schemes(color_scheme_kind)
|
.config
|
||||||
.get(&color_scheme_id)
|
.color_schemes(color_scheme_kind)
|
||||||
{
|
.get(&color_scheme_id)
|
||||||
|
.map(|color_scheme| color_scheme.name.clone()),
|
||||||
|
None => Some(format!("COSMIC {:?}", color_scheme_kind)),
|
||||||
|
} {
|
||||||
if self.dialog_opt.is_none() {
|
if self.dialog_opt.is_none() {
|
||||||
let (dialog, command) = Dialog::new(
|
let (dialog, command) = Dialog::new(
|
||||||
DialogKind::SaveFile {
|
DialogKind::SaveFile {
|
||||||
filename: format!("{}.ron", color_scheme.name),
|
filename: format!("{}.ron", color_scheme_name),
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
Message::DialogMessage,
|
Message::DialogMessage,
|
||||||
move |result| {
|
move |result| {
|
||||||
Message::ColorSchemeExportResult(
|
Message::ColorSchemeExportResult(
|
||||||
color_scheme_kind,
|
color_scheme_kind,
|
||||||
color_scheme_id,
|
color_scheme_id_opt,
|
||||||
result,
|
result,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -1547,45 +1552,85 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::ColorSchemeExportResult(color_scheme_kind, color_scheme_id, result) => {
|
Message::ColorSchemeExportResult(color_scheme_kind, color_scheme_id_opt, result) => {
|
||||||
//TODO: show errors in UI
|
//TODO: show errors in UI
|
||||||
self.dialog_opt = None;
|
self.dialog_opt = None;
|
||||||
if let DialogResult::Open(paths) = result {
|
if let DialogResult::Open(paths) = result {
|
||||||
let path = &paths[0];
|
let path = &paths[0];
|
||||||
if let Some(color_scheme) = self
|
match color_scheme_id_opt {
|
||||||
.config
|
Some(color_scheme_id) => {
|
||||||
.color_schemes(color_scheme_kind)
|
if let Some(color_scheme) = self
|
||||||
.get(&color_scheme_id)
|
.config
|
||||||
{
|
.color_schemes(color_scheme_kind)
|
||||||
match ron::ser::to_string_pretty(
|
.get(&color_scheme_id)
|
||||||
&color_scheme,
|
{
|
||||||
ron::ser::PrettyConfig::new(),
|
match ron::ser::to_string_pretty(
|
||||||
) {
|
&color_scheme,
|
||||||
Ok(ron) => {
|
ron::ser::PrettyConfig::new(),
|
||||||
if let Err(err) = fs::write(path, ron) {
|
) {
|
||||||
|
Ok(ron) => {
|
||||||
|
if let Err(err) = fs::write(path, ron) {
|
||||||
|
log::error!(
|
||||||
|
"failed to export {:?} to {:?}: {}",
|
||||||
|
color_scheme_id,
|
||||||
|
path,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::error!(
|
||||||
|
"failed to serialize color scheme {:?}: {}",
|
||||||
|
color_scheme_id,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::error!("failed to find color scheme {:?}", color_scheme_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let name = format!("COSMIC {:?}", color_scheme_kind);
|
||||||
|
let color_scheme = match color_scheme_kind {
|
||||||
|
ColorSchemeKind::Dark => ColorScheme::from((
|
||||||
|
name.as_str(),
|
||||||
|
&terminal_theme::cosmic_dark(),
|
||||||
|
)),
|
||||||
|
ColorSchemeKind::Light => ColorScheme::from((
|
||||||
|
name.as_str(),
|
||||||
|
&terminal_theme::cosmic_light(),
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
//TODO: do not duplicate code
|
||||||
|
match ron::ser::to_string_pretty(
|
||||||
|
&color_scheme,
|
||||||
|
ron::ser::PrettyConfig::new(),
|
||||||
|
) {
|
||||||
|
Ok(ron) => {
|
||||||
|
if let Err(err) = fs::write(path, ron) {
|
||||||
|
log::error!(
|
||||||
|
"failed to export {:?} to {:?}: {}",
|
||||||
|
color_scheme.name,
|
||||||
|
path,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
log::error!(
|
log::error!(
|
||||||
"failed to export {:?} to {:?}: {}",
|
"failed to serialize color scheme {:?}: {}",
|
||||||
color_scheme_id,
|
color_scheme.name,
|
||||||
path,
|
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
|
||||||
log::error!(
|
|
||||||
"failed to serialize color scheme {:?}: {}",
|
|
||||||
color_scheme_id,
|
|
||||||
err
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log::error!("failed to find color scheme {:?}", color_scheme_id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::ColorSchemeExpand(color_scheme_kind, color_scheme_id) => {
|
Message::ColorSchemeExpand(color_scheme_kind, color_scheme_id_opt) => {
|
||||||
self.color_scheme_expanded = Some((color_scheme_kind, color_scheme_id));
|
self.color_scheme_expanded = Some((color_scheme_kind, color_scheme_id_opt));
|
||||||
}
|
}
|
||||||
Message::ColorSchemeImport(color_scheme_kind) => {
|
Message::ColorSchemeImport(color_scheme_kind) => {
|
||||||
if self.dialog_opt.is_none() {
|
if self.dialog_opt.is_none() {
|
||||||
|
|
|
||||||
65
src/menu.rs
65
src/menu.rs
|
|
@ -97,39 +97,50 @@ pub fn context_menu<'a>(
|
||||||
|
|
||||||
pub fn color_scheme_menu<'a>(
|
pub fn color_scheme_menu<'a>(
|
||||||
kind: ColorSchemeKind,
|
kind: ColorSchemeKind,
|
||||||
id: ColorSchemeId,
|
id_opt: Option<ColorSchemeId>,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let menu_item =
|
let menu_item =
|
||||||
|label, message| menu_button(vec![widget::text(label).into()]).on_press(message);
|
|label, message| menu_button(vec![widget::text(label).into()]).on_press(message);
|
||||||
|
|
||||||
widget::container(column!(
|
let mut column = widget::column::with_capacity(if id_opt.is_some() { 3 } else { 1 });
|
||||||
menu_item(
|
if let Some(id) = id_opt {
|
||||||
|
column = column.push(menu_item(
|
||||||
fl!("rename"),
|
fl!("rename"),
|
||||||
Message::ColorSchemeRename(kind, id, name.to_string())
|
Message::ColorSchemeRename(kind, id, name.to_string()),
|
||||||
),
|
));
|
||||||
menu_item(fl!("export"), Message::ColorSchemeExport(kind, id)),
|
}
|
||||||
menu_item(fl!("delete"), Message::ColorSchemeDelete(kind, id)),
|
column = column.push(menu_item(
|
||||||
))
|
fl!("export"),
|
||||||
.padding(1)
|
Message::ColorSchemeExport(kind, id_opt),
|
||||||
//TODO: move style to libcosmic
|
));
|
||||||
.style(theme::Container::custom(|theme| {
|
if let Some(id) = id_opt {
|
||||||
let cosmic = theme.cosmic();
|
column = column.push(menu_item(
|
||||||
let component = &cosmic.background.component;
|
fl!("delete"),
|
||||||
widget::container::Appearance {
|
Message::ColorSchemeDelete(kind, id),
|
||||||
icon_color: Some(component.on.into()),
|
));
|
||||||
text_color: Some(component.on.into()),
|
}
|
||||||
background: Some(Background::Color(component.base.into())),
|
|
||||||
border: Border {
|
widget::container(column)
|
||||||
radius: 8.0.into(),
|
.padding(1)
|
||||||
width: 1.0,
|
//TODO: move style to libcosmic
|
||||||
color: component.divider.into(),
|
.style(theme::Container::custom(|theme| {
|
||||||
},
|
let cosmic = theme.cosmic();
|
||||||
..Default::default()
|
let component = &cosmic.background.component;
|
||||||
}
|
widget::container::Appearance {
|
||||||
}))
|
icon_color: Some(component.on.into()),
|
||||||
.width(Length::Fixed(120.0))
|
text_color: Some(component.on.into()),
|
||||||
.into()
|
background: Some(Background::Color(component.base.into())),
|
||||||
|
border: Border {
|
||||||
|
radius: 8.0.into(),
|
||||||
|
width: 1.0,
|
||||||
|
color: component.divider.into(),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.width(Length::Fixed(120.0))
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn menu_bar<'a>(config: &Config, key_binds: &HashMap<KeyBind, Action>) -> Element<'a, Message> {
|
pub fn menu_bar<'a>(config: &Config, key_binds: &HashMap<KeyBind, Action>) -> Element<'a, Message> {
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ impl From<(&str, &Colors)> for ColorScheme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cosmic_dark() -> Colors {
|
pub fn cosmic_dark() -> Colors {
|
||||||
let mut colors = auto_colors();
|
let mut colors = auto_colors();
|
||||||
|
|
||||||
let encode_rgb = |data: u32| -> Rgb {
|
let encode_rgb = |data: u32| -> Rgb {
|
||||||
|
|
@ -289,7 +289,7 @@ fn cosmic_dark() -> Colors {
|
||||||
colors
|
colors
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cosmic_light() -> Colors {
|
pub fn cosmic_light() -> Colors {
|
||||||
let mut colors = auto_colors();
|
let mut colors = auto_colors();
|
||||||
|
|
||||||
let encode_rgb = |data: u32| -> Rgb {
|
let encode_rgb = |data: u32| -> Rgb {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue