Skip to content

Commit

Permalink
Include builtin cosmic dark and light theme in color schemes list, fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jackpot51 committed Jun 5, 2024
1 parent 6946876 commit c0d1ab1
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 123 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

231 changes: 138 additions & 93 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,9 @@ pub enum Message {
AppTheme(AppTheme),
ColorSchemeCollapse,
ColorSchemeDelete(ColorSchemeKind, ColorSchemeId),
ColorSchemeExpand(ColorSchemeKind, ColorSchemeId),
ColorSchemeExport(ColorSchemeKind, ColorSchemeId),
ColorSchemeExportResult(ColorSchemeKind, ColorSchemeId, DialogResult),
ColorSchemeExpand(ColorSchemeKind, Option<ColorSchemeId>),
ColorSchemeExport(ColorSchemeKind, Option<ColorSchemeId>),
ColorSchemeExportResult(ColorSchemeKind, Option<ColorSchemeId>, DialogResult),
ColorSchemeImport(ColorSchemeKind),
ColorSchemeImportResult(ColorSchemeKind, DialogResult),
ColorSchemeRename(ColorSchemeKind, ColorSchemeId, String),
Expand Down Expand Up @@ -401,7 +401,7 @@ pub struct App {
startup_options: Option<tty::Options>,
term_config: term::Config,
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_rename_id: widget::Id,
color_scheme_tab_model: widget::segmented_button::SingleSelectModel,
Expand Down Expand Up @@ -696,65 +696,67 @@ impl App {
.into(),
);

if !self.config.color_schemes(color_scheme_kind).is_empty() {
let mut section = widget::settings::view_section("");
for (color_scheme_name, color_scheme_id) in
self.config.color_scheme_names(color_scheme_kind)
{
let expanded =
self.color_scheme_expanded == Some((color_scheme_kind, color_scheme_id));
let renaming = match &self.color_scheme_renaming {
Some((kind, id, value))
if kind == &color_scheme_kind && id == &color_scheme_id =>
{
Some(value)
}
_ => None,
};

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);

let mut popover = widget::popover(button);
if expanded {
let menu = menu::color_scheme_menu(
color_scheme_kind,
color_scheme_id,
&color_scheme_name,
);
popover = popover
.popup(menu)
.position(widget::popover::Position::Bottom);
let mut section = widget::settings::view_section("");
let builtin_name = format!("COSMIC {:?}", color_scheme_kind);
let color_scheme_names = 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
.into_iter()
.map(|(name, id)| (name, Some(id))),
) {
let expanded =
self.color_scheme_expanded == Some((color_scheme_kind, color_scheme_id_opt));
let renaming = match &self.color_scheme_renaming {
Some((kind, id, value))
if kind == &color_scheme_kind && Some(id) == color_scheme_id_opt.as_ref() =>
{
Some(value)
}
_ => None,
};

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);
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_opt),
)
}
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(
widget::row::with_children(vec![
Expand Down Expand Up @@ -1520,24 +1522,27 @@ impl Application for App {
.remove(&color_scheme_id);
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;
if let Some(color_scheme) = self
.config
.color_schemes(color_scheme_kind)
.get(&color_scheme_id)
{
if let Some(color_scheme_name) = match color_scheme_id_opt {
Some(color_scheme_id) => self
.config
.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() {
let (dialog, command) = Dialog::new(
DialogKind::SaveFile {
filename: format!("{}.ron", color_scheme.name),
filename: format!("{}.ron", color_scheme_name),
},
None,
Message::DialogMessage,
move |result| {
Message::ColorSchemeExportResult(
color_scheme_kind,
color_scheme_id,
color_scheme_id_opt,
result,
)
},
Expand All @@ -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
self.dialog_opt = None;
if let DialogResult::Open(paths) = result {
let path = &paths[0];
if let Some(color_scheme) = self
.config
.color_schemes(color_scheme_kind)
.get(&color_scheme_id)
{
match ron::ser::to_string_pretty(
&color_scheme,
ron::ser::PrettyConfig::new(),
) {
Ok(ron) => {
if let Err(err) = fs::write(path, ron) {
match color_scheme_id_opt {
Some(color_scheme_id) => {
if let Some(color_scheme) = self
.config
.color_schemes(color_scheme_kind)
.get(&color_scheme_id)
{
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_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!(
"failed to export {:?} to {:?}: {}",
color_scheme_id,
path,
"failed to serialize color scheme {:?}: {}",
color_scheme.name,
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) => {
self.color_scheme_expanded = Some((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_opt));
}
Message::ColorSchemeImport(color_scheme_kind) => {
if self.dialog_opt.is_none() {
Expand Down
65 changes: 38 additions & 27 deletions src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,39 +97,50 @@ pub fn context_menu<'a>(

pub fn color_scheme_menu<'a>(
kind: ColorSchemeKind,
id: ColorSchemeId,
id_opt: Option<ColorSchemeId>,
name: &str,
) -> Element<'a, Message> {
let menu_item =
|label, message| menu_button(vec![widget::text(label).into()]).on_press(message);

widget::container(column!(
menu_item(
let mut column = widget::column::with_capacity(if id_opt.is_some() { 3 } else { 1 });
if let Some(id) = id_opt {
column = column.push(menu_item(
fl!("rename"),
Message::ColorSchemeRename(kind, id, name.to_string())
),
menu_item(fl!("export"), Message::ColorSchemeExport(kind, id)),
menu_item(fl!("delete"), Message::ColorSchemeDelete(kind, id)),
))
.padding(1)
//TODO: move style to libcosmic
.style(theme::Container::custom(|theme| {
let cosmic = theme.cosmic();
let component = &cosmic.background.component;
widget::container::Appearance {
icon_color: Some(component.on.into()),
text_color: Some(component.on.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()
Message::ColorSchemeRename(kind, id, name.to_string()),
));
}
column = column.push(menu_item(
fl!("export"),
Message::ColorSchemeExport(kind, id_opt),
));
if let Some(id) = id_opt {
column = column.push(menu_item(
fl!("delete"),
Message::ColorSchemeDelete(kind, id),
));
}

widget::container(column)
.padding(1)
//TODO: move style to libcosmic
.style(theme::Container::custom(|theme| {
let cosmic = theme.cosmic();
let component = &cosmic.background.component;
widget::container::Appearance {
icon_color: Some(component.on.into()),
text_color: Some(component.on.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> {
Expand Down
Loading

0 comments on commit c0d1ab1

Please sign in to comment.