diff options
Diffstat (limited to 'src/displayapp')
23 files changed, 692 insertions, 194 deletions
diff --git a/src/displayapp/icons/music/disc.cpp b/src/displayapp/icons/music/disc.cpp new file mode 100644 index 00000000..0957873f --- /dev/null +++ b/src/displayapp/icons/music/disc.cpp @@ -0,0 +1,110 @@ +/* Copyright (C) 2020 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "lvgl/lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_DISC +#define LV_ATTRIBUTE_IMG_DISC +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_DISC uint8_t disc_map[] = { + 0xbd, 0xc1, 0xbe, 0xff, /* Color of index 0: foreground */ + 0x00, 0x00, 0x00, 0x00, /* Color of index 1: background */ + + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0f, 0xf8, 0x07, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0xff, 0xff, 0x81, 0xff, 0xff, + 0xff, 0xff, 0x07, 0xff, 0xff, 0xf0, 0x7f, 0xff, + 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, + 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, + 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, + 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, + 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, + 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, + 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, + 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, + 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, + 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x8f, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xf8, + 0x9f, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe7, 0xf3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xe3, 0xe3, 0xff, 0xff, 0xfc, + 0x9f, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xfc, + 0x8f, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xf8, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, + 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, + 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, + 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, + 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, + 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, + 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, + 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, + 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, + 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xff, 0x07, 0xff, 0xff, 0xf0, 0x7f, 0xff, + 0xff, 0xff, 0xc0, 0xff, 0xff, 0x81, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0f, 0xf8, 0x07, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, +}; + +const lv_img_dsc_t disc = { + { + LV_IMG_CF_INDEXED_1BIT, + 0, + 0, + 64, + 64 + }, + 520, + disc_map +};
\ No newline at end of file diff --git a/src/displayapp/icons/music/disc.png b/src/displayapp/icons/music/disc.png Binary files differnew file mode 100644 index 00000000..699734fb --- /dev/null +++ b/src/displayapp/icons/music/disc.png diff --git a/src/displayapp/icons/music/disc_f_1.cpp b/src/displayapp/icons/music/disc_f_1.cpp new file mode 100644 index 00000000..9b6b7417 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_1.cpp @@ -0,0 +1,79 @@ +/* Copyright (C) 2020 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "lvgl/lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_DISC_F_1 +#define LV_ATTRIBUTE_IMG_DISC_F_1 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_DISC_F_1 uint8_t disc_f_1_map[] = { + 0xbd, 0xc1, 0xbe, 0xff, /* Color of index 0: foreground */ + 0x00, 0x00, 0x00, 0x00, /* Color of index 1: background */ + + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, + 0xff, 0xff, 0xf0, 0x0f, + 0xff, 0xff, 0xc0, 0xff, + 0xff, 0xff, 0x07, 0xff, + 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xf8, 0x7f, 0xff, + 0xff, 0xf0, 0xff, 0xff, + 0xff, 0xe3, 0xff, 0xff, + 0xff, 0xc7, 0xf3, 0xff, + 0xff, 0x8f, 0xc3, 0xff, + 0xff, 0x1f, 0x87, 0xff, + 0xfe, 0x3f, 0x0f, 0xff, + 0xfc, 0x7e, 0x1f, 0xff, + 0xfc, 0x7c, 0x3f, 0xff, + 0xf8, 0xfc, 0x7f, 0xff, + 0xf9, 0xfc, 0xff, 0xff, + 0xf1, 0xff, 0xff, 0xff, + 0xf3, 0xff, 0xff, 0xff, + 0xe3, 0xff, 0xff, 0xff, + 0xe7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xf8, + 0x9f, 0xff, 0xff, 0xf0, + 0x9f, 0xff, 0xff, 0xe3, + 0x9f, 0xff, 0xff, 0xe7, + 0x9f, 0xff, 0xff, 0xe7, +}; + +const lv_img_dsc_t disc_f_1 = { + { + LV_IMG_CF_INDEXED_1BIT, + 0, + 0, + 32, + 32 + }, + 136, + disc_f_1_map +}; + diff --git a/src/displayapp/icons/music/disc_f_1.png b/src/displayapp/icons/music/disc_f_1.png Binary files differnew file mode 100644 index 00000000..94657734 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_1.png diff --git a/src/displayapp/icons/music/disc_f_2.cpp b/src/displayapp/icons/music/disc_f_2.cpp new file mode 100644 index 00000000..3d2331d1 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_2.cpp @@ -0,0 +1,79 @@ +/* Copyright (C) 2020 Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ +#pragma once + +#include "lvgl/lvgl.h" + +#ifndef LV_ATTRIBUTE_MEM_ALIGN +#define LV_ATTRIBUTE_MEM_ALIGN +#endif + +#ifndef LV_ATTRIBUTE_IMG_DISC_F_2 +#define LV_ATTRIBUTE_IMG_DISC_F_2 +#endif + +const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_IMG_DISC_F_2 uint8_t disc_f_2_map[] = { + 0xbd, 0xc1, 0xbe, 0xff, /* Color of index 0: foreground */ + 0x00, 0x00, 0x00, 0x00, /* Color of index 1: background */ + + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, + 0xff, 0xff, 0xf0, 0x0f, + 0xff, 0xff, 0xc0, 0xff, + 0xff, 0xff, 0x07, 0xff, + 0xff, 0xfc, 0x1f, 0xff, + 0xff, 0xf8, 0x7f, 0xf1, + 0xff, 0xf0, 0xff, 0x00, + 0xff, 0xe3, 0xfc, 0x03, + 0xff, 0xc7, 0xf0, 0x3f, + 0xff, 0x8f, 0xf0, 0xff, + 0xff, 0x1f, 0xf3, 0xff, + 0xfe, 0x3f, 0xff, 0xff, + 0xfc, 0x7f, 0xff, 0xff, + 0xfc, 0x7f, 0xff, 0xff, + 0xf8, 0xff, 0xff, 0xff, + 0xf9, 0xff, 0xff, 0xff, + 0xf1, 0xff, 0xff, 0xff, + 0xf3, 0xff, 0xff, 0xff, + 0xe3, 0xff, 0xff, 0xff, + 0xe7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xc7, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xf8, + 0x9f, 0xff, 0xff, 0xf0, + 0x9f, 0xff, 0xff, 0xe3, + 0x9f, 0xff, 0xff, 0xe7, + 0x9f, 0xff, 0xff, 0xe7, +}; + +const lv_img_dsc_t disc_f_2 = { + { + LV_IMG_CF_INDEXED_1BIT, + 0, + 0, + 32, + 32 + }, + 136, + disc_f_2_map +}; + diff --git a/src/displayapp/icons/music/disc_f_2.png b/src/displayapp/icons/music/disc_f_2.png Binary files differnew file mode 100644 index 00000000..4d9a4a38 --- /dev/null +++ b/src/displayapp/icons/music/disc_f_2.png diff --git a/src/displayapp/screens/Brightness.cpp b/src/displayapp/screens/Brightness.cpp index 9e3416c0..8ea9a771 100644 --- a/src/displayapp/screens/Brightness.cpp +++ b/src/displayapp/screens/Brightness.cpp @@ -11,15 +11,15 @@ void slider_event_cb(lv_obj_t * slider, lv_event_t event) { } Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} { - slider = lv_slider_create(lv_scr_act(), NULL); + slider = lv_slider_create(lv_scr_act(), nullptr); lv_obj_set_user_data(slider, this); lv_obj_set_width(slider, LV_DPI * 2); - lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(slider, nullptr, LV_ALIGN_CENTER, 0, 0); lv_obj_set_event_cb(slider, slider_event_cb); lv_slider_set_range(slider, 0, 2); lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); - slider_label = lv_label_create(lv_scr_act(), NULL); + slider_label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(slider_label, LevelToString(brightness.Level())); lv_obj_set_auto_realign(slider_label, true); lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index eabab21a..977321c1 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -34,15 +34,15 @@ Clock::Clock(DisplayApp* app, displayedChar[3] = 0; displayedChar[4] = 0; - batteryIcon = lv_label_create(lv_scr_act(), NULL); + batteryIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryIcon, Symbols::batteryFull); lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2); - batteryPlug = lv_label_create(lv_scr_act(), NULL); + batteryPlug = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(batteryPlug, Symbols::plug); lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0); - bleIcon = lv_label_create(lv_scr_act(), NULL); + bleIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(bleIcon, Symbols::bluetooth); lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0); @@ -50,14 +50,15 @@ Clock::Clock(DisplayApp* app, lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false)); lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0); - label_date = lv_label_create(lv_scr_act(), NULL); + label_date = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); - label_time = lv_label_create(lv_scr_act(), NULL); + label_time = lv_label_create(lv_scr_act(), nullptr); lv_label_set_style(label_time, LV_LABEL_STYLE_MAIN, LabelBigStyle); lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0); - backgroundLabel = lv_label_create(lv_scr_act(), NULL); + backgroundLabel = lv_label_create(lv_scr_act(), nullptr); backgroundLabel->user_data = this; lv_obj_set_click(backgroundLabel, true); lv_obj_set_event_cb(backgroundLabel, event_handler); @@ -67,23 +68,23 @@ Clock::Clock(DisplayApp* app, lv_label_set_text(backgroundLabel, ""); - heartbeatIcon = lv_label_create(lv_scr_act(), NULL); + heartbeatIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatIcon, Symbols::heartBeat); lv_obj_align(heartbeatIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 5, -2); - heartbeatValue = lv_label_create(lv_scr_act(), NULL); + heartbeatValue = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatValue, "0"); lv_obj_align(heartbeatValue, heartbeatIcon, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - heartbeatBpm = lv_label_create(lv_scr_act(), NULL); + heartbeatBpm = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(heartbeatBpm, "BPM"); lv_obj_align(heartbeatBpm, heartbeatValue, LV_ALIGN_OUT_RIGHT_MID, 5, 0); - stepValue = lv_label_create(lv_scr_act(), NULL); + stepValue = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(stepValue, "0"); lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, -2); - stepIcon = lv_label_create(lv_scr_act(), NULL); + stepIcon = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(stepIcon, Symbols::shoe); lv_obj_align(stepIcon, stepValue, LV_ALIGN_OUT_LEFT_MID, -5, 0); } diff --git a/src/displayapp/screens/DropDownDemo.cpp b/src/displayapp/screens/DropDownDemo.cpp index 735a0cce..ce3acd53 100644 --- a/src/displayapp/screens/DropDownDemo.cpp +++ b/src/displayapp/screens/DropDownDemo.cpp @@ -9,7 +9,7 @@ extern lv_font_t jetbrains_mono_bold_20; DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp *app) : Screen(app) { // Create the dropdown object, with many item, and fix its height - ddlist = lv_ddlist_create(lv_scr_act(), NULL); + ddlist = lv_ddlist_create(lv_scr_act(), nullptr); lv_ddlist_set_options(ddlist, "Apple\n" "Banana\n" "Orange\n" @@ -24,7 +24,7 @@ DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp *app) : Screen(app lv_ddlist_set_fix_width(ddlist, 150); lv_ddlist_set_draw_arrow(ddlist, true); lv_ddlist_set_fix_height(ddlist, 150); - lv_obj_align(ddlist, NULL, LV_ALIGN_IN_TOP_MID, 0, 20); + lv_obj_align(ddlist, nullptr, LV_ALIGN_IN_TOP_MID, 0, 20); } DropDownDemo::~DropDownDemo() { diff --git a/src/displayapp/screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp index e831114d..778409eb 100644 --- a/src/displayapp/screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -10,19 +10,19 @@ extern lv_font_t jetbrains_mono_bold_20; FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Ble& bleController) : Screen(app), bleController{bleController} { - titleLabel = lv_label_create(lv_scr_act(), NULL); + titleLabel = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(titleLabel, "Firmware update"); lv_obj_set_auto_realign(titleLabel, true); - lv_obj_align(titleLabel, NULL, LV_ALIGN_IN_TOP_MID, 0, 50); + lv_obj_align(titleLabel, nullptr, LV_ALIGN_IN_TOP_MID, 0, 50); - bar1 = lv_bar_create(lv_scr_act(), NULL); + bar1 = lv_bar_create(lv_scr_act(), nullptr); lv_obj_set_size(bar1, 200, 30); - lv_obj_align(bar1, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(bar1, nullptr, LV_ALIGN_CENTER, 0, 0); lv_bar_set_anim_time(bar1, 10); lv_bar_set_range(bar1, 0, 100); lv_bar_set_value(bar1, 0, LV_ANIM_OFF); - percentLabel = lv_label_create(lv_scr_act(), NULL); + percentLabel = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text(percentLabel, ""); lv_obj_set_auto_realign(percentLabel, true); lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); diff --git a/src/displayapp/screens/FirmwareValidation.cpp b/src/displayapp/screens/FirmwareValidation.cpp index 2300b41d..4ac399ff 100644 --- a/src/displayapp/screens/FirmwareValidation.cpp +++ b/src/displayapp/screens/FirmwareValidation.cpp @@ -20,20 +20,20 @@ namespace { FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::FirmwareValidator &validator) : Screen{app}, validator{validator} { - labelVersionInfo = lv_label_create(lv_scr_act(), NULL); - lv_obj_align(labelVersionInfo, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + labelVersionInfo = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(labelVersionInfo, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); lv_label_set_text(labelVersionInfo, "Version : "); lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT); - labelVersionValue = lv_label_create(lv_scr_act(), NULL); + labelVersionValue = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0); lv_label_set_recolor(labelVersionValue, true); sprintf(version, "%ld.%ld.%ld", Version::Major(), Version::Minor(), Version::Patch()); lv_label_set_text(labelVersionValue, version); - labelIsValidated = lv_label_create(lv_scr_act(), NULL); - lv_obj_align(labelIsValidated, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 50); + labelIsValidated = lv_label_create(lv_scr_act(), nullptr); + lv_obj_align(labelIsValidated, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 50); lv_label_set_recolor(labelIsValidated, true); lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK); lv_obj_set_width(labelIsValidated, 240); @@ -44,21 +44,21 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app, lv_label_set_text(labelIsValidated, "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version."); - buttonValidate = lv_btn_create(lv_scr_act(), NULL); + buttonValidate = lv_btn_create(lv_scr_act(), nullptr); lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); buttonValidate->user_data = this; lv_obj_set_event_cb(buttonValidate, ButtonEventHandler); - labelButtonValidate = lv_label_create(buttonValidate, NULL); + labelButtonValidate = lv_label_create(buttonValidate, nullptr); lv_label_set_recolor(labelButtonValidate, true); lv_label_set_text(labelButtonValidate, "#00ff00 Validate#"); - buttonReset = lv_btn_create(lv_scr_act(), NULL); + buttonReset = lv_btn_create(lv_scr_act(), nullptr); buttonReset->user_data = this; - lv_obj_align(buttonReset, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); lv_obj_set_event_cb(buttonReset, ButtonEventHandler); - labelButtonReset = lv_label_create(buttonReset, NULL); + labelButtonReset = lv_label_create(buttonReset, nullptr); lv_label_set_recolor(labelButtonReset, true); lv_label_set_text(labelButtonReset, "#ff0000 Reset#"); } diff --git a/src/displayapp/screens/Gauge.cpp b/src/displayapp/screens/Gauge.cpp index fd905231..81c283ca 100644 --- a/src/displayapp/screens/Gauge.cpp +++ b/src/displayapp/screens/Gauge.cpp @@ -25,11 +25,11 @@ Gauge::Gauge(Pinetime::Applications::DisplayApp *app) : Screen(app) { needle_colors[0] = LV_COLOR_ORANGE; /*Create a gauge*/ - gauge1 = lv_gauge_create(lv_scr_act(), NULL); + gauge1 = lv_gauge_create(lv_scr_act(), nullptr); lv_gauge_set_style(gauge1, LV_GAUGE_STYLE_MAIN, &style); lv_gauge_set_needle_count(gauge1, 1, needle_colors); lv_obj_set_size(gauge1, 180, 180); - lv_obj_align(gauge1, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(gauge1, nullptr, LV_ALIGN_CENTER, 0, 0); lv_gauge_set_scale(gauge1, 360, 60, 0); lv_gauge_set_range(gauge1, 0, 59); diff --git a/src/displayapp/screens/InfiniPaint.cpp b/src/displayapp/screens/InfiniPaint.cpp index b340f5d8..3ea75e9e 100644 --- a/src/displayapp/screens/InfiniPaint.cpp +++ b/src/displayapp/screens/InfiniPaint.cpp @@ -7,9 +7,9 @@ using namespace Pinetime::Applications::Screens; extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_bold_20; -InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp *app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl{lvgl} { +InfiniPaint::InfiniPaint(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl{lvgl} { app->SetTouchMode(DisplayApp::TouchModes::Polling); - std::fill(b, b+bufferSize, LV_COLOR_WHITE); + std::fill(b, b + bufferSize, LV_COLOR_WHITE); } InfiniPaint::~InfiniPaint() { @@ -33,10 +33,10 @@ bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) { bool InfiniPaint::OnTouchEvent(uint16_t x, uint16_t y) { lv_area_t area; - area.x1 = x-(width/2); - area.y1 = y-(height/2); - area.x2 = x+(width/2)-1; - area.y2 = y+(height/2)-1; + area.x1 = x - (width / 2); + area.y1 = y - (height / 2); + area.x2 = x + (width / 2) - 1; + area.y2 = y + (height / 2) - 1; lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::None); lvgl.FlushDisplay(&area, b); return true; diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index fb4f979b..f29135d5 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -11,24 +11,28 @@ namespace Pinetime { namespace Applications { namespace Screens { - - class InfiniPaint : public Screen{ - public: - InfiniPaint(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl); - ~InfiniPaint() override; - - bool Refresh() override; - bool OnButtonPushed() override; - bool OnTouchEvent(TouchEvents event) override; - bool OnTouchEvent(uint16_t x, uint16_t y) override; - - private: - Pinetime::Components::LittleVgl& lvgl; - static constexpr uint16_t width = 10; - static constexpr uint16_t height = 10; - static constexpr uint16_t bufferSize = width*height; - lv_color_t b[bufferSize]; - bool running = true; + + class InfiniPaint : public Screen { + public: + InfiniPaint(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl); + + ~InfiniPaint() override; + + bool Refresh() override; + + bool OnButtonPushed() override; + + bool OnTouchEvent(TouchEvents event) override; + + bool OnTouchEvent(uint16_t x, uint16_t y) override; + + private: + Pinetime::Components::LittleVgl& lvgl; + static constexpr uint16_t width = 10; + static constexpr uint16_t height = 10; + static constexpr uint16_t bufferSize = width * height; + lv_color_t b[bufferSize]; + bool running = true; }; } } diff --git a/src/displayapp/screens/Label.cpp b/src/displayapp/screens/Label.cpp index 780ee88e..540776cc 100644 --- a/src/displayapp/screens/Label.cpp +++ b/src/displayapp/screens/Label.cpp @@ -4,7 +4,7 @@ using namespace Pinetime::Applications::Screens; Label::Label(Pinetime::Applications::DisplayApp *app, const char *text) : Screen(app), text{text} { - label = lv_label_create(lv_scr_act(), NULL); + label = lv_label_create(lv_scr_act(), nullptr); lv_label_set_align(label, LV_LABEL_ALIGN_LEFT); lv_obj_set_size(label, 240, 240); lv_label_set_text(label, text); diff --git a/src/displayapp/screens/Meter.cpp b/src/displayapp/screens/Meter.cpp index c74b8bdf..273e111d 100644 --- a/src/displayapp/screens/Meter.cpp +++ b/src/displayapp/screens/Meter.cpp @@ -17,14 +17,14 @@ Meter::Meter(Pinetime::Applications::DisplayApp *app) : Screen(app) { style_lmeter.body.padding.left = 16; /*Line length*/ /*Create a line meter */ - lmeter = lv_lmeter_create(lv_scr_act(), NULL); + lmeter = lv_lmeter_create(lv_scr_act(), nullptr); lv_lmeter_set_range(lmeter, 0, 60); /*Set the range*/ lv_lmeter_set_value(lmeter, value); /*Set the current value*/ lv_lmeter_set_angle_offset(lmeter, 180); lv_lmeter_set_scale(lmeter, 360, 60); /*Set the angle and number of lines*/ lv_lmeter_set_style(lmeter, LV_LMETER_STYLE_MAIN, &style_lmeter); /*Apply the new style*/ lv_obj_set_size(lmeter, 150, 150); - lv_obj_align(lmeter, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(lmeter, nullptr, LV_ALIGN_CENTER, 0, 0); } diff --git a/src/displayapp/screens/Modal.cpp b/src/displayapp/screens/Modal.cpp index 63ae70c0..29f7bfa7 100644 --- a/src/displayapp/screens/Modal.cpp +++ b/src/displayapp/screens/Modal.cpp @@ -54,7 +54,7 @@ void Modal::Show(const char* msg) { modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK; modal_style.body.opa = LV_OPA_50; - obj = lv_obj_create(lv_scr_act(), NULL); + obj = lv_obj_create(lv_scr_act(), nullptr); lv_obj_set_style(obj, &modal_style); lv_obj_set_pos(obj, 0, 0); lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES); @@ -63,10 +63,10 @@ void Modal::Show(const char* msg) { static const char * btns2[] = {"Ok", ""}; /* Create the message box as a child of the modal background */ - mbox = lv_mbox_create(obj, NULL); + mbox = lv_mbox_create(obj, nullptr); lv_mbox_add_btns(mbox, btns2); lv_mbox_set_text(mbox, msg); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_align(mbox, nullptr, LV_ALIGN_CENTER, 0, 0); lv_obj_set_event_cb(mbox, Modal::mbox_event_cb); mbox->user_data = this; diff --git a/src/displayapp/screens/Music.cpp b/src/displayapp/screens/Music.cpp index 9b7d198b..225a15a4 100644 --- a/src/displayapp/screens/Music.cpp +++ b/src/displayapp/screens/Music.cpp @@ -1,72 +1,131 @@ +/* Copyright (C) 2020 JF, Adam Pigg, Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ #include <libs/lvgl/lvgl.h> + #include "Music.h" using namespace Pinetime::Applications::Screens; + extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_bold_20; -static void event_handler(lv_obj_t * obj, lv_event_t event) -{ - Music* screen = static_cast<Music *>(obj->user_data); +static void event_handler(lv_obj_t *obj, lv_event_t event) { + Music *screen = static_cast<Music *>(obj->user_data); screen->OnObjectEvent(obj, event); } -Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::MusicService &music) : Screen(app), musicService(music) { - lv_obj_t * label; - - btnVolDown = lv_btn_create(lv_scr_act(), NULL); - btnVolDown->user_data = this; - lv_obj_set_event_cb(btnVolDown, event_handler); - lv_obj_align(btnVolDown, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10); - label = lv_label_create(btnVolDown, NULL); - lv_label_set_text(label, "v-"); - - btnVolUp = lv_btn_create(lv_scr_act(), NULL); - btnVolUp->user_data = this; - lv_obj_set_event_cb(btnVolUp, event_handler); - lv_obj_align(btnVolUp, NULL, LV_ALIGN_IN_TOP_RIGHT, -10, 10); - label = lv_label_create(btnVolUp, NULL); - lv_label_set_text(label, "v+"); - - btnPrev = lv_btn_create(lv_scr_act(), NULL); - btnPrev->user_data = this; - lv_obj_set_event_cb(btnPrev, event_handler); - lv_obj_set_size(btnPrev, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnPrev, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 10,-10); - label = lv_label_create(btnPrev, NULL); - lv_label_set_text(label, "<<"); - - btnPlayPause = lv_btn_create(lv_scr_act(), NULL); - btnPlayPause->user_data = this; - lv_obj_set_event_cb(btnPlayPause, event_handler); - lv_obj_set_size(btnPlayPause, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnPlayPause, NULL, LV_ALIGN_IN_BOTTOM_MID, 0,-10); - txtPlayPause = lv_label_create(btnPlayPause, NULL); - lv_label_set_text(txtPlayPause, ">"); +/** + * Set the pixel array to display by the image + * This just calls lv_img_set_src but adds type safety + * + * @param img pointer to an image object + * @param data the image array + */ +inline void lv_img_set_src_arr(lv_obj_t *img, const lv_img_dsc_t *src_img) { + lv_img_set_src(img, src_img); +} - btnNext = lv_btn_create(lv_scr_act(), NULL); - btnNext->user_data = this; - lv_obj_set_event_cb(btnNext, event_handler); - lv_obj_set_size(btnNext, LV_HOR_RES / 4, LV_VER_RES / 4); - lv_obj_align(btnNext, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -10,-10); - label = lv_label_create(btnNext, NULL); - lv_label_set_text(label, ">>"); - - txtArtist = lv_label_create(lv_scr_act(), NULL); - lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL); - lv_obj_align(txtArtist, NULL, LV_ALIGN_IN_LEFT_MID, 0,-20); - lv_label_set_text(txtArtist, "Artist Name"); - lv_label_set_align(txtArtist, LV_LABEL_ALIGN_CENTER); - lv_obj_set_width(txtArtist, LV_HOR_RES); - - txtTrack = lv_label_create(lv_scr_act(), NULL); - lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_DOT); - lv_obj_align(txtTrack, NULL, LV_ALIGN_IN_LEFT_MID, 0,20); - lv_label_set_text(txtTrack, "This is a very long track name"); - lv_label_set_align(txtTrack, LV_LABEL_ALIGN_CENTER); - lv_obj_set_width(txtTrack, LV_HOR_RES); - - musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); +/** + * Music control watchapp + * + * TODO: Investigate Apple Media Service and AVRCPv1.6 support for seamless integration + */ +Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::MusicService &music) : Screen(app), musicService(music) { + lv_obj_t *label; + + btnVolDown = lv_btn_create(lv_scr_act(), nullptr); + btnVolDown->user_data = this; + lv_obj_set_event_cb(btnVolDown, event_handler); + lv_obj_set_size(btnVolDown, LV_HOR_RES / 3, 80); + lv_obj_align(btnVolDown, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + label = lv_label_create(btnVolDown, nullptr); + lv_label_set_text(label, "V-"); + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + + btnVolUp = lv_btn_create(lv_scr_act(), nullptr); + btnVolUp->user_data = this; + lv_obj_set_event_cb(btnVolUp, event_handler); + lv_obj_set_size(btnVolUp, LV_HOR_RES / 3, 80); + lv_obj_align(btnVolUp, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + label = lv_label_create(btnVolUp, nullptr); + lv_label_set_text(label, "V+"); + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + + btnPrev = lv_btn_create(lv_scr_act(), nullptr); + btnPrev->user_data = this; + lv_obj_set_event_cb(btnPrev, event_handler); + lv_obj_set_size(btnPrev, LV_HOR_RES / 3, 80); + lv_obj_align(btnPrev, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + label = lv_label_create(btnPrev, nullptr); + lv_label_set_text(label, "<<"); + + btnNext = lv_btn_create(lv_scr_act(), nullptr); + btnNext->user_data = this; + lv_obj_set_event_cb(btnNext, event_handler); + lv_obj_set_size(btnNext, LV_HOR_RES / 3, 80); + lv_obj_align(btnNext, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); + label = lv_label_create(btnNext, nullptr); + lv_label_set_text(label, ">>"); + + btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); + btnPlayPause->user_data = this; + lv_obj_set_event_cb(btnPlayPause, event_handler); + lv_obj_set_size(btnPlayPause, LV_HOR_RES / 3, 80); + lv_obj_align(btnPlayPause, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0); + txtPlayPause = lv_label_create(btnPlayPause, nullptr); + lv_label_set_text(txtPlayPause, ">"); + + txtTrackDuration = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(txtTrackDuration, LV_LABEL_LONG_SROLL); + lv_obj_align(txtTrackDuration, nullptr, LV_ALIGN_IN_TOP_LEFT, 12, 20); + lv_label_set_text(txtTrackDuration, "--:--/--:--"); + lv_label_set_align(txtTrackDuration, LV_ALIGN_IN_LEFT_MID); + lv_obj_set_width(txtTrackDuration, LV_HOR_RES); + + constexpr uint8_t FONT_HEIGHT = 12; + constexpr uint8_t LINE_PAD = 15; + constexpr int8_t MIDDLE_OFFSET = -25; + txtArtist = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL); + lv_obj_align(txtArtist, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 1 * FONT_HEIGHT); + lv_label_set_text(txtArtist, "Artist Name"); + lv_label_set_align(txtArtist, LV_ALIGN_IN_LEFT_MID); + lv_obj_set_width(txtArtist, LV_HOR_RES); + + txtTrack = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_SROLL); + lv_obj_align(txtTrack, nullptr, LV_ALIGN_IN_LEFT_MID, 12, MIDDLE_OFFSET + 2 * FONT_HEIGHT + LINE_PAD); + lv_label_set_text(txtTrack, "This is a very long getTrack name"); + lv_label_set_align(txtTrack, LV_ALIGN_IN_LEFT_MID); + lv_obj_set_width(txtTrack, LV_HOR_RES); + + /** Init animation */ + imgDisc = lv_img_create(lv_scr_act(), nullptr); + lv_img_set_src_arr(imgDisc, &disc); + lv_obj_align(imgDisc, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15, 15); + + imgDiscAnim = lv_img_create(lv_scr_act(), nullptr); + lv_img_set_src_arr(imgDiscAnim, &disc_f_1); + lv_obj_align(imgDiscAnim, nullptr, LV_ALIGN_IN_TOP_RIGHT, -15 - 32, 15); + + frameB = false; + + musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN); } Music::~Music() { @@ -79,47 +138,155 @@ bool Music::OnButtonPushed() { } bool Music::Refresh() { + if (artist != musicService.getArtist()) { + artist = musicService.getArtist(); + currentLength = 0; + lv_label_set_text(txtArtist, artist.data()); + } + + if (track != musicService.getTrack()) { + track = musicService.getTrack(); + currentLength = 0; + lv_label_set_text(txtTrack, track.data()); + } + + if (album != musicService.getAlbum()) { + album = musicService.getAlbum(); + currentLength = 0; + } + + if (playing != musicService.isPlaying()) { + playing = musicService.isPlaying(); + } + + // Because we increment this ourselves, + // we can't compare with the old data directly + // have to update it when there's actually new data + // just to avoid unnecessary draws that make UI choppy + if (lastLength != musicService.getProgress()) { + currentLength = musicService.getProgress(); + lastLength = currentLength; + UpdateLength(); + } + + if (totalLength != musicService.getTrackLength()) { + totalLength = musicService.getTrackLength(); + UpdateLength(); + } + + if (playing == Pinetime::Controllers::MusicService::MusicStatus::Playing) { + lv_label_set_text(txtPlayPause, "||"); + if (xTaskGetTickCount() - 1024 >= lastIncrement) { + + if (frameB) { + lv_img_set_src(imgDiscAnim, &disc_f_1); + } else { + lv_img_set_src(imgDiscAnim, &disc_f_2); + } + frameB = !frameB; + + if (currentLength < totalLength) { + currentLength += static_cast<int>((static_cast<float>(xTaskGetTickCount() - lastIncrement) / 1024.0f) * + musicService.getPlaybackSpeed()); + } else { + // Let's assume the getTrack finished, paused when the timer ends + // and there's no new getTrack being sent to us + // TODO: ideally this would be configurable + playing = false; + } + lastIncrement = xTaskGetTickCount(); + + UpdateLength(); + } + } else { + lv_label_set_text(txtPlayPause, ">"); + } + + return running; +} + +void Music::UpdateLength() { + if (totalLength > (99 * 60 * 60)) { + lv_label_set_text(txtTrackDuration, "Inf/Inf"); + } else if (totalLength > (99 * 60)) { + char timer[12]; + sprintf(timer, "%02d:%02d/%02d:%02d", + (currentLength / (60 * 60)) % 100, + ((currentLength % (60 * 60)) / 60) % 100, + (totalLength / (60 * 60)) % 100, + ((totalLength % (60 * 60)) / 60) % 100 + ); + lv_label_set_text(txtTrackDuration, timer); + } else { + char timer[12]; + sprintf(timer, "%02d:%02d/%02d:%02d", + (currentLength / 60) % 100, + (currentLength % 60) % 100, + (totalLength / 60) % 100, + (totalLength % 60) % 100 + ); + lv_label_set_text(txtTrackDuration, timer); + } +} - if (m_artist != musicService.artist()) { - m_artist = musicService.artist(); - lv_label_set_text(txtArtist, m_artist.data()); +void Music::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if (event == LV_EVENT_CLICKED) { + if (obj == btnVolDown) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLDOWN); + } else if (obj == btnVolUp) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLUP); + } else if (obj == btnPrev) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); + } else if (obj == btnPlayPause) { + if (playing == Pinetime::Controllers::MusicService::MusicStatus::Playing) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PAUSE); + + // Let's assume it stops playing instantly + playing = Controllers::MusicService::NotPlaying; + } else { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PLAY); + + // Let's assume it starts playing instantly + // TODO: In the future should check for BT connection for better UX + playing = Controllers::MusicService::Playing; + } + } else if (obj == btnNext) { + musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); } - if (m_track != musicService.track()) { - m_track = musicService.track(); - lv_label_set_text(txtTrack, m_track.data()); + } +} + + +bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch (event) { + case TouchEvents::SwipeUp: { + displayVolumeButtons = true; + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + + lv_obj_set_hidden(btnNext, displayVolumeButtons); + lv_obj_set_hidden(btnPrev, displayVolumeButtons); + return true; } - if (m_album != musicService.album()) { - m_album = musicService.album(); + case TouchEvents::SwipeDown: { + displayVolumeButtons = false; + lv_obj_set_hidden(btnNext, displayVolumeButtons); + lv_obj_set_hidden(btnPrev, displayVolumeButtons); + + lv_obj_set_hidden(btnVolDown, !displayVolumeButtons); + lv_obj_set_hidden(btnVolUp, !displayVolumeButtons); + return true; } - if (m_status != musicService.status()) { - m_status = musicService.status(); + case TouchEvents::SwipeLeft: { + musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); + return true; } - if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { - lv_label_set_text(txtPlayPause, "||"); - } else { - lv_label_set_text(txtPlayPause, ">"); + case TouchEvents::SwipeRight: { + musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); + return true; } - - return running; -} - -void Music::OnObjectEvent(lv_obj_t* obj, lv_event_t event) -{ - if (event == LV_EVENT_CLICKED) { - if (obj == btnVolDown) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLDOWN); - } else if (obj == btnVolUp) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLUP); - } else if (obj == btnPrev) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV); - } else if (obj == btnPlayPause) { - if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PAUSE); - } else { - musicService.event(Controllers::MusicService::EVENT_MUSIC_PLAY); - } - } else if (obj == btnNext) { - musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT); - } + default: { + return true; } -} + } +}
\ No newline at end of file diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index d43d31cc..81ba7935 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -1,3 +1,20 @@ +/* Copyright (C) 2020 JF, Adam Pigg, Avamander + + This file is part of InfiniTime. + + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ #pragma once #include <cstdint> @@ -13,37 +30,66 @@ #include <libs/lvgl/src/lv_core/lv_style.h> #include <libs/lvgl/src/lv_core/lv_obj.h> #include "../../Version.h" +#include "displayapp/icons/music/disc.cpp" +#include "displayapp/icons/music/disc_f_1.cpp" +#include "displayapp/icons/music/disc_f_2.cpp" namespace Pinetime { namespace Applications { namespace Screens { - - class Music : public Screen{ - public: - Music(DisplayApp* app, Pinetime::Controllers::MusicService &music); - ~Music() override; - - bool Refresh() override; - bool OnButtonPushed() override; - - void OnObjectEvent(lv_obj_t* obj, lv_event_t event); - - private: - lv_obj_t * btnPrev; - lv_obj_t * btnPlayPause; - lv_obj_t * btnNext; - lv_obj_t * btnVolDown; - lv_obj_t * btnVolUp; - lv_obj_t * txtArtist; - lv_obj_t * txtTrack; - lv_obj_t * txtPlayPause; - - bool running = true; - Pinetime::Controllers::MusicService &musicService; - std::string m_artist; - std::string m_album; - std::string m_track; - unsigned char m_status; + class Music : public Screen { + public: + Music(DisplayApp *app, Pinetime::Controllers::MusicService &music); + + ~Music() override; + + bool Refresh() override; + + bool OnButtonPushed() override; + + void OnObjectEvent(lv_obj_t *obj, lv_event_t event); + + private: + bool OnTouchEvent(TouchEvents event); + + void UpdateLength(); + + lv_obj_t *btnPrev; + lv_obj_t *btnPlayPause; + lv_obj_t *btnNext; + lv_obj_t *btnVolDown; + lv_obj_t *btnVolUp; + lv_obj_t *txtArtist; + lv_obj_t *txtTrack; + lv_obj_t *txtPlayPause; + + lv_obj_t *imgDisc; + lv_obj_t *imgDiscAnim; + lv_obj_t *txtTrackDuration; + + /** For the spinning disc animation */ + bool frameB; + + bool displayVolumeButtons = false; + Pinetime::Controllers::MusicService &musicService; + + std::string artist; + std::string album; + std::string track; + + /** Total length in seconds */ + int totalLength; + /** Current length in seconds */ + int currentLength; + /** Last length */ + int lastLength; + /** Last time an animation update or timer was incremented */ + TickType_t lastIncrement; + + bool playing; + + /** Watchapp */ + bool running = true; }; } } diff --git a/src/displayapp/screens/Screen.h b/src/displayapp/screens/Screen.h index dbf81a44..6b1d0eec 100644 --- a/src/displayapp/screens/Screen.h +++ b/src/displayapp/screens/Screen.h @@ -9,16 +9,28 @@ namespace Pinetime { namespace Screens { class Screen { public: - Screen(DisplayApp* app) : app{app} {} + explicit Screen(DisplayApp* app) : app{app} {} virtual ~Screen() = default; - // Return false if the app can be closed, true if it must continue to run + /** + * Most of the time, apps only react to events (touch events, for example). + * In this case you don't need to do anything in this method. + * + * For example, InfiniPaint does nothing in Refresh(). + * But, if you want to update your display periodically, draw an animation... + * you cannot do it in a touch event handler because these handlers are not + * called if the user does not touch the screen. + * + * That's why Refresh() is there: update the display periodically. + * + * @return false if the app can be closed, true if it must continue to run + **/ virtual bool Refresh() = 0; - // Return false if the button hasn't been handled by the app, true if it has been handled + /** @return false if the button hasn't been handled by the app, true if it has been handled */ virtual bool OnButtonPushed() { return false; } - // Return false if the event hasn't been handled by the app, true if it has been handled + /** @return false if the event hasn't been handled by the app, true if it has been handled */ virtual bool OnTouchEvent(TouchEvents event) { return false; } virtual bool OnTouchEvent(uint16_t x, uint16_t y) { return false; } diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 8a3b8dbb..867fdaeb 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -105,12 +105,12 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen1() { std::unique_ptr<Screen> SystemInfo::CreateScreen2() { auto& bleAddr = bleController.Address(); - sprintf(t2, "BLE MAC: \n %2x:%2x:%2x:%2x:%2x:%2x", + sprintf(t2, "BLE MAC: \n %02x:%02x:%02x:%02x:%02x:%02x", bleAddr[5], bleAddr[4], bleAddr[3], bleAddr[2], bleAddr[1], bleAddr[0]); return std::unique_ptr<Screen>(new Screens::Label(app, t2)); } std::unique_ptr<Screen> SystemInfo::CreateScreen3() { - strncpy(t3, "Hello from\nthe developper!", 27); + strncpy(t3, "Hello from\nthe developer!", 27); return std::unique_ptr<Screen>(new Screens::Label(app, t3)); } diff --git a/src/displayapp/screens/Tab.cpp b/src/displayapp/screens/Tab.cpp index adc32578..44b806c0 100644 --- a/src/displayapp/screens/Tab.cpp +++ b/src/displayapp/screens/Tab.cpp @@ -1,13 +1,13 @@ #include <cstdio> #include <libs/date/includes/date/date.h> -#include <Components/DateTime/DateTimeController.h> +#include "components/datetime/DateTimeController.h" #include <Version.h> #include <libs/lvgl/src/lv_core/lv_obj.h> #include <libs/lvgl/src/lv_font/lv_font.h> #include <libs/lvgl/lvgl.h> #include <libraries/log/nrf_log.h> #include "Tab.h" -#include <DisplayApp/DisplayApp.h> +#include "displayapp/DisplayApp.h" using namespace Pinetime::Applications::Screens; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index deb88472..75fa6ef5 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -30,7 +30,7 @@ Tile::Tile(DisplayApp* app, std::array<Applications, 6>& applications) : Screen( } modal.reset(new Modal(app)); - btnm1 = lv_btnm_create(lv_scr_act(), NULL); + btnm1 = lv_btnm_create(lv_scr_act(), nullptr); lv_btnm_set_map(btnm1, btnm_map1); lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES); |