#include #include #include #include #include #include "main.h" #include "utility_functions.h" SysState_t state = {.mode = 0x01, .te1 = -50, .te2 = 230, .te3 = 0, .te4 = 180, .kpd = 868, .speedB3 = 25, .speedB4 = 30}; uint64_t errorMask; lv_obj_t *currentTab; lv_obj_t *tabSettingsModeTime; lv_obj_t *tabSettingsTime; lv_obj_t *tabSettingsScreen; lv_obj_t *tabFilters; lv_obj_t *tabIntervals; lv_obj_t *tabPower; lv_obj_t *tabTemperature; lv_obj_t *btnOkModes; lv_obj_t *btnOkTime; lv_obj_t *btnOkScreen; lv_obj_t *btnOkFilters; lv_obj_t *btnOkIntervals; lv_obj_t *btnOkPower; lv_obj_t *btnOkTemperature; lv_obj_t *mainScreen; lv_obj_t *saveScreen; lv_obj_t *tabMain; lv_obj_t *tabSettings; lv_obj_t *tabService; lv_obj_t *tabHelp; uint16_t selectedTestDay; lv_obj_t *imgMode; lv_obj_t *dateLabel; lv_obj_t *dayLabel; lv_obj_t *timeLabel; lv_obj_t *sliderFilterSup; lv_obj_t *sliderFilterExh; lv_obj_t *powerMainLabel; lv_obj_t *balanceSwitch; lv_obj_t *labelTempSupStreet; lv_obj_t *labelTempSupHome; lv_obj_t *labelTempExhStreet; lv_obj_t *labelTempExhHome; lv_obj_t *btnStartStop; bool btnStartStopIsStop = false; lv_obj_t *btnConditioner; bool btnConditionerState = false; bool btnConditionerEnabled = false; lv_obj_t *rollerDaymodePower; lv_obj_t *rollerNightmodePower; lv_obj_t *rollerDayHour; lv_obj_t *rollerDayMinute; lv_obj_t *rollerNightHour; lv_obj_t *rollerNightMinute; lv_obj_t *rollerHour; lv_obj_t *rollerMinute; lv_obj_t *ddDay; lv_obj_t *ddMonth; lv_obj_t *ddYear; lv_obj_t *rollerScreenOff; lv_obj_t *passwordScreen; lv_obj_t *matrixFilterDays; lv_obj_t *rollerFilterHour; lv_obj_t *rollerFilterMinute; lv_obj_t *spinboxTempInterval; lv_obj_t *spinboxRotorPause; lv_obj_t *spinboxRotorPulse; lv_obj_t *spinboxNumRotors; lv_obj_t *labelServiceSup; lv_obj_t *labelServiceExh; lv_obj_t *rollerServiceSup; lv_obj_t *rollerServiceExh; lv_obj_t *ledSup; lv_obj_t *ledExh; lv_obj_t *labelServiceTempSupStreet; lv_obj_t *labelServiceTempSupHome; lv_obj_t *labelServiceTempExhStreet; lv_obj_t *labelServiceTempExhHome; lv_obj_t *spinboxServiceTempSupStreet; lv_obj_t *spinboxServiceTempSupHome; lv_obj_t *spinboxServiceTempExhStreet; lv_obj_t *spinboxServiceTempExhHome; lv_obj_t *labelHelpTempSupStreet; lv_obj_t *labelHelpTempSupHome; lv_obj_t *labelHelpTempExhStreet; lv_obj_t *labelHelpTempExhHome; lv_obj_t *labelHelpKpd; lv_obj_t *kpdHint; lv_obj_t *labelHelpSup; lv_obj_t *labelHelpExh; lv_obj_t *rotorSection; lv_obj_t *labelRotorSpeed[MAX_NUM_ROTORS]; lv_obj_t *rotorSpeedLine[MAX_NUM_ROTORS]; lv_obj_t *popupBg; lv_obj_t *loadingLabel; PopupWindow_t popupWindows[NUM_OF_POPUP_WINDOWS]; void placeWidgets(); void initStyles(); void createMainTab(lv_obj_t *parent); void createSettingsTab(lv_obj_t *parent); void createModePage(lv_obj_t *parent); void createTimePage(lv_obj_t *parent); void createScreenPage(lv_obj_t *parent); void createFiltersPage(lv_obj_t *parent); void createServiceTab(lv_obj_t *parent); lv_obj_t *createPasswordInput(lv_obj_t *parent); void createIntervalsPage(lv_obj_t *parent); void createServicePowerPage(lv_obj_t *parent); void createTempAdjustPage(lv_obj_t *parent); void createHelpTab(lv_obj_t *parent); void createDescrPage(lv_obj_t *parent); void createStatePage(lv_obj_t *parent); void createContactPage(lv_obj_t *parent); void createRotorSpeed(lv_obj_t *parent, uint8_t num); void createPopupScreen(); void updateConfigWidgets(); void updateWidgets(); void enableConditionerBtn(); void disableConditionerBtn(); void setConditionerBtnState(bool state); static void passwordKeyboardEventCb(lv_event_t *e); static void mainTabviewEventCb(lv_event_t *e); static void settingsTabviewEventCb(lv_event_t *e); static void serviceTabviewEventCb(lv_event_t *e); static lv_obj_t *getActiveTabSettings(lv_obj_t *matrix); static lv_obj_t *getActiveTabService(lv_obj_t *matrix); static void filterButtonsCb(lv_event_t *e); static void balanceSwitchCb(lv_event_t *e); static void startStopBtnCb(lv_event_t *e); static void conditionerBtnCb(lv_event_t *e); static void valueChangedCb(lv_event_t *e); static void OkBtnModeTimeCb(lv_event_t *e); static void OkBtnTimeCb(lv_event_t *e); static void OkBtnScreenCb(lv_event_t *e); static void OkBtnFiltersCb(lv_event_t *e); static void OkBtnIntervalCb(lv_event_t *e); static void OkBtnServicePowerCb(lv_event_t *e); static void OkBtnTempAdjustCb(lv_event_t *e); static void kpdLabelCb(lv_event_t *e); static void ddDateCb(lv_event_t *e); static void timePageClickedCb(lv_event_t *e); static void clearModesTab(); static void clearTimeTab(); static void clearScreenTab(); static void clearFiltersTab(); static void clearIntervalsTab(); static void clearPowerTab(); static void clearTemperatureTab(); static void clearCurrentTab(); void initStyles() { lv_style_init(&text_16); lv_style_set_text_font(&text_16, &montserrat_16_ru_en); lv_style_init(&text_20); lv_style_set_text_font(&text_20, &montserrat_20_ru_en); lv_style_init(&text_24); lv_style_set_text_font(&text_24, &montserrat_24_ru_en); lv_style_init(&text_28); lv_style_set_text_font(&text_28, &montserrat_28_ru_en); lv_style_init(&text_20_semibold); lv_style_set_text_font(&text_20_semibold, &montserrat_semibold_20_ru_en); lv_style_init(&text_24_semibold); lv_style_set_text_font(&text_24_semibold, &montserrat_semibold_24_ru_en); lv_style_init(&text_28_semibold); lv_style_set_text_font(&text_28_semibold, &montserrat_semibold_28_ru_en); lv_style_init(&styleRollerMain); lv_style_set_bg_color(&styleRollerMain, lv_color_white()); lv_style_set_text_color(&styleRollerMain, lv_color_black()); lv_style_set_border_color(&styleRollerMain, lv_palette_lighten(LV_PALETTE_BLUE, 1)); lv_style_set_border_width(&styleRollerMain, 3); lv_style_set_pad_all(&styleRollerMain, 7); lv_style_set_text_font(&styleRollerMain, &montserrat_20_ru_en); lv_style_set_anim_time(&styleRollerMain, 200); lv_style_init(&styleRollerSelected); lv_style_set_bg_color(&styleRollerSelected, lv_palette_lighten(LV_PALETTE_GREY, 2)); lv_style_set_text_color(&styleRollerSelected, lv_color_black()); lv_style_set_border_width(&styleRollerSelected, 0); lv_style_set_pad_all(&styleRollerSelected, 7); lv_style_set_text_font(&styleRollerSelected, &montserrat_28_ru_en); lv_style_set_anim_time(&styleRollerSelected, 1000); lv_style_init(&styleBackground); lv_style_set_bg_color(&styleBackground, lv_palette_lighten(LV_PALETTE_BLUE, 5)); lv_style_set_border_color(&styleBackground, lv_palette_lighten(LV_PALETTE_BLUE, 4)); lv_style_set_border_width(&styleBackground, 3); createRollerOptions(0, 23, 1, 2, rollerOptionsHour, sizeof(rollerOptionsHour)); createRollerOptions(0, 59, 1, 2, rollerOptionsMinute, sizeof(rollerOptionsMinute)); } void placeWidgets() { initStyles(); lv_obj_t *tabview = lv_tabview_create(lv_scr_act()); lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT); lv_tabview_set_tab_bar_size(tabview, 140); lv_obj_add_style(tabview, &text_20_semibold, 0); lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE); lv_obj_add_event_cb(tabview, mainTabviewEventCb, LV_EVENT_CLICKED, lv_tabview_get_tab_btns(tabview)); tabMain = lv_tabview_add_tab(tabview, "Главная"); tabSettings = lv_tabview_add_tab(tabview, "Настройки"); tabService = lv_tabview_add_tab(tabview, "Сервис"); tabHelp = lv_tabview_add_tab(tabview, "Помощь"); lv_obj_set_flex_flow(tabMain, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabMain, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabMain, LV_OBJ_FLAG_SCROLLABLE); createMainTab(tabMain); createSettingsTab(tabSettings); createServiceTab(tabService); createHelpTab(tabHelp); createPopupScreen(); mainScreen = lv_scr_act(); saveScreen = lv_obj_create(NULL); updateConfigWidgets(); updateWidgets(); } void createMainTab(lv_obj_t *parent) { lv_obj_t *headerSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(headerSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(headerSection, 0, 0); lv_obj_set_size(headerSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(headerSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(headerSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_hor(headerSection, 5, 0); lv_obj_set_style_pad_ver(headerSection, 20, 0); lv_obj_set_style_pad_column(headerSection, 15, 0); imgMode = lv_img_create(headerSection); lv_img_set_src(imgMode, &sun_yellow); lv_obj_set_size(imgMode, 100, 100); lv_obj_t *filtersSection = lv_obj_create(headerSection); lv_obj_set_style_bg_opa(filtersSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(filtersSection, 0, 0); lv_obj_set_size(filtersSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_flex_flow(filtersSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(filtersSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(filtersSection, 20, 0); sliderFilterSup = lv_slider_create(filtersSection); lv_obj_set_style_bg_color(sliderFilterSup, lv_palette_main(LV_PALETTE_BLUE), 0); lv_obj_clear_flag(sliderFilterSup, LV_OBJ_FLAG_CLICKABLE); lv_slider_set_range(sliderFilterSup, 0, 100); lv_slider_set_value(sliderFilterSup, 0, LV_ANIM_OFF); lv_obj_set_style_bg_opa(sliderFilterSup, LV_OPA_TRANSP, LV_PART_KNOB); sliderFilterExh = lv_slider_create(filtersSection); lv_obj_set_style_bg_color(sliderFilterExh, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); lv_obj_set_style_bg_color(sliderFilterExh, lv_palette_main(LV_PALETTE_RED), LV_PART_INDICATOR); lv_obj_set_style_bg_color(sliderFilterExh, lv_palette_main(LV_PALETTE_RED), LV_PART_KNOB ); lv_obj_clear_flag(sliderFilterExh, LV_OBJ_FLAG_CLICKABLE); lv_slider_set_range(sliderFilterExh, 0, 100); lv_slider_set_value(sliderFilterExh, 0, LV_ANIM_OFF); lv_obj_set_style_bg_opa(sliderFilterExh, LV_OPA_TRANSP, LV_PART_KNOB); lv_obj_t *timeSection = lv_obj_create(headerSection); lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(timeSection, 0, 0); lv_obj_set_size(timeSection, 200, LV_SIZE_CONTENT); lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_END); lv_obj_set_style_pad_all(timeSection, 5, 0); dateLabel = lv_label_create(timeSection); lv_obj_add_style(dateLabel, &text_24, 0); lv_label_set_text(dateLabel, ""); dayLabel = lv_label_create(timeSection); lv_obj_add_style(dayLabel, &text_24, 0); lv_label_set_text(dayLabel, ""); timeLabel = lv_label_create(timeSection); lv_obj_add_style(timeLabel, &text_24, 0); lv_label_set_text(timeLabel, ""); lv_obj_t *powerSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(powerSection, LV_OPA_TRANSP, 0); lv_obj_set_size(powerSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(powerSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(powerSection, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_hor(powerSection, 5, 0); lv_obj_set_style_pad_ver(powerSection, 10, 0); lv_obj_t *powerLabelSection = lv_obj_create(powerSection); lv_obj_set_style_bg_opa(powerLabelSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(powerLabelSection, 0, 0); lv_obj_set_size(powerLabelSection, LV_PCT(35), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(powerLabelSection, 0, 0); lv_obj_remove_flag(powerLabelSection, LV_OBJ_FLAG_SCROLLABLE); powerMainLabel = lv_label_create(powerLabelSection); lv_obj_add_style(powerMainLabel, &text_24_semibold, 0); lv_label_set_text(powerMainLabel, "Мощность: "); lv_obj_t *balanceLabelSection = lv_obj_create(powerSection); lv_obj_set_style_bg_opa(balanceLabelSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(balanceLabelSection, 0, 0); lv_obj_set_size(balanceLabelSection, LV_PCT(50), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(balanceLabelSection, 0, 0); lv_obj_t *balanceLabel = lv_label_create(balanceLabelSection); lv_obj_add_style(balanceLabel, &text_24, 0); lv_label_set_text(balanceLabel, "Соблюдение баланса"); lv_obj_center(balanceLabel); lv_obj_t *balanceSwitchSection = lv_obj_create(powerSection); lv_obj_set_style_bg_opa(balanceSwitchSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(balanceSwitchSection, 0, 0); lv_obj_set_size(balanceSwitchSection, LV_PCT(10), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(balanceSwitchSection, 0, 0); balanceSwitch = lv_switch_create(balanceSwitchSection); lv_obj_add_state(balanceSwitch, LV_STATE_CHECKED); lv_obj_add_event_cb(balanceSwitch, balanceSwitchCb, LV_EVENT_VALUE_CHANGED, NULL); lv_obj_center(balanceSwitch); lv_obj_t *tempSupSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(tempSupSection, LV_OPA_TRANSP, 0); lv_obj_set_size(tempSupSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(tempSupSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(tempSupSection, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_remove_flag(tempSupSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_pad_all(tempSupSection, 0, 0); lv_obj_set_style_pad_hor(tempSupSection, 5, 0); lv_obj_set_style_pad_ver(tempSupSection, 5, 0); lv_obj_t *tempLabelSection = lv_obj_create(tempSupSection); lv_obj_set_style_bg_opa(tempLabelSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempLabelSection, 0, 0); lv_obj_set_size(tempLabelSection, LV_PCT(35), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempLabelSection, 0, 0); lv_obj_t *labelTempSup = lv_label_create(tempLabelSection); lv_obj_add_style(labelTempSup, &text_24_semibold, 0); lv_label_set_text(labelTempSup, "Приток"); lv_obj_t *tempStreetSection = lv_obj_create(tempSupSection); lv_obj_set_style_bg_opa(tempStreetSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempStreetSection, 0, 0); lv_obj_set_size(tempStreetSection, LV_PCT(20), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempStreetSection, 0, 0); labelTempSupStreet = lv_label_create(tempStreetSection); lv_obj_add_style(labelTempSupStreet, &text_24, 0); lv_label_set_text(labelTempSupStreet, ""); lv_obj_center(labelTempSupStreet); lv_obj_t *tempArrowSection = lv_obj_create(tempSupSection); lv_obj_set_style_bg_opa(tempArrowSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempArrowSection, 0, 0); lv_obj_set_size(tempArrowSection, LV_PCT(20), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempArrowSection, 0, 0); lv_obj_t *imgArrowSup = lv_img_create(tempArrowSection); lv_img_set_src(imgArrowSup, &arrow); lv_obj_set_style_img_recolor_opa(imgArrowSup, 255, 0); lv_obj_set_style_img_recolor(imgArrowSup, lv_palette_main(LV_PALETTE_BLUE), 0); lv_obj_set_size(imgArrowSup, 63, 65); lv_obj_center(imgArrowSup); lv_obj_t *tempHomeSection = lv_obj_create(tempSupSection); lv_obj_set_style_bg_opa(tempHomeSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempHomeSection, 0, 0); lv_obj_set_size(tempHomeSection, LV_PCT(20), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempHomeSection, 0, 0); labelTempSupHome = lv_label_create(tempHomeSection); lv_obj_add_style(labelTempSupHome, &text_24, 0); lv_label_set_text(labelTempSupHome, ""); lv_obj_center(labelTempSupHome); lv_obj_t *tempExhSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(tempExhSection, LV_OPA_TRANSP, 0); lv_obj_set_size(tempExhSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(tempExhSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(tempExhSection, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_remove_flag(tempExhSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_pad_all(tempExhSection, 0, 0); lv_obj_set_style_pad_hor(tempExhSection, 5, 0); lv_obj_set_style_pad_ver(tempExhSection, 5, 0); tempLabelSection = lv_obj_create(tempExhSection); lv_obj_set_style_bg_opa(tempLabelSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempLabelSection, 0, 0); lv_obj_set_size(tempLabelSection, LV_PCT(35), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempLabelSection, 0, 0); lv_obj_t *labelTempExh = lv_label_create(tempLabelSection); lv_obj_add_style(labelTempExh, &text_24_semibold, 0); lv_label_set_text(labelTempExh, "Вытяжка"); tempStreetSection = lv_obj_create(tempExhSection); lv_obj_set_style_bg_opa(tempStreetSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempStreetSection, 0, 0); lv_obj_set_size(tempStreetSection, LV_PCT(20), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempStreetSection, 0, 0); labelTempExhStreet = lv_label_create(tempStreetSection); lv_obj_add_style(labelTempExhStreet, &text_24, 0); lv_label_set_text(labelTempExhStreet, ""); lv_obj_center(labelTempExhStreet); tempArrowSection = lv_obj_create(tempExhSection); lv_obj_set_style_bg_opa(tempArrowSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempArrowSection, 0, 0); lv_obj_set_size(tempArrowSection, LV_PCT(20), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempArrowSection, 0, 0); lv_obj_t *imgArrowExh = lv_img_create(tempArrowSection); lv_img_set_src(imgArrowExh, &arrow); lv_obj_set_style_img_recolor_opa(imgArrowExh, 255, 0); lv_obj_set_style_img_recolor(imgArrowExh, lv_palette_main(LV_PALETTE_RED), 0); lv_img_set_angle(imgArrowExh, 1800); lv_obj_set_size(imgArrowExh, 63, 65); lv_obj_center(imgArrowExh); tempHomeSection = lv_obj_create(tempExhSection); lv_obj_set_style_bg_opa(tempHomeSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(tempHomeSection, 0, 0); lv_obj_set_size(tempHomeSection, LV_PCT(20), LV_SIZE_CONTENT); lv_obj_set_style_pad_all(tempHomeSection, 0, 0); labelTempExhHome = lv_label_create(tempHomeSection); lv_obj_add_style(labelTempExhHome, &text_24, 0); lv_label_set_text(labelTempExhHome, ""); lv_obj_center(labelTempExhHome); lv_obj_t *buttonSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(buttonSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(buttonSection, 0, 0); lv_obj_set_size(buttonSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(buttonSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(buttonSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_hor(buttonSection, 5, 0); lv_obj_set_style_pad_ver(buttonSection, 10, 0); lv_obj_set_style_pad_column(buttonSection, 50, 0); btnStartStop = lv_btn_create(buttonSection); lv_obj_add_event_cb(btnStartStop, startStopBtnCb, LV_EVENT_CLICKED, NULL); lv_obj_t *btnStartLabel = lv_label_create(btnStartStop); lv_obj_add_style(btnStartLabel, &text_28, 0); lv_label_set_text(btnStartLabel, "Пуск"); lv_obj_center(btnStartLabel); btnConditioner = lv_btn_create(buttonSection); lv_obj_add_event_cb(btnConditioner, conditionerBtnCb, LV_EVENT_CLICKED, NULL); lv_obj_set_size(btnConditioner, 70, 70); lv_obj_set_style_bg_opa(btnConditioner, LV_OPA_TRANSP, 0); lv_obj_set_style_border_color(btnConditioner, lv_palette_lighten(LV_PALETTE_GREY, 2), 0); lv_obj_set_style_border_width(btnConditioner, 3, 0); lv_obj_clear_flag(btnConditioner, LV_OBJ_FLAG_CLICKABLE); lv_obj_t *icon = lv_label_create(btnConditioner); lv_obj_set_style_text_color(icon, lv_palette_lighten(LV_PALETTE_GREY, 2), 0); lv_obj_set_style_text_font(icon, &lv_font_montserrat_24, 0); lv_label_set_text(icon, LV_SYMBOL_REFRESH); lv_obj_center(icon); } void createSettingsTab(lv_obj_t *parent) { lv_obj_t *tabviewSettings = lv_tabview_create(parent); lv_tabview_set_tab_bar_position(tabviewSettings, LV_DIR_TOP); lv_tabview_set_tab_bar_size(tabviewSettings, 70); lv_obj_add_style(tabviewSettings, &text_20_semibold, 0); lv_obj_add_event_cb(tabviewSettings, settingsTabviewEventCb, LV_EVENT_CLICKED, lv_tabview_get_tab_btns(tabviewSettings)); tabSettingsModeTime = lv_tabview_add_tab(tabviewSettings, "Режимы"); tabSettingsTime = lv_tabview_add_tab(tabviewSettings, "Время"); tabSettingsScreen = lv_tabview_add_tab(tabviewSettings, "Экран"); tabFilters = lv_tabview_add_tab(tabviewSettings, "Фильтры"); lv_obj_clear_flag(lv_tabview_get_content(tabviewSettings), LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_flex_flow(tabSettingsModeTime, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabSettingsModeTime, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabSettingsModeTime, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_flex_flow(tabSettingsTime, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabSettingsTime, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabSettingsTime, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_flex_flow(tabSettingsScreen, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabSettingsScreen, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabSettingsScreen, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_flex_flow(tabFilters, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabFilters, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabFilters, LV_OBJ_FLAG_SCROLLABLE); createModePage(tabSettingsModeTime); createTimePage(tabSettingsTime); createScreenPage(tabSettingsScreen); createFiltersPage(tabFilters); } void createModePage(lv_obj_t *parent) { lv_obj_t *rollersSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(rollersSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(rollersSection, 0, 0); lv_obj_set_size(rollersSection, LV_PCT(105), LV_PCT(80)); lv_obj_set_flex_flow(rollersSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(rollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(rollersSection, 0, 0); lv_obj_remove_flag(rollersSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *daySection = lv_obj_create(rollersSection); lv_obj_set_style_bg_opa(daySection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(daySection, 0, 0); lv_obj_set_size(daySection, LV_PCT(50), LV_SIZE_CONTENT); lv_obj_set_flex_flow(daySection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(daySection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(daySection, 0, 0); lv_obj_set_style_pad_right(daySection, 5, 0); lv_obj_remove_flag(daySection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *dayLabel = lv_label_create(daySection); lv_obj_add_style(dayLabel, &text_28, 0); lv_label_set_text(dayLabel, "Дневной режим"); lv_obj_t *dayRollersSection = lv_obj_create(daySection); lv_obj_set_style_bg_opa(dayRollersSection, LV_OPA_TRANSP, 0); lv_obj_set_size(dayRollersSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(dayRollersSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(dayRollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(dayRollersSection, 0, 0); lv_obj_set_style_pad_hor(dayRollersSection, 7, 0); lv_obj_set_style_pad_ver(dayRollersSection, 5, 0); lv_obj_remove_flag(dayRollersSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *timeSection = lv_obj_create(dayRollersSection); lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(timeSection, 0, 0); lv_obj_set_size(timeSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(timeSection, 0, 0); lv_obj_set_style_pad_column(timeSection, 5, 0); lv_obj_remove_flag(timeSection, LV_OBJ_FLAG_SCROLLABLE); rollerDayHour = createRoller(timeSection, rollerOptionsHour, ROLLER_ROWS_DEFAULT); lv_obj_t *labelColon = lv_label_create(timeSection); lv_obj_add_style(labelColon, &text_28, 0); lv_label_set_text(labelColon, ":"); rollerDayMinute = createRoller(timeSection, rollerOptionsMinute, ROLLER_ROWS_DEFAULT); char optionsPowerAuto[600]; createRollerOptions(20, 90, 1, 1, optionsPowerAuto, sizeof(optionsPowerAuto)); rollerDaymodePower = createRoller(dayRollersSection, optionsPowerAuto, ROLLER_ROWS_DEFAULT); lv_obj_set_width(rollerDaymodePower, 90); lv_obj_set_style_text_align(rollerDaymodePower, LV_TEXT_ALIGN_LEFT, 0); lv_obj_t *labelPercent = lv_label_create(rollerDaymodePower); lv_obj_add_style(labelPercent, &text_28, 0); lv_label_set_text(labelPercent, "%"); lv_obj_align(labelPercent, LV_ALIGN_CENTER, 20, 0); lv_obj_t *nightSection = lv_obj_create(rollersSection); lv_obj_set_style_bg_opa(nightSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(nightSection, 0, 0); lv_obj_set_size(nightSection, LV_PCT(50), LV_SIZE_CONTENT); lv_obj_set_flex_flow(nightSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(nightSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(nightSection, 0, 0); lv_obj_set_style_pad_left(nightSection, 5, 0); lv_obj_remove_flag(nightSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *nightLabel = lv_label_create(nightSection); lv_obj_add_style(nightLabel, &text_28, 0); lv_label_set_text(nightLabel, "Ночной режим"); lv_obj_t *nightRollersSection = lv_obj_create(nightSection); lv_obj_set_style_bg_opa(nightRollersSection, LV_OPA_TRANSP, 0); lv_obj_set_size(nightRollersSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(nightRollersSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(nightRollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(nightRollersSection, 0, 0); lv_obj_set_style_pad_hor(nightRollersSection, 7, 0); lv_obj_set_style_pad_ver(nightRollersSection, 5, 0); lv_obj_remove_flag(nightRollersSection, LV_OBJ_FLAG_SCROLLABLE); timeSection = lv_obj_create(nightRollersSection); lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(timeSection, 0, 0); lv_obj_set_size(timeSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(timeSection, 0, 0); lv_obj_set_style_pad_column(timeSection, 5, 0); lv_obj_remove_flag(timeSection, LV_OBJ_FLAG_SCROLLABLE); rollerNightHour = createRoller(timeSection, rollerOptionsHour, ROLLER_ROWS_DEFAULT); labelColon = lv_label_create(timeSection); lv_obj_add_style(labelColon, &text_28, 0); lv_label_set_text(labelColon, ":"); rollerNightMinute = createRoller(timeSection, rollerOptionsMinute, ROLLER_ROWS_DEFAULT); rollerNightmodePower = createRoller(nightRollersSection, optionsPowerAuto, ROLLER_ROWS_DEFAULT); lv_obj_set_width(rollerNightmodePower, 90); lv_obj_set_style_text_align(rollerNightmodePower, LV_TEXT_ALIGN_LEFT, 0); labelPercent = lv_label_create(rollerNightmodePower); lv_obj_add_style(labelPercent, &text_28, 0); lv_label_set_text(labelPercent, "%"); lv_obj_align(labelPercent, LV_ALIGN_CENTER, 20, 0); lv_obj_t *btnSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(btnSection, 0, 0); lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20)); lv_obj_set_style_pad_all(btnSection, 0, 0); lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE); btnOkModes = lv_btn_create(btnSection); lv_obj_add_event_cb(btnOkModes, OkBtnModeTimeCb, LV_EVENT_CLICKED, NULL); lv_obj_center(btnOkModes); lv_obj_add_flag(btnOkModes, LV_OBJ_FLAG_HIDDEN); lv_obj_t *btnOkLabel = lv_label_create(btnOkModes); lv_obj_add_style(btnOkLabel, &text_28, 0); lv_label_set_text(btnOkLabel, "Ок"); lv_obj_center(btnOkLabel); lv_obj_add_event_cb(rollerDayHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes); lv_obj_add_event_cb(rollerDayMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes); lv_obj_add_event_cb(rollerDaymodePower, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes); lv_obj_add_event_cb(rollerNightHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes); lv_obj_add_event_cb(rollerNightMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes); lv_obj_add_event_cb(rollerNightmodePower, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkModes); } void createTimePage(lv_obj_t *parent) { lv_obj_t *rollersSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(rollersSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(rollersSection, 0, 0); lv_obj_set_size(rollersSection, LV_PCT(100), LV_PCT(80)); lv_obj_set_flex_flow(rollersSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(rollersSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_style_pad_all(rollersSection, 0, 0); lv_obj_remove_flag(rollersSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *timeSection = lv_obj_create(rollersSection); lv_obj_set_style_bg_opa(timeSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(timeSection, 0, 0); lv_obj_set_size(timeSection, LV_PCT(50), LV_PCT(100)); lv_obj_set_flex_flow(timeSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(timeSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(timeSection, 10, 0); lv_obj_remove_flag(timeSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *labelTime = lv_label_create(timeSection); lv_obj_add_style(labelTime, &text_28, 0); lv_label_set_text(labelTime, "Время"); lv_obj_t *timeRollersSection = lv_obj_create(timeSection); lv_obj_set_style_bg_opa(timeRollersSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(timeRollersSection, 0, 0); lv_obj_set_size(timeRollersSection, LV_SIZE_CONTENT, LV_PCT(85)); lv_obj_set_flex_flow(timeRollersSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(timeRollersSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(timeRollersSection, 10, 0); lv_obj_remove_flag(timeRollersSection, LV_OBJ_FLAG_SCROLLABLE); rollerHour = createRoller(timeRollersSection, rollerOptionsHour, ROLLER_ROWS_DEFAULT); lv_obj_t *labelColon = lv_label_create(timeRollersSection); lv_obj_add_style(labelColon, &text_28, 0); lv_label_set_text(labelColon, ":"); rollerMinute = createRoller(timeRollersSection, rollerOptionsMinute, ROLLER_ROWS_DEFAULT); lv_obj_t *dateSection = lv_obj_create(rollersSection); lv_obj_set_style_bg_opa(dateSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(dateSection, 0, 0); lv_obj_set_size(dateSection, LV_PCT(50), LV_PCT(100)); lv_obj_set_flex_flow(dateSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(dateSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(dateSection, 10, 0); lv_obj_remove_flag(dateSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *labelDate = lv_label_create(dateSection); lv_obj_add_style(labelDate, &text_28, 0); lv_label_set_text(labelDate, "Дата"); lv_obj_t *dateDropdownSection = lv_obj_create(dateSection); lv_obj_set_style_bg_opa(dateDropdownSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(dateDropdownSection, 0, 0); lv_obj_set_size(dateDropdownSection, LV_SIZE_CONTENT, LV_PCT(85)); lv_obj_set_flex_flow(dateDropdownSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(dateDropdownSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(dateDropdownSection, 10, 0); lv_obj_set_style_pad_row(dateDropdownSection, 20, 0); lv_obj_remove_flag(dateDropdownSection, LV_OBJ_FLAG_SCROLLABLE); char optionsDay[128] = {0}; const char *optionsMonth = "Января\nФевраля\nМарта\nАпреля\nМая\nИюня\nИюля\nАвгуста\nСентября\nОктября\nНоября\nДекабря"; char optionsYear[512] = {0}; createRollerOptions(1, 31, 1, 1, optionsDay, sizeof(optionsDay)); createRollerOptions(2025, 2099, 1, 1, optionsYear, sizeof(optionsYear)); createDateSetting(dateDropdownSection, optionsDay, &ddDay); createDateSetting(dateDropdownSection, optionsMonth, &ddMonth); createDateSetting(dateDropdownSection, optionsYear, &ddYear); lv_obj_add_event_cb(ddMonth, ddDateCb, LV_EVENT_VALUE_CHANGED, NULL); lv_obj_add_event_cb(ddYear, ddDateCb, LV_EVENT_VALUE_CHANGED, NULL); lv_obj_t *btnSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(btnSection, 0, 0); lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20)); lv_obj_set_style_pad_all(btnSection, 0, 0); lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE); btnOkTime = lv_btn_create(btnSection); lv_obj_add_event_cb(btnOkTime, OkBtnTimeCb, LV_EVENT_CLICKED, NULL); lv_obj_center(btnOkTime); lv_obj_add_flag(btnOkTime, LV_OBJ_FLAG_HIDDEN); lv_obj_t *btnOkLabel = lv_label_create(btnOkTime); lv_obj_add_style(btnOkLabel, &text_28, 0); lv_label_set_text(btnOkLabel, "Ок"); lv_obj_center(btnOkLabel); lv_obj_add_event_cb(rollerHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime); lv_obj_add_event_cb(rollerMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime); lv_obj_add_event_cb(ddDay, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime); lv_obj_add_event_cb(ddMonth, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime); lv_obj_add_event_cb(ddYear, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTime); } void createScreenPage(lv_obj_t *parent) { lv_obj_t *mainSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(mainSection, 0, 0); lv_obj_set_size(mainSection, LV_PCT(100), LV_PCT(80)); lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(mainSection, 0, 0); lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *label = lv_label_create(mainSection); lv_obj_add_style(label, &text_28, 0); lv_label_set_text(label, "Выключение экрана"); lv_obj_t *minSection = lv_obj_create(mainSection); lv_obj_set_style_bg_opa(minSection, LV_OPA_TRANSP, 0); lv_obj_set_size(minSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_flex_flow(minSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(minSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(minSection, 10, 0); char rollerOptions[] = "1\n2\n5\n10\n15"; rollerScreenOff = lv_roller_create(minSection); lv_roller_set_options(rollerScreenOff, rollerOptions, LV_ROLLER_MODE_NORMAL); lv_roller_set_visible_row_count(rollerScreenOff, ROLLER_ROWS_DEFAULT); lv_obj_set_width(rollerScreenOff, 80); lv_obj_add_style(rollerScreenOff, &styleRollerMain, LV_PART_MAIN); lv_obj_add_style(rollerScreenOff, &styleRollerSelected, LV_PART_SELECTED); label = lv_label_create(minSection); lv_obj_add_style(label, &text_28, 0); lv_label_set_text(label, "мин."); lv_obj_t *btnSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(btnSection, 0, 0); lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20)); lv_obj_set_style_pad_all(btnSection, 0, 0); lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE); btnOkScreen = lv_btn_create(btnSection); lv_obj_add_event_cb(btnOkScreen, OkBtnScreenCb, LV_EVENT_CLICKED, NULL); lv_obj_center(btnOkScreen); lv_obj_add_flag(btnOkScreen, LV_OBJ_FLAG_HIDDEN); lv_obj_t *btnOkLabel = lv_label_create(btnOkScreen); lv_obj_add_style(btnOkLabel, &text_28, 0); lv_label_set_text(btnOkLabel, "Ок"); lv_obj_center(btnOkLabel); lv_obj_add_event_cb(rollerScreenOff, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkScreen); } void createFiltersPage(lv_obj_t *parent) { static const char *daysMap[] = { "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс", "" }; lv_obj_t *mainSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(mainSection, 0, 0); lv_obj_set_size(mainSection, LV_PCT(100), LV_PCT(80)); lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_EVENLY, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(mainSection, 0, 0); lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE); matrixFilterDays = lv_btnmatrix_create(mainSection); lv_obj_add_style(matrixFilterDays, &text_24, 0); lv_obj_set_style_bg_opa(matrixFilterDays, LV_OPA_TRANSP, LV_PART_MAIN); lv_obj_set_style_border_width(matrixFilterDays, 0, 0); lv_obj_set_style_bg_color(matrixFilterDays, lv_palette_main(LV_PALETTE_BLUE), LV_PART_ITEMS|LV_STATE_CHECKED); lv_obj_set_style_pad_all(matrixFilterDays, 10, LV_PART_MAIN); lv_obj_set_style_pad_gap(matrixFilterDays, 5, LV_PART_MAIN); lv_btnmatrix_set_map(matrixFilterDays, daysMap); lv_btnmatrix_set_btn_ctrl_all(matrixFilterDays, LV_BTNMATRIX_CTRL_CHECKABLE|LV_BTNMATRIX_CTRL_CLICK_TRIG); lv_btnmatrix_set_one_checked(matrixFilterDays, true); lv_btnmatrix_set_btn_ctrl(matrixFilterDays, 0, LV_BTNMATRIX_CTRL_CHECKED); lv_obj_set_size(matrixFilterDays, LV_PCT(95), 60); lv_obj_add_event_cb(matrixFilterDays, filterButtonsCb, LV_EVENT_VALUE_CHANGED, NULL); lv_obj_t *labelCheckTime = lv_label_create(mainSection); lv_obj_add_style(labelCheckTime, &text_28, 0); lv_label_set_text(labelCheckTime, "Время проверки"); lv_obj_align(labelCheckTime, LV_ALIGN_TOP_MID, 0, 70); lv_obj_t *timeRollersSection = lv_obj_create(mainSection); lv_obj_set_style_bg_opa(timeRollersSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(timeRollersSection, 0, 0); lv_obj_set_size(timeRollersSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_flex_flow(timeRollersSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(timeRollersSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(timeRollersSection, 10, 0); lv_obj_remove_flag(timeRollersSection, LV_OBJ_FLAG_SCROLLABLE); rollerFilterHour = createRoller(timeRollersSection, rollerOptionsHour, 4); lv_obj_t *labelColon = lv_label_create(timeRollersSection); lv_obj_add_style(labelColon, &text_28, 0); lv_label_set_text(labelColon, ":"); rollerFilterMinute = createRoller(timeRollersSection, rollerOptionsMinute, 4); lv_obj_t *btnSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(btnSection, 0, 0); lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20)); lv_obj_set_style_pad_all(btnSection, 0, 0); lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE); btnOkFilters = lv_btn_create(btnSection); lv_obj_add_event_cb(btnOkFilters, OkBtnFiltersCb, LV_EVENT_CLICKED, NULL); lv_obj_center(btnOkFilters); lv_obj_add_flag(btnOkFilters, LV_OBJ_FLAG_HIDDEN); lv_obj_t *btnOkLabel = lv_label_create(btnOkFilters); lv_obj_add_style(btnOkLabel, &text_28, 0); lv_label_set_text(btnOkLabel, "Ок"); lv_obj_center(btnOkLabel); lv_obj_add_event_cb(matrixFilterDays, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkFilters); lv_obj_add_event_cb(rollerFilterHour, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkFilters); lv_obj_add_event_cb(rollerFilterMinute, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkFilters); } void createServiceTab(lv_obj_t *parent) { passwordScreen = createPasswordInput(parent); lv_obj_t *tabview = lv_tabview_create(parent); lv_tabview_set_tab_bar_position(tabview, LV_DIR_TOP); lv_tabview_set_tab_bar_size(tabview, 70); lv_obj_add_flag(tabview, LV_OBJ_FLAG_HIDDEN); lv_obj_add_style(tabview, &text_20_semibold, 0); lv_obj_add_event_cb(tabview, serviceTabviewEventCb, LV_EVENT_CLICKED, lv_tabview_get_tab_btns(tabview)); lv_obj_clear_flag(tabview, LV_OBJ_FLAG_SCROLLABLE); lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE); tabIntervals = lv_tabview_add_tab(tabview, "Интервалы"); tabPower = lv_tabview_add_tab(tabview, "Мощность"); tabTemperature = lv_tabview_add_tab(tabview, "Температура"); lv_obj_set_flex_flow(tabIntervals, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabIntervals, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabIntervals, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_flex_flow(tabPower, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabPower, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabPower, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_flex_flow(tabTemperature, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabTemperature, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(tabTemperature, LV_OBJ_FLAG_SCROLLABLE); createIntervalsPage(tabIntervals); createServicePowerPage(tabPower); createTempAdjustPage(tabTemperature); } lv_obj_t *createPasswordInput(lv_obj_t *parent) { // Create a container for better layout control lv_obj_t *cont = lv_obj_create(parent); lv_obj_set_size(cont, LV_PCT(100), LV_PCT(100)); lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); // Create the text area for password input lv_obj_t* ta = lv_textarea_create(cont); lv_obj_set_width(ta, LV_PCT(80)); lv_obj_set_height(ta, 50); lv_textarea_set_password_mode(ta, true); lv_textarea_set_one_line(ta, true); lv_textarea_set_placeholder_text(ta, "Введите пароль"); lv_obj_add_style(ta, &text_28, 0); lv_obj_set_align(ta, LV_ALIGN_TOP_MID); lv_obj_t* kbContainer = lv_obj_create(cont); lv_obj_set_size(kbContainer, 400, 225); lv_obj_set_align(kbContainer, LV_ALIGN_BOTTOM_MID); lv_obj_clear_flag(kbContainer, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_bg_color(kbContainer, lv_palette_lighten(LV_PALETTE_GREY, 3), 0); lv_obj_set_style_border_width(kbContainer, 0, 0); // Create the keyboard with specified layout lv_obj_t* keyboard = lv_keyboard_create(kbContainer); lv_obj_set_style_text_font(keyboard, &lv_font_montserrat_24, 0); lv_obj_set_style_bg_opa(keyboard, LV_OPA_TRANSP, 0); lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kbMap, kbCtrlMap); lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1); lv_obj_set_size(keyboard, 400, 250); lv_obj_align(keyboard, LV_ALIGN_CENTER, 0, 25); lv_obj_add_event_cb(keyboard, passwordKeyboardEventCb, LV_EVENT_READY, NULL); // Link the text area to the keyboard lv_keyboard_set_textarea(keyboard, ta); return cont; } void createIntervalsPage(lv_obj_t *parent) { lv_obj_t *mainSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(mainSection, 0, 0); lv_obj_set_size(mainSection, LV_PCT(105), LV_PCT(80)); lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(mainSection, 0, 0); lv_obj_set_style_pad_ver(mainSection, 5, 0); lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *tempSection = lv_obj_create(mainSection); lv_obj_set_size(tempSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(tempSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(tempSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(tempSection, 0, 0); lv_obj_set_style_pad_hor(tempSection, 10, 0); lv_obj_set_style_pad_ver(tempSection, 4, 0); lv_obj_t *title = lv_label_create(tempSection); lv_label_set_text(title, "Интервал корректировки температуры (мин)"); lv_obj_add_style(title, &text_20, 0); lv_obj_set_width(title, LV_PCT(55)); lv_obj_t *spinbox = createSpinbox(tempSection, 1, 5, 1, 1, 0); spinboxTempInterval = lv_obj_get_child(spinbox, 1); lv_obj_t *rotorPauseSection = lv_obj_create(mainSection); lv_obj_set_size(rotorPauseSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(rotorPauseSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(rotorPauseSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(rotorPauseSection, 0, 0); lv_obj_set_style_pad_hor(rotorPauseSection, 10, 0); lv_obj_set_style_pad_ver(rotorPauseSection, 4, 0); title = lv_label_create(rotorPauseSection); lv_label_set_text(title, "Пауза между импульсами барабана (сек)"); lv_obj_add_style(title, &text_20, 0); lv_obj_set_width(title, LV_PCT(55)); spinbox = createSpinbox(rotorPauseSection, 10, 120, 10, 3, 0); spinboxRotorPause = lv_obj_get_child(spinbox, 1); lv_obj_t *rotorPulseSection = lv_obj_create(mainSection); lv_obj_set_size(rotorPulseSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(rotorPulseSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(rotorPulseSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(rotorPulseSection, 0, 0); lv_obj_set_style_pad_hor(rotorPulseSection, 10, 0); lv_obj_set_style_pad_ver(rotorPulseSection, 4, 0); title = lv_label_create(rotorPulseSection); lv_label_set_text(title, "Импульс барабана (мс)"); lv_obj_add_style(title, &text_20, 0); lv_obj_set_width(title, LV_PCT(55)); spinbox = createSpinbox(rotorPulseSection, 100, 1000, 100, 4, 0); spinboxRotorPulse = lv_obj_get_child(spinbox, 1); lv_obj_t *rotorNumSection = lv_obj_create(mainSection); lv_obj_set_size(rotorNumSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(rotorNumSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(rotorNumSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(rotorNumSection, 0, 0); lv_obj_set_style_pad_hor(rotorNumSection, 10, 0); lv_obj_set_style_pad_ver(rotorNumSection, 4, 0); title = lv_label_create(rotorNumSection); lv_label_set_text(title, "Количество барабанов"); lv_obj_add_style(title, &text_20, 0); lv_obj_set_width(title, LV_PCT(55)); spinbox = createSpinbox(rotorNumSection, 1, 11, 1, 2, 0); spinboxNumRotors = lv_obj_get_child(spinbox, 1); lv_obj_t *btnSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(btnSection, 0, 0); lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20)); lv_obj_set_style_pad_all(btnSection, 0, 0); lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE); btnOkIntervals = lv_btn_create(btnSection); lv_obj_add_event_cb(btnOkIntervals, OkBtnIntervalCb, LV_EVENT_CLICKED, NULL); lv_obj_center(btnOkIntervals); lv_obj_add_flag(btnOkIntervals, LV_OBJ_FLAG_HIDDEN); lv_obj_t *btnOkLabel = lv_label_create(btnOkIntervals); lv_obj_add_style(btnOkLabel, &text_28, 0); lv_label_set_text(btnOkLabel, "Ок"); lv_obj_center(btnOkLabel); lv_obj_add_event_cb(spinboxTempInterval, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals); lv_obj_add_event_cb(spinboxRotorPause, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals); lv_obj_add_event_cb(spinboxRotorPulse, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals); lv_obj_add_event_cb(spinboxNumRotors, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkIntervals); } void createServicePowerPage(lv_obj_t *parent) { lv_obj_t *mainSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(mainSection, 0, 0); lv_obj_set_size(mainSection, LV_PCT(105), LV_PCT(80)); lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(mainSection, 0, 0); lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *topSection = lv_obj_create(mainSection); lv_obj_set_style_bg_opa(topSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(topSection, 0, 0); lv_obj_set_size(topSection, LV_PCT(105), LV_SIZE_CONTENT); lv_obj_set_flex_flow(topSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(topSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(topSection, 0, 0); lv_obj_clear_flag(topSection, LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *supplySection = lv_obj_create(topSection); lv_obj_set_style_bg_opa(supplySection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(supplySection, 0, 0); lv_obj_set_size(supplySection, LV_PCT(50), LV_SIZE_CONTENT); lv_obj_set_flex_flow(supplySection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(supplySection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(supplySection, 5, 0); lv_obj_t *label = lv_label_create(supplySection); lv_obj_add_style(label, &text_28, 0); lv_label_set_text(label, "Приток"); lv_obj_t *rollerSection = lv_obj_create(supplySection); lv_obj_set_style_bg_opa(rollerSection, LV_OPA_TRANSP, 0); lv_obj_set_size(rollerSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_flex_flow(rollerSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(rollerSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(rollerSection, 10, 0); lv_obj_set_style_pad_column(rollerSection, 30, 0); labelServiceSup = lv_label_create(rollerSection); lv_obj_add_style(labelServiceSup, &text_28, 0); char powerOptions[300] = "0\n"; createRollerOptions(20, 100, 1, 1, powerOptions + 2, sizeof(powerOptions - 2)); rollerServiceSup = createRoller(rollerSection, powerOptions, ROLLER_ROWS_DEFAULT); ledSup = lv_led_create(rollerSection); lv_led_set_color(ledSup, lv_palette_main(LV_PALETTE_GREEN)); lv_led_off(ledSup); lv_obj_t *exhaustSection = lv_obj_create(topSection); lv_obj_set_style_bg_opa(exhaustSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(exhaustSection, 0, 0); lv_obj_set_size(exhaustSection, LV_PCT(50), LV_SIZE_CONTENT); lv_obj_set_flex_flow(exhaustSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(exhaustSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(exhaustSection, 5, 0); label = lv_label_create(exhaustSection); lv_obj_add_style(label, &text_28, 0); lv_label_set_text(label, "Вытяжка"); rollerSection = lv_obj_create(exhaustSection); lv_obj_set_style_bg_opa(rollerSection, LV_OPA_TRANSP, 0); lv_obj_set_size(rollerSection, LV_SIZE_CONTENT, LV_SIZE_CONTENT); lv_obj_set_flex_flow(rollerSection, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(rollerSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(rollerSection, 10, 0); lv_obj_set_style_pad_column(rollerSection, 30, 0); labelServiceExh = lv_label_create(rollerSection); lv_obj_add_style(labelServiceExh, &text_28, 0); rollerServiceExh = createRoller(rollerSection, powerOptions, ROLLER_ROWS_DEFAULT); ledExh = lv_led_create(rollerSection); lv_led_set_color(ledExh, lv_palette_main(LV_PALETTE_GREEN)); lv_led_off(ledExh); lv_obj_t *btnSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(btnSection, 0, 0); lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20)); lv_obj_set_style_pad_all(btnSection, 0, 0); lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE); btnOkPower = lv_btn_create(btnSection); lv_obj_add_event_cb(btnOkPower, OkBtnServicePowerCb, LV_EVENT_CLICKED, NULL); lv_obj_center(btnOkPower); lv_obj_add_flag(btnOkPower, LV_OBJ_FLAG_HIDDEN); lv_obj_t *btnOkLabel = lv_label_create(btnOkPower); lv_obj_add_style(btnOkLabel, &text_28, 0); lv_label_set_text(btnOkLabel, "Ок"); lv_obj_center(btnOkLabel); lv_obj_add_event_cb(rollerServiceSup, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkPower); lv_obj_add_event_cb(rollerServiceExh, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkPower); } void createTempAdjustPage(lv_obj_t *parent) { const char* labels[] = { "Приток с улицы", "Приток в помещение", "Вытяжка из помещения", "Вытяжка на улицу" }; lv_obj_t **tempLabels[] = {&labelServiceTempSupStreet, &labelServiceTempSupHome, &labelServiceTempExhStreet, &labelServiceTempExhHome}; lv_obj_t **tempSettings[] = {&spinboxServiceTempSupStreet, &spinboxServiceTempSupHome, &spinboxServiceTempExhStreet, &spinboxServiceTempExhHome}; lv_obj_t *mainSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(mainSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(mainSection, 0, 0); lv_obj_set_size(mainSection, LV_PCT(105), LV_PCT(80)); lv_obj_set_flex_flow(mainSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(mainSection, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_style_pad_all(mainSection, 0, 0); lv_obj_set_style_pad_ver(mainSection, 5, 0); lv_obj_remove_flag(mainSection, LV_OBJ_FLAG_SCROLLABLE); for (uint8_t i = 0; i < 4; i++) { lv_obj_t *line = createTempSetting(mainSection, labels[i], tempLabels[i], tempSettings[i]); } lv_obj_t *btnSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(btnSection, LV_OPA_TRANSP, 0); lv_obj_set_style_border_width(btnSection, 0, 0); lv_obj_set_size(btnSection, LV_PCT(105), LV_PCT(20)); lv_obj_set_style_pad_all(btnSection, 0, 0); lv_obj_remove_flag(btnSection, LV_OBJ_FLAG_SCROLLABLE); btnOkTemperature = lv_btn_create(btnSection); lv_obj_add_event_cb(btnOkTemperature, OkBtnTempAdjustCb, LV_EVENT_CLICKED, NULL); lv_obj_center(btnOkTemperature); lv_obj_add_flag(btnOkTemperature, LV_OBJ_FLAG_HIDDEN); lv_obj_t *btnOkLabel = lv_label_create(btnOkTemperature); lv_obj_add_style(btnOkLabel, &text_28, 0); lv_label_set_text(btnOkLabel, "Ок"); lv_obj_center(btnOkLabel); lv_obj_add_event_cb(spinboxServiceTempSupStreet, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature); lv_obj_add_event_cb(spinboxServiceTempSupHome, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature); lv_obj_add_event_cb(spinboxServiceTempExhStreet, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature); lv_obj_add_event_cb(spinboxServiceTempExhHome, valueChangedCb, LV_EVENT_VALUE_CHANGED, btnOkTemperature); } void createHelpTab(lv_obj_t *parent) { lv_obj_t *tabview = lv_tabview_create(parent); lv_tabview_set_tab_bar_position(tabview, LV_DIR_TOP); lv_tabview_set_tab_bar_size(tabview, 70); lv_obj_add_style(tabview, &text_20_semibold, 0); lv_obj_clear_flag(tabview, LV_OBJ_FLAG_SCROLLABLE); lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE); lv_obj_t *tabDescr = lv_tabview_add_tab(tabview, "Описание"); lv_obj_t *tabState = lv_tabview_add_tab(tabview, "Состояние"); lv_obj_t *tabContacts = lv_tabview_add_tab(tabview, "Контакты"); lv_obj_set_flex_flow(tabDescr, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabDescr, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_flex_flow(tabState, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabState, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_set_flex_flow(tabContacts, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tabContacts, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); createDescrPage(tabDescr); createStatePage(tabState); createContactPage(tabContacts); } void createDescrPage(lv_obj_t *parent) { lv_obj_t *label = lv_label_create(parent); lv_obj_add_style(label, &text_24, 0); lv_label_set_text(label, "На Главной странице отображаются основные параметры работы установки.\n\n" "В левом верхнем углу показан текущий режим работы - дневной или ночной."); lv_obj_set_width(label, LV_PCT(100)); createSliderDescr(parent, "Показывает состояние приточного фильтра.", lv_palette_main(LV_PALETTE_BLUE)); createSliderDescr(parent, "Показывает состояние вытяжного фильтра.", lv_palette_main(LV_PALETTE_RED)); label = lv_label_create(parent); lv_obj_add_style(label, &text_24, 0); lv_label_set_text(label, "Пустая шкала состояния фильтра означает, что фильтр засорен либо отсутствует."); lv_obj_set_width(label, LV_PCT(100)); createArrowDescr( parent, "Обозначает направление движения приточного воздуха: температура на улице → температура в помещении.", lv_palette_main(LV_PALETTE_BLUE), false ); createArrowDescr( parent, "Обозначает направление движения вытяжного воздуха: температура на улице ← температура в помещении.", lv_palette_main(LV_PALETTE_RED), true ); label = lv_label_create(parent); lv_obj_add_style(label, &text_24, 0); lv_label_set_text(label, "Переключатель \"Соблюдение баланса\" используется для включения автоматического поддержания " "баланса между приточным и удаляемым воздухом. Эта функция включена по умолчанию. Рекомендуется " "оставить включенным в исправной ПВУ."); lv_obj_set_width(label, LV_PCT(100)); label = lv_label_create(parent); lv_obj_add_style(label, &text_24, 0); lv_label_set_text(label, "Кнопка для включения режима \"Ночного бриза\":"); lv_obj_set_width(label, LV_PCT(100)); createConditionerBtnMock(parent, "Выключено", lv_palette_main(LV_PALETTE_GREY)); createConditionerBtnMock(parent, "Включено", lv_palette_main(LV_PALETTE_BLUE)); createConditionerBtnMock(parent, "Недоступно", lv_palette_lighten(LV_PALETTE_GREY, 2)); label = lv_label_create(parent); lv_obj_add_style(label, &text_24, 0); lv_label_set_text(label, "Кнопка \"Пуск/Стоп\" служит для запуска и остановки работы ПВУ.\n\n" "Страница Настроек позволяет настроить мощность вентиляции в зависимости от времени " "суток, текущие время и дату, время автоматического выключения экрана, " "а также время проверки состояния фильтров."); lv_obj_set_width(label, LV_PCT(100)); } void createStatePage(lv_obj_t *parent) { lv_obj_t *tempSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(tempSection, LV_OPA_TRANSP, 0); lv_obj_set_size(tempSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(tempSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(tempSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_style_pad_all(tempSection, 10, 0); lv_obj_set_style_pad_hor(tempSection, 15, 0); lv_obj_t *label = lv_label_create(tempSection); lv_obj_add_style(label, &text_24_semibold, 0); lv_label_set_text(label, "Температура"); createStateLine(tempSection, "Приток с улицы", &labelHelpTempSupStreet); createStateLine(tempSection, "Приток в помещение", &labelHelpTempSupHome); createStateLine(tempSection, "Вытяжка на улицу", &labelHelpTempExhStreet); createStateLine(tempSection, "Вытяжка из помещения", &labelHelpTempExhHome); createStateLine(tempSection, "КПД", &labelHelpKpd); lv_obj_add_flag(labelHelpKpd, LV_OBJ_FLAG_CLICKABLE); lv_obj_add_event_cb(labelHelpKpd, kpdLabelCb, LV_EVENT_CLICKED, tempSection); lv_obj_t *fanSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(fanSection, LV_OPA_TRANSP, 0); lv_obj_set_size(fanSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(fanSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(fanSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_style_pad_all(fanSection, 10, 0); lv_obj_set_style_pad_hor(fanSection, 15, 0); label = lv_label_create(fanSection); lv_obj_add_style(label, &text_24_semibold, 0); lv_label_set_text(label, "Мощность вентиляторов"); createStateLine(fanSection, "Приток", &labelHelpSup); createStateLine(fanSection, "Вытяжка", &labelHelpExh); rotorSection = lv_obj_create(parent); lv_obj_set_style_bg_opa(rotorSection, LV_OPA_TRANSP, 0); lv_obj_set_size(rotorSection, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_flex_flow(rotorSection, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(rotorSection, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); lv_obj_set_style_pad_all(rotorSection, 10, 0); lv_obj_set_style_pad_hor(rotorSection, 15, 0); label = lv_label_create(rotorSection); lv_obj_add_style(label, &text_24_semibold, 0); lv_label_set_text(label, "Скорость барабанов"); } void createContactPage(lv_obj_t *parent) { lv_obj_t *label = lv_label_create(parent); lv_obj_add_style(label, &text_24, 0); lv_label_set_text(label, "Контактная информация представлена на нашем сайте:"); lv_obj_set_width(label, LV_PCT(100)); label = lv_label_create(parent); lv_obj_add_style(label, &text_24_semibold, 0); lv_label_set_text(label, "https://vorteks.su/kontakty/"); lv_obj_set_width(label, LV_PCT(100)); label = lv_label_create(parent); lv_obj_add_style(label, &text_24, 0); lv_label_set_text(label, "vorteks@vorteks.su\n\n" "(383) 335-63-06,\n" "(383) 363-10-28,\n" "факс: 335-65-30."); lv_obj_set_width(label, LV_PCT(100)); } void createRotorSpeed(lv_obj_t *parent, uint8_t num) { for (uint8_t i = 0; i < num; i++) { char rotorText[20]; sprintf(rotorText, "Барабан %i", i + 1); rotorSpeedLine[i] = createStateLine(parent, rotorText, &labelRotorSpeed[i]); } } void createPopupScreen() { lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_SCROLLABLE); popupBg = lv_obj_create(lv_layer_top()); lv_obj_set_size(popupBg, LV_PCT(105), LV_PCT(105)); lv_obj_center(popupBg); lv_obj_set_style_bg_color(popupBg, lv_color_black(), 0); lv_obj_set_style_border_width(popupBg, 0, 0); lv_obj_set_style_bg_opa(popupBg, LV_OPA_70, 0); loadingLabel = lv_label_create(popupBg); lv_obj_add_style(loadingLabel, &text_28, 0); lv_label_set_text(loadingLabel, "Загрузка"); lv_obj_set_style_text_color(loadingLabel, lv_color_white(), 0); lv_obj_center(loadingLabel); } void updateConfigWidgets() { lv_obj_del(loadingLabel); uint8_t hour, min; lv_roller_set_selected(rollerDaymodePower, 30 - 20, LV_ANIM_OFF); lv_roller_set_selected(rollerNightmodePower, 20 - 20, LV_ANIM_OFF); lv_roller_set_selected(rollerDayHour, 10, LV_ANIM_OFF); lv_roller_set_selected(rollerDayMinute, 0, LV_ANIM_OFF); lv_roller_set_selected(rollerNightHour, 22, LV_ANIM_OFF); lv_roller_set_selected(rollerNightMinute, 0, LV_ANIM_OFF); selectedTestDay = 0; lv_btnmatrix_set_selected_btn(matrixFilterDays, 0); lv_btnmatrix_set_btn_ctrl(matrixFilterDays, 0, LV_BTNMATRIX_CTRL_CHECKED); lv_roller_set_selected(rollerFilterHour, 12, LV_ANIM_OFF); lv_roller_set_selected(rollerFilterMinute, 0, LV_ANIM_OFF); createRotorSpeed(rotorSection, 1); } void updateWidgets() { bool showPopup = false; // errorMask = (uint64_t) 1 << 5; for (uint8_t i = 0; i < 64; i++) { if (!(errorMask & (uint64_t) 1 << i)) { deletePopup(&popupWindows[i]); continue; } if (!popupWindows[i].window) { if (i == 0) { createPopup(popupBg, "Нет соединения с главным модулем", false, 0, &popupWindows[0]); } if (i == ERROR_FILT_SUP_MISSING) { createPopup(popupBg, "Отсутствует приточный фильтр", true, i, &popupWindows[i]); } else if (i == ERROR_FILT_EXH_MISSING) { createPopup(popupBg, "Отсутствует вытяжной фильтр", true, i, &popupWindows[i]); } else if (i == ERROR_FILT_SUP_DIRTY) { createPopup(popupBg, "Засорен приточный фильтр", true, i, &popupWindows[i]); } else if (i == ERROR_FILT_EXH_DIRTY) { createPopup(popupBg, "Засорен вытяжной фильтр", true, i, &popupWindows[i]); } else if (ERROR_ROTOR_BASE <= i && i < ERROR_MODULE_BASE) { char errText[150] = {0}; sprintf(errText, "Неисправен барабан %u. Устраните неисправность и перезагрузите устройство.", i - ERROR_ROTOR_BASE + 1); createPopup(popupBg, errText, false, i, &popupWindows[i]); } else if (ERROR_MODULE_BASE <= i) { char errText[100] = {0}; sprintf(errText, "Нет соединения с модулем расширения %u", i - ERROR_MODULE_BASE + 1); createPopup(popupBg, errText, true, i, &popupWindows[i]); } } if (!popupWindows[i].ignored) { showPopup = true; } } if (showPopup) { lv_obj_clear_flag(lv_layer_top(), LV_OBJ_FLAG_HIDDEN); } else { lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_HIDDEN); } lv_img_set_src(imgMode, &sun_yellow); // lv_img_set_src(imgMode, &moon_purple); lv_slider_set_value(sliderFilterSup, 0, LV_ANIM_ON); lv_slider_set_value(sliderFilterExh, 0, LV_ANIM_ON); static const char *const months[] = { "января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря" }; lv_label_set_text_fmt(dateLabel, "%u %s", 1, months[1 - 1]); lv_label_set_text(dayLabel, days[2]); lv_label_set_text_fmt(timeLabel, "%02i:%02i", 12, 0); lv_label_set_text_fmt(powerMainLabel, "Мощность: %u%%", state.speedB4); lv_label_set_text_fmt(labelTempSupStreet, "%.1f °C", state.te1 / 10.0f); lv_label_set_text_fmt(labelTempSupHome, "%.1f °C", state.te4 / 10.0f); lv_label_set_text_fmt(labelTempExhStreet, "%.1f °C", state.te3 / 10.0f); lv_label_set_text_fmt(labelTempExhHome, "%.1f °C", state.te2 / 10.0f); bool isStarted = state.mode & 0x01; if (isStarted && !btnStartStopIsStop) { setStartStopButtonState(true); } else if (!isStarted && btnStartStopIsStop) { setStartStopButtonState(false); } lv_label_set_text_fmt(labelServiceSup, "%u%%", state.speedB4); lv_label_set_text_fmt(labelServiceExh, "%u%%", state.speedB3); lv_led_on(ledSup); // lv_led_off(ledSup); // lv_led_on(ledExh); lv_led_off(ledExh); lv_label_set_text_fmt(labelServiceTempSupStreet, "%.1f °C", state.te1 / 10.0f); lv_label_set_text_fmt(labelServiceTempSupHome, "%.1f °C", state.te4 / 10.0f); lv_label_set_text_fmt(labelServiceTempExhStreet, "%.1f °C", state.te3 / 10.0f); lv_label_set_text_fmt(labelServiceTempExhHome, "%.1f °C", state.te2 / 10.0f); if (state.te1 <= -100) { // *10 disableConditionerBtn(); } else { enableConditionerBtn(); } lv_label_set_text_fmt(labelHelpTempSupStreet, "%.1f °C", state.te1 / 10.0f); lv_label_set_text_fmt(labelHelpTempSupHome, "%.1f °C", state.te4 / 10.0f); lv_label_set_text_fmt(labelHelpTempExhStreet, "%.1f °C", state.te3 / 10.0f); lv_label_set_text_fmt(labelHelpTempExhHome, "%.1f °C", state.te2 / 10.0f); if (state.kpd == KPD_NONE * 10) { lv_label_set_text(labelHelpKpd, "-"); } else { lv_label_set_text_fmt(labelHelpKpd, "%.1f%%", state.kpd / 10.0f); if (kpdHint) { lv_obj_del(kpdHint); kpdHint = NULL; } } lv_label_set_text_fmt(labelHelpSup, "%u%%", 30); lv_label_set_text_fmt(labelHelpExh, "%u%%", 30); lv_label_set_text_fmt(labelRotorSpeed[0], "%.2f об./час", (float) 100 / 100.0f); } void enableConditionerBtn() { if (btnConditionerEnabled) return; lv_obj_t *icon = lv_obj_get_child(btnConditioner, 0); btnConditionerState = false; lv_obj_set_style_border_color(btnConditioner, lv_palette_main(LV_PALETTE_GREY), 0); lv_obj_set_style_text_color(icon, lv_palette_main(LV_PALETTE_GREY), 0); lv_obj_add_flag(btnConditioner, LV_OBJ_FLAG_CLICKABLE); btnConditionerEnabled = true; } void disableConditionerBtn() { if (!btnConditionerEnabled) return; lv_obj_t *icon = lv_obj_get_child(btnConditioner, 0); btnConditionerState = false; lv_obj_set_style_border_color(btnConditioner, lv_palette_lighten(LV_PALETTE_GREY, 2), 0); lv_obj_set_style_text_color(icon, lv_palette_lighten(LV_PALETTE_GREY, 2), 0); lv_obj_clear_flag(btnConditioner, LV_OBJ_FLAG_CLICKABLE); btnConditionerEnabled = false; } void setConditionerBtnState(bool state) { if (btnConditionerState == state || !btnConditionerEnabled) return; lv_obj_t *btn = btnConditioner; lv_obj_t *icon = lv_obj_get_child(btn, 0); if (state) { lv_obj_set_style_border_color(btn, lv_palette_main(LV_PALETTE_BLUE), 0); lv_obj_set_style_text_color(icon, lv_palette_main(LV_PALETTE_BLUE), 0); } else { lv_obj_set_style_border_color(btn, lv_palette_main(LV_PALETTE_GREY), 0); lv_obj_set_style_text_color(icon, lv_palette_main(LV_PALETTE_GREY), 0); } btnConditionerState = state; } void setStartStopButtonState(bool isStop) { lv_obj_t *btn = btnStartStop; lv_obj_t *label = lv_obj_get_child(btn, 0); if (isStop) { lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN); lv_label_set_text(label, "Стоп"); lv_obj_center(label); } else { lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_BLUE), LV_PART_MAIN); lv_label_set_text(label, "Пуск"); lv_obj_center(label); } btnStartStopIsStop = isStop; } /* Callbacks */ static void passwordKeyboardEventCb(lv_event_t *e) { lv_obj_t *keyboard = lv_event_get_target(e); lv_obj_t *textArea = lv_keyboard_get_textarea(keyboard); lv_obj_t *mainScreen = lv_obj_get_child(tabService, 1); if (lv_event_get_code(e) == LV_EVENT_READY) { if (textArea) { int value = atoi(lv_textarea_get_text(textArea)); lv_textarea_set_text(textArea, ""); if (value == PASSWORD) { lv_obj_add_flag(passwordScreen, LV_OBJ_FLAG_HIDDEN); lv_obj_clear_flag(mainScreen, LV_OBJ_FLAG_HIDDEN); bool isStarted = state.mode & 0x01; uint16_t selectedOptionB3 = 0; uint16_t selectedOptionB4 = 0; if (isStarted) { selectedOptionB3 = CLAMP(state.speedB3, 20, 100) - 19; selectedOptionB4 = CLAMP(state.speedB4, 20, 100) - 19; } lv_roller_set_selected(rollerServiceSup, selectedOptionB4, LV_ANIM_OFF); lv_roller_set_selected(rollerServiceExh, selectedOptionB3, LV_ANIM_OFF); } } } } static void mainTabviewEventCb(lv_event_t *e) { lv_obj_t *matrix = lv_event_get_user_data(e); uint16_t currentTabId = lv_btnmatrix_get_selected_btn(matrix); // Get references to the service tab screens (assuming they're children of tabService) lv_obj_t *passwordScreen = lv_obj_get_child(tabService, 0); // First child lv_obj_t *mainScreen = lv_obj_get_child(tabService, 1); // Second child if (currentTabId != TAB_SERVICE_ID) { lv_obj_clear_flag(passwordScreen, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(mainScreen, LV_OBJ_FLAG_HIDDEN); } clearCurrentTab(); if (currentTabId == TAB_SETTINGS_ID) { currentTab = getActiveTabSettings(lv_tabview_get_tab_btns(tabSettings)); } else if (currentTabId == TAB_SERVICE_ID) { currentTab = getActiveTabService(lv_tabview_get_tab_btns(tabService)); } else { currentTab = NULL; } } static void settingsTabviewEventCb(lv_event_t *e) { clearCurrentTab(); currentTab = getActiveTabSettings(lv_event_get_user_data(e)); lv_roller_set_selected(rollerMinute, state.time % 60, LV_ANIM_OFF); lv_roller_set_selected(rollerHour, state.time / 60, LV_ANIM_OFF); lv_dropdown_set_selected(ddDay, state.date - 1); lv_dropdown_set_selected(ddMonth, state.month - 1); lv_dropdown_set_selected(ddYear, state.year - 2025); } static void serviceTabviewEventCb(lv_event_t *e) { clearCurrentTab(); currentTab = getActiveTabService(lv_event_get_user_data(e)); } static lv_obj_t *getActiveTabSettings(lv_obj_t *matrix) { uint16_t currentTabId = lv_btnmatrix_get_selected_btn(matrix); if (currentTabId == TAB_MODES) return tabSettingsModeTime; else if (currentTabId == TAB_TIME) return tabSettingsTime; else if (currentTabId == TAB_SCREEN) return tabSettingsScreen; else if (currentTabId == TAB_FILTERS) return tabFilters; else return NULL; } static lv_obj_t *getActiveTabService(lv_obj_t *matrix) { uint16_t currentTabId = lv_btnmatrix_get_selected_btn(matrix); if (currentTabId == TAB_INTERVALS) return tabIntervals; else if (currentTabId == TAB_POWER) return tabPower; else if (currentTabId == TAB_TEMPERATURE) return tabTemperature; else return NULL; } static void filterButtonsCb(lv_event_t *e) { selectedTestDay = lv_btnmatrix_get_selected_btn(matrixFilterDays); } static void balanceSwitchCb(lv_event_t *e) {} static void startStopBtnCb(lv_event_t *e) { setStartStopButtonState(!btnStartStopIsStop); } static void conditionerBtnCb(lv_event_t *e) { if (!btnConditionerEnabled) return; setConditionerBtnState(!btnConditionerState); } static void valueChangedCb(lv_event_t *e) { lv_obj_t *associatedBtn = lv_event_get_user_data(e); lv_obj_remove_flag(associatedBtn, LV_OBJ_FLAG_HIDDEN); } static void OkBtnModeTimeCb(lv_event_t *e) { lv_obj_t *btn = lv_event_get_target(e); lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); } static void OkBtnTimeCb(lv_event_t *e) { lv_obj_t *btn = lv_event_get_target(e); lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); } static void OkBtnScreenCb(lv_event_t *e) { lv_obj_t *btn = lv_event_get_target(e); lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); } static void OkBtnFiltersCb(lv_event_t *e) { lv_obj_t *btn = lv_event_get_target(e); lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); } static void OkBtnIntervalCb(lv_event_t *e) { lv_obj_t *btn = lv_event_get_target(e); lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); } static void OkBtnServicePowerCb(lv_event_t *e) { lv_obj_t *btn = lv_event_get_target(e); lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); } static void OkBtnTempAdjustCb(lv_event_t *e) { lv_obj_t *btn = lv_event_get_target(e); lv_obj_add_flag(btn, LV_OBJ_FLAG_HIDDEN); } static void kpdLabelCb(lv_event_t *e) { lv_obj_t *parent = lv_event_get_user_data(e); lv_obj_t *kpdLabel = lv_event_get_target(e); if (strcmp(lv_label_get_text(kpdLabel), "-") != 0) return; if (kpdHint) { lv_obj_del(kpdHint); kpdHint = NULL; return; } kpdHint = lv_label_create(parent); lv_obj_add_style(kpdHint, &text_24, 0); lv_obj_set_width(kpdHint, LV_PCT(100)); lv_label_set_text(kpdHint, "Значение КПД неактуально, когда разница температур внутри и снаружи меньше 10°C."); } static void ddDateCb(lv_event_t *e) { static const uint8_t monTable[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; uint16_t year = lv_dropdown_get_selected(ddYear) + 2025; uint16_t month = lv_dropdown_get_selected(ddMonth) + 1; uint16_t date = lv_dropdown_get_selected(ddDay) + 1; uint8_t numDays = isLeapYear(year) && month == 2 ? 29 : monTable[month - 1]; if (numDays == lv_dropdown_get_option_cnt(ddDay)) return; char optionsDay[128] = {0}; createRollerOptions(1, numDays, 1, 1, optionsDay, sizeof(optionsDay)); lv_dropdown_set_options(ddDay, optionsDay); lv_dropdown_set_selected(ddDay, MIN(date, numDays) - 1); } static void timePageClickedCb(lv_event_t *e) { } static void clearModesTab() { // uint8_t hour, min; // lv_roller_set_selected(rollerDaymodePower, CLAMP(config.daySpeed, 20, 90) - 20, LV_ANIM_OFF); // lv_roller_set_selected(rollerNightmodePower, CLAMP(config.nightSpeed, 20, 90) - 20, LV_ANIM_OFF); // hour = config.dayStart / 60; // min = config.dayStart % 60; // lv_roller_set_selected(rollerDayHour, hour, LV_ANIM_OFF); // lv_roller_set_selected(rollerDayMinute, min, LV_ANIM_OFF); // hour = config.nightStart / 60; // min = config.nightStart % 60; // lv_roller_set_selected(rollerNightHour, hour, LV_ANIM_OFF); // lv_roller_set_selected(rollerNightMinute, min, LV_ANIM_OFF); lv_obj_add_flag(btnOkModes, LV_OBJ_FLAG_HIDDEN); } static void clearTimeTab() { lv_roller_set_selected(rollerMinute, state.time % 60, LV_ANIM_OFF); lv_roller_set_selected(rollerHour, state.time / 60, LV_ANIM_OFF); lv_dropdown_set_selected(ddDay, state.date - 1); lv_dropdown_set_selected(ddMonth, state.month - 1); lv_dropdown_set_selected(ddYear, state.year - 2025); lv_obj_add_flag(btnOkTime, LV_OBJ_FLAG_HIDDEN); } static void clearScreenTab() { // lv_roller_set_selected(rollerScreenOff, config.screenOff, LV_ANIM_OFF); lv_obj_add_flag(btnOkScreen, LV_OBJ_FLAG_HIDDEN); } static void clearFiltersTab() { // selectedTestDay = config.testDay; // lv_btnmatrix_set_selected_btn(matrixFilterDays, config.testDay); // lv_btnmatrix_set_btn_ctrl(matrixFilterDays, config.testDay, LV_BTNMATRIX_CTRL_CHECKED); // hour = config.testTime / 60; // min = config.testTime % 60; // lv_roller_set_selected(rollerFilterHour, hour, LV_ANIM_OFF); // lv_roller_set_selected(rollerFilterMinute, min, LV_ANIM_OFF); lv_obj_add_flag(btnOkFilters, LV_OBJ_FLAG_HIDDEN); } static void clearIntervalsTab() { // lv_spinbox_set_value(spinboxTempInterval, config.adjustInterval); // lv_spinbox_set_value(spinboxRotorPause, config.rotorPause); // lv_spinbox_set_value(spinboxRotorPulse, config.rotorImpulse); // lv_spinbox_set_value(spinboxNumRotors, config.numRotors); lv_obj_add_flag(btnOkIntervals, LV_OBJ_FLAG_HIDDEN); } static void clearPowerTab() { bool isStarted = state.mode & 0x01; uint16_t selectedOptionB3 = 0; uint16_t selectedOptionB4 = 0; if (isStarted) { selectedOptionB3 = CLAMP(state.speedB3, 20, 100) - 19; selectedOptionB4 = CLAMP(state.speedB4, 20, 100) - 19; } lv_roller_set_selected(rollerServiceSup, selectedOptionB4, LV_ANIM_OFF); lv_roller_set_selected(rollerServiceExh, selectedOptionB3, LV_ANIM_OFF); lv_obj_add_flag(btnOkPower, LV_OBJ_FLAG_HIDDEN); } static void clearTemperatureTab() { // lv_spinbox_set_value(spinboxServiceTempSupStreet, config.temperatureCorrections[0]); // lv_spinbox_set_value(spinboxServiceTempSupHome, config.temperatureCorrections[3]); // lv_spinbox_set_value(spinboxServiceTempExhStreet, config.temperatureCorrections[2]); // lv_spinbox_set_value(spinboxServiceTempExhHome, config.temperatureCorrections[1]); lv_obj_add_flag(btnOkTemperature, LV_OBJ_FLAG_HIDDEN); } static void clearCurrentTab() { if (currentTab == tabSettingsModeTime) { clearModesTab(); } else if (currentTab == tabSettingsTime) { clearTimeTab(); } else if (currentTab == tabSettingsScreen) { clearScreenTab(); } else if (currentTab == tabFilters) { clearFiltersTab(); } else if (currentTab == tabIntervals) { clearIntervalsTab(); } else if (currentTab == tabPower) { clearPowerTab(); } else if (currentTab == tabTemperature) { clearTemperatureTab(); } }