oxygengine_integration_vn_ui/gui/
backgrounds.rs1use 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}