Add the ability to edit the time of a workout and the associated activity. #183

Merged
savanni merged 5 commits from fitnesstrax/edit-time-and-activity into main 2024-02-09 13:31:40 +00:00
3 changed files with 60 additions and 5 deletions
Showing only changes of commit b5c42e3ac3 - Show all commits

View File

@ -14,15 +14,12 @@ General Public License for more details.
You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see <https://www.gnu.org/licenses/>. You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see <https://www.gnu.org/licenses/>.
*/ */
// use crate::components::{EditView, ParseError, TextEntry};
// use chrono::{Local, NaiveDate};
// use dimensioned::si;
use crate::{ use crate::{
components::{distance_field, duration_field, time_field}, components::{distance_field, duration_field, time_field},
types::{DistanceFormatter, DurationFormatter, FormatOption, TimeFormatter}, types::{DistanceFormatter, DurationFormatter, FormatOption, TimeFormatter},
}; };
use dimensioned::si; use dimensioned::si;
use ft_core::{TimeDistance, TimeDistanceActivity}; use ft_core::{TimeDistance, TimeDistanceActivity, TIME_DISTANCE_ACTIVITIES};
use glib::Object; use glib::Object;
use gtk::{prelude::*, subclass::prelude::*}; use gtk::{prelude::*, subclass::prelude::*};
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
@ -182,6 +179,7 @@ impl TimeDistanceEdit {
) )
.widget(), .widget(),
); );
details_row.append(&s.activity_menu(workout.activity));
details_row.append( details_row.append(
&distance_field(workout.distance.map(DistanceFormatter::from), { &distance_field(workout.distance.map(DistanceFormatter::from), {
let s = s.clone(); let s = s.clone();
@ -218,6 +216,12 @@ impl TimeDistanceEdit {
} }
} }
fn update_workout_type(&self, type_: TimeDistanceActivity) {
let mut workout = self.imp().workout.borrow_mut();
workout.activity = type_;
(self.imp().on_update.borrow())(workout.clone())
}
fn update_distance(&self, distance: Option<DistanceFormatter>) { fn update_distance(&self, distance: Option<DistanceFormatter>) {
let mut workout = self.imp().workout.borrow_mut(); let mut workout = self.imp().workout.borrow_mut();
workout.distance = distance.map(|d| *d); workout.distance = distance.map(|d| *d);
@ -229,4 +233,29 @@ impl TimeDistanceEdit {
workout.duration = duration.map(|d| *d); workout.duration = duration.map(|d| *d);
(self.imp().on_update.borrow())(workout.clone()); (self.imp().on_update.borrow())(workout.clone());
} }
fn activity_menu(&self, selected: TimeDistanceActivity) -> gtk::DropDown {
let options = TIME_DISTANCE_ACTIVITIES
.iter()
.map(|item| format!("{:?}", item))
.collect::<Vec<String>>();
let options = options.iter().map(|o| o.as_ref()).collect::<Vec<&str>>();
let selected_idx = TIME_DISTANCE_ACTIVITIES
.iter()
.position(|&v| v == selected)
.unwrap_or(0);
let menu = gtk::DropDown::from_strings(&options);
menu.set_selected(selected_idx as u32);
menu.connect_selected_item_notify({
let s = self.clone();
move |menu| {
let new_item = TIME_DISTANCE_ACTIVITIES[menu.selected() as usize];
s.update_workout_type(new_item);
}
});
menu
}
} }

View File

@ -1,4 +1,6 @@
mod legacy; mod legacy;
mod types; mod types;
pub use types::{Steps, TimeDistance, TimeDistanceActivity, TraxRecord, Weight}; pub use types::{
Steps, TimeDistance, TimeDistanceActivity, TraxRecord, Weight, TIME_DISTANCE_ACTIVITIES,
};

View File

@ -1,3 +1,19 @@
/*
Copyright 2023-2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
This file is part of FitnessTrax.
FitnessTrax is free software: you can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
FitnessTrax is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see <https://www.gnu.org/licenses/>.
*/
use chrono::{DateTime, FixedOffset, NaiveDate}; use chrono::{DateTime, FixedOffset, NaiveDate};
use dimensioned::si; use dimensioned::si;
use emseries::{Recordable, Timestamp}; use emseries::{Recordable, Timestamp};
@ -42,6 +58,14 @@ pub enum TimeDistanceActivity {
Walking, Walking,
} }
pub const TIME_DISTANCE_ACTIVITIES: [TimeDistanceActivity; 5] = [
TimeDistanceActivity::BikeRide,
TimeDistanceActivity::Rowing,
TimeDistanceActivity::Running,
TimeDistanceActivity::Swimming,
TimeDistanceActivity::Walking,
];
/// TimeDistance represents workouts characterized by a duration and a distance travelled. These /// TimeDistance represents workouts characterized by a duration and a distance travelled. These
/// sorts of workouts can occur many times a day, depending on how one records things. I might /// sorts of workouts can occur many times a day, depending on how one records things. I might
/// record a single 30-km workout if I go on a long-distanec ride. Or I might record multiple 5km /// record a single 30-km workout if I go on a long-distanec ride. Or I might record multiple 5km