menu: Better tail alignment for bubble windows

This commit is contained in:
K. Lange 2021-11-29 15:49:11 +09:00
parent 79f3d25f0b
commit 2b85c67661
5 changed files with 25 additions and 16 deletions

View File

@ -769,24 +769,26 @@ static void update_periodic_widgets(void) {
redraw();
}
int panel_menu_show(struct PanelWidget * this, struct MenuList * menu) {
int panel_menu_show_at(struct MenuList * menu, int x) {
int mwidth, mheight, offset;
/* Calculate the expected size of the menu window. */
menu_calculate_dimensions(menu, &mheight, &mwidth);
/* Are we too far left? */
if (this->left + this->width - (this->width + mwidth) / 2 < X_PAD) {
offset = this->left;
if (x - mwidth / 2 < X_PAD) {
offset = X_PAD;
menu->flags = (menu->flags & ~MENU_FLAG_BUBBLE) | MENU_FLAG_BUBBLE_LEFT;
} else if (this->left + this->width - (this->width + mwidth) / 2 + mwidth > width - X_PAD) {
offset = this->left + this->width - mwidth;
} else if (x + mwidth / 2 > width - X_PAD) {
offset = width - X_PAD - mwidth;
menu->flags = (menu->flags & ~MENU_FLAG_BUBBLE) | MENU_FLAG_BUBBLE_RIGHT;
} else {
offset = this->left + this->width - (this->width + mwidth) / 2;
offset = x - mwidth / 2;
menu->flags = (menu->flags & ~MENU_FLAG_BUBBLE) | MENU_FLAG_BUBBLE_CENTER;
}
menu->flags |= MENU_FLAG_TAIL_POSITION;
menu->tail_offset = x - offset;
/* Prepare the menu, which creates the window. */
menu_prepare(menu, yctx);
@ -800,6 +802,10 @@ int panel_menu_show(struct PanelWidget * this, struct MenuList * menu) {
return 1;
}
int panel_menu_show(struct PanelWidget * this, struct MenuList * menu) {
return panel_menu_show_at(menu, this->left + this->width / 2);
}
int main (int argc, char ** argv) {
if (argc < 2 || strcmp(argv[1],"--really")) {
fprintf(stderr,

View File

@ -70,6 +70,7 @@ struct MenuList {
struct menu_bar * _bar;
int closed;
int flags;
int tail_offset;
};
struct MenuSet {
@ -107,6 +108,7 @@ extern void menu_update_icon(struct MenuEntry * self, char * newIcon);
#define MENU_FLAG_BUBBLE_LEFT (1 << 1)
#define MENU_FLAG_BUBBLE_RIGHT (1 << 2)
#define MENU_FLAG_BUBBLE (MENU_FLAG_BUBBLE_LEFT | MENU_FLAG_BUBBLE_RIGHT | MENU_FLAG_BUBBLE_CENTER)
#define MENU_FLAG_TAIL_POSITION (1 << 3)
#define MENU_BAR_HEIGHT 24

View File

@ -81,6 +81,6 @@ extern int active_window;
extern void redraw(void);
extern char * ellipsify(char * input, int font_size, struct TT_Font * font, int max_width, int * out_width);
extern int panel_menu_show(struct PanelWidget * this, struct MenuList * menu);
extern int panel_menu_show_centered(struct PanelWidget * this, struct MenuList * menu);
extern int panel_menu_show_at(struct MenuList * menu, int x);
_End_C_Header

View File

@ -407,6 +407,7 @@ struct MenuList * menu_create(void) {
p->parent = NULL;
p->closed = 1;
p->flags = 0;
p->tail_offset = 0;
return p;
}
@ -535,7 +536,11 @@ static void _menu_redraw(yutani_window_t * menu_window, yutani_t * yctx, struct
/* Figure out where to draw the tail */
int tail_left = 0;
if (menu->flags & MENU_FLAG_BUBBLE_LEFT) {
/* Do we have a set tail? */
#define TAIL_BOUND 8
if (menu->flags & MENU_FLAG_TAIL_POSITION) {
tail_left = (menu->tail_offset < TAIL_BOUND) ? TAIL_BOUND : (menu->tail_offset > ctx->width - TAIL_BOUND) ? (ctx->width - TAIL_BOUND) : menu->tail_offset;
} else if (menu->flags & MENU_FLAG_BUBBLE_LEFT) {
tail_left = 16;
} else if (menu->flags & MENU_FLAG_BUBBLE_RIGHT) {
tail_left = ctx->width - 16;

View File

@ -46,14 +46,10 @@ static void _window_menu_close(struct MenuEntry * self) {
yutani_special_request_wid(yctx, _window_menu_wid, YUTANI_SPECIAL_REQUEST_PLEASE_CLOSE);
}
static void window_show_menu(yutani_wid_t wid, int y, int x) {
static void window_show_menu(yutani_wid_t wid, int x) {
if (window_menu->window) return;
_window_menu_wid = wid;
menu_prepare(window_menu, yctx);
if (window_menu->window) {
yutani_window_move(yctx, window_menu->window, y, x);
yutani_flip(yctx, window_menu->window);
}
panel_menu_show_at(window_menu, x);
}
static int widget_draw_windowlist(struct PanelWidget * this, gfx_context_t * ctx) {
@ -132,7 +128,7 @@ static int widget_rightclick_windowlist(struct PanelWidget * this, struct yutani
foreach(node, window_list) {
struct window_ad * ad = node->value;
if (evt->new_x >= ad->left && evt->new_x < ad->left + TOTAL_CELL_WIDTH) {
window_show_menu(ad->wid, evt->new_x, DROPDOWN_OFFSET);
window_show_menu(ad->wid, evt->new_x);
}
}
return 0;