Skip to content

Commit

Permalink
Merge pull request #3541 from thyttan/pomoplus
Browse files Browse the repository at this point in the history
pomoplus: increase size of fonts and buttons
  • Loading branch information
thyttan committed Sep 7, 2024
2 parents c43f2c9 + d7f7d2b commit 4d8c46b
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 24 deletions.
3 changes: 3 additions & 0 deletions apps/pomoplus/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
0.02-0.04: Bug fixes
0.05: Submitted to the app loader
0.06: Added setting to show clock after start/resume
0.07: Make fonts and buttons larger for legibility and ease of use. Hide
buttons when screen is locked. Toggle the graphical presentation when
pressing the (middle) hardware button.
42 changes: 42 additions & 0 deletions apps/pomoplus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Pomodoro Plus

> The Pomodoro Technique is a time management method developed by Francesco Cirillo in the late 1980s. It uses a kitchen timer to break work into intervals, typically 25 minutes in length, separated by short breaks. Each interval is known as a pomodoro, from the Italian word for tomato, after the tomato-shaped kitchen timer Cirillo used as a university student.
>
> The original technique has six steps:
>
> Decide on the task to be done.
> Set the Pomodoro timer (typically for 25 minutes).
> Work on the task.
> End work when the timer rings and take a short break (typically 5–10 minutes).
> Go back to Step 2 and repeat until you complete four pomodori.
> After four pomodori are done, take a long break (typically 20 to 30 minutes) instead of a short break. Once the long break is finished, return to step 2.
*Description gathered from https://en.wikipedia.org/wiki/Pomodoro_Technique*

## Usage

- Click the play button to start a pomodoro and get to work!
- Click the pause button if you're interrupted with something urgent.
- Click the cross button if you need to end your work session.
- Click the skip button if you forgot to start the pomodoro after the urgent interruption and ended up working for a long time! (Good on ya'!)
- Press the (middle) hardware button to toggle visibility of widgets and software buttons.

Configure the pomodori and break times in the settings.

## Features

Continues to run in the background if you exit the app while the pomodoro timer is running.

The buttons and widgets hide automatically when the screen is locked.

## Requests

Open an issue on the espruino/BangleApps issue tracker.

## Creator

bruceblore

## Contributors

notEvil, thyttan
98 changes: 75 additions & 23 deletions apps/pomoplus/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Bangle.POMOPLUS_ACTIVE = true; //Prevent the boot code from running. To avoid h

const storage = require("Storage");
const common = require("pomoplus-com.js");
const wu = require("widget_utils");

//Expire the state if necessary
if (
Expand All @@ -14,37 +15,45 @@ if (
common.state = common.STATE_DEFAULT;
}

const W = g.getWidth();
const H = g.getHeight();
const SCALING = W/176; // The UI was tweaked to look good on a Bangle.js 2 (176x176 px). SCALING automatically adapts so elements have the same proportions relative to the screen size on devices with other resolutions.
const BUTTON_HEIGHT = 56 * SCALING;
const BUTTON_TOP = H - BUTTON_HEIGHT;

function drawButtons() {
let w = g.getWidth();
let h = g.getHeight();
//Draw the backdrop
const BAR_TOP = h - 24;
g.setColor(0, 0, 1).setFontAlign(0, -1)
.clearRect(0, BAR_TOP, w, h)
.fillRect(0, BAR_TOP, w, h)
const ICONS_SIZE = 24;
const ICONS_ANCHOR_Y = BUTTON_TOP + BUTTON_HEIGHT / 2 - ICONS_SIZE / 2;
g.setColor(0, 0, 1)
.fillRect({x:0, y:BUTTON_TOP, x2:W-1, y2:H-1,r:15*SCALING})
.setColor(1, 1, 1);

if (!common.state.wasRunning) { //If the timer was never started, only show a play button
g.drawImage(common.BUTTON_ICONS.play, w / 2, BAR_TOP);
g.drawImage(common.BUTTON_ICONS.play, W / 2 - ICONS_SIZE / 2, ICONS_ANCHOR_Y);
} else {
g.drawLine(w / 2, BAR_TOP, w / 2, h);
g.setColor(g.theme.bg)
.fillRect(W / 2 - 2, BUTTON_TOP, W / 2 + 2, H)
.setColor(1,1,1);
if (common.state.running) {
g.drawImage(common.BUTTON_ICONS.pause, w / 4, BAR_TOP)
.drawImage(common.BUTTON_ICONS.skip, w * 3 / 4, BAR_TOP);
g.drawImage(common.BUTTON_ICONS.pause, W / 4 - ICONS_SIZE / 2, ICONS_ANCHOR_Y)
.drawImage(common.BUTTON_ICONS.skip, W * 3 / 4 - ICONS_SIZE / 2, ICONS_ANCHOR_Y);
} else {
g.drawImage(common.BUTTON_ICONS.reset, w / 4, BAR_TOP)
.drawImage(common.BUTTON_ICONS.play, w * 3 / 4, BAR_TOP);
g.drawImage(common.BUTTON_ICONS.reset, W / 4 - ICONS_SIZE / 2, ICONS_ANCHOR_Y)
.drawImage(common.BUTTON_ICONS.play, W * 3 / 4 - ICONS_SIZE / 2, ICONS_ANCHOR_Y);
}
}
}

function drawTimerAndMessage() {
let w = g.getWidth();
let h = g.getHeight();
const ANCHOR_X = W / 2;
const ANCHOR_Y = H * 3 / 8;
const TIME_SIZE = 48 * SCALING;
const LABEL_SIZE = 18 * SCALING;
g.reset()
.setFontAlign(0, 0)
.setFont("Vector", 36)
.clearRect(w / 2 - 60, h / 2 - 34, w / 2 + 60, h / 2 + 34)
.setFont("Vector", TIME_SIZE)
.clearRect(0, ANCHOR_Y - TIME_SIZE / 2, W-1, ANCHOR_Y + TIME_SIZE / 2 + 1.2 * LABEL_SIZE)

//Draw the timer
.drawString((() => {
Expand All @@ -59,29 +68,53 @@ function drawTimerAndMessage() {

if (hours >= 1) return `${parseInt(hours)}:${pad(minutes)}:${pad(seconds)}`;
else return `${parseInt(minutes)}:${pad(seconds)}`;
})(), w / 2, h / 2)
})(), ANCHOR_X, ANCHOR_Y)

//Draw the phase label
.setFont("Vector", 12)
.setFont("Vector", LABEL_SIZE)
.drawString(((currentPhase, numShortBreaks) => {
if (!common.state.wasRunning) return "Not started";
else if (currentPhase == common.PHASE_WORKING) return `Work ${numShortBreaks + 1}/${common.settings.numShortBreaks + 1}`
else if (currentPhase == common.PHASE_SHORT_BREAK) return `Short break ${numShortBreaks + 1}/${common.settings.numShortBreaks}`;
else return "Long break!";
})(common.state.phase, common.state.numShortBreaks),
w / 2, h / 2 + 18);
ANCHOR_X, ANCHOR_Y + 2*LABEL_SIZE);

//Update phase with vibation if needed
if (common.getTimeLeft() <= 0) {
common.nextPhase(true);
}
}

drawButtons();
Bangle.on("touch", (button, xy) => {
if (!Bangle.isLocked()) drawButtons();

let hideButtons = ()=>{
g.clearRect(0,BUTTON_TOP,W-1,H-1);
}

let graphicState = 0; // 0 - all is visible, 1 - widgets are hidden, 2 - widgets and buttons are hidden.
let onButtonSwitchGraphics = (n)=>{
if (process.env.HWVERSION == 2) n=2; // Translate Bangle.js 2 button to Bangle.js 1 middle button.
if (n == 2) {
if (graphicState == 0) {
wu.hide();
}
if (graphicState == 1) {
hideButtons();
}
if (graphicState == 2) {
wu.show();
drawButtons();
}
graphicState = (graphicState+1) % 3;
}
}

let onTouchSoftwareButtons = (button, xy) => {
//If we support full touch and we're not touching the keys, ignore.
//If we don't support full touch, we can't tell so just assume we are.
if (xy !== undefined && xy.y <= g.getHeight() - 24) return;
let isOutsideButtonArea = xy !== undefined && xy.y <= g.getHeight() - BUTTON_HEIGHT;
if (isOutsideButtonArea || graphicState == 2) return;

if (!common.state.wasRunning) {
//If we were never running, there is only one button: the start button
Expand Down Expand Up @@ -137,7 +170,13 @@ Bangle.on("touch", (button, xy) => {
if (common.settings.showClock) Bangle.showClock();
}
}
});
};

Bangle.setUI({
mode: "custom",
touch: onTouchSoftwareButtons,
btn: onButtonSwitchGraphics
})

let timerInterval;

Expand All @@ -156,10 +195,23 @@ if (common.state.running) {
setupTimerInterval();
}

Bangle.on('lock', (on, reason) => {
if (graphicState==2) return;
if (on) {
hideButtons();
wu.hide();
}
if (!on) {
drawButtons();
if (graphicState==0) wu.show();
}
});

//Save our state when the app is closed
E.on('kill', () => {
storage.writeJSON(common.STATE_PATH, common.state);
});

Bangle.loadWidgets();
Bangle.drawWidgets();
if (Bangle.isLocked()) wu.hide();
3 changes: 2 additions & 1 deletion apps/pomoplus/metadata.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "pomoplus",
"name": "Pomodoro Plus",
"version": "0.06",
"version": "0.07",
"description": "A configurable pomodoro timer that runs in the background.",
"icon": "icon.png",
"type": "app",
Expand All @@ -10,6 +10,7 @@
"BANGLEJS",
"BANGLEJS2"
],
"readme": "README.md",
"storage": [
{
"name": "pomoplus.app.js",
Expand Down

0 comments on commit 4d8c46b

Please sign in to comment.