Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve WidgetMut documentation #663

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions masonry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@
#![cfg_attr(not(debug_assertions), allow(unused))]
// False-positive with dev-dependencies only used in examples
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
// Needed because of the SelfMut macro
#![allow(clippy::needless_arbitrary_self_type)]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear how this can work without a #![feature(arbitrary_self_types)] (probably in a cfg_attr)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, this lint doesn't need #![feature(arbitrary_self_types)]. It applies to cases like:

fn foobar(self: Self) {}

which have a more concise version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't commented on the added line - I was commenting on "the top of masonry/src/lib.rs", because it isn't clear to me how the new docs can work without enabling the feature for std::ops::Receiver.
Like, they do seem to work based on local testing, but I'm really struggling to work out how.

I think it's a rustdoc bug.

// TODO - Add logo

Expand Down
10 changes: 5 additions & 5 deletions masonry/src/widget/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use crate::paint_scene_helpers::{fill_lin_gradient, stroke, UnitPoint};
use crate::widget::{Label, WidgetMut, WidgetPod};

use crate::{
theme, AccessCtx, AccessEvent, ArcStr, BoxConstraints, EventCtx, Insets, LayoutCtx,
LifeCycleCtx, PaintCtx, PointerEvent, Size, StatusChange, TextEvent, Widget, WidgetId,
theme, AccessCtx, AccessEvent, ArcStr, BoxConstraints, EventCtx, ImplMut, Insets, LayoutCtx,
LifeCycleCtx, PaintCtx, PointerEvent, SelfMut, Size, StatusChange, TextEvent, Widget, WidgetId,
};

// the minimum padding added to a button.
Expand Down Expand Up @@ -64,13 +64,13 @@ impl Button {
}

// --- MARK: WIDGETMUT ---
impl WidgetMut<'_, Button> {
impl ImplMut!('_, Button) {
/// Set the text.
pub fn set_text(&mut self, new_text: impl Into<ArcStr>) {
pub fn set_text(self: SelfMut!('_, Button), new_text: impl Into<ArcStr>) {
self.label_mut().set_text(new_text);
}

pub fn label_mut(&mut self) -> WidgetMut<'_, Label> {
pub fn label_mut(self: SelfMut!('_, Button)) -> WidgetMut<'_, Label> {
self.ctx.get_mut(&mut self.widget.label)
}
}
Expand Down
9 changes: 5 additions & 4 deletions masonry/src/widget/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ impl Checkbox {
}

// --- MARK: WIDGETMUT ---
impl WidgetMut<'_, Checkbox> {
pub fn set_checked(&mut self, checked: bool) {
use crate::{ImplMut, SelfMut};
impl ImplMut!('_, Checkbox) {
pub fn set_checked(self: SelfMut!('_, Checkbox), checked: bool) {
self.widget.checked = checked;
self.ctx.request_paint();
self.ctx.request_accessibility_update();
Expand All @@ -53,11 +54,11 @@ impl WidgetMut<'_, Checkbox> {
/// Set the text.
///
/// We enforce this to be an `ArcStr` to make the allocation explicit.
pub fn set_text(&mut self, new_text: ArcStr) {
pub fn set_text(self: SelfMut!('_, Checkbox), new_text: ArcStr) {
self.label_mut().set_text(new_text);
}

pub fn label_mut(&mut self) -> WidgetMut<'_, Label> {
pub fn label_mut(self: SelfMut!('_, Checkbox)) -> WidgetMut<'_, Label> {
self.ctx.get_mut(&mut self.widget.label)
}
}
Expand Down
37 changes: 25 additions & 12 deletions masonry/src/widget/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,32 +143,42 @@ impl GridParams {
}

// --- MARK: WIDGETMUT---
impl<'a> WidgetMut<'a, Grid> {
use crate::{ImplMut, SelfMut};
impl ImplMut!('_, Grid) {
/// Add a child widget.
///
/// See also [`with_child`].
///
/// [`with_child`]: Grid::with_child
pub fn add_child(&mut self, child: impl Widget, params: GridParams) {
pub fn add_child(self: SelfMut!('_, Grid), child: impl Widget, params: GridParams) {
let child_pod: WidgetPod<Box<dyn Widget>> = WidgetPod::new(Box::new(child));
self.insert_child_pod(child_pod, params);
}

pub fn add_child_id(&mut self, child: impl Widget, id: WidgetId, params: GridParams) {
pub fn add_child_id(
self: SelfMut!('_, Grid),
child: impl Widget,
id: WidgetId,
params: GridParams,
) {
let child_pod: WidgetPod<Box<dyn Widget>> = WidgetPod::new_with_id(Box::new(child), id);
self.insert_child_pod(child_pod, params);
}

/// Add a child widget.
pub fn insert_child_pod(&mut self, widget: WidgetPod<Box<dyn Widget>>, params: GridParams) {
pub fn insert_child_pod(
self: SelfMut!('_, Grid),
widget: WidgetPod<Box<dyn Widget>>,
params: GridParams,
) {
let child = new_grid_child(params, widget);
self.widget.children.push(child);
self.ctx.children_changed();
self.ctx.request_layout();
}

pub fn insert_grid_child_at(
&mut self,
self: SelfMut!('_, Grid),
idx: usize,
child: impl Widget,
params: impl Into<GridParams>,
Expand All @@ -177,7 +187,7 @@ impl<'a> WidgetMut<'a, Grid> {
}

pub fn insert_grid_child_pod(
&mut self,
self: SelfMut!('_, Grid),
idx: usize,
child: WidgetPod<Box<dyn Widget>>,
params: impl Into<GridParams>,
Expand All @@ -188,22 +198,25 @@ impl<'a> WidgetMut<'a, Grid> {
self.ctx.request_layout();
}

pub fn set_spacing(&mut self, spacing: f64) {
pub fn set_spacing(self: SelfMut!('_, Grid), spacing: f64) {
self.widget.grid_spacing = spacing;
self.ctx.request_layout();
}

pub fn set_width(&mut self, width: i32) {
pub fn set_width(self: SelfMut!('_, Grid), width: i32) {
self.widget.grid_width = width;
self.ctx.request_layout();
}

pub fn set_height(&mut self, height: i32) {
pub fn set_height(self: SelfMut!('_, Grid), height: i32) {
self.widget.grid_height = height;
self.ctx.request_layout();
}

pub fn child_mut(&mut self, idx: usize) -> Option<WidgetMut<'_, Box<dyn Widget>>> {
pub fn child_mut(
self: SelfMut!('_, Grid),
idx: usize,
) -> Option<WidgetMut<'_, Box<dyn Widget>>> {
let child = match self.widget.children[idx].widget_mut() {
Some(widget) => widget,
None => return None,
Expand All @@ -217,13 +230,13 @@ impl<'a> WidgetMut<'a, Grid> {
/// # Panics
///
/// Panics if the element at `idx` is not a widget.
pub fn update_child_grid_params(&mut self, idx: usize, params: GridParams) {
pub fn update_child_grid_params(self: SelfMut!('_, Grid), idx: usize, params: GridParams) {
let child = &mut self.widget.children[idx];
child.update_params(params);
self.ctx.request_layout();
}

pub fn remove_child(&mut self, idx: usize) {
pub fn remove_child(self: SelfMut!('_, Grid), idx: usize) {
let child = self.widget.children.remove(idx);
self.ctx.remove_child(child.widget);
self.ctx.request_layout();
Expand Down
2 changes: 1 addition & 1 deletion masonry/src/widget/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl Image {
}

// --- MARK: WIDGETMUT ---
impl<'a> WidgetMut<'a, Image> {
impl WidgetMut<'_, Image> {
/// Modify the widget's object fit.
#[inline]
pub fn set_fit_mode(&mut self, new_object_fit: ObjectFit) {
Expand Down
22 changes: 13 additions & 9 deletions masonry/src/widget/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,46 +107,50 @@ impl Label {
}

// --- MARK: WIDGETMUT ---
impl WidgetMut<'_, Label> {
use crate::{ImplMut, SelfMut};
impl ImplMut!('_, Label) {
pub fn text(&self) -> &ArcStr {
self.widget.text_layout.text()
}

pub fn set_text_properties<R>(&mut self, f: impl FnOnce(&mut TextLayout<ArcStr>) -> R) -> R {
pub fn set_text_properties<R>(
self: SelfMut!('_, Label),
f: impl FnOnce(&mut TextLayout<ArcStr>) -> R,
) -> R {
let ret = f(&mut self.widget.text_layout);
if self.widget.text_layout.needs_rebuild() {
self.ctx.request_layout();
}
ret
}

pub fn set_text(&mut self, new_text: impl Into<ArcStr>) {
pub fn set_text(self: SelfMut!('_, Label), new_text: impl Into<ArcStr>) {
let new_text = new_text.into();
self.set_text_properties(|layout| layout.set_text(new_text));
}

#[doc(alias = "set_text_color")]
pub fn set_text_brush(&mut self, brush: impl Into<TextBrush>) {
pub fn set_text_brush(self: SelfMut!('_, Label), brush: impl Into<TextBrush>) {
let brush = brush.into();
self.widget.brush = brush;
if !self.ctx.is_disabled() {
let brush = self.widget.brush.clone();
self.set_text_properties(|layout| layout.set_brush(brush));
}
}
pub fn set_text_size(&mut self, size: f32) {
pub fn set_text_size(self: SelfMut!('_, Label), size: f32) {
self.set_text_properties(|layout| layout.set_text_size(size));
}
pub fn set_alignment(&mut self, alignment: Alignment) {
pub fn set_alignment(self: SelfMut!('_, Label), alignment: Alignment) {
self.set_text_properties(|layout| layout.set_text_alignment(alignment));
}
pub fn set_font(&mut self, font_stack: FontStack<'static>) {
pub fn set_font(self: SelfMut!('_, Label), font_stack: FontStack<'static>) {
self.set_text_properties(|layout| layout.set_font(font_stack));
}
pub fn set_font_family(&mut self, family: FontFamily<'static>) {
pub fn set_font_family(self: SelfMut!('_, Label), family: FontFamily<'static>) {
self.set_font(FontStack::Single(family));
}
pub fn set_line_break_mode(&mut self, line_break_mode: LineBreaking) {
pub fn set_line_break_mode(self: SelfMut!('_, Label), line_break_mode: LineBreaking) {
self.widget.line_break_mode = line_break_mode;
self.ctx.request_paint();
}
Expand Down
35 changes: 35 additions & 0 deletions masonry/src/widget/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,38 @@ impl ObjectFit {
Affine::new([scalex, 0., 0., scaley, origin_x, origin_y])
}
}

// --- MARK: RECEIVER ---

#[cfg(FALSE)]
mod example {
// This:

impl ImplMut!('_, Button) {
/// Set the text.
pub fn set_text(self: SelfMut!('_, Button), new_text: impl Into<ArcStr>) {
self.label_mut().set_text(new_text);
}

pub fn label_mut(&mut self) -> WidgetMut<'_, Label> {
self.ctx.get_mut(&mut self.widget.label)
}
}

// Will resolve to this if cfg(doc):
impl Button {
/// Set the text.
pub fn set_text(self: WidgetMut<'_, Button>, new_text: impl Into<ArcStr>) {
self.label_mut().set_text(new_text);
}
}

// Else resolve to this
use crate::ImplMut;
impl ImplMut!('_, Button) {
/// Set the text.
pub fn set_text(self: &mut Self, new_text: impl Into<ArcStr>) {
self.label_mut().set_text(new_text);
}
}
}
22 changes: 12 additions & 10 deletions masonry/src/widget/portal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,28 +167,30 @@ impl<W: Widget> Portal<W> {
}

// --- MARK: WIDGETMUT ---
impl<W: Widget> WidgetMut<'_, Portal<W>> {
pub fn child_mut(&mut self) -> WidgetMut<'_, W> {

use crate::{ImplMut, SelfMut};
impl<W: Widget> ImplMut!('_, Portal<W>) {
pub fn child_mut(self: SelfMut!('_, Portal<W>)) -> WidgetMut<'_, W> {
self.ctx.get_mut(&mut self.widget.child)
}

pub fn horizontal_scrollbar_mut(&mut self) -> WidgetMut<'_, ScrollBar> {
pub fn horizontal_scrollbar_mut(self: SelfMut!('_, Portal<W>)) -> WidgetMut<'_, ScrollBar> {
self.ctx.get_mut(&mut self.widget.scrollbar_horizontal)
}

pub fn vertical_scrollbar_mut(&mut self) -> WidgetMut<'_, ScrollBar> {
pub fn vertical_scrollbar_mut(self: SelfMut!('_, Portal<W>)) -> WidgetMut<'_, ScrollBar> {
self.ctx.get_mut(&mut self.widget.scrollbar_vertical)
}

// TODO - rewrite doc
/// Set whether to constrain the child horizontally.
pub fn set_constrain_horizontal(&mut self, constrain: bool) {
pub fn set_constrain_horizontal(self: SelfMut!('_, Portal<W>), constrain: bool) {
self.widget.constrain_horizontal = constrain;
self.ctx.request_layout();
}

/// Set whether to constrain the child vertically.
pub fn set_constrain_vertical(&mut self, constrain: bool) {
pub fn set_constrain_vertical(self: SelfMut!('_, Portal<W>), constrain: bool) {
self.widget.constrain_vertical = constrain;
self.ctx.request_layout();
}
Expand All @@ -199,12 +201,12 @@ impl<W: Widget> WidgetMut<'_, Portal<W>> {
/// See [`content_must_fill`] for more details.
///
/// [`content_must_fill`]: ClipBox::content_must_fill
pub fn set_content_must_fill(&mut self, must_fill: bool) {
pub fn set_content_must_fill(self: SelfMut!('_, Portal<W>), must_fill: bool) {
self.widget.must_fill = must_fill;
self.ctx.request_layout();
}

pub fn set_viewport_pos(&mut self, position: Point) -> bool {
pub fn set_viewport_pos(self: SelfMut!('_, Portal<W>), position: Point) -> bool {
let portal_size = self.ctx.layout_rect().size();
let content_size = self
.ctx
Expand All @@ -228,12 +230,12 @@ impl<W: Widget> WidgetMut<'_, Portal<W>> {
pos_changed
}

pub fn pan_viewport_by(&mut self, translation: Vec2) -> bool {
pub fn pan_viewport_by(self: SelfMut!('_, Portal<W>), translation: Vec2) -> bool {
self.set_viewport_pos(self.widget.viewport_pos + translation)
}

// Note - Rect is in child coordinates
pub fn pan_viewport_to(&mut self, target: Rect) -> bool {
pub fn pan_viewport_to(self: SelfMut!('_, Portal<W>), target: Rect) -> bool {
let viewport = Rect::from_origin_size(self.widget.viewport_pos, self.ctx.widget_state.size);

let new_pos_x = compute_pan_range(
Expand Down
5 changes: 3 additions & 2 deletions masonry/src/widget/progress_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ impl ProgressBar {
}

// --- MARK: WIDGETMUT ---
impl WidgetMut<'_, ProgressBar> {
pub fn set_progress(&mut self, progress: Option<f64>) {
use crate::{ImplMut, SelfMut};
impl ImplMut!('_, ProgressBar) {
pub fn set_progress(self: SelfMut!('_, ProgressBar), progress: Option<f64>) {
self.widget.set_progress(progress);
self.ctx.request_layout();
self.ctx.request_accessibility_update();
Expand Down
Loading
Loading