spmenu/libs/draw.c

754 lines
23 KiB
C
Raw Normal View History

2023-05-14 00:21:16 +02:00
/* See LICENSE file for copyright and license details. */
void drawhighlights(struct item *item, int x, int y, int w, int p, const char *ittext) {
2023-05-08 23:00:45 +02:00
int i, indent;
char *highlight;
char c;
2023-03-08 19:20:18 +01:00
// limitation in order to prevent highlighting from drawing when the text isn't visible
if (columns > 5 && lines > 1) return;
char *itemtext = strdup(ittext);
2023-03-08 19:20:18 +01:00
2023-06-23 03:38:21 +02:00
if (!(strlen(itemtext) && strlen(tx.text))) return;
2023-03-16 11:58:38 +01:00
if (strstr(itemtext, "</")) return;
2023-06-23 03:38:21 +02:00
for (i = 0, highlight = itemtext; *highlight && tx.text[i];) {
if (((fuzzy && !fstrncmp(&(*highlight), &tx.text[i], 1)) || (!fuzzy && *highlight == tx.text[i]))) {
2023-05-08 23:00:45 +02:00
c = *highlight;
*highlight = '\0';
2023-06-23 03:38:21 +02:00
indent = TEXTW(itemtext) - sp.lrpad;
2023-05-08 23:00:45 +02:00
*highlight = c;
// highlight character
c = highlight[1];
highlight[1] = '\0';
draw_text(
draw,
2023-05-08 23:00:45 +02:00
x + indent + (p),
y,
2023-06-23 03:38:21 +02:00
MIN(w - indent - sp.lrpad, TEXTW(highlight) - sp.lrpad),
sp.bh, 0, highlight, 0, False,
item == selecteditem ? col_hlselfg : col_hlnormfg,
item == selecteditem ? col_hlselbg : col_hlnormbg,
item == selecteditem ? alpha_hlselfg : alpha_hlnormfg,
item == selecteditem ? alpha_hlselbg : alpha_hlnormbg);
2023-05-08 23:00:45 +02:00
highlight[1] = c;
i++;
}
highlight++;
}
2023-03-02 11:40:52 +01:00
}
char* get_text_n_sgr(struct item *item) {
char buffer[MAXITEMLENGTH];
int character, escape;
char *sgrtext = malloc(sizeof(buffer));
sgrtext[0] = '\0';
for (character = 0, escape = 0; item->text[escape]; escape++) {
if (item->text[escape] == '' && item->text[escape + 1] == '[') {
size_t colindex = strspn(item->text + escape + 2, "0123456789;");
if (item->text[escape + colindex + 2] == 'm' && sgr) { // last character in sequence is always 'm'
buffer[character] = '\0';
strcat(sgrtext, buffer);
escape += colindex + 2;
character = 0;
continue;
}
}
buffer[character++] = item->text[escape];
}
buffer[character] = '\0';
strcat(sgrtext, buffer);
return sgrtext;
}
int drawitemtext(struct item *item, int x, int y, int w) {
char buffer[MAXITEMLENGTH]; // buffer containing item text
int character, escape;
2023-06-23 03:38:21 +02:00
int leftpadding = sp.lrpad / 2; // padding
2023-05-08 23:00:45 +02:00
int fg = 7; // foreground
int bg = 0; // background
int bgfg = 0; // both
int ignore = 0; // ignore colors
int selitem = 0;
int priitem = 0;
char *bgcol;
char *fgcol;
2023-07-06 16:19:20 +02:00
char *obgcol;
char *ofgcol;
int bga;
int fga;
2023-07-06 16:19:20 +02:00
int obga;
int ofga;
int ox;
int oy;
int ow;
2023-07-07 16:05:01 +02:00
int oleftpadding;
// memcpy the correct scheme
if (item == selecteditem) {
selitem = 1;
bgcol = col_itemselbg;
fgcol = col_itemselfg;
bga = alpha_itemselbg;
fga = alpha_itemselfg;
2023-03-09 10:10:29 +01:00
if (item->hp) {
priitem = 1;
bgcol = col_itemselpribg;
fgcol = col_itemselprifg;
fga = alpha_itemselprifg;
bga = alpha_itemselpribg;
}
2023-03-02 11:40:52 +01:00
} else {
2023-05-13 16:07:29 +02:00
if (itemn) {
bgcol = col_itemnormbg2;
fgcol = col_itemnormfg2;
fga = alpha_itemnormfg2;
bga = alpha_itemnormbg2;
2023-05-13 16:07:29 +02:00
} else {
bgcol = col_itemnormbg;
fgcol = col_itemnormfg;
fga = alpha_itemnormfg;
bga = alpha_itemnormbg;
2023-05-13 16:07:29 +02:00
}
2023-03-09 10:10:29 +01:00
if (item->hp) {
priitem = 1;
bgcol = col_itemnormpribg;
fgcol = col_itemnormprifg;
fga = alpha_itemnormprifg;
bga = alpha_itemnormpribg;
}
}
if (is_selected(item->index)) {
2023-06-19 01:08:15 +02:00
selitem = (lines ? 1 : selitem);
bgcol = col_itemmarkedbg;
fgcol = col_itemmarkedfg;
fga = alpha_itemmarkedfg;
bga = alpha_itemmarkedbg;
}
// apply extra padding
if ((selitem && !priitem) && lines) {
leftpadding += selitempadding;
} else if (priitem && lines) {
leftpadding += priitempadding;
} else if (lines) {
leftpadding += normitempadding;
2023-03-02 11:40:52 +01:00
}
2023-03-28 15:10:57 +02:00
// don't color
if (!coloritems) {
bgcol = itemn ? col_itemnormbg2 : col_itemnormbg;
fgcol = itemn ? col_itemnormfg2 : col_itemnormfg;
bga = itemn ? alpha_itemnormbg2 : alpha_itemnormbg;
fga = itemn ? alpha_itemnormfg2 : alpha_itemnormfg;
}
2023-03-02 11:40:52 +01:00
2023-07-06 16:19:20 +02:00
ofga = fga;
obga = bga;
ofgcol = fgcol;
obgcol = bgcol;
2023-07-07 16:05:01 +02:00
oleftpadding = leftpadding;
2023-07-06 16:19:20 +02:00
2023-06-18 21:15:32 +02:00
if (!hidepowerline && powerlineitems && selitem) {
if (itempwlstyle == 2) {
draw_circle(draw, x - sp.plw, y, sp.plw, sp.bh, 0, col_menu, bgcol, alpha_menu, bga);
} else {
draw_arrow(draw, x - sp.plw, y, sp.plw, sp.bh, 0, itempwlstyle, col_menu, bgcol, alpha_menu, bga);
}
}
2023-07-03 18:48:38 +02:00
#if USEIMAGE
2023-07-03 19:12:53 +02:00
if (!hideimage && !imagetype && lines) {
2023-07-03 18:48:38 +02:00
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
ox = x;
oy = y;
ow = w;
2023-07-04 23:10:06 +02:00
// parse item text
for (character = 0, escape = 0; item->text[escape]; escape++) {
if (item->text[escape] == '' && item->text[escape + 1] == '[') {
size_t colindex = strspn(item->text + escape + 2, "0123456789;");
if (item->text[escape + colindex + 2] == 'm' && sgr) { // last character in sequence is always 'm'
buffer[character] = '\0';
apply_fribidi(buffer);
draw_text(draw, x, y, w, sp.bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
2023-07-04 23:10:06 +02:00
// position and width
x += MIN(w, TEXTW(buffer) - sp.lrpad + leftpadding);
w -= MIN(w, TEXTW(buffer) - sp.lrpad + leftpadding);
2023-03-29 20:23:49 +02:00
// no highlighting if colored text
leftpadding = 0;
2023-03-02 11:40:52 +01:00
char *c_character = item->text + escape + 1; // current character
2023-03-02 11:40:52 +01:00
// parse hex colors, m is always the last character
while (*c_character != 'm') {
unsigned nextchar = strtoul(c_character + 1, &c_character, 10);
2023-03-04 02:07:06 +01:00
if (ignore)
2023-05-08 23:00:45 +02:00
continue;
if (bgfg) {
if (bgfg < 4 && nextchar == 5) {
bgfg <<= 1;
continue;
}
if (bgfg == 4) {
fgcol = txtcols[fg = nextchar];
} else if (bgfg == 6) {
bgcol = txtcols[bg = nextchar];
}
2023-05-08 23:00:45 +02:00
ignore = 1;
2023-05-08 23:00:45 +02:00
continue;
}
if (nextchar == 1) {
fg |= 8;
fgcol = txtcols[fg];
2023-05-08 23:00:45 +02:00
} else if (nextchar == 22) {
fg &= ~8;
fgcol = txtcols[fg];
} else if (nextchar == 38) {
int r, g, b, c;
c = strtoul(c_character + 1, NULL, 10);
if (c == 5) {
bgfg = 2;
continue;
}
2023-07-21 01:23:43 +02:00
strtoul(c_character + 1, &c_character, 10);
r = strtoul(c_character + 1, &c_character, 10);
g = strtoul(c_character + 1, &c_character, 10);
b = strtoul(c_character + 1, &c_character, 10);
fgcol = malloc(8 * sizeof(char));
snprintf(fgcol, 8, "#%02X%02X%02X", r, g, b);
} else if (nextchar == 39) {
fga = ofga;
fgcol = ofgcol;
2023-05-08 23:00:45 +02:00
} else if (nextchar >= 30 && nextchar <= 37) {
fg = nextchar % 10 | (fg & 8);
fgcol = txtcols[fg];
2023-05-08 23:00:45 +02:00
} else if (nextchar >= 40 && nextchar <= 47) {
bg = nextchar % 10;
bgcol = txtcols[bg];
2023-05-08 23:00:45 +02:00
} else if (nextchar == 48) {
int r, g, b, c;
c = strtoul(c_character + 1, NULL, 10);
if (c == 5) {
bgfg = 3;
continue;
}
2023-07-21 01:23:43 +02:00
strtoul(c_character + 1, &c_character, 10);
r = strtoul(c_character + 1, &c_character, 10);
g = strtoul(c_character + 1, &c_character, 10);
b = strtoul(c_character + 1, &c_character, 10);
bgcol = malloc(8 * sizeof(char));
snprintf(bgcol, 8, "#%02X%02X%02X", r, g, b);
} else if (nextchar == 49) {
bga = obga;
bgcol = obgcol;
} else if (nextchar == 0) {
2023-07-06 16:19:20 +02:00
fgcol = ofgcol;
bgcol = obgcol;
fga = ofga;
bga = obga;
2023-03-02 11:40:52 +01:00
}
2023-05-08 23:00:45 +02:00
}
2023-03-02 11:40:52 +01:00
escape += colindex + 2;
character = 0;
2023-03-02 11:40:52 +01:00
2023-05-08 23:00:45 +02:00
continue;
}
}
2023-03-02 11:40:52 +01:00
buffer[character++] = item->text[escape];
2023-05-08 23:00:45 +02:00
}
2023-03-02 11:40:52 +01:00
buffer[character] = '\0';
2023-03-02 11:40:52 +01:00
// now draw any non-colored text
2023-03-02 11:40:52 +01:00
apply_fribidi(buffer);
2023-07-21 01:23:43 +02:00
int ret = draw_text(draw, x, y, w, sp.bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
if (!hidehighlight)
2023-07-07 16:05:01 +02:00
drawhighlights(item, ox, oy, ow, oleftpadding, item->nsgrtext);
2023-03-02 11:40:52 +01:00
2023-06-18 21:15:32 +02:00
if (!hidepowerline && powerlineitems && selitem) {
if (itempwlstyle == 2) {
2023-07-21 01:23:43 +02:00
draw_circle(draw, ret, y, sp.plw, sp.bh, 1, col_menu, obgcol, alpha_menu, obga);
} else {
2023-07-21 01:23:43 +02:00
draw_arrow(draw, ret, y, sp.plw, sp.bh, 1, itempwlstyle, col_menu, obgcol, alpha_menu, obga);
}
}
2023-07-21 01:23:43 +02:00
return ret;
2023-03-02 11:40:52 +01:00
}
int drawitem(int x, int y, int w) {
2023-05-08 23:00:45 +02:00
struct item *item;
2023-03-02 11:40:52 +01:00
2023-06-23 17:27:57 +02:00
int numberw = 0;
int modew = 0;
int larroww = 0;
int rarroww = 0;
int capsw = 0;
// add width
2023-06-23 17:27:57 +02:00
if (!hidelarrow) larroww = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hiderarrow) rarroww = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
if (!hidematchcount) numberw = pango_numbers ? TEXTWM(tx.numbers) : TEXTW(tx.numbers);
if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
2023-03-12 21:03:35 +01:00
2023-06-23 03:38:21 +02:00
if (!strcmp(tx.capstext, ""))
2023-06-23 17:27:57 +02:00
capsw = 0;
2023-03-12 21:03:35 +01:00
2023-05-08 23:00:45 +02:00
#if USEIMAGE
2023-03-26 16:42:11 +02:00
int ox = 0; // original x position
2023-05-08 23:00:45 +02:00
#endif
2023-03-02 11:40:52 +01:00
// draw items and image
2023-05-08 23:00:45 +02:00
if (lines > 0) {
int i = 0;
2023-03-24 04:04:37 +01:00
int rx = 0;
// draw image first
2023-05-08 23:00:45 +02:00
#if USEIMAGE
2023-07-03 18:48:38 +02:00
if (!hideimage && img.longestedge != 0 && imagetype) {
2023-03-24 04:04:37 +01:00
rx = ox;
rx += MAX((img.imagegaps * 2) + img.imagewidth + menumarginh, indentitems ? x : 0);
2023-03-24 04:04:37 +01:00
} else
2023-05-08 23:00:45 +02:00
#endif
2023-03-24 04:04:37 +01:00
if (!indentitems) {
rx = 0;
} else {
rx = x;
}
2023-05-07 15:33:09 +02:00
int itemoverride = 1;
itemn = 0;
2023-05-07 15:33:09 +02:00
for (item = currentitem; item != nextitem; item = item->right, i++) {
item->nsgrtext = get_text_n_sgr(item);
2023-05-08 23:00:45 +02:00
x = drawitemtext(
item,
2023-06-23 03:38:21 +02:00
rx + menumarginh + ((i / lines) * ((sp.mw - rx) / columns)) + (powerlineitems ? sp.plw : 0),
y + (((i % lines) + 1) * sp.bh),
(sp.mw - rx) / columns - (powerlineitems ? 2 * sp.plw : 0) - (2 * menumarginh)
);
2023-05-07 15:33:09 +02:00
if (item == selecteditem && itemoverride) {
2023-06-23 03:38:21 +02:00
sp.itemnumber = i;
2023-05-07 15:33:09 +02:00
itemoverride = 0;
}
2023-05-13 16:07:29 +02:00
itemn = !itemn;
2023-03-13 22:45:04 +01:00
}
2023-05-08 23:00:45 +02:00
// horizontal list
} else if (matches) {
2023-06-23 03:38:21 +02:00
x += sp.inputw;
if (!hidelarrow) {
2023-06-23 17:27:57 +02:00
w = larroww;
x = drawlarrow(x, y, w);
}
2023-06-23 03:38:21 +02:00
sp.itemnumber = 0;
2023-05-07 15:33:09 +02:00
int itemoverride = 1;
for (item = currentitem; item != nextitem; item = item->right) { // draw items
item->nsgrtext = get_text_n_sgr(item);
x = drawitemtext(item, x + (powerlineitems ? 2 * sp.plw : 0), y, MIN(pango_item ? TEXTWM(item->nsgrtext) : TEXTW(item->nsgrtext),
2023-06-23 03:38:21 +02:00
sp.mw - x -
2023-06-23 17:27:57 +02:00
rarroww -
numberw -
modew -
capsw -
2023-04-21 09:49:38 +02:00
menumarginh -
2023-06-23 03:38:21 +02:00
2 * sp.sp -
2 * borderwidth -
(powerlineitems ? 2 * sp.plw : 0)
2023-05-08 23:00:45 +02:00
));
2023-04-21 09:49:38 +02:00
2023-05-07 15:33:09 +02:00
if (itemoverride) {
2023-06-23 03:38:21 +02:00
sp.itemnumber++;
2023-05-07 15:33:09 +02:00
}
if (item == selecteditem) {
2023-05-07 15:33:09 +02:00
itemoverride = 0;
}
}
if (!hiderarrow) {
2023-06-23 17:27:57 +02:00
w = rarroww + numberw + modew + capsw + menumarginh + 2 * sp.sp + 2 * borderwidth;
2023-06-23 03:38:21 +02:00
x = drawrarrow(sp.mw - w, y, w);
}
2023-05-08 23:00:45 +02:00
}
2023-03-02 11:40:52 +01:00
2023-03-26 16:42:11 +02:00
return x;
}
int drawprompt(int x, int y, int w) {
2023-05-08 23:00:45 +02:00
if (prompt && *prompt && !hideprompt) {
x = draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, prompt, 0, pango_prompt ? True : False, col_promptfg, col_promptbg, alpha_promptfg, alpha_promptbg);
2023-03-26 16:42:11 +02:00
if (!hidepowerline && powerlineprompt) {
2023-06-07 21:31:10 +02:00
if (promptpwlstyle == 2) {
draw_circle(draw, x, y, sp.plw, sp.bh, 1, col_menu, col_promptbg, alpha_menu, alpha_promptbg);
2023-06-07 21:31:10 +02:00
} else {
draw_arrow(draw, x, y, sp.plw, sp.bh, 1, promptpwlstyle, col_menu, col_promptbg, alpha_menu, alpha_promptbg);
2023-06-07 21:31:10 +02:00
}
2023-06-23 03:38:21 +02:00
x += sp.plw;
2023-03-26 16:42:11 +02:00
}
2023-05-08 23:00:45 +02:00
}
2023-03-26 16:42:11 +02:00
return x;
}
int drawinput(int x, int y, int w) {
char *censort;
2023-05-08 23:00:45 +02:00
unsigned int curpos = 0;
int fh = caretheight;
int fw = MAX(2, caretwidth);
int fp = caretpadding;
2023-07-16 19:07:41 +02:00
if (fh > sp.bh || !fh) {
fh = sp.bh - sp.lrpad / 4;
}
2023-03-26 16:42:11 +02:00
2023-05-08 23:00:45 +02:00
if (passwd) {
2023-06-23 03:38:21 +02:00
censort = ecalloc(1, sizeof(tx.text));
2023-06-23 03:38:21 +02:00
for (int i = 0; i < strlen(tx.text); i++)
memcpy(&censort[i], password, strlen(tx.text));
2023-03-26 16:42:11 +02:00
apply_fribidi(censort);
draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, isrtl ? fribidi_text : censort, 0, pango_password ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg);
2023-03-26 16:42:11 +02:00
2023-06-23 03:38:21 +02:00
curpos = TEXTW(censort) - TEXTW(&tx.text[sp.cursor]);
2023-03-26 16:42:11 +02:00
free(censort);
2023-05-08 23:00:45 +02:00
} else if (!passwd) {
if (strlen(tx.text)) {
apply_fribidi(tx.text);
draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, isrtl ? fribidi_text : tx.text, 0, pango_input ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg);
curpos = TEXTW(tx.text) - TEXTW(&tx.text[sp.cursor]);
} else if (!hidepretext && pretext != NULL) {
apply_fribidi(pretext);
draw_text(draw, x + fw, y, w, sp.bh, sp.lrpad / 2, isrtl ? fribidi_text : pretext, 0, pango_pretext ? True : False, col_pretextfg, col_pretextbg, alpha_pretextfg, alpha_pretextbg);
}
2023-03-26 16:42:11 +02:00
}
2023-06-23 03:38:21 +02:00
if ((curpos += sp.lrpad / 2 - 1) < w && !hidecaret) {
curpos += fp;
draw_rect(draw, x + curpos, 2 + (sp.bh - fh) / 2 + y, fw, fh - 4, 1, 0, col_caretfg, col_caretbg, alpha_caretfg, alpha_caretbg);
2023-05-08 23:00:45 +02:00
}
2023-03-26 16:42:11 +02:00
return x;
}
int drawlarrow(int x, int y, int w) {
2023-03-29 22:01:45 +02:00
if (hidelarrow) return x;
2023-03-26 16:42:11 +02:00
if (currentitem->left) { // draw left arrow
draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2, leftarrow, 0, pango_leftarrow ? True : False, col_larrowfg, col_larrowbg, alpha_larrowfg, alpha_larrowbg);
2023-05-08 23:00:45 +02:00
x += w;
}
2023-03-26 16:42:11 +02:00
return x;
}
int drawrarrow(int x, int y, int w) {
2023-03-29 22:01:45 +02:00
if (hiderarrow) return x;
2023-03-26 16:42:11 +02:00
if (nextitem) { // draw right arrow
draw_text(draw, sp.mw - w, y, w, sp.bh, sp.lrpad / 2, rightarrow, 0, pango_rightarrow ? True : False, col_rarrowfg, col_rarrowbg, alpha_rarrowfg, alpha_rarrowbg);
2023-03-29 22:01:45 +02:00
x += w;
2023-05-08 23:00:45 +02:00
}
2023-03-02 11:40:52 +01:00
2023-03-26 16:42:11 +02:00
return x;
}
int drawnumber(int x, int y, int w) {
2023-04-05 19:07:29 +02:00
if (hidematchcount) return x;
2023-03-21 16:40:11 +01:00
int powerlinewidth = 0;
if (!hidepowerline && powerlinecount) {
2023-06-23 03:38:21 +02:00
powerlinewidth = sp.plw / 2;
}
2023-03-21 16:40:11 +01:00
draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2 + powerlinewidth, tx.numbers, 0, pango_numbers ? True : False, col_numfg, col_numbg, alpha_numfg, alpha_numbg);
2023-03-21 16:40:11 +01:00
2023-04-05 19:07:29 +02:00
// draw powerline for match count
if (!hidepowerline && powerlinecount) {
2023-06-07 21:31:10 +02:00
if (matchcountpwlstyle == 2) {
draw_circle(draw, x, y, sp.plw, sp.bh, 0, col_menu, col_numbg, alpha_menu, alpha_numbg);
2023-06-07 21:31:10 +02:00
} else {
draw_arrow(draw, x, y, sp.plw, sp.bh, 0, matchcountpwlstyle, col_menu, col_numbg, alpha_menu, alpha_numbg);
2023-06-07 21:31:10 +02:00
}
2023-04-05 19:07:29 +02:00
2023-06-23 03:38:21 +02:00
x += sp.plw;
2023-03-02 11:40:52 +01:00
}
2023-03-26 16:42:11 +02:00
return x;
}
int drawmode(int x, int y, int w) {
if (!hidemode) { // draw mode indicator
int powerlinewidth = 0;
if (!hidepowerline && powerlinemode) {
2023-06-23 03:38:21 +02:00
powerlinewidth = sp.plw / 2;
}
2023-03-21 16:40:11 +01:00
draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2 + powerlinewidth, tx.modetext, 0, pango_mode ? True : False, col_modefg, col_modebg, alpha_modefg, alpha_modebg);
2023-03-21 16:40:11 +01:00
// draw powerline for match count
if (!hidepowerline && powerlinemode) {
2023-06-07 21:31:10 +02:00
if (modepwlstyle == 2) {
draw_circle(draw, x, y, sp.plw, sp.bh, 0,
2023-06-07 21:31:10 +02:00
hidematchcount ? col_menu : col_numbg, col_modebg,
hidematchcount ? alpha_menu : alpha_numbg, alpha_modebg);
} else {
draw_arrow(draw, x, y, sp.plw, sp.bh, 0, modepwlstyle,
2023-06-07 21:31:10 +02:00
hidematchcount ? col_menu : col_numbg, col_modebg,
hidematchcount ? alpha_menu : alpha_numbg, alpha_modebg);
}
2023-03-21 16:40:11 +01:00
2023-06-23 03:38:21 +02:00
x += sp.plw;
2023-03-21 16:40:11 +01:00
}
2023-03-02 11:40:52 +01:00
}
2023-05-08 23:00:45 +02:00
return x;
2023-03-26 16:42:11 +02:00
}
int drawcaps(int x, int y, int w) {
if (!w) return x; // not caps lock
if (!hidecaps) { // draw caps lock indicator
int powerlinewidth = 0;
if (!hidepowerline && powerlinecaps) {
2023-06-23 03:38:21 +02:00
powerlinewidth = sp.plw / 2;
}
draw_text(draw, x, y, w, sp.bh, sp.lrpad / 2 + powerlinewidth, tx.capstext, 0, pango_caps ? True : False, col_capsfg, col_capsbg, alpha_capsfg, alpha_capsbg);
// draw powerline for caps lock indicator
if (!hidepowerline && powerlinecaps) {
2023-06-07 21:31:10 +02:00
if (capspwlstyle == 2) {
draw_circle(draw, x, y, sp.plw, sp.bh, 0,
2023-06-07 21:31:10 +02:00
hidemode ? hidematchcount ? col_menu : col_numbg : col_modebg, col_capsbg,
hidemode ? hidematchcount ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg);
} else {
draw_arrow(draw, x, y, sp.plw, sp.bh, 0, capspwlstyle,
2023-06-07 21:31:10 +02:00
hidemode ? hidematchcount ? col_menu : col_numbg : col_modebg, col_capsbg,
hidemode ? hidematchcount ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg);
}
2023-06-23 03:38:21 +02:00
x += sp.plw;
}
}
2023-05-08 23:00:45 +02:00
return x;
}
void drawmenu(void) {
2023-07-27 00:39:57 +02:00
if (sp.isdrawing) {
while (sp.isdrawing != 0) {
;
}
}
sp.isdrawing = 1;
#if USEWAYLAND
if (protocol) {
if (listfile) {
2023-07-09 23:56:34 +02:00
readstdin();
2023-07-09 23:56:34 +02:00
if (sp.listchanged) {
resizeclient();
match();
2023-06-23 03:38:21 +02:00
for (int i = 0; i < sp.itemnumber; i++) {
if (selecteditem && selecteditem->right && (selecteditem = selecteditem->right) == nextitem) {
currentitem = nextitem;
}
}
}
}
2023-07-27 00:39:57 +02:00
drawmenu_layer();
#if USEIMAGE
drawimage();
#endif
commit_drawable(&state);
} else {
2023-07-09 23:56:34 +02:00
#endif
#if USEX
if (listfile) {
readstdin();
if (sp.listchanged) {
match();
for (int i = 0; i < sp.itemnumber; i++) {
if (selecteditem && selecteditem->right && (selecteditem = selecteditem->right) == nextitem) {
currentitem = nextitem;
2023-07-09 23:56:34 +02:00
}
}
}
}
2023-07-27 00:39:57 +02:00
drawmenu_layer();
2023-07-27 00:39:57 +02:00
#if USEIMAGE
drawimage();
#endif
draw_map(draw, win, 0, 0, sp.mw, sp.mh);
2023-07-09 23:56:34 +02:00
#endif
#if USEWAYLAND
}
#endif
2023-07-27 00:39:57 +02:00
sp.isdrawing = 0;
}
void drawmenu_layer(void) {
2023-05-08 23:00:45 +02:00
int x = 0, y = 0, w = 0;
sp.plw = hidepowerline ? 0 : draw->font->h / 2 + 1; // powerline size
2023-03-26 16:42:11 +02:00
sp_strncpy(tx.modetext, sp.mode ? instext : normtext, sizeof(tx.modetext));
#if USEREGEX
if (regex && regextext && sp.mode) {
sp_strncpy(tx.modetext, regextext, sizeof(tx.modetext));
}
#endif
2023-03-26 16:42:11 +02:00
// draw menu first using menu scheme
draw_rect(draw, 0, 0, sp.mw, sp.mh, 1, 1, col_menu, col_menu, alpha_menu, alpha_menu);
2023-03-26 16:42:11 +02:00
2023-06-23 17:27:57 +02:00
int numberw = 0;
int modew = 0;
int capsw = 0;
2023-03-26 16:42:11 +02:00
// add width
2023-06-23 17:27:57 +02:00
if (!hidemode) modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
if (!hidecaps) capsw = pango_caps ? TEXTWM(tx.capstext) : TEXTW(tx.capstext);
2023-06-23 03:38:21 +02:00
if (!strcmp(tx.capstext, ""))
2023-06-23 17:27:57 +02:00
capsw = 0;
2023-03-26 16:42:11 +02:00
// calculate match count
if (!hidematchcount) {
recalculatenumbers();
2023-06-23 17:27:57 +02:00
numberw = TEXTW(tx.numbers);
2023-03-26 16:42:11 +02:00
}
x += menumarginh;
y += menumarginv;
2023-04-21 09:49:38 +02:00
calcoffsets();
2023-06-11 16:46:36 +02:00
get_mh();
2023-04-21 09:49:38 +02:00
int nh = 1;
2023-06-23 03:38:21 +02:00
// sp.bh must be removed from menu height resizing later
if ((hideprompt && hideinput && hidemode && hidematchcount && hidecaps) && lines) {
2023-06-23 03:38:21 +02:00
y -= sp.bh;
nh = 0;
}
if (!hidemode) {
modew = pango_mode ? TEXTWM(tx.modetext) : TEXTW(tx.modetext);
}
if (!hideprompt) {
2023-06-23 03:38:21 +02:00
w = sp.promptw;
x = drawprompt(x, y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0), w);
}
if (!hideinput) {
2023-06-23 03:38:21 +02:00
w = (lines > 0 || !matches) ? sp.mw - x : sp.inputw;
x = drawinput(x, y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0), w);
}
2023-04-05 18:58:48 +02:00
// draw the items, this function also calls drawrarrow() and drawlarrow()
if (!hideitem) {
drawitem(x, y - (nh ? lines ? itemposition ? sp.bh : 0 : 0 : 0), w);
}
if (!hidematchcount) {
2023-06-23 17:27:57 +02:00
w = numberw;
drawnumber(
sp.mw - numberw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh,
y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0),
w
);
}
2023-04-05 19:07:29 +02:00
if (!hidemode) {
2023-06-23 17:27:57 +02:00
w = modew;
drawmode(
sp.mw - modew - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh,
y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0),
w
);
}
if (!hidecaps) {
2023-06-23 17:27:57 +02:00
w = capsw;
drawcaps(
sp.mw - capsw - 2 * sp.sp - 2 * borderwidth - menumarginh,
y + (nh ? lines ? itemposition ? (sp.mh - sp.bh) : 0 : 0 : 0),
w
);
}
2023-07-27 00:39:57 +02:00
}