Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 70 additions & 12 deletions lib/widget/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ struct menu_t
size_t max_entry_len; // cached max length of entry texts (text + shortcut)
size_t max_hotkey_len; // cached max length of shortcuts
unsigned int current; // pointer to current menu entry
unsigned int top; // menu entry currently at the top of the scroll area
char *help_node;
};

Expand Down Expand Up @@ -128,7 +129,7 @@ menubar_paint_idx (const WMenuBar *menubar, unsigned int idx, int color)
const WRect *w = &CONST_WIDGET (menubar)->rect;
const menu_t *menu = MENU (g_list_nth_data (menubar->menu, menubar->current));
const menu_entry_t *entry = MENUENTRY (g_list_nth_data (menu->entries, idx));
const int y = 2 + idx;
const int y = 2 + idx - menu->top;
int x = menu->start_x;

if (x + menu->max_entry_len + 3 > (gsize) w->cols)
Expand All @@ -150,6 +151,12 @@ menubar_paint_idx (const WMenuBar *menubar, unsigned int idx, int color)
int yt, xt;

// menu text

// left non-connecting border
widget_gotoyx (menubar, y, x - 1);
tty_setcolor (MENU_FRAME_COLOR);
tty_print_char (mc_tty_frm[MC_TTY_FRM_DVERT]);

tty_setcolor (color);
widget_gotoyx (menubar, y, x);
tty_print_char ((unsigned char) entry->first_letter);
Expand All @@ -173,21 +180,48 @@ menubar_paint_idx (const WMenuBar *menubar, unsigned int idx, int color)
tty_print_string (entry->shortcut);
}

// right non-connecting border
widget_gotoyx (menubar, y, x + menu->max_entry_len + 2);
tty_setcolor (MENU_FRAME_COLOR);
tty_print_char (mc_tty_frm[MC_TTY_FRM_DVERT]);

// move cursor to the start of entry text
widget_gotoyx (menubar, y, x + 1);
}
}

/* --------------------------------------------------------------------------------------------- */

static void
menubar_draw_drop_entries (const WMenuBar *menubar, menu_t *menu)
{
const unsigned int lines = WIDGET (menubar)->rect.lines - 2;
const unsigned int count = g_list_length (menu->entries);
Comment thread
tuffnatty marked this conversation as resolved.

if (menu->top > 0 && count - menu->top < lines)
// Screen size has grown, don't leave the new space empty
menu->top = count % lines;

const unsigned int stop = MIN (count, menu->top + lines);
Comment thread
tuffnatty marked this conversation as resolved.

for (unsigned int i = menu->top; i < stop; i++)
menubar_paint_idx (menubar, i, i == menu->current ? MENU_SELECTED_COLOR : MENU_ENTRY_COLOR);
}

Comment thread
tuffnatty marked this conversation as resolved.
/* --------------------------------------------------------------------------------------------- */

static void
menubar_draw_drop (const WMenuBar *menubar)
{
menu_t *menu;
int column;

menu = MENU (g_list_nth_data (menubar->menu, menubar->current));

const WRect *w = &CONST_WIDGET (menubar)->rect;
const menu_t *menu = MENU (g_list_nth_data (menubar->menu, menubar->current));
const unsigned int count = g_list_length (menu->entries);
int column = menu->start_x - 1;
unsigned int i;

column = menu->start_x - 1;

if (column + menu->max_entry_len + 4 > (gsize) w->cols)
column = w->cols - menu->max_entry_len - 4;
Expand All @@ -199,8 +233,7 @@ menubar_draw_drop (const WMenuBar *menubar)
tty_setcolor (MENU_FRAME_COLOR);
tty_draw_box (w->y + 1, w->x + column, count + 2, menu->max_entry_len + 4, FALSE);

for (i = 0; i < count; i++)
menubar_paint_idx (menubar, i, i == menu->current ? MENU_SELECTED_COLOR : MENU_ENTRY_COLOR);
menubar_draw_drop_entries (menubar, menu);
}

/* --------------------------------------------------------------------------------------------- */
Expand Down Expand Up @@ -369,6 +402,26 @@ menubar_execute (WMenuBar *menubar)

Comment thread
tuffnatty marked this conversation as resolved.
/* --------------------------------------------------------------------------------------------- */

static void
menubar_scroll_to_view (WMenuBar *menubar, menu_t *menu, unsigned int idx)
{
const Widget *w = WIDGET (menubar);
const int lines = w->rect.lines - 3;

g_return_if_fail (lines > 0);

if (idx < menu->top)
menu->top = idx;
else if (idx > menu->top + lines)
menu->top = idx - lines;
else
return;

menubar_draw_drop_entries (menubar, menu);
}

/* --------------------------------------------------------------------------------------------- */

static void
menubar_down (WMenuBar *menubar)
{
Expand All @@ -385,6 +438,7 @@ menubar_down (WMenuBar *menubar)
}
while ((entry == NULL) || (entry->command == CK_IgnoreKey));

menubar_scroll_to_view (menubar, menu, menu->current);
menubar_paint_idx (menubar, menu->current, MENU_SELECTED_COLOR);
}

Expand All @@ -409,6 +463,7 @@ menubar_up (WMenuBar *menubar)
}
while ((entry == NULL) || (entry->command == CK_IgnoreKey));

menubar_scroll_to_view (menubar, menu, menu->current);
menubar_paint_idx (menubar, menu->current, MENU_SELECTED_COLOR);
}

Expand Down Expand Up @@ -440,6 +495,7 @@ menubar_first (WMenuBar *menubar)
break;
}

menubar_scroll_to_view (menubar, menu, menu->current);
menubar_paint_idx (menubar, menu->current, MENU_SELECTED_COLOR);
}
else
Expand Down Expand Up @@ -474,6 +530,7 @@ menubar_last (WMenuBar *menubar)
}
while ((entry == NULL) || (entry->command == CK_IgnoreKey));

menubar_scroll_to_view (menubar, menu, menu->current);
menubar_paint_idx (menubar, menu->current, MENU_SELECTED_COLOR);
}
else
Expand Down Expand Up @@ -743,7 +800,7 @@ menubar_mouse_on_menu_entry (const WMenuBar *menubar, int y, int x)
return FALSE;

menu = MENU (g_list_nth_data (menubar->menu, menubar->current));
entry = MENUENTRY (g_list_nth_data (menu->entries, y - 2));
entry = MENUENTRY (g_list_nth_data (menu->entries, menu->top + y - 2));
if (entry == NULL)
return FALSE; // separator line

Expand All @@ -755,7 +812,7 @@ menubar_mouse_on_menu_entry (const WMenuBar *menubar, int y, int x)
right_x = w->cols - 1;
}

bottom_y = g_list_length (menu->entries) + 2; // skip bar and top frame
bottom_y = g_list_length (menu->entries) + 2 - menu->top; // skip bar and top frame

return (x >= left_x && x < right_x && y > 1 && y < bottom_y);
}
Expand All @@ -766,16 +823,16 @@ static void
menubar_change_selected_item (WMenuBar *menubar, int y)
{
menu_t *menu;
menu_entry_t *entry;

y -= 2; // skip bar and top frame
menu = MENU (g_list_nth_data (menubar->menu, menubar->current));
entry = MENUENTRY (g_list_nth_data (menu->entries, y));

const int idx = menu->top + y - 2; // skip bar and top frame
const menu_entry_t *entry = MENUENTRY (g_list_nth_data (menu->entries, idx));

if (entry != NULL && entry->command != CK_IgnoreKey)
{
menubar_paint_idx (menubar, menu->current, MENU_ENTRY_COLOR);
menu->current = y;
menu->current = idx;
menubar_paint_idx (menubar, menu->current, MENU_SELECTED_COLOR);
}
}
Expand Down Expand Up @@ -939,6 +996,7 @@ menu_new (const char *name, GList *entries, const char *help_node)
menu->max_entry_len = 1;
menu->max_hotkey_len = 0;
menu->current = 0;
menu->top = 0;
menu->help_node = g_strdup (help_node);

return menu;
Expand Down
Loading