Skip to content

Commit

Permalink
Merge pull request #352 from kas-gui/work
Browse files Browse the repository at this point in the history
Prepare 0.11.0
  • Loading branch information
dhardy authored Sep 5, 2022
2 parents 20f4a21 + d21f920 commit d42e3d3
Show file tree
Hide file tree
Showing 19 changed files with 232 additions and 109 deletions.
143 changes: 136 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,145 @@
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.11.0]unreleased
## [0.11.0]2022-09-05

Bump MSRV to 1.62.0.
With a year since the previous release, KAS v0.11 sees *a lot* of changes. In
the interest of brevity, the list below is incomplete.

### Breaking changes
### Widget trait revision

One of the major nuisances with KAS v0.10 and earlier was the that `dyn Widget`
was not a valid type since the associated `Handler::Msg` type must be specified.
KAS v0.11 removes this associated type (#309), replacing it with a variadic
message stack, thus making `dyn Widget` a valid (unsized) type.

- Add `fn WidgetCore::identify`, returning a printable type
(example result: `TextButton#01`) (#266)
- New trait `WidgetExt: Widget` (#286)
- Add `Widget::handle_message`; rename `Handler::handle``handle_event` (#309)
- Merge `Handler` and `WidgetConfig` traits into `Widget` (#312)
- Replace `#[widget_core] core: CoreData` field with `core: widget_core!()` (#314)
- Remove bound `Widget: Any` (and thus `'static`) (#316)
- `Window` trait simplified; new `RootWidget` struct handles pop-ups (#318)
- Add `Widget::steal_event` (#319) and `Widget::pre_handle_event` (#324)
- Trait `Scrollable: Widget` is now a core trait; new trait `HasScrollBars` (#324)

#### Macros

This cycle saw the development of the `#[autoimpl]` and `impl_scope!` macros
which were split out into a new [`impl-tools` crate](https://crates.io/crates/impl-tools) in #300.

- `#[derive(Widget)]` becomes `widget!` (#258) becomes `#[widget]` (#300)
- Auto-detect which traits have manual impls (#258) and merge generated
methods into manual impls (#312, #335)
- `impl Self` syntax (#258, #300)
- New `#[autoimpl]` macro as a more capable version of `#[derive]` (#258, #272, #293, #294)
- Revise `make_widget!` into `impl_singleton!` (#272, #317)
- New `widget_index!` macro (#291)

#### Layout and margins

Widgets may now have complex internal layout, defined by a domain-specific
macro language (#259, #282, #304, #306, #314, #316, #322, #345, #348, #350).

- Better text, `EditBox` margins (#283)
- Menu entries use interior margins (#283)
- Fix initial window size on Wayland (#298)
- New struct `PixmapScaling` used by `Image` and `Svg` (#303, #321)
- Add `float` layout (#322)
- Revise `FrameRules`; add `MarginStyle` (#348)
- Add alignment hints to `AxisInfo`, removing from `set_rect` (#350)

### Configuration, WidgetId

Partial (localised) widget configuration is now possible (#276, #299).

The `WidgetId` type is now a path (#264, #265).
As a result, `WidgetId` is no longer `Copy` but persistent identifiers for
view widgets over a specific content are possible (#282).
Further, it is possible to determine whether one widget is the ancestor of
another purely by comparing `WidgetId`s.

- **Breaking:** `Ord for WidgetId` now considers a parent to come *before* its children
- Add `WidgetChildren::make_child_id` (#313, #330)

### Event handling

The widget trait revision (#309) introduced a variadic message stack
(`EventMgr::push_msg` and `EventMgr::try_pop_msg` methods), and allowed the
implementation of a generic `EventMgr::send` routing method replacing the
`SendEvent` trait, as well as removal of `VoidMsg`.

Momentum (flick) scrolling is now supported (#268).

- Rename `Manager``EventMgr`, `ManagerState``EventState` (#266)
- Disabled status is now a property of `EventState`, not of the widget (#292, #323)
- `Response` enum loses most variants; new `Scroll` enum (#264, #309)
- Add `Event::activate_on_press`, replacing `EventMgr::handle_generic (#311)
- Replace `kas::event::Event::Activate` with `kas::event::Command::Activate` (#323)
- Replace `Manager::handle_generic` with `Widget::pre_handle_event` (#324)
- Add `Event::MouseHover`, `Event::LostMouseHover`, `Event::LostNavFocus` (#324)
- New `ConfigMgr` type (introduced as `SetRectMgr` in #266, renamed in #330)
- Add `EventMgr::next_nav_focus_from` (#347)

### Themes and drawing

Support animations, driven by the theme *or* the widget (#269, #270, #271, #321).

- New `SizeMgr`, `DrawMgr` types wrapping theme size/draw interface (#266)
- Rename `DrawHandle``ThemeDraw`, `SizeHandle``ThemeSize` (#327)
- Merge most methods of `SizeMgr` into new `feature`, `align_feature` methods
over a `kas::theme::Feature` enum (#327)
- Add `SimpleTheme` as base theme (#332)
- `SizeMgr`: add methods `dpem`, `min_scroll_size`; remove `pixels_from_*` (#334)
- Clip text to widget rect (#336, #337)
- Auto-detect dark theme via `dark-light` crate (#337)
- Rename `SizeMgr::text_bound` with `text_rules` and revise (#338)

Visual tweaks include a "tick" mark for `CheckBox` (#298) and removal of "glow shadows" (#327).

### Data models

Data changes are now notified via broadcast (#323), using a version number to
check whether a view is current (#266, #289).

`Driver` trait impls are now also responsible for handling messages from view
widgets via the new `Driver::on_message` method (#334).

- New filters `ContainsString`, `ContainsCaseInsensitive` (#248)
- Add `SharedRc` methods `borrow`, `try_borrow`, `update_mut` (#334)
- Add `SharedData` trait as common base of all data model traits (#334)
- Rename `DefaultView``View`, `DefaultNav``NavView` (#335)
- New `kas_view` crate for view widgets (#335)

### Widgets

- New widgets `Mark` (#305, #316) and `MarkButton` (#319)
- New widget `dialog::TextEdit` (#318)
- New widget `Spinner` (#319, #334)
- New widget `TabStack` (#321)
- Invisible scroll bars (#324)
- Renames: `CheckBox`, `CheckButton`, `RadioBox`, `RadioButton`, `RadioGroup` (#330)
- `CheckButton` and `RadioButton` infer layout direction from text direction (#332)
- New `kas::widgets::edit` public module (#334)
- Rename `DragHandle``GripPart` (#339)

### Features & misc

- The minimum supported Rust version (MSRV) is now 1.62.0 (#256, #335).
- Use (some) Clippy lints (#256)
- `#[must_use]` annotations were added to methods returning a modification of self (#264, #266)
- Use `easy-cast` traits for conversions on `kas::geom` types (#284)
- Handle window focus gain/loss (#292)
- Make `&EventState` available to (theme) `DrawHandle` (#292)
- Do not panic when attempting to draw un-prepared text (#312)
- Merge example `filter-list` into `gallery` (#323)
- Remove `stack_dst` dependency, which was `unsafe` and used only as a
premature optimisation (#335)
- Update to WGPU 0.13 (#340) and winit to 0.27 (#351)
- Bump `easy-cast` dep (re-export as `kas::cast`) to 0.5.0, adding `cast_approx` functionality
([easy-cast#21](https://github.com/kas-gui/easy-cast/pull/21))

- `WidgetId` has been completely re-written, and now represents a path
- `Ord for WidgetId` now considers a parent to come *before* its children.
Note: previously ordering was used in `send` logic; this is no longer
recommended (use e.g. `Widget::find_child_index` instead).

## [0.10.1] — 2021-09-07

Expand Down
2 changes: 1 addition & 1 deletion crates/kas-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exclude = ["/screenshots"]
features = ["winit", "markdown", "yaml", "json", "ron"]
rustdoc-args = ["--cfg", "doc_cfg"]
# To build locally:
# RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --features=internal_doc,markdown,yaml,json,ron --no-deps --open
# RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --features=internal_doc,winit,markdown,yaml,json,ron --no-deps --open

[features]
# Use Generic Associated Types (this is too unstable to include in nightly!)
Expand Down
17 changes: 16 additions & 1 deletion crates/kas-core/src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub trait Directional: Copy + Sized + std::fmt::Debug + 'static {

macro_rules! fixed {
($d:ident, $df:ident, $dr:ident) => {
/// Fixed instantiation of [`Directional`]
/// Zero-sized instantiation of [`Directional`]
#[derive(Copy, Clone, Default, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct $d;
Expand Down Expand Up @@ -151,3 +151,18 @@ bitflags! {
const DOWN = 0b1000;
}
}

#[cfg(test)]
mod test {
use super::*;
use std::mem::size_of;

#[test]
fn size() {
assert_eq!(size_of::<Left>(), 0);
assert_eq!(size_of::<Right>(), 0);
assert_eq!(size_of::<Up>(), 0);
assert_eq!(size_of::<Down>(), 0);
assert_eq!(size_of::<Direction>(), 1);
}
}
56 changes: 28 additions & 28 deletions crates/kas-core/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,40 @@

//! Event handling
//!
//! See documentation of [`Event`] values.
//! ## Event handling model
//!
//! ## Event delivery
//! 1. Determine the target [`WidgetId`]. This is dependant on the type of
//! event and may (non-exhaustively) derive
//! from keyboard navigation (see [`EventState::set_nav_focus`], [`EventMgr::next_nav_focus`]),
//! from key bindings,
//! from mouse/touch coordinates (see [`crate::Layout::find_id`])
//! or from a mouse/touch grab ([`EventMgr::grab_press`]).
//! 2. Construct an [`Event`].
//! 3. Use [`EventMgr::send`] to traverse the widget tree from its root to the
//! target.
//!
//! Events can be addressed only to a [`WidgetId`], so the first step (for
//! mouse and touch events) is to use [`crate::Layout::find_id`] to translate a
//! coordinate to a [`WidgetId`].
//! In case a widget [`EventState::is_disabled`], then traversal of the
//! widget tree may stop early, depending on [`Event::pass_when_disabled`].
//! Otherwise, call [`Widget::steal_event`] on each ancestor, stopping early
//! if any returns [`Response::Used`]. In both cases the return traversal of
//! step 4 still happens, but only from the widget stopped at here.
//!
//! Events are then sent via [`EventMgr::send`] which traverses the widget tree
//! starting from the root (the window), following the path described by the
//! [`WidgetId`]:
//! In the normal case, [`Widget::handle_event`] is called on the target.
//! 4. Traverse back towards the widget tree's root.
//!
//! - In case any widget encountered is disabled, [`Unused`] is returned
//! - If the target is found, [`Widget::handle_event`] is called. This method may
//! handle the event and may push a message to the stack via
//! [`EventMgr::push_msg`].
//! - If no target is found, a warning is logged and [`Unused`] returned
//! If no handler has yet returned [`Response::Used`], then call
//! [`Widget::handle_unused`] on each ancestor visited.
//!
//! Then, for each parent back to the root,
//! If the message stack is non-empty (due to a handler calling [`EventMgr::push_msg`]),
//! call [`Widget::handle_message`] on each ancestor visited.
//!
//! - If [`Unused`] was returned, [`Widget::handle_unused`] is called
//! - Otherwise, if the message stack is non-empty, [`Widget::handle_message`]
//! is called
//!
//! This traversal of the widget tree is fast: (`O(len)`) where `len` is the
//! length of the path described by [`WidgetId`]. It is "clean": uninvolved
//! widgets are not sent any event, while actionable messages are sent to an
//! appropriate parent. It allows "recycling" of unused events.
//!
//! ### Keyboard focus
//!
//! Keyboard focus controls where otherwise undirected keyboard input is sent.
//! This may be set via [`EventState::set_nav_focus`] but is typically controlled
//! via the <kbd>Tab</kbd> key, via [`EventMgr::next_nav_focus`].
//! If a non-empty scroll action is set (due to a handler calling [`EventMgr::set_scroll`]),
//! call [`Widget::handle_scroll`] on each ancestor visited.
//! 5. If the message stack is non-empty on reaching the root widget then log a
//! warning (including the formatted message in debug builds).
//! It is expected that for any message a widget might push to the stack,
//! *some* ancestor will check for and handle this message (not doing so is
//! safe but probably means that some control is not operational).
//!
//! ### Pop-ups
//!
Expand Down
7 changes: 3 additions & 4 deletions crates/kas-core/src/geom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@

//! Geometry data types
//!
//! [`Coord`], [`Size`] and [`Offset`] are all integer (`i32`) types used for
//! widget UI layout, representing positions, sizes and scroll deltas
//! respectively.
//! [`Coord`], [`Size`] and [`Offset`] are all 2D integer (`i32`) types,
//! representing positions, sizes and scroll deltas respectively.
//!
//! [`Vec2`] is a floating-point (`f32`) type used mainly for screen-space
//! [`Vec2`] is a 2D floating-point (`f32`) type used mainly for screen-space
//! position during rendering.
//!
//! Conversions types mostly use [`Cast`] and [`Conv`]. [`From`] may be used to
Expand Down
6 changes: 4 additions & 2 deletions crates/kas-core/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// You may obtain a copy of the License in the LICENSE-APACHE file or at:
// https://www.apache.org/licenses/LICENSE-2.0

//! Layout solver
//! Layout utilities
//!
//! For documentation of layout resolution, see the [`Layout`] trait.
//!
//! Size units are physical (real) pixels. This applies to most of KAS.
//!
Expand All @@ -15,7 +17,7 @@
//!
//! [`AxisInfo`], [`Margins`] and [`Stretch`] are auxilliary data types.
//!
//! ## Layout engines
//! ## Solvers
//!
//! The [`RulesSolver`] and [`RulesSetter`] traits define interfaces for
//! layout engines:
Expand Down
7 changes: 4 additions & 3 deletions crates/kas-core/src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
//! Most of this module is simply a re-export of the [KAS Text] API, hence the
//! lower level of integration than other parts of the library.
//!
//! When using a [`Text`] object in a widget, the text *must* be prepared before
//! display by calling [`ConfigMgr::text_set_size`] from [`Layout::set_rect`].
//! Failure to do so may result in text displaying incorrectly or not at all.
//! [`Text`] objects *must* be prepared before usage, otherwise they may appear
//! empty. Call [`ConfigMgr::text_set_size`] from [`Layout::set_rect`] to set
//! text position and prepare. If text is adjusted, one may use e.g.
//! [`TextApi::prepare`] to update.
//!
//! [KAS Text]: https://github.com/kas-gui/kas-text/
Expand Down
4 changes: 3 additions & 1 deletion crates/kas-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

//! KAS macros
//!
//! This crate extends [impl-tools](https://crates.io/crates/impl-tools).
//! This crate extends [`impl-tools`](https://docs.rs/impl-tools/).
#![recursion_limit = "128"]
#![allow(clippy::let_and_return)]
Expand Down Expand Up @@ -449,6 +449,8 @@ pub fn widget_index(input: TokenStream) -> TokenStream {
/// // `self.base()`, which mut return an object implementing ThemeDraw
/// }
/// ```
///
/// Note: this is a very limited macro which *only* supports `ThemeDraw`.
#[proc_macro_attribute]
#[proc_macro_error]
pub fn extends(attr: TokenStream, item: TokenStream) -> TokenStream {
Expand Down
2 changes: 1 addition & 1 deletion crates/kas-resvg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#![cfg_attr(doc_cfg, feature(doc_cfg))]

pub use tiny_skia;
pub extern crate tiny_skia;

mod canvas;
pub use canvas::{Canvas, CanvasProgram};
Expand Down
2 changes: 1 addition & 1 deletion crates/kas-theme/src/dim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// You may obtain a copy of the License in the LICENSE-APACHE file or at:
// https://www.apache.org/licenses/LICENSE-2.0

//! Common implementation of [`kas::theme::ThemeSize`]
//! A shared implementation of [`ThemeSize`]
use linear_map::LinearMap;
use std::any::Any;
Expand Down
2 changes: 2 additions & 0 deletions crates/kas-theme/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ mod simple_theme;
mod theme_dst;
mod traits;

#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(doc_cfg, doc(cfg(internal_doc)))]
pub mod dim;

pub use colors::{Colors, ColorsLinear, ColorsSrgb, InputState};
Expand Down
2 changes: 1 addition & 1 deletion crates/kas-view/src/driver/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl_scope! {
}
}

/// Editor for [`kas::event::Config`]
/// Editor for [`kas::event::Config`](Config)
#[derive(Clone, Copy, Debug, Default)]
pub struct EventConfig;

Expand Down
2 changes: 1 addition & 1 deletion crates/kas-wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ futures = "0.3"
log = "0.4"
smallvec = "1.6.1"
wgpu = { version = "0.13.0", features = ["spirv"] }
winit = "0.27"
winit = "0.27.2"
thiserror = "1.0.23"
window_clipboard = { version = "0.2.0", optional = true }
guillotiere = "0.6.0"
Expand Down
5 changes: 1 addition & 4 deletions crates/kas-wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ use crate::shared::SharedState;
use window::Window;

pub use options::Options;

pub use kas;
pub use kas_theme as theme;
pub use wgpu;
pub extern crate wgpu;

/// Possible failures from constructing a [`Toolkit`]
///
Expand Down
Loading

0 comments on commit d42e3d3

Please sign in to comment.