emote2ss

Animated webp to spritesheets converting tool
git clone git://bsandro.tech/emote2ss
Log | Files | Refs | README | LICENSE

commit 98ad24380832ffffe3dcf82103e6845a4995982c
parent b9b7dc673617ae52eeb81b267f085b1c39e2c519
Author: bsandro <email@bsandro.tech>
Date:   Wed, 16 Aug 2023 16:06:12 +0300

Basic 'save window' ui layout.

Diffstat:
MTODO | 1+
Mgui/Makefile | 2+-
Mgui/main.c | 92++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
3 files changed, 60 insertions(+), 35 deletions(-)

diff --git a/TODO b/TODO @@ -3,3 +3,4 @@ - Support drag-n-drop for GUI version - Implement file open/save window - i18n +- Status bar with service/info messages diff --git a/gui/Makefile b/gui/Makefile @@ -3,7 +3,7 @@ SRC:=$(wildcard *.c) DEPS:=$(wildcard ../include/*.h) OBJ:=$(SRC:.c=.o) LIBS:=libwebp libwebpdemux x11 -CFLAGS=-Og -g -std=c99 -Wall -Wextra -ffast-math -I. -I../include/ ${shell pkg-config --cflags $(LIBS)} +CFLAGS=-O0 -g -std=c99 -Wall -Wextra -ffast-math -I. -I../include/ ${shell pkg-config --cflags $(LIBS)} LDFLAGS=-lc -lm ${shell pkg-config --libs $(LIBS)} all: $(NAME) diff --git a/gui/main.c b/gui/main.c @@ -42,33 +42,33 @@ typedef struct { uint8_t *data; size_t len; int width, height, stride; -} spritesheet_t; +} Spritesheet; typedef struct { uint8_t *rgba; int duration; bool is_key; -} frame_t; +} Frame; typedef struct { int width, height, bgcolor, loop_count; - frame_t *frames; + Frame *frames; uint32_t frame_count; void *raw_mem; char *path; -} animation_t; +} Animation; // let it be global variable for now -static animation_t *img = NULL; +static Animation *img = NULL; static int cols = 1; -void alloc_image(animation_t *img, uint32_t frame_count) { +void alloc_image(Animation *img, uint32_t frame_count) { assert(frame_count > 0); uint8_t *mem = NULL; - frame_t *frames = NULL; + Frame *frames = NULL; const uint64_t rgba_size = img->width * img->height * NUM_CHANNELS; const uint64_t img_size = frame_count * rgba_size * sizeof(uint8_t); - const uint64_t frames_size = frame_count * sizeof(frame_t); + const uint64_t frames_size = frame_count * sizeof(Frame); assert(img_size == (size_t)img_size); assert(frames_size == (size_t)frames_size); @@ -119,7 +119,7 @@ int read_file(const char *fname, const uint8_t **data, size_t *size) { return 0; } -int read_webp(const char *fname, animation_t *anim) { +int read_webp(const char *fname, Animation *anim) { printf("read_webp(%s)\n", fname); WebPData webp_data; @@ -155,7 +155,7 @@ int read_webp(const char *fname, animation_t *anim) { uint32_t frame_index = 0; int prev_ts = 0; while (WebPAnimDecoderHasMoreFrames(dec)) { - frame_t *frame; + Frame *frame; uint8_t *curr_rgba, *frame_rgba; int ts; if (!WebPAnimDecoderGetNext(dec, &frame_rgba, &ts)) { @@ -186,7 +186,7 @@ void write_file(const char *fname, uint8_t *data, size_t len) { } -spritesheet_t gen_spritesheet(animation_t *img, int cols) { +Spritesheet gen_spritesheet(Animation *img, int cols) { int rows = (int)img->frame_count / cols; if ((int)img->frame_count % cols > 0) { ++rows; @@ -215,7 +215,7 @@ spritesheet_t gen_spritesheet(animation_t *img, int cols) { //printf("size: %zu, encoded: %zu\n", img->width*img->height*sizeof(uint32_t), encoded); //assert(encoded!=0); //WebPFree(out); - spritesheet_t ss = {0}; + Spritesheet ss = {0}; ss.data = merged_orig; ss.stride = stride; ss.width = cols * img->width; @@ -229,35 +229,61 @@ spritesheet_t gen_spritesheet(animation_t *img, int cols) { int ButtonDialogSaveEvent(UIElement *element, UIMessage msg, int di, void *dp) { if (msg == UI_MSG_CLICKED) { - printf("save window close\n"); + printf("save dialog window close\n"); + // + UIElementDestroy(element->window); + } + return 0; +} - UIWindow *win_save = (UIWindow *)element->cp; - printf("win_save: %p\n", win_save); - UIElementDestroy(win_save); +int TableEvent(UIElement *element, UIMessage msg, int di, void *dp) { + static int selected = -1; + if (msg == UI_MSG_TABLE_GET_ITEM) { + //printf("table get item\n"); + UITableGetItem *m = (UITableGetItem *)dp; + m->isSelected = selected==m->index; + //printf("m->index = %d\n", m->index); + return snprintf(m->buffer, m->bufferBytes, "dir %d", m->index); + } else if (msg == UI_MSG_LEFT_DOWN) { + int hit = UITableHitTest((UITable *)element, element->window->cursorX, element->window->cursorY); + if (selected!=hit) { + selected = hit; + if (!UITableEnsureVisible((UITable *)element, selected)) { + UIElementRepaint(element, NULL); + } + } } return 0; } int ButtonSaveEvent(UIElement *element, UIMessage msg, int di, void *dp) { - (void)di; - (void)dp; if (msg == UI_MSG_CLICKED) { - printf("save\n"); + printf("save dialog window open\n"); - UIWindow *win_save = UIWindowCreate(0, 0, "Save File", 0, 0); - printf("win_save: %p\n", win_save); - UIPanel *panel_out = UIPanelCreate(&win_save->e, UI_PANEL_GRAY|UI_PANEL_MEDIUM_SPACING); - UILabel *lbl_title = UILabelCreate(&panel_out->e, 0, "Save File Title", -1); - UIButton *btn_save = UIButtonCreate(&panel_out->e, 0, "Save", -1); + UIWindow *win_save = UIWindowCreate((UIWindow *)element->cp, UI_WINDOW_INSPECTOR, "Save File", 0, 0); + UIPanel *panel_out = UIPanelCreate(&win_save->e, UI_PANEL_GRAY|UI_PANEL_EXPAND); + + UILabel *lbl_title = UILabelCreate(&panel_out->e, 0, "Save File", -1); + + UIPanel *panel_top = UIPanelCreate(&panel_out->e, UI_PANEL_GRAY|UI_PANEL_MEDIUM_SPACING|UI_PANEL_HORIZONTAL); + + UITextbox *path_input = UITextboxCreate(&panel_top->e, UI_ELEMENT_TAB_STOP|UI_ELEMENT_H_FILL); + UITextboxReplace(path_input, img->path, -1, false); + UITextbox *name_input = UITextboxCreate(&panel_top->e, UI_ELEMENT_TAB_STOP|UI_ELEMENT_H_FILL); + UITextboxReplace(name_input, "ehlo.webp", -1, false); + + UIButton *btn_save = UIButtonCreate(&panel_top->e, UI_ELEMENT_TAB_STOP, "Save", -1); btn_save->e.messageUser = ButtonDialogSaveEvent; - btn_save->e.cp = win_save; + + UITable *table = UITableCreate(&panel_out->e, UI_ELEMENT_V_FILL, "Directory"); + table->itemCount = 100; + table->e.messageUser = TableEvent; + UITableResizeColumns(table); } return 0; } int ButtonCloseEvent(UIElement *element, UIMessage msg, int di, void *dp) { - (void)di; - (void)dp; if (msg == UI_MSG_CLICKED) { free(img); UIWindow *win_main = (UIWindow *)element->cp; @@ -271,7 +297,7 @@ int ButtonCloseEvent(UIElement *element, UIMessage msg, int di, void *dp) { void update_preview(UIImageDisplay *img_disp) { // gen new spritesheet and refresh the preview - spritesheet_t ss = gen_spritesheet(img, cols); + Spritesheet ss = gen_spritesheet(img, cols); //printf("spritesheet width: %d, height: %d, stride: %d, len: %zu\n", ss.width, ss.height, ss.stride, ss.len); uint32_t *frame0 = calloc(ss.width*ss.height, sizeof(uint32_t)); @@ -281,7 +307,6 @@ void update_preview(UIImageDisplay *img_disp) { frame0[i] = UI_COLOR_FROM_RGBA(ss.data[i*4+0], ss.data[i*4+1], ss.data[i*4+2], ss.data[i*4+3]); } UIImageDisplaySetContent(img_disp, frame0, ss.width, ss.height, ss.stride); - //img_disp->zoom = 1.0f; UIElementRefresh(img_disp->e.parent); UIElementRefresh(&img_disp->e); @@ -291,13 +316,11 @@ void update_preview(UIImageDisplay *img_disp) { UILabel *label = (UILabel *)img_disp->e.cp; char label_text[256] = {0}; snprintf(&label_text, 255, "spritesheet width: %3d", cols); - UILabelSetContent(label, label_text, strlen(label_text)); + UILabelSetContent(label, label_text, -1); UIElementRefresh(label->e.parent); } int SliderEvent(UIElement *element, UIMessage msg, int di, void *dp) { - (void)di; - (void)dp; if (msg == UI_MSG_VALUE_CHANGED) { float slider_pos = ((UISlider *)element)->position; float step = 1.0f / (float)img->frame_count; @@ -337,6 +360,7 @@ int main(int argc, const char **argv) { //btnopen->e.messageUser = ButtonOpenEvent; UIButton *btnsave = UIButtonCreate(&panelh->e, 0, "Save", -1); btnsave->e.messageUser = ButtonSaveEvent; + btnsave->e.cp = win; UIButton *btn_exit = UIButtonCreate(&panelh->e, 0, "Close", -1); btn_exit->e.messageUser = ButtonCloseEvent; btn_exit->e.cp = win; @@ -351,9 +375,9 @@ int main(int argc, const char **argv) { return 0; } - img = malloc(sizeof(animation_t)); + img = malloc(sizeof(Animation)); assert(img!=NULL); - bzero(img, sizeof(animation_t)); + bzero(img, sizeof(Animation)); char out_name[NAME_MAX-1]; img->path = realpath(argv[1], NULL); assert(img->path!=NULL);