From 4ac7119c5b7d1fc086aeb3cd2493e0eece24a485 Mon Sep 17 00:00:00 2001 From: speedie Date: Mon, 3 Jul 2023 18:48:38 +0200 Subject: [PATCH] Add WIP icon support to spmenu --- docs/docs.md | 6 ++++++ docs/example.Xresources | 1 + docs/spmenu.conf | 1 + libs/argv.c | 6 ++++++ libs/conf/config.c | 1 + libs/draw.c | 14 ++++++++++++- libs/icon.c | 45 +++++++++++++++++++++++++++++++++++++++++ libs/icon.h | 5 +++++ libs/img.c | 3 ++- libs/options.h | 1 + libs/wl/wayland.c | 2 +- libs/x11/mouse.c | 2 +- libs/x11/xresources.h | 1 + scripts/spmenu_run | 2 +- spmenu.1 | 6 ++++++ spmenu.c | 2 ++ 16 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 libs/icon.c create mode 100644 libs/icon.h diff --git a/docs/docs.md b/docs/docs.md index d9bbddf..3c4d806 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -339,6 +339,12 @@ You may use long, descriptive arguments or the shorter arguments. `-nir, --no-image-resize` : Don't allow spmenu to resize itself to fit the image +`-di, --display-icons` +: Display the images as icons + +`-df, --display-image` +: Display the images as images in the image pane + `-wm, --managed, --x11-client` : Spawn spmenu as a window manager controlled client/window (X11 only) diff --git a/docs/example.Xresources b/docs/example.Xresources index daca8ba..4f6d31a 100644 --- a/docs/example.Xresources +++ b/docs/example.Xresources @@ -172,6 +172,7 @@ spmenu.imageheight: 200 spmenu.imageresize: 1 spmenu.imagegaps: 0 spmenu.imageposition: 0 +spmenu.imagetype: 1 spmenu.generatecache: 1 spmenu.maxcache: 512 diff --git a/docs/spmenu.conf b/docs/spmenu.conf index d9c3056..4285c09 100644 --- a/docs/spmenu.conf +++ b/docs/spmenu.conf @@ -201,6 +201,7 @@ spmenu = { resize = 1; // Allow spmenu to resize itself to fit the image (0/1) gaps = 0; // Image gaps (px) position = 0; // Image position (0: Top, 1: Bottom, 2: Center, 3: Top center) + type = 1; // Image type (0: Icon, 1: Image) cache = 1; // Cache images (0/1) maxcache = 512; // Max image size to cache (px) cachedir = "default"; // Cache directory. "default" means spmenu will determine automatically based on $XDG_CACHE_DIR diff --git a/libs/argv.c b/libs/argv.c index 5850fe7..12364a8 100644 --- a/libs/argv.c +++ b/libs/argv.c @@ -116,6 +116,10 @@ void readargs(int argc, char *argv[]) { imageposition = 2; } else if (!strcmp(argv[i], "-itc") || (!strcmp(argv[i], "--image-topcenter"))) { // image: top center imageposition = 3; + } else if (!strcmp(argv[i], "-di") || !(strcmp(argv[i], "--display-icons"))) { // image: display as icons + imagetype = 0; + } else if (!strcmp(argv[i], "-df") || !(strcmp(argv[i], "--display-image"))) { // image: display as an image + imagetype = 1; } else if (!strcmp(argv[i], "-b") || (!strcmp(argv[i], "--bottom"))) { // appears at the bottom of the screen menuposition = 0; } else if (!strcmp(argv[i], "-t") || (!strcmp(argv[i], "--top"))) { // appears at the top of the screen @@ -702,6 +706,8 @@ void usage(int status) { "spmenu -ib, --image-bottom Position the image at the bottom\n" "spmenu -ic, --image-center Position the image in the center\n" "spmenu -itc, --image-topcenter Position the image in the top center\n" + "spmenu -di, --display-icons Display the images as icons\n" + "spmenu -df, --display-image Display the images as images in the image pane\n" "spmenu -ir, --image-resize Allow spmenu to resize itself to fit the image\n" "spmenu -nir, --no-image-resize Don't allow spmenu to resize itself to fit the image\n" , status ? stderr : stdout); diff --git a/libs/conf/config.c b/libs/conf/config.c index 95ed777..45b28f6 100644 --- a/libs/conf/config.c +++ b/libs/conf/config.c @@ -415,6 +415,7 @@ void conf_init(void) { config_setting_lookup_int(conf, "resize", &imageresize); // spmenu.image.resize config_setting_lookup_int(conf, "gaps", &imagegaps); // spmenu.image.gaps config_setting_lookup_int(conf, "position", &imageposition); // spmenu.image.position + config_setting_lookup_int(conf, "type", &imagetype); // spmenu.image.type config_setting_lookup_int(conf, "cache", &generatecache); // spmenu.image.cache config_setting_lookup_int(conf, "maxcache", &maxcache); // spmenu.image.maxcache if (config_setting_lookup_string(conf, "cachedir", &dest)) // spmenu.image.cachedir diff --git a/libs/draw.c b/libs/draw.c index 781127d..4187e59 100644 --- a/libs/draw.c +++ b/libs/draw.c @@ -124,6 +124,18 @@ int drawitemtext(struct item *item, int x, int y, int w) { } } +#if USEIMAGE + if (!imagetype && lines) { + draw_rect(draw, x, y, w, sp.bh, 1, 1, fgcol, bgcol, fga, bga); + int nx = draw_icon(item, x, y + sp.lrpad / 4, sp.bh - sp.lrpad / 2, sp.bh - sp.lrpad / 2); + + if (nx != x) { + x = nx; + w -= sp.bh - sp.lrpad / 2; + } + } +#endif + // parse item text for (wr = 0, rd = 0; item->text[rd]; rd++) { if (item->text[rd] == '' && item->text[rd + 1] == '[') { @@ -304,7 +316,7 @@ int drawitem(int x, int y, int w) { // draw image first #if USEIMAGE - if (!hideimage && img.longestedge != 0) { + if (!hideimage && img.longestedge != 0 && imagetype) { rx = ox; rx += MAX((imagegaps * 2) + img.imagewidth + menumarginh, indentitems ? x : 0); } else diff --git a/libs/icon.c b/libs/icon.c new file mode 100644 index 0000000..b81af3f --- /dev/null +++ b/libs/icon.c @@ -0,0 +1,45 @@ +/* See LICENSE file for copyright and license details. */ + +#if USEIMAGE +int draw_icon(struct item *item, int x, int y, int w, int h) { + int ich = 0; + int icw = 0; + + if (hideimage) return x; + + if (item->image) { + image = imlib_load_image(item->image); + + if (!image) { + return x; + } + + imlib_context_set_image(image); + + icw = imlib_image_get_width(); + ich = imlib_image_get_height(); + + image = imlib_create_cropped_scaled_image(0, 0, icw, ich, w, h); // w = h = bh - lrpad / 2 + + icw = imlib_image_get_width(); + ich = imlib_image_get_height(); + + imlib_free_image(); + imlib_context_set_image(image); + + if (!image) { + return x; + } + + imlib_image_set_format("png"); + + // Draw the image + draw_set_img(draw, imlib_image_get_data(), w, h); + draw_img(draw, x, y); + + x += w; + } + + return x; +} +#endif diff --git a/libs/icon.h b/libs/icon.h new file mode 100644 index 0000000..6c79f9d --- /dev/null +++ b/libs/icon.h @@ -0,0 +1,5 @@ +/* See LICENSE file for copyright and license details. */ + +#if USEIMAGE +static int draw_icon(struct item *item, int x, int y, int w, int h); +#endif diff --git a/libs/img.c b/libs/img.c index e6cf4fd..886ccb2 100644 --- a/libs/img.c +++ b/libs/img.c @@ -38,7 +38,7 @@ void drawimage(void) { int width = 0, height = 0; char *limg = NULL; - if (!lines || !columns || hideimage) return; + if (!lines || !columns || hideimage || !imagetype) return; // load image cache if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) { @@ -311,6 +311,7 @@ void jumptoindex(unsigned int index) { } void resizetoimageheight(int imageheight) { + if (!imagetype) return; #if USEX if (!protocol) { resizetoimageheight_x11(imageheight); diff --git a/libs/options.h b/libs/options.h index cb7f4b6..f29536f 100644 --- a/libs/options.h +++ b/libs/options.h @@ -52,6 +52,7 @@ static int imageheight = 200; /* Default image height (px) */ static int imageresize = 1; /* Allow the spmenu window to resize itself to fit the image (0/1) */ static int imagegaps = 0; /* Image gaps */ static int imageposition = 0; /* Image position (0: Top, 1: Bottom, 2: Center, 3: Top center) */ +static int imagetype = 1; /* Image type (0: Icon, 1: Image) */ static int generatecache = 1; /* Generate image cache by default */ static int maxcache = 512; /* Max image size to cache */ static char *cachedir = "default"; /* Cache directory. Default means spmenu will determine automatically */ diff --git a/libs/wl/wayland.c b/libs/wl/wayland.c index 822dee1..c49a76d 100644 --- a/libs/wl/wayland.c +++ b/libs/wl/wayland.c @@ -274,7 +274,7 @@ void buttonpress_wl(uint32_t button, double ex, double ey) { } #if USEIMAGE - if (!hideimage && img.longestedge != 0) { + if (!hideimage && img.longestedge != 0 && imagetype) { x += MAX((imagegaps * 2) + img.imagewidth, indentitems ? sp.promptw : 0); } #endif diff --git a/libs/x11/mouse.c b/libs/x11/mouse.c index 05583ef..5ae4741 100644 --- a/libs/x11/mouse.c +++ b/libs/x11/mouse.c @@ -58,7 +58,7 @@ void buttonpress_x11(XEvent *e) { } #if USEIMAGE - if (!hideimage && img.longestedge != 0) { + if (!hideimage && img.longestedge != 0 && imagetype) { x += MAX((img.imagegaps * 2) + img.imagewidth, indentitems ? sp.promptw : 0); } #endif diff --git a/libs/x11/xresources.h b/libs/x11/xresources.h index 3cd2b1a..2d21224 100644 --- a/libs/x11/xresources.h +++ b/libs/x11/xresources.h @@ -157,6 +157,7 @@ ResourcePref resources[] = { { "imagegaps", INTEGER, &imagegaps }, { "imageposition", INTEGER, &imageposition }, { "imageresize", INTEGER, &imageresize }, + { "imagetype", INTEGER, &imagetype }, { "generatecache", INTEGER, &generatecache }, { "maxcache", INTEGER, &maxcache }, { "mode", INTEGER, &mode }, diff --git a/scripts/spmenu_run b/scripts/spmenu_run index 752a9b4..5176779 100755 --- a/scripts/spmenu_run +++ b/scripts/spmenu_run @@ -747,7 +747,7 @@ main() { RUNLAUNCHER_FM_ARGS="--insert $HIST_ARG $RUNLAUNCHER_FM_ARGS $MARGS" RUNLAUNCHER_RUN_ARGS="--insert $HIST_ARG $RUNLAUNCHER_RUN_ARGS $MARGS" RUNLAUNCHER_BM_ARGS="--insert $HIST_ARG -p Bookmarks $RUNLAUNCHER_BM_ARGS $MARGS" - RUNLAUNCHER_DESKTOP_ARGS="-sgr1 $DESCRIPTION_COLOR --lines 20 --columns 1 --image-size 100 --image-gaps 20 $RUNLAUNCHER_DESKTOP_ARGS $MARGS" + RUNLAUNCHER_DESKTOP_ARGS="-sgr1 $DESCRIPTION_COLOR --lines 20 --columns 1 --image-size 100 --image-gaps 20 --display-icons $RUNLAUNCHER_DESKTOP_ARGS $MARGS" RUNLAUNCHER_HELP_ARGS="--insert $HIST_ARG $RUNLAUNCHER_HELP_ARGS $MARGS" # dmenu compatibility diff --git a/spmenu.1 b/spmenu.1 index 09a063f..ea6eeec 100644 --- a/spmenu.1 +++ b/spmenu.1 @@ -366,6 +366,12 @@ Allow spmenu to resize itself to fit the image \f[V]-nir, --no-image-resize\f[R] Don\[cq]t allow spmenu to resize itself to fit the image .TP +\f[V]-di, --display-icons\f[R] +Display the images as icons +.TP +\f[V]-df, --display-image\f[R] +Display the images as images in the image pane +.TP \f[V]-wm, --managed, --x11-client\f[R] Spawn spmenu as a window manager controlled client/window (X11 only) .TP diff --git a/spmenu.c b/spmenu.c index 6a7138e..0097450 100644 --- a/spmenu.c +++ b/spmenu.c @@ -264,6 +264,8 @@ static char *fonts[] = { font }; // include functions #include "libs/img.h" #include "libs/img.c" +#include "libs/icon.h" +#include "libs/icon.c" #include "libs/rtl.h" #include "libs/rtl.c" #include "libs/sort.c"