Mercurial > hg > xemacs-beta
diff src/toolbar-x.c @ 215:1f0dabaa0855 r20-4b6
Import from CVS: tag r20-4b6
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:07:35 +0200 |
parents | 3d6bfa290dbd |
children | 0e522484dd2a |
line wrap: on
line diff
--- a/src/toolbar-x.c Mon Aug 13 10:06:48 2007 +0200 +++ b/src/toolbar-x.c Mon Aug 13 10:07:35 2007 +0200 @@ -41,11 +41,13 @@ static void x_draw_blank_toolbar_button (struct frame *f, int x, int y, int width, - int height, int threed) + int height, int threed, int border_width, + int vertical) { struct device *d = XDEVICE (f->device); EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness; + int sx = x, sy = y, swidth = width, sheight = height; Display *dpy = DEVICE_X_DISPLAY (d); Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); @@ -64,14 +66,35 @@ bottom_shadow_gc = background_gc; } + if (vertical) + { + sx += border_width; + swidth -= 2 * border_width; + } + else + { + sy += border_width; + sheight -= 2 * border_width; + } + /* Draw the outline. */ - x_output_shadows (f, x, y, width, height, top_shadow_gc, + x_output_shadows (f, sx, sy, swidth, sheight, top_shadow_gc, bottom_shadow_gc, background_gc, shadow_thickness); /* Blank the middle. */ - XFillRectangle (dpy, x_win, background_gc, x + shadow_thickness, - y + shadow_thickness, width - shadow_thickness * 2, - height - shadow_thickness * 2); + XFillRectangle (dpy, x_win, background_gc, sx + shadow_thickness, + sy + shadow_thickness, swidth - shadow_thickness * 2, + sheight - shadow_thickness * 2); + + /* Do the border */ + XFillRectangle (dpy, x_win, background_gc, x, y, + (vertical ? border_width : width), + (vertical ? height : border_width)); + XFillRectangle (dpy, x_win, background_gc, + (vertical ? sx + swidth : x), + (vertical ? y : sy + sheight), + (vertical ? border_width : width), + (vertical ? height : border_width)); } static void @@ -80,6 +103,7 @@ struct device *d = XDEVICE (f->device); EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); int shadow_thickness = ef->emacs_frame.toolbar_shadow_thickness; + int x_adj, y_adj, width_adj, height_adj; Display *dpy = DEVICE_X_DISPLAY (d); Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); @@ -88,6 +112,23 @@ struct toolbar_button *tb = XTOOLBAR_BUTTON (button); struct Lisp_Image_Instance *p; struct window *w; + int vertical = tb->vertical; + int border_width = tb->border_width; + + if (vertical) + { + x_adj = border_width; + width_adj = - 2 * border_width; + y_adj = 0; + height_adj = 0; + } + else + { + x_adj = 0; + width_adj = 0; + y_adj = border_width; + height_adj = - 2 * border_width; + } XSETFRAME (frame, f); window = FRAME_LAST_NONMINIBUF_WINDOW (f); @@ -116,13 +157,27 @@ background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f); /* Draw the outline. */ - x_output_shadows (f, tb->x, tb->y, tb->width, tb->height, top_shadow_gc, + x_output_shadows (f, tb->x + x_adj, tb->y + y_adj, + tb->width + width_adj, tb->height + height_adj, + top_shadow_gc, bottom_shadow_gc, background_gc, shadow_thickness); /* Clear the pixmap area. */ - XFillRectangle (dpy, x_win, background_gc, tb->x + shadow_thickness, - tb->y + shadow_thickness, tb->width - shadow_thickness * 2, - tb->height - shadow_thickness * 2); + XFillRectangle (dpy, x_win, background_gc, tb->x + x_adj + shadow_thickness, + tb->y + y_adj + shadow_thickness, + tb->width + width_adj - shadow_thickness * 2, + tb->height + height_adj - shadow_thickness * 2); + + /* Do the border. */ + XFillRectangle (dpy, x_win, background_gc, tb->x, tb->y, + (vertical ? border_width : tb->width), + (vertical ? tb->height : border_width)); + + XFillRectangle (dpy, x_win, background_gc, + (vertical ? tb->x + tb->width - border_width : tb->x), + (vertical ? tb->y : tb->y + tb->height - border_width), + (vertical ? border_width : tb->width), + (vertical ? tb->height : border_width)); background_gc = FRAME_X_TOOLBAR_PIXMAP_BACKGROUND_GC (f); @@ -135,10 +190,10 @@ if (IMAGE_INSTANCEP (instance)) { - int width = tb->width - shadow_thickness * 2; - int height = tb->height - shadow_thickness * 2; - int x_offset = shadow_thickness; - int y_offset = shadow_thickness; + int width = tb->width + width_adj - shadow_thickness * 2; + int height = tb->height + height_adj - shadow_thickness * 2; + int x_offset = x_adj + shadow_thickness; + int y_offset = y_adj + shadow_thickness; p = XIMAGE_INSTANCE (instance); @@ -299,12 +354,15 @@ tb->y = y; \ tb->width = width; \ tb->height = height; \ + tb->border_width = border_width; \ + tb->vertical = vert; \ \ if (tb->blank || NILP (tb->up_glyph)) \ { \ int threed = (EQ (Qt, tb->up_glyph) ? 1 : 0); \ x_draw_blank_toolbar_button (f, x, y, width, \ - height, threed); \ + height, threed, \ + border_width, vert); \ } \ else \ x_output_toolbar_button (f, button); \ @@ -350,15 +408,35 @@ struct device *d = XDEVICE (f->device); int x, y, bar_width, bar_height, vert; int max_pixpos, right_size, right_start, blank_size; + int border_width = FRAME_REAL_TOOLBAR_BORDER_WIDTH (f, pos); Lisp_Object button, window; + Display *dpy = DEVICE_X_DISPLAY (d); + Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); + GC background_gc = FRAME_X_TOOLBAR_BLANK_BACKGROUND_GC (f); get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 1); window = FRAME_LAST_NONMINIBUF_WINDOW (f); + /* Do the border */ + XFillRectangle (dpy, x_win, background_gc, x, y, + (vert ? bar_width : border_width), + (vert ? border_width : bar_height)); + XFillRectangle (dpy, x_win, background_gc, + (vert ? x : x + bar_width - border_width), + (vert ? y + bar_height - border_width : y), + (vert ? bar_width : border_width), + (vert ? border_width : bar_height)); + if (vert) - max_pixpos = y + bar_height; + { + max_pixpos = y + bar_height - border_width; + y += border_width; + } else - max_pixpos = x + bar_width; + { + max_pixpos = x + bar_width - border_width; + x += border_width; + } button = FRAME_TOOLBAR_DATA (f, pos)->toolbar_buttons; right_size = 0; @@ -406,7 +484,13 @@ height = bar_height; } - x_draw_blank_toolbar_button (f, x, y, width, height, 1); + /* + * Use a 3D pushright separator only if there isn't a toolbar + * border. A flat separator meshes with the border and looks + * better. + */ + x_draw_blank_toolbar_button (f, x, y, width, height, !border_width, + border_width, vert); if (vert) y += height; @@ -634,7 +718,10 @@ f->toolbar_visible_p[pos] = new_visibility; if (change < 0) - x_clear_toolbar (f, pos, change); + { + x_clear_toolbar (f, pos, change); + mark_frame_toolbar_buttons_dirty (f, pos); + } if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR) repl.width += change; else @@ -664,12 +751,104 @@ } static void +x_toolbar_border_width_changed_in_frame (struct frame *f, enum toolbar_pos pos, + Lisp_Object lispoldval) +{ + XtWidgetGeometry req, repl; + int newval, oldval; + + if (NILP (f->toolbar_visible_p[pos]) || ZEROP (f->toolbar_size[pos])) + { + return; + } + else if (!f->init_finished && !INTP (f->toolbar_border_width[pos])) + /* the size might not be set at all if we're in the process of + creating the frame. Otherwise it better be, and we'll crash + out if not. */ + { + newval = 0; + } + else + { + Lisp_Object frame; + + XSETFRAME (frame, f); + newval = XINT (Fspecifier_instance (Vtoolbar_border_width[pos], + frame, Qzero, Qnil)); + } + + if (INTP (lispoldval)) + oldval = XINT (lispoldval); + else + oldval = 0; + + if (oldval == newval) + return; + + /* We want the text area to stay the same size. So, we query the + current size and then adjust it for the change in the toolbar + size. */ + + in_specifier_change_function++; + if (!in_resource_setting) + /* mirror the value in the frame resources, unless already done. */ + { + Arg al [1]; + XtSetArg (al [0], + pos == TOP_TOOLBAR ? XtNtopToolBarBorderWidth : + pos == BOTTOM_TOOLBAR ? XtNbottomToolBarBorderWidth : + pos == LEFT_TOOLBAR ? XtNleftToolBarBorderWidth : + XtNrightToolBarBorderWidth, + newval); + XtSetValues (FRAME_X_TEXT_WIDGET (f), al, 1); + } + if (XtIsRealized (FRAME_X_CONTAINER_WIDGET (f))) + { + int change = 2 * (newval - oldval); + + req.request_mode = 0; + + /* + * We want the current size, not the future size, so briefly + * reset the border width value so the query method returns + * the correct value. + */ + f->toolbar_border_width[pos] = make_int (oldval); + XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl); + f->toolbar_border_width[pos] = make_int (newval); + + if (change < 0) + { + x_clear_toolbar (f, pos, change); + mark_frame_toolbar_buttons_dirty (f, pos); + } + if (pos == LEFT_TOOLBAR || pos == RIGHT_TOOLBAR) + repl.width += change; + else + repl.height += change; + + MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (f); + EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width, + repl.height); + } + in_specifier_change_function--; +} + +static void x_initialize_frame_toolbar_gcs (struct frame *f) { EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); XGCValues gcv; unsigned long flags = (GCForeground | GCBackground | GCGraphicsExposures); + /* + * If the user specified the global background resource, use it. + * Otherwise use the backgroundToolBarColor resource. + */ + if (ef->emacs_frame.background_pixel != -1) + ef->emacs_frame.background_toolbar_pixel = + ef->emacs_frame.background_pixel; + gcv.foreground = ef->emacs_frame.background_toolbar_pixel; gcv.background = ef->core.background_pixel; gcv.graphics_exposures = False; @@ -791,5 +970,6 @@ CONSOLE_HAS_METHOD (x, redraw_exposed_toolbars); CONSOLE_HAS_METHOD (x, redraw_frame_toolbars); CONSOLE_HAS_METHOD (x, toolbar_size_changed_in_frame); + CONSOLE_HAS_METHOD (x, toolbar_border_width_changed_in_frame); CONSOLE_HAS_METHOD (x, toolbar_visible_p_changed_in_frame); }