133 lines
3.7 KiB
Rust
Executable File
133 lines
3.7 KiB
Rust
Executable File
/*
|
|
* Copyright (C) 2022 Umut İnan Erdoğan <umutinanerdogan@pm.me>
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
use crate::{layout::position::Position, widget::Widget, window::Window};
|
|
use abletk_common::Renderer;
|
|
use winit::event::MouseButton;
|
|
|
|
pub struct Column {
|
|
widgets: Vec<Box<dyn Widget>>,
|
|
}
|
|
|
|
impl Widget for Column {
|
|
fn draw(&self, renderer: &mut Renderer) {
|
|
let (_, prev_y) = renderer.position();
|
|
self.widgets.iter().for_each(|widget| {
|
|
let pos = widget.position(renderer);
|
|
renderer.position_at(
|
|
renderer.position().0 + pos.x(),
|
|
renderer.position().1 + pos.y()
|
|
);
|
|
widget.draw(renderer);
|
|
renderer.position_at(
|
|
renderer.position().0,
|
|
renderer.position().1 + pos.height()
|
|
);
|
|
});
|
|
|
|
renderer.position_at(renderer.position().0, prev_y)
|
|
}
|
|
|
|
fn position(&self, renderer: &mut Renderer) -> Position {
|
|
let (width, height) = self.widgets.iter()
|
|
.map(|widget| widget.position(renderer))
|
|
.map(|pos| (pos.width(), pos.height()))
|
|
.fold((0, 0), |accum, item| (
|
|
if item.0 > accum.0 { item.0 } else { accum.0 },
|
|
accum.1 + item.1
|
|
));
|
|
|
|
Position::new(0, 0, width, height)
|
|
}
|
|
|
|
fn mouse_pressed(&mut self,
|
|
renderer: &mut Renderer,
|
|
window: &mut Window,
|
|
button: MouseButton,
|
|
x: u32,
|
|
y: u32,
|
|
) {
|
|
let mut pos = Position::new(0, 0, 0, 0);
|
|
for widget in &mut self.widgets {
|
|
let widget_pos = widget.position(renderer);
|
|
pos = Position::new(
|
|
widget_pos.x(),
|
|
pos.y() + widget_pos.y(),
|
|
widget_pos.width(),
|
|
widget_pos.height(),
|
|
);
|
|
|
|
if pos.contains(x, y) {
|
|
widget.mouse_pressed(
|
|
renderer,
|
|
window,
|
|
button,
|
|
x - pos.x(),
|
|
y - pos.y(),
|
|
);
|
|
}
|
|
|
|
pos = Position::new(
|
|
pos.x(),
|
|
pos.y() + widget_pos.height(),
|
|
pos.width(),
|
|
pos.height(),
|
|
)
|
|
}
|
|
}
|
|
|
|
fn mouse_released(&mut self,
|
|
renderer: &mut Renderer,
|
|
window: &mut Window,
|
|
button: MouseButton,
|
|
x: u32,
|
|
y: u32,
|
|
) {
|
|
let mut pos = Position::new(0, 0, 0, 0);
|
|
for widget in &mut self.widgets {
|
|
let widget_pos = widget.position(renderer);
|
|
pos = Position::new(
|
|
widget_pos.x(),
|
|
pos.y() + widget_pos.y(),
|
|
widget_pos.width(),
|
|
widget_pos.height(),
|
|
);
|
|
|
|
if pos.contains(x, y) {
|
|
widget.mouse_released(
|
|
renderer,
|
|
window,
|
|
button,
|
|
x - pos.x(),
|
|
y - pos.y(),
|
|
);
|
|
}
|
|
|
|
pos = Position::new(
|
|
pos.x(),
|
|
pos.y() + widget_pos.height(),
|
|
pos.width(),
|
|
pos.height(),
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Column {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
widgets: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn add<T: Widget + 'static>(mut self, widget: T) -> Self {
|
|
self.widgets.push(Box::new(widget));
|
|
self
|
|
}
|
|
}
|