tuigui/widgets/
shader_container.rsuse crate::preludes::widget_creation::*;
use crate::Shader;
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Shaders<S: Shader> {
Single(S),
Many(Vec<S>),
}
impl<S: Shader> Shaders<S> {
fn apply(&mut self, canvas: &mut Canvas) {
for col in 0..canvas.transform.size.cols {
for row in 0..canvas.transform.size.rows {
let position = Position::new(col as i16, row as i16);
match self {
Self::Single(ref mut single) => {
apply(
single,
canvas,
position,
);
},
Self::Many(many) => {
for shader in many {
apply(
shader,
canvas,
position,
);
}
},
};
}
}
}
}
fn apply<S: Shader>(
shader: &mut S,
canvas: &mut Canvas,
local_position: Position,
) {
let shader_config = shader.config();
let real_position = canvas.transform.position + local_position;
let shader_position = match shader_config.real_position {
true => real_position,
false => local_position,
};
if shader_config.whole_area == false {
if canvas.changed_at(local_position) == false {
return;
}
}
let content = canvas.get(local_position);
let result = shader.apply(canvas, shader_position, content);
canvas.set(local_position, result);
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ShaderContainer<W: Widget, S: Shader> {
pub widget: W,
pub shaders: Shaders<S>,
widget_data: WidgetData,
}
impl<W: Widget, S: Shader> ShaderContainer<W, S> {
pub fn new(shaders: Shaders<S>, widget: W) -> Self {
Self {
widget,
shaders,
widget_data: WidgetData::new(),
}
}
}
impl<W: Widget, S: Shader> Widget for ShaderContainer<W, S> {
fn draw(&mut self, canvas: &mut Canvas, state_frame: &EventStateFrame) {
self.widget.draw(canvas, state_frame);
self.shaders.apply(canvas);
}
fn widget_info(&self) -> WidgetInfo {
return self.widget.widget_info();
}
fn widget_data(&mut self) -> &mut WidgetData {
return &mut self.widget_data;
}
}