From 342cf49489d7f014db1bdbbdd922345c8db02cd6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 17 Sep 2013 18:31:37 +0300 Subject: [PATCH] Fixed display and padding of menu items; File menu displays OK. --- src/dispextern.h | 2 +- src/term.c | 6 ++-- src/xdisp.c | 71 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 17 deletions(-) diff --git a/src/dispextern.h b/src/dispextern.h index 0e6d934991a..f70b1f8092e 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3266,7 +3266,7 @@ extern int clear_mouse_face (Mouse_HLInfo *); extern int cursor_in_mouse_face_p (struct window *w); extern void tty_draw_row_with_mouse_face (struct window *, struct glyph_row *, int, int, enum draw_glyphs_face); -extern void display_tty_menu_item (const char *, int, int, int, int); +extern void display_tty_menu_item (const char *, int, int, int, int, int); /* Flags passed to try_window. */ #define TRY_WINDOW_CHECK_MARGINS (1 << 0) diff --git a/src/term.c b/src/term.c index f27bf8d900d..28338a3cc48 100644 --- a/src/term.c +++ b/src/term.c @@ -2942,9 +2942,11 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces, #endif for (i = 0; i < menu->count; i++) { - int max_width = width + 2; + int max_width = width + 2; /* +2 for padding blanks on each side */ cursor_to (sf, y + i, x); + if (menu->submenu[i]) + max_width += 2; /* for displaying " >" after the item */ enabled = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]); mousehere = (y + i == my && x <= mx && mx < x + max_width); @@ -2958,7 +2960,7 @@ tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces, menu_help_paneno = pn - 1; menu_help_itemno = i; } - display_tty_menu_item (menu->text[i], face, x, y + i, + display_tty_menu_item (menu->text[i], max_width, face, x, y + i, menu->submenu[i] != NULL); } update_frame_with_menu (sf); diff --git a/src/xdisp.c b/src/xdisp.c index 29d8118ff8e..b2e60549fcd 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -20576,6 +20576,40 @@ display_menu_bar (struct window *w) } #ifdef HAVE_MENUS +/* Deep copy of a glyph row, including the glyphs. */ +static void +deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from) +{ + int area, i, sum_used = 0; + struct glyph *pointers[1 + LAST_AREA]; + + /* Save glyph pointers of TO. */ + memcpy (pointers, to->glyphs, sizeof to->glyphs); + + /* Do a structure assignment. */ + *to = *from; + + /* Restore original pointers of TO. */ + memcpy (to->glyphs, pointers, sizeof to->glyphs); + + /* Count how many glyphs to copy and update glyph pointers. */ + for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area) + { + if (area > LEFT_MARGIN_AREA) + { + eassert (from->glyphs[area] - from->glyphs[area - 1] + == from->used[area - 1]); + to->glyphs[area] = to->glyphs[area - 1] + to->used[area - 1]; + } + sum_used += from->used[area]; + } + + /* Copy the glyphs. */ + eassert (sum_used <= to->glyphs[LAST_AREA] - to->glyphs[LEFT_MARGIN_AREA]); + for (i = 0; i < sum_used; i++) + to->glyphs[LEFT_MARGIN_AREA][i] = from->glyphs[LEFT_MARGIN_AREA][i]; +} + /* Display one menu item on a TTY, by overwriting the glyphs in the desired glyph matrix with glyphs produced from the menu item text. Called from term.c to display TTY drop-down menus one item at a @@ -20598,14 +20632,15 @@ display_menu_bar (struct window *w) item text. */ void -display_tty_menu_item (const char *item_text, int face_id, int x, int y, - int submenu) +display_tty_menu_item (const char *item_text, int width, int face_id, + int x, int y, int submenu) { struct it it; struct frame *f = SELECTED_FRAME (); struct window *w = XWINDOW (f->selected_window); int saved_used, saved_truncated, saved_width, saved_reversed; struct glyph_row *row; + size_t item_len = strlen (item_text); eassert (FRAME_TERMCAP_P (f)); @@ -20613,20 +20648,27 @@ display_tty_menu_item (const char *item_text, int face_id, int x, int y, it.first_visible_x = 0; it.last_visible_x = FRAME_COLS (f); row = it.glyph_row; - /* Copy the row contents from the current matrix. */ - *row = f->current_matrix->rows[y]; + /* Start with the row contents from the current matrix. */ + deep_copy_glyph_row (row, f->current_matrix->rows + y); saved_width = row->full_width_p; row->full_width_p = 1; saved_reversed = row->reversed_p; row->reversed_p = 0; + row->enabled_p = 1; - /* Arrange for the menu item glyphs to start at X and have the + /* We can only write over TEXT_AREA, as display_string cannot do + display margins. */ + x += row->used[LEFT_MARGIN_AREA]; + + /* Arrange for the menu item glyphs to start at (X,Y) and have the desired face. */ it.current_x = it.hpos = x; + it.current_y = it.vpos = y; saved_used = row->used[TEXT_AREA]; saved_truncated = row->truncated_on_right_p; row->used[TEXT_AREA] = x - row->used[LEFT_MARGIN_AREA]; it.face_id = face_id; + it.line_wrap = TRUNCATE; /* FIXME: This should be controlled by a user option. See the comments in redisplay_tool_bar and display_mode_line about this. @@ -20636,20 +20678,21 @@ display_tty_menu_item (const char *item_text, int face_id, int x, int y, it.paragraph_embedding = L2R; /* Pad with a space on the left. */ - display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, 0, -1); + display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1); + width--; + /* Display the menu item, pad with spaces to WIDTH. */ if (submenu) { - /* Indicate with ">" that there's a submenu. */ display_string (item_text, Qnil, Qnil, 0, 0, &it, - strlen (item_text), 0, FRAME_COLS (f) - 2, -1); - display_string (">", Qnil, Qnil, 0, 0, &it, 1, 0, 0, -1); + item_len, 0, FRAME_COLS (f) - 1, -1); + width -= item_len; + /* Indicate with " >" that there's a submenu. */ + display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0, + FRAME_COLS (f) - 1, -1); } else - { - /* Display the menu item, pad with one space. */ - display_string (item_text, Qnil, Qnil, 0, 0, &it, - strlen (item_text) + 1, 0, 0, -1); - } + display_string (item_text, Qnil, Qnil, 0, 0, &it, + width, 0, FRAME_COLS (f) - 1, -1); row->used[TEXT_AREA] = saved_used; row->truncated_on_right_p = saved_truncated; -- 2.39.2