#include "gtkmarshalers.h"
#include "gtkbindings.h"
#include "gtkprivate.h"
-#include "gtkalias.h"
#include "gtkdnd.h"
+#include "gtkalias.h"
#define SCROLL_DELAY_FACTOR 5
#define SCROLL_THRESHOLD 12
#define DND_THRESHOLD_MULTIPLIER 4
+#define FRAMES_PER_SECOND 45
+#define MSECS_BETWEEN_UPDATES (1000 / FRAMES_PER_SECOND)
enum {
SWITCH_PAGE,
guint dnd_timer;
guint switch_tab_timer;
+ gint drag_begin_x;
+ gint drag_begin_y;
+
+ gint drag_offset_x;
+ gint drag_offset_y;
+
+ GtkWidget *dnd_window;
GtkTargetList *source_targets;
GtkNotebookDragOperation operation;
GdkWindow *drag_window;
gint drag_window_y;
GtkNotebookPage *detached_tab;
- gboolean during_detach : 1;
- gboolean has_scrolled : 1;
+ guint32 timestamp;
+
+ guint during_reorder : 1;
+ guint during_detach : 1;
+ guint has_scrolled : 1;
};
static const GtkTargetEntry notebook_source_targets [] = {
static gint gtk_notebook_button_release (GtkWidget *widget,
GdkEventButton *event);
static gboolean gtk_notebook_popup_menu (GtkWidget *widget);
-static gint gtk_notebook_enter_notify (GtkWidget *widget,
- GdkEventCrossing *event);
static gint gtk_notebook_leave_notify (GtkWidget *widget,
GdkEventCrossing *event);
static gint gtk_notebook_motion_notify (GtkWidget *widget,
/*** Drag and drop Methods ***/
static void gtk_notebook_drag_begin (GtkWidget *widget,
GdkDragContext *context);
+static void gtk_notebook_drag_end (GtkWidget *widget,
+ GdkDragContext *context);
static gboolean gtk_notebook_drag_motion (GtkWidget *widget,
GdkDragContext *context,
gint x,
widget_class->button_press_event = gtk_notebook_button_press;
widget_class->button_release_event = gtk_notebook_button_release;
widget_class->popup_menu = gtk_notebook_popup_menu;
- widget_class->enter_notify_event = gtk_notebook_enter_notify;
widget_class->leave_notify_event = gtk_notebook_leave_notify;
widget_class->motion_notify_event = gtk_notebook_motion_notify;
widget_class->grab_notify = gtk_notebook_grab_notify;
widget_class->focus = gtk_notebook_focus;
widget_class->style_set = gtk_notebook_style_set;
widget_class->drag_begin = gtk_notebook_drag_begin;
+ widget_class->drag_end = gtk_notebook_drag_end;
widget_class->drag_motion = gtk_notebook_drag_motion;
widget_class->drag_leave = gtk_notebook_drag_leave;
widget_class->drag_drop = gtk_notebook_drag_drop;
while (offset != 0)
{
- current = gtk_notebook_search_page (notebook, current, offset < 0 ? STEP_PREV : STEP_NEXT, TRUE);
+ current = gtk_notebook_search_page (notebook, current,
+ offset < 0 ? STEP_PREV : STEP_NEXT,
+ TRUE);
+
+ if (!current)
+ {
+ gboolean wrap_around;
+
+ g_object_get (gtk_widget_get_settings (GTK_WIDGET (notebook)),
+ "gtk-keynav-wrap-around", &wrap_around,
+ NULL);
+
+ if (wrap_around)
+ current = gtk_notebook_search_page (notebook, NULL,
+ offset < 0 ? STEP_PREV : STEP_NEXT,
+ TRUE);
+ else
+ break;
+ }
+
offset += offset < 0 ? 1 : -1;
}
if (current)
gtk_notebook_switch_page (notebook, current->data, -1);
else
- gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (notebook)));
+ gtk_widget_error_bell (GTK_WIDGET (notebook));
}
static GtkDirectionType
GList *last, *child;
gint page_num;
+ if (!gtk_widget_is_focus (GTK_WIDGET (notebook)))
+ return;
+
if (!notebook->cur_page ||
!notebook->cur_page->reorderable)
return;
* gtk_notebook_button_press
* gtk_notebook_button_release
* gtk_notebook_popup_menu
- * gtk_notebook_enter_notify
* gtk_notebook_leave_notify
* gtk_notebook_motion_notify
* gtk_notebook_focus_in
* gtk_notebook_draw_focus
* gtk_notebook_style_set
* gtk_notebook_drag_begin
+ * gtk_notebook_drag_end
* gtk_notebook_drag_motion
* gtk_notebook_drag_drop
* gtk_notebook_drag_data_get
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK |
- GDK_BUTTON1_MOTION_MASK |
+ GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK |
GDK_SCROLL_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y;
page = tab->data;
page_changed = page != notebook->cur_page;
was_focus = gtk_widget_is_focus (widget);
-
+
gtk_notebook_switch_focus_tab (notebook, tab);
gtk_widget_grab_focus (widget);
-
+
if (page_changed && !was_focus)
gtk_widget_child_focus (page->child, GTK_DIR_TAB_FORWARD);
-
+
/* save press to possibly begin a drag */
if (page->reorderable || page->detachable)
{
priv->during_detach = FALSE;
+ priv->during_reorder = FALSE;
priv->pressed_button = event->button;
- priv->mouse_x = x - widget->allocation.x;
- priv->mouse_y = y - widget->allocation.y;
+ gdk_window_get_pointer (widget->window,
+ &priv->mouse_x,
+ &priv->mouse_y,
+ NULL);
+
+ priv->drag_begin_x = priv->mouse_x;
+ priv->drag_begin_y = priv->mouse_y;
+ priv->drag_offset_x = priv->drag_begin_x - page->allocation.x;
+ priv->drag_offset_y = priv->drag_begin_y - page->allocation.y;
}
}
gint x, y;
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
- x = priv->mouse_x + GTK_WIDGET (notebook)->allocation.x;
- y = priv->mouse_y + GTK_WIDGET (notebook)->allocation.y;
+ x = priv->mouse_x;
+ y = priv->mouse_y;
is_rtl = gtk_widget_get_direction ((GtkWidget *) notebook) == GTK_TEXT_DIR_RTL;
children = notebook->children;
gdk_window_hide (priv->drag_window);
}
-static gint
-gtk_notebook_button_release (GtkWidget *widget,
- GdkEventButton *event)
+static void
+gtk_notebook_stop_reorder (GtkNotebook *notebook)
{
- GtkNotebook *notebook;
GtkNotebookPrivate *priv;
GtkNotebookPage *page;
- GList *element;
- gint old_page_num, page_num;
-
- g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- if (event->type != GDK_BUTTON_RELEASE)
- return FALSE;
- notebook = GTK_NOTEBOOK (widget);
priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
page = notebook->cur_page;
- if (page->reorderable &&
- event->button == priv->pressed_button)
- {
- priv->pressed_button = -1;
+ if (!page)
+ return;
- if (!priv->during_detach)
+ priv->pressed_button = -1;
+
+ if (page->reorderable || page->detachable)
+ {
+ if (priv->during_reorder)
{
+ gint old_page_num, page_num;
+ GList *element;
+
element = get_drop_position (notebook, page->pack);
old_page_num = g_list_position (notebook->children, notebook->focus_tab);
page_num = reorder_tab (notebook, element, notebook->focus_tab);
- if (priv->has_scrolled ||
- old_page_num != page_num)
+ if (priv->has_scrolled || old_page_num != page_num)
g_signal_emit (notebook,
notebook_signals[PAGE_REORDERED], 0,
page->child, page_num);
priv->has_scrolled = FALSE;
+ priv->during_reorder = FALSE;
}
hide_drag_window (notebook, priv, page);
priv->dnd_timer = 0;
}
}
-
- if (event->button == notebook->button)
- {
- stop_scrolling (notebook);
- return TRUE;
- }
- else
- return FALSE;
}
static gint
-gtk_notebook_enter_notify (GtkWidget *widget,
- GdkEventCrossing *event)
+gtk_notebook_button_release (GtkWidget *widget,
+ GdkEventButton *event)
{
GtkNotebook *notebook;
- GtkNotebookArrow arrow;
- gint x, y;
+ GtkNotebookPrivate *priv;
+ GtkNotebookPage *page;
g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- notebook = GTK_NOTEBOOK (widget);
-
- if (!get_widget_coordinates (widget, (GdkEvent *)event, &x, &y))
+ if (event->type != GDK_BUTTON_RELEASE)
return FALSE;
- arrow = gtk_notebook_get_arrow (notebook, x, y);
+ notebook = GTK_NOTEBOOK (widget);
+ priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
+ page = notebook->cur_page;
- if (arrow != notebook->in_child)
- {
- notebook->in_child = arrow;
- gtk_notebook_redraw_arrows (notebook);
+ if (!priv->during_detach &&
+ page->reorderable &&
+ event->button == priv->pressed_button)
+ gtk_notebook_stop_reorder (notebook);
+ if (event->button == notebook->button)
+ {
+ stop_scrolling (notebook);
return TRUE;
}
-
- return TRUE;
+ else
+ return FALSE;
}
static gint
if (notebook->tab_pos == GTK_POS_TOP ||
notebook->tab_pos == GTK_POS_BOTTOM)
{
+ gint x;
+
is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+ x = priv->mouse_x - widget->allocation.x;
- if (priv->mouse_x > widget->allocation.width - 2 * container->border_width - SCROLL_THRESHOLD)
+ if (x > widget->allocation.width - 2 * container->border_width - SCROLL_THRESHOLD)
return (is_rtl) ? POINTER_BEFORE : POINTER_AFTER;
- else if (priv->mouse_x < SCROLL_THRESHOLD + container->border_width)
+ else if (x < SCROLL_THRESHOLD + container->border_width)
return (is_rtl) ? POINTER_AFTER : POINTER_BEFORE;
else
return POINTER_BETWEEN;
}
else
{
- if (priv->mouse_y > widget->allocation.height - 2 * container->border_width - SCROLL_THRESHOLD)
+ gint y;
+
+ y = priv->mouse_y - widget->allocation.y;
+ if (y > widget->allocation.height - 2 * container->border_width - SCROLL_THRESHOLD)
return POINTER_AFTER;
- else if (priv->mouse_y < SCROLL_THRESHOLD + container->border_width)
+ else if (y < SCROLL_THRESHOLD + container->border_width)
return POINTER_BEFORE;
else
return POINTER_BETWEEN;
GtkNotebook *notebook = GTK_NOTEBOOK (widget);
GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
GtkNotebookPage *page;
+ GtkNotebookArrow arrow;
GtkNotebookPointerPosition pointer_position;
GtkSettings *settings;
guint timeout;
- if (priv->pressed_button == -1)
+ page = notebook->cur_page;
+
+ if (!page)
return FALSE;
- if (!notebook->cur_page)
+ if (!(event->state & GDK_BUTTON1_MASK) &&
+ priv->pressed_button != -1)
+ {
+ gtk_notebook_stop_reorder (notebook);
+ stop_scrolling (notebook);
+ }
+
+ if (event->time < priv->timestamp + MSECS_BETWEEN_UPDATES)
return FALSE;
- page = notebook->cur_page;
+ priv->timestamp = event->time;
+ gdk_window_get_pointer (widget->window,
+ &priv->mouse_x,
+ &priv->mouse_y,
+ NULL);
+
+ arrow = gtk_notebook_get_arrow (notebook, priv->mouse_x, priv->mouse_y);
+ if (arrow != notebook->in_child)
+ {
+ notebook->in_child = arrow;
+ gtk_notebook_redraw_arrows (notebook);
+ }
- get_widget_coordinates (widget, (GdkEvent*) event, &priv->mouse_x, &priv->mouse_y);
- priv->mouse_x -= widget->allocation.x;
- priv->mouse_y -= widget->allocation.y;
+ if (priv->pressed_button == -1)
+ return FALSE;
if (page->detachable &&
- check_threshold (notebook,
- priv->mouse_x + widget->allocation.x,
- priv->mouse_y + widget->allocation.y))
+ check_threshold (notebook, priv->mouse_x, priv->mouse_y))
{
priv->detached_tab = notebook->cur_page;
priv->during_detach = TRUE;
return TRUE;
}
- if (page->reorderable)
+ if (page->reorderable &&
+ (priv->during_reorder ||
+ gtk_drag_check_threshold (widget, priv->drag_begin_x, priv->drag_begin_y, priv->mouse_x, priv->mouse_y)))
{
+ priv->during_reorder = TRUE;
pointer_position = get_pointer_position (notebook);
if (event->window == priv->drag_window &&
settings = gtk_widget_get_settings (GTK_WIDGET (notebook));
g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
- priv->dnd_timer = g_timeout_add (timeout * SCROLL_DELAY_FACTOR,
- (GSourceFunc) scroll_notebook_timer,
+ priv->dnd_timer = gdk_threads_add_timeout (timeout * SCROLL_DELAY_FACTOR,
+ scroll_notebook_timer,
(gpointer) notebook);
}
}
/* the drag operation is beginning, create the window */
if (priv->operation != DRAG_OPERATION_REORDER)
{
- show_drag_window (notebook, priv, page);
priv->operation = DRAG_OPERATION_REORDER;
+ show_drag_window (notebook, priv, page);
}
gtk_notebook_pages_allocate (notebook);
gtk_notebook_grab_notify (GtkWidget *widget,
gboolean was_grabbed)
{
+ GtkNotebook *notebook = GTK_NOTEBOOK (widget);
+
if (!was_grabbed)
- stop_scrolling (GTK_NOTEBOOK (widget));
+ {
+ gtk_notebook_stop_reorder (notebook);
+ stop_scrolling (notebook);
+ }
}
static void
{
GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
GtkNotebook *notebook = (GtkNotebook*) widget;
- GtkWidget *tab_label, *window;
- gint width, height;
+ GtkWidget *tab_label;
if (priv->dnd_timer)
{
priv->dnd_timer = 0;
}
+ priv->operation = DRAG_OPERATION_DETACH;
+ gtk_notebook_pages_allocate (notebook);
+
tab_label = priv->detached_tab->tab_label;
- gdk_drawable_get_size (priv->drag_window, &width, &height);
hide_drag_window (notebook, priv, notebook->cur_page);
g_object_ref (tab_label);
gtk_widget_unparent (tab_label);
- window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_container_add (GTK_CONTAINER (window), tab_label);
- gtk_widget_set_size_request (window, width, height);
+ priv->dnd_window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_container_add (GTK_CONTAINER (priv->dnd_window), tab_label);
+ gtk_widget_set_size_request (priv->dnd_window,
+ priv->detached_tab->allocation.width,
+ priv->detached_tab->allocation.height);
g_object_unref (tab_label);
- g_signal_connect (G_OBJECT (window), "expose-event",
+ g_signal_connect (G_OBJECT (priv->dnd_window), "expose-event",
G_CALLBACK (on_drag_icon_expose), notebook);
- gtk_drag_set_icon_widget (context, window, -2, -2);
+ gtk_drag_set_icon_widget (context, priv->dnd_window, -2, -2);
+}
- priv->operation = DRAG_OPERATION_DETACH;
- gtk_notebook_pages_allocate (notebook);
+static void
+gtk_notebook_drag_end (GtkWidget *widget,
+ GdkDragContext *context)
+{
+ GtkNotebookPrivate *priv = GTK_NOTEBOOK_GET_PRIVATE (widget);
+
+ gtk_notebook_stop_reorder (GTK_NOTEBOOK (widget));
+
+ GTK_BIN (priv->dnd_window)->child = NULL;
+ gtk_widget_destroy (priv->dnd_window);
+ priv->dnd_window = NULL;
+
+ priv->operation = DRAG_OPERATION_NONE;
}
static gboolean
{
notebook->click_child = arrow;
gtk_notebook_set_scroll_timer (notebook);
+ gdk_drag_status (context, 0, time);
return TRUE;
}
if (widget_group != -1 &&
source_widget_group != -1 &&
- widget_group == source_widget_group)
+ widget_group == source_widget_group &&
+ !(widget == GTK_NOTEBOOK (source_widget)->cur_page->child ||
+ gtk_widget_is_ancestor (widget, GTK_NOTEBOOK (source_widget)->cur_page->child)))
{
gdk_drag_status (context, GDK_ACTION_MOVE, time);
return TRUE;
settings = gtk_widget_get_settings (widget);
g_object_get (settings, "gtk-timeout-expand", &timeout, NULL);
- priv->switch_tab_timer = g_timeout_add (timeout,
- (GSourceFunc) gtk_notebook_switch_tab_timeout,
+ priv->switch_tab_timer = gdk_threads_add_timeout (timeout,
+ gtk_notebook_switch_tab_timeout,
widget);
}
}
gtk_container_remove (GTK_CONTAINER (from), child);
priv = GTK_NOTEBOOK_GET_PRIVATE (to);
- priv->mouse_x = x;
- priv->mouse_y = y;
+ priv->mouse_x = x + GTK_WIDGET (to)->allocation.x;
+ priv->mouse_y = y + GTK_WIDGET (to)->allocation.y;
element = get_drop_position (to, tab_pack);
page_num = g_list_position (to->children, element);
new_page = gtk_notebook_search_page (notebook, notebook->focus_tab,
search_direction, TRUE);
+ if (!new_page)
+ {
+ gboolean wrap_around;
+
+ g_object_get (gtk_widget_get_settings (GTK_WIDGET (notebook)),
+ "gtk-keynav-wrap-around", &wrap_around,
+ NULL);
+
+ if (wrap_around)
+ new_page = gtk_notebook_search_page (notebook, NULL,
+ search_direction, TRUE);
+ }
+
if (new_page)
gtk_notebook_switch_focus_tab (notebook, new_page);
else
- gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (notebook)));
-
+ gtk_widget_error_bell (GTK_WIDGET (notebook));
+
return TRUE;
}
gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
}
-static void
-gtk_notebook_redraw_tabs_union (GtkNotebook *notebook)
-{
- GtkWidget *widget;
- GtkNotebookPage *page;
- GdkRectangle redraw_rect;
- gint border;
- gint tab_pos = get_effective_tab_pos (notebook);
-
- widget = GTK_WIDGET (notebook);
- border = GTK_CONTAINER (notebook)->border_width;
-
- if (!GTK_WIDGET_MAPPED (notebook) || !notebook->first_tab)
- return;
-
- page = GTK_NOTEBOOK_PAGE (notebook->first_tab);
-
- redraw_rect.x = border;
- redraw_rect.y = border;
-
- switch (tab_pos)
- {
- case GTK_POS_TOP:
- redraw_rect.x = border;
- redraw_rect.y = page->allocation.height + border;
- break;
- case GTK_POS_BOTTOM:
- redraw_rect.x = border;
- redraw_rect.y = widget->allocation.height - border -
- page->allocation.height - widget->style->ythickness;
- break;
- case GTK_POS_RIGHT:
- redraw_rect.x = widget->allocation.width - border -
- page->allocation.width - widget->style->xthickness;
- redraw_rect.y = border;
- break;
- case GTK_POS_LEFT:
- redraw_rect.x = page->allocation.width + border;
- redraw_rect.y = border;
- break;
- }
-
- switch (tab_pos)
- {
- case GTK_POS_TOP:
- case GTK_POS_BOTTOM:
- redraw_rect.width = widget->allocation.width - 2 * border;
- redraw_rect.height = widget->style->ythickness;
- break;
- case GTK_POS_RIGHT:
- case GTK_POS_LEFT:
- redraw_rect.width = widget->style->xthickness;
- redraw_rect.height = widget->allocation.height - 2 * border;
- break;
- }
-
- redraw_rect.x += widget->allocation.x;
- redraw_rect.y += widget->allocation.y;
-
- gdk_window_invalidate_rect (widget->window, &redraw_rect, TRUE);
-}
-
static void
gtk_notebook_redraw_arrows (GtkNotebook *notebook)
{
}
}
-static gint
+static gboolean
gtk_notebook_timer (GtkNotebook *notebook)
{
gboolean retval = FALSE;
- GDK_THREADS_ENTER ();
-
if (notebook->timer)
{
gtk_notebook_do_arrow (notebook, notebook->click_child);
g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
notebook->need_timer = FALSE;
- notebook->timer = g_timeout_add (timeout * SCROLL_DELAY_FACTOR,
+ notebook->timer = gdk_threads_add_timeout (timeout * SCROLL_DELAY_FACTOR,
(GSourceFunc) gtk_notebook_timer,
(gpointer) notebook);
}
retval = TRUE;
}
- GDK_THREADS_LEAVE ();
-
return retval;
}
g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
- notebook->timer = g_timeout_add (timeout,
+ notebook->timer = gdk_threads_add_timeout (timeout,
(GSourceFunc) gtk_notebook_timer,
(gpointer) notebook);
notebook->need_timer = TRUE;
gtk_notebook_real_remove (GtkNotebook *notebook,
GList *list)
{
+ GtkNotebookPrivate *priv;
GtkNotebookPage *page;
GList * next_list;
gint need_resize = FALSE;
gboolean destroying;
+ priv = GTK_NOTEBOOK_GET_PRIVATE (notebook);
destroying = GTK_OBJECT_FLAGS (notebook) & GTK_IN_DESTRUCTION;
next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE);
gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1);
}
+ if (priv->detached_tab == list->data)
+ priv->detached_tab = NULL;
+
if (list == notebook->first_tab)
notebook->first_tab = next_list;
if (list == notebook->focus_tab && !destroying)
if (!NOTEBOOK_IS_TAB_LABEL_PARENT (notebook, notebook->cur_page) ||
!GTK_WIDGET_MAPPED (notebook->cur_page->tab_label))
{
- gtk_paint_box (widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- area, widget, "notebook",
- x, y, width, height);
+ gap_x = 0;
+ gap_width = 0;
}
else
{
step = STEP_PREV;
break;
}
-
- gtk_paint_box_gap (widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT,
- area, widget, "notebook",
- x, y, width, height,
- tab_pos, gap_x, gap_width);
}
+ gtk_paint_box_gap (widget->style, widget->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+ area, widget, "notebook",
+ x, y, width, height,
+ tab_pos, gap_x, gap_width);
showarrow = FALSE;
children = gtk_notebook_search_page (notebook, NULL, step, TRUE);
arrow = (ARROW_IS_LEFT (nbarrow) ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT);
arrow_size = scroll_arrow_hlength;
}
-
+
gtk_paint_arrow (widget->style, widget->window, state_type,
shadow_type, NULL, widget, "notebook",
arrow, TRUE, arrow_rect.x, arrow_rect.y,
{
GtkNotebookPrivate *priv;
GtkWidget *widget;
- GtkNotebookPage *page;
GList *children;
gint tab_pos = get_effective_tab_pos (notebook);
gint tab_overlap;
while (children)
{
+ GtkNotebookPage *page;
+
page = children->data;
children = children->next;
while (children)
{
+ GtkNotebookPage *page;
+
page = children->data;
children = children->next;
if (*tab_space > *max - *min - tab_overlap)
{
*show_arrows = TRUE;
- page = notebook->focus_tab->data;
/* take arrows into account */
*tab_space = widget->allocation.width - tab_overlap -
if (*tab_space > *max - *min - tab_overlap)
{
*show_arrows = TRUE;
- page = notebook->focus_tab->data;
/* take arrows into account */
*tab_space = widget->allocation.height -
{
*last_child = NULL;
children = NULL;
+
gtk_notebook_calc_tabs (notebook,
gtk_notebook_search_page (notebook,
notebook->first_tab,
STEP_PREV,
TRUE),
&children, remaining_space, STEP_PREV);
- notebook->first_tab = gtk_notebook_search_page(notebook,
- children,
- STEP_NEXT,
- TRUE);
+
+ if (*remaining_space == 0)
+ notebook->first_tab = children;
+ else
+ notebook->first_tab = gtk_notebook_search_page(notebook,
+ children,
+ STEP_NEXT,
+ TRUE);
}
}
}
gboolean allocate_at_bottom;
gint tab_overlap, tab_pos, tab_extra_space;
gint left_x, right_x, top_y, bottom_y, anchor;
+ gint xthickness, ythickness;
gboolean gap_left, packing_changed;
GtkAllocation child_allocation = { 0, };
gboolean allocation_changed = FALSE;
child_allocation.x = widget->allocation.x + container->border_width;
child_allocation.y = widget->allocation.y + container->border_width;
+ xthickness = widget->style->xthickness;
+ ythickness = widget->style->ythickness;
+
switch (tab_pos)
{
case GTK_POS_BOTTOM:
break;
}
- left_x = CLAMP (widget->allocation.x + priv->mouse_x - notebook->cur_page->allocation.width / 2,
+ left_x = CLAMP (priv->mouse_x - priv->drag_offset_x,
min, max - notebook->cur_page->allocation.width);
- top_y = CLAMP (widget->allocation.y + priv->mouse_y - notebook->cur_page->allocation.height / 2,
+ top_y = CLAMP (priv->mouse_y - priv->drag_offset_y,
min, max - notebook->cur_page->allocation.height);
right_x = left_x + notebook->cur_page->allocation.width;
bottom_y = top_y + notebook->cur_page->allocation.height;
page->allocation = child_allocation;
- if (priv->operation == DRAG_OPERATION_REORDER &&
- page == notebook->cur_page)
+ if (page == notebook->cur_page)
+ {
+ if (priv->operation == DRAG_OPERATION_REORDER ||
+ priv->operation == DRAG_OPERATION_DETACH)
+ {
+ /* needs to be allocated at 0,0
+ * to be shown in the drag window */
+ page->allocation.x = 0;
+ page->allocation.y = 0;
+ }
+ }
+ else
{
- /* needs to be allocated at 0,0
- * to be shown in the drag window */
- page->allocation.x = 0;
- page->allocation.y = 0;
+ switch (tab_pos)
+ {
+ case GTK_POS_TOP:
+ page->allocation.y += ythickness;
+ /* fall through */
+ case GTK_POS_BOTTOM:
+ page->allocation.height = MAX (1, page->allocation.height - ythickness);
+ break;
+ case GTK_POS_LEFT:
+ page->allocation.x += xthickness;
+ /* fall through */
+ case GTK_POS_RIGHT:
+ page->allocation.width = MAX (1, page->allocation.width - xthickness);
+ break;
+ }
}
/* calculate whether to leave a gap based on reorder operation or not */
gboolean showarrow = FALSE;
gint tab_space, min, max, remaining_space;
gint expanded_tabs, operation;
- gboolean changed;
if (!notebook->show_tabs || !notebook->children || !notebook->cur_page)
return;
&expanded_tabs, &remaining_space);
children = notebook->first_tab;
- changed = gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
- showarrow, STEP_NEXT,
- &remaining_space, &expanded_tabs, min, max);
+ gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
+ showarrow, STEP_NEXT,
+ &remaining_space, &expanded_tabs, min, max);
if (children && children != last_child)
{
children = notebook->children;
- changed |= gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
- showarrow, STEP_PREV,
- &remaining_space, &expanded_tabs, min, max);
+ gtk_notebook_calculate_tabs_allocation (notebook, &children, last_child,
+ showarrow, STEP_PREV,
+ &remaining_space, &expanded_tabs, min, max);
}
children = notebook->children;
if (!notebook->first_tab)
notebook->first_tab = notebook->children;
- if (changed || operation != DRAG_OPERATION_REORDER)
- gtk_notebook_redraw_tabs (notebook);
- else if (!changed)
- gtk_notebook_redraw_tabs_union (notebook);
+ gtk_notebook_redraw_tabs (notebook);
}
static void
* than the number of pages in the notebook, nothing
* will be done.
*
- * Switches to the page number @page_num.
- **/
+ * Switches to the page number @page_num.
+ *
+ * Note that due to historical reasons, GtkNotebook refuses
+ * to switch to a page unless the child widget is visible.
+ * Therefore, it is recommended to show child widgets before
+ * adding them to a notebook.
+ */
void
gtk_notebook_set_current_page (GtkNotebook *notebook,
gint page_num)