use egui::{vec2, Align, Checkbox, ComboBox, Layout, TextureId, Ui};
use radiance::{
AvailableOutputScreen, ScreenOutputNodeProps, ScreenOutputNodeState, SelectedOutputScreen,
};
const PREVIEW_ASPECT_RATIO: f32 = 1.;
const NORMAL_HEIGHT: f32 = 320.;
const NORMAL_WIDTH: f32 = 240.;
pub struct ScreenOutputNodeTile<'a> {
preview_image: TextureId,
visible: &'a mut bool,
screen: &'a mut Option<SelectedOutputScreen>,
available_screens: &'a [AvailableOutputScreen],
}
impl<'a> ScreenOutputNodeTile<'a> {
pub fn min_input_heights(_props: &ScreenOutputNodeProps) -> Vec<f32> {
(0..1).map(|_| NORMAL_HEIGHT).collect()
}
pub fn width_for_height(_props: &ScreenOutputNodeProps, height: f32) -> f32 {
NORMAL_WIDTH.min(0.5 * height)
}
pub fn new(
props: &'a mut ScreenOutputNodeProps,
_state: &'a ScreenOutputNodeState,
preview_image: TextureId,
) -> Self {
ScreenOutputNodeTile {
preview_image,
visible: &mut props.visible,
screen: &mut props.screen,
available_screens: &props.available_screens,
}
}
pub fn add_contents(self, ui: &mut Ui) {
let ScreenOutputNodeTile {
preview_image,
visible,
screen,
available_screens,
} = self;
ui.heading("Screen Output");
ui.with_layout(
Layout::bottom_up(Align::Center).with_cross_justify(true),
|ui| {
ui.add(Checkbox::new(visible, "Visible"));
let (mut screen_name, mut screen_resolution) = match screen.as_ref() {
Some(screen) => (screen.name.clone(), screen.resolution),
None => (String::new(), [0, 0]),
};
let available_resolutions: Vec<[u32; 2]> = screen
.as_ref()
.map(|screen| {
available_screens
.iter()
.find(|available_screen| available_screen.name == screen.name)
.map(|selected_available_screen| {
selected_available_screen
.suggested_resolutions
.iter()
.cloned()
})
})
.into_iter()
.flatten()
.flatten()
.collect();
let format_rez = |rez: &[u32; 2]| format!("{}x{}", rez[0], rez[1]);
ComboBox::from_id_salt(1)
.selected_text(format_rez(&screen_resolution))
.show_ui(ui, |ui| {
for available_resolution in available_resolutions.iter() {
ui.selectable_value(
&mut screen_resolution,
*available_resolution,
format_rez(available_resolution),
);
}
});
ComboBox::from_id_salt(0)
.selected_text(screen_name.as_str())
.show_ui(ui, |ui| {
for available_screen in available_screens.iter() {
ui.selectable_value(
&mut screen_name,
available_screen.name.clone(),
available_screen.name.as_str(),
);
}
});
if !screen_name.is_empty() && screen_resolution != [0, 0] {
*screen = Some(SelectedOutputScreen {
name: screen_name,
resolution: screen_resolution,
});
}
ui.centered_and_justified(|ui| {
let image_size = ui.available_size();
let image_size = (image_size * vec2(1., 1. / PREVIEW_ASPECT_RATIO)).min_elem()
* vec2(1., PREVIEW_ASPECT_RATIO);
ui.image((preview_image, image_size));
});
},
);
}
}