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 3
194 #define MAIN_MENU_OFFSET_Y 10
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);
240 hal_lcd_update_display();
243 event_ret_t handle_main_menu_buttons(watch_button button, main_menu_data_t *sdata)
248 if (sdata->pos > LAST_SCREEN)
250 draw_main_menu_screen(&main_menu_screen);
251 return EVENT_RET_HANDLED;
256 sdata->pos = LAST_SCREEN;
257 draw_main_menu_screen(&main_menu_screen);
258 return EVENT_RET_HANDLED;
261 if (sdata->pos < LAST_SCREEN) {
262 OswaldState.screen_id = sdata->pos;
263 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
264 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
266 OswaldState.screen_id = IDLE_SCREEN;
267 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
268 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
270 return EVENT_RET_HANDLED;
276 return EVENT_RET_UNHANDLED;
279 /* after MAIN_MENU_TIMEOUT seconds return to IDLE_SCREEN */
280 #define MAIN_MENU_TIMEOUT 10
282 event_ret_t main_menu_handle_events(uint16_t event, void *data)
285 case EVENT_SCREEN_VISIBLE:
286 main_menu_screen.tmo = 0;
287 main_menu_screen.pos = 2;
288 draw_main_menu_screen(&main_menu_screen);
289 return EVENT_RET_HANDLED;
291 case EVENT_USER_BUTTONS:
292 dbg_out("button event %d\n", *(int *)data);
293 main_menu_screen.tmo = 0;
294 return handle_main_menu_buttons(*(watch_button *)data, &main_menu_screen);
296 case EVENT_ONE_SEC_TIMER:
297 main_menu_screen.tmo++;
298 if (main_menu_screen.tmo > MAIN_MENU_TIMEOUT) {
299 OswaldState.screen_id = IDLE_SCREEN;
300 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
301 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
303 return EVENT_RET_HANDLED;
307 return EVENT_RET_UNHANDLED;
312 * Accelerometer and sensor display screen
315 accel_data_t accdata;
316 } accelscreen_data_t;
317 static accelscreen_data_t accel_screen = {
321 void draw_accel_screen(accel_data_t *accel_data)
325 hal_lcd_clear_display();
327 oswald_draw_bitmap(36, 0, acc_icon_width, acc_icon_height, acc_icon_bits);
329 oswald_draw_bitmap(81, 79, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
331 oswald_write_string(1, 40, FONT_6x9, FALSE, "X:");
332 oswald_write_number(15, 40, FONT_6x9, FALSE, accel_data->x);
333 oswald_write_string(1, 52, FONT_6x9, FALSE, "Y:");
334 oswald_write_number(15, 52, FONT_6x9, FALSE, accel_data->y);
335 oswald_write_string(1, 64, FONT_6x9, FALSE, "Z:");
336 oswald_write_number(15, 64, FONT_6x9, FALSE, accel_data->z);
338 oswald_write_string(1, 85, FONT_6x9, FALSE, "Light:");
339 oswald_write_number(50, 85, FONT_6x9, FALSE, 0);
341 oswald_draw_line(40, 30, 92, 30);
342 oswald_draw_line(92, 30, 92, 82);
343 oswald_draw_line(40, 82, 92, 82);
344 oswald_draw_line(40, 82, 40, 30);
346 x = 41+25+((accel_data->x * 50) / (254));
347 y = 31+25-((accel_data->y * 50) / (254));
348 oswald_draw_pixel(x, y, TRUE);
349 oswald_draw_pixel(x+1, y, TRUE);
350 oswald_draw_pixel(x-1, y, TRUE);
351 oswald_draw_pixel(x, y+1, TRUE);
352 oswald_draw_pixel(x, y-1, TRUE);
354 hal_lcd_update_display();
357 event_ret_t accel_handle_events(uint16_t event, void *data)
360 case EVENT_SCREEN_VISIBLE:
361 draw_accel_screen(&accel_screen.accdata);
362 hal_accelerometer_enable();
363 return EVENT_RET_HANDLED;
365 case EVENT_SCREEN_DESTROY:
366 hal_accelerometer_disable();
367 return EVENT_RET_HANDLED;
369 case EVENT_ACCEL_UPDATE: {
370 accel_data_t *accel_data = (accel_data_t *)data;
371 accel_screen.accdata.x = accel_data->x;
372 accel_screen.accdata.y = accel_data->y;
373 accel_screen.accdata.z = accel_data->z;
374 draw_accel_screen(&accel_screen.accdata);
376 return EVENT_RET_HANDLED;
378 case EVENT_USER_BUTTONS:
379 dbg_out("button event %d\n", *(int *)data);
382 return EVENT_RET_UNHANDLED;
385 return EVENT_RET_UNHANDLED;
390 * Date / time setup screen
396 } datetime_setup_data_t;
397 static datetime_setup_data_t dt_setup_screen = {
403 void draw_datetime_setup_screen(datetime_setup_data_t *sdata)
405 hal_lcd_clear_display();
407 oswald_draw_bitmap(36, 0, timesetup_icon_width, timesetup_icon_height, timesetup_icon_bits);
409 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
410 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
411 oswald_draw_bitmap(81, 70, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
413 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
414 oswald_write_character(2, 30, FONT_LCD13x21, FALSE, (OswaldClk.hour / 10));
415 oswald_write_character(15, 30, FONT_LCD13x21, FALSE, (OswaldClk.hour % 10));
417 oswald_write_character(25, 30, FONT_LCD13x21, FALSE, 10);
419 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
420 oswald_write_character(34, 30, FONT_LCD13x21, FALSE, (OswaldClk.minute / 10));
421 oswald_write_character(47, 30, FONT_LCD13x21, FALSE, (OswaldClk.minute % 10));
424 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
425 oswald_write_character(61, 38, FONT_LCD8x13, FALSE, (OswaldClk.second / 10));
426 oswald_write_character(69, 38, FONT_LCD8x13, FALSE, (OswaldClk.second % 10));
430 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
431 oswald_write_number(2, 55, FONT_DROID8x12, FALSE, OswaldClk.day);
433 oswald_write_character(15, 55, FONT_DROID8x12, FALSE, '.');
434 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
435 oswald_write_number(21, 55, FONT_DROID8x12, FALSE, OswaldClk.month);
437 oswald_write_character(36, 55, FONT_DROID8x12, FALSE, '.');
438 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
439 oswald_write_number(43, 55, FONT_DROID8x12, FALSE, OswaldClk.year);
442 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
443 if (OswaldClk.clk24hr) {
444 oswald_draw_bitmap(2, 76, checked_icon_width, checked_icon_height, checked_icon_bits);
446 oswald_draw_bitmap(2, 76, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
449 oswald_write_string(15, 73, FONT_DROID8x12, FALSE, "24hr");
451 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
452 if (OswaldClk.day_first) {
453 oswald_draw_bitmap(2, 86, checked_icon_width, checked_icon_height, checked_icon_bits);
455 oswald_draw_bitmap(2, 86, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
458 oswald_write_string(15, 83, FONT_DROID8x12, FALSE, "dd.mm. mm/dd");
460 hal_lcd_update_display();
463 void datetime_handle_updown(uint8_t pos, int8_t incr)
467 if (OswaldClk.hour == 0 && incr == -1) {
471 OswaldClk.hour += incr;
472 if (OswaldClk.hour > 23)
476 if (OswaldClk.minute == 0 && incr == -1) {
477 OswaldClk.minute = 59;
480 OswaldClk.minute += incr;
481 if (OswaldClk.minute > 59)
482 OswaldClk.minute = 0;
485 OswaldClk.second = 0;
488 if (OswaldClk.day == 1 && incr == -1) {
492 OswaldClk.day += incr;
493 if (OswaldClk.day > 31)
497 if (OswaldClk.month == 1 && incr == -1) {
498 OswaldClk.month = 12;
501 OswaldClk.month += incr;
502 if (OswaldClk.month > 12)
506 OswaldClk.year += incr;
508 case 6: // 24hr / 12hr
509 if (OswaldClk.clk24hr)
510 OswaldClk.clk24hr = FALSE;
512 OswaldClk.clk24hr = TRUE;
514 case 7: // dd.mm. / mm/dd
515 if (OswaldClk.day_first)
516 OswaldClk.day_first = FALSE;
518 OswaldClk.day_first = TRUE;
524 hal_set_rtc(&OswaldClk, TRUE);
526 hal_set_rtc(&OswaldClk, FALSE);
529 event_ret_t handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata)
533 datetime_handle_updown(sdata->pos, 1);
536 datetime_handle_updown(sdata->pos, -1);
543 OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
544 OswaldState.screen_id = IDLE_SCREEN;
545 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
546 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
547 return EVENT_RET_HANDLED;
550 return EVENT_RET_UNHANDLED;
553 draw_datetime_setup_screen(sdata);
554 return EVENT_RET_HANDLED;
557 event_ret_t datetime_setup_events(uint16_t event, void *data)
560 case EVENT_SCREEN_VISIBLE:
561 dt_setup_screen.pos = 0;
562 draw_datetime_setup_screen(&dt_setup_screen);
563 hal_enable_halfsecond_timer();
564 return EVENT_RET_HANDLED;
566 case EVENT_SCREEN_DESTROY:
567 hal_disable_halfsecond_timer();
568 return EVENT_RET_HANDLED;
570 case EVENT_USER_BUTTONS:
571 dbg_out("button event %d\n", *(int *)data);
572 return handle_setup_datetime_buttons(*(watch_button *)data, &dt_setup_screen);
574 case EVENT_HALF_SEC_TIMER:
575 if (dt_setup_screen.on)
576 dt_setup_screen.on = FALSE;
578 dt_setup_screen.on = TRUE;
579 draw_datetime_setup_screen(&dt_setup_screen);
580 return EVENT_RET_HANDLED;
583 return EVENT_RET_UNHANDLED;
586 return EVENT_RET_UNHANDLED;
597 } alarm_setup_data_t;
598 static alarm_setup_data_t alarm_setup_screen = {
604 void draw_alarm_setup_screen(alarm_setup_data_t *sdata)
606 hal_lcd_clear_display();
608 oswald_draw_bitmap(36, 0, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
610 if (sdata->set_mode) {
611 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
612 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
613 oswald_draw_bitmap(81, 70, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
615 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
618 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
619 oswald_write_character(18, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.hour / 10));
620 oswald_write_character(32, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.hour % 10));
622 oswald_write_character(42, 30, FONT_LCD13x21, FALSE, 10);
624 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
625 oswald_write_character(53, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.minute / 10));
626 oswald_write_character(67, 30, FONT_LCD13x21, FALSE, (OswaldAlarm.minute % 10));
629 oswald_write_character(3, 55, FONT_6x9, FALSE, 'S');
630 oswald_write_character(15, 55, FONT_6x9, FALSE, 'M');
631 oswald_write_character(27, 55, FONT_6x9, FALSE, 'T');
632 oswald_write_character(39, 55, FONT_6x9, FALSE, 'W');
633 oswald_write_character(51, 55, FONT_6x9, FALSE, 'T');
634 oswald_write_character(63, 55, FONT_6x9, FALSE, 'F');
635 oswald_write_character(75, 55, FONT_6x9, FALSE, 'S');
637 if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
638 // oswald_write_character(3, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_');
639 if ((OswaldAlarm.wday & WDAY_SUNDAY))
640 oswald_draw_bitmap(3, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
642 oswald_draw_bitmap(3, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
644 if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
645 // oswald_write_character(15, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_');
646 if ((OswaldAlarm.wday & WDAY_MONDAY))
647 oswald_draw_bitmap(15, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
649 oswald_draw_bitmap(15, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
651 if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
652 // oswald_write_character(27, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_');
653 if ((OswaldAlarm.wday & WDAY_TUESDAY))
654 oswald_draw_bitmap(27, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
656 oswald_draw_bitmap(27, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
658 if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
659 // oswald_write_character(39, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_');
660 if ((OswaldAlarm.wday & WDAY_WEDNESDAY))
661 oswald_draw_bitmap(39, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
663 oswald_draw_bitmap(39, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
665 if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
666 // oswald_write_character(51, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_');
667 if ((OswaldAlarm.wday & WDAY_THURSDAY))
668 oswald_draw_bitmap(51, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
670 oswald_draw_bitmap(51, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
672 if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
673 // oswald_write_character(63, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_');
674 if ((OswaldAlarm.wday & WDAY_FRIDAY))
675 oswald_draw_bitmap(63, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
677 oswald_draw_bitmap(63, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
679 if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8) {
680 // oswald_write_character(75, 65, FONT_6x9, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_');
681 if ((OswaldAlarm.wday & WDAY_SATURDAY))
682 oswald_draw_bitmap(75, 66, checked_icon_width, checked_icon_height, checked_icon_bits);
684 oswald_draw_bitmap(75, 66, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
687 hal_lcd_update_display();
690 void alarm_handle_updown(uint8_t pos, int8_t incr)
694 if (OswaldAlarm.hour == 0 && incr == -1) {
695 OswaldAlarm.hour = 23;
698 OswaldAlarm.hour += incr;
699 if (OswaldAlarm.hour > 23)
700 OswaldAlarm.hour = 0;
703 if (OswaldAlarm.minute == 0 && incr == -1) {
704 OswaldAlarm.minute = 59;
707 OswaldAlarm.minute += incr;
708 if (OswaldAlarm.minute > 59)
709 OswaldAlarm.minute = 0;
712 OswaldAlarm.wday ^= WDAY_SUNDAY;
715 OswaldAlarm.wday ^= WDAY_MONDAY;
718 OswaldAlarm.wday ^= WDAY_TUESDAY;
721 OswaldAlarm.wday ^= WDAY_WEDNESDAY;
724 OswaldAlarm.wday ^= WDAY_THURSDAY;
727 OswaldAlarm.wday ^= WDAY_FRIDAY;
730 OswaldAlarm.wday ^= WDAY_SATURDAY;
737 event_ret_t handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata)
739 if (alarm_setup_screen.set_mode) {
742 alarm_handle_updown(sdata->pos, 1);
745 alarm_handle_updown(sdata->pos, -1);
752 alarm_setup_screen.set_mode = FALSE;
755 return EVENT_RET_UNHANDLED;
761 alarm_setup_screen.set_mode = TRUE;
764 return EVENT_RET_UNHANDLED;
768 draw_alarm_setup_screen(sdata);
770 return EVENT_RET_HANDLED;
773 event_ret_t alarm_setup_events(uint16_t event, void *data)
776 case EVENT_SCREEN_VISIBLE:
777 alarm_setup_screen.pos = 0;
778 alarm_setup_screen.on = TRUE;
779 alarm_setup_screen.set_mode = FALSE;
780 draw_alarm_setup_screen(&alarm_setup_screen);
781 hal_enable_halfsecond_timer();
782 return EVENT_RET_HANDLED;
784 case EVENT_SCREEN_DESTROY:
785 hal_disable_halfsecond_timer();
786 return EVENT_RET_HANDLED;
788 case EVENT_USER_BUTTONS:
789 dbg_out("button event %d\n", *(int *)data);
790 return handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen);
792 case EVENT_HALF_SEC_TIMER:
793 if (alarm_setup_screen.set_mode) {
794 if (alarm_setup_screen.on)
795 alarm_setup_screen.on = FALSE;
797 alarm_setup_screen.on = TRUE;
799 alarm_setup_screen.on = TRUE;
800 draw_alarm_setup_screen(&alarm_setup_screen);
801 return EVENT_RET_HANDLED;
804 return EVENT_RET_UNHANDLED;
807 return EVENT_RET_UNHANDLED;
817 static test_menu_t test_menu = { 0 };
819 void draw_menu_test_screen(void)
821 hal_lcd_clear_display();
823 SetFont(MetaWatch16);
824 WriteLcdString(2, 2, "Menu");
826 WriteLcdString(2, 20, "Item 1");
827 WriteLcdString(2, 29, "Item 2");
828 WriteLcdString(2, 38, "Item 3");
829 WriteLcdString(2, 47, "Item 4");
830 WriteLcdString(2, 56, "Item 5");
832 WriteLcdString(50, 20+(9*test_menu.menu_pos), "*");
834 oswald_write_string(2, 2, FONT_DROID8x12, FALSE, "Menu");
836 oswald_write_string(2, 20, FONT_DROID8x12, FALSE, "Item 1");
837 oswald_write_string(2, 29, FONT_DROID8x12, FALSE, "Item 2");
838 oswald_write_string(2, 38, FONT_DROID8x12, FALSE, "Item 3");
839 oswald_write_string(2, 47, FONT_DROID8x12, FALSE, "Item 4");
840 oswald_write_string(2, 56, FONT_DROID8x12, FALSE, "Item 5");
842 oswald_write_character(50, 18+(9*test_menu.menu_pos), FONT_6x9, FALSE, 0x11);
844 hal_lcd_update_display();
847 event_ret_t handle_menu_user_buttons(watch_button button)
851 test_menu.menu_pos--;
852 test_menu.menu_pos %= 5;
855 test_menu.menu_pos++;
856 test_menu.menu_pos %= 5;
859 return EVENT_RET_UNHANDLED;
862 draw_menu_test_screen();
863 return EVENT_RET_HANDLED;
866 event_ret_t test_menu_handle_events(uint16_t event, void *data)
869 case EVENT_USER_BUTTONS:
870 dbg_out("button event %d\n", *(int *)data);
871 return handle_menu_user_buttons(*(watch_button *)data);
873 case EVENT_SCREEN_VISIBLE:
874 test_menu.menu_pos = 0;
875 draw_menu_test_screen();
878 return EVENT_RET_UNHANDLED;
881 return EVENT_RET_HANDLED;
899 static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE };
902 static void draw_stop_watch_screen(stopwatch_data_t *sdata)
907 hal_lcd_clear_display();
909 oswald_draw_bitmap(36, 0, stopwatch_icon_width, stopwatch_icon_height, stopwatch_icon_bits);
911 oswald_draw_bitmap(81, 6, startstopbutton_icon_width, startstopbutton_icon_height, startstopbutton_icon_bits);
912 oswald_draw_bitmap(81, 38, lapsebutton_icon_width, lapsebutton_icon_height, lapsebutton_icon_bits);
913 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
915 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->hr % 10));
916 gRow += oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->min / 10));
917 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->min % 10));
918 gRow += oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->sec / 10));
919 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD13x21, FALSE, (sdata->sec % 10));
920 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->csec / 10));
924 gRow += 13 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_hr % 10));
925 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_min / 10));
926 gRow += 13 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_min % 10));
927 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_sec / 10));
928 gRow += 3 + oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_sec % 10));
929 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_csec / 10));
930 gRow += oswald_write_character(gRow, gColumn, FONT_LCD8x13, FALSE, (sdata->lapse_csec % 10));
932 hal_lcd_update_display();
935 event_ret_t handle_stop_watch_buttons(watch_button button)
938 case BUTTON_A: // start/stop
939 if (stopwatch_screen.running) {
940 hal_disable_centisecond_timer();
941 stopwatch_screen.running = FALSE;
943 hal_enable_centisecond_timer();
944 stopwatch_screen.running = TRUE;
946 return EVENT_RET_HANDLED;
948 case BUTTON_B: // lapse
949 stopwatch_screen.lapse_hr = stopwatch_screen.hr;
950 stopwatch_screen.lapse_min = stopwatch_screen.min;
951 stopwatch_screen.lapse_sec = stopwatch_screen.sec;
952 stopwatch_screen.lapse_csec = stopwatch_screen.csec;
953 return EVENT_RET_HANDLED;
955 case BUTTON_F: // reset
956 stopwatch_screen.hr = 0;
957 stopwatch_screen.min = 0;
958 stopwatch_screen.sec = 0;
959 stopwatch_screen.csec = 0;
960 stopwatch_screen.lapse_hr = 0;
961 stopwatch_screen.lapse_min = 0;
962 stopwatch_screen.lapse_sec = 0;
963 stopwatch_screen.lapse_csec = 0;
964 return EVENT_RET_HANDLED;
967 return EVENT_RET_UNHANDLED;
970 return EVENT_RET_UNHANDLED;
973 event_ret_t stop_watch_handle_events(uint16_t event, void *data)
976 case EVENT_USER_BUTTONS:
977 dbg_out("button event %d\n", *(int *)data);
978 draw_stop_watch_screen(&stopwatch_screen);
979 return handle_stop_watch_buttons(*(watch_button *)data);
981 case EVENT_SCREEN_VISIBLE:
982 draw_stop_watch_screen(&stopwatch_screen);
983 return EVENT_RET_HANDLED;
985 case EVENT_SCREEN_DESTROY:
986 hal_disable_centisecond_timer();
987 stopwatch_screen.running = FALSE;
988 return EVENT_RET_HANDLED;
991 stopwatch_screen.csec++;
992 if (stopwatch_screen.csec > 99) {
993 stopwatch_screen.csec = 0;
994 stopwatch_screen.sec++;
996 if (stopwatch_screen.sec > 59) {
997 stopwatch_screen.sec = 0;
998 stopwatch_screen.min++;
1000 if (stopwatch_screen.min > 59) {
1001 stopwatch_screen.min = 0;
1002 stopwatch_screen.hr++;
1004 if (stopwatch_screen.hr > 59) {
1005 stopwatch_screen.hr = 0;
1007 if (stopwatch_screen.csec % 10 == 0)
1008 draw_stop_watch_screen(&stopwatch_screen);
1009 //update_stop_watch_screen(&stopwatch_screen);
1010 return EVENT_RET_HANDLED;
1013 return EVENT_RET_UNHANDLED;
1016 return EVENT_RET_HANDLED;
1021 * Alarm screen, shown when alarm is fired
1023 void draw_alarm_screen(void)
1025 hal_lcd_clear_display();
1027 oswald_draw_bitmap(36, 20, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
1029 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1031 hal_lcd_update_display();
1034 event_ret_t alarm_handle_events(uint16_t event, void *data)
1037 case EVENT_SCREEN_VISIBLE:
1038 draw_alarm_screen();
1039 hal_enable_halfsecond_timer();
1040 hal_vibration_set_state(TRUE);
1041 return EVENT_RET_HANDLED;
1043 case EVENT_SCREEN_DESTROY:
1044 hal_disable_halfsecond_timer();
1045 hal_lcd_set_backlight(FALSE);
1046 hal_vibration_set_state(FALSE);
1047 return EVENT_RET_HANDLED;
1049 case EVENT_USER_BUTTONS:
1050 dbg_out("button event %d\n", *(int *)data);
1051 return EVENT_RET_UNHANDLED;
1053 case EVENT_HALF_SEC_TIMER:
1054 hal_lcd_set_backlight(!hal_lcd_get_backlight());
1055 hal_vibration_set_state(!hal_vibration_get_state());
1057 return EVENT_RET_HANDLED;
1060 return EVENT_RET_UNHANDLED;
1063 return EVENT_RET_HANDLED;
1068 * Bluetooth setup screen
1076 static bluetooth_data_t bluetooth_screen = {
1083 void draw_bluetooth_screen(bluetooth_data_t *sdata)
1088 hal_lcd_clear_display();
1090 oswald_draw_bitmap(36, 0, Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits);
1092 if (sdata->set_mode) {
1093 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
1094 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
1095 oswald_draw_bitmap(81, 70, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
1097 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1100 oswald_write_string(1, 30, FONT_DROID8x12, FALSE, "Enable:");
1101 if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
1102 if (bluetooth_screen.bt_en)
1103 oswald_draw_bitmap(53, 33, checked_icon_width, checked_icon_height, checked_icon_bits);
1105 oswald_draw_bitmap(53, 33, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
1107 oswald_write_string(1, 40, FONT_DROID8x12, FALSE, "State:");
1108 switch (hal_bluetooth_get_state()) {
1110 oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "off");
1113 oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "on");
1115 case BLUETOOTH_CONNECTED:
1116 oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "conn.");
1121 oswald_write_string(1, 50, FONT_DROID8x12, FALSE, "Visible:");
1122 if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
1123 // oswald_write_character(53, 50, FONT_DROID8x12, hal_bluetooth_get_visible() ? 'x' : '_');
1124 if (hal_bluetooth_get_visible())
1125 oswald_draw_bitmap(53, 53, checked_icon_width, checked_icon_height, checked_icon_bits);
1127 oswald_draw_bitmap(53, 53, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
1130 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
1131 bd_addr = hal_bluetooth_get_local_bdaddr();
1132 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]);
1133 oswald_write_string(2, 85, FONT_5x7, FALSE, bstr);
1137 hal_lcd_update_display();
1140 void bluetooth_handle_updown(uint8_t pos, int8_t incr)
1144 if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
1145 hal_bluetooth_set_state(BLUETOOTH_OFF);
1146 bluetooth_screen.bt_en = FALSE;
1148 hal_bluetooth_set_state(BLUETOOTH_ON);
1149 bluetooth_screen.bt_en = TRUE;
1153 if (hal_bluetooth_get_state() >= BLUETOOTH_ON && !hal_bluetooth_get_visible()) {
1154 hal_bluetooth_set_visible(TRUE);
1156 hal_bluetooth_set_visible(FALSE);
1164 event_ret_t handle_bluetooth_buttons(watch_button button, bluetooth_data_t *sdata)
1166 if (bluetooth_screen.set_mode) {
1169 bluetooth_handle_updown(sdata->pos, 1);
1172 bluetooth_handle_updown(sdata->pos, -1);
1179 bluetooth_screen.set_mode = FALSE;
1182 return EVENT_RET_UNHANDLED;
1188 bluetooth_screen.set_mode = TRUE;
1191 return EVENT_RET_UNHANDLED;
1196 draw_bluetooth_screen(sdata);
1198 return EVENT_RET_HANDLED;
1201 event_ret_t bluetooth_screen_events(uint16_t event, void *data)
1204 case EVENT_SCREEN_VISIBLE:
1205 bluetooth_screen.pos = 0;
1206 bluetooth_screen.bt_en = (hal_bluetooth_get_state() > 0);
1207 draw_bluetooth_screen(&bluetooth_screen);
1208 hal_enable_halfsecond_timer();
1210 case EVENT_SCREEN_DESTROY:
1211 hal_disable_halfsecond_timer();
1213 case EVENT_USER_BUTTONS:
1214 dbg_out("button event %d\n", *(int *)data);
1215 return handle_bluetooth_buttons(*(watch_button *)data, &bluetooth_screen);
1217 case EVENT_HALF_SEC_TIMER:
1218 if (bluetooth_screen.set_mode) {
1219 if (bluetooth_screen.on)
1220 bluetooth_screen.on = FALSE;
1222 bluetooth_screen.on = TRUE;
1224 bluetooth_screen.on = TRUE;
1225 draw_bluetooth_screen(&bluetooth_screen);
1228 return EVENT_RET_UNHANDLED;
1231 return EVENT_RET_HANDLED;
1238 void draw_info_screen(void)
1240 hal_lcd_clear_display();
1242 oswald_draw_bitmap(36, 0, info_icon_width, info_icon_height, info_icon_bits);
1244 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1246 oswald_write_string(2, 29, FONT_DROID8x12, FALSE, "Oswald");
1247 oswald_write_string(35, 29, FONT_DROID8x12, FALSE, OSWALD_VERSION);
1248 oswald_write_string(2, 41, FONT_DROID8x12, FALSE, "HAL");
1249 oswald_write_string(35, 41, FONT_DROID8x12, FALSE, (char *)hal_get_version_string());
1250 oswald_write_string(2, 53, FONT_DROID8x12, FALSE, "Build");
1251 oswald_write_string(35, 53, FONT_DROID8x12, FALSE, (char *)hal_get_buildno_string());
1252 oswald_write_string(2, 65, FONT_DROID8x12, FALSE, "Radio");
1253 oswald_write_string(35, 65, FONT_DROID8x12, FALSE, (char *)hal_get_radio_version_string());
1255 hal_lcd_update_display();
1258 event_ret_t info_screen_handle_events(uint16_t event, void *data)
1261 case EVENT_SCREEN_VISIBLE:
1263 return EVENT_RET_HANDLED;
1265 case EVENT_USER_BUTTONS:
1266 dbg_out("button event %d\n", *(int *)data);
1269 return EVENT_RET_UNHANDLED;
1272 return EVENT_RET_UNHANDLED;
1280 int8_t pos; // marker position
1281 int8_t offset; // offset in msg list
1283 static messages_data_t messages_screen = {
1291 uint8_t year; // without century, add +1900
1296 #define MSG_TYPE_READ 0
1297 #define MSG_TYPE_NEW 1
1298 #define MSG_TYPE_END 127
1308 { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
1309 { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
1310 { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
1311 { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
1312 { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
1313 { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
1314 { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
1315 { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
1316 { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
1317 { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
1318 { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
1319 { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
1320 { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
1321 { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
1322 { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
1323 { MSG_TYPE_END, {0,0,0,0,0}, "Exit" },
1326 void draw_message_screen(messages_data_t *sdata)
1329 uint8_t strpos, msglen;
1332 hal_lcd_clear_display();
1335 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
1336 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
1338 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1340 Msg[sdata->offset + sdata->pos].type = MSG_TYPE_READ;
1341 snprintf(dstr, 19, "#%02d/%02d", sdata->pos + sdata->offset + 1, Msgs);
1342 oswald_write_string(30, 0, FONT_5x7, FALSE, dstr);
1343 oswald_draw_line(0,7,95,7);
1346 // here goes the text
1347 msglen = strlen(Msg[sdata->pos+sdata->offset].msg);
1350 while ((strpos < msglen) && (line < 6)) {
1351 strpos += oswald_write_string_length(4, 9+(line*12), 84, FONT_DROID8x12, FALSE, &Msg[sdata->pos+sdata->offset].msg[strpos]);
1356 oswald_draw_line(0,87,95,87);
1358 if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
1359 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);
1360 oswald_write_string(2, 89, FONT_5x7, FALSE, dstr);
1363 hal_lcd_update_display();
1366 event_ret_t handle_message_screen_buttons(watch_button button, messages_data_t *sdata)
1372 return EVENT_RET_HANDLED;
1375 // OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
1376 OswaldState.screen_id = MESSAGES_SCREEN;
1377 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
1378 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
1379 return EVENT_RET_HANDLED;
1385 return EVENT_RET_UNHANDLED;
1388 event_ret_t message_screen_handle_events(uint16_t event, void *data)
1391 case EVENT_SCREEN_VISIBLE:
1392 draw_message_screen(&messages_screen);
1393 return EVENT_RET_HANDLED;
1395 case EVENT_USER_BUTTONS:
1396 dbg_out("button event %d\n", *(int *)data);
1397 return handle_message_screen_buttons(*(watch_button *)data, &messages_screen);
1402 return EVENT_RET_UNHANDLED;
1405 void draw_messages_screen(messages_data_t *sdata)
1410 hal_lcd_clear_display();
1412 // oswald_draw_bitmap(36, 0, Message_icon_width, Message_icon_height, Message_icon_bits);
1414 oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
1415 oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
1416 oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
1418 if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
1419 snprintf(dstr, 19, "#%02d/%02d", sdata->pos + sdata->offset + 1, Msgs);
1420 oswald_write_string(30, 0, FONT_5x7, FALSE, dstr);
1422 oswald_draw_line(0,7,95,7);
1424 for (i=0; i<6; i++) {
1425 if (Msg[i+sdata->offset].type != MSG_TYPE_END) {
1426 //oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12, (Msg[i+sdata->offset].type == MSG_TYPE_NEW), Msg[i+sdata->offset].msg);
1427 if (Msg[i+sdata->offset].type == MSG_TYPE_NEW)
1428 oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12b, (i+sdata->offset) == (sdata->offset + sdata->pos), Msg[i+sdata->offset].msg);
1430 oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12, (i+sdata->offset) == (sdata->offset + sdata->pos), Msg[i+sdata->offset].msg);
1432 oswald_draw_bitmap(0, 66, leftbutton_icon_width, leftbutton_icon_height, leftbutton_icon_bits);
1436 // marker selected msg
1437 oswald_draw_line(1,9,1,81);
1438 oswald_draw_line_ww(1,10+(sdata->pos*12),1,20+(sdata->pos*12),2);
1440 oswald_draw_line(0,87,95,87);
1442 if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
1443 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);
1444 oswald_write_string(2, 89, FONT_5x7, FALSE, dstr);
1447 hal_lcd_update_display();
1450 event_ret_t handle_messages_screen_buttons(watch_button button, messages_data_t *sdata)
1455 if (sdata->pos < 0) {
1456 if (sdata->offset > 0) {
1459 if (sdata->offset < 0)
1463 sdata->offset = (Msgs - 5);
1464 if (sdata->offset < 0)
1468 draw_messages_screen(&messages_screen);
1469 return EVENT_RET_HANDLED;
1473 if (sdata->pos > 5) {
1476 if ((sdata->offset + 5) > Msgs) {
1481 draw_messages_screen(&messages_screen);
1482 return EVENT_RET_HANDLED;
1485 if (Msg[sdata->offset + sdata->pos].type == MSG_TYPE_END)
1486 return EVENT_RET_UNHANDLED;
1488 // OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
1489 OswaldState.screen_id = MESSAGE_SCREEN;
1490 OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
1491 OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
1492 return EVENT_RET_HANDLED;
1498 return EVENT_RET_UNHANDLED;
1501 event_ret_t messages_screen_handle_events(uint16_t event, void *data)
1504 case EVENT_SCREEN_VISIBLE:
1505 // messages_screen.pos = 0;
1506 // messages_screen.offset = 0;
1507 draw_messages_screen(&messages_screen);
1508 return EVENT_RET_HANDLED;
1510 case EVENT_USER_BUTTONS:
1511 dbg_out("button event %d\n", *(int *)data);
1512 return handle_messages_screen_buttons(*(watch_button *)data, &messages_screen);
1517 return EVENT_RET_UNHANDLED;