#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);
-
- 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)
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
/***********************************************************************