use super::{Label, MarkButton};
use crate::event::CursorIcon;
use crate::prelude::*;
use crate::theme::{FrameStyle, MarkStyle};
use crate::window::ResizeDirection;
use kas_macros::impl_self;
use std::fmt::Debug;
#[impl_self]
mod Border {
#[widget]
pub(crate) struct Border {
core: widget_core!(),
resizable: bool,
direction: ResizeDirection,
}
impl Self {
pub fn new(direction: ResizeDirection) -> Self {
Border {
core: Default::default(),
resizable: true,
direction,
}
}
pub fn set_resizable(&mut self, resizable: bool) {
self.resizable = resizable;
}
}
impl Layout for Self {
fn size_rules(&mut self, _: &mut SizeCx, _axis: AxisInfo) -> SizeRules {
SizeRules::EMPTY
}
fn draw(&self, _: DrawCx) {}
}
impl Tile for Self {
fn role(&self, _: &mut dyn RoleCx) -> Role<'_> {
Role::Border
}
}
impl Events for Self {
type Data = ();
fn mouse_over_icon(&self) -> Option<CursorIcon> {
if self.resizable {
Some(self.direction.into())
} else {
None
}
}
fn handle_event(&mut self, cx: &mut EventCx, _: &Self::Data, event: Event) -> IsUsed {
match event {
Event::PressStart(_) => {
cx.drag_resize_window(self.direction);
Used
}
_ => Unused,
}
}
}
}
#[derive(Copy, Clone, Debug)]
enum TitleBarButton {
Minimize,
Maximize,
Close,
}
#[impl_self]
mod TitleBarButtons {
#[derive(Default)]
#[widget]
#[layout(row! [
MarkButton::new_msg(MarkStyle::Chevron(Direction::Down), "Minimize", TitleBarButton::Minimize),
MarkButton::new_msg(MarkStyle::Chevron(Direction::Up), "Maximize", TitleBarButton::Maximize),
MarkButton::new_msg(MarkStyle::X, "Close", TitleBarButton::Close),
])]
pub struct TitleBarButtons {
core: widget_core!(),
}
impl Self {
#[inline]
pub fn new() -> Self {
TitleBarButtons {
core: Default::default(),
}
}
}
impl Events for Self {
type Data = ();
fn handle_messages(&mut self, cx: &mut EventCx, _: &Self::Data) {
if let Some(msg) = cx.try_pop() {
match msg {
TitleBarButton::Minimize => {
if let Some(w) = cx.winit_window() {
w.set_minimized(true);
}
}
TitleBarButton::Maximize => {
if let Some(w) = cx.winit_window() {
w.set_maximized(!w.is_maximized());
}
}
TitleBarButton::Close => cx.close_own_window(),
}
}
}
}
}
#[impl_self]
mod TitleBar {
#[widget]
#[layout(frame!(row! [
self.title.align(AlignHints::CENTER).with_stretch(Stretch::Maximize, Stretch::None),
self.buttons,
]).with_style(FrameStyle::None))]
pub struct TitleBar {
core: widget_core!(),
#[widget]
title: Label<String>,
#[widget]
buttons: TitleBarButtons,
}
impl Self {
#[inline]
pub fn new(title: impl ToString) -> Self {
TitleBar {
core: Default::default(),
title: Label::new(title.to_string()),
buttons: Default::default(),
}
}
pub fn title(&self) -> &str {
self.title.as_str()
}
pub fn set_title(&mut self, cx: &mut ConfigCx, title: String) {
self.title.set_string(cx, title)
}
}
impl Tile for Self {
fn role(&self, cx: &mut dyn RoleCx) -> Role<'_> {
cx.set_label(self.title.id());
Role::TitleBar
}
}
impl Events for Self {
type Data = ();
fn handle_event(&mut self, cx: &mut EventCx, _: &Self::Data, event: Event) -> IsUsed {
match event {
Event::PressStart(_) => {
cx.drag_window();
Used
}
_ => Unused,
}
}
}
}