#define MIN_HEIGHT 760*LV_VER_RES_MAX/1000
#define MIN_WIDTH 490*LV_HOR_RES_MAX/1000
const char* region = NULL;
bool MovingFlag = false;
bool ResizeFlag = false;
typedef struct {
bool isClosed;
bool isMinimized;
bool isFullScreen;
} WindowFlags;
WindowFlags objFlags[10];
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);
}
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 positions and sizes
lv_obj_set_x(windowTopbarFullScreenButton, new_width -220*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarMinimizeButton, new_width -280*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarCloseButton, new_width -340*LV_VER_RES_MAX/1000);
}
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 positions and sizes
lv_obj_set_x(windowTopbarFullScreenButton, new_width -220*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarMinimizeButton, new_width -280*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarCloseButton, new_width -340*LV_VER_RES_MAX/1000);
}
}
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);
}
lv_coord_t offset = -obj_height + 26; // fixed offset for window top bar
// Ensure the object stays within the top and bottom boundaries of the screen with offset
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 - offset) {
new_y = screen_height - obj_height - offset;
}
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 handle_fullscreen(lv_event_t *event) {
lv_event_code_t event_code = lv_event_get_code(event);
if (event_code == LV_EVENT_CLICKED) {
int type = lv_event_get_user_data(event);
lv_obj_t *obj = lv_event_get_target(event);
lv_obj_t *window = lv_obj_get_parent(obj);
lv_indev_t *indev = lv_indev_get_act();
lv_point_t vect;
lv_indev_get_vect(indev, &vect);
lv_coord_t screen_width = lv_obj_get_width(lv_scr_act());
lv_coord_t screen_height = LV_VER_RES_MAX - 100*LV_VER_RES_MAX/1000;
if (objFlags[type].isFullScreen == false)
{
objFlags[type].isFullScreen = true;
// Resize the window to match the screen size
lv_obj_set_size(window, screen_width, screen_height);
// Center the window on the screen
lv_obj_set_pos(window,0,100*LV_VER_RES_MAX/1000);
// Adjust button positions and sizes
lv_obj_set_x(windowTopbarFullScreenButton, screen_width -220*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarMinimizeButton, screen_width -280*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarCloseButton, screen_width -340*LV_VER_RES_MAX/1000);
} else if (objFlags[type].isFullScreen == true) {
objFlags[type].isFullScreen = false;
lv_obj_set_size(window, MIN_WIDTH,MIN_HEIGHT);
lv_obj_set_pos(window,LV_HOR_RES_MAX/4,LV_VER_RES_MAX/4);
// Adjust button positions and sizes
lv_obj_set_x(windowTopbarFullScreenButton, LV_HOR_RES_MAX/2 -220*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarMinimizeButton, LV_HOR_RES_MAX/2 -280*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarCloseButton, LV_HOR_RES_MAX/2 -340*LV_VER_RES_MAX/1000);
}
}
}
void handle_minimize(lv_event_t *event) {
lv_event_code_t event_code = lv_event_get_code(event);
if (event_code == LV_EVENT_CLICKED) {
int type = lv_event_get_user_data(event);
lv_obj_t *obj = lv_event_get_target(event);
lv_obj_t *window = lv_obj_get_parent(obj);
lv_indev_t *indev = lv_indev_get_act();
lv_point_t vect;
lv_indev_get_vect(indev, &vect);
lv_coord_t screen_width = lv_obj_get_width(lv_scr_act());
lv_coord_t screen_height = LV_VER_RES_MAX - 100*LV_VER_RES_MAX/1000;
if (objFlags[type].isMinimized == false)
{
objFlags[type].isMinimized = true;
lv_obj_set_size(window, LV_HOR_RES_MAX/2,LV_VER_RES_MAX/2);
lv_obj_set_pos(window,LV_HOR_RES_MAX/4,LV_VER_RES_MAX/4);
// Adjust button positions and sizes
lv_obj_set_x(windowTopbarFullScreenButton, LV_HOR_RES_MAX/2 -220*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarMinimizeButton, LV_HOR_RES_MAX/2 -280*LV_VER_RES_MAX/1000);
lv_obj_set_x(windowTopbarCloseButton, LV_HOR_RES_MAX/2 -340*LV_VER_RES_MAX/1000);
lv_obj_add_flag(window, LV_OBJ_FLAG_HIDDEN);
printf("minimized %d",type);
}
}
}
void handle_close(lv_event_t *event) {
lv_event_code_t event_code = lv_event_get_code(event);
if (event_code == LV_EVENT_CLICKED) {
int type = lv_event_get_user_data(event);
lv_obj_t *obj = lv_event_get_target(event);
lv_obj_t *window = lv_obj_get_parent(obj);
lv_indev_t *indev = lv_indev_get_act();
lv_point_t vect;
lv_indev_get_vect(indev, &vect);
lv_coord_t screen_width = lv_obj_get_width(lv_scr_act());
lv_coord_t screen_height = LV_VER_RES_MAX - 100*LV_VER_RES_MAX/1000;
if (objFlags[type].isClosed == false)
{
objFlags[type].isClosed = true;
lv_obj_del(window);
}
}
}
void windowUI_generator(int type,int sizeX, int sizeY) {
// Creating the main frame window
windowMainFrame[type] = lv_obj_create(Screen);
lv_obj_set_pos(windowMainFrame[type], LV_HOR_RES_MAX/2 - sizeX/2, LV_VER_RES_MAX/2 - sizeY/2);
lv_obj_set_size(windowMainFrame[type], sizeX, sizeY);
lv_obj_add_style(windowMainFrame[type], &style_WindowMainFrame, 0);
lv_obj_clear_flag(windowMainFrame[type], LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_event_cb(windowMainFrame[type], window_control_event_handler, LV_EVENT_LONG_PRESSED, NULL);
lv_obj_add_event_cb(windowMainFrame[type], drag_event_handler, LV_EVENT_PRESSING, NULL);
lv_obj_add_event_cb(windowMainFrame[type], resize_event_handler, LV_EVENT_PRESSING, NULL);
// Creating the full-screen button in the top bar
windowTopbarFullScreenButton = lv_btn_create(windowMainFrame[type]);
lv_obj_set_size(windowTopbarFullScreenButton, 12, 12);
lv_obj_align_to(windowTopbarFullScreenButton, windowMainFrame[type], LV_ALIGN_RIGHT_MID, 80 * LV_HOR_RES_MAX / 1000, -332.5 * LV_VER_RES_MAX / 1000);
lv_obj_add_style(windowTopbarFullScreenButton, &style_windowTopbarFullScreenButton, 0);
lv_obj_clear_flag(windowTopbarFullScreenButton, LV_OBJ_FLAG_SCROLLABLE);
// Creating the minimize button in the top bar
windowTopbarMinimizeButton = lv_btn_create(windowMainFrame[type]);
lv_obj_set_size(windowTopbarMinimizeButton, 12, 12);
lv_obj_align_to(windowTopbarMinimizeButton, windowTopbarFullScreenButton, 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);
// Creating the close button in the top bar
windowTopbarCloseButton = lv_btn_create(windowMainFrame[type]);
lv_obj_set_size(windowTopbarCloseButton, 12, 12);
lv_obj_align_to(windowTopbarCloseButton, windowTopbarMinimizeButton, LV_ALIGN_CENTER, -30 * LV_HOR_RES_MAX / 1000, 0);
lv_obj_add_style(windowTopbarCloseButton, &style_windowTopbarCloseButton, 0);
lv_obj_clear_flag(windowTopbarCloseButton, LV_OBJ_FLAG_SCROLLABLE);
// Creating the title frame
windowTitleFrame = lv_btn_create(windowMainFrame[type]);
lv_obj_set_size(windowTitleFrame, 220 * LV_HOR_RES_MAX / 1000, 80 * LV_VER_RES_MAX / 1000);
lv_obj_align_to(windowTitleFrame, windowMainFrame[type], LV_ALIGN_RIGHT_MID, -100 * LV_HOR_RES_MAX / 1000, -332.5 * LV_VER_RES_MAX / 1000);
lv_obj_add_style(windowTitleFrame, &style_windowTitleFrame, 0);
lv_obj_clear_flag(windowTitleFrame, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_clear_flag(windowTitleFrame, LV_OBJ_FLAG_CLICKABLE);
// Adding event callbacks for the buttons
lv_obj_add_event_cb(windowTopbarFullScreenButton, handle_fullscreen, LV_EVENT_ALL, type);
lv_obj_add_event_cb(windowTopbarMinimizeButton, handle_minimize, LV_EVENT_ALL, type);
lv_obj_add_event_cb(windowTopbarCloseButton, handle_close, LV_EVENT_ALL, type);
// Initializing object flags
objFlags[type].isClosed = false;
objFlags[type].isMinimized = false;
objFlags[type].isFullScreen = false;
printf("Generated");
}
void window_generator(int type, int sizeX, int sizeY) {
switch (type) {
case 1: // Simple window
windowUI_generator(type,sizeX,sizeY);
break;
case 2: // Chart window
windowUI_generator(type,sizeX,sizeY);
// Code for chart window
break;
}
}
void window_generatorCallback(lv_event_t * event){
int type = lv_event_get_user_data(event);
printf("Callback");
window_generator(type, 490*LV_HOR_RES_MAX / 1000, 760*LV_VER_RES_MAX/1000);
printf("%d",type);
}
void InitializeWindowsFlags(){
for (int i = 0; i < 10; ++i) {
objFlags[i].isClosed = true;
objFlags[i].isMinimized = false;
objFlags[i].isFullScreen = false;
}
}
1 Like
The code have been updated and now also supports Open,Close,Minimize
1 Like