112 lines
3.6 KiB
Rust
112 lines
3.6 KiB
Rust
use adw::glib::gobject_ffi::GValue;
|
|
use adw::glib::GString;
|
|
use adw::prelude::*;
|
|
use gtk::prelude::*;
|
|
use gtk::{StringList, Widget};
|
|
use relm4::{factory::FactoryView, gtk, prelude::*, FactorySender, RelmObjectExt};
|
|
use std::cell::{Cell, RefCell};
|
|
use std::rc::Rc;
|
|
|
|
#[derive(Debug)]
|
|
pub enum Msg {}
|
|
|
|
#[derive(Debug)]
|
|
pub enum OutputMsg {}
|
|
|
|
pub enum SettingType {
|
|
Select(Vec<&'static str>, Option<Box<dyn Fn(usize)>>),
|
|
Action,
|
|
Entry(
|
|
Option<String>,
|
|
Option<Box<dyn Fn(&str) -> bool>>,
|
|
Option<Box<dyn Fn(&str)>>,
|
|
),
|
|
Switch(bool, Option<Rc<Cell<bool>>>),
|
|
Spin(f64, f64, f64, f64, Option<Rc<Cell<f64>>>),
|
|
}
|
|
|
|
pub struct SettingItem {
|
|
title: String,
|
|
pub _type: SettingType,
|
|
}
|
|
|
|
impl SettingItem {
|
|
pub fn new(title: String, _type: SettingType) -> Self {
|
|
Self { title, _type }
|
|
}
|
|
pub fn widget(&mut self) -> Widget {
|
|
(match &mut self._type {
|
|
SettingType::Select(selects, selected) => {
|
|
let w = adw::ComboRow::builder().title(&self.title).build();
|
|
if let Some(selected) = selected.take() {
|
|
w.connect_selected_notify(move |s| {
|
|
selected(s.selected() as usize);
|
|
});
|
|
}
|
|
let model = StringList::new(selects.as_ref());
|
|
w.set_model(Some(&model));
|
|
w.upcast::<Widget>()
|
|
}
|
|
SettingType::Action => adw::EntryRow::builder()
|
|
.title(&self.title)
|
|
.build()
|
|
.upcast::<Widget>(),
|
|
SettingType::Entry(text, f, buffer) => {
|
|
let w = adw::EntryRow::new();
|
|
w.set_title(&self.title);
|
|
if let Some(text) = text {
|
|
w.set_text(text);
|
|
}
|
|
|
|
if let Some(f) = f.take() {
|
|
let mut buffer = buffer.take();
|
|
w.connect_text_notify(move |s| {
|
|
let text = s.text();
|
|
if !f(text.as_str()) {
|
|
s.add_css_class("error");
|
|
return;
|
|
} else {
|
|
s.remove_css_class("error");
|
|
}
|
|
|
|
if let Some(buffer) = buffer.as_ref() {
|
|
buffer(text.as_str());
|
|
}
|
|
});
|
|
}
|
|
w.upcast::<Widget>()
|
|
}
|
|
SettingType::Switch(t, v) => {
|
|
let w = adw::SwitchRow::new();
|
|
w.set_title(&self.title);
|
|
w.set_active(*t);
|
|
if let Some(v) = v {
|
|
let v = v.clone();
|
|
w.connect_active_notify(move |s| {
|
|
v.set(s.is_active());
|
|
});
|
|
}
|
|
w.upcast::<Widget>()
|
|
}
|
|
SettingType::Spin(min, max, clamb, value, v) => {
|
|
let w = adw::SpinRow::new(
|
|
Some(>k::Adjustment::new(*value, *min, *max, *clamb, 0.0, 0.0)),
|
|
*clamb,
|
|
0,
|
|
);
|
|
w.set_numeric(true);
|
|
if let Some(v) = v {
|
|
let v = v.clone();
|
|
w.connect_value_notify(move |s| {
|
|
v.set(s.value());
|
|
});
|
|
}
|
|
// w.set_range(*min, *max);
|
|
w.set_value(*value);
|
|
w.set_title(&self.title);
|
|
w.upcast::<Widget>()
|
|
}
|
|
})
|
|
}
|
|
}
|