From b5c42e3ac307958117115a605b46c4038bc552b9 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Fri, 9 Feb 2024 08:17:10 -0500 Subject: [PATCH] Add the activity type selector to the time-distance widget --- .../app/src/components/time_distance.rs | 37 +++++++++++++++++-- fitnesstrax/core/src/lib.rs | 4 +- fitnesstrax/core/src/types.rs | 24 ++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/fitnesstrax/app/src/components/time_distance.rs b/fitnesstrax/app/src/components/time_distance.rs index e42698f..b9698f3 100644 --- a/fitnesstrax/app/src/components/time_distance.rs +++ b/fitnesstrax/app/src/components/time_distance.rs @@ -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 . */ -// use crate::components::{EditView, ParseError, TextEntry}; -// use chrono::{Local, NaiveDate}; -// use dimensioned::si; use crate::{ components::{distance_field, duration_field, time_field}, types::{DistanceFormatter, DurationFormatter, FormatOption, TimeFormatter}, }; use dimensioned::si; -use ft_core::{TimeDistance, TimeDistanceActivity}; +use ft_core::{TimeDistance, TimeDistanceActivity, TIME_DISTANCE_ACTIVITIES}; use glib::Object; use gtk::{prelude::*, subclass::prelude::*}; use std::{cell::RefCell, rc::Rc}; @@ -182,6 +179,7 @@ impl TimeDistanceEdit { ) .widget(), ); + details_row.append(&s.activity_menu(workout.activity)); details_row.append( &distance_field(workout.distance.map(DistanceFormatter::from), { 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) { let mut workout = self.imp().workout.borrow_mut(); workout.distance = distance.map(|d| *d); @@ -229,4 +233,29 @@ impl TimeDistanceEdit { workout.duration = duration.map(|d| *d); (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::>(); + + let options = options.iter().map(|o| o.as_ref()).collect::>(); + + 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 + } } diff --git a/fitnesstrax/core/src/lib.rs b/fitnesstrax/core/src/lib.rs index 89895ad..f579628 100644 --- a/fitnesstrax/core/src/lib.rs +++ b/fitnesstrax/core/src/lib.rs @@ -1,4 +1,6 @@ mod legacy; mod types; -pub use types::{Steps, TimeDistance, TimeDistanceActivity, TraxRecord, Weight}; +pub use types::{ + Steps, TimeDistance, TimeDistanceActivity, TraxRecord, Weight, TIME_DISTANCE_ACTIVITIES, +}; diff --git a/fitnesstrax/core/src/types.rs b/fitnesstrax/core/src/types.rs index a48da32..5602a8e 100644 --- a/fitnesstrax/core/src/types.rs +++ b/fitnesstrax/core/src/types.rs @@ -1,3 +1,19 @@ +/* +Copyright 2023-2024, Savanni D'Gerinel + +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 . +*/ + use chrono::{DateTime, FixedOffset, NaiveDate}; use dimensioned::si; use emseries::{Recordable, Timestamp}; @@ -42,6 +58,14 @@ pub enum TimeDistanceActivity { 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 /// 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