Add WIP icon support to spmenu

This commit is contained in:
speedie 2023-07-03 18:48:38 +02:00
parent 3f456f3a37
commit 4ac7119c5b
16 changed files with 93 additions and 5 deletions

View file

@ -339,6 +339,12 @@ You may use long, descriptive arguments or the shorter arguments.
`-nir, --no-image-resize` `-nir, --no-image-resize`
: Don't allow spmenu to resize itself to fit the image : 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` `-wm, --managed, --x11-client`
: Spawn spmenu as a window manager controlled client/window (X11 only) : Spawn spmenu as a window manager controlled client/window (X11 only)

View file

@ -172,6 +172,7 @@ spmenu.imageheight: 200
spmenu.imageresize: 1 spmenu.imageresize: 1
spmenu.imagegaps: 0 spmenu.imagegaps: 0
spmenu.imageposition: 0 spmenu.imageposition: 0
spmenu.imagetype: 1
spmenu.generatecache: 1 spmenu.generatecache: 1
spmenu.maxcache: 512 spmenu.maxcache: 512

View file

@ -201,6 +201,7 @@ spmenu = {
resize = 1; // Allow spmenu to resize itself to fit the image (0/1) resize = 1; // Allow spmenu to resize itself to fit the image (0/1)
gaps = 0; // Image gaps (px) gaps = 0; // Image gaps (px)
position = 0; // Image position (0: Top, 1: Bottom, 2: Center, 3: Top center) 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) cache = 1; // Cache images (0/1)
maxcache = 512; // Max image size to cache (px) maxcache = 512; // Max image size to cache (px)
cachedir = "default"; // Cache directory. "default" means spmenu will determine automatically based on $XDG_CACHE_DIR cachedir = "default"; // Cache directory. "default" means spmenu will determine automatically based on $XDG_CACHE_DIR

View file

@ -116,6 +116,10 @@ void readargs(int argc, char *argv[]) {
imageposition = 2; imageposition = 2;
} else if (!strcmp(argv[i], "-itc") || (!strcmp(argv[i], "--image-topcenter"))) { // image: top center } else if (!strcmp(argv[i], "-itc") || (!strcmp(argv[i], "--image-topcenter"))) { // image: top center
imageposition = 3; 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 } else if (!strcmp(argv[i], "-b") || (!strcmp(argv[i], "--bottom"))) { // appears at the bottom of the screen
menuposition = 0; menuposition = 0;
} else if (!strcmp(argv[i], "-t") || (!strcmp(argv[i], "--top"))) { // appears at the top of the screen } 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 -ib, --image-bottom Position the image at the bottom\n"
"spmenu -ic, --image-center Position the image in the center\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 -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 -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" "spmenu -nir, --no-image-resize Don't allow spmenu to resize itself to fit the image\n"
, status ? stderr : stdout); , status ? stderr : stdout);

View file

@ -415,6 +415,7 @@ void conf_init(void) {
config_setting_lookup_int(conf, "resize", &imageresize); // spmenu.image.resize 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, "gaps", &imagegaps); // spmenu.image.gaps
config_setting_lookup_int(conf, "position", &imageposition); // spmenu.image.position 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, "cache", &generatecache); // spmenu.image.cache
config_setting_lookup_int(conf, "maxcache", &maxcache); // spmenu.image.maxcache config_setting_lookup_int(conf, "maxcache", &maxcache); // spmenu.image.maxcache
if (config_setting_lookup_string(conf, "cachedir", &dest)) // spmenu.image.cachedir if (config_setting_lookup_string(conf, "cachedir", &dest)) // spmenu.image.cachedir

View file

@ -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 // parse item text
for (wr = 0, rd = 0; item->text[rd]; rd++) { for (wr = 0, rd = 0; item->text[rd]; rd++) {
if (item->text[rd] == '' && item->text[rd + 1] == '[') { if (item->text[rd] == '' && item->text[rd + 1] == '[') {
@ -304,7 +316,7 @@ int drawitem(int x, int y, int w) {
// draw image first // draw image first
#if USEIMAGE #if USEIMAGE
if (!hideimage && img.longestedge != 0) { if (!hideimage && img.longestedge != 0 && imagetype) {
rx = ox; rx = ox;
rx += MAX((imagegaps * 2) + img.imagewidth + menumarginh, indentitems ? x : 0); rx += MAX((imagegaps * 2) + img.imagewidth + menumarginh, indentitems ? x : 0);
} else } else

45
libs/icon.c Normal file
View file

@ -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

5
libs/icon.h Normal file
View file

@ -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

View file

@ -38,7 +38,7 @@ void drawimage(void) {
int width = 0, height = 0; int width = 0, height = 0;
char *limg = NULL; char *limg = NULL;
if (!lines || !columns || hideimage) return; if (!lines || !columns || hideimage || !imagetype) return;
// load image cache // load image cache
if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) { if (sel && sel->image && strcmp(sel->image, limg ? limg : "")) {
@ -311,6 +311,7 @@ void jumptoindex(unsigned int index) {
} }
void resizetoimageheight(int imageheight) { void resizetoimageheight(int imageheight) {
if (!imagetype) return;
#if USEX #if USEX
if (!protocol) { if (!protocol) {
resizetoimageheight_x11(imageheight); resizetoimageheight_x11(imageheight);

View file

@ -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 imageresize = 1; /* Allow the spmenu window to resize itself to fit the image (0/1) */
static int imagegaps = 0; /* Image gaps */ static int imagegaps = 0; /* Image gaps */
static int imageposition = 0; /* Image position (0: Top, 1: Bottom, 2: Center, 3: Top center) */ 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 generatecache = 1; /* Generate image cache by default */
static int maxcache = 512; /* Max image size to cache */ static int maxcache = 512; /* Max image size to cache */
static char *cachedir = "default"; /* Cache directory. Default means spmenu will determine automatically */ static char *cachedir = "default"; /* Cache directory. Default means spmenu will determine automatically */

View file

@ -274,7 +274,7 @@ void buttonpress_wl(uint32_t button, double ex, double ey) {
} }
#if USEIMAGE #if USEIMAGE
if (!hideimage && img.longestedge != 0) { if (!hideimage && img.longestedge != 0 && imagetype) {
x += MAX((imagegaps * 2) + img.imagewidth, indentitems ? sp.promptw : 0); x += MAX((imagegaps * 2) + img.imagewidth, indentitems ? sp.promptw : 0);
} }
#endif #endif

View file

@ -58,7 +58,7 @@ void buttonpress_x11(XEvent *e) {
} }
#if USEIMAGE #if USEIMAGE
if (!hideimage && img.longestedge != 0) { if (!hideimage && img.longestedge != 0 && imagetype) {
x += MAX((img.imagegaps * 2) + img.imagewidth, indentitems ? sp.promptw : 0); x += MAX((img.imagegaps * 2) + img.imagewidth, indentitems ? sp.promptw : 0);
} }
#endif #endif

View file

@ -157,6 +157,7 @@ ResourcePref resources[] = {
{ "imagegaps", INTEGER, &imagegaps }, { "imagegaps", INTEGER, &imagegaps },
{ "imageposition", INTEGER, &imageposition }, { "imageposition", INTEGER, &imageposition },
{ "imageresize", INTEGER, &imageresize }, { "imageresize", INTEGER, &imageresize },
{ "imagetype", INTEGER, &imagetype },
{ "generatecache", INTEGER, &generatecache }, { "generatecache", INTEGER, &generatecache },
{ "maxcache", INTEGER, &maxcache }, { "maxcache", INTEGER, &maxcache },
{ "mode", INTEGER, &mode }, { "mode", INTEGER, &mode },

View file

@ -747,7 +747,7 @@ main() {
RUNLAUNCHER_FM_ARGS="--insert $HIST_ARG $RUNLAUNCHER_FM_ARGS $MARGS" RUNLAUNCHER_FM_ARGS="--insert $HIST_ARG $RUNLAUNCHER_FM_ARGS $MARGS"
RUNLAUNCHER_RUN_ARGS="--insert $HIST_ARG $RUNLAUNCHER_RUN_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_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" RUNLAUNCHER_HELP_ARGS="--insert $HIST_ARG $RUNLAUNCHER_HELP_ARGS $MARGS"
# dmenu compatibility # dmenu compatibility

View file

@ -366,6 +366,12 @@ Allow spmenu to resize itself to fit the image
\f[V]-nir, --no-image-resize\f[R] \f[V]-nir, --no-image-resize\f[R]
Don\[cq]t allow spmenu to resize itself to fit the image Don\[cq]t allow spmenu to resize itself to fit the image
.TP .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] \f[V]-wm, --managed, --x11-client\f[R]
Spawn spmenu as a window manager controlled client/window (X11 only) Spawn spmenu as a window manager controlled client/window (X11 only)
.TP .TP

View file

@ -264,6 +264,8 @@ static char *fonts[] = { font };
// include functions // include functions
#include "libs/img.h" #include "libs/img.h"
#include "libs/img.c" #include "libs/img.c"
#include "libs/icon.h"
#include "libs/icon.c"
#include "libs/rtl.h" #include "libs/rtl.h"
#include "libs/rtl.c" #include "libs/rtl.c"
#include "libs/sort.c" #include "libs/sort.c"