use crate::ui::layout_selection::selection_label;
use crate::ui::pills::show_pills;
use egui::{
Button, Color32, CornerRadius, Margin, Rect, Response, Sense, Shape, Ui, Vec2, Widget, pos2,
};
use epaint::RectShape;
use gled_model::{asset::scene::effect::Effect, collection::Collections, patching::Patch};
use gled_protocol::state::SoundSnapshot;
impl std::fmt::Debug for EffectWidget<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EffectWidget")
.field("effect", &self.effect)
.finish_non_exhaustive()
}
}
pub(crate) struct EffectWidget<'a> {
pub(crate) selectable: Option<(&'a mut usize, usize)>,
pub(crate) show_group: bool,
pub(crate) effect: &'a Effect,
pub(crate) thumbnail: Option<egui::TextureId>,
pub(crate) patch: Option<&'a Patch>,
pub(crate) beat_progression: Option<f32>,
pub(crate) collections: &'a Collections,
pub(crate) sound_data: &'a SoundSnapshot,
}
impl Widget for EffectWidget<'_> {
fn ui(self, ui: &mut Ui) -> Response {
let frame = if let Some((selected_effect, index)) = &self.selectable {
egui::Frame::NONE
.fill(if *selected_effect == index {
Color32::GOLD
} else {
Color32::TRANSPARENT
})
.inner_margin(Margin::from(10.0))
.corner_radius(CornerRadius::from(4.0))
} else {
egui::Frame::NONE
.inner_margin(Margin::from(10.0))
.corner_radius(CornerRadius::from(4.0))
};
let response = frame
.show(ui, |ui| {
let mut bg_rect = ui.available_rect_before_wrap() + Margin::same(5);
ui.painter()
.rect_filled(bg_rect, CornerRadius::ZERO, Color32::BLACK);
if let Some(beat_progression) = self.beat_progression {
let dimmer = self.effect.opacity.value(
beat_progression,
self.collections,
self.sound_data,
);
bg_rect.min.y += (bg_rect.height() * (1.0 - dimmer)).round().max(0.0);
ui.painter()
.rect_filled(bg_rect, CornerRadius::ZERO, Color32::DARK_GREEN);
}
let rect = ui.available_rect_before_wrap();
ui.allocate_rect(rect, Sense::hover());
ui.painter().add(Shape::Rect(RectShape::filled(
rect,
CornerRadius::default(),
Color32::BLACK,
)));
ui.painter().add(Shape::Rect({
let mut shape =
RectShape::filled(rect, CornerRadius::default(), Color32::WHITE);
if let Some(texture_id) = self.thumbnail {
shape = shape.with_texture(
texture_id,
Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)),
);
}
shape
}));
if self.show_group
&& let (Some(patch), Some(selection)) = (self.patch, self.effect.selection)
{
show_pills(
ui,
rect.right_top() + Vec2::new(0.0, 5.0),
vec![(selection_label(patch, selection), Color32::GOLD)],
);
}
})
.response;
if let Some((selected_effect, index)) = self.selectable {
let res = ui.put(response.rect, Button::new("").fill(Color32::TRANSPARENT));
if res.clicked() {
*selected_effect = index;
}
}
response
}
}