aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main.c12
-rw-r--r--renderer.c30
-rw-r--r--renderer.h4
-rw-r--r--ui.c5
-rw-r--r--ui.h2
-rw-r--r--widget.c46
-rw-r--r--widget.h10
7 files changed, 87 insertions, 22 deletions
diff --git a/main.c b/main.c
index 60781a9..1edaeda 100644
--- a/main.c
+++ b/main.c
@@ -396,24 +396,18 @@ comp_select(mu_Context *ctx, UI *ui) {
static void
comp_img(mu_Context *ctx, UI *ui) {
+ int w, h;
mu_Rect r;
- const char *data;
- int id, w, h;
+ /* Row that covers the rest of the window. */
r_get_window_size(&w, &h);
mu_layout_row(ctx, 1, &w, h);
-
- data = ui->comps[ui->comp_select.idx].imgfile;
- id = mu_get_id(ctx, &data, sizeof(data));
-
r = mu_layout_next(ctx);
r.w = w - r.x - ctx->style->spacing;
r.h = h - r.y - ctx->style->spacing;
mu_layout_set_next(ctx, r, 0);
- mu_update_control(ctx, id, r, 0);
-
- mu_draw_icon(ctx, 0, r, (mu_Color) {0, 0, 0, 0});
+ w_image(ctx, &ui->comp_img);
}
static void
diff --git a/renderer.c b/renderer.c
index 158f7e2..900a6c9 100644
--- a/renderer.c
+++ b/renderer.c
@@ -298,8 +298,9 @@ r_get_window_size(int *w, int*h) {
}
}
+/* Load an image and add it to the list of icons. Returns the id of the icon, or -1 on error. */
int
-r_push_icon(const char *path) {
+r_add_icon(const char *path) {
SDL_Surface *surface;
expect(icon_list.idx < ICONLIST_SIZE);
@@ -307,23 +308,32 @@ r_push_icon(const char *path) {
surface = IMG_Load(path);
if (!surface) {
fprintf(stderr, "failed to load %s: %s\n", path, SDL_GetError());
- return 1;
+ return -1;
}
icon_list.items[icon_list.idx] = SDL_CreateTextureFromSurface(renderer, surface);
if (!icon_list.items[icon_list.idx]) {
fprintf(stderr, "%s\n", SDL_GetError());
SDL_FreeSurface(surface);
- return 1;
+ return -1;
}
- icon_list.idx++;
SDL_FreeSurface(surface);
- return 0;
+ return icon_list.idx++;
}
+/* Remove the icon with the specified id from the icons list. */
void
-r_pop_icon(void) {
- if (icon_list.idx <= 0) {
- return;
- }
- SDL_DestroyTexture(icon_list.items[--icon_list.idx]);
+r_remove_icon(int id) {
+ SDL_Texture **dst, **src;
+ size_t size;
+
+ expect(id >= 0 && id < icon_list.idx);
+
+ SDL_DestroyTexture(icon_list.items[id]);
+
+ dst = icon_list.items + id;
+ src = icon_list.items + id + 1;
+ size = (icon_list.idx - id - 1) * sizeof(*icon_list.items);
+ memmove(dst, src, size);
+
+ icon_list.idx--;
}
diff --git a/renderer.h b/renderer.h
index 23d9123..0a31578 100644
--- a/renderer.h
+++ b/renderer.h
@@ -3,5 +3,5 @@ void r_free(void);
void r_input(mu_Context *ctx);
void r_render(mu_Context *ctx);
void r_get_window_size(int *w, int *h);
-int r_push_icon(const char *path);
-void r_pop_icon(void);
+int r_add_icon(const char *path);
+void r_remove_icon(int);
diff --git a/ui.c b/ui.c
index 3393d65..882206b 100644
--- a/ui.c
+++ b/ui.c
@@ -92,6 +92,7 @@ void
free_ui(UI *ui) {
w_free_select_compressor(&ui->comp_select);
free(ui->comps);
+ w_free_image(&ui->comp_img);
}
static void
@@ -254,8 +255,10 @@ init_comps(UI *ui) {
static int
init_comp_img(UI *ui) {
const Compressor *comp;
+
+ w_init_image(&ui->comp_img);
comp = &ui->comps[ui->comp_select.idx];
- return r_push_icon(comp->imgfile);
+ return w_set_image(&ui->comp_img, comp->imgfile);
}
void
diff --git a/ui.h b/ui.h
index b5c2635..fe3d783 100644
--- a/ui.h
+++ b/ui.h
@@ -47,6 +47,8 @@ typedef struct {
Compressor *comps;
int ncomps;
w_Select_Compressor comp_select;
+
+ w_Image comp_img;
} UI;
int init_ui(UI *ui);
diff --git a/widget.c b/widget.c
index 79e6028..2b0476e 100644
--- a/widget.c
+++ b/widget.c
@@ -6,15 +6,18 @@
#include <omp.h>
#include "microui.h"
+#include "renderer.h"
#include "unit.h"
#include "compressor.h"
#include "widget.h"
#include "util.h"
+#include "eprintf.h"
#define FORMAT "%.5g"
static const mu_Color RED = {255, 0, 0, 255};
+static const mu_Color WHITE = {255, 255, 255, 255};
static const char *sc_selected_name(w_Select_Compressor *select);
static int select_compressor_active(mu_Context *ctx, w_Select_Compressor *select);
@@ -280,6 +283,49 @@ w_number(mu_Context *ctx, const w_Number num) {
mu_label(ctx, num);
}
+void
+w_init_image(w_Image *img) {
+ img->id = -1;
+}
+
+void
+w_free_image(w_Image *img) {
+ if (img->id >= 0) {
+ r_remove_icon(img->id);
+ img->id = -1;
+ }
+}
+
+/* Load an image from a file. Returns non-zero on error. */
+int
+w_set_image(w_Image *img, const char *path) {
+ int id;
+
+ /* Remove old image. */
+ w_free_image(img);
+
+ /* Load new image. */
+ id = r_add_icon(path);
+ if (id < 0) {
+ weprintf("failed to load image %s", path);
+ return 1;
+ }
+ img->id = id;
+
+ return 0;
+}
+
+void
+w_image(mu_Context *ctx, w_Image *img) {
+ int id;
+ mu_Rect r;
+
+ id = mu_get_id(ctx, &img, sizeof(img));
+ r = mu_layout_next(ctx);
+ mu_update_control(ctx, id, r, 0);
+ mu_draw_icon(ctx, 0, r, WHITE);
+}
+
/* Update the active/selected status of a widget. id is the microui ID of the widget.
* *active is the active flag of the widget that will be toggled if anywhere in r is clicked. */
static void
diff --git a/widget.h b/widget.h
index 1351ba1..ab30f7a 100644
--- a/widget.h
+++ b/widget.h
@@ -64,3 +64,13 @@ typedef char w_Number[NUMBER_SIZE];
void w_init_number(w_Number num);
void w_set_number(w_Number num, double val);
void w_number(mu_Context *ctx, const w_Number num);
+
+
+typedef struct {
+ int id; /* icon id. */
+} w_Image;
+
+void w_init_image(w_Image *img);
+void w_free_image(w_Image *img);
+int w_set_image(w_Image *img, const char *path);
+void w_image(mu_Context *ctx, w_Image *img);