use std::rc::Rc;
use teksilo_canvas::{Rect, Size, SizeProposal};
use teksilo_core::event::{EventResponse, PointerButton, WidgetEvent};
use teksilo_core::widget::{CursorIcon, LayoutContext, PaintContext, Widget, WidgetPlacement};
use teksilo_core::widget_builder::HandlerSet;
use teksilo_core::widget_id::WidgetId;
use teksilo_core::{PlatformTitleBarHost, ResizeEdge};
pub struct ResizeStrip {
host: Rc<dyn PlatformTitleBarHost>,
edge: ResizeEdge,
width: f32,
height: f32,
}
impl std::fmt::Debug for ResizeStrip {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ResizeStrip")
.field("edge", &self.edge)
.field("width", &self.width)
.field("height", &self.height)
.finish_non_exhaustive()
}
}
impl ResizeStrip {
pub fn horizontal(
host: Rc<dyn PlatformTitleBarHost>,
edge: ResizeEdge,
thickness: f32,
) -> Self {
debug_assert!(matches!(edge, ResizeEdge::Top | ResizeEdge::Bottom));
Self {
host,
edge,
width: 0.0,
height: thickness,
}
}
pub fn vertical(host: Rc<dyn PlatformTitleBarHost>, edge: ResizeEdge, thickness: f32) -> Self {
debug_assert!(matches!(edge, ResizeEdge::Left | ResizeEdge::Right));
Self {
host,
edge,
width: thickness,
height: 0.0,
}
}
pub fn corner(host: Rc<dyn PlatformTitleBarHost>, edge: ResizeEdge, size: f32) -> Self {
debug_assert!(matches!(
edge,
ResizeEdge::TopLeft
| ResizeEdge::TopRight
| ResizeEdge::BottomLeft
| ResizeEdge::BottomRight
));
Self {
host,
edge,
width: size,
height: size,
}
}
}
fn cursor_for_edge(edge: ResizeEdge) -> CursorIcon {
match edge {
ResizeEdge::Top | ResizeEdge::Bottom => CursorIcon::RowResize,
ResizeEdge::Left | ResizeEdge::Right => CursorIcon::ColResize,
ResizeEdge::TopLeft | ResizeEdge::BottomRight => CursorIcon::NwseResize,
ResizeEdge::TopRight | ResizeEdge::BottomLeft => CursorIcon::NeswResize,
}
}
impl Widget for ResizeStrip {
fn build(&mut self, ctx: &mut teksilo_core::build_context::BuildContext) -> Vec<WidgetId> {
let host = self.host.clone();
let edge = self.edge;
let handlers = HandlerSet::new()
.cursor(cursor_for_edge(edge))
.on_pointer_event(move |evt, _ctx| {
if let WidgetEvent::PointerDown {
button: PointerButton::Primary,
..
} = evt
{
let _ = host.begin_resize(edge);
return EventResponse::Handled;
}
EventResponse::Ignored
});
ctx.apply_self_handlers(handlers);
Vec::new()
}
fn layout_response(
&self,
proposal: SizeProposal,
_ctx: &LayoutContext,
) -> teksilo_core::widget::LayoutResponse {
let w = if self.width > 0.0 {
self.width
} else {
proposal.width.unwrap_or(0.0)
};
let h = if self.height > 0.0 {
self.height
} else {
proposal.height.unwrap_or(0.0)
};
Size::new(w, h).into()
}
fn place_children(
&self,
_bounds: Rect,
_proposal: SizeProposal,
_children: &mut [WidgetPlacement],
_ctx: &LayoutContext,
) {
}
fn paint(&self, _bounds: Rect, _canvas: &mut teksilo_canvas::Canvas, _ctx: &PaintContext) {
}
}