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, HashSet};
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 pub custom_colors: HashMap<Box<str>, Override<Color>>,
184 pub custom_floats: HashMap<Box<str>, Override<f32>>,
185}
186
187impl PlayerSettings {
188 pub fn common() -> Self {
189 Self {
190 colors: ColorSettings::common(),
191 timing: TimingSettings::common(),
192 objects: ObjectSettings::common(),
193 layers: LayerSettings::common(),
194 layout: LayoutSettings::common(),
195 names: Names::new(),
196 custom_colors: HashMap::new(),
197 custom_floats: HashMap::new(),
198 }
199 }
200
201 pub fn apply_setting(&mut self, context: &mut SettingsContext, key: &str, value: &str) {
202 if let Some(parameter) = Parameter::create(key, context) {
203 let setter = parameter.value_setter(value, context);
204 self.set_character_default(setter);
205 }
206 }
207
208 pub fn extract_settings(
209 &mut self,
210 context: &mut SettingsContext,
211 config_map: &mut IndexMap<Box<str>, Box<str>>,
212 ) {
213 for (key, value) in config_map.drain(..) {
214 self.apply_setting(context, &key, &value);
215 }
216 }
217
218 pub fn reset(&mut self) {
219 self.colors.reset();
220 self.timing.reset();
221 self.layers.reset();
222 self.layout.reset();
223 self.names.reset();
224 for override_value in self.custom_colors.values_mut() {
225 override_value.reset();
226 }
227 for override_value in self.custom_floats.values_mut() {
228 override_value.reset();
229 }
230 }
231
232 pub fn set_aspect(&mut self, setter: Setter) {
233 use Setter::*;
234 match setter {
235 Color(parameter, value) => self
236 .colors
237 .get_mut(¶meter.parameter)
238 .set_aspect(parameter.name.as_deref(), Some(value)),
239 Timing(parameter, value) => self
240 .timing
241 .get_mut(¶meter.parameter)
242 .set_aspect(parameter.name.as_deref(), Some(value)),
243 ObjectImage(parameter, value) => self
244 .objects
245 .get_mut(¶meter.parameter)
246 .set_aspect(parameter.name.as_deref(), Some(value)),
247 ObjectAnchor(parameter, value) => self
248 .objects
249 .get_mut(¶meter.parameter)
250 .set_aspect(parameter.name.as_deref(), Some(value)),
251 ObjectScale(parameter, value) => self
252 .objects
253 .get_mut(¶meter.parameter)
254 .set_aspect(parameter.name.as_deref(), Some(value)),
255 LayerImage(parameter, value) => self
256 .layers
257 .get_mut(¶meter.parameter)
258 .set_aspect(parameter.name.as_deref(), Some(value)),
259 LayerLayout(parameter, value) => self
260 .layers
261 .get_mut(¶meter.parameter)
262 .set_aspect(parameter.name.as_deref(), Some(value)),
263 LayerAnchor(parameter, value) => self
264 .layers
265 .get_mut(¶meter.parameter)
266 .set_aspect(parameter.name.as_deref(), Some(value)),
267 Layout(parameter, value) => self
268 .layout
269 .get_mut(¶meter.parameter)
270 .set_aspect(parameter.name.as_deref(), Some(value)),
271 Name(parameter, value) => {
272 self.names.aspect.insert(parameter, value);
273 }
274 CustomColor(parameter, value) => self
275 .custom_colors
276 .entry(parameter.parameter.clone())
277 .or_default()
278 .set_aspect(parameter.name.as_deref(), Some(value)),
279 CustomFloat(parameter, value) => self
280 .custom_floats
281 .entry(parameter.parameter.clone())
282 .or_default()
283 .set_aspect(parameter.name.as_deref(), Some(value)),
284 }
285 }
286
287 pub fn reset_aspects(&mut self) {
288 self.colors.reset_aspects();
289 self.timing.reset_aspects();
290 self.objects.reset_aspects();
291 self.layers.reset_aspects();
292 self.layout.reset_aspects();
293 self.names.reset_aspects();
294 for override_value in self.custom_colors.values_mut() {
295 override_value.reset_aspects();
296 }
297 for override_value in self.custom_floats.values_mut() {
298 override_value.reset_aspects();
299 }
300 }
301}
302
303#[derive(Clone, Debug, PartialEq, Eq, Hash)]
304pub struct NamedParameter<T> {
305 name: Option<Box<str>>,
306 parameter: T,
307}
308
309trait ParameterNamer: Sized {
310 fn named(self, name: Option<Box<str>>) -> NamedParameter<Self> {
311 NamedParameter {
312 name,
313 parameter: self,
314 }
315 }
316}
317
318impl<T> ParameterNamer for T {}
319
320type NamedColorParameter = NamedParameter<ColorParameter>;
321type NamedTimingParameter = NamedParameter<TimingParameter>;
322type NamedObjectImageParameter = NamedParameter<ObjectImageParameter>;
323type NamedObjectAnchorParameter = NamedParameter<ObjectAnchorParameter>;
324type NamedObjectScaleParameter = NamedParameter<ObjectScaleParameter>;
325type NamedLayerImageParameter = NamedParameter<LayerImageParameter>;
326type NamedLayerLayoutParameter = NamedParameter<LayerLayoutParameter>;
327type NamedLayerAnchorParameter = NamedParameter<LayerAnchorParameter>;
328type NamedLayoutParameter = NamedParameter<LayoutParameter>;
329
330#[derive(Clone, Debug, PartialEq, Eq, Hash)]
331pub enum Parameter {
332 Color(NamedColorParameter),
333 Timing(NamedTimingParameter),
334 ObjectImage(NamedObjectImageParameter),
335 ObjectAnchor(NamedObjectAnchorParameter),
336 ObjectScale(NamedObjectScaleParameter),
337 LayerImage(NamedLayerImageParameter),
338 LayerLayout(NamedLayerLayoutParameter),
339 LayerAnchor(NamedLayerAnchorParameter),
340 Layout(NamedLayoutParameter),
341 Name(Box<str>),
342 CustomColor(NamedParameter<Box<str>>),
343 CustomFloat(NamedParameter<Box<str>>),
344}
345
346pub struct Object {
347 index: usize,
348 images: HashMap<Box<str>, usize>,
349}
350
351impl Object {
352 fn new(index: usize) -> Self {
353 Self {
354 index,
355 images: HashMap::new(),
356 }
357 }
358}
359
360pub struct LayerInfo {
361 pub name: Box<str>,
362 pub path: Box<str>,
363}
364
365pub fn extract_layers(layers: &mut Vec<LayerInfo>, config_map: &mut IndexMap<Box<str>, Box<str>>) {
366 let keys: Vec<_> = config_map.keys().cloned().collect();
367 for key in keys {
368 let Some(("Layer", name)) = key.split_once(':') else {
369 continue;
370 };
371
372 let path = config_map.shift_remove(&key).expect("Invalid layer");
373 layers.push(LayerInfo {
374 name: name.into(),
375 path,
376 });
377 }
378
379 if layers.is_empty() {
380 layers.push(LayerInfo {
381 name: "Background".into(),
382 path: Box::default(),
383 });
384 layers.push(LayerInfo {
385 name: "Character".into(),
386 path: Box::default(),
387 });
388 }
389}
390
391#[derive(Default)]
392pub struct SettingsContext {
393 pub object_cache: HashMap<Box<str>, Object>,
394 pub layers: Vec<LayerInfo>,
395 pub anchors: HashMap<Box<str>, usize>,
396 pub custom_color_names: HashSet<Box<str>>,
397 pub custom_float_names: HashSet<Box<str>>,
398}
399
400impl SettingsContext {
401 pub fn new() -> Self {
402 Self::default()
403 }
404}
405
406impl Parameter {
407 fn create_character(name: &str, context: &mut SettingsContext) -> Option<Self> {
408 let (main, sub) = name.split_once(':')?;
409
410 if main != "Character" {
411 return None;
412 }
413
414 let (character_name, option) = sub.split_once(':')?;
415
416 let character_name = character_name.into();
417 if option == "name" {
418 Some(Self::Name(character_name))
419 } else {
420 create_parameter(option, Some(character_name), context)
421 }
422 }
423
424 pub fn value_setter(self, value: &str, context: &mut SettingsContext) -> Setter {
425 fn color(repr: &str) -> Color {
426 match repr {
427 "black" => Color::BLACK,
428 "white" => Color::WHITE,
429
430 "red" => Color::RED,
431 "yellow" => Color::YELLOW,
432 "green" => Color::GREEN,
433 "cyan" => Color::CYAN,
434 "blue" => Color::BLUE,
435 "magenta" => Color::MAGENTA,
436
437 _ => repr
438 .parse::<Color>()
439 .unwrap_or_else(|_| panic!("Color '{repr}' does not exist")),
440 }
441 }
442
443 match self {
444 Self::Color(parameter) => Setter::Color(parameter, color(value)),
445 Self::Timing(parameter) => Setter::Timing(
446 parameter,
447 value.parse().expect("Parsing timing parameter failed"),
448 ),
449 Self::ObjectImage(parameter) => Setter::ObjectImage(parameter, Some(value.into())),
450 Self::ObjectAnchor(parameter) => Setter::ObjectAnchor(parameter, {
451 let (x, y) = value
452 .split_once(char::is_whitespace)
453 .expect("Parsing object anchor parameter failed");
454 let x = x.parse().expect("Parsing object anchor parameter failed");
455 let y = y.parse().expect("Parsing object anchor parameter failed");
456 [x, y]
457 }),
458 Self::ObjectScale(parameter) => Setter::ObjectScale(
459 parameter,
460 value.parse().expect("Parsing image scale parameter failed"),
461 ),
462 Self::LayerImage(parameter) => {
463 let index = if value.is_empty() {
464 None
465 } else {
466 let path = &context.layers[parameter.parameter.0].path;
467 let path_holder;
468 let full_path = if path.is_empty() {
469 value
470 } else {
471 path_holder = format!("{path}:{value}");
472 &path_holder
473 };
474 if let Some(Object { index, .. }) = context.object_cache.get(full_path) {
475 Some(*index)
476 } else {
477 eprintln!("Undefined image object {value:?}");
478 None
479 }
480 };
481 Setter::LayerImage(parameter, index)
482 }
483 Self::LayerLayout(parameter) => Setter::LayerLayout(
484 parameter,
485 value
486 .parse()
487 .expect("Parsing object layout parameter failed"),
488 ),
489 Self::LayerAnchor(parameter) => {
490 let index = if value.is_empty() {
491 None
492 } else {
493 let anchor_index = context.anchors.len();
494 Some(*context.anchors.entry(value.into()).or_insert(anchor_index))
495 };
496 Setter::LayerAnchor(parameter, index)
497 }
498 Self::Layout(parameter) => Setter::Layout(
499 parameter,
500 value.parse().expect("Parsing layout parameter failed"),
501 ),
502 Self::Name(parameter) => Setter::Name(parameter, value.into()),
503 Self::CustomColor(parameter) => Setter::CustomColor(parameter, color(value)),
504 Self::CustomFloat(parameter) => Setter::CustomFloat(
505 parameter,
506 value
507 .parse()
508 .unwrap_or_else(|_| panic!("Parsing custom float parameter failed: {value:?}")),
509 ),
510 }
511 }
512}
513
514fn create_parameter(
515 parameter_name: &str,
516 character_name: Option<Box<str>>,
517 context: &mut SettingsContext,
518) -> Option<Parameter> {
519 let (path, parameter_name) = parameter_name.split_once(':')?;
520 Some(match path {
521 "Color" => Parameter::Color(
522 match parameter_name {
523 "background" => ColorParameter::Background,
524 "foreground" => ColorParameter::Foreground,
525 "dialog-text-fill" => ColorParameter::Dialog(BoxColorParameter::TextFill),
526 "dialog-text-line" => ColorParameter::Dialog(BoxColorParameter::TextLine),
527 "dialog-name-fill" => ColorParameter::Dialog(BoxColorParameter::NameFill),
528 "dialog-name-line" => ColorParameter::Dialog(BoxColorParameter::NameLine),
529
530 "choice-default-text-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
531 selected: false,
532 parameter: BoxColorParameter::TextFill,
533 }),
534 "choice-default-text-line" => ColorParameter::Choice(SelectableBoxColorParameter {
535 selected: false,
536 parameter: BoxColorParameter::TextLine,
537 }),
538 "choice-default-name-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
539 selected: false,
540 parameter: BoxColorParameter::NameFill,
541 }),
542 "choice-default-name-line" => ColorParameter::Choice(SelectableBoxColorParameter {
543 selected: false,
544 parameter: BoxColorParameter::NameLine,
545 }),
546 "choice-select-text-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
547 selected: true,
548 parameter: BoxColorParameter::TextFill,
549 }),
550 "choice-select-text-line" => ColorParameter::Choice(SelectableBoxColorParameter {
551 selected: true,
552 parameter: BoxColorParameter::TextLine,
553 }),
554 "choice-select-name-fill" => ColorParameter::Choice(SelectableBoxColorParameter {
555 selected: true,
556 parameter: BoxColorParameter::NameFill,
557 }),
558 "choice-select-name-line" => ColorParameter::Choice(SelectableBoxColorParameter {
559 selected: true,
560 parameter: BoxColorParameter::NameLine,
561 }),
562
563 "revert-default-text-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
564 selected: false,
565 parameter: BoxColorParameter::TextFill,
566 }),
567 "revert-default-text-line" => ColorParameter::Revert(SelectableBoxColorParameter {
568 selected: false,
569 parameter: BoxColorParameter::TextLine,
570 }),
571 "revert-default-name-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
572 selected: false,
573 parameter: BoxColorParameter::NameFill,
574 }),
575 "revert-default-name-line" => ColorParameter::Revert(SelectableBoxColorParameter {
576 selected: false,
577 parameter: BoxColorParameter::NameLine,
578 }),
579 "revert-select-text-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
580 selected: true,
581 parameter: BoxColorParameter::TextFill,
582 }),
583 "revert-select-text-line" => ColorParameter::Revert(SelectableBoxColorParameter {
584 selected: true,
585 parameter: BoxColorParameter::TextLine,
586 }),
587 "revert-select-name-fill" => ColorParameter::Revert(SelectableBoxColorParameter {
588 selected: true,
589 parameter: BoxColorParameter::NameFill,
590 }),
591 "revert-select-name-line" => ColorParameter::Revert(SelectableBoxColorParameter {
592 selected: true,
593 parameter: BoxColorParameter::NameLine,
594 }),
595
596 _ => return None,
597 }
598 .named(character_name),
599 ),
600
601 "Timing" => Parameter::Timing(
602 match parameter_name {
603 "auto-next" => TimingParameter::AutoNext,
604 "letter" => TimingParameter::Letter,
605 "line" => TimingParameter::Line,
606 "select" => TimingParameter::Select,
607 "view" => TimingParameter::View,
608
609 _ => return None,
610 }
611 .named(character_name),
612 ),
613
614 "Image" => {
615 let (object_name, parameter_name) = parameter_name.rsplit_once(':')?;
616
617 let entry_count = context.object_cache.len();
618 let Object { index, images } = context
619 .object_cache
620 .entry(object_name.into())
621 .or_insert_with(|| Object::new(entry_count));
622
623 let image_index = images.len();
624 let parameter_index = *images.entry(parameter_name.into()).or_insert(image_index);
625
626 Parameter::ObjectImage(
627 ObjectImageParameter(*index, parameter_index).named(character_name),
628 )
629 }
630
631 "Anchor" => {
632 let (object_name, parameter_name) = parameter_name.rsplit_once(':')?;
633
634 let entry_count = context.object_cache.len();
635 let Object { index, .. } = context
636 .object_cache
637 .entry(object_name.into())
638 .or_insert_with(|| Object::new(entry_count));
639
640 let anchor_index = context.anchors.len();
641 let parameter_index = *context
642 .anchors
643 .entry(parameter_name.into())
644 .or_insert(anchor_index);
645
646 Parameter::ObjectAnchor(
647 ObjectAnchorParameter(*index, parameter_index).named(character_name),
648 )
649 }
650
651 "Transform" => {
652 let (object_name, parameter_name) = parameter_name.rsplit_once(':')?;
653
654 if parameter_name != "scale" {
655 return None;
656 }
657
658 let entry_count = context.object_cache.len();
659 let Object { index, .. } = context
660 .object_cache
661 .entry(object_name.into())
662 .or_insert_with(|| Object::new(entry_count));
663
664 Parameter::ObjectScale(ObjectScaleParameter(*index).named(character_name))
665 }
666
667 "Object" => {
668 let (layer_name, parameter_name) = parameter_name.split_once(':')?;
669 let layer = context
670 .layers
671 .iter()
672 .position(|layer| &*layer.name == layer_name)?;
673
674 match parameter_name {
675 "image" => Parameter::LayerImage(LayerImageParameter(layer).named(character_name)),
676 "hor" => Parameter::LayerLayout(
677 LayerLayoutParameter {
678 layer,
679 layout: LayerObjectLayoutParameter::Hor,
680 }
681 .named(character_name),
682 ),
683 "ver" => Parameter::LayerLayout(
684 LayerLayoutParameter {
685 layer,
686 layout: LayerObjectLayoutParameter::Ver,
687 }
688 .named(character_name),
689 ),
690 "scale" => Parameter::LayerLayout(
691 LayerLayoutParameter {
692 layer,
693 layout: LayerObjectLayoutParameter::Scale,
694 }
695 .named(character_name),
696 ),
697 "anchor" => {
698 Parameter::LayerAnchor(LayerAnchorParameter(layer).named(character_name))
699 }
700
701 _ => return None,
702 }
703 }
704
705 "Layout" => Parameter::Layout(
706 {
707 let (subpath, parameter_name) = parameter_name.split_once(':')?;
708 let box_layout_parameter = || {
709 Some(match parameter_name {
710 "hor" => BoxLayoutParameter::Hor,
711 "ver" => BoxLayoutParameter::Ver,
712 "width" => BoxLayoutParameter::Width,
713 "height" => BoxLayoutParameter::Height,
714 "corner" => BoxLayoutParameter::Corner,
715 "line" => BoxLayoutParameter::Line,
716 "text-size" => BoxLayoutParameter::TextSize,
717 "name-size" => BoxLayoutParameter::NameSize,
718
719 _ => return None,
720 })
721 };
722
723 let view_layout_parameter = || {
724 Some(match parameter_name {
725 "hor" => ViewLayoutParameter::Hor,
726 "ver" => ViewLayoutParameter::Ver,
727 "zoom" => ViewLayoutParameter::Zoom,
728
729 _ => return None,
730 })
731 };
732
733 match subpath {
734 "Main" => box_layout_parameter()?.main(),
735 "List" => box_layout_parameter()?.list(),
736 "View" => LayoutParameter::View(view_layout_parameter()?),
737
738 _ => return None,
739 }
740 }
741 .named(character_name),
742 ),
743
744 "Parameter" => {
745 let (type_name, param_name) = parameter_name.split_once(':')?;
746 let param_name: Box<str> = param_name.into();
747 match type_name {
748 "Color" => {
749 context.custom_color_names.insert(param_name.clone());
750 Parameter::CustomColor(param_name.named(character_name))
751 }
752 "Number" => {
753 context.custom_float_names.insert(param_name.clone());
754 Parameter::CustomFloat(param_name.named(character_name))
755 }
756 _ => return None,
757 }
758 }
759
760 _ => return None,
761 })
762}
763
764impl Parameter {
765 pub fn create_setter(key: &str, value: &str, context: &mut SettingsContext) -> Option<Setter> {
766 let parameter = if let Some(p) = create_parameter(key, None, context) {
767 p
768 } else {
769 Self::create_character(key, context)?
770 };
771 Some(parameter.value_setter(value, context))
772 }
773}
774
775impl DialogParameter for Parameter {
776 type Context = SettingsContext;
777
778 fn create(name: &str, context: &mut SettingsContext) -> Option<Self> {
779 if name == "-" {
780 None
781 } else if let Some(parameter) = create_parameter(name, None, context) {
782 Some(parameter)
783 } else {
784 let result = Self::create_character(name, context);
785 if result.is_none() {
786 eprintln!("Setting not availabe: {name}");
787 }
788 result
789 }
790 }
791}
792
793#[derive(Clone)]
794pub enum Setter {
795 Color(NamedColorParameter, Color),
796 Timing(NamedTimingParameter, f32),
797 ObjectImage(NamedObjectImageParameter, Option<Box<str>>),
798 ObjectAnchor(NamedObjectAnchorParameter, [f32; 2]),
799 ObjectScale(NamedObjectScaleParameter, f32),
800 LayerImage(NamedLayerImageParameter, Option<usize>),
801 LayerLayout(NamedLayerLayoutParameter, f32),
802 LayerAnchor(NamedLayerAnchorParameter, Option<usize>),
803 Layout(NamedLayoutParameter, f32),
804 Name(Box<str>, Box<str>),
805 CustomColor(NamedParameter<Box<str>>, Color),
806 CustomFloat(NamedParameter<Box<str>>, f32),
807}
808
809impl Setter {
810 pub fn change(self) -> Change {
811 match self {
812 Self::Color(parameter, value) => Change::Color(parameter, Some(value)),
813 Self::Timing(parameter, value) => Change::Timing(parameter, Some(value)),
814 Self::ObjectImage(parameter, value) => Change::ObjectImage(parameter, Some(value)),
815 Self::ObjectAnchor(parameter, value) => Change::ObjectAnchor(parameter, Some(value)),
816 Self::ObjectScale(parameter, value) => Change::ObjectScale(parameter, Some(value)),
817 Self::LayerImage(parameter, value) => Change::LayerImage(parameter, Some(value)),
818 Self::LayerLayout(parameter, value) => Change::LayerLayout(parameter, Some(value)),
819 Self::LayerAnchor(parameter, value) => Change::LayerAnchor(parameter, Some(value)),
820 Self::Layout(parameter, value) => Change::Layout(parameter, Some(value)),
821 Self::Name(parameter, value) => Change::Name(parameter, Some(value)),
822 Self::CustomColor(parameter, value) => Change::CustomColor(parameter, Some(value)),
823 Self::CustomFloat(parameter, value) => Change::CustomFloat(parameter, Some(value)),
824 }
825 }
826}
827
828pub enum Change {
829 Color(NamedColorParameter, Option<Color>),
830 Timing(NamedTimingParameter, Option<f32>),
831 ObjectImage(NamedObjectImageParameter, Option<Option<Box<str>>>),
832 ObjectAnchor(NamedObjectAnchorParameter, Option<[f32; 2]>),
833 ObjectScale(NamedObjectScaleParameter, Option<f32>),
834 LayerImage(NamedLayerImageParameter, Option<Option<usize>>),
835 LayerLayout(NamedLayerLayoutParameter, Option<f32>),
836 LayerAnchor(NamedLayerAnchorParameter, Option<Option<usize>>),
837 Layout(NamedLayoutParameter, Option<f32>),
838 Name(Box<str>, Option<Box<str>>),
839 CustomColor(NamedParameter<Box<str>>, Option<Color>),
840 CustomFloat(NamedParameter<Box<str>>, Option<f32>),
841}
842
843impl Change {
844 pub fn parameter(&self) -> Parameter {
845 match self {
846 Self::Color(parameter, _) => Parameter::Color(parameter.clone()),
847 Self::Timing(parameter, _) => Parameter::Timing(parameter.clone()),
848 Self::ObjectImage(parameter, _) => Parameter::ObjectImage(parameter.clone()),
849 Self::ObjectAnchor(parameter, _) => Parameter::ObjectAnchor(parameter.clone()),
850 Self::ObjectScale(parameter, _) => Parameter::ObjectScale(parameter.clone()),
851 Self::LayerImage(parameter, _) => Parameter::LayerImage(parameter.clone()),
852 Self::LayerLayout(parameter, _) => Parameter::LayerLayout(parameter.clone()),
853 Self::LayerAnchor(parameter, _) => Parameter::LayerAnchor(parameter.clone()),
854 Self::Layout(parameter, _) => Parameter::Layout(parameter.clone()),
855 Self::Name(parameter, _) => Parameter::Name(parameter.clone()),
856 Self::CustomColor(parameter, _) => Parameter::CustomColor(parameter.clone()),
857 Self::CustomFloat(parameter, _) => Parameter::CustomFloat(parameter.clone()),
858 }
859 }
860}
861
862impl DialogChange for Change {
863 type Parameter = Parameter;
864
865 fn default_change(parameter: Parameter) -> Self {
866 match parameter {
867 Parameter::Color(parameter) => Self::Color(parameter, None),
868 Parameter::Timing(parameter) => Self::Timing(parameter, None),
869 Parameter::ObjectImage(parameter) => Self::ObjectImage(parameter, None),
870 Parameter::ObjectAnchor(parameter) => Self::ObjectAnchor(parameter, None),
871 Parameter::ObjectScale(parameter) => Self::ObjectScale(parameter, None),
872 Parameter::LayerImage(parameter) => Self::LayerImage(parameter, None),
873 Parameter::LayerLayout(parameter) => Self::LayerLayout(parameter, None),
874 Parameter::LayerAnchor(parameter) => Self::LayerAnchor(parameter, None),
875 Parameter::Layout(parameter) => Self::Layout(parameter, None),
876 Parameter::Name(parameter) => Self::Name(parameter, None),
877 Parameter::CustomColor(parameter) => Self::CustomColor(parameter, None),
878 Parameter::CustomFloat(parameter) => Self::CustomFloat(parameter, None),
879 }
880 }
881
882 fn value_change(parameter: Parameter, value: &str, context: &mut SettingsContext) -> Self {
883 parameter.value_setter(value, context).change()
884 }
885}
886
887impl PlayerSettings {
888 pub fn revert(&mut self, parameter: &Parameter) {
889 use Parameter::*;
890 match parameter {
891 Color(parameter) => self
892 .colors
893 .get_mut(¶meter.parameter)
894 .set_scene(parameter.name.as_deref(), None),
895 Timing(parameter) => self
896 .timing
897 .get_mut(¶meter.parameter)
898 .set_scene(parameter.name.as_deref(), None),
899 ObjectImage(parameter) => self
900 .objects
901 .get_mut(¶meter.parameter)
902 .set_scene(parameter.name.as_deref(), None),
903 ObjectAnchor(parameter) => self
904 .objects
905 .get_mut(¶meter.parameter)
906 .set_scene(parameter.name.as_deref(), None),
907 ObjectScale(parameter) => self
908 .objects
909 .get_mut(¶meter.parameter)
910 .set_scene(parameter.name.as_deref(), None),
911 LayerImage(parameter) => self
912 .layers
913 .get_mut(¶meter.parameter)
914 .set_scene(parameter.name.as_deref(), None),
915 LayerLayout(parameter) => self
916 .layers
917 .get_mut(¶meter.parameter)
918 .set_scene(parameter.name.as_deref(), None),
919 LayerAnchor(parameter) => self
920 .layers
921 .get_mut(¶meter.parameter)
922 .set_scene(parameter.name.as_deref(), None),
923 Layout(parameter) => self
924 .layout
925 .get_mut(¶meter.parameter)
926 .set_scene(parameter.name.as_deref(), None),
927 Name(parameter) => {
928 self.names.scene.remove(parameter);
929 }
930 CustomColor(parameter) => {
931 if let Some(override_value) = self.custom_colors.get_mut(¶meter.parameter) {
932 override_value.set_scene(parameter.name.as_deref(), None);
933 }
934 }
935 CustomFloat(parameter) => {
936 if let Some(override_value) = self.custom_floats.get_mut(¶meter.parameter) {
937 override_value.set_scene(parameter.name.as_deref(), None);
938 }
939 }
940 }
941 }
942
943 pub fn change(&mut self, change: &Change) {
944 use Change::*;
945 match change {
946 Color(parameter, value) => self
947 .colors
948 .get_mut(¶meter.parameter)
949 .set_scene(parameter.name.as_deref(), *value),
950 Timing(parameter, value) => self
951 .timing
952 .get_mut(¶meter.parameter)
953 .set_scene(parameter.name.as_deref(), *value),
954 ObjectImage(parameter, value) => self
955 .objects
956 .get_mut(¶meter.parameter)
957 .set_scene(parameter.name.as_deref(), value.clone()),
958 ObjectScale(parameter, value) => self
959 .objects
960 .get_mut(¶meter.parameter)
961 .set_scene(parameter.name.as_deref(), *value),
962 ObjectAnchor(parameter, value) => self
963 .objects
964 .get_mut(¶meter.parameter)
965 .set_scene(parameter.name.as_deref(), *value),
966 LayerImage(parameter, value) => self
967 .layers
968 .get_mut(¶meter.parameter)
969 .set_scene(parameter.name.as_deref(), *value),
970 LayerLayout(parameter, value) => self
971 .layers
972 .get_mut(¶meter.parameter)
973 .set_scene(parameter.name.as_deref(), *value),
974 LayerAnchor(parameter, value) => self
975 .layers
976 .get_mut(¶meter.parameter)
977 .set_scene(parameter.name.as_deref(), *value),
978 Layout(parameter, value) => self
979 .layout
980 .get_mut(¶meter.parameter)
981 .set_scene(parameter.name.as_deref(), *value),
982 Name(parameter, value) => {
983 if let Some(value) = value {
984 self.names.scene.insert(parameter.clone(), value.clone());
985 } else {
986 self.names.scene.remove(parameter);
987 }
988 }
989 CustomColor(parameter, value) => self
990 .custom_colors
991 .entry(parameter.parameter.clone())
992 .or_default()
993 .set_scene(parameter.name.as_deref(), *value),
994 CustomFloat(parameter, value) => self
995 .custom_floats
996 .entry(parameter.parameter.clone())
997 .or_default()
998 .set_scene(parameter.name.as_deref(), *value),
999 }
1000 }
1001
1002 pub fn set_character_default(&mut self, change: Setter) {
1003 use Setter::*;
1004 match change {
1005 Color(parameter, value) => self
1006 .colors
1007 .get_mut(¶meter.parameter)
1008 .set_default(parameter.name, value),
1009 Timing(parameter, value) => self
1010 .timing
1011 .get_mut(¶meter.parameter)
1012 .set_default(parameter.name, value),
1013 ObjectImage(parameter, value) => self
1014 .objects
1015 .get_mut(¶meter.parameter)
1016 .set_default(parameter.name, value),
1017 ObjectAnchor(parameter, value) => self
1018 .objects
1019 .get_mut(¶meter.parameter)
1020 .set_default(parameter.name, value),
1021 ObjectScale(parameter, value) => self
1022 .objects
1023 .get_mut(¶meter.parameter)
1024 .set_default(parameter.name, value),
1025 LayerImage(parameter, value) => self
1026 .layers
1027 .get_mut(¶meter.parameter)
1028 .set_default(parameter.name, value),
1029 LayerLayout(parameter, value) => self
1030 .layers
1031 .get_mut(¶meter.parameter)
1032 .set_default(parameter.name, value),
1033 LayerAnchor(parameter, value) => self
1034 .layers
1035 .get_mut(¶meter.parameter)
1036 .set_default(parameter.name, value),
1037 Layout(parameter, value) => self
1038 .layout
1039 .get_mut(¶meter.parameter)
1040 .set_default(parameter.name, value),
1041 Name(parameter, value) => {
1042 self.names.default.insert(parameter, value);
1043 }
1044 CustomColor(parameter, value) => self
1045 .custom_colors
1046 .entry(parameter.parameter.clone())
1047 .or_default()
1048 .set_default(parameter.name, value),
1049 CustomFloat(parameter, value) => self
1050 .custom_floats
1051 .entry(parameter.parameter.clone())
1052 .or_default()
1053 .set_default(parameter.name, value),
1054 }
1055 }
1056
1057 pub fn custom_color(&self, name: &str, character: &str) -> Option<Color> {
1058 self.custom_colors.get(name).map(|o| o.get(character))
1059 }
1060
1061 pub fn custom_float(&self, name: &str, character: &str) -> Option<f32> {
1062 self.custom_floats.get(name).map(|o| o.get(character))
1063 }
1064}