132 lines
3.8 KiB
Rust
132 lines
3.8 KiB
Rust
//! Shared material UV-transform authoring used by Materials and Material Instances.
|
|
|
|
use bevy::prelude::Vec2;
|
|
use bevy_egui::egui;
|
|
use egui_phosphor_icons::icons;
|
|
use shared::{MaterialInputSet, MaterialParameter, MaterialParameterValue};
|
|
|
|
use crate::ui::design_system;
|
|
use crate::ui::design_system::typography::TypeRole;
|
|
|
|
pub(super) fn uv_transform_section(
|
|
ui: &mut egui::Ui,
|
|
offset: &mut Vec2,
|
|
tiling: &mut Vec2,
|
|
reset_offset: Vec2,
|
|
reset_tiling: Vec2,
|
|
) {
|
|
let palette = design_system::palette(ui);
|
|
let width = ui.available_width().max(1.0);
|
|
let height = match super::layout::ResponsiveMaterialLayout::for_width(width) {
|
|
super::layout::ResponsiveMaterialLayout::Reference => {
|
|
crate::ui::design_system::UV_SECTION_HEIGHT
|
|
}
|
|
super::layout::ResponsiveMaterialLayout::Compact => {
|
|
crate::ui::design_system::COMPACT_UV_SECTION_HEIGHT
|
|
}
|
|
super::layout::ResponsiveMaterialLayout::Transient => 100.0,
|
|
};
|
|
let (rect, _) = ui.allocate_exact_size(egui::vec2(width, height), egui::Sense::hover());
|
|
ui.painter().rect(
|
|
rect,
|
|
5.0,
|
|
palette.section,
|
|
egui::Stroke::new(1.0_f32, palette.border),
|
|
egui::StrokeKind::Inside,
|
|
);
|
|
let mut child = ui.new_child(egui::UiBuilder::new().max_rect(rect));
|
|
child.set_clip_rect(rect.intersect(ui.clip_rect()));
|
|
let geometry = super::layout::UvSectionGeometry::for_rect(rect);
|
|
child.painter().text(
|
|
geometry.title.left_center(),
|
|
egui::Align2::LEFT_CENTER,
|
|
"UV",
|
|
TypeRole::Section.font(),
|
|
palette.text_primary,
|
|
);
|
|
vec2_group(
|
|
&mut child,
|
|
geometry.offset,
|
|
"Offset",
|
|
offset,
|
|
reset_offset,
|
|
"Reset UV offset",
|
|
);
|
|
vec2_group(
|
|
&mut child,
|
|
geometry.tiling,
|
|
"Tiling",
|
|
tiling,
|
|
reset_tiling,
|
|
"Reset UV tiling",
|
|
);
|
|
}
|
|
|
|
fn vec2_group(
|
|
ui: &mut egui::Ui,
|
|
geometry: super::layout::UvGroupGeometry,
|
|
label: &str,
|
|
value: &mut Vec2,
|
|
reset: Vec2,
|
|
tooltip: &str,
|
|
) {
|
|
let palette = design_system::palette(ui);
|
|
ui.painter().text(
|
|
geometry.label.left_center(),
|
|
egui::Align2::LEFT_CENTER,
|
|
label,
|
|
TypeRole::Small.font(),
|
|
palette.text_muted,
|
|
);
|
|
ui.put(
|
|
geometry.x,
|
|
egui::DragValue::new(&mut value.x).speed(0.01).prefix("X "),
|
|
);
|
|
ui.put(
|
|
geometry.y,
|
|
egui::DragValue::new(&mut value.y).speed(0.01).prefix("Y "),
|
|
);
|
|
if let Some(reset_rect) = geometry.reset {
|
|
let enabled = *value != reset;
|
|
let response = ui.put(
|
|
reset_rect,
|
|
egui::Button::new(
|
|
egui::RichText::new(icons::ARROW_COUNTER_CLOCKWISE.as_str()).font(
|
|
egui::FontId::new(14.0, egui::FontFamily::Name("phosphor-bold".into())),
|
|
),
|
|
),
|
|
);
|
|
if enabled && response.clicked() {
|
|
*value = reset;
|
|
}
|
|
response.on_hover_text(tooltip);
|
|
}
|
|
}
|
|
|
|
pub(super) fn material_vec2_value(inputs: &MaterialInputSet, name: &str, default: Vec2) -> Vec2 {
|
|
inputs
|
|
.values
|
|
.iter()
|
|
.find(|parameter| parameter.name == name)
|
|
.and_then(|parameter| match parameter.value {
|
|
MaterialParameterValue::Vec2(value) => Some(value),
|
|
_ => None,
|
|
})
|
|
.unwrap_or(default)
|
|
}
|
|
|
|
pub(super) fn set_material_vec2_value(inputs: &mut MaterialInputSet, name: &str, value: Vec2) {
|
|
if let Some(parameter) = inputs
|
|
.values
|
|
.iter_mut()
|
|
.find(|parameter| parameter.name == name)
|
|
{
|
|
parameter.value = MaterialParameterValue::Vec2(value);
|
|
} else {
|
|
inputs.values.push(MaterialParameter {
|
|
name: name.into(),
|
|
value: MaterialParameterValue::Vec2(value),
|
|
});
|
|
}
|
|
}
|