use anyhow::Result;
use termusiclib::config::{SharedTuiSettings, TuiOverlay};
use tui_realm_stdlib::{Radio, Span};
use tuirealm::props::{Alignment, BorderSides, BorderType, Borders, TextSpan};
use tuirealm::{AttrValue, Attribute, Component, Event, MockComponent};
use super::popups::{YNConfirm, YNConfirmStyle};
use crate::ui::ids::{Id, IdConfigEditor};
use crate::ui::model::{Model, UserEvent};
use crate::ui::msg::{ConfigEditorLayout, ConfigEditorMsg, Msg};
mod color;
mod general;
mod key_combo;
mod update;
mod view;
#[derive(MockComponent)]
pub struct CEHeader {
component: Radio,
}
impl CEHeader {
pub fn new(layout: ConfigEditorLayout, config: &TuiOverlay) -> Self {
let mut this = Self {
component: Radio::default()
.borders(
Borders::default()
.modifiers(BorderType::Plain)
.sides(BorderSides::BOTTOM)
.color(config.settings.theme.library_highlight()),
)
.choices(ConfigEditorLayout::choice_array())
.foreground(config.settings.theme.library_highlight())
.background(config.settings.theme.library_background())
.value(layout.to_array_idx()),
};
this.attr(Attribute::Focus, AttrValue::Flag(true));
this
}
}
impl Component<Msg, UserEvent> for CEHeader {
fn on(&mut self, _ev: Event<UserEvent>) -> Option<Msg> {
None
}
}
#[derive(MockComponent)]
pub struct CEFooter {
component: Span,
}
impl CEFooter {
pub fn new(config: &TuiOverlay) -> Self {
Self {
component: Span::default()
.background(config.settings.theme.library_background())
.spans([
TextSpan::new(" Save parameters: ").bold(),
TextSpan::new(format!("<{}>", config.settings.keys.config_keys.save))
.bold()
.fg(config.settings.theme.library_highlight()),
TextSpan::new(" Exit: ").bold(),
TextSpan::new(format!("<{}>", config.settings.keys.escape))
.bold()
.fg(config.settings.theme.library_highlight()),
TextSpan::new(" Change panel: ").bold(),
TextSpan::new("<TAB>")
.bold()
.fg(config.settings.theme.library_highlight()),
TextSpan::new(" Change field: ").bold(),
TextSpan::new("<UP/DOWN>")
.bold()
.fg(config.settings.theme.library_highlight()),
TextSpan::new(" Select theme/Preview symbol: ").bold(),
TextSpan::new("<ENTER>")
.bold()
.fg(config.settings.theme.library_highlight()),
]),
}
}
}
impl Component<Msg, UserEvent> for CEFooter {
fn on(&mut self, _ev: Event<UserEvent>) -> Option<Msg> {
None
}
}
#[derive(MockComponent)]
pub struct ConfigSavePopup {
component: YNConfirm,
}
impl ConfigSavePopup {
pub fn new(config: SharedTuiSettings) -> Self {
let component =
YNConfirm::new_with_cb(config, " Config changed. Do you want to save? ", |config| {
YNConfirmStyle {
foreground_color: config.settings.theme.important_popup_foreground(),
background_color: config.settings.theme.important_popup_background(),
border_color: config.settings.theme.important_popup_border(),
title_alignment: Alignment::Center,
}
});
Self { component }
}
}
impl Component<Msg, UserEvent> for ConfigSavePopup {
fn on(&mut self, ev: Event<UserEvent>) -> Option<Msg> {
self.component.on(
ev,
Msg::ConfigEditor(ConfigEditorMsg::ConfigSaveOk),
Msg::ConfigEditor(ConfigEditorMsg::ConfigSaveCancel),
)
}
}
impl Model {
fn remount_config_header_footer(&mut self) -> Result<()> {
let layout = self.config_editor.last_layout;
self.app.remount(
Id::ConfigEditor(IdConfigEditor::Header),
Box::new(CEHeader::new(layout, &self.config_tui.read())),
Vec::new(),
)?;
self.app.remount(
Id::ConfigEditor(IdConfigEditor::Footer),
Box::new(CEFooter::new(&self.config_tui.read())),
Vec::new(),
)?;
Ok(())
}
fn umount_config_header_footer(&mut self) -> Result<()> {
self.app.umount(&Id::ConfigEditor(IdConfigEditor::Header))?;
self.app.umount(&Id::ConfigEditor(IdConfigEditor::Footer))?;
Ok(())
}
}