Merge branch 'develop' into infineat-external-resources
# Conflicts: # src/displayapp/screens/Symbols.h # src/displayapp/screens/settings/SettingWatchFace.cpp # src/displayapp/screens/settings/SettingWatchFace.h
This commit is contained in:
@@ -9,15 +9,15 @@ using namespace Pinetime;
|
||||
uint32_t BootloaderVersion::version = 0;
|
||||
char BootloaderVersion::versionString[BootloaderVersion::VERSION_STR_LEN] = "0.0.0";
|
||||
|
||||
const uint32_t BootloaderVersion::Major() {
|
||||
uint32_t BootloaderVersion::Major() {
|
||||
return (BootloaderVersion::version >> 16u) & 0xff;
|
||||
}
|
||||
|
||||
const uint32_t BootloaderVersion::Minor() {
|
||||
uint32_t BootloaderVersion::Minor() {
|
||||
return (BootloaderVersion::version >> 8u) & 0xff;
|
||||
}
|
||||
|
||||
const uint32_t BootloaderVersion::Patch() {
|
||||
uint32_t BootloaderVersion::Patch() {
|
||||
return BootloaderVersion::version & 0xff;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ const char* BootloaderVersion::VersionString() {
|
||||
return BootloaderVersion::versionString;
|
||||
}
|
||||
|
||||
const bool BootloaderVersion::IsValid() {
|
||||
bool BootloaderVersion::IsValid() {
|
||||
return BootloaderVersion::version >= 0x00010000;
|
||||
}
|
||||
|
||||
|
@@ -6,11 +6,11 @@
|
||||
namespace Pinetime {
|
||||
class BootloaderVersion {
|
||||
public:
|
||||
static const uint32_t Major();
|
||||
static const uint32_t Minor();
|
||||
static const uint32_t Patch();
|
||||
static uint32_t Major();
|
||||
static uint32_t Minor();
|
||||
static uint32_t Patch();
|
||||
static const char* VersionString();
|
||||
static const bool IsValid();
|
||||
static bool IsValid();
|
||||
static void SetVersion(uint32_t v);
|
||||
|
||||
private:
|
||||
|
@@ -9,21 +9,21 @@ set(NRF_BOARD pca10040)
|
||||
|
||||
# check if all the necessary tools paths have been provided.
|
||||
if (NOT NRF5_SDK_PATH)
|
||||
message(FATAL_ERROR "The path to the nRF5 SDK (NRF5_SDK_PATH) must be set.")
|
||||
message(FATAL_ERROR "The path to the nRF5 SDK (NRF5_SDK_PATH) must be set.")
|
||||
endif ()
|
||||
if (DEFINED ARM_NONE_EABI_TOOLCHAIN_PATH)
|
||||
set(ARM_NONE_EABI_TOOLCHAIN_BIN_PATH ${ARM_NONE_EABI_TOOLCHAIN_PATH}/bin)
|
||||
set(ARM_NONE_EABI_TOOLCHAIN_BIN_PATH ${ARM_NONE_EABI_TOOLCHAIN_PATH}/bin)
|
||||
endif ()
|
||||
|
||||
if (NOT NRF_TARGET MATCHES "nrf52")
|
||||
message(FATAL_ERROR "Only rRF52 boards are supported right now")
|
||||
message(FATAL_ERROR "Only rRF52 boards are supported right now")
|
||||
endif ()
|
||||
|
||||
# Setup toolchain
|
||||
include(${CMAKE_SOURCE_DIR}/cmake-nRF5x/arm-gcc-toolchain.cmake)
|
||||
|
||||
if (NOT DEFINED ARM_GCC_TOOLCHAIN)
|
||||
message(FATAL_ERROR "The toolchain must be set up before calling this macro")
|
||||
message(FATAL_ERROR "The toolchain must be set up before calling this macro")
|
||||
endif ()
|
||||
set(CMAKE_OSX_SYSROOT "/")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
||||
@@ -406,6 +406,8 @@ list(APPEND SOURCE_FILES
|
||||
displayapp/screens/Styles.cpp
|
||||
displayapp/Colors.cpp
|
||||
displayapp/widgets/Counter.cpp
|
||||
displayapp/widgets/PageIndicator.cpp
|
||||
displayapp/widgets/StatusIcons.cpp
|
||||
|
||||
## Settings
|
||||
displayapp/screens/settings/QuickSettings.cpp
|
||||
@@ -478,7 +480,7 @@ list(APPEND SOURCE_FILES
|
||||
FreeRTOS/port_cmsis.c
|
||||
|
||||
displayapp/LittleVgl.cpp
|
||||
displayapp/lv_pinetime_theme.c
|
||||
displayapp/InfiniTimeTheme.cpp
|
||||
|
||||
systemtask/SystemTask.cpp
|
||||
systemtask/SystemMonitor.cpp
|
||||
@@ -613,6 +615,8 @@ set(INCLUDE_FILES
|
||||
displayapp/screens/Alarm.h
|
||||
displayapp/Colors.h
|
||||
displayapp/widgets/Counter.h
|
||||
displayapp/widgets/PageIndicator.h
|
||||
displayapp/widgets/StatusIcons.h
|
||||
drivers/St7789.h
|
||||
drivers/SpiNorFlash.h
|
||||
drivers/SpiMaster.h
|
||||
@@ -654,16 +658,16 @@ set(INCLUDE_FILES
|
||||
drivers/Cst816s.h
|
||||
FreeRTOS/portmacro.h
|
||||
FreeRTOS/portmacro_cmsis.h
|
||||
libs/date/includes/date/tz.h
|
||||
libs/date/includes/date/chrono_io.h
|
||||
libs/date/includes/date/date.h
|
||||
libs/date/includes/date/islamic.h
|
||||
libs/date/includes/date/iso_week.h
|
||||
libs/date/includes/date/julian.h
|
||||
libs/date/includes/date/ptz.h
|
||||
libs/date/includes/date/tz_private.h
|
||||
libs/date/include/date/tz.h
|
||||
libs/date/include/date/chrono_io.h
|
||||
libs/date/include/date/date.h
|
||||
libs/date/include/date/islamic.h
|
||||
libs/date/include/date/iso_week.h
|
||||
libs/date/include/date/julian.h
|
||||
libs/date/include/date/ptz.h
|
||||
libs/date/include/date/tz_private.h
|
||||
displayapp/LittleVgl.h
|
||||
displayapp/lv_pinetime_theme.h
|
||||
displayapp/InfiniTimeTheme.h
|
||||
systemtask/SystemTask.h
|
||||
systemtask/SystemMonitor.h
|
||||
displayapp/screens/Symbols.h
|
||||
@@ -684,7 +688,7 @@ include_directories(
|
||||
../
|
||||
libs/
|
||||
FreeRTOS/
|
||||
libs/date/includes
|
||||
libs/date/include
|
||||
libs/mynewt-nimble/porting/npl/freertos/include
|
||||
libs/mynewt-nimble/nimble/include
|
||||
libs/mynewt-nimble/porting/nimble/include
|
||||
@@ -782,14 +786,60 @@ add_definitions(-DNRF52 -DNRF52832 -DNRF52832_XXAA -DNRF52_PAN_74 -DNRF52_PAN_64
|
||||
add_definitions(-DFREERTOS)
|
||||
add_definitions(-D__STACK_SIZE=1024)
|
||||
add_definitions(-D__HEAP_SIZE=4096)
|
||||
add_definitions(-DMYNEWT_VAL_BLE_LL_RFMGMT_ENABLE_TIME=1500)
|
||||
|
||||
# NOTE : Add the following defines to enable debug mode of the NRF SDK:
|
||||
#add_definitions(-DDEBUG)
|
||||
#add_definitions(-DDEBUG_NRF_USER)
|
||||
# Note: Only use this for debugging
|
||||
# Derive the low frequency clock from the main clock (SYNT)
|
||||
# add_definitions(-DCLOCK_CONFIG_LF_SRC=2)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
endif ()
|
||||
# Target hardware configuration options
|
||||
add_definitions(-DTARGET_DEVICE_${TARGET_DEVICE})
|
||||
add_definitions(-DTARGET_DEVICE_NAME="${TARGET_DEVICE}")
|
||||
if(TARGET_DEVICE STREQUAL "PINETIME")
|
||||
add_definitions(-DDRIVER_PINMAP_PINETIME)
|
||||
add_definitions(-DCLOCK_CONFIG_LF_SRC=1) # XTAL
|
||||
elseif(TARGET_DEVICE STREQUAL "MOY-TFK5") # P8a
|
||||
add_definitions(-DDRIVER_PINMAP_P8)
|
||||
add_definitions(-DCLOCK_CONFIG_LF_SRC=1) # XTAL
|
||||
elseif(TARGET_DEVICE STREQUAL "MOY-TIN5") # P8a variant 2
|
||||
add_definitions(-DDRIVER_PINMAP_P8)
|
||||
add_definitions(-DCLOCK_CONFIG_LF_SRC=1) # XTAL
|
||||
elseif(TARGET_DEVICE STREQUAL "MOY-TON5") # P8b
|
||||
add_definitions(-DDRIVER_PINMAP_P8)
|
||||
add_definitions(-DCLOCK_CONFIG_LF_SRC=0) # RC
|
||||
add_definitions(-DMYNEWT_VAL_BLE_LL_SCA=500)
|
||||
add_definitions(-DCLOCK_CONFIG_LF_CAL_ENABLED=1)
|
||||
elseif(TARGET_DEVICE STREQUAL "MOY-UNK") # P8b mirrored
|
||||
add_definitions(-DDRIVER_PINMAP_P8)
|
||||
add_definitions(-DCLOCK_CONFIG_LF_SRC=0) # RC
|
||||
add_definitions(-DMYNEWT_VAL_BLE_LL_SCA=500)
|
||||
add_definitions(-DCLOCK_CONFIG_LF_CAL_ENABLED=1)
|
||||
add_definitions(-DDRIVER_DISPLAY_MIRROR)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid TARGET_DEVICE")
|
||||
endif()
|
||||
|
||||
# Debug configuration
|
||||
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
|
||||
add_definitions(-DDEBUG)
|
||||
add_definitions(-DDEBUG_NRF_USER)
|
||||
|
||||
# NRF SDK Logging
|
||||
add_definitions(-DNRF_LOG_ENABLED=1)
|
||||
# add_definitions(-DNRF_LOG_BACKEND_RTT_ENABLED=1)
|
||||
# add_definitions(-DNRF_LOG_BACKEND_SERIAL_USES_RTT=1)
|
||||
|
||||
# NRF SDK individual modules logging
|
||||
# add_definitions(-DCLOCK_CONFIG_LOG_ENABLED=1)
|
||||
# add_definitions(-DCLOCK_CONFIG_LOG_LEVEL=4)
|
||||
# add_definitions(-DRTC_CONFIG_LOG_ENABLED=1)
|
||||
# add_definitions(-DRTC_CONFIG_LOG_LEVEL=4)
|
||||
|
||||
# Nimble Logging
|
||||
add_definitions(-DMYNEWT_VAL_NEWT_FEATURE_LOGCFG=1)
|
||||
# add_definitions(-DMYNEWT_VAL_LOG_LEVEL=0)
|
||||
# add_definitions(-DMYNEWT_VAL_BLE_HS_LOG_LVL=0)
|
||||
endif()
|
||||
|
||||
add_subdirectory(displayapp/fonts)
|
||||
target_compile_options(infinitime_fonts PUBLIC
|
||||
@@ -894,10 +944,15 @@ add_custom_command(TARGET ${EXECUTABLE_NAME}
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_FILE_NAME}.out "${EXECUTABLE_FILE_NAME}.hex"
|
||||
COMMENT "post build steps for ${EXECUTABLE_FILE_NAME}")
|
||||
|
||||
if(BUILD_RESOURCES)
|
||||
add_dependencies(${EXECUTABLE_NAME} GenerateResources)
|
||||
endif()
|
||||
|
||||
# Build binary intended to be used by bootloader
|
||||
set(EXECUTABLE_MCUBOOT_NAME "pinetime-mcuboot-app")
|
||||
set(EXECUTABLE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.hex)
|
||||
set(IMAGE_MCUBOOT_FILE_NAME_HEX ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.hex)
|
||||
set(IMAGE_MCUBOOT_FILE_NAME_BIN ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
|
||||
set(DFU_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
||||
set(NRF5_LINKER_SCRIPT_MCUBOOT "${CMAKE_SOURCE_DIR}/gcc_nrf52-mcuboot.ld")
|
||||
add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES})
|
||||
@@ -921,16 +976,21 @@ add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
|
||||
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_MCUBOOT_FILE_NAME}.out
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_FILE_NAME}.hex"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_FILE_NAME}.hex ${IMAGE_MCUBOOT_FILE_NAME}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_FILE_NAME}.hex ${IMAGE_MCUBOOT_FILE_NAME_HEX}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_FILE_NAME}.bin ${IMAGE_MCUBOOT_FILE_NAME_BIN}
|
||||
COMMENT "post build steps for ${EXECUTABLE_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
|
||||
if(BUILD_RESOURCES)
|
||||
add_dependencies(${EXECUTABLE_MCUBOOT_NAME} GenerateResources)
|
||||
endif()
|
||||
|
||||
if(BUILD_DFU)
|
||||
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_MCUBOOT_FILE_NAME} ${DFU_MCUBOOT_FILE_NAME}
|
||||
COMMENT "post build (DFU) steps for ${EXECUTABLE_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_MCUBOOT_FILE_NAME_HEX} ${DFU_MCUBOOT_FILE_NAME}
|
||||
COMMENT "post build (DFU) steps for ${EXECUTABLE_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# InfiniTime recovery firmware (autonomous)
|
||||
@@ -964,7 +1024,8 @@ add_custom_command(TARGET ${EXECUTABLE_RECOVERY_NAME}
|
||||
# InfiniTime recovery firmware (mcuboot)
|
||||
set(EXECUTABLE_RECOVERY_MCUBOOT_NAME "pinetime-mcuboot-recovery")
|
||||
set(EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.hex)
|
||||
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME_HEX ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}.hex)
|
||||
set(DFU_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
||||
add_executable(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} ${RECOVERY_SOURCE_FILES})
|
||||
target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk littlefs QCBOR infinitime_fonts)
|
||||
@@ -988,18 +1049,18 @@ add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}
|
||||
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.out "${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.hex"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.hex ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I ihex -O binary ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME} "${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}.hex ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME_HEX}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I ihex -O binary ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME_HEX} "${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}.bin"
|
||||
COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME}.bin recoveryImage > recoveryImage.h
|
||||
COMMENT "post build steps for ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
|
||||
if(BUILD_DFU)
|
||||
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME} ${DFU_RECOVERY_MCUBOOT_FILE_NAME}
|
||||
COMMENT "post build (DFU) steps for ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
add_custom_command(TARGET ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}
|
||||
POST_BUILD
|
||||
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_RECOVERY_MCUBOOT_FILE_NAME_HEX} ${DFU_RECOVERY_MCUBOOT_FILE_NAME}
|
||||
COMMENT "post build (DFU) steps for ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Build binary that writes the recovery image into the SPI flash memory
|
||||
@@ -1036,7 +1097,8 @@ add_custom_command(TARGET ${EXECUTABLE_RECOVERYLOADER_NAME}
|
||||
# Build binary that writes the recovery image (MCUBoot version)
|
||||
set(EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME "pinetime-mcuboot-recovery-loader")
|
||||
set(EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.hex)
|
||||
set(IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||
set(IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME_HEX ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.hex)
|
||||
set(DFU_MCUBOOT_RECOVERYLOADER_FILE_NAME ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
||||
add_executable(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} ${RECOVERYLOADER_SOURCE_FILES})
|
||||
target_link_libraries(${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME} nrf-sdk QCBOR infinitime_fonts)
|
||||
@@ -1063,82 +1125,86 @@ add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}
|
||||
COMMAND ${CMAKE_SIZE_UTIL} ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.out "${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.hex"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.hex ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I ihex -O binary ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME} "${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin"
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tools/mcuboot/imgtool.py create --align 4 --version 1.0.0 --header-size 32 --slot-size 475136 --pad-header ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.hex ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME_HEX}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I ihex -O binary ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME_HEX} "${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin"
|
||||
COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/bin2c.py ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME}.bin recoveryLoaderImage > recoveryLoaderImage.h
|
||||
COMMENT "post build steps for ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}"
|
||||
)
|
||||
|
||||
if(BUILD_DFU)
|
||||
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}
|
||||
POST_BUILD
|
||||
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME} ${DFU_MCUBOOT_RECOVERYLOADER_FILE_NAME}
|
||||
COMMENT "post build (DFU) steps for ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}"
|
||||
)
|
||||
add_custom_command(TARGET ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_NAME}
|
||||
POST_BUILD
|
||||
COMMAND adafruit-nrfutil dfu genpkg --dev-type 0x0052 --application ${IMAGE_MCUBOOT_RECOVERYLOADER_FILE_NAME_HEX} ${DFU_MCUBOOT_RECOVERYLOADER_FILE_NAME}
|
||||
COMMENT "post build (DFU) steps for ${EXECUTABLE_MCUBOOT_RECOVERYLOADER_FILE_NAME}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_RESOURCES)
|
||||
add_subdirectory(resources)
|
||||
endif()
|
||||
|
||||
|
||||
# FLASH
|
||||
if (USE_JLINK)
|
||||
add_custom_target(FLASH_ERASE
|
||||
COMMAND ${NRFJPROG} --eraseall -f ${NRF_TARGET}
|
||||
COMMENT "erasing flashing"
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${NRFJPROG} --program ${EXECUTABLE_FILE_NAME}.hex -f ${NRF_TARGET} --sectorerase
|
||||
COMMAND sleep 0.5s
|
||||
COMMAND ${NRFJPROG} --reset -f ${NRF_TARGET}
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
add_custom_target(FLASH_ERASE
|
||||
COMMAND ${NRFJPROG} --eraseall -f ${NRF_TARGET}
|
||||
COMMENT "erasing flashing"
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${NRFJPROG} --program ${EXECUTABLE_FILE_NAME}.hex -f ${NRF_TARGET} --sectorerase
|
||||
COMMAND sleep 0.5s
|
||||
COMMAND ${NRFJPROG} --reset -f ${NRF_TARGET}
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
|
||||
elseif (USE_GDB_CLIENT)
|
||||
add_custom_target(FLASH_ERASE
|
||||
COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'mon erase_mass'
|
||||
COMMENT "erasing flashing"
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'load' -ex 'kill' ${EXECUTABLE_FILE_NAME}.hex
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
elseif (USE_OPENOCD)
|
||||
if (USE_CMSIS_DAP)
|
||||
add_custom_target(FLASH_ERASE
|
||||
COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'mon erase_mass'
|
||||
COMMAND ${OPENOCD_BIN_PATH} -c 'source [find interface/cmsis-dap.cfg]' -c 'transport select swd'
|
||||
-c 'source [find target/nrf52.cfg]'
|
||||
-c 'init'
|
||||
-c 'halt'
|
||||
-c 'nrf5 mass_erase'
|
||||
-c 'halt'
|
||||
-c 'reset'
|
||||
-c 'exit'
|
||||
COMMENT "erasing flashing"
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${GDB_CLIENT_BIN_PATH} -nx --batch -ex 'target extended-remote ${GDB_CLIENT_TARGET_REMOTE}' -ex 'monitor swdp_scan' -ex 'attach 1' -ex 'load' -ex 'kill' ${EXECUTABLE_FILE_NAME}.hex
|
||||
COMMAND ${OPENOCD_BIN_PATH}
|
||||
-c 'tcl_port disabled'
|
||||
-c 'gdb_port 3333'
|
||||
-c 'telnet_port 4444'
|
||||
-c 'source [find interface/cmsis-dap.cfg]'
|
||||
-c 'transport select swd'
|
||||
-c 'source [find target/nrf52.cfg]'
|
||||
-c 'halt'
|
||||
-c "program \"${EXECUTABLE_FILE_NAME}.hex\""
|
||||
-c 'reset'
|
||||
-c 'shutdown'
|
||||
COMMENT "flashing ${EXECUTABLE_BIN_NAME}.hex"
|
||||
)
|
||||
else ()
|
||||
add_custom_target(FLASH_ERASE
|
||||
COMMAND ${OPENOCD_BIN_PATH} -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c init -c halt -c 'nrf5 mass_erase' -c reset -c shutdown
|
||||
COMMENT "erasing flashing"
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${OPENOCD_BIN_PATH} -c "tcl_port disabled" -c "gdb_port 3333" -c "telnet_port 4444" -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c "program \"${EXECUTABLE_FILE_NAME}.hex\"" -c reset -c shutdown
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
elseif (USE_OPENOCD)
|
||||
if (USE_CMSIS_DAP)
|
||||
add_custom_target(FLASH_ERASE
|
||||
COMMAND ${OPENOCD_BIN_PATH} -c 'source [find interface/cmsis-dap.cfg]' -c 'transport select swd'
|
||||
-c 'source [find target/nrf52.cfg]'
|
||||
-c 'init'
|
||||
-c 'halt'
|
||||
-c 'nrf5 mass_erase'
|
||||
-c 'halt'
|
||||
-c 'reset'
|
||||
-c 'exit'
|
||||
COMMENT "erasing flashing"
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${OPENOCD_BIN_PATH}
|
||||
-c 'tcl_port disabled'
|
||||
-c 'gdb_port 3333'
|
||||
-c 'telnet_port 4444'
|
||||
-c 'source [find interface/cmsis-dap.cfg]'
|
||||
-c 'transport select swd'
|
||||
-c 'source [find target/nrf52.cfg]'
|
||||
-c 'halt'
|
||||
-c "program \"${EXECUTABLE_FILE_NAME}.hex\""
|
||||
-c 'reset'
|
||||
-c 'shutdown'
|
||||
COMMENT "flashing ${EXECUTABLE_BIN_NAME}.hex"
|
||||
)
|
||||
else ()
|
||||
add_custom_target(FLASH_ERASE
|
||||
COMMAND ${OPENOCD_BIN_PATH} -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c init -c halt -c 'nrf5 mass_erase' -c reset -c shutdown
|
||||
COMMENT "erasing flashing"
|
||||
)
|
||||
add_custom_target("FLASH_${EXECUTABLE_NAME}"
|
||||
DEPENDS ${EXECUTABLE_NAME}
|
||||
COMMAND ${OPENOCD_BIN_PATH} -c "tcl_port disabled" -c "gdb_port 3333" -c "telnet_port 4444" -f interface/stlink.cfg -c 'transport select hla_swd' -f target/nrf52.cfg -c "program \"${EXECUTABLE_FILE_NAME}.hex\"" -c reset -c shutdown
|
||||
COMMENT "flashing ${EXECUTABLE_FILE_NAME}.hex"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "components/ble/NotificationManager.h"
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
using namespace Pinetime::Controllers;
|
||||
|
||||
@@ -9,73 +10,117 @@ constexpr uint8_t NotificationManager::MessageSize;
|
||||
void NotificationManager::Push(NotificationManager::Notification&& notif) {
|
||||
notif.id = GetNextId();
|
||||
notif.valid = true;
|
||||
notifications[writeIndex] = std::move(notif);
|
||||
writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0;
|
||||
if (!empty)
|
||||
readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0;
|
||||
else
|
||||
empty = false;
|
||||
|
||||
newNotification = true;
|
||||
}
|
||||
|
||||
NotificationManager::Notification NotificationManager::GetLastNotification() {
|
||||
NotificationManager::Notification notification = notifications[readIndex];
|
||||
notification.index = 1;
|
||||
return notification;
|
||||
if (beginIdx > 0) {
|
||||
--beginIdx;
|
||||
} else {
|
||||
beginIdx = notifications.size() - 1;
|
||||
}
|
||||
notifications[beginIdx] = std::move(notif);
|
||||
if (size < notifications.size()) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
NotificationManager::Notification::Id NotificationManager::GetNextId() {
|
||||
return nextId++;
|
||||
}
|
||||
|
||||
NotificationManager::Notification NotificationManager::GetNext(NotificationManager::Notification::Id id) {
|
||||
auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n) {
|
||||
return n.valid && n.id == id;
|
||||
});
|
||||
if (currentIterator == notifications.end() || currentIterator->id != id)
|
||||
return Notification {};
|
||||
|
||||
auto& lastNotification = notifications[readIndex];
|
||||
|
||||
NotificationManager::Notification result;
|
||||
|
||||
if (currentIterator == (notifications.end() - 1))
|
||||
result = *(notifications.begin());
|
||||
else
|
||||
result = *(currentIterator + 1);
|
||||
|
||||
if (result.id <= id)
|
||||
NotificationManager::Notification NotificationManager::GetLastNotification() const {
|
||||
if (this->IsEmpty()) {
|
||||
return {};
|
||||
|
||||
result.index = (lastNotification.id - result.id) + 1;
|
||||
return result;
|
||||
}
|
||||
return this->At(0);
|
||||
}
|
||||
|
||||
NotificationManager::Notification NotificationManager::GetPrevious(NotificationManager::Notification::Id id) {
|
||||
auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n) {
|
||||
return n.valid && n.id == id;
|
||||
});
|
||||
if (currentIterator == notifications.end() || currentIterator->id != id)
|
||||
return Notification {};
|
||||
|
||||
auto& lastNotification = notifications[readIndex];
|
||||
|
||||
NotificationManager::Notification result;
|
||||
|
||||
if (currentIterator == notifications.begin())
|
||||
result = *(notifications.end() - 1);
|
||||
else
|
||||
result = *(currentIterator - 1);
|
||||
|
||||
if (result.id >= id)
|
||||
return {};
|
||||
|
||||
result.index = (lastNotification.id - result.id) + 1;
|
||||
return result;
|
||||
const NotificationManager::Notification& NotificationManager::At(NotificationManager::Notification::Idx idx) const {
|
||||
if (idx >= notifications.size()) {
|
||||
assert(false);
|
||||
return notifications.at(beginIdx); // this should not happen
|
||||
}
|
||||
size_t read_idx = (beginIdx + idx) % notifications.size();
|
||||
return notifications.at(read_idx);
|
||||
}
|
||||
|
||||
bool NotificationManager::AreNewNotificationsAvailable() {
|
||||
NotificationManager::Notification& NotificationManager::At(NotificationManager::Notification::Idx idx) {
|
||||
if (idx >= notifications.size()) {
|
||||
assert(false);
|
||||
return notifications.at(beginIdx); // this should not happen
|
||||
}
|
||||
size_t read_idx = (beginIdx + idx) % notifications.size();
|
||||
return notifications.at(read_idx);
|
||||
}
|
||||
|
||||
NotificationManager::Notification::Idx NotificationManager::IndexOf(NotificationManager::Notification::Id id) const {
|
||||
for (NotificationManager::Notification::Idx idx = 0; idx < this->size; idx++) {
|
||||
const NotificationManager::Notification& notification = this->At(idx);
|
||||
if (notification.id == id) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
NotificationManager::Notification NotificationManager::Get(NotificationManager::Notification::Id id) const {
|
||||
NotificationManager::Notification::Idx idx = this->IndexOf(id);
|
||||
if (idx == this->size) {
|
||||
return {};
|
||||
}
|
||||
return this->At(idx);
|
||||
}
|
||||
|
||||
NotificationManager::Notification NotificationManager::GetNext(NotificationManager::Notification::Id id) const {
|
||||
NotificationManager::Notification::Idx idx = this->IndexOf(id);
|
||||
if (idx == this->size) {
|
||||
return {};
|
||||
}
|
||||
if (idx == 0 || idx > notifications.size()) {
|
||||
return {};
|
||||
}
|
||||
return this->At(idx - 1);
|
||||
}
|
||||
|
||||
NotificationManager::Notification NotificationManager::GetPrevious(NotificationManager::Notification::Id id) const {
|
||||
NotificationManager::Notification::Idx idx = this->IndexOf(id);
|
||||
if (idx == this->size) {
|
||||
return {};
|
||||
}
|
||||
if (static_cast<size_t>(idx + 1) >= notifications.size()) {
|
||||
return {};
|
||||
}
|
||||
return this->At(idx + 1);
|
||||
}
|
||||
|
||||
void NotificationManager::DismissIdx(NotificationManager::Notification::Idx idx) {
|
||||
if (this->IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (idx >= size) {
|
||||
assert(false);
|
||||
return; // this should not happen
|
||||
}
|
||||
if (idx == 0) { // just remove the first element, don't need to change the other elements
|
||||
notifications.at(beginIdx).valid = false;
|
||||
beginIdx = (beginIdx + 1) % notifications.size();
|
||||
} else {
|
||||
// overwrite the specified entry by moving all later messages one index to the front
|
||||
for (size_t i = idx; i < size - 1; ++i) {
|
||||
this->At(i) = this->At(i + 1);
|
||||
}
|
||||
this->At(size - 1).valid = false;
|
||||
}
|
||||
--size;
|
||||
}
|
||||
|
||||
void NotificationManager::Dismiss(NotificationManager::Notification::Id id) {
|
||||
NotificationManager::Notification::Idx idx = this->IndexOf(id);
|
||||
if (idx == this->size) {
|
||||
return;
|
||||
}
|
||||
this->DismissIdx(idx);
|
||||
}
|
||||
|
||||
bool NotificationManager::AreNewNotificationsAvailable() const {
|
||||
return newNotification;
|
||||
}
|
||||
|
||||
@@ -84,9 +129,7 @@ bool NotificationManager::ClearNewNotificationFlag() {
|
||||
}
|
||||
|
||||
size_t NotificationManager::NbNotifications() const {
|
||||
return std::count_if(notifications.begin(), notifications.end(), [](const Notification& n) {
|
||||
return n.valid;
|
||||
});
|
||||
return size;
|
||||
}
|
||||
|
||||
const char* NotificationManager::Notification::Message() const {
|
||||
|
@@ -26,9 +26,9 @@ namespace Pinetime {
|
||||
|
||||
struct Notification {
|
||||
using Id = uint8_t;
|
||||
Id id;
|
||||
using Idx = uint8_t;
|
||||
Id id = 0;
|
||||
bool valid = false;
|
||||
uint8_t index;
|
||||
uint8_t size;
|
||||
std::array<char, MessageSize + 1> message;
|
||||
Categories category = Categories::Unknown;
|
||||
@@ -36,27 +36,38 @@ namespace Pinetime {
|
||||
const char* Message() const;
|
||||
const char* Title() const;
|
||||
};
|
||||
Notification::Id nextId {0};
|
||||
|
||||
void Push(Notification&& notif);
|
||||
Notification GetLastNotification();
|
||||
Notification GetNext(Notification::Id id);
|
||||
Notification GetPrevious(Notification::Id id);
|
||||
Notification GetLastNotification() const;
|
||||
Notification Get(Notification::Id id) const;
|
||||
Notification GetNext(Notification::Id id) const;
|
||||
Notification GetPrevious(Notification::Id id) const;
|
||||
// Return the index of the notification with the specified id, if not found return NbNotifications()
|
||||
Notification::Idx IndexOf(Notification::Id id) const;
|
||||
bool ClearNewNotificationFlag();
|
||||
bool AreNewNotificationsAvailable();
|
||||
bool AreNewNotificationsAvailable() const;
|
||||
void Dismiss(Notification::Id id);
|
||||
|
||||
static constexpr size_t MaximumMessageSize() {
|
||||
return MessageSize;
|
||||
};
|
||||
bool IsEmpty() const {
|
||||
return size == 0;
|
||||
}
|
||||
size_t NbNotifications() const;
|
||||
|
||||
private:
|
||||
Notification::Id nextId {0};
|
||||
Notification::Id GetNextId();
|
||||
const Notification& At(Notification::Idx idx) const;
|
||||
Notification& At(Notification::Idx idx);
|
||||
void DismissIdx(Notification::Idx idx);
|
||||
|
||||
static constexpr uint8_t TotalNbNotifications = 5;
|
||||
std::array<Notification, TotalNbNotifications> notifications;
|
||||
uint8_t readIndex = 0;
|
||||
uint8_t writeIndex = 0;
|
||||
bool empty = true;
|
||||
size_t beginIdx = TotalNbNotifications - 1; // index of the newest notification
|
||||
size_t size = 0; // number of valid notifications in buffer
|
||||
|
||||
std::atomic<bool> newNotification {false};
|
||||
};
|
||||
}
|
||||
|
@@ -74,14 +74,6 @@ BrightnessController::Levels BrightnessController::Level() const {
|
||||
return level;
|
||||
}
|
||||
|
||||
void BrightnessController::Backup() {
|
||||
backupLevel = level;
|
||||
}
|
||||
|
||||
void BrightnessController::Restore() {
|
||||
Set(backupLevel);
|
||||
}
|
||||
|
||||
void BrightnessController::Step() {
|
||||
switch (level) {
|
||||
case Levels::Low:
|
||||
@@ -123,4 +115,4 @@ const char* BrightnessController::ToString() {
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,15 +15,11 @@ namespace Pinetime {
|
||||
void Higher();
|
||||
void Step();
|
||||
|
||||
void Backup();
|
||||
void Restore();
|
||||
|
||||
const char* GetIcon();
|
||||
const char* ToString();
|
||||
|
||||
private:
|
||||
Levels level = Levels::High;
|
||||
Levels backupLevel = Levels::High;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ namespace Pinetime {
|
||||
class Settings {
|
||||
public:
|
||||
enum class ClockType : uint8_t { H24, H12 };
|
||||
enum class Notification : uint8_t { ON, OFF };
|
||||
enum class Notification : uint8_t { On, Off, Sleep };
|
||||
enum class ChimesOption : uint8_t { None, Hours, HalfHours };
|
||||
enum class WakeUpMode : uint8_t {
|
||||
SingleTap = 0,
|
||||
@@ -251,7 +251,7 @@ namespace Pinetime {
|
||||
uint32_t screenTimeOut = 15000;
|
||||
|
||||
ClockType clockType = ClockType::H24;
|
||||
Notification notificationStatus = Notification::ON;
|
||||
Notification notificationStatus = Notification::On;
|
||||
|
||||
uint8_t clockFace = 0;
|
||||
ChimesOption chimesOption = ChimesOption::None;
|
||||
|
@@ -129,6 +129,10 @@ void DisplayApp::InitHw() {
|
||||
}
|
||||
|
||||
void DisplayApp::Refresh() {
|
||||
auto LoadPreviousScreen = [this]() {
|
||||
LoadApp(returnToApp, returnDirection);
|
||||
};
|
||||
|
||||
TickType_t queueTimeout;
|
||||
switch (state) {
|
||||
case States::Idle:
|
||||
@@ -136,7 +140,7 @@ void DisplayApp::Refresh() {
|
||||
break;
|
||||
case States::Running:
|
||||
if (!currentScreen->IsRunning()) {
|
||||
LoadApp(returnToApp, returnDirection);
|
||||
LoadPreviousScreen();
|
||||
}
|
||||
queueTimeout = lv_task_handler();
|
||||
break;
|
||||
@@ -149,12 +153,10 @@ void DisplayApp::Refresh() {
|
||||
if (xQueueReceive(msgQueue, &msg, queueTimeout)) {
|
||||
switch (msg) {
|
||||
case Messages::DimScreen:
|
||||
// Backup brightness is the brightness to return to after dimming or sleeping
|
||||
brightnessController.Backup();
|
||||
brightnessController.Set(Controllers::BrightnessController::Levels::Low);
|
||||
break;
|
||||
case Messages::RestoreBrightness:
|
||||
brightnessController.Restore();
|
||||
brightnessController.Set(settingsController.GetBrightness());
|
||||
break;
|
||||
case Messages::GoToSleep:
|
||||
while (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) {
|
||||
@@ -165,7 +167,7 @@ void DisplayApp::Refresh() {
|
||||
state = States::Idle;
|
||||
break;
|
||||
case Messages::GoToRunning:
|
||||
brightnessController.Restore();
|
||||
brightnessController.Set(settingsController.GetBrightness());
|
||||
state = States::Running;
|
||||
break;
|
||||
case Messages::UpdateTimeOut:
|
||||
@@ -181,7 +183,7 @@ void DisplayApp::Refresh() {
|
||||
case Messages::TimerDone:
|
||||
if (currentApp == Apps::Timer) {
|
||||
auto* timer = static_cast<Screens::Timer*>(currentScreen.get());
|
||||
timer->SetDone();
|
||||
timer->Reset();
|
||||
} else {
|
||||
LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down);
|
||||
}
|
||||
@@ -224,9 +226,7 @@ void DisplayApp::Refresh() {
|
||||
break;
|
||||
}
|
||||
} else if (returnTouchEvent == gesture) {
|
||||
LoadApp(returnToApp, returnDirection);
|
||||
brightnessController.Set(settingsController.GetBrightness());
|
||||
brightnessController.Backup();
|
||||
LoadPreviousScreen();
|
||||
}
|
||||
} else {
|
||||
touchHandler.CancelTap();
|
||||
@@ -237,9 +237,7 @@ void DisplayApp::Refresh() {
|
||||
if (currentApp == Apps::Clock) {
|
||||
PushMessageToSystemTask(System::Messages::GoToSleep);
|
||||
} else {
|
||||
LoadApp(returnToApp, returnDirection);
|
||||
brightnessController.Set(settingsController.GetBrightness());
|
||||
brightnessController.Backup();
|
||||
LoadPreviousScreen();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -303,6 +301,8 @@ void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction
|
||||
|
||||
void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) {
|
||||
touchHandler.CancelTap();
|
||||
brightnessController.Set(settingsController.GetBrightness());
|
||||
|
||||
currentScreen.reset(nullptr);
|
||||
SetFullRefresh(direction);
|
||||
|
||||
@@ -311,7 +311,8 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
|
||||
|
||||
switch (app) {
|
||||
case Apps::Launcher:
|
||||
currentScreen = std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, dateTimeController);
|
||||
currentScreen =
|
||||
std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, bleController, dateTimeController);
|
||||
ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::SwipeDown);
|
||||
break;
|
||||
case Apps::None:
|
||||
@@ -367,7 +368,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
|
||||
currentScreen = std::make_unique<Screens::Timer>(this, timerController);
|
||||
break;
|
||||
case Apps::Alarm:
|
||||
currentScreen = std::make_unique<Screens::Alarm>(this, alarmController, settingsController, *systemTask);
|
||||
currentScreen = std::make_unique<Screens::Alarm>(this, alarmController, settingsController.GetClockType(), *systemTask);
|
||||
break;
|
||||
|
||||
// Settings
|
||||
@@ -377,7 +378,8 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
|
||||
dateTimeController,
|
||||
brightnessController,
|
||||
motorController,
|
||||
settingsController);
|
||||
settingsController,
|
||||
bleController);
|
||||
ReturnApp(Apps::Clock, FullRefreshDirections::LeftAnim, TouchEvents::SwipeLeft);
|
||||
break;
|
||||
case Apps::Settings:
|
||||
|
@@ -1,41 +1,13 @@
|
||||
/**
|
||||
* @file lv_pinetime_theme.c
|
||||
*
|
||||
*/
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "displayapp/lv_pinetime_theme.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void theme_apply(lv_obj_t* obj, lv_theme_style_t name);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
static lv_theme_t theme;
|
||||
|
||||
static lv_style_t style_circle;
|
||||
|
||||
static lv_style_t style_bg;
|
||||
static lv_style_t style_box;
|
||||
static lv_style_t style_box_border;
|
||||
static lv_style_t style_btn;
|
||||
static lv_style_t style_btn_border;
|
||||
static lv_style_t style_title;
|
||||
static lv_style_t style_label_white;
|
||||
static lv_style_t style_back;
|
||||
static lv_style_t style_icon;
|
||||
static lv_style_t style_bar_indic;
|
||||
static lv_style_t style_slider_knob;
|
||||
@@ -51,7 +23,6 @@ static lv_style_t style_arc_knob;
|
||||
static lv_style_t style_arc_indic;
|
||||
static lv_style_t style_table_cell;
|
||||
static lv_style_t style_pad_small;
|
||||
static lv_style_t style_bg_grad;
|
||||
static lv_style_t style_lmeter;
|
||||
static lv_style_t style_chart_serie;
|
||||
static lv_style_t style_cb_bg;
|
||||
@@ -59,26 +30,15 @@ static lv_style_t style_cb_bullet;
|
||||
|
||||
static bool inited;
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void style_init_reset(lv_style_t* style) {
|
||||
if (inited)
|
||||
if (inited) {
|
||||
lv_style_reset(style);
|
||||
else
|
||||
} else {
|
||||
lv_style_init(style);
|
||||
}
|
||||
}
|
||||
|
||||
static void basic_init(void) {
|
||||
|
||||
style_init_reset(&style_circle);
|
||||
lv_style_set_radius(&style_circle, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
|
||||
static void basic_init() {
|
||||
style_init_reset(&style_bg);
|
||||
lv_style_set_bg_opa(&style_bg, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_bg, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
@@ -87,41 +47,27 @@ static void basic_init(void) {
|
||||
style_init_reset(&style_box);
|
||||
lv_style_set_bg_opa(&style_box, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_radius(&style_box, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_value_color(&style_box, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_value_color(&style_box, LV_STATE_DEFAULT, Colors::bg);
|
||||
lv_style_set_value_font(&style_box, LV_STATE_DEFAULT, theme.font_normal);
|
||||
|
||||
style_init_reset(&style_box_border);
|
||||
lv_style_set_bg_opa(&style_box_border, LV_STATE_DEFAULT, LV_OPA_TRANSP);
|
||||
lv_style_set_border_width(&style_box_border, LV_STATE_DEFAULT, 2);
|
||||
lv_style_set_border_color(&style_box_border, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_text_color(&style_box, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
|
||||
style_init_reset(&style_title);
|
||||
lv_style_set_text_color(&style_title, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_text_font(&style_title, LV_STATE_DEFAULT, theme.font_subtitle);
|
||||
|
||||
style_init_reset(&style_label_white);
|
||||
lv_style_set_text_color(&style_label_white, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_text_color(&style_label_white, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_text_color(&style_label_white, LV_STATE_DISABLED, LV_COLOR_GRAY);
|
||||
|
||||
style_init_reset(&style_btn);
|
||||
lv_style_set_radius(&style_btn, LV_STATE_DEFAULT, 10);
|
||||
lv_style_set_bg_opa(&style_btn, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_DISABLED, LV_PINETIME_BLUE);
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_DISABLED | LV_STATE_CHECKED, lv_color_hex3(0x888));
|
||||
lv_style_set_border_color(&style_btn, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_DEFAULT, Colors::bg);
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_CHECKED, Colors::highlight);
|
||||
lv_style_set_bg_color(&style_btn, LV_STATE_DISABLED, Colors::bgDark);
|
||||
lv_style_set_border_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_border_width(&style_btn, LV_STATE_DEFAULT, 0);
|
||||
|
||||
lv_style_set_text_color(&style_btn, LV_STATE_DEFAULT, lv_color_hex(0xffffff));
|
||||
lv_style_set_text_color(&style_btn, LV_STATE_CHECKED, lv_color_hex(0xffffff));
|
||||
lv_style_set_text_color(&style_btn, LV_STATE_CHECKED, lv_color_hex(0xffffff));
|
||||
lv_style_set_text_color(&style_btn, LV_STATE_DISABLED, lv_color_hex(0x888888));
|
||||
lv_style_set_text_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_text_color(&style_btn, LV_STATE_DISABLED, LV_COLOR_GRAY);
|
||||
|
||||
lv_style_set_value_color(&style_btn, LV_STATE_DEFAULT, lv_color_hex(0xffffff));
|
||||
lv_style_set_value_color(&style_btn, LV_STATE_CHECKED, lv_color_hex(0xffffff));
|
||||
lv_style_set_value_color(&style_btn, LV_STATE_CHECKED, lv_color_hex(0xffffff));
|
||||
lv_style_set_value_color(&style_btn, LV_STATE_DISABLED, lv_color_hex(0x888888));
|
||||
lv_style_set_value_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_value_color(&style_btn, LV_STATE_DISABLED, LV_COLOR_GRAY);
|
||||
|
||||
lv_style_set_pad_left(&style_btn, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_pad_right(&style_btn, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
@@ -130,27 +76,12 @@ static void basic_init(void) {
|
||||
lv_style_set_pad_inner(&style_btn, LV_STATE_DEFAULT, LV_DPX(15));
|
||||
lv_style_set_outline_width(&style_btn, LV_STATE_DEFAULT, LV_DPX(2));
|
||||
lv_style_set_outline_opa(&style_btn, LV_STATE_DEFAULT, LV_OPA_0);
|
||||
lv_style_set_outline_color(&style_btn, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_outline_color(&style_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_transition_time(&style_btn, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_transition_delay(&style_btn, LV_STATE_DEFAULT, 0);
|
||||
|
||||
style_init_reset(&style_btn_border);
|
||||
lv_style_set_radius(&style_btn_border, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_border_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_border_width(&style_btn_border, LV_STATE_DEFAULT, 2);
|
||||
lv_style_set_bg_opa(&style_btn_border, LV_STATE_DEFAULT, LV_OPA_TRANSP);
|
||||
lv_style_set_bg_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_text_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_value_color(&style_btn_border, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_transition_prop_3(&style_btn_border, LV_STATE_DEFAULT, LV_STYLE_BG_OPA);
|
||||
|
||||
style_init_reset(&style_icon);
|
||||
lv_style_set_text_color(&style_icon, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
|
||||
style_init_reset(&style_back);
|
||||
lv_style_set_value_color(&style_back, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_value_str(&style_back, LV_STATE_DEFAULT, LV_SYMBOL_LEFT);
|
||||
lv_style_set_value_font(&style_back, LV_STATE_DEFAULT, theme.font_subtitle);
|
||||
lv_style_set_text_color(&style_icon, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
|
||||
style_init_reset(&style_bar_indic);
|
||||
lv_style_set_bg_opa(&style_bar_indic, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
@@ -165,15 +96,11 @@ static void basic_init(void) {
|
||||
|
||||
style_init_reset(&style_list_btn);
|
||||
lv_style_set_bg_opa(&style_list_btn, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_list_btn, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_bg_color(&style_list_btn, LV_STATE_CHECKED, LV_PINETIME_GRAY);
|
||||
lv_style_set_bg_color(&style_list_btn, LV_STATE_CHECKED | LV_STATE_PRESSED, lv_color_darken(LV_PINETIME_GRAY, LV_OPA_20));
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_CHECKED, LV_PINETIME_WHITE);
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_CHECKED | LV_STATE_PRESSED, LV_PINETIME_WHITE);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_CHECKED, LV_PINETIME_WHITE);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_CHECKED | LV_STATE_PRESSED, LV_PINETIME_WHITE);
|
||||
lv_style_set_bg_color(&style_list_btn, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_DEFAULT, Colors::bg);
|
||||
lv_style_set_text_color(&style_list_btn, LV_STATE_CHECKED, LV_COLOR_WHITE);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_DEFAULT, Colors::bg);
|
||||
lv_style_set_image_recolor(&style_list_btn, LV_STATE_CHECKED, LV_COLOR_WHITE);
|
||||
lv_style_set_pad_left(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 25);
|
||||
lv_style_set_pad_right(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 25);
|
||||
lv_style_set_pad_top(&style_list_btn, LV_STATE_DEFAULT, LV_HOR_RES / 100);
|
||||
@@ -182,25 +109,23 @@ static void basic_init(void) {
|
||||
|
||||
style_init_reset(&style_ddlist_list);
|
||||
// Causes lag unfortunately, so we'll have to live with the selected item overflowing the corner
|
||||
//lv_style_set_clip_corner(&style_ddlist_list, LV_STATE_DEFAULT, true);
|
||||
// lv_style_set_clip_corner(&style_ddlist_list, LV_STATE_DEFAULT, true);
|
||||
lv_style_set_text_line_space(&style_ddlist_list, LV_STATE_DEFAULT, LV_VER_RES / 25);
|
||||
lv_style_set_shadow_width(&style_ddlist_list, LV_STATE_DEFAULT, LV_VER_RES / 20);
|
||||
lv_style_set_shadow_color(&style_ddlist_list, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_style_set_bg_color(&style_ddlist_list, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_style_set_bg_color(&style_ddlist_list, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_style_set_pad_all(&style_ddlist_list, LV_STATE_DEFAULT, 20);
|
||||
|
||||
style_init_reset(&style_ddlist_selected);
|
||||
lv_style_set_bg_opa(&style_ddlist_selected, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_ddlist_selected, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_bg_color(&style_ddlist_selected, LV_STATE_DEFAULT, Colors::bg);
|
||||
|
||||
style_init_reset(&style_sw_bg);
|
||||
lv_style_set_bg_opa(&style_sw_bg, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_sw_bg, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_bg_color(&style_sw_bg, LV_STATE_DEFAULT, Colors::bg);
|
||||
lv_style_set_radius(&style_sw_bg, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
|
||||
style_init_reset(&style_sw_indic);
|
||||
lv_style_set_bg_opa(&style_sw_indic, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_sw_indic, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_style_set_bg_color(&style_sw_indic, LV_STATE_DEFAULT, Colors::highlight);
|
||||
|
||||
style_init_reset(&style_sw_knob);
|
||||
lv_style_set_bg_opa(&style_sw_knob, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
@@ -228,12 +153,12 @@ static void basic_init(void) {
|
||||
lv_style_set_pad_right(&style_slider_knob, LV_STATE_PRESSED, 14);
|
||||
|
||||
style_init_reset(&style_arc_indic);
|
||||
lv_style_set_line_color(&style_arc_indic, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
|
||||
lv_style_set_line_color(&style_arc_indic, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_style_set_line_width(&style_arc_indic, LV_STATE_DEFAULT, LV_DPX(25));
|
||||
lv_style_set_line_rounded(&style_arc_indic, LV_STATE_DEFAULT, true);
|
||||
|
||||
style_init_reset(&style_arc_bg);
|
||||
lv_style_set_line_color(&style_arc_bg, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_style_set_line_color(&style_arc_bg, LV_STATE_DEFAULT, Colors::bg);
|
||||
lv_style_set_line_width(&style_arc_bg, LV_STATE_DEFAULT, LV_DPX(25));
|
||||
lv_style_set_line_rounded(&style_arc_bg, LV_STATE_DEFAULT, true);
|
||||
lv_style_set_pad_all(&style_arc_bg, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
@@ -245,7 +170,7 @@ static void basic_init(void) {
|
||||
lv_style_set_pad_all(&style_arc_knob, LV_STATE_DEFAULT, LV_DPX(5));
|
||||
|
||||
style_init_reset(&style_table_cell);
|
||||
lv_style_set_border_color(&style_table_cell, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
|
||||
lv_style_set_border_color(&style_table_cell, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||
lv_style_set_border_width(&style_table_cell, LV_STATE_DEFAULT, 1);
|
||||
lv_style_set_border_side(&style_table_cell, LV_STATE_DEFAULT, LV_BORDER_SIDE_FULL);
|
||||
lv_style_set_pad_left(&style_table_cell, LV_STATE_DEFAULT, 5);
|
||||
@@ -261,11 +186,6 @@ static void basic_init(void) {
|
||||
lv_style_set_pad_bottom(&style_pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
lv_style_set_pad_inner(&style_pad_small, LV_STATE_DEFAULT, pad_small_value);
|
||||
|
||||
style_init_reset(&style_bg_grad);
|
||||
lv_style_set_bg_color(&style_bg_grad, LV_STATE_DEFAULT, lv_color_hsv_to_rgb(10, 10, 40));
|
||||
lv_style_set_bg_grad_color(&style_bg_grad, LV_STATE_DEFAULT, lv_color_hsv_to_rgb(10, 10, 20));
|
||||
lv_style_set_bg_grad_dir(&style_bg_grad, LV_STATE_DEFAULT, LV_GRAD_DIR_VER);
|
||||
|
||||
style_init_reset(&style_lmeter);
|
||||
lv_style_set_radius(&style_lmeter, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_style_set_pad_left(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
@@ -274,30 +194,30 @@ static void basic_init(void) {
|
||||
lv_style_set_pad_inner(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(30));
|
||||
lv_style_set_scale_width(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(25));
|
||||
|
||||
lv_style_set_line_color(&style_lmeter, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_scale_grad_color(&style_lmeter, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_scale_end_color(&style_lmeter, LV_STATE_DEFAULT, lv_color_hex3(0x888));
|
||||
lv_style_set_line_color(&style_lmeter, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_scale_grad_color(&style_lmeter, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_scale_end_color(&style_lmeter, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||
lv_style_set_line_width(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_scale_end_line_width(&style_lmeter, LV_STATE_DEFAULT, LV_DPX(7));
|
||||
|
||||
style_init_reset(&style_chart_serie);
|
||||
lv_style_set_line_color(&style_chart_serie, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
|
||||
lv_style_set_line_color(&style_chart_serie, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_line_width(&style_chart_serie, LV_STATE_DEFAULT, 4);
|
||||
lv_style_set_size(&style_chart_serie, LV_STATE_DEFAULT, 4);
|
||||
lv_style_set_bg_opa(&style_chart_serie, LV_STATE_DEFAULT, 0);
|
||||
|
||||
lv_style_reset(&style_cb_bg);
|
||||
lv_style_set_radius(&style_cb_bg, LV_STATE_DEFAULT, LV_DPX(4));
|
||||
lv_style_set_pad_inner(&style_cb_bg, LV_STATE_DEFAULT, LV_DPX(10));
|
||||
lv_style_set_outline_color(&style_cb_bg, LV_STATE_DEFAULT, theme.color_primary);
|
||||
lv_style_set_pad_inner(&style_cb_bg, LV_STATE_DEFAULT, 18);
|
||||
lv_style_set_outline_color(&style_cb_bg, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_style_set_outline_width(&style_cb_bg, LV_STATE_DEFAULT, LV_DPX(2));
|
||||
lv_style_set_outline_pad(&style_cb_bg, LV_STATE_DEFAULT, LV_DPX(20));
|
||||
lv_style_set_transition_time(&style_cb_bg, LV_STATE_DEFAULT, 0);
|
||||
lv_style_set_transition_prop_6(&style_cb_bg, LV_STATE_DEFAULT, LV_STYLE_OUTLINE_OPA);
|
||||
|
||||
lv_style_reset(&style_cb_bullet);
|
||||
lv_style_set_outline_opa(&style_cb_bullet, LV_STATE_FOCUSED, LV_OPA_TRANSP);
|
||||
lv_style_set_radius(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(4));
|
||||
lv_style_set_pattern_image(&style_cb_bullet, LV_STATE_CHECKED, LV_SYMBOL_OK);
|
||||
lv_style_set_pattern_recolor(&style_cb_bullet, LV_STATE_CHECKED, LV_COLOR_WHITE);
|
||||
lv_style_set_pad_left(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8));
|
||||
lv_style_set_pad_right(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8));
|
||||
@@ -305,10 +225,6 @@ static void basic_init(void) {
|
||||
lv_style_set_pad_bottom(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8));
|
||||
}
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Initialize the default
|
||||
* @param color_primary the primary color of the theme
|
||||
@@ -347,9 +263,7 @@ lv_theme_t* lv_pinetime_theme_init(lv_color_t color_primary,
|
||||
static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) {
|
||||
lv_style_list_t* list;
|
||||
|
||||
/*To avoid warnings*/
|
||||
uint32_t name_int = (uint32_t) name;
|
||||
switch (name_int) {
|
||||
switch (name) {
|
||||
case LV_THEME_NONE:
|
||||
break;
|
||||
|
||||
@@ -376,7 +290,6 @@ static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) {
|
||||
lv_obj_clean_style_list(obj, LV_BTN_PART_MAIN);
|
||||
list = lv_obj_get_style_list(obj, LV_BTN_PART_MAIN);
|
||||
_lv_style_list_add_style(list, &style_btn);
|
||||
//_lv_style_list_add_style(list, &style_bg_grad);
|
||||
break;
|
||||
|
||||
case LV_THEME_BTNMATRIX:
|
||||
@@ -386,8 +299,6 @@ static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) {
|
||||
|
||||
list = lv_obj_get_style_list(obj, LV_BTNMATRIX_PART_BTN);
|
||||
_lv_style_list_add_style(list, &style_btn);
|
||||
//_lv_style_list_add_style(list, &style_bg_grad);
|
||||
//_lv_style_list_add_style(list, &style_bg_click);
|
||||
break;
|
||||
|
||||
case LV_THEME_BAR:
|
||||
@@ -490,7 +401,7 @@ static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) {
|
||||
_lv_style_list_add_style(list, &style_scrollbar);
|
||||
break;
|
||||
|
||||
case LV_THEME_TABLE:
|
||||
case LV_THEME_TABLE: {
|
||||
list = lv_obj_get_style_list(obj, LV_TABLE_PART_BG);
|
||||
_lv_style_list_add_style(list, &style_bg);
|
||||
|
||||
@@ -503,7 +414,7 @@ static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) {
|
||||
_lv_style_list_add_style(list, &style_table_cell);
|
||||
_lv_style_list_add_style(list, &style_label_white);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case LV_THEME_LINEMETER:
|
||||
list = lv_obj_get_style_list(obj, LV_LINEMETER_PART_MAIN);
|
||||
@@ -533,7 +444,3 @@ static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) {
|
||||
|
||||
lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
@@ -1,39 +1,17 @@
|
||||
/**
|
||||
* @file lv_pinetime_theme.h
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef LV_PINETIME_THEME_H
|
||||
#define LV_PINETIME_THEME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
/*Colors*/
|
||||
#define LV_PINETIME_WHITE lv_color_hex(0xffffff)
|
||||
#define LV_PINETIME_LIGHT lv_color_hex(0xf3f8fe)
|
||||
#define LV_PINETIME_GRAY lv_color_hex(0x8a8a8a)
|
||||
#define LV_PINETIME_LIGHT_GRAY lv_color_hex(0xc4c4c4)
|
||||
#define LV_PINETIME_BLUE lv_color_hex(0x5d697e)
|
||||
#define LV_PINETIME_GREEN lv_color_hex(0x4cb242)
|
||||
#define LV_PINETIME_RED lv_color_hex(0xd51732)
|
||||
namespace Colors {
|
||||
static constexpr lv_color_t orange = LV_COLOR_MAKE(0xff, 0xb0, 0x0);
|
||||
static constexpr lv_color_t green = LV_COLOR_MAKE(0x0, 0xb0, 0x0);
|
||||
static constexpr lv_color_t lightGray = LV_COLOR_MAKE(0xb0, 0xb0, 0xb0);
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
static constexpr lv_color_t bg = LV_COLOR_MAKE(0x5d, 0x69, 0x7e);
|
||||
static constexpr lv_color_t bgAlt = LV_COLOR_MAKE(0x38, 0x38, 0x38);
|
||||
static constexpr lv_color_t bgDark = LV_COLOR_MAKE(0x18, 0x18, 0x18);
|
||||
static constexpr lv_color_t highlight = green;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the default
|
||||
@@ -53,12 +31,3 @@ lv_theme_t* lv_pinetime_theme_init(lv_color_t color_primary,
|
||||
const lv_font_t* font_normal,
|
||||
const lv_font_t* font_subtitle,
|
||||
const lv_font_t* font_title);
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
@@ -1,5 +1,5 @@
|
||||
#include "displayapp/LittleVgl.h"
|
||||
#include "displayapp/lv_pinetime_theme.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
@@ -6,6 +6,8 @@ find_program(LV_FONT_CONV "lv_font_conv" NO_CACHE REQUIRED
|
||||
message(STATUS "Using ${LV_FONT_CONV} to generate font files")
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/jetbrains_mono_bold_20.c_zero.patch
|
||||
${CMAKE_CURRENT_BINARY_DIR}/jetbrains_mono_bold_20.c_zero.patch COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_LIST_DIR}/jetbrains_mono_bold_20.c_M.patch
|
||||
${CMAKE_CURRENT_BINARY_DIR}/jetbrains_mono_bold_20.c_M.patch COPYONLY)
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
|
||||
# FindPython3 module introduces with CMake 3.12
|
||||
# https://cmake.org/cmake/help/latest/module/FindPython3.html
|
||||
|
@@ -1,16 +1,19 @@
|
||||
# Fonts
|
||||
|
||||
* [Jetbrains Mono](https://www.jetbrains.com/fr-fr/lp/mono/)
|
||||
* [Awesome font from LVGL](https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff)
|
||||
* [Open Sans Light from Google](https://fonts.google.com/specimen/Open+Sans)
|
||||
- [Jetbrains Mono](https://www.jetbrains.com/lp/mono/)
|
||||
- [Font Awesome](https://fontawesome.com/v5/cheatsheet/free/solid)
|
||||
- [Open Sans Light](https://fonts.google.com/specimen/Open+Sans)
|
||||
- [Material Symbols](https://fonts.google.com/icons)
|
||||
|
||||
### How to add new symbols:
|
||||
|
||||
* Browse [this cheatsheet](https://fontawesome.com/cheatsheet/free/solid) and pick symbols
|
||||
* For each symbol, add its hex code (0xf641 for the 'Ad' icon, for example) to the *Range* list (or the symbol list when its simple enough) in the `fonts.json` file
|
||||
* Convert this hex value into a UTF-8 code
|
||||
- Browse the cheat sheets and pick symbols
|
||||
- [Font Awesome](https://fontawesome.com/v5/cheatsheet/free/solid)
|
||||
- [Material Symbols](https://fonts.google.com/icons)
|
||||
- For each symbol, add its hex code (0xf641 for the 'Ad' icon, for example) to the *Range* list in the `fonts.json` file
|
||||
- Convert this hex value into a UTF-8 code
|
||||
using [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f185&mode=hex)
|
||||
* Define the new symbols in `src/displayapp/screens/Symbols.h`:
|
||||
- Define the new symbols in `src/displayapp/screens/Symbols.h`:
|
||||
|
||||
```
|
||||
static constexpr const char* newSymbol = "\xEF\x86\x85";
|
||||
@@ -20,11 +23,12 @@ static constexpr const char* newSymbol = "\xEF\x86\x85";
|
||||
|
||||
inside `fonts`, there is a dictionary of fonts,
|
||||
and for each font there is:
|
||||
* sources - list of file,range(,symbols) wanted (as a dictionary of those)
|
||||
* bpp - bits per pixel.
|
||||
* size - size.
|
||||
* patches - list of extra "patches" to run: a path to a .patch file. (may be relative)
|
||||
* compress - optional. default disabled. add `"compress": true` to enable
|
||||
|
||||
- sources - list of file,range(,symbols) wanted (as a dictionary of those)
|
||||
- bpp - bits per pixel.
|
||||
- size - size.
|
||||
- patches - list of extra "patches" to run: a path to a .patch file. (may be relative)
|
||||
- compress - optional. default disabled. add `"compress": true` to enable
|
||||
|
||||
### Navigation font
|
||||
|
||||
|
@@ -7,12 +7,12 @@
|
||||
},
|
||||
{
|
||||
"file": "FontAwesome5-Solid+Brands+Regular.woff",
|
||||
"range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015"
|
||||
"range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015, 0xf00c"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 20,
|
||||
"patches": ["jetbrains_mono_bold_20.c_zero.patch"]
|
||||
"patches": ["jetbrains_mono_bold_20.c_zero.patch", "jetbrains_mono_bold_20.c_M.patch"]
|
||||
},
|
||||
"jetbrains_mono_42": {
|
||||
"sources": [
|
||||
@@ -57,8 +57,8 @@
|
||||
"lv_font_sys_48": {
|
||||
"sources": [
|
||||
{
|
||||
"file": "icons_sys_48.ttf",
|
||||
"range": "0xe902, 0xe904-0xe907, 0xe90b-0xe90c"
|
||||
"file": "material-design-icons/MaterialIcons-Regular.ttf",
|
||||
"range": "0xf00b, 0xe3aa-0xe3ac, 0xe7f6-0xe7f7, 0xe8b8, 0xef44"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
|
@@ -67,7 +67,7 @@ def main():
|
||||
subprocess.check_call(line)
|
||||
if patches:
|
||||
for patch in patches:
|
||||
subprocess.check_call(['/usr/bin/patch', name+'.c', patch])
|
||||
subprocess.check_call(['/usr/bin/env', 'patch', name+'.c', patch])
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
8
src/displayapp/fonts/jetbrains_mono_bold_20.c_M.patch
Normal file
8
src/displayapp/fonts/jetbrains_mono_bold_20.c_M.patch
Normal file
@@ -0,0 +1,8 @@
|
||||
@@ -217,7 +217,7 @@
|
||||
0xc0, 0xe0, 0x70, 0x38, 0x1c, 0xf, 0xff, 0xfc,
|
||||
|
||||
/* U+004D "M" */
|
||||
- 0xf3, 0xfc, 0xfd, 0x3f, 0xcf, 0xff, 0xff, 0xfe,
|
||||
+ 0xf3, 0xfc, 0xff, 0x3f, 0xcf, 0xff, 0xff, 0xfe,
|
||||
0xdf, 0xb7, 0xe1, 0xf8, 0x7e, 0x1f, 0x87, 0xe1,
|
||||
0xf8, 0x70,
|
File diff suppressed because it is too large
Load Diff
202
src/displayapp/fonts/material-design-icons/LICENSE
Normal file
202
src/displayapp/fonts/material-design-icons/LICENSE
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
Binary file not shown.
@@ -18,10 +18,18 @@
|
||||
#include "displayapp/screens/Alarm.h"
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
|
||||
namespace {
|
||||
void ValueChangedHandler(void* userData) {
|
||||
auto* screen = static_cast<Alarm*>(userData);
|
||||
screen->OnValueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
static void btnEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* screen = static_cast<Alarm*>(obj->user_data);
|
||||
screen->OnButtonEvent(obj, event);
|
||||
@@ -34,58 +42,33 @@ static void StopAlarmTaskCallback(lv_task_t* task) {
|
||||
|
||||
Alarm::Alarm(DisplayApp* app,
|
||||
Controllers::AlarmController& alarmController,
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Controllers::Settings::ClockType clockType,
|
||||
System::SystemTask& systemTask)
|
||||
: Screen(app), alarmController {alarmController}, settingsController {settingsController}, systemTask {systemTask} {
|
||||
: Screen(app), alarmController {alarmController}, systemTask {systemTask} {
|
||||
|
||||
time = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
hourCounter.Create();
|
||||
lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
if (clockType == Controllers::Settings::ClockType::H12) {
|
||||
hourCounter.EnableTwelveHourMode();
|
||||
|
||||
alarmHours = alarmController.Hours();
|
||||
alarmMinutes = alarmController.Minutes();
|
||||
lv_label_set_text_fmt(time, "%02hhu:%02hhu", alarmHours, alarmMinutes);
|
||||
lblampm = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
|
||||
lv_label_set_text_static(lblampm, "AM");
|
||||
lv_label_set_align(lblampm, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 0, 30);
|
||||
}
|
||||
hourCounter.SetValue(alarmController.Hours());
|
||||
hourCounter.SetValueChangedEventCallback(this, ValueChangedHandler);
|
||||
|
||||
lv_obj_align(time, lv_scr_act(), LV_ALIGN_CENTER, 0, -25);
|
||||
minuteCounter.Create();
|
||||
lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
|
||||
minuteCounter.SetValue(alarmController.Minutes());
|
||||
minuteCounter.SetValueChangedEventCallback(this, ValueChangedHandler);
|
||||
|
||||
lblampm = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
|
||||
lv_obj_set_style_local_text_color(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_label_set_text_static(lblampm, " ");
|
||||
lv_label_set_align(lblampm, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 0, 30);
|
||||
|
||||
btnHoursUp = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnHoursUp->user_data = this;
|
||||
lv_obj_set_event_cb(btnHoursUp, btnEventHandler);
|
||||
lv_obj_set_size(btnHoursUp, 60, 40);
|
||||
lv_obj_align(btnHoursUp, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, -85);
|
||||
txtHrUp = lv_label_create(btnHoursUp, nullptr);
|
||||
lv_label_set_text_static(txtHrUp, "+");
|
||||
|
||||
btnHoursDown = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnHoursDown->user_data = this;
|
||||
lv_obj_set_event_cb(btnHoursDown, btnEventHandler);
|
||||
lv_obj_set_size(btnHoursDown, 60, 40);
|
||||
lv_obj_align(btnHoursDown, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, 35);
|
||||
txtHrDown = lv_label_create(btnHoursDown, nullptr);
|
||||
lv_label_set_text_static(txtHrDown, "-");
|
||||
|
||||
btnMinutesUp = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnMinutesUp->user_data = this;
|
||||
lv_obj_set_event_cb(btnMinutesUp, btnEventHandler);
|
||||
lv_obj_set_size(btnMinutesUp, 60, 40);
|
||||
lv_obj_align(btnMinutesUp, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, -85);
|
||||
txtMinUp = lv_label_create(btnMinutesUp, nullptr);
|
||||
lv_label_set_text_static(txtMinUp, "+");
|
||||
|
||||
btnMinutesDown = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnMinutesDown->user_data = this;
|
||||
lv_obj_set_event_cb(btnMinutesDown, btnEventHandler);
|
||||
lv_obj_set_size(btnMinutesDown, 60, 40);
|
||||
lv_obj_align(btnMinutesDown, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, 35);
|
||||
txtMinDown = lv_label_create(btnMinutesDown, nullptr);
|
||||
lv_label_set_text_static(txtMinDown, "-");
|
||||
lv_obj_t* colonLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(colonLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
||||
lv_label_set_text_static(colonLabel, ":");
|
||||
lv_obj_align(colonLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, -29);
|
||||
|
||||
btnStop = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnStop->user_data = this;
|
||||
@@ -97,6 +80,8 @@ Alarm::Alarm(DisplayApp* app,
|
||||
lv_label_set_text_static(txtStop, Symbols::stop);
|
||||
lv_obj_set_hidden(btnStop, true);
|
||||
|
||||
static constexpr lv_color_t bgColor = Colors::bgAlt;
|
||||
|
||||
btnRecur = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnRecur->user_data = this;
|
||||
lv_obj_set_event_cb(btnRecur, btnEventHandler);
|
||||
@@ -104,13 +89,18 @@ Alarm::Alarm(DisplayApp* app,
|
||||
lv_obj_align(btnRecur, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||
txtRecur = lv_label_create(btnRecur, nullptr);
|
||||
SetRecurButtonState();
|
||||
lv_obj_set_style_local_bg_color(btnRecur, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor);
|
||||
|
||||
btnInfo = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnInfo->user_data = this;
|
||||
lv_obj_set_event_cb(btnInfo, btnEventHandler);
|
||||
lv_obj_set_size(btnInfo, 50, 40);
|
||||
lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_CENTER, 0, -85);
|
||||
txtInfo = lv_label_create(btnInfo, nullptr);
|
||||
lv_obj_set_size(btnInfo, 50, 50);
|
||||
lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, -4);
|
||||
lv_obj_set_style_local_bg_color(btnInfo, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor);
|
||||
lv_obj_set_style_local_border_width(btnInfo, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 4);
|
||||
lv_obj_set_style_local_border_color(btnInfo, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
|
||||
lv_obj_t* txtInfo = lv_label_create(btnInfo, nullptr);
|
||||
lv_label_set_text_static(txtInfo, "i");
|
||||
|
||||
enableSwitch = lv_switch_create(lv_scr_act(), nullptr);
|
||||
@@ -119,6 +109,7 @@ Alarm::Alarm(DisplayApp* app,
|
||||
lv_obj_set_size(enableSwitch, 100, 50);
|
||||
// Align to the center of 115px from edge
|
||||
lv_obj_align(enableSwitch, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 7, 0);
|
||||
lv_obj_set_style_local_bg_color(enableSwitch, LV_SWITCH_PART_BG, LV_STATE_DEFAULT, bgColor);
|
||||
|
||||
UpdateAlarmTime();
|
||||
|
||||
@@ -136,8 +127,14 @@ Alarm::~Alarm() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
void Alarm::DisableAlarm() {
|
||||
if (alarmController.State() == AlarmController::AlarmState::Set) {
|
||||
alarmController.DisableAlarm();
|
||||
lv_switch_off(enableSwitch, LV_ANIM_ON);
|
||||
}
|
||||
}
|
||||
|
||||
void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) {
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
if (event == LV_EVENT_CLICKED) {
|
||||
if (obj == btnStop) {
|
||||
StopAlerting();
|
||||
@@ -159,49 +156,8 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
// If any other button was pressed, disable the alarm
|
||||
// this is to make it clear that the alarm won't be set until it is turned back on
|
||||
if (alarmController.State() == AlarmController::AlarmState::Set) {
|
||||
alarmController.DisableAlarm();
|
||||
lv_switch_off(enableSwitch, LV_ANIM_ON);
|
||||
}
|
||||
if (obj == btnMinutesUp) {
|
||||
if (alarmMinutes >= 59) {
|
||||
alarmMinutes = 0;
|
||||
} else {
|
||||
alarmMinutes++;
|
||||
}
|
||||
UpdateAlarmTime();
|
||||
return;
|
||||
}
|
||||
if (obj == btnMinutesDown) {
|
||||
if (alarmMinutes == 0) {
|
||||
alarmMinutes = 59;
|
||||
} else {
|
||||
alarmMinutes--;
|
||||
}
|
||||
UpdateAlarmTime();
|
||||
return;
|
||||
}
|
||||
if (obj == btnHoursUp) {
|
||||
if (alarmHours >= 23) {
|
||||
alarmHours = 0;
|
||||
} else {
|
||||
alarmHours++;
|
||||
}
|
||||
UpdateAlarmTime();
|
||||
return;
|
||||
}
|
||||
if (obj == btnHoursDown) {
|
||||
if (alarmHours == 0) {
|
||||
alarmHours = 23;
|
||||
} else {
|
||||
alarmHours--;
|
||||
}
|
||||
UpdateAlarmTime();
|
||||
return;
|
||||
}
|
||||
if (obj == btnRecur) {
|
||||
DisableAlarm();
|
||||
ToggleRecurrence();
|
||||
}
|
||||
}
|
||||
@@ -224,30 +180,20 @@ bool Alarm::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
return alarmController.State() == AlarmController::AlarmState::Alerting && event == TouchEvents::SwipeDown;
|
||||
}
|
||||
|
||||
void Alarm::OnValueChanged() {
|
||||
DisableAlarm();
|
||||
UpdateAlarmTime();
|
||||
}
|
||||
|
||||
void Alarm::UpdateAlarmTime() {
|
||||
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
|
||||
switch (alarmHours) {
|
||||
case 0:
|
||||
lv_label_set_text_static(lblampm, "AM");
|
||||
lv_label_set_text_fmt(time, "%02d:%02d", 12, alarmMinutes);
|
||||
break;
|
||||
case 1 ... 11:
|
||||
lv_label_set_text_static(lblampm, "AM");
|
||||
lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes);
|
||||
break;
|
||||
case 12:
|
||||
lv_label_set_text_static(lblampm, "PM");
|
||||
lv_label_set_text_fmt(time, "%02d:%02d", 12, alarmMinutes);
|
||||
break;
|
||||
case 13 ... 23:
|
||||
lv_label_set_text_static(lblampm, "PM");
|
||||
lv_label_set_text_fmt(time, "%02d:%02d", alarmHours - 12, alarmMinutes);
|
||||
break;
|
||||
if (lblampm != nullptr) {
|
||||
if (hourCounter.GetValue() >= 12) {
|
||||
lv_label_set_text_static(lblampm, "PM");
|
||||
} else {
|
||||
lv_label_set_text_static(lblampm, "AM");
|
||||
}
|
||||
} else {
|
||||
lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes);
|
||||
}
|
||||
alarmController.SetAlarmTime(alarmHours, alarmMinutes);
|
||||
alarmController.SetAlarmTime(hourCounter.GetValue(), minuteCounter.GetValue());
|
||||
}
|
||||
|
||||
void Alarm::SetAlerting() {
|
||||
@@ -283,6 +229,9 @@ void Alarm::SetSwitchState(lv_anim_enable_t anim) {
|
||||
}
|
||||
|
||||
void Alarm::ShowInfo() {
|
||||
if (btnMessage != nullptr) {
|
||||
return;
|
||||
}
|
||||
btnMessage = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnMessage->user_data = this;
|
||||
lv_obj_set_event_cb(btnMessage, btnEventHandler);
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "systemtask/SystemTask.h"
|
||||
#include "displayapp/LittleVgl.h"
|
||||
#include "components/alarm/AlarmController.h"
|
||||
#include "displayapp/widgets/Counter.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
@@ -29,29 +30,28 @@ namespace Pinetime {
|
||||
public:
|
||||
Alarm(DisplayApp* app,
|
||||
Controllers::AlarmController& alarmController,
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Controllers::Settings::ClockType clockType,
|
||||
System::SystemTask& systemTask);
|
||||
~Alarm() override;
|
||||
void SetAlerting();
|
||||
void OnButtonEvent(lv_obj_t* obj, lv_event_t event);
|
||||
bool OnButtonPushed() override;
|
||||
bool OnTouchEvent(TouchEvents event) override;
|
||||
void OnValueChanged();
|
||||
void StopAlerting();
|
||||
|
||||
private:
|
||||
uint8_t alarmHours;
|
||||
uint8_t alarmMinutes;
|
||||
Controllers::AlarmController& alarmController;
|
||||
Controllers::Settings& settingsController;
|
||||
System::SystemTask& systemTask;
|
||||
|
||||
lv_obj_t *time, *lblampm, *btnStop, *txtStop, *btnMinutesUp, *btnMinutesDown, *btnHoursUp, *btnHoursDown, *txtMinUp, *txtMinDown,
|
||||
*txtHrUp, *txtHrDown, *btnRecur, *txtRecur, *btnInfo, *txtInfo, *enableSwitch;
|
||||
lv_obj_t *btnStop, *txtStop, *btnRecur, *txtRecur, *btnInfo, *enableSwitch;
|
||||
lv_obj_t* lblampm = nullptr;
|
||||
lv_obj_t* txtMessage = nullptr;
|
||||
lv_obj_t* btnMessage = nullptr;
|
||||
lv_task_t* taskStopAlarm = nullptr;
|
||||
|
||||
enum class EnableButtonState { On, Off, Alerting };
|
||||
void DisableAlarm();
|
||||
void SetRecurButtonState();
|
||||
void SetSwitchState(lv_anim_enable_t anim);
|
||||
void SetAlarm();
|
||||
@@ -59,6 +59,8 @@ namespace Pinetime {
|
||||
void HideInfo();
|
||||
void ToggleRecurrence();
|
||||
void UpdateAlarmTime();
|
||||
Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_76);
|
||||
Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@@ -1,33 +1,34 @@
|
||||
#include "displayapp/screens/ApplicationList.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <array>
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/screens/Tile.h"
|
||||
#include <functional>
|
||||
#include "displayapp/Apps.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
constexpr std::array<Tile::Applications, ApplicationList::applications.size()> ApplicationList::applications;
|
||||
|
||||
auto ApplicationList::CreateScreenList() const {
|
||||
std::array<std::function<std::unique_ptr<Screen>()>, nScreens> screens;
|
||||
for (size_t i = 0; i < screens.size(); i++) {
|
||||
screens[i] = [this, i]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen(i);
|
||||
};
|
||||
}
|
||||
return screens;
|
||||
}
|
||||
|
||||
ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp* app,
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Pinetime::Controllers::Battery& batteryController,
|
||||
Pinetime::Controllers::Ble& bleController,
|
||||
Controllers::DateTime& dateTimeController)
|
||||
: Screen(app),
|
||||
settingsController {settingsController},
|
||||
batteryController {batteryController},
|
||||
bleController {bleController},
|
||||
dateTimeController {dateTimeController},
|
||||
screens {app,
|
||||
settingsController.GetAppMenu(),
|
||||
{
|
||||
[this]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen1();
|
||||
},
|
||||
[this]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen2();
|
||||
},
|
||||
//[this]() -> std::unique_ptr<Screen> { return CreateScreen3(); }
|
||||
},
|
||||
Screens::ScreenListModes::UpDown} {
|
||||
screens {app, settingsController.GetAppMenu(), CreateScreenList(), Screens::ScreenListModes::UpDown} {
|
||||
}
|
||||
|
||||
ApplicationList::~ApplicationList() {
|
||||
@@ -38,42 +39,18 @@ bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
return screens.OnTouchEvent(event);
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> ApplicationList::CreateScreen1() {
|
||||
std::array<Screens::Tile::Applications, 6> applications {{
|
||||
{Symbols::stopWatch, Apps::StopWatch},
|
||||
{Symbols::clock, Apps::Alarm},
|
||||
{Symbols::hourGlass, Apps::Timer},
|
||||
{Symbols::shoe, Apps::Steps},
|
||||
{Symbols::heartBeat, Apps::HeartRate},
|
||||
{Symbols::music, Apps::Music},
|
||||
}};
|
||||
std::unique_ptr<Screen> ApplicationList::CreateScreen(unsigned int screenNum) const {
|
||||
std::array<Tile::Applications, appsPerScreen> apps;
|
||||
for (int i = 0; i < appsPerScreen; i++) {
|
||||
apps[i] = applications[screenNum * appsPerScreen + i];
|
||||
}
|
||||
|
||||
return std::make_unique<Screens::Tile>(0, 2, app, settingsController, batteryController, dateTimeController, applications);
|
||||
return std::make_unique<Screens::Tile>(screenNum,
|
||||
nScreens,
|
||||
app,
|
||||
settingsController,
|
||||
batteryController,
|
||||
bleController,
|
||||
dateTimeController,
|
||||
apps);
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
|
||||
std::array<Screens::Tile::Applications, 6> applications {{
|
||||
{Symbols::paintbrush, Apps::Paint},
|
||||
{Symbols::paddle, Apps::Paddle},
|
||||
{"2", Apps::Twos},
|
||||
{Symbols::chartLine, Apps::Motion},
|
||||
{Symbols::drum, Apps::Metronome},
|
||||
{Symbols::map, Apps::Navigation},
|
||||
}};
|
||||
|
||||
return std::make_unique<Screens::Tile>(1, 2, app, settingsController, batteryController, dateTimeController, applications);
|
||||
}
|
||||
|
||||
/*std::unique_ptr<Screen> ApplicationList::CreateScreen3() {
|
||||
std::array<Screens::Tile::Applications, 6> applications {
|
||||
{{"A", Apps::Meter},
|
||||
{"B", Apps::Navigation},
|
||||
{"C", Apps::Clock},
|
||||
{"D", Apps::Music},
|
||||
{"E", Apps::SysInfo},
|
||||
{"F", Apps::Brightness}
|
||||
}
|
||||
};
|
||||
|
||||
return std::make_unique<Screens::Tile>(2, 3, app, settingsController, batteryController, dateTimeController, applications);
|
||||
}*/
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
@@ -7,6 +8,8 @@
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "components/settings/Settings.h"
|
||||
#include "components/battery/BatteryController.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/screens/Tile.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
@@ -16,19 +19,41 @@ namespace Pinetime {
|
||||
explicit ApplicationList(DisplayApp* app,
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Pinetime::Controllers::Battery& batteryController,
|
||||
Pinetime::Controllers::Ble& bleController,
|
||||
Controllers::DateTime& dateTimeController);
|
||||
~ApplicationList() override;
|
||||
bool OnTouchEvent(TouchEvents event) override;
|
||||
|
||||
private:
|
||||
auto CreateScreenList() const;
|
||||
std::unique_ptr<Screen> CreateScreen(unsigned int screenNum) const;
|
||||
|
||||
Controllers::Settings& settingsController;
|
||||
Pinetime::Controllers::Battery& batteryController;
|
||||
Pinetime::Controllers::Ble& bleController;
|
||||
Controllers::DateTime& dateTimeController;
|
||||
|
||||
ScreenList<2> screens;
|
||||
std::unique_ptr<Screen> CreateScreen1();
|
||||
std::unique_ptr<Screen> CreateScreen2();
|
||||
// std::unique_ptr<Screen> CreateScreen3();
|
||||
static constexpr int appsPerScreen = 6;
|
||||
|
||||
// Increment this when more space is needed
|
||||
static constexpr int nScreens = 2;
|
||||
|
||||
static constexpr std::array<Tile::Applications, appsPerScreen * nScreens> applications {{
|
||||
{Symbols::stopWatch, Apps::StopWatch},
|
||||
{Symbols::clock, Apps::Alarm},
|
||||
{Symbols::hourGlass, Apps::Timer},
|
||||
{Symbols::shoe, Apps::Steps},
|
||||
{Symbols::heartBeat, Apps::HeartRate},
|
||||
{Symbols::music, Apps::Music},
|
||||
|
||||
{Symbols::paintbrush, Apps::Paint},
|
||||
{Symbols::paddle, Apps::Paddle},
|
||||
{"2", Apps::Twos},
|
||||
{Symbols::chartLine, Apps::Motion},
|
||||
{Symbols::drum, Apps::Metronome},
|
||||
{Symbols::map, Apps::Navigation},
|
||||
}};
|
||||
ScreenList<nScreens> screens;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "displayapp/screens/BatteryInfo.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "components/battery/BatteryController.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -16,9 +17,9 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont
|
||||
lv_obj_align(charging_bar, nullptr, LV_ALIGN_CENTER, 0, 10);
|
||||
lv_bar_set_anim_time(charging_bar, 1000);
|
||||
lv_obj_set_style_local_radius(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, lv_color_hex(0x222222));
|
||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
lv_obj_set_style_local_bg_opa(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_OPA_100);
|
||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, lv_color_hex(0xFF0000));
|
||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_ON);
|
||||
|
||||
status = lv_label_create(lv_scr_act(), nullptr);
|
||||
@@ -33,7 +34,7 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont
|
||||
lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60);
|
||||
|
||||
voltage = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange);
|
||||
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10);
|
||||
lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95);
|
||||
@@ -62,7 +63,7 @@ void BatteryInfo::Refresh() {
|
||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||
lv_label_set_text_static(status, "Battery low");
|
||||
} else {
|
||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::highlight);
|
||||
lv_label_set_text_static(status, "Discharging");
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include "Version.h"
|
||||
#include "components/firmwarevalidator/FirmwareValidator.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -42,7 +43,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app,
|
||||
lv_obj_set_size(buttonValidate, 115, 50);
|
||||
lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
|
||||
lv_obj_set_event_cb(buttonValidate, ButtonEventHandler);
|
||||
lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(buttonValidate, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
|
||||
labelButtonValidate = lv_label_create(buttonValidate, nullptr);
|
||||
lv_label_set_text_static(labelButtonValidate, "Validate");
|
||||
@@ -51,7 +52,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app,
|
||||
buttonReset->user_data = this;
|
||||
lv_obj_set_size(buttonReset, 115, 50);
|
||||
lv_obj_align(buttonReset, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||
lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0x0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(buttonReset, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
lv_obj_set_event_cb(buttonReset, ButtonEventHandler);
|
||||
|
||||
labelButtonReset = lv_label_create(buttonReset, nullptr);
|
||||
|
@@ -1,37 +1,35 @@
|
||||
#include "displayapp/screens/FlashLight.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
namespace {
|
||||
void event_handler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* screen = static_cast<FlashLight*>(obj->user_data);
|
||||
screen->OnClickEvent(obj, event);
|
||||
void EventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
if (event == LV_EVENT_CLICKED) {
|
||||
auto* screen = static_cast<FlashLight*>(obj->user_data);
|
||||
screen->Toggle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FlashLight::FlashLight(Pinetime::Applications::DisplayApp* app,
|
||||
System::SystemTask& systemTask,
|
||||
Controllers::BrightnessController& brightnessController)
|
||||
: Screen(app),
|
||||
systemTask {systemTask},
|
||||
brightnessController {brightnessController}
|
||||
: Screen(app), systemTask {systemTask}, brightnessController {brightnessController} {
|
||||
|
||||
{
|
||||
brightnessController.Backup();
|
||||
|
||||
brightnessLevel = brightnessController.Level();
|
||||
brightnessController.Set(Controllers::BrightnessController::Levels::Low);
|
||||
|
||||
flashLight = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48);
|
||||
lv_label_set_text_static(flashLight, Symbols::highlight);
|
||||
lv_label_set_text_static(flashLight, Symbols::flashlight);
|
||||
lv_obj_align(flashLight, nullptr, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
for (auto& i : indicators) {
|
||||
i = lv_obj_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_size(i, 15, 10);
|
||||
lv_obj_set_style_local_border_width(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 2);
|
||||
for (auto& indicator : indicators) {
|
||||
indicator = lv_obj_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_size(indicator, 15, 10);
|
||||
lv_obj_set_style_local_border_width(indicator, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 2);
|
||||
}
|
||||
|
||||
lv_obj_align(indicators[1], flashLight, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
|
||||
@@ -48,7 +46,7 @@ FlashLight::FlashLight(Pinetime::Applications::DisplayApp* app,
|
||||
lv_label_set_text_static(backgroundAction, "");
|
||||
lv_obj_set_click(backgroundAction, true);
|
||||
backgroundAction->user_data = this;
|
||||
lv_obj_set_event_cb(backgroundAction, event_handler);
|
||||
lv_obj_set_event_cb(backgroundAction, EventHandler);
|
||||
|
||||
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
|
||||
}
|
||||
@@ -56,27 +54,19 @@ FlashLight::FlashLight(Pinetime::Applications::DisplayApp* app,
|
||||
FlashLight::~FlashLight() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
brightnessController.Restore();
|
||||
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
|
||||
}
|
||||
|
||||
void FlashLight::SetColors() {
|
||||
if (isOn) {
|
||||
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
for (auto& i : indicators) {
|
||||
lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_WHITE);
|
||||
lv_obj_set_style_local_border_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
}
|
||||
} else {
|
||||
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
for (auto& i : indicators) {
|
||||
lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_BLACK);
|
||||
lv_obj_set_style_local_border_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
}
|
||||
lv_color_t bgColor = isOn ? LV_COLOR_WHITE : LV_COLOR_BLACK;
|
||||
lv_color_t fgColor = isOn ? Colors::lightGray : LV_COLOR_WHITE;
|
||||
|
||||
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, bgColor);
|
||||
lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, fgColor);
|
||||
for (auto& indicator : indicators) {
|
||||
lv_obj_set_style_local_bg_color(indicator, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, fgColor);
|
||||
lv_obj_set_style_local_bg_color(indicator, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, bgColor);
|
||||
lv_obj_set_style_local_border_color(indicator, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, fgColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,37 +85,43 @@ void FlashLight::SetIndicators() {
|
||||
}
|
||||
}
|
||||
|
||||
void FlashLight::OnClickEvent(lv_obj_t* obj, lv_event_t event) {
|
||||
if (obj == backgroundAction && event == LV_EVENT_CLICKED) {
|
||||
isOn = !isOn;
|
||||
SetColors();
|
||||
void FlashLight::Toggle() {
|
||||
isOn = !isOn;
|
||||
SetColors();
|
||||
if (isOn) {
|
||||
brightnessController.Set(brightnessLevel);
|
||||
} else {
|
||||
brightnessController.Set(Controllers::BrightnessController::Levels::Low);
|
||||
}
|
||||
}
|
||||
|
||||
bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
using namespace Pinetime::Controllers;
|
||||
|
||||
auto SetState = [this]() {
|
||||
if (isOn) {
|
||||
brightnessController.Set(brightnessLevel);
|
||||
}
|
||||
SetIndicators();
|
||||
};
|
||||
|
||||
if (event == TouchEvents::SwipeLeft) {
|
||||
if (brightnessLevel == BrightnessController::Levels::High) {
|
||||
brightnessLevel = BrightnessController::Levels::Medium;
|
||||
brightnessController.Set(brightnessLevel);
|
||||
SetIndicators();
|
||||
SetState();
|
||||
} else if (brightnessLevel == BrightnessController::Levels::Medium) {
|
||||
brightnessLevel = BrightnessController::Levels::Low;
|
||||
brightnessController.Set(brightnessLevel);
|
||||
SetIndicators();
|
||||
SetState();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (event == TouchEvents::SwipeRight) {
|
||||
if (brightnessLevel == BrightnessController::Levels::Low) {
|
||||
brightnessLevel = BrightnessController::Levels::Medium;
|
||||
brightnessController.Set(brightnessLevel);
|
||||
SetIndicators();
|
||||
SetState();
|
||||
} else if (brightnessLevel == BrightnessController::Levels::Medium) {
|
||||
brightnessLevel = BrightnessController::Levels::High;
|
||||
brightnessController.Set(brightnessLevel);
|
||||
SetIndicators();
|
||||
SetState();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ namespace Pinetime {
|
||||
~FlashLight() override;
|
||||
|
||||
bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override;
|
||||
void OnClickEvent(lv_obj_t* obj, lv_event_t event);
|
||||
void Toggle();
|
||||
|
||||
private:
|
||||
void SetIndicators();
|
||||
@@ -26,7 +26,7 @@ namespace Pinetime {
|
||||
Pinetime::System::SystemTask& systemTask;
|
||||
Controllers::BrightnessController& brightnessController;
|
||||
|
||||
Controllers::BrightnessController::Levels brightnessLevel;
|
||||
Controllers::BrightnessController::Levels brightnessLevel = Controllers::BrightnessController::Levels::High;
|
||||
|
||||
lv_obj_t* flashLight;
|
||||
lv_obj_t* backgroundAction;
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include <components/heartrate/HeartRateController.h>
|
||||
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -36,10 +37,11 @@ HeartRate::HeartRate(Pinetime::Applications::DisplayApp* app,
|
||||
|
||||
lv_obj_set_style_local_text_font(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
||||
|
||||
if (isHrRunning)
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
else
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
if (isHrRunning) {
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
} else {
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
}
|
||||
|
||||
lv_label_set_text_static(label_hr, "000");
|
||||
lv_obj_align(label_hr, nullptr, LV_ALIGN_CENTER, 0, -40);
|
||||
@@ -97,12 +99,12 @@ void HeartRate::OnStartStopEvent(lv_event_t event) {
|
||||
heartRateController.Start();
|
||||
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
|
||||
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
} else {
|
||||
heartRateController.Stop();
|
||||
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
|
||||
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "displayapp/screens/InfiniPaint.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/LittleVgl.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
#include <algorithm> // std::fill
|
||||
|
||||
@@ -26,7 +27,7 @@ bool InfiniPaint::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
selectColor = LV_COLOR_MAGENTA;
|
||||
break;
|
||||
case 1:
|
||||
selectColor = LV_COLOR_MAKE(0x0, 0xb0, 0x0);
|
||||
selectColor = Colors::green;
|
||||
break;
|
||||
case 2:
|
||||
selectColor = LV_COLOR_WHITE;
|
||||
|
@@ -3,34 +3,9 @@
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::DisplayApp* app, lv_obj_t* labelText)
|
||||
: Screen(app), labelText {labelText} {
|
||||
: Screen(app), labelText {labelText}, pageIndicator(screenID, numScreens) {
|
||||
|
||||
if (numScreens > 1) {
|
||||
pageIndicatorBasePoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[0].y = 0;
|
||||
pageIndicatorBasePoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[1].y = LV_VER_RES;
|
||||
|
||||
pageIndicatorBase = lv_line_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111));
|
||||
lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true);
|
||||
lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2);
|
||||
|
||||
uint16_t indicatorSize = LV_VER_RES / numScreens;
|
||||
uint16_t indicatorPos = indicatorSize * screenID;
|
||||
|
||||
pageIndicatorPoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[0].y = indicatorPos;
|
||||
pageIndicatorPoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[1].y = indicatorPos + indicatorSize;
|
||||
|
||||
pageIndicator = lv_line_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true);
|
||||
lv_line_set_points(pageIndicator, pageIndicatorPoints, 2);
|
||||
}
|
||||
pageIndicator.Create();
|
||||
}
|
||||
|
||||
Label::~Label() {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/widgets/PageIndicator.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
namespace Pinetime {
|
||||
@@ -14,10 +15,7 @@ namespace Pinetime {
|
||||
|
||||
private:
|
||||
lv_obj_t* labelText = nullptr;
|
||||
lv_point_t pageIndicatorBasePoints[2];
|
||||
lv_point_t pageIndicatorPoints[2];
|
||||
lv_obj_t* pageIndicatorBase;
|
||||
lv_obj_t* pageIndicator;
|
||||
Widgets::PageIndicator pageIndicator;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -16,37 +16,14 @@ List::List(uint8_t screenID,
|
||||
DisplayApp* app,
|
||||
Controllers::Settings& settingsController,
|
||||
std::array<Applications, MAXLISTITEMS>& applications)
|
||||
: Screen(app), settingsController {settingsController} {
|
||||
: Screen(app), settingsController {settingsController}, pageIndicator(screenID, numScreens) {
|
||||
|
||||
// Set the background to Black
|
||||
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(0, 0, 0));
|
||||
|
||||
settingsController.SetSettingsMenu(screenID);
|
||||
|
||||
if (numScreens > 1) {
|
||||
pageIndicatorBasePoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[0].y = 0;
|
||||
pageIndicatorBasePoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[1].y = LV_VER_RES;
|
||||
|
||||
pageIndicatorBase = lv_line_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111));
|
||||
lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2);
|
||||
|
||||
const uint16_t indicatorSize = LV_VER_RES / numScreens;
|
||||
const uint16_t indicatorPos = indicatorSize * screenID;
|
||||
|
||||
pageIndicatorPoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[0].y = indicatorPos;
|
||||
pageIndicatorPoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[1].y = indicatorPos + indicatorSize;
|
||||
|
||||
pageIndicator = lv_line_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_line_set_points(pageIndicator, pageIndicatorPoints, 2);
|
||||
}
|
||||
pageIndicator.Create();
|
||||
|
||||
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/widgets/PageIndicator.h"
|
||||
#include "displayapp/Apps.h"
|
||||
#include "components/settings/Settings.h"
|
||||
|
||||
@@ -35,10 +36,7 @@ namespace Pinetime {
|
||||
|
||||
lv_obj_t* itemApps[MAXLISTITEMS];
|
||||
|
||||
lv_point_t pageIndicatorBasePoints[2];
|
||||
lv_point_t pageIndicatorPoints[2];
|
||||
lv_obj_t* pageIndicatorBase;
|
||||
lv_obj_t* pageIndicator;
|
||||
Widgets::PageIndicator pageIndicator;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include "displayapp/screens/Metronome.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -12,7 +13,7 @@ namespace {
|
||||
lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x, uint8_t y) {
|
||||
lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font);
|
||||
lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_label_set_text(label, name);
|
||||
lv_obj_align(label, reference, align, x, y);
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#include "displayapp/screens/Motion.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -19,7 +20,7 @@ Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionContr
|
||||
|
||||
/*Add 3 data series*/
|
||||
ser1 = lv_chart_add_series(chart, LV_COLOR_RED);
|
||||
ser2 = lv_chart_add_series(chart, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
ser2 = lv_chart_add_series(chart, Colors::green);
|
||||
ser3 = lv_chart_add_series(chart, LV_COLOR_YELLOW);
|
||||
|
||||
lv_chart_init_points(chart, ser1, 0);
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <cstdint>
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "components/ble/NavigationService.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -192,7 +193,7 @@ void Navigation::Refresh() {
|
||||
if (progress > 90) {
|
||||
lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
} else {
|
||||
lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(barProgress, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::orange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@
|
||||
#include "components/ble/MusicService.h"
|
||||
#include "components/ble/AlertNotificationService.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include <algorithm>
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
extern lv_font_t jetbrains_mono_extrabold_compressed;
|
||||
@@ -20,30 +22,23 @@ Notifications::Notifications(DisplayApp* app,
|
||||
motorController {motorController},
|
||||
systemTask {systemTask},
|
||||
mode {mode} {
|
||||
|
||||
notificationManager.ClearNewNotificationFlag();
|
||||
auto notification = notificationManager.GetLastNotification();
|
||||
if (notification.valid) {
|
||||
currentId = notification.id;
|
||||
currentItem = std::make_unique<NotificationItem>(notification.Title(),
|
||||
notification.Message(),
|
||||
notification.index,
|
||||
1,
|
||||
notification.category,
|
||||
notificationManager.NbNotifications(),
|
||||
mode,
|
||||
alertNotificationService,
|
||||
motorController);
|
||||
validDisplay = true;
|
||||
} else {
|
||||
currentItem = std::make_unique<NotificationItem>("Notification",
|
||||
"No notification to display",
|
||||
0,
|
||||
notification.category,
|
||||
notificationManager.NbNotifications(),
|
||||
Modes::Preview,
|
||||
alertNotificationService,
|
||||
motorController);
|
||||
currentItem = std::make_unique<NotificationItem>(alertNotificationService, motorController);
|
||||
validDisplay = false;
|
||||
}
|
||||
|
||||
if (mode == Modes::Preview) {
|
||||
systemTask.PushMessage(System::Messages::DisableSleeping);
|
||||
if (notification.category == Controllers::NotificationManager::Categories::IncomingCall) {
|
||||
@@ -77,7 +72,7 @@ Notifications::~Notifications() {
|
||||
void Notifications::Refresh() {
|
||||
if (mode == Modes::Preview && timeoutLine != nullptr) {
|
||||
TickType_t tick = xTaskGetTickCount();
|
||||
int32_t pos = 240 - ((tick - timeoutTickCountStart) / (timeoutLength / 240));
|
||||
int32_t pos = LV_HOR_RES - ((tick - timeoutTickCountStart) / (timeoutLength / LV_HOR_RES));
|
||||
if (pos <= 0) {
|
||||
running = false;
|
||||
} else {
|
||||
@@ -85,6 +80,40 @@ void Notifications::Refresh() {
|
||||
lv_line_set_points(timeoutLine, timeoutLinePoints, 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (dismissingNotification) {
|
||||
dismissingNotification = false;
|
||||
auto notification = notificationManager.Get(currentId);
|
||||
if (!notification.valid) {
|
||||
notification = notificationManager.GetLastNotification();
|
||||
}
|
||||
currentId = notification.id;
|
||||
|
||||
if (!notification.valid) {
|
||||
validDisplay = false;
|
||||
}
|
||||
|
||||
currentItem.reset(nullptr);
|
||||
if (afterDismissNextMessageFromAbove) {
|
||||
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
|
||||
} else {
|
||||
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
|
||||
}
|
||||
|
||||
if (validDisplay) {
|
||||
Controllers::NotificationManager::Notification::Idx currentIdx = notificationManager.IndexOf(currentId);
|
||||
currentItem = std::make_unique<NotificationItem>(notification.Title(),
|
||||
notification.Message(),
|
||||
currentIdx + 1,
|
||||
notification.category,
|
||||
notificationManager.NbNotifications(),
|
||||
alertNotificationService,
|
||||
motorController);
|
||||
} else {
|
||||
currentItem = std::make_unique<NotificationItem>(alertNotificationService, motorController);
|
||||
}
|
||||
}
|
||||
|
||||
running = currentItem->IsRunning() && running;
|
||||
}
|
||||
|
||||
@@ -108,52 +137,84 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case Pinetime::Applications::TouchEvents::SwipeRight:
|
||||
if (validDisplay) {
|
||||
Controllers::NotificationManager::Notification previousNotification;
|
||||
auto previousMessage = notificationManager.GetPrevious(currentId);
|
||||
auto nextMessage = notificationManager.GetNext(currentId);
|
||||
if (!previousMessage.valid) {
|
||||
// dismissed last message (like 5/5), need to go one message down (like 4/4)
|
||||
afterDismissNextMessageFromAbove = false; // show next message coming from below
|
||||
} else {
|
||||
afterDismissNextMessageFromAbove = true; // show next message coming from above
|
||||
}
|
||||
notificationManager.Dismiss(currentId);
|
||||
if (previousMessage.valid) {
|
||||
currentId = previousMessage.id;
|
||||
} else if (nextMessage.valid) {
|
||||
currentId = nextMessage.id;
|
||||
} else {
|
||||
// don't update id, won't be found be refresh and try to load latest message or no message box
|
||||
}
|
||||
currentItem.reset(nullptr);
|
||||
app->SetFullRefresh(DisplayApp::FullRefreshDirections::RightAnim);
|
||||
// create black transition screen to let the notification dismiss to blackness
|
||||
lv_obj_t* blackBox = lv_obj_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_size(blackBox, LV_HOR_RES, LV_VER_RES);
|
||||
lv_obj_set_style_local_bg_color(blackBox, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
dismissingNotification = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case Pinetime::Applications::TouchEvents::SwipeDown: {
|
||||
Controllers::NotificationManager::Notification previousNotification;
|
||||
if (validDisplay)
|
||||
if (validDisplay) {
|
||||
previousNotification = notificationManager.GetPrevious(currentId);
|
||||
else
|
||||
} else {
|
||||
previousNotification = notificationManager.GetLastNotification();
|
||||
}
|
||||
|
||||
if (!previousNotification.valid)
|
||||
if (!previousNotification.valid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
validDisplay = true;
|
||||
currentId = previousNotification.id;
|
||||
Controllers::NotificationManager::Notification::Idx currentIdx = notificationManager.IndexOf(currentId);
|
||||
validDisplay = true;
|
||||
currentItem.reset(nullptr);
|
||||
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down);
|
||||
currentItem = std::make_unique<NotificationItem>(previousNotification.Title(),
|
||||
previousNotification.Message(),
|
||||
previousNotification.index,
|
||||
currentIdx + 1,
|
||||
previousNotification.category,
|
||||
notificationManager.NbNotifications(),
|
||||
mode,
|
||||
alertNotificationService,
|
||||
motorController);
|
||||
}
|
||||
return true;
|
||||
case Pinetime::Applications::TouchEvents::SwipeUp: {
|
||||
Controllers::NotificationManager::Notification nextNotification;
|
||||
if (validDisplay)
|
||||
if (validDisplay) {
|
||||
nextNotification = notificationManager.GetNext(currentId);
|
||||
else
|
||||
} else {
|
||||
nextNotification = notificationManager.GetLastNotification();
|
||||
}
|
||||
|
||||
if (!nextNotification.valid) {
|
||||
running = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
validDisplay = true;
|
||||
currentId = nextNotification.id;
|
||||
Controllers::NotificationManager::Notification::Idx currentIdx = notificationManager.IndexOf(currentId);
|
||||
validDisplay = true;
|
||||
currentItem.reset(nullptr);
|
||||
app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up);
|
||||
currentItem = std::make_unique<NotificationItem>(nextNotification.Title(),
|
||||
nextNotification.Message(),
|
||||
nextNotification.index,
|
||||
currentIdx + 1,
|
||||
nextNotification.category,
|
||||
notificationManager.NbNotifications(),
|
||||
mode,
|
||||
alertNotificationService,
|
||||
motorController);
|
||||
}
|
||||
@@ -170,34 +231,49 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
Notifications::NotificationItem::NotificationItem(Pinetime::Controllers::AlertNotificationService& alertNotificationService,
|
||||
Pinetime::Controllers::MotorController& motorController)
|
||||
: NotificationItem("Notification",
|
||||
"No notification to display",
|
||||
0,
|
||||
Controllers::NotificationManager::Categories::Unknown,
|
||||
0,
|
||||
alertNotificationService,
|
||||
motorController) {
|
||||
}
|
||||
|
||||
Notifications::NotificationItem::NotificationItem(const char* title,
|
||||
const char* msg,
|
||||
uint8_t notifNr,
|
||||
Controllers::NotificationManager::Categories category,
|
||||
uint8_t notifNb,
|
||||
Modes mode,
|
||||
Pinetime::Controllers::AlertNotificationService& alertNotificationService,
|
||||
Pinetime::Controllers::MotorController& motorController)
|
||||
: mode {mode}, alertNotificationService {alertNotificationService}, motorController {motorController} {
|
||||
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL);
|
||||
: alertNotificationService {alertNotificationService}, motorController {motorController} {
|
||||
container = lv_cont_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_size(container, LV_HOR_RES, LV_VER_RES);
|
||||
lv_obj_set_style_local_bg_color(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
lv_obj_set_style_local_pad_all(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_border_width(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
|
||||
lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38));
|
||||
lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
|
||||
lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
|
||||
lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
subject_container = lv_cont_create(container, nullptr);
|
||||
lv_obj_set_style_local_bg_color(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
lv_obj_set_style_local_pad_all(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
|
||||
lv_obj_set_style_local_pad_inner(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
|
||||
lv_obj_set_style_local_border_width(subject_container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
|
||||
lv_obj_set_pos(container1, 0, 50);
|
||||
lv_obj_set_size(container1, LV_HOR_RES, 190);
|
||||
lv_obj_set_pos(subject_container, 0, 50);
|
||||
lv_obj_set_size(subject_container, LV_HOR_RES, LV_VER_RES - 50);
|
||||
lv_cont_set_layout(subject_container, LV_LAYOUT_COLUMN_LEFT);
|
||||
lv_cont_set_fit(subject_container, LV_FIT_NONE);
|
||||
|
||||
lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
|
||||
lv_cont_set_fit(container1, LV_FIT_NONE);
|
||||
|
||||
lv_obj_t* alert_count = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_t* alert_count = lv_label_create(container, nullptr);
|
||||
lv_label_set_text_fmt(alert_count, "%i/%i", notifNr, notifNb);
|
||||
lv_obj_align(alert_count, NULL, LV_ALIGN_IN_TOP_RIGHT, 0, 16);
|
||||
|
||||
lv_obj_t* alert_type = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_t* alert_type = lv_label_create(container, nullptr);
|
||||
lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange);
|
||||
if (title == nullptr) {
|
||||
lv_label_set_text_static(alert_type, "Notification");
|
||||
} else {
|
||||
@@ -214,39 +290,34 @@ Notifications::NotificationItem::NotificationItem(const char* title,
|
||||
lv_obj_set_width(alert_type, 180);
|
||||
lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 16);
|
||||
|
||||
/////////
|
||||
lv_obj_t* alert_subject = lv_label_create(subject_container, nullptr);
|
||||
lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK);
|
||||
lv_obj_set_width(alert_subject, LV_HOR_RES - 20);
|
||||
|
||||
switch (category) {
|
||||
default: {
|
||||
lv_obj_t* alert_subject = lv_label_create(container1, nullptr);
|
||||
lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0));
|
||||
lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK);
|
||||
lv_obj_set_width(alert_subject, LV_HOR_RES - 20);
|
||||
default:
|
||||
lv_label_set_text(alert_subject, msg);
|
||||
} break;
|
||||
break;
|
||||
case Controllers::NotificationManager::Categories::IncomingCall: {
|
||||
lv_obj_set_height(container1, 108);
|
||||
lv_obj_t* alert_subject = lv_label_create(container1, nullptr);
|
||||
lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0));
|
||||
lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK);
|
||||
lv_obj_set_width(alert_subject, LV_HOR_RES - 20);
|
||||
lv_obj_set_height(subject_container, 108);
|
||||
lv_label_set_text_static(alert_subject, "Incoming call from");
|
||||
|
||||
lv_obj_t* alert_caller = lv_label_create(container1, nullptr);
|
||||
lv_obj_t* alert_caller = lv_label_create(subject_container, nullptr);
|
||||
lv_obj_align(alert_caller, alert_subject, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
|
||||
lv_label_set_long_mode(alert_caller, LV_LABEL_LONG_BREAK);
|
||||
lv_obj_set_width(alert_caller, LV_HOR_RES - 20);
|
||||
lv_label_set_text(alert_caller, msg);
|
||||
|
||||
bt_accept = lv_btn_create(lv_scr_act(), nullptr);
|
||||
bt_accept = lv_btn_create(container, nullptr);
|
||||
bt_accept->user_data = this;
|
||||
lv_obj_set_event_cb(bt_accept, CallEventHandler);
|
||||
lv_obj_set_size(bt_accept, 76, 76);
|
||||
lv_obj_align(bt_accept, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
|
||||
label_accept = lv_label_create(bt_accept, nullptr);
|
||||
lv_label_set_text_static(label_accept, Symbols::phone);
|
||||
lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
|
||||
bt_reject = lv_btn_create(lv_scr_act(), nullptr);
|
||||
bt_reject = lv_btn_create(container, nullptr);
|
||||
bt_reject->user_data = this;
|
||||
lv_obj_set_event_cb(bt_reject, CallEventHandler);
|
||||
lv_obj_set_size(bt_reject, 76, 76);
|
||||
@@ -255,14 +326,14 @@ Notifications::NotificationItem::NotificationItem(const char* title,
|
||||
lv_label_set_text_static(label_reject, Symbols::phoneSlash);
|
||||
lv_obj_set_style_local_bg_color(bt_reject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
|
||||
bt_mute = lv_btn_create(lv_scr_act(), nullptr);
|
||||
bt_mute = lv_btn_create(container, nullptr);
|
||||
bt_mute->user_data = this;
|
||||
lv_obj_set_event_cb(bt_mute, CallEventHandler);
|
||||
lv_obj_set_size(bt_mute, 76, 76);
|
||||
lv_obj_align(bt_mute, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||
label_mute = lv_label_create(bt_mute, nullptr);
|
||||
lv_label_set_text_static(label_mute, Symbols::volumMute);
|
||||
lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
@@ -33,12 +33,13 @@ namespace Pinetime {
|
||||
|
||||
class NotificationItem {
|
||||
public:
|
||||
NotificationItem(Pinetime::Controllers::AlertNotificationService& alertNotificationService,
|
||||
Pinetime::Controllers::MotorController& motorController);
|
||||
NotificationItem(const char* title,
|
||||
const char* msg,
|
||||
uint8_t notifNr,
|
||||
Controllers::NotificationManager::Categories,
|
||||
uint8_t notifNb,
|
||||
Modes mode,
|
||||
Pinetime::Controllers::AlertNotificationService& alertNotificationService,
|
||||
Pinetime::Controllers::MotorController& motorController);
|
||||
~NotificationItem();
|
||||
@@ -48,16 +49,17 @@ namespace Pinetime {
|
||||
void OnCallButtonEvent(lv_obj_t*, lv_event_t event);
|
||||
|
||||
private:
|
||||
lv_obj_t* container1;
|
||||
lv_obj_t* container;
|
||||
lv_obj_t* subject_container;
|
||||
lv_obj_t* bt_accept;
|
||||
lv_obj_t* bt_mute;
|
||||
lv_obj_t* bt_reject;
|
||||
lv_obj_t* label_accept;
|
||||
lv_obj_t* label_mute;
|
||||
lv_obj_t* label_reject;
|
||||
Modes mode;
|
||||
Pinetime::Controllers::AlertNotificationService& alertNotificationService;
|
||||
Pinetime::Controllers::MotorController& motorController;
|
||||
|
||||
bool running = true;
|
||||
};
|
||||
|
||||
@@ -68,15 +70,19 @@ namespace Pinetime {
|
||||
System::SystemTask& systemTask;
|
||||
Modes mode = Modes::Normal;
|
||||
std::unique_ptr<NotificationItem> currentItem;
|
||||
Controllers::NotificationManager::Notification::Id currentId;
|
||||
Pinetime::Controllers::NotificationManager::Notification::Id currentId;
|
||||
bool validDisplay = false;
|
||||
bool afterDismissNextMessageFromAbove = false;
|
||||
|
||||
lv_point_t timeoutLinePoints[2] {{0, 1}, {239, 1}};
|
||||
lv_obj_t* timeoutLine = nullptr;
|
||||
TickType_t timeoutTickCountStart;
|
||||
|
||||
static const TickType_t timeoutLength = pdMS_TO_TICKS(7000);
|
||||
bool interacted = true;
|
||||
|
||||
bool dismissingNotification = false;
|
||||
|
||||
lv_task_t* taskRefresh;
|
||||
};
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ using namespace Pinetime::Applications::Screens;
|
||||
|
||||
PassKey::PassKey(Pinetime::Applications::DisplayApp* app, uint32_t key) : Screen(app) {
|
||||
passkeyLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(passkeyLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFF00));
|
||||
lv_obj_set_style_local_text_color(passkeyLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||
lv_obj_set_style_local_text_font(passkeyLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_fmt(passkeyLabel, "%06u", key);
|
||||
lv_obj_align(passkeyLabel, nullptr, LV_ALIGN_CENTER, 0, -20);
|
||||
|
@@ -20,7 +20,7 @@ Steps::Steps(Pinetime::Applications::DisplayApp* app,
|
||||
lv_obj_set_style_local_bg_opa(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, LV_OPA_0);
|
||||
lv_obj_set_style_local_border_width(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 2);
|
||||
lv_obj_set_style_local_radius(stepsArc, LV_ARC_PART_BG, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_line_color(stepsArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, lv_color_hex(0x0000FF));
|
||||
lv_obj_set_style_local_line_color(stepsArc, LV_ARC_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE);
|
||||
lv_arc_set_end_angle(stepsArc, 200);
|
||||
lv_obj_set_size(stepsArc, 240, 240);
|
||||
lv_arc_set_range(stepsArc, 0, 500);
|
||||
@@ -32,7 +32,7 @@ Steps::Steps(Pinetime::Applications::DisplayApp* app,
|
||||
lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal()));
|
||||
|
||||
lSteps = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00));
|
||||
lv_obj_set_style_local_text_color(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_LIME);
|
||||
lv_obj_set_style_local_text_font(lSteps, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_fmt(lSteps, "%li", stepsCount);
|
||||
lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -40);
|
||||
|
@@ -1,10 +1,7 @@
|
||||
#include "displayapp/screens/StopWatch.h"
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -30,25 +27,17 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask)
|
||||
: Screen(app),
|
||||
systemTask {systemTask},
|
||||
currentState {States::Init},
|
||||
startTime {},
|
||||
oldTimeElapsed {},
|
||||
currentTimeSeparated {},
|
||||
lapBuffer {},
|
||||
lapNr {} {
|
||||
StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask) : Screen(app), systemTask {systemTask} {
|
||||
|
||||
time = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_label_set_text_static(time, "00:00");
|
||||
lv_obj_align(time, lv_scr_act(), LV_ALIGN_CENTER, 0, -45);
|
||||
|
||||
msecTime = lv_label_create(lv_scr_act(), nullptr);
|
||||
// lv_obj_set_style_local_text_font(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
|
||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_label_set_text_static(msecTime, "00");
|
||||
lv_obj_align(msecTime, lv_scr_act(), LV_ALIGN_CENTER, 0, 3);
|
||||
|
||||
@@ -65,24 +54,15 @@ StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask)
|
||||
lv_obj_set_event_cb(btnStopLap, stop_lap_event_handler);
|
||||
lv_obj_set_size(btnStopLap, 115, 50);
|
||||
lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
|
||||
lv_obj_set_style_local_bg_color(btnStopLap, LV_BTN_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_MAKE(0x18, 0x18, 0x18));
|
||||
txtStopLap = lv_label_create(btnStopLap, nullptr);
|
||||
lv_obj_set_style_local_text_color(txtStopLap, LV_BTN_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_label_set_text_static(txtStopLap, Symbols::stop);
|
||||
lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
|
||||
lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
|
||||
|
||||
lapOneText = lv_label_create(lv_scr_act(), nullptr);
|
||||
// lv_obj_set_style_local_text_font(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
|
||||
lv_obj_set_style_local_text_color(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||
lv_obj_align(lapOneText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 30);
|
||||
lv_label_set_text_static(lapOneText, "");
|
||||
|
||||
lapTwoText = lv_label_create(lv_scr_act(), nullptr);
|
||||
// lv_obj_set_style_local_text_font(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
|
||||
lv_obj_set_style_local_text_color(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||
lv_obj_align(lapTwoText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 55);
|
||||
lv_label_set_text_static(lapTwoText, "");
|
||||
lapText = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(lapText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||
lv_obj_align(lapText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 30);
|
||||
lv_label_set_text_static(lapText, "");
|
||||
|
||||
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
|
||||
}
|
||||
@@ -96,16 +76,14 @@ StopWatch::~StopWatch() {
|
||||
void StopWatch::Reset() {
|
||||
currentState = States::Init;
|
||||
oldTimeElapsed = 0;
|
||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
|
||||
lv_label_set_text_static(time, "00:00");
|
||||
lv_label_set_text_static(msecTime, "00");
|
||||
|
||||
lv_label_set_text_static(lapOneText, "");
|
||||
lv_label_set_text_static(lapTwoText, "");
|
||||
lapBuffer.clearBuffer();
|
||||
lapNr = 0;
|
||||
lv_label_set_text_static(lapText, "");
|
||||
lapsDone = 0;
|
||||
lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
|
||||
lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
|
||||
}
|
||||
@@ -113,8 +91,8 @@ void StopWatch::Reset() {
|
||||
void StopWatch::Start() {
|
||||
lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
|
||||
lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
lv_label_set_text_static(txtPlayPause, Symbols::pause);
|
||||
lv_label_set_text_static(txtStopLap, Symbols::lapsFlag);
|
||||
startTime = xTaskGetTickCount();
|
||||
@@ -125,7 +103,7 @@ void StopWatch::Start() {
|
||||
void StopWatch::Pause() {
|
||||
startTime = 0;
|
||||
// Store the current time elapsed in cache
|
||||
oldTimeElapsed += timeElapsed;
|
||||
oldTimeElapsed = laps[lapsDone];
|
||||
currentState = States::Halted;
|
||||
lv_label_set_text_static(txtPlayPause, Symbols::play);
|
||||
lv_label_set_text_static(txtStopLap, Symbols::stop);
|
||||
@@ -136,9 +114,9 @@ void StopWatch::Pause() {
|
||||
|
||||
void StopWatch::Refresh() {
|
||||
if (currentState == States::Running) {
|
||||
timeElapsed = xTaskGetTickCount() - startTime;
|
||||
currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed));
|
||||
laps[lapsDone] = oldTimeElapsed + xTaskGetTickCount() - startTime;
|
||||
|
||||
TimeSeparated_t currentTimeSeparated = convertTicksToTimeSegments(laps[lapsDone]);
|
||||
lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
|
||||
lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
|
||||
}
|
||||
@@ -163,18 +141,17 @@ void StopWatch::stopLapBtnEventHandler(lv_event_t event) {
|
||||
}
|
||||
// If running, then this button is used to save laps
|
||||
if (currentState == States::Running) {
|
||||
lapBuffer.addLaps(currentTimeSeparated);
|
||||
lapNr++;
|
||||
if (lapBuffer[1]) {
|
||||
lv_label_set_text_fmt(lapOneText,
|
||||
"#%2d %2d:%02d.%02d",
|
||||
(lapNr - 1),
|
||||
lapBuffer[1]->mins,
|
||||
lapBuffer[1]->secs,
|
||||
lapBuffer[1]->hundredths);
|
||||
}
|
||||
if (lapBuffer[0]) {
|
||||
lv_label_set_text_fmt(lapTwoText, "#%2d %2d:%02d.%02d", lapNr, lapBuffer[0]->mins, lapBuffer[0]->secs, lapBuffer[0]->hundredths);
|
||||
lv_label_set_text(lapText, "");
|
||||
lapsDone = std::min(lapsDone + 1, maxLapCount);
|
||||
for (int i = lapsDone - displayedLaps; i < lapsDone; i++) {
|
||||
if (i < 0) {
|
||||
lv_label_ins_text(lapText, LV_LABEL_POS_LAST, "\n");
|
||||
continue;
|
||||
}
|
||||
TimeSeparated_t times = convertTicksToTimeSegments(laps[i]);
|
||||
char buffer[16];
|
||||
sprintf(buffer, "#%2d %2d:%02d.%02d\n", i + 1, times.mins, times.secs, times.hundredths);
|
||||
lv_label_ins_text(lapText, LV_LABEL_POS_LAST, buffer);
|
||||
}
|
||||
} else if (currentState == States::Halted) {
|
||||
Reset();
|
||||
|
@@ -1,13 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "displayapp/LittleVgl.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
#include "portmacro_cmsis.h"
|
||||
|
||||
#include <array>
|
||||
#include "systemtask/SystemTask.h"
|
||||
|
||||
namespace Pinetime::Applications::Screens {
|
||||
@@ -20,46 +18,6 @@ namespace Pinetime::Applications::Screens {
|
||||
int hundredths;
|
||||
};
|
||||
|
||||
// A simple buffer to hold the latest two laps
|
||||
template <int N> struct LapTextBuffer_t {
|
||||
LapTextBuffer_t() : buffer {}, currentSize {}, capacity {N}, head {-1} {
|
||||
}
|
||||
|
||||
void addLaps(const TimeSeparated_t& timeVal) {
|
||||
head++;
|
||||
head %= capacity;
|
||||
buffer[head] = timeVal;
|
||||
|
||||
if (currentSize < capacity) {
|
||||
currentSize++;
|
||||
}
|
||||
}
|
||||
|
||||
void clearBuffer() {
|
||||
buffer = {};
|
||||
currentSize = 0;
|
||||
head = -1;
|
||||
}
|
||||
|
||||
TimeSeparated_t* operator[](std::size_t idx) {
|
||||
// Sanity check for out-of-bounds
|
||||
if (idx >= 0 && idx < capacity) {
|
||||
if (idx < currentSize) {
|
||||
// This transformation is to ensure that head is always pointing to index 0.
|
||||
const auto transformed_idx = (head - idx) % capacity;
|
||||
return (&buffer[transformed_idx]);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<TimeSeparated_t, N> buffer;
|
||||
uint8_t currentSize;
|
||||
uint8_t capacity;
|
||||
int8_t head;
|
||||
};
|
||||
|
||||
class StopWatch : public Screen {
|
||||
public:
|
||||
StopWatch(DisplayApp* app, System::SystemTask& systemTask);
|
||||
@@ -76,15 +34,15 @@ namespace Pinetime::Applications::Screens {
|
||||
|
||||
private:
|
||||
Pinetime::System::SystemTask& systemTask;
|
||||
TickType_t timeElapsed;
|
||||
States currentState;
|
||||
States currentState = States::Init;
|
||||
TickType_t startTime;
|
||||
TickType_t oldTimeElapsed;
|
||||
TimeSeparated_t currentTimeSeparated; // Holds Mins, Secs, millisecs
|
||||
LapTextBuffer_t<2> lapBuffer;
|
||||
int lapNr = 0;
|
||||
TickType_t oldTimeElapsed = 0;
|
||||
static constexpr int maxLapCount = 20;
|
||||
TickType_t laps[maxLapCount + 1];
|
||||
static constexpr int displayedLaps = 2;
|
||||
int lapsDone = 0;
|
||||
lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap;
|
||||
lv_obj_t *lapOneText, *lapTwoText;
|
||||
lv_obj_t* lapText;
|
||||
|
||||
lv_task_t* taskRefresh;
|
||||
};
|
||||
|
@@ -1,8 +1,9 @@
|
||||
#include "Styles.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
void Pinetime::Applications::Screens::SetRadioButtonStyle(lv_obj_t* checkbox) {
|
||||
lv_obj_set_style_local_radius(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_obj_set_style_local_border_width(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, 9);
|
||||
lv_obj_set_style_local_border_color(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_border_color(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, Colors::highlight);
|
||||
lv_obj_set_style_local_bg_color(checkbox, LV_CHECKBOX_PART_BULLET, LV_STATE_CHECKED, LV_COLOR_WHITE);
|
||||
}
|
||||
|
@@ -37,20 +37,20 @@ namespace Pinetime {
|
||||
static constexpr const char* chartLine = "\xEF\x88\x81";
|
||||
static constexpr const char* eye = "\xEF\x81\xAE";
|
||||
static constexpr const char* home = "\xEF\x80\x95";
|
||||
static constexpr const char* sleep = "\xEE\xBD\x84";
|
||||
static constexpr const char* circle = "\xEF\x84\x91";
|
||||
|
||||
// lv_font_sys_48.c
|
||||
static constexpr const char* settings = "\xEE\xA4\x82"; // e902
|
||||
static constexpr const char* settings = "\xEE\xA2\xB8";
|
||||
|
||||
static constexpr const char* brightnessHigh = "\xEE\xA4\x84"; // e904
|
||||
static constexpr const char* brightnessLow = "\xEE\xA4\x85"; // e905
|
||||
static constexpr const char* brightnessMedium = "\xEE\xA4\x86"; // e906
|
||||
static constexpr const char* brightnessLow = "\xEE\x8E\xAA";
|
||||
static constexpr const char* brightnessMedium = "\xEE\x8E\xAB";
|
||||
static constexpr const char* brightnessHigh = "\xEE\x8E\xAC";
|
||||
|
||||
static constexpr const char* notificationsOff = "\xEE\xA4\x8B"; // e90b
|
||||
static constexpr const char* notificationsOn = "\xEE\xA4\x8C"; // e90c
|
||||
|
||||
static constexpr const char* highlight = "\xEE\xA4\x87"; // e907
|
||||
static constexpr const char* notificationsOff = "\xEE\x9F\xB6";
|
||||
static constexpr const char* notificationsOn = "\xEE\x9F\xB7";
|
||||
|
||||
static constexpr const char* flashlight = "\xEF\x80\x8B";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "components/motion/MotionController.h"
|
||||
#include "drivers/Watchdog.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -136,20 +137,25 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
|
||||
uptimeSeconds = uptimeSeconds % secondsInAMinute;
|
||||
// TODO handle more than 100 days of uptime
|
||||
|
||||
#ifndef TARGET_DEVICE_NAME
|
||||
#define TARGET_DEVICE_NAME "UNKNOWN"
|
||||
#endif
|
||||
|
||||
lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_recolor(label, true);
|
||||
lv_label_set_text_fmt(label,
|
||||
"#808080 Date# %02d/%02d/%04d\n"
|
||||
"#808080 Date# %04d-%02d-%02d\n"
|
||||
"#808080 Time# %02d:%02d:%02d\n"
|
||||
"#808080 Uptime#\n %02lud %02lu:%02lu:%02lu\n"
|
||||
"#808080 Battery# %d%%/%03imV\n"
|
||||
"#808080 Backlight# %s\n"
|
||||
"#808080 Last reset# %s\n"
|
||||
"#808080 Accel.# %s\n"
|
||||
"#808080 Touch.# %x.%x.%x\n",
|
||||
dateTimeController.Day(),
|
||||
static_cast<uint8_t>(dateTimeController.Month()),
|
||||
"#808080 Touch.# %x.%x.%x\n"
|
||||
"#808080 Model# %s",
|
||||
dateTimeController.Year(),
|
||||
static_cast<uint8_t>(dateTimeController.Month()),
|
||||
dateTimeController.Day(),
|
||||
dateTimeController.Hours(),
|
||||
dateTimeController.Minutes(),
|
||||
dateTimeController.Seconds(),
|
||||
@@ -164,7 +170,8 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
|
||||
ToString(motionController.DeviceType()),
|
||||
touchPanel.GetChipId(),
|
||||
touchPanel.GetVendorId(),
|
||||
touchPanel.GetFwVersion());
|
||||
touchPanel.GetFwVersion(),
|
||||
TARGET_DEVICE_NAME);
|
||||
lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0);
|
||||
return std::make_unique<Screens::Label>(1, 5, app, label);
|
||||
}
|
||||
@@ -212,7 +219,7 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen4() {
|
||||
lv_table_set_col_cnt(infoTask, 4);
|
||||
lv_table_set_row_cnt(infoTask, maxTaskCount + 1);
|
||||
lv_obj_set_style_local_pad_all(infoTask, LV_TABLE_PART_CELL1, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_border_color(infoTask, LV_TABLE_PART_CELL1, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_obj_set_style_local_border_color(infoTask, LV_TABLE_PART_CELL1, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
|
||||
lv_table_set_cell_value(infoTask, 0, 0, "#");
|
||||
lv_table_set_col_width(infoTask, 0, 30);
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#include "displayapp/screens/Tile.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/screens/BatteryIcon.h"
|
||||
#include "components/ble/BleController.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -26,46 +28,26 @@ Tile::Tile(uint8_t screenID,
|
||||
uint8_t numScreens,
|
||||
DisplayApp* app,
|
||||
Controllers::Settings& settingsController,
|
||||
Pinetime::Controllers::Battery& batteryController,
|
||||
Controllers::Battery& batteryController,
|
||||
Controllers::Ble& bleController,
|
||||
Controllers::DateTime& dateTimeController,
|
||||
std::array<Applications, 6>& applications)
|
||||
: Screen(app), batteryController {batteryController}, dateTimeController {dateTimeController} {
|
||||
: Screen(app),
|
||||
dateTimeController {dateTimeController},
|
||||
pageIndicator(screenID, numScreens),
|
||||
statusIcons(batteryController, bleController) {
|
||||
|
||||
settingsController.SetAppMenu(screenID);
|
||||
|
||||
statusIcons.Create();
|
||||
lv_obj_align(statusIcons.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -8, 0);
|
||||
|
||||
// Time
|
||||
label_time = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(label_time, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
|
||||
// Battery
|
||||
batteryIcon.Create(lv_scr_act());
|
||||
lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, -8, 0);
|
||||
|
||||
if (numScreens > 1) {
|
||||
pageIndicatorBasePoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[0].y = 0;
|
||||
pageIndicatorBasePoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[1].y = LV_VER_RES;
|
||||
|
||||
pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111));
|
||||
lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2);
|
||||
|
||||
const uint16_t indicatorSize = LV_VER_RES / numScreens;
|
||||
const uint16_t indicatorPos = indicatorSize * screenID;
|
||||
|
||||
pageIndicatorPoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[0].y = indicatorPos;
|
||||
pageIndicatorPoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[1].y = indicatorPos + indicatorSize;
|
||||
|
||||
pageIndicator = lv_line_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xb0, 0xb0, 0xb0));
|
||||
lv_line_set_points(pageIndicator, pageIndicatorPoints, 2);
|
||||
}
|
||||
pageIndicator.Create();
|
||||
|
||||
uint8_t btIndex = 0;
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
@@ -90,7 +72,7 @@ Tile::Tile(uint8_t screenID,
|
||||
lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_OPA_50);
|
||||
lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DEFAULT, LV_COLOR_AQUA);
|
||||
lv_obj_set_style_local_bg_opa(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, LV_OPA_50);
|
||||
lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, lv_color_hex(0x111111));
|
||||
lv_obj_set_style_local_bg_color(btnm1, LV_BTNMATRIX_PART_BTN, LV_STATE_DISABLED, Colors::bgDark);
|
||||
lv_obj_set_style_local_pad_all(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_pad_inner(btnm1, LV_BTNMATRIX_PART_BG, LV_STATE_DEFAULT, 10);
|
||||
|
||||
@@ -116,7 +98,7 @@ Tile::~Tile() {
|
||||
|
||||
void Tile::UpdateScreen() {
|
||||
lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str());
|
||||
batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining());
|
||||
statusIcons.Update();
|
||||
}
|
||||
|
||||
void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) {
|
||||
|
@@ -7,9 +7,9 @@
|
||||
#include "displayapp/Apps.h"
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "components/settings/Settings.h"
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "components/battery/BatteryController.h"
|
||||
#include <displayapp/screens/BatteryIcon.h>
|
||||
#include "displayapp/widgets/PageIndicator.h"
|
||||
#include "displayapp/widgets/StatusIcons.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
@@ -25,7 +25,8 @@ namespace Pinetime {
|
||||
uint8_t numScreens,
|
||||
DisplayApp* app,
|
||||
Controllers::Settings& settingsController,
|
||||
Pinetime::Controllers::Battery& batteryController,
|
||||
Controllers::Battery& batteryController,
|
||||
Controllers::Ble& bleController,
|
||||
Controllers::DateTime& dateTimeController,
|
||||
std::array<Applications, 6>& applications);
|
||||
|
||||
@@ -35,19 +36,15 @@ namespace Pinetime {
|
||||
void OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId);
|
||||
|
||||
private:
|
||||
Pinetime::Controllers::Battery& batteryController;
|
||||
Controllers::DateTime& dateTimeController;
|
||||
|
||||
lv_task_t* taskUpdate;
|
||||
|
||||
lv_obj_t* label_time;
|
||||
lv_point_t pageIndicatorBasePoints[2];
|
||||
lv_point_t pageIndicatorPoints[2];
|
||||
lv_obj_t* pageIndicatorBase;
|
||||
lv_obj_t* pageIndicator;
|
||||
lv_obj_t* btnm1;
|
||||
|
||||
BatteryIcon batteryIcon;
|
||||
Widgets::PageIndicator pageIndicator;
|
||||
Widgets::StatusIcons statusIcons;
|
||||
|
||||
const char* btnmMap[8];
|
||||
Pinetime::Applications::Apps apps[6];
|
||||
|
@@ -1,13 +1,20 @@
|
||||
#include "displayapp/screens/Timer.h"
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
static void btnEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* screen = static_cast<Timer*>(obj->user_data);
|
||||
screen->OnButtonEvent(obj, event);
|
||||
if (event == LV_EVENT_PRESSED) {
|
||||
screen->ButtonPressed();
|
||||
} else if (event == LV_EVENT_RELEASED || event == LV_EVENT_PRESS_LOST) {
|
||||
screen->MaskReset();
|
||||
} else if (event == LV_EVENT_SHORT_CLICKED) {
|
||||
screen->ToggleRunning();
|
||||
}
|
||||
}
|
||||
|
||||
Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) : Screen(app), timerController {timerController} {
|
||||
@@ -23,14 +30,37 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController) : S
|
||||
lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
lv_obj_align(secondCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
|
||||
|
||||
btnPlayPause = lv_btn_create(lv_scr_act(), nullptr);
|
||||
highlightObjectMask = lv_objmask_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_size(highlightObjectMask, 240, 50);
|
||||
lv_obj_align(highlightObjectMask, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
|
||||
lv_draw_mask_line_param_t tmpMaskLine;
|
||||
|
||||
lv_draw_mask_line_points_init(&tmpMaskLine, 0, 0, 0, 240, LV_DRAW_MASK_LINE_SIDE_LEFT);
|
||||
highlightMask = lv_objmask_add_mask(highlightObjectMask, &tmpMaskLine);
|
||||
|
||||
lv_obj_t* btnHighlight = lv_obj_create(highlightObjectMask, nullptr);
|
||||
lv_obj_set_style_local_radius(btnHighlight, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_obj_set_style_local_bg_color(btnHighlight, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
|
||||
lv_obj_set_size(btnHighlight, LV_HOR_RES, 50);
|
||||
lv_obj_align(btnHighlight, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
|
||||
btnObjectMask = lv_objmask_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_size(btnObjectMask, 240, 50);
|
||||
lv_obj_align(btnObjectMask, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
|
||||
lv_draw_mask_line_points_init(&tmpMaskLine, 0, 0, 0, 240, LV_DRAW_MASK_LINE_SIDE_RIGHT);
|
||||
btnMask = lv_objmask_add_mask(btnObjectMask, &tmpMaskLine);
|
||||
|
||||
btnPlayPause = lv_btn_create(btnObjectMask, nullptr);
|
||||
btnPlayPause->user_data = this;
|
||||
lv_obj_set_style_local_radius(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38));
|
||||
lv_obj_set_style_local_bg_color(btnPlayPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
lv_obj_set_event_cb(btnPlayPause, btnEventHandler);
|
||||
lv_obj_set_size(btnPlayPause, LV_HOR_RES, 50);
|
||||
lv_obj_align(btnPlayPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
txtPlayPause = lv_label_create(btnPlayPause, nullptr);
|
||||
|
||||
txtPlayPause = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_align(txtPlayPause, btnPlayPause, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
if (timerController.IsRunning()) {
|
||||
SetTimerRunning();
|
||||
@@ -46,11 +76,46 @@ Timer::~Timer() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
void Timer::ButtonPressed() {
|
||||
pressTime = xTaskGetTickCount();
|
||||
buttonPressing = true;
|
||||
}
|
||||
|
||||
void Timer::MaskReset() {
|
||||
buttonPressing = false;
|
||||
// A click event is processed before a release event,
|
||||
// so the release event would override the "Pause" text without this check
|
||||
if (!timerController.IsRunning()) {
|
||||
lv_label_set_text_static(txtPlayPause, "Start");
|
||||
}
|
||||
maskPosition = 0;
|
||||
UpdateMask();
|
||||
}
|
||||
|
||||
void Timer::UpdateMask() {
|
||||
lv_draw_mask_line_param_t maskLine;
|
||||
|
||||
lv_draw_mask_line_points_init(&maskLine, maskPosition, 0, maskPosition, 240, LV_DRAW_MASK_LINE_SIDE_LEFT);
|
||||
lv_objmask_update_mask(highlightObjectMask, highlightMask, &maskLine);
|
||||
|
||||
lv_draw_mask_line_points_init(&maskLine, maskPosition, 0, maskPosition, 240, LV_DRAW_MASK_LINE_SIDE_RIGHT);
|
||||
lv_objmask_update_mask(btnObjectMask, btnMask, &maskLine);
|
||||
}
|
||||
|
||||
void Timer::Refresh() {
|
||||
if (timerController.IsRunning()) {
|
||||
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
|
||||
minuteCounter.SetValue(seconds / 60);
|
||||
secondCounter.SetValue(seconds % 60);
|
||||
} else if (buttonPressing && xTaskGetTickCount() > pressTime + pdMS_TO_TICKS(150)) {
|
||||
lv_label_set_text_static(txtPlayPause, "Reset");
|
||||
maskPosition += 15;
|
||||
if (maskPosition > 240) {
|
||||
MaskReset();
|
||||
Reset();
|
||||
} else {
|
||||
UpdateMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,25 +131,21 @@ void Timer::SetTimerStopped() {
|
||||
lv_label_set_text_static(txtPlayPause, "Start");
|
||||
}
|
||||
|
||||
void Timer::OnButtonEvent(lv_obj_t* obj, lv_event_t event) {
|
||||
if (event == LV_EVENT_CLICKED) {
|
||||
if (obj == btnPlayPause) {
|
||||
if (timerController.IsRunning()) {
|
||||
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
|
||||
minuteCounter.SetValue(seconds / 60);
|
||||
secondCounter.SetValue(seconds % 60);
|
||||
timerController.StopTimer();
|
||||
SetTimerStopped();
|
||||
} else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) {
|
||||
timerController.StartTimer((secondCounter.GetValue() + minuteCounter.GetValue() * 60) * 1000);
|
||||
Refresh();
|
||||
SetTimerRunning();
|
||||
}
|
||||
}
|
||||
void Timer::ToggleRunning() {
|
||||
if (timerController.IsRunning()) {
|
||||
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
|
||||
minuteCounter.SetValue(seconds / 60);
|
||||
secondCounter.SetValue(seconds % 60);
|
||||
timerController.StopTimer();
|
||||
SetTimerStopped();
|
||||
} else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) {
|
||||
timerController.StartTimer((secondCounter.GetValue() + minuteCounter.GetValue() * 60) * 1000);
|
||||
Refresh();
|
||||
SetTimerRunning();
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::SetDone() {
|
||||
void Timer::Reset() {
|
||||
minuteCounter.SetValue(0);
|
||||
secondCounter.SetValue(0);
|
||||
SetTimerStopped();
|
||||
|
@@ -5,29 +5,42 @@
|
||||
#include "systemtask/SystemTask.h"
|
||||
#include "displayapp/LittleVgl.h"
|
||||
#include "displayapp/widgets/Counter.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#include "components/timer/TimerController.h"
|
||||
|
||||
namespace Pinetime::Applications::Screens {
|
||||
class Timer : public Screen {
|
||||
public:
|
||||
enum class Modes { Normal, Done };
|
||||
|
||||
Timer(DisplayApp* app, Controllers::TimerController& timerController);
|
||||
~Timer() override;
|
||||
void Refresh() override;
|
||||
void SetDone();
|
||||
void OnButtonEvent(lv_obj_t* obj, lv_event_t event);
|
||||
void Reset();
|
||||
void ToggleRunning();
|
||||
void ButtonPressed();
|
||||
void MaskReset();
|
||||
|
||||
private:
|
||||
void SetTimerRunning();
|
||||
void SetTimerStopped();
|
||||
void UpdateMask();
|
||||
Controllers::TimerController& timerController;
|
||||
|
||||
lv_obj_t* msecTime;
|
||||
lv_obj_t* btnPlayPause;
|
||||
lv_obj_t* txtPlayPause;
|
||||
|
||||
lv_obj_t* btnObjectMask;
|
||||
lv_obj_t* highlightObjectMask;
|
||||
lv_objmask_mask_t* btnMask;
|
||||
lv_objmask_mask_t* highlightMask;
|
||||
|
||||
lv_task_t* taskRefresh;
|
||||
Widgets::Counter minuteCounter = Widgets::Counter(0, 59);
|
||||
Widgets::Counter secondCounter = Widgets::Counter(0, 59);
|
||||
Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76);
|
||||
Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_76);
|
||||
|
||||
bool buttonPressing = false;
|
||||
int maskPosition = 0;
|
||||
TickType_t pressTime;
|
||||
};
|
||||
}
|
||||
|
@@ -1,10 +1,7 @@
|
||||
#include "displayapp/screens/Twos.h"
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -21,33 +18,33 @@ Twos::Twos(Pinetime::Applications::DisplayApp* app) : Screen(app) {
|
||||
lv_style_set_border_width(&style_cell1, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell1, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell1, LV_STATE_DEFAULT, lv_color_hex(0xcdc0b4));
|
||||
lv_style_set_pad_top(&style_cell1, LV_STATE_DEFAULT, 25);
|
||||
lv_style_set_pad_top(&style_cell1, LV_STATE_DEFAULT, 29);
|
||||
lv_style_set_text_color(&style_cell1, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
|
||||
lv_style_set_border_color(&style_cell2, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell2, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell2, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell2, LV_STATE_DEFAULT, lv_color_hex(0xefdfc6));
|
||||
lv_style_set_pad_top(&style_cell2, LV_STATE_DEFAULT, 25);
|
||||
lv_style_set_pad_top(&style_cell2, LV_STATE_DEFAULT, 29);
|
||||
lv_style_set_text_color(&style_cell2, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
|
||||
lv_style_set_border_color(&style_cell3, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell3, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell3, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell3, LV_STATE_DEFAULT, lv_color_hex(0xef9263));
|
||||
lv_style_set_pad_top(&style_cell3, LV_STATE_DEFAULT, 25);
|
||||
lv_style_set_pad_top(&style_cell3, LV_STATE_DEFAULT, 29);
|
||||
|
||||
lv_style_set_border_color(&style_cell4, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell4, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell4, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell4, LV_STATE_DEFAULT, lv_color_hex(0xf76142));
|
||||
lv_style_set_pad_top(&style_cell4, LV_STATE_DEFAULT, 25);
|
||||
lv_style_set_pad_top(&style_cell4, LV_STATE_DEFAULT, 29);
|
||||
|
||||
lv_style_set_border_color(&style_cell5, LV_STATE_DEFAULT, lv_color_hex(0xbbada0));
|
||||
lv_style_set_border_width(&style_cell5, LV_STATE_DEFAULT, 3);
|
||||
lv_style_set_bg_opa(&style_cell5, LV_STATE_DEFAULT, LV_OPA_COVER);
|
||||
lv_style_set_bg_color(&style_cell5, LV_STATE_DEFAULT, lv_color_hex(0x007dc5));
|
||||
lv_style_set_pad_top(&style_cell5, LV_STATE_DEFAULT, 25);
|
||||
lv_style_set_pad_top(&style_cell5, LV_STATE_DEFAULT, 29);
|
||||
|
||||
// format grid display
|
||||
|
||||
@@ -57,24 +54,22 @@ Twos::Twos(Pinetime::Applications::DisplayApp* app) : Screen(app) {
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL3, &style_cell3);
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL4, &style_cell4);
|
||||
lv_obj_add_style(gridDisplay, LV_TABLE_PART_CELL4 + 1, &style_cell5);
|
||||
lv_table_set_col_cnt(gridDisplay, 4);
|
||||
lv_table_set_row_cnt(gridDisplay, 4);
|
||||
lv_table_set_col_width(gridDisplay, 0, LV_HOR_RES / 4);
|
||||
lv_table_set_col_width(gridDisplay, 1, LV_HOR_RES / 4);
|
||||
lv_table_set_col_width(gridDisplay, 2, LV_HOR_RES / 4);
|
||||
lv_table_set_col_width(gridDisplay, 3, LV_HOR_RES / 4);
|
||||
lv_obj_align(gridDisplay, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
|
||||
lv_obj_clean_style_list(gridDisplay, LV_TABLE_PART_BG);
|
||||
|
||||
// initialize grid
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int col = 0; col < 4; col++) {
|
||||
lv_table_set_col_cnt(gridDisplay, nCols);
|
||||
lv_table_set_row_cnt(gridDisplay, nRows);
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
static constexpr int colWidth = LV_HOR_RES_MAX / nCols;
|
||||
lv_table_set_col_width(gridDisplay, col, colWidth);
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
grid[row][col].value = 0;
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 1);
|
||||
lv_table_set_cell_align(gridDisplay, row, col, LV_LABEL_ALIGN_CENTER);
|
||||
}
|
||||
}
|
||||
// Move one pixel down to remove a gap
|
||||
lv_obj_align(gridDisplay, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 1);
|
||||
|
||||
lv_obj_clean_style_list(gridDisplay, LV_TABLE_PART_BG);
|
||||
|
||||
placeNewTile();
|
||||
placeNewTile();
|
||||
|
||||
@@ -82,7 +77,7 @@ Twos::Twos(Pinetime::Applications::DisplayApp* app) : Screen(app) {
|
||||
scoreText = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_width(scoreText, LV_HOR_RES);
|
||||
lv_label_set_align(scoreText, LV_ALIGN_IN_LEFT_MID);
|
||||
lv_obj_align(scoreText, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 10);
|
||||
lv_obj_align(scoreText, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
lv_label_set_recolor(scoreText, true);
|
||||
lv_label_set_text_fmt(scoreText, "Score #FFFF00 %i#", score);
|
||||
}
|
||||
@@ -97,39 +92,38 @@ Twos::~Twos() {
|
||||
}
|
||||
|
||||
bool Twos::placeNewTile() {
|
||||
std::vector<std::pair<int, int>> availableCells;
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int col = 0; col < 4; col++) {
|
||||
if (!grid[row][col].value) {
|
||||
availableCells.push_back(std::make_pair(row, col));
|
||||
}
|
||||
unsigned int emptyCells[nCells];
|
||||
unsigned int nEmpty = 0;
|
||||
for (unsigned int i = 0; i < nCells; i++) {
|
||||
const unsigned int row = i / nCols;
|
||||
const unsigned int col = i % nCols;
|
||||
if (grid[row][col].value == 0) {
|
||||
emptyCells[nEmpty] = i;
|
||||
nEmpty++;
|
||||
}
|
||||
}
|
||||
|
||||
if (availableCells.size() == 0) {
|
||||
if (nEmpty == 0) {
|
||||
return false; // game lost
|
||||
}
|
||||
|
||||
auto it = availableCells.cbegin();
|
||||
int random = rand() % availableCells.size();
|
||||
std::advance(it, random);
|
||||
std::pair<int, int> newCell = *it;
|
||||
int random = rand() % nEmpty;
|
||||
|
||||
if ((rand() % 100) < 90)
|
||||
grid[newCell.first][newCell.second].value = 2;
|
||||
else
|
||||
grid[newCell.first][newCell.second].value = 4;
|
||||
updateGridDisplay(grid);
|
||||
if ((rand() % 100) < 90) {
|
||||
grid[emptyCells[random] / nCols][emptyCells[random] % nCols].value = 2;
|
||||
} else {
|
||||
grid[emptyCells[random] / nCols][emptyCells[random] % nCols].value = 4;
|
||||
}
|
||||
updateGridDisplay();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Twos::tryMerge(TwosTile grid[][4], int& newRow, int& newCol, int oldRow, int oldCol) {
|
||||
bool Twos::tryMerge(int newRow, int newCol, int oldRow, int oldCol) {
|
||||
if (grid[newRow][newCol].value == grid[oldRow][oldCol].value) {
|
||||
if ((newCol != oldCol) || (newRow != oldRow)) {
|
||||
if (!grid[newRow][newCol].merged) {
|
||||
unsigned int newVal = grid[oldRow][oldCol].value *= 2;
|
||||
grid[newRow][newCol].value = newVal;
|
||||
score += newVal;
|
||||
grid[newRow][newCol].value *= 2;
|
||||
score += grid[newRow][newCol].value;
|
||||
lv_label_set_text_fmt(scoreText, "Score #FFFF00 %i#", score);
|
||||
grid[oldRow][oldCol].value = 0;
|
||||
grid[newRow][newCol].merged = true;
|
||||
@@ -140,7 +134,7 @@ bool Twos::tryMerge(TwosTile grid[][4], int& newRow, int& newCol, int oldRow, in
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Twos::tryMove(TwosTile grid[][4], int newRow, int newCol, int oldRow, int oldCol) {
|
||||
bool Twos::tryMove(int newRow, int newCol, int oldRow, int oldCol) {
|
||||
if (((newCol >= 0) && (newCol != oldCol)) || ((newRow >= 0) && (newRow != oldRow))) {
|
||||
grid[newRow][newCol].value = grid[oldRow][oldCol].value;
|
||||
grid[oldRow][oldCol].value = 0;
|
||||
@@ -151,28 +145,30 @@ bool Twos::tryMove(TwosTile grid[][4], int newRow, int newCol, int oldRow, int o
|
||||
|
||||
bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
bool validMove = false;
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int col = 0; col < 4; col++) {
|
||||
grid[row][col].merged = false; // reinitialize merge state
|
||||
}
|
||||
for (unsigned int i = 0; i < nCells; i++) {
|
||||
const unsigned int row = i / nCols;
|
||||
const unsigned int col = i % nCols;
|
||||
grid[row][col].merged = false; // reinitialize merge state
|
||||
}
|
||||
switch (event) {
|
||||
case TouchEvents::SwipeLeft:
|
||||
for (int col = 1; col < 4; col++) { // ignore tiles already on far left
|
||||
for (int row = 0; row < 4; row++) {
|
||||
if (grid[row][col].value) {
|
||||
for (int col = 1; col < nCols; col++) { // ignore tiles already on far left
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
if (grid[row][col].value > 0) {
|
||||
int newCol = -1;
|
||||
for (int potentialNewCol = col - 1; potentialNewCol >= 0; potentialNewCol--) {
|
||||
if (!grid[row][potentialNewCol].value) {
|
||||
if (grid[row][potentialNewCol].value == 0) {
|
||||
newCol = potentialNewCol;
|
||||
} else { // blocked by another tile
|
||||
if (tryMerge(grid, row, potentialNewCol, row, col))
|
||||
if (tryMerge(row, potentialNewCol, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tryMove(grid, row, newCol, row, col))
|
||||
if (tryMove(row, newCol, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -181,21 +177,23 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
}
|
||||
return true;
|
||||
case TouchEvents::SwipeRight:
|
||||
for (int col = 2; col >= 0; col--) { // ignore tiles already on far right
|
||||
for (int row = 0; row < 4; row++) {
|
||||
if (grid[row][col].value) {
|
||||
for (int col = nCols - 2; col >= 0; col--) { // ignore tiles already on far right
|
||||
for (int row = 0; row < nRows; row++) {
|
||||
if (grid[row][col].value > 0) {
|
||||
int newCol = -1;
|
||||
for (int potentialNewCol = col + 1; potentialNewCol < 4; potentialNewCol++) {
|
||||
if (!grid[row][potentialNewCol].value) {
|
||||
for (int potentialNewCol = col + 1; potentialNewCol < nCols; potentialNewCol++) {
|
||||
if (grid[row][potentialNewCol].value == 0) {
|
||||
newCol = potentialNewCol;
|
||||
} else { // blocked by another tile
|
||||
if (tryMerge(grid, row, potentialNewCol, row, col))
|
||||
if (tryMerge(row, potentialNewCol, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tryMove(grid, row, newCol, row, col))
|
||||
if (tryMove(row, newCol, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,21 +202,23 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
}
|
||||
return true;
|
||||
case TouchEvents::SwipeUp:
|
||||
for (int row = 1; row < 4; row++) { // ignore tiles already on top
|
||||
for (int col = 0; col < 4; col++) {
|
||||
if (grid[row][col].value) {
|
||||
for (int row = 1; row < nRows; row++) { // ignore tiles already on top
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
if (grid[row][col].value > 0) {
|
||||
int newRow = -1;
|
||||
for (int potentialNewRow = row - 1; potentialNewRow >= 0; potentialNewRow--) {
|
||||
if (!grid[potentialNewRow][col].value) {
|
||||
if (grid[potentialNewRow][col].value == 0) {
|
||||
newRow = potentialNewRow;
|
||||
} else { // blocked by another tile
|
||||
if (tryMerge(grid, potentialNewRow, col, row, col))
|
||||
if (tryMerge(potentialNewRow, col, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tryMove(grid, newRow, col, row, col))
|
||||
if (tryMove(newRow, col, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,21 +227,23 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
}
|
||||
return true;
|
||||
case TouchEvents::SwipeDown:
|
||||
for (int row = 2; row >= 0; row--) { // ignore tiles already on bottom
|
||||
for (int col = 0; col < 4; col++) {
|
||||
if (grid[row][col].value) {
|
||||
for (int row = nRows - 2; row >= 0; row--) { // ignore tiles already on bottom
|
||||
for (int col = 0; col < nCols; col++) {
|
||||
if (grid[row][col].value > 0) {
|
||||
int newRow = -1;
|
||||
for (int potentialNewRow = row + 1; potentialNewRow < 4; potentialNewRow++) {
|
||||
if (!grid[potentialNewRow][col].value) {
|
||||
for (int potentialNewRow = row + 1; potentialNewRow < nRows; potentialNewRow++) {
|
||||
if (grid[potentialNewRow][col].value == 0) {
|
||||
newRow = potentialNewRow;
|
||||
} else { // blocked by another tile
|
||||
if (tryMerge(grid, potentialNewRow, col, row, col))
|
||||
if (tryMerge(potentialNewRow, col, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tryMove(grid, newRow, col, row, col))
|
||||
if (tryMove(newRow, col, row, col)) {
|
||||
validMove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,36 +257,36 @@ bool Twos::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Twos::updateGridDisplay(TwosTile grid[][4]) {
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int col = 0; col < 4; col++) {
|
||||
if (grid[row][col].value) {
|
||||
char buffer[7];
|
||||
sprintf(buffer, "%d", grid[row][col].value);
|
||||
lv_table_set_cell_value(gridDisplay, row, col, buffer);
|
||||
} else {
|
||||
lv_table_set_cell_value(gridDisplay, row, col, "");
|
||||
}
|
||||
switch (grid[row][col].value) {
|
||||
case 0:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 1);
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 2);
|
||||
break;
|
||||
case 8:
|
||||
case 16:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 3);
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 4);
|
||||
break;
|
||||
default:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 5);
|
||||
break;
|
||||
}
|
||||
void Twos::updateGridDisplay() {
|
||||
for (unsigned int i = 0; i < nCells; i++) {
|
||||
const unsigned int row = i / nCols;
|
||||
const unsigned int col = i % nCols;
|
||||
if (grid[row][col].value > 0) {
|
||||
char buffer[7];
|
||||
sprintf(buffer, "%d", grid[row][col].value);
|
||||
lv_table_set_cell_value(gridDisplay, row, col, buffer);
|
||||
} else {
|
||||
lv_table_set_cell_value(gridDisplay, row, col, "");
|
||||
}
|
||||
switch (grid[row][col].value) {
|
||||
case 0:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 1);
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 2);
|
||||
break;
|
||||
case 8:
|
||||
case 16:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 3);
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 4);
|
||||
break;
|
||||
default:
|
||||
lv_table_set_cell_type(gridDisplay, row, col, 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -26,11 +26,14 @@ namespace Pinetime {
|
||||
|
||||
lv_obj_t* scoreText;
|
||||
lv_obj_t* gridDisplay;
|
||||
TwosTile grid[4][4];
|
||||
static constexpr int nCols = 4;
|
||||
static constexpr int nRows = 4;
|
||||
static constexpr int nCells = nCols * nRows;
|
||||
TwosTile grid[nRows][nCols];
|
||||
unsigned int score = 0;
|
||||
void updateGridDisplay(TwosTile grid[][4]);
|
||||
bool tryMerge(TwosTile grid[][4], int& newRow, int& newCol, int oldRow, int oldCol);
|
||||
bool tryMove(TwosTile grid[][4], int newRow, int newCol, int oldRow, int oldCol);
|
||||
void updateGridDisplay();
|
||||
bool tryMerge(int newRow, int newCol, int oldRow, int oldCol);
|
||||
bool tryMove(int newRow, int newCol, int oldRow, int oldCol);
|
||||
bool placeNewTile();
|
||||
};
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/screens/NotificationIcon.h"
|
||||
#include "components/settings/Settings.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
LV_IMG_DECLARE(bg_clock);
|
||||
|
||||
@@ -73,14 +74,14 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
|
||||
lv_obj_align(plugIcon, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
|
||||
|
||||
notificationIcon = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00));
|
||||
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_LIME);
|
||||
lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false));
|
||||
lv_obj_align(notificationIcon, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
|
||||
// Date - Day / Week day
|
||||
|
||||
label_date_day = lv_label_create(lv_scr_act(), NULL);
|
||||
lv_obj_set_style_local_text_color(label_date_day, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xff, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_text_color(label_date_day, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange);
|
||||
lv_label_set_text_fmt(label_date_day, "%s\n%02i", dateTimeController.DayOfWeekShortToString(), dateTimeController.Day());
|
||||
lv_label_set_align(label_date_day, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(label_date_day, NULL, LV_ALIGN_CENTER, 50, 0);
|
||||
|
@@ -3,8 +3,6 @@
|
||||
#include <date/date.h>
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <cstdio>
|
||||
#include "displayapp/screens/BatteryIcon.h"
|
||||
#include "displayapp/screens/BleIcon.h"
|
||||
#include "displayapp/screens/NotificationIcon.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "components/battery/BatteryController.h"
|
||||
@@ -13,6 +11,7 @@
|
||||
#include "components/heartrate/HeartRateController.h"
|
||||
#include "components/motion/MotionController.h"
|
||||
#include "components/settings/Settings.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
WatchFaceDigital::WatchFaceDigital(DisplayApp* app,
|
||||
@@ -26,28 +25,16 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app,
|
||||
: Screen(app),
|
||||
currentDateTime {{}},
|
||||
dateTimeController {dateTimeController},
|
||||
batteryController {batteryController},
|
||||
bleController {bleController},
|
||||
notificatioManager {notificatioManager},
|
||||
settingsController {settingsController},
|
||||
heartRateController {heartRateController},
|
||||
motionController {motionController} {
|
||||
motionController {motionController},
|
||||
statusIcons(batteryController, bleController) {
|
||||
|
||||
batteryIcon.Create(lv_scr_act());
|
||||
lv_obj_align(batteryIcon.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, 0, 0);
|
||||
|
||||
batteryPlug = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFF0000));
|
||||
lv_label_set_text_static(batteryPlug, Symbols::plug);
|
||||
lv_obj_align(batteryPlug, batteryIcon.GetObject(), LV_ALIGN_OUT_LEFT_MID, -5, 0);
|
||||
|
||||
bleIcon = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x0082FC));
|
||||
lv_label_set_text_static(bleIcon, Symbols::bluetooth);
|
||||
lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0);
|
||||
statusIcons.Create();
|
||||
|
||||
notificationIcon = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00));
|
||||
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_LIME);
|
||||
lv_label_set_text_static(notificationIcon, NotificationIcon::GetIcon(false));
|
||||
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
|
||||
@@ -94,24 +81,7 @@ WatchFaceDigital::~WatchFaceDigital() {
|
||||
}
|
||||
|
||||
void WatchFaceDigital::Refresh() {
|
||||
powerPresent = batteryController.IsPowerPresent();
|
||||
if (powerPresent.IsUpdated()) {
|
||||
lv_label_set_text_static(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get()));
|
||||
}
|
||||
|
||||
batteryPercentRemaining = batteryController.PercentRemaining();
|
||||
if (batteryPercentRemaining.IsUpdated()) {
|
||||
auto batteryPercent = batteryPercentRemaining.Get();
|
||||
batteryIcon.SetBatteryPercentage(batteryPercent);
|
||||
}
|
||||
|
||||
bleState = bleController.IsConnected();
|
||||
bleRadioEnabled = bleController.IsRadioEnabled();
|
||||
if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
|
||||
lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get()));
|
||||
}
|
||||
lv_obj_realign(batteryPlug);
|
||||
lv_obj_realign(bleIcon);
|
||||
statusIcons.Update();
|
||||
|
||||
notificationState = notificatioManager.AreNewNotificationsAvailable();
|
||||
if (notificationState.IsUpdated()) {
|
||||
|
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <displayapp/screens/BatteryIcon.h>
|
||||
#include <lvgl/src/lv_core/lv_obj.h>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
@@ -8,6 +7,7 @@
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "components/ble/BleController.h"
|
||||
#include "displayapp/widgets/StatusIcons.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Controllers {
|
||||
@@ -59,25 +59,20 @@ namespace Pinetime {
|
||||
lv_obj_t* label_time;
|
||||
lv_obj_t* label_time_ampm;
|
||||
lv_obj_t* label_date;
|
||||
lv_obj_t* bleIcon;
|
||||
lv_obj_t* batteryPlug;
|
||||
lv_obj_t* heartbeatIcon;
|
||||
lv_obj_t* heartbeatValue;
|
||||
lv_obj_t* stepIcon;
|
||||
lv_obj_t* stepValue;
|
||||
lv_obj_t* notificationIcon;
|
||||
|
||||
BatteryIcon batteryIcon;
|
||||
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::Battery& batteryController;
|
||||
Controllers::Ble& bleController;
|
||||
Controllers::NotificationManager& notificatioManager;
|
||||
Controllers::Settings& settingsController;
|
||||
Controllers::HeartRateController& heartRateController;
|
||||
Controllers::MotionController& motionController;
|
||||
|
||||
lv_task_t* taskRefresh;
|
||||
Widgets::StatusIcons statusIcons;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -42,13 +42,6 @@ namespace {
|
||||
auto* screen = static_cast<WatchFacePineTimeStyle*>(obj->user_data);
|
||||
screen->UpdateSelected(obj, event);
|
||||
}
|
||||
|
||||
bool IsBleIconVisible(bool isRadioEnabled, bool isConnected) {
|
||||
if (!isRadioEnabled) {
|
||||
return true;
|
||||
}
|
||||
return isConnected;
|
||||
}
|
||||
}
|
||||
|
||||
WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app,
|
||||
@@ -111,11 +104,11 @@ WatchFacePineTimeStyle::WatchFacePineTimeStyle(DisplayApp* app,
|
||||
lv_obj_align(plugIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 2);
|
||||
|
||||
bleIcon = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000));
|
||||
lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
lv_label_set_text_static(bleIcon, "");
|
||||
|
||||
notificationIcon = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000));
|
||||
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
lv_label_set_text_static(notificationIcon, "");
|
||||
|
||||
// Calendar icon
|
||||
|
@@ -149,7 +149,7 @@ void WatchFaceTerminal::Refresh() {
|
||||
}
|
||||
|
||||
if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
|
||||
lv_label_set_text_fmt(label_date, "[DATE]#007fff %04d.%02d.%02d#", short(year), char(month), char(day));
|
||||
lv_label_set_text_fmt(label_date, "[DATE]#007fff %04d-%02d-%02d#", short(year), char(month), char(day));
|
||||
|
||||
currentYear = year;
|
||||
currentMonth = month;
|
||||
|
@@ -2,19 +2,29 @@
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/screens/BatteryIcon.h"
|
||||
#include "components/ble/BleController.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
namespace {
|
||||
void ButtonEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* screen = static_cast<QuickSettings*>(obj->user_data);
|
||||
screen->OnButtonEvent(obj, event);
|
||||
if (event == LV_EVENT_CLICKED) {
|
||||
screen->OnButtonEvent(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void lv_update_task(struct _lv_task_t* task) {
|
||||
auto* user_data = static_cast<QuickSettings*>(task->user_data);
|
||||
user_data->UpdateScreen();
|
||||
}
|
||||
|
||||
enum class ButtonState : lv_state_t {
|
||||
NotificationsOn = LV_STATE_CHECKED,
|
||||
NotificationsOff = LV_STATE_DEFAULT,
|
||||
Sleep = 0x40,
|
||||
};
|
||||
}
|
||||
|
||||
QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app,
|
||||
@@ -22,13 +32,16 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app,
|
||||
Controllers::DateTime& dateTimeController,
|
||||
Controllers::BrightnessController& brightness,
|
||||
Controllers::MotorController& motorController,
|
||||
Pinetime::Controllers::Settings& settingsController)
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Controllers::Ble& bleController)
|
||||
: Screen(app),
|
||||
batteryController {batteryController},
|
||||
dateTimeController {dateTimeController},
|
||||
brightness {brightness},
|
||||
motorController {motorController},
|
||||
settingsController {settingsController} {
|
||||
settingsController {settingsController},
|
||||
statusIcons(batteryController, bleController) {
|
||||
|
||||
statusIcons.Create();
|
||||
|
||||
// This is the distance (padding) between all objects on this screen.
|
||||
static constexpr uint8_t innerDistance = 10;
|
||||
@@ -38,9 +51,6 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app,
|
||||
lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
|
||||
batteryIcon.Create(lv_scr_act());
|
||||
lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
|
||||
|
||||
static constexpr uint8_t barHeight = 20 + innerDistance;
|
||||
static constexpr uint8_t buttonHeight = (LV_VER_RES_MAX - barHeight - innerDistance) / 2;
|
||||
static constexpr uint8_t buttonWidth = (LV_HOR_RES_MAX - innerDistance) / 2; // wide buttons
|
||||
@@ -49,7 +59,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app,
|
||||
|
||||
lv_style_init(&btn_style);
|
||||
lv_style_set_radius(&btn_style, LV_STATE_DEFAULT, buttonHeight / 4);
|
||||
lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38));
|
||||
lv_style_set_bg_color(&btn_style, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
|
||||
btn1 = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btn1->user_data = this;
|
||||
@@ -72,25 +82,29 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app,
|
||||
lv_obj_t* lbl_btn;
|
||||
lbl_btn = lv_label_create(btn2, nullptr);
|
||||
lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48);
|
||||
lv_label_set_text_static(lbl_btn, Symbols::highlight);
|
||||
lv_label_set_text_static(lbl_btn, Symbols::flashlight);
|
||||
|
||||
btn3 = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btn3->user_data = this;
|
||||
lv_obj_set_event_cb(btn3, ButtonEventHandler);
|
||||
lv_btn_set_checkable(btn3, true);
|
||||
lv_obj_add_style(btn3, LV_BTN_PART_MAIN, &btn_style);
|
||||
lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, static_cast<lv_state_t>(ButtonState::NotificationsOff), LV_COLOR_RED);
|
||||
static constexpr lv_color_t violet = LV_COLOR_MAKE(0x60, 0x00, 0xff);
|
||||
lv_obj_set_style_local_bg_color(btn3, LV_BTN_PART_MAIN, static_cast<lv_state_t>(ButtonState::Sleep), violet);
|
||||
lv_obj_set_size(btn3, buttonWidth, buttonHeight);
|
||||
lv_obj_align(btn3, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, buttonXOffset, 0);
|
||||
|
||||
btn3_lvl = lv_label_create(btn3, nullptr);
|
||||
lv_obj_set_style_local_text_font(btn3_lvl, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48);
|
||||
|
||||
if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::ON) {
|
||||
lv_obj_add_state(btn3, LV_STATE_CHECKED);
|
||||
if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::On) {
|
||||
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn);
|
||||
} else {
|
||||
lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::NotificationsOn));
|
||||
} else if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::Off) {
|
||||
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff);
|
||||
} else {
|
||||
lv_label_set_text_static(btn3_lvl, Symbols::sleep);
|
||||
lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::Sleep));
|
||||
}
|
||||
|
||||
btn4 = lv_btn_create(lv_scr_act(), nullptr);
|
||||
@@ -118,34 +132,36 @@ QuickSettings::~QuickSettings() {
|
||||
|
||||
void QuickSettings::UpdateScreen() {
|
||||
lv_label_set_text(label_time, dateTimeController.FormattedTime().c_str());
|
||||
batteryIcon.SetBatteryPercentage(batteryController.PercentRemaining());
|
||||
statusIcons.Update();
|
||||
}
|
||||
|
||||
void QuickSettings::OnButtonEvent(lv_obj_t* object, lv_event_t event) {
|
||||
if (object == btn2 && event == LV_EVENT_CLICKED) {
|
||||
|
||||
running = false;
|
||||
void QuickSettings::OnButtonEvent(lv_obj_t* object) {
|
||||
if (object == btn2) {
|
||||
app->StartApp(Apps::FlashLight, DisplayApp::FullRefreshDirections::Up);
|
||||
|
||||
} else if (object == btn1 && event == LV_EVENT_CLICKED) {
|
||||
} else if (object == btn1) {
|
||||
|
||||
brightness.Step();
|
||||
lv_label_set_text_static(btn1_lvl, brightness.GetIcon());
|
||||
settingsController.SetBrightness(brightness.Level());
|
||||
|
||||
} else if (object == btn3 && event == LV_EVENT_VALUE_CHANGED) {
|
||||
} else if (object == btn3) {
|
||||
|
||||
if (lv_obj_get_state(btn3, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) {
|
||||
settingsController.SetNotificationStatus(Controllers::Settings::Notification::ON);
|
||||
motorController.RunForDuration(35);
|
||||
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn);
|
||||
} else {
|
||||
settingsController.SetNotificationStatus(Controllers::Settings::Notification::OFF);
|
||||
if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::On) {
|
||||
settingsController.SetNotificationStatus(Controllers::Settings::Notification::Off);
|
||||
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff);
|
||||
lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::NotificationsOff));
|
||||
} else if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::Off) {
|
||||
settingsController.SetNotificationStatus(Controllers::Settings::Notification::Sleep);
|
||||
lv_label_set_text_static(btn3_lvl, Symbols::sleep);
|
||||
lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::Sleep));
|
||||
} else {
|
||||
settingsController.SetNotificationStatus(Controllers::Settings::Notification::On);
|
||||
lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn);
|
||||
lv_obj_set_state(btn3, static_cast<lv_state_t>(ButtonState::NotificationsOn));
|
||||
motorController.RunForDuration(35);
|
||||
}
|
||||
|
||||
} else if (object == btn4 && event == LV_EVENT_CLICKED) {
|
||||
running = false;
|
||||
} else if (object == btn4) {
|
||||
settingsController.SetSettingsMenu(0);
|
||||
app->StartApp(Apps::Settings, DisplayApp::FullRefreshDirections::Up);
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#include "components/motor/MotorController.h"
|
||||
#include "components/settings/Settings.h"
|
||||
#include "components/battery/BatteryController.h"
|
||||
#include <displayapp/screens/BatteryIcon.h>
|
||||
#include "displayapp/widgets/StatusIcons.h"
|
||||
|
||||
namespace Pinetime {
|
||||
|
||||
@@ -22,16 +22,16 @@ namespace Pinetime {
|
||||
Controllers::DateTime& dateTimeController,
|
||||
Controllers::BrightnessController& brightness,
|
||||
Controllers::MotorController& motorController,
|
||||
Pinetime::Controllers::Settings& settingsController);
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Controllers::Ble& bleController);
|
||||
|
||||
~QuickSettings() override;
|
||||
|
||||
void OnButtonEvent(lv_obj_t* object, lv_event_t event);
|
||||
void OnButtonEvent(lv_obj_t* object);
|
||||
|
||||
void UpdateScreen();
|
||||
|
||||
private:
|
||||
Pinetime::Controllers::Battery& batteryController;
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::BrightnessController& brightness;
|
||||
Controllers::MotorController& motorController;
|
||||
@@ -49,7 +49,7 @@ namespace Pinetime {
|
||||
lv_obj_t* btn3_lvl;
|
||||
lv_obj_t* btn4;
|
||||
|
||||
BatteryIcon batteryIcon;
|
||||
Widgets::StatusIcons statusIcons;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,8 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::array<SettingChimes::Option, 3> SettingChimes::options;
|
||||
|
||||
SettingChimes::SettingChimes(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
|
||||
: Screen(app), settingsController {settingsController} {
|
||||
|
||||
@@ -40,37 +42,16 @@ SettingChimes::SettingChimes(Pinetime::Applications::DisplayApp* app, Pinetime::
|
||||
lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);
|
||||
|
||||
optionsTotal = 0;
|
||||
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], " Off");
|
||||
cbOption[optionsTotal]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
|
||||
SetRadioButtonStyle(cbOption[optionsTotal]);
|
||||
if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::None) {
|
||||
lv_checkbox_set_checked(cbOption[optionsTotal], true);
|
||||
for (unsigned int i = 0; i < options.size(); i++) {
|
||||
cbOption[i] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text(cbOption[i], options[i].name);
|
||||
if (settingsController.GetChimeOption() == options[i].chimesOption) {
|
||||
lv_checkbox_set_checked(cbOption[i], true);
|
||||
}
|
||||
cbOption[i]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[i], event_handler);
|
||||
SetRadioButtonStyle(cbOption[i]);
|
||||
}
|
||||
|
||||
optionsTotal++;
|
||||
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], " Every hour");
|
||||
cbOption[optionsTotal]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
|
||||
SetRadioButtonStyle(cbOption[optionsTotal]);
|
||||
if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours) {
|
||||
lv_checkbox_set_checked(cbOption[optionsTotal], true);
|
||||
}
|
||||
|
||||
optionsTotal++;
|
||||
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], " Every 30 mins");
|
||||
cbOption[optionsTotal]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
|
||||
SetRadioButtonStyle(cbOption[optionsTotal]);
|
||||
if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours) {
|
||||
lv_checkbox_set_checked(cbOption[optionsTotal], true);
|
||||
}
|
||||
|
||||
optionsTotal++;
|
||||
}
|
||||
|
||||
SettingChimes::~SettingChimes() {
|
||||
@@ -80,18 +61,10 @@ SettingChimes::~SettingChimes() {
|
||||
|
||||
void SettingChimes::UpdateSelected(lv_obj_t* object, lv_event_t event) {
|
||||
if (event == LV_EVENT_VALUE_CHANGED) {
|
||||
for (uint8_t i = 0; i < optionsTotal; i++) {
|
||||
for (uint8_t i = 0; i < options.size(); i++) {
|
||||
if (object == cbOption[i]) {
|
||||
lv_checkbox_set_checked(cbOption[i], true);
|
||||
if (i == 0) {
|
||||
settingsController.SetChimeOption(Controllers::Settings::ChimesOption::None);
|
||||
}
|
||||
if (i == 1) {
|
||||
settingsController.SetChimeOption(Controllers::Settings::ChimesOption::Hours);
|
||||
}
|
||||
if (i == 2) {
|
||||
settingsController.SetChimeOption(Controllers::Settings::ChimesOption::HalfHours);
|
||||
}
|
||||
settingsController.SetChimeOption(options[i].chimesOption);
|
||||
} else {
|
||||
lv_checkbox_set_checked(cbOption[i], false);
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <lvgl/lvgl.h>
|
||||
#include "components/settings/Settings.h"
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include <array>
|
||||
|
||||
namespace Pinetime {
|
||||
|
||||
@@ -18,9 +19,19 @@ namespace Pinetime {
|
||||
void UpdateSelected(lv_obj_t* object, lv_event_t event);
|
||||
|
||||
private:
|
||||
struct Option {
|
||||
Controllers::Settings::ChimesOption chimesOption;
|
||||
const char* name;
|
||||
};
|
||||
static constexpr std::array<Option, 3> options = {{
|
||||
{Controllers::Settings::ChimesOption::None, " Off"},
|
||||
{Controllers::Settings::ChimesOption::Hours, " Every hour"},
|
||||
{Controllers::Settings::ChimesOption::HalfHours, " Every 30 mins"}
|
||||
}};
|
||||
|
||||
std::array<lv_obj_t*, options.size()> cbOption;
|
||||
|
||||
Controllers::Settings& settingsController;
|
||||
uint8_t optionsTotal;
|
||||
lv_obj_t* cbOption[3];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr std::array<uint16_t, 4> SettingDisplay::options;
|
||||
constexpr std::array<uint16_t, 6> SettingDisplay::options;
|
||||
|
||||
SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
|
||||
: Screen(app), settingsController {settingsController} {
|
||||
@@ -30,7 +30,7 @@ SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime
|
||||
lv_obj_set_pos(container1, 10, 60);
|
||||
lv_obj_set_width(container1, LV_HOR_RES - 20);
|
||||
lv_obj_set_height(container1, LV_VER_RES - 50);
|
||||
lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
|
||||
lv_cont_set_layout(container1, LV_LAYOUT_PRETTY_TOP);
|
||||
|
||||
lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_static(title, "Display timeout");
|
||||
@@ -46,7 +46,7 @@ SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime
|
||||
char buffer[12];
|
||||
for (unsigned int i = 0; i < options.size(); i++) {
|
||||
cbOption[i] = lv_checkbox_create(container1, nullptr);
|
||||
sprintf(buffer, "%3d seconds", options[i] / 1000);
|
||||
sprintf(buffer, "%2ds", options[i] / 1000);
|
||||
lv_checkbox_set_text(cbOption[i], buffer);
|
||||
cbOption[i]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[i], event_handler);
|
||||
|
@@ -20,7 +20,7 @@ namespace Pinetime {
|
||||
void UpdateSelected(lv_obj_t* object, lv_event_t event);
|
||||
|
||||
private:
|
||||
static constexpr std::array<uint16_t, 4> options = {5000, 15000, 20000, 30000};
|
||||
static constexpr std::array<uint16_t, 6> options = {5000, 7000, 10000, 15000, 20000, 30000};
|
||||
|
||||
Controllers::Settings& settingsController;
|
||||
lv_obj_t* cbOption[options.size()];
|
||||
|
@@ -11,13 +11,36 @@ namespace {
|
||||
constexpr int16_t POS_X_DAY = -72;
|
||||
constexpr int16_t POS_X_MONTH = 0;
|
||||
constexpr int16_t POS_X_YEAR = 72;
|
||||
constexpr int16_t POS_Y_PLUS = -50;
|
||||
constexpr int16_t POS_Y_TEXT = -6;
|
||||
constexpr int16_t POS_Y_MINUS = 40;
|
||||
|
||||
void event_handler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* screen = static_cast<SettingSetDate*>(obj->user_data);
|
||||
screen->HandleButtonPress(obj, event);
|
||||
if (event == LV_EVENT_CLICKED) {
|
||||
screen->HandleButtonPress();
|
||||
}
|
||||
}
|
||||
|
||||
void ValueChangedHandler(void* userData) {
|
||||
auto* screen = static_cast<SettingSetDate*>(userData);
|
||||
screen->CheckDay();
|
||||
}
|
||||
|
||||
int MaximumDayOfMonth(uint8_t month, uint16_t year) {
|
||||
switch (month) {
|
||||
case 2: {
|
||||
if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0)) {
|
||||
return 29;
|
||||
}
|
||||
return 28;
|
||||
}
|
||||
case 4:
|
||||
case 6:
|
||||
case 9:
|
||||
case 11:
|
||||
return 30;
|
||||
default:
|
||||
return 31;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,164 +58,54 @@ SettingSetDate::SettingSetDate(Pinetime::Applications::DisplayApp* app, Pinetime
|
||||
lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);
|
||||
|
||||
dayValue = static_cast<int>(dateTimeController.Day());
|
||||
lblDay = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_fmt(lblDay, "%d", dayValue);
|
||||
lv_label_set_align(lblDay, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblDay, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_TEXT);
|
||||
lv_obj_set_auto_realign(lblDay, true);
|
||||
dayCounter.SetValueChangedEventCallback(this, ValueChangedHandler);
|
||||
dayCounter.Create();
|
||||
dayCounter.SetValue(dateTimeController.Day());
|
||||
lv_obj_align(dayCounter.GetObject(), nullptr, LV_ALIGN_CENTER, POS_X_DAY, POS_Y_TEXT);
|
||||
|
||||
monthValue = static_cast<int>(dateTimeController.Month());
|
||||
lblMonth = lv_label_create(lv_scr_act(), nullptr);
|
||||
UpdateMonthLabel();
|
||||
lv_label_set_align(lblMonth, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblMonth, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_TEXT);
|
||||
lv_obj_set_auto_realign(lblMonth, true);
|
||||
monthCounter.EnableMonthMode();
|
||||
monthCounter.SetValueChangedEventCallback(this, ValueChangedHandler);
|
||||
monthCounter.Create();
|
||||
monthCounter.SetValue(static_cast<int>(dateTimeController.Month()));
|
||||
lv_obj_align(monthCounter.GetObject(), nullptr, LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_TEXT);
|
||||
|
||||
yearValue = static_cast<int>(dateTimeController.Year());
|
||||
if (yearValue < 2021)
|
||||
yearValue = 2021;
|
||||
lblYear = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_fmt(lblYear, "%d", yearValue);
|
||||
lv_label_set_align(lblYear, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblYear, lv_scr_act(), LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_TEXT);
|
||||
lv_obj_set_auto_realign(lblYear, true);
|
||||
|
||||
btnDayPlus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnDayPlus->user_data = this;
|
||||
lv_obj_set_size(btnDayPlus, 50, 40);
|
||||
lv_obj_align(btnDayPlus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_PLUS);
|
||||
lv_obj_set_style_local_value_str(btnDayPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+");
|
||||
lv_obj_set_event_cb(btnDayPlus, event_handler);
|
||||
|
||||
btnDayMinus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnDayMinus->user_data = this;
|
||||
lv_obj_set_size(btnDayMinus, 50, 40);
|
||||
lv_obj_align(btnDayMinus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_MINUS);
|
||||
lv_obj_set_style_local_value_str(btnDayMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-");
|
||||
lv_obj_set_event_cb(btnDayMinus, event_handler);
|
||||
|
||||
btnMonthPlus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnMonthPlus->user_data = this;
|
||||
lv_obj_set_size(btnMonthPlus, 50, 40);
|
||||
lv_obj_align(btnMonthPlus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_PLUS);
|
||||
lv_obj_set_style_local_value_str(btnMonthPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+");
|
||||
lv_obj_set_event_cb(btnMonthPlus, event_handler);
|
||||
|
||||
btnMonthMinus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnMonthMinus->user_data = this;
|
||||
lv_obj_set_size(btnMonthMinus, 50, 40);
|
||||
lv_obj_align(btnMonthMinus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MONTH, POS_Y_MINUS);
|
||||
lv_obj_set_style_local_value_str(btnMonthMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-");
|
||||
lv_obj_set_event_cb(btnMonthMinus, event_handler);
|
||||
|
||||
btnYearPlus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnYearPlus->user_data = this;
|
||||
lv_obj_set_size(btnYearPlus, 50, 40);
|
||||
lv_obj_align(btnYearPlus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_PLUS);
|
||||
lv_obj_set_style_local_value_str(btnYearPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+");
|
||||
lv_obj_set_event_cb(btnYearPlus, event_handler);
|
||||
|
||||
btnYearMinus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnYearMinus->user_data = this;
|
||||
lv_obj_set_size(btnYearMinus, 50, 40);
|
||||
lv_obj_align(btnYearMinus, lv_scr_act(), LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_MINUS);
|
||||
lv_obj_set_style_local_value_str(btnYearMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-");
|
||||
lv_obj_set_event_cb(btnYearMinus, event_handler);
|
||||
yearCounter.SetValueChangedEventCallback(this, ValueChangedHandler);
|
||||
yearCounter.Create();
|
||||
yearCounter.SetValue(dateTimeController.Year());
|
||||
lv_obj_align(yearCounter.GetObject(), nullptr, LV_ALIGN_CENTER, POS_X_YEAR, POS_Y_TEXT);
|
||||
|
||||
btnSetTime = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnSetTime->user_data = this;
|
||||
lv_obj_set_size(btnSetTime, 120, 48);
|
||||
lv_obj_align(btnSetTime, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
lv_obj_set_style_local_bg_color(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x38, 0x38, 0x38));
|
||||
lv_obj_set_style_local_value_str(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Set");
|
||||
lv_obj_set_event_cb(btnSetTime, event_handler);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED);
|
||||
}
|
||||
|
||||
SettingSetDate::~SettingSetDate() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
void SettingSetDate::HandleButtonPress(lv_obj_t* object, lv_event_t event) {
|
||||
if (event != LV_EVENT_CLICKED)
|
||||
return;
|
||||
|
||||
if (object == btnDayPlus) {
|
||||
dayValue++;
|
||||
if (dayValue > MaximumDayOfMonth())
|
||||
dayValue = 1;
|
||||
lv_label_set_text_fmt(lblDay, "%d", dayValue);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
} else if (object == btnDayMinus) {
|
||||
dayValue--;
|
||||
if (dayValue < 1)
|
||||
dayValue = MaximumDayOfMonth();
|
||||
lv_label_set_text_fmt(lblDay, "%d", dayValue);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
} else if (object == btnMonthPlus) {
|
||||
monthValue++;
|
||||
if (monthValue > 12)
|
||||
monthValue = 1;
|
||||
UpdateMonthLabel();
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
CheckDay();
|
||||
} else if (object == btnMonthMinus) {
|
||||
monthValue--;
|
||||
if (monthValue < 1)
|
||||
monthValue = 12;
|
||||
UpdateMonthLabel();
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
CheckDay();
|
||||
} else if (object == btnYearPlus) {
|
||||
yearValue++;
|
||||
lv_label_set_text_fmt(lblYear, "%d", yearValue);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
CheckDay();
|
||||
} else if (object == btnYearMinus) {
|
||||
yearValue--;
|
||||
lv_label_set_text_fmt(lblYear, "%d", yearValue);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
CheckDay();
|
||||
} else if (object == btnSetTime) {
|
||||
NRF_LOG_INFO("Setting date (manually) to %04d-%02d-%02d", yearValue, monthValue, dayValue);
|
||||
dateTimeController.SetTime(static_cast<uint16_t>(yearValue),
|
||||
static_cast<uint8_t>(monthValue),
|
||||
static_cast<uint8_t>(dayValue),
|
||||
0,
|
||||
dateTimeController.Hours(),
|
||||
dateTimeController.Minutes(),
|
||||
dateTimeController.Seconds(),
|
||||
nrf_rtc_counter_get(portNRF_RTC_REG));
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
int SettingSetDate::MaximumDayOfMonth() const {
|
||||
switch (monthValue) {
|
||||
case 2:
|
||||
if ((((yearValue % 4) == 0) && ((yearValue % 100) != 0)) || ((yearValue % 400) == 0))
|
||||
return 29;
|
||||
return 28;
|
||||
case 4:
|
||||
case 6:
|
||||
case 9:
|
||||
case 11:
|
||||
return 30;
|
||||
default:
|
||||
return 31;
|
||||
}
|
||||
void SettingSetDate::HandleButtonPress() {
|
||||
const uint16_t yearValue = yearCounter.GetValue();
|
||||
const uint8_t monthValue = monthCounter.GetValue();
|
||||
const uint8_t dayValue = dayCounter.GetValue();
|
||||
NRF_LOG_INFO("Setting date (manually) to %04d-%02d-%02d", yearValue, monthValue, dayValue);
|
||||
dateTimeController.SetTime(yearValue,
|
||||
monthValue,
|
||||
dayValue,
|
||||
0,
|
||||
dateTimeController.Hours(),
|
||||
dateTimeController.Minutes(),
|
||||
dateTimeController.Seconds(),
|
||||
nrf_rtc_counter_get(portNRF_RTC_REG));
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED);
|
||||
}
|
||||
|
||||
void SettingSetDate::CheckDay() {
|
||||
int maxDay = MaximumDayOfMonth();
|
||||
if (dayValue > maxDay) {
|
||||
dayValue = maxDay;
|
||||
lv_label_set_text_fmt(lblDay, "%d", dayValue);
|
||||
lv_obj_align(lblDay, lv_scr_act(), LV_ALIGN_CENTER, POS_X_DAY, POS_Y_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingSetDate::UpdateMonthLabel() {
|
||||
lv_label_set_text_static(
|
||||
lblMonth,
|
||||
Pinetime::Controllers::DateTime::MonthShortToStringLow(static_cast<Pinetime::Controllers::DateTime::Months>(monthValue)));
|
||||
const int maxDay = MaximumDayOfMonth(monthCounter.GetValue(), yearCounter.GetValue());
|
||||
dayCounter.SetMax(maxDay);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <lvgl/lvgl.h>
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/widgets/Counter.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
@@ -13,28 +14,17 @@ namespace Pinetime {
|
||||
SettingSetDate(DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController);
|
||||
~SettingSetDate() override;
|
||||
|
||||
void HandleButtonPress(lv_obj_t* object, lv_event_t event);
|
||||
void HandleButtonPress();
|
||||
void CheckDay();
|
||||
|
||||
private:
|
||||
Controllers::DateTime& dateTimeController;
|
||||
|
||||
int dayValue;
|
||||
int monthValue;
|
||||
int yearValue;
|
||||
lv_obj_t* lblDay;
|
||||
lv_obj_t* lblMonth;
|
||||
lv_obj_t* lblYear;
|
||||
lv_obj_t* btnDayPlus;
|
||||
lv_obj_t* btnDayMinus;
|
||||
lv_obj_t* btnMonthPlus;
|
||||
lv_obj_t* btnMonthMinus;
|
||||
lv_obj_t* btnYearPlus;
|
||||
lv_obj_t* btnYearMinus;
|
||||
lv_obj_t* btnSetTime;
|
||||
|
||||
int MaximumDayOfMonth() const;
|
||||
void CheckDay();
|
||||
void UpdateMonthLabel();
|
||||
Widgets::Counter dayCounter = Widgets::Counter(1, 31, jetbrains_mono_bold_20);
|
||||
Widgets::Counter monthCounter = Widgets::Counter(1, 12, jetbrains_mono_bold_20);
|
||||
Widgets::Counter yearCounter = Widgets::Counter(1970, 9999, jetbrains_mono_bold_20);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -5,21 +5,22 @@
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "components/settings/Settings.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
namespace {
|
||||
constexpr int16_t POS_X_HOURS = -72;
|
||||
constexpr int16_t POS_X_MINUTES = 0;
|
||||
constexpr int16_t POS_X_SECONDS = 72;
|
||||
constexpr int16_t POS_Y_PLUS = -50;
|
||||
constexpr int16_t POS_Y_TEXT = -6;
|
||||
constexpr int16_t POS_Y_MINUS = 40;
|
||||
constexpr int16_t OFS_Y_COLON = -2;
|
||||
constexpr int16_t POS_Y_TEXT = -7;
|
||||
|
||||
void event_handler(lv_obj_t* obj, lv_event_t event) {
|
||||
void SetTimeEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* screen = static_cast<SettingSetTime*>(obj->user_data);
|
||||
screen->HandleButtonPress(obj, event);
|
||||
if (event == LV_EVENT_CLICKED) {
|
||||
screen->SetTime();
|
||||
}
|
||||
}
|
||||
void ValueChangedHandler(void* userData) {
|
||||
auto* screen = static_cast<SettingSetTime*>(userData);
|
||||
screen->UpdateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +28,7 @@ SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp* app,
|
||||
Pinetime::Controllers::DateTime& dateTimeController,
|
||||
Pinetime::Controllers::Settings& settingsController)
|
||||
: Screen(app), dateTimeController {dateTimeController}, settingsController {settingsController} {
|
||||
|
||||
lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_static(title, "Set current time");
|
||||
lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
|
||||
@@ -34,160 +36,72 @@ SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp* app,
|
||||
|
||||
lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
|
||||
|
||||
lv_label_set_text_static(icon, Symbols::clock);
|
||||
lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);
|
||||
|
||||
hoursValue = static_cast<int>(dateTimeController.Hours());
|
||||
lblHours = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblHours, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_fmt(lblHours, "%02d", hoursValue);
|
||||
lv_label_set_align(lblHours, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblHours, lv_scr_act(), LV_ALIGN_CENTER, POS_X_HOURS, POS_Y_TEXT);
|
||||
lv_obj_set_auto_realign(lblHours, true);
|
||||
lv_obj_t* staticLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(staticLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_static(staticLabel, "00:00:00");
|
||||
lv_obj_align(staticLabel, lv_scr_act(), LV_ALIGN_CENTER, 0, POS_Y_TEXT);
|
||||
|
||||
lv_obj_t* lblColon1 = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblColon1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_static(lblColon1, ":");
|
||||
lv_label_set_align(lblColon1, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblColon1, lv_scr_act(), LV_ALIGN_CENTER, (POS_X_HOURS + POS_X_MINUTES) / 2, POS_Y_TEXT + OFS_Y_COLON);
|
||||
hourCounter.Create();
|
||||
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
|
||||
hourCounter.EnableTwelveHourMode();
|
||||
}
|
||||
hourCounter.SetValue(dateTimeController.Hours());
|
||||
lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_CENTER, -75, POS_Y_TEXT);
|
||||
hourCounter.SetValueChangedEventCallback(this, ValueChangedHandler);
|
||||
|
||||
minutesValue = static_cast<int>(dateTimeController.Minutes());
|
||||
lblMinutes = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblMinutes, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_fmt(lblMinutes, "%02d", minutesValue);
|
||||
lv_label_set_align(lblMinutes, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblMinutes, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MINUTES, POS_Y_TEXT);
|
||||
lv_obj_set_auto_realign(lblMinutes, true);
|
||||
|
||||
lv_obj_t* lblColon2 = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblColon2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_static(lblColon2, ":");
|
||||
lv_label_set_align(lblColon2, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblColon2, lv_scr_act(), LV_ALIGN_CENTER, (POS_X_MINUTES + POS_X_SECONDS) / 2, POS_Y_TEXT + OFS_Y_COLON);
|
||||
|
||||
lv_obj_t* lblSeconds = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblSeconds, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||
lv_label_set_text_static(lblSeconds, "00");
|
||||
lv_label_set_align(lblSeconds, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblSeconds, lv_scr_act(), LV_ALIGN_CENTER, POS_X_SECONDS, POS_Y_TEXT);
|
||||
minuteCounter.Create();
|
||||
minuteCounter.SetValue(dateTimeController.Minutes());
|
||||
lv_obj_align(minuteCounter.GetObject(), nullptr, LV_ALIGN_CENTER, 0, POS_Y_TEXT);
|
||||
minuteCounter.SetValueChangedEventCallback(this, ValueChangedHandler);
|
||||
|
||||
lblampm = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(lblampm, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20);
|
||||
lv_label_set_text_static(lblampm, " ");
|
||||
lv_label_set_align(lblampm, LV_LABEL_ALIGN_CENTER);
|
||||
lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, POS_X_SECONDS, POS_Y_PLUS);
|
||||
|
||||
btnHoursPlus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnHoursPlus->user_data = this;
|
||||
lv_obj_set_size(btnHoursPlus, 50, 40);
|
||||
lv_obj_align(btnHoursPlus, lv_scr_act(), LV_ALIGN_CENTER, -72, -50);
|
||||
lv_obj_set_style_local_value_str(btnHoursPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+");
|
||||
lv_obj_set_event_cb(btnHoursPlus, event_handler);
|
||||
|
||||
btnHoursMinus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnHoursMinus->user_data = this;
|
||||
lv_obj_set_size(btnHoursMinus, 50, 40);
|
||||
lv_obj_align(btnHoursMinus, lv_scr_act(), LV_ALIGN_CENTER, -72, 40);
|
||||
lv_obj_set_style_local_value_str(btnHoursMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-");
|
||||
lv_obj_set_event_cb(btnHoursMinus, event_handler);
|
||||
|
||||
btnMinutesPlus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnMinutesPlus->user_data = this;
|
||||
lv_obj_set_size(btnMinutesPlus, 50, 40);
|
||||
lv_obj_align(btnMinutesPlus, lv_scr_act(), LV_ALIGN_CENTER, 0, -50);
|
||||
lv_obj_set_style_local_value_str(btnMinutesPlus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "+");
|
||||
lv_obj_set_event_cb(btnMinutesPlus, event_handler);
|
||||
|
||||
btnMinutesMinus = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnMinutesMinus->user_data = this;
|
||||
lv_obj_set_size(btnMinutesMinus, 50, 40);
|
||||
lv_obj_align(btnMinutesMinus, lv_scr_act(), LV_ALIGN_CENTER, 0, 40);
|
||||
lv_obj_set_style_local_value_str(btnMinutesMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-");
|
||||
lv_obj_set_event_cb(btnMinutesMinus, event_handler);
|
||||
lv_obj_align(lblampm, lv_scr_act(), LV_ALIGN_CENTER, 75, -50);
|
||||
|
||||
btnSetTime = lv_btn_create(lv_scr_act(), nullptr);
|
||||
btnSetTime->user_data = this;
|
||||
lv_obj_set_size(btnSetTime, 120, 48);
|
||||
lv_obj_set_size(btnSetTime, 120, 50);
|
||||
lv_obj_align(btnSetTime, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
lv_obj_set_style_local_value_str(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "Set");
|
||||
lv_obj_set_event_cb(btnSetTime, event_handler);
|
||||
lv_obj_set_style_local_bg_color(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
lv_obj_set_style_local_value_color(btnSetTime, LV_BTN_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_GRAY);
|
||||
lv_obj_set_event_cb(btnSetTime, SetTimeEventHandler);
|
||||
|
||||
SetHourLabels();
|
||||
UpdateScreen();
|
||||
lv_obj_set_state(btnSetTime, LV_STATE_DISABLED);
|
||||
}
|
||||
|
||||
SettingSetTime::~SettingSetTime() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
void SettingSetTime::SetHourLabels() {
|
||||
void SettingSetTime::UpdateScreen() {
|
||||
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
|
||||
switch (hoursValue) {
|
||||
case 0:
|
||||
lv_label_set_text_static(lblHours, "12");
|
||||
lv_label_set_text_static(lblampm, "AM");
|
||||
break;
|
||||
case 1 ... 11:
|
||||
lv_label_set_text_fmt(lblHours, "%02d", hoursValue);
|
||||
lv_label_set_text_static(lblampm, "AM");
|
||||
break;
|
||||
case 12:
|
||||
lv_label_set_text_static(lblHours, "12");
|
||||
lv_label_set_text_static(lblampm, "PM");
|
||||
break;
|
||||
case 13 ... 23:
|
||||
lv_label_set_text_fmt(lblHours, "%02d", hoursValue - 12);
|
||||
lv_label_set_text_static(lblampm, "PM");
|
||||
break;
|
||||
if (hourCounter.GetValue() >= 12) {
|
||||
lv_label_set_text_static(lblampm, "PM");
|
||||
} else {
|
||||
lv_label_set_text_static(lblampm, "AM");
|
||||
}
|
||||
} else {
|
||||
lv_label_set_text_fmt(lblHours, "%02d", hoursValue);
|
||||
}
|
||||
lv_obj_set_state(btnSetTime, LV_STATE_DEFAULT);
|
||||
}
|
||||
|
||||
void SettingSetTime::HandleButtonPress(lv_obj_t* object, lv_event_t event) {
|
||||
if (event != LV_EVENT_CLICKED)
|
||||
return;
|
||||
|
||||
if (object == btnHoursPlus) {
|
||||
hoursValue++;
|
||||
if (hoursValue > 23) {
|
||||
hoursValue = 0;
|
||||
}
|
||||
SetHourLabels();
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
} else if (object == btnHoursMinus) {
|
||||
hoursValue--;
|
||||
if (hoursValue < 0) {
|
||||
hoursValue = 23;
|
||||
}
|
||||
SetHourLabels();
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
} else if (object == btnMinutesPlus) {
|
||||
minutesValue++;
|
||||
if (minutesValue > 59) {
|
||||
minutesValue = 0;
|
||||
}
|
||||
lv_label_set_text_fmt(lblMinutes, "%02d", minutesValue);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
} else if (object == btnMinutesMinus) {
|
||||
minutesValue--;
|
||||
if (minutesValue < 0) {
|
||||
minutesValue = 59;
|
||||
}
|
||||
lv_label_set_text_fmt(lblMinutes, "%02d", minutesValue);
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_RELEASED);
|
||||
} else if (object == btnSetTime) {
|
||||
NRF_LOG_INFO("Setting time (manually) to %02d:%02d:00", hoursValue, minutesValue);
|
||||
dateTimeController.SetTime(dateTimeController.Year(),
|
||||
static_cast<uint8_t>(dateTimeController.Month()),
|
||||
dateTimeController.Day(),
|
||||
static_cast<uint8_t>(dateTimeController.DayOfWeek()),
|
||||
static_cast<uint8_t>(hoursValue),
|
||||
static_cast<uint8_t>(minutesValue),
|
||||
0,
|
||||
nrf_rtc_counter_get(portNRF_RTC_REG));
|
||||
lv_btn_set_state(btnSetTime, LV_BTN_STATE_DISABLED);
|
||||
}
|
||||
void SettingSetTime::SetTime() {
|
||||
const int hoursValue = hourCounter.GetValue();
|
||||
const int minutesValue = minuteCounter.GetValue();
|
||||
NRF_LOG_INFO("Setting time (manually) to %02d:%02d:00", hoursValue, minutesValue);
|
||||
dateTimeController.SetTime(dateTimeController.Year(),
|
||||
static_cast<uint8_t>(dateTimeController.Month()),
|
||||
dateTimeController.Day(),
|
||||
static_cast<uint8_t>(dateTimeController.DayOfWeek()),
|
||||
static_cast<uint8_t>(hoursValue),
|
||||
static_cast<uint8_t>(minutesValue),
|
||||
0,
|
||||
nrf_rtc_counter_get(portNRF_RTC_REG));
|
||||
lv_obj_set_state(btnSetTime, LV_STATE_DISABLED);
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <lvgl/lvgl.h>
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "components/settings/Settings.h"
|
||||
#include "displayapp/widgets/Counter.h"
|
||||
#include "displayapp/screens/Screen.h"
|
||||
|
||||
namespace Pinetime {
|
||||
@@ -16,24 +17,17 @@ namespace Pinetime {
|
||||
Pinetime::Controllers::Settings& settingsController);
|
||||
~SettingSetTime() override;
|
||||
|
||||
void HandleButtonPress(lv_obj_t* object, lv_event_t event);
|
||||
void SetTime();
|
||||
void UpdateScreen();
|
||||
|
||||
private:
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::Settings& settingsController;
|
||||
|
||||
void SetHourLabels();
|
||||
|
||||
int hoursValue;
|
||||
int minutesValue;
|
||||
lv_obj_t* lblHours;
|
||||
lv_obj_t* lblMinutes;
|
||||
lv_obj_t* lblampm;
|
||||
lv_obj_t* btnHoursPlus;
|
||||
lv_obj_t* btnHoursMinus;
|
||||
lv_obj_t* btnMinutesPlus;
|
||||
lv_obj_t* btnMinutesMinus;
|
||||
lv_obj_t* btnSetTime;
|
||||
Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_42);
|
||||
Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_42);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
@@ -123,8 +124,7 @@ void SettingShakeThreshold::UpdateSelected(lv_obj_t* object, lv_event_t event) {
|
||||
vCalTime = xTaskGetTickCount();
|
||||
lv_label_set_text_static(calLabel, "Ready!");
|
||||
lv_obj_set_click(positionArc, false);
|
||||
lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_MAKE(0x0, 0xb0, 0x0));
|
||||
lv_obj_set_style_local_bg_color(calButton, LV_BTN_PART_MAIN, LV_STATE_CHECKED, Colors::highlight);
|
||||
} else if (lv_btn_get_state(calButton) == LV_BTN_STATE_RELEASED) {
|
||||
calibrating = 0;
|
||||
lv_obj_set_click(positionArc, true);
|
||||
|
@@ -17,7 +17,6 @@ SettingSteps::SettingSteps(Pinetime::Applications::DisplayApp* app, Pinetime::Co
|
||||
|
||||
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
|
||||
|
||||
// lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111));
|
||||
lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
|
||||
lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
|
||||
lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
|
||||
|
@@ -20,7 +20,7 @@ namespace Pinetime {
|
||||
void UpdateSelected(lv_obj_t* object, lv_event_t event);
|
||||
|
||||
private:
|
||||
static constexpr std::array<const char*, 2> options = {" 12-hour", " 24-hour"};
|
||||
static constexpr std::array<const char*, 2> options = {"12-hour", "24-hour"};
|
||||
Controllers::Settings& settingsController;
|
||||
lv_obj_t* cbOption[options.size()];
|
||||
};
|
||||
|
@@ -42,7 +42,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::
|
||||
|
||||
optionsTotal = 0;
|
||||
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], " Single Tap");
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], "Single Tap");
|
||||
cbOption[optionsTotal]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
|
||||
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)) {
|
||||
@@ -50,7 +50,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::
|
||||
}
|
||||
optionsTotal++;
|
||||
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], " Double Tap");
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], "Double Tap");
|
||||
cbOption[optionsTotal]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
|
||||
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
|
||||
@@ -58,7 +58,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::
|
||||
}
|
||||
optionsTotal++;
|
||||
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], " Raise Wrist");
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], "Raise Wrist");
|
||||
cbOption[optionsTotal]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
|
||||
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) {
|
||||
@@ -66,7 +66,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::
|
||||
}
|
||||
optionsTotal++;
|
||||
cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr);
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], " Shake Wake");
|
||||
lv_checkbox_set_text_static(cbOption[optionsTotal], "Shake Wake");
|
||||
cbOption[optionsTotal]->user_data = this;
|
||||
lv_obj_set_event_cb(cbOption[optionsTotal], event_handler);
|
||||
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)) {
|
||||
|
@@ -38,7 +38,7 @@ bool SettingWatchFace::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> SettingWatchFace::CreateScreen1() {
|
||||
std::array<const char*, 4> watchfaces {" Digital face", " Analog face", " PineTimeStyle", " Terminal"};
|
||||
std::array<const char*, 4> watchfaces {"Digital face", "Analog face", "PineTimeStyle", "Terminal"};
|
||||
return std::make_unique<Screens::CheckboxList>(0, 2, app, settingsController, title,
|
||||
symbol, &Controllers::Settings::SetClockFace,
|
||||
&Controllers::Settings::GetClockFace,
|
||||
@@ -46,7 +46,7 @@ std::unique_ptr<Screen> SettingWatchFace::CreateScreen1() {
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> SettingWatchFace::CreateScreen2() {
|
||||
std::array<const char*, 4> watchfaces {" Infineat face", "", "", ""};
|
||||
std::array<const char*, 4> watchfaces {"Infineat face", "", "", ""};
|
||||
return std::make_unique<Screens::CheckboxList>(1, 2, app, settingsController, title,
|
||||
symbol, &Controllers::Settings::SetClockFace,
|
||||
&Controllers::Settings::GetClockFace,
|
||||
|
@@ -1,33 +1,27 @@
|
||||
#include "displayapp/screens/settings/Settings.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <array>
|
||||
#include "displayapp/screens/List.h"
|
||||
#include <functional>
|
||||
#include "displayapp/Apps.h"
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
constexpr std::array<List::Applications, Settings::entries.size()> Settings::entries;
|
||||
|
||||
auto Settings::CreateScreenList() const {
|
||||
std::array<std::function<std::unique_ptr<Screen>()>, nScreens> screens;
|
||||
for (size_t i = 0; i < screens.size(); i++) {
|
||||
screens[i] = [this, i]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen(i);
|
||||
};
|
||||
}
|
||||
return screens;
|
||||
}
|
||||
|
||||
Settings::Settings(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
|
||||
: Screen(app),
|
||||
settingsController {settingsController},
|
||||
screens {app,
|
||||
settingsController.GetSettingsMenu(),
|
||||
{
|
||||
[this]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen1();
|
||||
},
|
||||
[this]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen2();
|
||||
},
|
||||
[this]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen3();
|
||||
},
|
||||
[this]() -> std::unique_ptr<Screen> {
|
||||
return CreateScreen4();
|
||||
},
|
||||
},
|
||||
Screens::ScreenListModes::UpDown} {
|
||||
screens {app, settingsController.GetSettingsMenu(), CreateScreenList(), Screens::ScreenListModes::UpDown} {
|
||||
}
|
||||
|
||||
Settings::~Settings() {
|
||||
@@ -38,48 +32,11 @@ bool Settings::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
return screens.OnTouchEvent(event);
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> Settings::CreateScreen1() {
|
||||
std::array<Screens::List::Applications, 4> applications {{
|
||||
{Symbols::sun, "Display", Apps::SettingDisplay},
|
||||
{Symbols::eye, "Wake Up", Apps::SettingWakeUp},
|
||||
{Symbols::clock, "Time format", Apps::SettingTimeFormat},
|
||||
{Symbols::home, "Watch face", Apps::SettingWatchFace},
|
||||
}};
|
||||
std::unique_ptr<Screen> Settings::CreateScreen(unsigned int screenNum) const {
|
||||
std::array<List::Applications, entriesPerScreen> screens;
|
||||
for (int i = 0; i < entriesPerScreen; i++) {
|
||||
screens[i] = entries[screenNum * entriesPerScreen + i];
|
||||
}
|
||||
|
||||
return std::make_unique<Screens::List>(0, 4, app, settingsController, applications);
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> Settings::CreateScreen2() {
|
||||
std::array<Screens::List::Applications, 4> applications {{
|
||||
{Symbols::shoe, "Steps", Apps::SettingSteps},
|
||||
{Symbols::clock, "Set date", Apps::SettingSetDate},
|
||||
{Symbols::clock, "Set time", Apps::SettingSetTime},
|
||||
{Symbols::batteryHalf, "Battery", Apps::BatteryInfo},
|
||||
}};
|
||||
|
||||
return std::make_unique<Screens::List>(1, 4, app, settingsController, applications);
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> Settings::CreateScreen3() {
|
||||
|
||||
std::array<Screens::List::Applications, 4> applications {{
|
||||
{Symbols::clock, "Chimes", Apps::SettingChimes},
|
||||
{Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold},
|
||||
{Symbols::check, "Firmware", Apps::FirmwareValidation},
|
||||
{Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth},
|
||||
}};
|
||||
|
||||
return std::make_unique<Screens::List>(2, 4, app, settingsController, applications);
|
||||
}
|
||||
|
||||
std::unique_ptr<Screen> Settings::CreateScreen4() {
|
||||
|
||||
std::array<Screens::List::Applications, 4> applications {{
|
||||
{Symbols::list, "About", Apps::SysInfo},
|
||||
{Symbols::none, "None", Apps::None},
|
||||
{Symbols::none, "None", Apps::None},
|
||||
{Symbols::none, "None", Apps::None},
|
||||
}};
|
||||
|
||||
return std::make_unique<Screens::List>(3, 4, app, settingsController, applications);
|
||||
return std::make_unique<Screens::List>(screenNum, nScreens, app, settingsController, screens);
|
||||
}
|
||||
|
@@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "displayapp/screens/ScreenList.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "displayapp/screens/List.h"
|
||||
|
||||
namespace Pinetime {
|
||||
|
||||
@@ -17,14 +20,38 @@ namespace Pinetime {
|
||||
bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override;
|
||||
|
||||
private:
|
||||
auto CreateScreenList() const;
|
||||
std::unique_ptr<Screen> CreateScreen(unsigned int screenNum) const;
|
||||
|
||||
Controllers::Settings& settingsController;
|
||||
|
||||
ScreenList<4> screens;
|
||||
static constexpr int entriesPerScreen = 4;
|
||||
|
||||
std::unique_ptr<Screen> CreateScreen1();
|
||||
std::unique_ptr<Screen> CreateScreen2();
|
||||
std::unique_ptr<Screen> CreateScreen3();
|
||||
std::unique_ptr<Screen> CreateScreen4();
|
||||
// Increment this when more space is needed
|
||||
static constexpr int nScreens = 4;
|
||||
|
||||
static constexpr std::array<List::Applications, entriesPerScreen * nScreens> entries {{
|
||||
{Symbols::sun, "Display", Apps::SettingDisplay},
|
||||
{Symbols::eye, "Wake Up", Apps::SettingWakeUp},
|
||||
{Symbols::clock, "Time format", Apps::SettingTimeFormat},
|
||||
{Symbols::home, "Watch face", Apps::SettingWatchFace},
|
||||
|
||||
{Symbols::shoe, "Steps", Apps::SettingSteps},
|
||||
{Symbols::clock, "Set date", Apps::SettingSetDate},
|
||||
{Symbols::clock, "Set time", Apps::SettingSetTime},
|
||||
{Symbols::batteryHalf, "Battery", Apps::BatteryInfo},
|
||||
|
||||
{Symbols::clock, "Chimes", Apps::SettingChimes},
|
||||
{Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold},
|
||||
{Symbols::check, "Firmware", Apps::FirmwareValidation},
|
||||
{Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth},
|
||||
|
||||
{Symbols::list, "About", Apps::SysInfo},
|
||||
{Symbols::none, "None", Apps::None},
|
||||
{Symbols::none, "None", Apps::None},
|
||||
{Symbols::none, "None", Apps::None},
|
||||
}};
|
||||
ScreenList<nScreens> screens;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,6 @@
|
||||
#include "displayapp/widgets/Counter.h"
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Widgets;
|
||||
|
||||
@@ -6,35 +8,51 @@ namespace {
|
||||
void upBtnEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* widget = static_cast<Counter*>(obj->user_data);
|
||||
if (event == LV_EVENT_SHORT_CLICKED || event == LV_EVENT_LONG_PRESSED_REPEAT) {
|
||||
widget->Increment();
|
||||
widget->UpBtnPressed();
|
||||
}
|
||||
}
|
||||
|
||||
void downBtnEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* widget = static_cast<Counter*>(obj->user_data);
|
||||
if (event == LV_EVENT_SHORT_CLICKED || event == LV_EVENT_LONG_PRESSED_REPEAT) {
|
||||
widget->Decrement();
|
||||
widget->DownBtnPressed();
|
||||
}
|
||||
}
|
||||
constexpr int digitCount(int number) {
|
||||
int digitCount = 0;
|
||||
while (number > 0) {
|
||||
digitCount++;
|
||||
number /= 10;
|
||||
}
|
||||
return digitCount;
|
||||
}
|
||||
}
|
||||
|
||||
Counter::Counter(int min, int max) : min {min}, max {max} {
|
||||
Counter::Counter(int min, int max, lv_font_t& font) : min {min}, max {max}, value {min}, font {font}, leadingZeroCount {digitCount(max)} {
|
||||
}
|
||||
|
||||
void Counter::Increment() {
|
||||
void Counter::UpBtnPressed() {
|
||||
value++;
|
||||
if (value > max) {
|
||||
value = min;
|
||||
}
|
||||
UpdateLabel();
|
||||
|
||||
if (ValueChangedHandler != nullptr) {
|
||||
ValueChangedHandler(userData);
|
||||
}
|
||||
};
|
||||
|
||||
void Counter::Decrement() {
|
||||
void Counter::DownBtnPressed() {
|
||||
value--;
|
||||
if (value < min) {
|
||||
value = max;
|
||||
}
|
||||
UpdateLabel();
|
||||
|
||||
if (ValueChangedHandler != nullptr) {
|
||||
ValueChangedHandler(userData);
|
||||
}
|
||||
};
|
||||
|
||||
void Counter::SetValue(int newValue) {
|
||||
@@ -58,23 +76,64 @@ void Counter::ShowControls() {
|
||||
}
|
||||
|
||||
void Counter::UpdateLabel() {
|
||||
lv_label_set_text_fmt(number, "%.2i", value);
|
||||
if (twelveHourMode) {
|
||||
if (value == 0) {
|
||||
lv_label_set_text_static(number, "12");
|
||||
} else if (value <= 12) {
|
||||
lv_label_set_text_fmt(number, "%.*i", leadingZeroCount, value);
|
||||
} else {
|
||||
lv_label_set_text_fmt(number, "%.*i", leadingZeroCount, value - 12);
|
||||
}
|
||||
} else if (monthMode) {
|
||||
lv_label_set_text(number, Controllers::DateTime::MonthShortToStringLow(static_cast<Controllers::DateTime::Months>(value)));
|
||||
} else {
|
||||
lv_label_set_text_fmt(number, "%.*i", leadingZeroCount, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Value is kept between 0 and 23, but the displayed value is converted to 12-hour.
|
||||
// Make sure to set the max and min values to 0 and 23. Otherwise behaviour is undefined
|
||||
void Counter::EnableTwelveHourMode() {
|
||||
twelveHourMode = true;
|
||||
}
|
||||
|
||||
// Value is kept between 1 and 12, but the displayed value is the corresponding month
|
||||
// Make sure to set the max and min values to 1 and 12. Otherwise behaviour is undefined
|
||||
void Counter::EnableMonthMode() {
|
||||
monthMode = true;
|
||||
}
|
||||
|
||||
// Counter cannot be resized after creation,
|
||||
// so the newMax value must have the same number of digits as the old one
|
||||
void Counter::SetMax(int newMax) {
|
||||
max = newMax;
|
||||
if (value > max) {
|
||||
value = max;
|
||||
UpdateLabel();
|
||||
}
|
||||
}
|
||||
|
||||
void Counter::SetValueChangedEventCallback(void* userData, void (*handler)(void* userData)) {
|
||||
this->userData = userData;
|
||||
this->ValueChangedHandler = handler;
|
||||
}
|
||||
|
||||
void Counter::Create() {
|
||||
constexpr lv_color_t bgColor = LV_COLOR_MAKE(0x38, 0x38, 0x38);
|
||||
|
||||
counterContainer = lv_obj_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_bg_color(counterContainer, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor);
|
||||
lv_obj_set_style_local_bg_color(counterContainer, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
|
||||
number = lv_label_create(counterContainer, nullptr);
|
||||
lv_obj_set_style_local_text_font(number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
||||
lv_obj_set_style_local_text_font(number, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &font);
|
||||
lv_obj_align(number, nullptr, LV_ALIGN_CENTER, 0, 0);
|
||||
lv_obj_set_auto_realign(number, true);
|
||||
lv_label_set_text_static(number, "00");
|
||||
if (monthMode) {
|
||||
lv_label_set_text_static(number, "Jan");
|
||||
} else {
|
||||
lv_label_set_text_fmt(number, "%d", max);
|
||||
}
|
||||
|
||||
static constexpr uint8_t padding = 5;
|
||||
const uint8_t width = lv_obj_get_width(number) + padding * 2;
|
||||
const uint8_t width = std::max(lv_obj_get_width(number) + padding * 2, 58);
|
||||
static constexpr uint8_t btnHeight = 50;
|
||||
const uint8_t containerHeight = btnHeight * 2 + lv_obj_get_height(number) + padding * 2;
|
||||
|
||||
@@ -83,7 +142,7 @@ void Counter::Create() {
|
||||
UpdateLabel();
|
||||
|
||||
upBtn = lv_btn_create(counterContainer, nullptr);
|
||||
lv_obj_set_style_local_bg_color(upBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor);
|
||||
lv_obj_set_style_local_bg_color(upBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
lv_obj_set_size(upBtn, width, btnHeight);
|
||||
lv_obj_align(upBtn, nullptr, LV_ALIGN_IN_TOP_MID, 0, 0);
|
||||
upBtn->user_data = this;
|
||||
@@ -95,7 +154,7 @@ void Counter::Create() {
|
||||
lv_obj_align(upLabel, nullptr, LV_ALIGN_CENTER, 0, 0);
|
||||
|
||||
downBtn = lv_btn_create(counterContainer, nullptr);
|
||||
lv_obj_set_style_local_bg_color(downBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, bgColor);
|
||||
lv_obj_set_style_local_bg_color(downBtn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
|
||||
lv_obj_set_size(downBtn, width, btnHeight);
|
||||
lv_obj_align(downBtn, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
downBtn->user_data = this;
|
||||
|
@@ -6,14 +6,18 @@ namespace Pinetime {
|
||||
namespace Widgets {
|
||||
class Counter {
|
||||
public:
|
||||
Counter(int min, int max);
|
||||
Counter(int min, int max, lv_font_t& font);
|
||||
|
||||
void Create();
|
||||
void Increment();
|
||||
void Decrement();
|
||||
void UpBtnPressed();
|
||||
void DownBtnPressed();
|
||||
void SetValue(int newValue);
|
||||
void HideControls();
|
||||
void ShowControls();
|
||||
void EnableTwelveHourMode();
|
||||
void EnableMonthMode();
|
||||
void SetMax(int newMax);
|
||||
void SetValueChangedEventCallback(void* userData, void (*handler)(void* userData));
|
||||
|
||||
int GetValue() const {
|
||||
return value;
|
||||
@@ -25,6 +29,7 @@ namespace Pinetime {
|
||||
|
||||
private:
|
||||
void UpdateLabel();
|
||||
void (*ValueChangedHandler)(void* userData) = nullptr;
|
||||
|
||||
lv_obj_t* counterContainer;
|
||||
lv_obj_t* upBtn;
|
||||
@@ -33,9 +38,15 @@ namespace Pinetime {
|
||||
lv_obj_t* upperLine;
|
||||
lv_obj_t* lowerLine;
|
||||
lv_point_t linePoints[2];
|
||||
int value = 0;
|
||||
int min;
|
||||
int max;
|
||||
int value;
|
||||
const int leadingZeroCount;
|
||||
bool twelveHourMode = false;
|
||||
bool monthMode = false;
|
||||
lv_font_t& font;
|
||||
|
||||
void* userData = nullptr;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
32
src/displayapp/widgets/PageIndicator.cpp
Normal file
32
src/displayapp/widgets/PageIndicator.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "displayapp/widgets/PageIndicator.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Widgets;
|
||||
|
||||
PageIndicator::PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens) : nCurrentScreen {nCurrentScreen}, nScreens {nScreens} {
|
||||
}
|
||||
|
||||
void PageIndicator::Create() {
|
||||
pageIndicatorBasePoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[0].y = 0;
|
||||
pageIndicatorBasePoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorBasePoints[1].y = LV_VER_RES;
|
||||
|
||||
pageIndicatorBase = lv_line_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_line_width(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, Colors::bgDark);
|
||||
lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2);
|
||||
|
||||
const int16_t indicatorSize = LV_VER_RES / nScreens;
|
||||
const int16_t indicatorPos = indicatorSize * nCurrentScreen;
|
||||
|
||||
pageIndicatorPoints[0].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[0].y = indicatorPos;
|
||||
pageIndicatorPoints[1].x = LV_HOR_RES - 1;
|
||||
pageIndicatorPoints[1].y = indicatorPos + indicatorSize;
|
||||
|
||||
pageIndicator = lv_line_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_line_width(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||
lv_obj_set_style_local_line_color(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_line_set_points(pageIndicator, pageIndicatorPoints, 2);
|
||||
}
|
23
src/displayapp/widgets/PageIndicator.h
Normal file
23
src/displayapp/widgets/PageIndicator.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
namespace Widgets {
|
||||
class PageIndicator {
|
||||
public:
|
||||
PageIndicator(uint8_t nCurrentScreen, uint8_t nScreens);
|
||||
void Create();
|
||||
|
||||
private:
|
||||
uint8_t nCurrentScreen;
|
||||
uint8_t nScreens;
|
||||
|
||||
lv_point_t pageIndicatorBasePoints[2];
|
||||
lv_point_t pageIndicatorPoints[2];
|
||||
lv_obj_t* pageIndicatorBase;
|
||||
lv_obj_t* pageIndicator;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
49
src/displayapp/widgets/StatusIcons.cpp
Normal file
49
src/displayapp/widgets/StatusIcons.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "displayapp/widgets/StatusIcons.h"
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
|
||||
using namespace Pinetime::Applications::Widgets;
|
||||
|
||||
StatusIcons::StatusIcons(Controllers::Battery& batteryController, Controllers::Ble& bleController)
|
||||
: batteryController {batteryController}, bleController {bleController} {
|
||||
}
|
||||
|
||||
void StatusIcons::Create() {
|
||||
container = lv_cont_create(lv_scr_act(), nullptr);
|
||||
lv_cont_set_layout(container, LV_LAYOUT_ROW_TOP);
|
||||
lv_cont_set_fit(container, LV_FIT_TIGHT);
|
||||
lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
|
||||
lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
|
||||
|
||||
bleIcon = lv_label_create(container, nullptr);
|
||||
lv_obj_set_style_local_text_color(bleIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x0082FC));
|
||||
lv_label_set_text_static(bleIcon, Screens::Symbols::bluetooth);
|
||||
|
||||
batteryPlug = lv_label_create(container, nullptr);
|
||||
lv_obj_set_style_local_text_color(batteryPlug, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
lv_label_set_text_static(batteryPlug, Screens::Symbols::plug);
|
||||
|
||||
batteryIcon.Create(container);
|
||||
|
||||
lv_obj_align(container, nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
|
||||
}
|
||||
|
||||
void StatusIcons::Update() {
|
||||
powerPresent = batteryController.IsPowerPresent();
|
||||
if (powerPresent.IsUpdated()) {
|
||||
lv_obj_set_hidden(batteryPlug, !powerPresent.Get());
|
||||
}
|
||||
|
||||
batteryPercentRemaining = batteryController.PercentRemaining();
|
||||
if (batteryPercentRemaining.IsUpdated()) {
|
||||
auto batteryPercent = batteryPercentRemaining.Get();
|
||||
batteryIcon.SetBatteryPercentage(batteryPercent);
|
||||
}
|
||||
|
||||
bleState = bleController.IsConnected();
|
||||
bleRadioEnabled = bleController.IsRadioEnabled();
|
||||
if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
|
||||
lv_obj_set_hidden(bleIcon, !bleState.Get());
|
||||
}
|
||||
|
||||
lv_obj_realign(container);
|
||||
}
|
39
src/displayapp/widgets/StatusIcons.h
Normal file
39
src/displayapp/widgets/StatusIcons.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "components/battery/BatteryController.h"
|
||||
#include "components/ble/BleController.h"
|
||||
#include "displayapp/screens/BatteryIcon.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
namespace Widgets {
|
||||
class StatusIcons {
|
||||
public:
|
||||
StatusIcons(Controllers::Battery& batteryController, Controllers::Ble& bleController);
|
||||
void Align();
|
||||
void Create();
|
||||
lv_obj_t* GetObject() {
|
||||
return container;
|
||||
}
|
||||
void Update();
|
||||
|
||||
private:
|
||||
Screens::BatteryIcon batteryIcon;
|
||||
Pinetime::Controllers::Battery& batteryController;
|
||||
Controllers::Ble& bleController;
|
||||
|
||||
Screens::DirtyValue<uint8_t> batteryPercentRemaining {};
|
||||
Screens::DirtyValue<bool> powerPresent {};
|
||||
Screens::DirtyValue<bool> bleState {};
|
||||
Screens::DirtyValue<bool> bleRadioEnabled {};
|
||||
|
||||
lv_obj_t* bleIcon;
|
||||
lv_obj_t* batteryPlug;
|
||||
lv_obj_t* container;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,8 +4,8 @@
|
||||
namespace Pinetime {
|
||||
namespace PinMap {
|
||||
|
||||
#ifdef WATCH_P8
|
||||
// COLMI P8
|
||||
#if defined(DRIVER_PINMAP_P8)
|
||||
// COLMI P8 and variants
|
||||
static constexpr uint8_t Charging = 19;
|
||||
static constexpr uint8_t Cst816sReset = 13;
|
||||
static constexpr uint8_t Button = 17;
|
||||
|
@@ -21,7 +21,10 @@ void St7789::Init() {
|
||||
MemoryDataAccessControl();
|
||||
ColumnAddressSet();
|
||||
RowAddressSet();
|
||||
// P8B Mirrored version does not need display inversion.
|
||||
#ifndef DRIVER_DISPLAY_MIRROR
|
||||
DisplayInversionOn();
|
||||
#endif
|
||||
NormalModeOn();
|
||||
SetVdv();
|
||||
DisplayOn();
|
||||
@@ -62,7 +65,18 @@ void St7789::ColMod() {
|
||||
|
||||
void St7789::MemoryDataAccessControl() {
|
||||
WriteCommand(static_cast<uint8_t>(Commands::MemoryDataAccessControl));
|
||||
#ifdef DRIVER_DISPLAY_MIRROR
|
||||
// [7] = MY = Page Address Order, 0 = Top to bottom, 1 = Bottom to top
|
||||
// [6] = MX = Column Address Order, 0 = Left to right, 1 = Right to left
|
||||
// [5] = MV = Page/Column Order, 0 = Normal mode, 1 = Reverse mode
|
||||
// [4] = ML = Line Address Order, 0 = LCD refresh from top to bottom, 1 = Bottom to top
|
||||
// [3] = RGB = RGB/BGR Order, 0 = RGB, 1 = BGR
|
||||
// [2] = MH = Display Data Latch Order, 0 = LCD refresh from left to right, 1 = Right to left
|
||||
// [0 .. 1] = Unused
|
||||
WriteData(0b01000000);
|
||||
#else
|
||||
WriteData(0x00);
|
||||
#endif
|
||||
}
|
||||
|
||||
void St7789::ColumnAddressSet() {
|
||||
|
@@ -161,7 +161,7 @@ typedef void* lv_anim_user_data_t;
|
||||
#define LV_USE_OUTLINE 0
|
||||
|
||||
/*1: enable pattern drawing on rectangles*/
|
||||
#define LV_USE_PATTERN 0
|
||||
#define LV_USE_PATTERN 1
|
||||
|
||||
/*1: enable value string drawing on rectangles*/
|
||||
#define LV_USE_VALUE_STR 1
|
||||
@@ -678,7 +678,7 @@ typedef void* lv_obj_user_data_t;
|
||||
#endif
|
||||
|
||||
/*Mask (dependencies: -)*/
|
||||
#define LV_USE_OBJMASK 0
|
||||
#define LV_USE_OBJMASK 1
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define LV_USE_MSGBOX 0
|
||||
|
19
src/main.cpp
19
src/main.cpp
@@ -300,10 +300,29 @@ void nimble_port_ll_task_func(void* args) {
|
||||
}
|
||||
}
|
||||
|
||||
void calibrate_lf_clock_rc(nrf_drv_clock_evt_type_t event) {
|
||||
// 16 * 0.25s = 4s calibration cycle
|
||||
// Not recursive, call is deferred via internal calibration timer
|
||||
nrf_drv_clock_calibration_start(16, calibrate_lf_clock_rc);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
logger.Init();
|
||||
|
||||
nrf_drv_clock_init();
|
||||
nrf_drv_clock_lfclk_request(NULL);
|
||||
|
||||
// When loading the firmware via the Wasp-OS reloader-factory, which uses the used internal LF RC oscillator,
|
||||
// the LF clock has to be explicitly restarted because InfiniTime uses the external crystal oscillator if available.
|
||||
// If the clock is not restarted, the Bluetooth timers fail to initialize.
|
||||
nrfx_clock_lfclk_start();
|
||||
while (!nrf_clock_lf_is_running()) {
|
||||
}
|
||||
|
||||
// The RC source for the LF clock has to be calibrated
|
||||
#if (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LFCLK_RC)
|
||||
nrf_drv_clock_calibration_start(0, calibrate_lf_clock_rc);
|
||||
#endif
|
||||
|
||||
// Unblock i2c?
|
||||
nrf_gpio_cfg(Pinetime::PinMap::TwiScl,
|
||||
|
29
src/resources/CMakeLists.txt
Normal file
29
src/resources/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
find_program(LV_FONT_CONV "lv_font_conv" NO_CACHE REQUIRED
|
||||
HINTS "${CMAKE_SOURCE_DIR}/node_modules/.bin")
|
||||
message(STATUS "Using ${LV_FONT_CONV} to generate font files")
|
||||
|
||||
find_program(LV_IMG_CONV "lv_img_conv" NO_CACHE REQUIRED
|
||||
HINTS "${CMAKE_SOURCE_DIR}/node_modules/.bin")
|
||||
message(STATUS "Using ${LV_IMG_CONV} to generate font files")
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
|
||||
# FindPython3 module introduces with CMake 3.12
|
||||
# https://cmake.org/cmake/help/latest/module/FindPython3.html
|
||||
find_package(Python3 REQUIRED)
|
||||
else()
|
||||
set(Python3_EXECUTABLE "python")
|
||||
endif()
|
||||
|
||||
# generate fonts
|
||||
add_custom_target(GenerateResources
|
||||
COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/generate-fonts.py --lv-font-conv "${LV_FONT_CONV}" ${CMAKE_CURRENT_SOURCE_DIR}/fonts.json
|
||||
COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/generate-img.py --lv-img-conv "${LV_IMG_CONV}" ${CMAKE_CURRENT_SOURCE_DIR}/images.json
|
||||
COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/generate-package.py --config ${CMAKE_CURRENT_SOURCE_DIR}/fonts.json --config ${CMAKE_CURRENT_SOURCE_DIR}/images.json --obsolete obsolete_files.json --output infinitime-resources-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/fonts.json
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/images.json
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
||||
COMMENT "Generate fonts and images for resource package"
|
||||
)
|
||||
|
62
src/resources/fonts.json
Normal file
62
src/resources/fonts.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"teko" : {
|
||||
"sources": [
|
||||
{
|
||||
"file": "fonts/Teko-Light.ttf",
|
||||
"symbols": "0123456789:/amp"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 28,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
},
|
||||
"bebas" : {
|
||||
"sources": [
|
||||
{
|
||||
"file": "fonts/BebasNeue-Regular.ttf",
|
||||
"symbols": "0123456789:"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 120,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
},
|
||||
"lv_font_dots_40": {
|
||||
"sources": [
|
||||
{
|
||||
"file": "fonts/repetitionscrolling.ttf",
|
||||
"symbols": "0123456789-MONTUEWEDTHUFRISATSUN WK"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 40,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
},
|
||||
"7segments_40" : {
|
||||
"sources": [
|
||||
{
|
||||
"file": "fonts/7segment.woff",
|
||||
"symbols": "0123456789: -"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 40,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
},
|
||||
"7segments_115" : {
|
||||
"sources": [
|
||||
{
|
||||
"file": "fonts/7segment.woff",
|
||||
"symbols": "0123456789: -"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 115,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
}
|
||||
}
|
BIN
src/resources/fonts/7segment.woff
Normal file
BIN
src/resources/fonts/7segment.woff
Normal file
Binary file not shown.
BIN
src/resources/fonts/BebasNeue-Regular.ttf
Normal file
BIN
src/resources/fonts/BebasNeue-Regular.ttf
Normal file
Binary file not shown.
BIN
src/resources/fonts/Teko-Light.ttf
Normal file
BIN
src/resources/fonts/Teko-Light.ttf
Normal file
Binary file not shown.
BIN
src/resources/fonts/repetitionscrolling.ttf
Normal file
BIN
src/resources/fonts/repetitionscrolling.ttf
Normal file
Binary file not shown.
80
src/resources/generate-fonts.py
Executable file
80
src/resources/generate-fonts.py
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import io
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import typing
|
||||
import os.path
|
||||
import argparse
|
||||
import subprocess
|
||||
|
||||
class Source(object):
|
||||
def __init__(self, d):
|
||||
self.file = d['file']
|
||||
if not os.path.exists(self.file):
|
||||
self.file = os.path.join(os.path.dirname(sys.argv[0]), self.file)
|
||||
self.range = d.get('range')
|
||||
self.symbols = d.get('symbols')
|
||||
|
||||
|
||||
def gen_lvconv_line(lv_font_conv: str, dest: str, size: int, bpp: int, format: str, sources: typing.List[Source], compress:bool=False):
|
||||
if format != "lvgl" and format != "bin":
|
||||
format = "bin" if dest.lower().endswith(".bin") else "lvgl"
|
||||
|
||||
args = [lv_font_conv, '--size', str(size), '--output', dest, '--bpp', str(bpp), '--format', format]
|
||||
if not compress:
|
||||
args.append('--no-compress')
|
||||
for source in sources:
|
||||
args.extend(['--font', source.file])
|
||||
if source.range:
|
||||
args.extend(['--range', source.range])
|
||||
if source.symbols:
|
||||
args.extend(['--symbols', source.symbols])
|
||||
|
||||
return args
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description='auto generate LVGL font files from fonts')
|
||||
ap.add_argument('config', type=str, help='config file to use')
|
||||
ap.add_argument('-f', '--font', type=str, action='append', help='Choose specific fonts to generate (default: all)', default=[])
|
||||
ap.add_argument('--lv-font-conv', type=str, help='Path to "lv_font_conf" executable', default="lv_font_conv")
|
||||
args = ap.parse_args()
|
||||
|
||||
if not shutil.which(args.lv_font_conv):
|
||||
sys.exit(f"Missing lv_font_conv. Make sure it's findable (in PATH) or specify it manually")
|
||||
if not os.path.exists(args.config):
|
||||
sys.exit(f'Error: the config file {args.config} does not exist.')
|
||||
if not os.access(args.config, os.R_OK):
|
||||
sys.exit(f'Error: the config file {args.config} is not accessible (permissions?).')
|
||||
with open(args.config, 'r') as fd:
|
||||
data = json.load(fd)
|
||||
|
||||
fonts_to_run = set(data.keys())
|
||||
|
||||
if args.font:
|
||||
enabled_fonts = set()
|
||||
for font in args.font:
|
||||
enabled_fonts.add(font[:-2] if font.endswith('.c') else font)
|
||||
d = enabled_fonts.difference(fonts_to_run)
|
||||
if d:
|
||||
print(f'Warning: requested font{"s" if len(d)>1 else ""} missing: {" ".join(d)}')
|
||||
fonts_to_run = fonts_to_run.intersection(enabled_fonts)
|
||||
|
||||
for name in fonts_to_run:
|
||||
font = data[name]
|
||||
sources = font.pop('sources')
|
||||
patches = font.pop('patches') if 'patches' in font else []
|
||||
font['sources'] = [Source(thing) for thing in sources]
|
||||
extension = 'c' if font['format'] != 'bin' else 'bin'
|
||||
font.pop('target_path')
|
||||
line = gen_lvconv_line(args.lv_font_conv, f'{name}.{extension}', **font)
|
||||
subprocess.check_call(line)
|
||||
if patches:
|
||||
for patch in patches:
|
||||
subprocess.check_call(['/usr/bin/env', 'patch', name+'.'+extension, patch])
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
56
src/resources/generate-img.py
Executable file
56
src/resources/generate-img.py
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import io
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import typing
|
||||
import os.path
|
||||
import argparse
|
||||
import subprocess
|
||||
|
||||
def gen_lvconv_line(lv_img_conv: str, dest: str, color_format: str, output_format: str, binary_format: str, sources: str):
|
||||
args = [lv_img_conv, sources, '--force', '--output-file', dest, '--color-format', color_format, '--output-format', output_format, '--binary-format', binary_format]
|
||||
|
||||
return args
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description='auto generate LVGL font files from fonts')
|
||||
ap.add_argument('config', type=str, help='config file to use')
|
||||
ap.add_argument('-i', '--image', type=str, action='append', help='Choose specific images to generate (default: all)', default=[])
|
||||
ap.add_argument('--lv-img-conv', type=str, help='Path to "lv_img_conf" executable', default="lv_img_conv")
|
||||
args = ap.parse_args()
|
||||
|
||||
if not shutil.which(args.lv_img_conv):
|
||||
sys.exit(f"Missing lv_img_conv. Make sure it's findable (in PATH) or specify it manually")
|
||||
if not os.path.exists(args.config):
|
||||
sys.exit(f'Error: the config file {args.config} does not exist.')
|
||||
if not os.access(args.config, os.R_OK):
|
||||
sys.exit(f'Error: the config file {args.config} is not accessible (permissions?).')
|
||||
with open(args.config, 'r') as fd:
|
||||
data = json.load(fd)
|
||||
|
||||
images_to_run = set(data.keys())
|
||||
|
||||
if args.image:
|
||||
enabled_images = set()
|
||||
for image in args.image:
|
||||
enabled_images.add(image[:-2] if image.endswith('.c') else image)
|
||||
d = enabled_images.difference(images_to_run)
|
||||
if d:
|
||||
print(f'Warning: requested image{"s" if len(d)>1 else ""} missing: {" ".join(d)}')
|
||||
images_to_run = images_to_run.intersection(enabled_images)
|
||||
|
||||
for name in images_to_run:
|
||||
image = data[name]
|
||||
if not os.path.exists(image['sources']):
|
||||
image['sources'] = os.path.join(os.path.dirname(sys.argv[0]), image['sources'])
|
||||
extension = 'bin'
|
||||
image.pop('target_path')
|
||||
line = gen_lvconv_line(args.lv_img_conv, f'{name}.{extension}', **image)
|
||||
subprocess.check_call(line)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
72
src/resources/generate-package.py
Executable file
72
src/resources/generate-package.py
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import io
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import typing
|
||||
import os.path
|
||||
import argparse
|
||||
import subprocess
|
||||
from zipfile import ZipFile
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description='auto generate LVGL font files from fonts')
|
||||
ap.add_argument('--config', '-c', type=str, action='append', help='config file to use')
|
||||
ap.add_argument('--obsolete', type=str, help='List of obsolete files')
|
||||
ap.add_argument('--output', type=str, help='output file name')
|
||||
args = ap.parse_args()
|
||||
|
||||
for config_file in args.config:
|
||||
if not os.path.exists(config_file):
|
||||
sys.exit(f'Error: the config file {config_file} does not exist.')
|
||||
if not os.access(config_file, os.R_OK):
|
||||
sys.exit(f'Error: the config file {config_file} is not accessible (permissions?).')
|
||||
|
||||
if args.obsolete:
|
||||
obsolete_file_path = os.path.join(os.path.dirname(sys.argv[0]), args.obsolete)
|
||||
if not os.path.exists(obsolete_file_path):
|
||||
sys.exit(f'Error: the "obsolete" file {args.obsolete} does not exist.')
|
||||
if not os.access(obsolete_file_path, os.R_OK):
|
||||
sys.exit(f'Error: the "obsolete" file {args.obsolete} is not accessible (permissions?).')
|
||||
|
||||
zf = ZipFile(args.output, mode='w')
|
||||
resource_files = []
|
||||
|
||||
for config_file in args.config:
|
||||
with open(config_file, 'r') as fd:
|
||||
data = json.load(fd)
|
||||
|
||||
resource_names = set(data.keys())
|
||||
for name in resource_names:
|
||||
resource = data[name]
|
||||
resource_files.append({
|
||||
"filename": name+'.bin',
|
||||
"path": resource['target_path'] + name+'.bin'
|
||||
})
|
||||
|
||||
path = name + '.bin'
|
||||
if not os.path.exists(path):
|
||||
path = os.path.join(os.path.dirname(sys.argv[0]), path)
|
||||
zf.write(path)
|
||||
|
||||
if args.obsolete:
|
||||
obsolete_file_path = os.path.join(os.path.dirname(sys.argv[0]), args.obsolete)
|
||||
with open(obsolete_file_path, 'r') as fd:
|
||||
obsolete_data = json.load(fd)
|
||||
else:
|
||||
obsolete_data = {}
|
||||
output = {
|
||||
'resources': resource_files,
|
||||
'obsolete_files': obsolete_data
|
||||
}
|
||||
|
||||
|
||||
with open("resources.json", 'w') as fd:
|
||||
json.dump(output, fd, indent=4)
|
||||
|
||||
zf.write('resources.json')
|
||||
zf.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
9
src/resources/images.json
Normal file
9
src/resources/images.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"pine_small" : {
|
||||
"sources": "images/pine_logo.png",
|
||||
"color_format": "CF_TRUE_COLOR",
|
||||
"output_format": "bin",
|
||||
"binary_format": "ARGB8565_RBSWAP",
|
||||
"target_path": "/images/"
|
||||
}
|
||||
}
|
BIN
src/resources/images/pine_logo.png
Normal file
BIN
src/resources/images/pine_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
253
src/resources/images/pine_logo.svg
Normal file
253
src/resources/images/pine_logo.svg
Normal file
@@ -0,0 +1,253 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="110.49872"
|
||||
height="150.24246"
|
||||
viewBox="0 0 29.236118 39.751652"
|
||||
version="1.1"
|
||||
id="svg2418"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04, custom)"
|
||||
sodipodi:docname="pine_logo.svg"
|
||||
inkscape:export-filename="/home/diegomiguel/Syncthing/Watchface/pine_logo_new_2_transparent.png"
|
||||
inkscape:export-xdpi="19.807983"
|
||||
inkscape:export-ydpi="19.807983"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview2420"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
units="px"
|
||||
inkscape:zoom="4.1424077"
|
||||
inkscape:cx="69.886892"
|
||||
inkscape:cy="73.387272"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1026"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g972"
|
||||
inkscape:snap-page="true" />
|
||||
<defs
|
||||
id="defs2415" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
id="layer1"
|
||||
transform="translate(-91.35232,-110.1768)"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="display:none;opacity:1;fill:#ffffff;fill-opacity:1;stroke:#4d4d4d;stroke-width:0"
|
||||
id="rect2129"
|
||||
width="29.236118"
|
||||
height="39.751652"
|
||||
x="91.352318"
|
||||
y="110.1768"
|
||||
inkscape:label="bg" />
|
||||
<g
|
||||
id="g32004"
|
||||
style="display:none;stroke:none"
|
||||
inkscape:export-filename="/Users/diegomiguel/Syncthing/Watchface/logo_pine.png"
|
||||
inkscape:export-xdpi="19.965168"
|
||||
inkscape:export-ydpi="19.965168"
|
||||
inkscape:label="pine_logo"
|
||||
transform="translate(75.060638,-5.5438717)">
|
||||
<g
|
||||
id="g13016"
|
||||
inkscape:label="pine"
|
||||
style="display:inline;fill:#6f2d00;fill-opacity:1;stroke:none"
|
||||
transform="matrix(1.1631294,0,0,1.1631294,-5.0422885,-22.11978)"
|
||||
inkscape:export-filename="/Users/diegomiguel/Syncthing/Watchface/logo_pine.png"
|
||||
inkscape:export-xdpi="31.276381"
|
||||
inkscape:export-ydpi="31.276381"
|
||||
sodipodi:insensitive="true">
|
||||
<path
|
||||
id="path5716"
|
||||
style="fill:#6f2d00;fill-opacity:1;stroke:none;stroke-width:2.34917;stroke-linecap:round"
|
||||
inkscape:transform-center-x="1.2687941"
|
||||
d="M 116.82422,535.70898 102.4375,542.5 l -14.386719,6.78906 14.386719,6.78906 11,5.19141 v 15.80664 h 3.38672 v -14.20703 -3.93555 -9.64453 z"
|
||||
transform="scale(0.26458333)" />
|
||||
<path
|
||||
style="fill:#6f2d00;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 18.341872,136.77692 3.331558,7.57837 7.029221,-3.22172 z"
|
||||
id="path5936"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#6f2d00;fill-opacity:1;stroke:none;stroke-width:1.51181;stroke-linecap:round"
|
||||
id="path7773"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="116.64632"
|
||||
sodipodi:cy="501.86975"
|
||||
sodipodi:r1="14.699218"
|
||||
sodipodi:r2="7.3496094"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:arg2="2.0943951"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
transform="matrix(0.39243637,0,0,0.31059853,-17.750778,-19.228227)"
|
||||
inkscape:transform-center-x="1.4421265"
|
||||
d="m 123.99592,514.59965 -11.02441,-6.36495 -11.02441,-6.36495 11.02441,-6.36495 11.02442,-6.36494 0,12.72989 z" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#6f2d00;fill-opacity:1;stroke:none;stroke-width:1.51181;stroke-linecap:round"
|
||||
id="path7877"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="116.64632"
|
||||
sodipodi:cy="501.86975"
|
||||
sodipodi:r1="14.699218"
|
||||
sodipodi:r2="7.3496094"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:arg2="2.0943951"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
transform="matrix(-0.3940968,0,0,-0.29190487,69.062729,278.57074)"
|
||||
inkscape:transform-center-x="-1.4482278"
|
||||
inkscape:transform-center-y="3.6892669e-06"
|
||||
d="m 123.99592,514.59965 -11.02441,-6.36495 -11.02441,-6.36495 11.02441,-6.36495 11.02442,-6.36494 0,12.72989 z" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#6f2d00;fill-opacity:1;stroke:none;stroke-width:1.51181;stroke-linecap:round"
|
||||
id="path7929"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="116.64632"
|
||||
sodipodi:cy="501.86975"
|
||||
sodipodi:r1="14.699218"
|
||||
sodipodi:r2="7.3496094"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:arg2="2.0943951"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
transform="matrix(0.34926521,0,0,0.27033526,-12.397729,-7.5515591)"
|
||||
inkscape:transform-center-x="1.28348"
|
||||
inkscape:transform-center-y="1.7340579e-06"
|
||||
d="m 123.99592,514.59965 -11.02441,-6.36495 -11.02441,-6.36495 11.02441,-6.36495 11.02442,-6.36494 0,12.72989 z" />
|
||||
<path
|
||||
style="fill:#6f2d00;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 24.903849,122.34368 -1.378447,3.99721 5.0395,-2.31516 z"
|
||||
id="path7964"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:#6f2d00;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 30.909733,118.50827 v 4.63122 l -3.122345,-1.29967 z"
|
||||
id="path11445" />
|
||||
</g>
|
||||
<g
|
||||
id="g13032"
|
||||
transform="matrix(-1.1631294,0,0,1.1631294,66.861771,-22.11978)"
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none"
|
||||
inkscape:label="pine"
|
||||
inkscape:export-filename="/Users/diegomiguel/Syncthing/Watchface/logo_pine.png"
|
||||
inkscape:export-xdpi="31.276381"
|
||||
inkscape:export-ydpi="31.276381">
|
||||
<path
|
||||
id="path13018"
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none;stroke-width:2.34917;stroke-linecap:round"
|
||||
inkscape:transform-center-x="1.2687941"
|
||||
d="M 116.82422,535.70898 102.4375,542.5 l -14.386719,6.78906 14.386719,6.78906 11,5.19141 v 15.80664 h 3.38672 v -14.20703 -3.93555 -9.64453 z"
|
||||
transform="scale(0.26458333)" />
|
||||
<path
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 18.341872,136.77692 3.331558,7.57837 7.029221,-3.22172 z"
|
||||
id="path13020"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none;stroke-width:1.51181;stroke-linecap:round"
|
||||
id="path13022"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="116.64632"
|
||||
sodipodi:cy="501.86975"
|
||||
sodipodi:r1="14.699218"
|
||||
sodipodi:r2="7.3496094"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:arg2="2.0943951"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
transform="matrix(0.39243637,0,0,0.31059853,-17.750778,-19.228227)"
|
||||
inkscape:transform-center-x="1.4421265"
|
||||
d="m 123.99592,514.59965 -11.02441,-6.36495 -11.02441,-6.36495 11.02441,-6.36495 11.02442,-6.36494 0,12.72989 z" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none;stroke-width:1.51181;stroke-linecap:round"
|
||||
id="path13024"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="116.64632"
|
||||
sodipodi:cy="501.86975"
|
||||
sodipodi:r1="14.699218"
|
||||
sodipodi:r2="7.3496094"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:arg2="2.0943951"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
transform="matrix(-0.3940968,0,0,-0.29190487,69.062729,278.57074)"
|
||||
inkscape:transform-center-x="-1.4482278"
|
||||
inkscape:transform-center-y="3.6892669e-06"
|
||||
d="m 123.99592,514.59965 -11.02441,-6.36495 -11.02441,-6.36495 11.02441,-6.36495 11.02442,-6.36494 0,12.72989 z" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none;stroke-width:1.51181;stroke-linecap:round"
|
||||
id="path13026"
|
||||
inkscape:flatsided="false"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="116.64632"
|
||||
sodipodi:cy="501.86975"
|
||||
sodipodi:r1="14.699218"
|
||||
sodipodi:r2="7.3496094"
|
||||
sodipodi:arg1="1.0471976"
|
||||
sodipodi:arg2="2.0943951"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
transform="matrix(0.34926521,0,0,0.27033526,-12.397729,-7.5515591)"
|
||||
inkscape:transform-center-x="1.28348"
|
||||
inkscape:transform-center-y="1.7340579e-06"
|
||||
d="m 123.99592,514.59965 -11.02441,-6.36495 -11.02441,-6.36495 11.02441,-6.36495 11.02442,-6.36494 0,12.72989 z" />
|
||||
<path
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 24.903849,122.34368 -1.378447,3.99721 5.0395,-2.31516 z"
|
||||
id="path13028"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:#de5a00;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 30.909733,118.50827 v 4.63122 l -3.122345,-1.29967 z"
|
||||
id="path13030" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g972"
|
||||
style="display:inline;stroke:none"
|
||||
inkscape:export-filename="/Users/diegomiguel/Syncthing/Watchface/logo_pine.png"
|
||||
inkscape:export-xdpi="19.965168"
|
||||
inkscape:export-ydpi="19.965168"
|
||||
inkscape:label="pine_logo"
|
||||
transform="translate(75.060638,-5.5438717)">
|
||||
<path
|
||||
id="path952"
|
||||
style="fill:#0f0f0f;fill-opacity:1;stroke:none;stroke-width:0.307744px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 30.909731,115.72067 v 5.38671 l -3.631692,-1.51168 z m -6.985621,4.46108 -1.603312,4.64927 5.861591,-2.69283 z m 6.98562,10.72311 -4.478564,-2.00136 -4.478563,-2.00136 4.478563,-2.00136 4.478568,-2.00137 v 4.00273 z m -12.461069,-3.7293 5.05343,2.16104 5.053431,2.16105 -5.053431,2.16105 -5.053434,2.16104 v -4.32209 z m 12.461067,14.24725 -5.032139,-2.29945 -5.032139,-2.29944 5.032139,-2.29943 5.032144,-2.29945 v 4.59888 z m -14.618046,-4.45333 3.875033,8.81462 8.175894,-3.74728 z m 14.618058,5.77232 -4.427436,2.0899 -4.427436,2.08929 4.427436,2.0893 3.385191,1.59762 v 4.86441 h 1.042245 v -4.37214 -1.21114 -2.96805 z"
|
||||
inkscape:label="left" />
|
||||
<path
|
||||
id="path968"
|
||||
style="fill:#575757;fill-opacity:1;stroke:none;stroke-width:0.307744px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 30.909752,115.72067 v 5.38671 l 3.631691,-1.51168 z m 6.98562,4.46108 1.603312,4.64927 -5.86159,-2.69283 z m -6.985619,10.72311 4.478564,-2.00136 4.478563,-2.00136 -4.478563,-2.00136 -4.478568,-2.00136 v 4.00272 z m 12.461067,-3.72931 -5.05343,2.16105 -5.05343,2.16105 5.05343,2.16104 5.053435,2.16105 v -4.32209 z m -12.461065,14.24726 5.032139,-2.29945 5.032139,-2.29944 -5.032139,-2.29944 -5.032144,-2.29944 v 4.59888 z m 14.618045,-4.45333 -3.875033,8.81462 -8.175893,-3.74728 z m -14.618058,5.77231 4.427436,2.0899 4.427436,2.0893 -4.427436,2.0893 -3.385191,1.59763 v 4.8644 h -1.042245 v -4.37213 -1.21115 -2.96805 z"
|
||||
inkscape:label="right" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
6
src/resources/obsolete_files.json
Normal file
6
src/resources/obsolete_files.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"path": "/example-of-obsolete-file.bin",
|
||||
"since": "1.11.0"
|
||||
}
|
||||
]
|
@@ -251,7 +251,8 @@ void SystemTask::Work() {
|
||||
case Messages::TouchWakeUp: {
|
||||
if (touchHandler.GetNewTouchInfo()) {
|
||||
auto gesture = touchHandler.GestureGet();
|
||||
if (gesture != Pinetime::Applications::TouchEvents::None &&
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
|
||||
gesture != Pinetime::Applications::TouchEvents::None &&
|
||||
((gesture == Pinetime::Applications::TouchEvents::DoubleTap &&
|
||||
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) ||
|
||||
(gesture == Pinetime::Applications::TouchEvents::Tap &&
|
||||
@@ -280,7 +281,7 @@ void SystemTask::Work() {
|
||||
}
|
||||
break;
|
||||
case Messages::OnNewNotification:
|
||||
if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::ON) {
|
||||
if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::On) {
|
||||
if (state == SystemTaskState::Sleeping) {
|
||||
GoToRunning();
|
||||
} else {
|
||||
@@ -388,7 +389,8 @@ void SystemTask::Work() {
|
||||
break;
|
||||
case Messages::OnNewHour:
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours &&
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours &&
|
||||
alarmController.State() != AlarmController::AlarmState::Alerting) {
|
||||
if (state == SystemTaskState::Sleeping) {
|
||||
GoToRunning();
|
||||
@@ -399,7 +401,8 @@ void SystemTask::Work() {
|
||||
break;
|
||||
case Messages::OnNewHalfHour:
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours &&
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours &&
|
||||
alarmController.State() != AlarmController::AlarmState::Alerting) {
|
||||
if (state == SystemTaskState::Sleeping) {
|
||||
GoToRunning();
|
||||
@@ -483,13 +486,13 @@ void SystemTask::UpdateMotion() {
|
||||
motionController.IsSensorOk(motionSensor.IsOk());
|
||||
motionController.Update(motionValues.x, motionValues.y, motionValues.z, motionValues.steps);
|
||||
|
||||
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) &&
|
||||
motionController.Should_RaiseWake(state == SystemTaskState::Sleeping)) {
|
||||
GoToRunning();
|
||||
}
|
||||
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) &&
|
||||
motionController.Should_ShakeWake(settingsController.GetShakeThreshold())) {
|
||||
GoToRunning();
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep) {
|
||||
if ((settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) &&
|
||||
motionController.Should_RaiseWake(state == SystemTaskState::Sleeping)) ||
|
||||
(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) &&
|
||||
motionController.Should_ShakeWake(settingsController.GetShakeThreshold()))) {
|
||||
GoToRunning();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user