aboutsummaryrefslogtreecommitdiff
path: root/src/ui.c
diff options
context:
space:
mode:
authorKrow Savcik <krow@savcik.xyz>2023-09-26 22:32:35 +0300
committerKrow Savcik <krow@savcik.xyz>2023-09-26 22:32:35 +0300
commit9e660e594f6d3a43ea1427fb872801a2fcedad93 (patch)
tree459cd0c6fc5fef0366f7ef249ae19dd67c363772 /src/ui.c
initial commit
Diffstat (limited to 'src/ui.c')
-rw-r--r--src/ui.c692
1 files changed, 692 insertions, 0 deletions
diff --git a/src/ui.c b/src/ui.c
new file mode 100644
index 0000000..ccc2de9
--- /dev/null
+++ b/src/ui.c
@@ -0,0 +1,692 @@
+#include <stdio.h>
+#include <assert.h>
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_image.h>
+
+#include "ui.h"
+#include "cdraw.h"
+#include "types.h"
+#include "canvas.h"
+#include "tools.h"
+#include "debug.h"
+#include "palette.h"
+
+#define fpan main_ui->focus_panel
+#define LENGTH(X) (sizeof X / sizeof *X)
+#define MAX(a, b) (((a) > (b)) ? (a) : (b));
+
+static const SDL_Rect ui_frame_rect[] = {
+ {0, 0, 8, 8},
+ {16, 0, 8, 8},
+ {0, 16, 8, 8},
+ {16, 16, 8, 8},
+ {8, 0, 8, 8},
+ {8, 16, 8, 8},
+ {0, 8, 8, 8},
+ {16, 8, 8, 8},
+};
+static const SDL_Rect ui_buttons_rect[] = {
+ {0, 24, 28, 28},
+ {0, 52, 28, 28},
+ {0, 80, 32, 32},
+ /* TODO: y -= 2 all the rects below */
+ {28, 26, 28, 28}, /* Pencil */
+ {28, 54, 28, 28}, /* Eraser */
+ {84, 26, 28, 28}, /* Fill Bucket */
+ {56, 26, 28, 28}, /* Zoom in */
+ {56, 54, 28, 28}, /* Zoom out */
+ {84, 54, 28, 28}, /* Clown */
+ {56, 82, 28, 28}, /* Color Picker */
+};
+
+struct UIPanel {
+ uint8 type, redraw;
+ SDL_Rect geom;
+ SDL_Texture *pres;
+};
+
+struct UIPanelCanvas {
+ UIPanel head;
+ /* Canvas *canv; */
+};
+
+struct UIPanelPalette {
+ UIPanel head;
+};
+
+struct UIPanelButtons {
+ UIPanel head;
+};
+
+struct UIPanelDivider {
+ UIPanel head;
+ UIPanel *x, *y;
+ uint8 st; /* states: (0 bit - hor/vert, 1 bit - ra/lb) */
+ int fw, lw, of;
+};
+
+struct UIPanelTimeline {
+ UIPanel head;
+};
+
+struct UI {
+ SDL_Texture *theme;
+ int w, h;
+ UIPanel *focus_panel;
+ UIPanelDivider p_divs[3];
+ UIPanelCanvas p_canvas;
+ UIPanelPalette p_palette;
+ UIPanelButtons p_buttons;
+ UIPanelTimeline p_timeline;
+};
+
+UI *main_ui;
+
+static UIPanel *ui_focus_panel(int, int);
+static void ui_focus_panel_change(int, int);
+
+/* Panel functions */
+static uint8 ui_panel_init(UIPanel *, uint8);
+static uint8 ui_panel_resize(UIPanel *, int, int, uint, uint);
+static uint8 ui_panel_draw_frame(UIPanel *);
+static uint8 ui_panel_redraw(UIPanel *);
+static uint8 ui_panel_present(UIPanel *);
+
+/* Panel canvas functions */
+static uint8 ui_panel_canvas_init(UIPanelCanvas *);
+static uint8 ui_panel_canvas_redraw(UIPanelCanvas *);
+
+/* Panel palette functions */
+static uint8 ui_panel_palette_init(UIPanelPalette *);
+static uint8 ui_panel_palette_redraw(UIPanelPalette *);
+
+/* Panel buttons functions */
+static uint8 ui_panel_buttons_init(UIPanelButtons *);
+static uint8 ui_panel_buttons_redraw(UIPanelButtons *);
+
+/* Panel timeline functions */
+static uint8 ui_panel_timeline_init(UIPanelTimeline *);
+static uint8 ui_panel_timeline_redraw(UIPanelTimeline *);
+
+/* Panel divider functions */
+static uint8 ui_panel_divider_init(UIPanelDivider *, int, int, int, uint8, UIPanel *, UIPanel *);
+static uint8 ui_panel_divider_resize(UIPanelDivider *, int, int, int, int);
+
+void
+ui_create(const char *path)
+{
+/* TODO: error checking */
+ int i;
+ main_ui = malloc(sizeof *main_ui);
+ main_ui->theme = NULL;
+ main_ui->focus_panel = NULL;
+ main_ui->w = main_ui->h = -1;
+ if (ui_theme_load(path))
+ exit(1);
+
+ SDL_SetTextureBlendMode(main_ui->theme, SDL_BLENDMODE_BLEND);
+
+ ui_panel_canvas_init(&main_ui->p_canvas);
+ ui_panel_palette_init(&main_ui->p_palette);
+ ui_panel_buttons_init(&main_ui->p_buttons);
+ ui_panel_timeline_init(&main_ui->p_timeline);
+
+ /* ui_panel_divider_init(&main_ui->p_divs[0], 5, 10, 100, 1, &main_ui->p_canvas, &main_ui->p_timeline); */
+ ui_panel_divider_init(&main_ui->p_divs[0], 5, 5, 120, 0, &main_ui->p_divs[1], &main_ui->p_divs[2]);
+ ui_panel_divider_init(&main_ui->p_divs[1], 0, 8, 22+31*((tool_array_size()+2)/3), 3, &main_ui->p_palette, &main_ui->p_buttons);
+ ui_panel_divider_init(&main_ui->p_divs[2], 0, 5, 70, 3, &main_ui->p_canvas, &main_ui->p_timeline);
+
+ ui_resize();
+}
+
+void
+ui_destroy()
+{
+ if (main_ui == NULL) return;
+ if (main_ui->theme) SDL_DestroyTexture(main_ui->theme);
+ free(main_ui);
+}
+
+uint8
+ui_resize()
+{
+ static int w, h;
+ if (main_ui == NULL)
+ return 1;
+
+ SDL_GetRendererOutputSize(ren, &w, &h);
+ if (w != main_ui->w || h != main_ui->h) {
+ main_ui->w = w;
+ main_ui->h = h;
+ ui_panel_resize(&main_ui->p_divs[0], 0, 0, w, h);
+ /* ui_panel_resize(&main_ui->p_palette.head, 5, 5, 120, main_ui->h-42-31*((tool_array_size()+2)/3)); */
+ /* ui_panel_resize(&main_ui->p_buttons.head, 5, main_ui->h-27-31*((tool_array_size()+2)/3), 120, 22+31*((tool_array_size()+2)/3)); */
+ /* ui_panel_resize(&main_ui->p_canvas.head, 130, 5, main_ui->w - 135, main_ui->h-85); */
+ /* ui_panel_resize(&main_ui->p_timeline.head, 130, main_ui->h-75, main_ui->w - 135,70); */
+ ui_redraw();
+ }
+ return 0;
+}
+
+void
+ui_redraw()
+{
+ main_ui->p_canvas.head.redraw = 1;
+ main_ui->p_palette.head.redraw = 1;
+ main_ui->p_buttons.head.redraw = 1;
+ main_ui->p_timeline.head.redraw = 1;
+}
+
+void
+ui_redraw_panel(uint8 type)
+{
+ switch (type) {
+ case UI_PANELTYPE_PALETTE:
+ main_ui->p_palette.head.redraw = 1;
+ break;
+ case UI_PANELTYPE_CANVAS:
+ main_ui->p_canvas.head.redraw = 1;
+ break;
+ case UI_PANELTYPE_BUTTONS:
+ main_ui->p_buttons.head.redraw = 1;
+ break;
+ case UI_PANELTYPE_TIMELINE:
+ main_ui->p_timeline.head.redraw = 1;
+ break;
+ default:
+ fprintf(stderr, "%s:%d:ui_redraw_panel: No implementation for %u\n", __FILE__, __LINE__, type);
+ break;
+ }
+}
+
+void
+ui_present()
+{
+ if (main_ui->p_palette.head.redraw)
+ ui_panel_redraw(&main_ui->p_palette.head);
+ if (main_ui->p_canvas.head.redraw)
+ ui_panel_redraw(&main_ui->p_canvas.head);
+ if (main_ui->p_buttons.head.redraw)
+ ui_panel_redraw(&main_ui->p_buttons.head);
+ if (main_ui->p_timeline.head.redraw)
+ ui_panel_redraw(&main_ui->p_timeline.head);
+ ui_panel_present(&main_ui->p_palette.head);
+ ui_panel_present(&main_ui->p_canvas.head);
+ ui_panel_present(&main_ui->p_buttons.head);
+ ui_panel_present(&main_ui->p_timeline.head);
+}
+
+void
+ui_mousel_down(int x, int y)
+{
+ int col;
+ Arg arg;
+ ui_focus_panel_change(x, y);
+
+ if (main_ui->focus_panel == NULL)
+ return;
+
+ switch (main_ui->focus_panel->type) {
+ case UI_PANELTYPE_CANVAS:
+ if (cur_canvas != NULL) {
+ canvas_mousel_down(cur_canvas,
+ x - fpan->geom.x - 8,
+ y - fpan->geom.y - 8);
+ fpan->redraw = 1;
+ }
+ break;
+ case UI_PANELTYPE_PALETTE:
+ if (cur_canvas == NULL)
+ return;
+ col = (x - fpan->geom.x - 8) / 26;
+ if (col > 3) col = 3;
+ col += (((y - fpan->geom.y - 8) / 26) << 2);
+
+
+ if (col < ((Palette *)def_palette)->num && col >= 0)
+ cur_canvas->cur_col = col;
+ break;
+ case UI_PANELTYPE_BUTTONS:
+
+ /* TODO Better */
+ col = (x - fpan->geom.x - 15) / 30;
+ if (col > 2)
+ break;
+
+ col += 3 * ((y - fpan->geom.y - 2) / 30);
+
+ if (col >= tool_array_size() || col < 0)
+ break;
+ switch (tool_array[col]) {
+ case TOOL_TYPE_ZOOMOUT:
+ /* TODO: user functions must mostly be wrappers for internal fucntions */
+ arg.i = -1;
+ user_canvas_zoom_change(&arg);
+ break;
+ case TOOL_TYPE_ZOOMIN:
+ arg.i = 1;
+ user_canvas_zoom_change(&arg);
+ break;
+ case TOOL_TYPE_CLOWN:
+ fprintf(stdout, "You have been clowned 🤡\n");
+ break;
+ case TOOL_TYPE_EMPTY:
+ break;
+ default:
+ tool_change(col);
+ break;
+ }
+ break;
+ }
+}
+
+void
+ui_mousel_up(int x, int y)
+{
+ ui_focus_panel_change(x, y);
+
+ if (main_ui->focus_panel == NULL)
+ return;
+
+ switch (main_ui->focus_panel->type) {
+ case UI_PANELTYPE_CANVAS:
+ if (cur_canvas != NULL)
+ canvas_mousel_up(cur_canvas);
+ fpan->redraw = 1;
+ break;
+ }
+}
+
+void
+ui_mouse_move(int x, int y)
+{
+ ui_focus_panel_change(x, y);
+
+ if (main_ui->focus_panel == NULL)
+ return;
+
+ switch (main_ui->focus_panel->type) {
+ case UI_PANELTYPE_CANVAS:
+ if (cur_canvas != NULL) {
+ canvas_mouse_move(cur_canvas,
+ x - fpan->geom.x - 8,
+ y - fpan->geom.y - 8);
+ fpan->redraw = 1;
+ }
+ break;
+ }
+}
+
+uint8
+ui_theme_load(const char *path)
+{
+/* TODO: check path */
+ if (main_ui->theme != NULL)
+ SDL_DestroyTexture(main_ui->theme);
+
+ SDL_Surface *surf = IMG_Load(path);
+ if (surf == NULL) return 1;
+ main_ui->theme = SDL_CreateTextureFromSurface(ren, surf);
+ SDL_FreeSurface(surf);
+ if (main_ui->theme == NULL) return 1;
+
+ return 0;
+}
+
+static UIPanel *
+ui_focus_panel(int x, int y)
+{
+ SDL_Rect *r;
+ if (main_ui == NULL) return NULL;
+
+ r = &main_ui->p_palette.head.geom;
+ if (r->x <= x && r->y <= y
+ && x - r->x < r->w && y - r->y < r->h)
+ return &main_ui->p_palette.head;
+
+ r = &main_ui->p_buttons.head.geom;
+ if (r->x <= x && r->y <= y
+ && x - r->x < r->w && y - r->y < r->h)
+ return &main_ui->p_buttons.head;
+
+ r = &main_ui->p_canvas.head.geom;
+ if (r->x <= x && r->y <= y
+ && x - r->x < r->w && y - r->y < r->h)
+ return &main_ui->p_canvas.head;
+
+ return NULL;
+}
+
+static void
+ui_focus_panel_change(int x, int y)
+{
+ UIPanel *u;
+ u = ui_focus_panel(x, y);
+
+ if (u == main_ui->focus_panel)
+ return;
+
+ if (main_ui->focus_panel != NULL) {
+ switch (main_ui->focus_panel->type) {
+ case UI_PANELTYPE_CANVAS:
+ is_drawing = 0;
+ main_ui->focus_panel = u;
+ ui_redraw_panel(UI_PANELTYPE_CANVAS);
+ break;
+ default:
+ break;
+ }
+ }
+
+ main_ui->focus_panel = u;
+}
+
+/* Panel functions */
+static uint8
+ui_panel_init(UIPanel *p, uint8 type)
+{
+ p->pres = NULL;
+ p->type = type;
+ p->redraw = 1;
+ p->geom.w = p->geom.h = 0;
+
+ return 0;
+}
+
+static uint8
+ui_panel_resize(UIPanel *p, int x, int y, uint w, uint h)
+{
+ if (p->type == UI_PANELTYPE_DIVIDER)
+ return ui_panel_divider_resize((UIPanelDivider *)p, x, y, w, h);
+ p->geom.x = x;
+ p->geom.y = y;
+
+ /* assert(w > 16 && h > 16); */
+ if (w < 16 || h < 16)
+ return 1;
+ if (p->geom.w == w && p->geom.h == h)
+ return 0;
+
+ p->geom.w = w;
+ p->geom.h = h;
+
+ if (p->pres != NULL)
+ SDL_DestroyTexture(p->pres);
+
+ p->pres = SDL_CreateTexture(
+ ren, SDL_PIXELFORMAT_RGBA8888,
+ SDL_TEXTUREACCESS_TARGET,
+ w, h);
+
+ SDL_SetTextureBlendMode(p->pres, SDL_BLENDMODE_BLEND);
+
+ return 0;
+}
+
+static uint8
+ui_panel_redraw(UIPanel *p)
+{
+/* TODO: something for paralel threads? */
+/* TODO: Correct switch case intendation(not here) */
+ if (p->pres == NULL)
+ return 1;
+
+ p->redraw = 0;
+
+ SDL_SetRenderTarget(ren, p->pres);
+ SDL_SetRenderDrawColor(ren, 0, 0, 0, 0);
+ SDL_RenderClear(ren);
+ switch (p->type) {
+ case UI_PANELTYPE_CANVAS:
+ ui_panel_canvas_redraw((UIPanelCanvas *)p);
+ break;
+ case UI_PANELTYPE_PALETTE:
+ ui_panel_palette_redraw((UIPanelPalette *)p);
+ break;
+ case UI_PANELTYPE_BUTTONS:
+ ui_panel_buttons_redraw((UIPanelButtons *)p);
+ break;
+ case UI_PANELTYPE_TIMELINE:
+ ui_panel_draw_frame(p);
+ break;
+ default:
+ fprintf(stderr, "%s:%d:ui_panel_redraw: No redraw fuction for %u\n", __FILE__, __LINE__, p->type);
+ break;
+ }
+ SDL_SetRenderTarget(ren, NULL);
+
+ return 0;
+}
+
+static uint8
+ui_panel_draw_frame(UIPanel *p)
+{
+ static SDL_Rect dest;
+ dest.x = 0;
+ dest.y = 0;
+ dest.h = 8;
+ dest.w = p->geom.w;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[4], &dest);
+ dest.y = p->geom.h-8;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[5], &dest);
+ dest.w = 8;
+ dest.h = p->geom.h;
+ dest.y = 0;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[6], &dest);
+ dest.x = p->geom.w-8;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[7], &dest);
+
+ dest.h = 8;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[1], &dest);
+ dest.x = 0;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[0], &dest);
+ dest.y = p->geom.h-8;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[2], &dest);
+ dest.x = p->geom.w-8;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_frame_rect[3], &dest);
+
+ return 0;
+}
+
+static uint8
+ui_panel_present(UIPanel *p)
+{
+ return SDL_RenderCopy(ren, p->pres, NULL, &p->geom);
+}
+
+/* Panel canvas functions */
+static uint8
+ui_panel_canvas_init(UIPanelCanvas *p)
+{
+ return ui_panel_init((UIPanel *)p, UI_PANELTYPE_CANVAS);
+}
+
+static uint8
+ui_panel_canvas_redraw(UIPanelCanvas *p)
+{
+ static SDL_Rect dest;
+ dest.x = 8;
+ dest.y = 8;
+ dest.w = p->head.geom.w - 16;
+ dest.h = p->head.geom.h - 16;
+ SDL_RenderSetViewport(ren, &dest);
+ SDL_SetRenderDrawColor(ren, 18, 18, 18, 255);
+ SDL_RenderClear(ren);
+ if (cur_canvas != NULL) {
+ SDL_RenderSetViewport(ren, NULL);
+ canvas_redraw(cur_canvas, ren,
+ mouseX - p->head.geom.x - 8,
+ mouseY - p->head.geom.y - 8);
+ SDL_SetRenderTarget(ren, p->head.pres);
+ SDL_RenderSetViewport(ren, &dest);
+ canvas_present(cur_canvas, ren);
+ }
+ SDL_RenderSetViewport(ren, NULL);
+ ui_panel_draw_frame(&p->head);
+ return 0;
+}
+
+/* Panel palette functions */
+static uint8
+ui_panel_palette_init(UIPanelPalette *p)
+{
+ return ui_panel_init((UIPanel *)p, UI_PANELTYPE_PALETTE);
+}
+
+static uint8
+ui_panel_palette_redraw(UIPanelPalette *p)
+{
+ static SDL_Rect dest;
+ Palette *pp;
+ int i;
+
+ pp = def_palette;
+ dest.x = 8;
+ dest.y = 8;
+ dest.w = p->head.geom.w - 16;
+ dest.h = p->head.geom.h - 16;
+ SDL_RenderSetViewport(ren, &dest);
+ SDL_SetRenderDrawColor(ren, 18, 18, 18, 255);
+ SDL_RenderClear(ren);
+
+ SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
+ if (pp != NULL) {
+ dest.x = dest.y = 0;
+ dest.w = 120;
+ if (pp->num > 3) {
+ dest.h = 26 * (pp->num >> 2);
+ SDL_RenderFillRect(ren, &dest);
+ }
+
+ if (pp->num % 4) {
+ dest.w = 26 * (pp->num % 4);
+ dest.h = 26;
+ dest.y = 26 * (pp->num >> 2);
+ SDL_RenderFillRect(ren, &dest);
+ }
+
+ dest.w = dest.h = 24;
+ for (i = 0; i < pp->num; ++i) {
+ dest.x = 1 + (i % 4) * 26;
+ dest.y = 1 + (i / 4) * 26;
+ SDL_SetRenderDrawColor(ren,
+ pp->clist[i].r, pp->clist[i].g,
+ pp->clist[i].b, 255);
+ SDL_RenderFillRect(ren, &dest);
+ }
+ }
+ SDL_RenderSetViewport(ren, NULL);
+ ui_panel_draw_frame(&p->head);
+ return 0;
+}
+
+/* Panel buttons functions */
+static uint8
+ui_panel_buttons_init(UIPanelButtons *p)
+{
+ return ui_panel_init((UIPanel *)p, UI_PANELTYPE_BUTTONS);
+}
+
+static uint8
+ui_panel_buttons_redraw(UIPanelButtons *p)
+{
+ static SDL_Rect dest1;
+ static SDL_Rect dest2;
+ int i;
+
+ dest1.x = 14;
+ dest1.y = 0;
+ dest1.w = p->head.geom.w - 28;
+ dest1.h = p->head.geom.h;
+ SDL_RenderSetViewport(ren, &dest1);
+ SDL_SetRenderDrawColor(ren, INTTOCOL(back_c), 255);
+ SDL_RenderClear(ren);
+ dest1.w = 28;
+ dest1.h = 28;
+ dest2.w = 32;
+ dest2.h = 32;
+ for (i = 0; i < tool_array_size(); ++i) {
+ if (tool_array[i] == TOOL_TYPE_EMPTY) continue;
+ dest1.x = 2 + (i % 3) * 30;
+ dest1.y = 2 + (i / 3) * 30;
+ dest2.x = (i % 3) * 30;
+ dest2.y = (i / 3) * 30;
+ SDL_RenderCopy(ren, main_ui->theme, &ui_buttons_rect[2], &dest2);
+ if (i == tool_cur)
+ SDL_RenderCopy(ren, main_ui->theme, &ui_buttons_rect[0], &dest1);
+ else
+ SDL_RenderCopy(ren, main_ui->theme, &ui_buttons_rect[1], &dest1);
+ SDL_RenderCopy(ren, main_ui->theme, &ui_buttons_rect[tool_array[i]+3], &dest1);
+ }
+ SDL_RenderSetViewport(ren, NULL);
+ /* ui_panel_draw_frame(&p->head); */
+ return 0;
+}
+
+/* Panel timeline functions */
+static uint8
+ui_panel_timeline_init(UIPanelTimeline *p)
+{
+ return ui_panel_init((UIPanel *)p, UI_PANELTYPE_TIMELINE);
+}
+
+/* Panel divider functions */
+static uint8
+ui_panel_divider_init(UIPanelDivider *p, int fw, int lw, int of, uint8 st, UIPanel *p1, UIPanel *p2)
+{
+ ui_panel_init((UIPanel *)p, UI_PANELTYPE_DIVIDER);
+ p->fw = fw;
+ p->lw = lw;
+ p->of = of;
+ p->st = st;
+ p->x = p1;
+ p->y = p2;
+ return 0;
+}
+
+static uint8
+ui_panel_divider_resize(UIPanelDivider *p, int x, int y, int w, int h)
+{
+ SDL_Rect g1, g2;
+ p->head.geom.x = x;
+ p->head.geom.y = y;
+ p->head.geom.w = w;
+ p->head.geom.h = h;
+
+ if (p->st & 1) {
+ /* Horizontal line */
+ g1.w = g2.w = MAX(0, p->head.geom.w - 2 * p->fw);
+
+ if (p->st & 2) {
+ g2.h = p->of;
+ g1.h = MAX(0, p->head.geom.h - 2 * p->fw - p->of - p->lw);
+ } else {
+ g1.h = p->of;
+ g2.h = MAX(0, p->head.geom.h - 2 * p->fw - p->of - p->lw);
+ }
+
+ g1.x = g2.x = x + p->fw;
+ g1.y = y + p->fw;
+ g2.y = y + p->fw + p->lw + g1.h;
+ } else {
+ /* Vertical line */
+ g1.h = g2.h = MAX(0, p->head.geom.h - 2 * p->fw);
+
+ if (p->st & 2) {
+ g2.w = p->of;
+ g1.w = MAX(0, p->head.geom.w - 2 * p->fw - p->of - p->lw);
+ } else {
+ g1.w = p->of;
+ g2.w = MAX(0, p->head.geom.w - 2 * p->fw - p->of - p->lw);
+ }
+
+ g1.y = g2.y = x + p->fw;
+ g1.x = x + p->fw;
+ g2.x = x + p->fw + p->lw + g1.w;
+ }
+
+ ui_panel_resize(p->x, g1.x, g1.y, g1.w, g1.h);
+ ui_panel_resize(p->y, g2.x, g2.y, g2.w, g2.h);
+
+ return 0;
+}