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(¶meter.parameter)
228 .set_aspect(parameter.name.as_deref(), Some(value)),
229 Timing(parameter, value) => self
230 .timing
231 .get_mut(¶meter.parameter)
232 .set_aspect(parameter.name.as_deref(), Some(value)),
233 ObjectImage(parameter, value) => self
234 .objects
235 .get_mut(¶meter.parameter)
236 .set_aspect(parameter.name.as_deref(), Some(value)),
237 ObjectAnchor(parameter, value) => self
238 .objects
239 .get_mut(¶meter.parameter)
240 .set_aspect(parameter.name.as_deref(), Some(value)),
241 ObjectScale(parameter, value) => self
242 .objects
243 .get_mut(¶meter.parameter)
244 .set_aspect(parameter.name.as_deref(), Some(value)),
245 LayerImage(parameter, value) => self
246 .layers
247 .get_mut(¶meter.parameter)
248 .set_aspect(parameter.name.as_deref(), Some(value)),
249 LayerLayout(parameter, value) => self
250 .layers
251 .get_mut(¶meter.parameter)
252 .set_aspect(parameter.name.as_deref(), Some(value)),
253 LayerAnchor(parameter, value) => self
254 .layers
255 .get_mut(¶meter.parameter)
256 .set_aspect(parameter.name.as_deref(), Some(value)),
257 Layout(parameter, value) => self
258 .layout
259 .get_mut(¶meter.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(¶meter.parameter)
831 .set_scene(parameter.name.as_deref(), None),
832 Timing(parameter) => self
833 .timing
834 .get_mut(¶meter.parameter)
835 .set_scene(parameter.name.as_deref(), None),
836 ObjectImage(parameter) => self
837 .objects
838 .get_mut(¶meter.parameter)
839 .set_scene(parameter.name.as_deref(), None),
840 ObjectAnchor(parameter) => self
841 .objects
842 .get_mut(¶meter.parameter)
843 .set_scene(parameter.name.as_deref(), None),
844 ObjectScale(parameter) => self
845 .objects
846 .get_mut(¶meter.parameter)
847 .set_scene(parameter.name.as_deref(), None),
848 LayerImage(parameter) => self
849 .layers
850 .get_mut(¶meter.parameter)
851 .set_scene(parameter.name.as_deref(), None),
852 LayerLayout(parameter) => self
853 .layers
854 .get_mut(¶meter.parameter)
855 .set_scene(parameter.name.as_deref(), None),
856 LayerAnchor(parameter) => self
857 .layers
858 .get_mut(¶meter.parameter)
859 .set_scene(parameter.name.as_deref(), None),
860 Layout(parameter) => self
861 .layout
862 .get_mut(¶meter.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(¶meter.parameter)
876 .set_scene(parameter.name.as_deref(), *value),
877 Timing(parameter, value) => self
878 .timing
879 .get_mut(¶meter.parameter)
880 .set_scene(parameter.name.as_deref(), *value),
881 ObjectImage(parameter, value) => self
882 .objects
883 .get_mut(¶meter.parameter)
884 .set_scene(parameter.name.as_deref(), value.clone()),
885 ObjectScale(parameter, value) => self
886 .objects
887 .get_mut(¶meter.parameter)
888 .set_scene(parameter.name.as_deref(), *value),
889 ObjectAnchor(parameter, value) => self
890 .objects
891 .get_mut(¶meter.parameter)
892 .set_scene(parameter.name.as_deref(), *value),
893 LayerImage(parameter, value) => self
894 .layers
895 .get_mut(¶meter.parameter)
896 .set_scene(parameter.name.as_deref(), *value),
897 LayerLayout(parameter, value) => self
898 .layers
899 .get_mut(¶meter.parameter)
900 .set_scene(parameter.name.as_deref(), *value),
901 LayerAnchor(parameter, value) => self
902 .layers
903 .get_mut(¶meter.parameter)
904 .set_scene(parameter.name.as_deref(), *value),
905 Layout(parameter, value) => self
906 .layout
907 .get_mut(¶meter.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(¶meter.parameter)
925 .set_default(parameter.name, value),
926 Timing(parameter, value) => self
927 .timing
928 .get_mut(¶meter.parameter)
929 .set_default(parameter.name, value),
930 ObjectImage(parameter, value) => self
931 .objects
932 .get_mut(¶meter.parameter)
933 .set_default(parameter.name, value),
934 ObjectAnchor(parameter, value) => self
935 .objects
936 .get_mut(¶meter.parameter)
937 .set_default(parameter.name, value),
938 ObjectScale(parameter, value) => self
939 .objects
940 .get_mut(¶meter.parameter)
941 .set_default(parameter.name, value),
942 LayerImage(parameter, value) => self
943 .layers
944 .get_mut(¶meter.parameter)
945 .set_default(parameter.name, value),
946 LayerLayout(parameter, value) => self
947 .layers
948 .get_mut(¶meter.parameter)
949 .set_default(parameter.name, value),
950 LayerAnchor(parameter, value) => self
951 .layers
952 .get_mut(¶meter.parameter)
953 .set_default(parameter.name, value),
954 Layout(parameter, value) => self
955 .layout
956 .get_mut(¶meter.parameter)
957 .set_default(parameter.name, value),
958 Name(parameter, value) => {
959 self.names.default.insert(parameter, value);
960 }
961 }
962 }
963}