Skip to main content

vn_settings/
lib.rs

1mod color;
2mod layer;
3mod layout;
4mod object;
5mod timing;
6
7pub use color::ColorSettings;
8pub use layer::LayerSettings;
9pub use layout::{BoxLayoutSettings, LayoutSettings, ViewLayoutSettings};
10pub use object::ObjectSettings;
11pub use timing::TimingSettings;
12
13use color::{BoxColorParameter, ColorParameter, SelectableBoxColorParameter};
14use layer::{
15    LayerAnchorParameter, LayerImageParameter, LayerLayoutParameter, LayerObjectLayoutParameter,
16};
17use layout::{BoxLayoutParameter, LayoutParameter, ViewLayoutParameter};
18use object::{ObjectAnchorParameter, ObjectImageParameter, ObjectScaleParameter};
19use timing::TimingParameter;
20
21use dialogi::{DialogChange, DialogParameter};
22use indexmap::IndexMap;
23use simple_color::Color;
24
25use std::collections::HashMap;
26
27trait Settings<Parameter> {
28    type Value;
29
30    fn get_mut(&mut self, parameter: &Parameter) -> &mut Self::Value;
31}
32
33trait Resettable {
34    fn reset(&mut self) {}
35    fn reset_aspects(&mut self) {}
36}
37
38#[derive(Default)]
39pub struct Override<T> {
40    default: T,
41    characters_default: HashMap<Box<str>, T>,
42    characters_aspect: HashMap<Box<str>, T>,
43    aspect: Option<T>,
44    characters_scene: HashMap<Box<str>, T>,
45    scene: Option<T>,
46}
47
48impl<T> Override<T> {
49    fn set_default(&mut self, name: Option<Box<str>>, value: T) {
50        if let Some(name) = name {
51            self.characters_default.insert(name, value);
52        } else {
53            self.default = value;
54        }
55    }
56
57    fn set_aspect(&mut self, name: Option<&str>, value: Option<T>) {
58        let Some(name) = name else {
59            self.aspect = value;
60            return;
61        };
62
63        if let Some(value) = value {
64            self.characters_aspect.insert(name.into(), value);
65        } else {
66            self.characters_aspect.remove(name);
67        }
68    }
69
70    fn set_scene(&mut self, name: Option<&str>, value: Option<T>) {
71        let Some(name) = name else {
72            self.scene = value;
73            return;
74        };
75
76        if let Some(value) = value {
77            self.characters_scene.insert(name.into(), value);
78        } else {
79            self.characters_scene.remove(name);
80        }
81    }
82}
83
84impl<T> Resettable for Override<T> {
85    fn reset(&mut self) {
86        self.scene = None;
87    }
88
89    fn reset_aspects(&mut self) {
90        self.aspect = None;
91        self.characters_aspect.clear();
92    }
93}
94
95impl<T> From<T> for Override<T> {
96    fn from(default: T) -> Self {
97        Self {
98            default,
99            characters_default: HashMap::new(),
100            characters_aspect: HashMap::new(),
101            aspect: None,
102            characters_scene: HashMap::new(),
103            scene: None,
104        }
105    }
106}
107
108impl<T> Override<T> {
109    pub fn get(&self, name: &str) -> T
110    where
111        T: Copy,
112    {
113        *self.get_ref(name)
114    }
115
116    pub fn get_ref(&self, name: &str) -> &T {
117        if let Some(scene) = &self.scene {
118            scene
119        } else if name.is_empty() {
120            if let Some(aspect) = &self.aspect {
121                aspect
122            } else {
123                &self.default
124            }
125        } else if let Some(character_scene) = self.characters_scene.get(name) {
126            character_scene
127        } else if let Some(aspect) = &self.aspect {
128            aspect
129        } else if let Some(character_aspect) = self.characters_aspect.get(name) {
130            character_aspect
131        } else if let Some(character_default) = self.characters_default.get(name) {
132            character_default
133        } else {
134            &self.default
135        }
136    }
137}
138
139#[derive(Default)]
140pub struct Names {
141    pub default: HashMap<Box<str>, Box<str>>,
142    pub aspect: HashMap<Box<str>, Box<str>>,
143    pub scene: HashMap<Box<str>, Box<str>>,
144}
145
146impl Names {
147    pub fn new() -> Self {
148        Self::default()
149    }
150
151    pub fn reset(&mut self) {
152        self.scene.clear();
153    }
154
155    pub fn reset_aspects(&mut self) {
156        self.aspect.clear();
157    }
158
159    pub fn get<'a>(&'a self, name: &'a str) -> &'a str {
160        self.scene
161            .get(name)
162            .or_else(|| self.aspect.get(name))
163            .or_else(|| self.default.get(name))
164            .map_or(name, |v| v)
165    }
166}
167
168type OvrrideColorSettings = ColorSettings<Override<Color>>;
169type OverrideTimingSettings = TimingSettings<Override<f32>>;
170type OverrideObjectSettings =
171    ObjectSettings<Override<Option<Box<str>>>, Override<[f32; 2]>, Override<f32>>;
172type OverrideLayerSettings =
173    LayerSettings<Override<Option<usize>>, Override<f32>, Override<Option<usize>>>;
174type OverrideLayoutSettings = LayoutSettings<Override<f32>>;
175
176pub struct PlayerSettings {
177    pub colors: OvrrideColorSettings,
178    pub timing: OverrideTimingSettings,
179    pub objects: OverrideObjectSettings,
180    pub layers: OverrideLayerSettings,
181    pub layout: OverrideLayoutSettings,
182    pub names: Names,
183}
184
185impl PlayerSettings {
186    pub fn common() -> Self {
187        Self {
188            colors: ColorSettings::common(),
189            timing: TimingSettings::common(),
190            objects: ObjectSettings::common(),
191            layers: LayerSettings::common(),
192            layout: LayoutSettings::common(),
193            names: Names::new(),
194        }
195    }
196
197    pub fn apply_setting(&mut self, context: &mut SettingsContext, key: &str, value: &str) {
198        if let Some(parameter) = Parameter::create(key, context) {
199            let setter = parameter.value_setter(value, context);
200            self.set_character_default(setter);
201        }
202    }
203
204    pub fn extract_settings(
205        &mut self,
206        context: &mut SettingsContext,
207        config_map: &mut IndexMap<Box<str>, Box<str>>,
208    ) {
209        for (key, value) in config_map.drain(..) {
210            self.apply_setting(context, &key, &value);
211        }
212    }
213
214    pub fn reset(&mut self) {
215        self.colors.reset();
216        self.timing.reset();
217        self.layers.reset();
218        self.layout.reset();
219        self.names.reset();
220    }
221
222    pub fn set_aspect(&mut self, setter: Setter) {
223        use Setter::*;
224        match setter {
225            Color(parameter, value) => self
226                .colors
227                .get_mut(&parameter.parameter)
228                .set_aspect(parameter.name.as_deref(), Some(value)),
229            Timing(parameter, value) => self
230                .timing
231                .get_mut(&parameter.parameter)
232                .set_aspect(parameter.name.as_deref(), Some(value)),
233            ObjectImage(parameter, value) => self
234                .objects
235                .get_mut(&parameter.parameter)
236                .set_aspect(parameter.name.as_deref(), Some(value)),
237            ObjectAnchor(parameter, value) => self
238                .objects
239                .get_mut(&parameter.parameter)
240                .set_aspect(parameter.name.as_deref(), Some(value)),
241            ObjectScale(parameter, value) => self
242                .objects
243                .get_mut(&parameter.parameter)
244                .set_aspect(parameter.name.as_deref(), Some(value)),
245            LayerImage(parameter, value) => self
246                .layers
247                .get_mut(&parameter.parameter)
248                .set_aspect(parameter.name.as_deref(), Some(value)),
249            LayerLayout(parameter, value) => self
250                .layers
251                .get_mut(&parameter.parameter)
252                .set_aspect(parameter.name.as_deref(), Some(value)),
253            LayerAnchor(parameter, value) => self
254                .layers
255                .get_mut(&parameter.parameter)
256                .set_aspect(parameter.name.as_deref(), Some(value)),
257            Layout(parameter, value) => self
258                .layout
259                .get_mut(&parameter.parameter)
260                .set_aspect(parameter.name.as_deref(), Some(value)),
261            Name(parameter, value) => {
262                self.names.aspect.insert(parameter, value);
263            }
264        }
265    }
266
267    pub fn reset_aspects(&mut self) {
268        self.colors.reset_aspects();
269        self.timing.reset_aspects();
270        self.objects.reset_aspects();
271        self.layers.reset_aspects();
272        self.layout.reset_aspects();
273        self.names.reset_aspects();
274    }
275}
276
277#[derive(Clone, Debug, PartialEq, Eq, Hash)]
278pub struct NamedParameter<T> {
279    name: Option<Box<str>>,
280    parameter: T,
281}
282
283trait ParameterNamer: Sized {
284    fn named(self, name: Option<Box<str>>) -> NamedParameter<Self> {
285        NamedParameter {
286            name,
287            parameter: self,
288        }
289    }
290}
291
292impl<T> ParameterNamer for T {}
293
294type NamedColorParameter = NamedParameter<ColorParameter>;
295type NamedTimingParameter = NamedParameter<TimingParameter>;
296type NamedObjectImageParameter = NamedParameter<ObjectImageParameter>;
297type NamedObjectAnchorParameter = NamedParameter<ObjectAnchorParameter>;
298type NamedObjectScaleParameter = NamedParameter<ObjectScaleParameter>;
299type NamedLayerImageParameter = NamedParameter<LayerImageParameter>;
300type NamedLayerLayoutParameter = NamedParameter<LayerLayoutParameter>;
301type NamedLayerAnchorParameter = NamedParameter<LayerAnchorParameter>;
302type NamedLayoutParameter = NamedParameter<LayoutParameter>;
303
304#[derive(Clone, Debug, PartialEq, Eq, Hash)]
305pub enum Parameter {
306    Color(NamedColorParameter),
307    Timing(NamedTimingParameter),
308    ObjectImage(NamedObjectImageParameter),
309    ObjectAnchor(NamedObjectAnchorParameter),
310    ObjectScale(NamedObjectScaleParameter),
311    LayerImage(NamedLayerImageParameter),
312    LayerLayout(NamedLayerLayoutParameter),
313    LayerAnchor(NamedLayerAnchorParameter),
314    Layout(NamedLayoutParameter),
315    Name(Box<str>),
316}
317
318pub struct Object {
319    index: usize,
320    images: HashMap<Box<str>, usize>,
321}
322
323impl Object {
324    fn new(index: usize) -> Self {
325        Self {
326            index,
327            images: HashMap::new(),
328        }
329    }
330}
331
332pub struct LayerInfo {
333    pub name: Box<str>,
334    pub path: Box<str>,
335}
336
337pub fn extract_layers(layers: &mut Vec<LayerInfo>, config_map: &mut IndexMap<Box<str>, Box<str>>) {
338    let keys: Vec<_> = config_map.keys().cloned().collect();
339    for key in keys {
340        let Some(("Layer", name)) = key.split_once(':') else {
341            continue;
342        };
343
344        let path = config_map.shift_remove(&key).expect("Invalid layer");
345        layers.push(LayerInfo {
346            name: name.into(),
347            path,
348        });
349    }
350
351    if layers.is_empty() {
352        layers.push(LayerInfo {
353            name: "Background".into(),
354            path: Box::default(),
355        });
356        layers.push(LayerInfo {
357            name: "Character".into(),
358            path: Box::default(),
359        });
360    }
361}
362
363#[derive(Default)]
364pub struct SettingsContext {
365    pub object_cache: HashMap<Box<str>, Object>,
366    pub layers: Vec<LayerInfo>,
367    pub anchors: HashMap<Box<str>, usize>,
368}
369
370impl SettingsContext {
371    pub fn new() -> Self {
372        Self::default()
373    }
374}
375
376impl Parameter {
377    fn create_character(name: &str, context: &mut SettingsContext) -> Option<Self> {
378        let (main, sub) = name.split_once(':')?;
379
380        if main != "Character" {
381            return None;
382        }
383
384        let (character_name, option) = sub.split_once(':')?;
385
386        let character_name = character_name.into();
387        if option == "name" {
388            Some(Self::Name(character_name))
389        } else {
390            create_parameter(option, Some(character_name), context)
391        }
392    }
393
394    pub fn value_setter(self, value: &str, context: &mut SettingsContext) -> Setter {
395        fn color(repr: &str) -> Color {
396            match repr {
397                "black" => Color::BLACK,
398                "white" => Color::WHITE,
399
400                "red" => Color::RED,
401                "yellow" => Color::YELLOW,
402                "green" => Color::GREEN,
403                "cyan" => Color::CYAN,
404                "blue" => Color::BLUE,
405                "magenta" => Color::MAGENTA,
406
407                _ => repr
408                    .parse::<Color>()
409                    .unwrap_or_else(|_| panic!("Color '{repr}' does not exist")),
410            }
411        }
412
413        match self {
414            Self::Color(parameter) => Setter::Color(parameter, color(value)),
415            Self::Timing(parameter) => Setter::Timing(
416                parameter,
417                value.parse().expect("Parsing timing parameter failed"),
418            ),
419            Self::ObjectImage(parameter) => Setter::ObjectImage(parameter, Some(value.into())),
420            Self::ObjectAnchor(parameter) => Setter::ObjectAnchor(parameter, {
421                let (x, y) = value
422                    .split_once(char::is_whitespace)
423                    .expect("Parsing object anchor parameter failed");
424                let x = x.parse().expect("Parsing object anchor parameter failed");
425                let y = y.parse().expect("Parsing object anchor parameter failed");
426                [x, y]
427            }),
428            Self::ObjectScale(parameter) => Setter::ObjectScale(
429                parameter,
430                value.parse().expect("Parsing image scale parameter failed"),
431            ),
432            Self::LayerImage(parameter) => {
433                let index = if value.is_empty() {
434                    None
435                } else {
436                    let path = &context.layers[parameter.parameter.0].path;
437                    let path_holder;
438                    let full_path = if path.is_empty() {
439                        value
440                    } else {
441                        path_holder = format!("{path}:{value}");
442                        &path_holder
443                    };
444                    if let Some(Object { index, .. }) = context.object_cache.get(full_path) {
445                        Some(*index)
446                    } else {
447                        eprintln!("Undefined image object {value:?}");
448                        None
449                    }
450                };
451                Setter::LayerImage(parameter, index)
452            }
453            Self::LayerLayout(parameter) => Setter::LayerLayout(
454                parameter,
455                value
456                    .parse()
457                    .expect("Parsing object layout parameter failed"),
458            ),
459            Self::LayerAnchor(parameter) => {
460                let index = if value.is_empty() {
461                    None
462                } else {
463                    let anchor_index = context.anchors.len();
464                    Some(*context.anchors.entry(value.into()).or_insert(anchor_index))
465                };
466                Setter::LayerAnchor(parameter, index)
467            }
468            Self::Layout(parameter) => Setter::Layout(
469                parameter,
470                value.parse().expect("Parsing layout parameter failed"),
471            ),
472            Self::Name(parameter) => Setter::Name(parameter, value.into()),
473        }
474    }
475}
476
477fn create_parameter(
478    parameter_name: &str,
479    character_name: Option<Box<str>>,
480    context: &mut SettingsContext,
481) -> Option<Parameter> {
482    let (path, parameter_name) = parameter_name.split_once(':')?;
483    Some(match path {
484        "Color" => Parameter::Color(
485            match parameter_name {
486                "background" => ColorParameter::Background,
487                "foreground" => ColorParameter::Foreground,
488                "dialog-text-fill" => ColorParameter::Dialog(BoxColorParameter::TextFill),
489                "dialog-text-line" => ColorParameter::Dialog(BoxColorParameter::TextLine),
490                "dialog-name-fill" => ColorParameter::Dialog(BoxColorParameter::NameFill),
491                "dialog-name-line" => ColorParameter::Dialog(BoxColorParameter::NameLine),
492
493                "choice-default-text-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
494                    selected: false,
495                    parameter: BoxColorParameter::TextFill,
496                }),
497                "choice-default-text-line" => ColorParameter::Choice(SelectableBoxColorParameter {
498                    selected: false,
499                    parameter: BoxColorParameter::TextLine,
500                }),
501                "choice-default-name-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
502                    selected: false,
503                    parameter: BoxColorParameter::NameFill,
504                }),
505                "choice-default-name-line" => ColorParameter::Choice(SelectableBoxColorParameter {
506                    selected: false,
507                    parameter: BoxColorParameter::NameLine,
508                }),
509                "choice-select-text-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
510                    selected: true,
511                    parameter: BoxColorParameter::TextFill,
512                }),
513                "choice-select-text-line" => ColorParameter::Choice(SelectableBoxColorParameter {
514                    selected: true,
515                    parameter: BoxColorParameter::TextLine,
516                }),
517                "choice-select-name-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
518                    selected: true,
519                    parameter: BoxColorParameter::NameFill,
520                }),
521                "choice-select-name-line" => ColorParameter::Choice(SelectableBoxColorParameter {
522                    selected: true,
523                    parameter: BoxColorParameter::NameLine,
524                }),
525
526                "revert-default-text-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
527                    selected: false,
528                    parameter: BoxColorParameter::TextFill,
529                }),
530                "revert-default-text-line" => ColorParameter::Revert(SelectableBoxColorParameter {
531                    selected: false,
532                    parameter: BoxColorParameter::TextLine,
533                }),
534                "revert-default-name-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
535                    selected: false,
536                    parameter: BoxColorParameter::NameFill,
537                }),
538                "revert-default-name-line" => ColorParameter::Revert(SelectableBoxColorParameter {
539                    selected: false,
540                    parameter: BoxColorParameter::NameLine,
541                }),
542                "revert-select-text-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
543                    selected: true,
544                    parameter: BoxColorParameter::TextFill,
545                }),
546                "revert-select-text-line" => ColorParameter::Revert(SelectableBoxColorParameter {
547                    selected: true,
548                    parameter: BoxColorParameter::TextLine,
549                }),
550                "revert-select-name-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
551                    selected: true,
552                    parameter: BoxColorParameter::NameFill,
553                }),
554                "revert-select-name-line" => ColorParameter::Revert(SelectableBoxColorParameter {
555                    selected: true,
556                    parameter: BoxColorParameter::NameLine,
557                }),
558
559                _ => return None,
560            }
561            .named(character_name),
562        ),
563
564        "Timing" => Parameter::Timing(
565            match parameter_name {
566                "auto-next" => TimingParameter::AutoNext,
567                "letter" => TimingParameter::Letter,
568                "line" => TimingParameter::Line,
569                "select" => TimingParameter::Select,
570                "view" => TimingParameter::View,
571
572                _ => return None,
573            }
574            .named(character_name),
575        ),
576
577        "Image" => {
578            let (object_name, parameter_name) = parameter_name.rsplit_once(':')?;
579
580            let entry_count = context.object_cache.len();
581            let Object { index, images } = context
582                .object_cache
583                .entry(object_name.into())
584                .or_insert_with(|| Object::new(entry_count));
585
586            let image_index = images.len();
587            let parameter_index = *images.entry(parameter_name.into()).or_insert(image_index);
588
589            Parameter::ObjectImage(
590                ObjectImageParameter(*index, parameter_index).named(character_name),
591            )
592        }
593
594        "Anchor" => {
595            let (object_name, parameter_name) = parameter_name.rsplit_once(':')?;
596
597            let entry_count = context.object_cache.len();
598            let Object { index, .. } = context
599                .object_cache
600                .entry(object_name.into())
601                .or_insert_with(|| Object::new(entry_count));
602
603            let anchor_index = context.anchors.len();
604            let parameter_index = *context
605                .anchors
606                .entry(parameter_name.into())
607                .or_insert(anchor_index);
608
609            Parameter::ObjectAnchor(
610                ObjectAnchorParameter(*index, parameter_index).named(character_name),
611            )
612        }
613
614        "Transform" => {
615            let (object_name, parameter_name) = parameter_name.rsplit_once(':')?;
616
617            if parameter_name != "scale" {
618                return None;
619            }
620
621            let entry_count = context.object_cache.len();
622            let Object { index, .. } = context
623                .object_cache
624                .entry(object_name.into())
625                .or_insert_with(|| Object::new(entry_count));
626
627            Parameter::ObjectScale(ObjectScaleParameter(*index).named(character_name))
628        }
629
630        "Object" => {
631            let (layer_name, parameter_name) = parameter_name.split_once(':')?;
632            let layer = context
633                .layers
634                .iter()
635                .position(|layer| &*layer.name == layer_name)?;
636
637            match parameter_name {
638                "image" => Parameter::LayerImage(LayerImageParameter(layer).named(character_name)),
639                "hor" => Parameter::LayerLayout(
640                    LayerLayoutParameter {
641                        layer,
642                        layout: LayerObjectLayoutParameter::Hor,
643                    }
644                    .named(character_name),
645                ),
646                "ver" => Parameter::LayerLayout(
647                    LayerLayoutParameter {
648                        layer,
649                        layout: LayerObjectLayoutParameter::Ver,
650                    }
651                    .named(character_name),
652                ),
653                "scale" => Parameter::LayerLayout(
654                    LayerLayoutParameter {
655                        layer,
656                        layout: LayerObjectLayoutParameter::Scale,
657                    }
658                    .named(character_name),
659                ),
660                "anchor" => {
661                    Parameter::LayerAnchor(LayerAnchorParameter(layer).named(character_name))
662                }
663
664                _ => return None,
665            }
666        }
667
668        "Layout" => Parameter::Layout(
669            {
670                let (subpath, parameter_name) = parameter_name.split_once(':')?;
671                let box_layout_parameter = || {
672                    Some(match parameter_name {
673                        "hor" => BoxLayoutParameter::Hor,
674                        "ver" => BoxLayoutParameter::Ver,
675                        "width" => BoxLayoutParameter::Width,
676                        "height" => BoxLayoutParameter::Height,
677                        "corner" => BoxLayoutParameter::Corner,
678                        "line" => BoxLayoutParameter::Line,
679                        "text-size" => BoxLayoutParameter::TextSize,
680                        "name-size" => BoxLayoutParameter::NameSize,
681
682                        _ => return None,
683                    })
684                };
685
686                let view_layout_parameter = || {
687                    Some(match parameter_name {
688                        "hor" => ViewLayoutParameter::Hor,
689                        "ver" => ViewLayoutParameter::Ver,
690                        "zoom" => ViewLayoutParameter::Zoom,
691
692                        _ => return None,
693                    })
694                };
695
696                match subpath {
697                    "Main" => box_layout_parameter()?.main(),
698                    "List" => box_layout_parameter()?.list(),
699                    "View" => LayoutParameter::View(view_layout_parameter()?),
700
701                    _ => return None,
702                }
703            }
704            .named(character_name),
705        ),
706
707        _ => return None,
708    })
709}
710
711impl Parameter {
712    pub fn create_setter(key: &str, value: &str, context: &mut SettingsContext) -> Option<Setter> {
713        let parameter = if let Some(p) = create_parameter(key, None, context) {
714            p
715        } else {
716            Self::create_character(key, context)?
717        };
718        Some(parameter.value_setter(value, context))
719    }
720}
721
722impl DialogParameter for Parameter {
723    type Context = SettingsContext;
724
725    fn create(name: &str, context: &mut SettingsContext) -> Option<Self> {
726        if name == "-" {
727            None
728        } else if let Some(parameter) = create_parameter(name, None, context) {
729            Some(parameter)
730        } else {
731            let result = Self::create_character(name, context);
732            if result.is_none() {
733                eprintln!("Setting not availabe: {name}");
734            }
735            result
736        }
737    }
738}
739
740#[derive(Clone)]
741pub enum Setter {
742    Color(NamedColorParameter, Color),
743    Timing(NamedTimingParameter, f32),
744    ObjectImage(NamedObjectImageParameter, Option<Box<str>>),
745    ObjectAnchor(NamedObjectAnchorParameter, [f32; 2]),
746    ObjectScale(NamedObjectScaleParameter, f32),
747    LayerImage(NamedLayerImageParameter, Option<usize>),
748    LayerLayout(NamedLayerLayoutParameter, f32),
749    LayerAnchor(NamedLayerAnchorParameter, Option<usize>),
750    Layout(NamedLayoutParameter, f32),
751    Name(Box<str>, Box<str>),
752}
753
754impl Setter {
755    pub fn change(self) -> Change {
756        match self {
757            Self::Color(parameter, value) => Change::Color(parameter, Some(value)),
758            Self::Timing(parameter, value) => Change::Timing(parameter, Some(value)),
759            Self::ObjectImage(parameter, value) => Change::ObjectImage(parameter, Some(value)),
760            Self::ObjectAnchor(parameter, value) => Change::ObjectAnchor(parameter, Some(value)),
761            Self::ObjectScale(parameter, value) => Change::ObjectScale(parameter, Some(value)),
762            Self::LayerImage(parameter, value) => Change::LayerImage(parameter, Some(value)),
763            Self::LayerLayout(parameter, value) => Change::LayerLayout(parameter, Some(value)),
764            Self::LayerAnchor(parameter, value) => Change::LayerAnchor(parameter, Some(value)),
765            Self::Layout(parameter, value) => Change::Layout(parameter, Some(value)),
766            Self::Name(parameter, value) => Change::Name(parameter, Some(value)),
767        }
768    }
769}
770
771pub enum Change {
772    Color(NamedColorParameter, Option<Color>),
773    Timing(NamedTimingParameter, Option<f32>),
774    ObjectImage(NamedObjectImageParameter, Option<Option<Box<str>>>),
775    ObjectAnchor(NamedObjectAnchorParameter, Option<[f32; 2]>),
776    ObjectScale(NamedObjectScaleParameter, Option<f32>),
777    LayerImage(NamedLayerImageParameter, Option<Option<usize>>),
778    LayerLayout(NamedLayerLayoutParameter, Option<f32>),
779    LayerAnchor(NamedLayerAnchorParameter, Option<Option<usize>>),
780    Layout(NamedLayoutParameter, Option<f32>),
781    Name(Box<str>, Option<Box<str>>),
782}
783
784impl Change {
785    pub fn parameter(&self) -> Parameter {
786        match self {
787            Self::Color(parameter, _) => Parameter::Color(parameter.clone()),
788            Self::Timing(parameter, _) => Parameter::Timing(parameter.clone()),
789            Self::ObjectImage(parameter, _) => Parameter::ObjectImage(parameter.clone()),
790            Self::ObjectAnchor(parameter, _) => Parameter::ObjectAnchor(parameter.clone()),
791            Self::ObjectScale(parameter, _) => Parameter::ObjectScale(parameter.clone()),
792            Self::LayerImage(parameter, _) => Parameter::LayerImage(parameter.clone()),
793            Self::LayerLayout(parameter, _) => Parameter::LayerLayout(parameter.clone()),
794            Self::LayerAnchor(parameter, _) => Parameter::LayerAnchor(parameter.clone()),
795            Self::Layout(parameter, _) => Parameter::Layout(parameter.clone()),
796            Self::Name(parameter, _) => Parameter::Name(parameter.clone()),
797        }
798    }
799}
800
801impl DialogChange for Change {
802    type Parameter = Parameter;
803
804    fn default_change(parameter: Parameter) -> Self {
805        match parameter {
806            Parameter::Color(parameter) => Self::Color(parameter, None),
807            Parameter::Timing(parameter) => Self::Timing(parameter, None),
808            Parameter::ObjectImage(parameter) => Self::ObjectImage(parameter, None),
809            Parameter::ObjectAnchor(parameter) => Self::ObjectAnchor(parameter, None),
810            Parameter::ObjectScale(parameter) => Self::ObjectScale(parameter, None),
811            Parameter::LayerImage(parameter) => Self::LayerImage(parameter, None),
812            Parameter::LayerLayout(parameter) => Self::LayerLayout(parameter, None),
813            Parameter::LayerAnchor(parameter) => Self::LayerAnchor(parameter, None),
814            Parameter::Layout(parameter) => Self::Layout(parameter, None),
815            Parameter::Name(parameter) => Self::Name(parameter, None),
816        }
817    }
818
819    fn value_change(parameter: Parameter, value: &str, context: &mut SettingsContext) -> Self {
820        parameter.value_setter(value, context).change()
821    }
822}
823
824impl PlayerSettings {
825    pub fn revert(&mut self, parameter: &Parameter) {
826        use Parameter::*;
827        match parameter {
828            Color(parameter) => self
829                .colors
830                .get_mut(&parameter.parameter)
831                .set_scene(parameter.name.as_deref(), None),
832            Timing(parameter) => self
833                .timing
834                .get_mut(&parameter.parameter)
835                .set_scene(parameter.name.as_deref(), None),
836            ObjectImage(parameter) => self
837                .objects
838                .get_mut(&parameter.parameter)
839                .set_scene(parameter.name.as_deref(), None),
840            ObjectAnchor(parameter) => self
841                .objects
842                .get_mut(&parameter.parameter)
843                .set_scene(parameter.name.as_deref(), None),
844            ObjectScale(parameter) => self
845                .objects
846                .get_mut(&parameter.parameter)
847                .set_scene(parameter.name.as_deref(), None),
848            LayerImage(parameter) => self
849                .layers
850                .get_mut(&parameter.parameter)
851                .set_scene(parameter.name.as_deref(), None),
852            LayerLayout(parameter) => self
853                .layers
854                .get_mut(&parameter.parameter)
855                .set_scene(parameter.name.as_deref(), None),
856            LayerAnchor(parameter) => self
857                .layers
858                .get_mut(&parameter.parameter)
859                .set_scene(parameter.name.as_deref(), None),
860            Layout(parameter) => self
861                .layout
862                .get_mut(&parameter.parameter)
863                .set_scene(parameter.name.as_deref(), None),
864            Name(parameter) => {
865                self.names.scene.remove(parameter);
866            }
867        }
868    }
869
870    pub fn change(&mut self, change: &Change) {
871        use Change::*;
872        match change {
873            Color(parameter, value) => self
874                .colors
875                .get_mut(&parameter.parameter)
876                .set_scene(parameter.name.as_deref(), *value),
877            Timing(parameter, value) => self
878                .timing
879                .get_mut(&parameter.parameter)
880                .set_scene(parameter.name.as_deref(), *value),
881            ObjectImage(parameter, value) => self
882                .objects
883                .get_mut(&parameter.parameter)
884                .set_scene(parameter.name.as_deref(), value.clone()),
885            ObjectScale(parameter, value) => self
886                .objects
887                .get_mut(&parameter.parameter)
888                .set_scene(parameter.name.as_deref(), *value),
889            ObjectAnchor(parameter, value) => self
890                .objects
891                .get_mut(&parameter.parameter)
892                .set_scene(parameter.name.as_deref(), *value),
893            LayerImage(parameter, value) => self
894                .layers
895                .get_mut(&parameter.parameter)
896                .set_scene(parameter.name.as_deref(), *value),
897            LayerLayout(parameter, value) => self
898                .layers
899                .get_mut(&parameter.parameter)
900                .set_scene(parameter.name.as_deref(), *value),
901            LayerAnchor(parameter, value) => self
902                .layers
903                .get_mut(&parameter.parameter)
904                .set_scene(parameter.name.as_deref(), *value),
905            Layout(parameter, value) => self
906                .layout
907                .get_mut(&parameter.parameter)
908                .set_scene(parameter.name.as_deref(), *value),
909            Name(parameter, value) => {
910                if let Some(value) = value {
911                    self.names.scene.insert(parameter.clone(), value.clone());
912                } else {
913                    self.names.scene.remove(parameter);
914                }
915            }
916        }
917    }
918
919    pub fn set_character_default(&mut self, change: Setter) {
920        use Setter::*;
921        match change {
922            Color(parameter, value) => self
923                .colors
924                .get_mut(&parameter.parameter)
925                .set_default(parameter.name, value),
926            Timing(parameter, value) => self
927                .timing
928                .get_mut(&parameter.parameter)
929                .set_default(parameter.name, value),
930            ObjectImage(parameter, value) => self
931                .objects
932                .get_mut(&parameter.parameter)
933                .set_default(parameter.name, value),
934            ObjectAnchor(parameter, value) => self
935                .objects
936                .get_mut(&parameter.parameter)
937                .set_default(parameter.name, value),
938            ObjectScale(parameter, value) => self
939                .objects
940                .get_mut(&parameter.parameter)
941                .set_default(parameter.name, value),
942            LayerImage(parameter, value) => self
943                .layers
944                .get_mut(&parameter.parameter)
945                .set_default(parameter.name, value),
946            LayerLayout(parameter, value) => self
947                .layers
948                .get_mut(&parameter.parameter)
949                .set_default(parameter.name, value),
950            LayerAnchor(parameter, value) => self
951                .layers
952                .get_mut(&parameter.parameter)
953                .set_default(parameter.name, value),
954            Layout(parameter, value) => self
955                .layout
956                .get_mut(&parameter.parameter)
957                .set_default(parameter.name, value),
958            Name(parameter, value) => {
959                self.names.default.insert(parameter, value);
960            }
961        }
962    }
963}