diff --git a/CHANGELOG.md b/CHANGELOG.md index cfba44592..3e267cd09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,127 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.14.0] — 2023-09? +## [0.14.1] — 2023-12-12 + +The focus of this version is *input data*: widgets now have a `Data` associated type, passed by reference +to event handlers and to a new `update` method. The key advantages of this change are: + +- Declarative specification of trees with changeable widgets. For example, before this change a `counter` must construct a label displaying the initial count *and* explicitly update this label when the count changes; now the displayed label is effectively a function of the count. +- As a direct result of the above, it is no longer necessary for parent nodes to refer to children by name, thus it is no longer necessary to use structs with named fields (at least in the common cases). +- "View widgets" are now much more tightly integrated with other widgets, making the `SingleView` widget redundant. + +For more on *input data*, read the [design document](https://github.com/kas-gui/design/blob/input-data/widget/input-data.md). + +### Changes to macros + +- New layout syntax: `row![a, b, c]` instead of `row: [a, b, c]` (#390) +- Support debugging of `#[widget]` macro via `KAS_DEBUG_WIDGET=WidgetName` (#410) + +### Changes to widget traits + +- Merge `WidgetCore` into `Layout` (#398) +- Remove `Debug` bound on widgets (#389) +- Add `Event::is_reusable`, remove `Widget::handle_unused`, call `handle_event` instead but only for reusable events (#389) +- Add new `trait Events: Sized`, used to implement `Widget` (#391, #392) + +- Add fns `Widget::_configure`, `_send`, `_replay`, `_nav_next`, `_broadcast` as new dyn-safe API (#391, #392) +- Implement `Widget` for `&mut T` and `Box` where `T: Widget + ?Sized` (#392) +- Add associated type `Widget::Data` and `Events::Data` (#395) +- Add `Node` type pairing a `&mut dyn Widget` with input data `&A` (#395, #396,#398) +- Add `trait AppData` for root-level shared data (#395, #396?) +- Add `Events::update` (#396) +- Rename `Events::handle_message` → `Events::handle_messages` (#396) +- Rename `WidgetExt` → `LayoutExt` (#398) +- Replace `Events::pre_handle_event` with `Events::mouse_hover` (#401) +- Remove `ConfigCx::restrict_recursion_to`, replacing with `Events::configure_recurse` and `update_recurse` (#405, #410) +- Do not require configuration of hidden widgets (#405) +- Remove `Events::pre_configure`; call `Events::configure` and `update` before recursion (#410) +- Add widget state tracking to catch invalid method call order (#410) + +### Changes to core event handling + +- Rename `Action::SET_SIZE` → `SET_RECT` (#386) +- `next_nav_focus` is now always handled as a pending action (#386) +- Add `Event::CursorMove` for motion without a grab press (#389) +- Add `EventState::request_update` (#386, #396) +- Add `Action::EVENT_CONFIG`, `UPDATE`; remove `Action::EMPTY` (#396) +- Add `EventState::change_config` (#396) +- Replace `Event::ReceivedCharacter` with `Key` over Winit's new keyboard-input API (#400, #404) +- Revise `enum Command` (#400) +- Revise `enum Event`: remove `None`, change field style of `NavFocus` (#401) +- Rename `EventState::request_char_focus` → `request_key_focus` (#404) +- Add `enum FocusSource`, used by `Event::NavFocus` (#404) +- Add `fn EventState::depress_with_key` (#405) +- Rename `enum Response` → `IsUsed` and re-export `{Used, Unused}` (#406) +- Send `Event::PressMove` immediately instead of batching (#412) +- Change behaviour when `Press::grab` is used twice in a row (#412) +- Replace `*cx |= action` with `EventState::action(id, action)` (#413) +- Apply `Action::RECONFIGURE` and `Action::UPDATE` to sub-trees (#413) +- Rename `EventState::request_update` to `request_timer` and remove `first` paramameter (#421) + +### Changes to app, windowing, WGPU + +- Use Winit's window suspend/resume cycle (#403) +- Adjust shell construction: replace custom constructors with `ShellBuilder`; tweak `WgpuBuilder` (#416) +- Use "logical pixel" window sizing on all platforms and improve initial window sizing (#417) +- Rename `Shell` → `Application` (#422) +- Remove usage of WGPU's "wgsl" feature (#425) + +### Other core changes + +- Add `kas::messages` module (#385) +- Add `Command::Debug` to print widget heirarchy to log, temporarily activated via F8 (#389) +- Remove `Window` trait; rename `RootWidget` → `Window` (#393) +- Rename `ConfigMgr`, `DrawMgr`, `EventMgr`, `SizeMgr` → `ConfigCx`, ... (#399) +- Support dragging and drag-resizing of windows via border (#400) +- Add `enum WindowCommand` (#400) +- Add `Popup` widget as root of all popups (#405) +- Rename `AccelLabel`/`AccelString`/... → `AccessLabel`/`AccessString`/... (#405) +- Remove `dark-light` from being a default dependency (#411) +- Rename `struct WidgetId` → `Id` (#413) +- Event config: adjust serialization formats and support TOML (#416) +- Change font size unit from `Point / Em` to `Pixel / Em` (#419) +- Rename `mod kas::class` → `classes` (#424) + +### Changes to themes + +- Add `FrameStyle::None`, `FrameStyle::Tab` (#399) + +### Changes to widget library + +- Remove `MapMessage` adapter (#389) +- `Slider`, `Spinner` now have a default step size (#389) +- `EditField`: set selection on focus; change behaviour of left/right arrow keys given a selection without shift key pressed (#389) +- Revise `EditGuard` to use input data (#396) +- Revise `EditField` constructors and provided `EditGuard` implementations (#396) +- Add widget `Adapt` to store local data and handle messages (#396, #400) +- Add fns `AdaptWidget::map`, `map_any`, `on_update`, `on_configure` (#396, #397, #400) +- Revise `Stack`, `TabStack` widget constructors; add a `Tab` widget (#399, #410) +- Replace `TextButton` with `Button::label`, `label_msg` constructors (#399) +- Add `Text` widget (?) +- Add `ScrollText` widget (#419) +- Add `AdaptEventCx`, `AdaptConfigCx` (#421, #423) + +### Changes to view widgets + +- Move fns `make_id`, `reconstruct_key` to trait `DataKey` (#389) +- Move all of `kas::model` to `kas-view` crate and revise to use input data (#396, #421) +- Revise filter-list (#397) +- `ListView` and `MatrixView` no longer use a default (unconfigured) view-widget for sizing. They may now have an initial size of zero and grow. (#410) -Add input data: widgets now have a `Data` associated type, passed by reference -to event handlers and a new `update` method. This replaces the old data models. +### Fixes + +- Fix animation of `RadioBox` (#385) +- Fix calling of `handle_scroll` (#386) +- Improved handling of pending actions (#386, #412, #413) +- Fix calls to prepare `EditField` text before setting bounds (#399) +- Fix Mandlebrot example's `shader64` feature (#400) +- Fix drag-opening of a `ComboBox` (#412) +- Fix infinite loop in `ListView::_nav_next` and `MatrixView::_nav_next` (#421) + +## [0.14.0-alpha] — 2023-09-08 -There are *lots* more changes. TODO: write changelog. +Alpha release; changelog omitted. ## [0.13.0] — 2023-02-26 diff --git a/Cargo.toml b/Cargo.toml index c3946b467..ffa436b2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -118,14 +118,14 @@ x11 = ["kas-core/x11"] unsafe_node = ["kas-core/unsafe_node"] [dependencies] -kas-core = { version = "0.14.0-alpha", path = "crates/kas-core" } -kas-dylib = { version = "0.14.0-alpha", path = "crates/kas-dylib", optional = true } -kas-widgets = { version = "0.14.0-alpha", path = "crates/kas-widgets" } -kas-view = { version = "0.14.0-alpha", path = "crates/kas-view", optional = true } -kas-resvg = { version = "0.14.0-alpha", path = "crates/kas-resvg", optional = true } +kas-core = { version = "0.14.1", path = "crates/kas-core" } +kas-dylib = { version = "0.14.1", path = "crates/kas-dylib", optional = true } +kas-widgets = { version = "0.14.1", path = "crates/kas-widgets" } +kas-view = { version = "0.14.1", path = "crates/kas-view", optional = true } +kas-resvg = { version = "0.14.1", path = "crates/kas-resvg", optional = true } [dependencies.kas-wgpu] -version = "0.14.0-alpha" +version = "0.14.1" path = "crates/kas-wgpu" optional = true default-features = false diff --git a/ROADMAP.md b/ROADMAP.md index b348a2739..9a12e3dc3 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -159,6 +159,17 @@ with very basic support for a toolkit-drawn titlebar. Removal of `kas-theme` crate (most contents merged into `kas-core`). +### 0.14.0 — December 2023 + +Add *input data*: widgets now have a `Data` associated type, passed by reference +to event handlers and to a new `update` method. The key advantages of this change are: + +- Declarative specification of trees with changeable widgets. For example, before this change a `counter` must construct a label displaying the initial count *and* explicitly update this label when the count changes; now the displayed label is effectively a function of the count. +- As a direct result of the above, it is no longer necessary for parent nodes to refer to children by name, thus it is no longer necessary to use structs with named fields (at least in the common cases). +- "View widgets" are now much more tightly integrated with other widgets, making the `SingleView` widget redundant. + +For more on *input data*, read the [design document](https://github.com/kas-gui/design/blob/input-data/widget/input-data.md). + Future work ----------- diff --git a/crates/kas-core/Cargo.toml b/crates/kas-core/Cargo.toml index 62568e09b..6b4350ba1 100644 --- a/crates/kas-core/Cargo.toml +++ b/crates/kas-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-core" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -109,7 +109,7 @@ arboard = { version = "3.2.0", optional = true, default-features = false } [dependencies.kas-macros] -version = "0.14.0-alpha" +version = "0.14.1" path = "../kas-macros" [dependencies.kas-text] diff --git a/crates/kas-core/src/core/node.rs b/crates/kas-core/src/core/node.rs index 368ae179b..940d16c27 100644 --- a/crates/kas-core/src/core/node.rs +++ b/crates/kas-core/src/core/node.rs @@ -110,14 +110,20 @@ impl<'a, T> NodeT for (&'a mut dyn Widget, &'a T) { } } -/// Public API over a contextualized mutable widget +/// Type-erased widget with input data /// -/// Note: this type has no publically supported utility over [`Node`]. -/// It is, however, required for Kas's internals. -#[cfg(feature = "unsafe_node")] -pub struct Node<'a>(&'a mut dyn Widget, &'a ()); -#[cfg(not(feature = "unsafe_node"))] -pub struct Node<'a>(Box); +/// This type is a `&mut dyn Widget` paired with input data `&A`, +/// where the type `A` is erased. +/// +/// The default implementation of this type uses a boxed trait object. +/// The `unsafe_node` feature enables a more efficient unboxed implementation +/// (this must make assumptions about VTables beyond what Rust specifies, thus +/// lacks even the usual programmer-provided verification of `unsafe` code). +pub struct Node<'a>( + #[cfg(not(feature = "unsafe_node"))] Box, + #[cfg(feature = "unsafe_node")] &'a mut dyn Widget, + #[cfg(feature = "unsafe_node")] &'a (), +); impl<'a> Node<'a> { /// Construct diff --git a/crates/kas-dylib/Cargo.toml b/crates/kas-dylib/Cargo.toml index 342715251..f058721bd 100644 --- a/crates/kas-dylib/Cargo.toml +++ b/crates/kas-dylib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-dylib" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -20,7 +20,7 @@ raster = ["kas-wgpu/raster"] resvg = ["dep:kas-resvg"] [dependencies] -kas-core = { version = "0.14.0-alpha", path = "../kas-core" } -kas-widgets = { version = "0.14.0-alpha", path = "../kas-widgets" } -kas-resvg = { version = "0.14.0-alpha", path = "../kas-resvg", optional = true } -kas-wgpu = { version = "0.14.0-alpha", path = "../kas-wgpu", default-features = false } +kas-core = { version = "0.14.1", path = "../kas-core" } +kas-widgets = { version = "0.14.1", path = "../kas-widgets" } +kas-resvg = { version = "0.14.1", path = "../kas-resvg", optional = true } +kas-wgpu = { version = "0.14.1", path = "../kas-wgpu", default-features = false } diff --git a/crates/kas-macros/Cargo.toml b/crates/kas-macros/Cargo.toml index 36e38f14a..4acb7e0b6 100644 --- a/crates/kas-macros/Cargo.toml +++ b/crates/kas-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-macros" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" diff --git a/crates/kas-resvg/Cargo.toml b/crates/kas-resvg/Cargo.toml index 75c8a699b..72160ccf8 100644 --- a/crates/kas-resvg/Cargo.toml +++ b/crates/kas-resvg/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-resvg" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -31,7 +31,7 @@ thiserror = "1.0.23" [dependencies.kas] # We must rename this package since macros expect kas to be in scope: -version = "0.14.0-alpha" +version = "0.14.1" package = "kas-core" path = "../kas-core" features = ["spawn"] diff --git a/crates/kas-view/Cargo.toml b/crates/kas-view/Cargo.toml index 6bc0d8abf..4f72d55e0 100644 --- a/crates/kas-view/Cargo.toml +++ b/crates/kas-view/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-view" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -19,9 +19,9 @@ rustdoc-args = ["--cfg", "doc_cfg"] # RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --no-deps --open [dependencies] -kas-widgets = { version = "0.14.0-alpha", path = "../kas-widgets" } +kas-widgets = { version = "0.14.1", path = "../kas-widgets" } log = "0.4" linear-map = "1.2.0" # We must rename this package since macros expect kas to be in scope: -kas = { version = "0.14.0-alpha", package = "kas-core", path = "../kas-core" } +kas = { version = "0.14.1", package = "kas-core", path = "../kas-core" } diff --git a/crates/kas-wgpu/Cargo.toml b/crates/kas-wgpu/Cargo.toml index 5734d99a8..cba18da95 100644 --- a/crates/kas-wgpu/Cargo.toml +++ b/crates/kas-wgpu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-wgpu" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -39,7 +39,7 @@ wgpu-core = "0.18.1" [dependencies.kas] # Rename package purely for convenience: -version = "0.14.0-alpha" +version = "0.14.1" package = "kas-core" path = "../kas-core" diff --git a/crates/kas-widgets/Cargo.toml b/crates/kas-widgets/Cargo.toml index e2fe243f6..ed0d9402e 100644 --- a/crates/kas-widgets/Cargo.toml +++ b/crates/kas-widgets/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-widgets" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -28,8 +28,8 @@ smallvec = "1.6.1" unicode-segmentation = "1.7" thiserror = "1.0.23" image = { version = "0.24.1", optional = true } -kas-macros = { version = "0.14.0-alpha", path = "../kas-macros" } +kas-macros = { version = "0.14.1", path = "../kas-macros" } linear-map = "1.2.0" # We must rename this package since macros expect kas to be in scope: -kas = { version = "0.14.0-alpha", package = "kas-core", path = "../kas-core" } +kas = { version = "0.14.1", package = "kas-core", path = "../kas-core" } diff --git a/examples/mandlebrot/Cargo.toml b/examples/mandlebrot/Cargo.toml index bcad74a72..b5010c2e5 100644 --- a/examples/mandlebrot/Cargo.toml +++ b/examples/mandlebrot/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kas-mandlebrot" -version = "0.14.0-alpha" +version = "0.14.1" authors = ["Diggory Hardy "] edition = "2021" license = "Apache-2.0" @@ -8,8 +8,8 @@ description = "KAS GUI / Mandlebrot example" publish = false [dependencies] -kas = { version = "0.14.0-alpha", features = ["wgpu"], path = "../.." } -kas-wgpu = { version = "0.14.0-alpha", path = "../../crates/kas-wgpu" } +kas = { version = "0.14.1", features = ["wgpu"], path = "../.." } +kas-wgpu = { version = "0.14.1", path = "../../crates/kas-wgpu" } chrono = "0.4" env_logger = "0.10" log = "0.4"