forked from RepoMirrors/bemenu
Add a feedback for touchscreen support
The idea is to write "Scroll up…", "Scroll down…" when the finger touching bemenu will trigger a page scroll on release.
This commit is contained in:
parent
a111aa2afa
commit
9b8da12467
@ -212,6 +212,8 @@ usage(FILE *out, const char *name)
|
||||
" --nf defines the normal foreground color. (wx)\n"
|
||||
" --hb defines the highlighted background color. (wx)\n"
|
||||
" --hf defines the highlighted foreground color. (wx)\n"
|
||||
" --fbb defines the feedback background color. (wx)\n"
|
||||
" --fbf defines the feedback foreground color. (wx)\n"
|
||||
" --sb defines the selected background color. (wx)\n"
|
||||
" --sf defines the selected foreground color. (wx)\n"
|
||||
" --scb defines the scrollbar background color. (wx)\n"
|
||||
@ -257,10 +259,9 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
{ "prefix", required_argument, 0, 'P' },
|
||||
{ "password", no_argument, 0, 'x' },
|
||||
{ "scrollbar", required_argument, 0, 0x100 },
|
||||
{ "ifne", no_argument, 0, 0x115 },
|
||||
{ "fork", no_argument, 0, 0x116 },
|
||||
{ "no-exec", no_argument, 0, 0x117 },
|
||||
|
||||
{ "ifne", no_argument, 0, 0x117 },
|
||||
{ "fork", no_argument, 0, 0x118 },
|
||||
{ "no-exec", no_argument, 0, 0x119 },
|
||||
{ "bottom", no_argument, 0, 'b' },
|
||||
{ "grab", no_argument, 0, 'f' },
|
||||
{ "no-overlap", no_argument, 0, 'n' },
|
||||
@ -279,12 +280,14 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
{ "nf", required_argument, 0, 0x107 },
|
||||
{ "hb", required_argument, 0, 0x108 },
|
||||
{ "hf", required_argument, 0, 0x109 },
|
||||
{ "sb", required_argument, 0, 0x110 },
|
||||
{ "sf", required_argument, 0, 0x111 },
|
||||
{ "scb", required_argument, 0, 0x112 },
|
||||
{ "scf", required_argument, 0, 0x113 },
|
||||
{ "fbb", required_argument, 0, 0x110 },
|
||||
{ "fbf", required_argument, 0, 0x111 },
|
||||
{ "sb", required_argument, 0, 0x112 },
|
||||
{ "sf", required_argument, 0, 0x113 },
|
||||
{ "scb", required_argument, 0, 0x114 },
|
||||
{ "scf", required_argument, 0, 0x115 },
|
||||
|
||||
{ "disco", no_argument, 0, 0x114 },
|
||||
{ "disco", no_argument, 0, 0x116 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -336,13 +339,13 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
case 0x100:
|
||||
client->scrollbar = (!strcmp(optarg, "none") ? BM_SCROLLBAR_NONE : (!strcmp(optarg, "always") ? BM_SCROLLBAR_ALWAYS : (!strcmp(optarg, "autohide") ? BM_SCROLLBAR_AUTOHIDE : BM_SCROLLBAR_NONE)));
|
||||
break;
|
||||
case 0x115:
|
||||
case 0x117:
|
||||
client->ifne = true;
|
||||
break;
|
||||
case 0x116:
|
||||
case 0x118:
|
||||
client->force_fork = true;
|
||||
break;
|
||||
case 0x117:
|
||||
case 0x119:
|
||||
client->no_exec = true;
|
||||
break;
|
||||
case 'x':
|
||||
@ -374,7 +377,7 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
case 'W':
|
||||
client->width_factor = strtof(optarg, NULL);
|
||||
break;
|
||||
case 0x118:
|
||||
case 0x120:
|
||||
client->cursor_height = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case 0x101:
|
||||
@ -405,19 +408,25 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
client->colors[BM_COLOR_HIGHLIGHTED_FG] = optarg;
|
||||
break;
|
||||
case 0x110:
|
||||
client->colors[BM_COLOR_SELECTED_BG] = optarg;
|
||||
client->colors[BM_COLOR_FEEDBACK_BG] = optarg;
|
||||
break;
|
||||
case 0x111:
|
||||
client->colors[BM_COLOR_SELECTED_FG] = optarg;
|
||||
client->colors[BM_COLOR_FEEDBACK_FG] = optarg;
|
||||
break;
|
||||
case 0x112:
|
||||
client->colors[BM_COLOR_SCROLLBAR_BG] = optarg;
|
||||
client->colors[BM_COLOR_SELECTED_BG] = optarg;
|
||||
break;
|
||||
case 0x113:
|
||||
client->colors[BM_COLOR_SELECTED_FG] = optarg;
|
||||
break;
|
||||
case 0x114:
|
||||
client->colors[BM_COLOR_SCROLLBAR_BG] = optarg;
|
||||
break;
|
||||
case 0x115:
|
||||
client->colors[BM_COLOR_SCROLLBAR_FG] = optarg;
|
||||
break;
|
||||
|
||||
case 0x114:
|
||||
case 0x116:
|
||||
disco();
|
||||
break;
|
||||
|
||||
|
10
lib/bemenu.h
10
lib/bemenu.h
@ -317,6 +317,14 @@ struct bm_touch {
|
||||
struct bm_touch_point points[2];
|
||||
};
|
||||
|
||||
enum bm_event_feedback_mask {
|
||||
TOUCH_WILL_SCROLL_UP = 1 << 1,
|
||||
TOUCH_WILL_SCROLL_DOWN = 1 << 2,
|
||||
TOUCH_WILL_SCROLL_FIRST = 1 << 3,
|
||||
TOUCH_WILL_SCROLL_LAST = 1 << 4,
|
||||
TOUCH_WILL_CANCEL = 1 << 5,
|
||||
};
|
||||
|
||||
/**
|
||||
* Colorable element constants.
|
||||
*
|
||||
@ -331,6 +339,8 @@ enum bm_color {
|
||||
BM_COLOR_ITEM_FG,
|
||||
BM_COLOR_HIGHLIGHTED_BG,
|
||||
BM_COLOR_HIGHLIGHTED_FG,
|
||||
BM_COLOR_FEEDBACK_BG,
|
||||
BM_COLOR_FEEDBACK_FG,
|
||||
BM_COLOR_SELECTED_BG,
|
||||
BM_COLOR_SELECTED_FG,
|
||||
BM_COLOR_SCROLLBAR_BG,
|
||||
|
@ -386,6 +386,11 @@ struct bm_menu {
|
||||
* Should the entry should follow the title spacing
|
||||
*/
|
||||
bool spacing;
|
||||
|
||||
/**
|
||||
* Mask representing a feedback to bring to user
|
||||
*/
|
||||
uint32_t event_feedback;
|
||||
};
|
||||
|
||||
/* library.c */
|
||||
|
87
lib/menu.c
87
lib/menu.c
@ -23,6 +23,8 @@ static const char *default_colors[BM_COLOR_LAST] = {
|
||||
"#CACACAFF", // BM_COLOR_ITEM_FG
|
||||
"#121212FF", // BM_COLOR_HIGHLIGHTED_BG
|
||||
"#D81860FF", // BM_COLOR_HIGHLIGHTED_FG
|
||||
"#D81860FF", // BM_COLOR_FEEDBACK_BG
|
||||
"#121212FF", // BM_COLOR_FEEDBACK_FG
|
||||
"#121212FF", // BM_COLOR_SELECTED_BG
|
||||
"#D81860FF", // BM_COLOR_SELECTED_FG
|
||||
"#121212FF", // BM_COLOR_SCROLLBAR_BG
|
||||
@ -826,6 +828,31 @@ menu_scroll_up(struct bm_menu *menu, uint16_t count)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
menu_scroll_first(struct bm_menu *menu, uint16_t count)
|
||||
{
|
||||
(void) count;
|
||||
menu->index = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
menu_scroll_last(struct bm_menu *menu, uint16_t count)
|
||||
{
|
||||
menu->index = count - 1;
|
||||
}
|
||||
|
||||
void
|
||||
bm_menu_add_event_feedback(struct bm_menu *menu, uint32_t event_feedback)
|
||||
{
|
||||
menu->event_feedback |= event_feedback;
|
||||
}
|
||||
|
||||
void
|
||||
bm_menu_remove_event_feedback(struct bm_menu *menu, uint32_t event_feedback)
|
||||
{
|
||||
menu->event_feedback &= ~event_feedback;
|
||||
}
|
||||
|
||||
enum bm_run_result
|
||||
bm_menu_run_with_key(struct bm_menu *menu, enum bm_key key, uint32_t unicode)
|
||||
{
|
||||
@ -1181,20 +1208,56 @@ bm_menu_run_with_touch(struct bm_menu *menu, struct bm_touch touch, uint32_t uni
|
||||
continue;
|
||||
|
||||
menu_point_select(menu, point.pos_x, point.pos_y, displayed);
|
||||
bm_menu_remove_event_feedback(menu,
|
||||
TOUCH_WILL_CANCEL
|
||||
| TOUCH_WILL_SCROLL_FIRST
|
||||
| TOUCH_WILL_SCROLL_LAST
|
||||
| TOUCH_WILL_SCROLL_UP
|
||||
| TOUCH_WILL_SCROLL_DOWN
|
||||
);
|
||||
|
||||
if (point.event_mask & TOUCH_EVENT_UP) {
|
||||
if (point.pos_y < (int32_t) (bm_menu_get_height(menu) / displayed)) {
|
||||
menu_scroll_up(menu, count);
|
||||
} else if ((uint32_t) point.pos_y > bm_menu_get_height(menu)) {
|
||||
menu_scroll_down(menu, count);
|
||||
} else if (point.pos_x > 0
|
||||
&& (uint32_t) point.pos_x < bm_menu_get_width(menu)) {
|
||||
{
|
||||
struct bm_item *highlighted = bm_menu_get_highlighted_item(menu);
|
||||
if (highlighted && !bm_menu_item_is_selected(menu, highlighted))
|
||||
list_add_item(&menu->selection, highlighted);
|
||||
if (point.pos_y < (int32_t) (bm_menu_get_height(menu) / displayed)) {
|
||||
if (point.pos_y < ((int32_t) (bm_menu_get_height(menu) / displayed)) - 50) {
|
||||
if (point.event_mask & TOUCH_EVENT_UP) {
|
||||
menu_scroll_first(menu, count);
|
||||
} else if (point.event_mask & TOUCH_EVENT_MOTION) {
|
||||
bm_menu_add_event_feedback(menu, TOUCH_WILL_SCROLL_FIRST);
|
||||
}
|
||||
} else {
|
||||
if (point.event_mask & TOUCH_EVENT_UP) {
|
||||
menu_scroll_up(menu, count);
|
||||
} else if (point.event_mask & TOUCH_EVENT_MOTION) {
|
||||
bm_menu_add_event_feedback(menu, TOUCH_WILL_SCROLL_UP);
|
||||
}
|
||||
}
|
||||
} else if ((uint32_t) point.pos_y > bm_menu_get_height(menu)) {
|
||||
if ((uint32_t) point.pos_y > bm_menu_get_height(menu) + 50) {
|
||||
if (point.event_mask & TOUCH_EVENT_UP) {
|
||||
menu_scroll_last(menu, count);
|
||||
} else if (point.event_mask & TOUCH_EVENT_MOTION) {
|
||||
bm_menu_add_event_feedback(menu, TOUCH_WILL_SCROLL_LAST);
|
||||
}
|
||||
} else {
|
||||
if (point.event_mask & TOUCH_EVENT_UP) {
|
||||
menu_scroll_down(menu, count);
|
||||
} else if (point.event_mask & TOUCH_EVENT_MOTION) {
|
||||
bm_menu_add_event_feedback(menu, TOUCH_WILL_SCROLL_DOWN);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (point.pos_x > 0 && (uint32_t) point.pos_x < bm_menu_get_width(menu)) {
|
||||
if (point.event_mask & TOUCH_EVENT_UP) {
|
||||
{
|
||||
struct bm_item *highlighted = bm_menu_get_highlighted_item(menu);
|
||||
if (highlighted && !bm_menu_item_is_selected(menu, highlighted))
|
||||
list_add_item(&menu->selection, highlighted);
|
||||
}
|
||||
return BM_RUN_RESULT_SELECTED;
|
||||
}
|
||||
} else {
|
||||
if (!(point.event_mask & TOUCH_EVENT_UP)) {
|
||||
bm_menu_add_event_feedback(menu, TOUCH_WILL_CANCEL);
|
||||
}
|
||||
return BM_RUN_RESULT_SELECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,47 @@ bm_cairo_color_from_menu_color(const struct bm_menu *menu, enum bm_color color,
|
||||
c->a = (float)menu->colors[color].a / 255.0f;
|
||||
}
|
||||
|
||||
static char *
|
||||
bm_cairo_entry_message(char *entry_text, bool highlighted, uint32_t event_feedback, uint32_t index, uint32_t count)
|
||||
{
|
||||
if (!highlighted || !event_feedback) {
|
||||
return entry_text ? entry_text : "";
|
||||
} else {
|
||||
if (event_feedback & TOUCH_WILL_CANCEL) {
|
||||
return "Cancel…";
|
||||
}
|
||||
if (event_feedback & TOUCH_WILL_SCROLL_FIRST) {
|
||||
if (index == 0) {
|
||||
return "Already on the first page…";
|
||||
} else {
|
||||
return "First page…";
|
||||
}
|
||||
}
|
||||
if (event_feedback & TOUCH_WILL_SCROLL_UP) {
|
||||
if (index == 0) {
|
||||
return "Already on the first page…";
|
||||
} else {
|
||||
return "Previous page…";
|
||||
}
|
||||
}
|
||||
if (event_feedback & TOUCH_WILL_SCROLL_DOWN) {
|
||||
if (index == count - 1) {
|
||||
return "Already on the last page…";
|
||||
} else {
|
||||
return "Next page…";
|
||||
}
|
||||
}
|
||||
if (event_feedback & TOUCH_WILL_SCROLL_LAST) {
|
||||
if (index == count - 1) {
|
||||
return "Already on the last page…";
|
||||
} else {
|
||||
return "Last page…";
|
||||
}
|
||||
}
|
||||
return "Not handled feedback…";
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *out_result)
|
||||
{
|
||||
@ -303,8 +344,13 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
|
||||
bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu));
|
||||
|
||||
if (highlighted) {
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_FG, &paint.fg);
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_BG, &paint.bg);
|
||||
if (menu->event_feedback) {
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_FEEDBACK_FG, &paint.fg);
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_FEEDBACK_BG, &paint.bg);
|
||||
} else {
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_FG, &paint.fg);
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_HIGHLIGHTED_BG, &paint.bg);
|
||||
}
|
||||
} else if (bm_menu_item_is_selected(menu, items[i])) {
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_FG, &paint.fg);
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_SELECTED_BG, &paint.bg);
|
||||
@ -313,14 +359,15 @@ bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const s
|
||||
bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_BG, &paint.bg);
|
||||
}
|
||||
|
||||
char *line_str = bm_cairo_entry_message(items[i]->text, highlighted, menu->event_feedback, i, count);
|
||||
if (menu->prefix && highlighted) {
|
||||
paint.pos = (struct pos){ spacing_x, posy+vpadding };
|
||||
paint.box = (struct box){ 4, 0, vpadding, -vpadding, width - paint.pos.x, height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s %s", menu->prefix, (items[i]->text ? items[i]->text : ""));
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s %s", menu->prefix, line_str);
|
||||
} else {
|
||||
paint.pos = (struct pos){ spacing_x, posy+vpadding };
|
||||
paint.box = (struct box){ 4 + prefix_x, 0, vpadding, -vpadding, width - paint.pos.x, height };
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : ""));
|
||||
bm_cairo_draw_line(cairo, &paint, &result, "%s", line_str);
|
||||
}
|
||||
|
||||
posy += (spacing_y ? spacing_y : result.height);
|
||||
|
Loading…
Reference in New Issue
Block a user