How can I maintain a static appearance for the three buttons at the top of the window while adjusting the window size? Is there a way to achieve this effect using LVGL’s layout features?
This is what i have done so far
#define MIN_HEIGHT 100
#define MIN_WIDTH 150
const char* region = NULL;
bool MovingFlag = false;
bool ResizeFlag = false;
bool chartWindow = false; bool chartMinimized = false;
bool timerWindow = false; bool timerMinimized = false;
bool tempWindow = false; bool tempMinimized = false;
uint32_t WINDOW_LAYOUT;
void handle_resize(lv_obj_t *obj, const char *region) {
if (region != NULL) {
if (strcmp(region, "LEFT_MID") == 0 || strcmp(region, "RIGHT_MID") == 0 ) {
MovingFlag = true;
} else {
MovingFlag = false;
}
}
}
void handle_drag(lv_obj_t *obj, const char *region) {
if (region != NULL) {
handle_resize(&obj, ®ion);
// Handle the drag behavior only for TOP_MID region
if (strcmp(region, "TOP_MID") == 0) {
MovingFlag = true;
} else {
MovingFlag = false;
}
}
}
const char *determine_region(int touched_vertical_region, int touched_horizontal_region) {
if ((touched_vertical_region == 0 && touched_horizontal_region == 1) ||
(touched_vertical_region == 0 && touched_horizontal_region == 0) ||
(touched_vertical_region == 0 && touched_horizontal_region == 2)) {
return "TOP_MID";
} else if ((touched_vertical_region == 2 && touched_horizontal_region == 1) ||
(touched_vertical_region == 2 && touched_horizontal_region == 0) ||
(touched_vertical_region == 2 && touched_horizontal_region == 2)) {
return "BOTTOM_MID";
} else if (touched_vertical_region == 1 && touched_horizontal_region == 0) {
return "LEFT_MID";
} else if (touched_vertical_region == 1 && touched_horizontal_region == 2) {
return "RIGHT_MID";
} else {
return NULL;
}
}
static void resize_event_handler(lv_event_t *event) {
lv_obj_t *obj = lv_event_get_target(event);
lv_indev_t *indev = lv_indev_get_act();
if (indev == NULL) return;
lv_point_t vect;
lv_indev_get_vect(indev, &vect);
lv_coord_t obj_width = lv_obj_get_width(obj);
lv_coord_t obj_height = lv_obj_get_height(obj);
if (region && strcmp(region, "BOTTOM_MID") == 0) {
lv_coord_t new_height = obj_height + vect.y;
lv_coord_t new_width = obj_width - vect.x;
// Ensure the object height doesn't become too small
if (new_height < MIN_HEIGHT) {
new_height = MIN_HEIGHT;
}
// Ensure the object stays within the top and bottom boundaries of the screen
lv_coord_t screen_height = lv_obj_get_height(lv_scr_act());
if (lv_obj_get_y(obj) + new_height > screen_height) {
new_height = screen_height - lv_obj_get_y(obj);
}
lv_obj_set_height(obj, new_height);
// Adjust button and title frame positions and sizes
lv_obj_align(windowTopbarCloseButton, LV_ALIGN_CENTER, new_width * 25 / 100, -new_height * 43 / 100);
lv_obj_align_to(windowTopbarMinimizeButton, windowTopbarCloseButton, LV_ALIGN_CENTER, new_width * 10 / 100, 0);
lv_obj_align_to(windowTopbarFullScreenButton, windowTopbarMinimizeButton, LV_ALIGN_CENTER, new_width * 10 / 100, 0);
lv_obj_align(windowTitleFrame, LV_ALIGN_LEFT_MID, (new_width * 5 / 100) - 90*LV_HOR_RES_MAX/1000, -new_height * 44 / 100);
}
else if (region && strcmp(region, "LEFT_MID") == 0) {
lv_coord_t new_width = obj_width - vect.x;
lv_coord_t new_x = lv_obj_get_x(obj) + vect.x;
// Ensure the object width doesn't become too small
if (new_width < MIN_WIDTH) {
new_width = MIN_WIDTH;
new_x = lv_obj_get_x(obj) + obj_width - MIN_WIDTH;
}
// Ensure the object stays within the left and right boundaries of the screen
if (new_x < 0) {
new_x = 0;
}
lv_coord_t screen_width = lv_obj_get_width(lv_scr_act());
if (new_x + new_width > screen_width) {
new_width = screen_width - new_x;
}
lv_obj_set_width(obj, new_width);
lv_obj_set_x(obj, new_x);
// Adjust button and title frame positions and sizes
lv_obj_align(windowTopbarCloseButton, LV_ALIGN_CENTER, new_width * 25 / 100, -obj_height * 43 / 100);
lv_obj_align_to(windowTopbarMinimizeButton, windowTopbarCloseButton, LV_ALIGN_CENTER, new_width * 10 / 100, 0);
lv_obj_align_to(windowTopbarFullScreenButton, windowTopbarMinimizeButton, LV_ALIGN_CENTER, new_width * 10 / 100, 0);
lv_obj_align(windowTitleFrame, LV_ALIGN_LEFT_MID, (new_width * 5 / 100) - 90*LV_HOR_RES_MAX/1000, -obj_height * 44 / 100);
}
else if (region && strcmp(region, "RIGHT_MID") == 0) {
lv_coord_t new_width = obj_width + vect.x;
// Ensure the object width doesn't become too small
if (new_width < MIN_WIDTH) {
new_width = MIN_WIDTH;
}
// Ensure the object stays within the left and right boundaries of the screen
lv_coord_t screen_width = lv_obj_get_width(lv_scr_act());
if (lv_obj_get_x(obj) + new_width > screen_width) {
new_width = screen_width - lv_obj_get_x(obj);
}
lv_obj_set_width(obj, new_width);
// Adjust button and title frame positions and sizes
lv_obj_align(windowTopbarCloseButton, LV_ALIGN_CENTER, new_width * 25 / 100, -obj_height * 43 / 100);
lv_obj_align_to(windowTopbarMinimizeButton, windowTopbarCloseButton, LV_ALIGN_CENTER, new_width * 10 / 100, 0);
lv_obj_align_to(windowTopbarFullScreenButton, windowTopbarMinimizeButton, LV_ALIGN_CENTER, new_width * 10 / 100, 0);
lv_obj_align(windowTitleFrame, LV_ALIGN_LEFT_MID, (new_width * 5 / 100) - 90*LV_HOR_RES_MAX/1000, -obj_height * 44 / 100);
}
}
static void drag_event_handler(lv_event_t * event) {
if ((region && strcmp(region, "TOP_MID") == 0)) {
lv_obj_t * obj = lv_event_get_target(event);
lv_indev_t * indev = lv_indev_get_act();
if (indev == NULL) return;
lv_point_t vect;
lv_indev_get_vect(indev, &vect);
lv_coord_t obj_height = lv_obj_get_height(obj);
lv_coord_t new_x = lv_obj_get_x(obj) + vect.x;
lv_coord_t new_y = lv_obj_get_y(obj) + vect.y;
// Ensure the object stays within the left and right boundaries of the screen
if (new_x < 0) {
new_x = 0;
}
lv_coord_t screen_width = lv_obj_get_width(lv_scr_act());
if (new_x + lv_obj_get_width(obj) > screen_width) {
new_x = screen_width - lv_obj_get_width(obj);
}
// Ensure the object stays within the top and bottom boundaries of the screen
if (new_y < 0) {
new_y = 0;
}
lv_coord_t screen_height = lv_obj_get_height(lv_scr_act());
if (new_y + obj_height > screen_height) {
new_y = screen_height - obj_height;
}
lv_obj_set_pos(obj, new_x, new_y);
}
}
void window_control_event_handler(lv_event_t *event) {
lv_obj_t *obj = lv_event_get_target(event);
lv_event_code_t event_code = lv_event_get_code(event);
if (event_code == LV_EVENT_LONG_PRESSED_REPEAT || event_code == LV_EVENT_LONG_PRESSED) {
lv_point_t point;
lv_indev_get_point(lv_indev_get_act(), &point); // Get touch coordinates
lv_coord_t obj_x = lv_obj_get_x(obj);
lv_coord_t obj_y = lv_obj_get_y(obj);
lv_coord_t obj_width = lv_obj_get_width(obj);
lv_coord_t obj_height = lv_obj_get_height(obj);
// Calculate touch position relative to the object
lv_coord_t touch_x = point.x - obj_x;
lv_coord_t touch_y = point.y - obj_y;
lv_coord_t third_width = obj_width / 3;
lv_coord_t third_height = obj_height / 3;
int touched_horizontal_region = touch_x / third_width;
int touched_vertical_region = touch_y / third_height;
// Determine the current region based on touch coordinates
region = determine_region(touched_vertical_region, touched_horizontal_region);
// Update label and handle drag behavior
handle_drag(obj, region);
}
}
void window_generator(int type,int sizeX, int sizeY) {
switch (type){
case 1: {// temperature window
windowMainFrame[1] = lv_obj_create(Screen);
lv_obj_set_pos(windowMainFrame[1], LV_HOR_RES_MAX/2 - sizeX/2, LV_VER_RES_MAX/2 - sizeY/2);
lv_obj_set_size(windowMainFrame[1], sizeX, sizeY);
lv_obj_add_style(windowMainFrame[1],&style_WindowMainFrame,0);
lv_obj_clear_flag(windowMainFrame[1], LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_event_cb(windowMainFrame[1], window_control_event_handler, LV_EVENT_LONG_PRESSED, NULL);
lv_obj_add_event_cb(windowMainFrame[1], drag_event_handler, LV_EVENT_PRESSING, NULL);
lv_obj_add_event_cb(windowMainFrame[1], resize_event_handler, LV_EVENT_PRESSING, NULL);
windowTopbarCloseButton = lv_btn_create(windowMainFrame[1]);
lv_obj_set_size(windowTopbarCloseButton, 12 , 12 );
lv_obj_align(windowTopbarCloseButton, LV_ALIGN_CENTER, 180*LV_HOR_RES_MAX/1000, -320*LV_VER_RES_MAX/1000);
lv_obj_add_style(windowTopbarCloseButton,&style_windowTopbarCloseButton,0);
lv_obj_clear_flag(windowTopbarCloseButton, LV_OBJ_FLAG_SCROLLABLE);
windowTopbarMinimizeButton = lv_btn_create(windowMainFrame[1]);
lv_obj_set_size(windowTopbarMinimizeButton, 12 , 12 );
lv_obj_align_to(windowTopbarMinimizeButton, windowTopbarCloseButton, LV_ALIGN_CENTER, -30*LV_HOR_RES_MAX/1000, 0);
lv_obj_add_style(windowTopbarMinimizeButton,&style_windowTopbarMinimizeButton,0);
lv_obj_clear_flag(windowTopbarMinimizeButton, LV_OBJ_FLAG_SCROLLABLE);
windowTopbarFullScreenButton = lv_btn_create(windowMainFrame[1]);
lv_obj_set_size(windowTopbarFullScreenButton, 12 , 12 );
lv_obj_align_to(windowTopbarFullScreenButton, windowTopbarMinimizeButton, LV_ALIGN_CENTER, -30*LV_HOR_RES_MAX/1000, 0);
lv_obj_add_style(windowTopbarFullScreenButton,&style_windowTopbarFullScreenButton,0);
lv_obj_clear_flag(windowTopbarFullScreenButton, LV_OBJ_FLAG_SCROLLABLE);
windowTitleFrame = lv_obj_create(windowMainFrame[1]);
lv_obj_align(windowTitleFrame, LV_ALIGN_LEFT_MID, - 70*LV_HOR_RES_MAX/1000, -320*LV_VER_RES_MAX/1000);
lv_obj_set_size(windowTitleFrame, 200*LV_HOR_RES_MAX/1000, 80*LV_VER_RES_MAX/1000 );
lv_obj_add_style(windowTitleFrame,&style_windowTitleFrame,0);
lv_obj_clear_flag(windowTitleFrame, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_align(windowTitleFrame, LV_ALIGN_LEFT_MID);
break;
case 2: // chart window
break;
case 3: // timer window
break;
}
}
}