gtknotebook.c 230 KB
Newer Older
1
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
Cody Russell's avatar
Cody Russell committed
2
/* GTK - The GIMP Toolkit
Elliot Lee's avatar
Elliot Lee committed
3 4 5
 * 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"
29

30 31
#include "gtknotebook.h"

32
#include <stdio.h>
Johan Dahlin's avatar
Johan Dahlin committed
33
#include <string.h>
34 35 36

#include <gdk/gdkkeysyms.h>

37 38 39 40
#include "gtkmain.h"
#include "gtkmenu.h"
#include "gtkmenuitem.h"
#include "gtklabel.h"
41
#include "gtkintl.h"
42
#include "gtkmarshalers.h"
43
#include "gtkbindings.h"
44
#include "gtkprivate.h"
45
#include "gtkdnd.h"
Johan Dahlin's avatar
Johan Dahlin committed
46
#include "gtkbuildable.h"
47

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

/**
 * SECTION:gtknotebook
 * @Short_description: A tabbed notebook container
 * @Title: GtkNotebook
 * @See_also: #GtkContainer
 *
 * The #GtkNotebook widget is a #GtkContainer whose children are pages that
 * can be switched between using tab labels along one edge.
 *
 * There are many configuration options for GtkNotebook. Among other
 * things, you can choose on which edge the tabs appear
 * (see gtk_notebook_set_tab_pos()), whether, if there are too many
 * tabs to fit the notebook should be made bigger or scrolling
 * arrows added (see gtk_notebook_set_scrollable()), and whether there
 * will be a popup menu allowing the users to switch pages.
 * (see gtk_notebook_popup_enable(), gtk_notebook_popup_disable())
 *
 * <refsect2 id="GtkNotebook-BUILDER-UI">
 * <title>GtkNotebook as GtkBuildable</title>
 * <para>
 * The GtkNotebook implementation of the #GtkBuildable interface
 * supports placing children into tabs by specifying "tab" as the
 * "type" attribute of a &lt;child&gt; element. Note that the content
 * of the tab must be created before the tab can be filled.
 * A tab child can be specified without specifying a &lt;child&gt;
 * type attribute.
75
 *
76 77 78
 * To add a child widget in the notebooks action area, specify
 * "action-start" or "action-end" as the "type" attribute of the &lt;child&gt;
 * element.
79
 * </para>
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
 * <example>
 * <title>A UI definition fragment with GtkNotebook</title>
 * <programlisting><![CDATA[
 * <object class="GtkNotebook">
 *   <child>
 *     <object class="GtkLabel" id="notebook-content">
 *       <property name="label">Content</property>
 *     </object>
 *   </child>
 *   <child type="tab">
 *     <object class="GtkLabel" id="notebook-tab">
 *       <property name="label">Tab</property>
 *     </object>
 *   </child>
 * </object>
 * ]]></programlisting>
 * </example>
 * </refsect2>
 */


101
#define SCROLL_DELAY_FACTOR   5
102 103
#define SCROLL_THRESHOLD      12
#define DND_THRESHOLD_MULTIPLIER 4
104 105
#define FRAMES_PER_SECOND     45
#define MSECS_BETWEEN_UPDATES (1000 / FRAMES_PER_SECOND)
Elliot Lee's avatar
Elliot Lee committed
106

107
typedef struct _GtkNotebookPage GtkNotebookPage;
108 109 110 111 112 113 114 115 116 117 118 119 120 121

typedef enum
{
  DRAG_OPERATION_NONE,
  DRAG_OPERATION_REORDER,
  DRAG_OPERATION_DETACH
} GtkNotebookDragOperation;

enum {
  ACTION_WIDGET_START,
  ACTION_WIDGET_END,
  N_ACTION_WIDGETS
};

122
struct _GtkNotebookPrivate
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
{
  GtkNotebookDragOperation   operation;
  GtkNotebookPage           *cur_page;
  GtkNotebookPage           *detached_tab;
  GtkTargetList             *source_targets;
  GtkWidget                 *action_widget[N_ACTION_WIDGETS];
  GtkWidget                 *dnd_window;
  GtkWidget                 *menu;

  GdkWindow               *drag_window;
  GdkWindow               *event_window;

  GList         *children;
  GList         *first_tab;             /* The first tab visible (for scrolling notebooks) */
  GList         *focus_tab;

  gint           drag_begin_x;
  gint           drag_begin_y;
  gint           drag_offset_x;
  gint           drag_offset_y;
  gint           drag_window_x;
  gint           drag_window_y;
  gint           mouse_x;
  gint           mouse_y;
  gint           pressed_button;

149
  GQuark         group;
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181

  guint          dnd_timer;
  guint          switch_tab_timer;

  guint16        tab_hborder;
  guint16        tab_vborder;

  guint32        timer;
  guint32        timestamp;

  guint          button             : 2;
  guint          child_has_focus    : 1;
  guint          click_child        : 3;
  guint          during_detach      : 1;
  guint          during_reorder     : 1;
  guint          focus_out          : 1; /* Flag used by ::move-focus-out implementation */
  guint          has_scrolled       : 1;
  guint          have_visible_child : 1;
  guint          homogeneous        : 1;
  guint          in_child           : 3;
  guint          need_timer         : 1;
  guint          show_border        : 1;
  guint          show_tabs          : 1;
  guint          scrollable         : 1;
  guint          tab_pos            : 2;

  guint          has_before_previous : 1;
  guint          has_before_next     : 1;
  guint          has_after_previous  : 1;
  guint          has_after_next      : 1;
};

182 183
enum {
  SWITCH_PAGE,
184 185
  FOCUS_TAB,
  SELECT_PAGE,
186
  CHANGE_CURRENT_PAGE,
187
  MOVE_FOCUS_OUT,
188
  REORDER_TAB,
189 190 191
  PAGE_REORDERED,
  PAGE_REMOVED,
  PAGE_ADDED,
192
  CREATE_WINDOW,
193 194 195
  LAST_SIGNAL
};

196 197 198 199 200
enum {
  STEP_PREV,
  STEP_NEXT
};

201 202 203 204 205 206 207 208 209
typedef enum
{
  ARROW_NONE,
  ARROW_LEFT_BEFORE,
  ARROW_RIGHT_BEFORE,
  ARROW_LEFT_AFTER,
  ARROW_RIGHT_AFTER
} GtkNotebookArrow;

210 211 212 213 214 215 216
typedef enum
{
  POINTER_BEFORE,
  POINTER_AFTER,
  POINTER_BETWEEN
} GtkNotebookPointerPosition;

217 218 219
#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)

220
enum {
221 222 223 224 225 226 227
  PROP_0,
  PROP_TAB_POS,
  PROP_SHOW_TABS,
  PROP_SHOW_BORDER,
  PROP_SCROLLABLE,
  PROP_PAGE,
  PROP_ENABLE_POPUP,
228
  PROP_GROUP_NAME
229 230 231
};

enum {
Tim Janik's avatar
Tim Janik committed
232 233 234 235 236 237
  CHILD_PROP_0,
  CHILD_PROP_TAB_LABEL,
  CHILD_PROP_MENU_LABEL,
  CHILD_PROP_POSITION,
  CHILD_PROP_TAB_EXPAND,
  CHILD_PROP_TAB_FILL,
238 239 240
  CHILD_PROP_TAB_PACK,
  CHILD_PROP_REORDERABLE,
  CHILD_PROP_DETACHABLE
241 242
};

243 244
#define GTK_NOTEBOOK_PAGE(_glist_)         ((GtkNotebookPage *)((GList *)(_glist_))->data)

245 246 247 248 249 250 251
/* 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)
252
#define NOTEBOOK_IS_TAB_LABEL_PARENT(_notebook_,_page_) (gtk_widget_get_parent (((GtkNotebookPage *) (_page_))->tab_label) == ((GtkWidget *) (_notebook_)))
253

254 255 256 257 258
struct _GtkNotebookPage
{
  GtkWidget *child;
  GtkWidget *tab_label;
  GtkWidget *menu_label;
259
  GtkWidget *last_focus_child;	/* Last descendant of the page that had focus */
260 261 262 263 264 265

  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;
266 267
  guint reorderable  : 1;
  guint detachable   : 1;
268

269 270 271 272 273
  /* if true, the tab label was visible on last allocation; we track this so
   * that we know to redraw the tab area if a tab label was hidden then shown
   * without changing position */
  guint tab_allocated_visible : 1;

274 275
  GtkRequisition requisition;
  GtkAllocation allocation;
276

277 278
  gulong mnemonic_activate_signal;
  gulong notify_visible_handler;
279 280
};

281
static const GtkTargetEntry notebook_targets [] = {
282
  { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, 0 },
283 284
};

285 286
#ifdef G_DISABLE_CHECKS
#define CHECK_FIND_CHILD(notebook, child)                           \
287
 gtk_notebook_find_child (notebook, child, G_STRLOC)
288 289
#else
#define CHECK_FIND_CHILD(notebook, child)                           \
290
 gtk_notebook_find_child (notebook, child, NULL)
291 292
#endif
 
293
/*** GtkNotebook Methods ***/
294 295 296 297
static gboolean gtk_notebook_select_page         (GtkNotebook      *notebook,
						  gboolean          move_focus);
static gboolean gtk_notebook_focus_tab           (GtkNotebook      *notebook,
						  GtkNotebookTab    type);
298
static gboolean gtk_notebook_change_current_page (GtkNotebook      *notebook,
299 300 301
						  gint              offset);
static void     gtk_notebook_move_focus_out      (GtkNotebook      *notebook,
						  GtkDirectionType  direction_type);
302
static gboolean gtk_notebook_reorder_tab         (GtkNotebook      *notebook,
303 304
						  GtkDirectionType  direction_type,
						  gboolean          move_to_last);
305 306
static void     gtk_notebook_remove_tab_label    (GtkNotebook      *notebook,
						  GtkNotebookPage  *page);
307 308 309 310 311 312 313 314 315 316
static void     gtk_notebook_set_tab_label_packing   (GtkNotebook  *notebook,
                                                      GtkWidget    *child,
                                                      gboolean      expand,
                                                      gboolean      fill,
                                                      GtkPackType   pack_type);
static void     gtk_notebook_query_tab_label_packing (GtkNotebook  *notebook,
                                                      GtkWidget    *child,
                                                      gboolean     *expand,
                                                      gboolean     *fill,
                                                      GtkPackType  *pack_type);
317

318
/*** GObject Methods ***/
319 320 321 322 323 324 325 326
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);
327

328
/*** GtkWidget Methods ***/
329
static void gtk_notebook_destroy             (GtkWidget        *widget);
330 331 332
static void gtk_notebook_map                 (GtkWidget        *widget);
static void gtk_notebook_unmap               (GtkWidget        *widget);
static void gtk_notebook_realize             (GtkWidget        *widget);
333
static void gtk_notebook_unrealize           (GtkWidget        *widget);
334 335
static void gtk_notebook_size_request        (GtkWidget        *widget,
					      GtkRequisition   *requisition);
336 337 338 339 340 341
static void gtk_notebook_get_preferred_width (GtkWidget        *widget,
					      gint             *minimum,
					      gint             *natural);
static void gtk_notebook_get_preferred_height(GtkWidget        *widget,
					      gint             *minimum,
					      gint             *natural);
342 343
static void gtk_notebook_size_allocate       (GtkWidget        *widget,
					      GtkAllocation    *allocation);
Benjamin Otte's avatar
Benjamin Otte committed
344 345
static gint gtk_notebook_draw                (GtkWidget        *widget,
                                              cairo_t          *cr);
346 347 348 349
static gint gtk_notebook_button_press        (GtkWidget        *widget,
					      GdkEventButton   *event);
static gint gtk_notebook_button_release      (GtkWidget        *widget,
					      GdkEventButton   *event);
350
static gboolean gtk_notebook_popup_menu      (GtkWidget        *widget);
351 352 353 354
static gint gtk_notebook_leave_notify        (GtkWidget        *widget,
					      GdkEventCrossing *event);
static gint gtk_notebook_motion_notify       (GtkWidget        *widget,
					      GdkEventMotion   *event);
355 356
static gint gtk_notebook_focus_in            (GtkWidget        *widget,
					      GdkEventFocus    *event);
357 358
static gint gtk_notebook_focus_out           (GtkWidget        *widget,
					      GdkEventFocus    *event);
Matthias Clasen's avatar
Matthias Clasen committed
359 360
static void gtk_notebook_grab_notify         (GtkWidget          *widget,
					      gboolean            was_grabbed);
361 362
static void gtk_notebook_state_flags_changed (GtkWidget          *widget,
					      GtkStateFlags       previous_state);
363 364
static gint gtk_notebook_focus               (GtkWidget        *widget,
					      GtkDirectionType  direction);
365
static void gtk_notebook_style_updated       (GtkWidget        *widget);
366

367 368 369
/*** Drag and drop Methods ***/
static void gtk_notebook_drag_begin          (GtkWidget        *widget,
					      GdkDragContext   *context);
370 371
static void gtk_notebook_drag_end            (GtkWidget        *widget,
					      GdkDragContext   *context);
372 373
static gboolean gtk_notebook_drag_failed     (GtkWidget        *widget,
					      GdkDragContext   *context,
374
					      GtkDragResult     result);
375 376 377 378 379
static gboolean gtk_notebook_drag_motion     (GtkWidget        *widget,
					      GdkDragContext   *context,
					      gint              x,
					      gint              y,
					      guint             time);
380 381 382
static void gtk_notebook_drag_leave          (GtkWidget        *widget,
					      GdkDragContext   *context,
					      guint             time);
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
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);

401
/*** GtkContainer Methods ***/
Tim Janik's avatar
Tim Janik committed
402
static void gtk_notebook_set_child_property  (GtkContainer     *container,
403
					      GtkWidget        *child,
Tim Janik's avatar
Tim Janik committed
404 405 406 407
					      guint             property_id,
					      const GValue     *value,
					      GParamSpec       *pspec);
static void gtk_notebook_get_child_property  (GtkContainer     *container,
408
					      GtkWidget        *child,
Tim Janik's avatar
Tim Janik committed
409 410 411
					      guint             property_id,
					      GValue           *value,
					      GParamSpec       *pspec);
412 413 414 415
static void gtk_notebook_add                 (GtkContainer     *container,
					      GtkWidget        *widget);
static void gtk_notebook_remove              (GtkContainer     *container,
					      GtkWidget        *widget);
416 417
static void gtk_notebook_set_focus_child     (GtkContainer     *container,
					      GtkWidget        *child);
Manish Singh's avatar
Manish Singh committed
418
static GType gtk_notebook_child_type       (GtkContainer     *container);
419 420
static void gtk_notebook_forall              (GtkContainer     *container,
					      gboolean		include_internals,
421 422
					      GtkCallback       callback,
					      gpointer          callback_data);
423 424
static GtkWidgetPath * gtk_notebook_get_path_for_child (GtkContainer *container,
                                                        GtkWidget    *widget);
425

426 427 428 429 430 431 432
/*** GtkNotebook Methods ***/
static gint gtk_notebook_real_insert_page    (GtkNotebook      *notebook,
					      GtkWidget        *child,
					      GtkWidget        *tab_label,
					      GtkWidget        *menu_label,
					      gint              position);

433 434 435 436 437
static GtkNotebook *gtk_notebook_create_window (GtkNotebook    *notebook,
                                                GtkWidget      *page,
                                                gint            x,
                                                gint            y);

438
/*** GtkNotebook Private Functions ***/
439 440
static void gtk_notebook_redraw_tabs         (GtkNotebook      *notebook);
static void gtk_notebook_redraw_arrows       (GtkNotebook      *notebook);
441
static void gtk_notebook_real_remove         (GtkNotebook      *notebook,
442
					      GList            *list);
443 444
static void gtk_notebook_update_labels       (GtkNotebook      *notebook);
static gint gtk_notebook_timer               (GtkNotebook      *notebook);
445
static void gtk_notebook_set_scroll_timer    (GtkNotebook *notebook);
446 447
static gint gtk_notebook_page_compare        (gconstpointer     a,
					      gconstpointer     b);
448
static GList* gtk_notebook_find_child        (GtkNotebook      *notebook,
449 450
					      GtkWidget        *child,
					      const gchar      *function);
451 452 453 454 455 456
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);
457 458
static void  gtk_notebook_child_reordered    (GtkNotebook      *notebook,
			                      GtkNotebookPage  *page);
459

460
/*** GtkNotebook Drawing Functions ***/
461
static void gtk_notebook_paint               (GtkWidget        *widget,
Benjamin Otte's avatar
Benjamin Otte committed
462
					      cairo_t          *cr);
463 464
static void gtk_notebook_draw_tab            (GtkNotebook      *notebook,
					      GtkNotebookPage  *page,
465
					      cairo_t          *cr,
466
                                              GtkRegionFlags    flags);
467
static void gtk_notebook_draw_arrow          (GtkNotebook      *notebook,
468
                                              cairo_t          *cr,
469
					      GtkNotebookArrow  arrow);
470

471
/*** GtkNotebook Size Allocate Functions ***/
472
static void gtk_notebook_pages_allocate      (GtkNotebook      *notebook);
473
static gboolean gtk_notebook_page_allocate   (GtkNotebook      *notebook,
Matthias Clasen's avatar
Matthias Clasen committed
474
					      GtkNotebookPage  *page);
475 476
static void gtk_notebook_calc_tabs           (GtkNotebook      *notebook,
			                      GList            *start,
477 478 479
					      GList           **end,
					      gint             *tab_space,
					      guint             direction);
480

481
/*** GtkNotebook Page Switch Methods ***/
482
static void gtk_notebook_real_switch_page    (GtkNotebook      *notebook,
483
					      GtkWidget        *child,
484
					      guint             page_num);
485

486
/*** GtkNotebook Page Switch Functions ***/
487
static void gtk_notebook_switch_page         (GtkNotebook      *notebook,
488
					      GtkNotebookPage  *page);
489 490
static gint gtk_notebook_page_select         (GtkNotebook      *notebook,
					      gboolean          move_focus);
491 492
static void gtk_notebook_switch_focus_tab    (GtkNotebook      *notebook,
                                              GList            *new_child);
493 494
static void gtk_notebook_menu_switch_page    (GtkWidget        *widget,
					      GtkNotebookPage  *page);
495

496
/*** GtkNotebook Menu Functions ***/
497 498 499 500
static void gtk_notebook_menu_item_create    (GtkNotebook      *notebook,
					      GList            *list);
static void gtk_notebook_menu_label_unparent (GtkWidget        *widget,
					      gpointer          data);
501 502
static void gtk_notebook_menu_detacher       (GtkWidget        *widget,
					      GtkMenu          *menu);
503

504
/*** GtkNotebook Private Setters ***/
505 506 507 508 509
static void gtk_notebook_update_tab_states             (GtkNotebook *notebook);
static gboolean gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child,
							    gboolean overload,
							    gpointer data);

510 511 512
static gboolean focus_tabs_in  (GtkNotebook      *notebook);
static gboolean focus_child_in (GtkNotebook      *notebook,
				GtkDirectionType  direction);
Elliot Lee's avatar
Elliot Lee committed
513

514
static void stop_scrolling (GtkNotebook *notebook);
515 516 517 518 519
static void do_detach_tab  (GtkNotebook *from,
			    GtkNotebook *to,
			    GtkWidget   *child,
			    gint         x,
			    gint         y);
520

Johan Dahlin's avatar
Johan Dahlin committed
521 522
/* GtkBuildable */
static void gtk_notebook_buildable_init           (GtkBuildableIface *iface);
523
static void gtk_notebook_buildable_add_child      (GtkBuildable *buildable,
Johan Dahlin's avatar
Johan Dahlin committed
524 525 526
						   GtkBuilder   *builder,
						   GObject      *child,
						   const gchar  *type);
527

528
static guint notebook_signals[LAST_SIGNAL] = { 0 };
Elliot Lee's avatar
Elliot Lee committed
529

Johan Dahlin's avatar
Johan Dahlin committed
530 531 532
G_DEFINE_TYPE_WITH_CODE (GtkNotebook, gtk_notebook, GTK_TYPE_CONTAINER,
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
						gtk_notebook_buildable_init))
Elliot Lee's avatar
Elliot Lee committed
533

534 535 536 537 538
static void
add_tab_bindings (GtkBindingSet    *binding_set,
		  GdkModifierType   modifiers,
		  GtkDirectionType  direction)
{
539
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
540 541
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
542
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
543 544 545 546 547 548 549 550 551
                                "move_focus_out", 1,
                                GTK_TYPE_DIRECTION_TYPE, direction);
}

static void
add_arrow_bindings (GtkBindingSet    *binding_set,
		    guint             keysym,
		    GtkDirectionType  direction)
{
552
  guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
553 554 555 556 557 558 559 560 561
  
  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);
}

562 563 564 565 566 567
static void
add_reorder_bindings (GtkBindingSet    *binding_set,
		      guint             keysym,
		      GtkDirectionType  direction,
		      gboolean          move_to_last)
{
568
  guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
569 570 571 572 573 574 575 576 577 578 579

  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);
}

580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
static gboolean
gtk_object_handled_accumulator (GSignalInvocationHint *ihint,
                                GValue                *return_accu,
                                const GValue          *handler_return,
                                gpointer               dummy)
{
  gboolean continue_emission;
  GObject *object;

  object = g_value_get_object (handler_return);
  g_value_set_object (return_accu, object);
  continue_emission = !object;

  return continue_emission;
}

596
static void
597 598 599
gtk_notebook_compute_expand (GtkWidget *widget,
                             gboolean  *hexpand_p,
                             gboolean  *vexpand_p)
600
{
601
  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
  GtkNotebookPrivate *priv = notebook->priv;
  gboolean hexpand;
  gboolean vexpand;
  GList *list;
  GtkNotebookPage *page;

  hexpand = FALSE;
  vexpand = FALSE;

  for (list = priv->children; list; list = list->next)
    {
      page = list->data;

      hexpand = hexpand ||
        gtk_widget_compute_expand (page->child, GTK_ORIENTATION_HORIZONTAL);

      vexpand = vexpand ||
        gtk_widget_compute_expand (page->child, GTK_ORIENTATION_VERTICAL);

      if (hexpand & vexpand)
        break;
    }

  *hexpand_p = hexpand;
  *vexpand_p = vexpand;
}

Elliot Lee's avatar
Elliot Lee committed
629 630 631
static void
gtk_notebook_class_init (GtkNotebookClass *class)
{
Tim Janik's avatar
Tim Janik committed
632 633 634
  GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
635 636
  GtkBindingSet *binding_set;
  
637 638
  gobject_class->set_property = gtk_notebook_set_property;
  gobject_class->get_property = gtk_notebook_get_property;
639

640
  widget_class->destroy = gtk_notebook_destroy;
Elliot Lee's avatar
Elliot Lee committed
641 642 643
  widget_class->map = gtk_notebook_map;
  widget_class->unmap = gtk_notebook_unmap;
  widget_class->realize = gtk_notebook_realize;
644
  widget_class->unrealize = gtk_notebook_unrealize;
645 646
  widget_class->get_preferred_width = gtk_notebook_get_preferred_width;
  widget_class->get_preferred_height = gtk_notebook_get_preferred_height;
Elliot Lee's avatar
Elliot Lee committed
647
  widget_class->size_allocate = gtk_notebook_size_allocate;
Benjamin Otte's avatar
Benjamin Otte committed
648
  widget_class->draw = gtk_notebook_draw;
Elliot Lee's avatar
Elliot Lee committed
649
  widget_class->button_press_event = gtk_notebook_button_press;
650
  widget_class->button_release_event = gtk_notebook_button_release;
651
  widget_class->popup_menu = gtk_notebook_popup_menu;
652 653
  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
654
  widget_class->grab_notify = gtk_notebook_grab_notify;
655
  widget_class->state_flags_changed = gtk_notebook_state_flags_changed;
656
  widget_class->focus_in_event = gtk_notebook_focus_in;
657
  widget_class->focus_out_event = gtk_notebook_focus_out;
658
  widget_class->focus = gtk_notebook_focus;
659
  widget_class->style_updated = gtk_notebook_style_updated;
660
  widget_class->drag_begin = gtk_notebook_drag_begin;
661
  widget_class->drag_end = gtk_notebook_drag_end;
662
  widget_class->drag_motion = gtk_notebook_drag_motion;
663
  widget_class->drag_leave = gtk_notebook_drag_leave;
664 665 666
  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;
667
  widget_class->drag_failed = gtk_notebook_drag_failed;
668
  widget_class->compute_expand = gtk_notebook_compute_expand;
669

Elliot Lee's avatar
Elliot Lee committed
670 671
  container_class->add = gtk_notebook_add;
  container_class->remove = gtk_notebook_remove;
672
  container_class->forall = gtk_notebook_forall;
Lars Hamann's avatar
Lars Hamann committed
673
  container_class->set_focus_child = gtk_notebook_set_focus_child;
Tim Janik's avatar
Tim Janik committed
674 675
  container_class->get_child_property = gtk_notebook_get_child_property;
  container_class->set_child_property = gtk_notebook_set_child_property;
676
  container_class->child_type = gtk_notebook_child_type;
677
  container_class->get_path_for_child = gtk_notebook_get_path_for_child;
678

679
  class->switch_page = gtk_notebook_real_switch_page;
680
  class->insert_page = gtk_notebook_real_insert_page;
681

682 683
  class->focus_tab = gtk_notebook_focus_tab;
  class->select_page = gtk_notebook_select_page;
684
  class->change_current_page = gtk_notebook_change_current_page;
685
  class->move_focus_out = gtk_notebook_move_focus_out;
686
  class->reorder_tab = gtk_notebook_reorder_tab;
687
  class->create_window = gtk_notebook_create_window;
688
  
689 690 691
  g_object_class_install_property (gobject_class,
				   PROP_PAGE,
				   g_param_spec_int ("page",
692 693
 						     P_("Page"),
 						     P_("The index of the current page"),
694
 						     -1,
695
 						     G_MAXINT,
696
 						     -1,
697
 						     GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
698 699
  g_object_class_install_property (gobject_class,
				   PROP_TAB_POS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
700
				   g_param_spec_enum ("tab-pos",
701 702
 						      P_("Tab Position"),
 						      P_("Which side of the notebook holds the tabs"),
703 704
 						      GTK_TYPE_POSITION_TYPE,
 						      GTK_POS_TOP,
705
 						      GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
706 707
  g_object_class_install_property (gobject_class,
				   PROP_SHOW_TABS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
708
				   g_param_spec_boolean ("show-tabs",
709
 							 P_("Show Tabs"),
710
							 P_("Whether tabs should be shown"),
711
 							 TRUE,
712
 							 GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
713 714
  g_object_class_install_property (gobject_class,
				   PROP_SHOW_BORDER,
Matthias Clasen's avatar
x  
Matthias Clasen committed
715
				   g_param_spec_boolean ("show-border",
716
 							 P_("Show Border"),
717
							 P_("Whether the border should be shown"),
718
 							 TRUE,
719
 							 GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
720 721 722
  g_object_class_install_property (gobject_class,
				   PROP_SCROLLABLE,
				   g_param_spec_boolean ("scrollable",
723 724
 							 P_("Scrollable"),
 							 P_("If TRUE, scroll arrows are added if there are too many tabs to fit"),
725
 							 FALSE,
726
 							 GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
727 728
  g_object_class_install_property (gobject_class,
				   PROP_ENABLE_POPUP,
Matthias Clasen's avatar
x  
Matthias Clasen committed
729
				   g_param_spec_boolean ("enable-popup",
730 731
 							 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"),
732
 							 FALSE,
733
 							 GTK_PARAM_READWRITE));
Matthias Clasen's avatar
Matthias Clasen committed
734 735

  /**
736
   * GtkNotebook:group-name:
Matthias Clasen's avatar
Matthias Clasen committed
737
   *
738
   * Group name for tab drag and drop.
Matthias Clasen's avatar
Matthias Clasen committed
739 740
   *
   * Since: 2.24
741
   */
742
  g_object_class_install_property (gobject_class,
743 744 745 746 747 748
				   PROP_GROUP_NAME,
				   g_param_spec_string ("group-name",
							P_("Group Name"),
							P_("Group name for tab drag and drop"),
                                                        NULL,
							GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
749 750 751

  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_LABEL,
Matthias Clasen's avatar
x  
Matthias Clasen committed
752
					      g_param_spec_string ("tab-label", 
753
								   P_("Tab label"),
Matthias Clasen's avatar
Matthias Clasen committed
754
								   P_("The string displayed on the child's tab label"),
Tim Janik's avatar
Tim Janik committed
755
								   NULL,
756
								   GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
757 758
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_MENU_LABEL,
Matthias Clasen's avatar
x  
Matthias Clasen committed
759
					      g_param_spec_string ("menu-label", 
760
								   P_("Menu label"), 
Matthias Clasen's avatar
Matthias Clasen committed
761
								   P_("The string displayed in the child's menu entry"),
Tim Janik's avatar
Tim Janik committed
762
								   NULL,
763
								   GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
764 765
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_POSITION,
766
					      g_param_spec_int ("position", 
767 768
								P_("Position"), 
								P_("The index of the child in the parent"),
Tim Janik's avatar
Tim Janik committed
769
								-1, G_MAXINT, 0,
770
								GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
771 772
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_EXPAND,
Matthias Clasen's avatar
x  
Matthias Clasen committed
773
					      g_param_spec_boolean ("tab-expand", 
774
								    P_("Tab expand"), 
775
								    P_("Whether to expand the child's tab"),
776
								    FALSE,
777
								    GTK_PARAM_READWRITE));
Tim Janik's avatar
Tim Janik committed
778 779
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_FILL,
Matthias Clasen's avatar
x  
Matthias Clasen committed
780
					      g_param_spec_boolean ("tab-fill", 
781
								    P_("Tab fill"), 
782
								    P_("Whether the child's tab should fill the allocated area"),
Tim Janik's avatar
Tim Janik committed
783
								    TRUE,
784
								    GTK_PARAM_READWRITE));
785 786 787 788 789 790 791

  /**
   * GtkNotebook:tab-pack:
   *
   *  Deprecated: 2.20: The tab packing functionality of children should not
   *  be used anymore and support will be removed in the future.
   */
Tim Janik's avatar
Tim Janik committed
792 793
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_TAB_PACK,
Matthias Clasen's avatar
x  
Matthias Clasen committed
794
					      g_param_spec_enum ("tab-pack", 
795 796
								 P_("Tab pack type"),
								 P_("A GtkPackType indicating whether the child is packed with reference to the start or end of the parent"),
797
								 GTK_TYPE_PACK_TYPE, GTK_PACK_START,
798
								 GTK_PARAM_READWRITE));
799 800 801 802
  gtk_container_class_install_child_property (container_class,
					      CHILD_PROP_REORDERABLE,
					      g_param_spec_boolean ("reorderable",
								    P_("Tab reorderable"),
803
								    P_("Whether the tab is reorderable by user action"),
804 805 806 807 808 809 810 811 812
								    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));
813 814 815 816 817 818 819 820 821 822

/**
 * 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
 */  
823
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
824
					   g_param_spec_boolean ("has-secondary-backward-stepper",
825 826
								 P_("Secondary backward stepper"),
								 P_("Display a second backward arrow button on the opposite end of the tab area"),
827
								 FALSE,
828
								 GTK_PARAM_READABLE));
829

830 831 832 833 834 835 836 837 838
/**
 * 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
 */  
839
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
840
					   g_param_spec_boolean ("has-secondary-forward-stepper",
841 842
								 P_("Secondary forward stepper"),
								 P_("Display a second forward arrow button on the opposite end of the tab area"),
843
								 FALSE,
844
								 GTK_PARAM_READABLE));
845

846 847 848 849 850 851 852 853
/**
 * GtkNotebook:has-backward-stepper:
 *
 * The "has-backward-stepper" property determines whether 
 * the standard backward arrow button is displayed.
 *
 * Since: 2.4
 */  
854
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
855
					   g_param_spec_boolean ("has-backward-stepper",
856 857
								 P_("Backward stepper"),
								 P_("Display the standard backward arrow button"),
858
								 TRUE,
859
								 GTK_PARAM_READABLE));
860

861 862 863 864 865 866 867 868
/**
 * GtkNotebook:has-forward-stepper:
 *
 * The "has-forward-stepper" property determines whether 
 * the standard forward arrow button is displayed.
 *
 * Since: 2.4
 */  
869
  gtk_widget_class_install_style_property (widget_class,
Matthias Clasen's avatar
x  
Matthias Clasen committed
870
					   g_param_spec_boolean ("has-forward-stepper",
871 872
								 P_("Forward stepper"),
								 P_("Display the standard forward arrow button"),
873
								 TRUE,
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
								 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));
908

909 910 911
  /**
   * GtkNotebook:arrow-spacing:
   *
912
   * The "arrow-spacing" property defines the spacing between the scroll
913 914 915 916 917 918
   * arrows and the tabs.
   *
   * Since: 2.10
   */
  gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("arrow-spacing",
919 920
                                                             P_("Arrow spacing"),
                                                             P_("Scroll arrow spacing"),
921 922 923 924 925
                                                             0,
                                                             G_MAXINT,
                                                             0,
                                                             GTK_PARAM_READABLE));

926 927 928 929 930 931 932 933
  /**
   * GtkNotebook::switch-page:
   * @notebook: the object which received the signal.
   * @page: the new current page
   * @page_num: the index of the page
   *
   * Emitted when the user or a function changes the current page.
   */
934
  notebook_signals[SWITCH_PAGE] =
935
    g_signal_new (I_("switch-page"),
Manish Singh's avatar
Manish Singh committed
936 937 938 939
		  G_TYPE_FROM_CLASS (gobject_class),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkNotebookClass, switch_page),
		  NULL, NULL,
940
		  _gtk_marshal_VOID__OBJECT_UINT,
Manish Singh's avatar
Manish Singh committed
941
		  G_TYPE_NONE, 2,
942
		  GTK_TYPE_WIDGET,
Manish Singh's avatar
Manish Singh committed
943
		  G_TYPE_UINT);
944
  notebook_signals[FOCUS_TAB] = 
945
    g_signal_new (I_("focus-tab"),
Manish Singh's avatar
Manish Singh committed
946
                  G_TYPE_FROM_CLASS (gobject_class),
947 948 949
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
                  NULL, NULL,
950
                  _gtk_marshal_BOOLEAN__ENUM,
951
                  G_TYPE_BOOLEAN, 1,
952
                  GTK_TYPE_NOTEBOOK_TAB);
953
  notebook_signals[SELECT_PAGE] = 
954
    g_signal_new (I_("select-page"),
Manish Singh's avatar
Manish Singh committed
955
                  G_TYPE_FROM_CLASS (gobject_class),
956 957 958
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, select_page),
                  NULL, NULL,
959 960
                  _gtk_marshal_BOOLEAN__BOOLEAN,
                  G_TYPE_BOOLEAN, 1,
961
                  G_TYPE_BOOLEAN);
962
  notebook_signals[CHANGE_CURRENT_PAGE] = 
963
    g_signal_new (I_("change-current-page"),
Manish Singh's avatar
Manish Singh committed
964
                  G_TYPE_FROM_CLASS (gobject_class),
965 966 967
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
                  NULL, NULL,
968 969
                  _gtk_marshal_BOOLEAN__INT,
                  G_TYPE_BOOLEAN, 1,
970
                  G_TYPE_INT);
971
  notebook_signals[MOVE_FOCUS_OUT] =
972
    g_signal_new (I_("move-focus-out"),
Manish Singh's avatar
Manish Singh committed
973
                  G_TYPE_FROM_CLASS (gobject_class),
974 975 976 977 978 979
                  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);
980
  notebook_signals[REORDER_TAB] =
981
    g_signal_new (I_("reorder-tab"),
982 983 984 985
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkNotebookClass, reorder_tab),
                  NULL, NULL,
986 987
                  _gtk_marshal_BOOLEAN__ENUM_BOOLEAN,
                  G_TYPE_BOOLEAN, 2,
988 989 990
                  GTK_TYPE_DIRECTION_TYPE,
		  G_TYPE_BOOLEAN);
  /**
991
   * GtkNotebook::page-reordered:
992 993 994 995
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
996 997
   * the ::page-reordered signal is emitted in the notebook
   * right after a page has been reordered.
998 999 1000
   *
   * Since: 2.10
   **/
1001
  notebook_signals[PAGE_REORDERED] =
1002
    g_signal_new (I_("page-reordered"),
1003
                  G_TYPE_FROM_CLASS (gobject_class),
1004
                  G_SIGNAL_RUN_LAST,
1005 1006 1007
                  G_STRUCT_OFFSET (GtkNotebookClass, page_reordered),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1008
                  G_TYPE_NONE, 2,
1009 1010
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1011
  /**
1012
   * GtkNotebook::page-removed:
1013 1014 1015 1016
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the @child page number
   *
1017
   * the ::page-removed signal is emitted in the notebook
1018
   * right after a page is removed from the notebook.
1019 1020 1021
   *
   * Since: 2.10
   **/
1022
  notebook_signals[PAGE_REMOVED] =
1023
    g_signal_new (I_("page-removed"),
1024
                  G_TYPE_FROM_CLASS (gobject_class),
1025
                  G_SIGNAL_RUN_LAST,
1026 1027 1028
                  G_STRUCT_OFFSET (GtkNotebookClass, page_removed),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1029
                  G_TYPE_NONE, 2,
1030 1031
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1032
  /**
1033
   * GtkNotebook::page-added:
1034 1035 1036 1037
   * @notebook: the #GtkNotebook
   * @child: the child #GtkWidget affected
   * @page_num: the new page number for @child
   *
1038 1039
   * the ::page-added signal is emitted in the notebook
   * right after a page is added to the notebook.
1040 1041 1042
   *
   * Since: 2.10
   **/
1043
  notebook_signals[PAGE_ADDED] =
1044
    g_signal_new (I_("page-added"),
1045
                  G_TYPE_FROM_CLASS (gobject_class),
1046
                  G_SIGNAL_RUN_LAST,
1047 1048 1049
                  G_STRUCT_OFFSET (GtkNotebookClass, page_added),
                  NULL, NULL,
                  _gtk_marshal_VOID__OBJECT_UINT,
1050
                  G_TYPE_NONE, 2,
1051 1052
                  GTK_TYPE_WIDGET,
                  G_TYPE_UINT);
1053

1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
  /**
   * GtkNotebook::create-window:
   * @notebook: the #GtkNotebook emitting the signal
   * @page: the tab of @notebook that is being detached
   * @x: the X coordinate where the drop happens
   * @y: the Y coordinate where the drop happens
   *
   * The ::create-window signal is emitted when a detachable
   * tab is dropped on the root window. 
   *
   * A handler for this signal can create a window containing 
   * a notebook where the tab will be attached. It is also 
   * responsible for moving/resizing the window and adding the 
   * necessary properties to the notebook (e.g. the 
1068
   * #GtkNotebook:group ).
1069 1070 1071 1072 1073 1074
   *
   * Returns: a #GtkNotebook that @page should be added to, or %NULL.
   *
   * Since: 2.12
   */
  notebook_signals[CREATE_WINDOW] = 
1075
    g_signal_new (I_("create-window"),
1076 1077 1078 1079 1080 1081 1082 1083
                  G_TYPE_FROM_CLASS (gobject_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GtkNotebookClass, create_window),
                  gtk_object_handled_accumulator, NULL,
                  _gtk_marshal_OBJECT__OBJECT_INT_INT,
                  GTK_TYPE_NOTEBOOK, 3,
                  GTK_TYPE_WIDGET, G_TYPE_INT, G_TYPE_INT);
 
Manish Singh's avatar
Manish Singh committed
1084
  binding_set = gtk_binding_set_by_class (class);
1085
  gtk_binding_entry_add_signal (binding_set,
1086
                                GDK_KEY_space, 0,
1087
                                "select-page", 1, 
1088
                                G_TYPE_BOOLEAN, FALSE);
1089
  gtk_binding_entry_add_signal (binding_set,
1090
                                GDK_KEY_KP_Space, 0,
1091
                                "select-page", 1, 
1092 1093
                                G_TYPE_BOOLEAN, FALSE);
  
1094
  gtk_binding_entry_add_signal (binding_set,
1095
                                GDK_KEY_Home, 0,
1096
                                "focus-tab", 1, 
1097 1098
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_FIRST);
  gtk_binding_entry_add_signal (binding_set,
1099
                                GDK_KEY_KP_Home, 0,
1100
                                "focus-tab", 1, 
1101 1102
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_FIRST);
  gtk_binding_entry_add_signal (binding_set,
1103
                                GDK_KEY_End, 0,
1104
                                "focus-tab", 1, 
1105 1106
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_LAST);
  gtk_binding_entry_add_signal (binding_set,
1107
                                GDK_KEY_KP_End, 0,
1108
                                "focus-tab", 1, 
1109
                                GTK_TYPE_NOTEBOOK_TAB, GTK_NOTEBOOK_TAB_LAST);
1110 1111

  gtk_binding_entry_add_signal (binding_set,
1112
                                GDK_KEY_Page_Up, GDK_CONTROL_MASK,
1113
                                "change-current-page", 1,
1114 1115
                                G_TYPE_INT, -1);
  gtk_binding_entry_add_signal (binding_set,
1116
                                GDK_KEY_Page_Down, GDK_CONTROL_MASK,
1117
                                "change-current-page", 1,