Source

pebble / zulu / src / zulu.c

Full commit
Trammell Hudson 740bd0e 





























Trammell Hudson dcf051c 





Trammell Hudson 580422b 



Trammell Hudson dcf051c 
















Trammell Hudson 580422b 
Trammell Hudson 740bd0e 






Trammell Hudson 580422b 
Trammell Hudson ec09299 



Trammell Hudson 580422b 

Trammell Hudson ec09299 

Trammell Hudson dcf051c 
Trammell Hudson ec09299 


Trammell Hudson dcf051c 

Trammell Hudson ec09299 
Trammell Hudson dcf051c 




Trammell Hudson ec09299 
Trammell Hudson dcf051c 
















Trammell Hudson 580422b 
Trammell Hudson 740bd0e 








































































Trammell Hudson 580422b 





Trammell Hudson dcf051c 

Trammell Hudson 580422b 



Trammell Hudson dcf051c 





Trammell Hudson 740bd0e 







Trammell Hudson 580422b 
Trammell Hudson 740bd0e 

Trammell Hudson dcf051c 
Trammell Hudson 580422b 
Trammell Hudson 740bd0e 































/** \file
 * Sun up/sundown clock with 24 hour face and moon phase.
 *
 */
#include "pebble_os.h"
#include "pebble_app.h"
#include "pebble_fonts.h"
#include "pebble_th.h"

#define UUID { 0x06, 0x97, 0xE5, 0x7F, 0x60, 0xF7, 0x43, 0xC5, 0x80, 0xC4, 0x35, 0x9D, 0xB2, 0x7E, 0xCD, 0xEE }

PBL_APP_INFO(
	UUID,
	"Moonphase",
	"hudson",
	1, 0, // Version
	RESOURCE_ID_IMAGE_MENU_ICON,
	APP_INFO_WATCH_FACE
);


// Local timezone GMT offset
static const int gmt_offset = -5;

static Window window;
static Layer graphics_layer;
static PblTm now;
static GFont font_thin;
static GFont font_thick;


// Dimensions of the watch face
#define W PEBBLE_SCREEN_WIDTH
#define H PEBBLE_SCREEN_WIDTH
#define R (W/2 - 2)

// Circle points computed at startup and the path is dynamically adjuste
#define NUM_POINTS 256
static GPoint circle_points[NUM_POINTS];
static GPath circle_path;
static GPathInfo circle_info = { NUM_POINTS, circle_points };

// Hour markers
static GPath hour_path;
static GPoint hour_points[] = { { 0, R - 2 }, { 0, R + 2 } };
static GPathInfo hour_info = { 2, hour_points };

// Hour hand
static GPath hand_path;
static GPoint hand_points[] = {
	{  0, 0 },
	{ -5, -10 },
	{  0, -R },
	{ +5, -10 },
	{  0, 0 },
};
static GPathInfo hand_info = { 5, hand_points };


static void
graphics_layer_update(
        Layer * const me,
        GContext * ctx
)
{
	(void) me;

	const int w = me->bounds.size.w;
	const int h = me->bounds.size.h;

	graphics_context_set_stroke_color(ctx, GColorWhite);
	graphics_context_set_fill_color(ctx, GColorWhite);

	// Draw the outline circle
	graphics_draw_circle(ctx, GPoint(w/2,h/2), R);

	// Compute the sun up / sun down time and
	// draw the semi-circle
	int sun_up = 120;
	int sun_down = 140;

	circle_path.num_points = sun_down - sun_up;
	circle_path.points = &circle_points[sun_up];

	GPoint temp = circle_path.points[0];
	circle_path.points[0] = GPoint(w/2,h/2);
	gpath_draw_filled(ctx, &circle_path);
	circle_path.points[0] = temp;

	// Draw the hour marks
	for (int hour = 0 ; hour < 23 ; hour++)
	{
		gpath_rotate_to(&hour_path, (hour * TRIG_MAX_ANGLE) / 24);
		gpath_draw_outline(ctx, &hour_path);
	}

	// Draw the hour hand outline and filled with black
	int hand_angle = ((now.tm_hour * 60 + now.tm_min) * TRIG_MAX_ANGLE) / (60 * 24);

	gpath_rotate_to(&hand_path, hand_angle);
	graphics_context_set_fill_color(ctx, GColorBlack);
	gpath_draw_filled(ctx, &hand_path);
	graphics_context_set_stroke_color(ctx, GColorWhite);
	gpath_draw_outline(ctx, &hand_path);

#if 0
	const timezone_t * const tz = container_of(me, timezone_t, layer);

	const int orig_hour = now.tm_hour;

	now.tm_hour += tz->offset - gmt_offset;
	if (now.tm_hour > 24)
		now.tm_hour -= 24;
	if (now.tm_hour < 0)
		now.tm_hour += 24;

	char buf[32];
	string_format_time(
		buf,
		sizeof(buf),
		"%H:%M",
		&now
	);


	const int night_time = (now.tm_hour > 18 || now.tm_hour < 6);
	now.tm_hour = orig_hour;

	const int w = me->bounds.size.w;
	const int h = me->bounds.size.h;
		
	// it is night there, draw in black video
	graphics_context_set_fill_color(ctx, night_time ? GColorBlack : GColorWhite);
	graphics_context_set_text_color(ctx, !night_time ? GColorBlack : GColorWhite);
	graphics_fill_rect(ctx, GRect(0, 0, w, h), 0, 0);

	graphics_text_draw(ctx,
		tz->name,
		font_thin,
		GRect(0, 0, w, h/3),
		GTextOverflowModeTrailingEllipsis,
		GTextAlignmentCenter,
		NULL
	);

	graphics_text_draw(ctx,
		buf,
		font_thick,
		GRect(0, h/3, w, 2*h/3),
		GTextOverflowModeTrailingEllipsis,
		GTextAlignmentCenter,
		NULL
	);
#endif
}


/** Called once per minute */
static void
handle_tick(
	AppContextRef ctx,
	PebbleTickEvent * const event
)
{
	(void) ctx;

	now = *event->tick_time;

	layer_mark_dirty(&graphics_layer);
}


static void
handle_init(
	AppContextRef ctx
)
{
	(void) ctx;
	// Compute the points around the circle
	for (int i = 0 ; i < NUM_POINTS ; i++)
	{
		const uint32_t angle = (i * TRIG_MAX_ANGLE) / NUM_POINTS;
		const int s = sin_lookup(angle);
		const int c = cos_lookup(angle);
		circle_points[i].x = (W/2) + (R * s) / 0x10000;
		circle_points[i].y = (H/2) - (R * c) / 0x10000;
	}

	gpath_init(&circle_path, &circle_info);

	gpath_init(&hour_path, &hour_info);
	gpath_move_to(&hour_path, GPoint(W/2,H/2));

	gpath_init(&hand_path, &hand_info);
	gpath_move_to(&hand_path, GPoint(W/2,H/2));

	get_time(&now);

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

	resource_init_current_app(&RESOURCES);

	//font_thin = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ARIAL_16));
	font_thick = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ARIAL_BLACK_30));

	layer_init(&graphics_layer, GRect(0, 1, W, H));
	layer_add_child(&window.layer, &graphics_layer);
	graphics_layer.update_proc = graphics_layer_update;
	layer_mark_dirty(&graphics_layer);
}


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

	fonts_unload_custom_font(font_thin);
	fonts_unload_custom_font(font_thick);
}


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

	app_event_loop(params, &handlers);
}