comparison src/xdisp.c @ 69242:b3f04bf9fce0

Minimize the unpleasent visual impact of the requirement that non-toolkit tool-bars must occupy an integral number of screen lines, by distributing the rows evenly over the tool-bar screen area. (Vtool_bar_border): New variable. (syms_of_xdisp): DEFVAR_LISP it. (display_tool_bar_line): Add HEIGHT arg for desired row height. Make tool-bar row the desired height. Use default face for border below tool-bar. (tool_bar_lines_needed): Add N_ROWS arg. Use it to return number of actual tool-bar rows. (redisplay_tool_bar): Calculate f->n_tool_bar_rows initially. Adjust the height of the tool-bar rows to fill tool-bar screen area. (redisplay_tool_bar): Calculate f->n_tool_bar_rows when tool-bar area is resized.
author Kim F. Storm <storm@cua.dk>
date Thu, 02 Mar 2006 21:55:26 +0000
parents b85178809d5c
children 2c8c2aaf3daa a380ca43a190 5754737d1e04
comparison
equal deleted inserted replaced
69241:d34c25a166bd 69242:b3f04bf9fce0
267 267
268 /* Non-zero means to reposition window if cursor line is only partially visible. */ 268 /* Non-zero means to reposition window if cursor line is only partially visible. */
269 269
270 int make_cursor_line_fully_visible_p; 270 int make_cursor_line_fully_visible_p;
271 271
272 /* Margin below tool bar in pixels. 0 or nil means no margin.
273 If value is `internal-border-width' or `border-width',
274 the corresponding frame parameter is used. */
275
276 Lisp_Object Vtool_bar_border;
277
272 /* Margin around tool bar buttons in pixels. */ 278 /* Margin around tool bar buttons in pixels. */
273 279
274 Lisp_Object Vtool_bar_button_margin; 280 Lisp_Object Vtool_bar_button_margin;
275 281
276 /* Thickness of shadow to draw around tool bar buttons. */ 282 /* Thickness of shadow to draw around tool bar buttons. */
850 static int text_outside_line_unchanged_p P_ ((struct window *, int, int)); 856 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
851 static void store_mode_line_noprop_char P_ ((char)); 857 static void store_mode_line_noprop_char P_ ((char));
852 static int store_mode_line_noprop P_ ((const unsigned char *, int, int)); 858 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
853 static void x_consider_frame_title P_ ((Lisp_Object)); 859 static void x_consider_frame_title P_ ((Lisp_Object));
854 static void handle_stop P_ ((struct it *)); 860 static void handle_stop P_ ((struct it *));
855 static int tool_bar_lines_needed P_ ((struct frame *)); 861 static int tool_bar_lines_needed P_ ((struct frame *, int *));
856 static int single_display_spec_intangible_p P_ ((Lisp_Object)); 862 static int single_display_spec_intangible_p P_ ((Lisp_Object));
857 static void ensure_echo_area_buffers P_ ((void)); 863 static void ensure_echo_area_buffers P_ ((void));
858 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object)); 864 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
859 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *)); 865 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
860 static int with_echo_area_buffer P_ ((struct window *, int, 866 static int with_echo_area_buffer P_ ((struct window *, int,
961 #ifdef HAVE_WINDOW_SYSTEM 967 #ifdef HAVE_WINDOW_SYSTEM
962 968
963 static void update_tool_bar P_ ((struct frame *, int)); 969 static void update_tool_bar P_ ((struct frame *, int));
964 static void build_desired_tool_bar_string P_ ((struct frame *f)); 970 static void build_desired_tool_bar_string P_ ((struct frame *f));
965 static int redisplay_tool_bar P_ ((struct frame *)); 971 static int redisplay_tool_bar P_ ((struct frame *));
966 static void display_tool_bar_line P_ ((struct it *)); 972 static void display_tool_bar_line P_ ((struct it *, int));
967 static void notice_overwritten_cursor P_ ((struct window *, 973 static void notice_overwritten_cursor P_ ((struct window *,
968 enum glyph_row_area, 974 enum glyph_row_area,
969 int, int, int, int)); 975 int, int, int, int));
970 976
971 977
9422 9428
9423 UNGCPRO; 9429 UNGCPRO;
9424 } 9430 }
9425 9431
9426 9432
9427 /* Display one line of the tool-bar of frame IT->f. */ 9433 /* Display one line of the tool-bar of frame IT->f.
9434
9435 HEIGHT specifies the desired height of the tool-bar line.
9436 If the actual height of the glyph row is less than HEIGHT, the
9437 row's height is increased to HEIGHT, and the icons are centered
9438 vertically in the new height. */
9428 9439
9429 static void 9440 static void
9430 display_tool_bar_line (it) 9441 display_tool_bar_line (it, height)
9431 struct it *it; 9442 struct it *it;
9443 int height;
9432 { 9444 {
9433 struct glyph_row *row = it->glyph_row; 9445 struct glyph_row *row = it->glyph_row;
9434 int max_x = it->last_visible_x; 9446 int max_x = it->last_visible_x;
9435 struct glyph *last; 9447 struct glyph *last;
9436 9448
9482 } 9494 }
9483 9495
9484 out:; 9496 out:;
9485 9497
9486 row->displays_text_p = row->used[TEXT_AREA] != 0; 9498 row->displays_text_p = row->used[TEXT_AREA] != 0;
9499 /* Use default face for the border below the tool bar. */
9500 if (!row->displays_text_p)
9501 it->face_id = DEFAULT_FACE_ID;
9487 extend_face_to_end_of_line (it); 9502 extend_face_to_end_of_line (it);
9488 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1; 9503 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9489 last->right_box_line_p = 1; 9504 last->right_box_line_p = 1;
9490 if (last == row->glyphs[TEXT_AREA]) 9505 if (last == row->glyphs[TEXT_AREA])
9491 last->left_box_line_p = 1; 9506 last->left_box_line_p = 1;
9507
9508 /* Make line the desired height and center it vertically. */
9509 if ((height -= it->max_ascent + it->max_descent) > 0)
9510 {
9511 it->max_ascent += height / 2;
9512 it->max_descent += (height + 1) / 2;
9513 }
9514
9492 compute_line_metrics (it); 9515 compute_line_metrics (it);
9493 9516
9494 /* If line is empty, make it occupy the rest of the tool-bar. */ 9517 /* If line is empty, make it occupy the rest of the tool-bar. */
9495 if (!row->displays_text_p) 9518 if (!row->displays_text_p)
9496 { 9519 {
9510 ++it->glyph_row; 9533 ++it->glyph_row;
9511 } 9534 }
9512 9535
9513 9536
9514 /* Value is the number of screen lines needed to make all tool-bar 9537 /* Value is the number of screen lines needed to make all tool-bar
9515 items of frame F visible. */ 9538 items of frame F visible. The number of actual rows needed is
9539 returned in *N_ROWS if non-NULL. */
9516 9540
9517 static int 9541 static int
9518 tool_bar_lines_needed (f) 9542 tool_bar_lines_needed (f, n_rows)
9519 struct frame *f; 9543 struct frame *f;
9544 int *n_rows;
9520 { 9545 {
9521 struct window *w = XWINDOW (f->tool_bar_window); 9546 struct window *w = XWINDOW (f->tool_bar_window);
9522 struct it it; 9547 struct it it;
9523 9548
9524 /* Initialize an iterator for iteration over 9549 /* Initialize an iterator for iteration over
9530 9555
9531 while (!ITERATOR_AT_END_P (&it)) 9556 while (!ITERATOR_AT_END_P (&it))
9532 { 9557 {
9533 it.glyph_row = w->desired_matrix->rows; 9558 it.glyph_row = w->desired_matrix->rows;
9534 clear_glyph_row (it.glyph_row); 9559 clear_glyph_row (it.glyph_row);
9535 display_tool_bar_line (&it); 9560 display_tool_bar_line (&it, 0);
9536 } 9561 }
9562
9563 if (n_rows)
9564 *n_rows = it.vpos;
9537 9565
9538 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f); 9566 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9539 } 9567 }
9540 9568
9541 9569
9561 { 9589 {
9562 update_tool_bar (f, 1); 9590 update_tool_bar (f, 1);
9563 if (f->n_tool_bar_items) 9591 if (f->n_tool_bar_items)
9564 { 9592 {
9565 build_desired_tool_bar_string (f); 9593 build_desired_tool_bar_string (f);
9566 nlines = tool_bar_lines_needed (f); 9594 nlines = tool_bar_lines_needed (f, NULL);
9567 } 9595 }
9568 } 9596 }
9569 9597
9570 return make_number (nlines); 9598 return make_number (nlines);
9571 } 9599 }
9606 9634
9607 /* Build a string that represents the contents of the tool-bar. */ 9635 /* Build a string that represents the contents of the tool-bar. */
9608 build_desired_tool_bar_string (f); 9636 build_desired_tool_bar_string (f);
9609 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1); 9637 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9610 9638
9639 if (f->n_tool_bar_rows == 0)
9640 {
9641 (void)tool_bar_lines_needed (f, &f->n_tool_bar_rows);
9642 if (f->n_tool_bar_rows == 0)
9643 f->n_tool_bar_rows = -1;
9644 }
9645
9611 /* Display as many lines as needed to display all tool-bar items. */ 9646 /* Display as many lines as needed to display all tool-bar items. */
9612 while (it.current_y < it.last_visible_y) 9647
9613 display_tool_bar_line (&it); 9648 if (f->n_tool_bar_rows > 0)
9649 {
9650 int border, rows, height, extra;
9651
9652 if (INTEGERP (Vtool_bar_border))
9653 border = XINT (Vtool_bar_border);
9654 else if (EQ (Vtool_bar_border, Qinternal_border_width))
9655 border = FRAME_INTERNAL_BORDER_WIDTH (f);
9656 else if (EQ (Vtool_bar_border, Qborder_width))
9657 border = f->border_width;
9658 else
9659 border = 0;
9660 if (border < 0)
9661 border = 0;
9662
9663 rows = f->n_tool_bar_rows;
9664 height = (it.last_visible_y - border) / rows;
9665 extra = it.last_visible_y - border - height * rows;
9666
9667 while (it.current_y < it.last_visible_y)
9668 {
9669 int h = 0;
9670 if (extra > 0 && rows-- > 0)
9671 {
9672 h = (extra + rows - 1) / rows;
9673 extra -= h;
9674 }
9675 display_tool_bar_line (&it, height + h);
9676 }
9677 }
9678 else
9679 {
9680 while (it.current_y < it.last_visible_y)
9681 display_tool_bar_line (&it, 0);
9682 }
9614 9683
9615 /* It doesn't make much sense to try scrolling in the tool-bar 9684 /* It doesn't make much sense to try scrolling in the tool-bar
9616 window, so don't do it. */ 9685 window, so don't do it. */
9617 w->desired_matrix->no_scrolling_p = 1; 9686 w->desired_matrix->no_scrolling_p = 1;
9618 w->must_be_updated_p = 1; 9687 w->must_be_updated_p = 1;
9641 change_height_p = 1; 9710 change_height_p = 1;
9642 9711
9643 /* Resize windows as needed by changing the `tool-bar-lines' 9712 /* Resize windows as needed by changing the `tool-bar-lines'
9644 frame parameter. */ 9713 frame parameter. */
9645 if (change_height_p 9714 if (change_height_p
9646 && (nlines = tool_bar_lines_needed (f), 9715 && (nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
9647 nlines != WINDOW_TOTAL_LINES (w))) 9716 nlines != WINDOW_TOTAL_LINES (w)))
9648 { 9717 {
9649 extern Lisp_Object Qtool_bar_lines; 9718 extern Lisp_Object Qtool_bar_lines;
9650 Lisp_Object frame; 9719 Lisp_Object frame;
9651 int old_height = WINDOW_TOTAL_LINES (w); 9720 int old_height = WINDOW_TOTAL_LINES (w);
23640 23709
23641 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p, 23710 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
23642 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */); 23711 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
23643 make_cursor_line_fully_visible_p = 1; 23712 make_cursor_line_fully_visible_p = 1;
23644 23713
23714 DEFVAR_LISP ("tool-bar-border", &Vtool_bar_border,
23715 doc: /* *Border below tool-bar in pixels.
23716 If an integer, use it as the height of the border.
23717 If it is one of `internal-border-width' or `border-width', use the
23718 value of the corresponding frame parameter.
23719 Otherwise, no border is added below the tool-bar. */);
23720 Vtool_bar_border = Qinternal_border_width;
23721
23645 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin, 23722 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
23646 doc: /* *Margin around tool-bar buttons in pixels. 23723 doc: /* *Margin around tool-bar buttons in pixels.
23647 If an integer, use that for both horizontal and vertical margins. 23724 If an integer, use that for both horizontal and vertical margins.
23648 Otherwise, value should be a pair of integers `(HORZ . VERT)' with 23725 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
23649 HORZ specifying the horizontal margin, and VERT specifying the 23726 HORZ specifying the horizontal margin, and VERT specifying the