Commit bfeabdc3 authored by Jan Djärv's avatar Jan Djärv

Add ability to put Gtk+ tool bar on the left/right/bottom or top. Default top.

* lisp/menu-bar.el (menu-bar-showhide-tool-bar-menu-customize-enable-left)
(menu-bar-showhide-tool-bar-menu-customize-disable)
(menu-bar-showhide-tool-bar-menu-customize-enable-right)
(menu-bar-showhide-tool-bar-menu-customize-enable-top)
(menu-bar-showhide-tool-bar-menu-customize-enable-bottom): New functions
(menu-bar-showhide-tool-bar-menu): If tool bar is moveable,
make a menu for Options => toolbar that can move it.

* src/frame.c (Qtool_bar_position): New variable.
(make_frame): Set tool_bar_position to Qtop.
(frame_parms): Add tool-bar-position.
(x_report_frame_params): Store tool_bar_position.
(x_set_fringe_width): Reset wm size hint after fringe changes.

* src/frame.h (struct frame): Add tool_bar_position.
(Qbottom): Declare.

* src/gtkutil.c (FRAME_TOTAL_PIXEL_WIDTH): New macro.
(xg_frame_set_char_size): Add FRAME_TOOLBAR_WIDTH to pixelwidth.
(xg_height_or_width_changed): Use FRAME_TOTAL_PIXEL_WIDTH.
(xg_create_frame_widgets): Create a hobox for placing widgets
vertically.  Use gtk_box_pack_start.
(xg_height_or_width_changed): Renamed from xg_height_changed.
(x_wm_set_size_hint): Add FRAME_TOOLBAR_WIDTH to base_width.
(xg_update_frame_menubar, free_frame_menubar): Change to
xg_height_or_width_changed.
(xg_tool_bar_detach_callback): Update left/right/top/bottom tool bar
size correctly.  Remove hardcoded 4, instead use handlebox size -
toolbar size.
(xg_tool_bar_attach_callback): Update left/right/top/bottom tool bar
size correctly.  Use handlebox size + toolbar size as additional
size.
(xg_pack_tool_bar): POS is a new parameter.
Set orientation of tool bar based on pos.
Only make handlebox_widget if NULL.
Check if tool bar goes to vbox or hbox depending on pos.
(xg_update_tool_bar_sizes): New function.
(update_frame_tool_bar): Remove old_req, new_req. Do not get tool bar
height, call xg_update_tool_bar_sizes instead.
(free_frame_tool_bar): Remove from hbox or vbox depending on
toolbar_in_hbox,  Set all FRAME_TOOLBAR_*_(WIDTH|HEIGHT) to zero.
(xg_change_toolbar_position): New function.

* src/gtkutil.h (xg_change_toolbar_position): Declare.

* src/window.c (calc_absolute_offset): Check for FRAME_TOOLBAR_TOP_HEIGHT
and FRAME_TOOLBAR_LEFT_WIDTH.

* src/xfns.c (x_set_tool_bar_position): New function.
(xic_set_statusarea): Use FRAME_TOOLBAR_TOP_HEIGHT.
(x_frame_parm_handlers): Add x_set_tool_bar_position.
(syms_of_xfns): if USE_GTK, provide move-toolbar.

* src/xterm.c (x_set_window_size_1): Add FRAME_TOOLBAR_WIDTH to pixelwidth.

* src/xterm.h (struct x_output): Add toolbar_top_height,
toolbar_bottom_height, toolbar_left_width, toolbar_right_width.  Remove
toolbar_height.
if USE_GTK: Add hbox_widget and toolbar_in_hbox.
(FRAME_TOOLBAR_TOP_HEIGHT, FRAME_TOOLBAR_BOTTOM_HEIGHT)
(FRAME_TOOLBAR_LEFT_WIDTH, FRAME_TOOLBAR_RIGHT_WIDTH): New macros.
(FRAME_TOOLBAR_HEIGHT): Is now TOP_HEIGHT + BOTTOM_HEIGHT.
parent 063e5294
2010-07-29 Jan Djärv <jan.h.d@swipnet.se>
* menu-bar.el (menu-bar-showhide-tool-bar-menu-customize-enable-left)
(menu-bar-showhide-tool-bar-menu-customize-disable)
(menu-bar-showhide-tool-bar-menu-customize-enable-right)
(menu-bar-showhide-tool-bar-menu-customize-enable-top)
(menu-bar-showhide-tool-bar-menu-customize-enable-bottom): New functions
(menu-bar-showhide-tool-bar-menu): If tool bar is moveable,
make a menu for Options => toolbar that can move it.
2010-07-29 Chong Yidong <cyd@stupidchicken.com>
* emacs-lisp/package-x.el (package--make-rss-entry):
......
......@@ -968,11 +968,95 @@ mail status in mode line"))
:help ,(purecopy "Turn menu-bar on/off")
:button (:toggle . (> (frame-parameter nil 'menu-bar-lines) 0))))
(define-key menu-bar-showhide-menu [showhide-tool-bar]
`(menu-item ,(purecopy "Tool-bar") toggle-tool-bar-mode-from-frame
:help ,(purecopy "Turn tool-bar on/off")
:visible (display-graphic-p)
:button (:toggle . (> (frame-parameter nil 'tool-bar-lines) 0))))
(defun menu-bar-showhide-tool-bar-menu-customize-disable ()
"Do not display tool bars."
(interactive)
(customize-set-variable 'tool-bar-mode nil))
(defun menu-bar-showhide-tool-bar-menu-customize-enable-left ()
"Display tool bars on the left side."
(interactive)
(customize-set-variable 'tool-bar-mode t)
(set-frame-parameter nil 'tool-bar-position 'left))
(defun menu-bar-showhide-tool-bar-menu-customize-enable-right ()
"Display tool bars on the right side."
(interactive)
(customize-set-variable 'tool-bar-mode t)
(set-frame-parameter nil 'tool-bar-position 'right))
(defun menu-bar-showhide-tool-bar-menu-customize-enable-top ()
"Display tool bars on the top side."
(interactive)
(customize-set-variable 'tool-bar-mode t)
(set-frame-parameter nil 'tool-bar-position 'top))
(defun menu-bar-showhide-tool-bar-menu-customize-enable-bottom ()
"Display tool bars on the bottom side."
(interactive)
(customize-set-variable 'tool-bar-mode t)
(set-frame-parameter nil 'tool-bar-position 'bottom))
(if (featurep 'move-toolbar)
(progn
(defvar menu-bar-showhide-tool-bar-menu (make-sparse-keymap "Tool-bar"))
(define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-left]
`(menu-item ,(purecopy "On the left")
menu-bar-showhide-tool-bar-menu-customize-enable-left
:help ,(purecopy "Tool-bar at the left side")
:visible (display-graphic-p)
:button
(:radio . (and tool-bar-mode
(eq (frame-parameter nil 'tool-bar-position)
'left)))))
(define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-right]
`(menu-item ,(purecopy "On the right")
menu-bar-showhide-tool-bar-menu-customize-enable-right
:help ,(purecopy "Tool-bar at the right side")
:visible (display-graphic-p)
:button
(:radio . (and tool-bar-mode
(eq (frame-parameter nil 'tool-bar-position)
'right)))))
(define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-bottom]
`(menu-item ,(purecopy "On the bottom")
menu-bar-showhide-tool-bar-menu-customize-enable-bottom
:help ,(purecopy "Tool-bar at the bottom")
:visible (display-graphic-p)
:button
(:radio . (and tool-bar-mode
(eq (frame-parameter nil 'tool-bar-position)
'bottom)))))
(define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-top]
`(menu-item ,(purecopy "On the top")
menu-bar-showhide-tool-bar-menu-customize-enable-top
:help ,(purecopy "Tool-bar at the top")
:visible (display-graphic-p)
:button
(:radio . (and tool-bar-mode
(eq (frame-parameter nil 'tool-bar-position)
'top)))))
(define-key menu-bar-showhide-tool-bar-menu [showhide-tool-bar-none]
`(menu-item ,(purecopy "None")
menu-bar-showhide-tool-bar-menu-customize-disable
:help ,(purecopy "Turn tool-bar off")
:visible (display-graphic-p)
:button (:radio . (eq tool-bar-mode nil))))
(define-key menu-bar-showhide-menu [showhide-tool-bar]
`(menu-item ,(purecopy "Tool-bar") ,menu-bar-showhide-tool-bar-menu
:visible (display-graphic-p)))
)
;; else not tool bar that can move.
(define-key menu-bar-showhide-menu [showhide-tool-bar]
`(menu-item ,(purecopy "Tool-bar") toggle-tool-bar-mode-from-frame
:help ,(purecopy "Turn tool-bar on/off")
:visible (display-graphic-p)
:button (:toggle . (> (frame-parameter nil 'tool-bar-lines) 0))))
)
(define-key menu-bar-options-menu [showhide]
`(menu-item ,(purecopy "Show/Hide") ,menu-bar-showhide-menu))
......
2010-07-29 Jan Djärv <jan.h.d@swipnet.se>
* xterm.h (struct x_output): Add toolbar_top_height,
toolbar_bottom_height, toolbar_left_width, toolbar_right_width. Remove
toolbar_height.
if USE_GTK: Add hbox_widget and toolbar_in_hbox.
(FRAME_TOOLBAR_TOP_HEIGHT, FRAME_TOOLBAR_BOTTOM_HEIGHT)
(FRAME_TOOLBAR_LEFT_WIDTH, FRAME_TOOLBAR_RIGHT_WIDTH): New macros.
(FRAME_TOOLBAR_HEIGHT): Is now TOP_HEIGHT + BOTTOM_HEIGHT.
* xterm.c (x_set_window_size_1): Add FRAME_TOOLBAR_WIDTH to pixelwidth.
* xfns.c (x_set_tool_bar_position): New function.
(xic_set_statusarea): Use FRAME_TOOLBAR_TOP_HEIGHT.
(x_frame_parm_handlers): Add x_set_tool_bar_position.
(syms_of_xfns): if USE_GTK, provide move-toolbar.
* window.c (calc_absolute_offset): Check for FRAME_TOOLBAR_TOP_HEIGHT
and FRAME_TOOLBAR_LEFT_WIDTH.
* gtkutil.h (xg_change_toolbar_position): Declare.
* gtkutil.c (FRAME_TOTAL_PIXEL_WIDTH): New macro.
(xg_frame_set_char_size): Add FRAME_TOOLBAR_WIDTH to pixelwidth.
(xg_height_or_width_changed): Use FRAME_TOTAL_PIXEL_WIDTH.
(xg_create_frame_widgets): Create a hobox for placing widgets
vertically. Use gtk_box_pack_start.
(xg_height_or_width_changed): Renamed from xg_height_changed.
(x_wm_set_size_hint): Add FRAME_TOOLBAR_WIDTH to base_width.
(xg_update_frame_menubar, free_frame_menubar): Change to
xg_height_or_width_changed.
(xg_tool_bar_detach_callback): Update left/right/top/bottom tool bar
size correctly. Remove hardcoded 4, instead use handlebox size -
toolbar size.
(xg_tool_bar_attach_callback): Update left/right/top/bottom tool bar
size correctly. Use handlebox size + toolbar size as additional
size.
(xg_pack_tool_bar): POS is a new parameter.
Set orientation of tool bar based on pos.
Only make handlebox_widget if NULL.
Check if tool bar goes to vbox or hbox depending on pos.
(xg_update_tool_bar_sizes): New function.
(update_frame_tool_bar): Remove old_req, new_req. Do not get tool bar
height, call xg_update_tool_bar_sizes instead.
(free_frame_tool_bar): Remove from hbox or vbox depending on
toolbar_in_hbox, Set all FRAME_TOOLBAR_*_(WIDTH|HEIGHT) to zero.
(xg_change_toolbar_position): New function.
* frame.h (struct frame): Add tool_bar_position.
(Qbottom): Declare.
* frame.c (Qtool_bar_position): New variable.
(make_frame): Set tool_bar_position to Qtop.
(frame_parms): Add tool-bar-position.
(x_report_frame_params): Store tool_bar_position.
(x_set_fringe_width): Reset wm size hint after fringe changes.
2010-07-29 Dan Nicolaescu <dann@ics.uci.edu>
Make lisp_time_argument declaration work on all systems.
......
......@@ -119,7 +119,7 @@ Lisp_Object Qparent_id;
Lisp_Object Qtitle, Qname;
Lisp_Object Qexplicit_name;
Lisp_Object Qunsplittable;
Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
Lisp_Object Qmenu_bar_lines, Qtool_bar_lines, Qtool_bar_position;
Lisp_Object Vmenu_bar_mode, Vtool_bar_mode;
Lisp_Object Qleft_fringe, Qright_fringe;
Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
......@@ -323,6 +323,7 @@ make_frame (int mini_p)
f->menu_bar_window = Qnil;
f->tool_bar_window = Qnil;
f->tool_bar_items = Qnil;
f->tool_bar_position = Qtop;
f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
f->n_tool_bar_items = 0;
f->left_fringe_width = f->right_fringe_width = 0;
......@@ -2816,6 +2817,7 @@ static struct frame_parm_table frame_parms[] =
{"font-backend", &Qfont_backend},
{"alpha", &Qalpha},
{"sticky", &Qsticky},
{"tool-bar-position", &Qtool_bar_position},
};
#ifdef HAVE_WINDOW_SYSTEM
......@@ -3209,6 +3211,7 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
store_in_alist (alistptr, Qparent_id, tem);
store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position);
}
......@@ -3441,6 +3444,11 @@ void
x_set_fringe_width (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
{
compute_fringe_widths (f, 1);
#ifdef HAVE_X_WINDOWS
/* Must adjust this so window managers report correct number of columns. */
if (FRAME_X_WINDOW (f) != 0)
x_wm_set_size_hint (f, 0, 0);
#endif
}
void
......
......@@ -191,6 +191,10 @@ struct frame
/* Desired and current tool-bar items. */
Lisp_Object tool_bar_items;
/* Where tool bar is, can be left, right, top or bottom. The native
tool bar only supports top. */
Lisp_Object tool_bar_position;
/* Desired and current contents displayed in tool_bar_window. */
Lisp_Object desired_tool_bar_string, current_tool_bar_string;
......@@ -1071,7 +1075,7 @@ extern Lisp_Object Qbackground_mode;
extern Lisp_Object Qx_resource_name;
extern Lisp_Object Qleft, Qright, Qtop, Qbox;
extern Lisp_Object Qleft, Qright, Qtop, Qbox, Qbottom;
extern Lisp_Object Qdisplay;
#ifdef HAVE_WINDOW_SYSTEM
......
......@@ -44,6 +44,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#define FRAME_TOTAL_PIXEL_HEIGHT(f) \
(FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))
#define FRAME_TOTAL_PIXEL_WIDTH(f) \
(FRAME_PIXEL_WIDTH (f) + FRAME_TOOLBAR_WIDTH (f))
/* Avoid "differ in sign" warnings */
#define SSDATA(x) ((char *) SDATA (x))
......@@ -640,7 +643,8 @@ xg_frame_set_char_size (FRAME_PTR f, int cols, int rows)
/* FRAME_TEXT_COLS_TO_PIXEL_WIDTH uses scroll_bar_actual_width, so call it
after calculating that value. */
pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols)
+ FRAME_TOOLBAR_WIDTH (f);
/* Do this before resize, as we don't know yet if we will be resized. */
......@@ -677,14 +681,15 @@ xg_frame_set_char_size (FRAME_PTR f, int cols, int rows)
}
}
/* Handle height changes (i.e. add/remove menu/toolbar).
/* Handle height/width changes (i.e. add/remove/move menu/toolbar).
The policy is to keep the number of editable lines. */
static void
xg_height_changed (FRAME_PTR f)
xg_height_or_width_changed (FRAME_PTR f)
{
gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
FRAME_PIXEL_WIDTH (f), FRAME_TOTAL_PIXEL_HEIGHT (f));
FRAME_TOTAL_PIXEL_WIDTH (f),
FRAME_TOTAL_PIXEL_HEIGHT (f));
f->output_data.x->hint_flags = 0;
x_wm_set_size_hint (f, 0, 0);
}
......@@ -733,7 +738,7 @@ int
xg_create_frame_widgets (FRAME_PTR f)
{
GtkWidget *wtop;
GtkWidget *wvbox;
GtkWidget *wvbox, *whbox;
GtkWidget *wfixed;
GdkColor bg;
GtkRcStyle *style;
......@@ -749,12 +754,14 @@ xg_create_frame_widgets (FRAME_PTR f)
xg_set_screen (wtop, f);
wvbox = gtk_vbox_new (FALSE, 0);
whbox = gtk_hbox_new (FALSE, 0);
wfixed = gtk_fixed_new (); /* Must have this to place scroll bars */
if (! wtop || ! wvbox || ! wfixed)
if (! wtop || ! wvbox || ! whbox || ! wfixed)
{
if (wtop) gtk_widget_destroy (wtop);
if (wvbox) gtk_widget_destroy (wvbox);
if (whbox) gtk_widget_destroy (whbox);
if (wfixed) gtk_widget_destroy (wfixed);
UNBLOCK_INPUT;
......@@ -775,11 +782,13 @@ xg_create_frame_widgets (FRAME_PTR f)
FRAME_GTK_OUTER_WIDGET (f) = wtop;
FRAME_GTK_WIDGET (f) = wfixed;
f->output_data.x->vbox_widget = wvbox;
f->output_data.x->hbox_widget = whbox;
gtk_widget_set_has_window (wfixed, TRUE);
gtk_container_add (GTK_CONTAINER (wtop), wvbox);
gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (wvbox), whbox, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (whbox), wfixed, TRUE, TRUE, 0);
if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
......@@ -889,7 +898,7 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, int user_position)
size_hints.height_inc = FRAME_LINE_HEIGHT (f);
hint_flags |= GDK_HINT_BASE_SIZE;
base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
base_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0) + FRAME_TOOLBAR_WIDTH (f);
base_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0)
+ FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f);
......@@ -2828,7 +2837,7 @@ xg_update_frame_menubar (FRAME_PTR f)
gtk_widget_show_all (x->menubar_widget);
gtk_widget_size_request (x->menubar_widget, &req);
FRAME_MENUBAR_HEIGHT (f) = req.height;
xg_height_changed (f);
xg_height_or_width_changed (f);
UNBLOCK_INPUT;
return 1;
......@@ -2851,7 +2860,7 @@ free_frame_menubar (FRAME_PTR f)
the container. */
x->menubar_widget = 0;
FRAME_MENUBAR_HEIGHT (f) = 0;
xg_height_changed (f);
xg_height_or_width_changed (f);
UNBLOCK_INPUT;
}
}
......@@ -3548,13 +3557,21 @@ xg_tool_bar_detach_callback (GtkHandleBox *wbox,
if (f)
{
GtkRequisition req, req2;
FRAME_X_OUTPUT (f)->toolbar_detached = 1;
/* When detaching a tool bar, not everything dissapear. There are
a few pixels left that are used to drop the tool bar back into
place. */
FRAME_TOOLBAR_HEIGHT (f) = 4;
xg_height_changed (f);
gtk_widget_size_request (GTK_WIDGET (wbox), &req);
gtk_widget_size_request (w, &req2);
req.width -= req2.width;
req.height -= req2.height;
if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0)
FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height;
else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0)
FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height;
else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0)
FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width;
else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0)
FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width;
xg_height_or_width_changed (f);
}
}
......@@ -3575,13 +3592,21 @@ xg_tool_bar_attach_callback (GtkHandleBox *wbox,
if (f)
{
GtkRequisition req;
GtkRequisition req, req2;
FRAME_X_OUTPUT (f)->toolbar_detached = 0;
gtk_widget_size_request (w, &req);
FRAME_TOOLBAR_HEIGHT (f) = req.height;
xg_height_changed (f);
gtk_widget_size_request (GTK_WIDGET (wbox), &req);
gtk_widget_size_request (w, &req2);
req.width += req2.width;
req.height += req2.height;
if (FRAME_TOOLBAR_TOP_HEIGHT (f) != 0)
FRAME_TOOLBAR_TOP_HEIGHT (f) = req.height;
else if (FRAME_TOOLBAR_BOTTOM_HEIGHT (f) != 0)
FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = req.height;
else if (FRAME_TOOLBAR_RIGHT_WIDTH (f) != 0)
FRAME_TOOLBAR_RIGHT_WIDTH (f) = req.width;
else if (FRAME_TOOLBAR_LEFT_WIDTH (f) != 0)
FRAME_TOOLBAR_LEFT_WIDTH (f) = req.width;
xg_height_or_width_changed (f);
}
}
......@@ -3656,41 +3681,63 @@ xg_tool_bar_item_expose_callback (GtkWidget *w,
return FALSE;
}
#ifdef HAVE_GTK_ORIENTABLE_SET_ORIENTATION
#define toolbar_set_orientation(w, o) \
gtk_orientable_set_orientation (GTK_ORIENTABLE (w), o)
#else
#define toolbar_set_orientation(w, o) \
gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o)
#endif
/* Attach a tool bar to frame F. */
static void
xg_pack_tool_bar (FRAME_PTR f)
xg_pack_tool_bar (FRAME_PTR f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
int vbox_pos = x->menubar_widget ? 1 : 0;
x->handlebox_widget = gtk_handle_box_new ();
g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached",
G_CALLBACK (xg_tool_bar_detach_callback), f);
g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached",
G_CALLBACK (xg_tool_bar_attach_callback), f);
gtk_container_add (GTK_CONTAINER (x->handlebox_widget),
x->toolbar_widget);
gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget,
FALSE, FALSE, 0);
int into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
gtk_box_reorder_child (GTK_BOX (x->vbox_widget), x->handlebox_widget,
vbox_pos);
toolbar_set_orientation (x->toolbar_widget,
into_hbox
? GTK_ORIENTATION_VERTICAL
: GTK_ORIENTATION_HORIZONTAL);
if (!x->handlebox_widget)
{
x->handlebox_widget = gtk_handle_box_new ();
g_signal_connect (G_OBJECT (x->handlebox_widget), "child-detached",
G_CALLBACK (xg_tool_bar_detach_callback), f);
g_signal_connect (G_OBJECT (x->handlebox_widget), "child-attached",
G_CALLBACK (xg_tool_bar_attach_callback), f);
gtk_container_add (GTK_CONTAINER (x->handlebox_widget),
x->toolbar_widget);
}
gtk_widget_show (x->toolbar_widget);
gtk_widget_show (x->handlebox_widget);
if (into_hbox)
{
gtk_box_pack_start (GTK_BOX (x->hbox_widget), x->handlebox_widget,
FALSE, FALSE, 0);
if (EQ (pos, Qleft))
gtk_box_reorder_child (GTK_BOX (x->hbox_widget),
x->handlebox_widget,
0);
x->toolbar_in_hbox = 1;
}
else
{
int vbox_pos = x->menubar_widget ? 1 : 0;
gtk_box_pack_start (GTK_BOX (x->vbox_widget), x->handlebox_widget,
FALSE, FALSE, 0);
if (EQ (pos, Qtop))
gtk_box_reorder_child (GTK_BOX (x->vbox_widget),
x->handlebox_widget,
vbox_pos);
x->toolbar_in_hbox = 0;
}
}
/* Create a tool bar for frame F. */
#ifdef HAVE_GTK_ORIENTABLE_SET_ORIENTATION
#define toolbar_set_orientation(w, o) \
gtk_orientable_set_orientation (GTK_ORIENTABLE (w), o)
#else
#define toolbar_set_orientation(w, o) \
gtk_toolbar_set_orientation (GTK_TOOLBAR (w), o)
#endif
static void
xg_create_tool_bar (FRAME_PTR f)
......@@ -3875,6 +3922,50 @@ xg_show_toolbar_item (GtkToolItem *ti)
gtk_widget_show (GTK_WIDGET (ti));
}
static int
xg_update_tool_bar_sizes (FRAME_PTR f)
{
struct x_output *x = f->output_data.x;
GtkRequisition req;
int nl = 0, nr = 0, nt = 0, nb = 0;
gtk_widget_size_request (GTK_WIDGET (x->handlebox_widget), &req);
if (x->toolbar_in_hbox)
{
int pos;
gtk_container_child_get (GTK_CONTAINER (x->hbox_widget),
x->handlebox_widget,
"position", &pos, NULL);
if (pos == 0) nl = req.width;
else nr = req.width;
}
else
{
int pos;
gtk_container_child_get (GTK_CONTAINER (x->vbox_widget),
x->handlebox_widget,
"position", &pos, NULL);
if (pos == 0 || (pos == 1 && x->menubar_widget)) nt = req.height;
else nb = req.height;
}
if (nl != FRAME_TOOLBAR_LEFT_WIDTH (f)
|| nr != FRAME_TOOLBAR_RIGHT_WIDTH (f)
|| nt != FRAME_TOOLBAR_TOP_HEIGHT (f)
|| nb != FRAME_TOOLBAR_BOTTOM_HEIGHT (f))
{
FRAME_TOOLBAR_RIGHT_WIDTH (f) = FRAME_TOOLBAR_LEFT_WIDTH (f)
= FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0;
FRAME_TOOLBAR_LEFT_WIDTH (f) = nl;
FRAME_TOOLBAR_RIGHT_WIDTH (f) = nr;
FRAME_TOOLBAR_TOP_HEIGHT (f) = nt;
FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = nb;
return 1;
}
return 0;
}
/* Update the tool bar for frame F. Add new buttons and remove old. */
......@@ -3884,7 +3975,6 @@ void
update_frame_tool_bar (FRAME_PTR f)
{
int i;
GtkRequisition old_req, new_req;
struct x_output *x = f->output_data.x;
int hmargin = 0, vmargin = 0;
GtkToolbar *wtoolbar;
......@@ -3925,7 +4015,6 @@ update_frame_tool_bar (FRAME_PTR f)
xg_create_tool_bar (f);
wtoolbar = GTK_TOOLBAR (x->toolbar_widget);
gtk_widget_size_request (GTK_WIDGET (wtoolbar), &old_req);
dir = gtk_widget_get_direction (GTK_WIDGET (wtoolbar));
for (i = 0; i < f->n_tool_bar_items; ++i)
......@@ -4143,18 +4232,16 @@ update_frame_tool_bar (FRAME_PTR f)
if (ti) gtk_widget_hide_all (GTK_WIDGET (ti));
} while (ti != NULL);
new_req.height = 0;
if (pack_tool_bar && f->n_tool_bar_items != 0)
xg_pack_tool_bar (f);
gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req);
if (old_req.height != new_req.height
&& ! FRAME_X_OUTPUT (f)->toolbar_detached)
if (f->n_tool_bar_items != 0)
{
FRAME_TOOLBAR_HEIGHT (f) = new_req.height;
xg_height_changed (f);
if (pack_tool_bar)
xg_pack_tool_bar (f, f->tool_bar_position);
gtk_widget_show (x->toolbar_widget);
gtk_widget_show (x->handlebox_widget);
if (xg_update_tool_bar_sizes (f))
xg_height_or_width_changed (f);
}
UNBLOCK_INPUT;
}
......@@ -4172,21 +4259,54 @@ free_frame_tool_bar (FRAME_PTR f)
BLOCK_INPUT;
/* We may have created the toolbar_widget in xg_create_tool_bar, but
not the x->handlebox_widget which is created in xg_pack_tool_bar. */
if (is_packed)
gtk_container_remove (GTK_CONTAINER (x->vbox_widget),
x->handlebox_widget);
if (is_packed)
{
if (x->toolbar_in_hbox)
gtk_container_remove (GTK_CONTAINER (x->hbox_widget),
x->handlebox_widget);
else
gtk_container_remove (GTK_CONTAINER (x->vbox_widget),
x->handlebox_widget);
}
else
gtk_widget_destroy (x->toolbar_widget);
x->toolbar_widget = 0;
x->handlebox_widget = 0;
FRAME_TOOLBAR_HEIGHT (f) = 0;
xg_height_changed (f);
FRAME_TOOLBAR_TOP_HEIGHT (f) = FRAME_TOOLBAR_BOTTOM_HEIGHT (f) = 0;
FRAME_TOOLBAR_LEFT_WIDTH (f) = FRAME_TOOLBAR_RIGHT_WIDTH (f) = 0;
xg_height_or_width_changed (f);
UNBLOCK_INPUT;
}
}
int
xg_change_toolbar_position (FRAME_PTR f, Lisp_Object pos)
{
struct x_output *x = f->output_data.x;
if (! x->toolbar_widget || ! x->handlebox_widget)
return 1;
BLOCK_INPUT;
g_object_ref (x->handlebox_widget);
if (x->toolbar_in_hbox)
gtk_container_remove (GTK_CONTAINER (x->hbox_widget),
x->handlebox_widget);
else
gtk_container_remove (GTK_CONTAINER (x->vbox_widget),
x->handlebox_widget);
xg_pack_tool_bar (f, pos);
g_object_unref (x->handlebox_widget);
if (xg_update_tool_bar_sizes (f))
xg_height_or_width_changed (f);