#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))
/* 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. */
}
}
-/* 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);
}
xg_create_frame_widgets (FRAME_PTR f)
{
GtkWidget *wtop;
- GtkWidget *wvbox;
+ GtkWidget *wvbox, *whbox;
GtkWidget *wfixed;
GdkColor bg;
GtkRcStyle *style;
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;
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);
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);
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;
the container. */
x->menubar_widget = 0;
FRAME_MENUBAR_HEIGHT (f) = 0;
- xg_height_changed (f);
+ xg_height_or_width_changed (f);
UNBLOCK_INPUT;
}
}
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);
}
}
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);
}
}
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);
+ int into_hbox = EQ (pos, Qleft) || EQ (pos, Qright);
- 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);
-
- 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)
gtk_widget_set_name (x->toolbar_widget, "emacs-toolbar");
gtk_toolbar_set_style (GTK_TOOLBAR (x->toolbar_widget), GTK_TOOLBAR_ICONS);
- toolbar_set_orientation (x->toolbar_widget,
- GTK_ORIENTATION_HORIZONTAL);
+ toolbar_set_orientation (x->toolbar_widget, GTK_ORIENTATION_HORIZONTAL);
}
int i)
{
GtkToolItem *ti = gtk_tool_item_new ();
- GtkWidget *vb = EQ (Vtool_bar_style, Qboth_horiz)
+ Lisp_Object style = Ftool_bar_get_system_style ();
+ int both_horiz = EQ (style, Qboth_horiz);
+ int text_image = EQ (style, Qtext_image_horiz);
+
+ GtkWidget *vb = both_horiz || text_image
? gtk_hbox_new (FALSE, 0) : gtk_vbox_new (FALSE, 0);
GtkWidget *wb = gtk_button_new ();
GtkWidget *weventbox = gtk_event_box_new ();
- if (wimage)
+ if (wimage && ! text_image)
gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vb), gtk_label_new (label), TRUE, TRUE, 0);
+
+ if (wimage && text_image)
+ gtk_box_pack_start (GTK_BOX (vb), wimage, TRUE, TRUE, 0);
+
gtk_button_set_focus_on_click (GTK_BUTTON (wb), FALSE);
gtk_button_set_relief (GTK_BUTTON (wb), GTK_RELIEF_NONE);
gtk_container_add (GTK_CONTAINER (wb), vb);
xg_show_toolbar_item (GtkToolItem *ti)
{
Lisp_Object style = Ftool_bar_get_system_style ();
+ int both_horiz = EQ (style, Qboth_horiz);
+ int text_image = EQ (style, Qtext_image_horiz);
- int show_label = EQ (style, Qboth)
- || EQ (style, Qboth_horiz) || EQ (style, Qtext);
+ int horiz = both_horiz || text_image;
+ int show_label = ! EQ (style, Qimage);
int show_image = ! EQ (style, Qtext);
- int horiz = EQ (style, Qboth_horiz);
GtkWidget *weventbox = gtk_bin_get_child (GTK_BIN (ti));
GtkWidget *wbutton = gtk_bin_get_child (GTK_BIN (weventbox));
new_box = gtk_hbox_new (FALSE, 0);
else if (GTK_IS_HBOX (vb) && !horiz && show_label && show_image)
new_box = gtk_vbox_new (FALSE, 0);
- if (new_box)
+
+ if (!new_box && horiz)
+ gtk_box_reorder_child (GTK_BOX (vb), wlbl, text_image ? 0 : 1);
+ else if (new_box)
{
g_object_ref (G_OBJECT (wimage));
g_object_ref (G_OBJECT (wlbl));
gtk_container_remove (GTK_CONTAINER (vb), wimage);
gtk_container_remove (GTK_CONTAINER (vb), wlbl);
gtk_widget_destroy (GTK_WIDGET (vb));
- gtk_box_pack_start (GTK_BOX (new_box), wimage, TRUE, TRUE, 0);
+ if (! text_image)
+ gtk_box_pack_start (GTK_BOX (new_box), wimage, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (new_box), wlbl, TRUE, TRUE, 0);
+ if (text_image)
+ gtk_box_pack_start (GTK_BOX (new_box), wimage, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (wbutton), new_box);
g_object_unref (G_OBJECT (wimage));
g_object_unref (G_OBJECT (wlbl));
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. */
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;
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)
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;
}
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);
+
+ UNBLOCK_INPUT;
+ return 1;
+}
+
\f
/***********************************************************************