Renamed Array to Stack

This commit is contained in:
Jonathan Johnson 2023-10-30 21:41:14 -07:00
parent c9c4c9aeed
commit 93a9545cc4
No known key found for this signature in database
GPG key ID: A66D6A34D6620579
5 changed files with 70 additions and 71 deletions

View file

@ -1,14 +1,14 @@
use std::string::ToString; use std::string::ToString;
use gooey::value::Dynamic; use gooey::value::Dynamic;
use gooey::widgets::array::Array; use gooey::widgets::stack::Stack;
use gooey::widgets::{Button, Label}; use gooey::widgets::{Button, Label};
use gooey::{widgets, Run}; use gooey::{widgets, Run};
fn main() -> gooey::Result { fn main() -> gooey::Result {
let counter = Dynamic::new(0i32); let counter = Dynamic::new(0i32);
let label = counter.map_each(ToString::to_string); let label = counter.map_each(ToString::to_string);
Array::rows(widgets![ Stack::rows(widgets![
Label::new(label), Label::new(label),
Button::new("+").on_click(counter.with_clone(|counter| { Button::new("+").on_click(counter.with_clone(|counter| {
move |_| { move |_| {

View file

@ -1,7 +1,7 @@
use gooey::styles::components::TextColor; use gooey::styles::components::TextColor;
use gooey::styles::Styles; use gooey::styles::Styles;
use gooey::widget::{Widget, Widgets}; use gooey::widget::{Widget, Widgets};
use gooey::widgets::array::Array; use gooey::widgets::stack::Stack;
use gooey::widgets::{Button, Style}; use gooey::widgets::{Button, Style};
use gooey::window::Window; use gooey::window::Window;
use gooey::{styles, Run}; use gooey::{styles, Run};
@ -9,7 +9,7 @@ use kludgine::Color;
fn main() -> gooey::Result { fn main() -> gooey::Result {
Window::for_widget( Window::for_widget(
Array::rows( Stack::rows(
Widgets::new() Widgets::new()
.with_widget(Button::new("Default")) .with_widget(Button::new("Default"))
.with_widget(red_text(Button::new("Styled"))), .with_widget(red_text(Button::new("Styled"))),

View file

@ -29,9 +29,8 @@ impl Tick {
/// Processes `input`. /// Processes `input`.
/// ///
/// If the event matches a key that has been marked as /// If the event matches a key that has been marked as handled, [`HANDLED`]
/// handled, [`HANDLED`] will be returned. Otherwise, [`UNHANDLED`] will be /// will be returned. Otherwise, [`IGNORED`] will be returned,
/// returned,
#[must_use] #[must_use]
pub fn key_input(&self, input: &KeyEvent) -> EventHandling { pub fn key_input(&self, input: &KeyEvent) -> EventHandling {
let mut state = self.data.state(); let mut state = self.data.state();

View file

@ -1,10 +1,10 @@
//! Built-in [`Widget`](crate::widget::Widget) implementations. //! Built-in [`Widget`](crate::widget::Widget) implementations.
pub mod array;
mod button; mod button;
mod canvas; mod canvas;
mod input; mod input;
mod label; mod label;
pub mod stack;
mod style; mod style;
mod tilemap; mod tilemap;

View file

@ -12,11 +12,11 @@ use crate::widget::{ManagedWidget, Widget, Widgets};
use crate::ConstraintLimit; use crate::ConstraintLimit;
/// A widget that displays a collection of [`Widgets`] in a /// A widget that displays a collection of [`Widgets`] in a
/// [direction](ArrayDirection). /// [direction](StackDirection).
#[derive(Debug)] #[derive(Debug)]
pub struct Array { pub struct Stack {
/// The direction to display the children using. /// The direction to display the children using.
pub direction: Value<ArrayDirection>, pub direction: Value<StackDirection>,
/// The children widgets that belong to this array. /// The children widgets that belong to this array.
pub children: Value<Widgets>, pub children: Value<Widgets>,
layout: Layout, layout: Layout,
@ -25,10 +25,10 @@ pub struct Array {
synced_children: Vec<ManagedWidget>, synced_children: Vec<ManagedWidget>,
} }
impl Array { impl Stack {
/// Returns a new widget with the given direction and widgets. /// Returns a new widget with the given direction and widgets.
pub fn new( pub fn new(
direction: impl IntoValue<ArrayDirection>, direction: impl IntoValue<StackDirection>,
widgets: impl IntoValue<Widgets>, widgets: impl IntoValue<Widgets>,
) -> Self { ) -> Self {
let mut direction = direction.into_value(); let mut direction = direction.into_value();
@ -46,12 +46,12 @@ impl Array {
/// Returns a new instance that displays `widgets` in a series of columns. /// Returns a new instance that displays `widgets` in a series of columns.
pub fn columns(widgets: impl IntoValue<Widgets>) -> Self { pub fn columns(widgets: impl IntoValue<Widgets>) -> Self {
Self::new(ArrayDirection::columns(), widgets) Self::new(StackDirection::columns(), widgets)
} }
/// Returns a new instance that displays `widgets` in a series of rows. /// Returns a new instance that displays `widgets` in a series of rows.
pub fn rows(widgets: impl IntoValue<Widgets>) -> Self { pub fn rows(widgets: impl IntoValue<Widgets>) -> Self {
Self::new(ArrayDirection::rows(), widgets) Self::new(StackDirection::rows(), widgets)
} }
fn synchronize_children(&mut self, context: &mut EventContext<'_, '_>) { fn synchronize_children(&mut self, context: &mut EventContext<'_, '_>) {
@ -83,7 +83,7 @@ impl Array {
// This is a brand new child. // This is a brand new child.
self.synced_children self.synced_children
.insert(index, context.push_child(widget.clone())); .insert(index, context.push_child(widget.clone()));
self.layout.insert(index, ArrayDimension::FitContent); self.layout.insert(index, StackDimension::FitContent);
} }
} }
} }
@ -99,7 +99,7 @@ impl Array {
} }
} }
impl Widget for Array { impl Widget for Stack {
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) { fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
self.synchronize_children(&mut context.as_event_context()); self.synchronize_children(&mut context.as_event_context());
self.layout.update( self.layout.update(
@ -144,31 +144,21 @@ impl Widget for Array {
} }
} }
/// The direction of an [`Array`] widget. /// The direction of an [`Stack`] widget.
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct ArrayDirection { pub struct StackDirection {
/// The orientation of the widgets. /// The orientation of the widgets.
pub orientation: ArrayOrientation, pub orientation: StackOrientationn,
/// If true, the widgets will be laid out in reverse order. /// If true, the widgets will be laid out in reverse order.
pub reverse: bool, pub reverse: bool,
} }
/// The orientation (Row/Column) of an [`Array`] widget. impl StackDirection {
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ArrayOrientation {
/// The child widgets should be displayed as rows.
Row,
/// The child widgets should be displayed as columns.
Column,
}
impl ArrayDirection {
/// Display child widgets as columns. /// Display child widgets as columns.
#[must_use] #[must_use]
pub const fn columns() -> Self { pub const fn columns() -> Self {
Self { Self {
orientation: ArrayOrientation::Column, orientation: StackOrientationn::Column,
reverse: false, reverse: false,
} }
} }
@ -177,7 +167,7 @@ impl ArrayDirection {
#[must_use] #[must_use]
pub const fn columns_rev() -> Self { pub const fn columns_rev() -> Self {
Self { Self {
orientation: ArrayOrientation::Column, orientation: StackOrientationn::Column,
reverse: true, reverse: true,
} }
} }
@ -186,7 +176,7 @@ impl ArrayDirection {
#[must_use] #[must_use]
pub const fn rows() -> Self { pub const fn rows() -> Self {
Self { Self {
orientation: ArrayOrientation::Row, orientation: StackOrientationn::Row,
reverse: false, reverse: false,
} }
} }
@ -195,7 +185,7 @@ impl ArrayDirection {
#[must_use] #[must_use]
pub const fn rows_rev() -> Self { pub const fn rows_rev() -> Self {
Self { Self {
orientation: ArrayOrientation::Row, orientation: StackOrientationn::Row,
reverse: true, reverse: true,
} }
} }
@ -203,31 +193,41 @@ impl ArrayDirection {
/// Splits a size into its measured and other parts. /// Splits a size into its measured and other parts.
pub(crate) fn split_size<U>(self, s: Size<U>) -> (U, U) { pub(crate) fn split_size<U>(self, s: Size<U>) -> (U, U) {
match self.orientation { match self.orientation {
ArrayOrientation::Row => (s.height, s.width), StackOrientationn::Row => (s.height, s.width),
ArrayOrientation::Column => (s.width, s.height), StackOrientationn::Column => (s.width, s.height),
} }
} }
/// Combines split values into a [`Size`]. /// Combines split values into a [`Size`].
pub(crate) fn make_size<U>(self, measured: U, other: U) -> Size<U> { pub(crate) fn make_size<U>(self, measured: U, other: U) -> Size<U> {
match self.orientation { match self.orientation {
ArrayOrientation::Row => Size::new(other, measured), StackOrientationn::Row => Size::new(other, measured),
ArrayOrientation::Column => Size::new(measured, other), StackOrientationn::Column => Size::new(measured, other),
} }
} }
/// Combines split values into a [`Point`]. /// Combines split values into a [`Point`].
pub(crate) fn make_point<U>(self, measured: U, other: U) -> Point<U> { pub(crate) fn make_point<U>(self, measured: U, other: U) -> Point<U> {
match self.orientation { match self.orientation {
ArrayOrientation::Row => Point::new(other, measured), StackOrientationn::Row => Point::new(other, measured),
ArrayOrientation::Column => Point::new(measured, other), StackOrientationn::Column => Point::new(measured, other),
} }
} }
} }
/// The strategy to use when laying a widget out inside of an [`Array`]. /// The orientation (Row/Column) of an [`Stack`] widget.
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ArrayDimension {
pub enum StackOrientationn {
/// The child widgets should be displayed as rows.
Row,
/// The child widgets should be displayed as columns.
Column,
}
/// The strategy to use when laying a widget out inside of an [`Stack`].
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum StackDimension {
/// Attempt to lay out the widget based on its contents. /// Attempt to lay out the widget based on its contents.
FitContent, FitContent,
/// Use a fractional amount of the available space. /// Use a fractional amount of the available space.
@ -242,24 +242,24 @@ pub enum ArrayDimension {
#[derive(Debug)] #[derive(Debug)]
struct Layout { struct Layout {
children: OrderedLots<ArrayDimension>, children: OrderedLots<StackDimension>,
layouts: Vec<ArrayLayout>, layouts: Vec<StackLayout>,
pub other: UPx, pub other: UPx,
total_weights: u32, total_weights: u32,
allocated_space: UPx, allocated_space: UPx,
fractional: Vec<(LotId, u8)>, fractional: Vec<(LotId, u8)>,
measured: Vec<LotId>, measured: Vec<LotId>,
pub orientation: ArrayDirection, pub orientation: StackDirection,
} }
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
struct ArrayLayout { struct StackLayout {
pub offset: UPx, pub offset: UPx,
pub size: UPx, pub size: UPx,
} }
impl Layout { impl Layout {
pub const fn new(orientation: ArrayDirection) -> Self { pub const fn new(orientation: StackDirection) -> Self {
Self { Self {
orientation, orientation,
children: OrderedLots::new(), children: OrderedLots::new(),
@ -273,23 +273,23 @@ impl Layout {
} }
#[cfg(test)] // only used in testing #[cfg(test)] // only used in testing
pub fn push(&mut self, child: ArrayDimension) { pub fn push(&mut self, child: StackDimension) {
self.insert(self.len(), child); self.insert(self.len(), child);
} }
pub fn remove(&mut self, index: usize) -> ArrayDimension { pub fn remove(&mut self, index: usize) -> StackDimension {
let (id, dimension) = self.children.remove_by_index(index).expect("invalid index"); let (id, dimension) = self.children.remove_by_index(index).expect("invalid index");
self.layouts.remove(index); self.layouts.remove(index);
match dimension { match dimension {
ArrayDimension::FitContent => { StackDimension::FitContent => {
self.measured.retain(|&measured| measured != id); self.measured.retain(|&measured| measured != id);
} }
ArrayDimension::Fractional { weight } => { StackDimension::Fractional { weight } => {
self.fractional.retain(|(measured, _)| *measured != id); self.fractional.retain(|(measured, _)| *measured != id);
self.total_weights -= u32::from(weight); self.total_weights -= u32::from(weight);
} }
ArrayDimension::Exact(size) => { StackDimension::Exact(size) => {
self.allocated_space -= size; self.allocated_space -= size;
} }
} }
@ -307,26 +307,26 @@ impl Layout {
self.children.swap(a, b); self.children.swap(a, b);
} }
pub fn insert(&mut self, index: usize, child: ArrayDimension) { pub fn insert(&mut self, index: usize, child: StackDimension) {
let id = self.children.insert(index, child); let id = self.children.insert(index, child);
let layout = match child { let layout = match child {
ArrayDimension::FitContent => { StackDimension::FitContent => {
self.measured.push(id); self.measured.push(id);
UPx(0) UPx(0)
} }
ArrayDimension::Fractional { weight } => { StackDimension::Fractional { weight } => {
self.total_weights += u32::from(weight); self.total_weights += u32::from(weight);
self.fractional.push((id, weight)); self.fractional.push((id, weight));
UPx(0) UPx(0)
} }
ArrayDimension::Exact(size) => { StackDimension::Exact(size) => {
self.allocated_space += size; self.allocated_space += size;
size size
} }
}; };
self.layouts.insert( self.layouts.insert(
index, index,
ArrayLayout { StackLayout {
offset: UPx(0), offset: UPx(0),
size: layout, size: layout,
}, },
@ -407,7 +407,7 @@ impl Layout {
} }
impl Deref for Layout { impl Deref for Layout {
type Target = [ArrayLayout]; type Target = [StackLayout];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.layouts &self.layouts
@ -421,12 +421,12 @@ mod tests {
use kludgine::figures::units::UPx; use kludgine::figures::units::UPx;
use kludgine::figures::Size; use kludgine::figures::Size;
use super::{ArrayDimension, ArrayDirection, Layout}; use super::{Layout, StackDimension, StackDirection};
use crate::ConstraintLimit; use crate::ConstraintLimit;
struct Child { struct Child {
size: UPx, size: UPx,
dimension: ArrayDimension, dimension: StackDimension,
other: UPx, other: UPx,
divisible_by: Option<UPx>, divisible_by: Option<UPx>,
} }
@ -435,19 +435,19 @@ mod tests {
pub fn new(size: impl Into<UPx>, other: impl Into<UPx>) -> Self { pub fn new(size: impl Into<UPx>, other: impl Into<UPx>) -> Self {
Self { Self {
size: size.into(), size: size.into(),
dimension: ArrayDimension::FitContent, dimension: StackDimension::FitContent,
other: other.into(), other: other.into(),
divisible_by: None, divisible_by: None,
} }
} }
pub fn fixed_size(mut self, size: UPx) -> Self { pub fn fixed_size(mut self, size: UPx) -> Self {
self.dimension = ArrayDimension::Exact(size); self.dimension = StackDimension::Exact(size);
self self
} }
pub fn weighted(mut self, weight: u8) -> Self { pub fn weighted(mut self, weight: u8) -> Self {
self.dimension = ArrayDimension::Fractional { weight }; self.dimension = StackDimension::Fractional { weight };
self self
} }
@ -458,7 +458,7 @@ mod tests {
} }
fn assert_measured_children_in_orientation( fn assert_measured_children_in_orientation(
orientation: ArrayDirection, orientation: StackDirection,
children: &[Child], children: &[Child],
available: Size<ConstraintLimit>, available: Size<ConstraintLimit>,
expected: &[UPx], expected: &[UPx],
@ -510,18 +510,18 @@ mod tests {
expected_other: UPx, expected_other: UPx,
) { ) {
assert_measured_children_in_orientation( assert_measured_children_in_orientation(
ArrayDirection::rows(), StackDirection::rows(),
children, children,
ArrayDirection::rows().make_size(main_constraint, other_constraint), StackDirection::rows().make_size(main_constraint, other_constraint),
expected, expected,
ArrayDirection::rows().make_size(expected_measured, expected_other), StackDirection::rows().make_size(expected_measured, expected_other),
); );
assert_measured_children_in_orientation( assert_measured_children_in_orientation(
ArrayDirection::columns(), StackDirection::columns(),
children, children,
ArrayDirection::columns().make_size(main_constraint, other_constraint), StackDirection::columns().make_size(main_constraint, other_constraint),
expected, expected,
ArrayDirection::columns().make_size(expected_measured, expected_other), StackDirection::columns().make_size(expected_measured, expected_other),
); );
} }