From 2b54d6df282ef7125bfa6dd40da3672c4c0ef4b7 Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Fri, 15 Jul 2016 23:44:38 -0700 Subject: [PATCH] Make `View::draw` take a &self (instead of a &mut self) TrackedView, the only user of the mutability, now uses internal mutability with a Cell. --- src/printer.rs | 7 ++++++- src/view/button.rs | 2 +- src/view/dialog.rs | 4 ++-- src/view/edit_view.rs | 2 +- src/view/linear_layout.rs | 4 ++-- src/view/menu_popup.rs | 2 +- src/view/mod.rs | 2 +- src/view/select_view.rs | 2 +- src/view/shadow_view.rs | 2 +- src/view/stack_view.rs | 4 ++-- src/view/text_view.rs | 2 +- src/view/tracked_view.rs | 17 +++++++++++++---- src/view/view_wrapper.rs | 6 +++--- 13 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/printer.rs b/src/printer.rs index dbf1f1a..1d26bf1 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -173,7 +173,7 @@ impl Printer { } /// Returns a printer on a subset of this one's area. - pub fn sub_printer>(&self, offset: S, size: S, focused: bool) + pub fn sub_printer, T: Into>(&self, offset: S, size: T, focused: bool) -> Printer { let offset = offset.into().or_min(self.size); Printer { @@ -184,4 +184,9 @@ impl Printer { theme: self.theme.clone(), } } + + /// Returns a sub-printer with the given offset. + pub fn offset>(&self, offset: S, focused: bool) -> Printer { + self.sub_printer(offset, self.size, focused) + } } diff --git a/src/view/button.rs b/src/view/button.rs index 1967f82..4b20ed9 100644 --- a/src/view/button.rs +++ b/src/view/button.rs @@ -29,7 +29,7 @@ impl Button { } impl View for Button { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { let style = if !printer.focused { ColorStyle::Primary } else { diff --git a/src/view/dialog.rs b/src/view/dialog.rs index 32d1ecd..0b10fe3 100644 --- a/src/view/dialog.rs +++ b/src/view/dialog.rs @@ -111,7 +111,7 @@ impl Dialog { } impl View for Dialog { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { // This will be the buttons_height used by the buttons. let mut buttons_height = 0; @@ -133,7 +133,7 @@ impl View for Dialog { .get_offset(width, printer.size.x - overhead.horizontal()); let y = printer.size.y - self.padding.bottom - self.borders.bottom - 1; - for (i, button) in self.buttons.iter_mut().enumerate() { + for (i, button) in self.buttons.iter().enumerate() { let size = button.size; // Add some special effect to the focused button button.draw(&printer.sub_printer(Vec2::new(offset, y), diff --git a/src/view/edit_view.rs b/src/view/edit_view.rs index 1ac29ef..37169e4 100644 --- a/src/view/edit_view.rs +++ b/src/view/edit_view.rs @@ -79,7 +79,7 @@ impl EditView { } impl View for EditView { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { assert!(printer.size.x == self.last_length); let width = self.content.width(); diff --git a/src/view/linear_layout.rs b/src/view/linear_layout.rs index 2c23fe7..21d0e26 100644 --- a/src/view/linear_layout.rs +++ b/src/view/linear_layout.rs @@ -162,10 +162,10 @@ fn try_focus((i, child): (usize, &mut Child), source: direction::Direction) } impl View for LinearLayout { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { // Use pre-computed sizes let mut offset = Vec2::zero(); - for (i, child) in self.children.iter_mut().enumerate() { + for (i, child) in self.children.iter().enumerate() { let printer = &printer.sub_printer(offset, child.size, i == self.focus); child.view.draw(printer); diff --git a/src/view/menu_popup.rs b/src/view/menu_popup.rs index 9987040..ba08e94 100644 --- a/src/view/menu_popup.rs +++ b/src/view/menu_popup.rs @@ -133,7 +133,7 @@ impl MenuPopup { } impl View for MenuPopup { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { let h = self.menu.len(); let offset = self.align.v.get_offset(h, printer.size.y); let printer = diff --git a/src/view/mod.rs b/src/view/mod.rs index 5175188..e4fdecb 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -127,7 +127,7 @@ pub trait View { fn layout(&mut self, Vec2) {} /// Draws the view with the given printer (includes bounds) and focus. - fn draw(&mut self, printer: &Printer); + fn draw(&self, printer: &Printer); /// Finds the view pointed to by the given path. /// diff --git a/src/view/select_view.rs b/src/view/select_view.rs index 394ca07..5491fb6 100644 --- a/src/view/select_view.rs +++ b/src/view/select_view.rs @@ -132,7 +132,7 @@ impl SelectView { } impl View for SelectView { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { let h = self.items.len(); let offset = self.align.v.get_offset(h, printer.size.y); diff --git a/src/view/shadow_view.rs b/src/view/shadow_view.rs index bd1a3bd..4cdebe8 100644 --- a/src/view/shadow_view.rs +++ b/src/view/shadow_view.rs @@ -56,7 +56,7 @@ impl ViewWrapper for ShadowView { self.view.layout(size - offset); } - fn wrap_draw(&mut self, printer: &Printer) { + fn wrap_draw(&self, printer: &Printer) { // Skip the first row/column let printer = diff --git a/src/view/stack_view.rs b/src/view/stack_view.rs index 7bb634a..20cf162 100644 --- a/src/view/stack_view.rs +++ b/src/view/stack_view.rs @@ -61,11 +61,11 @@ impl StackView { } impl View for StackView { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { let last = self.layers.len(); let mut previous = Vec2::zero(); printer.with_color(ColorStyle::Primary, |printer| { - for (i, v) in self.layers.iter_mut().enumerate() { + for (i, v) in self.layers.iter().enumerate() { // Place the view // Center the view let offset = v.position diff --git a/src/view/text_view.rs b/src/view/text_view.rs index 6473a24..3d7d33b 100644 --- a/src/view/text_view.rs +++ b/src/view/text_view.rs @@ -194,7 +194,7 @@ impl<'a> Iterator for LinesIterator<'a> { } impl View for TextView { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { let h = self.rows.len(); let offset = self.align.v.get_offset(h, printer.size.y); diff --git a/src/view/tracked_view.rs b/src/view/tracked_view.rs index cbcc075..966a0cb 100644 --- a/src/view/tracked_view.rs +++ b/src/view/tracked_view.rs @@ -1,3 +1,5 @@ +use std::cell::Cell; + use view::{IdView, View, ViewWrapper}; use Printer; use vec::Vec2; @@ -7,7 +9,14 @@ pub struct TrackedView { /// Wrapped view. pub view: T, /// Last position the view was located. - pub offset: Vec2, + offset: Cell, +} + +impl TrackedView { + /// Return the last offset at which the view was drawn. + pub fn offset(&self) -> Vec2 { + self.offset.get() + } } impl TrackedView { @@ -15,7 +24,7 @@ impl TrackedView { pub fn new(view: T) -> Self { TrackedView { view: view, - offset: Vec2::zero(), + offset: Cell::new(Vec2::zero()), } } @@ -28,8 +37,8 @@ impl TrackedView { impl ViewWrapper for TrackedView { wrap_impl!(&self.view); - fn wrap_draw(&mut self, printer: &Printer) { - self.offset = printer.offset; + fn wrap_draw(&self, printer: &Printer) { + self.offset.set(printer.offset); self.view.draw(printer); } } diff --git a/src/view/view_wrapper.rs b/src/view/view_wrapper.rs index de73b7d..fad4c99 100644 --- a/src/view/view_wrapper.rs +++ b/src/view/view_wrapper.rs @@ -18,8 +18,8 @@ pub trait ViewWrapper { fn get_view_mut(&mut self) -> &mut View; /// Wraps the `draw` method. - fn wrap_draw(&mut self, printer: &Printer) { - self.get_view_mut().draw(printer); + fn wrap_draw(&self, printer: &Printer) { + self.get_view().draw(printer); } /// Wraps the `get_min_size` method. @@ -54,7 +54,7 @@ pub trait ViewWrapper { } impl View for T { - fn draw(&mut self, printer: &Printer) { + fn draw(&self, printer: &Printer) { self.wrap_draw(printer); }