Skip to content

Commit

Permalink
Merge pull request #419 from kas-gui/work
Browse files Browse the repository at this point in the history
ScrollText widget, font sizes in pixels, AdaptWidget::on_messages, misc fixes
  • Loading branch information
dhardy authored Nov 22, 2023
2 parents 89af4e2 + 38814e9 commit 935396d
Show file tree
Hide file tree
Showing 10 changed files with 404 additions and 20 deletions.
3 changes: 2 additions & 1 deletion crates/kas-core/src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ enum ProxyAction {
#[cfg(test)]
mod test {
use super::*;
use raw_window_handle as raw;
use std::time::Instant;

struct Draw;
Expand Down Expand Up @@ -231,7 +232,7 @@ mod test {

fn new<W>(_: &mut Self::Shared, _: W) -> Result<Self>
where
W: raw_window_handle::HasRawWindowHandle + raw_window_handle::HasRawDisplayHandle,
W: raw::HasWindowHandle + raw::HasDisplayHandle,
Self: Sized,
{
todo!()
Expand Down
8 changes: 5 additions & 3 deletions crates/kas-core/src/theme/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct Config {
#[cfg_attr(feature = "serde", serde(skip))]
dirty: bool,

/// Standard font size, in units of points-per-Em
/// Standard font size, in units of pixels-per-Em
#[cfg_attr(feature = "serde", serde(default = "defaults::font_size"))]
font_size: f32,

Expand Down Expand Up @@ -146,7 +146,9 @@ impl Default for RasterConfig {
impl Config {
/// Standard font size
///
/// Units: points per Em. Pixel size depends on the screen's scale factor.
/// Units: logical (unscaled) pixels per Em.
///
/// To convert to Points, multiply by three quarters.
#[inline]
pub fn font_size(&self) -> f32 {
self.font_size
Expand Down Expand Up @@ -279,7 +281,7 @@ mod defaults {
}

pub fn font_size() -> f32 {
10.0
14.0
}

pub fn color_schemes() -> BTreeMap<String, ColorsSrgb> {
Expand Down
5 changes: 2 additions & 3 deletions crates/kas-core/src/theme/dimensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ pub struct Dimensions {
}

impl Dimensions {
pub fn new(params: &Parameters, pt_size: f32, scale: f32) -> Self {
let dpp = scale * (96.0 / 72.0);
let dpem = dpp * pt_size;
pub fn new(params: &Parameters, font_size: f32, scale: f32) -> Self {
let dpem = scale * font_size;

let text_m0 = (params.m_text.0 * scale).cast_nearest();
let text_m1 = (params.m_text.1 * scale).cast_nearest();
Expand Down
11 changes: 7 additions & 4 deletions crates/kas-macros/src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ pub fn widget(attr_span: Span, mut args: WidgetArgs, scope: &mut Scope) -> Resul
let (fn_set_rect, fn_nav_next, fn_find_id);
let mut fn_nav_next_err = None;
let mut fn_draw = None;
let mut gen_layout = false;

if let Some(inner) = opt_derive {
required_layout_methods = quote! {
Expand Down Expand Up @@ -693,7 +692,6 @@ pub fn widget(attr_span: Span, mut args: WidgetArgs, scope: &mut Scope) -> Resul
self.rect().contains(coord).then(|| self.id())
};
if let Some((_, layout)) = args.layout.take() {
gen_layout = true;
fn_nav_next = match layout.nav_next(children.iter().map(|(ident, _, _)| ident)) {
Ok(toks) => Some(toks),
Err((span, msg)) => {
Expand Down Expand Up @@ -913,9 +911,8 @@ pub fn widget(attr_span: Span, mut args: WidgetArgs, scope: &mut Scope) -> Resul
if !has_item("nav_next") {
if let Some(method) = fn_nav_next {
layout_impl.items.push(Verbatim(method));
} else if gen_layout {
} else if let Some((span, msg)) = fn_nav_next_err {
// We emit a warning here only if nav_next is not explicitly defined
let (span, msg) = fn_nav_next_err.unwrap();
emit_warning!(span, "unable to generate `fn Layout::nav_next`: {}", msg,);
}
}
Expand Down Expand Up @@ -957,6 +954,12 @@ pub fn widget(attr_span: Span, mut args: WidgetArgs, scope: &mut Scope) -> Resul
layout_impl.items.push(Verbatim(method));
}
} else if let Some(fn_size_rules) = fn_size_rules {
if fn_nav_next.is_none() {
if let Some((span, msg)) = fn_nav_next_err {
emit_warning!(span, "unable to generate `fn Layout::nav_next`: {}", msg,);
}
}

scope.generated.push(quote! {
impl #impl_generics ::kas::Layout for #impl_target {
#required_layout_methods
Expand Down
39 changes: 34 additions & 5 deletions crates/kas-widgets/src/adapt/adapt_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

//! Event adapters

use kas::event::ConfigCx;
use kas::event::{ConfigCx, EventCx};
use kas::{autoimpl, impl_scope, widget_index, Events, Widget};
use std::fmt::Debug;

impl_scope! {
/// Wrapper to call a closure on update
Expand All @@ -21,6 +22,7 @@ impl_scope! {
pub inner: W,
on_configure: Option<Box<dyn Fn(&mut ConfigCx, &mut W)>>,
on_update: Option<Box<dyn Fn(&mut ConfigCx, &mut W, &W::Data)>>,
message_handlers: Vec<Box<dyn Fn(&mut EventCx, &mut W, &W::Data)>>,
}

impl Self {
Expand All @@ -32,12 +34,11 @@ impl_scope! {
inner,
on_configure: None,
on_update: None,
message_handlers: vec![],
}
}

/// Call the given closure on [`Events::configure`]
///
/// Returns a wrapper around the input widget.
#[must_use]
pub fn on_configure<F>(mut self, f: F) -> Self
where
Expand All @@ -48,8 +49,6 @@ impl_scope! {
}

/// Call the given closure on [`Events::update`]
///
/// Returns a wrapper around the input widget.
#[must_use]
pub fn on_update<F>(mut self, f: F) -> Self
where
Expand All @@ -58,6 +57,30 @@ impl_scope! {
self.on_update = Some(Box::new(f));
self
}

/// Add a handler on message of type `M`
#[must_use]
pub fn on_message<M, H>(self, handler: H) -> Self
where
M: Debug + 'static,
H: Fn(&mut EventCx, &mut W, &W::Data, M) + 'static,
{
self.on_messages(move |cx, w, data| {
if let Some(m) = cx.try_pop() {
handler(cx, w, data, m);
}
})
}

/// Add a generic message handler
#[must_use]
pub fn on_messages<H>(mut self, handler: H) -> Self
where
H: Fn(&mut EventCx, &mut W, &W::Data) + 'static,
{
self.message_handlers.push(Box::new(handler));
self
}
}

impl Events for Self {
Expand All @@ -83,5 +106,11 @@ impl_scope! {
f(cx, &mut self.inner, data);
}
}

fn handle_messages(&mut self, cx: &mut EventCx, data: &W::Data) {
for handler in self.message_handlers.iter() {
handler(cx, &mut self.inner, data);
}
}
}
}
28 changes: 26 additions & 2 deletions crates/kas-widgets/src/adapt/adapt_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
use super::{Map, MapAny, OnUpdate, Reserve, WithLabel};
use kas::cast::{Cast, CastFloat};
use kas::dir::Directional;
use kas::event::ConfigCx;
use kas::event::{ConfigCx, EventCx};
use kas::geom::Vec2;
use kas::layout::{AxisInfo, SizeRules};
use kas::text::AccessString;
use kas::theme::SizeCx;
#[allow(unused)] use kas::Events;
use kas::Widget;
#[allow(unused)] use kas::{Events, Layout};
use std::fmt::Debug;

/// Provides `.map_any()`
///
Expand Down Expand Up @@ -66,6 +67,29 @@ pub trait AdaptWidget: Widget + Sized {
OnUpdate::new(self).on_update(f)
}

/// Add a handler on message of type `M`
///
/// Returns a wrapper around the input widget.
#[must_use]
fn on_message<M, H>(self, handler: H) -> OnUpdate<Self>
where
M: Debug + 'static,
H: Fn(&mut EventCx, &mut Self, &Self::Data, M) + 'static,
{
OnUpdate::new(self).on_message(handler)
}

/// Add a generic message handler
///
/// Returns a wrapper around the input widget.
#[must_use]
fn on_messages<H>(self, handler: H) -> OnUpdate<Self>
where
H: Fn(&mut EventCx, &mut Self, &Self::Data) + 'static,
{
OnUpdate::new(self).on_messages(handler)
}

/// Construct a wrapper, setting minimum size in pixels
///
/// The input size is scaled by the scale factor.
Expand Down
6 changes: 5 additions & 1 deletion crates/kas-widgets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@
//! - [`Filler`]: an empty widget, sometimes used to fill space
//! - [`Image`]: a pixmap image
//! - [`Label`], [`AccessLabel`]: are static text labels
//! - [`Text`]: a dynamic (input-data derived) text label
//! - [`Mark`]: a small mark
//! - [`ScrollLabel`]: text label supporting scrolling and selection
//! - [`ScrollLabel`]: static text label supporting scrolling and selection
//! - [`ScrollText`]: dynamic text label supporting scrolling and selection
//! - [`Separator`]: a visible bar to separate things
//! - [`format_value`] and [`format_data`] are constructors for [`Text`],
//! displaying a text label derived from input data
Expand Down Expand Up @@ -84,6 +86,7 @@ mod radio_box;
mod scroll;
mod scroll_bar;
mod scroll_label;
mod scroll_text;
mod separator;
mod slider;
mod spinner;
Expand Down Expand Up @@ -111,6 +114,7 @@ pub use radio_box::{RadioBox, RadioButton};
pub use scroll::ScrollRegion;
pub use scroll_bar::{ScrollBar, ScrollBarRegion, ScrollBars, ScrollMsg};
pub use scroll_label::ScrollLabel;
pub use scroll_text::ScrollText;
pub use separator::Separator;
pub use slider::{Slider, SliderValue};
pub use spinner::{Spinner, SpinnerValue};
Expand Down
2 changes: 1 addition & 1 deletion crates/kas-widgets/src/scroll_label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use kas::text::{SelectionHelper, Text};
use kas::theme::TextClass;

impl_scope! {
/// A text label supporting scrolling and selection
/// A static text label supporting scrolling and selection
///
/// Line-wrapping is enabled; default alignment is derived from the script
/// (usually top-left).
Expand Down
Loading

0 comments on commit 935396d

Please sign in to comment.