From f1df2ea2a92557e8846fa2ab3cf45dc3d2bef492 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 15 May 2024 09:31:28 +0200 Subject: [PATCH] bin: Use improved widget base interface --- bin/commands/inbox/select/ui.rs | 130 ++++++++++++++-------------- bin/commands/issue/select/ui.rs | 146 ++++++++++++++++---------------- bin/commands/patch/select/ui.rs | 134 ++++++++++++++--------------- 3 files changed, 208 insertions(+), 202 deletions(-) diff --git a/bin/commands/inbox/select/ui.rs b/bin/commands/inbox/select/ui.rs index 459a15d4..9ee62d15 100644 --- a/bin/commands/inbox/select/ui.rs +++ b/bin/commands/inbox/select/ui.rs @@ -22,7 +22,7 @@ use tui::ui::widget::input::{TextField, TextFieldProps}; use tui::ui::widget::list::{Table, TableProps, TableUtils}; use tui::ui::widget::text::{Paragraph, ParagraphProps}; use tui::ui::widget::window::{Shortcuts, ShortcutsProps}; -use tui::ui::widget::{BaseView, BoxedAny, Properties, RenderProps, Widget}; +use tui::ui::widget::{BoxedAny, Properties, RenderProps, Widget, WidgetBase}; use tui::Selection; @@ -113,7 +113,7 @@ impl<'a> BoxedAny for BrowserProps<'a> {} pub struct Browser<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: BrowserProps<'a>, /// Notification widget @@ -130,11 +130,7 @@ impl<'a: 'static> Widget for Browser<'a> { let props = BrowserProps::from(state); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: props.clone(), notifications: Container::new(state, action_tx.clone()) .header( @@ -155,8 +151,11 @@ impl<'a: 'static> Widget for Browser<'a> { table .downcast_mut::>() .and_then(|table| { - let selected = table.selected(); - table.base_mut().send(Action::Select { selected }).ok() + table + .send(Action::Select { + selected: table.selected(), + }) + .ok() }); }) .on_update(|state| { @@ -196,7 +195,7 @@ impl<'a: 'static> Widget for Browser<'a> { } else { match key { Key::Char('/') => { - let _ = self.base.send(Action::OpenSearch); + let _ = self.send(Action::OpenSearch); } Key::Char('\n') => { self.props @@ -260,7 +259,11 @@ impl<'a: 'static> Widget for Browser<'a> { } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -302,7 +305,7 @@ impl<'a> BoxedAny for BrowserPageProps<'a> {} pub struct BrowserPage<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: BrowserPageProps<'a>, /// Sections widget @@ -319,11 +322,7 @@ impl<'a: 'static> Widget for BrowserPage<'a> { let props = BrowserPageProps::from(state); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: props.clone(), sections: SectionGroup::new(state, action_tx.clone()) .section(Browser::new(state, action_tx.clone()).to_boxed()) @@ -350,10 +349,10 @@ impl<'a: 'static> Widget for BrowserPage<'a> { if self.props.handle_keys { match key { Key::Esc | Key::Ctrl('c') => { - let _ = self.base.send(Action::Exit { selection: None }); + let _ = self.send(Action::Exit { selection: None }); } Key::Char('?') => { - let _ = self.base.send(Action::OpenHelp); + let _ = self.send(Action::OpenHelp); } _ => {} } @@ -384,11 +383,15 @@ impl<'a: 'static> Widget for BrowserPage<'a> { .render(frame, RenderProps::from(shortcuts_area)); if page_size != self.props.page_size { - let _ = self.base.send(Action::BrowserPageSize(page_size)); + let _ = self.send(Action::BrowserPageSize(page_size)); } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -399,7 +402,7 @@ impl Properties for SearchProps {} pub struct Search { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props _props: SearchProps, /// Search input field @@ -414,44 +417,39 @@ impl Widget for Search { where Self: Sized, { - let input = TextField::new(state, action_tx.clone()) - .on_event(|field| { - field - .downcast_mut::>() - .and_then(|field| { - let text = field.text().unwrap_or(&String::new()).to_string(); - field - .base_mut() - .send(Action::UpdateSearch { value: text }) - .ok() - }); - }) - .on_update(|state| { - TextFieldProps::default() - .text(&state.browser.search.read().to_string()) - .title("Search") - .inline(true) - .to_boxed() - }) - .to_boxed(); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), _props: SearchProps {}, - input, + input: TextField::new(state, action_tx.clone()) + .on_event(|widget| { + widget + .downcast_mut::>() + .and_then(|field| { + field + .send(Action::UpdateSearch { + value: field.text().unwrap_or(&String::new()).to_string(), + }) + .ok() + }); + }) + .on_update(|state| { + TextFieldProps::default() + .text(&state.browser.search.read().to_string()) + .title("Search") + .inline(true) + .to_boxed() + }) + .to_boxed(), } } fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc => { - let _ = self.base.send(Action::CloseSearch); + let _ = self.send(Action::CloseSearch); } Key::Char('\n') => { - let _ = self.base.send(Action::ApplySearch); + let _ = self.send(Action::ApplySearch); } _ => { self.input.handle_event(key); @@ -471,7 +469,11 @@ impl Widget for Search { self.input.render(frame, RenderProps::from(layout[0])); } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -501,7 +503,7 @@ impl<'a> BoxedAny for HelpPageProps<'a> {} pub struct HelpPage<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: HelpPageProps<'a>, /// Content widget @@ -519,11 +521,7 @@ impl<'a: 'static> Widget for HelpPage<'a> { Self: Sized, { Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: HelpPageProps::from(state), content: Container::new(state, action_tx.clone()) .header( @@ -541,10 +539,10 @@ impl<'a: 'static> Widget for HelpPage<'a> { paragraph .downcast_mut::>() .and_then(|paragraph| { - let progress = paragraph.progress(); paragraph - .base_mut() - .send(Action::ScrollHelp { progress }) + .send(Action::ScrollHelp { + progress: paragraph.progress(), + }) .ok() }); }) @@ -593,10 +591,10 @@ impl<'a: 'static> Widget for HelpPage<'a> { fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc | Key::Ctrl('c') => { - let _ = self.base.send(Action::Exit { selection: None }); + let _ = self.send(Action::Exit { selection: None }); } Key::Char('?') => { - let _ = self.base.send(Action::LeavePage); + let _ = self.send(Action::LeavePage); } _ => { self.content.handle_event(key); @@ -624,11 +622,15 @@ impl<'a: 'static> Widget for HelpPage<'a> { .render(frame, RenderProps::from(shortcuts_area)); if page_size != self.props.page_size { - let _ = self.base.send(Action::HelpPageSize(page_size)); + let _ = self.send(Action::HelpPageSize(page_size)); } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } diff --git a/bin/commands/issue/select/ui.rs b/bin/commands/issue/select/ui.rs index 8de20890..ac902769 100644 --- a/bin/commands/issue/select/ui.rs +++ b/bin/commands/issue/select/ui.rs @@ -24,7 +24,7 @@ use tui::ui::widget::input::{TextField, TextFieldProps}; use tui::ui::widget::list::{Table, TableProps, TableUtils}; use tui::ui::widget::text::{Paragraph, ParagraphProps}; use tui::ui::widget::window::{Shortcuts, ShortcutsProps}; -use tui::ui::widget::{BaseView, BoxedAny, Properties, RenderProps, Widget}; +use tui::ui::widget::{BoxedAny, Properties, RenderProps, Widget, WidgetBase}; use tui::Selection; @@ -133,7 +133,7 @@ impl<'a> BoxedAny for BrowserProps<'a> {} pub struct Browser<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: BrowserProps<'a>, /// Notifications widget @@ -150,11 +150,7 @@ impl<'a: 'static> Widget for Browser<'a> { let props = BrowserProps::from(state); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: BrowserProps::from(state), issues: Container::new(state, action_tx.clone()) .header( @@ -169,8 +165,11 @@ impl<'a: 'static> Widget for Browser<'a> { table .downcast_mut::>() .and_then(|table| { - let selected = table.selected(); - table.base_mut().send(Action::Select { selected }).ok() + table + .send(Action::Select { + selected: table.selected(), + }) + .ok() }); }) .on_update(|state| { @@ -212,7 +211,7 @@ impl<'a: 'static> Widget for Browser<'a> { } else { match key { Key::Char('/') => { - let _ = self.base.send(Action::OpenSearch); + let _ = self.send(Action::OpenSearch); } Key::Char('\n') => { let operation = match self.props.mode { @@ -279,7 +278,11 @@ impl<'a: 'static> Widget for Browser<'a> { } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -321,7 +324,7 @@ impl<'a> BoxedAny for BrowserPageProps<'a> {} pub struct BrowserPage<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: BrowserPageProps<'a>, /// Sections widget @@ -338,11 +341,7 @@ impl<'a: 'static> Widget for BrowserPage<'a> { let props = BrowserPageProps::from(state); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: props.clone(), sections: SectionGroup::new(state, action_tx.clone()) .section(Browser::new(state, action_tx.clone()).to_boxed()) @@ -369,10 +368,10 @@ impl<'a: 'static> Widget for BrowserPage<'a> { if self.props.handle_keys { match key { Key::Esc | Key::Ctrl('c') => { - let _ = self.base.send(Action::Exit { selection: None }); + let _ = self.send(Action::Exit { selection: None }); } Key::Char('?') => { - let _ = self.base.send(Action::OpenHelp); + let _ = self.send(Action::OpenHelp); } _ => {} } @@ -403,11 +402,15 @@ impl<'a: 'static> Widget for BrowserPage<'a> { .render(frame, RenderProps::from(shortcuts_area)); if page_size != self.props.page_size { - let _ = self.base.send(Action::BrowserPageSize(page_size)); + let _ = self.send(Action::BrowserPageSize(page_size)); } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -418,7 +421,7 @@ impl Properties for SearchProps {} pub struct Search { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props _props: SearchProps, /// Search input field @@ -433,44 +436,39 @@ impl Widget for Search { where Self: Sized, { - let input = TextField::new(state, action_tx.clone()) - .on_event(|field| { - field - .downcast_mut::>() - .and_then(|field| { - let text = field.text().unwrap_or(&String::new()).to_string(); - field - .base_mut() - .send(Action::UpdateSearch { value: text }) - .ok() - }); - }) - .on_update(|state| { - TextFieldProps::default() - .text(&state.browser.search.read().to_string()) - .title("Search") - .inline(true) - .to_boxed() - }) - .to_boxed(); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), _props: SearchProps {}, - input, + input: TextField::new(state, action_tx.clone()) + .on_event(|widget| { + widget + .downcast_mut::>() + .and_then(|field| { + field + .send(Action::UpdateSearch { + value: field.text().unwrap_or(&String::new()).to_string(), + }) + .ok() + }); + }) + .on_update(|state| { + TextFieldProps::default() + .text(&state.browser.search.read().to_string()) + .title("Search") + .inline(true) + .to_boxed() + }) + .to_boxed(), } } fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc => { - let _ = self.base.send(Action::CloseSearch); + let _ = self.send(Action::CloseSearch); } Key::Char('\n') => { - let _ = self.base.send(Action::ApplySearch); + let _ = self.send(Action::ApplySearch); } _ => { self.input.handle_event(key); @@ -490,7 +488,11 @@ impl Widget for Search { self.input.render(frame, RenderProps::from(layout[0])); } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -517,7 +519,7 @@ impl<'a> BoxedAny for HelpPageProps<'a> {} pub struct HelpPage<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: HelpPageProps<'a>, /// Content widget @@ -535,11 +537,7 @@ impl<'a: 'static> Widget for HelpPage<'a> { Self: Sized, { Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: HelpPageProps::from(state), content: Container::new(state, action_tx.clone()) .header( @@ -553,6 +551,17 @@ impl<'a: 'static> Widget for HelpPage<'a> { ) .content( Paragraph::new(state, action_tx.clone()) + .on_event(|paragraph| { + paragraph + .downcast_mut::>() + .and_then(|paragraph| { + paragraph + .send(Action::ScrollHelp { + progress: paragraph.progress(), + }) + .ok() + }); + }) .on_update(|state| { let props = HelpPageProps::from(state); @@ -561,17 +570,6 @@ impl<'a: 'static> Widget for HelpPage<'a> { .page_size(props.page_size) .to_boxed() }) - .on_event(|paragraph| { - paragraph - .downcast_mut::>() - .and_then(|paragraph| { - let progress = paragraph.progress(); - paragraph - .base_mut() - .send(Action::ScrollHelp { progress }) - .ok() - }); - }) .to_boxed(), ) .footer( @@ -609,10 +607,10 @@ impl<'a: 'static> Widget for HelpPage<'a> { fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc | Key::Ctrl('c') => { - let _ = self.base.send(Action::Exit { selection: None }); + let _ = self.send(Action::Exit { selection: None }); } Key::Char('?') => { - let _ = self.base.send(Action::LeavePage); + let _ = self.send(Action::LeavePage); } _ => { self.content.handle_event(key); @@ -640,11 +638,15 @@ impl<'a: 'static> Widget for HelpPage<'a> { .render(frame, RenderProps::from(shortcuts_area)); if page_size != self.props.page_size { - let _ = self.base.send(Action::HelpPageSize(page_size)); + let _ = self.send(Action::HelpPageSize(page_size)); } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } diff --git a/bin/commands/patch/select/ui.rs b/bin/commands/patch/select/ui.rs index 632e3b97..e6310701 100644 --- a/bin/commands/patch/select/ui.rs +++ b/bin/commands/patch/select/ui.rs @@ -25,7 +25,7 @@ use tui::ui::widget::input::{TextField, TextFieldProps}; use tui::ui::widget::list::{Table, TableProps, TableUtils}; use tui::ui::widget::text::{Paragraph, ParagraphProps}; use tui::ui::widget::window::{Shortcuts, ShortcutsProps}; -use tui::ui::widget::{BaseView, BoxedAny, Properties, RenderProps, Widget}; +use tui::ui::widget::{BoxedAny, Properties, RenderProps, Widget, WidgetBase}; use tui::Selection; @@ -133,7 +133,7 @@ impl<'a: 'static> BoxedAny for BrowserProps<'a> {} pub struct Browser<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: BrowserProps<'a>, /// Patches widget @@ -150,11 +150,7 @@ impl<'a: 'static> Widget for Browser<'a> { let props = BrowserProps::from(state); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: props.clone(), patches: Container::new(state, action_tx.clone()) .header( @@ -169,8 +165,11 @@ impl<'a: 'static> Widget for Browser<'a> { table .downcast_mut::>() .and_then(|table| { - let selected = table.selected(); - table.base_mut().send(Action::Select { selected }).ok() + table + .send(Action::Select { + selected: table.selected(), + }) + .ok() }); }) .on_update(|state| { @@ -212,13 +211,13 @@ impl<'a: 'static> Widget for Browser<'a> { } else { match key { Key::Esc | Key::Ctrl('c') => { - let _ = self.base.send(Action::Exit { selection: None }); + let _ = self.send(Action::Exit { selection: None }); } Key::Char('?') => { - let _ = self.base.send(Action::OpenHelp); + let _ = self.send(Action::OpenHelp); } Key::Char('/') => { - let _ = self.base.send(Action::OpenSearch); + let _ = self.send(Action::OpenSearch); } Key::Char('\n') => { let operation = match self.props.mode { @@ -301,7 +300,11 @@ impl<'a: 'static> Widget for Browser<'a> { } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -344,7 +347,7 @@ impl<'a> BoxedAny for BrowserPageProps<'a> {} pub struct BrowserPage<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: BrowserPageProps<'a>, /// Sections widget @@ -361,11 +364,7 @@ impl<'a: 'static> Widget for BrowserPage<'a> { let props = BrowserPageProps::from(state); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: props.clone(), sections: SectionGroup::new(state, action_tx.clone()) .section(Browser::new(state, action_tx.clone()).to_boxed()) @@ -392,10 +391,10 @@ impl<'a: 'static> Widget for BrowserPage<'a> { if self.props.handle_keys { match key { Key::Esc | Key::Ctrl('c') => { - let _ = self.base.send(Action::Exit { selection: None }); + let _ = self.send(Action::Exit { selection: None }); } Key::Char('?') => { - let _ = self.base.send(Action::OpenHelp); + let _ = self.send(Action::OpenHelp); } _ => {} } @@ -426,11 +425,15 @@ impl<'a: 'static> Widget for BrowserPage<'a> { .render(frame, RenderProps::from(shortcuts_area)); if page_size != self.props.page_size { - let _ = self.base.send(Action::BrowserPageSize(page_size)); + let _ = self.send(Action::BrowserPageSize(page_size)); } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -441,7 +444,7 @@ impl Properties for SearchProps {} pub struct Search { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props _props: SearchProps, /// Search input field @@ -456,44 +459,39 @@ impl Widget for Search { where Self: Sized, { - let input = TextField::new(state, action_tx.clone()) - .on_event(|field| { - field - .downcast_mut::>() - .and_then(|field| { - let text = field.text().unwrap_or(&String::new()).to_string(); - field - .base_mut() - .send(Action::UpdateSearch { value: text }) - .ok() - }); - }) - .on_update(|state| { - TextFieldProps::default() - .text(&state.browser.search.read().to_string()) - .title("Search") - .inline(true) - .to_boxed() - }) - .to_boxed(); Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), _props: SearchProps {}, - input, + input: TextField::new(state, action_tx.clone()) + .on_event(|widget| { + widget + .downcast_mut::>() + .and_then(|field| { + field + .send(Action::UpdateSearch { + value: field.text().unwrap_or(&String::new()).to_string(), + }) + .ok() + }); + }) + .on_update(|state| { + TextFieldProps::default() + .text(&state.browser.search.read().to_string()) + .title("Search") + .inline(true) + .to_boxed() + }) + .to_boxed(), } } fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc => { - let _ = self.base.send(Action::CloseSearch); + let _ = self.send(Action::CloseSearch); } Key::Char('\n') => { - let _ = self.base.send(Action::ApplySearch); + let _ = self.send(Action::ApplySearch); } _ => { self.input.handle_event(key); @@ -513,7 +511,11 @@ impl Widget for Search { self.input.render(frame, RenderProps::from(layout[0])); } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } } @@ -540,7 +542,7 @@ impl<'a> BoxedAny for HelpPageProps<'a> {} pub struct HelpPage<'a> { /// Internal base - base: BaseView, + base: WidgetBase, /// Internal props props: HelpPageProps<'a>, /// Content widget @@ -558,11 +560,7 @@ impl<'a: 'static> Widget for HelpPage<'a> { Self: Sized, { Self { - base: BaseView { - action_tx: action_tx.clone(), - on_update: None, - on_event: None, - }, + base: WidgetBase::new(action_tx.clone()), props: HelpPageProps::from(state), content: Container::new(state, action_tx.clone()) .header( @@ -580,10 +578,10 @@ impl<'a: 'static> Widget for HelpPage<'a> { paragraph .downcast_mut::>() .and_then(|paragraph| { - let progress = paragraph.progress(); paragraph - .base_mut() - .send(Action::ScrollHelp { progress }) + .send(Action::ScrollHelp { + progress: paragraph.progress(), + }) .ok() }); }) @@ -632,10 +630,10 @@ impl<'a: 'static> Widget for HelpPage<'a> { fn handle_event(&mut self, key: termion::event::Key) { match key { Key::Esc | Key::Ctrl('c') => { - let _ = self.base.send(Action::Exit { selection: None }); + let _ = self.send(Action::Exit { selection: None }); } Key::Char('?') => { - let _ = self.base.send(Action::LeavePage); + let _ = self.send(Action::LeavePage); } _ => { self.content.handle_event(key); @@ -662,11 +660,15 @@ impl<'a: 'static> Widget for HelpPage<'a> { .render(frame, RenderProps::from(shortcuts_area)); if page_size != self.props.page_size { - let _ = self.base.send(Action::HelpPageSize(page_size)); + let _ = self.send(Action::HelpPageSize(page_size)); } } - fn base_mut(&mut self) -> &mut BaseView { + fn base(&self) -> &WidgetBase { + &self.base + } + + fn base_mut(&mut self) -> &mut WidgetBase { &mut self.base } }