use crate::core::algebra::{Vector2, Vector3};
use crate::dock::SplitDirection;
use crate::{
brush::Brush,
core::{
color::{Color, Hsv},
pool::Handle,
},
dock::TileContent,
draw::SharedTexture,
messagebox::MessageBoxResult,
popup::Placement,
ttf::SharedFont,
window::WindowTitle,
Control, HorizontalAlignment, MouseState, Orientation, Thickness, UINode, VerticalAlignment,
};
use std::{cell::Cell, fmt::Debug, path::PathBuf};
macro_rules! define_constructor {
($var:tt($inner:ident : $inner_var:tt) => fn $name:ident(), layout: $perform_layout:expr) => {
pub fn $name(destination: Handle<UINode<M, C>>, direction: MessageDirection) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::$var($inner::$inner_var),
destination,
direction,
perform_layout: Cell::new($perform_layout),
flags: 0
}
}
};
($var:tt($inner:ident : $inner_var:tt) => fn $name:ident($typ:ty), layout: $perform_layout:expr) => {
pub fn $name(destination: Handle<UINode<M, C>>, direction: MessageDirection, value:$typ) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::$var($inner::$inner_var(value)),
destination,
direction,
perform_layout: Cell::new($perform_layout),
flags: 0
}
}
};
($var:tt($inner:ident : $inner_var:tt) => fn $name:ident( $($params:ident : $types:ty),+ ), layout: $perform_layout:expr) => {
pub fn $name(destination: Handle<UINode<M, C>>, direction: MessageDirection, $($params : $types),+) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::$var($inner::$inner_var { $($params),+ } ),
destination,
direction,
perform_layout: Cell::new($perform_layout),
flags: 0
}
}
}
}
macro_rules! define_constructor_unbound {
($var:tt($inner:ident : $inner_var:tt) => fn $name:ident(), layout: $perform_layout:expr) => {
pub fn $name<M: MessageData, C: Control<M, C>>(destination: Handle<UINode<M, C>>, direction: MessageDirection) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::$var($inner::$inner_var),
destination,
direction,
perform_layout: Cell::new($perform_layout),
flags: 0
}
}
};
($var:tt($inner:ident : $inner_var:tt) => fn $name:ident($typ:ty), layout: $perform_layout:expr) => {
pub fn $name<M: MessageData, C: Control<M, C>>(destination: Handle<UINode<M, C>>, direction: MessageDirection, value:$typ) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::$var($inner::$inner_var(value)),
destination,
direction,
perform_layout: Cell::new($perform_layout),
flags: 0
}
}
};
($var:tt($inner:ident : $inner_var:tt) => fn $name:ident( $($params:ident : $types:ty),+ ), layout: $perform_layout:expr) => {
pub fn $name<M: MessageData, C: Control<M, C>>(destination: Handle<UINode<M, C>>, direction: MessageDirection, $($params : $types),+) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::$var($inner::$inner_var { $($params),+ } ),
destination,
direction,
perform_layout: Cell::new($perform_layout),
flags: 0
}
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum WidgetMessage<M: MessageData, C: Control<M, C>> {
MouseDown {
pos: Vector2<f32>,
button: MouseButton,
},
MouseUp {
pos: Vector2<f32>,
button: MouseButton,
},
MouseMove {
pos: Vector2<f32>,
state: MouseState,
},
MouseWheel {
pos: Vector2<f32>,
amount: f32,
},
MouseLeave,
MouseEnter,
Text(char),
KeyDown(KeyCode),
KeyUp(KeyCode),
GotFocus,
DragStarted(Handle<UINode<M, C>>),
DragOver(Handle<UINode<M, C>>),
Drop(Handle<UINode<M, C>>),
LostFocus,
TopMost,
Unlink,
Remove,
LinkWith(Handle<UINode<M, C>>),
LinkWithReverse(Handle<UINode<M, C>>),
Background(Brush),
Foreground(Brush),
Name(String),
Width(f32),
Height(f32),
VerticalAlignment(VerticalAlignment),
HorizontalAlignment(HorizontalAlignment),
MaxSize(Vector2<f32>),
MinSize(Vector2<f32>),
Row(usize),
Column(usize),
Margin(Thickness),
HitTestVisibility(bool),
Visibility(bool),
ZIndex(usize),
DesiredPosition(Vector2<f32>),
Enabled(bool),
Center,
Cursor(Option<CursorIcon>),
Opacity(f32),
}
impl<M: MessageData, C: Control<M, C>> WidgetMessage<M, C> {
define_constructor!(Widget(WidgetMessage:Remove) => fn remove(), layout: false);
define_constructor!(Widget(WidgetMessage:Unlink) => fn unlink(), layout: false);
define_constructor!(Widget(WidgetMessage:LinkWith) => fn link(Handle<UINode<M, C>>), layout: false);
define_constructor!(Widget(WidgetMessage:LinkWithReverse) => fn link_reverse(Handle<UINode<M, C>>), layout: false);
define_constructor!(Widget(WidgetMessage:Background) => fn background(Brush), layout: false);
define_constructor!(Widget(WidgetMessage:Foreground) => fn foreground(Brush), layout: false);
define_constructor!(Widget(WidgetMessage:Visibility) => fn visibility(bool), layout: false);
define_constructor!(Widget(WidgetMessage:Width) => fn width(f32), layout: false);
define_constructor!(Widget(WidgetMessage:Height) => fn height(f32), layout: false);
define_constructor!(Widget(WidgetMessage:DesiredPosition) => fn desired_position(Vector2<f32>), layout: false);
define_constructor!(Widget(WidgetMessage:Center) => fn center(), layout: true);
define_constructor!(Widget(WidgetMessage:TopMost) => fn topmost(), layout: false);
define_constructor!(Widget(WidgetMessage:Enabled) => fn enabled(bool), layout: false);
define_constructor!(Widget(WidgetMessage:Name) => fn name(String), layout: false);
define_constructor!(Widget(WidgetMessage:Row) => fn row(usize), layout: false);
define_constructor!(Widget(WidgetMessage:Column) => fn column(usize), layout: false);
define_constructor!(Widget(WidgetMessage:Cursor) => fn cursor(Option<CursorIcon>), layout: false);
define_constructor!(Widget(WidgetMessage:ZIndex) => fn z_index(usize), layout: false);
define_constructor!(Widget(WidgetMessage:HitTestVisibility) => fn hit_test_visibility(bool), layout: false);
define_constructor!(Widget(WidgetMessage:Margin) => fn margin(Thickness), layout: false);
define_constructor!(Widget(WidgetMessage:MinSize) => fn min_size(Vector2<f32>), layout: false);
define_constructor!(Widget(WidgetMessage:MaxSize) => fn max_size(Vector2<f32>), layout: false);
define_constructor!(Widget(WidgetMessage:HorizontalAlignment) => fn horizontal_alignment(HorizontalAlignment), layout: false);
define_constructor!(Widget(WidgetMessage:VerticalAlignment) => fn vertical_alignment(VerticalAlignment), layout: false);
define_constructor!(Widget(WidgetMessage:Opacity) => fn opacity(f32), layout: false);
define_constructor!(Widget(WidgetMessage:GotFocus) => fn got_focus(), layout: false);
define_constructor!(Widget(WidgetMessage:LostFocus) => fn lost_focus(), layout: false);
define_constructor!(Widget(WidgetMessage:MouseDown) => fn mouse_down(pos: Vector2<f32>, button: MouseButton), layout: false);
define_constructor!(Widget(WidgetMessage:MouseUp) => fn mouse_up(pos: Vector2<f32>, button: MouseButton), layout: false);
define_constructor!(Widget(WidgetMessage:MouseMove) => fn mouse_move(pos: Vector2<f32>, state: MouseState), layout: false);
define_constructor!(Widget(WidgetMessage:MouseWheel) => fn mouse_wheel(pos: Vector2<f32>, amount: f32), layout: false);
define_constructor!(Widget(WidgetMessage:MouseLeave) => fn mouse_leave(), layout: false);
define_constructor!(Widget(WidgetMessage:MouseEnter) => fn mouse_enter(), layout: false);
define_constructor!(Widget(WidgetMessage:Text) => fn text(char), layout: false);
define_constructor!(Widget(WidgetMessage:KeyDown) => fn key_down(KeyCode), layout: false);
define_constructor!(Widget(WidgetMessage:KeyUp) => fn key_up(KeyCode), layout: false);
define_constructor!(Widget(WidgetMessage:DragStarted) => fn drag_started(Handle<UINode<M, C>>), layout: false);
define_constructor!(Widget(WidgetMessage:DragOver) => fn drag_over(Handle<UINode<M, C>>), layout: false);
define_constructor!(Widget(WidgetMessage:Drop) => fn drop(Handle<UINode<M, C>>), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ButtonMessage<M: MessageData, C: Control<M, C>> {
Click,
Content(Handle<UINode<M, C>>),
}
impl<M: MessageData, C: Control<M, C>> ButtonMessage<M, C> {
define_constructor!(Button(ButtonMessage:Click) => fn click(), layout: false);
define_constructor!(Button(ButtonMessage:Content) => fn content(Handle<UINode<M, C>>), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ScrollBarMessage {
Value(f32),
MinValue(f32),
MaxValue(f32),
}
impl ScrollBarMessage {
define_constructor_unbound!(ScrollBar(ScrollBarMessage:Value) => fn value(f32), layout: false);
define_constructor_unbound!(ScrollBar(ScrollBarMessage:MaxValue) => fn max_value(f32), layout: false);
define_constructor_unbound!(ScrollBar(ScrollBarMessage:MinValue) => fn min_value(f32), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum CheckBoxMessage {
Check(Option<bool>),
}
impl CheckBoxMessage {
define_constructor_unbound!(CheckBox(CheckBoxMessage:Check) => fn checked(Option<bool>), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ExpanderMessage {
Expand(bool),
}
impl ExpanderMessage {
define_constructor_unbound!(Expander(ExpanderMessage:Expand) => fn expand(bool), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum WindowMessage<M: MessageData, C: Control<M, C>> {
Open { center: bool },
OpenModal { center: bool },
Close,
Minimize(bool),
CanMinimize(bool),
CanClose(bool),
CanResize(bool),
MoveStart,
Move(Vector2<f32>),
MoveEnd,
Title(WindowTitle<M, C>),
}
impl<M: MessageData, C: Control<M, C>> WindowMessage<M, C> {
define_constructor!(Window(WindowMessage:Open) => fn open(center: bool), layout: false);
define_constructor!(Window(WindowMessage:OpenModal) => fn open_modal(center: bool), layout: false);
define_constructor!(Window(WindowMessage:Close) => fn close(), layout: false);
define_constructor!(Window(WindowMessage:Minimize) => fn minimize(bool), layout: false);
define_constructor!(Window(WindowMessage:CanMinimize) => fn can_minimize(bool), layout: false);
define_constructor!(Window(WindowMessage:CanClose) => fn can_close(bool), layout: false);
define_constructor!(Window(WindowMessage:CanResize) => fn can_resize(bool), layout: false);
define_constructor!(Window(WindowMessage:MoveStart) => fn move_start(), layout: false);
define_constructor!(Window(WindowMessage:Move) => fn move_to(Vector2<f32>), layout: false);
define_constructor!(Window(WindowMessage:MoveEnd) => fn move_end(), layout: false);
define_constructor!(Window(WindowMessage:Title) => fn title(WindowTitle<M, C>), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ScrollViewerMessage<M: MessageData, C: Control<M, C>> {
Content(Handle<UINode<M, C>>),
BringIntoView(Handle<UINode<M, C>>),
}
impl<M: MessageData, C: Control<M, C>> ScrollViewerMessage<M, C> {
define_constructor!(ScrollViewer(ScrollViewerMessage:Content) => fn content(Handle<UINode<M, C>>), layout: false);
define_constructor!(ScrollViewer(ScrollViewerMessage:BringIntoView) => fn bring_into_view(Handle<UINode<M, C>>), layout: true);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ListViewMessage<M: MessageData, C: Control<M, C>> {
SelectionChanged(Option<usize>),
Items(Vec<Handle<UINode<M, C>>>),
AddItem(Handle<UINode<M, C>>),
}
impl<M: MessageData, C: Control<M, C>> ListViewMessage<M, C> {
define_constructor!(ListView(ListViewMessage:SelectionChanged) => fn selection(Option<usize>), layout: false);
define_constructor!(ListView(ListViewMessage:Items) => fn items(Vec<Handle<UINode<M, C>>>), layout: false);
define_constructor!(ListView(ListViewMessage:AddItem) => fn add_item(Handle<UINode<M, C>>), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum DropdownListMessage<M: MessageData, C: Control<M, C>> {
SelectionChanged(Option<usize>),
Items(Vec<Handle<UINode<M, C>>>),
AddItem(Handle<UINode<M, C>>),
}
impl<M: MessageData, C: Control<M, C>> DropdownListMessage<M, C> {
define_constructor!(DropdownList(DropdownListMessage:SelectionChanged) => fn selection(Option<usize>), layout: false);
define_constructor!(DropdownList(DropdownListMessage:Items) => fn items(Vec<Handle<UINode<M, C>>>), layout: false);
define_constructor!(DropdownList(DropdownListMessage:AddItem) => fn add_item(Handle<UINode<M, C>>), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum PopupMessage<M: MessageData, C: Control<M, C>> {
Open,
Close,
Content(Handle<UINode<M, C>>),
Placement(Placement),
}
impl<M: MessageData, C: Control<M, C>> PopupMessage<M, C> {
define_constructor!(Popup(PopupMessage:Open) => fn open(), layout: false);
define_constructor!(Popup(PopupMessage:Close) => fn close(), layout: false);
define_constructor!(Popup(PopupMessage:Content) => fn content(Handle<UINode<M, C>>), layout: false);
define_constructor!(Popup(PopupMessage:Placement) => fn placement(Placement), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum FileSelectorMessage {
Root(Option<PathBuf>),
Path(PathBuf),
Commit(PathBuf),
Cancel,
}
impl FileSelectorMessage {
define_constructor_unbound!(FileSelector(FileSelectorMessage:Commit) => fn commit(PathBuf), layout: false);
define_constructor_unbound!(FileSelector(FileSelectorMessage:Root) => fn root(Option<PathBuf>), layout: false);
define_constructor_unbound!(FileSelector(FileSelectorMessage:Path) => fn path(PathBuf), layout: false);
define_constructor_unbound!(FileSelector(FileSelectorMessage:Cancel) => fn cancel(), layout: false);
}
#[derive(Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Debug)]
pub enum TreeExpansionStrategy {
Direct,
RecursiveDescendants,
RecursiveAncestors,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct SelectionState(pub(in crate) bool);
#[derive(Debug, Clone, PartialEq)]
pub enum TreeMessage<M: MessageData, C: Control<M, C>> {
Expand {
expand: bool,
expansion_strategy: TreeExpansionStrategy,
},
AddItem(Handle<UINode<M, C>>),
RemoveItem(Handle<UINode<M, C>>),
SetItems(Vec<Handle<UINode<M, C>>>),
Select(SelectionState),
}
impl<M: MessageData, C: Control<M, C>> TreeMessage<M, C> {
define_constructor!(Tree(TreeMessage:AddItem) => fn add_item(Handle<UINode<M, C>>), layout: false);
define_constructor!(Tree(TreeMessage:RemoveItem) => fn remove_item(Handle<UINode<M, C>>), layout: false);
define_constructor!(Tree(TreeMessage:SetItems) => fn set_items(Vec<Handle<UINode<M, C>>>), layout: false);
define_constructor!(Tree(TreeMessage:Expand) => fn expand(expand: bool, expansion_strategy: TreeExpansionStrategy), layout: false);
pub(in crate) fn select(
destination: Handle<UINode<M, C>>,
direction: MessageDirection,
select: bool,
) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::Tree(TreeMessage::Select(SelectionState(select))),
destination,
direction,
perform_layout: Cell::new(false),
flags: 0,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum TreeRootMessage<M: MessageData, C: Control<M, C>> {
AddItem(Handle<UINode<M, C>>),
RemoveItem(Handle<UINode<M, C>>),
Items(Vec<Handle<UINode<M, C>>>),
Selected(Vec<Handle<UINode<M, C>>>),
ExpandAll,
CollapseAll,
}
impl<M: MessageData, C: Control<M, C>> TreeRootMessage<M, C> {
define_constructor!(TreeRoot(TreeRootMessage:AddItem) => fn add_item(Handle<UINode<M, C>>), layout: false);
define_constructor!(TreeRoot(TreeRootMessage:RemoveItem) => fn remove_item(Handle<UINode<M, C>>), layout: false);
define_constructor!(TreeRoot(TreeRootMessage:Items) => fn items(Vec<Handle<UINode<M, C>>>), layout: false);
define_constructor!(TreeRoot(TreeRootMessage:Selected) => fn select(Vec<Handle<UINode<M, C>>>), layout: false);
define_constructor!(TreeRoot(TreeRootMessage:ExpandAll) => fn expand_all(), layout: false);
define_constructor!(TreeRoot(TreeRootMessage:CollapseAll) => fn collapse_all(), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum FileBrowserMessage {
Root(Option<PathBuf>),
Path(PathBuf),
}
impl FileBrowserMessage {
define_constructor_unbound!(FileBrowser(FileBrowserMessage:Root) => fn root(Option<PathBuf>), layout: false);
define_constructor_unbound!(FileBrowser(FileBrowserMessage:Path) => fn path(PathBuf), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum TextBoxMessage {
Text(String),
}
impl TextBoxMessage {
define_constructor_unbound!(TextBox(TextBoxMessage:Text) => fn text(String), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum TextMessage {
Text(String),
Wrap(bool),
Font(SharedFont),
VerticalAlignment(VerticalAlignment),
HorizontalAlignment(HorizontalAlignment),
}
impl TextMessage {
define_constructor_unbound!(Text(TextMessage:Text) => fn text(String), layout: false);
define_constructor_unbound!(Text(TextMessage:Wrap) => fn wrap(bool), layout: false);
define_constructor_unbound!(Text(TextMessage:Font) => fn font(SharedFont), layout: false);
define_constructor_unbound!(Text(TextMessage:VerticalAlignment) => fn vertical_alignment(VerticalAlignment), layout: false);
define_constructor_unbound!(Text(TextMessage:HorizontalAlignment) => fn horizontal_alignment(HorizontalAlignment), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ImageMessage {
Texture(Option<SharedTexture>),
Flip(bool),
}
impl ImageMessage {
define_constructor_unbound!(Image(ImageMessage:Texture) => fn texture(Option<SharedTexture>), layout: false);
define_constructor_unbound!(Image(ImageMessage:Flip) => fn flip(bool), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum TileMessage<M: MessageData, C: Control<M, C>> {
Content(TileContent<M, C>),
Split {
window: Handle<UINode<M, C>>,
direction: SplitDirection,
first: bool,
},
}
impl<M: MessageData, C: Control<M, C>> TileMessage<M, C> {
define_constructor!(Tile(TileMessage:Content) => fn content(TileContent<M, C>), layout: false);
pub(in crate) fn split(
destination: Handle<UINode<M, C>>,
direction: MessageDirection,
window: Handle<UINode<M, C>>,
split_direction: SplitDirection,
first: bool,
) -> UiMessage<M, C> {
UiMessage {
handled: Cell::new(false),
data: UiMessageData::Tile(TileMessage::Split {
window,
direction: split_direction,
first,
}),
destination,
direction,
perform_layout: Cell::new(false),
flags: 0,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum NumericUpDownMessage {
Value(f32),
}
impl NumericUpDownMessage {
define_constructor_unbound!(NumericUpDown(NumericUpDownMessage:Value) => fn value(f32), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum Vec3EditorMessage {
Value(Vector3<f32>),
}
impl Vec3EditorMessage {
define_constructor_unbound!(Vec3Editor(Vec3EditorMessage:Value) => fn value(Vector3<f32>), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ScrollPanelMessage<M: MessageData, C: Control<M, C>> {
VerticalScroll(f32),
HorizontalScroll(f32),
BringIntoView(Handle<UINode<M, C>>),
}
impl<M: MessageData, C: Control<M, C>> ScrollPanelMessage<M, C> {
define_constructor!(ScrollPanel(ScrollPanelMessage:VerticalScroll) => fn vertical_scroll(f32), layout: false);
define_constructor!(ScrollPanel(ScrollPanelMessage:HorizontalScroll) => fn horizontal_scroll(f32), layout: false);
define_constructor!(ScrollPanel(ScrollPanelMessage:BringIntoView) => fn bring_into_view(Handle<UINode<M, C>>), layout: true);
}
#[derive(Debug, Clone, PartialEq)]
pub enum MenuMessage {
Activate,
Deactivate,
}
impl MenuMessage {
define_constructor_unbound!(Menu(MenuMessage:Activate) => fn activate(), layout: false);
define_constructor_unbound!(Menu(MenuMessage:Deactivate) => fn deactivate(), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum MenuItemMessage {
Open,
Close,
Click,
}
impl MenuItemMessage {
define_constructor_unbound!(MenuItem(MenuItemMessage:Open) => fn open(), layout: false);
define_constructor_unbound!(MenuItem(MenuItemMessage:Close) => fn close(), layout: false);
define_constructor_unbound!(MenuItem(MenuItemMessage:Click) => fn click(), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum MessageBoxMessage {
Open {
title: Option<String>,
text: Option<String>,
},
Close(MessageBoxResult),
}
impl MessageBoxMessage {
define_constructor_unbound!(MessageBox(MessageBoxMessage:Open) => fn open(title: Option<String>, text: Option<String>), layout: false);
define_constructor_unbound!(MessageBox(MessageBoxMessage:Close) => fn close(MessageBoxResult), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum DecoratorMessage {
Select(bool),
HoverBrush(Brush),
NormalBrush(Brush),
PressedBrush(Brush),
SelectedBrush(Brush),
}
impl DecoratorMessage {
define_constructor_unbound!(Decorator(DecoratorMessage:Select) => fn select(bool), layout: false);
define_constructor_unbound!(Decorator(DecoratorMessage:HoverBrush) => fn hover_brush(Brush), layout: false);
define_constructor_unbound!(Decorator(DecoratorMessage:NormalBrush) => fn normal_brush(Brush), layout: false);
define_constructor_unbound!(Decorator(DecoratorMessage:PressedBrush) => fn pressed_brush(Brush), layout: false);
define_constructor_unbound!(Decorator(DecoratorMessage:SelectedBrush) => fn selected_brush(Brush), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ProgressBarMessage {
Progress(f32),
}
impl ProgressBarMessage {
define_constructor_unbound!(ProgressBar(ProgressBarMessage:Progress) => fn progress(f32), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum HueBarMessage {
Hue(f32),
Orientation(Orientation),
}
impl HueBarMessage {
define_constructor_unbound!(HueBar(HueBarMessage:Hue) => fn hue(f32), layout: false);
define_constructor_unbound!(HueBar(HueBarMessage:Orientation) => fn orientation(Orientation), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum AlphaBarMessage {
Alpha(f32),
Orientation(Orientation),
}
impl AlphaBarMessage {
define_constructor_unbound!(AlphaBar(AlphaBarMessage:Alpha) => fn alpha(f32), layout: false);
define_constructor_unbound!(AlphaBar(AlphaBarMessage:Orientation) => fn orientation(Orientation), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum SaturationBrightnessFieldMessage {
Hue(f32),
Saturation(f32),
Brightness(f32),
}
impl SaturationBrightnessFieldMessage {
define_constructor_unbound!(SaturationBrightnessField(SaturationBrightnessFieldMessage:Hue) => fn hue(f32), layout: false);
define_constructor_unbound!(SaturationBrightnessField(SaturationBrightnessFieldMessage:Saturation) => fn saturation(f32), layout: false);
define_constructor_unbound!(SaturationBrightnessField(SaturationBrightnessFieldMessage:Brightness) => fn brightness(f32), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ColorPickerMessage {
Color(Color),
Hsv(Hsv),
}
impl ColorPickerMessage {
define_constructor_unbound!(ColorPicker(ColorPickerMessage:Color) => fn color(Color), layout: false);
define_constructor_unbound!(ColorPicker(ColorPickerMessage:Hsv) => fn hsv(Hsv), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum ColorFieldMessage {
Color(Color),
}
impl ColorFieldMessage {
define_constructor_unbound!(ColorField(ColorFieldMessage:Color) => fn color(Color), layout: false);
}
#[derive(Debug, Clone, PartialEq)]
pub enum UiMessageData<M: MessageData, C: Control<M, C>> {
Widget(WidgetMessage<M, C>),
Button(ButtonMessage<M, C>),
ScrollBar(ScrollBarMessage),
CheckBox(CheckBoxMessage),
Window(WindowMessage<M, C>),
ListView(ListViewMessage<M, C>),
DropdownList(DropdownListMessage<M, C>),
Popup(PopupMessage<M, C>),
ScrollViewer(ScrollViewerMessage<M, C>),
Tree(TreeMessage<M, C>),
TreeRoot(TreeRootMessage<M, C>),
FileBrowser(FileBrowserMessage),
FileSelector(FileSelectorMessage),
TextBox(TextBoxMessage),
NumericUpDown(NumericUpDownMessage),
Vec3Editor(Vec3EditorMessage),
Menu(MenuMessage),
MenuItem(MenuItemMessage),
MessageBox(MessageBoxMessage),
Decorator(DecoratorMessage),
Text(TextMessage),
ScrollPanel(ScrollPanelMessage<M, C>),
Tile(TileMessage<M, C>),
ProgressBar(ProgressBarMessage),
Image(ImageMessage),
HueBar(HueBarMessage),
AlphaBar(AlphaBarMessage),
ColorPicker(ColorPickerMessage),
ColorField(ColorFieldMessage),
Expander(ExpanderMessage),
SaturationBrightnessField(SaturationBrightnessFieldMessage),
User(M),
}
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Hash)]
pub enum MessageDirection {
ToWidget,
FromWidget,
}
impl MessageDirection {
pub fn reverse(self) -> Self {
match self {
Self::ToWidget => Self::FromWidget,
Self::FromWidget => Self::ToWidget,
}
}
}
pub trait MessageData: 'static + Debug + Clone + PartialEq {}
#[derive(Debug, Clone, PartialEq)]
pub struct UiMessage<M: MessageData, C: Control<M, C>> {
handled: Cell<bool>,
data: UiMessageData<M, C>,
destination: Handle<UINode<M, C>>,
direction: MessageDirection,
perform_layout: Cell<bool>,
pub flags: u64,
}
impl<M: MessageData, C: Control<M, C>> UiMessage<M, C> {
#[must_use = "method creates new value which must be used"]
pub fn reverse(&self) -> Self {
Self {
handled: self.handled.clone(),
data: self.data.clone(),
destination: self.destination,
direction: self.direction.reverse(),
perform_layout: self.perform_layout.clone(),
flags: self.flags,
}
}
pub fn destination(&self) -> Handle<UINode<M, C>> {
self.destination
}
pub fn data(&self) -> &UiMessageData<M, C> {
&self.data
}
pub fn set_handled(&self, handled: bool) {
self.handled.set(handled);
}
pub fn handled(&self) -> bool {
self.handled.get()
}
pub fn direction(&self) -> MessageDirection {
self.direction
}
pub fn set_perform_layout(&self, value: bool) {
self.perform_layout.set(value);
}
pub fn need_perform_layout(&self) -> bool {
self.perform_layout.get()
}
pub fn user(destination: Handle<UINode<M, C>>, direction: MessageDirection, msg: M) -> Self {
Self {
handled: Cell::new(false),
data: UiMessageData::User(msg),
destination,
direction,
perform_layout: Cell::new(false),
flags: 0,
}
}
pub fn has_flags(&self, flags: u64) -> bool {
self.flags & flags != 0
}
}
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
pub enum ButtonState {
Pressed,
Released,
}
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
pub enum MouseButton {
Left,
Right,
Middle,
Other(u16),
}
pub enum OsEvent {
MouseInput {
button: MouseButton,
state: ButtonState,
},
CursorMoved {
position: Vector2<f32>,
},
KeyboardInput {
button: KeyCode,
state: ButtonState,
},
Character(char),
KeyboardModifiers(KeyboardModifiers),
MouseWheel(f32, f32),
}
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
pub struct KeyboardModifiers {
pub alt: bool,
pub shift: bool,
pub control: bool,
pub system: bool,
}
impl KeyboardModifiers {
pub fn is_none(self) -> bool {
!self.shift && !self.control && !self.alt && !self.system
}
}
impl Default for KeyboardModifiers {
fn default() -> Self {
Self {
alt: false,
shift: false,
control: false,
system: false,
}
}
}
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
#[repr(u32)]
pub enum KeyCode {
Key1,
Key2,
Key3,
Key4,
Key5,
Key6,
Key7,
Key8,
Key9,
Key0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
Escape,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
F16,
F17,
F18,
F19,
F20,
F21,
F22,
F23,
F24,
Snapshot,
Scroll,
Pause,
Insert,
Home,
Delete,
End,
PageDown,
PageUp,
Left,
Up,
Right,
Down,
Backspace,
Return,
Space,
Compose,
Caret,
Numlock,
Numpad0,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
AbntC1,
AbntC2,
NumpadAdd,
Apostrophe,
Apps,
At,
Ax,
Backslash,
Calculator,
Capital,
Colon,
Comma,
Convert,
NumpadDecimal,
NumpadDivide,
Equals,
Grave,
Kana,
Kanji,
LAlt,
LBracket,
LControl,
LShift,
LWin,
Mail,
MediaSelect,
MediaStop,
Minus,
NumpadMultiply,
Mute,
MyComputer,
NavigateForward,
NavigateBackward,
NextTrack,
NoConvert,
NumpadComma,
NumpadEnter,
NumpadEquals,
OEM102,
Period,
PlayPause,
Power,
PrevTrack,
RAlt,
RBracket,
RControl,
RShift,
RWin,
Semicolon,
Slash,
Sleep,
Stop,
NumpadSubtract,
Sysrq,
Tab,
Underline,
Unlabeled,
VolumeDown,
VolumeUp,
Wake,
WebBack,
WebFavorites,
WebForward,
WebHome,
WebRefresh,
WebSearch,
WebStop,
Yen,
Copy,
Paste,
Cut,
Asterisk,
Plus,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CursorIcon {
Default,
Crosshair,
Hand,
Arrow,
Move,
Text,
Wait,
Help,
Progress,
NotAllowed,
ContextMenu,
Cell,
VerticalText,
Alias,
Copy,
NoDrop,
Grab,
Grabbing,
AllScroll,
ZoomIn,
ZoomOut,
EResize,
NResize,
NeResize,
NwResize,
SResize,
SeResize,
SwResize,
WResize,
EwResize,
NsResize,
NeswResize,
NwseResize,
ColResize,
RowResize,
}
impl Default for CursorIcon {
fn default() -> Self {
CursorIcon::Default
}
}