veloren_voxygen/ui/
img_ids.rs

1use super::{Graphic, SampleStrat, Transform};
2use common::{
3    assets::{self, AssetExt, DotVoxAsset, Error},
4    figure::Segment,
5};
6use std::sync::Arc;
7use vek::*;
8
9pub enum BlankGraphic {}
10pub enum ImageGraphic {}
11
12pub trait GraphicCreator<'a> {
13    type Specifier;
14    fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error>;
15}
16impl GraphicCreator<'_> for BlankGraphic {
17    type Specifier = ();
18
19    fn new_graphic(_: ()) -> Result<Graphic, Error> { Ok(Graphic::Blank) }
20}
21impl<'a> GraphicCreator<'a> for ImageGraphic {
22    type Specifier = &'a str;
23
24    fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
25        let image = assets::Image::load(specifier)?.read().to_image();
26        Ok(Graphic::Image(image, None))
27    }
28}
29
30pub enum VoxelGraphic {}
31// TODO: Are these unneeded now that we have PixArtGraphic?
32pub enum VoxelSsGraphic {}
33pub enum VoxelSs4Graphic {}
34pub enum VoxelSs9Graphic {}
35
36pub enum VoxelPixArtGraphic {}
37
38fn load_segment(specifier: &str) -> Result<Arc<Segment>, Error> {
39    let dot_vox = DotVoxAsset::load(specifier)?;
40    let seg = Segment::from_vox_model_index(&dot_vox.read().0, 0);
41    Ok(Arc::new(seg))
42}
43
44impl<'a> GraphicCreator<'a> for VoxelGraphic {
45    type Specifier = &'a str;
46
47    fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
48        Ok(Graphic::Voxel(
49            load_segment(specifier)?,
50            Transform {
51                ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
52                ..Default::default()
53            },
54            SampleStrat::None,
55        ))
56    }
57}
58impl<'a> GraphicCreator<'a> for VoxelSsGraphic {
59    type Specifier = (&'a str, u8);
60
61    fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
62        Ok(Graphic::Voxel(
63            load_segment(specifier.0)?,
64            Transform {
65                ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
66                ..Default::default()
67            },
68            SampleStrat::SuperSampling(specifier.1),
69        ))
70    }
71}
72impl<'a> GraphicCreator<'a> for VoxelSs4Graphic {
73    type Specifier = &'a str;
74
75    fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
76        Ok(Graphic::Voxel(
77            load_segment(specifier)?,
78            Transform {
79                ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
80                ..Default::default()
81            },
82            SampleStrat::SuperSampling(4),
83        ))
84    }
85}
86impl<'a> GraphicCreator<'a> for VoxelSs9Graphic {
87    type Specifier = &'a str;
88
89    fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
90        Ok(Graphic::Voxel(
91            load_segment(specifier)?,
92            Transform {
93                ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
94                ..Default::default()
95            },
96            SampleStrat::SuperSampling(9),
97        ))
98    }
99}
100impl<'a> GraphicCreator<'a> for VoxelPixArtGraphic {
101    type Specifier = &'a str;
102
103    fn new_graphic(specifier: Self::Specifier) -> Result<Graphic, Error> {
104        Ok(Graphic::Voxel(
105            load_segment(specifier)?,
106            Transform {
107                ori: Quaternion::rotation_x(-std::f32::consts::PI / 2.0),
108                ..Default::default()
109            },
110            SampleStrat::PixelCoverage,
111        ))
112    }
113}
114
115pub struct Rotations {
116    pub none: conrod_core::image::Id,
117    pub cw90: conrod_core::image::Id,
118    pub cw180: conrod_core::image::Id,
119    pub cw270: conrod_core::image::Id,
120    pub source_north: conrod_core::image::Id,
121    pub target_north: conrod_core::image::Id,
122}
123
124/// This macro will automatically load all specified assets, get the
125/// corresponding ImgIds and create a struct with all of them.
126///
127/// Example usage:
128/// ```ignore
129/// use veloren_voxygen::{
130///     image_ids,
131///     ui::img_ids::{BlankGraphic, ImageGraphic, VoxelGraphic},
132/// };
133///
134/// image_ids! {
135///     pub struct Imgs {
136///         <VoxelGraphic>
137///         button1: "specifier1",
138///         button2: "specifier2",
139///
140///         <ImageGraphic>
141///         background: "background",
142///
143///         <BlankGraphic>
144///         blank: (),
145///     }
146/// }
147/// ```
148#[macro_export]
149macro_rules! image_ids {
150    ($($v:vis struct $Ids:ident { $( <$T:ty> $( $name:ident: $specifier:expr ),* $(,)? )* })*) => {
151        $(
152            $v struct $Ids {
153                $($( $v $name: conrod_core::image::Id, )*)*
154            }
155
156            impl $Ids {
157                pub fn load(ui: &mut $crate::ui::Ui) -> Result<Self, common::assets::Error> {
158                    use $crate::ui::img_ids::GraphicCreator;
159                    Ok(Self {
160                        $($( $name: ui.add_graphic(<$T as GraphicCreator>::new_graphic($specifier)?), )*)*
161                    })
162                }
163            }
164        )*
165    };
166}
167#[macro_export]
168macro_rules! image_ids_ice {
169    ($($v:vis struct $Ids:ident { $( <$T:ty> $( $(#[$($attribute:tt)*])? $name:ident: $specifier:expr ),* $(,)? )* })*) => {
170        $(
171            $v struct $Ids {
172                $($( $(#[$($attribute)*])? $v $name: $crate::ui::GraphicId, )*)*
173            }
174
175            impl $Ids {
176                pub fn load(ui: &mut $crate::ui::ice::IcedUi) -> Result<Self, common::assets::Error> {
177                    use $crate::ui::img_ids::GraphicCreator;
178                    Ok(Self {
179                        $($( $(#[$($attribute)*])? $name: ui.add_graphic(<$T as GraphicCreator>::new_graphic($specifier)?), )*)*
180                    })
181                }
182            }
183        )*
184    };
185}
186
187// TODO: combine with the img_ids macro above using a marker for specific fields
188// that should be `Rotations` instead of `widget::Id`
189#[macro_export]
190macro_rules! rotation_image_ids {
191    ($($v:vis struct $Ids:ident { $( <$T:ty> $( $name:ident: $specifier:expr ),* $(,)? )* })*) => {
192        $(
193            $v struct $Ids {
194                $($( $v $name: $crate::ui::img_ids::Rotations, )*)*
195            }
196
197            impl $Ids {
198                pub fn load(ui: &mut $crate::ui::Ui) -> Result<Self, common::assets::Error> {
199                    use $crate::ui::img_ids::GraphicCreator;
200                    Ok(Self {
201                        $($( $name: ui.add_graphic_with_rotations(<$T as GraphicCreator>::new_graphic($specifier)?), )*)*
202                    })
203                }
204            }
205        )*
206    };
207}