add support for marking items (ie. multi selection)

This commit is contained in:
speedie 2023-05-16 18:54:26 +02:00
parent eadb69d6eb
commit 12b69656a7
7 changed files with 56 additions and 0 deletions

View file

@ -290,6 +290,13 @@ spmenu = {
function = "selectitem";
argument = "0";
},
// Ctrl+Enter: Mark input
{ mode = -1;
modifier = "Ctrl";
key = "Enter";
function = "markitem";
argument = "0";
},
// Tab: Tab complete
{ mode = -1;
modifier = "None";

View file

@ -12,6 +12,7 @@ static Key keys[] = {
*/
{ -1, 0, XK_Return, selectitem, {.i = +1 } },
{ -1, Shift, XK_Return, selectitem, {0} },
{ -1, Ctrl, XK_Return, markitem, {0} },
{ -1, 0, XK_Tab, complete, {0} },
{ -1, Ctrl, XK_v, paste, {.i = 2 } },
{ -1, Ctrl|Shift, XK_v, paste, {.i = 1 } },

View file

@ -240,6 +240,27 @@ void backspace(Arg *arg) {
drawmenu();
}
void markitem(Arg *arg) {
if (sel && is_selected(sel->index)) {
for (int i = 0; i < sel_size; i++) {
if (sel_index[i] == sel->index) {
sel_index[i] = -1;
}
}
} else {
for (int i = 0; i < sel_size; i++) {
if (sel_index[i] == -1) {
sel_index[i] = sel->index;
return;
}
}
sel_size++;
sel_index = realloc(sel_index, (sel_size + 1) * sizeof(int));
sel_index[sel_size - 1] = sel->index;
}
}
void selectitem(Arg *arg) {
char *selection;
@ -257,6 +278,13 @@ void selectitem(Arg *arg) {
selection = text;
}
for (int i = 0; i < sel_size; i++) {
if (sel_index[i] != -1 && (!sel || sel->index != sel_index[i])) {
puts(items[sel_index[i]].text);
savehistory(items[sel_index[i]].text);
}
}
if (!selection)
return;

View file

@ -26,6 +26,7 @@ static void deleteword(Arg *arg);
static void movecursor(Arg *arg);
static void navhistory(Arg *arg);
static void backspace(Arg *arg);
static void markitem(Arg *arg);
static void selectitem(Arg *arg);
static void quit(Arg *arg);
static void complete(Arg *arg);

View file

@ -352,6 +352,7 @@ static FuncList fl[] = {
{ "navhistory", navhistory },
{ "backspace", backspace },
{ "selectitem", selectitem },
{ "markitem", markitem },
{ "quit", quit },
{ "complete", complete },
{ "setimgsize", setimgsize },

View file

@ -71,6 +71,10 @@ int drawitemtext(struct item *item, int x, int y, int w) {
}
}
if (is_selected(item->index)) {
memcpy(scm, scheme[SchemeItemSel], sizeof(scm));
}
// apply extra padding
if ((selitem && !priitem) && lines) {
leftpadding += selitempadding;

View file

@ -157,6 +157,8 @@ static size_t cursor;
static struct item *items = NULL, *backup_items, *list_items;
static struct item *matches, *matchend;
static struct item *prev, *curr, *next, *sel;
static int *sel_index = NULL;
static unsigned int sel_size = 0;
static int screen;
static int itemn = 0;
@ -224,6 +226,7 @@ static Clr **scheme;
static Clr textclrs[256];
// declare functions
static int is_selected(size_t index);
static void calcoffsets(void);
static void recalculatenumbers(void);
static void usage(void);
@ -288,6 +291,16 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr;
#include "libs/event.h"
#include "libs/event.c"
int is_selected(size_t index) {
for (int i = 0; i < sel_size; i++) {
if (sel_index[i] == index) {
return 1;
}
}
return 0;
}
void appenditem(struct item *item, struct item **list, struct item **last) {
if (*last)
(*last)->right = item;
@ -382,6 +395,7 @@ void cleanup(void) {
drw_free(drw);
XSync(dpy, False);
XCloseDisplay(dpy);
free(sel_index);
}
char * cistrstr(const char *h, const char *n) {