4 #include "oswald_main.h"
5 #include "oswald_watch_faces.h"
6 #include "oswald_graphics.h"
7 #include "oswald_hal.h"
9 #include "oswald_screens.h"
11 #if defined(__GNUC__) && (__MSP430X__ > 0)
12 __attribute__((__far__))
14 #include "bitmaps/startstopbutton_icon.xbm"
16 #if defined(__GNUC__) && (__MSP430X__ > 0)
17 __attribute__((__far__))
19 #include "bitmaps/lapsebutton_icon.xbm"
21 #if defined(__GNUC__) && (__MSP430X__ > 0)
22 __attribute__((__far__))
24 #include "bitmaps/upbutton_icon.xbm"
26 #if defined(__GNUC__) && (__MSP430X__ > 0)
27 __attribute__((__far__))
29 #include "bitmaps/downbutton_icon.xbm"
31 #if defined(__GNUC__) && (__MSP430X__ > 0)
32 __attribute__((__far__))
34 #include "bitmaps/leftbutton_icon.xbm"
36 #if defined(__GNUC__) && (__MSP430X__ > 0)
37 __attribute__((__far__))
39 #include "bitmaps/rightbutton_icon.xbm"
41 #if defined(__GNUC__) && (__MSP430X__ > 0)
42 __attribute__((__far__))
44 #include "bitmaps/enterbutton_icon.xbm"
46 #if defined(__GNUC__) && (__MSP430X__ > 0)
47 __attribute__((__far__))
49 #include "bitmaps/checked_icon.xbm"
51 #if defined(__GNUC__) && (__MSP430X__ > 0)
52 __attribute__((__far__))
54 #include "bitmaps/unchecked_icon.xbm"
56 #if defined(__GNUC__) && (__MSP430X__ > 0)
57 __attribute__((__far__))
59 #include "bitmaps/main_menu_icon.xbm"
61 #if defined(__GNUC__) && (__MSP430X__ > 0)
62 __attribute__((__far__))
64 #include "bitmaps/timesetup_icon.xbm"
66 #if defined(__GNUC__) && (__MSP430X__ > 0)
67 __attribute__((__far__))
69 #include "bitmaps/stopwatch_icon.xbm"
71 #if defined(__GNUC__) && (__MSP430X__ > 0)
72 __attribute__((__far__))
74 #include "bitmaps/alarm_icon.xbm"
76 #if defined(__GNUC__) && (__MSP430X__ > 0)
77 __attribute__((__far__))
79 #include "bitmaps/Bluetooth_icon.xbm"
81 #if defined(__GNUC__) && (__MSP430X__ > 0)
82 __attribute__((__far__))
84 #include "bitmaps/info_icon.xbm"
86 #if defined(__GNUC__) && (__MSP430X__ > 0)
87 __attribute__((__far__))
89 #include "bitmaps/acc_icon.xbm"
91 #if defined(__GNUC__) && (__MSP430X__ > 0)
92 __attribute__((__far__))
94 #include "bitmaps/Message_icon.xbm"
96 #if defined(__GNUC__) && (__MSP430X__ > 0)
97 __attribute__((__far__))
99 #include "bitmaps/Exit_icon.xbm"
103 * Common event handler part of the watch faces
106 void (*screendraw_func)(boolean show_seconds);
107 boolean show_seconds;
110 static idle_data_t idle_screen = {
116 event_ret_t idle_handle_user_buttons(watch_button button)
120 if (idle_screen.show_seconds)
121 idle_screen.show_seconds = FALSE;
123 idle_screen.show_seconds = TRUE;
126 if (idle_screen.analogue == TRUE) {
127 idle_screen.analogue = FALSE;
128 idle_screen.screendraw_func = DrawLcdDigitalClock;
130 idle_screen.analogue = TRUE;
131 idle_screen.screendraw_func = DrawLcdAnaClock;
135 OswaldState.screen_id = MAIN_MENU_SCREEN;
136 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
137 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
138 return EVENT_RET_HANDLED;
141 OswaldState.screen_id = DATETIME_SETTING_SCREEN;
142 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
143 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
144 return EVENT_RET_HANDLED;
147 return EVENT_RET_UNHANDLED;
151 idle_screen.screendraw_func(idle_screen.show_seconds);
153 return EVENT_RET_HANDLED;
156 event_ret_t idle_handle_events(uint16_t event, void *data)
159 case EVENT_ONE_SEC_TIMER:
160 case EVENT_SCREEN_VISIBLE:
161 idle_screen.screendraw_func(idle_screen.show_seconds);
162 return EVENT_RET_HANDLED;
164 case EVENT_USER_BUTTONS:
165 dbg_out("button event %d\n", *(int *)data);
166 return idle_handle_user_buttons(*(watch_button *)data);
169 return EVENT_RET_UNHANDLED;
172 return EVENT_RET_UNHANDLED;
183 static main_menu_data_t main_menu_screen = {
188 #define MAIN_MENU_GRID_PIXEL 84
189 #define MAIN_MENU_GRID_X 3
190 // GRID_Y is +1 since there is one empty row for title icon
191 #define MAIN_MENU_GRID_Y 3
192 #define MAIN_MENU_GRID_SPACING 0
193 #define MAIN_MENU_OFFSET_X 6
194 #define MAIN_MENU_OFFSET_Y 8
196 void draw_main_menu_screen(main_menu_data_t *sdata)
198 uint8_t pf = sdata->pos - 2;
200 hal_lcd_clear_display();
202 // oswald_draw_bitmap(36, 0, main_menu_icon_width, main_menu_icon_height, main_menu_icon_bits);
204 oswald_draw_bitmap(81, 6, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
205 oswald_draw_bitmap(81, 38, leftbutton_icon_width, leftbutton_icon_height, leftbutton_icon_bits);
206 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
208 oswald_draw_bitmpa_invert_opt(MAIN_MENU_OFFSET_X+((0+1) * MAIN_MENU_GRID_SPACING) + (0 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
209 MAIN_MENU_OFFSET_Y+(0 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)),
210 alarm_icon_width, alarm_icon_height, alarm_icon_bits, (sdata->pos == ALARM_SETUP_SCREEN));
211 oswald_draw_bitmpa_invert_opt(MAIN_MENU_OFFSET_X+((1+1) * MAIN_MENU_GRID_SPACING) + (1 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
212 MAIN_MENU_OFFSET_Y+(0 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)),
213 stopwatch_icon_width, stopwatch_icon_height, stopwatch_icon_bits, (sdata->pos == STOP_WATCH_SCREEN));
214 oswald_draw_bitmpa_invert_opt(MAIN_MENU_OFFSET_X+((2+1) * MAIN_MENU_GRID_SPACING) + (2 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
215 MAIN_MENU_OFFSET_Y+(0 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)),
216 Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits, (sdata->pos == BLUETOOTH_SCREEN));
217 oswald_draw_bitmpa_invert_opt(MAIN_MENU_OFFSET_X+((0+1) * MAIN_MENU_GRID_SPACING) + (0 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
218 MAIN_MENU_OFFSET_Y+(1 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)),
219 acc_icon_width, acc_icon_height, acc_icon_bits, (sdata->pos == ACCEL_DISPLAY_SCREEN));
220 oswald_draw_bitmpa_invert_opt(MAIN_MENU_OFFSET_X+((1+1) * MAIN_MENU_GRID_SPACING) + (1 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
221 MAIN_MENU_OFFSET_Y+(1 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)),
222 Message_icon_width, Message_icon_height, Message_icon_bits, (sdata->pos == MESSAGES_SCREEN));
223 oswald_draw_bitmpa_invert_opt(MAIN_MENU_OFFSET_X+((2+1) * MAIN_MENU_GRID_SPACING) + (2 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
224 MAIN_MENU_OFFSET_Y+(1 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)),
225 info_icon_width, info_icon_height, info_icon_bits, (sdata->pos == INFO_SCREEN));
226 oswald_draw_bitmpa_invert_opt(MAIN_MENU_OFFSET_X+((0+1) * MAIN_MENU_GRID_SPACING) + (0 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
227 MAIN_MENU_OFFSET_Y+(2 * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)),
228 Exit_icon_width, Exit_icon_height, Exit_icon_bits, (sdata->pos == LAST_SCREEN));
230 // round the corners of the inverted icon a little
231 hal_lcd_set_pixel(MAIN_MENU_OFFSET_X+((pf%MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)) % (MAIN_MENU_GRID_X*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
232 MAIN_MENU_OFFSET_Y+((pf/MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)) % (MAIN_MENU_GRID_Y*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)), FALSE);
233 hal_lcd_set_pixel(MAIN_MENU_OFFSET_X+23+((pf%MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)) % (MAIN_MENU_GRID_X*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
234 MAIN_MENU_OFFSET_Y+((pf/MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)) % (MAIN_MENU_GRID_Y*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)), FALSE);
235 hal_lcd_set_pixel(MAIN_MENU_OFFSET_X+((pf%MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)) % (MAIN_MENU_GRID_X*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
236 MAIN_MENU_OFFSET_Y+23+((pf/MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)) % (MAIN_MENU_GRID_Y*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)), FALSE);
237 hal_lcd_set_pixel(MAIN_MENU_OFFSET_X+23+((pf%MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)) % (MAIN_MENU_GRID_X*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_X)),
238 MAIN_MENU_OFFSET_Y+23+((pf/MAIN_MENU_GRID_X) * (MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)) % (MAIN_MENU_GRID_Y*(MAIN_MENU_GRID_PIXEL / MAIN_MENU_GRID_Y)), FALSE);
241 // finally a nice border
242 oswald_draw_line(3, 0, 95, 0);
243 oswald_draw_line(2, 1, 95, 1);
244 oswald_draw_line(1, 2, 95, 2);
246 oswald_draw_line(0, 3, 0, 92);
247 oswald_draw_line(1, 3, 1, 93);
248 oswald_draw_line(2, 3, 2, 94);
250 oswald_draw_line(1, 93, 95, 93);
251 oswald_draw_line(2, 94, 95, 94);
252 oswald_draw_line(3, 95, 95, 95);
254 hal_lcd_update_display();
257 event_ret_t handle_main_menu_buttons(watch_button button, main_menu_data_t *sdata)
262 if (sdata->pos > LAST_SCREEN)
264 draw_main_menu_screen(&main_menu_screen);
265 return EVENT_RET_HANDLED;
270 sdata->pos = LAST_SCREEN;
271 draw_main_menu_screen(&main_menu_screen);
272 return EVENT_RET_HANDLED;
275 if (sdata->pos < LAST_SCREEN) {
276 OswaldState.screen_id = sdata->pos;
277 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
278 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
280 OswaldState.screen_id = IDLE_SCREEN;
281 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
282 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
284 return EVENT_RET_HANDLED;
290 return EVENT_RET_UNHANDLED;
293 /* after MAIN_MENU_TIMEOUT seconds return to IDLE_SCREEN */
294 #define MAIN_MENU_TIMEOUT 10
296 event_ret_t main_menu_handle_events(uint16_t event, void *data)
299 case EVENT_SCREEN_VISIBLE:
300 main_menu_screen.tmo = 0;
301 main_menu_screen.pos = 2;
302 draw_main_menu_screen(&main_menu_screen);
303 return EVENT_RET_HANDLED;
305 case EVENT_USER_BUTTONS:
306 dbg_out("button event %d\n", *(int *)data);
307 main_menu_screen.tmo = 0;
308 return handle_main_menu_buttons(*(watch_button *)data, &main_menu_screen);
310 case EVENT_ONE_SEC_TIMER:
311 main_menu_screen.tmo++;
312 if (main_menu_screen.tmo > MAIN_MENU_TIMEOUT) {
313 OswaldState.screen_id = IDLE_SCREEN;
314 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
315 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
317 return EVENT_RET_HANDLED;
321 return EVENT_RET_UNHANDLED;
326 * Accelerometer and sensor display screen
329 accel_data_t accdata;
330 } accelscreen_data_t;
331 static accelscreen_data_t accel_screen = {
335 void draw_accel_screen(accel_data_t *accel_data)
339 hal_lcd_clear_display();
341 oswald_draw_bitmap(36, 0, acc_icon_width, acc_icon_height, acc_icon_bits);
343 oswald_draw_bitmap(81, 79, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
345 oswald_write_string(1, 40, FONT_6x9, FALSE, "X:");
346 oswald_write_number(15, 40, FONT_6x9, FALSE, accel_data->x);
347 oswald_write_string(1, 52, FONT_6x9, FALSE, "Y:");
348 oswald_write_number(15, 52, FONT_6x9, FALSE, accel_data->y);
349 oswald_write_string(1, 64, FONT_6x9, FALSE, "Z:");
350 oswald_write_number(15, 64, FONT_6x9, FALSE, accel_data->z);
352 oswald_write_string(1, 85, FONT_6x9, FALSE, "Light:");
353 oswald_write_number(50, 85, FONT_6x9, FALSE, 0);
355 oswald_draw_line(40, 30, 92, 30);
356 oswald_draw_line(92, 30, 92, 82);
357 oswald_draw_line(40, 82, 92, 82);
358 oswald_draw_line(40, 82, 40, 30);
360 x = 41+25+((accel_data->x * 50) / (254));
361 y = 31+25-((accel_data->y * 50) / (254));
362 oswald_draw_pixel(x, y, TRUE);
363 oswald_draw_pixel(x+1, y, TRUE);
364 oswald_draw_pixel(x-1, y, TRUE);
365 oswald_draw_pixel(x, y+1, TRUE);
366 oswald_draw_pixel(x, y-1, TRUE);
368 hal_lcd_update_display();
371 event_ret_t accel_handle_events(uint16_t event, void *data)
374 case EVENT_SCREEN_VISIBLE:
375 draw_accel_screen(&accel_screen.accdata);
376 hal_accelerometer_enable();
377 return EVENT_RET_HANDLED;
379 case EVENT_SCREEN_DESTROY:
380 hal_accelerometer_disable();
381 return EVENT_RET_HANDLED;
383 case EVENT_ACCEL_UPDATE: {
384 accel_data_t *accel_data = (accel_data_t *)data;
385 accel_screen.accdata.x = accel_data->x;
386 accel_screen.accdata.y = accel_data->y;
387 accel_screen.accdata.z = accel_data->z;
388 draw_accel_screen(&accel_screen.accdata);
390 return EVENT_RET_HANDLED;
392 case EVENT_USER_BUTTONS:
393 dbg_out("button event %d\n", *(int *)data);
396 return EVENT_RET_UNHANDLED;
399 return EVENT_RET_UNHANDLED;
404 * Date / time setup screen
410 } datetime_setup_data_t;
411 static datetime_setup_data_t dt_setup_screen = {
417 void draw_datetime_setup_screen(datetime_setup_data_t *sdata)
419 hal_lcd_clear_display();
421 oswald_draw_bitmap(36, 0, timesetup_icon_width, timesetup_icon_height, timesetup_icon_bits);
423 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
424 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
425 oswald_draw_bitmap(81, 70, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
427 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
428 oswald_write_character(2, 30, FONT_LCD13x21, FALSE, (OswaldClk.hour / 10));
429 oswald_write_character(15, 30, FONT_LCD13x21, FALSE, (OswaldClk.hour % 10));
431 oswald_write_character(25, 30, FONT_LCD13x21, FALSE, 10);
433 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
434 oswald_write_character(34, 30, FONT_LCD13x21, FALSE, (OswaldClk.minute / 10));
435 oswald_write_character(47, 30, FONT_LCD13x21, FALSE, (OswaldClk.minute % 10));
438 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
439 oswald_write_character(61, 38, FONT_LCD8x13, FALSE, (OswaldClk.second / 10));
440 oswald_write_character(69, 38, FONT_LCD8x13, FALSE, (OswaldClk.second % 10));
444 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
445 oswald_write_number(2, 55, FONT_DROID8x12, FALSE, OswaldClk.day);
447 oswald_write_character(15, 55, FONT_DROID8x12, FALSE, '.');
448 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
449 oswald_write_number(21, 55, FONT_DROID8x12, FALSE, OswaldClk.month);
451 oswald_write_character(36, 55, FONT_DROID8x12, FALSE, '.');
452 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
453 oswald_write_number(43, 55, FONT_DROID8x12, FALSE, OswaldClk.year);
456 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
457 if (OswaldClk.clk24hr) {
458 oswald_draw_bitmap(2, 76, checked_icon_width, checked_icon_height, checked_icon_bits);
460 oswald_draw_bitmap(2, 76, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
463 oswald_write_string(15, 73, FONT_DROID8x12, FALSE, "24hr");
465 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
466 if (OswaldClk.day_first) {
467 oswald_draw_bitmap(2, 86, checked_icon_width, checked_icon_height, checked_icon_bits);
469 oswald_draw_bitmap(2, 86, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
472 oswald_write_string(15, 83, FONT_DROID8x12, FALSE, "dd.mm. mm/dd");
474 hal_lcd_update_display();
477 void datetime_handle_updown(uint8_t pos, int8_t incr)
481 if (OswaldClk.hour == 0 && incr == -1) {
485 OswaldClk.hour += incr;
486 if (OswaldClk.hour > 23)
490 if (OswaldClk.minute == 0 && incr == -1) {
491 OswaldClk.minute = 59;
494 OswaldClk.minute += incr;
495 if (OswaldClk.minute > 59)
496 OswaldClk.minute = 0;
499 OswaldClk.second = 0;
502 if (OswaldClk.day == 1 && incr == -1) {
506 OswaldClk.day += incr;
507 if (OswaldClk.day > 31)
511 if (OswaldClk.month == 1 && incr == -1) {
512 OswaldClk.month = 12;
515 OswaldClk.month += incr;
516 if (OswaldClk.month > 12)
520 OswaldClk.year += incr;
522 case 6: // 24hr / 12hr
523 if (OswaldClk.clk24hr)
524 OswaldClk.clk24hr = FALSE;
526 OswaldClk.clk24hr = TRUE;
528 case 7: // dd.mm. / mm/dd
529 if (OswaldClk.day_first)
530 OswaldClk.day_first = FALSE;
532 OswaldClk.day_first = TRUE;
538 hal_set_rtc(&OswaldClk, TRUE);
540 hal_set_rtc(&OswaldClk, FALSE);
543 event_ret_t handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata)
547 datetime_handle_updown(sdata->pos, 1);
550 datetime_handle_updown(sdata->pos, -1);
557 OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
558 OswaldState.screen_id = IDLE_SCREEN;
559 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
560 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
561 return EVENT_RET_HANDLED;
564 return EVENT_RET_UNHANDLED;
567 draw_datetime_setup_screen(sdata);
568 return EVENT_RET_HANDLED;
571 event_ret_t datetime_setup_events(uint16_t event, void *data)
574 case EVENT_SCREEN_VISIBLE:
575 dt_setup_screen.pos = 0;
576 draw_datetime_setup_screen(&dt_setup_screen);
577 hal_enable_halfsecond_timer();
578 return EVENT_RET_HANDLED;
580 case EVENT_SCREEN_DESTROY:
581 hal_disable_halfsecond_timer();
582 return EVENT_RET_HANDLED;
584 case EVENT_USER_BUTTONS:
585 dbg_out("button event %d\n", *(int *)data);
586 return handle_setup_datetime_buttons(*(watch_button *)data, &dt_setup_screen);
588 case EVENT_HALF_SEC_TIMER:
589 if (dt_setup_screen.on)
590 dt_setup_screen.on = FALSE;
592 dt_setup_screen.on = TRUE;
593 draw_datetime_setup_screen(&dt_setup_screen);
594 return EVENT_RET_HANDLED;
597 return EVENT_RET_UNHANDLED;
600 return EVENT_RET_UNHANDLED;
611 } alarm_setup_data_t;
612 static alarm_setup_data_t alarm_setup_screen = {
618 void draw_alarm_setup_screen(alarm_setup_data_t *sdata)
620 hal_lcd_clear_display();
622 oswald_draw_bitmap(36, 0, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
624 if (sdata->set_mode) {
625 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
626 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
627 oswald_draw_bitmap(81, 70, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
629 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
632 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
633 oswald_write_character(18, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.hour / 10));
634 oswald_write_character(32, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.hour % 10));
636 oswald_write_character(42, 30, FONT_LCD13x21, FALSE, 10);
638 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
639 oswald_write_character(53, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.minute / 10));
640 oswald_write_character(67, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.minute % 10));
643 oswald_write_character(3, 55, FONT_6x9, FALSE, 'S');
644 oswald_write_character(15, 55, FONT_6x9, FALSE, 'M');
645 oswald_write_character(27, 55, FONT_6x9, FALSE, 'T');
646 oswald_write_character(39, 55, FONT_6x9, FALSE, 'W');
647 oswald_write_character(51, 55, FONT_6x9, FALSE, 'T');
648 oswald_write_character(63, 55, FONT_6x9, FALSE, 'F');
649 oswald_write_character(75, 55, FONT_6x9, FALSE, 'S');
651 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
652 // oswald_write_character(3, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_');
653 if ((OswaldAlarm.wday & WDAY_SUNDAY))
654 oswald_draw_bitmap(3, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
656 oswald_draw_bitmap(3, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
658 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
659 // oswald_write_character(15, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_');
660 if ((OswaldAlarm.wday & WDAY_MONDAY))
661 oswald_draw_bitmap(15, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
663 oswald_draw_bitmap(15, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
665 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
666 // oswald_write_character(27, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_');
667 if ((OswaldAlarm.wday & WDAY_TUESDAY))
668 oswald_draw_bitmap(27, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
670 oswald_draw_bitmap(27, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
672 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
673 // oswald_write_character(39, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_');
674 if ((OswaldAlarm.wday & WDAY_WEDNESDAY))
675 oswald_draw_bitmap(39, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
677 oswald_draw_bitmap(39, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
679 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
680 // oswald_write_character(51, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_');
681 if ((OswaldAlarm.wday & WDAY_THURSDAY))
682 oswald_draw_bitmap(51, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
684 oswald_draw_bitmap(51, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
686 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
687 // oswald_write_character(63, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_');
688 if ((OswaldAlarm.wday & WDAY_FRIDAY))
689 oswald_draw_bitmap(63, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
691 oswald_draw_bitmap(63, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
693 if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8) {
694 // oswald_write_character(75, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_');
695 if ((OswaldAlarm.wday & WDAY_SATURDAY))
696 oswald_draw_bitmap(75, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
698 oswald_draw_bitmap(75, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
701 hal_lcd_update_display();
704 void alarm_handle_updown(uint8_t pos, int8_t incr)
708 if (OswaldAlarm.hour == 0 && incr == -1) {
709 OswaldAlarm.hour = 23;
712 OswaldAlarm.hour += incr;
713 if (OswaldAlarm.hour > 23)
714 OswaldAlarm.hour = 0;
717 if (OswaldAlarm.minute == 0 && incr == -1) {
718 OswaldAlarm.minute = 59;
721 OswaldAlarm.minute += incr;
722 if (OswaldAlarm.minute > 59)
723 OswaldAlarm.minute = 0;
726 OswaldAlarm.wday ^= WDAY_SUNDAY;
729 OswaldAlarm.wday ^= WDAY_MONDAY;
732 OswaldAlarm.wday ^= WDAY_TUESDAY;
735 OswaldAlarm.wday ^= WDAY_WEDNESDAY;
738 OswaldAlarm.wday ^= WDAY_THURSDAY;
741 OswaldAlarm.wday ^= WDAY_FRIDAY;
744 OswaldAlarm.wday ^= WDAY_SATURDAY;
751 event_ret_t handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata)
753 if (alarm_setup_screen.set_mode) {
756 alarm_handle_updown(sdata->pos, 1);
759 alarm_handle_updown(sdata->pos, -1);
766 alarm_setup_screen.set_mode = FALSE;
769 return EVENT_RET_UNHANDLED;
775 alarm_setup_screen.set_mode = TRUE;
778 return EVENT_RET_UNHANDLED;
782 draw_alarm_setup_screen(sdata);
784 return EVENT_RET_HANDLED;
787 event_ret_t alarm_setup_events(uint16_t event, void *data)
790 case EVENT_SCREEN_VISIBLE:
791 alarm_setup_screen.pos = 0;
792 alarm_setup_screen.on = TRUE;
793 alarm_setup_screen.set_mode = FALSE;
794 draw_alarm_setup_screen(&alarm_setup_screen);
795 hal_enable_halfsecond_timer();
796 return EVENT_RET_HANDLED;
798 case EVENT_SCREEN_DESTROY:
799 hal_disable_halfsecond_timer();
800 return EVENT_RET_HANDLED;
802 case EVENT_USER_BUTTONS:
803 dbg_out("button event %d\n", *(int *)data);
804 return handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen);
806 case EVENT_HALF_SEC_TIMER:
807 if (alarm_setup_screen.set_mode) {
808 if (alarm_setup_screen.on)
809 alarm_setup_screen.on = FALSE;
811 alarm_setup_screen.on = TRUE;
813 alarm_setup_screen.on = TRUE;
814 draw_alarm_setup_screen(&alarm_setup_screen);
815 return EVENT_RET_HANDLED;
818 return EVENT_RET_UNHANDLED;
821 return EVENT_RET_UNHANDLED;
831 static test_menu_t test_menu = { 0 };
833 void draw_menu_test_screen(void)
835 hal_lcd_clear_display();
837 SetFont(MetaWatch16);
838 WriteLcdString(2, 2, "Menu");
840 WriteLcdString(2, 20, "Item 1");
841 WriteLcdString(2, 29, "Item 2");
842 WriteLcdString(2, 38, "Item 3");
843 WriteLcdString(2, 47, "Item 4");
844 WriteLcdString(2, 56, "Item 5");
846 WriteLcdString(50, 20+(9*test_menu.menu_pos), "*");
848 oswald_write_string(2, 2, FONT_DROID8x12, FALSE, "Menu");
850 oswald_write_string(2, 20, FONT_DROID8x12, FALSE, "Item 1");
851 oswald_write_string(2, 29, FONT_DROID8x12, FALSE, "Item 2");
852 oswald_write_string(2, 38, FONT_DROID8x12, FALSE, "Item 3");
853 oswald_write_string(2, 47, FONT_DROID8x12, FALSE, "Item 4");
854 oswald_write_string(2, 56, FONT_DROID8x12, FALSE, "Item 5");
856 oswald_write_character(50, 18+(9*test_menu.menu_pos), FONT_6x9, FALSE, 0x11);
858 hal_lcd_update_display();
861 event_ret_t handle_menu_user_buttons(watch_button button)
865 test_menu.menu_pos--;
866 test_menu.menu_pos %= 5;
869 test_menu.menu_pos++;
870 test_menu.menu_pos %= 5;
873 return EVENT_RET_UNHANDLED;
876 draw_menu_test_screen();
877 return EVENT_RET_HANDLED;
880 event_ret_t test_menu_handle_events(uint16_t event, void *data)
883 case EVENT_USER_BUTTONS:
884 dbg_out("button event %d\n", *(int *)data);
885 return handle_menu_user_buttons(*(watch_button *)data);
887 case EVENT_SCREEN_VISIBLE:
888 test_menu.menu_pos = 0;
889 draw_menu_test_screen();
892 return EVENT_RET_UNHANDLED;
895 return EVENT_RET_HANDLED;
913 static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE };
916 static void draw_stop_watch_screen(stopwatch_data_t *sdata)
921 hal_lcd_clear_display();
923 oswald_draw_bitmap(36, 0, stopwatch_icon_width, stopwatch_icon_height, stopwatch_icon_bits);
925 oswald_draw_bitmap(81, 6, startstopbutton_icon_width, startstopbutton_icon_height, startstopbutton_icon_bits);
926 oswald_draw_bitmap(81, 38, lapsebutton_icon_width, lapsebutton_icon_height, lapsebutton_icon_bits);
927 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
929 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->hr % 10));
930 gRow += oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->min / 10));
931 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->min % 10));
932 gRow += oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->sec / 10));
933 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->sec % 10));
934 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->csec / 10));
938 gRow += 13 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_hr % 10));
939 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_min / 10));
940 gRow += 13 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_min % 10));
941 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_sec / 10));
942 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_sec % 10));
943 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_csec / 10));
944 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_csec % 10));
946 hal_lcd_update_display();
949 event_ret_t handle_stop_watch_buttons(watch_button button)
952 case BUTTON_A: // start/stop
953 if (stopwatch_screen.running) {
954 hal_disable_centisecond_timer();
955 stopwatch_screen.running = FALSE;
957 hal_enable_centisecond_timer();
958 stopwatch_screen.running = TRUE;
960 return EVENT_RET_HANDLED;
962 case BUTTON_B: // lapse
963 stopwatch_screen.lapse_hr = stopwatch_screen.hr;
964 stopwatch_screen.lapse_min = stopwatch_screen.min;
965 stopwatch_screen.lapse_sec = stopwatch_screen.sec;
966 stopwatch_screen.lapse_csec = stopwatch_screen.csec;
967 return EVENT_RET_HANDLED;
969 case BUTTON_F: // reset
970 stopwatch_screen.hr = 0;
971 stopwatch_screen.min = 0;
972 stopwatch_screen.sec = 0;
973 stopwatch_screen.csec = 0;
974 stopwatch_screen.lapse_hr = 0;
975 stopwatch_screen.lapse_min = 0;
976 stopwatch_screen.lapse_sec = 0;
977 stopwatch_screen.lapse_csec = 0;
978 return EVENT_RET_HANDLED;
981 return EVENT_RET_UNHANDLED;
984 return EVENT_RET_UNHANDLED;
987 event_ret_t stop_watch_handle_events(uint16_t event, void *data)
990 case EVENT_USER_BUTTONS:
991 dbg_out("button event %d\n", *(int *)data);
992 draw_stop_watch_screen(&stopwatch_screen);
993 return handle_stop_watch_buttons(*(watch_button *)data);
995 case EVENT_SCREEN_VISIBLE:
996 draw_stop_watch_screen(&stopwatch_screen);
997 return EVENT_RET_HANDLED;
999 case EVENT_SCREEN_DESTROY:
1000 hal_disable_centisecond_timer();
1001 stopwatch_screen.running = FALSE;
1002 return EVENT_RET_HANDLED;
1004 case EVENT_CS_TIMER:
1005 stopwatch_screen.csec++;
1006 if (stopwatch_screen.csec > 99) {
1007 stopwatch_screen.csec = 0;
1008 stopwatch_screen.sec++;
1010 if (stopwatch_screen.sec > 59) {
1011 stopwatch_screen.sec = 0;
1012 stopwatch_screen.min++;
1014 if (stopwatch_screen.min > 59) {
1015 stopwatch_screen.min = 0;
1016 stopwatch_screen.hr++;
1018 if (stopwatch_screen.hr > 59) {
1019 stopwatch_screen.hr = 0;
1021 if (stopwatch_screen.csec % 10 == 0)
1022 draw_stop_watch_screen(&stopwatch_screen);
1023 //update_stop_watch_screen(&stopwatch_screen);
1024 return EVENT_RET_HANDLED;
1027 return EVENT_RET_UNHANDLED;
1030 return EVENT_RET_HANDLED;
1035 * Alarm screen, shown when alarm is fired
1037 void draw_alarm_screen(void)
1039 hal_lcd_clear_display();
1041 oswald_draw_bitmap(36, 20, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
1043 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1045 hal_lcd_update_display();
1048 event_ret_t alarm_handle_events(uint16_t event, void *data)
1051 case EVENT_SCREEN_VISIBLE:
1052 draw_alarm_screen();
1053 hal_enable_halfsecond_timer();
1054 hal_vibration_set_state(TRUE);
1055 return EVENT_RET_HANDLED;
1057 case EVENT_SCREEN_DESTROY:
1058 hal_disable_halfsecond_timer();
1059 hal_lcd_set_backlight(FALSE);
1060 hal_vibration_set_state(FALSE);
1061 return EVENT_RET_HANDLED;
1063 case EVENT_USER_BUTTONS:
1064 dbg_out("button event %d\n", *(int *)data);
1065 return EVENT_RET_UNHANDLED;
1067 case EVENT_HALF_SEC_TIMER:
1068 hal_lcd_set_backlight(!hal_lcd_get_backlight());
1069 hal_vibration_set_state(!hal_vibration_get_state());
1071 return EVENT_RET_HANDLED;
1074 return EVENT_RET_UNHANDLED;
1077 return EVENT_RET_HANDLED;
1082 * Bluetooth setup screen
1090 static bluetooth_data_t bluetooth_screen = {
1097 void draw_bluetooth_screen(bluetooth_data_t *sdata)
1102 hal_lcd_clear_display();
1104 oswald_draw_bitmap(36, 0, Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits);
1106 if (sdata->set_mode) {
1107 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
1108 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
1109 oswald_draw_bitmap(81, 70, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
1111 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1114 oswald_write_string(1, 30, FONT_DROID8x12, FALSE, "Enable:");
1115 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
1116 if (bluetooth_screen.bt_en)
1117 oswald_draw_bitmap(53, 33, checked_icon_width, checked_icon_height, checked_icon_bits);
1119 oswald_draw_bitmap(53, 33, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
1121 oswald_write_string(1, 40, FONT_DROID8x12, FALSE, "State:");
1122 switch (hal_bluetooth_get_state()) {
1124 oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "off");
1127 oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "on");
1129 case BLUETOOTH_CONNECTED:
1130 oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "conn.");
1135 oswald_write_string(1, 50, FONT_DROID8x12, FALSE, "Visible:");
1136 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
1137 // oswald_write_character(53, 50, FONT_DROID8x12, hal_bluetooth_get_visible() ? 'x' : '_');
1138 if (hal_bluetooth_get_visible())
1139 oswald_draw_bitmap(53, 53, checked_icon_width, checked_icon_height, checked_icon_bits);
1141 oswald_draw_bitmap(53, 53, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
1144 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
1145 bd_addr = hal_bluetooth_get_local_bdaddr();
1146 snprintf(bstr, 20, "%02x:%02x:%02x:%02x:%02x:%02x", bd_addr[5], bd_addr[4], bd_addr[3], bd_addr[2], bd_addr[1], bd_addr[0]);
1147 oswald_write_string(2, 85, FONT_5x7, FALSE, bstr);
1151 hal_lcd_update_display();
1154 void bluetooth_handle_updown(uint8_t pos, int8_t incr)
1158 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
1159 hal_bluetooth_set_state(BLUETOOTH_OFF);
1160 bluetooth_screen.bt_en = FALSE;
1162 hal_bluetooth_set_state(BLUETOOTH_ON);
1163 bluetooth_screen.bt_en = TRUE;
1167 if (hal_bluetooth_get_state() >= BLUETOOTH_ON && !hal_bluetooth_get_visible()) {
1168 hal_bluetooth_set_visible(TRUE);
1170 hal_bluetooth_set_visible(FALSE);
1178 event_ret_t handle_bluetooth_buttons(watch_button button, bluetooth_data_t *sdata)
1180 if (bluetooth_screen.set_mode) {
1183 bluetooth_handle_updown(sdata->pos, 1);
1186 bluetooth_handle_updown(sdata->pos, -1);
1193 bluetooth_screen.set_mode = FALSE;
1196 return EVENT_RET_UNHANDLED;
1202 bluetooth_screen.set_mode = TRUE;
1205 return EVENT_RET_UNHANDLED;
1210 draw_bluetooth_screen(sdata);
1212 return EVENT_RET_HANDLED;
1215 event_ret_t bluetooth_screen_events(uint16_t event, void *data)
1218 case EVENT_SCREEN_VISIBLE:
1219 bluetooth_screen.pos = 0;
1220 bluetooth_screen.bt_en = (hal_bluetooth_get_state() > 0);
1221 draw_bluetooth_screen(&bluetooth_screen);
1222 hal_enable_halfsecond_timer();
1224 case EVENT_SCREEN_DESTROY:
1225 hal_disable_halfsecond_timer();
1227 case EVENT_USER_BUTTONS:
1228 dbg_out("button event %d\n", *(int *)data);
1229 return handle_bluetooth_buttons(*(watch_button *)data, &bluetooth_screen);
1231 case EVENT_HALF_SEC_TIMER:
1232 if (bluetooth_screen.set_mode) {
1233 if (bluetooth_screen.on)
1234 bluetooth_screen.on = FALSE;
1236 bluetooth_screen.on = TRUE;
1238 bluetooth_screen.on = TRUE;
1239 draw_bluetooth_screen(&bluetooth_screen);
1242 return EVENT_RET_UNHANDLED;
1245 return EVENT_RET_HANDLED;
1252 void draw_info_screen(void)
1254 hal_lcd_clear_display();
1256 oswald_draw_bitmap(36, 0, info_icon_width, info_icon_height, info_icon_bits);
1258 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1260 oswald_write_string(2, 29, FONT_DROID8x12, FALSE, "Oswald");
1261 oswald_write_string(35, 29, FONT_DROID8x12, FALSE, OSWALD_VERSION);
1262 oswald_write_string(2, 41, FONT_DROID8x12, FALSE, "HAL");
1263 oswald_write_string(35, 41, FONT_DROID8x12, FALSE, (char *)hal_get_version_string());
1264 oswald_write_string(2, 53, FONT_DROID8x12, FALSE, "Build");
1265 oswald_write_string(35, 53, FONT_DROID8x12, FALSE, (char *)hal_get_buildno_string());
1266 oswald_write_string(2, 65, FONT_DROID8x12, FALSE, "Radio");
1267 oswald_write_string(35, 65, FONT_DROID8x12, FALSE, (char *)hal_get_radio_version_string());
1269 hal_lcd_update_display();
1272 event_ret_t info_screen_handle_events(uint16_t event, void *data)
1275 case EVENT_SCREEN_VISIBLE:
1277 return EVENT_RET_HANDLED;
1279 case EVENT_USER_BUTTONS:
1280 dbg_out("button event %d\n", *(int *)data);
1283 return EVENT_RET_UNHANDLED;
1286 return EVENT_RET_UNHANDLED;
1294 int8_t pos; // marker position
1295 int8_t offset; // offset in msg list
1297 static messages_data_t messages_screen = {
1305 uint8_t year; // without century, add +1900
1310 #define MSG_TYPE_READ 0
1311 #define MSG_TYPE_NEW 1
1312 #define MSG_TYPE_END 127
1322 { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
1323 { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
1324 { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
1325 { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
1326 { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
1327 { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
1328 { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
1329 { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
1330 { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
1331 { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
1332 { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
1333 { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
1334 { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
1335 { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
1336 { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
1337 { MSG_TYPE_END, {0,0,0,0,0}, "Exit" },
1340 void draw_message_screen(messages_data_t *sdata)
1343 uint8_t strpos, msglen;
1346 hal_lcd_clear_display();
1349 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
1350 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
1352 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1354 Msg[sdata->offset + sdata->pos].type = MSG_TYPE_READ;
1355 snprintf(dstr, 19, "#%02d/%02d", sdata->pos + sdata->offset + 1, Msgs);
1356 oswald_write_string(30, 0, FONT_5x7, FALSE, dstr);
1357 oswald_draw_line(0,7,95,7);
1360 // here goes the text
1361 msglen = strlen(Msg[sdata->pos+sdata->offset].msg);
1364 while ((strpos < msglen) && (line < 6)) {
1365 strpos += oswald_write_string_length(4, 9+(line*12), 84, FONT_DROID8x12, FALSE, &Msg[sdata->pos+sdata->offset].msg[strpos]);
1370 oswald_draw_line(0,87,95,87);
1372 if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
1373 snprintf(dstr, 19, "%c %02d.%02d.%04d,%02d:%02d", (Msg[sdata->pos+sdata->offset].type == MSG_TYPE_NEW) ? '*':' ', Msg[sdata->pos+sdata->offset].td.day, Msg[sdata->pos+sdata->offset].td.month, Msg[sdata->pos+sdata->offset].td.year+1900, Msg[sdata->pos+sdata->offset].td.hour, Msg[sdata->pos+sdata->offset].td.minute);
1374 oswald_write_string(2, 89, FONT_5x7, FALSE, dstr);
1377 hal_lcd_update_display();
1380 event_ret_t handle_message_screen_buttons(watch_button button, messages_data_t *sdata)
1386 return EVENT_RET_HANDLED;
1389 // OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
1390 OswaldState.screen_id = MESSAGES_SCREEN;
1391 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
1392 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
1393 return EVENT_RET_HANDLED;
1399 return EVENT_RET_UNHANDLED;
1402 event_ret_t message_screen_handle_events(uint16_t event, void *data)
1405 case EVENT_SCREEN_VISIBLE:
1406 draw_message_screen(&messages_screen);
1407 return EVENT_RET_HANDLED;
1409 case EVENT_USER_BUTTONS:
1410 dbg_out("button event %d\n", *(int *)data);
1411 return handle_message_screen_buttons(*(watch_button *)data, &messages_screen);
1416 return EVENT_RET_UNHANDLED;
1419 void draw_messages_screen(messages_data_t *sdata)
1424 hal_lcd_clear_display();
1426 // oswald_draw_bitmap(36, 0, Message_icon_width, Message_icon_height, Message_icon_bits);
1428 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
1429 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
1430 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1432 if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
1433 snprintf(dstr, 19, "#%02d/%02d", sdata->pos + sdata->offset + 1, Msgs);
1434 oswald_write_string(30, 0, FONT_5x7, FALSE, dstr);
1436 oswald_draw_line(0,7,95,7);
1438 for (i=0; i<6; i++) {
1439 if (Msg[i+sdata->offset].type != MSG_TYPE_END) {
1440 //oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12, (Msg[i+sdata->offset].type == MSG_TYPE_NEW), Msg[i+sdata->offset].msg);
1441 if (Msg[i+sdata->offset].type == MSG_TYPE_NEW)
1442 oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12b, (i+sdata->offset) == (sdata->offset + sdata->pos), Msg[i+sdata->offset].msg);
1444 oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12, (i+sdata->offset) == (sdata->offset + sdata->pos), Msg[i+sdata->offset].msg);
1446 oswald_draw_bitmap(0, 66, leftbutton_icon_width, leftbutton_icon_height, leftbutton_icon_bits);
1450 // marker selected msg
1451 oswald_draw_line(1,9,1,81);
1452 oswald_draw_line_ww(1,10+(sdata->pos*12),1,20+(sdata->pos*12),2);
1454 oswald_draw_line(0,87,95,87);
1456 if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
1457 snprintf(dstr, 19, "%c %02d.%02d.%04d,%02d:%02d", (Msg[sdata->pos+sdata->offset].type == MSG_TYPE_NEW) ? '*':' ', Msg[sdata->pos+sdata->offset].td.day, Msg[sdata->pos+sdata->offset].td.month, Msg[sdata->pos+sdata->offset].td.year+1900, Msg[sdata->pos+sdata->offset].td.hour, Msg[sdata->pos+sdata->offset].td.minute);
1458 oswald_write_string(2, 89, FONT_5x7, FALSE, dstr);
1461 hal_lcd_update_display();
1464 event_ret_t handle_messages_screen_buttons(watch_button button, messages_data_t *sdata)
1469 if (sdata->pos < 0) {
1470 if (sdata->offset > 0) {
1473 if (sdata->offset < 0)
1477 sdata->offset = (Msgs - 5);
1478 if (sdata->offset < 0)
1482 draw_messages_screen(&messages_screen);
1483 return EVENT_RET_HANDLED;
1487 if (sdata->pos > 5) {
1490 if ((sdata->offset + 5) > Msgs) {
1495 draw_messages_screen(&messages_screen);
1496 return EVENT_RET_HANDLED;
1499 if (Msg[sdata->offset + sdata->pos].type == MSG_TYPE_END)
1500 return EVENT_RET_UNHANDLED;
1502 // OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
1503 OswaldState.screen_id = MESSAGE_SCREEN;
1504 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
1505 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
1506 return EVENT_RET_HANDLED;
1512 return EVENT_RET_UNHANDLED;
1515 event_ret_t messages_screen_handle_events(uint16_t event, void *data)
1518 case EVENT_SCREEN_VISIBLE:
1519 // messages_screen.pos = 0;
1520 // messages_screen.offset = 0;
1521 draw_messages_screen(&messages_screen);
1522 return EVENT_RET_HANDLED;
1524 case EVENT_USER_BUTTONS:
1525 dbg_out("button event %d\n", *(int *)data);
1526 return handle_messages_screen_buttons(*(watch_button *)data, &messages_screen);
1531 return EVENT_RET_UNHANDLED;