From e94a7b1a7afe102d74f075e76f2674287f2d2153 Mon Sep 17 00:00:00 2001 From: Lars Hamann Date: Mon, 16 Nov 1998 23:40:50 +0000 Subject: [PATCH] new flags : homogeneous; new guints : tab_hborder, tab_vborder; marked Tue Nov 17 00:06:29 1998 Lars Hamann * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; new guints : tab_hborder, tab_vborder; marked tab_border deprecated (struct _GtkNotebookPage): new flags : expand, fill, pack * gtk/gtknotebook.h/c (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous tabs (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border (gtk_notebook_set_tab_hborder): new function. set tab_hborder (gtk_notebook_set_tab_vborder): new function. set tab_vborder (gtk_notebook_query_tab_label): new function. get tab_label widget. (gtk_notebook_set_tab_label): new function. set tab_label widget. (gtk_notebook_set_tab_label_text): new function. set tab_label text. (gtk_notebook_query_menu_label): new function. get tab_label widget. (gtk_notebook_set_menu_label): new function. set tab_label widget. (gtk_notebook_set_menu_label_text): new function. set tab_label text. (gtk_notebook_set_tab_label_packing): new function. set tab_label fill, expand, fill_type (gtk_notebook_query_tab_label_packing): new function. get tab_label fill, expand, fill_type (gtk_notebook_real_page_position): return logic page number (gtk_notebook_search_page) search next/prev logic page (gtk_notebook_update_labels): set logic page number. (gtk_notebook_page_compare): renamed gtk_notebook_find_page (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK (gtk_notebook_button_press) (gtk_notebook_key_press) (gtk_notebook_focus) (gtk_notebook_pages_allocate) (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) use gtk_notebook_search_page (gtk_notebook_page_allocate): fixed allocation bug (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. (gtk_notebook_init): unset GTK_NO_WINDOW flag (gtk_notebook_size_request): check whether page->child is visible. changes due to tab h/vborder, homogeneous tabs (gtk_notebook_paint): don't draw invisible tabs (gtk_notebook_switch_page): calculate page_num if it's less than 0 (gtk_notebook_append_*) (gtk_notebook_prepend_*) (gtk_notebook_insert_page): removed sanity checks * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. --- ChangeLog | 45 + ChangeLog.pre-2-0 | 45 + ChangeLog.pre-2-10 | 45 + ChangeLog.pre-2-2 | 45 + ChangeLog.pre-2-4 | 45 + ChangeLog.pre-2-6 | 45 + ChangeLog.pre-2-8 | 45 + gtk/gtknotebook.c | 5094 +++++++++++++++++++++++++------------------- gtk/gtknotebook.h | 183 +- gtk/testgtk.c | 237 ++- tests/testgtk.c | 237 ++- 11 files changed, 3657 insertions(+), 2409 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 9ff3fd9334..45054c9c6b 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,48 @@ +Tue Nov 17 00:06:29 1998 Lars Hamann + + * gtk/gtknotebook.h (struct _GtkNotebook): new flags : homogeneous; + new guints : tab_hborder, tab_vborder; marked tab_border deprecated + (struct _GtkNotebookPage): new flags : expand, fill, pack + + * gtk/gtknotebook.h/c + (gtk_notebook_set_homogeneous_tabs): new function. set homogeneneous + tabs + (gtk_notebook_set_tab_border): set tab_h/vborder to tab_border + (gtk_notebook_set_tab_hborder): new function. set tab_hborder + (gtk_notebook_set_tab_vborder): new function. set tab_vborder + (gtk_notebook_query_tab_label): new function. get tab_label widget. + (gtk_notebook_set_tab_label): new function. set tab_label widget. + (gtk_notebook_set_tab_label_text): new function. set tab_label text. + (gtk_notebook_query_menu_label): new function. get tab_label widget. + (gtk_notebook_set_menu_label): new function. set tab_label widget. + (gtk_notebook_set_menu_label_text): new function. set tab_label text. + (gtk_notebook_set_tab_label_packing): new function. set tab_label + fill, expand, fill_type + (gtk_notebook_query_tab_label_packing): new function. get tab_label + fill, expand, fill_type + + (gtk_notebook_real_page_position): return logic page number + (gtk_notebook_search_page) search next/prev logic page + (gtk_notebook_update_labels): set logic page number. + (gtk_notebook_page_compare): renamed gtk_notebook_find_page + (gtk_notebook_set/get_child_arg): new args CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, CHILD_ARG_TAB_PACK + (gtk_notebook_button_press) (gtk_notebook_key_press) + (gtk_notebook_focus) (gtk_notebook_pages_allocate) + (gtk_notebook_calc_tabs) (gtk_notebook_switch_focus_tab) + use gtk_notebook_search_page + (gtk_notebook_page_allocate): fixed allocation bug + (gtk_notebook_set/get_arg): new args TAB_HBORDER, TAB_VBORDER. + (gtk_notebook_init): unset GTK_NO_WINDOW flag + (gtk_notebook_size_request): check whether page->child is visible. + changes due to tab h/vborder, homogeneous tabs + (gtk_notebook_paint): don't draw invisible tabs + (gtk_notebook_switch_page): calculate page_num if it's less than 0 + (gtk_notebook_append_*) (gtk_notebook_prepend_*) + (gtk_notebook_insert_page): removed sanity checks + + * gtk/testgtk.c (create_notebook): extended Notebook sample a bit. + Mon Nov 16 15:10:33 1998 Owen Taylor * gtk/gtktext.c: Optimizations for moving point n diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c index 536afd0797..f165b24b40 100644 --- a/gtk/gtknotebook.c +++ b/gtk/gtknotebook.c @@ -30,6 +30,7 @@ #define TAB_CURVATURE 1 #define ARROW_SIZE 12 #define ARROW_SPACING 0 +#define FOCUS_WIDTH 1 #define NOTEBOOK_INIT_SCROLL_DELAY (200) #define NOTEBOOK_SCROLL_DELAY (100) @@ -51,6 +52,8 @@ enum { ARG_SHOW_BORDER, ARG_SCROLLABLE, ARG_TAB_BORDER, + ARG_TAB_HBORDER, + ARG_TAB_VBORDER, ARG_PAGE, ARG_ENABLE_POPUP }; @@ -59,36 +62,33 @@ enum { CHILD_ARG_0, CHILD_ARG_TAB_LABEL, CHILD_ARG_MENU_LABEL, - CHILD_ARG_POSITION + CHILD_ARG_POSITION, + CHILD_ARG_TAB_EXPAND, + CHILD_ARG_TAB_FILL, + CHILD_ARG_TAB_PACK }; +/** GtkNotebook Methods **/ static void gtk_notebook_class_init (GtkNotebookClass *klass); static void gtk_notebook_init (GtkNotebook *notebook); -static void gtk_notebook_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); + +/** GtkObject Methods **/ +static void gtk_notebook_destroy (GtkObject *object); +static void gtk_notebook_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id); static void gtk_notebook_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void gtk_notebook_set_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id); -static void gtk_notebook_get_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id); -static void gtk_notebook_destroy (GtkObject *object); + +/** GtkWidget Methods **/ static void gtk_notebook_map (GtkWidget *widget); static void gtk_notebook_unmap (GtkWidget *widget); static void gtk_notebook_realize (GtkWidget *widget); -static void gtk_notebook_panel_realize (GtkNotebook *notebook); static void gtk_notebook_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_notebook_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_notebook_paint (GtkWidget *widget, - GdkRectangle *area); static void gtk_notebook_draw (GtkWidget *widget, GdkRectangle *area); static gint gtk_notebook_expose (GtkWidget *widget, @@ -105,72 +105,100 @@ static gint gtk_notebook_motion_notify (GtkWidget *widget, GdkEventMotion *event); static gint gtk_notebook_key_press (GtkWidget *widget, GdkEventKey *event); -static void gtk_notebook_add (GtkContainer *container, - GtkWidget *widget); -static void gtk_notebook_remove (GtkContainer *container, - GtkWidget *widget); -static void gtk_notebook_real_remove (GtkNotebook *notebook, - GList *list, - guint page_num); -static void gtk_notebook_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); -static void gtk_notebook_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num); -static void gtk_notebook_draw_tab (GtkNotebook *notebook, - GtkNotebookPage *page, - GdkRectangle *area); -static void gtk_notebook_set_focus_child (GtkContainer *container, - GtkWidget *child); static gint gtk_notebook_focus_in (GtkWidget *widget, GdkEventFocus *event); static gint gtk_notebook_focus_out (GtkWidget *widget, GdkEventFocus *event); static void gtk_notebook_draw_focus (GtkWidget *widget); -static void gtk_notebook_focus_changed (GtkNotebook *notebook, +static void gtk_notebook_style_set (GtkWidget *widget, + GtkStyle *previous_style); + +/** GtkContainer Methods **/ +static void gtk_notebook_set_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id); +static void gtk_notebook_get_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id); +static void gtk_notebook_add (GtkContainer *container, + GtkWidget *widget); +static void gtk_notebook_remove (GtkContainer *container, + GtkWidget *widget); +static gint gtk_notebook_focus (GtkContainer *container, + GtkDirectionType direction); +static void gtk_notebook_set_focus_child (GtkContainer *container, + GtkWidget *child); +static GtkType gtk_notebook_child_type (GtkContainer *container); +static void gtk_notebook_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); + +/** GtkNotebook Private Functions **/ +static void gtk_notebook_panel_realize (GtkNotebook *notebook); +static void gtk_notebook_expose_tabs (GtkNotebook *notebook); +static void gtk_notebook_focus_changed (GtkNotebook *notebook, GtkNotebookPage *old_page); +static void gtk_notebook_real_remove (GtkNotebook *notebook, + GList *list); +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); +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); + +/** GtkNotebook Drawing Functions **/ +static void gtk_notebook_paint (GtkWidget *widget, + GdkRectangle *area); +static void gtk_notebook_draw_tab (GtkNotebook *notebook, + GtkNotebookPage *page, + GdkRectangle *area); +static void gtk_notebook_draw_arrow (GtkNotebook *notebook, + guint arrow); +static void gtk_notebook_set_shape (GtkNotebook *notebook); + +/** GtkNotebook Size Allocate Functions **/ static void gtk_notebook_pages_allocate (GtkNotebook *notebook, GtkAllocation *allocation); static void gtk_notebook_page_allocate (GtkNotebook *notebook, GtkNotebookPage *page, GtkAllocation *allocation); -static void gtk_notebook_draw_arrow (GtkNotebook *notebook, - guint arrow); -static gint gtk_notebook_timer (GtkNotebook *notebook); -static gint gtk_notebook_focus (GtkContainer *container, - GtkDirectionType direction); -static gint gtk_notebook_page_select (GtkNotebook *notebook); -static void gtk_notebook_calc_tabs (GtkNotebook *notebook, - GList *start, +static void gtk_notebook_calc_tabs (GtkNotebook *notebook, + GList *start, GList **end, gint *tab_space, guint direction); -static void gtk_notebook_expose_tabs (GtkNotebook *notebook); -static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook, - GList *new_child); + +/** GtkNotebook Page Switch Methods **/ static void gtk_notebook_real_switch_page (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num); + +/** GtkNotebook Page Switch Functions **/ +static void gtk_notebook_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num); +static gint gtk_notebook_page_select (GtkNotebook *notebook); +static void gtk_notebook_switch_focus_tab (GtkNotebook *notebook, + GList *new_child); static void gtk_notebook_menu_switch_page (GtkWidget *widget, GtkNotebookPage *page); -static void gtk_notebook_update_labels (GtkNotebook *notebook, - GList *list, - guint page_num); + +/** GtkNotebook Menu Functions **/ +static void gtk_notebook_menu_item_create (GtkNotebook *notebook, + GList *list); +static void gtk_notebook_menu_label_unparent (GtkWidget *widget, + gpointer data); static void gtk_notebook_menu_detacher (GtkWidget *widget, GtkMenu *menu); -static void gtk_notebook_menu_label_unparent (GtkWidget *widget, - gpointer data); -static void gtk_notebook_menu_item_create (GtkNotebook *notebook, - GtkNotebookPage *page, - gint position); -static GtkType gtk_notebook_child_type (GtkContainer *container); -static gint gtk_notebook_find_page (gconstpointer a, - gconstpointer b); -static void gtk_notebook_set_shape (GtkNotebook *notebook); -static void gtk_notebook_style_set (GtkWidget *widget, - GtkStyle *previous_style); + static GtkContainerClass *parent_class = NULL; static guint notebook_signals[LAST_SIGNAL] = { 0 }; @@ -215,6 +243,8 @@ gtk_notebook_class_init (GtkNotebookClass *class) gtk_object_add_arg_type ("GtkNotebook::page", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_PAGE); gtk_object_add_arg_type ("GtkNotebook::tab_pos", GTK_TYPE_POSITION_TYPE, GTK_ARG_READWRITE, ARG_TAB_POS); gtk_object_add_arg_type ("GtkNotebook::tab_border", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_BORDER); + gtk_object_add_arg_type ("GtkNotebook::tab_hborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_HBORDER); + gtk_object_add_arg_type ("GtkNotebook::tab_vborder", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_TAB_VBORDER); gtk_object_add_arg_type ("GtkNotebook::show_tabs", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_TABS); gtk_object_add_arg_type ("GtkNotebook::show_border", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SHOW_BORDER); gtk_object_add_arg_type ("GtkNotebook::scrollable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_SCROLLABLE); @@ -223,14 +253,16 @@ gtk_notebook_class_init (GtkNotebookClass *class) gtk_container_add_child_arg_type ("GtkNotebook::tab_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_TAB_LABEL); gtk_container_add_child_arg_type ("GtkNotebook::menu_label", GTK_TYPE_STRING, GTK_ARG_READWRITE, CHILD_ARG_MENU_LABEL); gtk_container_add_child_arg_type ("GtkNotebook::position", GTK_TYPE_INT, GTK_ARG_READWRITE, CHILD_ARG_POSITION); + gtk_container_add_child_arg_type ("GtkNotebook::tab_fill", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_FILL); + gtk_container_add_child_arg_type ("GtkNotebook::tab_pack", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_TAB_PACK); notebook_signals[SWITCH_PAGE] = gtk_signal_new ("switch_page", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page), - gtk_marshal_NONE__POINTER_UINT, - GTK_TYPE_NONE, 2, + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (GtkNotebookClass, switch_page), + gtk_marshal_NONE__POINTER_UINT, + GTK_TYPE_NONE, 2, GTK_TYPE_POINTER, GTK_TYPE_UINT); @@ -271,9 +303,65 @@ gtk_notebook_class_init (GtkNotebookClass *class) } static void -gtk_notebook_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) +gtk_notebook_init (GtkNotebook *notebook) +{ + GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); + GTK_WIDGET_UNSET_FLAGS (notebook, GTK_NO_WINDOW); + + notebook->cur_page = NULL; + notebook->children = NULL; + notebook->first_tab = NULL; + notebook->focus_tab = NULL; + notebook->panel = NULL; + notebook->menu = NULL; + + notebook->tab_border = 2; + notebook->tab_hborder = 2; + notebook->tab_vborder = 2; + + notebook->show_tabs = TRUE; + notebook->show_border = TRUE; + notebook->tab_pos = GTK_POS_TOP; + notebook->scrollable = FALSE; + notebook->in_child = 0; + notebook->click_child = 0; + notebook->button = 0; + notebook->need_timer = 0; + notebook->child_has_focus = FALSE; +} + +GtkWidget* +gtk_notebook_new (void) +{ + return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ())); +} + +/* Private GtkObject Methods : + * + * gtk_notebook_destroy + * gtk_notebook_set_arg + * gtk_notebook_get_arg + */ +static void +gtk_notebook_destroy (GtkObject *object) +{ + GtkNotebook *notebook; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (object)); + + notebook = GTK_NOTEBOOK (object); + + if (notebook->menu) + gtk_notebook_popup_disable (notebook); + + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} + +static void +gtk_notebook_set_arg (GtkObject *object, + GtkArg *arg, + guint arg_id) { GtkNotebook *notebook; @@ -305,15 +393,21 @@ gtk_notebook_set_arg (GtkObject *object, case ARG_TAB_BORDER: gtk_notebook_set_tab_border (notebook, GTK_VALUE_UINT (*arg)); break; + case ARG_TAB_HBORDER: + gtk_notebook_set_tab_hborder (notebook, GTK_VALUE_UINT (*arg)); + break; + case ARG_TAB_VBORDER: + gtk_notebook_set_tab_vborder (notebook, GTK_VALUE_UINT (*arg)); + break; default: break; } } static void -gtk_notebook_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) +gtk_notebook_get_arg (GtkObject *object, + GtkArg *arg, + guint arg_id) { GtkNotebook *notebook; @@ -342,164 +436,11 @@ gtk_notebook_get_arg (GtkObject *object, case ARG_TAB_BORDER: GTK_VALUE_UINT (*arg) = notebook->tab_border; break; - default: - arg->type = GTK_TYPE_INVALID; + case ARG_TAB_HBORDER: + GTK_VALUE_UINT (*arg) = notebook->tab_hborder; break; - } -} - -static void -gtk_notebook_set_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id) -{ - GtkNotebook *notebook; - GtkNotebookPage *page = NULL; - GList *list; - gint position; - - notebook = GTK_NOTEBOOK (container); - - switch (arg_id) - { - case CHILD_ARG_TAB_LABEL: - /* a NULL pointer indicates a default_tab setting, otherwise - * we need to set the associated label - */ - - if (!(list = g_list_find_custom (notebook->children, child, - gtk_notebook_find_page))) - return; - - page = list->data; - - if (GTK_VALUE_STRING (*arg)) - { - page->default_tab = FALSE; - if (page->tab_label) - gtk_widget_unparent (page->tab_label); - page->tab_label = gtk_label_new (GTK_VALUE_STRING (*arg)); - gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); - if (notebook->show_tabs) - { - gtk_widget_show (page->tab_label); - gtk_notebook_pages_allocate - (notebook, &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } - } - else - { - page->default_tab = TRUE; - if (page->tab_label) - gtk_widget_unparent (page->tab_label); - if (!notebook->show_tabs) - page->tab_label = NULL; - else - { - gchar string[32]; - - sprintf (string, "Page %u", g_list_index (notebook->children, page) + 1); - page->tab_label = gtk_label_new (string); - gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); - gtk_widget_show (page->tab_label); - gtk_notebook_pages_allocate - (notebook, &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } - } - break; - case CHILD_ARG_MENU_LABEL: - - for (position = 0, list = notebook->children; list; - list = list->next, position++) - { - page = list->data; - if (page->child == child) - break; - } - - if (page->menu_label) - { - if (notebook->menu) - { - gtk_container_remove (GTK_CONTAINER (notebook->menu), - page->menu_label->parent); - gtk_widget_queue_resize (notebook->menu); - } - if (!page->default_menu) - gtk_widget_unref (page->menu_label); - } - if (GTK_VALUE_STRING (*arg)) - { - page->menu_label = gtk_label_new (GTK_VALUE_STRING (*arg)); - gtk_widget_ref (page->menu_label); - gtk_object_sink (GTK_OBJECT(page->menu_label)); - page->default_menu = FALSE; - } - else - page->default_menu = TRUE; - - if (notebook->menu) - gtk_notebook_menu_item_create (notebook, page, position); - - break; - case CHILD_ARG_POSITION: - gtk_notebook_reorder_child (notebook, child, GTK_VALUE_INT (*arg)); - break; - default: - break; - } -} - -static void -gtk_notebook_get_child_arg (GtkContainer *container, - GtkWidget *child, - GtkArg *arg, - guint arg_id) -{ - GtkNotebook *notebook; - GtkNotebookPage *page = NULL; - GList *list; - - notebook = GTK_NOTEBOOK (container); - - if (!(list = g_list_find_custom (notebook->children, child, - gtk_notebook_find_page))) - { - arg->type = GTK_TYPE_INVALID; - return; - } - - page = list->data; - - switch (arg_id) - { - case CHILD_ARG_TAB_LABEL: - if (page->default_tab) - GTK_VALUE_STRING (*arg) = NULL; - else - { - if (page->tab_label && GTK_IS_LABEL (page->tab_label)) - GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (page->tab_label)->label); - else - GTK_VALUE_STRING (*arg) = NULL; - } - break; - case CHILD_ARG_MENU_LABEL: - if (page->default_menu) - GTK_VALUE_STRING (*arg) = NULL; - else - { - if (page->menu_label && GTK_IS_LABEL (page->menu_label)) - GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (page->menu_label)->label); - else - GTK_VALUE_STRING (*arg) = NULL; - } - break; - case CHILD_ARG_POSITION: - GTK_VALUE_INT (*arg) = g_list_position (notebook->children, list); + case ARG_TAB_VBORDER: + GTK_VALUE_UINT (*arg) = notebook->tab_vborder; break; default: arg->type = GTK_TYPE_INVALID; @@ -507,797 +448,26 @@ gtk_notebook_get_child_arg (GtkContainer *container, } } -static GtkType -gtk_notebook_child_type (GtkContainer *container) -{ - return GTK_TYPE_WIDGET; -} - -static void -gtk_notebook_init (GtkNotebook *notebook) -{ - GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); - - notebook->cur_page = NULL; - notebook->children = NULL; - notebook->first_tab = NULL; - notebook->focus_tab = NULL; - notebook->panel = NULL; - notebook->menu = NULL; - - notebook->tab_border = 3; - notebook->show_tabs = TRUE; - notebook->show_border = TRUE; - notebook->tab_pos = GTK_POS_TOP; - notebook->scrollable = FALSE; - notebook->in_child = 0; - notebook->click_child = 0; - notebook->button = 0; - notebook->need_timer = 0; - notebook->child_has_focus = FALSE; -} - -GtkWidget* -gtk_notebook_new (void) -{ - return GTK_WIDGET (gtk_type_new (gtk_notebook_get_type ())); -} - -static void -gtk_notebook_destroy (GtkObject *object) -{ - GtkNotebook *notebook; - - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (object)); - - notebook = GTK_NOTEBOOK (object); - - if (notebook->menu) - gtk_notebook_popup_disable (notebook); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -void -gtk_notebook_append_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - - gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1); -} - -void -gtk_notebook_append_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - - gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1); -} - -void -gtk_notebook_prepend_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - - gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0); -} - -void -gtk_notebook_prepend_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - - gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0); -} - -void -gtk_notebook_insert_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - gint position) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - - gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position); -} - -void -gtk_notebook_insert_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label, - gint position) -{ - GtkNotebookPage *page; - gint nchildren; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - - page = g_new (GtkNotebookPage, 1); - page->child = child; - page->requisition.width = 0; - page->requisition.height = 0; - page->allocation.x = 0; - page->allocation.y = 0; - page->allocation.width = 0; - page->allocation.height = 0; - page->default_menu = FALSE; - page->default_tab = FALSE; - - nchildren = g_list_length (notebook->children); - if ((position < 0) || (position > nchildren)) - position = nchildren; - - notebook->children = g_list_insert (notebook->children, page, position); - - if (!tab_label) - { - page->default_tab = TRUE; - if (notebook->show_tabs) - tab_label = gtk_label_new (""); - } - page->tab_label = tab_label; - page->menu_label = menu_label; - - if (!menu_label) - page->default_menu = TRUE; - else - { - gtk_widget_ref (page->menu_label); - gtk_object_sink (GTK_OBJECT(page->menu_label)); - } - - if (notebook->menu) - gtk_notebook_menu_item_create (notebook, page, position); - - gtk_notebook_update_labels - (notebook, g_list_nth (notebook->children, position), position + 1); - - if (!notebook->first_tab) - notebook->first_tab = notebook->children; - - gtk_widget_set_parent (child, GTK_WIDGET (notebook)); - if (tab_label) - { - gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook)); - gtk_widget_show (tab_label); - } - - if (!notebook->cur_page) - { - gtk_notebook_switch_page (notebook, page, 0); - gtk_notebook_switch_focus_tab (notebook, NULL); - } - - if (GTK_WIDGET_VISIBLE (notebook)) - { - if (GTK_WIDGET_REALIZED (notebook) && - !GTK_WIDGET_REALIZED (child)) - gtk_widget_realize (child); - - if (GTK_WIDGET_MAPPED (notebook) && - !GTK_WIDGET_MAPPED (child) && notebook->cur_page == page) - gtk_widget_map (child); - - if (tab_label) - { - if (GTK_WIDGET_REALIZED (notebook) && - !GTK_WIDGET_REALIZED (tab_label)) - gtk_widget_realize (tab_label); - - if (GTK_WIDGET_MAPPED (notebook) && - !GTK_WIDGET_MAPPED (tab_label)) - gtk_widget_map (tab_label); - } - } - - if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (child); -} - -void -gtk_notebook_remove_page (GtkNotebook *notebook, - gint page_num) -{ - GList *list; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (page_num >= 0) - { - list = g_list_nth (notebook->children, page_num); - if (list) - gtk_notebook_real_remove (notebook, list, page_num); - } - else - { - list = g_list_last (notebook->children); - if (list) - gtk_notebook_real_remove - (notebook, list, g_list_index (notebook->children, list->data)); - } -} - -static void -gtk_notebook_add (GtkContainer *container, - GtkWidget *widget) -{ - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - g_return_if_fail (widget != NULL); - - gtk_notebook_insert_page_menu (GTK_NOTEBOOK (container), widget, - NULL, NULL, -1); -} - -static void -gtk_notebook_remove (GtkContainer *container, - GtkWidget *widget) -{ - GtkNotebook *notebook; - GtkNotebookPage *page; - GList *children; - guint page_num; - - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - g_return_if_fail (widget != NULL); - - notebook = GTK_NOTEBOOK (container); - - children = notebook->children; - page_num = 0; - while (children) - { - page = children->data; - if (page->child == widget) - { - gtk_notebook_real_remove (notebook, children, page_num); - break; - } - page_num++; - children = children->next; - } -} - -gint -gtk_notebook_page_num (GtkNotebook *notebook, - GtkWidget *child) -{ - GList *children; - gint num; - - g_return_val_if_fail (notebook != NULL, -1); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); - - num = 0; - children = notebook->children; - while (children) - { - GtkNotebookPage *page; - - page = children->data; - if (page->child == child) - return num; - - children = children->next; - num++; - } - - return -1; -} - -static void -gtk_notebook_real_remove (GtkNotebook *notebook, - GList *list, - guint page_num) -{ - GtkNotebookPage *page; - GList * next_list; - gint need_resize = FALSE; - - if (list->prev) - { - next_list = list->prev; - page_num--; - } - else if (list->next) - { - next_list = list->next; - page_num++; - } - else - next_list = NULL; - - if (notebook->cur_page == list->data) - { - notebook->cur_page = NULL; - if (next_list) - { - page = next_list->data; - gtk_notebook_switch_page (notebook, page, page_num); - } - } - - if (list == notebook->first_tab) - notebook->first_tab = next_list; - if (list == notebook->focus_tab) - gtk_notebook_switch_focus_tab (notebook, next_list); - - page = list->data; - - if ((GTK_WIDGET_VISIBLE (page->child) || - (page->tab_label && GTK_WIDGET_VISIBLE (page->tab_label))) - && GTK_WIDGET_VISIBLE (notebook)) - need_resize = TRUE; - - gtk_widget_unparent (page->child); - - if (page->tab_label) - gtk_widget_unparent (page->tab_label); - - if (notebook->menu) - { - gtk_container_remove (GTK_CONTAINER (notebook->menu), - page->menu_label->parent); - gtk_widget_queue_resize (notebook->menu); - } - if (!page->default_menu) - gtk_widget_unref (page->menu_label); - - gtk_notebook_update_labels (notebook, list->next, page_num + 1); - - notebook->children = g_list_remove_link (notebook->children, list); - g_list_free (list); - g_free (page); - - if (need_resize) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); - -} - -gint -gtk_notebook_current_page (GtkNotebook *notebook) -{ - GList *children; - gint cur_page; - - g_return_val_if_fail (notebook != NULL, -1); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); - - if (notebook->cur_page) - { - cur_page = 0; - children = notebook->children; - - while (children) - { - if (children->data == notebook->cur_page) - break; - children = children->next; - cur_page += 1; - } - - if (!children) - cur_page = -1; - } - else - { - cur_page = -1; - } - - return cur_page; -} - -void -gtk_notebook_set_page (GtkNotebook *notebook, - gint page_num) -{ - GList *list; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (page_num >= 0) - { - list = g_list_nth (notebook->children, page_num); - if (list) - gtk_notebook_switch_page (notebook, list->data, page_num); - } - else - { - list = g_list_last (notebook->children); - if (list) - gtk_notebook_switch_page (notebook, list->data, - g_list_index (notebook->children, list->data)); - } -} - -void -gtk_notebook_next_page (GtkNotebook *notebook) -{ - GtkNotebookPage *page; - GList *children; - gint num; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - children = notebook->children; - num = 0; - while (children) - { - if (notebook->cur_page == children->data) - break; - children = children->next; - num++; - } - - if (!children) - return; - - if (children->next) - { - children = children->next; - num++; - } - else - { - children = notebook->children; - num = 0; - } - - page = children->data; - gtk_notebook_switch_page (notebook, page, num); -} - -void -gtk_notebook_prev_page (GtkNotebook *notebook) -{ - GtkNotebookPage *page; - GList *children; - gint num; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - children = notebook->children; - num = 0; - while (children) - { - if (notebook->cur_page == children->data) - break; - children = children->next; - num++; - } - - if (!children) - return; - - if (children->prev) - { - children = children->prev; - num--; - } - else - { - while (children->next) - { - children = children->next; - num++; - } - } - - page = children->data; - gtk_notebook_switch_page (notebook, page, num); -} - -void -gtk_notebook_reorder_child (GtkNotebook *notebook, - GtkWidget *child, - gint position) -{ - GList *list; - GtkNotebookPage *page; - gint old_pos; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (child != NULL); - g_return_if_fail (GTK_IS_WIDGET (child)); - - for (old_pos = 0, list = notebook->children; list; - list = list->next, old_pos++) - { - page = list->data; - if (page->child == child) - break; - } - - if (!list || old_pos == position) - return; - - notebook->children = g_list_remove_link (notebook->children, list); - - if (position <= 0 || !notebook->children) - { - list->next = notebook->children; - if (list->next) - list->next->prev = list; - notebook->children = list; - } - else - { - GList *work; - - if ((work = g_list_nth (notebook->children, position))) - { - list->prev = work->prev; - if (list->prev) - list->prev->next = list; - list->next = work; - work->prev = list; - } - else - { - work = g_list_last (notebook->children); - work->next = list; - list->prev = work; - } - } - - if (notebook->menu) - { - GtkWidget *menu_item; - - menu_item = page->menu_label->parent; - gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label); - gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item); - gtk_notebook_menu_item_create (notebook, page, position); - gtk_widget_queue_resize (notebook->menu); - } - - gtk_notebook_update_labels (notebook, notebook->children, 1); - - if (notebook->show_tabs) - { - gtk_notebook_pages_allocate (notebook, - &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } -} - -static void -gtk_notebook_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) -{ - GtkNotebook *notebook; - GList *children; - - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - g_return_if_fail (callback != NULL); - - notebook = GTK_NOTEBOOK (container); - - children = notebook->children; - while (children) - { - GtkNotebookPage *page; - - page = children->data; - children = children->next; - (* callback) (page->child, callback_data); - if (include_internals) - { - if (page->tab_label) - (* callback) (page->tab_label, callback_data); - if (page->menu_label) - (* callback) (page->menu_label, callback_data); - } - } -} - -static void -gtk_notebook_expose_tabs (GtkNotebook *notebook) -{ - GtkWidget *widget; - GtkNotebookPage *page; - GdkEventExpose event; - gint border; - - widget = GTK_WIDGET (notebook); - border = GTK_CONTAINER (notebook)->border_width; - - page = notebook->first_tab->data; - - event.type = GDK_EXPOSE; - event.window = widget->window; - event.count = 0; - event.area.x = border; - event.area.y = border; - - switch (notebook->tab_pos) - { - case GTK_POS_BOTTOM: - event.area.y = widget->allocation.height - border - - page->allocation.height - widget->style->klass->ythickness; - if (notebook->first_tab->data != notebook->cur_page) - event.area.y -= widget->style->klass->ythickness; - case GTK_POS_TOP: - event.area.width = widget->allocation.width - 2 * border; - event.area.height = page->allocation.height - + widget->style->klass->ythickness; - if (notebook->first_tab->data != notebook->cur_page) - event.area.height += widget->style->klass->ythickness; - break; - case GTK_POS_RIGHT: - event.area.x = widget->allocation.width - border - - page->allocation.width - widget->style->klass->xthickness; - if (notebook->first_tab->data != notebook->cur_page) - event.area.x -= widget->style->klass->xthickness; - case GTK_POS_LEFT: - event.area.width = page->allocation.width - + widget->style->klass->xthickness; - event.area.height = widget->allocation.height - 2 * border; - if (notebook->first_tab->data != notebook->cur_page) - event.area.width += widget->style->klass->xthickness; - break; - } - gtk_widget_event (widget, (GdkEvent *) &event); -} - -void -gtk_notebook_set_tab_pos (GtkNotebook *notebook, - GtkPositionType pos) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (notebook->tab_pos != pos) - { - notebook->tab_pos = pos; - - if (GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); - } -} - -void -gtk_notebook_set_show_tabs (GtkNotebook *notebook, - gboolean show_tabs) -{ - GtkNotebookPage *page; - GList *children; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - show_tabs = show_tabs != FALSE; - - if (notebook->show_tabs == show_tabs) - return; - - notebook->show_tabs = show_tabs; - children = notebook->children; - - if (!show_tabs) - { - GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); - - while (children) - { - page = children->data; - children = children->next; - if (page->default_tab) - { - gtk_widget_destroy (page->tab_label); - page->tab_label = NULL; - } - else - gtk_widget_hide (page->tab_label); - } - - if (notebook->panel) - gdk_window_hide (notebook->panel); - } - else - { - gchar string[32]; - gint i = 1; - - GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); - - while (children) - { - page = children->data; - children = children->next; - if (page->default_tab) - { - sprintf (string, "Page %d", i); - page->tab_label = gtk_label_new (string); - gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); - } - gtk_widget_show (page->tab_label); - i++; - } - } - gtk_widget_queue_resize (GTK_WIDGET (notebook)); -} - -void -gtk_notebook_set_show_border (GtkNotebook *notebook, - gint show_border) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (notebook->show_border != show_border) - { - notebook->show_border = show_border; - - if (GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); - } -} - -void -gtk_notebook_set_scrollable (GtkNotebook *notebook, - gint scrollable) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - scrollable = (scrollable != FALSE); - - if (scrollable != notebook->scrollable) - { - notebook->scrollable = scrollable; - - if (GTK_WIDGET_REALIZED (notebook)) - { - if (scrollable) - { - gtk_notebook_panel_realize (notebook); - } - else if (notebook->panel) - { - gdk_window_destroy (notebook->panel); - notebook->panel = NULL; - } - } - - if (GTK_WIDGET_VISIBLE (notebook)) - gtk_widget_queue_resize (GTK_WIDGET(notebook)); - } -} - +/* Private GtkWidget Methods : + * + * gtk_notebook_map + * gtk_notebook_unmap + * gtk_notebook_realize + * gtk_notebook_size_request + * gtk_notebook_size_allocate + * gtk_notebook_draw + * gtk_notebook_expose + * gtk_notebook_button_press + * gtk_notebook_button_release + * gtk_notebook_enter_notify + * gtk_notebook_leave_notify + * gtk_notebook_motion_notify + * gtk_notebook_key_press + * gtk_notebook_focus_in + * gtk_notebook_focus_out + * gtk_notebook_draw_focus + * gtk_notebook_style_set + */ static void gtk_notebook_map (GtkWidget *widget) { @@ -1371,8 +541,8 @@ gtk_notebook_realize (GtkWidget *widget) attributes.visual = gtk_widget_get_visual (widget); attributes.colormap = gtk_widget_get_colormap (widget); attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK; + attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK); attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; @@ -1387,51 +557,6 @@ gtk_notebook_realize (GtkWidget *widget) gtk_notebook_panel_realize (notebook); } -static void -gtk_notebook_panel_realize (GtkNotebook *notebook) -{ - GtkWidget *widget; - GdkWindowAttr attributes; - gint attributes_mask; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - widget = GTK_WIDGET (notebook); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK - | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK - | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK; - - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; - - attributes.width = 2 * ARROW_SIZE + ARROW_SPACING; - attributes.height = ARROW_SIZE; - - attributes.x = widget->allocation.width - attributes.width - - GTK_CONTAINER (notebook)->border_width; - attributes.y = widget->allocation.height - ARROW_SIZE - - GTK_CONTAINER (notebook)->border_width; - if (notebook->tab_pos == GTK_POS_TOP) - attributes.y = GTK_CONTAINER (notebook)->border_width; - else if (notebook->tab_pos == GTK_POS_LEFT) - attributes.x = widget->allocation.x - + GTK_CONTAINER (notebook)->border_width; - - - notebook->panel = gdk_window_new (widget->window, &attributes, - attributes_mask); - gtk_style_set_background (widget->style, notebook->panel, - GTK_STATE_NORMAL); - gdk_window_set_back_pixmap (widget->window, NULL, TRUE); - gdk_window_set_user_data (notebook->panel, widget); -} - static void gtk_notebook_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -1439,6 +564,8 @@ gtk_notebook_size_request (GtkWidget *widget, GtkNotebook *notebook; GtkNotebookPage *page; GList *children; + gboolean switch_page = FALSE; + gint vis_pages; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_NOTEBOOK (widget)); @@ -1448,20 +575,34 @@ gtk_notebook_size_request (GtkWidget *widget, widget->requisition.width = 0; widget->requisition.height = 0; - children = notebook->children; - while (children) + for (children = notebook->children, vis_pages = 0; children; + children = children->next) { page = children->data; - children = children->next; if (GTK_WIDGET_VISIBLE (page->child)) { + vis_pages++; gtk_widget_size_request (page->child, &page->child->requisition); widget->requisition.width = MAX (widget->requisition.width, page->child->requisition.width); widget->requisition.height = MAX (widget->requisition.height, page->child->requisition.height); + + if (GTK_WIDGET_MAPPED (page->child) && page != notebook->cur_page) + gtk_widget_unmap (page->child); + if (notebook->menu && page->menu_label->parent && + !GTK_WIDGET_VISIBLE (page->menu_label->parent)) + gtk_widget_show (page->menu_label->parent); + } + else + { + if (page == notebook->cur_page) + switch_page = TRUE; + if (notebook->menu && page->menu_label->parent && + GTK_WIDGET_VISIBLE (page->menu_label->parent)) + gtk_widget_hide (page->menu_label->parent); } } @@ -1475,109 +616,189 @@ gtk_notebook_size_request (GtkWidget *widget, gint tab_width = 0; gint tab_height = 0; gint tab_max = 0; + gint padding; - children = notebook->children; - while (children) + for (children = notebook->children; children; + children = children->next) { page = children->data; - children = children->next; if (GTK_WIDGET_VISIBLE (page->child)) { + if (!GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_show (page->tab_label); + gtk_widget_size_request (page->tab_label, &page->tab_label->requisition); - + page->requisition.width = - (page->tab_label->requisition.width + - (widget->style->klass->xthickness + notebook->tab_border) - * 2); + page->tab_label->requisition.width + + 2 * widget->style->klass->xthickness; page->requisition.height = - (page->tab_label->requisition.height + - (widget->style->klass->ythickness + notebook->tab_border) - * 2); + page->tab_label->requisition.height + + 2 * widget->style->klass->ythickness; switch (notebook->tab_pos) { case GTK_POS_TOP: case GTK_POS_BOTTOM: - page->requisition.width -= TAB_OVERLAP; - - tab_width += page->requisition.width; + page->requisition.height += 2 * (notebook->tab_vborder + + FOCUS_WIDTH); tab_height = MAX (tab_height, page->requisition.height); tab_max = MAX (tab_max, page->requisition.width); break; case GTK_POS_LEFT: case GTK_POS_RIGHT: - page->requisition.height -= TAB_OVERLAP; - + page->requisition.width += 2 * (notebook->tab_hborder + + FOCUS_WIDTH); tab_width = MAX (tab_width, page->requisition.width); - tab_height += page->requisition.height; tab_max = MAX (tab_max, page->requisition.height); break; } } + else if (GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_hide (page->tab_label); } children = notebook->children; - if (children && children->next && notebook->scrollable) + if (vis_pages) { - if ((notebook->tab_pos == GTK_POS_TOP) || - (notebook->tab_pos == GTK_POS_BOTTOM)) + switch (notebook->tab_pos) { - if (widget->requisition.width < tab_width) - { - tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING); - tab_height = MAX (tab_height, ARROW_SIZE); - } - } - else - { - if (widget->requisition.height < tab_height) - { - tab_height = tab_max + ARROW_SIZE + ARROW_SPACING; - tab_width = MAX (tab_width, - ARROW_SPACING + 2 * ARROW_SIZE); - } - } - } + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + if (tab_height == 0) + break; - while (children) - { - page = children->data; - children = children->next; - - if (GTK_WIDGET_VISIBLE (page->child)) - { - if ((notebook->tab_pos == GTK_POS_TOP) || - (notebook->tab_pos == GTK_POS_BOTTOM)) - page->requisition.height = tab_height; - else - page->requisition.width = tab_width; + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.width < tab_width) + tab_height = MAX (tab_height, ARROW_SIZE); + + padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH + + notebook->tab_hborder) - TAB_OVERLAP; + tab_max += padding; + while (children) + { + page = children->data; + children = children->next; + + if (!GTK_WIDGET_VISIBLE (page->child)) + continue; + + if (notebook->homogeneous) + page->requisition.width = tab_max; + else + page->requisition.width += padding; + + tab_width += page->requisition.width; + page->requisition.height = tab_height; + } + + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.width < tab_width) + tab_width = tab_max + 2 * (ARROW_SIZE + ARROW_SPACING); + + if (notebook->homogeneous && !notebook->scrollable) + widget->requisition.width = MAX (widget->requisition.width, + vis_pages * tab_max + + TAB_OVERLAP); + else + widget->requisition.width = MAX (widget->requisition.width, + tab_width + TAB_OVERLAP); + + widget->requisition.height += tab_height; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + if (tab_width == 0) + break; + + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.height < tab_height) + tab_width = MAX (tab_width, ARROW_SPACING +2 * ARROW_SIZE); + + padding = 2 * (TAB_CURVATURE + FOCUS_WIDTH + + notebook->tab_vborder) - TAB_OVERLAP; + tab_max += padding; + + while (children) + { + page = children->data; + children = children->next; + + if (!GTK_WIDGET_VISIBLE (page->child)) + continue; + + page->requisition.width = tab_width; + + if (notebook->homogeneous) + page->requisition.height = tab_max; + else + page->requisition.height += padding; + + tab_height += page->requisition.height; + } + + if (notebook->scrollable && vis_pages > 1 && + widget->requisition.height < tab_height) + tab_height = tab_max + ARROW_SIZE + ARROW_SPACING; + + widget->requisition.width += tab_width; + + if (notebook->homogeneous && !notebook->scrollable) + widget->requisition.height = + MAX (widget->requisition.height, + vis_pages * tab_max + TAB_OVERLAP); + else + widget->requisition.height = + MAX (widget->requisition.height, + tab_height + TAB_OVERLAP); + + if (!notebook->homogeneous || notebook->scrollable) + vis_pages = 1; + widget->requisition.height = MAX (widget->requisition.height, + vis_pages * tab_max + + TAB_OVERLAP); + break; } } - - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - case GTK_POS_BOTTOM: - tab_width += widget->style->klass->xthickness; - widget->requisition.width = MAX (widget->requisition.width, - tab_width); - widget->requisition.height += tab_height; - break; - case GTK_POS_LEFT: - case GTK_POS_RIGHT: - tab_height += widget->style->klass->ythickness; - widget->requisition.width += tab_width; - widget->requisition.height = MAX (widget->requisition.height, - tab_height); - break; - } } } + widget->requisition.width += GTK_CONTAINER (widget)->border_width * 2; widget->requisition.height += GTK_CONTAINER (widget)->border_width * 2; + + if (switch_page) + { + if (vis_pages) + { + for (children = notebook->children; children; + children = children->next) + { + page = children->data; + if (GTK_WIDGET_VISIBLE (page->child)) + { + gtk_notebook_switch_page (notebook, page, -1); + break; + } + } + } + else if (GTK_WIDGET_VISIBLE (widget)) + { + widget->requisition.width = GTK_CONTAINER (widget)->border_width * 2; + widget->requisition.height= GTK_CONTAINER (widget)->border_width * 2; + } + } + if (vis_pages && !notebook->cur_page) + { + children = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); + if (children) + { + notebook->first_tab = children; + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (children),-1); + } + } } static void @@ -1611,26 +832,28 @@ gtk_notebook_size_allocate (GtkWidget *widget, { child_allocation.x += widget->style->klass->xthickness; child_allocation.y += widget->style->klass->ythickness; - child_allocation.width = MAX (1, - child_allocation.width - widget->style->klass->xthickness * 2); - child_allocation.height = MAX (1, - child_allocation.height - widget->style->klass->ythickness * 2); + child_allocation.width = MAX (1, child_allocation.width - + widget->style->klass->xthickness * 2); + child_allocation.height = MAX (1, child_allocation.height - + widget->style->klass->ythickness * 2); - if (notebook->show_tabs && notebook->children) + if (notebook->show_tabs && notebook->children && notebook->cur_page) { switch (notebook->tab_pos) { case GTK_POS_TOP: child_allocation.y += notebook->cur_page->requisition.height; case GTK_POS_BOTTOM: - child_allocation.height = MAX (1, - child_allocation.height - notebook->cur_page->requisition.height); + child_allocation.height = + MAX (1, child_allocation.height - + notebook->cur_page->requisition.height); break; case GTK_POS_LEFT: child_allocation.x += notebook->cur_page->requisition.width; case GTK_POS_RIGHT: - child_allocation.width = MAX (1, - child_allocation.width - notebook->cur_page->requisition.width); + child_allocation.width = + MAX (1, child_allocation.width - + notebook->cur_page->requisition.width); break; } } @@ -1651,144 +874,6 @@ gtk_notebook_size_allocate (GtkWidget *widget, gtk_notebook_set_shape (notebook); } -static void -gtk_notebook_paint (GtkWidget *widget, - GdkRectangle *area) -{ - GtkNotebook *notebook; - GtkNotebookPage *page; - GList *children; - gint width, height; - gint x, y; - gint showarrow; - gint gap_x = 0, gap_width = 0; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - g_return_if_fail (area != NULL); - - if (GTK_WIDGET_DRAWABLE (widget)) - { - notebook = GTK_NOTEBOOK (widget); - - if (notebook->show_tabs || notebook->show_border) - { - x = GTK_CONTAINER (widget)->border_width; - y = GTK_CONTAINER (widget)->border_width; - width = widget->allocation.width - x * 2; - height = widget->allocation.height - y * 2; - - if (notebook->show_tabs && notebook->children) - { - - if (!GTK_WIDGET_MAPPED (notebook->cur_page->tab_label)) - { - GtkNotebookPage *page; - - page = notebook->first_tab->data; - - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += page->allocation.height + - widget->style->klass->ythickness; - case GTK_POS_BOTTOM: - height -= page->allocation.height + - widget->style->klass->ythickness; - break; - case GTK_POS_LEFT: - x += page->allocation.width + - widget->style->klass->xthickness; - case GTK_POS_RIGHT: - width -= page->allocation.width + - widget->style->klass->xthickness; - break; - } - gtk_paint_box (widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - area, widget, "notebook", - x, y, width, height); - } - else - { - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += notebook->cur_page->allocation.height; - case GTK_POS_BOTTOM: - height -= notebook->cur_page->allocation.height; - break; - case GTK_POS_LEFT: - x += notebook->cur_page->allocation.width; - case GTK_POS_RIGHT: - width -= notebook->cur_page->allocation.width; - break; - } - - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - gap_x = notebook->cur_page->allocation.x - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.width; - break; - case GTK_POS_BOTTOM: - gap_x = notebook->cur_page->allocation.x - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.width; - break; - case GTK_POS_LEFT: - gap_x = notebook->cur_page->allocation.y - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.height; - break; - case GTK_POS_RIGHT: - gap_x = notebook->cur_page->allocation.y - - GTK_CONTAINER(notebook)->border_width; - gap_width = notebook->cur_page->allocation.height; - break; - } - gtk_paint_box_gap(widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - area, widget, "notebook", - x, y, width, height, - notebook->tab_pos, gap_x, gap_width); - } - children = g_list_last (notebook->children); - showarrow = FALSE; - - while (children) - { - page = children->data; - children = children->prev; - - if (!GTK_WIDGET_MAPPED (page->tab_label)) - showarrow = TRUE; - else if (notebook->cur_page != page) - gtk_notebook_draw_tab (notebook, page, area); - } - - if (showarrow && notebook->scrollable && notebook->show_tabs) - { - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); - } - if (notebook->cur_page && - GTK_WIDGET_MAPPED(((GtkNotebookPage *) - (notebook->cur_page))->tab_label)) - gtk_notebook_draw_tab (notebook, notebook->cur_page, area); - } - else if (notebook->show_border) - { - gtk_paint_box(widget->style, widget->window, - GTK_STATE_NORMAL, GTK_SHADOW_OUT, - area, widget, "notebook", - x, y, width, height); - } - } - } -} - static void gtk_notebook_draw (GtkWidget *widget, GdkRectangle *area) @@ -1832,8 +917,8 @@ gtk_notebook_expose (GtkWidget *widget, gtk_notebook_paint (widget, &event->area); if (notebook->cur_page && gtk_widget_intersect (notebook->cur_page->tab_label, - &event->area, &child_area)) - gtk_widget_draw_focus (widget); + &event->area, &child_area)) + gtk_widget_draw_focus (widget); child_event = *event; if (notebook->cur_page && @@ -1861,8 +946,8 @@ gtk_notebook_button_press (GtkWidget *widget, notebook = GTK_NOTEBOOK (widget); - if (event->type != GDK_BUTTON_PRESS || !notebook->children - || notebook->button) + if (event->type != GDK_BUTTON_PRESS || !notebook->children || + notebook->button) return FALSE; if (event->window == notebook->panel) @@ -1872,13 +957,15 @@ gtk_notebook_button_press (GtkWidget *widget, gtk_grab_add (widget); notebook->button = event->button; - + if (event->x <= ARROW_SIZE + ARROW_SPACING / 2) { notebook->click_child = GTK_ARROW_LEFT; if (event->button == 1) { - if (!notebook->focus_tab || notebook->focus_tab->prev) + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)) gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT); if (!notebook->timer) @@ -1892,7 +979,11 @@ gtk_notebook_button_press (GtkWidget *widget, else if (event->button == 2) gtk_notebook_page_select (GTK_NOTEBOOK (widget)); else if (event->button == 3) - gtk_notebook_switch_focus_tab (notebook, notebook->children); + gtk_notebook_switch_focus_tab (notebook, + gtk_notebook_search_page (notebook, + NULL, + STEP_NEXT, + TRUE)); gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); } else @@ -1900,8 +991,11 @@ gtk_notebook_button_press (GtkWidget *widget, notebook->click_child = GTK_ARROW_RIGHT; if (event->button == 1) { - if (!notebook->focus_tab || notebook->focus_tab->next) + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)) gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT); + if (!notebook->timer) { notebook->timer = gtk_timeout_add @@ -1913,8 +1007,9 @@ gtk_notebook_button_press (GtkWidget *widget, else if (event->button == 2) gtk_notebook_page_select (GTK_NOTEBOOK (widget)); else if (event->button == 3) - gtk_notebook_switch_focus_tab (notebook, - g_list_last (notebook->children)); + gtk_notebook_switch_focus_tab + (notebook, gtk_notebook_search_page (notebook, NULL, + STEP_PREV, TRUE)); gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); } } @@ -2113,6 +1208,603 @@ gtk_notebook_motion_notify (GtkWidget *widget, return FALSE; } +static gint +gtk_notebook_key_press (GtkWidget *widget, + GdkEventKey *event) +{ + GtkNotebook *notebook; + GtkDirectionType direction = 0; + GList *list; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + notebook = GTK_NOTEBOOK (widget); + + if (!notebook->children || !notebook->show_tabs) + return FALSE; + + switch (event->keyval) + { + case GDK_Up: + direction = GTK_DIR_UP; + break; + case GDK_Left: + direction = GTK_DIR_LEFT; + break; + case GDK_Down: + direction = GTK_DIR_DOWN; + break; + case GDK_Right: + direction = GTK_DIR_RIGHT; + break; + case GDK_Tab: + case GDK_ISO_Left_Tab: + if (event->state & GDK_SHIFT_MASK) + direction = GTK_DIR_TAB_BACKWARD; + else + direction = GTK_DIR_TAB_FORWARD; + break; + case GDK_Home: + list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); + if (list) + gtk_notebook_switch_focus_tab (notebook, list); + return TRUE; + case GDK_End: + list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE); + if (list) + gtk_notebook_switch_focus_tab (notebook, list); + return TRUE; + case GDK_Return: + case GDK_space: + gtk_notebook_page_select (GTK_NOTEBOOK (widget)); + return TRUE; + default: + return FALSE; + } + return gtk_container_focus (GTK_CONTAINER (widget), direction); +} + +static gint +gtk_notebook_focus_in (GtkWidget *widget, + GdkEventFocus *event) +{ + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + GTK_NOTEBOOK (widget)->child_has_focus = FALSE; + GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); + gtk_widget_draw_focus (widget); + + return FALSE; +} + +static gint +gtk_notebook_focus_out (GtkWidget *widget, + GdkEventFocus *event) +{ + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); + gtk_widget_draw_focus (widget); + + return FALSE; +} + +static void +gtk_notebook_draw_focus (GtkWidget *widget) +{ + GtkNotebook *notebook; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + + notebook = GTK_NOTEBOOK (widget); + + if (GTK_WIDGET_DRAWABLE (widget) && notebook->show_tabs && + notebook->focus_tab) + { + GtkNotebookPage *page; + GdkRectangle area; + + page = notebook->focus_tab->data; + + area.x = widget->allocation.x; + area.y = widget->allocation.y; + area.width = widget->allocation.width; + area.height = widget->allocation.height; + + gtk_notebook_draw_tab(GTK_NOTEBOOK(widget), page, &area); + } +} + +static void +gtk_notebook_style_set (GtkWidget *widget, + GtkStyle *previous_style) +{ + if (GTK_WIDGET_REALIZED (widget) && + !GTK_WIDGET_NO_WINDOW (widget)) + { + gtk_style_set_background (widget->style, widget->window, widget->state); + if (GTK_WIDGET_DRAWABLE (widget)) + gdk_window_clear (widget->window); + } + + gtk_widget_queue_draw (widget); + gtk_notebook_set_shape (GTK_NOTEBOOK(widget)); +} + +/* Private GtkContainer Methods : + * + * gtk_notebook_set_child_arg + * gtk_notebook_get_child_arg + * gtk_notebook_add + * gtk_notebook_remove + * gtk_notebook_focus + * gtk_notebook_set_focus_child + * gtk_notebook_child_type + * gtk_notebook_forall + */ +static void +gtk_notebook_set_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id) +{ + gboolean expand; + gboolean fill; + GtkPackType pack_type; + + switch (arg_id) + { + case CHILD_ARG_TAB_LABEL: + /* a NULL pointer indicates a default_tab setting, otherwise + * we need to set the associated label + */ + gtk_notebook_set_tab_label_text (GTK_NOTEBOOK (container), child, + GTK_VALUE_STRING(*arg)); + break; + case CHILD_ARG_MENU_LABEL: + gtk_notebook_set_menu_label_text (GTK_NOTEBOOK (container), child, + GTK_VALUE_STRING (*arg)); + break; + case CHILD_ARG_POSITION: + gtk_notebook_reorder_child (GTK_NOTEBOOK (container), child, + GTK_VALUE_INT (*arg)); + break; + case CHILD_ARG_TAB_EXPAND: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child, + GTK_VALUE_BOOL (*arg), + fill, pack_type); + break; + case CHILD_ARG_TAB_FILL: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child, + expand, + GTK_VALUE_BOOL (*arg), + pack_type); + break; + case CHILD_ARG_TAB_PACK: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (container), child, + expand, fill, + GTK_VALUE_BOOL (*arg)); + break; + default: + break; + } +} + +static void +gtk_notebook_get_child_arg (GtkContainer *container, + GtkWidget *child, + GtkArg *arg, + guint arg_id) +{ + GList *list; + GtkNotebook *notebook; + GtkWidget *label; + gboolean expand; + gboolean fill; + GtkPackType pack_type; + + notebook = GTK_NOTEBOOK (container); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + { + arg->type = GTK_TYPE_INVALID; + return; + } + + switch (arg_id) + { + case CHILD_ARG_TAB_LABEL: + label = gtk_notebook_query_tab_label (notebook, child); + + if (label && GTK_IS_LABEL (label)) + GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label); + else + GTK_VALUE_STRING (*arg) = NULL; + break; + case CHILD_ARG_MENU_LABEL: + label = gtk_notebook_query_menu_label (notebook, child); + + if (label && GTK_IS_LABEL (label)) + GTK_VALUE_STRING (*arg) = g_strdup (GTK_LABEL (label)->label); + else + GTK_VALUE_STRING (*arg) = NULL; + break; + case CHILD_ARG_POSITION: + GTK_VALUE_INT (*arg) = g_list_position (notebook->children, list); + break; + case CHILD_ARG_TAB_EXPAND: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + &expand, NULL, NULL); + GTK_VALUE_BOOL (*arg) = expand; + break; + case CHILD_ARG_TAB_FILL: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + NULL, &fill, NULL); + GTK_VALUE_BOOL (*arg) = fill; + break; + case CHILD_ARG_TAB_PACK: + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (container), child, + NULL, NULL, &pack_type); + GTK_VALUE_BOOL (*arg) = pack_type; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +static void +gtk_notebook_add (GtkContainer *container, + GtkWidget *widget) +{ + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); + + gtk_notebook_insert_page_menu (GTK_NOTEBOOK (container), widget, + NULL, NULL, -1); +} + +static void +gtk_notebook_remove (GtkContainer *container, + GtkWidget *widget) +{ + GtkNotebook *notebook; + GtkNotebookPage *page; + GList *children; + guint page_num; + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); + g_return_if_fail (widget != NULL); + + notebook = GTK_NOTEBOOK (container); + + children = notebook->children; + page_num = 0; + while (children) + { + page = children->data; + if (page->child == widget) + { + gtk_notebook_real_remove (notebook, children); + break; + } + page_num++; + children = children->next; + } +} + +static gint +gtk_notebook_focus (GtkContainer *container, + GtkDirectionType direction) +{ + GtkNotebook *notebook; + GtkWidget *focus_child; + GtkNotebookPage *page = NULL; + GtkNotebookPage *old_page = NULL; + + g_return_val_if_fail (container != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (container), FALSE); + + notebook = GTK_NOTEBOOK (container); + + if (!GTK_WIDGET_DRAWABLE (notebook) || !GTK_WIDGET_SENSITIVE (container) || + !notebook->children || !notebook->cur_page) + return FALSE; + + focus_child = container->focus_child; + gtk_container_set_focus_child (container, NULL); + + if (!notebook->show_tabs) + { + if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) && + GTK_WIDGET_SENSITIVE (notebook->cur_page->child)) + { + if (GTK_IS_CONTAINER (notebook->cur_page->child)) + { + if (gtk_container_focus + (GTK_CONTAINER (notebook->cur_page->child), direction)) + return TRUE; + } + else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child)) + { + if (!focus_child) + { + gtk_widget_grab_focus (notebook->cur_page->child); + return TRUE; + } + } + } + return FALSE; + } + + if (notebook->focus_tab) + old_page = notebook->focus_tab->data; + + if (focus_child && old_page && focus_child == old_page->child && + notebook->child_has_focus) + { + if (GTK_WIDGET_DRAWABLE (old_page->child)) + { + if (GTK_IS_CONTAINER (old_page->child) && + !GTK_WIDGET_HAS_FOCUS (old_page->child)) + { + if (gtk_container_focus (GTK_CONTAINER (old_page->child), + direction)) + return TRUE; + } + gtk_widget_grab_focus (GTK_WIDGET(notebook)); + return TRUE; + } + return FALSE; + } + + switch (direction) + { + case GTK_DIR_TAB_FORWARD: + case GTK_DIR_RIGHT: + case GTK_DIR_DOWN: + gtk_notebook_switch_focus_tab + (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)); + break; + case GTK_DIR_TAB_BACKWARD: + case GTK_DIR_LEFT: + case GTK_DIR_UP: + gtk_notebook_switch_focus_tab + (notebook, gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)); + break; + } + + if (notebook->focus_tab) + { + if (!GTK_WIDGET_HAS_FOCUS (container)) + gtk_widget_grab_focus (GTK_WIDGET (container)); + + page = notebook->focus_tab->data; + if (GTK_WIDGET_MAPPED (page->tab_label)) + gtk_notebook_focus_changed (notebook, old_page); + else + { + gtk_notebook_pages_allocate (notebook, + &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); + } + return TRUE; + } + + gtk_notebook_focus_changed (notebook, old_page); + return FALSE; +} + +static void +gtk_notebook_set_focus_child (GtkContainer *container, + GtkWidget *child) +{ + GtkNotebook *notebook; + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); + + if (child) + { + g_return_if_fail (GTK_IS_WIDGET (child)); + + notebook = GTK_NOTEBOOK (container); + + notebook->child_has_focus = TRUE; + if (!notebook->focus_tab) + { + GList *children; + GtkNotebookPage *page; + + children = notebook->children; + while (children) + { + page = children->data; + if (page->child == child || page->tab_label == child) + gtk_notebook_switch_focus_tab (notebook, children); + children = children->next; + } + } + } + parent_class->set_focus_child (container, child); +} + +static void +gtk_notebook_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + GtkNotebook *notebook; + GList *children; + + g_return_if_fail (container != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (container)); + g_return_if_fail (callback != NULL); + + notebook = GTK_NOTEBOOK (container); + + children = notebook->children; + while (children) + { + GtkNotebookPage *page; + + page = children->data; + children = children->next; + (* callback) (page->child, callback_data); + if (include_internals) + { + if (page->tab_label) + (* callback) (page->tab_label, callback_data); + if (page->menu_label) + (* callback) (page->menu_label, callback_data); + } + } +} + +static GtkType +gtk_notebook_child_type (GtkContainer *container) +{ + return GTK_TYPE_WIDGET; +} + +/* Private GtkNotebook Functions: + * + * gtk_notebook_panel_realize + * gtk_notebook_expose_tabs + * gtk_notebook_focus_changed + * gtk_notebook_real_remove + * gtk_notebook_update_labels + * gtk_notebook_timer + * gtk_notebook_page_compare + * gtk_notebook_real_page_position + * gtk_notebook_search_page + */ +static void +gtk_notebook_panel_realize (GtkNotebook *notebook) +{ + GtkWidget *widget; + GdkWindowAttr attributes; + gint attributes_mask; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + widget = GTK_WIDGET (notebook); + + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = gtk_widget_get_events (widget); + attributes.event_mask |= GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK + | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + attributes.width = 2 * ARROW_SIZE + ARROW_SPACING; + attributes.height = ARROW_SIZE; + + attributes.x = (widget->allocation.width - attributes.width - + GTK_CONTAINER (notebook)->border_width); + attributes.y = (widget->allocation.height - ARROW_SIZE - + GTK_CONTAINER (notebook)->border_width); + if (notebook->tab_pos == GTK_POS_TOP) + attributes.y = GTK_CONTAINER (notebook)->border_width; + else if (notebook->tab_pos == GTK_POS_LEFT) + attributes.x = (widget->allocation.x + + GTK_CONTAINER (notebook)->border_width); + + notebook->panel = gdk_window_new (widget->window, &attributes, + attributes_mask); + gtk_style_set_background (widget->style, notebook->panel, + GTK_STATE_NORMAL); + gdk_window_set_back_pixmap (widget->window, NULL, TRUE); + gdk_window_set_user_data (notebook->panel, widget); +} + +static void +gtk_notebook_expose_tabs (GtkNotebook *notebook) +{ + GtkWidget *widget; + GtkNotebookPage *page; + GdkEventExpose event; + gint border; + + widget = GTK_WIDGET (notebook); + border = GTK_CONTAINER (notebook)->border_width; + + if (!GTK_WIDGET_MAPPED (notebook) || !notebook->first_tab) + return; + + page = notebook->first_tab->data; + + event.type = GDK_EXPOSE; + event.window = widget->window; + event.count = 0; + event.area.x = border; + event.area.y = border; + + switch (notebook->tab_pos) + { + case GTK_POS_BOTTOM: + event.area.y = (widget->allocation.height - border - + page->allocation.height - + widget->style->klass->ythickness); + if (page != notebook->cur_page) + event.area.y -= widget->style->klass->ythickness; + case GTK_POS_TOP: + event.area.width = widget->allocation.width - 2 * border; + event.area.height = (page->allocation.height + + widget->style->klass->ythickness); + if (page != notebook->cur_page) + event.area.height += widget->style->klass->ythickness; + break; + case GTK_POS_RIGHT: + event.area.x = (widget->allocation.width - border - + page->allocation.width - + widget->style->klass->xthickness); + if (page != notebook->cur_page) + event.area.x -= widget->style->klass->xthickness; + case GTK_POS_LEFT: + event.area.width = (page->allocation.width + + widget->style->klass->xthickness); + event.area.height = widget->allocation.height - 2 * border; + if (page != notebook->cur_page) + event.area.width += widget->style->klass->xthickness; + break; + } + gtk_widget_event (widget, (GdkEvent *) &event); +} + +static void +gtk_notebook_focus_changed (GtkNotebook *notebook, + GtkNotebookPage *old_page) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + gtk_notebook_expose_tabs(notebook); +} + static gint gtk_notebook_timer (GtkNotebook *notebook) { @@ -2123,21 +1815,24 @@ gtk_notebook_timer (GtkNotebook *notebook) { if (notebook->click_child == GTK_ARROW_LEFT) { - if (!notebook->focus_tab || notebook->focus_tab->prev) + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)) gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_LEFT); } else if (notebook->click_child == GTK_ARROW_RIGHT) { - if (!notebook->focus_tab || notebook->focus_tab->next) + if (!notebook->focus_tab || + gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)) gtk_container_focus (GTK_CONTAINER (notebook), GTK_DIR_RIGHT); } - if (notebook->need_timer) { notebook->need_timer = FALSE; - notebook->timer = gtk_timeout_add - (NOTEBOOK_SCROLL_DELAY, (GtkFunction) gtk_notebook_timer, - (gpointer) notebook); + notebook->timer = gtk_timeout_add (NOTEBOOK_SCROLL_DELAY, + (GtkFunction) gtk_notebook_timer, + (gpointer) notebook); return FALSE; } return TRUE; @@ -2145,113 +1840,343 @@ gtk_notebook_timer (GtkNotebook *notebook) return FALSE; } -static void -gtk_notebook_draw_arrow (GtkNotebook *notebook, guint arrow) +static gint +gtk_notebook_page_compare (gconstpointer a, + gconstpointer b) { - GtkStateType state_type; - GtkShadowType shadow_type; - GtkWidget *widget; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - widget = GTK_WIDGET(notebook); - - if (GTK_WIDGET_DRAWABLE (notebook)) - { - if (notebook->in_child == arrow) - { - if (notebook->click_child == arrow) - state_type = GTK_STATE_ACTIVE; - else - state_type = GTK_STATE_PRELIGHT; - } - else - state_type = GTK_STATE_NORMAL; - - if (notebook->click_child == arrow) - shadow_type = GTK_SHADOW_IN; - else - shadow_type = GTK_SHADOW_OUT; - - if (arrow == GTK_ARROW_LEFT) - { - if (notebook->focus_tab && !notebook->focus_tab->prev) - { - shadow_type = GTK_SHADOW_ETCHED_IN; - state_type = GTK_STATE_NORMAL; - } - - if (notebook->tab_pos == GTK_POS_LEFT || - notebook->tab_pos == GTK_POS_RIGHT) - arrow = GTK_ARROW_UP; - - gdk_window_clear_area (notebook->panel, 0, 0, ARROW_SIZE, ARROW_SIZE); - gtk_paint_arrow (widget->style, notebook->panel, state_type, - shadow_type, NULL, GTK_WIDGET(notebook), "notebook", - arrow, TRUE, - 0, 0, ARROW_SIZE, ARROW_SIZE); - } - else - { - if (notebook->focus_tab && !notebook->focus_tab->next) - { - shadow_type = GTK_SHADOW_ETCHED_IN; - state_type = GTK_STATE_NORMAL; - } - - if (notebook->tab_pos == GTK_POS_LEFT || - notebook->tab_pos == GTK_POS_RIGHT) - arrow = GTK_ARROW_DOWN; - gdk_window_clear_area(notebook->panel, ARROW_SIZE + ARROW_SPACING, - 0, ARROW_SIZE, ARROW_SIZE); - gtk_paint_arrow (widget->style, notebook->panel, state_type, - shadow_type, NULL, GTK_WIDGET(notebook), "notebook", - arrow, TRUE, ARROW_SIZE + ARROW_SPACING, - 0, ARROW_SIZE, ARROW_SIZE); - } - } + return (((GtkNotebookPage *) a)->child != b); } static void -gtk_notebook_real_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num) +gtk_notebook_real_remove (GtkNotebook *notebook, + GList *list) { - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (page != NULL); + GtkNotebookPage *page; + GList * next_list; + gint need_resize = FALSE; - if (notebook->cur_page == page) + next_list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE); + if (!next_list) + next_list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE); + + if (notebook->cur_page == list->data) + { + notebook->cur_page = NULL; + if (next_list) + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (next_list), -1); + } + + if (list == notebook->first_tab) + notebook->first_tab = next_list; + if (list == notebook->focus_tab) + gtk_notebook_switch_focus_tab (notebook, next_list); + + page = list->data; + + if (GTK_WIDGET_VISIBLE (page->child) && GTK_WIDGET_VISIBLE (notebook)) + need_resize = TRUE; + + gtk_widget_unparent (page->child); + + if (page->tab_label) + gtk_widget_unparent (page->tab_label); + + if (notebook->menu) + { + gtk_container_remove (GTK_CONTAINER (notebook->menu), + page->menu_label->parent); + gtk_widget_queue_resize (notebook->menu); + } + if (!page->default_menu) + gtk_widget_unref (page->menu_label); + + notebook->children = g_list_remove_link (notebook->children, list); + g_list_free (list); + g_free (page); + + gtk_notebook_update_labels (notebook); + if (need_resize) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} + +static void +gtk_notebook_update_labels (GtkNotebook *notebook) +{ + GtkNotebookPage *page; + GList *list; + gchar string[32]; + gint page_num = 1; + + for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE); + list; + list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE)) + { + page = list->data; + sprintf (string, "Page %u", page_num++); + if (notebook->show_tabs) + { + if (page->default_tab) + { + if (!page->tab_label) + { + page->tab_label = gtk_label_new (string); + gtk_widget_set_parent (page->tab_label, + GTK_WIDGET (notebook)); + } + else + gtk_label_set (GTK_LABEL (page->tab_label), string); + } + + if (GTK_WIDGET_VISIBLE (page->child) && + !GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_show (page->tab_label); + else if (!GTK_WIDGET_VISIBLE (page->child) && + GTK_WIDGET_VISIBLE (page->tab_label)) + gtk_widget_hide (page->tab_label); + } + if (notebook->menu && page->default_menu) + { + if (page->tab_label && GTK_IS_LABEL (page->tab_label)) + gtk_label_set (GTK_LABEL (page->menu_label), + GTK_LABEL (page->tab_label)->label); + else + gtk_label_set (GTK_LABEL (page->menu_label), string); + } + } +} + +static gint +gtk_notebook_real_page_position (GtkNotebook *notebook, + GList *list) +{ + GList *work; + gint count_start; + + g_return_val_if_fail (notebook != NULL, -1); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); + g_return_val_if_fail (list != NULL, -1); + + for (work = notebook->children, count_start = 0; + work && work != list; work = work->next) + if (GTK_NOTEBOOK_PAGE (work)->pack == GTK_PACK_START) + count_start++; + + if (!work) + return -1; + + if (GTK_NOTEBOOK_PAGE (list)->pack == GTK_PACK_START) + return count_start; + + return (count_start + g_list_length (list) - 1); +} + +static GList * +gtk_notebook_search_page (GtkNotebook *notebook, + GList *list, + gint direction, + gboolean find_visible) +{ + GtkNotebookPage *page = NULL; + GList *old_list = NULL; + gint flag = 0; + + g_return_val_if_fail (notebook != NULL, NULL); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + + switch (direction) + { + case STEP_PREV: + flag = GTK_PACK_END; + break; + + case STEP_NEXT: + flag = GTK_PACK_START; + break; + } + + if (list) + page = list->data; + + if (!page || page->pack == flag) + { + if (list) + { + old_list = list; + list = list->next; + } + else + list = notebook->children; + + while (list) + { + page = list->data; + if (page->pack == flag && + (!find_visible || GTK_WIDGET_VISIBLE (page->child))) + return list; + old_list = list; + list = list->next; + } + list = old_list; + } + else + { + old_list = list; + list = list->prev; + } + while (list) + { + page = list->data; + if (page->pack != flag && + (!find_visible || GTK_WIDGET_VISIBLE (page->child))) + return list; + old_list = list; + list = list->prev; + } + return NULL; +} + +/* Private GtkNotebook Drawing Functions: + * + * gtk_notebook_paint + * gtk_notebook_draw_tab + * gtk_notebook_draw_arrow + * gtk_notebook_set_shape + */ +static void +gtk_notebook_paint (GtkWidget *widget, + GdkRectangle *area) +{ + GtkNotebook *notebook; + GtkNotebookPage *page; + GList *children; + gboolean showarrow; + gint width, height; + gint x, y; + gint gap_x = 0, gap_width = 0; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + g_return_if_fail (area != NULL); + + if (!GTK_WIDGET_DRAWABLE (widget)) return; - if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child)) - gtk_widget_unmap (notebook->cur_page->child); - - notebook->cur_page = page; + notebook = GTK_NOTEBOOK (widget); - if (!notebook->focus_tab || - notebook->focus_tab->data != (gpointer) notebook->cur_page) - notebook->focus_tab = - g_list_find (notebook->children, notebook->cur_page); - - gtk_notebook_pages_allocate (notebook, >K_WIDGET (notebook)->allocation); - - if (GTK_WIDGET_MAPPED (notebook)) + if ((!notebook->show_tabs && !notebook->show_border) || + !notebook->cur_page || !GTK_WIDGET_VISIBLE (notebook->cur_page->child)) { - if (GTK_WIDGET_REALIZED (notebook->cur_page->child)) - gtk_widget_map (notebook->cur_page->child); - else - { - gtk_widget_map (notebook->cur_page->child); - gtk_widget_size_allocate (GTK_WIDGET (notebook), - >K_WIDGET (notebook)->allocation); - } + gdk_window_clear_area (widget->window, + area->x, area->y, + area->width, area->height); + return; } - - if (GTK_WIDGET_DRAWABLE (notebook)) - gtk_widget_queue_draw (GTK_WIDGET (notebook)); - gtk_notebook_set_shape (notebook); + + x = GTK_CONTAINER (widget)->border_width; + y = GTK_CONTAINER (widget)->border_width; + width = widget->allocation.width - x * 2; + height = widget->allocation.height - y * 2; + + if (notebook->show_border && (!notebook->show_tabs || !notebook->children)) + { + + gtk_paint_box(widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + area, widget, "notebook", + x, y, width, height); + return; + } + + + if (!GTK_WIDGET_MAPPED (notebook->cur_page->tab_label)) + { + page = notebook->first_tab->data; + + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + y += page->allocation.height + widget->style->klass->ythickness; + case GTK_POS_BOTTOM: + height -= page->allocation.height + widget->style->klass->ythickness; + break; + case GTK_POS_LEFT: + x += page->allocation.width + widget->style->klass->xthickness; + case GTK_POS_RIGHT: + width -= page->allocation.width + widget->style->klass->xthickness; + break; + } + gtk_paint_box (widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + area, widget, "notebook", + x, y, width, height); + } + else + { + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + y += notebook->cur_page->allocation.height; + case GTK_POS_BOTTOM: + height -= notebook->cur_page->allocation.height; + break; + case GTK_POS_LEFT: + x += notebook->cur_page->allocation.width; + case GTK_POS_RIGHT: + width -= notebook->cur_page->allocation.width; + break; + } + + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + gap_x = (notebook->cur_page->allocation.x - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.width; + break; + case GTK_POS_BOTTOM: + gap_x = (notebook->cur_page->allocation.x - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.width; + break; + case GTK_POS_LEFT: + gap_x = (notebook->cur_page->allocation.y - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.height; + break; + case GTK_POS_RIGHT: + gap_x = (notebook->cur_page->allocation.y - + GTK_CONTAINER(notebook)->border_width); + gap_width = notebook->cur_page->allocation.height; + break; + } + gtk_paint_box_gap(widget->style, widget->window, + GTK_STATE_NORMAL, GTK_SHADOW_OUT, + area, widget, "notebook", + x, y, width, height, + notebook->tab_pos, gap_x, gap_width); + } + + showarrow = FALSE; + children = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE); + while (children) + { + page = children->data; + children = gtk_notebook_search_page (notebook, children, + STEP_PREV, TRUE); + if (!GTK_WIDGET_VISIBLE (page->child)) + continue; + if (!GTK_WIDGET_MAPPED (page->tab_label)) + showarrow = TRUE; + else if (page != notebook->cur_page) + gtk_notebook_draw_tab (notebook, page, area); + } + + if (showarrow && notebook->scrollable) + { + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + } + gtk_notebook_draw_tab (notebook, notebook->cur_page, area); } static void @@ -2326,162 +2251,202 @@ gtk_notebook_draw_tab (GtkNotebook *notebook, } static void -gtk_notebook_set_focus_child (GtkContainer *container, - GtkWidget *child) +gtk_notebook_draw_arrow (GtkNotebook *notebook, + guint arrow) { - GtkNotebook *notebook; + GtkStateType state_type; + GtkShadowType shadow_type; + GtkWidget *widget; - g_return_if_fail (container != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (container)); - - if (child) - { - g_return_if_fail (GTK_IS_WIDGET (child)); - - notebook = GTK_NOTEBOOK (container); - - notebook->child_has_focus = TRUE; - if (!notebook->focus_tab) - { - GList *children; - GtkNotebookPage *page; - - children = notebook->children; - while (children) - { - page = children->data; - if (page->child == child || page->tab_label == child) - gtk_notebook_switch_focus_tab (notebook, children); - children = children->next; - } - } - } - parent_class->set_focus_child (container, child); -} - -static gint -gtk_notebook_focus_in (GtkWidget *widget, - GdkEventFocus *event) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - GTK_NOTEBOOK (widget)->child_has_focus = FALSE; - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - gtk_widget_draw_focus (widget); - - return FALSE; -} - -static gint -gtk_notebook_focus_out (GtkWidget *widget, - GdkEventFocus *event) -{ - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - gtk_widget_draw_focus (widget); - - return FALSE; -} - -static void -gtk_notebook_draw_focus (GtkWidget *widget) -{ - GtkNotebook *notebook; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); - - notebook = GTK_NOTEBOOK (widget); - - if (GTK_WIDGET_DRAWABLE (widget) && notebook->show_tabs && - notebook->focus_tab) - { - GtkNotebookPage *page; - GdkRectangle area; - - page = notebook->focus_tab->data; - - area.x = widget->allocation.x; - area.y = widget->allocation.y; - area.width = widget->allocation.width; - area.height = widget->allocation.height; - - gtk_notebook_draw_tab(GTK_NOTEBOOK(widget), page, &area); - } -} - -static void -gtk_notebook_focus_changed (GtkNotebook *notebook, GtkNotebookPage *old_page) -{ g_return_if_fail (notebook != NULL); g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - gtk_notebook_expose_tabs(notebook); -} + widget = GTK_WIDGET(notebook); -static void -gtk_notebook_calc_tabs (GtkNotebook *notebook, - GList *start, - GList **end, - gint *tab_space, - guint direction) -{ - GtkNotebookPage *page = NULL; - GList *children; - - children = start; - switch (notebook->tab_pos) + if (GTK_WIDGET_DRAWABLE (notebook)) { - case GTK_POS_TOP: - case GTK_POS_BOTTOM: - while (children) + if (notebook->in_child == arrow) + { + if (notebook->click_child == arrow) + state_type = GTK_STATE_ACTIVE; + else + state_type = GTK_STATE_PRELIGHT; + } + else + state_type = GTK_STATE_NORMAL; + + if (notebook->click_child == arrow) + shadow_type = GTK_SHADOW_IN; + else + shadow_type = GTK_SHADOW_OUT; + + if (arrow == GTK_ARROW_LEFT) { - page = children->data; - *tab_space -= page->requisition.width; - if (*tab_space < 0 || children == *end) + if (notebook->focus_tab && + !gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_PREV, TRUE)) { - if (*tab_space < 0) - { - *tab_space = - (*tab_space + page->requisition.width); - *end = children; - } - break; + shadow_type = GTK_SHADOW_ETCHED_IN; + state_type = GTK_STATE_NORMAL; } - if (direction == STEP_NEXT) - children = children->next; - else - children = children->prev; + + if (notebook->tab_pos == GTK_POS_LEFT || + notebook->tab_pos == GTK_POS_RIGHT) + arrow = GTK_ARROW_UP; + + gdk_window_clear_area (notebook->panel, 0, 0, ARROW_SIZE, ARROW_SIZE); + gtk_paint_arrow (widget->style, notebook->panel, state_type, + shadow_type, NULL, GTK_WIDGET(notebook), "notebook", + arrow, TRUE, + 0, 0, ARROW_SIZE, ARROW_SIZE); } - break; - case GTK_POS_LEFT: - case GTK_POS_RIGHT: - while (children) + else { - page = children->data; - *tab_space -= page->requisition.height; - if (*tab_space < 0 || children == *end) + if (notebook->focus_tab && + !gtk_notebook_search_page (notebook, notebook->focus_tab, + STEP_NEXT, TRUE)) { - if (*tab_space < 0) - { - *tab_space = - (*tab_space + page->requisition.height); - *end = children; - } - break; + shadow_type = GTK_SHADOW_ETCHED_IN; + state_type = GTK_STATE_NORMAL; } - if (direction == STEP_NEXT) - children = children->next; - else - children = children->prev; + + if (notebook->tab_pos == GTK_POS_LEFT || + notebook->tab_pos == GTK_POS_RIGHT) + arrow = GTK_ARROW_DOWN; + + gdk_window_clear_area(notebook->panel, ARROW_SIZE + ARROW_SPACING, + 0, ARROW_SIZE, ARROW_SIZE); + gtk_paint_arrow (widget->style, notebook->panel, state_type, + shadow_type, NULL, GTK_WIDGET(notebook), "notebook", + arrow, TRUE, ARROW_SIZE + ARROW_SPACING, + 0, ARROW_SIZE, ARROW_SIZE); } - break; } } +static void +gtk_notebook_set_shape (GtkNotebook *notebook) +{ + GtkWidget *widget = NULL; + GdkPixmap *pm = NULL; + GdkGC *pmgc = NULL; + GdkColor col; + gint x, y, width, height, w, h, depth; + GtkNotebookPage *page; + GList *children; + + if (!GTK_WIDGET(notebook)->window) + return; + + widget = GTK_WIDGET(notebook); + + w = widget->allocation.width; + h = widget->allocation.height; + + pm = gdk_pixmap_new (widget->window, w, h, 1); + pmgc = gdk_gc_new (pm); + + /* clear the shape mask */ + col.pixel = 0; + gdk_gc_set_foreground(pmgc, &col); + gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, w, h); + + col.pixel = 1; + gdk_gc_set_foreground(pmgc, &col); + + /* draw the shape for the notebook page itself */ + x = GTK_CONTAINER(notebook)->border_width; + y = GTK_CONTAINER(notebook)->border_width; + width = widget->allocation.width - x * 2; + height = widget->allocation.height - y * 2; + + if (notebook->show_tabs && notebook->children) + { + if (!(notebook->show_tabs)) + { + page = notebook->first_tab->data; + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + y += page->allocation.height + + widget->style->klass->ythickness; + case GTK_POS_BOTTOM: + height -= page->allocation.height + + widget->style->klass->ythickness; + break; + case GTK_POS_LEFT: + x += page->allocation.width + + widget->style->klass->xthickness; + case GTK_POS_RIGHT: + width -= page->allocation.width + + widget->style->klass->xthickness; + break; + } + } + else + { + page = notebook->cur_page; + if (!GTK_WIDGET_MAPPED (page->tab_label)) + { + if (notebook->tab_pos == GTK_POS_LEFT) + { + x -= widget->style->klass->xthickness * 2; + width += widget->style->klass->xthickness * 2; + } + else if (notebook->tab_pos == GTK_POS_RIGHT) + width += widget->style->klass->xthickness * 2; + } + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + y += page->allocation.height; + case GTK_POS_BOTTOM: + height -= page->allocation.height; + break; + case GTK_POS_LEFT: + x += page->allocation.width; + case GTK_POS_RIGHT: + width -= page->allocation.width; + break; + } + } + } + gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); + + /* if theres an area for scrollign arrows draw the shape for them */ + if (notebook->panel) + { + gdk_window_get_geometry(notebook->panel, &x, &y, &width, &height, &depth); + gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); + } + + /* draw the shapes of all the children */ + children = notebook->children; + while (children) + { + page = children->data; + if (GTK_WIDGET_MAPPED (page->tab_label)) + { + x = page->allocation.x; + y = page->allocation.y; + width = page->allocation.width; + height = page->allocation.height; + gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); + } + children = children->next; + } + /* set the mask */ + gdk_window_shape_combine_mask(widget->window, pm, 0, 0); + gdk_pixmap_unref(pm); + gdk_gc_destroy(pmgc); +} + +/* Private GtkNotebook Size Allocate Functions: + * + * gtk_notebook_pages_allocate + * gtk_notebook_page_allocate + * gtk_notebook_calc_tabs + */ static void gtk_notebook_pages_allocate (GtkNotebook *notebook, GtkAllocation *allocation) @@ -2490,26 +2455,27 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook, GtkContainer *container; GtkNotebookPage *page = NULL; GtkAllocation child_allocation; - GList *children; + GList *children = NULL; GList *last_child = NULL; - gint showarrow = FALSE; + gboolean showarrow = FALSE; gint tab_space = 0; + gint delta; gint x = 0; gint y = 0; gint i; gint n = 1; gint old_fill = 0; gint new_fill = 0; - - if (!notebook->show_tabs || !notebook->children) + + if (!notebook->show_tabs || !notebook->children || !notebook->cur_page) return; - + widget = GTK_WIDGET (notebook); container = GTK_CONTAINER (notebook); - + child_allocation.x = container->border_width; child_allocation.y = container->border_width; - + switch (notebook->tab_pos) { case GTK_POS_BOTTOM: @@ -2539,7 +2505,7 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook, else if (notebook->first_tab) focus_tab = notebook->first_tab; else - focus_tab = notebook->children; + focus_tab = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE); switch (notebook->tab_pos) { @@ -2549,20 +2515,27 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook, { page = children->data; children = children->next; - tab_space += page->requisition.width; + + if (GTK_WIDGET_VISIBLE (page->child)) + tab_space += page->requisition.width; } - if (tab_space > allocation->width - 2 * container->border_width - TAB_OVERLAP) + if (tab_space > + allocation->width - 2 * container->border_width - TAB_OVERLAP) { showarrow = TRUE; page = focus_tab->data; - - tab_space = (allocation->width - TAB_OVERLAP - page->requisition.width - - 2 * (container->border_width + ARROW_SPACING + ARROW_SIZE)); - x = allocation->width - 2 * ARROW_SIZE - ARROW_SPACING - container->border_width; - + + tab_space = (allocation->width - TAB_OVERLAP - + page->requisition.width - + 2 * (container->border_width + ARROW_SPACING + + ARROW_SIZE)); + x = (allocation->width - 2 * ARROW_SIZE - ARROW_SPACING - + container->border_width); + page = notebook->children->data; if (notebook->tab_pos == GTK_POS_TOP) - y = container->border_width + (page->requisition.height - ARROW_SIZE) / 2; + y = (container->border_width + + (page->requisition.height - ARROW_SIZE) / 2); else y = (allocation->height - container->border_width - ARROW_SIZE - (page->requisition.height - ARROW_SIZE) / 2); @@ -2574,164 +2547,336 @@ gtk_notebook_pages_allocate (GtkNotebook *notebook, { page = children->data; children = children->next; - tab_space += page->requisition.height; + + if (GTK_WIDGET_VISIBLE (page->child)) + tab_space += page->requisition.height; } - if (tab_space > (allocation->height - 2 * container->border_width - TAB_OVERLAP)) + if (tab_space > + (allocation->height - 2 * container->border_width - TAB_OVERLAP)) { showarrow = TRUE; page = focus_tab->data; tab_space = (allocation->height - ARROW_SIZE - ARROW_SPACING - TAB_OVERLAP - - 2 * container->border_width - page->requisition.height); + 2 * container->border_width - + page->requisition.height); y = allocation->height - container->border_width - ARROW_SIZE; - + page = notebook->children->data; if (notebook->tab_pos == GTK_POS_LEFT) x = (container->border_width + - (page->requisition.width - (2 * ARROW_SIZE - ARROW_SPACING)) / 2); + (page->requisition.width - + (2 * ARROW_SIZE - ARROW_SPACING)) / 2); else x = (allocation->width - container->border_width - - (2 * ARROW_SIZE - ARROW_SPACING) - - (page->requisition.width - (2 * ARROW_SIZE - ARROW_SPACING)) / 2); + (2 * ARROW_SIZE - ARROW_SPACING) - + (page->requisition.width - + (2 * ARROW_SIZE - ARROW_SPACING)) / 2); } break; } if (showarrow) /* first_tab <- focus_tab */ { - children = focus_tab->prev; - while (children) - { - if (notebook->first_tab == children) - break; - children = children->prev; - } - - if (!children) - notebook->first_tab = focus_tab; - else - gtk_notebook_calc_tabs (notebook, focus_tab->prev, - &(notebook->first_tab), &tab_space, - STEP_PREV); if (tab_space <= 0) { - notebook->first_tab = notebook->first_tab->next; - if (!notebook->first_tab) - notebook->first_tab = focus_tab; - last_child = focus_tab->next; + notebook->first_tab = focus_tab; + last_child = gtk_notebook_search_page (notebook, focus_tab, + STEP_NEXT, TRUE); } - else /* focus_tab -> end */ + else { - if (!notebook->first_tab) - notebook->first_tab = notebook->children; - children = NULL; - gtk_notebook_calc_tabs (notebook, focus_tab->next, - &children, &tab_space, STEP_NEXT); - - if (tab_space <= 0) - last_child = children; - else /* start <- first_tab */ + if (notebook->first_tab && notebook->first_tab != focus_tab) { - last_child = NULL; + /* Is first_tab really predecessor of focus_tab ? */ + page = notebook->first_tab->data; + if (GTK_WIDGET_VISIBLE (page->child)) + for (children = focus_tab; + children && children != notebook->first_tab; + children = gtk_notebook_search_page (notebook, + children, + STEP_PREV, + TRUE)); + } + if (!children) + notebook->first_tab = focus_tab; + else + gtk_notebook_calc_tabs (notebook, + gtk_notebook_search_page (notebook, + focus_tab, + STEP_PREV, + TRUE), + &(notebook->first_tab), &tab_space, + STEP_PREV); + + if (tab_space <= 0) + { + notebook->first_tab = + gtk_notebook_search_page (notebook, notebook->first_tab, + STEP_NEXT, TRUE); + if (!notebook->first_tab) + notebook->first_tab = focus_tab; + last_child = gtk_notebook_search_page (notebook, focus_tab, + STEP_NEXT, TRUE); + } + else /* focus_tab -> end */ + { + if (!notebook->first_tab) + notebook->first_tab = gtk_notebook_search_page (notebook, + NULL, + STEP_NEXT, + TRUE); children = NULL; - gtk_notebook_calc_tabs (notebook,notebook->first_tab->prev, - &children, &tab_space, STEP_PREV); - if (children) - notebook->first_tab = children->next; - else - notebook->first_tab = notebook->children; + gtk_notebook_calc_tabs (notebook, + gtk_notebook_search_page (notebook, + focus_tab, + STEP_NEXT, + TRUE), + &children, &tab_space, STEP_NEXT); + + if (tab_space <= 0) + last_child = children; + else /* start <- first_tab */ + { + last_child = NULL; + children = NULL; + gtk_notebook_calc_tabs + (notebook, + gtk_notebook_search_page (notebook, + notebook->first_tab, + STEP_PREV, + TRUE), + &children, &tab_space, STEP_PREV); + notebook->first_tab = gtk_notebook_search_page(notebook, + children, + STEP_NEXT, + TRUE); + } } } - + if (GTK_WIDGET_REALIZED (notebook)) { gdk_window_move (notebook->panel, x, y); gdk_window_show (notebook->panel); } - + if (tab_space < 0) { tab_space = -tab_space; n = 0; - children = notebook->first_tab; - while (children != last_child) - { - children = children->next; - n++; - } + for (children = notebook->first_tab; + children && children != last_child; + children = gtk_notebook_search_page (notebook, children, + STEP_NEXT, TRUE)) + n++; } else tab_space = 0; - - children = notebook->children; - while (children != notebook->first_tab) + + /*unmap all non-visible tabs*/ + for (children = gtk_notebook_search_page (notebook, NULL, + STEP_NEXT, TRUE); + children && children != notebook->first_tab; + children = gtk_notebook_search_page (notebook, children, + STEP_NEXT, TRUE)) { page = children->data; - children = children->next; - if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label)) gtk_widget_unmap (page->tab_label); - } - children = last_child; - while (children) + for (children = last_child; children; + children = gtk_notebook_search_page (notebook, children, + STEP_NEXT, TRUE)) { page = children->data; - children = children->next; - if (page->tab_label && GTK_WIDGET_MAPPED (page->tab_label)) gtk_widget_unmap (page->tab_label); } } else /* !showarrow */ { - notebook->first_tab = notebook->children; + notebook->first_tab = gtk_notebook_search_page (notebook, NULL, + STEP_NEXT, TRUE); tab_space = 0; if (GTK_WIDGET_REALIZED (notebook)) gdk_window_hide (notebook->panel); } - children = notebook->first_tab; } - else - children = notebook->children; - - i = 1; - while (children != last_child) + + if (!showarrow) { + gint c = 0; + + n = 0; + children = notebook->children; + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + while (children) + { + page = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (page->child)) + { + c++; + tab_space += page->requisition.width; + if (page->expand) + n++; + } + } + tab_space -= allocation->width; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + while (children) + { + page = children->data; + children = children->next; + + if (GTK_WIDGET_VISIBLE (page->child)) + { + c++; + tab_space += page->requisition.height; + if (page->expand) + n++; + } + } + tab_space -= allocation->height; + } + tab_space += 2 * container->border_width + TAB_OVERLAP; + tab_space *= -1; + notebook->first_tab = gtk_notebook_search_page (notebook, NULL, + STEP_NEXT, TRUE); + if (notebook->homogeneous && n) + n = c; + } + + children = notebook->first_tab; + i = 1; + while (children) + { + if (children == last_child) + { + gtk_notebook_set_shape (notebook); + return; + children = NULL; + break; + } + page = children->data; - children = children->next; + if (!showarrow && page->pack != GTK_PACK_START) + break; + children = gtk_notebook_search_page (notebook, children, STEP_NEXT,TRUE); - if (GTK_WIDGET_VISIBLE (page->child)) + delta = 0; + if (n && (showarrow || page->expand || notebook->homogeneous)) { new_fill = (tab_space * i++) / n; - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - case GTK_POS_BOTTOM: - child_allocation.width = page->requisition.width + TAB_OVERLAP + new_fill - old_fill; - break; - case GTK_POS_LEFT: - case GTK_POS_RIGHT: - child_allocation.height = page->requisition.height + TAB_OVERLAP + new_fill - old_fill; - break; - } + delta = new_fill - old_fill; old_fill = new_fill; - gtk_notebook_page_allocate (notebook, page, &child_allocation); + } + + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.width = (page->requisition.width + + TAB_OVERLAP + delta); + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.height = (page->requisition.height + + TAB_OVERLAP + delta); + break; + } + + gtk_notebook_page_allocate (notebook, page, &child_allocation); + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.x += child_allocation.width - TAB_OVERLAP; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.y += child_allocation.height - TAB_OVERLAP; + break; + } + + if (GTK_WIDGET_REALIZED (notebook) && + page->tab_label && !GTK_WIDGET_MAPPED (page->tab_label)) + gtk_widget_map (page->tab_label); + } + + if (children) + { + children = notebook->children; + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.x = (allocation->x + allocation->width - + container->border_width); + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.y = (allocation->y + allocation->height - + container->border_width); + break; + } + + while (children != last_child) + { + page = children->data; + children = children->next; + + if (page->pack != GTK_PACK_END || !GTK_WIDGET_VISIBLE (page->child)) + continue; + + delta = 0; + if (n && (page->expand || notebook->homogeneous)) + { + new_fill = (tab_space * i++) / n; + delta = new_fill - old_fill; + old_fill = new_fill; + } + switch (notebook->tab_pos) { case GTK_POS_TOP: case GTK_POS_BOTTOM: - child_allocation.x += child_allocation.width - TAB_OVERLAP; + child_allocation.width = (page->requisition.width + + TAB_OVERLAP + delta); + child_allocation.x -= child_allocation.width; break; case GTK_POS_LEFT: case GTK_POS_RIGHT: - child_allocation.y += child_allocation.height - TAB_OVERLAP; + child_allocation.height = (page->requisition.height + + TAB_OVERLAP + delta); + child_allocation.y -= child_allocation.height; break; } - - if (GTK_WIDGET_REALIZED (notebook) && - page->tab_label && !GTK_WIDGET_MAPPED (page->tab_label)) + + gtk_notebook_page_allocate (notebook, page, &child_allocation); + + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + child_allocation.x += TAB_OVERLAP; + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + child_allocation.y += TAB_OVERLAP; + break; + } + + if (GTK_WIDGET_REALIZED (notebook) && page->tab_label && + !GTK_WIDGET_MAPPED (page->tab_label)) gtk_widget_map (page->tab_label); } } @@ -2744,7 +2889,9 @@ gtk_notebook_page_allocate (GtkNotebook *notebook, GtkAllocation *allocation) { GtkAllocation child_allocation; - gint xthickness, ythickness; + gint xthickness; + gint ythickness; + gint padding; g_return_if_fail (notebook != NULL); g_return_if_fail (page != NULL); @@ -2775,32 +2922,53 @@ gtk_notebook_page_allocate (GtkNotebook *notebook, switch (notebook->tab_pos) { case GTK_POS_TOP: - child_allocation.x = xthickness + notebook->tab_border; - child_allocation.y = ythickness + notebook->tab_border + page->allocation.y; - child_allocation.width = page->allocation.width - child_allocation.x * 2; - child_allocation.height = page->allocation.height - ythickness - 2 * notebook->tab_border; - child_allocation.x += page->allocation.x; - break; case GTK_POS_BOTTOM: - child_allocation.x = xthickness + notebook->tab_border; - child_allocation.width = page->allocation.width - child_allocation.x * 2; - child_allocation.height = page->allocation.height - ythickness - 2 * notebook->tab_border; - child_allocation.x += page->allocation.x; - child_allocation.y = page->allocation.y + notebook->tab_border; + padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_hborder; + if (page->fill) + { + child_allocation.x = (xthickness + FOCUS_WIDTH + + notebook->tab_hborder); + child_allocation.width = (page->allocation.width - + 2 * child_allocation.x); + child_allocation.x += page->allocation.x; + } + else + { + child_allocation.x = (page->allocation.x + + (page->allocation.width - + page->tab_label->requisition.width) / 2); + child_allocation.width = page->tab_label->requisition.width; + } + child_allocation.y = (notebook->tab_vborder + FOCUS_WIDTH + + page->allocation.y); + if (notebook->tab_pos == GTK_POS_TOP) + child_allocation.y += ythickness; + child_allocation.height = (page->allocation.height - ythickness - + 2 * (notebook->tab_vborder + FOCUS_WIDTH)); break; case GTK_POS_LEFT: - child_allocation.x = xthickness + notebook->tab_border + page->allocation.x; - child_allocation.y = ythickness + notebook->tab_border; - child_allocation.width = page->allocation.width - xthickness - 2 * notebook->tab_border; - child_allocation.height = page->allocation.height - child_allocation.y * 2; - child_allocation.y += page->allocation.y; - break; case GTK_POS_RIGHT: - child_allocation.y = ythickness + notebook->tab_border; - child_allocation.width = page->allocation.width - xthickness - 2 * notebook->tab_border; - child_allocation.height = page->allocation.height - child_allocation.y * 2; - child_allocation.x = page->allocation.x + notebook->tab_border; - child_allocation.y += page->allocation.y; + padding = TAB_CURVATURE + FOCUS_WIDTH + notebook->tab_vborder; + if (page->fill) + { + child_allocation.y = ythickness + padding; + child_allocation.height = (page->allocation.height - + 2 * child_allocation.y); + child_allocation.y += page->allocation.y; + } + else + { + child_allocation.y = (page->allocation.y + + (page->allocation.height - + page->tab_label->requisition.height) / 2); + child_allocation.height = page->tab_label->requisition.height; + } + child_allocation.x = (page->allocation.x + notebook->tab_hborder + + FOCUS_WIDTH); + if (notebook->tab_pos == GTK_POS_LEFT) + child_allocation.x += xthickness; + child_allocation.width = (page->allocation.width - xthickness - + 2 * (notebook->tab_hborder + FOCUS_WIDTH)); break; } @@ -2808,8 +2976,280 @@ gtk_notebook_page_allocate (GtkNotebook *notebook, gtk_widget_size_allocate (page->tab_label, &child_allocation); } +static void +gtk_notebook_calc_tabs (GtkNotebook *notebook, + GList *start, + GList **end, + gint *tab_space, + guint direction) +{ + GtkNotebookPage *page = NULL; + GList *children; + GList *last_list = NULL; + gboolean pack; + + if (!start) + return; + + children = start; + pack = GTK_NOTEBOOK_PAGE (start)->pack; + if (pack == GTK_PACK_END) + direction = (direction == STEP_PREV) ? STEP_NEXT : STEP_PREV; + + while (1) + { + switch (notebook->tab_pos) + { + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + while (children) + { + page = children->data; + if (GTK_WIDGET_VISIBLE (page->child)) + { + if (page->pack == pack) + { + *tab_space -= page->requisition.width; + if (*tab_space < 0 || children == *end) + { + if (*tab_space < 0) + { + *tab_space = - (*tab_space + + page->requisition.width); + *end = children; + } + return; + } + } + last_list = children; + } + if (direction == STEP_NEXT) + children = children->next; + else + children = children->prev; + } + break; + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + while (children) + { + page = children->data; + if (GTK_WIDGET_VISIBLE (page->child)) + { + if (page->pack == pack) + { + *tab_space -= page->requisition.height; + if (*tab_space < 0 || children == *end) + { + if (*tab_space < 0) + { + *tab_space = - (*tab_space + + page->requisition.height); + *end = children; + } + return; + } + } + last_list = children; + } + if (direction == STEP_NEXT) + children = children->next; + else + children = children->prev; + } + break; + } + if (direction == STEP_PREV) + return; + pack = (pack == GTK_PACK_END) ? GTK_PACK_START : GTK_PACK_END; + direction = STEP_PREV; + children = last_list; + } +} + +/* Private GtkNotebook Page Switch Methods: + * + * gtk_notebook_real_switch_page + */ static void -gtk_notebook_menu_switch_page (GtkWidget *widget, +gtk_notebook_real_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (page != NULL); + + if (notebook->cur_page == page || !GTK_WIDGET_VISIBLE (page->child)) + return; + + if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child)) + gtk_widget_unmap (notebook->cur_page->child); + + notebook->cur_page = page; + + if (!notebook->focus_tab || + notebook->focus_tab->data != (gpointer) notebook->cur_page) + notebook->focus_tab = + g_list_find (notebook->children, notebook->cur_page); + + gtk_notebook_pages_allocate (notebook, >K_WIDGET (notebook)->allocation); + gtk_notebook_expose_tabs (notebook); + + if (GTK_WIDGET_MAPPED (notebook)) + { + if (GTK_WIDGET_REALIZED (notebook->cur_page->child)) + gtk_widget_map (notebook->cur_page->child); + else + { + gtk_widget_map (notebook->cur_page->child); + gtk_widget_size_allocate (GTK_WIDGET (notebook), + >K_WIDGET (notebook)->allocation); + } + } + + if (GTK_WIDGET_DRAWABLE (notebook)) + gtk_widget_queue_draw (GTK_WIDGET (notebook)); + gtk_notebook_set_shape (notebook); +} + +/* Private GtkNotebook Page Switch Functions: + * + * gtk_notebook_switch_page + * gtk_notebook_page_select + * gtk_notebook_switch_focus_tab + * gtk_notebook_menu_switch_page + */ +static void +gtk_notebook_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (page != NULL); + + if (notebook->cur_page == page) + return; + + if (page_num < 0) + page_num = g_list_index (notebook->children, page); + + gtk_signal_emit (GTK_OBJECT (notebook), + notebook_signals[SWITCH_PAGE], + page, + page_num); +} + +static gint +gtk_notebook_page_select (GtkNotebook *notebook) +{ + GtkNotebookPage *page; + + g_return_val_if_fail (notebook != NULL, FALSE); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); + + if (!notebook->focus_tab) + return FALSE; + + page = notebook->focus_tab->data; + gtk_notebook_switch_page (notebook, page, -1); + + if (GTK_WIDGET_VISIBLE (page->child)) + { + if (GTK_IS_CONTAINER (page->child)) + { + if (gtk_container_focus (GTK_CONTAINER (page->child), + GTK_DIR_TAB_FORWARD)) + return TRUE; + } + else if (GTK_WIDGET_CAN_FOCUS (page->child)) + { + gtk_widget_grab_focus (page->child); + return TRUE; + } + } + return FALSE; +} + +static void +gtk_notebook_switch_focus_tab (GtkNotebook *notebook, + GList *new_child) +{ + GList *old_child; + GtkNotebookPage *old_page = NULL; + GtkNotebookPage *page; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->focus_tab == new_child) + return; + + old_child = notebook->focus_tab; + notebook->focus_tab = new_child; + + if (notebook->scrollable && GTK_WIDGET_DRAWABLE (notebook)) + { + if ((new_child == NULL) != (old_child == NULL)) + { + gdk_window_clear (notebook->panel); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + } + else + { + GList *olist; + GList *nlist; + + olist = gtk_notebook_search_page (notebook, old_child, + STEP_PREV, TRUE); + nlist = gtk_notebook_search_page (notebook, new_child, + STEP_PREV, TRUE); + + if ((olist == NULL) != (nlist == NULL)) + { + gdk_window_clear_area (notebook->panel, 0, 0, + ARROW_SIZE, ARROW_SIZE); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); + } + + olist = gtk_notebook_search_page (notebook, old_child, + STEP_NEXT, TRUE); + nlist = gtk_notebook_search_page (notebook, new_child, + STEP_NEXT, TRUE); + + if ((olist == NULL) != (nlist == NULL)) + { + gdk_window_clear_area (notebook->panel, + ARROW_SIZE + ARROW_SPACING, 0, + ARROW_SIZE, ARROW_SIZE); + gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); + } + } + } + + if (!notebook->show_tabs || !notebook->focus_tab) + return; + + if (old_child) + old_page = old_child->data; + + page = notebook->focus_tab->data; + if (GTK_WIDGET_MAPPED (page->tab_label)) + gtk_notebook_focus_changed (notebook, old_page); + else + { + gtk_notebook_pages_allocate (notebook, + &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); + } + + gtk_notebook_set_shape (notebook); +} + +static void +gtk_notebook_menu_switch_page (GtkWidget *widget, GtkNotebookPage *page) { GtkNotebook *notebook; @@ -2819,7 +3259,7 @@ gtk_notebook_menu_switch_page (GtkWidget *widget, g_return_if_fail (widget != NULL); g_return_if_fail (page != NULL); - notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget + notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget (GTK_MENU (widget->parent))); if (notebook->cur_page == page) @@ -2839,362 +3279,20 @@ gtk_notebook_menu_switch_page (GtkWidget *widget, page_num); } +/* Private GtkNotebook Menu Functions: + * + * gtk_notebook_menu_item_create + * gtk_notebook_menu_label_unparent + * gtk_notebook_menu_detacher + */ static void -gtk_notebook_switch_page (GtkNotebook *notebook, - GtkNotebookPage *page, - guint page_num) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - g_return_if_fail (page != NULL); - - if (notebook->cur_page == page) - return; - - gtk_signal_emit (GTK_OBJECT (notebook), - notebook_signals[SWITCH_PAGE], - page, - page_num); -} - -static gint -gtk_notebook_focus (GtkContainer *container, - GtkDirectionType direction) -{ - GtkNotebook *notebook; - GtkWidget *focus_child; - GtkNotebookPage *page = NULL; - GtkNotebookPage *old_page = NULL; - gint return_val; - - g_return_val_if_fail (container != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (container), FALSE); - - notebook = GTK_NOTEBOOK (container); - - if (!GTK_WIDGET_DRAWABLE (notebook) || - !GTK_WIDGET_SENSITIVE (container) || - !notebook->children) - return FALSE; - - focus_child = container->focus_child; - gtk_container_set_focus_child (container, NULL); - - if (!notebook->show_tabs) - { - if (GTK_WIDGET_DRAWABLE (notebook->cur_page->child) && - GTK_WIDGET_SENSITIVE (notebook->cur_page->child)) - { - if (GTK_IS_CONTAINER (notebook->cur_page->child)) - { - if (gtk_container_focus (GTK_CONTAINER (notebook->cur_page->child), direction)) - return TRUE; - } - else if (GTK_WIDGET_CAN_FOCUS (notebook->cur_page->child)) - { - if (!focus_child) - { - gtk_widget_grab_focus (notebook->cur_page->child); - return TRUE; - } - } - } - return FALSE; - } - - if (notebook->focus_tab) - old_page = notebook->focus_tab->data; - - return_val = FALSE; - - if (focus_child && old_page && focus_child == old_page->child && - notebook->child_has_focus) - { - if (GTK_WIDGET_DRAWABLE (old_page->child)) - { - if (GTK_IS_CONTAINER (old_page->child) && - !GTK_WIDGET_HAS_FOCUS (old_page->child)) - { - if (gtk_container_focus (GTK_CONTAINER (old_page->child), - direction)) - return TRUE; - } - gtk_widget_grab_focus (GTK_WIDGET(notebook)); - return TRUE; - } - return FALSE; - } - - switch (direction) - { - case GTK_DIR_TAB_FORWARD: - case GTK_DIR_RIGHT: - case GTK_DIR_DOWN: - if (!notebook->focus_tab) - gtk_notebook_switch_focus_tab (notebook, notebook->children); - else - gtk_notebook_switch_focus_tab (notebook, notebook->focus_tab->next); - - if (!notebook->focus_tab) - { - gtk_notebook_focus_changed (notebook, old_page); - return FALSE; - } - - page = notebook->focus_tab->data; - return_val = TRUE; - break; - - case GTK_DIR_TAB_BACKWARD: - case GTK_DIR_LEFT: - case GTK_DIR_UP: - if (!notebook->focus_tab) - gtk_notebook_switch_focus_tab (notebook, g_list_last (notebook->children)); - else - gtk_notebook_switch_focus_tab (notebook, notebook->focus_tab->prev); - - if (!notebook->focus_tab) - { - gtk_notebook_focus_changed (notebook, old_page); - return FALSE; - } - - page = notebook->focus_tab->data; - return_val = TRUE; - break; - } - - if (return_val) - { - if (!GTK_WIDGET_HAS_FOCUS (container)) - gtk_widget_grab_focus (GTK_WIDGET (container)); - - if (GTK_WIDGET_MAPPED (page->tab_label)) - gtk_notebook_focus_changed (notebook, old_page); - else - { - gtk_notebook_pages_allocate (notebook, - &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } - } - - return return_val; -} - -static gint -gtk_notebook_page_select (GtkNotebook *notebook) -{ - g_return_val_if_fail (notebook != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE); - - if (notebook->focus_tab) - { - GtkNotebookPage *page; - GList *children; - gint num; - - page = notebook->focus_tab->data; - - children = notebook->children; - num = 0; - while (children != notebook->focus_tab) - { - children = children->next; - num++; - } - - gtk_notebook_switch_page (notebook, page, num); - - if (GTK_WIDGET_VISIBLE (page->child)) - { - if (GTK_IS_CONTAINER (page->child)) - { - if (gtk_container_focus (GTK_CONTAINER (page->child), - GTK_DIR_TAB_FORWARD)) - return TRUE; - } - else if (GTK_WIDGET_CAN_FOCUS (page->child)) - { - gtk_widget_grab_focus (page->child); - return TRUE; - } - } - } - return FALSE; -} - -static void -gtk_notebook_switch_focus_tab (GtkNotebook *notebook, - GList *new_child) -{ - GList *old_tab; - GtkNotebookPage *old_page = NULL; +gtk_notebook_menu_item_create (GtkNotebook *notebook, + GList *list) +{ GtkNotebookPage *page; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (notebook->focus_tab == new_child) - return; - - old_tab = notebook->focus_tab; - notebook->focus_tab = new_child; - - if (notebook->scrollable && GTK_WIDGET_DRAWABLE (notebook)) - { - if ((new_child == NULL) != (old_tab == NULL)) - { - gdk_window_clear (notebook->panel); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); - - } - else - { - if ((old_tab->prev == NULL) != (new_child->prev == NULL)) - { - gdk_window_clear_area (notebook->panel, 0, 0, - ARROW_SIZE, ARROW_SIZE); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_LEFT); - } - if ((old_tab->next == NULL) != (new_child->next == NULL)) - { - gdk_window_clear_area (notebook->panel, - ARROW_SIZE + ARROW_SPACING, 0, - ARROW_SIZE, ARROW_SIZE); - gtk_notebook_draw_arrow (notebook, GTK_ARROW_RIGHT); - } - } - } - - if (!notebook->show_tabs || !notebook->focus_tab) - return; - - if (old_tab) - old_page = old_tab->data; - - page = notebook->focus_tab->data; - if (GTK_WIDGET_MAPPED (page->tab_label)) - gtk_notebook_focus_changed (notebook, old_page); - else - { - gtk_notebook_pages_allocate (notebook, - &(GTK_WIDGET (notebook)->allocation)); - gtk_notebook_expose_tabs (notebook); - } - - gtk_notebook_set_shape (notebook); -} - -static gint -gtk_notebook_key_press (GtkWidget *widget, - GdkEventKey *event) -{ - GtkNotebook *notebook; - GtkDirectionType direction = 0; - gint return_val; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_NOTEBOOK (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - notebook = GTK_NOTEBOOK (widget); - return_val = TRUE; - - if (!notebook->children || !notebook->show_tabs) - return FALSE; - - switch (event->keyval) - { - case GDK_Up: - direction = GTK_DIR_UP; - break; - case GDK_Left: - direction = GTK_DIR_LEFT; - break; - case GDK_Down: - direction = GTK_DIR_DOWN; - break; - case GDK_Right: - direction = GTK_DIR_RIGHT; - break; - case GDK_Tab: - case GDK_ISO_Left_Tab: - if (event->state & GDK_SHIFT_MASK) - direction = GTK_DIR_TAB_BACKWARD; - else - direction = GTK_DIR_TAB_FORWARD; - break; - case GDK_Home: - gtk_notebook_switch_focus_tab (notebook, notebook->children); - return TRUE; - case GDK_End: - gtk_notebook_switch_focus_tab (notebook, - g_list_last (notebook->children)); - return TRUE; - case GDK_Return: - case GDK_space: - gtk_notebook_page_select (GTK_NOTEBOOK (widget)); - return TRUE; - default: - return_val = FALSE; - } - if (return_val) - return gtk_container_focus (GTK_CONTAINER (widget), direction); - return return_val; -} - -void -gtk_notebook_set_tab_border (GtkNotebook *notebook, - guint tab_border) -{ - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (notebook->tab_border != tab_border) - { - notebook->tab_border = tab_border; - - if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) - gtk_widget_queue_resize (GTK_WIDGET (notebook)); - } -} - -static void -gtk_notebook_update_labels (GtkNotebook *notebook, - GList *list, - guint page_num) -{ - GtkNotebookPage *page; - gchar string[32]; - - while (list) - { - page = list->data; - list = list->next; - sprintf (string, "Page %u", page_num); - if (notebook->show_tabs && page->default_tab) - gtk_label_set (GTK_LABEL (page->tab_label), string); - if (notebook->menu && page->default_menu) - { - if (page->tab_label && GTK_IS_LABEL (page->tab_label)) - gtk_label_set (GTK_LABEL (page->menu_label), - GTK_LABEL (page->tab_label)->label); - else - gtk_label_set (GTK_LABEL (page->menu_label), string); - } - page_num++; - } -} - -static void -gtk_notebook_menu_item_create (GtkNotebook *notebook, - GtkNotebookPage *page, - gint position) -{ GtkWidget *menu_item; + page = list->data; if (page->default_menu) { if (page->tab_label && GTK_IS_LABEL (page->tab_label)) @@ -3208,37 +3306,12 @@ gtk_notebook_menu_item_create (GtkNotebook *notebook, menu_item = gtk_menu_item_new (); gtk_widget_freeze_accelerators (menu_item); gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label); - gtk_menu_insert (GTK_MENU (notebook->menu), menu_item, position); + gtk_menu_insert (GTK_MENU (notebook->menu), menu_item, + gtk_notebook_real_page_position (notebook, list)); gtk_signal_connect (GTK_OBJECT (menu_item), "activate", GTK_SIGNAL_FUNC (gtk_notebook_menu_switch_page), page); - gtk_widget_show (menu_item); -} - -void -gtk_notebook_popup_enable (GtkNotebook *notebook) -{ - GtkNotebookPage *page; - GList *children; - - g_return_if_fail (notebook != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); - - if (notebook->menu) - return; - - notebook->menu = gtk_menu_new (); - - children = notebook->children; - while (children) - { - page = children->data; - children = children->next; - gtk_notebook_menu_item_create (notebook, page, -1); - } - gtk_notebook_update_labels (notebook, notebook->children,1); - - gtk_menu_attach_to_widget (GTK_MENU (notebook->menu), GTK_WIDGET (notebook), - gtk_notebook_menu_detacher); + if (GTK_WIDGET_VISIBLE (page->child)) + gtk_widget_show (menu_item); } static void @@ -3249,6 +3322,513 @@ gtk_notebook_menu_label_unparent (GtkWidget *widget, GTK_BIN(widget)->child = NULL; } +static void +gtk_notebook_menu_detacher (GtkWidget *widget, + GtkMenu *menu) +{ + GtkNotebook *notebook; + + g_return_if_fail (widget != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + + notebook = GTK_NOTEBOOK (widget); + g_return_if_fail (notebook->menu == (GtkWidget*) menu); + + notebook->menu = NULL; +} + +/* Public GtkNotebook Page Insert/Remove Methods : + * + * gtk_notebook_append_page + * gtk_notebook_append_page_menu + * gtk_notebook_prepend_page + * gtk_notebook_prepend_page_menu + * gtk_notebook_insert_page + * gtk_notebook_insert_page_menu + * gtk_notebook_remove_page + */ +void +gtk_notebook_append_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, -1); +} + +void +gtk_notebook_append_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, -1); +} + +void +gtk_notebook_prepend_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, 0); +} + +void +gtk_notebook_prepend_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, menu_label, 0); +} + +void +gtk_notebook_insert_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + gint position) +{ + gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position); +} + +void +gtk_notebook_insert_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label, + gint position) +{ + GtkNotebookPage *page; + gint nchildren; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + + page = g_new (GtkNotebookPage, 1); + page->child = child; + page->requisition.width = 0; + page->requisition.height = 0; + page->allocation.x = 0; + page->allocation.y = 0; + page->allocation.width = 0; + page->allocation.height = 0; + page->default_menu = FALSE; + page->default_tab = FALSE; + + nchildren = g_list_length (notebook->children); + if ((position < 0) || (position > nchildren)) + position = nchildren; + + notebook->children = g_list_insert (notebook->children, page, position); + + if (!tab_label) + { + page->default_tab = TRUE; + if (notebook->show_tabs) + tab_label = gtk_label_new (""); + } + page->tab_label = tab_label; + page->menu_label = menu_label; + page->expand = FALSE; + page->fill = TRUE; + page->pack = GTK_PACK_START; + + if (!menu_label) + page->default_menu = TRUE; + else + { + gtk_widget_ref (page->menu_label); + gtk_object_sink (GTK_OBJECT(page->menu_label)); + } + + if (notebook->menu) + gtk_notebook_menu_item_create (notebook, + g_list_find (notebook->children, page)); + + gtk_notebook_update_labels (notebook); + + if (!notebook->first_tab) + notebook->first_tab = notebook->children; + + gtk_widget_set_parent (child, GTK_WIDGET (notebook)); + if (tab_label) + gtk_widget_set_parent (tab_label, GTK_WIDGET (notebook)); + + if (!notebook->cur_page) + { + gtk_notebook_switch_page (notebook, page, 0); + gtk_notebook_switch_focus_tab (notebook, NULL); + } + + if (GTK_WIDGET_VISIBLE (notebook)) + { + if (GTK_WIDGET_REALIZED (notebook) && + !GTK_WIDGET_REALIZED (child)) + gtk_widget_realize (child); + + if (GTK_WIDGET_MAPPED (notebook) && + !GTK_WIDGET_MAPPED (child) && notebook->cur_page == page) + gtk_widget_map (child); + + if (tab_label) + { + if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child)) + { + if (!GTK_WIDGET_VISIBLE (tab_label)) + gtk_widget_show (tab_label); + + if (GTK_WIDGET_REALIZED (notebook) && + !GTK_WIDGET_REALIZED (tab_label)) + gtk_widget_realize (tab_label); + + if (GTK_WIDGET_MAPPED (notebook) && + !GTK_WIDGET_MAPPED (tab_label)) + gtk_widget_map (tab_label); + } + else if (GTK_WIDGET_VISIBLE (tab_label)) + gtk_widget_hide (tab_label); + } + } + + if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (child); +} + +void +gtk_notebook_remove_page (GtkNotebook *notebook, + gint page_num) +{ + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (page_num >= 0) + { + list = g_list_nth (notebook->children, page_num); + if (list) + gtk_notebook_real_remove (notebook, list); + } + else + { + list = g_list_last (notebook->children); + if (list) + gtk_notebook_real_remove (notebook, list); + } +} + +/* Public GtkNotebook Page Switch Methods : + * gtk_notebook_current_page + * gtk_notebook_page_num + * gtk_notebook_set_page + * gtk_notebook_next_page + * gtk_notebook_prev_page + */ +gint +gtk_notebook_current_page (GtkNotebook *notebook) +{ + g_return_val_if_fail (notebook != NULL, -1); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); + + if (!notebook->cur_page) + return -1; + + return g_list_index (notebook->children, notebook->cur_page); +} + +gint +gtk_notebook_page_num (GtkNotebook *notebook, + GtkWidget *child) +{ + GList *children; + gint num; + + g_return_val_if_fail (notebook != NULL, -1); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1); + + num = 0; + children = notebook->children; + while (children) + { + GtkNotebookPage *page; + + page = children->data; + if (page->child == child) + return num; + + children = children->next; + num++; + } + + return -1; +} + +void +gtk_notebook_set_page (GtkNotebook *notebook, + gint page_num) +{ + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (page_num >= 0) + list = g_list_nth (notebook->children, page_num); + else + { + list = g_list_last (notebook->children); + page_num = g_list_length (notebook->children) - 1; + } + if (list) + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), page_num); +} + +void +gtk_notebook_next_page (GtkNotebook *notebook) +{ + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + list = g_list_find (notebook->children, notebook->cur_page); + if (!list) + return; + + list = gtk_notebook_search_page (notebook, list, STEP_NEXT, TRUE); + if (!list) + return; + + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1); +} + +void +gtk_notebook_prev_page (GtkNotebook *notebook) +{ + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + list = g_list_find (notebook->children, notebook->cur_page); + if (!list) + return; + + list = gtk_notebook_search_page (notebook, list, STEP_PREV, TRUE); + if (!list) + return; + + gtk_notebook_switch_page (notebook, GTK_NOTEBOOK_PAGE (list), -1); +} + +/* Public GtkNotebook/Tab Style Functions + * + * gtk_notebook_set_show_border + * gtk_notebook_set_show_tabs + * gtk_notebook_set_tab_pos + * gtk_notebook_set_homogeneous_tabs + * gtk_notebook_set_tab_border + * gtk_notebook_set_tab_hborder + * gtk_notebook_set_tab_vborder + * gtk_notebook_set_scrollable + */ +void +gtk_notebook_set_show_border (GtkNotebook *notebook, + gint show_border) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->show_border != show_border) + { + notebook->show_border = show_border; + + if (GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); + } +} + +void +gtk_notebook_set_show_tabs (GtkNotebook *notebook, + gboolean show_tabs) +{ + GtkNotebookPage *page; + GList *children; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + show_tabs = show_tabs != FALSE; + + if (notebook->show_tabs == show_tabs) + return; + + notebook->show_tabs = show_tabs; + children = notebook->children; + + if (!show_tabs) + { + GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); + + while (children) + { + page = children->data; + children = children->next; + if (page->default_tab) + { + gtk_widget_destroy (page->tab_label); + page->tab_label = NULL; + } + else + gtk_widget_hide (page->tab_label); + } + + if (notebook->panel) + gdk_window_hide (notebook->panel); + } + else + { + GTK_WIDGET_SET_FLAGS (notebook, GTK_CAN_FOCUS); + gtk_notebook_update_labels (notebook); + } + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} + +void +gtk_notebook_set_tab_pos (GtkNotebook *notebook, + GtkPositionType pos) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->tab_pos != pos) + { + notebook->tab_pos = pos; + if (GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); + } +} + +void +gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook, + gboolean homogeneous) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (homogeneous == notebook->homogeneous) + return; + + notebook->homogeneous = homogeneous; + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} + +void +gtk_notebook_set_tab_border (GtkNotebook *notebook, + guint tab_border) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + notebook->tab_border = tab_border; + notebook->tab_hborder = tab_border; + notebook->tab_vborder = tab_border; + + if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} + +void +gtk_notebook_set_tab_hborder (GtkNotebook *notebook, + guint tab_hborder) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->tab_hborder == tab_hborder) + return; + + notebook->tab_hborder = tab_hborder; + + if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} + +void +gtk_notebook_set_tab_vborder (GtkNotebook *notebook, + guint tab_vborder) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->tab_vborder == tab_vborder) + return; + + notebook->tab_vborder = tab_vborder; + + if (GTK_WIDGET_VISIBLE (notebook) && notebook->show_tabs) + gtk_widget_queue_resize (GTK_WIDGET (notebook)); +} + +void +gtk_notebook_set_scrollable (GtkNotebook *notebook, + gint scrollable) +{ + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + scrollable = (scrollable != FALSE); + + if (scrollable != notebook->scrollable) + { + notebook->scrollable = scrollable; + + if (GTK_WIDGET_REALIZED (notebook)) + { + if (scrollable) + { + gtk_notebook_panel_realize (notebook); + } + else if (notebook->panel) + { + gdk_window_destroy (notebook->panel); + notebook->panel = NULL; + } + } + + if (GTK_WIDGET_VISIBLE (notebook)) + gtk_widget_queue_resize (GTK_WIDGET(notebook)); + } +} + +/* Public GtkNotebook Popup Menu Methods: + * + * gtk_notebook_popup_enable + * gtk_notebook_popup_disable + */ +void +gtk_notebook_popup_enable (GtkNotebook *notebook) +{ + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + + if (notebook->menu) + return; + + notebook->menu = gtk_menu_new (); + for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE); + list; + list = gtk_notebook_search_page (notebook, list, STEP_NEXT, FALSE)) + gtk_notebook_menu_item_create (notebook, list); + + gtk_notebook_update_labels (notebook); + gtk_menu_attach_to_widget (GTK_MENU (notebook->menu), + GTK_WIDGET (notebook), + gtk_notebook_menu_detacher); +} + void gtk_notebook_popup_disable (GtkNotebook *notebook) { @@ -3263,157 +3843,317 @@ gtk_notebook_popup_disable (GtkNotebook *notebook) gtk_widget_destroy (notebook->menu); } -static void -gtk_notebook_menu_detacher (GtkWidget *widget, - GtkMenu *menu) +/* Public GtkNotebook Page Properties Functions: + * + * gtk_notebook_query_tab_label + * gtk_notebook_set_tab_label + * gtk_notebook_set_tab_label_text + * gtk_notebook_query_menu_label + * gtk_notebook_set_menu_label + * gtk_notebook_set_menu_label_text + * gtk_notebook_set_tab_label_packing + * gtk_notebook_query_tab_label_packing + */ +GtkWidget * +gtk_notebook_query_tab_label (GtkNotebook *notebook, + GtkWidget *child) { - GtkNotebook *notebook; + GList *list; + + g_return_val_if_fail (notebook != NULL, NULL); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + g_return_val_if_fail (child != NULL, NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return NULL; + + if (GTK_NOTEBOOK_PAGE (list)->default_tab) + return NULL; + + return GTK_NOTEBOOK_PAGE (list)->tab_label; +} + +void +gtk_notebook_set_tab_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label) +{ + GtkNotebookPage *page; + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_NOTEBOOK (widget)); + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; - notebook = GTK_NOTEBOOK (widget); - g_return_if_fail (notebook->menu == (GtkWidget*) menu); + /* a NULL pointer indicates a default_tab setting, otherwise + * we need to set the associated label + */ - notebook->menu = NULL; + page = list->data; + if (page->tab_label) + gtk_widget_unparent (page->tab_label); + + if (tab_label) + { + page->default_tab = FALSE; + page->tab_label = tab_label; + gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); + } + else + { + page->default_tab = TRUE; + page->tab_label = NULL; + + if (notebook->show_tabs) + { + gchar string[32]; + + sprintf (string, "Page %u", + gtk_notebook_real_page_position (notebook, list)); + page->tab_label = gtk_label_new (string); + gtk_widget_set_parent (page->tab_label, GTK_WIDGET (notebook)); + } + } + + if (notebook->show_tabs && GTK_WIDGET_VISIBLE (child)) + { + gtk_widget_show (page->tab_label); + gtk_widget_queue_resize (GTK_WIDGET (notebook)); + } } -static gint -gtk_notebook_find_page (gconstpointer a, - gconstpointer b) +void +gtk_notebook_set_tab_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *tab_text) { - return (((GtkNotebookPage *) a)->child != b); + GtkWidget *tab_label = NULL; + + if (tab_text) + tab_label = gtk_label_new (tab_text); + gtk_notebook_set_tab_label (notebook, child, tab_label); } -static void -gtk_notebook_set_shape (GtkNotebook *notebook) +GtkWidget * +gtk_notebook_query_menu_label (GtkNotebook *notebook, + GtkWidget *child) { - GtkWidget *widget = NULL; - GdkPixmap *pm = NULL; - GdkGC *pmgc = NULL; - GdkColor col; - gint x, y, width, height, w, h, depth; - GtkNotebookPage *page; - GList *children; - - if (!GTK_WIDGET(notebook)->window) - return; + GList *list; - widget = GTK_WIDGET(notebook); - - w = widget->allocation.width; - h = widget->allocation.height; - - pm = gdk_pixmap_new (widget->window, w, h, 1); - pmgc = gdk_gc_new (pm); + g_return_val_if_fail (notebook != NULL, NULL); + g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL); + g_return_val_if_fail (child != NULL, NULL); - /* clear the shape mask */ - col.pixel = 0; - gdk_gc_set_foreground(pmgc, &col); - gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, w, h); + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return NULL; - col.pixel = 1; - gdk_gc_set_foreground(pmgc, &col); + if (GTK_NOTEBOOK_PAGE (list)->default_menu) + return NULL; - /* draw the shape for the notebook page itself */ - x = GTK_CONTAINER(notebook)->border_width; - y = GTK_CONTAINER(notebook)->border_width; - width = widget->allocation.width - x * 2; - height = widget->allocation.height - y * 2; + return GTK_NOTEBOOK_PAGE (list)->menu_label; +} - if (notebook->show_tabs && notebook->children) - { - if (!(notebook->show_tabs)) - { - page = notebook->first_tab->data; - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += page->allocation.height + - widget->style->klass->ythickness; - case GTK_POS_BOTTOM: - height -= page->allocation.height + - widget->style->klass->ythickness; - break; - case GTK_POS_LEFT: - x += page->allocation.width + - widget->style->klass->xthickness; - case GTK_POS_RIGHT: - width -= page->allocation.width + - widget->style->klass->xthickness; - break; - } - } - else - { - page = notebook->cur_page; - if (!GTK_WIDGET_MAPPED (page->tab_label)) - { - if (notebook->tab_pos == GTK_POS_LEFT) - { - x -= widget->style->klass->xthickness * 2; - width += widget->style->klass->xthickness * 2; - } - else if (notebook->tab_pos == GTK_POS_RIGHT) - width += widget->style->klass->xthickness * 2; - } - switch (notebook->tab_pos) - { - case GTK_POS_TOP: - y += page->allocation.height; - case GTK_POS_BOTTOM: - height -= page->allocation.height; - break; - case GTK_POS_LEFT: - x += page->allocation.width; - case GTK_POS_RIGHT: - width -= page->allocation.width; - break; - } - } - } - gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); - - /* if theres an area for scrollign arrows draw the shape for them */ - if (notebook->panel) - { - gdk_window_get_geometry(notebook->panel, &x, &y, &width, &height, &depth); - gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); - } - - /* draw the shapes of all the children */ - children = notebook->children; - while (children) - { - page = children->data; - if (GTK_WIDGET_MAPPED (page->tab_label)) - { - x = page->allocation.x; - y = page->allocation.y; - width = page->allocation.width; - height = page->allocation.height; - gdk_draw_rectangle(pm, pmgc, TRUE, x, y, width, height); - } - children = children->next; - } - /* set the mask */ - gdk_window_shape_combine_mask(widget->window, pm, 0, 0); - gdk_pixmap_unref(pm); - gdk_gc_destroy(pmgc); -} - -static void -gtk_notebook_style_set (GtkWidget *widget, - GtkStyle *previous_style) +void +gtk_notebook_set_menu_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *menu_label) { - if (GTK_WIDGET_REALIZED (widget) && - !GTK_WIDGET_NO_WINDOW (widget)) - { - gtk_style_set_background (widget->style, widget->window, widget->state); - if (GTK_WIDGET_DRAWABLE (widget)) - gdk_window_clear (widget->window); - } - - gtk_widget_queue_draw (widget); - gtk_notebook_set_shape (GTK_NOTEBOOK(widget)); + GtkNotebookPage *page; + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; + + page = list->data; + if (page->menu_label) + { + if (notebook->menu) + { + gtk_container_remove (GTK_CONTAINER (notebook->menu), + page->menu_label->parent); + gtk_widget_queue_resize (notebook->menu); + } + if (!page->default_menu) + gtk_widget_unref (page->menu_label); + } + + if (menu_label) + { + page->menu_label = menu_label; + gtk_widget_ref (page->menu_label); + gtk_object_sink (GTK_OBJECT(page->menu_label)); + page->default_menu = FALSE; + } + else + page->default_menu = TRUE; + + if (notebook->menu) + gtk_notebook_menu_item_create (notebook, list); +} + +void +gtk_notebook_set_menu_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *menu_text) +{ + GtkWidget *menu_label = NULL; + + if (menu_text) + menu_label = gtk_label_new (menu_text); + gtk_notebook_set_menu_label (notebook, child, menu_label); +} + +void +gtk_notebook_set_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean expand, + gboolean fill, + GtkPackType pack_type) +{ + GtkNotebookPage *page; + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; + + page = list->data; + if (page->pack == pack_type && page->expand == expand && page->fill == fill) + return; + + page->expand = expand; + page->fill = fill; + + if (page->pack != pack_type) + { + page->pack = pack_type; + if (notebook->menu) + { + GtkWidget *menu_item; + + menu_item = page->menu_label->parent; + gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label); + gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item); + gtk_notebook_menu_item_create (notebook, list); + gtk_widget_queue_resize (notebook->menu); + } + gtk_notebook_update_labels (notebook); + } + + if (!notebook->show_tabs) + return; + + gtk_notebook_pages_allocate (notebook, &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); +} + +void +gtk_notebook_query_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean *expand, + gboolean *fill, + GtkPackType *pack_type) +{ + GList *list; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + + if (!(list = g_list_find_custom (notebook->children, child, + gtk_notebook_page_compare))) + return; + + if (expand) + *expand = GTK_NOTEBOOK_PAGE (list)->expand; + if (fill) + *fill = GTK_NOTEBOOK_PAGE (list)->fill; + if (pack_type) + *pack_type = GTK_NOTEBOOK_PAGE (list)->pack; +} + +void +gtk_notebook_reorder_child (GtkNotebook *notebook, + GtkWidget *child, + gint position) +{ + GList *list; + GList *work; + GtkNotebookPage *page; + gint old_pos; + + g_return_if_fail (notebook != NULL); + g_return_if_fail (GTK_IS_NOTEBOOK (notebook)); + g_return_if_fail (child != NULL); + g_return_if_fail (GTK_IS_WIDGET (child)); + + for (old_pos = 0, list = notebook->children; list; + list = list->next, old_pos++) + { + page = list->data; + if (page->child == child) + break; + } + + if (!list || old_pos == position) + return; + + notebook->children = g_list_remove_link (notebook->children, list); + + if (position <= 0 || !notebook->children) + { + list->next = notebook->children; + if (list->next) + list->next->prev = list; + notebook->children = list; + } + else if (position > 0 && (work = g_list_nth (notebook->children, position))) + { + list->prev = work->prev; + if (list->prev) + list->prev->next = list; + list->next = work; + work->prev = list; + } + else + { + work = g_list_last (notebook->children); + work->next = list; + list->prev = work; + } + + if (notebook->menu) + { + GtkWidget *menu_item; + + menu_item = page->menu_label->parent; + gtk_container_remove (GTK_CONTAINER (menu_item), page->menu_label); + gtk_container_remove (GTK_CONTAINER (notebook->menu), menu_item); + gtk_notebook_menu_item_create (notebook, list); + gtk_widget_queue_resize (notebook->menu); + } + + gtk_notebook_update_labels (notebook); + + if (notebook->show_tabs) + { + gtk_notebook_pages_allocate (notebook, + &(GTK_WIDGET (notebook)->allocation)); + gtk_notebook_expose_tabs (notebook); + } } diff --git a/gtk/gtknotebook.h b/gtk/gtknotebook.h index 013e08c2b0..ad049b9d10 100644 --- a/gtk/gtknotebook.h +++ b/gtk/gtknotebook.h @@ -35,6 +35,8 @@ extern "C" { #define GTK_IS_NOTEBOOK(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_NOTEBOOK)) #define GTK_IS_NOTEBOOK_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_NOTEBOOK)) +#define GTK_NOTEBOOK_PAGE(_glist_) ((GtkNotebookPage *)((GList *)(_glist_))->data) + typedef struct _GtkNotebook GtkNotebook; typedef struct _GtkNotebookClass GtkNotebookClass; @@ -54,16 +56,21 @@ struct _GtkNotebook guint32 timer; - guint16 tab_border; + guint16 tab_border; /* deprecated field, + * use tab_hborder, tab_vborder instead + */ + guint16 tab_hborder; + guint16 tab_vborder; - guint show_tabs : 1; - guint show_border : 1; - guint tab_pos : 2; - guint scrollable : 1; - guint in_child : 2; - guint click_child : 2; - guint button : 2; - guint need_timer : 1; + guint show_tabs : 1; + guint homogeneous : 1; + guint show_border : 1; + guint tab_pos : 2; + guint scrollable : 1; + guint in_child : 2; + guint click_child : 2; + guint button : 2; + guint need_timer : 1; guint child_has_focus : 1; }; @@ -81,62 +88,122 @@ struct _GtkNotebookPage GtkWidget *child; GtkWidget *tab_label; GtkWidget *menu_label; + guint default_menu : 1; guint default_tab : 1; + guint expand : 1; + guint fill : 1; + guint pack : 1; + GtkRequisition requisition; GtkAllocation allocation; }; +/*********************************************************** + * Creation, insertion, deletion * + ***********************************************************/ -GtkType gtk_notebook_get_type (void); -GtkWidget* gtk_notebook_new (void); -void gtk_notebook_append_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label); -void gtk_notebook_append_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label); -void gtk_notebook_prepend_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label); -void gtk_notebook_prepend_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label); -void gtk_notebook_insert_page (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - gint position); -void gtk_notebook_insert_page_menu (GtkNotebook *notebook, - GtkWidget *child, - GtkWidget *tab_label, - GtkWidget *menu_label, - gint position); -void gtk_notebook_remove_page (GtkNotebook *notebook, - gint page_num); -gint gtk_notebook_current_page (GtkNotebook *notebook); -gint gtk_notebook_page_num (GtkNotebook *notebook, - GtkWidget *child); -void gtk_notebook_set_page (GtkNotebook *notebook, - gint page_num); -void gtk_notebook_next_page (GtkNotebook *notebook); -void gtk_notebook_prev_page (GtkNotebook *notebook); -void gtk_notebook_reorder_child (GtkNotebook *notebook, - GtkWidget *child, - gint position); -void gtk_notebook_set_tab_pos (GtkNotebook *notebook, - GtkPositionType pos); -void gtk_notebook_set_show_tabs (GtkNotebook *notebook, - gboolean show_tabs); -void gtk_notebook_set_show_border (GtkNotebook *notebook, - gint show_border); -void gtk_notebook_set_scrollable (GtkNotebook *notebook, - gint scrollable); -void gtk_notebook_set_tab_border (GtkNotebook *notebook, - guint border_width); -void gtk_notebook_popup_enable (GtkNotebook *notebook); -void gtk_notebook_popup_disable (GtkNotebook *notebook); +GtkType gtk_notebook_get_type (void); +GtkWidget * gtk_notebook_new (void); +void gtk_notebook_append_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_notebook_append_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label); +void gtk_notebook_prepend_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_notebook_prepend_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label); +void gtk_notebook_insert_page (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + gint position); +void gtk_notebook_insert_page_menu (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label, + GtkWidget *menu_label, + gint position); +void gtk_notebook_remove_page (GtkNotebook *notebook, + gint page_num); + +/*********************************************************** + * query, set current NoteebookPage * + ***********************************************************/ + +gint gtk_notebook_current_page (GtkNotebook *notebook); +gint gtk_notebook_page_num (GtkNotebook *notebook, + GtkWidget *child); +void gtk_notebook_set_page (GtkNotebook *notebook, + gint page_num); +void gtk_notebook_next_page (GtkNotebook *notebook); +void gtk_notebook_prev_page (GtkNotebook *notebook); + +/*********************************************************** + * set Notebook, NotebookTab style * + ***********************************************************/ + +void gtk_notebook_set_show_border (GtkNotebook *notebook, + gboolean show_border); +void gtk_notebook_set_show_tabs (GtkNotebook *notebook, + gboolean show_tabs); +void gtk_notebook_set_tab_pos (GtkNotebook *notebook, + GtkPositionType pos); +void gtk_notebook_set_homogeneous_tabs (GtkNotebook *notebook, + gboolean homogeneous); +void gtk_notebook_set_tab_border (GtkNotebook *notebook, + guint border_width); +void gtk_notebook_set_tab_hborder (GtkNotebook *notebook, + guint tab_hborder); +void gtk_notebook_set_tab_vborder (GtkNotebook *notebook, + guint tab_vborder); +void gtk_notebook_set_scrollable (GtkNotebook *notebook, + gboolean scrollable); + +/*********************************************************** + * enable/disable PopupMenu * + ***********************************************************/ + +void gtk_notebook_popup_enable (GtkNotebook *notebook); +void gtk_notebook_popup_disable (GtkNotebook *notebook); + +/*********************************************************** + * query/set NotebookPage Properties * + ***********************************************************/ + +GtkWidget * gtk_notebook_query_tab_label (GtkNotebook *notebook, + GtkWidget *child); +void gtk_notebook_set_tab_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_notebook_set_tab_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *tab_text); +GtkWidget * gtk_notebook_query_menu_label (GtkNotebook *notebook, + GtkWidget *child); +void gtk_notebook_set_menu_label (GtkNotebook *notebook, + GtkWidget *child, + GtkWidget *menu_label); +void gtk_notebook_set_menu_label_text (GtkNotebook *notebook, + GtkWidget *child, + gchar *menu_text); +void gtk_notebook_query_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean *expand, + gboolean *fill, + GtkPackType *pack_type); +void gtk_notebook_set_tab_label_packing (GtkNotebook *notebook, + GtkWidget *child, + gboolean expand, + gboolean fill, + GtkPackType pack_type); +void gtk_notebook_reorder_child (GtkNotebook *notebook, + GtkWidget *child, + gint position); #ifdef __cplusplus } diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 6bc73ff347..31c5522615 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -5698,6 +5698,7 @@ GdkPixmap *book_open; GdkPixmap *book_closed; GdkBitmap *book_open_mask; GdkBitmap *book_closed_mask; +GtkWidget *sample_notebook; static void page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) @@ -5709,33 +5710,71 @@ page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) if (page == oldpage) return; - - pixwid = ((GtkBoxChild*)(GTK_BOX (page->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (page->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); if (oldpage) { - pixwid = ((GtkBoxChild*) (GTK_BOX - (oldpage->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (oldpage->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); } } +static void +tab_fill (GtkToggleButton *button, GtkWidget *child) +{ + gboolean expand; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, NULL, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, button->active, pack_type); +} + +static void +tab_expand (GtkToggleButton *button, GtkWidget *child) +{ + gboolean fill; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + NULL, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + button->active, fill, pack_type); +} + +static void +tab_pack (GtkToggleButton *button, GtkWidget *child) + +{ + gboolean expand; + gboolean fill; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, &fill, NULL); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, fill, button->active); +} + static void create_pages (GtkNotebook *notebook, gint start, gint end) { GtkWidget *child = NULL; + GtkWidget *button; GtkWidget *label; - GtkWidget *entry; - GtkWidget *box; GtkWidget *hbox; + GtkWidget *vbox; GtkWidget *label_box; GtkWidget *menu_box; - GtkWidget *button; GtkWidget *pixwid; gint i; char buffer[32]; @@ -5743,47 +5782,38 @@ create_pages (GtkNotebook *notebook, gint start, gint end) for (i = start; i <= end; i++) { sprintf (buffer, "Page %d", i); - - switch (i % 4) - { - case 3: - child = gtk_button_new_with_label (buffer); - gtk_container_border_width (GTK_CONTAINER(child), 10); - break; - case 2: - child = gtk_label_new (buffer); - break; - case 1: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); - - box = gtk_vbox_new (TRUE,0); - gtk_container_border_width (GTK_CONTAINER (box), 10); - gtk_container_add (GTK_CONTAINER (child), box); - label = gtk_label_new (buffer); - gtk_box_pack_start (GTK_BOX(box), label, TRUE, TRUE, 5); + child = gtk_frame_new (buffer); + gtk_container_border_width (GTK_CONTAINER (child), 10); - entry = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX(box), entry, TRUE, TRUE, 5); - - hbox = gtk_hbox_new (TRUE,0); - gtk_box_pack_start (GTK_BOX(box), hbox, TRUE, TRUE, 5); + vbox = gtk_vbox_new (TRUE,0); + gtk_container_border_width (GTK_CONTAINER (vbox), 10); + gtk_container_add (GTK_CONTAINER (child), vbox); - button = gtk_button_new_with_label ("Ok"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); + hbox = gtk_hbox_new (TRUE,0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); - button = gtk_button_new_with_label ("Cancel"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); - break; - case 0: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); + button = gtk_check_button_new_with_label ("Fill Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_fill), child); - label = gtk_label_new (buffer); - gtk_container_add (GTK_CONTAINER (child), label); - break; - } + button = gtk_check_button_new_with_label ("Expand Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_expand), child); + + button = gtk_check_button_new_with_label ("Pack end"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_pack), child); + + button = gtk_button_new_with_label ("Hide Page"); + gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_hide), + GTK_OBJECT (child)); gtk_widget_show_all (child); @@ -5794,7 +5824,7 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0); gtk_widget_show_all (label_box); - + menu_box = gtk_hbox_new (FALSE, 0); pixwid = gtk_pixmap_new (book_closed, book_closed_mask); gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0); @@ -5802,7 +5832,6 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0); gtk_widget_show_all (menu_box); - gtk_notebook_append_page_menu (notebook, child, label_box, menu_box); } } @@ -5814,9 +5843,17 @@ rotate_notebook (GtkButton *button, gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4); } +static void +show_all_pages (GtkButton *button, + GtkNotebook *notebook) +{ + gtk_container_foreach (GTK_CONTAINER (notebook), + (GtkCallback) gtk_widget_show, NULL); +} + static void standard_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5829,7 +5866,7 @@ standard_notebook (GtkButton *button, static void notabs_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5841,7 +5878,7 @@ notabs_notebook (GtkButton *button, static void scrollable_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gtk_notebook_set_show_tabs (notebook, TRUE); gtk_notebook_set_scrollable (notebook, TRUE); @@ -5859,6 +5896,13 @@ notebook_popup (GtkToggleButton *button, gtk_notebook_popup_disable (notebook); } +static void +notebook_homogeneous (GtkToggleButton *button, + GtkNotebook *notebook) +{ + gtk_notebook_set_homogeneous_tabs (notebook, button->active); +} + static void create_notebook (void) { @@ -5867,9 +5911,9 @@ create_notebook (void) GtkWidget *box2; GtkWidget *button; GtkWidget *separator; - GtkWidget *notebook; GtkWidget *omenu; GdkColor *transparent = NULL; + GtkWidget *label; static OptionMenuItem items[] = { @@ -5892,72 +5936,91 @@ create_notebook (void) box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), box1); - notebook = gtk_notebook_new (); - gtk_signal_connect (GTK_OBJECT (notebook), "switch_page", + sample_notebook = gtk_notebook_new (); + gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page", GTK_SIGNAL_FUNC (page_switch), NULL); - gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); - gtk_box_pack_start (GTK_BOX (box1), notebook, TRUE, TRUE, 0); - gtk_container_border_width (GTK_CONTAINER (notebook), 10); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP); + gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (sample_notebook), 10); - gtk_widget_realize (notebook); - book_open = gdk_pixmap_create_from_xpm_d (notebook->window, + gtk_widget_realize (sample_notebook); + book_open = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_open_mask, transparent, book_open_xpm); - book_closed = gdk_pixmap_create_from_xpm_d (notebook->window, + book_closed = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_closed_mask, transparent, book_closed_xpm); - create_pages (GTK_NOTEBOOK (notebook), 1, 5); + create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10); - box2 = gtk_hbox_new (TRUE, 5); + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - omenu = build_option_menu (items, 3, 0, notebook); - gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, FALSE, 0); - button = gtk_check_button_new_with_label ("enable popup menu"); - gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0); + button = gtk_check_button_new_with_label ("popup menu"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC (notebook_popup), - GTK_OBJECT (notebook)); - + GTK_OBJECT (sample_notebook)); + + button = gtk_check_button_new_with_label ("homogeneous tabs"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC (notebook_homogeneous), + GTK_OBJECT (sample_notebook)); + + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); + gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); + + label = gtk_label_new ("Notebook Style :"); + gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0); + + omenu = build_option_menu (items, 3, 0, sample_notebook); + gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0); + + button = gtk_button_new_with_label ("Show all Pages"); + gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (show_all_pages), sample_notebook); + box2 = gtk_hbox_new (TRUE, 10); gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - button = gtk_button_new_with_label ("close"); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_widget_destroy), - GTK_OBJECT (window)); - gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); - gtk_widget_grab_default (button); - - button = gtk_button_new_with_label ("next"); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_notebook_next_page), - GTK_OBJECT (notebook)); - gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); button = gtk_button_new_with_label ("prev"); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_notebook_prev_page), - GTK_OBJECT (notebook)); + GTK_OBJECT (sample_notebook)); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); + + button = gtk_button_new_with_label ("next"); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_notebook_next_page), + GTK_OBJECT (sample_notebook)); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); button = gtk_button_new_with_label ("rotate"); gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (rotate_notebook), - notebook); + GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); + + separator = gtk_hseparator_new (); + gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5); + + button = gtk_button_new_with_label ("close"); + gtk_container_border_width (GTK_CONTAINER (button), 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (window)); + gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); } if (!GTK_WIDGET_VISIBLE (window)) diff --git a/tests/testgtk.c b/tests/testgtk.c index 6bc73ff347..31c5522615 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -5698,6 +5698,7 @@ GdkPixmap *book_open; GdkPixmap *book_closed; GdkBitmap *book_open_mask; GdkBitmap *book_closed_mask; +GtkWidget *sample_notebook; static void page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) @@ -5709,33 +5710,71 @@ page_switch (GtkWidget *widget, GtkNotebookPage *page, gint page_num) if (page == oldpage) return; - - pixwid = ((GtkBoxChild*)(GTK_BOX (page->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (page->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (page->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_open, book_open_mask); if (oldpage) { - pixwid = ((GtkBoxChild*) (GTK_BOX - (oldpage->tab_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->tab_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); - pixwid = ((GtkBoxChild*) (GTK_BOX (oldpage->menu_label)->children->data))->widget; + pixwid = ((GtkBoxChild*) + (GTK_BOX (oldpage->menu_label)->children->data))->widget; gtk_pixmap_set (GTK_PIXMAP (pixwid), book_closed, book_closed_mask); } } +static void +tab_fill (GtkToggleButton *button, GtkWidget *child) +{ + gboolean expand; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, NULL, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, button->active, pack_type); +} + +static void +tab_expand (GtkToggleButton *button, GtkWidget *child) +{ + gboolean fill; + GtkPackType pack_type; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + NULL, &fill, &pack_type); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + button->active, fill, pack_type); +} + +static void +tab_pack (GtkToggleButton *button, GtkWidget *child) + +{ + gboolean expand; + gboolean fill; + + gtk_notebook_query_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + &expand, &fill, NULL); + gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (sample_notebook), child, + expand, fill, button->active); +} + static void create_pages (GtkNotebook *notebook, gint start, gint end) { GtkWidget *child = NULL; + GtkWidget *button; GtkWidget *label; - GtkWidget *entry; - GtkWidget *box; GtkWidget *hbox; + GtkWidget *vbox; GtkWidget *label_box; GtkWidget *menu_box; - GtkWidget *button; GtkWidget *pixwid; gint i; char buffer[32]; @@ -5743,47 +5782,38 @@ create_pages (GtkNotebook *notebook, gint start, gint end) for (i = start; i <= end; i++) { sprintf (buffer, "Page %d", i); - - switch (i % 4) - { - case 3: - child = gtk_button_new_with_label (buffer); - gtk_container_border_width (GTK_CONTAINER(child), 10); - break; - case 2: - child = gtk_label_new (buffer); - break; - case 1: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); - - box = gtk_vbox_new (TRUE,0); - gtk_container_border_width (GTK_CONTAINER (box), 10); - gtk_container_add (GTK_CONTAINER (child), box); - label = gtk_label_new (buffer); - gtk_box_pack_start (GTK_BOX(box), label, TRUE, TRUE, 5); + child = gtk_frame_new (buffer); + gtk_container_border_width (GTK_CONTAINER (child), 10); - entry = gtk_entry_new (); - gtk_box_pack_start (GTK_BOX(box), entry, TRUE, TRUE, 5); - - hbox = gtk_hbox_new (TRUE,0); - gtk_box_pack_start (GTK_BOX(box), hbox, TRUE, TRUE, 5); + vbox = gtk_vbox_new (TRUE,0); + gtk_container_border_width (GTK_CONTAINER (vbox), 10); + gtk_container_add (GTK_CONTAINER (child), vbox); - button = gtk_button_new_with_label ("Ok"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); + hbox = gtk_hbox_new (TRUE,0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5); - button = gtk_button_new_with_label ("Cancel"); - gtk_box_pack_start (GTK_BOX(hbox), button, TRUE, TRUE, 5); - break; - case 0: - child = gtk_frame_new (buffer); - gtk_container_border_width (GTK_CONTAINER (child), 10); + button = gtk_check_button_new_with_label ("Fill Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (button), TRUE); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_fill), child); - label = gtk_label_new (buffer); - gtk_container_add (GTK_CONTAINER (child), label); - break; - } + button = gtk_check_button_new_with_label ("Expand Tab"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_expand), child); + + button = gtk_check_button_new_with_label ("Pack end"); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5); + gtk_signal_connect (GTK_OBJECT (button), "toggled", + GTK_SIGNAL_FUNC (tab_pack), child); + + button = gtk_button_new_with_label ("Hide Page"); + gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_hide), + GTK_OBJECT (child)); gtk_widget_show_all (child); @@ -5794,7 +5824,7 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0); gtk_widget_show_all (label_box); - + menu_box = gtk_hbox_new (FALSE, 0); pixwid = gtk_pixmap_new (book_closed, book_closed_mask); gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0); @@ -5802,7 +5832,6 @@ create_pages (GtkNotebook *notebook, gint start, gint end) label = gtk_label_new (buffer); gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0); gtk_widget_show_all (menu_box); - gtk_notebook_append_page_menu (notebook, child, label_box, menu_box); } } @@ -5814,9 +5843,17 @@ rotate_notebook (GtkButton *button, gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos + 1) % 4); } +static void +show_all_pages (GtkButton *button, + GtkNotebook *notebook) +{ + gtk_container_foreach (GTK_CONTAINER (notebook), + (GtkCallback) gtk_widget_show, NULL); +} + static void standard_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5829,7 +5866,7 @@ standard_notebook (GtkButton *button, static void notabs_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gint i; @@ -5841,7 +5878,7 @@ notabs_notebook (GtkButton *button, static void scrollable_notebook (GtkButton *button, - GtkNotebook *notebook) + GtkNotebook *notebook) { gtk_notebook_set_show_tabs (notebook, TRUE); gtk_notebook_set_scrollable (notebook, TRUE); @@ -5859,6 +5896,13 @@ notebook_popup (GtkToggleButton *button, gtk_notebook_popup_disable (notebook); } +static void +notebook_homogeneous (GtkToggleButton *button, + GtkNotebook *notebook) +{ + gtk_notebook_set_homogeneous_tabs (notebook, button->active); +} + static void create_notebook (void) { @@ -5867,9 +5911,9 @@ create_notebook (void) GtkWidget *box2; GtkWidget *button; GtkWidget *separator; - GtkWidget *notebook; GtkWidget *omenu; GdkColor *transparent = NULL; + GtkWidget *label; static OptionMenuItem items[] = { @@ -5892,72 +5936,91 @@ create_notebook (void) box1 = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), box1); - notebook = gtk_notebook_new (); - gtk_signal_connect (GTK_OBJECT (notebook), "switch_page", + sample_notebook = gtk_notebook_new (); + gtk_signal_connect (GTK_OBJECT (sample_notebook), "switch_page", GTK_SIGNAL_FUNC (page_switch), NULL); - gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); - gtk_box_pack_start (GTK_BOX (box1), notebook, TRUE, TRUE, 0); - gtk_container_border_width (GTK_CONTAINER (notebook), 10); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP); + gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0); + gtk_container_border_width (GTK_CONTAINER (sample_notebook), 10); - gtk_widget_realize (notebook); - book_open = gdk_pixmap_create_from_xpm_d (notebook->window, + gtk_widget_realize (sample_notebook); + book_open = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_open_mask, transparent, book_open_xpm); - book_closed = gdk_pixmap_create_from_xpm_d (notebook->window, + book_closed = gdk_pixmap_create_from_xpm_d (sample_notebook->window, &book_closed_mask, transparent, book_closed_xpm); - create_pages (GTK_NOTEBOOK (notebook), 1, 5); + create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10); - box2 = gtk_hbox_new (TRUE, 5); + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - omenu = build_option_menu (items, 3, 0, notebook); - gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, FALSE, 0); - button = gtk_check_button_new_with_label ("enable popup menu"); - gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0); + button = gtk_check_button_new_with_label ("popup menu"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC (notebook_popup), - GTK_OBJECT (notebook)); - + GTK_OBJECT (sample_notebook)); + + button = gtk_check_button_new_with_label ("homogeneous tabs"); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC (notebook_homogeneous), + GTK_OBJECT (sample_notebook)); + + box2 = gtk_hbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (box2), 10); + gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); + + label = gtk_label_new ("Notebook Style :"); + gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0); + + omenu = build_option_menu (items, 3, 0, sample_notebook); + gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0); + + button = gtk_button_new_with_label ("Show all Pages"); + gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (show_all_pages), sample_notebook); + box2 = gtk_hbox_new (TRUE, 10); gtk_container_border_width (GTK_CONTAINER (box2), 10); gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0); - - button = gtk_button_new_with_label ("close"); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_widget_destroy), - GTK_OBJECT (window)); - gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); - gtk_widget_grab_default (button); - - button = gtk_button_new_with_label ("next"); - gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (gtk_notebook_next_page), - GTK_OBJECT (notebook)); - gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); button = gtk_button_new_with_label ("prev"); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (gtk_notebook_prev_page), - GTK_OBJECT (notebook)); + GTK_OBJECT (sample_notebook)); + gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); + + button = gtk_button_new_with_label ("next"); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_notebook_next_page), + GTK_OBJECT (sample_notebook)); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); - GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); button = gtk_button_new_with_label ("rotate"); gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (rotate_notebook), - notebook); + GTK_SIGNAL_FUNC (rotate_notebook), sample_notebook); gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0); + + separator = gtk_hseparator_new (); + gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5); + + button = gtk_button_new_with_label ("close"); + gtk_container_border_width (GTK_CONTAINER (button), 5); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + GTK_OBJECT (window)); + gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); } if (!GTK_WIDGET_VISIBLE (window))