+ return EVENT_RET_HANDLED;
+ break;
+ default:
+ return EVENT_RET_UNHANDLED;
+ break;
+ };
+ return EVENT_RET_HANDLED;
+}
+
+
+/*
+ * Bluetooth setup screen
+ */
+typedef struct {
+ uint8_t pos;
+ boolean bt_en;
+ boolean set_mode;
+ boolean on;
+} bluetooth_data_t;
+static bluetooth_data_t bluetooth_screen = {
+ 0,
+ FALSE,
+ FALSE,
+ TRUE
+};
+
+void draw_bluetooth_screen(bluetooth_data_t *sdata)
+{
+ char bstr[20];
+ uint8_t *bd_addr;
+
+ hal_lcd_clear_display();
+
+ oswald_draw_bitmap(36, 0, Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits);
+
+ if (sdata->set_mode) {
+ oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
+ oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
+ oswald_draw_bitmap(81, 70, rightbutton_icon_width, rightbutton_icon_height, rightbutton_icon_bits);
+ } else {
+ oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
+ }
+
+ oswald_write_string(1, 30, FONT_DROID8x12, FALSE, "Enable:");
+ if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
+ if (bluetooth_screen.bt_en)
+ oswald_draw_bitmap(53, 33, checked_icon_width, checked_icon_height, checked_icon_bits);
+ else
+ oswald_draw_bitmap(53, 33, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
+ }
+ oswald_write_string(1, 40, FONT_DROID8x12, FALSE, "State:");
+ switch (hal_bluetooth_get_state()) {
+ case BLUETOOTH_OFF:
+ oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "off");
+ break;
+ case BLUETOOTH_ON:
+ oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "on");
+ break;
+ case BLUETOOTH_CONNECTED:
+ oswald_write_string(53, 40, FONT_DROID8x12, FALSE, "conn.");
+ break;
+ default:
+ break;
+ };
+ oswald_write_string(1, 50, FONT_DROID8x12, FALSE, "Visible:");
+ if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
+ // oswald_write_character(53, 50, FONT_DROID8x12, hal_bluetooth_get_visible() ? 'x' : '_');
+ if (hal_bluetooth_get_visible())
+ oswald_draw_bitmap(53, 53, checked_icon_width, checked_icon_height, checked_icon_bits);
+ else
+ oswald_draw_bitmap(53, 53, unchecked_icon_width, unchecked_icon_height, unchecked_icon_bits);
+ }
+
+ if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
+ bd_addr = hal_bluetooth_get_local_bdaddr();
+ 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]);
+ oswald_write_string(2, 85, FONT_5x7, FALSE, bstr);
+ } else {
+ }
+
+ hal_lcd_update_display();
+}
+
+void bluetooth_handle_updown(uint8_t pos, int8_t incr)
+{
+ switch (pos) {
+ case 0:
+ if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
+ hal_bluetooth_set_state(BLUETOOTH_OFF);
+ bluetooth_screen.bt_en = FALSE;
+ } else {
+ hal_bluetooth_set_state(BLUETOOTH_ON);
+ bluetooth_screen.bt_en = TRUE;
+ }
+ break;
+ case 1:
+ if (hal_bluetooth_get_state() >= BLUETOOTH_ON && !hal_bluetooth_get_visible()) {
+ hal_bluetooth_set_visible(TRUE);
+ } else {
+ hal_bluetooth_set_visible(FALSE);
+ }
+ break;
+ default:
+ break;
+ };
+}
+
+event_ret_t handle_bluetooth_buttons(watch_button button, bluetooth_data_t *sdata)
+{
+ if (bluetooth_screen.set_mode) {
+ switch (button) {
+ case BUTTON_A:
+ bluetooth_handle_updown(sdata->pos, 1);
+ break;
+ case BUTTON_B:
+ bluetooth_handle_updown(sdata->pos, -1);
+ break;
+ case BUTTON_C:
+ sdata->pos++;
+ sdata->pos %= 2;
+ break;
+ case BUTTON_F:
+ bluetooth_screen.set_mode = FALSE;
+ break;
+ default:
+ return EVENT_RET_UNHANDLED;
+ break;
+ }
+ } else {
+ switch (button) {
+ case BUTTON_F:
+ bluetooth_screen.set_mode = TRUE;
+ break;
+ default:
+ return EVENT_RET_UNHANDLED;
+ break;
+ }
+ }
+
+ draw_bluetooth_screen(sdata);
+
+ return EVENT_RET_HANDLED;
+}
+
+event_ret_t bluetooth_screen_events(uint16_t event, void *data)
+{
+ switch (event) {
+ case EVENT_SCREEN_VISIBLE:
+ bluetooth_screen.pos = 0;
+ bluetooth_screen.bt_en = (hal_bluetooth_get_state() > 0);
+ draw_bluetooth_screen(&bluetooth_screen);
+ hal_enable_halfsecond_timer();
+ break;
+ case EVENT_SCREEN_DESTROY:
+ hal_disable_halfsecond_timer();
+ break;
+ case EVENT_USER_BUTTONS:
+ dbg_out("button event %d\n", *(int *)data);
+ return handle_bluetooth_buttons(*(watch_button *)data, &bluetooth_screen);
+ break;
+ case EVENT_HALF_SEC_TIMER:
+ if (bluetooth_screen.set_mode) {
+ if (bluetooth_screen.on)
+ bluetooth_screen.on = FALSE;
+ else
+ bluetooth_screen.on = TRUE;
+ } else
+ bluetooth_screen.on = TRUE;
+ draw_bluetooth_screen(&bluetooth_screen);
+ break;
+ default:
+ return EVENT_RET_UNHANDLED;
+ break;
+ };
+ return EVENT_RET_HANDLED;
+}
+
+
+/*
+ * Info Screen
+ */
+void draw_info_screen(void)
+{
+ hal_lcd_clear_display();
+
+ oswald_draw_bitmap(36, 0, info_icon_width, info_icon_height, info_icon_bits);
+
+ oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
+
+ oswald_write_string(2, 29, FONT_DROID8x12, FALSE, "Oswald");
+ oswald_write_string(35, 29, FONT_DROID8x12, FALSE, OSWALD_VERSION);
+ oswald_write_string(2, 41, FONT_DROID8x12, FALSE, "HAL");
+ oswald_write_string(35, 41, FONT_DROID8x12, FALSE, (char *)hal_get_version_string());
+ oswald_write_string(2, 53, FONT_DROID8x12, FALSE, "Build");
+ oswald_write_string(35, 53, FONT_DROID8x12, FALSE, (char *)hal_get_buildno_string());
+ oswald_write_string(2, 65, FONT_DROID8x12, FALSE, "Radio");
+ oswald_write_string(35, 65, FONT_DROID8x12, FALSE, (char *)hal_get_radio_version_string());
+
+ hal_lcd_update_display();
+}
+
+event_ret_t info_screen_handle_events(uint16_t event, void *data)
+{
+ switch (event) {
+ case EVENT_SCREEN_VISIBLE:
+ draw_info_screen();
+ return EVENT_RET_HANDLED;
+ break;
+ case EVENT_USER_BUTTONS:
+ dbg_out("button event %d\n", *(int *)data);
+ break;
+ default:
+ return EVENT_RET_UNHANDLED;
+ break;
+ };
+ return EVENT_RET_UNHANDLED;
+}
+
+
+/*
+ * Messages Screens
+ */
+typedef struct {
+ int8_t pos; // marker position
+ int8_t offset; // offset in msg list
+} messages_data_t;
+static messages_data_t messages_screen = {
+ 0,
+ 0,
+};
+
+typedef struct {
+ uint8_t day;
+ uint8_t month;
+ uint8_t year; // without century, add +1900
+ uint8_t hour;
+ uint8_t minute;
+} msg_timedate_t;
+
+#define MSG_TYPE_READ 0
+#define MSG_TYPE_NEW 1
+#define MSG_TYPE_END 127
+
+typedef struct {
+ uint8_t type;
+ msg_timedate_t td;
+ char *msg;
+} message_t;
+
+uint8_t Msgs = 15;
+message_t Msg[] = {
+ { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
+ { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
+ { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
+ { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
+ { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
+ { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
+ { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
+ { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
+ { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
+ { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
+ { MSG_TYPE_READ, {9,5,113,0,38}, "Testmessage with more text than fits into the menu." },
+ { MSG_TYPE_NEW, {9,5,113,0,39}, "Sitting in the train waiting to arrive." },
+ { MSG_TYPE_READ, {9,5,113,0,40}, "People in the train are annoying!" },
+ { MSG_TYPE_READ, {9,5,113,0,40}, "Auch auf Deutsch geht das hier und Text können lang sein." },
+ { MSG_TYPE_NEW, {8,5,113,0,40}, "Und hier noch eine neue Nachricht, die nun wirklich lang ist, laenger als die anderen." },
+ { MSG_TYPE_END, {0,0,0,0,0}, "Exit" },
+};
+
+void draw_message_screen(messages_data_t *sdata)
+{
+ char dstr[32];
+ uint8_t strpos, msglen;
+ uint8_t line;
+
+ hal_lcd_clear_display();
+
+#if 0
+ oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
+ oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
+#endif
+ oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
+
+ Msg[sdata->offset + sdata->pos].type = MSG_TYPE_READ;
+ snprintf(dstr, 19, "#%02d/%02d", sdata->pos + sdata->offset + 1, Msgs);
+ oswald_write_string(30, 0, FONT_5x7, FALSE, dstr);
+ oswald_draw_line(0,7,95,7);
+
+
+ // here goes the text
+ msglen = strlen(Msg[sdata->pos+sdata->offset].msg);
+ strpos=0;
+ line=0;
+ while ((strpos < msglen) && (line < 6)) {
+ strpos += oswald_write_string_length(4, 9+(line*12), 84, FONT_DROID8x12, FALSE, &Msg[sdata->pos+sdata->offset].msg[strpos]);
+ line++;
+ }
+
+
+ oswald_draw_line(0,87,95,87);
+
+ if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
+ 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);
+ oswald_write_string(2, 89, FONT_5x7, FALSE, dstr);
+ }
+
+ hal_lcd_update_display();
+}
+
+event_ret_t handle_message_screen_buttons(watch_button button, messages_data_t *sdata)
+{
+ switch (button) {
+ case BUTTON_A:
+ break;
+ case BUTTON_B:
+ return EVENT_RET_HANDLED;
+ break;
+ case BUTTON_C:
+ // OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
+ OswaldState.screen_id = MESSAGES_SCREEN;
+ OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
+ OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
+ return EVENT_RET_HANDLED;
+ break;
+ default:
+ break;
+ }
+
+ return EVENT_RET_UNHANDLED;
+}
+
+event_ret_t message_screen_handle_events(uint16_t event, void *data)
+{
+ switch (event) {
+ case EVENT_SCREEN_VISIBLE:
+ draw_message_screen(&messages_screen);
+ return EVENT_RET_HANDLED;
+ break;
+ case EVENT_USER_BUTTONS:
+ dbg_out("button event %d\n", *(int *)data);
+ return handle_message_screen_buttons(*(watch_button *)data, &messages_screen);
+ break;
+ default:
+ break;
+ };
+ return EVENT_RET_UNHANDLED;
+}
+
+void draw_messages_screen(messages_data_t *sdata)
+{
+ char dstr[32];
+ int i;
+
+ hal_lcd_clear_display();
+
+ // oswald_draw_bitmap(36, 0, Message_icon_width, Message_icon_height, Message_icon_bits);
+
+ oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
+ oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
+ oswald_draw_bitmap(81, 70, enterbutton_icon_width, enterbutton_icon_height, enterbutton_icon_bits);
+
+ if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
+ snprintf(dstr, 19, "#%02d/%02d", sdata->pos + sdata->offset + 1, Msgs);
+ oswald_write_string(30, 0, FONT_5x7, FALSE, dstr);
+ }
+ oswald_draw_line(0,7,95,7);
+
+ for (i=0; i<6; i++) {
+ if (Msg[i+sdata->offset].type != MSG_TYPE_END) {
+ //oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12, (Msg[i+sdata->offset].type == MSG_TYPE_NEW), Msg[i+sdata->offset].msg);
+ if (Msg[i+sdata->offset].type == MSG_TYPE_NEW)
+ oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12b, (i+sdata->offset) == (sdata->offset + sdata->pos), Msg[i+sdata->offset].msg);
+ else
+ oswald_write_string_length(4, 9+(i*12), 84, FONT_DROID8x12, (i+sdata->offset) == (sdata->offset + sdata->pos), Msg[i+sdata->offset].msg);
+ } else {
+ oswald_draw_bitmap(0, 66, leftbutton_icon_width, leftbutton_icon_height, leftbutton_icon_bits);
+ }
+ }
+
+ // marker selected msg
+ oswald_draw_line(1,9,1,81);
+ oswald_draw_line_ww(1,10+(sdata->pos*12),1,20+(sdata->pos*12),2);
+
+ oswald_draw_line(0,87,95,87);
+
+ if (Msg[sdata->offset + sdata->pos].type != MSG_TYPE_END) {
+ 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);
+ oswald_write_string(2, 89, FONT_5x7, FALSE, dstr);
+ }
+
+ hal_lcd_update_display();
+}
+
+event_ret_t handle_messages_screen_buttons(watch_button button, messages_data_t *sdata)
+{
+ switch (button) {
+ case BUTTON_A:
+ sdata->pos--;
+ if (sdata->pos < 0) {
+ if (sdata->offset > 0) {
+ sdata->pos = 0;
+ sdata->offset--;
+ if (sdata->offset < 0)
+ sdata->offset = 0;
+ } else {
+ sdata->pos = 5;
+ sdata->offset = (Msgs - 5);
+ if (sdata->offset < 0)
+ sdata->offset = 0;
+ }
+ }
+ draw_messages_screen(&messages_screen);
+ return EVENT_RET_HANDLED;
+ break;
+ case BUTTON_B:
+ sdata->pos++;
+ if (sdata->pos > 5) {
+ sdata->pos = 5;
+ sdata->offset++;
+ if ((sdata->offset + 5) > Msgs) {
+ sdata->offset = 0;
+ sdata->pos = 0;
+ }
+ }
+ draw_messages_screen(&messages_screen);
+ return EVENT_RET_HANDLED;
+ break;
+ case BUTTON_C:
+ if (Msg[sdata->offset + sdata->pos].type == MSG_TYPE_END)
+ return EVENT_RET_UNHANDLED;
+ else
+ // OswaldState.screen->event_func(EVENT_SCREEN_DESTROY, NULL);
+ OswaldState.screen_id = MESSAGE_SCREEN;
+ OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
+ OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
+ return EVENT_RET_HANDLED;
+ break;
+ default:
+ break;
+ }
+
+ return EVENT_RET_UNHANDLED;
+}
+
+event_ret_t messages_screen_handle_events(uint16_t event, void *data)
+{
+ switch (event) {
+ case EVENT_SCREEN_VISIBLE:
+// messages_screen.pos = 0;
+// messages_screen.offset = 0;
+ draw_messages_screen(&messages_screen);
+ return EVENT_RET_HANDLED;
+ break;
+ case EVENT_USER_BUTTONS:
+ dbg_out("button event %d\n", *(int *)data);
+ return handle_messages_screen_buttons(*(watch_button *)data, &messages_screen);