Browse Source

added rounded root panel rendering

Iver 1 month ago
parent
commit
3d5ce22b2d
3 changed files with 148 additions and 22 deletions
  1. 22 6
      src/headers/lemonguice.h
  2. 10 3
      src/launch_program/main.c
  3. 116 13
      src/library/main.c

+ 22 - 6
src/headers/lemonguice.h

@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include "../headers/sourparse.h"
+#include <SDL2/SDL.h>
 
 enum {
     LG_WIDGET_TYPE_PANEL = 0,
@@ -22,6 +23,13 @@ enum {
     LG_WIDGET_ALIGNMENT_DOWN = 5,
 };
 
+typedef struct {
+    SDL_Window* sdl_window;
+    SDL_Renderer* sdl_renderer;
+    SDL_Texture* sdl_window_texture;
+    uint32_t* frame_buffer;
+    uint16_t width, height;
+} LG_window_data;
 
 typedef struct {
     uint32_t* image_data;
@@ -46,8 +54,8 @@ typedef struct {
     uint32_t background_color;
     
     uint32_t border_color;
-    uint32_t border_size;
-    uint32_t border_radius;
+    uint16_t border_size;
+    uint16_t radius;
     
     int32_t width;
     int32_t height;
@@ -90,7 +98,7 @@ typedef struct {
     LG_text_data text_data;
 } LG_text_widget_data;
 
-typedef struct {
+typedef struct LG_widget {
     uint32_t type; // 0 panel, 1 text, 2 button, 3 input, 4 image
     uint32_t id;
     LG_image_widget_data image_widget_data;
@@ -98,9 +106,10 @@ typedef struct {
     LG_button_widget_data button_widget_data;
     LG_text_widget_data text_widget_data;
     LG_widget_style* widget_style;
-    LG_widget** children;
+    struct LG_widget** children;
     uint32_t child_count;
-    LG_widget* parent;
+    struct LG_widget* parent;
+    LG_window_data* window_data;
 } LG_widget;
 
 typedef struct {
@@ -108,6 +117,7 @@ typedef struct {
     LG_font_style* default_font_style;
     LG_widget* default_widget;
     uint32_t current_id;
+    uint16_t current_window_panel_count;
 } LG_context;
 
 // functions
@@ -116,7 +126,7 @@ LG_font_face* LG_new_font_face(char* filename);
 
 LG_font_style* LG_new_font_style();
 
-LG_widget* LG_new_window();
+LG_widget* LG_new_window(char* title, uint16_t width, uint16_t height);
 
 LG_widget* LG_add_panel_widget(LG_widget* parent_widget);
 
@@ -126,4 +136,10 @@ LG_widget* LG_add_button_widget(LG_widget* parent_widget);
 
 LG_image* LG_load_image(char* filename);
 
+int LG_render_window(LG_widget* window_widget);
+
+int LG_init();
+
+LG_context* LG_get_context();
+
 #endif // LEMON_GUICE_H

+ 10 - 3
src/launch_program/main.c

@@ -1,4 +1,4 @@
-#include "src/headers/lemonguice.h"
+#include "../headers/lemonguice.h"
 
 int main(){
     LG_init(); // init
@@ -11,10 +11,10 @@ int main(){
     font_style->font_size = 20;
 
 
-    LG_widget* root_panel = LG_new_window(); // create new SDL window, return the root panel 
+    LG_widget* root_panel = LG_new_window("LemonGUIce", 800, 800); // create new SDL window, return the root panel 
 
     // LG_add_child_panel(root_panel, new_panel); // maybe?
-
+/*
     LG_widget* left_panel = LG_new_child_panel(root_panel);
     LG_widget* right_panel = LG_new_child_panel(root_panel);
 
@@ -33,6 +33,13 @@ int main(){
     LG_widget* image = LG_add_image_widget(right_panel);
 
     image->image_widget_data.image = LG_load_image("images/test_image.bmp");
+*/
+
+    LG_context* context = LG_get_context();
+
+    while (context->current_window_panel_count){
+        LG_render_window(root_panel);
+    }
 
     return 0;
 }

+ 116 - 13
src/library/main.c

@@ -1,9 +1,13 @@
-#include "headers/lemonguice.h"
-#include "headers/sourparse.h"
-#include "headers/pitmap.h"
+#include "../headers/lemonguice.h"
+#include "../headers/sourparse.h"
+#include "../headers/pitmap.h"
 
 LG_context context;
 
+LG_context* LG_get_context(){
+    return &context;
+}
+
 LG_font_face* LG_new_font_face(char* filename){
     LG_font_face* font_face = malloc(sizeof(LG_font_face));
     
@@ -13,23 +17,50 @@ LG_font_face* LG_new_font_face(char* filename){
 }
 
 LG_font_style* LG_new_font_style(){
-    LG_font_style* font_style = malloc(sizeof(LG_new_font_style));
+    LG_font_style* font_style = malloc(sizeof(LG_font_style));
 
     *font_style = *context.default_font_style;
 
     return font_style;
 }
 
-LG_widget* LG_new_window(){
+LG_widget* LG_new_window(char* title, uint16_t width, uint16_t height){
     LG_widget* widget = malloc(sizeof(LG_widget));
+  
+    *widget = *context.default_widget;    
 
-    *widget = *context.default_widget;
-
+    widget->window_data = malloc(sizeof(LG_window_data));
+    
     widget->id = context.current_id++;
     widget->children = NULL;
     widget->parent = NULL;
     widget->type = LG_WIDGET_TYPE_PANEL;
 
+    widget->window_data->width = width;
+    widget->window_data->height = height;
+
+    widget->window_data->sdl_window = SDL_CreateWindow(
+        title, 
+        SDL_WINDOWPOS_CENTERED, 
+        SDL_WINDOWPOS_CENTERED, 
+        width, 
+        height, 0
+    );
+    widget->window_data->sdl_renderer = SDL_CreateRenderer(widget->window_data->sdl_window, -1, SDL_RENDERER_ACCELERATED);
+    widget->window_data->sdl_window_texture = SDL_CreateTexture(
+        widget->window_data->sdl_renderer, 
+        SDL_PIXELFORMAT_RGBA8888, 
+        SDL_TEXTUREACCESS_STREAMING, 
+        width, 
+        height
+    );
+
+    widget->window_data->frame_buffer = malloc(
+        sizeof(uint32_t) * width * height
+    );
+
+    context.current_window_panel_count++;
+
     return widget;
 }
 
@@ -40,7 +71,7 @@ LG_widget* LG_add_widget(LG_widget* parent_widget){
 
     parent_widget->children = realloc(parent_widget->children, sizeof(LG_widget*) * ++parent_widget->child_count);
 
-    parent_widget->children[parent_widget->child_count - 1] = &widget;    
+    parent_widget->children[parent_widget->child_count - 1] = widget;    
 
     widget->id = context.current_id++;
 
@@ -81,6 +112,76 @@ LG_image* LG_load_image(char* filename){
     image->height = temp_image->height;
 
     free(temp_image);
+
+    return image;
+}
+
+int LG_render_window(LG_widget* window_widget){
+    SDL_Event event;
+
+    while (SDL_PollEvent(&event)){
+        switch (event.type){
+            case SDL_QUIT: {
+                context.current_window_panel_count--;
+
+                break;
+            }
+
+            default: {
+                break;
+            }
+        }
+    }
+
+    int child_count = window_widget->child_count;
+
+    uint16_t current_width = window_widget->window_data->width;
+    uint16_t current_height = window_widget->window_data->height;
+
+    // generate styling
+
+    // for (int child_i = 0; child_i < child_count; child_i++){
+    //     uint16_t width;
+    //     uint16_t height;
+
+    //     if ()
+
+    //     for (int y = 0; y < )
+    // }
+
+    // rasterize
+
+    uint16_t r = window_widget->widget_style->radius;
+
+    for (int y = 0; y < current_height; y++){
+        int x_offset;
+
+        if (y < r) x_offset = r - (int)((float)r * ((float)sqrt((float)1 - ((float)(r - y) / (float)r) * ((float)(r - y) / (float)r))));
+        else if (y < current_height - r) x_offset = 0;
+        else x_offset = r - (int)((float)r * ((float)sqrt((float)1 - ((float)(r - (current_height - y)) / (float)r) * ((float)(r - (current_height - y)) / (float)r))));
+
+        for (int x = x_offset; x < current_width - x_offset; x++){
+            window_widget->window_data->frame_buffer[y * current_height + x] = window_widget->widget_style->background_color;
+        }
+    }
+
+    // copy frame data to window
+
+    int width_int = (int)window_widget->window_data->width;
+
+    SDL_LockTexture(
+        window_widget->window_data->sdl_window_texture, 
+        NULL, 
+        (void*)&window_widget->window_data->frame_buffer, 
+        &width_int
+    );
+
+    SDL_UnlockTexture(window_widget->window_data->sdl_window_texture);
+
+    SDL_RenderCopy(window_widget->window_data->sdl_renderer, window_widget->window_data->sdl_window_texture, NULL, NULL);
+    SDL_RenderPresent(window_widget->window_data->sdl_renderer);
+
+    return 0;
 }
 
 int LG_init(){
@@ -98,15 +199,17 @@ int LG_init(){
 
     context.default_widget = malloc(sizeof(LG_widget));
 
+    context.default_widget->widget_style = malloc(sizeof(LG_widget_style));
+
     context.default_widget->id = context.current_id++;
     context.default_widget->children = NULL;
     context.default_widget->child_count = 0;
     context.default_widget->parent = NULL;
     context.default_widget->type = LG_WIDGET_TYPE_PANEL;
-    context.default_widget->widget_style->background_color = 0x2E2E2EFF;
-    context.default_widget->widget_style->border_color = 0x000000FF;
-    context.default_widget->widget_style->border_radius = 0;
-    context.default_widget->widget_style->border_size = 4;
+    context.default_widget->widget_style->background_color = 0xAAAAFFFF;
+    context.default_widget->widget_style->border_color = 0xFFFFFFFF;
+    context.default_widget->widget_style->radius = 40;
+    context.default_widget->widget_style->border_size = 10;
     context.default_widget->widget_style->height = -1;
     context.default_widget->widget_style->width = -1;
     context.default_widget->widget_style->margin = 0;
@@ -122,8 +225,8 @@ int LG_init(){
     context.default_widget->widget_style->widget_alignment_horizontal = LG_WIDGET_ALIGNMENT_CENTER_HORIZONTAL;
     context.default_widget->widget_style->widget_alignment_vertical = LG_WIDGET_ALIGNMENT_CENTER_VERTICAL;
 
-
     context.current_id = 0;
 
+
     return 0;
 }