Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
50 changes: 42 additions & 8 deletions appinfo.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,52 @@
{
"versionLabel": "1.0",
"uuid": "081b46ac-5530-413c-b82e-a192fb698838",
"appKeys": {},
"longName": "Tea Timer",
"versionCode": 14,
"capabilities": [
""
],
"companyName": "Ouroboros",
"longName": "Tea Timer",
"projectType": "native",
"resources": {
"media": [
{
"characterRegex": "[0-9:]",
"file": "fonts/Dosis-Watch.ttf",
"name": "FONT_DOSIS_WATCH_46",
"type": "font"
},
{
"file": "images/plus_icon_white.png",
"name": "PLUS_ICON",
"type": "png"
},
{
"file": "images/play_icon_white.png",
"name": "PLAY_ICON",
"type": "png"
},
{
"file": "images/pause_icon_white.png",
"name": "PAUSE_ICON",
"type": "png"
},
{
"file": "images/minus_icon_white.png",
"name": "MINUS_ICON",
"type": "png"
},
{
"file": "images/tea_timer_icon.png",
"menuIcon": true,
"name": "TEA_TIMER_ICON",
"type": "png"
}
]
},
"shortName": "Tea Timer",
"companyName": "",
"uuid": "081b46ac-5530-413c-b82e-a192fb698839",
"versionCode": 14,
"versionLabel": "1.0",
"watchapp": {
"watchface": false
},
"resources": {
"media": []
}
}
Binary file added resources/fonts/Dosis-Watch.ttf
Binary file not shown.
Binary file added resources/images/minus_icon_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/pause_icon_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/play_icon_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/plus_icon_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/images/tea_timer_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
86 changes: 86 additions & 0 deletions src/controller.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <pebble.h>
#include "controller.h"
#include "util.h"

#define BUTTON_CLICK_TIME_SHIFT 30
#define INITIAL_TIME 3*60

typedef struct TimerController {
TimerDisplay *display;
int timer_running;
int time_left;
TickSource tick_source;
} TimerController;

void click_config_provider(void *context);
void toggle_timer(ClickRecognizerRef recognizer, void *context);
void handle_up(ClickRecognizerRef recognizer, void *context);
void handle_down(ClickRecognizerRef recognizer, void *context);

TimerController *timer_controller_create(TimerDisplay *display, TickSource source) {
TimerController *self = calloc(1, sizeof(TimerController));
self->display = display;
self->time_left = INITIAL_TIME;
self->tick_source = source;
timer_display_set_click_config_provider(self->display, click_config_provider, self);
timer_display_update(self->display, self->time_left);
return self;
}

void timer_controller_destroy(TimerController *controller) {
timer_display_destroy(controller->display);
free(controller);
}

void timer_controller_tick(TimerController *controller) {
controller->time_left = MAX(0, controller->time_left-1);

if(controller->time_left == 0) {
timer_display_alert(controller->display);
}

if(controller->time_left < 5 && controller->time_left > 0) {
timer_display_warning(controller->display);
}

timer_display_update(controller->display, controller->time_left);
}

void click_config_provider(void *context) {
window_set_click_context(BUTTON_ID_UP, context);
window_set_click_context(BUTTON_ID_SELECT, context);
window_set_click_context(BUTTON_ID_DOWN, context);
window_single_repeating_click_subscribe(BUTTON_ID_UP, 60, handle_up);
window_single_click_subscribe(BUTTON_ID_SELECT, toggle_timer);
window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 60, handle_down);
}

void toggle_timer(ClickRecognizerRef recognizer, void *context) {
TimerController *controller = (TimerController *)context;
TOGGLE(controller->timer_running);
timer_display_cancel(controller->display);
timer_display_set_mode(controller->display, controller->timer_running);
controller->tick_source(controller->timer_running);
}

void handle_up(ClickRecognizerRef recognizer, void *context) {
TimerController *controller = (TimerController *)context;
if(!controller->timer_running) {
controller->time_left = MIN(controller->time_left
+ BUTTON_CLICK_TIME_SHIFT
- (controller->time_left % BUTTON_CLICK_TIME_SHIFT),
99*60);
}

timer_display_update(controller->display, controller->time_left);
}

void handle_down(ClickRecognizerRef recognizer, void *context) {
TimerController *controller = (TimerController *)context;
if(!controller->timer_running) {
int mod = controller->time_left % BUTTON_CLICK_TIME_SHIFT;
controller->time_left = MAX(controller->time_left - (mod > 0 ? mod : BUTTON_CLICK_TIME_SHIFT), 0);
}

timer_display_update(controller->display, controller->time_left);
}
9 changes: 9 additions & 0 deletions src/controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include "display.h"
typedef struct TimerController TimerController;
typedef void (*TickSource)(int enabled);

TimerController *timer_controller_create(TimerDisplay *display, TickSource source);
void timer_controller_destroy(TimerController *controller);
void timer_controller_tick(TimerController *controller);
131 changes: 80 additions & 51 deletions src/display.c
Original file line number Diff line number Diff line change
@@ -1,73 +1,102 @@
#include "display.h"
#include "time_handler.h"
#include "util.h"

#ifndef TOGGLE
#define TOGGLE(x) x = !x
#endif
typedef struct TimerDisplay {
Window *window;
TextLayer *time_text;
ActionBarLayer *action_bar;
InverterLayer *inverter;
GBitmap *bitmap_plus_icon;
GBitmap *bitmap_play_icon;
GBitmap *bitmap_minus_icon;
GBitmap *bitmap_pause_icon;
} TimerDisplay;

bool flash_background = true;
bool light_enabled = false;
TimerDisplay* timer_display_create() {
TimerDisplay* self = calloc(1, sizeof(TimerDisplay));

static Window *window = NULL;
static TextLayer *timer = NULL;
self->bitmap_plus_icon = gbitmap_create_with_resource(RESOURCE_ID_PLUS_ICON);
self->bitmap_play_icon = gbitmap_create_with_resource(RESOURCE_ID_PLAY_ICON);
self->bitmap_minus_icon = gbitmap_create_with_resource(RESOURCE_ID_MINUS_ICON);
self->bitmap_pause_icon = gbitmap_create_with_resource(RESOURCE_ID_PAUSE_ICON);

self->window = window_create();
window_stack_push(self->window, true);
window_set_background_color(self->window, GColorWhite);

void update_display_with_time(int time_left) {
if (!timer) { return; }

static char time_text[] = "00:00:00";
self->time_text = text_layer_create(GRect(0, 48, 144 - ACTION_BAR_WIDTH, 138));
text_layer_set_text_color(self->time_text, GColorBlack);
text_layer_set_text_alignment(self->time_text, GTextAlignmentCenter);
text_layer_set_background_color(self->time_text, GColorClear);
text_layer_set_font(self->time_text, fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DOSIS_WATCH_46)));
layer_add_child(window_get_root_layer(self->window), text_layer_get_layer(self->time_text));

self->action_bar = action_bar_layer_create();
action_bar_layer_add_to_window(self->action_bar, self->window);

self->inverter = inverter_layer_create(GRect(0, 0, 144, 168));
layer_set_hidden(inverter_layer_get_layer(self->inverter), true);
layer_add_child(window_get_root_layer(self->window), inverter_layer_get_layer(self->inverter));

timer_display_update(self, 0);
timer_display_set_mode(self, STOPPED);
return self;
}

void timer_display_destroy(TimerDisplay *display) {
window_destroy(display->window);
text_layer_destroy(display->time_text);
action_bar_layer_destroy(display->action_bar);
inverter_layer_destroy(display->inverter);
gbitmap_destroy(display->bitmap_play_icon);
gbitmap_destroy(display->bitmap_plus_icon);
gbitmap_destroy(display->bitmap_minus_icon);
gbitmap_destroy(display->bitmap_pause_icon);
free(display);
}

void timer_display_update(TimerDisplay *display, int time_left) {
static char time_text[] = "00:00";
struct tm pebble_time_left = {
.tm_sec = time_left%60,
.tm_min = time_left/60
};

strftime(time_text, sizeof(time_text), "%M:%S", &pebble_time_left);

text_layer_set_text(timer, time_text);
text_layer_set_text(display->time_text, time_text);
}

void alert() {
vibes_short_pulse();
TOGGLE(light_enabled);
// XXX Need to figure out how to do this in a way that doesn't cause the
// light to just stay on.
//light_enable(light_enabled);
void timer_display_set_click_config_provider(TimerDisplay *display, ClickConfigProvider provider, void *context) {
action_bar_layer_set_context(display->action_bar, context);
action_bar_layer_set_click_config_provider(display->action_bar, provider);
}

void warning() {
int foreground = (flash_background ? GColorBlack : GColorWhite);
int background = (flash_background ? GColorWhite : GColorBlack);
text_layer_set_text_color(timer, foreground);
window_set_background_color(window, background);
TOGGLE(flash_background);
void timer_display_set_mode(TimerDisplay *display, TimerDisplayMode mode) {
switch (mode) {
case STOPPED:
action_bar_layer_set_icon(display->action_bar, BUTTON_ID_UP, display->bitmap_plus_icon);
action_bar_layer_set_icon(display->action_bar, BUTTON_ID_SELECT, display->bitmap_play_icon);
action_bar_layer_set_icon(display->action_bar, BUTTON_ID_DOWN, display->bitmap_minus_icon);
break;
default:
action_bar_layer_set_icon(display->action_bar, BUTTON_ID_UP, NULL);
action_bar_layer_set_icon(display->action_bar, BUTTON_ID_SELECT, display->bitmap_pause_icon);
action_bar_layer_set_icon(display->action_bar, BUTTON_ID_DOWN, NULL);
break;
}
}

Window* get_window() {
return window;
void timer_display_alert(TimerDisplay *display) {
layer_set_hidden(inverter_layer_get_layer(display->inverter), true);
vibes_short_pulse();
}

void initialize_display() {
Window *old_window = window;
TextLayer *old_timer = timer;

window = window_create();
window_stack_push(window, true);
window_set_background_color(window, GColorBlack);

timer = text_layer_create(GRect(14, 49, 130, 50));
text_layer_set_text_color(timer, GColorWhite);
text_layer_set_background_color(timer, GColorClear);
text_layer_set_font(timer, fonts_get_system_font(FONT_KEY_BITHAM_42_MEDIUM_NUMBERS));

layer_add_child(window_get_root_layer(window), text_layer_get_layer(timer));
text_layer_set_text(timer, "Starting...");

update_display_with_time((int) current_time());

if (old_window) { window_destroy(old_window); }
if (old_timer) { text_layer_destroy(old_timer); }
void timer_display_warning(TimerDisplay *display) {
layer_set_hidden(inverter_layer_get_layer(display->inverter),
!layer_get_hidden(inverter_layer_get_layer(display->inverter)));
}

void deinitialize_display() {
if (window) { window_destroy(window); window = NULL; }
if (timer) { text_layer_destroy(timer); timer = NULL; }
void timer_display_cancel(TimerDisplay *display) {
layer_set_hidden(inverter_layer_get_layer(display->inverter), true);
vibes_cancel();
}
23 changes: 14 additions & 9 deletions src/display.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
#pragma once
#include <pebble.h>

#ifndef __MY_DISPLAY_H
#define __MY_DISPLAY_H
typedef struct TimerDisplay TimerDisplay;
typedef enum {
STOPPED, RUNNING
} TimerDisplayMode;

void update_display_with_time(int display);
void alert();
void warning();
void initialize_display();
void deinitialize_display();
Window* get_window();
TimerDisplay *timer_display_create();
void timer_display_destroy(TimerDisplay *display);

#endif
void timer_display_set_click_config_provider(TimerDisplay *display, ClickConfigProvider provider, void *context);
void timer_display_set_mode(TimerDisplay *display, TimerDisplayMode mode);

void timer_display_update(TimerDisplay *display, int value);
void timer_display_alert(TimerDisplay *display);
void timer_display_warning(TimerDisplay *display);
void timer_display_cancel(TimerDisplay *display);
34 changes: 0 additions & 34 deletions src/time_handler.c

This file was deleted.

17 changes: 0 additions & 17 deletions src/time_handler.h

This file was deleted.

Loading