#include <lvgl.h>
#include <TFT_eSPI.h>
// Global references for widgets so callbacks can control them
static lv_obj_t * slider_label;
static lv_obj_t * left_led;
static lv_obj_t * right_led;
// Callback: Updates the text percentage below the slider as you drag it
static void slider_event_cb(lv_event_t * e) {
lv_obj_t * slider = lv_event_get_target(e);
int value = (int)lv_slider_get_value(slider);
lv_label_set_text_fmt(slider_label, "%d%%", value);
}
// Callback: Toggles the Dark Gray LED when the Switch changes state
static void switch_event_cb(lv_event_t * e) {
lv_obj_t * sw = lv_event_get_target(e);
if(lv_obj_has_state(sw, LV_STATE_CHECKED)) {
lv_led_on(left_led);
} else {
lv_led_off(left_led);
}
}
// Callback: Flashes or toggles the Olive Green LED when the "Left" Button is clicked
static void button_event_cb(lv_event_t * e) {
// Toggle the right LED state every time the button is pressed
if(lv_led_get_brightness(right_led) > 0) {
lv_led_off(right_led);
} else {
lv_led_on(right_led);
}
}
void create_cyd_mockup_ui() {
// 1. Screen canvas background color (light gray with subtle blue tint)
lv_obj_t * scr = lv_scr_act();
lv_obj_set_style_bg_color(scr, lv_color_hex(0xDCE4EC), LV_PART_MAIN);
// 2. Main Top Header Label
lv_obj_t * header_label = lv_label_create(scr);
lv_label_set_text(header_label, "Hello, Kafkar.com!");
lv_obj_set_style_text_color(header_label, lv_color_hex(0x333333), LV_PART_MAIN);
lv_obj_align(header_label, LV_ALIGN_TOP_MID, 0, 25);
// 3. Central Toggle Switch
lv_obj_t * sw = lv_switch_create(scr);
lv_obj_align(sw, LV_ALIGN_TOP_MID, 0, 65);
lv_obj_add_state(sw, LV_STATE_CHECKED); // Match the active state in image
lv_obj_set_style_bg_color(sw, lv_color_hex(0x5B7CFA), LV_PART_INDICATOR | LV_STATE_CHECKED);
lv_obj_add_event_cb(sw, switch_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
// 4. Central "Left" Button
lv_obj_t * btn = lv_btn_create(scr);
lv_obj_set_size(btn, 70, 35);
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 10);
lv_obj_set_style_bg_color(btn, lv_color_hex(0x5B7CFA), LV_PART_MAIN);
lv_obj_set_style_radius(btn, 8, LV_PART_MAIN); // Clean rounded edges
lv_obj_add_event_cb(btn, button_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_t * btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "Left");
lv_obj_center(btn_label);
// 5. Left Indicator (Dark Gray Circle)
left_led = lv_led_create(scr);
lv_obj_set_size(left_led, 20, 20);
lv_obj_align(left_led, LV_ALIGN_CENTER, -65, 10);
lv_led_set_color(left_led, lv_color_hex(0x5A5A52));
lv_led_on(left_led); // Starts active matching the picture
// 6. Right Indicator (Olive Green Circle)
right_led = lv_led_create(scr);
lv_obj_set_size(right_led, 24, 24); // Proportionally larger as seen in your photo
lv_obj_align(right_led, LV_ALIGN_CENTER, 65, 25);
lv_led_set_color(right_led, lv_color_hex(0x7D8E2B));
lv_led_on(right_led);
// 7. Bottom Horizontal Slider Track
lv_obj_t * slider = lv_slider_create(scr);
lv_obj_set_size(slider, 200, 12);
lv_obj_align(slider, LV_ALIGN_BOTTOM_MID, 0, -60);
lv_slider_set_value(slider, 0, LV_ANIM_OFF); // Starts at 0%
// Style adjustments to look sleek and blue
lv_obj_set_style_bg_color(slider, lv_color_hex(0x5B7CFA), LV_PART_INDICATOR);
lv_obj_set_style_bg_color(slider, lv_color_hex(0x5B7CFA), LV_PART_KNOB);
lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
// 8. Percentage Label centered right below the slider
slider_label = lv_label_create(scr);
lv_label_set_text(slider_label, "0%");
lv_obj_set_style_text_color(slider_label, lv_color_hex(0x555555), LV_PART_MAIN);
lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 15);
}
void setup() {
Serial.begin(115200);
// Core LVGL Initialization
lv_init();
// NOTE: Ensure your existing TFT_eSPI & XPT2046 touch drivers
// register their read callbacks here so hardware touch translates to LVGL.
create_cyd_mockup_ui();
}
void loop() {
lv_timer_handler(); /* Let the LVGL engine refresh state */
delay(5);
}