oxygengine_integration_vn_ui/gui/
backgrounds.rs

1use crate::{VisualNovelBackgroundsProps, VisualNovelStoryUsed};
2use oxygengine_core::ecs::ResRead;
3use oxygengine_user_interface::raui::core::prelude::*;
4use oxygengine_visual_novel::{resource::VnStoryManager, Position};
5
6pub fn visual_novel_backgrounds_container(context: WidgetContext) -> WidgetNode {
7    let WidgetContext {
8        key,
9        shared_props,
10        process_context,
11        named_slots,
12        ..
13    } = context;
14    unpack_named_slots!(named_slots => content);
15
16    if content.is_none() {
17        content = make_widget!(visual_novel_backgrounds).into();
18    }
19
20    let name = shared_props
21        .read_cloned_or_default::<VisualNovelStoryUsed>()
22        .0;
23    let story = match process_context.owned_ref::<ResRead<VnStoryManager>>() {
24        Some(story) => match story.get(&name) {
25            Some(story) => story,
26            None => return Default::default(),
27        },
28        None => return Default::default(),
29    };
30    let scene = if story.active_scene().phase() < 0.5 {
31        match story.active_scene().from() {
32            Some(name) => story.scene(name),
33            None => None,
34        }
35    } else {
36        match story.active_scene().to() {
37            Some(name) => story.scene(name),
38            None => None,
39        }
40    };
41    let scene = match scene {
42        Some(scene) => scene,
43        None => return Default::default(),
44    };
45    let phase = scene.background_style.phase();
46
47    if let Some(p) = content.props_mut() {
48        p.write(VisualNovelBackgroundsProps {
49            phase,
50            from: story.background(scene.background_style.from()).cloned(),
51            to: story.background(scene.background_style.to()).cloned(),
52        });
53    }
54
55    let Position(tx, ty) = scene.camera_position.value();
56    let r = scene.camera_rotation.value();
57    let container_props = ContentBoxProps {
58        transform: Transform {
59            pivot: (0.5, 0.5).into(),
60            translation: (tx, ty).into(),
61            rotation: r,
62            ..Default::default()
63        },
64        ..Default::default()
65    };
66
67    widget! {
68        (#{key} content_box: {container_props} [
69            {content}
70        ])
71    }
72}
73
74pub fn visual_novel_backgrounds(context: WidgetContext) -> WidgetNode {
75    let WidgetContext { key, props, .. } = context;
76
77    let VisualNovelBackgroundsProps { phase, from, to } = props.read_cloned_or_default();
78
79    let from = if phase < 1.0 {
80        match from {
81            Some(from) => {
82                let props = ImageBoxProps {
83                    content_keep_aspect_ratio: Some(ImageBoxAspectRatio {
84                        horizontal_alignment: 0.5,
85                        vertical_alignment: 0.5,
86                        outside: true,
87                    }),
88                    material: ImageBoxMaterial::Image(ImageBoxImage {
89                        id: from.image.to_owned(),
90                        ..Default::default()
91                    }),
92                    transform: Transform {
93                        pivot: (0.5, 0.5).into(),
94                        scale: from.scale.into(),
95                        ..Default::default()
96                    },
97                    ..Default::default()
98                };
99                widget! { (#{"from"} image_box: {props} | {WidgetAlpha(1.0 - phase)}) }
100            }
101            None => Default::default(),
102        }
103    } else {
104        Default::default()
105    };
106    let to = if phase > 0.0 {
107        match to {
108            Some(to) => {
109                let props = ImageBoxProps {
110                    content_keep_aspect_ratio: Some(ImageBoxAspectRatio {
111                        horizontal_alignment: 0.5,
112                        vertical_alignment: 0.5,
113                        outside: true,
114                    }),
115                    material: ImageBoxMaterial::Image(ImageBoxImage {
116                        id: to.image.to_owned(),
117                        ..Default::default()
118                    }),
119                    transform: Transform {
120                        pivot: (0.5, 0.5).into(),
121                        scale: to.scale.into(),
122                        ..Default::default()
123                    },
124                    ..Default::default()
125                };
126                widget! { (#{"to"} image_box: {props} | {WidgetAlpha(phase)}) }
127            }
128            None => Default::default(),
129        }
130    } else {
131        Default::default()
132    };
133
134    widget! {
135        (#{key} content_box [
136            {from}
137            {to}
138        ])
139    }
140}