Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactorings #18

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cedd0a0
added developer_key.* to .gitignore
thomas-gruen Apr 5, 2020
bd35f96
added new file Pomodoro.mc
thomas-gruen Apr 5, 2020
b14574f
moved Pomodoro code from GarmodoroApp.mc to Pomodoro.mc
thomas-gruen Apr 5, 2020
07abde2
moved code from StopMenuDelgate.mc to Pomodoro.mc
thomas-gruen Apr 5, 2020
a4f72fb
moved code from GarmodoroView.mc to Pomodoro.mc
thomas-gruen Apr 5, 2020
2a03501
moved globals from GarmodoroDelegate.mc to Pomodoro.mc
thomas-gruen Apr 5, 2020
07c5422
moved shouldTick() to globals and
thomas-gruen Apr 5, 2020
2b322e3
moved code from GarmodoroDelegate.mc to Pomodoro.mc
thomas-gruen Apr 6, 2020
32ebbed
cleaned up GarmodoroDelegate
thomas-gruen Apr 6, 2020
8994b50
moved globals into module Pomodoro
thomas-gruen Apr 6, 2020
0c1b3a2
removed refactoring leftover isLongBreak2()
thomas-gruen Apr 6, 2020
fb029e8
refactoring: better names and order of functions
thomas-gruen Apr 6, 2020
f3bae4b
merge minute countdown routines for pomodoro and break states
thomas-gruen Apr 6, 2020
52be38a
cleaned up GarmodoroView
thomas-gruen Apr 7, 2020
bf26dab
renamed variables and restructured GarmodoroView
thomas-gruen Apr 7, 2020
c868416
bugfix: device context dc needed in calculateDrawingPositions()
thomas-gruen Apr 7, 2020
174d4a4
renamed variables and reordered code in Pomodoro.mc
thomas-gruen Apr 7, 2020
f55368e
changed pomodoro state handling
thomas-gruen Apr 7, 2020
c8bd31b
created central function for state transitions
thomas-gruen Apr 7, 2020
f5c05a2
used transitionToState() and removed intermediaries
thomas-gruen Apr 7, 2020
2703249
finished refactoring: comments and code ordering
thomas-gruen Apr 11, 2020
90a7bbb
handling of properties.mk
thomas-gruen Apr 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
.settings

*.swp
developer_key.*
properties.mk
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Pomodoro for Garmin devices using Connect IQ
## Development

To run the project, you can either import the project into Eclipse the usual way. Or use the `Makefile`:
* Copy `properties.mk.example` to `properties.mk`
* Edit `properties.mk` file and make sure the paths there are valid on your computer. Change the `DEVICE` variable if you want/need.
* Run `make run` to build the project and run the Connect IQ simulator on the chosen `DEVICE`.

Expand Down
File renamed without changes.
8 changes: 3 additions & 5 deletions source/GarmodoroApp.mc
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
using Toybox.Application as App;
using Toybox.Timer as Timer;
using Pomodoro;

class GarmodoroApp extends App.AppBase {

function initialize() {
AppBase.initialize();
Pomodoro.initialize();
}

function onStart(state) {
timer = new Timer.Timer();
tickTimer = new Timer.Timer();
}

function onStop(state) {
tickTimer.stop();
timer.stop();
Pomodoro.stopTimers();
}

function getInitialView() {
Expand Down
100 changes: 14 additions & 86 deletions source/GarmodoroDelegate.mc
Original file line number Diff line number Diff line change
@@ -1,83 +1,24 @@
using Toybox.Application as App;
using Toybox.Attention as Attention;
using Toybox.WatchUi as Ui;

var timer;
var tickTimer;
var minutes = 0;
var pomodoroNumber = 1;
var isPomodoroTimerStarted = false;
var isBreakTimerStarted = false;

function ping( dutyCycle, length ) {
if ( Attention has :vibrate ) {
Attention.vibrate( [ new Attention.VibeProfile( dutyCycle, length ) ] );
}
}

function play( tone ) {
if ( Attention has :playTone && ! App.getApp().getProperty( "muteSounds" ) ) {
Attention.playTone( tone );
}
}

function isLongBreak() {
return ( pomodoroNumber % App.getApp().getProperty( "numberOfPomodorosBeforeLongBreak" ) ) == 0;
}

function resetMinutes() {
minutes = App.getApp().getProperty( "pomodoroLength" );
}
using Pomodoro;

class GarmodoroDelegate extends Ui.BehaviorDelegate {
function initialize() {
Ui.BehaviorDelegate.initialize();
}

function pomodoroCallback() {
minutes -= 1;

if ( minutes == 0 ) {
play( 10 ); // Attention.TONE_LAP
ping( 100, 1500 );
tickTimer.stop();
timer.stop();
isPomodoroTimerStarted = false;
minutes = App.getApp().getProperty( isLongBreak() ? "longBreakLength" : "shortBreakLength" );

timer.start( method( :breakCallback ), 60 * 1000, true );
isBreakTimerStarted = true;
}

Ui.requestUpdate();
function onBack() {
Ui.popView( Ui.SLIDE_RIGHT );
return true;
}

function breakCallback() {
minutes -= 1;

if ( minutes == 0 ) {
play( 7 ); // Attention.TONE_INTERVAL_ALERT
ping( 100, 1500 );
timer.stop();

isBreakTimerStarted = false;
pomodoroNumber += 1;
resetMinutes();
function onSelect() {
if ( Pomodoro.isInReadyState() ) {
Pomodoro.transitionToState( Pomodoro.stateRunning );
Ui.requestUpdate();
} else { // pomodoro is in running or break state
onMenu();
}

Ui.requestUpdate();
}

function shouldTick() {
return App.getApp().getProperty( "tickStrength" ) > 0;
}

function tickCallback() {
ping( App.getApp().getProperty( "tickStrength" ), App.getApp().getProperty( "tickDuration" ) );
}

function onBack() {
Ui.popView( Ui.SLIDE_RIGHT );
return true;
}

Expand All @@ -89,23 +30,10 @@ class GarmodoroDelegate extends Ui.BehaviorDelegate {
return true;
}

function onSelect() {
if ( isBreakTimerStarted || isPomodoroTimerStarted ) {
Ui.pushView( new Rez.Menus.StopMenu(), new StopMenuDelegate(), Ui.SLIDE_UP );
return true;
}

play( 1 ); // Attention.TONE_START
ping( 75, 1500 );
resetMinutes();
timer.start( method( :pomodoroCallback ), 60 * 1000, true );
if ( me.shouldTick() ) {
tickTimer.start( method( :tickCallback ), 1000, true );
}
isPomodoroTimerStarted = true;

Ui.requestUpdate();

// also called from onSelect() when Pomodoro running or in break
function onMenu() {
Ui.pushView( new Rez.Menus.StopMenu(),
new StopMenuDelegate(), Ui.SLIDE_UP );
return true;
}
}
144 changes: 97 additions & 47 deletions source/GarmodoroView.mc
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ using Toybox.System as System;
using Toybox.Time;
using Toybox.Time.Gregorian;
using Toybox.Lang;
using Pomodoro;

class GarmodoroView extends Ui.View {
hidden var pomodoroSubtitle;
hidden var shortBreakLabel;
hidden var longBreakLabel;
hidden var readyLabel;

// all elements are centered in X direction
hidden var centerX;
hidden var centerY;

// all offsets are in Y direction
hidden var pomodoroOffset;
hidden var captionOffset;
hidden var readyLabelOffset;
Expand All @@ -24,80 +26,128 @@ class GarmodoroView extends Ui.View {
View.initialize();
}

function onLayout( dc ) {
hidden function loadResources() {
pomodoroSubtitle = Ui.loadResource( Rez.Strings.PomodoroSubtitle );
shortBreakLabel = Ui.loadResource( Rez.Strings.ShortBreakLabel );
longBreakLabel = Ui.loadResource( Rez.Strings.LongBreakLabel );
readyLabel = Ui.loadResource( Rez.Strings.ReadyLabel );
}

var height = dc.getHeight();
centerX = dc.getWidth() / 2;
centerY = height / 2;
var mediumOffset = Gfx.getFontHeight( Gfx.FONT_MEDIUM );
var mediumOffsetHalf = mediumOffset / 2;
var mildOffset = Gfx.getFontHeight( Gfx.FONT_NUMBER_MILD );
var screenShape = System.getDeviceSettings().screenShape;
hidden function calculateDrawingPositions( dc ) {
me.centerX = dc.getWidth() / 2;

me.timeOffset = height - mildOffset;
// offsets relative to the top and bottom of the watch face
me.pomodoroOffset = 5;
if ( System.SCREEN_SHAPE_RECTANGLE != screenShape ) {
me.pomodoroOffset += mediumOffset;

var heightOfFontMild = Gfx.getFontHeight( Gfx.FONT_NUMBER_MILD );
me.timeOffset = dc.getHeight() - heightOfFontMild;

// offsets relative to the center
var centerY = dc.getHeight() / 2;
var heightOfFontLarge = Gfx.getFontHeight( Gfx.FONT_LARGE );
me.readyLabelOffset = centerY - heightOfFontLarge /2;

var heightOfFontHot = Gfx.getFontHeight( Gfx.FONT_NUMBER_THAI_HOT );
me.minutesOffset = centerY - heightOfFontHot / 2;

var heightOfFontTiny = Gfx.getFontHeight( Gfx.FONT_TINY );
me.captionOffset = me.timeOffset - heightOfFontTiny;

me.adjustOffsetsForRoundScreen();
}

// 'special' case: non rectangular screens
hidden function adjustOffsetsForRoundScreen() {
var screenShape = System.getDeviceSettings().screenShape;
if ( screenShape != System.SCREEN_SHAPE_RECTANGLE ) {
var heightOfFontMedium = Gfx.getFontHeight( Gfx.FONT_MEDIUM );
me.pomodoroOffset += heightOfFontMedium;

me.timeOffset -= 5;
}
}

me.readyLabelOffset = me.centerY - ( Gfx.getFontHeight( Gfx.FONT_LARGE ) / 2 );
me.minutesOffset = me.centerY - ( Gfx.getFontHeight( Gfx.FONT_NUMBER_THAI_HOT ) / 2 );
me.captionOffset = me.timeOffset - Gfx.getFontHeight( Gfx.FONT_TINY );
function onLayout( dc ) {
me.loadResources();
me.calculateDrawingPositions( dc );
}

function onShow() {
}

function onHide() {
}

function onUpdate( dc ) {
dc.setColor( Gfx.COLOR_TRANSPARENT, Gfx.COLOR_BLACK );
dc.clear();
if ( isBreakTimerStarted ) {
dc.setColor( Gfx.COLOR_GREEN, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.pomodoroOffset, Gfx.FONT_MEDIUM, isLongBreak() ? me.longBreakLabel : me.shortBreakLabel, Gfx.TEXT_JUSTIFY_CENTER );
me.drawMinutes( dc );

dc.setColor( Gfx.COLOR_DK_GREEN, Gfx.COLOR_TRANSPARENT );
me.drawCaption( dc );
} else if ( isPomodoroTimerStarted ) {
dc.setColor( Gfx.COLOR_YELLOW, Gfx.COLOR_TRANSPARENT );
me.drawMinutes( dc );
dc.setColor( Gfx.COLOR_ORANGE, Gfx.COLOR_TRANSPARENT );
me.drawCaption( dc );
} else {
dc.setColor( Gfx.COLOR_ORANGE, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.readyLabelOffset, Gfx.FONT_LARGE, me.readyLabel, Gfx.TEXT_JUSTIFY_CENTER );
me.drawBackground( dc, Gfx.COLOR_BLACK );

if ( Pomodoro.isInBreakState() ) {
me.drawBreakLabel( dc, Gfx.COLOR_GREEN );
me.drawMinutes( dc, Gfx.COLOR_GREEN );
me.drawCaption( dc, Gfx.COLOR_DK_GREEN );
} else if ( Pomodoro.isInRunningState() ) {
me.drawPomodoroLabel( dc, Gfx.COLOR_LT_GRAY );
me.drawMinutes( dc, Gfx.COLOR_YELLOW );
me.drawCaption( dc, Gfx.COLOR_ORANGE );
} else { // Pomodoro is in ready state
me.drawPomodoroLabel( dc, Gfx.COLOR_LT_GRAY );
me.drawReadyLabel( dc, Gfx.COLOR_ORANGE );
}

if ( ! isBreakTimerStarted ) {
dc.setColor( Gfx.COLOR_LT_GRAY, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.pomodoroOffset, Gfx.FONT_MEDIUM, "Pomodoro #" + pomodoroNumber, Gfx.TEXT_JUSTIFY_CENTER );
}
me.drawTime( dc, Gfx.COLOR_LT_GRAY );
}

hidden function drawBackground( dc, backgroundColor ) {
dc.setColor( Gfx.COLOR_TRANSPARENT, backgroundColor );
dc.clear();
}

dc.setColor( Gfx.COLOR_LT_GRAY, Gfx.COLOR_TRANSPARENT );
dc.drawText( self.centerX, self.timeOffset, Gfx.FONT_NUMBER_MILD, self.getTime(), Gfx.TEXT_JUSTIFY_CENTER );
hidden function drawPomodoroLabel( dc, foregroundColor ) {
var pomodoroLabel = "Pomodoro #" + Pomodoro.getIteration();
dc.setColor( foregroundColor, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.pomodoroOffset, Gfx.FONT_MEDIUM,
pomodoroLabel, Gfx.TEXT_JUSTIFY_CENTER );
}

hidden function drawMinutes( dc ) {
dc.drawText( me.centerX, me.minutesOffset, Gfx.FONT_NUMBER_THAI_HOT, minutes.format( "%02d" ), Gfx.TEXT_JUSTIFY_CENTER );
hidden function drawBreakLabel( dc, foregroundColor ) {
var labelForBreak = Pomodoro.isLongBreak() ?
me.longBreakLabel :
me.shortBreakLabel;
dc.setColor( foregroundColor, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.pomodoroOffset, Gfx.FONT_MEDIUM,
labelForBreak, Gfx.TEXT_JUSTIFY_CENTER );
}

hidden function drawCaption( dc ) {
dc.drawText( me.centerX, me.captionOffset, Gfx.FONT_TINY, me.pomodoroSubtitle, Gfx.TEXT_JUSTIFY_CENTER );
hidden function drawReadyLabel( dc, foregroundColor ) {
dc.setColor( foregroundColor, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.readyLabelOffset, Gfx.FONT_LARGE,
me.readyLabel, Gfx.TEXT_JUSTIFY_CENTER );
}

function onHide() {
hidden function drawMinutes( dc, foregroundColor ) {
var minutesAsText = Pomodoro.getMinutesLeft();
dc.setColor( foregroundColor, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.minutesOffset, Gfx.FONT_NUMBER_THAI_HOT,
minutesAsText, Gfx.TEXT_JUSTIFY_CENTER );
}

hidden function drawCaption( dc, foregroundColor ) {
dc.setColor( foregroundColor, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.captionOffset, Gfx.FONT_TINY,
me.pomodoroSubtitle, Gfx.TEXT_JUSTIFY_CENTER );
}

hidden function drawTime( dc, foregroundColor ) {
dc.setColor( foregroundColor, Gfx.COLOR_TRANSPARENT );
dc.drawText( me.centerX, me.timeOffset, Gfx.FONT_NUMBER_MILD,
me.getTime(), Gfx.TEXT_JUSTIFY_CENTER );
}

function getTime() {
hidden function getTime() {
var today = Gregorian.info( Time.now(), Time.FORMAT_SHORT );
return Lang.format( "$1$:$2$", [
today.hour.format( "%02d" ),
today.min.format( "%02d" ),
] );
today.hour.format( "%02d" ),
today.min.format( "%02d" ),
] );
}
}
Loading