pebble / stopwatch / src / stopwatch.c

/** \file
 * Stopwatch display
 */
#include "pebble_os.h"
#include "pebble_app.h"
#include "pebble_fonts.h"

PBL_APP_INFO(
	"Stopwatch",
	"hudson",
	1, // Version
	INVALID_RESOURCE,
	0 // App, not watch face
);


static Window window;
static TextLayer time_layer;
//static TextLayer elapsed_layer;
static Layer layer;
static char time_buffer[12];
static char remaining_buffer[12];
static GFont big_font;

static AppTimerHandle timer_handle;
#define COOKIE_MY_TIMER 1

static int seconds;
static int miliseconds;


static void
monospace_text(
	GContext * ctx,
	const char * buf,
	GFont font,
	GPoint xy,
	int x_size,
	int y_size
)
{
	while (1)
	{
		const char c = *buf++;
		char str[2] = { c, '\0' };

		if (c == '\0')
			break;

		graphics_text_draw(
			ctx,
			str,
			font,
			GRect(xy.x, xy.y, x_size, y_size),
			GTextOverflowModeTrailingEllipsis,
			GTextAlignmentRight,
			NULL
		);

		xy.x += x_size;
	}
}


/**
 */
static void
layer_update(
	Layer * const me,
	GContext * ctx
)
{
	const unsigned w = me->bounds.size.w;
	const unsigned h = me->bounds.size.h;
	static char buf[16];
	int ms = miliseconds += 1;
	int s = seconds;

	buf[5] = '\0';
	buf[4] = ('0' + ms % 10); ms /= 10;
	buf[3] = ('0' + s % 10); s /= 10;
	buf[2] = ('0' + s % 10); s /= 10;
	buf[1] = ('0' + s % 10); s /= 10;
	buf[0] = ('0' + s % 10); s /= 10;

	monospace_text(
		ctx,
		buf,
		big_font,
		GPoint(0,0),
		28,
		60
	);

#if 0
	const int bar_h = h / run_count;
	int y = 0;

	graphics_context_set_fill_color(ctx, GColorWhite);

	for (int i = 0 ; i < interval_count ; i++)
	{
		if (intervals[i] < 0)
			continue;

		int bar_w;
		if (i < interval)
			bar_w = 0;
		else
		if (i == interval)
			bar_w = (w * remaining) / intervals[i];
		else
			bar_w = w;

		graphics_fill_rect(ctx, GRect(0, y, bar_w, bar_h - 2), 2, GCornersAll);
		y += bar_h;
	}
#endif
}


static void
handle_timer(
	AppContextRef ctx,
	AppTimerHandle handle,
	uint32_t cookie
)
{
	(void)handle;

	if (cookie != COOKIE_MY_TIMER)
		return;

	timer_handle = app_timer_send_event(
		ctx,
		100 /* milliseconds */,
		COOKIE_MY_TIMER
	);

	layer_mark_dirty(&layer);

}



static void
handle_tick(
	AppContextRef ctx,
	PebbleTickEvent * const event
)
{
	(void) ctx;
	const PblTm * const ptm = event->tick_time;

	string_format_time(
		time_buffer,
		sizeof(time_buffer),
		"%H:%M:%S",
		ptm
	);

	text_layer_set_text(&time_layer, time_buffer);

	seconds++;
	miliseconds = 0;
	
	if (!timer_handle)
		timer_handle = app_timer_send_event(
			ctx,
			100 /* milliseconds */,
			COOKIE_MY_TIMER
		);

#if 0
	if (remaining != 0)
		remaining--;
	else
	if (interval < interval_count-1)
	{
		remaining = intervals[++interval];
		if (remaining < 0)
		{
			remaining = -remaining;
			walk = 1;
			vibes_long_pulse();
		} else {
			walk = 0;
			vibes_double_pulse();
		}
	}

	int min = remaining / 60;
	int sec = remaining % 60;

	if (walk)
	{
		text_layer_set_text_color(&elapsed_layer, GColorBlack);
		text_layer_set_background_color(&elapsed_layer, GColorWhite);
	} else {
		text_layer_set_text_color(&elapsed_layer, GColorWhite);
		text_layer_set_background_color(&elapsed_layer, GColorClear);
	}

	remaining_buffer[0] = '0' + (min / 10) % 10;
	remaining_buffer[1] = '0' + (min / 1) % 10;
	remaining_buffer[2] = ':';
	remaining_buffer[3] = '0' + (sec / 10) % 10;
	remaining_buffer[4] = '0' + (sec / 1) % 10;
	remaining_buffer[5] = '\0';

	text_layer_set_text(&elapsed_layer, remaining_buffer);
#endif
}


static void
handle_init(
	AppContextRef ctx
)
{
	(void) ctx;

	window_init(&window, "Odometer");
	window_stack_push(&window, true);
	window_set_background_color(&window, GColorBlack);

	resource_init_current_app(&RESOURCES);

	text_layer_init(&time_layer, GRect(30,-3,100,30));
	text_layer_set_text_color(&time_layer, GColorWhite);
        text_layer_set_background_color(&time_layer, GColorClear);
	text_layer_set_text(&time_layer, "");
	text_layer_set_font(&time_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28));

	big_font = fonts_get_system_font(FONT_KEY_GOTHAM_42_LIGHT);

#if 0
	text_layer_init(&elapsed_layer, GRect(7,26,132,44));
	text_layer_set_text(&elapsed_layer, "");

	text_layer_set_font(&elapsed_layer, fonts_get_system_font(FONT_KEY_GOTHAM_42_BOLD));
#endif

	// Layer to draw the bargraphs
	layer_add_child(&window.layer, &time_layer.layer);
	//layer_add_child(&window.layer, &elapsed_layer.layer);

	layer_init(&layer, GRect(0,70,144,168-70));
	layer.update_proc = layer_update;

	layer_add_child(&window.layer, &layer);
}


static void
handle_deinit(
	AppContextRef ctx
)
{
	(void) ctx;
}


void
pbl_main(
	void * const params
)
{
	PebbleAppHandlers handlers = {
		.init_handler	= handle_init,
		.deinit_handler	= handle_deinit,
		.timer_handler	= handle_timer,
		.tick_info	= {
			.tick_handler = handle_tick,
			.tick_units = SECOND_UNIT,
		},
	};

	app_event_loop(params, &handlers);
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.