gtknotebook.c 196 KB
Newer Older
1
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
Elliot Lee's avatar
Elliot Lee committed
2 3 4 5
/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
7 8 9 10 11 12
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16 17 18
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
19
 */
20 21

/*
22
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23 24 25 26 27
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

28
#include <config.h>
Elliot Lee's avatar
Elliot Lee committed
29
#include "gtknotebook.h"
30 31 32 33 34 35
#include "gtkmain.h"
#include "gtkmenu.h"
#include "gtkmenuitem.h"
#include "gtklabel.h"
#include <gdk/gdkkeysyms.h>
#include <stdio.h>
36
#include "gtkintl.h"
37
#include "gtkmarshalers.h"
38
#include "gtkbindings.h"
39
#include "gtkprivate.h"
40
#include "gtkalias.h"
41
#include "gtkdnd.h"
Elliot Lee's avatar
Elliot Lee committed
42

43 44 45
#define ARROW_SIZE            12
#define ARROW_SPACING         0
#define SCROLL_DELAY_FACTOR   5
46 47
#define SCROLL_THRESHOLD      12
#define DND_THRESHOLD_MULTIPLIER 4
Elliot Lee's avatar
Elliot Lee committed
48

49 50
enum {
  SWITCH_PAGE,
51 52
  FOCUS_TAB,
  SELECT_PAGE,
53
  CHANGE_CURRENT_PAGE,
54
  MOVE_FOCUS_OUT,
55
  REORDER_TAB,
56 57 58
  PAGE_REORDERED,
  PAGE_REMOVED,
  PAGE_ADDED,
59 60 61
  LAST_SIGNAL
};

62 63 64 65 66
enum {
  STEP_PREV,
  STEP_NEXT
};

67 68 69 70 71 72 73 74 75
typedef enum
{
  ARROW_NONE,
  ARROW_LEFT_BEFORE,
  ARROW_RIGHT_BEFORE,
  ARROW_LEFT_AFTER,
  ARROW_RIGHT_AFTER
} GtkNotebookArrow;

76 77 78 79 80 81 82 83 84 85 86 87 88 89
typedef enum
{
  POINTER_BEFORE,
  POINTER_AFTER,
  POINTER_BETWEEN
} GtkNotebookPointerPosition;

typedef enum
{
  DRAG_OPERATION_NONE,
  DRAG_OPERATION_REORDER,
  DRAG_OPERATION_DETACH
} GtkNotebookDragOperation;

90 91 92
#define ARROW_IS_LEFT(arrow)  ((arrow) == ARROW_LEFT_BEFORE || (arrow) == ARROW_LEFT_AFTER)
#define ARROW_IS_BEFORE(arrow) ((arrow) == ARROW_LEFT_BEFORE || (arrow) == ARROW_RIGHT_BEFORE)

93
enum {
94 95 96 97 98 99 100 101 102 103
  PROP_0,
  PROP_TAB_POS,
  PROP_SHOW_TABS,
  PROP_SHOW_BORDER,
  PROP_SCROLLABLE,
  PROP_TAB_BORDER,
  PROP_TAB_HBORDER,
  PROP_TAB_VBORDER,
  PROP_PAGE,
  PROP_ENABLE_POPUP,
104
  PROP_GROUP_ID,
105
  PROP_HOMOGENEOUS
106 107 108
};

enum {
Tim Janik's avatar
Tim Janik committed
109 110 111 112 113 114
  CHILD_PROP_0,
  CHILD_PROP_TAB_LABEL,
  CHILD_PROP_MENU_LABEL,
  CHILD_PROP_POSITION,
  CHILD_PROP_TAB_EXPAND,
  CHILD_PROP_TAB_FILL,
115 116 117
  CHILD_PROP_TAB_PACK,
  CHILD_PROP_REORDERABLE,
  CHILD_PROP_DETACHABLE
118 119
};

120 121
#define GTK_NOTEBOOK_PAGE(_glist_)         ((GtkNotebookPage *)((GList *)(_glist_))->data)

122 123 124 125 126 127 128 129
/* some useful defines for calculating coords */
#define PAGE_LEFT_X(_page_)   (((GtkNotebookPage *) (_page_))->allocation.x)
#define PAGE_RIGHT_X(_page_)  (((GtkNotebookPage *) (_page_))->allocation.x + ((GtkNotebookPage *) (_page_))->allocation.width)
#define PAGE_MIDDLE_X(_page_) (((GtkNotebookPage *) (_page_))->allocation.x + ((GtkNotebookPage *) (_page_))->allocation.width / 2)
#define PAGE_TOP_Y(_page_)    (((GtkNotebookPage *) (_page_))->allocation.y)
#define PAGE_BOTTOM_Y(_page_) (((GtkNotebookPage *) (_page_))->allocation.y + ((GtkNotebookPage *) (_page_))->allocation.height)
#define PAGE_MIDDLE_Y(_page_) (((GtkNotebookPage *) (_page_))->allocation.y + ((GtkNotebookPage *) (_page_))->allocation.height / 2)

130 131 132 133 134
struct _GtkNotebookPage
{
  GtkWidget *child;
  GtkWidget *tab_label;
  GtkWidget *menu_label;
135
  GtkWidget *last_focus_child;	/* Last descendant of the page that had focus */
136 137 138 139 140 141

  guint default_menu : 1;	/* If true, we create the menu label ourself */
  guint default_tab  : 1;	/* If true, we create the tab label ourself */
  guint expand       : 1;
  guint fill         : 1;
  guint pack         : 1;
142 143
  guint reorderable  : 1;
  guint detachable   : 1;
144 145 146

  GtkRequisition requisition;
  GtkAllocation allocation;
147

148 149
  gulong mnemonic_activate_signal;
  gulong notify_visible_handler;
150 151
};

152 153 154 155 156 157 158 159 160 161 162
#define GTK_NOTEBOOK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_NOTEBOOK, GtkNotebookPrivate))

typedef struct _GtkNotebookPrivate GtkNotebookPrivate;

struct _GtkNotebookPrivate
{
  gint  group_id;
  gint  mouse_x;
  gint  mouse_y;
  gint  pressed_button;
  guint dnd_timer;
163
  guint switch_tab_timer;
164 165 166 167 168
  GtkTargetList *source_targets;
  gboolean during_detach;
  gboolean has_scrolled;
};

169
static const GtkTargetEntry notebook_source_targets [] = {
170 171 172 173
  { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 },
  { "application/x-rootwindow-drop", 0, 1 }
};

174 175 176 177
static const GtkTargetEntry notebook_dest_targets[] = {
  { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 }
};

178 179
#ifdef G_DISABLE_CHECKS
#define CHECK_FIND_CHILD(notebook, child)                           \
180
 gtk_notebook_find_child (notebook, child, G_STRLOC)
181 182
#else
#define CHECK_FIND_CHILD(notebook, child)                           \
183
 gtk_notebook_find_child (notebook, child, NULL)
184 185
#endif
 
186
/*** GtkNotebook Methods ***/
187 188
static void gtk_notebook_class_init          (GtkNotebookClass *klass);
static void gtk_notebook_init                (GtkNotebook      *notebook);
189

190 191 192 193 194 195 196 197
static gboolean gtk_notebook_select_page         (GtkNotebook      *notebook,
						  gboolean          move_focus);
static gboolean gtk_notebook_focus_tab           (GtkNotebook      *notebook,
						  GtkNotebookTab    type);
static void     gtk_notebook_change_current_page (GtkNotebook      *notebook,
						  gint              offset);
static void     gtk_notebook_move_focus_out      (GtkNotebook      *notebook,
						  GtkDirectionType  direction_type);
198 199 200
static void     gtk_notebook_reorder_tab         (GtkNotebook      *notebook,
						  GtkDirectionType  direction_type,
						  gboolean          move_to_last);
201

202
/*** GtkObject Methods ***/
203
static void gtk_notebook_destroy             (GtkObject        *object);
204 205 206 207 208 209 210 211
static void gtk_notebook_set_property	     (GObject         *object,
					      guint            prop_id,
					      const GValue    *value,
					      GParamSpec      *pspec);
static void gtk_notebook_get_property	     (GObject         *object,
					      guint            prop_id,
					      GValue          *value,
					      GParamSpec      *pspec);
212

213
/*** GtkWidget Methods ***/
214 215 216
static void gtk_notebook_map                 (GtkWidget        *widget);
static void gtk_notebook_unmap               (GtkWidget        *widget);
static void gtk_notebook_realize             (GtkWidget        *widget);
217
static void gtk_notebook_unrealize           (GtkWidget        *widget);
218 219 220 221 222 223
static void gtk_notebook_size_request        (GtkWidget        *widget,
					      GtkRequisition   *requisition);
static void gtk_notebook_size_allocate       (GtkWidget        *widget,
					      GtkAllocation    *allocation);
static gint gtk_notebook_expose              (GtkWidget        *widget,
					      GdkEventExpose   *event);
224 225
static gboolean gtk_notebook_scroll          (GtkWidget        *widget,
                                              GdkEventScroll   *event);
226 227 228 229
static gint gtk_notebook_button_press        (GtkWidget        *widget,
					      GdkEventButton   *event);
static gint gtk_notebook_button_release      (GtkWidget        *widget,
					      GdkEventButton   *event);
230
static gboolean gtk_notebook_popup_menu      (GtkWidget        *widget);
231 232 233 234 235 236
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,
					      GdkEventMotion   *event);
237 238
static gint gtk_notebook_focus_in            (GtkWidget        *widget,
					      GdkEventFocus    *event);
239 240
static gint gtk_notebook_focus_out           (GtkWidget        *widget,
					      GdkEventFocus    *event);
Matthias Clasen's avatar
Matthias Clasen committed
241 242 243 244
static void gtk_notebook_grab_notify         (GtkWidget          *widget,
					      gboolean            was_grabbed);
static void gtk_notebook_state_changed       (GtkWidget          *widget,
					      GtkStateType        previous_state);
245
static void gtk_notebook_draw_focus          (GtkWidget        *widget);
246 247
static gint gtk_notebook_focus               (GtkWidget        *widget,
					      GtkDirectionType  direction);
248 249
static void gtk_notebook_style_set           (GtkWidget        *widget,
					      GtkStyle         *previous);
250

251 252 253 254 255 256 257 258
/*** Drag and drop Methods ***/
static void gtk_notebook_drag_begin          (GtkWidget        *widget,
					      GdkDragContext   *context);
static gboolean gtk_notebook_drag_motion     (GtkWidget        *widget,
					      GdkDragContext   *context,
					      gint              x,
					      gint              y,
					      guint             time);
259 260 261
static void gtk_notebook_drag_leave          (GtkWidget        *widget,
					      GdkDragContext   *context,
					      guint             time);
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
static gboolean gtk_notebook_drag_drop       (GtkWidget        *widget,
					      GdkDragContext   *context,
					      gint              x,
					      gint              y,
					      guint             time);
static void gtk_notebook_drag_data_get       (GtkWidget        *widget,
					      GdkDragContext   *context,
					      GtkSelectionData *data,
					      guint             info,
					      guint             time);
static void gtk_notebook_drag_data_received  (GtkWidget        *widget,
					      GdkDragContext   *context,
					      gint              x,
					      gint              y,
					      GtkSelectionData *data,
					      guint             info,
					      guint             time);

280
/*** GtkContainer Methods ***/
Tim Janik's avatar
Tim Janik committed
281
static void gtk_notebook_set_child_property  (GtkContainer     *container,
282
					      GtkWidget        *child,
Tim Janik's avatar
Tim Janik committed
283 284 285 286
					      guint             property_id,
					      const GValue     *value,
					      GParamSpec       *pspec);
static void gtk_notebook_get_child_property  (GtkContainer     *container,
287
					      GtkWidget        *child,
Tim Janik's avatar
Tim Janik committed
288 289 290
					      guint             property_id,
					      GValue           *value,
					      GParamSpec       *pspec);
291 292 293 294
static void gtk_notebook_add                 (GtkContainer     *container,
					      GtkWidget        *widget);
static void gtk_notebook_remove              (GtkContainer     *container,
					      GtkWidget        *widget);
295 296
static void gtk_notebook_set_focus_child     (GtkContainer     *container,
					      GtkWidget        *child);
Manish Singh's avatar
Manish Singh committed
297
static GType gtk_notebook_child_type       (GtkContainer     *container);
298 299
static void gtk_notebook_forall              (GtkContainer     *container,
					      gboolean		include_internals,
300 301
					      GtkCallback       callback,
					      gpointer          callback_data);
302

303 304 305 306 307 308 309
/*** GtkNotebook Methods ***/
static gint gtk_notebook_real_insert_page    (GtkNotebook      *notebook,
					      GtkWidget        *child,
					      GtkWidget        *tab_label,
					      GtkWidget        *menu_label,
					      gint              position);

310
/*** GtkNotebook Private Functions ***/
311 312
static void gtk_notebook_redraw_tabs         (GtkNotebook      *notebook);
static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
313
static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
314
					      GList            *list);
315 316 317 318
static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
static gint gtk_notebook_timer               (GtkNotebook      *notebook);
static gint gtk_notebook_page_compare        (gconstpointer     a,
					      gconstpointer     b);
319
static GList* gtk_notebook_find_child        (GtkNotebook      *notebook,
320 321
					      GtkWidget        *child,
					      const gchar      *function);
322 323 324 325 326 327 328
static gint  gtk_notebook_real_page_position (GtkNotebook      *notebook,
					      GList            *list);
static GList * gtk_notebook_search_page      (GtkNotebook      *notebook,
					      GList            *list,
					      gint              direction,
					      gboolean          find_visible);

329
/*** GtkNotebook Drawing Functions ***/
330 331
static void gtk_notebook_paint               (GtkWidget        *widget,
					      GdkRectangle     *area);
332 333 334
static void gtk_notebook_draw_tab            (GtkNotebook      *notebook,
					      GtkNotebookPage  *page,
					      GdkRectangle     *area);
335
static void gtk_notebook_draw_arrow          (GtkNotebook      *notebook,
336
					      GtkNotebookArrow  arrow);
337

338
/*** GtkNotebook Size Allocate Functions ***/
339 340
static void gtk_notebook_pages_allocate      (GtkNotebook              *notebook,
					      GtkNotebookDragOperation  operation);
341 342 343
static void gtk_notebook_page_allocate       (GtkNotebook      *notebook,
					      GtkNotebookPage  *page,
					      GtkAllocation    *allocation);
344 345
static void gtk_notebook_calc_tabs           (GtkNotebook      *notebook,
			                      GList            *start,
346 347 348
					      GList           **end,
					      gint             *tab_space,
					      guint             direction);
349

350
/*** GtkNotebook Page Switch Methods ***/
351
static void gtk_notebook_real_switch_page    (GtkNotebook      *notebook,
Lars Hamann's avatar
Lars Hamann committed
352
					      GtkNotebookPage  *page,
353
					      guint             page_num);
354

355
/*** GtkNotebook Page Switch Functions ***/
356 357
static void gtk_notebook_switch_page         (GtkNotebook      *notebook,
					      GtkNotebookPage  *page,
358
					      gint              page_num);
359 360
static gint gtk_notebook_page_select         (GtkNotebook      *notebook,
					      gboolean          move_focus);
361 362
static void gtk_notebook_switch_focus_tab    (GtkNotebook      *notebook,
                                              GList            *new_child);
363 364
static void gtk_notebook_menu_switch_page    (GtkWidget        *widget,
					      GtkNotebookPage  *page);
365

366
/*** GtkNotebook Menu Functions ***/
367 368 369 370
static void gtk_notebook_menu_item_create    (GtkNotebook      *notebook,
					      GList            *list);
static void gtk_notebook_menu_label_unparent (GtkWidget        *widget,
					      gpointer          data);
371 372
static void gtk_notebook_menu_detacher       (GtkWidget        *widget,
					      GtkMenu          *menu);
373

374 375 376 377 378 379 380 381 382 383
/*** GtkNotebook Private Setters ***/
static void gtk_notebook_set_homogeneous_tabs_internal (GtkNotebook *notebook,
							gboolean     homogeneous);
static void gtk_notebook_set_tab_border_internal       (GtkNotebook *notebook,
							guint        border_width);
static void gtk_notebook_set_tab_hborder_internal      (GtkNotebook *notebook,
							guint        tab_hborder);
static void gtk_notebook_set_tab_vborder_internal      (GtkNotebook *notebook,
							guint        tab_vborder);

384 385 386 387 388
static void gtk_notebook_update_tab_states             (GtkNotebook *notebook);
static gboolean gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child,
							    gboolean overload,
							    gpointer data);

389 390 391
static gboolean focus_tabs_in  (GtkNotebook      *notebook);
static gboolean focus_child_in (GtkNotebook      *notebook,
				GtkDirectionType  direction);
Elliot Lee's avatar
Elliot Lee committed
392

393 394 395
static void stop_scrolling (GtkNotebook *notebook);


396 397 398
static GtkNotebookWindowCreationFunc window_creation_hook = NULL;
static gpointer window_creation_hook_data;

399
static GtkContainerClass *parent_class = NULL;
400
static guint notebook_signals[LAST_SIGNAL] = { 0 };
Elliot Lee's avatar
Elliot Lee committed
401

Manish Singh's avatar
Manish Singh committed
402
GType
403
gtk_notebook_get_type (void)
Elliot Lee's avatar
Elliot Lee committed
404
{
Manish Singh's avatar
Manish Singh committed
405
  static GType notebook_type = 0;
Elliot Lee's avatar
Elliot Lee committed
406 407 408

  if (!notebook_type)
    {
Manish Singh's avatar
Manish Singh committed
409
      static const GTypeInfo notebook_info =
Elliot Lee's avatar
Elliot Lee committed
410 411
      {
	sizeof (GtkNotebookClass),
Manish Singh's avatar
Manish Singh committed
412 413 414 415 416 417 418 419
	NULL,		/* base_init */
	NULL,		/* base_finalize */
	(GClassInitFunc) gtk_notebook_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_data */
	sizeof (GtkNotebook),
	0,		/* n_preallocs */
	(GInstanceInitFunc) gtk_notebook_init,
Elliot Lee's avatar
Elliot Lee committed
420 421
      };

Matthias Clasen's avatar
Matthias Clasen committed
422
      notebook_type = g_type_register_static (GTK_TYPE_CONTAINER, I_("GtkNotebook"),
Manish Singh's avatar
Manish Singh committed
423
					      &notebook_info, 0);
Elliot Lee's avatar
Elliot Lee committed
424 425 426 427 428
    }

  return notebook_type;
}

429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
static void
add_tab_bindings (GtkBindingSet    *binding_set,
		  GdkModifierType   modifiers,
		  GtkDirectionType  direction)
{
  gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}

static void
add_arrow_bindings (GtkBindingSet    *binding_set,
		    guint             keysym,
		    GtkDirectionType  direction)
{
  guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
  
  gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
  gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}

457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
static void
add_reorder_bindings (GtkBindingSet    *binding_set,
		      guint             keysym,
		      GtkDirectionType  direction,
		      gboolean          move_to_last)
{
  guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;

  gtk_binding_entry_add_signal (binding_set, keysym, GDK_MOD1_MASK,
				"reorder_tab", 2,
				GTK_TYPE_DIRECTION_TYPE, direction,
				G_TYPE_BOOLEAN, move_to_last);
  gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_MOD1_MASK,
				"reorder_tab", 2,
				GTK_TYPE_DIRECTION_TYPE, direction,
				G_TYPE_BOOLEAN, move_to_last);
}

Elliot Lee's avatar
Elliot Lee committed
475 476 477
static void
gtk_notebook_class_init (GtkNotebookClass *class)
{
Tim Janik's avatar
Tim Janik committed
478 479 480 481
  GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
  GtkObjectClass *object_class = GTK_OBJECT_CLASS (class);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
482 483
  GtkBindingSet *binding_set;
  
Tim Janik's avatar
Tim Janik committed
484
  parent_class = g_type_class_peek_parent (class);
485

486 487
  gobject_class->set_property = gtk_notebook_set_property;
  gobject_class->get_property = gtk_notebook_get_property;
488 489
  object_class->destroy = gtk_notebook_destroy;

Elliot Lee's avatar
Elliot Lee committed
490 491 492
  widget_class->map = gtk_notebook_map;
  widget_class->unmap = gtk_notebook_unmap;
  widget_class->realize = gtk_notebook_realize;
493
  widget_class->unrealize = gtk_notebook_unrealize;
Elliot Lee's avatar
Elliot Lee committed
494 495 496
  widget_class->size_request = gtk_notebook_size_request;
  widget_class->size_allocate = gtk_notebook_size_allocate;
  widget_class->expose_event = gtk_notebook_expose;
497
  widget_class->scroll_event = gtk_notebook_scroll;
Elliot Lee's avatar
Elliot Lee committed
498
  widget_class->button_press_event = gtk_notebook_button_press;
499
  widget_class->button_release_event = gtk_notebook_button_release;
500
  widget_class->popup_menu = gtk_notebook_popup_menu;
501 502 503
  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;
Matthias Clasen's avatar
Matthias Clasen committed
504 505
  widget_class->grab_notify = gtk_notebook_grab_notify;
  widget_class->state_changed = gtk_notebook_state_changed;
506
  widget_class->focus_in_event = gtk_notebook_focus_in;
507
  widget_class->focus_out_event = gtk_notebook_focus_out;
508
  widget_class->focus = gtk_notebook_focus;
509
  widget_class->style_set = gtk_notebook_style_set;
510 511
  widget_class->drag_begin = gtk_notebook_drag_begin;
  widget_class->drag_motion = gtk_notebook_drag_motion;
512
  widget_class->drag_leave = gtk_notebook_drag_leave;
513 514 515 516
  widget_class->drag_drop = gtk_notebook_drag_drop;
  widget_class->drag_data_get = gtk_notebook_drag_data_get;
  widget_class->drag_data_received = gtk_notebook_drag_data_received;

Elliot Lee's avatar
Elliot Lee committed
517 518
  container_class->add = gtk_notebook_add;
  container_class->remove = gtk_notebook_remove;
519
  container_class->forall = gtk_notebook_forall;
Lars Hamann's avatar
Lars Hamann committed
520
  container_class->set_focus_child = gtk_notebook_set_focus_child;
Tim Janik's avatar
Tim Janik committed
521 522
  container_class->get_child_property = gtk_notebook_get_child_property;
  container_class->set_child_property = gtk_notebook_set_child_property;
523
  container_class->child_type = gtk_notebook_child_type;
524

525
  class->switch_page = gtk_notebook_real_switch_page;
526
  class->insert_page = gtk_notebook_real_insert_page;
527

528 529
  class->focus_tab = gtk_notebook_focus_tab;
  class->select_page = gtk_notebook_select_page;
530
  class->change_current_page = gtk_notebook_change_current_page;
531
  class->move_focus_out = gtk_notebook_move_focus_out;
532
  class->reorder_tab = gtk_notebook_reorder_tab;
533
  
534 535 536
  g_object_class_install_property (gobject_class,
				   PROP_PAGE,
				   g_param_spec_int ("page",
537 538
 						     P_("Page"),
 						     P_("The index of the current page"),
539 540 541
 						     0,
 						     G_MAXINT,
 						     0,
542
 						     GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
543 544
  g_object_class_install_property (gobject_class,
				   PROP_TAB_POS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
545
				   g_param_spec_enum ("tab-pos",
546 547
 						      P_("Tab Position"),
 						      P_("Which side of the notebook holds the tabs"),
548 549
 						      GTK_TYPE_POSITION_TYPE,
 						      GTK_POS_TOP,
550
 						      GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
551 552
  g_object_class_install_property (gobject_class,
				   PROP_TAB_BORDER,
Matthias Clasen's avatar
x  
Matthias Clasen committed
553
				   g_param_spec_uint ("tab-border",
554 555
 						      P_("Tab Border"),
 						      P_("Width of the border around the tab labels"),
556 557 558
 						      0,
 						      G_MAXUINT,
 						      2,
559
 						      GTK_PARAM_WRITABLE));
Tim Janik's avatar
Tim Janik committed
560 561
  g_object_class_install_property (gobject_class,
				   PROP_TAB_HBORDER,
Matthias Clasen's avatar
x  
Matthias Clasen committed
562
				   g_param_spec_uint ("tab-hborder",
563 564
 						      P_("Horizontal Tab Border"),
 						      P_("Width of the horizontal border of tab labels"),
565 566 567
 						      0,
 						      G_MAXUINT,
 						      2,
568
 						      GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
569 570
  g_object_class_install_property (gobject_class,
				   PROP_TAB_VBORDER,
Matthias Clasen's avatar
x  
Matthias Clasen committed
571
				   g_param_spec_uint ("tab-vborder",
572 573
 						      P_("Vertical Tab Border"),
 						      P_("Width of the vertical border of tab labels"),
574 575 576
 						      0,
 						      G_MAXUINT,
 						      2,
577
 						      GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
578 579
  g_object_class_install_property (gobject_class,
				   PROP_SHOW_TABS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
580
				   g_param_spec_boolean ("show-tabs",
581 582
 							 P_("Show Tabs"),
 							 P_("Whether tabs should be shown or not"),
583
 							 TRUE,
584
 							 GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
585 586
  g_object_class_install_property (gobject_class,
				   PROP_SHOW_BORDER,
Matthias Clasen's avatar
x  
Matthias Clasen committed
587
				   g_param_spec_boolean ("show-border",
588 589
 							 P_("Show Border"),
 							 P_("Whether the border should be shown or not"),
590
 							 TRUE,
591
 							 GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
592 593 594
  g_object_class_install_property (gobject_class,
				   PROP_SCROLLABLE,
				   g_param_spec_boolean ("scrollable",
595 596
 							 P_("Scrollable"),
 							 P_("If TRUE, scroll arrows are added if there are too many tabs to fit"),
597
 							 FALSE,
598
 							 GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
599 600
  g_object_class_install_property (gobject_class,
				   PROP_ENABLE_POPUP,
Matthias Clasen's avatar
x  
Matthias Clasen committed
601
				   g_param_spec_boolean ("enable-popup",
602 603
 							 P_("Enable Popup"),
 							 P_("If TRUE, pressing the right mouse button on the notebook pops up a menu that you can use to go to a page"),
604
 							 FALSE,
605
 							 GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
606 607 608
  g_object_class_install_property (gobject_class,
				   PROP_HOMOGENEOUS,
				   g_param_spec_boolean ("homogeneous",
609 610
 							 P_("Homogeneous"),
 							 P_("Whether tabs should have homogeneous sizes"),
611
 							 FALSE,
612
							 GTK_PARAM_READWRITE));
613 614 615 616 617 618 619 620 621
  g_object_class_install_property (gobject_class,
				   PROP_GROUP_ID,
				   g_param_spec_int ("group-id",
						     P_("Group ID"),
						     P_("Group ID for tabs drag and drop"),
						     -1,
						     G_MAXINT,
						     -1,
						     GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
622 623 624

  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_LABEL,
Matthias Clasen's avatar
x  
Matthias Clasen committed
625
					      g_param_spec_string ("tab-label", 
626
								   P_("Tab label"),
Matthias Clasen's avatar
Matthias Clasen committed
627
								   P_("The string displayed on the child's tab label"),
Tim Janik's avatar
Tim Janik committed
628
								   NULL,
629
								   GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
630 631
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_MENU_LABEL,
Matthias Clasen's avatar
x  
Matthias Clasen committed
632
					      g_param_spec_string ("menu-label", 
633
								   P_("Menu label"), 
Matthias Clasen's avatar
Matthias Clasen committed
634
								   P_("The string displayed in the child's menu entry"),
Tim Janik's avatar
Tim Janik committed
635
								   NULL,
636
								   GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
637 638
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_POSITION,
639
					      g_param_spec_int ("position", 
640 641
								P_("Position"), 
								P_("The index of the child in the parent"),
Tim Janik's avatar
Tim Janik committed
642
								-1, G_MAXINT, 0,
643
								GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
644 645
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_EXPAND,
Matthias Clasen's avatar
x  
Matthias Clasen committed
646
					      g_param_spec_boolean ("tab-expand", 
647
								    P_("Tab expand"), 
Matthias Clasen's avatar
Matthias Clasen committed
648
								    P_("Whether to expand the child's tab or not"),
Tim Janik's avatar
Tim Janik committed
649
								    TRUE,
650
								    GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
651 652
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_FILL,
Matthias Clasen's avatar
x  
Matthias Clasen committed
653
					      g_param_spec_boolean ("tab-fill", 
654
								    P_("Tab fill"), 
Matthias Clasen's avatar
Matthias Clasen committed
655
								    P_("Whether the child's tab should fill the allocated area or not"),
Tim Janik's avatar
Tim Janik committed
656
								    TRUE,
657
								    GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
658 659
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_PACK,
Matthias Clasen's avatar
x  
Matthias Clasen committed
660
					      g_param_spec_enum ("tab-pack", 
661 662
								 P_("Tab pack type"),
								 P_("A GtkPackType indicating whether the child is packed with reference to the start or end of the parent"),
663
								 GTK_TYPE_PACK_TYPE, GTK_PACK_START,
664
								 GTK_PARAM_READWRITE));
665 666 667 668 669 670 671 672 673 674 675 676 677 678
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_REORDERABLE,
					      g_param_spec_boolean ("reorderable",
								    P_("Tab reorderable"),
								    P_("Whether the tab is reorderable by user action or not"),
								    FALSE,
								    GTK_PARAM_READWRITE));
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_DETACHABLE,
					      g_param_spec_boolean ("detachable",
								    P_("Tab detachable"),
								    P_("Whether the tab is detachable"),
								    FALSE,
								    GTK_PARAM_READWRITE));
679 680 681 682 683 684 685 686 687 688

/**
 * GtkNotebook:has-secondary-backward-stepper:
 *
 * The "has-secondary-backward-stepper" property determines whether 
 * a second backward arrow button is displayed on the opposite end 
 * of the tab area.
 *
 * Since: 2.4
 */  
689
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
690
					   g_param_spec_boolean ("has-secondary-backward-stepper",
691 692
								 P_("Secondary backward stepper"),
								 P_("Display a second backward arrow button on the opposite end of the tab area"),
693
								 FALSE,
694
								 GTK_PARAM_READABLE));
695

696 697 698 699 700 701 702 703 704
/**
 * GtkNotebook:has-secondary-forward-stepper:
 *
 * The "has-secondary-forward-stepper" property determines whether 
 * a second forward arrow button is displayed on the opposite end 
 * of the tab area.
 *
 * Since: 2.4
 */  
705
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
706
					   g_param_spec_boolean ("has-secondary-forward-stepper",
707 708
								 P_("Secondary forward stepper"),
								 P_("Display a second forward arrow button on the opposite end of the tab area"),
709
								 FALSE,
710
								 GTK_PARAM_READABLE));
711

712 713 714 715 716 717 718 719
/**
 * GtkNotebook:has-backward-stepper:
 *
 * The "has-backward-stepper" property determines whether 
 * the standard backward arrow button is displayed.
 *
 * Since: 2.4
 */  
720
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
721
					   g_param_spec_boolean ("has-backward-stepper",
722 723
								 P_("Backward stepper"),
								 P_("Display the standard backward arrow button"),
724
								 TRUE,
725
								 GTK_PARAM_READABLE));
726

727 728 729 730 731 732 733 734
/**
 * GtkNotebook:has-forward-stepper:
 *
 * The "has-forward-stepper" property determines whether 
 * the standard forward arrow button is displayed.
 *
 * Since: 2.4
 */  
735
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
736
					   g_param_spec_boolean ("has-forward-stepper",
737 738
								 P_("Forward stepper"),
								 P_("Display the standard forward arrow button"),
739
								 TRUE,
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773
								 GTK_PARAM_READABLE));
  
/**
 * GtkNotebook:tab-overlap:
 *
 * The "tab-overlap" property defines size of tab overlap
 * area.
 *
 * Since: 2.10
 */  
  gtk_widget_class_install_style_property (widget_class,
					   g_param_spec_int ("tab-overlap",
							     P_("Tab overlap"),
							     P_("Size of tab overlap area"),
							     G_MININT,
							     G_MAXINT,
							     2,
							     GTK_PARAM_READABLE));

/**
 * GtkNotebook:tab-curvature:
 *
 * The "tab-curvature" property defines size of tab curvature.
 *
 * Since: 2.10
 */  
  gtk_widget_class_install_style_property (widget_class,
					   g_param_spec_int ("tab-curvature",
							     P_("Tab curvature"),
							     P_("Size of tab curvature"),
							     0,
							     G_MAXINT,
							     1,
							     GTK_PARAM_READABLE));
774

775
  notebook_signals[SWITCH_PAGE] =
Matthias Clasen's avatar
Matthias Clasen committed
776
    g_signal_new (I_("switch_page"),
Manish Singh's avatar
Manish Singh committed
777 778 779 780 781 782 783 784
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkNotebookClass, switch_page),
		  NULL, NULL,
		  _gtk_marshal_VOID__POINTER_UINT,
		  G_TYPE_NONE, 2,
		  G_TYPE_POINTER,
		  G_TYPE_UINT);
785
  notebook_signals[FOCUS_TAB] = 
Matthias Clasen's avatar
Matthias Clasen committed
786
    g_signal_new (I_("focus_tab"),
Manish Singh's avatar
Manish Singh committed
787
                  G_TYPE_FROM_CLASS (gobject_class),
788 789 790
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
                  NULL, NULL,
791
                  _gtk_marshal_BOOLEAN__ENUM,
792
                  G_TYPE_BOOLEAN, 1,
793
                  GTK_TYPE_NOTEBOOK_TAB);
794
  notebook_signals[SELECT_PAGE] = 
Matthias Clasen's avatar
Matthias Clasen committed
795
    g_signal_new (I_("select_page"),
Manish Singh's avatar
Manish Singh committed
796
                  G_TYPE_FROM_CLASS (gobject_class),
797 798 799
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, select_page),
                  NULL, NULL,
800 801
                  _gtk_marshal_BOOLEAN__BOOLEAN,
                  G_TYPE_BOOLEAN, 1,
802
                  G_TYPE_BOOLEAN);
803
  notebook_signals[CHANGE_CURRENT_PAGE] = 
Matthias Clasen's avatar
Matthias Clasen committed
804
    g_signal_new (I_("change_current_page"),
Manish Singh's avatar
Manish Singh committed
805
                  G_TYPE_FROM_CLASS (gobject_class),
806 807 808
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
                  NULL, NULL,
809 810
                  _gtk_marshal_VOID__INT,
                  G_TYPE_NONE, 1,
811
                  G_TYPE_INT);
812
  notebook_signals[MOVE_FOCUS_OUT] =
Matthias Clasen's avatar
Matthias Clasen committed
813
    g_signal_new (I_("move_focus_out"),
Manish Singh's avatar
Manish Singh committed
814
                  G_TYPE_FROM_CLASS (gobject_class),
815 816 817 818 819 820
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, move_focus_out),
                  NULL, NULL,
                  _gtk_marshal_VOID__ENUM,
                  G_TYPE_NONE, 1,
                  GTK_TYPE_DIRECTION_TYPE);
821 822 823 824 825 826 827 828 829 830 831
  notebook_signals[REORDER_TAB] =
    g_signal_new (I_("reorder_tab"),
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, reorder_tab),
                  NULL, NULL,
                  _gtk_marshal_VOID__ENUM_BOOLEAN,
                  G_TYPE_NONE, 2,
                  GTK_TYPE_DIRECTION_TYPE,
		  G_TYPE_BOOLEAN);
  /**
832
   * GtkNotebook::page-reordered:
833 834 835 836
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
837 838
   * the ::page-reordered signal is emitted in the notebook
   * right after a page has been reordered.
839 840 841
   *
   * Since: 2.10
   **/
842 843
  notebook_signals[PAGE_REORDERED] =
    g_signal_new (I_("page_reordered"),
844
                  G_TYPE_FROM_CLASS (gobject_class),
845
                  G_SIGNAL_RUN_LAST,
846
                  0, NULL, NULL,
847
		  _gtk_marshal_VOID__OBJECT_UINT,
848
                  G_TYPE_NONE, 2,
849
		  GTK_TYPE_WIDGET,
850 851
		  G_TYPE_UINT);
  /**
852
   * GtkNotebook::page-removed:
853 854 855 856
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the @child page number
   *
857
   * the ::page-removed signal is emitted in the notebook
858
   * right after a page is removed from the notebook.
859 860 861
   *
   * Since: 2.10
   **/
862 863
  notebook_signals[PAGE_REMOVED] =
    g_signal_new (I_("page_removed"),
864
                  G_TYPE_FROM_CLASS (gobject_class),
865
                  G_SIGNAL_RUN_LAST,
866
                  0, NULL, NULL,
867
		  _gtk_marshal_VOID__OBJECT_UINT,
868
                  G_TYPE_NONE, 2,
869
		  GTK_TYPE_WIDGET,
870 871
		  G_TYPE_UINT);
  /**
872
   * GtkNotebook::page-added:
873 874 875 876
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
877 878
   * the ::page-added signal is emitted in the notebook
   * right after a page is added to the notebook.
879 880 881
   *
   * Since: 2.10
   **/
882 883
  notebook_signals[PAGE_ADDED] =
    g_signal_new (I_("page_added"),
884
                  G_TYPE_FROM_CLASS (gobject_class),
885
                  G_SIGNAL_RUN_LAST,
886
                  0, NULL, NULL,
887
		  _gtk_marshal_VOID__OBJECT_UINT,
888
                  G_TYPE_NONE, 2,
889
		  GTK_TYPE_WIDGET,
890 891
		  G_TYPE_UINT);

Manish Singh's avatar
Manish Singh committed
892
  binding_set = gtk_binding_set_by_class (class);
893 894 895 896
  gtk_binding_entry_add_signal (binding_set,
                                GDK_space, 0,
                                "select_page", 1, 
                                G_TYPE_BOOLEAN, FALSE);
897 898 899 900 901
  gtk_binding_entry_add_signal (binding_set,
                                GDK_KP_Space, 0,
                                "select_page", 1, 
                                G_TYPE_BOOLEAN, FALSE);
  
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
  gtk_binding_entry_add_signal (binding_set,
                                GDK_Home, 0,
                                "focus_tab", 1, 
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_FIRST);
  gtk_binding_entry_add_signal (binding_set,
                                GDK_KP_Home, 0,
                                "focus_tab", 1, 
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_FIRST);
  gtk_binding_entry_add_signal (binding_set,
                                GDK_End, 0,
                                "focus_tab", 1, 
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_LAST);
  gtk_binding_entry_add_signal (binding_set,
                                GDK_KP_End, 0,
                                "focus_tab", 1, 
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_LAST);
918 919 920 921 922 923 924 925 926

  gtk_binding_entry_add_signal (binding_set,
                                GDK_Page_Up, GDK_CONTROL_MASK,