Replace all entries with AdwEntryRow

This commit is contained in:
Elias Projahn 2022-05-01 19:09:29 +02:00
parent fe83811a8a
commit 1db96062fb
13 changed files with 67 additions and 138 deletions

View file

@ -68,16 +68,8 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="AdwActionRow" id="name_row"> <object class="AdwEntryRow" id="name_row">
<property name="focusable">False</property>
<property name="title" translatable="yes">Name of the medium</property> <property name="title" translatable="yes">Name of the medium</property>
<property name="activatable-widget">name_entry</property>
<child>
<object class="GtkEntry" id="name_entry">
<property name="valign">center</property>
<property name="hexpand">True</property>
</object>
</child>
</object> </object>
</child> </child>
<style> <style>

View file

@ -85,16 +85,8 @@
</object> </object>
</child> </child>
<child> <child>
<object class="AdwActionRow"> <object class="AdwEntryRow" id="comment_row">
<property name="focusable">False</property>
<property name="title" translatable="yes">Comment</property> <property name="title" translatable="yes">Comment</property>
<property name="activatable-widget">comment_entry</property>
<child>
<object class="GtkEntry" id="comment_entry">
<property name="valign">center</property>
<property name="hexpand">True</property>
</object>
</child>
</object> </object>
</child> </child>
<style> <style>

View file

@ -85,16 +85,8 @@
</object> </object>
</child> </child>
<child> <child>
<object class="AdwActionRow"> <object class="AdwEntryRow" id="title_row">
<property name="focusable">False</property>
<property name="title" translatable="yes">Title</property> <property name="title" translatable="yes">Title</property>
<property name="activatable-widget">title_entry</property>
<child>
<object class="GtkEntry" id="title_entry">
<property name="valign">center</property>
<property name="hexpand">True</property>
</object>
</child>
</object> </object>
</child> </child>
<style> <style>

View file

@ -50,17 +50,10 @@
<child> <child>
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<property name="valign">start</property>
<child> <child>
<object class="AdwActionRow"> <object class="AdwEntryRow" id="title_row">
<property name="focusable">False</property>
<property name="title" translatable="yes">Title</property> <property name="title" translatable="yes">Title</property>
<property name="activatable-widget">title_entry</property>
<child>
<object class="GtkEntry" id="title_entry">
<property name="valign">center</property>
<property name="hexpand">True</property>
</object>
</child>
</object> </object>
</child> </child>
<style> <style>

View file

@ -1,5 +1,5 @@
use crate::navigator::{NavigationHandle, Screen}; use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::{Editor, EntryRow, Section, Widget}; use crate::widgets::{Editor, Section, Widget};
use anyhow::Result; use anyhow::Result;
use gettextrs::gettext; use gettextrs::gettext;
use gtk::{builders::ListBoxBuilder, glib::clone, prelude::*}; use gtk::{builders::ListBoxBuilder, glib::clone, prelude::*};
@ -14,7 +14,7 @@ pub struct EnsembleEditor {
id: String, id: String,
editor: Editor, editor: Editor,
name: EntryRow, name: adw::EntryRow,
} }
impl Screen<Option<Ensemble>, Ensemble> for EnsembleEditor { impl Screen<Option<Ensemble>, Ensemble> for EnsembleEditor {
@ -28,8 +28,8 @@ impl Screen<Option<Ensemble>, Ensemble> for EnsembleEditor {
.css_classes(vec![String::from("boxed-list")]) .css_classes(vec![String::from("boxed-list")])
.build(); .build();
let name = EntryRow::new(&gettext("Name")); let name = adw::EntryRow::builder().title(&gettext("Name")).build();
list.append(&name.widget); list.append(&name);
let section = Section::new(&gettext("General"), &list); let section = Section::new(&gettext("General"), &list);
editor.add_content(&section.widget); editor.add_content(&section.widget);
@ -68,7 +68,6 @@ impl Screen<Option<Ensemble>, Ensemble> for EnsembleEditor {
})); }));
this.name this.name
.entry
.connect_changed(clone!(@weak this => move |_| this.validate())); .connect_changed(clone!(@weak this => move |_| this.validate()));
this.validate(); this.validate();
@ -80,14 +79,14 @@ impl Screen<Option<Ensemble>, Ensemble> for EnsembleEditor {
impl EnsembleEditor { impl EnsembleEditor {
/// Validate inputs and enable/disable saving. /// Validate inputs and enable/disable saving.
fn validate(&self) { fn validate(&self) {
self.editor.set_may_save(!self.name.get_text().is_empty()); self.editor.set_may_save(!self.name.text().is_empty());
} }
/// Save the ensemble. /// Save the ensemble.
fn save(&self) -> Result<Ensemble> { fn save(&self) -> Result<Ensemble> {
let name = self.name.get_text(); let name = self.name.text();
let ensemble = Ensemble::new(self.id.clone(), name); let ensemble = Ensemble::new(self.id.clone(), name.to_string());
self.handle.backend.db().update_ensemble(ensemble.clone())?; self.handle.backend.db().update_ensemble(ensemble.clone())?;
self.handle.backend.library_changed(); self.handle.backend.library_changed();

View file

@ -1,8 +1,8 @@
use crate::navigator::{NavigationHandle, Screen}; use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::{Editor, EntryRow, Section, Widget}; use crate::widgets::{Editor, Section, Widget};
use anyhow::Result; use anyhow::Result;
use gettextrs::gettext; use gettextrs::gettext;
use gtk::{glib::clone, prelude::*, builders::ListBoxBuilder}; use gtk::{builders::ListBoxBuilder, glib::clone, prelude::*};
use musicus_backend::db::{generate_id, Instrument}; use musicus_backend::db::{generate_id, Instrument};
use std::rc::Rc; use std::rc::Rc;
@ -14,7 +14,7 @@ pub struct InstrumentEditor {
id: String, id: String,
editor: Editor, editor: Editor,
name: EntryRow, name: adw::EntryRow,
} }
impl Screen<Option<Instrument>, Instrument> for InstrumentEditor { impl Screen<Option<Instrument>, Instrument> for InstrumentEditor {
@ -28,8 +28,8 @@ impl Screen<Option<Instrument>, Instrument> for InstrumentEditor {
.css_classes(vec![String::from("boxed-list")]) .css_classes(vec![String::from("boxed-list")])
.build(); .build();
let name = EntryRow::new(&gettext("Name")); let name = adw::EntryRow::builder().title(&gettext("Name")).build();
list.append(&name.widget); list.append(&name);
let section = Section::new(&gettext("General"), &list); let section = Section::new(&gettext("General"), &list);
editor.add_content(&section.widget); editor.add_content(&section.widget);
@ -68,7 +68,6 @@ impl Screen<Option<Instrument>, Instrument> for InstrumentEditor {
})); }));
this.name this.name
.entry
.connect_changed(clone!(@weak this => move |_| this.validate())); .connect_changed(clone!(@weak this => move |_| this.validate()));
this.validate(); this.validate();
@ -80,14 +79,14 @@ impl Screen<Option<Instrument>, Instrument> for InstrumentEditor {
impl InstrumentEditor { impl InstrumentEditor {
/// Validate inputs and enable/disable saving. /// Validate inputs and enable/disable saving.
fn validate(&self) { fn validate(&self) {
self.editor.set_may_save(!self.name.get_text().is_empty()); self.editor.set_may_save(!self.name.text().is_empty());
} }
/// Save the instrument. /// Save the instrument.
fn save(&self) -> Result<Instrument> { fn save(&self) -> Result<Instrument> {
let name = self.name.get_text(); let name = self.name.text();
let instrument = Instrument::new(self.id.clone(), name); let instrument = Instrument::new(self.id.clone(), name.to_string());
self.handle self.handle
.backend .backend

View file

@ -1,5 +1,5 @@
use crate::navigator::{NavigationHandle, Screen}; use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::{Editor, EntryRow, Section, Widget}; use crate::widgets::{Editor, Section, Widget};
use anyhow::Result; use anyhow::Result;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
@ -15,8 +15,8 @@ pub struct PersonEditor {
id: String, id: String,
editor: Editor, editor: Editor,
first_name: EntryRow, first_name: adw::EntryRow,
last_name: EntryRow, last_name: adw::EntryRow,
} }
impl Screen<Option<Person>, Person> for PersonEditor { impl Screen<Option<Person>, Person> for PersonEditor {
@ -30,11 +30,16 @@ impl Screen<Option<Person>, Person> for PersonEditor {
.css_classes(vec![String::from("boxed-list")]) .css_classes(vec![String::from("boxed-list")])
.build(); .build();
let first_name = EntryRow::new(&gettext("First name")); let first_name = adw::EntryRow::builder()
let last_name = EntryRow::new(&gettext("Last name")); .title(&gettext("First name"))
.build();
list.append(&first_name.widget); let last_name = adw::EntryRow::builder()
list.append(&last_name.widget); .title(&gettext("Last name"))
.build();
list.append(&first_name);
list.append(&last_name);
let section = Section::new(&gettext("General"), &list); let section = Section::new(&gettext("General"), &list);
editor.add_content(&section.widget); editor.add_content(&section.widget);
@ -76,11 +81,9 @@ impl Screen<Option<Person>, Person> for PersonEditor {
})); }));
this.first_name this.first_name
.entry
.connect_changed(clone!(@weak this => move |_| this.validate())); .connect_changed(clone!(@weak this => move |_| this.validate()));
this.last_name this.last_name
.entry
.connect_changed(clone!(@weak this => move |_| this.validate())); .connect_changed(clone!(@weak this => move |_| this.validate()));
this.validate(); this.validate();
@ -92,17 +95,20 @@ impl Screen<Option<Person>, Person> for PersonEditor {
impl PersonEditor { impl PersonEditor {
/// Validate inputs and enable/disable saving. /// Validate inputs and enable/disable saving.
fn validate(&self) { fn validate(&self) {
self.editor.set_may_save( self.editor
!self.first_name.get_text().is_empty() && !self.last_name.get_text().is_empty(), .set_may_save(!self.first_name.text().is_empty() && !self.last_name.text().is_empty());
);
} }
/// Save the person. /// Save the person.
fn save(self: &Rc<Self>) -> Result<Person> { fn save(self: &Rc<Self>) -> Result<Person> {
let first_name = self.first_name.get_text(); let first_name = self.first_name.text();
let last_name = self.last_name.get_text(); let last_name = self.last_name.text();
let person = Person::new(self.id.clone(), first_name, last_name); let person = Person::new(
self.id.clone(),
first_name.to_string(),
last_name.to_string(),
);
self.handle.backend.db().update_person(person.clone())?; self.handle.backend.db().update_person(person.clone())?;
self.handle.backend.library_changed(); self.handle.backend.library_changed();

View file

@ -19,7 +19,7 @@ pub struct RecordingEditor {
save_button: gtk::Button, save_button: gtk::Button,
info_bar: gtk::InfoBar, info_bar: gtk::InfoBar,
work_row: adw::ActionRow, work_row: adw::ActionRow,
comment_entry: gtk::Entry, comment_row: adw::EntryRow,
performance_list: Rc<List>, performance_list: Rc<List>,
id: String, id: String,
work: RefCell<Option<Work>>, work: RefCell<Option<Work>>,
@ -39,7 +39,7 @@ impl Screen<Option<Recording>, Recording> for RecordingEditor {
get_widget!(builder, gtk::InfoBar, info_bar); get_widget!(builder, gtk::InfoBar, info_bar);
get_widget!(builder, adw::ActionRow, work_row); get_widget!(builder, adw::ActionRow, work_row);
get_widget!(builder, gtk::Button, work_button); get_widget!(builder, gtk::Button, work_button);
get_widget!(builder, gtk::Entry, comment_entry); get_widget!(builder, adw::EntryRow, comment_row);
get_widget!(builder, gtk::Frame, performance_frame); get_widget!(builder, gtk::Frame, performance_frame);
get_widget!(builder, gtk::Button, add_performer_button); get_widget!(builder, gtk::Button, add_performer_button);
@ -48,7 +48,7 @@ impl Screen<Option<Recording>, Recording> for RecordingEditor {
let (id, work, performances) = match recording { let (id, work, performances) = match recording {
Some(recording) => { Some(recording) => {
comment_entry.set_text(&recording.comment); comment_row.set_text(&recording.comment);
(recording.id, Some(recording.work), recording.performances) (recording.id, Some(recording.work), recording.performances)
} }
None => (generate_id(), None, Vec::new()), None => (generate_id(), None, Vec::new()),
@ -60,7 +60,7 @@ impl Screen<Option<Recording>, Recording> for RecordingEditor {
save_button, save_button,
info_bar, info_bar,
work_row, work_row,
comment_entry, comment_row,
performance_list, performance_list,
id, id,
work: RefCell::new(work), work: RefCell::new(work),
@ -184,7 +184,7 @@ impl RecordingEditor {
.borrow() .borrow()
.clone() .clone()
.expect("Tried to create recording without work!"), .expect("Tried to create recording without work!"),
self.comment_entry.text().to_string(), self.comment_row.text().to_string(),
self.performances.borrow().clone(), self.performances.borrow().clone(),
); );

View file

@ -17,7 +17,7 @@ pub struct WorkEditor {
handle: NavigationHandle<Work>, handle: NavigationHandle<Work>,
widget: gtk::Stack, widget: gtk::Stack,
save_button: gtk::Button, save_button: gtk::Button,
title_entry: gtk::Entry, title_row: adw::EntryRow,
info_bar: gtk::InfoBar, info_bar: gtk::InfoBar,
composer_row: adw::ActionRow, composer_row: adw::ActionRow,
instrument_list: Rc<List>, instrument_list: Rc<List>,
@ -39,7 +39,7 @@ impl Screen<Option<Work>, Work> for WorkEditor {
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, save_button); get_widget!(builder, gtk::Button, save_button);
get_widget!(builder, gtk::InfoBar, info_bar); get_widget!(builder, gtk::InfoBar, info_bar);
get_widget!(builder, gtk::Entry, title_entry); get_widget!(builder, adw::EntryRow, title_row);
get_widget!(builder, gtk::Button, composer_button); get_widget!(builder, gtk::Button, composer_button);
get_widget!(builder, adw::ActionRow, composer_row); get_widget!(builder, adw::ActionRow, composer_row);
get_widget!(builder, gtk::Frame, instrument_frame); get_widget!(builder, gtk::Frame, instrument_frame);
@ -56,7 +56,7 @@ impl Screen<Option<Work>, Work> for WorkEditor {
let (id, composer, instruments, structure) = match work { let (id, composer, instruments, structure) = match work {
Some(work) => { Some(work) => {
title_entry.set_text(&work.title); title_row.set_text(&work.title);
(work.id, Some(work.composer), work.instruments, work.parts) (work.id, Some(work.composer), work.instruments, work.parts)
} }
None => (generate_id(), None, Vec::new(), Vec::new()), None => (generate_id(), None, Vec::new(), Vec::new()),
@ -68,7 +68,7 @@ impl Screen<Option<Work>, Work> for WorkEditor {
save_button, save_button,
id, id,
info_bar, info_bar,
title_entry, title_row,
composer_row, composer_row,
instrument_list, instrument_list,
part_list, part_list,
@ -105,7 +105,7 @@ impl Screen<Option<Work>, Work> for WorkEditor {
}); });
})); }));
this.title_entry this.title_row
.connect_changed(clone!(@weak this => move |_| this.validate())); .connect_changed(clone!(@weak this => move |_| this.validate()));
this.instrument_list.set_make_widget_cb( this.instrument_list.set_make_widget_cb(
@ -245,14 +245,14 @@ impl WorkEditor {
/// Validate inputs and enable/disable saving. /// Validate inputs and enable/disable saving.
fn validate(&self) { fn validate(&self) {
self.save_button self.save_button
.set_sensitive(!self.title_entry.text().is_empty() && self.composer.borrow().is_some()); .set_sensitive(!self.title_row.text().is_empty() && self.composer.borrow().is_some());
} }
/// Save the work. /// Save the work.
fn save(self: &Rc<Self>) -> Result<Work> { fn save(self: &Rc<Self>) -> Result<Work> {
let work = Work::new( let work = Work::new(
self.id.clone(), self.id.clone(),
self.title_entry.text().to_string(), self.title_row.text().to_string(),
self.composer self.composer
.borrow() .borrow()
.clone() .clone()

View file

@ -11,7 +11,7 @@ pub struct WorkPartEditor {
handle: NavigationHandle<WorkPart>, handle: NavigationHandle<WorkPart>,
widget: gtk::Box, widget: gtk::Box,
save_button: gtk::Button, save_button: gtk::Button,
title_entry: gtk::Entry, title_row: adw::EntryRow,
} }
impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor { impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor {
@ -24,17 +24,17 @@ impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor {
get_widget!(builder, gtk::Box, widget); get_widget!(builder, gtk::Box, widget);
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, save_button); get_widget!(builder, gtk::Button, save_button);
get_widget!(builder, gtk::Entry, title_entry); get_widget!(builder, adw::EntryRow, title_row);
if let Some(section) = section { if let Some(section) = section {
title_entry.set_text(&section.title); title_row.set_text(&section.title);
} }
let this = Rc::new(Self { let this = Rc::new(Self {
handle, handle,
widget, widget,
save_button, save_button,
title_entry, title_row,
}); });
// Connect signals and callbacks // Connect signals and callbacks
@ -46,13 +46,13 @@ impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor {
this.save_button this.save_button
.connect_clicked(clone!(@weak this => move |_| { .connect_clicked(clone!(@weak this => move |_| {
let section = WorkPart { let section = WorkPart {
title: this.title_entry.text().to_string(), title: this.title_row.text().to_string(),
}; };
this.handle.pop(Some(section)); this.handle.pop(Some(section));
})); }));
this.title_entry this.title_row
.connect_changed(clone!(@weak this => move |_| this.validate())); .connect_changed(clone!(@weak this => move |_| this.validate()));
this.validate(); this.validate();
@ -65,7 +65,7 @@ impl WorkPartEditor {
/// Validate inputs and enable/disable saving. /// Validate inputs and enable/disable saving.
fn validate(&self) { fn validate(&self) {
self.save_button self.save_button
.set_sensitive(!self.title_entry.text().is_empty()); .set_sensitive(!self.title_row.text().is_empty());
} }
} }

View file

@ -18,7 +18,7 @@ pub struct MediumEditor {
session: Arc<ImportSession>, session: Arc<ImportSession>,
widget: gtk::Stack, widget: gtk::Stack,
done_button: gtk::Button, done_button: gtk::Button,
name_entry: gtk::Entry, name_row: adw::EntryRow,
status_page: adw::StatusPage, status_page: adw::StatusPage,
track_set_list: Rc<List>, track_set_list: Rc<List>,
track_sets: RefCell<Vec<TrackSetData>>, track_sets: RefCell<Vec<TrackSetData>>,
@ -37,7 +37,7 @@ impl Screen<(Arc<ImportSession>, Option<Medium>), Medium> for MediumEditor {
get_widget!(builder, gtk::Stack, widget); get_widget!(builder, gtk::Stack, widget);
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, done_button); get_widget!(builder, gtk::Button, done_button);
get_widget!(builder, gtk::Entry, name_entry); get_widget!(builder, adw::EntryRow, name_row);
get_widget!(builder, gtk::Button, add_button); get_widget!(builder, gtk::Button, add_button);
get_widget!(builder, gtk::Frame, frame); get_widget!(builder, gtk::Frame, frame);
get_widget!(builder, adw::StatusPage, status_page); get_widget!(builder, adw::StatusPage, status_page);
@ -52,7 +52,7 @@ impl Screen<(Arc<ImportSession>, Option<Medium>), Medium> for MediumEditor {
session, session,
widget, widget,
done_button, done_button,
name_entry, name_row,
status_page, status_page,
track_set_list: list, track_set_list: list,
track_sets: RefCell::new(Vec::new()), track_sets: RefCell::new(Vec::new()),
@ -78,7 +78,7 @@ impl Screen<(Arc<ImportSession>, Option<Medium>), Medium> for MediumEditor {
}); });
})); }));
this.name_entry this.name_row
.connect_changed(clone!(@weak this => move |_| this.validate())); .connect_changed(clone!(@weak this => move |_| this.validate()));
add_button.connect_clicked(clone!(@weak this => move |_| { add_button.connect_clicked(clone!(@weak this => move |_| {
@ -137,7 +137,7 @@ impl Screen<(Arc<ImportSession>, Option<Medium>), Medium> for MediumEditor {
// Initialize, if necessary. // Initialize, if necessary.
if let Some(medium) = medium { if let Some(medium) = medium {
this.name_entry.set_text(&medium.name); this.name_row.set_text(&medium.name);
let mut track_sets: Vec<TrackSetData> = Vec::new(); let mut track_sets: Vec<TrackSetData> = Vec::new();
@ -175,7 +175,7 @@ impl MediumEditor {
/// Validate inputs and enable/disable saving. /// Validate inputs and enable/disable saving.
fn validate(&self) { fn validate(&self) {
self.done_button.set_sensitive( self.done_button.set_sensitive(
!self.name_entry.text().is_empty() && !self.track_sets.borrow().is_empty(), !self.name_row.text().is_empty() && !self.track_sets.borrow().is_empty(),
); );
} }
@ -200,7 +200,7 @@ impl MediumEditor {
let medium = Medium::new( let medium = Medium::new(
generate_id(), generate_id(),
self.name_entry.text().to_string(), self.name_row.text().to_string(),
Some(self.session.source_id().to_owned()), Some(self.session.source_id().to_owned()),
tracks, tracks,
); );

View file

@ -1,41 +0,0 @@
use adw::{prelude::*, builders::ActionRowBuilder};
use gtk::builders::EntryBuilder;
/// A list box row with an entry.
pub struct EntryRow {
/// The actual GTK widget.
pub widget: adw::ActionRow,
/// The managed entry.
pub entry: gtk::Entry,
}
impl EntryRow {
/// Create a new entry row.
pub fn new(title: &str) -> Self {
let entry = EntryBuilder::new()
.hexpand(true)
.valign(gtk::Align::Center)
.build();
let widget = ActionRowBuilder::new()
.focusable(false)
.activatable_widget(&entry)
.title(title)
.build();
widget.add_suffix(&entry);
Self { widget, entry }
}
/// Set the text of the entry.
pub fn set_text(&self, text: &str) {
self.entry.set_text(text);
}
/// Get the text that was entered by the user.
pub fn get_text(&self) -> String {
self.entry.text().to_string()
}
}

View file

@ -6,9 +6,6 @@ pub use button_row::*;
pub mod editor; pub mod editor;
pub use editor::*; pub use editor::*;
pub mod entry_row;
pub use entry_row::*;
pub mod list; pub mod list;
pub use list::*; pub use list::*;