nightshade 0.8.0

A cross-platform data-oriented game engine.
Documentation
use crate::prelude::*;

pub fn material_properties_ui(ui: &mut egui::Ui, material: &mut Material, id_salt: &str) -> bool {
    let mut changed = false;

    ui.horizontal(|ui| {
        ui.label("Base Color:");
        if ui
            .color_edit_button_rgba_unmultiplied(&mut material.base_color)
            .changed()
        {
            changed = true;
        }
    });

    changed |= color_sliders_rgba(ui, &mut material.base_color);

    ui.separator();

    ui.horizontal(|ui| {
        ui.label("Alpha Mode:");
        egui::ComboBox::from_id_salt(format!("{}_alpha_mode", id_salt))
            .selected_text(match material.alpha_mode {
                AlphaMode::Opaque => "Opaque",
                AlphaMode::Mask => "Mask",
                AlphaMode::Blend => "Blend",
            })
            .show_ui(ui, |ui| {
                if ui
                    .selectable_value(&mut material.alpha_mode, AlphaMode::Opaque, "Opaque")
                    .changed()
                {
                    changed = true;
                }
                if ui
                    .selectable_value(&mut material.alpha_mode, AlphaMode::Mask, "Mask")
                    .changed()
                {
                    changed = true;
                }
                if ui
                    .selectable_value(&mut material.alpha_mode, AlphaMode::Blend, "Blend")
                    .changed()
                {
                    changed = true;
                }
            });
    });

    if material.alpha_mode == AlphaMode::Mask {
        ui.horizontal(|ui| {
            ui.label("Alpha Cutoff:");
            if ui
                .add(egui::Slider::new(&mut material.alpha_cutoff, 0.0..=1.0).fixed_decimals(2))
                .changed()
            {
                changed = true;
            }
        });
    }

    ui.separator();

    ui.horizontal(|ui| {
        ui.label("Roughness:");
        if ui
            .add(egui::Slider::new(&mut material.roughness, 0.0..=1.0).fixed_decimals(2))
            .changed()
        {
            changed = true;
        }
    });

    ui.horizontal(|ui| {
        ui.label("Metallic:");
        if ui
            .add(egui::Slider::new(&mut material.metallic, 0.0..=1.0).fixed_decimals(2))
            .changed()
        {
            changed = true;
        }
    });

    ui.horizontal(|ui| {
        ui.label("Unlit:");
        if ui.checkbox(&mut material.unlit, "").changed() {
            changed = true;
        }
    });

    ui.separator();

    ui.label("Emissive Factor:");
    changed |= color_sliders_rgb(ui, &mut material.emissive_factor);

    changed
}

fn color_channel_slider(ui: &mut egui::Ui, label: &str, value: &mut f32) -> bool {
    let mut changed = false;
    ui.horizontal(|ui| {
        ui.label(label);
        if ui
            .add(egui::Slider::new(value, 0.0..=1.0).fixed_decimals(2))
            .changed()
        {
            changed = true;
        }
    });
    changed
}

pub fn color_sliders_rgba(ui: &mut egui::Ui, color: &mut [f32; 4]) -> bool {
    let mut changed = false;
    changed |= color_channel_slider(ui, "R:", &mut color[0]);
    changed |= color_channel_slider(ui, "G:", &mut color[1]);
    changed |= color_channel_slider(ui, "B:", &mut color[2]);
    changed |= color_channel_slider(ui, "A:", &mut color[3]);
    changed
}

pub fn color_sliders_rgb(ui: &mut egui::Ui, color: &mut [f32; 3]) -> bool {
    let mut changed = false;
    changed |= color_channel_slider(ui, "R:", &mut color[0]);
    changed |= color_channel_slider(ui, "G:", &mut color[1]);
    changed |= color_channel_slider(ui, "B:", &mut color[2]);
    changed
}